public void png_set_IHDR(uint width, uint height, byte bit_depth, PNG_COLOR_TYPE color_type, PNG_INTERLACE interlace_type, PNG_COMPRESSION_TYPE compression_type, PNG_FILTER_TYPE filter_type) { info_ptr_width = width; info_ptr_height = height; info_ptr_bit_depth = bit_depth; info_ptr_color_type = color_type; info_ptr_compression_type = compression_type; info_ptr_filter_type = filter_type; info_ptr_interlace_type = interlace_type; png_check_IHDR(info_ptr_width, info_ptr_height, info_ptr_bit_depth, info_ptr_color_type, info_ptr_interlace_type, info_ptr_compression_type, info_ptr_filter_type); // find number of channels switch (info_ptr_color_type) { case PNG_COLOR_TYPE.GRAY: case PNG_COLOR_TYPE.PALETTE: info_ptr_channels = 1; break; case PNG_COLOR_TYPE.RGB: info_ptr_channels = 3; break; case PNG_COLOR_TYPE.GRAY_ALPHA: info_ptr_channels = 2; break; case PNG_COLOR_TYPE.RGB_ALPHA: info_ptr_channels = 4; break; } info_ptr_pixel_depth = (byte)(info_ptr_channels * info_ptr_bit_depth); // check for potential overflow if (width > (PNG.UINT_32_MAX >> 3) // 8-byte RGBA pixels - 64 // bigrowbuf hack - 1 // filter byte - 7 * 8 // rounding of width to multiple of 8 pixels - 8) // extra max_pixel_depth pad { info_ptr_rowbytes = 0; } else { info_ptr_rowbytes = PNG_ROWBYTES(info_ptr_pixel_depth, width); } }
public bool png_get_IHDR(ref uint width, ref uint height, ref byte bit_depth, ref PNG_COLOR_TYPE color_type, ref PNG_INTERLACE interlace_type, ref PNG_COMPRESSION_TYPE compression_type, ref PNG_FILTER_TYPE filter_type) { // This is redundant if we can be sure that the info_ptr values were all // assigned in png_set_IHDR(). We do the check anyhow in case an // application has ignored our advice not to mess with the members // of info_ptr directly. png_check_IHDR(info_ptr_width, info_ptr_height, info_ptr_bit_depth, info_ptr_color_type, info_ptr_interlace_type, info_ptr_compression_type, info_ptr_filter_type); width = info_ptr_width; height = info_ptr_height; bit_depth = info_ptr_bit_depth; color_type = info_ptr_color_type; compression_type = info_ptr_compression_type; filter_type = info_ptr_filter_type; interlace_type = info_ptr_interlace_type; return(true); }
public bool png_get_IHDR(ref uint width, ref uint height, ref byte bit_depth, ref PNG_COLOR_TYPE color_type, ref PNG_INTERLACE interlace_type, ref PNG_COMPRESSION_TYPE compression_type, ref PNG_FILTER_TYPE filter_type) { // This is redundant if we can be sure that the info_ptr values were all // assigned in png_set_IHDR(). We do the check anyhow in case an // application has ignored our advice not to mess with the members // of info_ptr directly. png_check_IHDR(info_ptr_width, info_ptr_height, info_ptr_bit_depth, info_ptr_color_type, info_ptr_interlace_type, info_ptr_compression_type, info_ptr_filter_type); width=info_ptr_width; height=info_ptr_height; bit_depth=info_ptr_bit_depth; color_type=info_ptr_color_type; compression_type=info_ptr_compression_type; filter_type=info_ptr_filter_type; interlace_type=info_ptr_interlace_type; return true; }
public void png_set_IHDR(uint width, uint height, byte bit_depth, PNG_COLOR_TYPE color_type, PNG_INTERLACE interlace_type, PNG_COMPRESSION_TYPE compression_type, PNG_FILTER_TYPE filter_type) { info_ptr_width=width; info_ptr_height=height; info_ptr_bit_depth=bit_depth; info_ptr_color_type=color_type; info_ptr_compression_type=compression_type; info_ptr_filter_type=filter_type; info_ptr_interlace_type=interlace_type; png_check_IHDR(info_ptr_width, info_ptr_height, info_ptr_bit_depth, info_ptr_color_type, info_ptr_interlace_type, info_ptr_compression_type, info_ptr_filter_type); // find number of channels switch(info_ptr_color_type) { case PNG_COLOR_TYPE.GRAY: case PNG_COLOR_TYPE.PALETTE: info_ptr_channels=1; break; case PNG_COLOR_TYPE.RGB: info_ptr_channels=3; break; case PNG_COLOR_TYPE.GRAY_ALPHA: info_ptr_channels=2; break; case PNG_COLOR_TYPE.RGB_ALPHA: info_ptr_channels=4; break; } info_ptr_pixel_depth=(byte)(info_ptr_channels*info_ptr_bit_depth); // check for potential overflow if(width>(PNG.UINT_32_MAX>>3) // 8-byte RGBA pixels -64 // bigrowbuf hack -1 // filter byte -7*8 // rounding of width to multiple of 8 pixels -8) // extra max_pixel_depth pad info_ptr_rowbytes=0; else info_ptr_rowbytes=PNG_ROWBYTES(info_ptr_pixel_depth, width); }
// Write the IHDR chunk, and update the png_struct with the necessary // information. Note that the rest of this code depends upon this // information being correct. void png_write_IHDR(uint width, uint height, byte bit_depth, PNG_COLOR_TYPE color_type, PNG_COMPRESSION_TYPE compression_type, PNG_FILTER_TYPE filter_type, PNG_INTERLACE interlace_type) { byte[] buf=new byte[13]; // buffer to store the IHDR info // Check that we have valid input data from the application info switch(color_type) { case PNG_COLOR_TYPE.GRAY: switch(bit_depth) { case 1: case 2: case 4: case 8: case 16: channels=1; break; default: throw new PNG_Exception("Invalid bit depth for grayscale image"); } break; case PNG_COLOR_TYPE.RGB: if(bit_depth!=8&&bit_depth!=16) throw new PNG_Exception("Invalid bit depth for RGB image"); channels=3; break; case PNG_COLOR_TYPE.PALETTE: switch(bit_depth) { case 1: case 2: case 4: case 8: channels=1; break; default: throw new PNG_Exception("Invalid bit depth for paletted image"); } break; case PNG_COLOR_TYPE.GRAY_ALPHA: if(bit_depth!=8&&bit_depth!=16) throw new PNG_Exception("Invalid bit depth for grayscale+alpha image"); channels=2; break; case PNG_COLOR_TYPE.RGB_ALPHA: if(bit_depth!=8&&bit_depth!=16) throw new PNG_Exception("Invalid bit depth for RGBA image"); channels=4; break; default: throw new PNG_Exception("Invalid image color type specified"); } if(compression_type!=PNG_COMPRESSION_TYPE.BASE) { Debug.WriteLine("Invalid compression type specified"); compression_type=PNG_COMPRESSION_TYPE.BASE; } // Write filter_method 64 (intrapixel differencing) only if // 1. Libpng did not write a PNG signature (this filter_method is only // used in PNG datastreams that are embedded in MNG datastreams) and // 2. The application called png_permit_mng_features with a mask that // included PNG_FLAG_MNG_FILTER_64 and // 3. The filter_method is 64 and // 4. The color_type is RGB or RGBA if(!((mng_features_permitted&PNG_FLAG_MNG.FILTER_64)==PNG_FLAG_MNG.FILTER_64&&((mode&PNG_MODE.HAVE_PNG_SIGNATURE)==PNG_MODE.None)&& (color_type==PNG_COLOR_TYPE.RGB||color_type==PNG_COLOR_TYPE.RGB_ALPHA)&&(filter_type==PNG_FILTER_TYPE.INTRAPIXEL_DIFFERENCING))&& filter_type!=PNG_FILTER_TYPE.BASE) { Debug.WriteLine("Invalid filter type specified"); filter_type=PNG_FILTER_TYPE.BASE; } interlace_type=PNG_INTERLACE.NONE; // Save the relevent information this.bit_depth=bit_depth; this.color_type=color_type; info_ptr_interlace_type=interlace_type; this.filter_type=filter_type; this.compression_type=compression_type; this.width=width; this.height=height; pixel_depth=(byte)(bit_depth*channels); rowbytes=PNG_ROWBYTES(pixel_depth, width); // set the usr info, so any transformations can modify it usr_width=width; usr_bit_depth=bit_depth; usr_channels=channels; // pack the header information into the buffer png_save_uint_32(buf, width); png_save_uint_32(buf, 4, height); buf[8]=bit_depth; buf[9]=(byte)color_type; buf[10]=(byte)compression_type; buf[11]=(byte)filter_type; buf[12]=(byte)interlace_type; // write the chunk png_write_chunk(PNG.IHDR, buf, 13); // initialize zlib with PNG info if(do_filter==PNG_FILTER.None) { if(color_type==PNG_COLOR_TYPE.PALETTE||bit_depth<8) do_filter=PNG_FILTER.NONE; else do_filter=PNG_FILTER.ALL; } if((flags&PNG_FLAG.ZLIB_CUSTOM_STRATEGY)!=PNG_FLAG.ZLIB_CUSTOM_STRATEGY) { if(do_filter!=PNG_FILTER.NONE) zlib_strategy=zlib.Z_FILTERED; else zlib_strategy=zlib.Z_DEFAULT_STRATEGY; } if((flags&PNG_FLAG.ZLIB_CUSTOM_LEVEL)!=PNG_FLAG.ZLIB_CUSTOM_LEVEL) zlib_level=zlib.Z_DEFAULT_COMPRESSION; if((flags&PNG_FLAG.ZLIB_CUSTOM_MEM_LEVEL)!=PNG_FLAG.ZLIB_CUSTOM_MEM_LEVEL) zlib_mem_level=8; if((flags&PNG_FLAG.ZLIB_CUSTOM_WINDOW_BITS)!=PNG_FLAG.ZLIB_CUSTOM_WINDOW_BITS) zlib_window_bits=15; if((flags&PNG_FLAG.ZLIB_CUSTOM_METHOD)!=PNG_FLAG.ZLIB_CUSTOM_METHOD) zlib_method=8; int ret=zlib.deflateInit2(zstream, zlib_level, zlib_method, zlib_window_bits, zlib_mem_level, zlib_strategy); if(ret!=zlib.Z_OK) { if(ret==zlib.Z_VERSION_ERROR) throw new PNG_Exception("zlib failed to initialize compressor -- version error"); if(ret==zlib.Z_STREAM_ERROR) throw new PNG_Exception("zlib failed to initialize compressor -- stream error"); if(ret==zlib.Z_MEM_ERROR) throw new PNG_Exception("zlib failed to initialize compressor -- mem error"); throw new PNG_Exception("zlib failed to initialize compressor"); } zstream.next_out=0; zstream.out_buf=zbuf; zstream.avail_out=zbuf_size; mode=PNG_MODE.HAVE_IHDR; }
void png_check_IHDR(uint width, uint height, int bit_depth, PNG_COLOR_TYPE color_type, PNG_INTERLACE interlace_type, PNG_COMPRESSION_TYPE compression_type, PNG_FILTER_TYPE filter_type) { bool error = false; // Check for width and height valid values if (width == 0) { Debug.WriteLine("Image width is zero in IHDR"); error = true; } if (height == 0) { Debug.WriteLine("Image height is zero in IHDR"); error = true; } if (width > PNG.USER_WIDTH_MAX) { Debug.WriteLine("Image width exceeds user limit in IHDR"); error = true; } if (height > PNG.USER_HEIGHT_MAX) { Debug.WriteLine("Image height exceeds user limit in IHDR"); error = true; } if (width > PNG.UINT_31_MAX) { Debug.WriteLine("Invalid image width in IHDR"); error = true; } if (height > PNG.UINT_31_MAX) { Debug.WriteLine("Invalid image height in IHDR"); error = true; } if (width > (PNG.UINT_32_MAX >> 3) // 8-byte RGBA pixels - 64 // bigrowbuf hack - 1 // filter byte - 7 * 8 // rounding of width to multiple of 8 pixels - 8) // extra max_pixel_depth pad { Debug.WriteLine("Width is too large for libpng to process pixels"); } // Check other values if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 && bit_depth != 8 && bit_depth != 16) { Debug.WriteLine("Invalid bit depth in IHDR"); error = true; } if (color_type != PNG_COLOR_TYPE.GRAY && color_type != PNG_COLOR_TYPE.PALETTE && color_type != PNG_COLOR_TYPE.RGB && color_type != PNG_COLOR_TYPE.RGB_ALPHA && color_type != PNG_COLOR_TYPE.GRAY_ALPHA) { Debug.WriteLine("Invalid color type in IHDR"); error = true; } if (((color_type == PNG_COLOR_TYPE.PALETTE) && bit_depth > 8) || ((color_type == PNG_COLOR_TYPE.RGB || color_type == PNG_COLOR_TYPE.GRAY_ALPHA || color_type == PNG_COLOR_TYPE.RGB_ALPHA) && bit_depth < 8)) { Debug.WriteLine("Invalid color type/bit depth combination in IHDR"); error = true; } if (interlace_type >= PNG_INTERLACE.LAST) { Debug.WriteLine("Unknown interlace method in IHDR"); error = true; } if (compression_type != PNG_COMPRESSION_TYPE.BASE) { Debug.WriteLine("Unknown compression method in IHDR"); error = true; } // Accept filter_method 64 (intrapixel differencing) only if // 1. Libpng did not read a PNG signature (this filter_method is only // used in PNG datastreams that are embedded in MNG datastreams) and // 2. The application called png_permit_mng_features with a mask that // included PNG_FLAG_MNG_FILTER_64 and // 3. The filter_method is 64 and // 4. The color_type is RGB or RGBA if ((mode & PNG_MODE.HAVE_PNG_SIGNATURE) == PNG_MODE.HAVE_PNG_SIGNATURE && mng_features_permitted != PNG_FLAG_MNG.None) { Debug.WriteLine("MNG features are not allowed in a PNG datastream"); } if (filter_type != PNG_FILTER_TYPE.BASE) { if (!((mng_features_permitted & PNG_FLAG_MNG.FILTER_64) == PNG_FLAG_MNG.FILTER_64 && (filter_type == PNG_FILTER_TYPE.INTRAPIXEL_DIFFERENCING) && ((mode & PNG_MODE.HAVE_PNG_SIGNATURE) != PNG_MODE.HAVE_PNG_SIGNATURE) && (color_type == PNG_COLOR_TYPE.RGB || color_type == PNG_COLOR_TYPE.RGB_ALPHA))) { Debug.WriteLine("Unknown filter method in IHDR"); error = true; } if ((mode & PNG_MODE.HAVE_PNG_SIGNATURE) == PNG_MODE.HAVE_PNG_SIGNATURE) { Debug.WriteLine("Invalid filter method in IHDR"); error = true; } } if (error) { throw new PNG_Exception("Invalid IHDR data"); } }
void png_check_IHDR(uint width, uint height, int bit_depth, PNG_COLOR_TYPE color_type, PNG_INTERLACE interlace_type, PNG_COMPRESSION_TYPE compression_type, PNG_FILTER_TYPE filter_type) { bool error=false; // Check for width and height valid values if(width==0) { Debug.WriteLine("Image width is zero in IHDR"); error=true; } if(height==0) { Debug.WriteLine("Image height is zero in IHDR"); error=true; } if(width>PNG.USER_WIDTH_MAX) { Debug.WriteLine("Image width exceeds user limit in IHDR"); error=true; } if(height>PNG.USER_HEIGHT_MAX) { Debug.WriteLine("Image height exceeds user limit in IHDR"); error=true; } if(width>PNG.UINT_31_MAX) { Debug.WriteLine("Invalid image width in IHDR"); error=true; } if(height>PNG.UINT_31_MAX) { Debug.WriteLine("Invalid image height in IHDR"); error=true; } if(width>(PNG.UINT_32_MAX>>3) // 8-byte RGBA pixels -64 // bigrowbuf hack -1 // filter byte -7*8 // rounding of width to multiple of 8 pixels -8) // extra max_pixel_depth pad Debug.WriteLine("Width is too large for libpng to process pixels"); // Check other values if(bit_depth!=1&&bit_depth!=2&&bit_depth!=4&&bit_depth!=8&&bit_depth!=16) { Debug.WriteLine("Invalid bit depth in IHDR"); error=true; } if(color_type!=PNG_COLOR_TYPE.GRAY&&color_type!=PNG_COLOR_TYPE.PALETTE&&color_type!=PNG_COLOR_TYPE.RGB&& color_type!=PNG_COLOR_TYPE.RGB_ALPHA&&color_type!=PNG_COLOR_TYPE.GRAY_ALPHA) { Debug.WriteLine("Invalid color type in IHDR"); error=true; } if(((color_type==PNG_COLOR_TYPE.PALETTE)&&bit_depth>8)|| ((color_type==PNG_COLOR_TYPE.RGB||color_type==PNG_COLOR_TYPE.GRAY_ALPHA||color_type==PNG_COLOR_TYPE.RGB_ALPHA)&&bit_depth<8)) { Debug.WriteLine("Invalid color type/bit depth combination in IHDR"); error=true; } if(interlace_type>=PNG_INTERLACE.LAST) { Debug.WriteLine("Unknown interlace method in IHDR"); error=true; } if(compression_type!=PNG_COMPRESSION_TYPE.BASE) { Debug.WriteLine("Unknown compression method in IHDR"); error=true; } // Accept filter_method 64 (intrapixel differencing) only if // 1. Libpng did not read a PNG signature (this filter_method is only // used in PNG datastreams that are embedded in MNG datastreams) and // 2. The application called png_permit_mng_features with a mask that // included PNG_FLAG_MNG_FILTER_64 and // 3. The filter_method is 64 and // 4. The color_type is RGB or RGBA if((mode&PNG_MODE.HAVE_PNG_SIGNATURE)==PNG_MODE.HAVE_PNG_SIGNATURE&&mng_features_permitted!=PNG_FLAG_MNG.None) Debug.WriteLine("MNG features are not allowed in a PNG datastream"); if(filter_type!=PNG_FILTER_TYPE.BASE) { if(!((mng_features_permitted&PNG_FLAG_MNG.FILTER_64)==PNG_FLAG_MNG.FILTER_64&& (filter_type==PNG_FILTER_TYPE.INTRAPIXEL_DIFFERENCING)&& ((mode&PNG_MODE.HAVE_PNG_SIGNATURE)!=PNG_MODE.HAVE_PNG_SIGNATURE)&& (color_type==PNG_COLOR_TYPE.RGB||color_type==PNG_COLOR_TYPE.RGB_ALPHA))) { Debug.WriteLine("Unknown filter method in IHDR"); error=true; } if((mode&PNG_MODE.HAVE_PNG_SIGNATURE)==PNG_MODE.HAVE_PNG_SIGNATURE) { Debug.WriteLine("Invalid filter method in IHDR"); error=true; } } if(error) throw new PNG_Exception("Invalid IHDR data"); }