MCPcopy Create free account
hub / github.com/DFHack/dfhack / unfilterScanline

Function unfilterScanline

depends/lodepng/lodepng.cpp:4101–4196  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

4099}
4100
4101static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon,
4102 size_t bytewidth, unsigned char filterType, size_t length) {
4103 /*
4104 For PNG filter method 0
4105 unfilter a PNG image scanline by scanline. when the pixels are smaller than 1 byte,
4106 the filter works byte per byte (bytewidth = 1)
4107 precon is the previous unfiltered scanline, recon the result, scanline the current one
4108 the incoming scanlines do NOT include the filtertype byte, that one is given in the parameter filterType instead
4109 recon and scanline MAY be the same memory address! precon must be disjoint.
4110 */
4111
4112 size_t i;
4113 switch(filterType) {
4114 case 0:
4115 for(i = 0; i != length; ++i) recon[i] = scanline[i];
4116 break;
4117 case 1:
4118 for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
4119 for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + recon[i - bytewidth];
4120 break;
4121 case 2:
4122 if(precon) {
4123 for(i = 0; i != length; ++i) recon[i] = scanline[i] + precon[i];
4124 } else {
4125 for(i = 0; i != length; ++i) recon[i] = scanline[i];
4126 }
4127 break;
4128 case 3:
4129 if(precon) {
4130 for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i] + (precon[i] >> 1u);
4131 for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) >> 1u);
4132 } else {
4133 for(i = 0; i != bytewidth; ++i) recon[i] = scanline[i];
4134 for(i = bytewidth; i < length; ++i) recon[i] = scanline[i] + (recon[i - bytewidth] >> 1u);
4135 }
4136 break;
4137 case 4:
4138 if(precon) {
4139 for(i = 0; i != bytewidth; ++i) {
4140 recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/
4141 }
4142
4143 /* Unroll independent paths of the paeth predictor. A 6x and 8x version would also be possible but that
4144 adds too much code. Whether this actually speeds anything up at all depends on compiler and settings. */
4145 if(bytewidth >= 4) {
4146 for(; i + 3 < length; i += 4) {
4147 size_t j = i - bytewidth;
4148 unsigned char s0 = scanline[i + 0], s1 = scanline[i + 1], s2 = scanline[i + 2], s3 = scanline[i + 3];
4149 unsigned char r0 = recon[j + 0], r1 = recon[j + 1], r2 = recon[j + 2], r3 = recon[j + 3];
4150 unsigned char p0 = precon[i + 0], p1 = precon[i + 1], p2 = precon[i + 2], p3 = precon[i + 3];
4151 unsigned char q0 = precon[j + 0], q1 = precon[j + 1], q2 = precon[j + 2], q3 = precon[j + 3];
4152 recon[i + 0] = s0 + paethPredictor(r0, p0, q0);
4153 recon[i + 1] = s1 + paethPredictor(r1, p1, q1);
4154 recon[i + 2] = s2 + paethPredictor(r2, p2, q2);
4155 recon[i + 3] = s3 + paethPredictor(r3, p3, q3);
4156 }
4157 } else if(bytewidth >= 3) {
4158 for(; i + 2 < length; i += 3) {

Callers 1

unfilterFunction · 0.85

Calls 1

paethPredictorFunction · 0.85

Tested by

no test coverage detected