in: non-interlaced image with size w*h out: the same pixels, but re-ordered according to PNG's Adam7 interlacing, with no padding bits between scanlines, but between reduced images so that each reduced image starts at a byte. bpp: bits per pixel there are no padding bits, not between scanlines, not between reduced images in has the following size in bits: w * h * bpp. out is possibly bigger due
| 5331 | NOTE: comments about padding bits are only relevant if bpp < 8 |
| 5332 | */ |
| 5333 | static void Adam7_interlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) |
| 5334 | { |
| 5335 | unsigned passw[7], passh[7]; |
| 5336 | size_t filter_passstart[8], padded_passstart[8], passstart[8]; |
| 5337 | unsigned i; |
| 5338 | |
| 5339 | Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); |
| 5340 | |
| 5341 | if(bpp >= 8) |
| 5342 | { |
| 5343 | for(i = 0; i < 7; i++) |
| 5344 | { |
| 5345 | unsigned x, y, b; |
| 5346 | size_t bytewidth = bpp / 8; |
| 5347 | for(y = 0; y < passh[i]; y++) |
| 5348 | for(x = 0; x < passw[i]; x++) |
| 5349 | { |
| 5350 | size_t pixelinstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth; |
| 5351 | size_t pixeloutstart = passstart[i] + (y * passw[i] + x) * bytewidth; |
| 5352 | for(b = 0; b < bytewidth; b++) |
| 5353 | { |
| 5354 | out[pixeloutstart + b] = in[pixelinstart + b]; |
| 5355 | } |
| 5356 | } |
| 5357 | } |
| 5358 | } |
| 5359 | else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ |
| 5360 | { |
| 5361 | for(i = 0; i < 7; i++) |
| 5362 | { |
| 5363 | unsigned x, y, b; |
| 5364 | unsigned ilinebits = bpp * passw[i]; |
| 5365 | unsigned olinebits = bpp * w; |
| 5366 | size_t obp, ibp; /*bit pointers (for out and in buffer)*/ |
| 5367 | for(y = 0; y < passh[i]; y++) |
| 5368 | for(x = 0; x < passw[i]; x++) |
| 5369 | { |
| 5370 | ibp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp; |
| 5371 | obp = (8 * passstart[i]) + (y * ilinebits + x * bpp); |
| 5372 | for(b = 0; b < bpp; b++) |
| 5373 | { |
| 5374 | unsigned char bit = readBitFromReversedStream(&ibp, in); |
| 5375 | setBitOfReversedStream(&obp, out, bit); |
| 5376 | } |
| 5377 | } |
| 5378 | } |
| 5379 | } |
| 5380 | } |
| 5381 | |
| 5382 | /*out must be buffer big enough to contain uncompressed IDAT chunk data, and in must contain the full image. |
| 5383 | return value is error**/ |
no test coverage detected