Beispiel #1
0
        public void png_set_filter(PNG_FILTER_TYPE method, PNG_FILTER_VALUE filters)
        {
            if ((mng_features_permitted & PNG_FLAG_MNG.FILTER_64) == PNG_FLAG_MNG.FILTER_64 &&
                method == PNG_FILTER_TYPE.INTRAPIXEL_DIFFERENCING)
            {
                method = PNG_FILTER_TYPE.BASE;
            }

            if (method != PNG_FILTER_TYPE.BASE)
            {
                throw new PNG_Exception("Unknown custom filter method");
            }
            switch (filters)
            {
            case PNG_FILTER_VALUE.NONE: do_filter = PNG_FILTER.NONE; break;

            case PNG_FILTER_VALUE.SUB: do_filter = PNG_FILTER.SUB; break;

            case PNG_FILTER_VALUE.UP: do_filter = PNG_FILTER.UP; break;

            case PNG_FILTER_VALUE.AVG: do_filter = PNG_FILTER.AVG; break;

            case PNG_FILTER_VALUE.PAETH: do_filter = PNG_FILTER.PAETH; break;

            default: Debug.WriteLine("Unknown row filter for method 0"); do_filter = PNG_FILTER.NONE; break;
            }

            png_set_filter2();
        }
		unsafe void png_read_filter_row(png_row_info row_info, byte[] row, byte[] prev_row, PNG_FILTER_VALUE filter)
		{
			fixed(byte* row__=row, prev_row__=prev_row)
			{
				byte* row_=row__+1, prev_row_=prev_row__+1;

				switch(filter)
				{
					case PNG_FILTER_VALUE.NONE: break;
					case PNG_FILTER_VALUE.SUB:
						{
							uint istop=row_info.rowbytes;
							uint bpp=(uint)(row_info.pixel_depth+7)>>3;
							byte* rp=row_+bpp, lp=row_;

							for(uint i=bpp; i<istop; i++)
							{
								*rp=(byte)(((int)(*rp)+(int)(*lp++))&0xff);
								rp++;
							}
						}
						break;
					case PNG_FILTER_VALUE.UP:
						{
							uint istop=row_info.rowbytes;
							byte* rp=row_, pp=prev_row_;

							for(uint i=0; i<istop; i++)
							{
								*rp=(byte)(((int)(*rp)+(int)(*pp++))&0xff);
								rp++;
							}
						}
						break;
					case PNG_FILTER_VALUE.AVG:
						{
							byte* rp=row_, pp=prev_row_, lp=row_;
							uint bpp=(uint)(row_info.pixel_depth+7)>>3;
							uint istop=row_info.rowbytes-bpp;

							for(uint i=0; i<bpp; i++)
							{
								*rp=(byte)(((int)(*rp)+((int)(*pp++)/2))&0xff);
								rp++;
							}

							for(uint i=0; i<istop; i++)
							{
								*rp=(byte)(((int)(*rp)+(int)(*pp+++*lp++)/2)&0xff);
								rp++;
							}
						}
						break;
					case PNG_FILTER_VALUE.PAETH:
						{
							byte* rp=row_, pp=prev_row_, lp=row_, cp=prev_row_;
							uint bpp=(uint)(row_info.pixel_depth+7)>>3;
							uint istop=row_info.rowbytes-bpp;

							for(uint i=0; i<bpp; i++)
							{
								*rp=(byte)(((int)(*rp)+(int)(*pp++))&0xff);
								rp++;
							}

							for(uint i=0; i<istop; i++) // use leftover rp, pp
							{
								int a=*lp++;
								int b=*pp++;
								int c=*cp++;

								int p=b-c;
								int pc=a-c;

								//int pa=abs(p);
								//int pb=abs(pc);
								//pc=abs(p+pc);
								int pa=p<0?-p:p;
								int pb=pc<0?-pc:pc;
								pc=(p+pc)<0?-(p+pc):p+pc;

								p=(pa<=pb&&pa<=pc)?a:(pb<=pc)?b:c;

								*rp=(byte)(((int)(*rp)+p)&0xff);
								rp++;
							}
						}
						break;
					default:
						Debug.WriteLine("Ignoring bad adaptive filter type");
						*row_=0;
						break;
				}

			}
		}
		public void png_set_filter(PNG_FILTER_TYPE method, PNG_FILTER_VALUE filters)
		{
			if((mng_features_permitted&PNG_FLAG_MNG.FILTER_64)==PNG_FLAG_MNG.FILTER_64&&
				method==PNG_FILTER_TYPE.INTRAPIXEL_DIFFERENCING) method=PNG_FILTER_TYPE.BASE;

			if(method!=PNG_FILTER_TYPE.BASE) throw new PNG_Exception("Unknown custom filter method");
			switch(filters)
			{
				case PNG_FILTER_VALUE.NONE: do_filter=PNG_FILTER.NONE; break;
				case PNG_FILTER_VALUE.SUB: do_filter=PNG_FILTER.SUB; break;
				case PNG_FILTER_VALUE.UP: do_filter=PNG_FILTER.UP; break;
				case PNG_FILTER_VALUE.AVG: do_filter=PNG_FILTER.AVG; break;
				case PNG_FILTER_VALUE.PAETH: do_filter=PNG_FILTER.PAETH; break;
				default: Debug.WriteLine("Unknown row filter for method 0"); do_filter=PNG_FILTER.NONE; break;
			}

			png_set_filter2();
		}