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.ImagingException;
20
21 final 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) throws ImagingException {
33 final int pixelIndexBits = bitsPerPixel * pixelIndexInScanline;
34 final int sampleIndexBits = pixelIndexBits + sampleIndex * bitDepth;
35 final int sampleIndexBytes = sampleIndexBits >> 3;
36
37 if (bitDepth == 8) {
38 return 0xff & bytes[sampleIndexBytes];
39 }
40 if (bitDepth < 8) {
41 int b = 0xff & bytes[sampleIndexBytes];
42 final int bitsToShift = 8 - ((pixelIndexBits & 7) + bitDepth);
43 b >>= bitsToShift;
44
45 final int bitmask = (1 << bitDepth) - 1;
46 return b & bitmask;
47 }
48 if (bitDepth == 16) {
49 return (0xff & bytes[sampleIndexBytes]) << 8 | 0xff & bytes[sampleIndexBytes + 1];
50 }
51
52 throw new ImagingException("PNG: bad BitDepth: " + bitDepth);
53 }
54
55 public int getSampleAsByte(final int pixelIndexInScanline, final int sampleIndex) throws ImagingException {
56 int sample = getSample(pixelIndexInScanline, sampleIndex);
57
58 final int rot = 8 - bitDepth;
59 if (rot > 0) {
60 sample = sample * 255 / ((1 << bitDepth) - 1);
61 } else if (rot < 0) {
62 sample >>= -rot;
63 }
64
65 return 0xff & sample;
66 }
67 }