Question

I want to read a PNG file with libpng and I want to use the filter png_set_rgb_to_gray_fixed to convert RGB values into grayscale. The original image has 8 bits per channel, hence 3 bytes per pixel. I expect the output to be 8 bit per pixel. However png_get_rowbytes tells me that row size is 3*width. What I'm doing wrong?

Here is my code (I removed the error checking code for brevity):

FILE *fp = fopen(filename,"rb");
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
png_infop info_ptr = png_create_info_struct(png_ptr);    
png_infop end_info = png_create_info_struct(png_ptr);
png_init_io(png_ptr, fp);
png_uint_32 width,height;
int color_depth,color_type, interlace_type, compression_type, filter_method;    
png_read_info(png_ptr, info_ptr);    
png_get_IHDR(png_ptr, info_ptr, &width, &height,
             &color_depth, &color_type, &interlace_type,
             &compression_type, &filter_method);
assert(color_type == PNG_COLOR_TYPE_RGB); 
png_set_rgb_to_gray_fixed(png_ptr, 3,-1,-1);

int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
assert(rowbytes == width ); // FAILS: rowbytes == 3*width
Was it helpful?

Solution

You need to call png_read_update_info:

png_read_update_info() updates the structure pointed to by info_ptr to reflect any transformations that have been requested. For example, rowbytes will be updated to handle expansion of an interlaced image with png_read_update_info().

So:

png_set_rgb_to_gray_fixed(png_ptr, 3,-1,-1);
png_read_update_info(png_ptr, info_ptr);
int rowbytes = png_get_rowbytes(png_ptr, info_ptr);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top