1:
37:
38: package ;
39:
40: import ;
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46:
47: import ;
48: import ;
49: import ;
50: import ;
51:
52: public class BMPInfoHeader
53: {
54:
55: protected int biSize;
56:
57:
58: protected int biWidth;
59:
60:
61: protected int biHeight;
62:
63:
64: protected short biPlanes;
65:
66:
67: protected short biBitCount;
68:
69:
70: protected int biCompression;
71:
72:
73: protected int biSizeImage;
74:
75:
76: protected int biXPelsPerMeter;
77:
78:
79: protected int biYPelsPerMeter;
80:
81:
82: protected int biClrUsed;
83:
84:
85: protected int biClrImportant;
86:
87:
88: public static final int SIZE = 40;
89:
90:
93: public static final int BI_RGB = 0;
94: public static final int BI_RLE8 = 1;
95: public static final int BI_RLE4 = 2;
96: public static final int BI_BITFIELDS = 3;
97:
98:
105: public BMPInfoHeader(ImageInputStream in) throws IOException, BMPException
106: {
107: byte[] data = new byte[SIZE];
108:
109: if (in.read(data) != SIZE)
110: throw new IOException("Couldn't read header.");
111: ByteBuffer buf = ByteBuffer.wrap(data);
112: buf.order(ByteOrder.LITTLE_ENDIAN);
113:
114: int n;
115: if ((n = buf.getInt()) != SIZE)
116: throw new BMPException("Invalid BITMAPINFOHEADER size: " + n);
117:
118: biWidth = buf.getInt();
119: biHeight = buf.getInt();
120: biPlanes = buf.getShort();
121: setBitCount(buf.getShort());
122: setCompression(buf.getInt());
123: biSizeImage = buf.getInt();
124: biXPelsPerMeter = buf.getInt();
125: biYPelsPerMeter = buf.getInt();
126: biClrUsed = buf.getInt();
127: biClrImportant = buf.getInt();
128: }
129:
130:
138: public BMPInfoHeader(ImageOutputStream out, IIOImage im, ImageWriteParam param) throws IOException
139: {
140: RenderedImage img = im.getRenderedImage();
141: ColorModel cMod = img.getColorModel();
142:
143: biSize = SIZE;
144: biWidth = img.getWidth();
145: biHeight = img.getHeight();
146: biPlanes = 1;
147:
148: if (param != null && param.canWriteCompressed())
149: {
150: String compType = param.getCompressionType();
151: if (compType.equals("BI_RLE8"))
152: {
153: biCompression = BI_RLE8;
154: biBitCount = 8;
155: }
156: else if (compType.equals("BI_RLE4"))
157: {
158: biCompression = BI_RLE4;
159: biBitCount = 4;
160: }
161: else
162: {
163: biCompression = BI_RGB;
164: biBitCount = (short) cMod.getPixelSize();
165: }
166: }
167: else
168: {
169: biBitCount = (short) cMod.getPixelSize();
170: biCompression = BI_RGB;
171: }
172:
173: biXPelsPerMeter = 0x0;
174: biYPelsPerMeter = 0x0;
175: biClrUsed = 0;
176: biClrImportant = 0;
177: biSizeImage = ((biWidth * biHeight) * 3)
178: + ((4 - ((biWidth * 3) % 4)) * biHeight);
179: out.write(intToDWord(biSize));
180: out.write(intToDWord(biWidth));
181: out.write(intToDWord(biHeight));
182: out.write(intToWord(biPlanes));
183: out.write(intToWord(biBitCount));
184: out.write(intToDWord(biCompression));
185: out.write(intToDWord(biSizeImage));
186: out.write(intToDWord(biXPelsPerMeter));
187: out.write(intToDWord(biYPelsPerMeter));
188: out.write(intToDWord(biClrUsed));
189: out.write(intToDWord(biClrImportant));
190: }
191:
192:
199: private byte[] intToWord(int val)
200: {
201: byte b[] = new byte[2];
202: b[0] = (byte) (val & 0x00FF);
203: b[1] = (byte) ((val >> 8) & 0x00FF);
204: return b;
205: }
206:
207:
214: private byte[] intToDWord(int val)
215: {
216: byte b[] = new byte[4];
217: b[0] = (byte) (val & 0x00FF);
218: b[1] = (byte) ((val >> 8) & 0x000000FF);
219: b[2] = (byte) ((val >> 16) & 0x000000FF);
220: b[3] = (byte) ((val >> 24) & 0x000000FF);
221: return b;
222: }
223:
224:
225: public void setBitCount(short bitcount) throws BMPException
226: {
227: switch (bitcount)
228: {
229: case 1:
230: case 4:
231: case 8:
232: case 16:
233: case 24:
234: case 32:
235: biBitCount = bitcount;
236: break;
237:
238: default:
239: throw new BMPException("Invalid number of bits per pixel: " + bitcount);
240: }
241: }
242:
243: public short getBitCount()
244: {
245: return biBitCount;
246: }
247:
248: public void setCompression(int compression) throws BMPException
249: {
250: switch (compression)
251: {
252: case BI_RLE8:
253: if (getBitCount() != 8)
254: throw new BMPException("Invalid number of bits per pixel.");
255: biCompression = compression;
256: break;
257: case BI_RLE4:
258: if (getBitCount() != 4)
259: throw new BMPException("Invalid number of bits per pixel.");
260: biCompression = compression;
261: break;
262:
263: case BI_RGB:
264: case BI_BITFIELDS:
265: biCompression = compression;
266: break;
267:
268: default:
269: throw new BMPException("Unknown bitmap compression type.");
270: }
271: }
272:
273: public int getNumberOfPaletteEntries()
274: {
275: if (biClrUsed == 0)
276: switch (biBitCount)
277: {
278: case 1:
279: return 2;
280: case 4:
281: return 16;
282: case 8:
283: return 256;
284:
285: default:
286: return 0;
287: }
288:
289: return biClrUsed;
290: }
291:
292: public int getCompression()
293: {
294: return biCompression;
295: }
296:
297: public Dimension getSize()
298: {
299: return new Dimension(biWidth, biHeight);
300: }
301:
302: public int getWidth()
303: {
304: return biWidth;
305: }
306:
307: public int getHeight()
308: {
309: return biHeight;
310: }
311:
312: public void setSize(Dimension d)
313: {
314: biWidth = (int) d.getWidth();
315: biHeight = (int) d.getHeight();
316: }
317: }