1:
37:
38: package ;
39:
40: import ;
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46:
47: public abstract class BMPDecoder {
48:
49: protected BMPInfoHeader infoHeader;
50: protected BMPFileHeader fileHeader;
51: protected long offset;
52:
53: public BMPDecoder(BMPFileHeader fh, BMPInfoHeader ih){
54: fileHeader = fh;
55: infoHeader = ih;
56: offset = BMPFileHeader.SIZE + BMPInfoHeader.SIZE;
57: }
58:
59:
63: public static BMPDecoder getDecoder(BMPFileHeader fh, BMPInfoHeader ih){
64: switch(ih.getCompression()){
65: case BMPInfoHeader.BI_RGB:
66: switch(ih.getBitCount()){
67: case 32:
68: return new DecodeBF32(fh, ih, true);
69:
70: case 24:
71: return new DecodeRGB24(fh, ih);
72:
73: case 16:
74: return new DecodeBF16(fh, ih, true);
75:
76: case 8:
77: return new DecodeRGB8(fh, ih);
78:
79: case 4:
80: return new DecodeRGB4(fh, ih);
81:
82: case 1:
83: return new DecodeRGB1(fh, ih);
84:
85: default:
86: return null;
87: }
88:
89: case BMPInfoHeader.BI_RLE8:
90: return new DecodeRLE8(fh, ih);
91:
92: case BMPInfoHeader.BI_RLE4:
93: return new DecodeRLE4(fh, ih);
94:
95: case BMPInfoHeader.BI_BITFIELDS:
96: switch(ih.getBitCount()){
97: case 16:
98: return new DecodeBF16(fh, ih, false);
99:
100: case 32:
101: return new DecodeBF32(fh, ih, false);
102:
103: default:
104: return null;
105: }
106:
107: default:
108: return null;
109: }
110: }
111:
112:
115: public abstract BufferedImage decode(ImageInputStream in)
116: throws IOException, BMPException;
117:
118:
121: protected int[] readBitMasks(ImageInputStream in) throws IOException {
122: int[] bitmasks = new int[3];
123: byte[] temp = new byte[12];
124: if(in.read(temp) != 12)
125: throw new IOException("Couldn't read bit masks.");
126: offset += 12;
127:
128: ByteBuffer buf = ByteBuffer.wrap(temp);
129: buf.order(ByteOrder.LITTLE_ENDIAN);
130: bitmasks[0] = buf.getInt();
131: bitmasks[1] = buf.getInt();
132: bitmasks[2] = buf.getInt();
133: return bitmasks;
134: }
135:
136:
140: protected IndexColorModel readPalette(ImageInputStream in) throws IOException {
141: int N = infoHeader.getNumberOfPaletteEntries();
142: byte[] r = new byte[N];
143: byte[] g = new byte[N];
144: byte[] b = new byte[N];
145: for(int i=0;i<N;i++){
146: byte[] RGBquad = new byte[4];
147: if(in.read(RGBquad) != 4)
148: throw new IOException("Error reading palette information.");
149:
150: r[i] = RGBquad[2];
151: g[i] = RGBquad[1];
152: b[i] = RGBquad[0];
153: }
154:
155: offset += 4*N;
156: return new IndexColorModel(8, N, r, g, b);
157: }
158:
159:
162: protected void skipToImage(ImageInputStream in) throws IOException {
163: byte[] d = new byte[1];
164: long n = fileHeader.getOffset() - offset;
165: for(int i=0;i<n;i++)
166: in.read(d);
167: }
168: }