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(); }