2 Copyright (C) 2006 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package gnu
.javax
.imageio
.bmp
;
41 import java
.awt
.image
.BufferedImage
;
42 import java
.awt
.image
.PixelGrabber
;
43 import java
.io
.IOException
;
44 import java
.nio
.BufferUnderflowException
;
45 import java
.nio
.ByteBuffer
;
47 import javax
.imageio
.IIOImage
;
48 import javax
.imageio
.ImageWriteParam
;
49 import javax
.imageio
.metadata
.IIOMetadata
;
50 import javax
.imageio
.stream
.ImageOutputStream
;
52 public class EncodeRLE4
55 protected BMPInfoHeader infoHeader
;
56 protected BMPFileHeader fileHeader
;
57 protected long offset
;
62 private static final byte ESCAPE
= (byte)0;
63 private static final byte EOL
= (byte)0; // end of line
64 private static final byte EOB
= (byte)1; // end of bitmap
65 private static final byte DELTA
= (byte)2; // delta
68 * Constructs an instance of this class.
70 * @param fh - the file header to use.
71 * @param ih - the info header to use.
73 public EncodeRLE4(BMPFileHeader fh
, BMPInfoHeader ih
)
78 offset
= BMPFileHeader
.SIZE
+ BMPInfoHeader
.SIZE
;
84 * @param o - the image output stream
85 * @param streamMetadata - metadata associated with this stream, or
87 * @param image - an IIOImage containing image data.
88 * @param param - image writing parameters, or null
89 * @exception IOException if a write error occurs
91 public void encode(ImageOutputStream o
, IIOMetadata streamMetadata
,
92 IIOImage image
, ImageWriteParam param
) throws IOException
101 size
= (infoHeader
.biWidth
* infoHeader
.biHeight
) - 1;
103 rowIndex
= size
- infoHeader
.biWidth
;
104 lastRowIndex
= rowIndex
;
105 ByteBuffer buf
= ByteBuffer
.allocate(size
);
108 bitmap
= new int[infoHeader
.biWidth
* infoHeader
.biHeight
];
109 PixelGrabber pg
= new PixelGrabber((BufferedImage
) image
.getRenderedImage(),
110 0, 0, infoHeader
.biWidth
,
111 infoHeader
.biHeight
, bitmap
, 0,
115 for (j
= 0; j
< size
; j
++)
117 value
= bitmap
[rowIndex
];
118 buf
.put((byte) (value
& 0xFF));
120 if (rowCount
== infoHeader
.biWidth
)
123 rowIndex
= lastRowIndex
- infoHeader
.biWidth
;
124 lastRowIndex
= rowIndex
;
132 o
.write(uncompress(infoHeader
.biWidth
, infoHeader
.biHeight
, buf
));
136 wb
.printStackTrace();
141 * Uncompresses the image stored in the buffer.
143 * @param w - the width of the image
144 * @param h - the height of the image
145 * @param buf - the ByteBuffer containing the pixel values.
146 * @return byte array containing the uncompressed image
147 * @throws IOException if an error is encountered while reading
150 private byte[] uncompress(int w
, int h
, ByteBuffer buf
)
153 byte[] cmd
= new byte[2];
154 byte[] data
= new byte[w
* h
>> 1];
163 while (((x
>> 1) + y
* w
) < w
* h
)
169 catch (BufferUnderflowException e
)
171 throw new IOException("Error reading compressed data.");
174 if (cmd
[0] == ESCAPE
)
189 catch (BufferUnderflowException e
)
191 throw new IOException("Error reading compressed data.");
194 int dx
= cmd
[0] & (0xFF);
195 int dy
= cmd
[1] & (0xFF);
201 int length
= cmd
[1] & (0xFF);
203 int bytesize
= length
;
204 bytesize
+= (bytesize
& 1);
206 bytesize
+= (bytesize
& 1);
208 byte[] run
= new byte[bytesize
];
213 catch (BufferUnderflowException e
)
215 throw new IOException("Error reading compressed data.");
220 length
+= (length
& 1);
222 System
.arraycopy(run
, 0, data
,
223 ((x
>> 1) + w
* (h
- y
- 1)), length
);
227 for (int i
= 0; i
< length
; i
++)
230 data
[((x
+ i
) >> 1) + w
* (h
- y
- 1)] |= ((run
[i
>> 1] & 0xF0) >> 4);
232 data
[((x
+ i
) >> 1) + w
* (h
- y
- 1)] |= ((run
[i
>> 1] & 0x0F) << 4);
235 x
+= cmd
[1] & (0xFF);
241 int length
= cmd
[0] & (0xFF);
244 length
+= (length
& 1);
246 for (int i
= 0; i
< length
; i
++)
247 data
[(h
- y
- 1) * w
+ i
+ (x
>> 1)] = cmd
[1];
251 for (int i
= 0; i
< length
; i
++)
254 data
[((x
+ i
) >> 1) + w
* (h
- y
- 1)] |= ((cmd
[1] & 0xF0) >> 4);
256 data
[((x
+ i
) >> 1) + w
* (h
- y
- 1)] |= ((cmd
[1] & 0x0F) << 4);
259 x
+= cmd
[0] & (0xFF);
264 catch (ArrayIndexOutOfBoundsException e
)
266 throw new BMPException("Invalid RLE data.");