| 4080 | } |
| 4081 | |
| 4082 | static unsigned unfilter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) |
| 4083 | { |
| 4084 | /* |
| 4085 | For PNG filter method 0 |
| 4086 | this function unfilters a single image (e.g. without interlacing this is called once, with Adam7 seven times) |
| 4087 | out must have enough bytes allocated already, in must have the scanlines + 1 filtertype byte per scanline |
| 4088 | w and h are image dimensions or dimensions of reduced image, bpp is bits per pixel |
| 4089 | in and out are allowed to be the same memory address (but aren't the same size since in has the extra filter bytes) |
| 4090 | */ |
| 4091 | |
| 4092 | unsigned y; |
| 4093 | unsigned char* prevline = 0; |
| 4094 | |
| 4095 | /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/ |
| 4096 | size_t bytewidth = (bpp + 7) / 8; |
| 4097 | size_t linebytes = (w * bpp + 7) / 8; |
| 4098 | |
| 4099 | for(y = 0; y < h; y++) |
| 4100 | { |
| 4101 | size_t outindex = linebytes * y; |
| 4102 | size_t inindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ |
| 4103 | unsigned char filterType = in[inindex]; |
| 4104 | |
| 4105 | CERROR_TRY_RETURN(unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes)); |
| 4106 | |
| 4107 | prevline = &out[outindex]; |
| 4108 | } |
| 4109 | |
| 4110 | return 0; |
| 4111 | } |
| 4112 | |
| 4113 | /* |
| 4114 | in: Adam7 interlaced image, with no padding bits between scanlines, but between |
no test coverage detected