001: ///////////////////////////////////////////////////////////////////////////////
002: //
003: // This program is free software; you can redistribute it and/or modify
004: // it under the terms of the GNU General Public License and GNU Library
005: // General Public License as published by the Free Software Foundation;
006: // either version 2, or (at your option) any later version.
007: //
008: // This program is distributed in the hope that it will be useful,
009: // but WITHOUT ANY WARRANTY; without even the implied warranty of
010: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
011: // GNU General Public License and GNU Library General Public License
012: // for more details.
013: //
014: // You should have received a copy of the GNU General Public License
015: // and GNU Library General Public License along with this program; if
016: // not, write to the Free Software Foundation, 675 Mass Ave, Cambridge,
017: // MA 02139, USA.
018: //
019: //////////////////////////////////////////////////////////////////////////////
020:
021: package org.rdesktop.server.rdp.rdp5.cliprdr;
022:
023: import java.awt.*;
024: import java.io.*;
025: import java.awt.image.*;
026:
027: public class ClipBMP extends Component {
028: private final static int BITMAPFILEHEADER_SIZE = 14;
029: private final static int BITMAPINFOHEADER_SIZE = 40;
030:
031: private int m_bfSize = 0;
032: private int m_bfReserved1 = 0;
033: private int m_bfReserved2 = 0;
034: private byte m_bfType[] = { 'B', 'M' };
035: private byte m_bitmapFileHeader[] = new byte[14];
036: private byte m_bitmapInfoHeader[] = new byte[40];
037: private int m_bfOffBits = BITMAPFILEHEADER_SIZE
038: + BITMAPINFOHEADER_SIZE;
039:
040: private int m_biWidth = 0;
041: private int m_biHeight = 0;
042: private int m_biPlanes = 1;
043: private int m_biBitCount = 24;
044: private int m_biCompression = 0;
045: private int m_biSizeImage = 0x030000;
046: private int m_biXPelsPerMeter = 0x0;
047: private int m_biYPelsPerMeter = 0x0;
048: private int m_biClrUsed = 0;
049: private int m_biClrImportant = 0;
050: private int m_biSize = BITMAPINFOHEADER_SIZE;
051:
052: private int m_bitmap[];
053: private OutputStream m_outputStream;
054:
055: public ClipBMP() {
056: }
057:
058: public byte[] getBitmapAsBytes(Image parImage, int parWidth,
059: int parHeight) {
060: try {
061: m_outputStream = new ByteArrayOutputStream();
062: save(parImage, parWidth, parHeight);
063: m_outputStream.close();
064: } catch (Exception saveEx) {
065: saveEx.printStackTrace();
066: }
067:
068: return ((ByteArrayOutputStream) m_outputStream).toByteArray();
069: }
070:
071: public void saveBitmap(String parFilename, Image parImage,
072: int parWidth, int parHeight) {
073: try {
074: m_outputStream = new FileOutputStream(parFilename);
075: save(parImage, parWidth, parHeight);
076: m_outputStream.close();
077: } catch (Exception saveEx) {
078: saveEx.printStackTrace();
079: }
080: }
081:
082: private void save(Image parImage, int parWidth, int parHeight) {
083: try {
084: convertImage(parImage, parWidth, parHeight);
085: writeBitmapInfoHeader();
086: writeBitmap();
087: } catch (Exception saveEx) {
088: saveEx.printStackTrace();
089: }
090: }
091:
092: private boolean convertImage(Image parImage, int parWidth,
093: int parHeight) {
094: int pad;
095: m_bitmap = new int[parWidth * parHeight];
096: PixelGrabber pg = new PixelGrabber(parImage, 0, 0, parWidth,
097: parHeight, m_bitmap, 0, parWidth);
098:
099: try {
100: pg.grabPixels();
101: } catch (InterruptedException e) {
102: e.printStackTrace();
103: return (false);
104: }
105:
106: pad = (4 - ((parWidth * 3) % 4)) * parHeight;
107: m_biSizeImage = ((parWidth * parHeight) * 3) + pad;
108: m_bfSize = m_biSizeImage + BITMAPFILEHEADER_SIZE
109: + BITMAPINFOHEADER_SIZE;
110: m_biWidth = parWidth;
111: m_biHeight = parHeight;
112: return (true);
113: }
114:
115: private void writeBitmap() {
116: int size;
117: int value;
118: int j;
119: int i;
120: int rowCount;
121: int rowIndex;
122: int lastRowIndex;
123: int pad;
124: int padCount;
125: byte rgb[] = new byte[3];
126:
127: size = (m_biWidth * m_biHeight) - 1;
128: pad = 4 - ((m_biWidth * 3) % 4);
129: if (pad == 4) {
130: pad = 0;
131: }
132:
133: rowCount = 1;
134: padCount = 0;
135: rowIndex = size - m_biWidth;
136: lastRowIndex = rowIndex;
137: try {
138: for (j = 0; j < size; j++) {
139: value = m_bitmap[rowIndex];
140: rgb[0] = (byte) (value & 0xFF);
141: rgb[1] = (byte) ((value >> 8) & 0xFF);
142: rgb[2] = (byte) ((value >> 16) & 0xFF);
143: m_outputStream.write(rgb);
144: if (rowCount == m_biWidth) {
145: padCount += pad;
146: for (i = 1; i <= pad; i++) {
147: m_outputStream.write(0x00);
148: }
149: rowCount = 1;
150: rowIndex = lastRowIndex - m_biWidth;
151: lastRowIndex = rowIndex;
152: } else {
153: rowCount++;
154: }
155:
156: rowIndex++;
157: }
158:
159: m_bfSize += padCount - pad;
160: m_biSizeImage += padCount - pad;
161: } catch (Exception wb) {
162: wb.printStackTrace();
163: }
164: }
165:
166: private void writeBitmapFileHeader() {
167: try {
168: m_outputStream.write(m_bfType);
169: m_outputStream.write(intToDWord(m_bfSize));
170: m_outputStream.write(intToWord(m_bfReserved1));
171: m_outputStream.write(intToWord(m_bfReserved2));
172: m_outputStream.write(intToDWord(m_bfOffBits));
173: } catch (Exception wbfh) {
174: wbfh.printStackTrace();
175: }
176: }
177:
178: private void writeBitmapInfoHeader() {
179: try {
180: m_outputStream.write(intToDWord(m_biSize));
181: m_outputStream.write(intToDWord(m_biWidth));
182: m_outputStream.write(intToDWord(m_biHeight));
183: m_outputStream.write(intToWord(m_biPlanes));
184: m_outputStream.write(intToWord(m_biBitCount));
185: m_outputStream.write(intToDWord(m_biCompression));
186: m_outputStream.write(intToDWord(m_biSizeImage));
187: m_outputStream.write(intToDWord(m_biXPelsPerMeter));
188: m_outputStream.write(intToDWord(m_biYPelsPerMeter));
189: m_outputStream.write(intToDWord(m_biClrUsed));
190: m_outputStream.write(intToDWord(m_biClrImportant));
191: } catch (Exception wbih) {
192: wbih.printStackTrace();
193: }
194: }
195:
196: private byte[] intToWord(int parValue) {
197: byte retValue[] = new byte[2];
198: retValue[0] = (byte) (parValue & 0x00FF);
199: retValue[1] = (byte) ((parValue >> 8) & 0x00FF);
200: return (retValue);
201: }
202:
203: private byte[] intToDWord(int parValue) {
204: byte retValue[] = new byte[4];
205: retValue[0] = (byte) (parValue & 0x00FF);
206: retValue[1] = (byte) ((parValue >> 8) & 0x000000FF);
207: retValue[2] = (byte) ((parValue >> 16) & 0x000000FF);
208: retValue[3] = (byte) ((parValue >> 24) & 0x000000FF);
209: return (retValue);
210: }
211:
212: public static Image loadbitmap(InputStream fs) {
213: Image image;
214: try {
215: int bilen = 40;
216: byte bi[] = new byte[bilen];
217: fs.read(bi, 0, bilen);
218:
219: int nbisize = (((int) bi[3] & 0xff) << 24)
220: | (((int) bi[2] & 0xff) << 16)
221: | (((int) bi[1] & 0xff) << 8) | (int) bi[0] & 0xff;
222:
223: int nwidth = (((int) bi[7] & 0xff) << 24)
224: | (((int) bi[6] & 0xff) << 16)
225: | (((int) bi[5] & 0xff) << 8) | (int) bi[4] & 0xff;
226:
227: int nheight = (((int) bi[11] & 0xff) << 24)
228: | (((int) bi[10] & 0xff) << 16)
229: | (((int) bi[9] & 0xff) << 8) | (int) bi[8] & 0xff;
230:
231: int nplanes = (((int) bi[13] & 0xff) << 8) | (int) bi[12]
232: & 0xff;
233:
234: int nbitcount = (((int) bi[15] & 0xff) << 8) | (int) bi[14]
235: & 0xff;
236:
237: int ncompression = (((int) bi[19]) << 24)
238: | (((int) bi[18]) << 16) | (((int) bi[17]) << 8)
239: | (int) bi[16];
240:
241: int nsizeimage = (((int) bi[23] & 0xff) << 24)
242: | (((int) bi[22] & 0xff) << 16)
243: | (((int) bi[21] & 0xff) << 8) | (int) bi[20]
244: & 0xff;
245:
246: int nxpm = (((int) bi[27] & 0xff) << 24)
247: | (((int) bi[26] & 0xff) << 16)
248: | (((int) bi[25] & 0xff) << 8) | (int) bi[24]
249: & 0xff;
250:
251: int nypm = (((int) bi[31] & 0xff) << 24)
252: | (((int) bi[30] & 0xff) << 16)
253: | (((int) bi[29] & 0xff) << 8) | (int) bi[28]
254: & 0xff;
255:
256: int nclrused = (((int) bi[35] & 0xff) << 24)
257: | (((int) bi[34] & 0xff) << 16)
258: | (((int) bi[33] & 0xff) << 8) | (int) bi[32]
259: & 0xff;
260:
261: int nclrimp = (((int) bi[39] & 0xff) << 24)
262: | (((int) bi[38] & 0xff) << 16)
263: | (((int) bi[37] & 0xff) << 8) | (int) bi[36]
264: & 0xff;
265:
266: if (nbitcount == 24) {
267: int npad = (nsizeimage / nheight) - nwidth * 3;
268: int ndata[] = new int[nheight * nwidth];
269: byte brgb[] = new byte[(nwidth + npad) * 3 * nheight];
270: fs.read(brgb, 0, (nwidth + npad) * 3 * nheight);
271: int nindex = 0;
272: for (int j = 0; j < nheight; j++) {
273: for (int i = 0; i < nwidth; i++) {
274: ndata[nwidth * (nheight - j - 1) + i] = (255 & 0xff) << 24
275: | (((int) brgb[nindex + 2] & 0xff) << 16)
276: | (((int) brgb[nindex + 1] & 0xff) << 8)
277: | (int) brgb[nindex] & 0xff;
278: nindex += 3;
279: }
280:
281: nindex += npad;
282: }
283:
284: image = Toolkit.getDefaultToolkit().createImage(
285: new MemoryImageSource(nwidth, nheight, ndata,
286: 0, nwidth));
287: } else if (nbitcount == 16) {
288: int nNumColors = 0;
289: if (nclrused > 0) {
290: nNumColors = nclrused;
291: } else {
292: nNumColors = (1 & 0xff) << nbitcount;
293: }
294:
295: if (nsizeimage == 0) {
296: nsizeimage = ((((nwidth * nbitcount) + 31) & ~31) >> 3);
297: nsizeimage *= nheight;
298: }
299:
300: int npalette[] = new int[nNumColors];
301: byte bpalette[] = new byte[nNumColors * 4];
302: fs.read(bpalette, 0, nNumColors * 4);
303: int nindex8 = 0;
304: for (int n = 0; n < nNumColors; n++) {
305: npalette[n] = (255 & 0xff) << 24
306: | (((int) bpalette[nindex8 + 2] & 0xff) << 16)
307: | (((int) bpalette[nindex8 + 1] & 0xff) << 8)
308: | (int) bpalette[nindex8] & 0xff;
309: nindex8 += 4;
310: }
311:
312: int npad8 = (nsizeimage / nheight) - nwidth;
313: int ndata8[] = new int[nwidth * nheight];
314: byte bdata[] = new byte[(nwidth + npad8) * nheight];
315: fs.read(bdata, 0, (nwidth + npad8) * nheight);
316: nindex8 = 0;
317: for (int j8 = 0; j8 < nheight; j8++) {
318: for (int i8 = 0; i8 < nwidth; i8++) {
319: ndata8[nwidth * (nheight - j8 - 1) + i8] = npalette[((int) bdata[nindex8] & 0xff)]
320: | npalette[((int) bdata[nindex8 + 1] & 0xff)] << 8;
321: nindex8 += 2;
322: }
323:
324: nindex8 += npad8;
325: }
326:
327: image = Toolkit.getDefaultToolkit().createImage(
328: new MemoryImageSource(nwidth, nheight, ndata8,
329: 0, nwidth));
330: } else if (nbitcount == 8) {
331: int nNumColors = 0;
332: if (nclrused > 0) {
333: nNumColors = nclrused;
334: } else {
335: nNumColors = (1 & 0xff) << nbitcount;
336: }
337:
338: if (nsizeimage == 0) {
339: nsizeimage = ((((nwidth * nbitcount) + 31) & ~31) >> 3);
340: nsizeimage *= nheight;
341: }
342:
343: int npalette[] = new int[nNumColors];
344: byte bpalette[] = new byte[nNumColors * 4];
345: fs.read(bpalette, 0, nNumColors * 4);
346: int nindex8 = 0;
347: for (int n = 0; n < nNumColors; n++) {
348: npalette[n] = (255 & 0xff) << 24
349: | (((int) bpalette[nindex8 + 2] & 0xff) << 16)
350: | (((int) bpalette[nindex8 + 1] & 0xff) << 8)
351: | (int) bpalette[nindex8] & 0xff;
352: nindex8 += 4;
353: }
354:
355: int npad8 = (nsizeimage / nheight) - nwidth;
356: int ndata8[] = new int[nwidth * nheight];
357: byte bdata[] = new byte[(nwidth + npad8) * nheight];
358: fs.read(bdata, 0, (nwidth + npad8) * nheight);
359: nindex8 = 0;
360: for (int j8 = 0; j8 < nheight; j8++) {
361: for (int i8 = 0; i8 < nwidth; i8++) {
362: ndata8[nwidth * (nheight - j8 - 1) + i8] = npalette[((int) bdata[nindex8] & 0xff)];
363: nindex8++;
364: }
365:
366: nindex8 += npad8;
367: }
368:
369: image = Toolkit.getDefaultToolkit().createImage(
370: new MemoryImageSource(nwidth, nheight, ndata8,
371: 0, nwidth));
372: } else if (nbitcount == 4) {
373: int nNumColors = 0;
374: if (nclrused > 0) {
375: nNumColors = nclrused;
376: } else {
377: nNumColors = (1 & 0xff) << nbitcount;
378: }
379:
380: if (nsizeimage == 0) {
381: nsizeimage = ((((nwidth * nbitcount) + 31) & ~31) >> 3);
382: nsizeimage *= nheight;
383: }
384:
385: int npalette[] = new int[nNumColors + 1];
386: byte bpalette[] = new byte[nNumColors * 4];
387: fs.read(bpalette, 0, nNumColors * 4);
388: int nindex8 = 0;
389: for (int n = 0; n < nNumColors; n++) {
390: npalette[n] = (255 & 0xff) << 24
391: | (((int) bpalette[nindex8 + 2] & 0xff) << 16)
392: | (((int) bpalette[nindex8 + 1] & 0xff) << 8)
393: | (int) bpalette[nindex8] & 0xff;
394: nindex8 += 4;
395: }
396:
397: int npad8 = (nsizeimage * 2 / nheight) - nwidth;
398: if (npad8 == 4) {
399: npad8 = 0;
400: }
401:
402: int ndata8[] = new int[nwidth * nheight];
403: byte bdata[] = new byte[(nwidth / 2 + npad8) * nheight];
404: fs.read(bdata, 0, (nwidth / 2 + npad8) * nheight);//(nwidth) * nheight);
405: nindex8 = 0;
406: for (int j8 = 0; j8 < nheight; j8++) {
407: for (int i8 = 0; i8 < (nwidth) - 1; i8 += 2) {
408: ndata8[nwidth * (nheight - j8 - 1) + i8] = npalette[((int) (bdata[nindex8] & 0x0f))];
409: ndata8[nwidth * (nheight - j8 - 1) + i8 + 1] = npalette[((int) (bdata[nindex8] & 0xf0) / 0xf)];
410: System.out.print("1:" + (bdata[nindex8] & 0x0f)
411: + "\t");
412: System.out.print("2:"
413: + ((bdata[nindex8] & 0xf0) / 0xf)
414: + "\t");
415: nindex8++;
416: }
417:
418: //nindex8 += npad8;
419: }
420:
421: image = Toolkit.getDefaultToolkit().createImage(
422: new MemoryImageSource(nwidth, nheight, ndata8,
423: 0, nwidth));
424: } else {
425: image = null;
426: }
427:
428: fs.close();
429: return image;
430: } catch (Exception e) {
431: }
432:
433: return null;
434: }
435: }
|