1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46:
47: import ;
48: import ;
49: import ;
50: import ;
51:
52: public class EncodeRLE8
53: extends BMPEncoder
54: {
55: protected BMPInfoHeader infoHeader;
56: protected BMPFileHeader fileHeader;
57: protected long offset;
58:
59:
62: private static final byte ESCAPE = (byte)0;
63: private static final byte EOL = (byte)0;
64: private static final byte EOB = (byte)1;
65: private static final byte DELTA = (byte)2;
66:
67:
73: public EncodeRLE8(BMPFileHeader fh, BMPInfoHeader ih)
74: {
75: super();
76: fileHeader = fh;
77: infoHeader = ih;
78: offset = BMPFileHeader.SIZE + BMPInfoHeader.SIZE;
79: }
80:
81:
91: public void encode(ImageOutputStream o, IIOMetadata streamMetadata,
92: IIOImage image, ImageWriteParam param) throws IOException
93: {
94: int size;
95: int value;
96: int j;
97: int rowCount;
98: int rowIndex;
99: int lastRowIndex;
100: int[] bitmap;
101: size = (infoHeader.biWidth * infoHeader.biHeight) - 1;
102: rowCount = 1;
103: rowIndex = size - infoHeader.biWidth;
104: lastRowIndex = rowIndex;
105: ByteBuffer buf = ByteBuffer.allocate(size);
106: try
107: {
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,
112: infoHeader.biWidth);
113: pg.grabPixels();
114:
115: for (j = 0; j < size; j++)
116: {
117: value = bitmap[rowIndex];
118: buf.put((byte) (value & 0xFF));
119:
120: if (rowCount == infoHeader.biWidth)
121: {
122: rowCount = 1;
123: rowIndex = lastRowIndex - infoHeader.biWidth;
124: lastRowIndex = rowIndex;
125: }
126: else
127: rowCount++;
128: rowIndex++;
129: }
130:
131: buf.flip();
132: o.write(uncompress(infoHeader.biWidth, infoHeader.biHeight, buf));
133: }
134: catch (Exception wb)
135: {
136: wb.printStackTrace();
137: }
138: }
139:
140:
141:
151: private byte[] uncompress(int w, int h, ByteBuffer buf) throws IOException
152: {
153: byte[] cmd = new byte[2];
154: byte[] data = new byte[w * h];
155: int offIn = 0;
156: int x = 0, y = 0;
157:
158: try
159: {
160: while ((x + y * w) < w * h)
161: {
162: try
163: {
164: buf.get(cmd);
165: }
166: catch (BufferUnderflowException e)
167: {
168: throw new IOException("Error reading compressed data.");
169: }
170:
171: if (cmd[0] == ESCAPE)
172: {
173: switch (cmd[1])
174: {
175: case EOB:
176: return data;
177: case EOL:
178: x = 0;
179: y++;
180: break;
181: case DELTA:
182: try
183: {
184: buf.get(cmd);
185: }
186: catch (BufferUnderflowException e)
187: {
188: throw new IOException("Error reading compressed data.");
189: }
190:
191: int dx = cmd[0] & (0xFF);
192: int dy = cmd[1] & (0xFF);
193: x += dx;
194: y += dy;
195: break;
196:
197: default:
198: int length = cmd[1] & (0xFF);
199: int copylength = length;
200:
201: length += (length & 1);
202:
203: byte[] run = new byte[length];
204:
205: try
206: {
207: buf.get(run);
208: }
209: catch (BufferUnderflowException e)
210: {
211: throw new IOException("Error reading compressed data.");
212: }
213:
214: System.arraycopy(run, 0, data, (x + w * (h - y - 1)),
215: copylength);
216: x += copylength;
217: break;
218: }
219: }
220: else
221: {
222: int length = cmd[0] & (0xFF);
223: for (int i = 0; i < length; i++)
224: data[(h - y - 1) * w + x++] = cmd[1];
225: }
226: }
227: return data;
228: }
229: catch (ArrayIndexOutOfBoundsException e)
230: {
231: throw new BMPException("Invalid RLE data.");
232: }
233: }
234: }