42 #include "drain/util/FileInfo.h"
44 #include "drain/util/JSON.h"
83 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);
118 mout.
debug(
"path='" , path ,
"'" );
122 FILE *fp = fopen(path.c_str(),
"rb");
124 throw std::runtime_error(std::string(
"FilePng: could not open file: ") + path);
129 const size_t PNG_BYTES_TO_CHECK=4;
130 png_byte buf[PNG_BYTES_TO_CHECK];
133 if (fread((
void *)buf,
size_t(1), PNG_BYTES_TO_CHECK, fp) != PNG_BYTES_TO_CHECK){
135 throw std::runtime_error(std::string(
"FilePng: suspicious size of file: ") + path);
140 if (png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK) != 0){
142 throw std::runtime_error(std::string(
"FilePng: not a png file: ") + path);
146 png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
149 throw std::runtime_error(std::string(
"FilePng: problem in allocating image memory for: ")+path);
152 png_infop info_ptr = png_create_info_struct(png_ptr);
155 png_destroy_read_struct(&png_ptr,(png_infopp)NULL, (png_infopp)NULL);
156 throw std::runtime_error(std::string(
"FilePng: problem in allocating info memory for: ")+path);
169 png_set_palette_to_rgb(png_ptr);
171 png_init_io(png_ptr, fp);
172 png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK);
176 mout.debug3(
"reading data" );
178 png_read_png(png_ptr, info_ptr, png_transforms, NULL);
185 mout.debug3(
"reading image comments" );
187 png_textp text_ptr = NULL;
188 png_get_text(png_ptr, info_ptr,&text_ptr, &num_text);
190 for (
int i = 0; i < num_text; ++i) {
191 mout << text_ptr[i].key <<
'=' << text_ptr[i].text <<
'\n';
198 const unsigned int inputBitDepth = png_get_bit_depth(png_ptr, info_ptr);
200 switch (inputBitDepth) {
203 t.setType<
unsigned short>();
206 t.setType<
unsigned char>();
210 png_destroy_read_struct(&png_ptr,&info_ptr, (png_infopp)NULL);
212 throw std::runtime_error(std::string(
"FilePng: unsupported bit depth in : ")+path);
217 mout.
debug(
"initialize, type " , image.getType().name() );
220 const unsigned int width = png_get_image_width(png_ptr, info_ptr);
221 const unsigned int height = png_get_image_height(png_ptr, info_ptr);
222 const unsigned int channels = png_get_channels(png_ptr, info_ptr);
228 if ((channels!=g.channels.
getChannelCount()) || (width!=g.area.getWidth()) || (height!=g.area.getHeight())){
231 g.set(width,height,3,1);
234 g.setGeometry(width,height,3);
237 g.set(width,height,1,1);
240 g.setGeometry(width,height,1);
243 throw std::runtime_error(std::string(
"FilePng: invalid channel count in : ")+path);
248 image.initialize(t, g);
250 mout.debug3() <<
"png geometry ok, ";
251 mout <<
"png channels =" << channels <<
"\n";
252 mout <<
"png bit_depth=" << inputBitDepth <<
"\n";
256 #ifdef PNG_pCAL_SUPPORTED___DEFUNCT
258 if (info_ptr->pcal_X0 == info_ptr->pcal_X1){
259 mout.toOStr() <<
"physical scale supported, but no intensity range, pcalX0=" << info_ptr->pcal_X0 <<
", pcalX1=" << info_ptr->pcal_X1 << mout.endl;
260 image.setDefaultLimits();
263 image.setLimits(info_ptr->pcal_X0, info_ptr->pcal_X1);
264 mout.
note(
"setting physical scale: " , image );
277 const unsigned int targetBitDepth = 8*image.getConf().getElementSize();
279 const bool from8to8 = (inputBitDepth == 8) && (targetBitDepth == 8);
280 const bool from8to16 = (inputBitDepth == 8) && (targetBitDepth == 16);
283 mout.
debug(
"8-bit input, 8-bit target, easy..." );
285 else if (from8to16) {
286 mout.
note(
"-bit input, 16-bit target, rescaling..." );
289 if ((inputBitDepth == 16) && (targetBitDepth == 16)){
290 mout.
debug(
"16-bit input, 16-bit target, ok..." );
293 mout.
warn(inputBitDepth ,
"-bit input, ", targetBitDepth ,
"-bit target, problems ahead?" );
297 png_bytep *row_pointers = png_get_rows(png_ptr, info_ptr);
300 for (
unsigned int j = 0; j < height; ++j) {
302 for (
unsigned int i = 0; i < width; ++i) {
303 for (
unsigned int k = 0; k < channels; ++k) {
306 image.put(i,j,k, p[i0]);
308 else if (from8to16) {
309 image.put(i,j,k, p[i0]<<8);
312 image.put(i,j,k, (p[i0*2]<<8) + (p[i0*2+1]<<0));
319 png_destroy_read_struct(&png_ptr,&info_ptr, (png_infopp)NULL);
Definition: FileInfo.h:48
static void readValue(std::istream &istr, Castable &v, bool keepType=false)
Read a value (JSON syntax). Read stream until a value has been extracted, with type recognition.
Definition: JSON.cpp:52
LogSourc e is the means for a function or any program segment to "connect" to a Log.
Definition: Log.h:308
Logger & note(const TT &... args)
For top-level information.
Definition: Log.h:485
Logger & warn(const TT &... args)
Possible error, but execution can continue.
Definition: Log.h:426
Logger & debug(const TT &... args)
Public, yet typically used "internally", when TIMING=true.
Definition: Log.h:676
Utilities related to std::type_info.
Definition: Type.h:51
size_t getChannelCount() const
Return the number of channels (image and alpha)
Definition: Geometry.h:108
For reading and writing images in PNG format.
Definition: FilePng.h:63
static void write(const ImageFrame &image, const std::string &path)
Writes image to a png file.
Definition: FilePng.cpp:291
static FileInfo fileInfo
Syntax for recognising image files.
Definition: FilePng.h:101
static void read(ImageFrame &image, const std::string &path, int png_transforms=0)
Definition: FilePng.cpp:70
static short int compressionLevel
Default compression level for png_set_compression_level(png_ptr, ...);.
Definition: FilePng.h:105
static void readOld(T &image, const std::string &path, int png_transforms=0)
Syntax for recognising png files.
Definition: FilePng.h:114
Definition: Geometry.h:145
Image with static geometry.
Definition: ImageFrame.h:67
Definition: DataSelector.cpp:1277