コード例 #1
0
 public PNG_INFO png_get_sBIT(ref png_color_8 sig_bit)
 {
     if ((info_ptr_valid & PNG_INFO.sBIT) != PNG_INFO.sBIT)
     {
         return(PNG_INFO.None);
     }
     sig_bit = info_ptr_sig_bit;
     return(PNG_INFO.sBIT);
 }
コード例 #2
0
		public PNG_INFO png_get_sBIT(ref png_color_8 sig_bit)
		{
			if((info_ptr_valid&PNG_INFO.sBIT)!=PNG_INFO.sBIT) return PNG_INFO.None;
			sig_bit=info_ptr_sig_bit;
			return PNG_INFO.sBIT;
		}
コード例 #3
0
 public void png_set_sBIT(png_color_8 sig_bit)
 {
     info_ptr_sig_bit = sig_bit;
     info_ptr_valid  |= PNG_INFO.sBIT;
 }
コード例 #4
0
		public void png_set_sBIT(png_color_8 sig_bit)
		{
			info_ptr_sig_bit=sig_bit;
			info_ptr_valid|=PNG_INFO.sBIT;
		}
コード例 #5
0
		// Shift pixel values to take advantage of whole range. Pass the
		// true number of bits in bit_depth. The row should be packed
		// according to row_info->bit_depth. Thus, if you had a row of
		// bit depth 4, but the pixels only had values from 0 to 7, you
		// would pass 3 as bit_depth, and this routine would translate the
		// data to 0 to 15.
		unsafe void png_do_shift(png_row_info row_info, byte[] row, png_color_8 bit_depth)
		{
			if(row_info.color_type==PNG_COLOR_TYPE.PALETTE) return;

			int[] shift_start=new int[4], shift_dec=new int[4];
			uint channels=0;

			if((row_info.color_type&PNG_COLOR_TYPE.COLOR_MASK)==PNG_COLOR_TYPE.COLOR_MASK)
			{
				shift_start[channels]=row_info.bit_depth-bit_depth.red;
				shift_dec[channels]=bit_depth.red; channels++;
				shift_start[channels]=row_info.bit_depth-bit_depth.green;
				shift_dec[channels]=bit_depth.green; channels++;
				shift_start[channels]=row_info.bit_depth-bit_depth.blue;
				shift_dec[channels]=bit_depth.blue; channels++;
			}
			else
			{
				shift_start[channels]=row_info.bit_depth-bit_depth.gray;
				shift_dec[channels]=bit_depth.gray; channels++;
			}
			if((row_info.color_type&PNG_COLOR_TYPE.ALPHA_MASK)==PNG_COLOR_TYPE.ALPHA_MASK)
			{
				shift_start[channels]=row_info.bit_depth-bit_depth.alpha;
				shift_dec[channels]=bit_depth.alpha; channels++;
			}

			fixed(byte* row_=row)
			{
				// with low row depths, could only be grayscale, so one channel
				byte* bp=row_+1; // skip filter value
				if(row_info.bit_depth<8)
				{
					byte mask;
					uint row_bytes=row_info.rowbytes;

					if(bit_depth.gray==1&&row_info.bit_depth==2) mask=0x55;
					else if(row_info.bit_depth==4&&bit_depth.gray==3) mask=0x11;
					else mask=0xff;

					for(uint i=0; i<row_bytes; i++, bp++)
					{
						ushort v=*bp;
						*bp=0;
						for(int j=shift_start[0]; j>-shift_dec[0]; j-=shift_dec[0])
						{
							if(j>0) *bp|=(byte)((v<<j)&0xff);
							else *bp|=(byte)((v>>(-j))&mask);
						}
					}
				}
				else if(row_info.bit_depth==8)
				{
					uint istop=channels*row_info.width;

					for(uint i=0; i<istop; i++, bp++)
					{
						int c=(int)(i%channels);

						ushort v=*bp;
						*bp=0;
						for(int j=shift_start[c]; j>-shift_dec[c]; j-=shift_dec[c])
						{
							if(j>0) *bp|=(byte)((v<<j)&0xff);
							else *bp|=(byte)((v>>(-j))&0xff);
						}
					}
				}
				else
				{
					uint istop=channels*row_info.width;

					for(uint i=0; i<istop; i++)
					{
						int c=(int)(i%channels);

						ushort v=(ushort)(((ushort)(*bp)<<8)+*(bp+1));
						ushort value=0;
						for(int j=shift_start[c]; j>-shift_dec[c]; j-=shift_dec[c])
						{
							if(j>0) value|=(ushort)((v<<j)&(ushort)0xffff);
							else value|=(ushort)((v>>(-j))&(ushort)0xffff);
						}
						*bp++=(byte)(value>>8);
						*bp++=(byte)(value&0xff);
					}
				}
			}
		}
コード例 #6
0
		// write the sBIT chunk
		void png_write_sBIT(png_color_8 sbit, PNG_COLOR_TYPE color_type)
		{
			uint size;

			// make sure we don't depend upon the order of PNG_COLOR_8
			if((color_type&PNG_COLOR_TYPE.COLOR_MASK)==PNG_COLOR_TYPE.COLOR_MASK)
			{
				byte maxbits=color_type==PNG_COLOR_TYPE.PALETTE?(byte)8:usr_bit_depth;
				if(sbit.red==0||sbit.red>maxbits||sbit.green==0||sbit.green>maxbits||sbit.blue==0||sbit.blue>maxbits)
				{
					Debug.WriteLine("Invalid sBIT depth specified");
					return;
				}
				buf4[0]=sbit.red;
				buf4[1]=sbit.green;
				buf4[2]=sbit.blue;
				size=3;
			}
			else
			{
				if(sbit.gray==0||sbit.gray>usr_bit_depth)
				{
					Debug.WriteLine("Invalid sBIT depth specified");
					return;
				}
				buf4[0]=sbit.gray;
				size=1;
			}

			if((color_type&PNG_COLOR_TYPE.ALPHA_MASK)==PNG_COLOR_TYPE.ALPHA_MASK)
			{
				if(sbit.alpha==0||sbit.alpha>usr_bit_depth)
				{
					Debug.WriteLine("Invalid sBIT depth specified");
					return;
				}
				buf4[size++]=sbit.alpha;
			}

			png_write_chunk(PNG.sBIT, buf4, size);
		}
コード例 #7
0
 public void png_set_shift(png_color_8 true_bits)
 {
     transformations |= PNG_TRANSFORMATION.SHIFT;
     shift            = true_bits;
 }
コード例 #8
0
		// Reverse the effects of png_do_shift. This routine merely shifts the
		// pixels back to their significant bits values. Thus, if you have
		// a row of bit depth 8, but only 5 are significant, this will shift
		// the values back to 0 through 31.
		static unsafe void png_do_unshift(ref png_row_info row_info, byte[] row, ref png_color_8 sig_bits)
		{
			if(row_info.color_type==PNG_COLOR_TYPE.PALETTE) return;

			int[] shift=new int[4];
			uint channels=0;
			ushort value=0;
			uint row_width=row_info.width;

			if((row_info.color_type&PNG_COLOR_TYPE.COLOR_MASK)==PNG_COLOR_TYPE.COLOR_MASK)
			{
				shift[channels++]=row_info.bit_depth-sig_bits.red;
				shift[channels++]=row_info.bit_depth-sig_bits.green;
				shift[channels++]=row_info.bit_depth-sig_bits.blue;
			}
			else shift[channels++]=row_info.bit_depth-sig_bits.gray;

			if((row_info.color_type&PNG_COLOR_TYPE.ALPHA_MASK)==PNG_COLOR_TYPE.ALPHA_MASK)
				shift[channels++]=row_info.bit_depth-sig_bits.alpha;

			for(uint c=0; c<channels; c++)
			{
				if(shift[c]<=0) shift[c]=0;
				else value=1;
			}

			if(value==0) return;

			fixed(byte* row_=row)
			{
				byte* bp=row_+1; // skip filter value

				switch(row_info.bit_depth)
				{
					case 2:
						{
							uint istop=row_info.rowbytes;
							for(uint i=0; i<istop; i++)
							{
								*bp>>=1;
								*bp++&=0x55;
							}
						}
						break;
					case 4:
						{
							uint istop=row_info.rowbytes;
							byte mask=(byte)((((int)0xf0>>shift[0])&(int)0xf0)|(byte)((int)0xf>>shift[0]));
							for(uint i=0; i<istop; i++)
							{
								*bp>>=shift[0];
								*bp++&=mask;
							}
						}
						break;
					case 8:
						{
							uint istop=row_width*channels;
							for(uint i=0; i<istop; i++) *bp++>>=shift[i%channels];
						}
						break;
					case 16:
						{
							uint istop=row_width*channels;
							for(uint i=0; i<istop; i++)
							{
								value=(ushort)((*bp<<8)+*(bp+1));
								value>>=shift[i%channels];
								*bp++=(byte)(value>>8);
								*bp++=(byte)(value&0xff);
							}
						}
						break;
				}
			}
		}
コード例 #9
0
		public void png_set_shift(png_color_8 true_bits)
		{
			transformations|=PNG_TRANSFORMATION.SHIFT;
			shift=true_bits;
		}