83 void readOld(T & image,
const std::string &path,
int png_transforms = 0);
89 void read(
ImageFrame & image,
const std::string &path,
int png_transforms = 0);
119 void readFile(
const std::string & path, png_structp & png_ptr, png_infop & info_ptr,
int png_transforms);
125 void readConfiguration(png_structp & png_ptr, png_infop & info_ptr,
ImageConf & conf);
128 void copyData(png_structp & png_ptr, png_infop & info_ptr,
const ImageConf & pngConf,
ImageFrame & image);
132 void copyData8to8(png_structp & png_ptr, png_infop & info_ptr,
ImageFrame & image);
135 void copyData8to16(png_structp & png_ptr, png_infop & info_ptr,
ImageFrame & image);
138 void copyData16(png_structp & png_ptr, png_infop & info_ptr,
ImageFrame & image);
148 mout.
debug(
"path='" , path ,
"'" );
152 FILE *fp = fopen(path.c_str(),
"rb");
154 throw std::runtime_error(std::string(
"FilePng: could not open file: ") + path);
159 const size_t PNG_BYTES_TO_CHECK=4;
160 png_byte buf[PNG_BYTES_TO_CHECK];
163 if (fread((
void *)buf,
size_t(1), PNG_BYTES_TO_CHECK, fp) != PNG_BYTES_TO_CHECK){
165 throw std::runtime_error(std::string(
"FilePng: suspicious size of file: ") + path);
170 if (png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK) != 0){
172 throw std::runtime_error(std::string(
"FilePng: not a png file: ") + path);
176 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
179 throw std::runtime_error(std::string(
"FilePng: problem in allocating image memory for: ")+path);
182 png_infop info_ptr = png_create_info_struct(png_ptr);
185 png_destroy_read_struct(&png_ptr,(png_infopp)NULL, (png_infopp)NULL);
186 throw std::runtime_error(std::string(
"FilePng: problem in allocating info memory for: ")+path);
199 png_set_palette_to_rgb(png_ptr);
201 png_init_io(png_ptr, fp);
202 png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK);
206 mout.debug3(
"reading data" );
208 png_read_png(png_ptr, info_ptr, png_transforms, NULL);
215 mout.debug3(
"reading image comments" );
217 png_textp text_ptr = NULL;
218 png_get_text(png_ptr, info_ptr,&text_ptr, &num_text);
220 for (
int i = 0; i < num_text; ++i) {
221 mout << text_ptr[i].key <<
'=' << text_ptr[i].text <<
'\n';
228 const unsigned int inputBitDepth = png_get_bit_depth(png_ptr, info_ptr);
230 switch (inputBitDepth) {
233 t.setType<
unsigned short>();
236 t.setType<
unsigned char>();
240 png_destroy_read_struct(&png_ptr,&info_ptr, (png_infopp)NULL);
242 throw std::runtime_error(std::string(
"FilePng: unsupported bit depth in : ")+path);
247 mout.
debug(
"initialize, type " , image.getType().name() );
250 const unsigned int width = png_get_image_width(png_ptr, info_ptr);
251 const unsigned int height = png_get_image_height(png_ptr, info_ptr);
252 const unsigned int channels = png_get_channels(png_ptr, info_ptr);
258 if ((channels!=g.channels.
getChannelCount()) || (width!=g.area.getWidth()) || (height!=g.area.getHeight())){
261 g.set(width,height,3,1);
264 g.setGeometry(width,height,3);
267 g.set(width,height,1,1);
270 g.setGeometry(width,height,1);
273 throw std::runtime_error(std::string(
"FilePng: invalid channel count in : ")+path);
278 image.initialize(t, g);
280 mout.debug3() <<
"png geometry ok, ";
281 mout <<
"png channels =" << channels <<
"\n";
282 mout <<
"png bit_depth=" << inputBitDepth <<
"\n";
286#ifdef PNG_pCAL_SUPPORTED___DEFUNCT
288 if (info_ptr->pcal_X0 == info_ptr->pcal_X1){
289 mout.toOStr() <<
"physical scale supported, but no intensity range, pcalX0=" << info_ptr->pcal_X0 <<
", pcalX1=" << info_ptr->pcal_X1 << mout.endl;
290 image.setDefaultLimits();
293 image.setLimits(info_ptr->pcal_X0, info_ptr->pcal_X1);
294 mout.
note(
"setting physical scale: " , image );
307 const unsigned int targetBitDepth = 8*image.getConf().getElementSize();
309 const bool from8to8 = (inputBitDepth == 8) && (targetBitDepth == 8);
310 const bool from8to16 = (inputBitDepth == 8) && (targetBitDepth == 16);
313 mout.
debug(
"8-bit input, 8-bit target, easy..." );
315 else if (from8to16) {
316 mout.
note(
"-bit input, 16-bit target, rescaling..." );
319 if ((inputBitDepth == 16) && (targetBitDepth == 16)){
320 mout.
debug(
"16-bit input, 16-bit target, ok..." );
323 mout.
warn(inputBitDepth ,
"-bit input, ", targetBitDepth ,
"-bit target, problems ahead?" );
327 png_bytep *row_pointers = png_get_rows(png_ptr, info_ptr);
330 for (
unsigned int j = 0; j < height; ++j) {
332 for (
unsigned int i = 0; i < width; ++i) {
333 for (
unsigned int k = 0; k < channels; ++k) {
336 image.put(i,j,k, p[i0]);
338 else if (from8to16) {
339 image.put(i,j,k, p[i0]<<8);
342 image.put(i,j,k, (p[i0*2]<<8) + (p[i0*2+1]<<0));
349 png_destroy_read_struct(&png_ptr,&info_ptr, (png_infopp)NULL);