| 5136 | #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ |
| 5137 | |
| 5138 | static void filterScanline(unsigned char* out, const unsigned char* scanline, const unsigned char* prevline, |
| 5139 | size_t length, size_t bytewidth, unsigned char filterType) |
| 5140 | { |
| 5141 | size_t i; |
| 5142 | switch(filterType) |
| 5143 | { |
| 5144 | case 0: /*None*/ |
| 5145 | for(i = 0; i != length; ++i) out[i] = scanline[i]; |
| 5146 | break; |
| 5147 | case 1: /*Sub*/ |
| 5148 | for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; |
| 5149 | for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - scanline[i - bytewidth]; |
| 5150 | break; |
| 5151 | case 2: /*Up*/ |
| 5152 | if(prevline) |
| 5153 | { |
| 5154 | for(i = 0; i != length; ++i) out[i] = scanline[i] - prevline[i]; |
| 5155 | } |
| 5156 | else |
| 5157 | { |
| 5158 | for(i = 0; i != length; ++i) out[i] = scanline[i]; |
| 5159 | } |
| 5160 | break; |
| 5161 | case 3: /*Average*/ |
| 5162 | if(prevline) |
| 5163 | { |
| 5164 | for(i = 0; i != bytewidth; ++i) out[i] = scanline[i] - (prevline[i] >> 1); |
| 5165 | for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) >> 1); |
| 5166 | } |
| 5167 | else |
| 5168 | { |
| 5169 | for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; |
| 5170 | for(i = bytewidth; i < length; ++i) out[i] = scanline[i] - (scanline[i - bytewidth] >> 1); |
| 5171 | } |
| 5172 | break; |
| 5173 | case 4: /*Paeth*/ |
| 5174 | if(prevline) |
| 5175 | { |
| 5176 | /*paethPredictor(0, prevline[i], 0) is always prevline[i]*/ |
| 5177 | for(i = 0; i != bytewidth; ++i) out[i] = (scanline[i] - prevline[i]); |
| 5178 | for(i = bytewidth; i < length; ++i) |
| 5179 | { |
| 5180 | out[i] = (scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth])); |
| 5181 | } |
| 5182 | } |
| 5183 | else |
| 5184 | { |
| 5185 | for(i = 0; i != bytewidth; ++i) out[i] = scanline[i]; |
| 5186 | /*paethPredictor(scanline[i - bytewidth], 0, 0) is always scanline[i - bytewidth]*/ |
| 5187 | for(i = bytewidth; i < length; ++i) out[i] = (scanline[i] - scanline[i - bytewidth]); |
| 5188 | } |
| 5189 | break; |
| 5190 | default: return; /*unexisting filter type given*/ |
| 5191 | } |
| 5192 | } |
| 5193 | |
| 5194 | /* log2 approximation. A slight bit faster than std::log. */ |
| 5195 | static float flog2(float f) |
no test coverage detected