Exemple #1
0
        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);
            }
        }
Exemple #2
0
        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;
		}
Exemple #6
0
        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");
		}