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 org.apache.commons.imaging.ImageReadException;
20
21 class BitParser {
22 private final byte[] bytes;
23 private final int bitsPerPixel;
24 private final int bitDepth;
25
26 BitParser(final byte[] bytes, final int bitsPerPixel, final int bitDepth) {
27 this.bytes = bytes.clone();
28 this.bitsPerPixel = bitsPerPixel;
29 this.bitDepth = bitDepth;
30 }
31
32 public int getSample(final int pixelIndexInScanline, final int sampleIndex)
33 throws ImageReadException {
34 final int pixelIndexBits = bitsPerPixel * pixelIndexInScanline;
35 final int sampleIndexBits = pixelIndexBits + (sampleIndex * bitDepth);
36 final int sampleIndexBytes = sampleIndexBits >> 3;
37
38 if (bitDepth == 8) {
39 return 0xff & bytes[sampleIndexBytes];
40 }
41 if (bitDepth < 8) {
42 int b = 0xff & bytes[sampleIndexBytes];
43 final int bitsToShift = 8 - ((pixelIndexBits & 7) + bitDepth);
44 b >>= bitsToShift;
45
46 final int bitmask = (1 << bitDepth) - 1;
47 return b & bitmask;
48 }
49 if (bitDepth == 16) {
50 return (((0xff & bytes[sampleIndexBytes]) << 8) | (0xff & bytes[sampleIndexBytes + 1]));
51 }
52
53 throw new ImageReadException("PNG: bad BitDepth: " + bitDepth);
54 }
55
56 public int getSampleAsByte(final int pixelIndexInScanline, final int sampleIndex)
57 throws ImageReadException {
58 int sample = getSample(pixelIndexInScanline, sampleIndex);
59
60 final int rot = 8 - bitDepth;
61 if (rot > 0) {
62 sample = sample * 255 / ((1 << bitDepth) - 1);
63 } else if (rot < 0) {
64 sample >>= -rot;
65 }
66
67 return 0xff & sample;
68 }
69 }