2 * Copyright (c) 2003-2009 jMonkeyEngine
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 package com.jme.image;
35 import java.awt.Toolkit;
36 import java.awt.image.MemoryImageSource;
37 import java.io.IOException;
40 * <code>BitmapHeader</code> defines header information about a bitmap (BMP) image
43 * @version $Id: BitmapHeader.java,v 1.13 2006/01/13 19:40:05 renanse Exp $
45 public class BitmapHeader {
47 * the number of bits that makes up the image.
57 private int compression;
58 private int sizeimage;
66 * <code>readMap32</code> reads a 32 bit bitmap file.
67 * @param data the byte data that contains the file information.
68 * @return the Image that contains the bitmap.
70 public java.awt.Image readMap32(byte[] data) {
72 int xwidth = sizeimage / height;
73 int ndata[] = new int[height * width];
74 byte brgb[] = new byte[width * 4 * height];
76 for(int i = 0; i < width * 4 * height; i++) {
77 if(i+54 >= data.length) {
80 brgb[i] = data[i + 54];
84 for (int j = 0; j < height; j++) {
85 for (int i = 0; i < width; i++) {
86 ndata[width * (height - j - 1) + i] =
87 constructInt3(brgb, nindex);
93 Toolkit.getDefaultToolkit().createImage(
94 new MemoryImageSource(width, height, ndata, 0, width));
100 * <code>readMap24</code> reads a 24 bit bitmap file.
101 * @param data the byte data that contains the file information.
102 * @return the Image that contains the bitmap.
104 public java.awt.Image readMap24(byte[] data)
106 java.awt.Image image;
107 int npad = (sizeimage / height) - width * 3;
108 int ndata[] = new int[height * width];
109 byte brgb[] = new byte[(width + npad) * 3 * height];
110 for(int i = 0; i < brgb.length; i++) {
111 if(i + 54>= data.length) {
114 brgb[i] = data[i + 54];
119 for (int j = 0; j < height; j++) {
120 for (int i = 0; i < width; i++) {
121 ndata[width * (height - j - 1) + i] =
122 constructInt3(brgb, nindex);
129 Toolkit.getDefaultToolkit().createImage(
130 new MemoryImageSource(width, height, ndata, 0, width));
136 * <code>readMap8</code> reads a 8 bit bitmap file.
137 * @param data the byte data that contains the file information.
138 * @return the Image that contains the bitmap.
140 public java.awt.Image readMap8(byte[] data) {
141 java.awt.Image image;
145 nNumColors = clrused;
147 nNumColors = (1 & 0xff) << bitcount;
150 if (sizeimage == 0) {
151 sizeimage = ((((width * bitcount) + 31) & ~31) >> 3);
155 int npalette[] = new int[nNumColors];
156 byte bpalette[] = new byte[nNumColors * 4];
158 for(int i = 0; i < nNumColors * 4; i++) {
159 bpalette[i] = data[i + 54];
164 for (int n = 0; n < nNumColors; n++) {
165 npalette[n] = constructInt3(bpalette, nindex8);
169 int npad8 = (sizeimage / height) - width;
170 int ndata8[] = new int[width * height];
171 byte bdata[] = new byte[(width + npad8) * height];
172 for(int i = 0; i < bdata.length; i++) {
173 bdata[i] = data[i + bpalette.length + 54];
177 for (int j8 = 0; j8 < height; j8++) {
178 for (int i8 = 0; i8 < width; i8++) {
179 ndata8[width * (height - j8 - 1) + i8] =
180 npalette[(bdata[nindex8] & 0xff)];
188 Toolkit.getDefaultToolkit().createImage(
189 new MemoryImageSource(
200 * Builds an int from a byte array - convert little to big endian.
201 * @param in Byte array to convert
202 * @param offset offset in byte array
203 * @return Big endian int from in[offset]-in[offset+3]
205 private int constructInt(byte[] in, int offset) {
206 int ret = (in[offset + 3] & 0xff);
207 ret = (ret << 8) | (in[offset + 2] & 0xff);
208 ret = (ret << 8) | (in[offset + 1] & 0xff);
209 ret = (ret << 8) | (in[offset + 0] & 0xff);
214 * Builds an int from a byte array - convert little to big endian
215 * set high order bytes to 0xfff..
216 * @param in Byte array to convert.
217 * @param offset Offset in byte array.
218 * @return Big endian int from in[offset]-in[offset+2] with higher order of 0xff
220 private int constructInt3(byte[] in, int offset) {
222 ret = (ret << 8) | (in[offset + 2] & 0xff);
223 ret = (ret << 8) | (in[offset + 1] & 0xff);
224 ret = (ret << 8) | (in[offset + 0] & 0xff);
229 * Builds a long from a byte array - convert little to big endian.
230 * @param in Byte array to convert.
231 * @param offset Offset in byte array.
232 * @return Big endian long from in[offset]-in[offset+7]
234 private long constructLong(byte[] in, int offset) {
235 long ret = ((long) in[offset + 7] & 0xff);
236 ret |= (ret << 8) | ((long) in[offset + 6] & 0xff);
237 ret |= (ret << 8) | ((long) in[offset + 5] & 0xff);
238 ret |= (ret << 8) | ((long) in[offset + 4] & 0xff);
239 ret |= (ret << 8) | ((long) in[offset + 3] & 0xff);
240 ret |= (ret << 8) | ((long) in[offset + 2] & 0xff);
241 ret |= (ret << 8) | ((long) in[offset + 1] & 0xff);
242 ret |= (ret << 8) | ((long) in[offset + 0] & 0xff);
247 * Builds an double from a byte array - convert little to big endian.
248 * @param in Byte array to convert.
249 * @param offset Offset in byte array.
250 * @return Big endian double from in[offset]-in[offset+7]
252 private double constructDouble(byte[] in, int offset) {
253 long ret = constructLong(in, offset);
254 return (Double.longBitsToDouble(ret));
258 * Builds an short from a byte array - convert little to big endian.
259 * @param in Byte array to convert.
260 * @param offset Offset in byte array.
261 * @return Big endian short from in[offset]-in[offset+1]
263 private short constructShort(byte[] in, int offset) {
264 short ret = (short) (in[offset + 1] & 0xff);
265 ret = (short) ((ret << 8) | (short) (in[offset + 0] & 0xff));
270 * Reads in a bitmap header from the byte[] and chops it up into BitemapHeader variables
271 * @param data The byte[] to read.
273 public final void read(byte[] data){
274 final int bflen = 14;
275 byte bf[] = new byte[bflen];
276 for(int i = 0; i < bf.length; i++) {
279 final int bilen = 40;
280 byte bi[] = new byte[bilen];
281 for(int i = 0; i < bi.length; i++) {
282 bi[i] = data[i + 14];
285 size = constructInt(bf, 2);
286 bisize = constructInt(bi, 2);
287 width = constructInt(bi, 4);
288 height = constructInt(bi, 8);
289 planes = constructShort(bi, 12);
290 bitcount = constructShort(bi, 14);
291 compression = constructInt(bi, 16);
292 sizeimage = (constructInt(bi, 20) == 0 ? size - constructInt(bf,10) : constructInt(bi, 20));
293 xpm = constructInt(bi, 24);
294 ypm = constructInt(bi, 28);
295 clrused = constructInt(bi, 32);
296 clrimp = constructInt(bi, 36);