1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.imaging.formats.png;
18
19 import java.awt.image.BufferedImage;
20 import java.io.IOException;
21 import java.io.InputStream;
22
23 import org.apache.commons.imaging.ImagingException;
24 import org.apache.commons.imaging.formats.png.chunks.PngChunkPlte;
25 import org.apache.commons.imaging.formats.png.transparencyfilters.AbstractTransparencyFilter;
26
27 final class ScanExpediterInterlaced extends AbstractScanExpediter {
28 private static final int[] STARTING_ROW = { 0, 0, 4, 0, 2, 0, 1 };
29 private static final int[] STARTING_COL = { 0, 4, 0, 2, 0, 1, 0 };
30 private static final int[] ROW_INCREMENT = { 8, 8, 8, 4, 4, 2, 2 };
31 private static final int[] COL_INCREMENT = { 8, 8, 4, 4, 2, 2, 1 };
32
33
34
35 ScanExpediterInterlaced(final int width, final int height, final InputStream is, final BufferedImage bi, final PngColorType pngColorType,
36 final int bitDepth, final int bitsPerPixel, final PngChunkPlte pngChunkPLTE, final GammaCorrection gammaCorrection,
37 final AbstractTransparencyFilter abstractTransparencyFilter) {
38 super(width, height, is, bi, pngColorType, bitDepth, bitsPerPixel, pngChunkPLTE, gammaCorrection, abstractTransparencyFilter);
39 }
40
41 @Override
42 public void drive() throws ImagingException, IOException {
43
44 int pass = 1;
45 while (pass <= 7) {
46 byte[] prev = null;
47
48 int y = STARTING_ROW[pass - 1];
49
50
51 while (y < height) {
52 int x = STARTING_COL[pass - 1];
53 int pixelIndexInScanline = 0;
54
55 if (x < width) {
56
57 final int columnsInRow = 1 + (width - STARTING_COL[pass - 1] - 1) / COL_INCREMENT[pass - 1];
58 final int bitsPerScanLine = bitsPerPixel * columnsInRow;
59 final int pixelBytesPerScanLine = getBitsToBytesRoundingUp(bitsPerScanLine);
60
61 final byte[] unfiltered = getNextScanline(is, pixelBytesPerScanLine, prev, bytesPerPixel);
62
63 prev = unfiltered;
64
65 final BitParser fBitParser = new BitParser(unfiltered, bitsPerPixel, bitDepth);
66
67 while (x < width) {
68 visit(x, y, bi, fBitParser, pixelIndexInScanline);
69
70 x += COL_INCREMENT[pass - 1];
71 pixelIndexInScanline++;
72 }
73 }
74 y += ROW_INCREMENT[pass - 1];
75 }
76 pass += 1;
77 }
78 }
79
80 private void visit(final int x, final int y, final BufferedImage bi, final BitParser fBitParser, final int pixelIndexInScanline)
81 throws ImagingException, IOException {
82 final int rgb = getRgb(fBitParser, pixelIndexInScanline);
83 bi.setRGB(x, y, rgb);
84 }
85 }