| 4006 | } |
| 4007 | |
| 4008 | static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon, |
| 4009 | size_t bytewidth, unsigned char filterType, size_t length) |
| 4010 | { |
| 4011 | /* |
| 4012 | For PNG filter method 0 |
| 4013 | unfilter a PNG image scanline by scanline. when the pixels are smaller than 1 byte, |
| 4014 | the filter works byte per byte (bytewidth = 1) |
| 4015 | precon is the previous unfiltered scanline, recon the result, scanline the current one |
| 4016 | the incoming scanlines do NOT include the filtertype byte, that one is given in the parameter filterType instead |
| 4017 | recon and scanline MAY be the same memory address! precon must be disjoint. |
| 4018 | */ |
| 4019 | |
| 4020 | size_t i; |
| 4021 | switch(filterType) |
| 4022 | { |
| 4023 | case 0: |
| 4024 | for(i = 0; i < length; i++) recon[i] = scanline[i]; |
| 4025 | break; |
| 4026 | case 1: |
| 4027 | for(i = 0; i < bytewidth; i++) recon[i] = scanline[i]; |
| 4028 | for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + recon[i - bytewidth]; |
| 4029 | break; |
| 4030 | case 2: |
| 4031 | if(precon) |
| 4032 | { |
| 4033 | for(i = 0; i < length; i++) recon[i] = scanline[i] + precon[i]; |
| 4034 | } |
| 4035 | else |
| 4036 | { |
| 4037 | for(i = 0; i < length; i++) recon[i] = scanline[i]; |
| 4038 | } |
| 4039 | break; |
| 4040 | case 3: |
| 4041 | if(precon) |
| 4042 | { |
| 4043 | for(i = 0; i < bytewidth; i++) recon[i] = scanline[i] + precon[i] / 2; |
| 4044 | for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) / 2); |
| 4045 | } |
| 4046 | else |
| 4047 | { |
| 4048 | for(i = 0; i < bytewidth; i++) recon[i] = scanline[i]; |
| 4049 | for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + recon[i - bytewidth] / 2; |
| 4050 | } |
| 4051 | break; |
| 4052 | case 4: |
| 4053 | if(precon) |
| 4054 | { |
| 4055 | for(i = 0; i < bytewidth; i++) |
| 4056 | { |
| 4057 | recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/ |
| 4058 | } |
| 4059 | for(i = bytewidth; i < length; i++) |
| 4060 | { |
| 4061 | recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth])); |
| 4062 | } |
| 4063 | } |
| 4064 | else |
| 4065 | { |
no test coverage detected