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