OSDN Git Service

2bc3ccc84f022e59c2752629b73ff193d0a740b2
[mikumikustudio/MikuMikuStudio.git] / src / com / jme / image / BitmapHeader.java
1 /*
2  * Copyright (c) 2003-2009 jMonkeyEngine
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
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.
15  *
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.
19  *
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.
31  */
32
33 package com.jme.image;
34
35 import java.awt.Toolkit;
36 import java.awt.image.MemoryImageSource;
37 import java.io.IOException;
38
39 /**
40  * <code>BitmapHeader</code> defines header information about a bitmap (BMP) image
41  * file format.
42  * @author Mark Powell
43  * @version $Id: BitmapHeader.java,v 1.13 2006/01/13 19:40:05 renanse Exp $
44  */
45 public class BitmapHeader {
46     /**
47      * the number of bits that makes up the image.
48      */
49     public int bitcount;
50
51     private int size;
52     private int bisize;
53     private int width;
54     private int height;
55     private int planes;
56
57     private int compression;
58     private int sizeimage;
59     private int xpm;
60     private int ypm;
61     private int clrused;
62     private int clrimp;
63
64     /**
65      *
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.
69      */
70     public java.awt.Image readMap32(byte[] data) {
71         java.awt.Image image;
72         int xwidth = sizeimage / height;
73         int ndata[] = new int[height * width];
74         byte brgb[] = new byte[width * 4 * height];
75
76         for(int i = 0; i < width * 4 * height; i++) {
77             if(i+54 >= data.length) {
78                 break;
79             }
80             brgb[i] = data[i + 54];
81         }
82         int nindex = 0;
83
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);
88                 nindex += 4;
89             }
90         }
91
92         image =
93             Toolkit.getDefaultToolkit().createImage(
94                 new MemoryImageSource(width, height, ndata, 0, width));
95         return (image);
96     }
97
98     /**
99      *
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.
103      */
104     public java.awt.Image readMap24(byte[] data)
105         throws IOException {
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) {
112                 break;
113             }
114             brgb[i] = data[i + 54];
115         }
116
117         int nindex = 0;
118
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);
123                 nindex += 3;
124             }
125             nindex += npad;
126         }
127
128         image =
129             Toolkit.getDefaultToolkit().createImage(
130                 new MemoryImageSource(width, height, ndata, 0, width));
131         return image;
132     }
133
134     /**
135      *
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.
139      */
140     public java.awt.Image readMap8(byte[] data) {
141          java.awt.Image image;
142         int nNumColors = 0;
143
144         if (clrused > 0) {
145             nNumColors = clrused;
146         } else {
147             nNumColors = (1 & 0xff) << bitcount;
148         }
149
150         if (sizeimage == 0) {
151             sizeimage = ((((width * bitcount) + 31) & ~31) >> 3);
152             sizeimage *= height;
153         }
154
155         int npalette[] = new int[nNumColors];
156         byte bpalette[] = new byte[nNumColors * 4];
157
158         for(int i = 0; i < nNumColors * 4; i++) {
159             bpalette[i] = data[i + 54];
160         }
161
162         int nindex8 = 0;
163
164         for (int n = 0; n < nNumColors; n++) {
165             npalette[n] = constructInt3(bpalette, nindex8);
166             nindex8 += 4;
167         }
168
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];
174         }
175         nindex8 = 0;
176
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)];
181                 nindex8++;
182             }
183
184             nindex8 += npad8;
185         }
186
187         image =
188             Toolkit.getDefaultToolkit().createImage(
189                 new MemoryImageSource(
190                     width,
191                     height,
192                     ndata8,
193                     0,
194                     width));
195
196         return image;
197     }
198
199     /**
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]
204      */
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);
210         return (ret);
211     }
212
213     /**
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
219      */
220     private int constructInt3(byte[] in, int offset) {
221         int ret = 0xff;
222         ret = (ret << 8) | (in[offset + 2] & 0xff);
223         ret = (ret << 8) | (in[offset + 1] & 0xff);
224         ret = (ret << 8) | (in[offset + 0] & 0xff);
225         return (ret);
226     }
227
228     /**
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]
233      */
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);
243         return (ret);
244     }
245
246     /**
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]
251      */
252     private double constructDouble(byte[] in, int offset) {
253         long ret = constructLong(in, offset);
254         return (Double.longBitsToDouble(ret));
255     }
256
257     /**
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]
262      */
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));
266         return (ret);
267     }
268
269     /**
270      * Reads in a bitmap header from the byte[] and chops it up into BitemapHeader variables
271      * @param data The byte[] to read.
272      */
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++) {
277             bf[i] = data[i];
278         }
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];
283         }
284
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);
297
298     }
299 }