| 3860 | } |
| 3861 | |
| 3862 | static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon, |
| 3863 | size_t bytewidth, unsigned char filterType, size_t length) |
| 3864 | { |
| 3865 | /* |
| 3866 | For PNG filter method 0 |
| 3867 | unfilter a PNG image scanline by scanline. when the pixels are smaller than 1 byte, |
| 3868 | the filter works byte per byte (bytewidth = 1) |
| 3869 | precon is the previous unfiltered scanline, recon the result, scanline the current one |
| 3870 | the incoming scanlines do NOT include the filtertype byte, that one is given in the parameter filterType instead |
| 3871 | recon and scanline MAY be the same memory address! precon must be disjoint. |
| 3872 | */ |
| 3873 | |
| 3874 | size_t i; |
| 3875 | switch(filterType) |
| 3876 | { |
| 3877 | case 0: |
| 3878 | for(i = 0; i < length; i++) recon[i] = scanline[i]; |
| 3879 | break; |
| 3880 | case 1: |
| 3881 | for(i = 0; i < bytewidth; i++) recon[i] = scanline[i]; |
| 3882 | for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + recon[i - bytewidth]; |
| 3883 | break; |
| 3884 | case 2: |
| 3885 | if(precon) |
| 3886 | { |
| 3887 | for(i = 0; i < length; i++) recon[i] = scanline[i] + precon[i]; |
| 3888 | } |
| 3889 | else |
| 3890 | { |
| 3891 | for(i = 0; i < length; i++) recon[i] = scanline[i]; |
| 3892 | } |
| 3893 | break; |
| 3894 | case 3: |
| 3895 | if(precon) |
| 3896 | { |
| 3897 | for(i = 0; i < bytewidth; i++) recon[i] = scanline[i] + precon[i] / 2; |
| 3898 | for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) / 2); |
| 3899 | } |
| 3900 | else |
| 3901 | { |
| 3902 | for(i = 0; i < bytewidth; i++) recon[i] = scanline[i]; |
| 3903 | for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + recon[i - bytewidth] / 2; |
| 3904 | } |
| 3905 | break; |
| 3906 | case 4: |
| 3907 | if(precon) |
| 3908 | { |
| 3909 | for(i = 0; i < bytewidth; i++) |
| 3910 | { |
| 3911 | recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/ |
| 3912 | } |
| 3913 | for(i = bytewidth; i < length; i++) |
| 3914 | { |
| 3915 | recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth])); |
| 3916 | } |
| 3917 | } |
| 3918 | else |
| 3919 | { |
no test coverage detected