80 void readOld(T & image,
const std::string &path,
int png_transforms = 0);
86 void read(
ImageFrame & image,
const std::string &path,
int png_transforms = 0);
116 void readFile(
const std::string & path, png_structp & png_ptr, png_infop & info_ptr,
int png_transforms);
122 void readConfiguration(png_structp & png_ptr, png_infop & info_ptr,
ImageConf & conf);
125 void copyData(png_structp & png_ptr, png_infop & info_ptr,
const ImageConf & pngConf,
ImageFrame & image);
129 void copyData8to8(png_structp & png_ptr, png_infop & info_ptr,
ImageFrame & image);
132 void copyData8to16(png_structp & png_ptr, png_infop & info_ptr,
ImageFrame & image);
135 void copyData16(png_structp & png_ptr, png_infop & info_ptr,
ImageFrame & image);
145 mout.
debug(
"path='" , path ,
"'" );
149 FILE *fp = fopen(path.c_str(),
"rb");
151 throw std::runtime_error(std::string(
"FilePng: could not open file: ") + path);
156 const size_t PNG_BYTES_TO_CHECK=4;
157 png_byte buf[PNG_BYTES_TO_CHECK];
160 if (fread((
void *)buf,
size_t(1), PNG_BYTES_TO_CHECK, fp) != PNG_BYTES_TO_CHECK){
162 throw std::runtime_error(std::string(
"FilePng: suspicious size of file: ") + path);
167 if (png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK) != 0){
169 throw std::runtime_error(std::string(
"FilePng: not a png file: ") + path);
173 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
176 throw std::runtime_error(std::string(
"FilePng: problem in allocating image memory for: ")+path);
179 png_infop info_ptr = png_create_info_struct(png_ptr);
182 png_destroy_read_struct(&png_ptr,(png_infopp)NULL, (png_infopp)NULL);
183 throw std::runtime_error(std::string(
"FilePng: problem in allocating info memory for: ")+path);
196 png_set_palette_to_rgb(png_ptr);
198 png_init_io(png_ptr, fp);
199 png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK);
203 mout.debug3(
"reading data" );
205 png_read_png(png_ptr, info_ptr, png_transforms, NULL);
212 mout.debug3(
"reading image comments" );
214 png_textp text_ptr = NULL;
215 png_get_text(png_ptr, info_ptr,&text_ptr, &num_text);
217 for (
int i = 0; i < num_text; ++i) {
218 mout << text_ptr[i].key <<
'=' << text_ptr[i].text <<
'\n';
225 const unsigned int inputBitDepth = png_get_bit_depth(png_ptr, info_ptr);
227 switch (inputBitDepth) {
230 t.setType<
unsigned short>();
233 t.setType<
unsigned char>();
237 png_destroy_read_struct(&png_ptr,&info_ptr, (png_infopp)NULL);
239 throw std::runtime_error(std::string(
"FilePng: unsupported bit depth in : ")+path);
244 mout.
debug(
"initialize, type " , image.getType().name() );
247 const unsigned int width = png_get_image_width(png_ptr, info_ptr);
248 const unsigned int height = png_get_image_height(png_ptr, info_ptr);
249 const unsigned int channels = png_get_channels(png_ptr, info_ptr);
255 if ((channels!=g.channels.
getChannelCount()) || (width!=g.area.getWidth()) || (height!=g.area.getHeight())){
258 g.set(width,height,3,1);
261 g.setGeometry(width,height,3);
264 g.set(width,height,1,1);
267 g.setGeometry(width,height,1);
270 throw std::runtime_error(std::string(
"FilePng: invalid channel count in : ")+path);
275 image.initialize(t, g);
277 mout.debug3() <<
"png geometry ok, ";
278 mout <<
"png channels =" << channels <<
"\n";
279 mout <<
"png bit_depth=" << inputBitDepth <<
"\n";
283#ifdef PNG_pCAL_SUPPORTED___DEFUNCT
285 if (info_ptr->pcal_X0 == info_ptr->pcal_X1){
286 mout.toOStr() <<
"physical scale supported, but no intensity range, pcalX0=" << info_ptr->pcal_X0 <<
", pcalX1=" << info_ptr->pcal_X1 << mout.endl;
287 image.setDefaultLimits();
290 image.setLimits(info_ptr->pcal_X0, info_ptr->pcal_X1);
291 mout.
note(
"setting physical scale: " , image );
304 const unsigned int targetBitDepth = 8*image.getConf().getElementSize();
306 const bool from8to8 = (inputBitDepth == 8) && (targetBitDepth == 8);
307 const bool from8to16 = (inputBitDepth == 8) && (targetBitDepth == 16);
310 mout.
debug(
"8-bit input, 8-bit target, easy..." );
312 else if (from8to16) {
313 mout.
note(
"-bit input, 16-bit target, rescaling..." );
316 if ((inputBitDepth == 16) && (targetBitDepth == 16)){
317 mout.
debug(
"16-bit input, 16-bit target, ok..." );
320 mout.
warn(inputBitDepth ,
"-bit input, ", targetBitDepth ,
"-bit target, problems ahead?" );
324 png_bytep *row_pointers = png_get_rows(png_ptr, info_ptr);
327 for (
unsigned int j = 0; j < height; ++j) {
329 for (
unsigned int i = 0; i < width; ++i) {
330 for (
unsigned int k = 0; k < channels; ++k) {
333 image.put(i,j,k, p[i0]);
335 else if (from8to16) {
336 image.put(i,j,k, p[i0]<<8);
339 image.put(i,j,k, (p[i0*2]<<8) + (p[i0*2+1]<<0));
346 png_destroy_read_struct(&png_ptr,&info_ptr, (png_infopp)NULL);