| 3961 | } |
| 3962 | |
| 3963 | static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon, |
| 3964 | size_t bytewidth, unsigned char filterType, size_t length) |
| 3965 | { |
| 3966 | /* |
| 3967 | For PNG filter method 0 |
| 3968 | unfilter a PNG image scanline by scanline. when the pixels are smaller than 1 byte, |
| 3969 | the filter works byte per byte (bytewidth = 1) |
| 3970 | precon is the previous unfiltered scanline, recon the result, scanline the current one |
| 3971 | the incoming scanlines do NOT include the filtertype byte, that one is given in the parameter filterType instead |
| 3972 | recon and scanline MAY be the same memory address! precon must be disjoint. |
| 3973 | */ |
| 3974 | |
| 3975 | size_t i; |
| 3976 | switch(filterType) |
| 3977 | { |
| 3978 | case 0: |
| 3979 | for(i = 0; i != length; ++i) recon[i] = scanline[i]; |
| 3980 | break; |
| 3981 | case 1: |
| 3982 | for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; |
| 3983 | for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + recon[i - bytewidth]; |
| 3984 | break; |
| 3985 | case 2: |
| 3986 | if(precon) |
| 3987 | { |
| 3988 | for(i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i]; |
| 3989 | } |
| 3990 | else |
| 3991 | { |
| 3992 | for(i = 0; i != length; ++i) recon[i] = scanline[i]; |
| 3993 | } |
| 3994 | break; |
| 3995 | case 3: |
| 3996 | if(precon) |
| 3997 | { |
| 3998 | for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + (precon[i] >> 1); |
| 3999 | for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) >> 1); |
| 4000 | } |
| 4001 | else |
| 4002 | { |
| 4003 | for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i]; |
| 4004 | for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + (recon[i - bytewidth] >> 1); |
| 4005 | } |
| 4006 | break; |
| 4007 | case 4: |
| 4008 | if(precon) |
| 4009 | { |
| 4010 | for(i = 0; i != bytewidth; ++i) |
| 4011 | { |
| 4012 | recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/ |
| 4013 | } |
| 4014 | for(i = bytewidth; i < length; ++i) |
| 4015 | { |
| 4016 | recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth])); |
| 4017 | } |
| 4018 | } |
| 4019 | else |
| 4020 | { |
no test coverage detected