24#include <core/exception.h>
25#include <fvutils/color/rgbyuv.h>
26#include <fvutils/readers/png.h>
64 d_ = setup_read(filename);
70PNGReader::setup_read(
const char *filename)
72 PNGReaderData *d =
new PNGReaderData();
75 if ((d->infile = fopen(filename,
"rb")) == NULL) {
76 throw Exception(
"Cannot open PNG file %s: %s", filename, ::strerror(errno));
79 d->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
81 if (d->png_ptr == NULL) {
83 throw Exception(
"Could not create PNG read struct");
87 d->info_ptr = png_create_info_struct(d->png_ptr);
88 if (d->info_ptr == NULL) {
90 png_destroy_read_struct(&d->png_ptr, (png_infopp)NULL, (png_infopp)NULL);
91 throw Exception(
"Could not create PNG info struct");
98 if (setjmp(png_jmpbuf(d->png_ptr))) {
99 std::string err(::strerror(errno));
101 png_destroy_read_struct(&d->png_ptr, &d->info_ptr, (png_infopp)NULL);
104 throw Exception(
"Could not read PNG file %s: %s", filename, err.c_str());
108 png_init_io(d->png_ptr, d->infile);
112 png_read_info(d->png_ptr, d->info_ptr);
115 png_set_strip_16(d->png_ptr);
119 png_set_strip_alpha(d->png_ptr);
123 png_set_packing(d->png_ptr);
125 png_byte color_type = png_get_color_type(d->png_ptr, d->info_ptr);
128 if (color_type == PNG_COLOR_TYPE_PALETTE)
129 png_set_palette_to_rgb(d->png_ptr);
132 if (color_type == PNG_COLOR_TYPE_GRAY)
133 png_set_gray_to_rgb(d->png_ptr);
140 double screen_gamma = 2.2;
141 if (png_get_sRGB(d->png_ptr, d->info_ptr, &intent)) {
142 png_set_gamma(d->png_ptr, screen_gamma, 0.45455);
145 if (png_get_gAMA(d->png_ptr, d->info_ptr, &image_gamma)) {
146 png_set_gamma(d->png_ptr, screen_gamma, image_gamma);
148 png_set_gamma(d->png_ptr, screen_gamma, 0.45455);
155 d->number_passes = png_set_interlace_handling(d->png_ptr);
160 png_read_update_info(d->png_ptr, d->info_ptr);
170 png_destroy_read_struct(&d_->png_ptr, &d_->info_ptr, (png_infopp)NULL);
180 buffer = yuv422planar_buffer;
186 return YUV422_PLANAR;
193 return png_get_image_width(d_->png_ptr, d_->info_ptr);
203 return png_get_image_height(d_->png_ptr, d_->info_ptr);
212 if (buffer == NULL) {
213 throw Exception(
"PNGReader::read: buffer == NULL");
216 throw Exception(
"Can read PNG file only once.");
220 png_bytep row_pointer;
221 row_pointer = (png_bytep)png_malloc(d_->png_ptr, png_get_rowbytes(d_->png_ptr, d_->info_ptr));
226 for (
int pass = 0; pass < d_->number_passes; ++pass) {
227 for (
unsigned y = 0; y < lheight; ++y) {
228 png_read_rows(d_->png_ptr, &row_pointer, (png_bytepp)NULL, 1);
229 convert_line_rgb_to_yuv422planar(row_pointer, buffer, lwidth, lheight, 0, y);
234 png_read_end(d_->png_ptr, d_->info_ptr);
235 png_free(d_->png_ptr, row_pointer);
Base class for exceptions in Fawkes.
virtual void set_buffer(unsigned char *yuv422planar_buffer)
Set buffer that the read image should be written to.
virtual unsigned int pixel_height()
Get height of read image in pixels.
virtual ~PNGReader()
Destructor.
PNGReader(const char *filename)
Constructor.
virtual colorspace_t colorspace()
Get colorspace from the just read image.
virtual void read()
Read data from file.
virtual unsigned int pixel_width()
Get width of read image in pixels.
Fawkes library namespace.