1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.imaging.formats.bmp;
18
19 import static org.apache.commons.imaging.common.BinaryFunctions.read2Bytes;
20 import static org.apache.commons.imaging.common.BinaryFunctions.readByte;
21
22 import java.io.IOException;
23 import java.nio.ByteOrder;
24
25 import org.apache.commons.imaging.ImagingException;
26
27 final class PixelParserRgb extends AbstractPixelParserSimple {
28 private int byteCount;
29 private int cachedBitCount;
30 private int cachedByte;
31
32 PixelParserRgb(final BmpHeaderInfo bhi, final byte[] colorTable, final byte[] imageData) {
33 super(bhi, colorTable, imageData);
34
35 }
36
37 @Override
38 public int getNextRgb() throws ImagingException, IOException {
39
40 switch (bhi.bitsPerPixel) {
41 case 1:
42 case 4: {
43 if (cachedBitCount < bhi.bitsPerPixel) {
44 if (cachedBitCount != 0) {
45 throw new ImagingException("Unexpected leftover bits: " + cachedBitCount + "/" + bhi.bitsPerPixel);
46 }
47
48 cachedBitCount += 8;
49 cachedByte = 0xff & imageData[byteCount];
50 byteCount++;
51 }
52 final int cacheMask = (1 << bhi.bitsPerPixel) - 1;
53 final int sample = cacheMask & cachedByte >> 8 - bhi.bitsPerPixel;
54 cachedByte = 0xff & cachedByte << bhi.bitsPerPixel;
55 cachedBitCount -= bhi.bitsPerPixel;
56 return getColorTableRgb(sample);
57 }
58 case 8: {
59 final int sample = 0xff & imageData[byteCount + 0];
60 final int rgb = getColorTableRgb(sample);
61 byteCount += 1;
62 return rgb;
63 }
64 case 16: {
65 final int data = read2Bytes("Pixel", is, "BMP Image Data", ByteOrder.LITTLE_ENDIAN);
66 final int blue = (0x1f & data >> 0) << 3;
67 final int green = (0x1f & data >> 5) << 3;
68 final int red = (0x1f & data >> 10) << 3;
69 final int alpha = 0xff;
70 final int rgb = alpha << 24 | red << 16 | green << 8 | blue << 0;
71 byteCount += 2;
72 return rgb;
73 }
74 case 24: {
75 final int blue = 0xff & imageData[byteCount + 0];
76 final int green = 0xff & imageData[byteCount + 1];
77 final int red = 0xff & imageData[byteCount + 2];
78 final int alpha = 0xff;
79 final int rgb = alpha << 24 | red << 16 | green << 8 | blue << 0;
80 byteCount += 3;
81 return rgb;
82 }
83 case 32: {
84 final int blue = 0xff & imageData[byteCount + 0];
85 final int green = 0xff & imageData[byteCount + 1];
86 final int red = 0xff & imageData[byteCount + 2];
87 final int alpha = 0xff;
88 final int rgb = alpha << 24 | red << 16 | green << 8 | blue << 0;
89 byteCount += 4;
90 return rgb;
91 }
92 default:
93 break;
94 }
95
96 throw new ImagingException("Unknown BitsPerPixel: " + bhi.bitsPerPixel);
97 }
98
99 @Override
100 public void newline() throws ImagingException, IOException {
101 cachedBitCount = 0;
102
103 while (byteCount % 4 != 0) {
104 readByte("Pixel", is, "BMP Image Data");
105 byteCount++;
106 }
107 }
108 }