10 #ifndef PNGREADER_HPP_
11 #define PNGREADER_HPP_
39 template<
class Container2d,
typename T, std::
size_t Nb_components, std::
size_t Nb_block>
55 :
base(),png_ptr(NULL),info_ptr(NULL),sig_read(0),width(0),height(0),bit_depth(0),color_type(0),
56 interlace_type(0), number_passes(0),infile(NULL),row_stride(0),
57 block_ind(1),block_size(0),last_block_size(0),last_it(0),finished(0),initialized(0)
66 :
base(data_filename),png_ptr(NULL),info_ptr(NULL),sig_read(0),width(0),height(0),bit_depth(0),color_type(0),
67 interlace_type(0), number_passes(0),infile(NULL),row_stride(0),
68 block_ind(1),block_size(0),last_block_size(0),last_it(0),finished(0),initialized(0)
105 int read(Container2d & in);
111 unsigned int sig_read;
112 png_uint_32 width, height;
113 int bit_depth, color_type, interlace_type, number_passes;
114 png_bytep row_pointers[1];
132 template<
class Container2d,
typename T, std::
size_t Nb_components, std::
size_t Nb_block>
136 if (Nb_components != 1 && Nb_components != 3){
137 std::ostringstream err;
138 err <<
FILE_READ_ERROR << this->data_filename_ <<
" | Nb_components should be 1 or 3.";
139 slip::slip_exception exc(std::string(
"slip"), std::string(
"PngReader::initialize()"), err.str());
143 if ((infile = fopen(this->data_filename_.c_str(),
"rb")) == NULL) {
144 std::ostringstream err;
146 slip::slip_exception exc(std::string(
"slip"), std::string(
"PngReader::initialize()"), err.str());
156 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
160 std::ostringstream err;
161 err <<
FILE_READ_ERROR << this->data_filename_ <<
" | png_struct initialization failed.";
162 slip::slip_exception exc(std::string(
"slip"), std::string(
"PngReader::initialize()"), err.str());
168 info_ptr = png_create_info_struct(png_ptr);
169 if (info_ptr == NULL)
171 png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
173 std::ostringstream err;
174 err <<
FILE_READ_ERROR << this->data_filename_ <<
" | info_ptr initialization failed.";
175 slip::slip_exception exc(std::string(
"slip"), std::string(
"PngReader::initialize()"), err.str());
184 if (setjmp(png_jmpbuf(png_ptr)))
187 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
190 std::ostringstream err;
191 err <<
FILE_READ_ERROR << this->data_filename_ <<
" | PNG library has signaled an error";
192 slip::slip_exception exc(std::string(
"slip"), std::string(
"PngReader::initialize()"), err.str());
197 png_init_io(png_ptr, infile);
200 png_set_sig_bytes(png_ptr, sig_read);
205 png_read_info(png_ptr, info_ptr);
207 png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
208 &interlace_type, int_p_NULL, int_p_NULL);
210 if(png_ptr->channels != Nb_components){
212 std::ostringstream err;
213 err <<
FILE_READ_ERROR << this->data_filename_ <<
" | Nb_components does not match.";
214 slip::slip_exception exc(std::string(
"slip"), std::string(
"PngReader::initialize()"), err.str());
225 png_set_strip_16(png_ptr);
235 png_set_packing(png_ptr);
239 png_set_packswap(png_ptr);
243 if (color_type == PNG_COLOR_TYPE_PALETTE){
244 png_set_palette_to_rgb(png_ptr);
248 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8){
249 png_set_expand_gray_1_2_4_to_8(png_ptr);
253 png_set_swap(png_ptr);
259 number_passes = png_set_interlace_handling(png_ptr);
262 row_pointers[0] = NULL;
265 row_pointers[0] =
reinterpret_cast<png_bytep
>(png_malloc(png_ptr, png_get_rowbytes(png_ptr,info_ptr)));
268 row_stride = png_get_rowbytes(png_ptr,info_ptr);
269 block_size =
static_cast<int>(height) / Nb_block;
270 last_block_size =
static_cast<int>(height) % Nb_block;
271 last_block_size = (last_block_size == 0 ? block_size : block_size+last_block_size);
272 last_it = (Nb_block == 1);
273 finished = (last_it && last_block_size == 0);
278 template<
class Container2d,
typename T, std::
size_t Nb_components, std::
size_t Nb_block>
281 std::ostringstream err;
282 err <<
FILE_READ_ERROR << this->data_filename_ <<
" | The reader needs to be initialized before reading.";
290 in.resize(last_block_size,static_cast<std::size_t>(width),T());
292 in.resize(block_size,static_cast<std::size_t>(width),T());
294 if(static_cast<std::size_t>(height) - static_cast<std::size_t>(png_ptr->row_number)< in.height()){
295 std::ostringstream err;
296 err <<
FILE_READ_ERROR << this->data_filename_ <<
" | Bad image dimensions.";
303 for (
int pass = 0; pass < number_passes; pass++)
306 for(
unsigned int i=0; i < in.height(); ++i)
308 png_read_rows(png_ptr, &row_pointers[0], png_bytepp_NULL, 1);
309 T * ptr_i =
reinterpret_cast<T *
>(in[i]);
310 std::copy(row_pointers[0],row_pointers[0]+row_stride,ptr_i);
317 png_read_end(png_ptr, info_ptr);
321 last_it = (block_ind == Nb_block);
325 template<
class Container2d,
typename T, std::
size_t Nb_components, std::
size_t Nb_block>
331 png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
338 free(row_pointers[0]);
virtual ~PngReader()
Destructor.
Contains the container reader base class.
int read(Container2d &in)
virtual read function. If Nb_block is more than one, it reads only one container, and returns 0...
standard exception extension name have been changed to eliminate conflicts with QT ...
PngReader()
Default constructor.
Some definitions specific to libpng.
const std::string FILE_OPEN_ERROR
ContainerReader is the base class of the readers classes. All readers are working the same way: ...
void copy(_II first, _II last, _OI output_first)
Copy algorithm optimized for slip iterators.
void release()
release the reading process.
Provides SLIP error messages.
void initialize()
initialized the reading process.
PngReader(std::string data_filename)
PngReader, inherited from ContainerReader, is a reader for png images.
Container2d container_type
ContainerReader< Container2d, T, Nb_block > base
const std::string FILE_READ_ERROR