1 package de.desy.acop.video.timageio;
2
3 import java.awt.Graphics2D;
4 import java.awt.Transparency;
5 import java.awt.color.ColorSpace;
6 import java.awt.image.BufferedImage;
7 import java.awt.image.ColorModel;
8 import java.awt.image.ComponentColorModel;
9 import java.awt.image.DataBuffer;
10 import java.awt.image.DataBufferByte;
11 import java.awt.image.DataBufferInt;
12 import java.awt.image.DataBufferUShort;
13 import java.awt.image.DirectColorModel;
14 import java.awt.image.Raster;
15 import java.awt.image.SampleModel;
16 import java.awt.image.WritableRaster;
17 import java.io.ByteArrayInputStream;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.util.Arrays;
21 import java.util.Hashtable;
22
23 import de.desy.acop.video.displayer.ColorMap;
24 import de.desy.acop.video.displayer.HuffmanDecompression;
25 import de.desy.acop.video.displayer.ImageFormat;
26 import de.desy.tine.types.IMAGE;
27 import de.desy.tine.types.IMAGE.FrameHeader;
28
29
30
31
32
33
34
35 public class TBufferedImage {
36
37
38
39
40 private BufferedImage bufferedImage;
41
42
43
44
45 private TImageMetadata tiMetadata;
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 public TBufferedImage(BufferedImage bufferedImage, TImageMetadata tiMetadata) {
61 if (bufferedImage == null)
62 throw new NullPointerException("bufferedImage == null!");
63 this.bufferedImage = bufferedImage;
64 this.tiMetadata = tiMetadata;
65 }
66
67
68
69
70
71
72
73
74 public TBufferedImage(IMAGE ti) {
75 this(TBufferedImage.toBufferedImage(ti), new TImageMetadata(ti));
76 }
77
78
79
80
81
82
83
84
85 public TBufferedImage(IMAGE ti, ColorMap colorMap, boolean normalize, boolean aoiExpansion) {
86 this(TBufferedImage.toBufferedImage(ti, colorMap, normalize, aoiExpansion), new TImageMetadata(ti));
87 }
88
89
90
91
92
93
94 public BufferedImage getBufferedImage() {
95 return bufferedImage;
96 }
97
98 public void setBufferedImage(BufferedImage image) {
99 this.bufferedImage = image;
100 }
101
102
103
104
105
106
107 public TImageMetadata getMetadata() {
108 return tiMetadata;
109 }
110
111
112
113
114
115
116
117 public void setMetadata(TImageMetadata metadata) {
118 this.tiMetadata = metadata;
119 }
120
121
122
123
124
125
126
127
128 public static BufferedImage toBufferedImage(IMAGE ti) {
129 return toBufferedImage(ti, null, false, false);
130 }
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148 public static BufferedImage toBufferedImage(IMAGE ti, ColorMap colorMap, boolean normalize, boolean aoiExpansion) {
149 return toBufferedImage(ti, colorMap, normalize, -1, -1, aoiExpansion);
150 }
151
152 public static BufferedImage toBufferedImage(IMAGE ti, ColorMap colorMap, boolean normalize, int min, int max,
153 boolean aoiExpansion) {
154 if (ti == null)
155 throw new NullPointerException("ti == null!");
156
157 BufferedImage destImage = null;
158
159 final FrameHeader frmHdr = ti.getFrameHeader();
160 if ((frmHdr.aoiWidth == -1 && frmHdr.aoiHeight != -1) || (frmHdr.aoiWidth != -1 && frmHdr.aoiHeight == -1))
161 throw new IllegalArgumentException("aoiWidth=" + frmHdr.aoiWidth + ", aoiHeight=" + frmHdr.aoiHeight);
162
163 final boolean isAOI = (frmHdr.aoiWidth != -1);
164
165 final ImageFormat format = ImageFormat.valueOf(frmHdr.imageFormat);
166 final int w = (isAOI ? frmHdr.aoiWidth : frmHdr.sourceWidth);
167 final int h = (isAOI ? frmHdr.aoiHeight : frmHdr.sourceHeight);
168 final int bpp = frmHdr.bytesPerPixel;
169 final int bits = frmHdr.effectiveBitsPerPixel;
170 final int appendedSize = frmHdr.appendedFrameSize;
171 final int wh = w * h;
172 byte[] byteArray = ti.getImageFrameBuffer();
173
174 if (bits < 8)
175 throw new IllegalArgumentException("bits=" + bits);
176 if (byteArray.length < appendedSize)
177 throw new IllegalArgumentException("format=" + format + ", size=" + appendedSize
178 + ", w=" + w + ", h=" + h + ", bpp=" + bpp + ", data.size=" + byteArray.length);
179
180 final Hashtable<?, ?> props = TImageMetadata.createProperties(ti);
181
182 switch (format) {
183 case IMAGE_FORMAT_GRAY:
184 if (appendedSize != wh * bpp)
185 throw new IllegalArgumentException("format=" + format + ", size=" + appendedSize
186 + ", w=" + w + ", h=" + h + ", bpp=" + bpp);
187
188 switch (bpp) {
189 case 1:
190
191 if (bits != 8)
192 throw new IllegalArgumentException("format=" + format + ", bits=" + bits);
193 if (normalize)
194 byteArray = normalizeGray(Arrays.copyOf(byteArray, wh),
195 min == -1 ? 0x0 : min, max == -1 ? 0xff : max);
196 if (colorMap == null || colorMap.equals(ColorMap.NONE))
197 destImage = createImageGray(w, h, bits, new DataBufferByte(byteArray, wh), props);
198 else
199 destImage = createImageIndexed(colorMap.getLUT(bits), w, h, new DataBufferByte(byteArray, wh),
200 props);
201 break;
202
203 case 2:
204
205 if (bits > 16)
206 throw new IllegalArgumentException("format=" + format + ", bits=" + bits);
207 short[] shortArray = createShortArray(byteArray, wh, bits);
208 if (normalize)
209 normalizeGray(shortArray, (1 << bits) - 1, min == -1 ? 0x0 : min, max == -1 ? 0xffff : max);
210
211 if (colorMap == null || ColorMap.NONE.equals(colorMap) || ColorMap.GRAYSCALE.equals(colorMap))
212
213 destImage = createImageGray(w, h, bits, new DataBufferUShort(shortArray, wh), props);
214 else
215
216 destImage = createImageIndexed(colorMap.getLUT(bits), w, h,
217 new DataBufferUShort(shortArray, wh), props);
218 break;
219
220 default:
221 throw new IllegalArgumentException("format=" + format + ", bpp=" + bpp);
222 }
223 break;
224
225 case IMAGE_FORMAT_RGB:
226
227 if (bpp != 3 || bits != 24)
228 throw new IllegalArgumentException("format=" + format + ", bpp=" + bpp + ", bits=" + bits);
229 if (appendedSize != wh * bpp)
230 throw new IllegalArgumentException("format=" + format + ", size=" + appendedSize
231 + ", w=" + w + ", h=" + h + ", bpp=" + bpp);
232 int[] intArray = createIntArray(byteArray, wh, bpp);
233 if (normalize)
234 normalizeRGB(intArray, min == -1 ? 0x0 : min, max == -1 ? 0xff : max);
235
236 destImage = createImageRGB(w, h, new DataBufferInt(intArray, wh), props);
237 break;
238
239 case IMAGE_FORMAT_RGBA:
240
241 if (bpp != 4 || bits != 32)
242 throw new IllegalArgumentException("format=" + format + ", bpp=" + bpp + ", bits=" + bits);
243 if (appendedSize != wh * bpp)
244 throw new IllegalArgumentException("format=" + format + ", size=" + appendedSize
245 + ", w=" + w + ", h=" + h + ", bpp=" + bpp);
246 intArray = createIntArray(byteArray, wh, bpp);
247 if (normalize)
248 normalizeRGB(intArray, min == -1 ? 0x0 : min, max == -1 ? 0xff : max);
249
250 destImage = createImageRGB(w, h, new DataBufferInt(intArray, wh), props);
251 break;
252
253 case IMAGE_FORMAT_HUFFYUV:
254
255 if (bpp != 1 || bits != 8)
256 throw new IllegalArgumentException("format=" + format + ", bpp=" + bpp + ", bits=" + bits);
257 if (frmHdr.sourceFormat != 0)
258 throw new IllegalArgumentException("format=" + format + ", srcFormat="
259 + ImageFormat.valueOf(frmHdr.sourceFormat));
260 byte[] compressed = Arrays.copyOf(byteArray, appendedSize);
261 byte[] uncompressed = new byte[wh * bpp];
262 HuffmanDecompression.decompressHuffYUV(compressed, 0, uncompressed, 0, uncompressed.length);
263 if (normalize)
264 normalizeGray(uncompressed, min == -1 ? 0x0 : min, max == -1 ? 0xff : max);
265 if (colorMap == null || colorMap.equals(ColorMap.NONE))
266 destImage = createImageGray(w, h, bits, new DataBufferByte(uncompressed, wh), props);
267 else
268 destImage = createImageIndexed(colorMap.getLUT(bits), w, h, new DataBufferByte(uncompressed, wh), props);
269 break;
270
271 case IMAGE_FORMAT_JPEG:
272
273
274
275 if ((bpp != 1 && bpp != 3) || (bpp == 1 && bits != 8) || (bpp == 3 && bits != 24))
276 throw new IllegalArgumentException("format=" + format + ", bpp=" + bpp + ", bits=" + bits);
277
278
279 BufferedImage bi = createImageJPEG(w, wh, Arrays.copyOf(byteArray, appendedSize), props);
280 switch (bi.getType()) {
281 case BufferedImage.TYPE_BYTE_GRAY:
282 byteArray = ((DataBufferByte) bi.getRaster().getDataBuffer()).getData();
283 if (normalize)
284 normalizeGray(byteArray, min == -1 ? 0x0 : min, max == -1 ? 0xff : max);
285 if (colorMap == null || colorMap.equals(ColorMap.NONE))
286 destImage = bi;
287 else
288 destImage = new BufferedImage(colorMap.getLUT(bits), bi.getRaster(), false, props);
289 break;
290
291 case BufferedImage.TYPE_3BYTE_BGR:
292 byteArray = ((DataBufferByte) bi.getRaster().getDataBuffer()).getData();
293 if (normalize)
294 normalizeBGR(byteArray, min == -1 ? 0x0 : min, max == -1 ? 0xff : max);
295
296 destImage = bi;
297 break;
298
299 case BufferedImage.TYPE_INT_RGB:
300 intArray = ((DataBufferInt) bi.getRaster().getDataBuffer()).getData();
301 if (normalize)
302 normalizeRGB(intArray, min == -1 ? 0x0 : min, max == -1 ? 0xff : max);
303
304 destImage = bi;
305 break;
306
307 default:
308 throw new IllegalArgumentException("Unsupported image format: " + bi.getType());
309 }
310 break;
311
312 default:
313 throw new IllegalArgumentException("tiFormat=" + format);
314 }
315 return (aoiExpansion && isAOI) ? expanseAOI(destImage, props) : destImage;
316 }
317
318
319
320
321
322
323
324
325 public static IMAGE toIMAGE(BufferedImage bi) {
326 return toIMAGE(bi, false);
327 }
328
329
330
331
332
333
334
335
336
337
338
339
340
341 @SuppressWarnings("deprecation")
342 public static IMAGE toIMAGE(BufferedImage bi, boolean rejectNonArchival) {
343 TImageMetadata tiMetadata = new TImageMetadata(bi, rejectNonArchival);
344 if (tiMetadata == null)
345 throw new NullPointerException("tiMetadata == null!");
346
347 IMAGE ti = new IMAGE(0);
348 tiMetadata.write(ti);
349 ti.setImageFrameBuffer(getData(bi));
350
351 return ti;
352 }
353
354
355
356
357
358
359 public IMAGE toIMAGE() {
360 return toIMAGE(bufferedImage);
361 }
362
363
364
365
366
367
368
369
370
371
372 public IMAGE toIMAGE(boolean rejectNonArchival) {
373 return toIMAGE(bufferedImage, rejectNonArchival);
374 }
375
376
377
378
379
380
381
382
383
384
385 public static boolean isSupported(int format) {
386 return ImageFormat.valueOf(format).isSupported();
387 }
388
389
390
391
392
393
394
395
396
397 public static boolean containsAOI(IMAGE ti) {
398 return (ti.getFrameHeader().aoiHeight != -1 || ti.getFrameHeader().aoiWidth != -1);
399 }
400
401
402
403
404
405
406
407
408
409
410 public static Hashtable<String, Object> getProperties(BufferedImage bi) {
411 String[] propertyNames = bi.getPropertyNames();
412 if (propertyNames == null)
413 return null;
414
415 Hashtable<String, Object> properties = new Hashtable<String, Object>(32);
416 for (int i = 0; i < propertyNames.length; i++) {
417 String name = propertyNames[i];
418 properties.put(name, bi.getProperty(name));
419 }
420 return properties;
421 }
422
423 private static BufferedImage createImageGray(int w, int h, int bits, DataBuffer db, Hashtable<?, ?> props) {
424 WritableRaster raster = Raster.createInterleavedRaster(db, w, h, w, 1, new int[] { 0 }, null);
425 ColorModel cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY),
426 new int[] { bits }, false, true, Transparency.OPAQUE, db.getDataType());
427 return new BufferedImage(cm, raster, false, props);
428 }
429
430 private static BufferedImage createImageIndexed(ColorModel cm, int w, int h, DataBuffer db, Hashtable<?, ?> props) {
431 WritableRaster raster = Raster.createInterleavedRaster(db, w, h, w, 1, new int[] { 0 }, null);
432 return new BufferedImage(cm, raster, false, props);
433 }
434
435 private static BufferedImage createImageRGB(int w, int h, DataBuffer db, Hashtable<?, ?> props) {
436 ColorModel cm = new DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x0);
437 SampleModel sm = cm.createCompatibleSampleModel(w, h);
438 WritableRaster raster = WritableRaster.createWritableRaster(sm, db, null);
439 return new BufferedImage(cm, raster, false, props);
440 }
441
442 private static BufferedImage expanseAOI(BufferedImage srcImage, Hashtable<?, ?> props) {
443 if (srcImage == null)
444 throw new NullPointerException("srcImage == null!");
445
446 int srcWidth = (Integer) props.get(TImageMetadata.KEY_SOURCE_WIDTH);
447 int srcHeight = (Integer) props.get(TImageMetadata.KEY_SOURCE_HEIGHT);
448 int xStart = (Integer) props.get(TImageMetadata.KEY_XSTART);
449 int yStart = (Integer) props.get(TImageMetadata.KEY_YSTART);
450
451 ColorModel cm = new DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x0);
452 WritableRaster raster = cm.createCompatibleWritableRaster(srcWidth, srcHeight);
453 BufferedImage bi = new BufferedImage(cm, raster, false, props);
454
455 Graphics2D g2d = bi.createGraphics();
456 g2d.drawImage(srcImage, xStart, yStart, null);
457 srcImage.flush();
458 g2d.dispose();
459
460 return bi;
461 }
462
463 private static BufferedImage createImageJPEG(int w, int h, byte[] dataArray, Hashtable<?, ?> properties) {
464
465 javax.imageio.ImageIO.setUseCache(false);
466
467 InputStream bis = new ByteArrayInputStream(dataArray);
468 BufferedImage bi;
469 try {
470 bi = javax.imageio.ImageIO.read(bis);
471
472 } catch (IOException e) {
473 throw new IllegalArgumentException(e);
474 } finally {
475 try {
476 bis.close();
477 } catch (IOException ignored) {
478 }
479 }
480 ColorModel cm = bi.getColorModel();
481 return new BufferedImage(cm, bi.getRaster(), cm.isAlphaPremultiplied(), properties);
482 }
483
484 private static short[] createShortArray(byte[] byteArray, int wh, int bits) {
485 final int maxValue = (1 << bits) - 1;
486 short[] shortArray = new short[wh];
487 for (int i = 0, j = 0; i < wh;) {
488 int gray0 = byteArray[j++] & 0xff;
489 int gray1 = byteArray[j++] & 0xff;
490 int pixel = ((gray1 << 8) | gray0);
491 if (pixel > maxValue)
492 throw new IllegalArgumentException("Invalid pixel at " + i + ": " + pixel);
493 shortArray[i++] = (short) pixel;
494 }
495 return shortArray;
496 }
497
498 private static int[] createIntArray(byte[] byteArray, int wh, int bpp) {
499 int[] intArray = new int[wh];
500 for (int i = 0, j = 0; i < wh; j += bpp) {
501 int red = byteArray[j] & 0xff;
502 int green = byteArray[j + 1] & 0xff;
503 int blue = byteArray[j + 2] & 0xff;
504 intArray[i++] = 0xff000000 | (red << 16) | (green << 8) | blue;
505 }
506 return intArray;
507 }
508
509 private static int[] getExtrema(byte[] array) {
510 int max = Byte.MIN_VALUE;
511 int min = Byte.MAX_VALUE;
512 for (int i : array) {
513 max = (max >= i) ? max : i;
514 min = (min <= i) ? min : i;
515 }
516 return (new int[] { min, max });
517 }
518
519 private static int[] getExtrema(short[] array) {
520 int max = Short.MIN_VALUE;
521 int min = Short.MAX_VALUE;
522 for (int i : array) {
523 max = (max >= i) ? max : i;
524 min = (min <= i) ? min : i;
525 }
526 return (new int[] { min, max });
527 }
528
529 private static int[] getExtrema(int[] array) {
530 int max = Integer.MIN_VALUE;
531 int min = Integer.MAX_VALUE;
532 for (int pixel : array) {
533 pixel = (int) (0.299 * ((pixel >> 16) & 0xff) + 0.587 * ((pixel >> 8) & 0xff) + 0.114 * (pixel & 0xff));
534 max = (max >= pixel) ? max : pixel;
535 min = (min <= pixel) ? min : pixel;
536 }
537 return (new int[] { min, max });
538 }
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558 private static byte[] normalizeGray(byte[] dataArray, final int lowest, final int highest) {
559
560 if (highest <= lowest)
561 throw new IllegalArgumentException(highest + " <= " + lowest);
562
563 final int[] extrema = getExtrema(dataArray);
564
565
566 if (extrema[0] == extrema[1])
567 return dataArray;
568
569 int min = Math.max(extrema[0], lowest);
570 int max = Math.min(extrema[1], highest);
571
572
573 double constant = 255D / (max - min);
574 double offset = constant * min;
575
576
577 int size = dataArray.length;
578 for (int i = 0, pixel; i < size; i++) {
579 pixel = (dataArray[i] & 0xff);
580 if (pixel < min)
581 pixel = min;
582 if (pixel > max)
583 pixel = max;
584 dataArray[i] = (byte) (constant * pixel - offset);
585 }
586 return dataArray;
587 }
588
589 private static short[] normalizeGray(short[] dataArray, int colors, int lowest, int highest) {
590 if (highest <= lowest)
591 throw new IllegalArgumentException(highest + " <= " + lowest);
592
593 final int[] extrema = getExtrema(dataArray);
594
595
596 if (extrema[0] == extrema[1])
597 return dataArray;
598
599 int min = Math.max(extrema[0], lowest);
600 int max = Math.min(extrema[1], Math.min(colors, highest));
601
602
603 double constant = 1D * colors / (max - min);
604 double offset = constant * min;
605
606
607 int size = dataArray.length;
608 for (int i = 0, pixel; i < size; i++) {
609 pixel = (dataArray[i] & colors);
610 if (pixel < min)
611 pixel = min;
612 if (pixel > max)
613 pixel = max;
614 dataArray[i] = (short) (constant * pixel - offset);
615 }
616 return dataArray;
617 }
618
619 private static int[] normalizeRGB(int[] dataArray, final int lowest, final int highest) {
620
621
622 final int[] extrema = getExtrema(dataArray);
623 int min = Math.max(extrema[0], lowest);
624 int max = Math.min(extrema[1], highest);
625
626
627 final double constant = 255D / (max - min);
628 final double offset = constant * min;
629
630
631 final int size = dataArray.length;
632 for (int i = 0, pixel; i < size; i++) {
633 pixel = dataArray[i];
634 int r = (pixel >> 16) & 0xff;
635 int g = (pixel >> 8) & 0xff;
636 int b = pixel & 0xff;
637
638 double dY = constant - (offset / (0.299 * r + 0.587 * g + 0.114 * b));
639 r *= dY;
640 g *= dY;
641 b *= dY;
642
643 if (r < 0)
644 r = 0;
645 if (g < 0)
646 g = 0;
647 if (b < 0)
648 b = 0;
649 if (r > 0xff)
650 r = 0xff;
651 if (g > 0xff)
652 g = 0xff;
653 if (b > 0xff)
654 b = 0xff;
655
656 dataArray[i] = 0xff000000 | (r << 16) | (g << 8) | (b);
657 }
658 return dataArray;
659 }
660
661 private static byte[] normalizeBGR(byte[] dataArray, int lowest, int highest) {
662
663 final int[] extrema = getExtrema(dataArray);
664 int min = Math.max(extrema[0], lowest);
665 int max = Math.min(extrema[1], highest);
666
667
668 final double constant = 255D / (max - min);
669 final double offset = constant * min;
670
671
672 final int size = dataArray.length;
673 for (int i = 0; i < size; i += 3) {
674 int r = (dataArray[i + 2] & 0xff);
675 int g = (dataArray[i + 1] & 0xff);
676 int b = (dataArray[i] & 0xff);
677
678 double dY = constant - (offset / (0.299 * r + 0.587 * g + 0.114 * b));
679 r *= dY;
680 g *= dY;
681 b *= dY;
682
683 if (r < 0)
684 r = 0;
685 if (g < 0)
686 g = 0;
687 if (b < 0)
688 b = 0;
689 if (r > 0xff)
690 r = 0xff;
691 if (g > 0xff)
692 g = 0xff;
693 if (b > 0xff)
694 b = 0xff;
695
696 dataArray[i + 2] = (byte) r;
697 dataArray[i + 1] = (byte) g;
698 dataArray[i] = (byte) b;
699 }
700 return dataArray;
701 }
702
703
704
705
706
707
708 private static byte[] getData(BufferedImage bi) {
709
710 final int[] intArray;
711 final short[] shortArray;
712 final byte[] byteArray;
713
714 final byte[] data;
715
716 int length;
717
718 final int imageType = bi.getType();
719
720 switch (imageType) {
721 case BufferedImage.TYPE_BYTE_GRAY:
722 return ((DataBufferByte) bi.getRaster().getDataBuffer()).getData();
723
724 case BufferedImage.TYPE_USHORT_GRAY:
725 shortArray = ((DataBufferUShort) bi.getRaster().getDataBuffer()).getData();
726 length = shortArray.length;
727 data = new byte[2 * length];
728 for (int i = 0, pos = 0; i < length; i++) {
729 data[pos++] = (byte) (shortArray[i]);
730 data[pos++] = (byte) (shortArray[i] >>> 8);
731 }
732 return data;
733
734 case BufferedImage.TYPE_INT_RGB:
735 case BufferedImage.TYPE_INT_ARGB:
736 intArray = ((DataBufferInt) bi.getRaster().getDataBuffer()).getData();
737 length = intArray.length;
738 data = new byte[3 * length];
739 for (int i = 0, pos = 0; i < length; i++) {
740 data[pos++] = (byte) (intArray[i] >>> 16);
741 data[pos++] = (byte) (intArray[i] >>> 8);
742 data[pos++] = (byte) (intArray[i] & 0xff);
743 }
744 return data;
745
746 case BufferedImage.TYPE_INT_BGR:
747 intArray = ((DataBufferInt) bi.getRaster().getDataBuffer()).getData();
748 length = intArray.length;
749 data = new byte[3 * length];
750 for (int i = 0, pos = 0; i < length; i++) {
751 data[pos++] = (byte) (intArray[i] & 0xff);
752 data[pos++] = (byte) (intArray[i] >>> 8);
753 data[pos++] = (byte) (intArray[i] >>> 16);
754 }
755 return data;
756
757 case BufferedImage.TYPE_3BYTE_BGR:
758 byteArray = ((DataBufferByte) bi.getRaster().getDataBuffer()).getData();
759 length = byteArray.length;
760 data = new byte[length];
761 for (int i = 0, pos = 0; pos < length; i += 3) {
762 data[pos++] = byteArray[i + 2];
763 data[pos++] = byteArray[i + 1];
764 data[pos++] = byteArray[i];
765 }
766 return data;
767
768 case BufferedImage.TYPE_4BYTE_ABGR:
769 byteArray = ((DataBufferByte) bi.getRaster().getDataBuffer()).getData();
770 length = byteArray.length / 4 * 3;
771 data = new byte[length];
772 for (int i = 0, pos = 0; pos < length; i += 4) {
773 data[pos++] = byteArray[i + 3];
774 data[pos++] = byteArray[i + 2];
775 data[pos++] = byteArray[i + 1];
776 }
777 return data;
778
779 default:
780 intArray = bi.getRGB(0, 0, bi.getWidth(), bi.getHeight(), null, 0, bi.getWidth());
781 length = intArray.length;
782 data = new byte[3 * length];
783 for (int i = 0, pos = 0; i < length; i++) {
784 data[pos++] = (byte) (intArray[i] >>> 16);
785 data[pos++] = (byte) (intArray[i] >>> 8);
786 data[pos++] = (byte) (intArray[i] & 0xff);
787 }
788 return data;
789 }
790 }
791
792 public static BufferedImage toImageRGB(BufferedImage src) {
793 final int type = src.getType();
794 if (type == BufferedImage.TYPE_INT_RGB)
795 return src;
796 BufferedImage dest = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_RGB);
797 dest.getGraphics().drawImage(src, 0, 0, null);
798 src.flush();
799 return dest;
800 }
801
802 }