1 /*
2 * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
61 import javax.imageio.event.IIOReadWarningListener;
62
63 import java.io.*;
64 import java.nio.*;
65 import java.security.AccessController;
66 import java.security.PrivilegedAction;
67 import java.util.ArrayList;
68 import java.util.Iterator;
69 import java.util.StringTokenizer;
70
71 import com.sun.imageio.plugins.common.ImageUtil;
72 import com.sun.imageio.plugins.common.I18N;
73
74 /** This class is the Java Image IO plugin reader for BMP images.
75 * It may subsample the image, clip the image, select sub-bands,
76 * and shift the decoded image origin if the proper decoding parameter
77 * are set in the provided {@code ImageReadParam}.
78 *
79 * This class supports Microsoft Windows Bitmap Version 3-5,
80 * as well as OS/2 Bitmap Version 2.x (for single-image BMP file).
81 */
82 public class BMPImageReader extends ImageReader implements BMPConstants {
83 // BMP Image types
84 private static final int VERSION_2_1_BIT = 0;
85 private static final int VERSION_2_4_BIT = 1;
86 private static final int VERSION_2_8_BIT = 2;
87 private static final int VERSION_2_24_BIT = 3;
88
89 private static final int VERSION_3_1_BIT = 4;
90 private static final int VERSION_3_4_BIT = 5;
91 private static final int VERSION_3_8_BIT = 6;
92 private static final int VERSION_3_24_BIT = 7;
93
94 private static final int VERSION_3_NT_16_BIT = 8;
95 private static final int VERSION_3_NT_32_BIT = 9;
96
97 private static final int VERSION_4_1_BIT = 10;
98 private static final int VERSION_4_4_BIT = 11;
99 private static final int VERSION_4_8_BIT = 12;
100 private static final int VERSION_4_16_BIT = 13;
101 private static final int VERSION_4_24_BIT = 14;
102 private static final int VERSION_4_32_BIT = 15;
103
104 private static final int VERSION_3_XP_EMBEDDED = 16;
105 private static final int VERSION_4_XP_EMBEDDED = 17;
106 private static final int VERSION_5_XP_EMBEDDED = 18;
107
108 // BMP variables
109 private long bitmapFileSize;
110 private long bitmapOffset;
111 private long bitmapStart;
112 private long compression;
113 private long imageSize;
114 private byte palette[];
115 private int imageType;
116 private int numBands;
117 private boolean isBottomUp;
118 private int bitsPerPixel;
119 private int redMask, greenMask, blueMask, alphaMask;
120
121 private SampleModel sampleModel, originalSampleModel;
122 private ColorModel colorModel, originalColorModel;
123
124 /** The input stream where reads from */
125 private ImageInputStream iis = null;
126
392 metadata.redMask = redMask;
393 metadata.greenMask = greenMask;
394 metadata.blueMask = blueMask;
395
396 if (colorsUsed != 0) {
397 // there is a palette
398 sizeOfPalette = (int)colorsUsed*4;
399 palette = new byte[sizeOfPalette];
400 iis.readFully(palette, 0, sizeOfPalette);
401
402 metadata.palette = palette;
403 metadata.paletteSize = (int)colorsUsed;
404 }
405 metadata.bmpVersion = VERSION_3_NT;
406
407 break;
408 default:
409 throw new
410 IIOException(I18N.getString("BMPImageReader2"));
411 }
412 } else if (size == 108 || size == 124) {
413 // Windows 4.x BMP
414 if (size == 108)
415 metadata.bmpVersion = VERSION_4;
416 else if (size == 124)
417 metadata.bmpVersion = VERSION_5;
418
419 // rgb masks, valid only if comp is BI_BITFIELDS
420 redMask = (int)iis.readUnsignedInt();
421 greenMask = (int)iis.readUnsignedInt();
422 blueMask = (int)iis.readUnsignedInt();
423 // Only supported for 32bpp BI_RGB argb
424 alphaMask = (int)iis.readUnsignedInt();
425 long csType = iis.readUnsignedInt();
426 int redX = iis.readInt();
427 int redY = iis.readInt();
428 int redZ = iis.readInt();
429 int greenX = iis.readInt();
430 int greenY = iis.readInt();
431 int greenZ = iis.readInt();
891 throw new
892 IIOException(I18N.getString("BMPImageReader1"));
893 }
894
895 break;
896
897 case VERSION_3_24_BIT:
898 // 24-bit images are not compressed
899 read24Bit(bdata);
900 break;
901
902 case VERSION_3_NT_16_BIT:
903 read16Bit(sdata);
904 break;
905
906 case VERSION_3_NT_32_BIT:
907 read32Bit(idata);
908 break;
909
910 case VERSION_3_XP_EMBEDDED:
911 case VERSION_4_XP_EMBEDDED:
912 case VERSION_5_XP_EMBEDDED:
913 bi = readEmbedded((int)compression, bi, param);
914 break;
915
916 case VERSION_4_1_BIT:
917 read1Bit(bdata);
918 break;
919
920 case VERSION_4_4_BIT:
921 switch((int)compression) {
922
923 case BI_RGB:
924 read4Bit(bdata);
925 break;
926
927 case BI_RLE4:
928 readRLE4(bdata);
929 break;
930
931 default:
932 throw new
933 IIOException(I18N.getString("BMPImageReader1"));
934 }
935 break;
936
937 case VERSION_4_8_BIT:
938 switch((int)compression) {
939
940 case BI_RGB:
941 read8Bit(bdata);
942 break;
943
944 case BI_RLE8:
945 readRLE8(bdata);
946 break;
947
948 default:
949 throw new
950 IIOException(I18N.getString("BMPImageReader1"));
951 }
952 break;
953
954 case VERSION_4_16_BIT:
955 read16Bit(sdata);
956 break;
957
958 case VERSION_4_24_BIT:
959 read24Bit(bdata);
960 break;
961
962 case VERSION_4_32_BIT:
963 read32Bit(idata);
964 break;
965 }
966
967 if (abortRequested())
968 processReadAborted();
969 else
970 processImageComplete();
971
972 return bi;
973 }
974
975 public boolean canReadRaster() {
976 return true;
977 }
978
979 public Raster readRaster(int imageIndex,
980 ImageReadParam param) throws IOException {
981 BufferedImage bi = read(imageIndex, param);
1983 if (p[0] == '/') p[0] = '\\';
1984 if (p[1] == '/') p[1] = '\\';
1985 if (p[3] == '/') p[3] = '\\';
1986
1987
1988 if ((p[0] == '\\') && (p[1] == '\\')) {
1989 if ((p[2] == '?') && (p[3] == '\\')) {
1990 // long path: whether unc or local
1991 return ((p[4] == 'U' || p[4] == 'u') &&
1992 (p[5] == 'N' || p[5] == 'n') &&
1993 (p[6] == 'C' || p[6] == 'c'));
1994 } else {
1995 // device path or short unc notation
1996 return true;
1997 }
1998 } else {
1999 return false;
2000 }
2001 }
2002 }
|
1 /*
2 * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
61 import javax.imageio.event.IIOReadWarningListener;
62
63 import java.io.*;
64 import java.nio.*;
65 import java.security.AccessController;
66 import java.security.PrivilegedAction;
67 import java.util.ArrayList;
68 import java.util.Iterator;
69 import java.util.StringTokenizer;
70
71 import com.sun.imageio.plugins.common.ImageUtil;
72 import com.sun.imageio.plugins.common.I18N;
73
74 /** This class is the Java Image IO plugin reader for BMP images.
75 * It may subsample the image, clip the image, select sub-bands,
76 * and shift the decoded image origin if the proper decoding parameter
77 * are set in the provided {@code ImageReadParam}.
78 *
79 * This class supports Microsoft Windows Bitmap Version 3-5,
80 * as well as OS/2 Bitmap Version 2.x (for single-image BMP file).
81 * It also supports undocumented DIB header of type BITMAPV2INFOHEADER
82 * & BITMAPV3INFOHEADER.
83 */
84 public class BMPImageReader extends ImageReader implements BMPConstants {
85 // BMP Image types
86 private static final int VERSION_2_1_BIT = 0;
87 private static final int VERSION_2_4_BIT = 1;
88 private static final int VERSION_2_8_BIT = 2;
89 private static final int VERSION_2_24_BIT = 3;
90
91 private static final int VERSION_3_1_BIT = 4;
92 private static final int VERSION_3_4_BIT = 5;
93 private static final int VERSION_3_8_BIT = 6;
94 private static final int VERSION_3_24_BIT = 7;
95
96 private static final int VERSION_3_NT_16_BIT = 8;
97 private static final int VERSION_3_NT_32_BIT = 9;
98
99 // All VERSION_3_EXT_* are for BITMAPV2INFOHEADER & BITMAPV3INFOHEADER
100 private static final int VERSION_3_EXT_1_BIT = 10;
101 private static final int VERSION_3_EXT_4_BIT = 11;
102 private static final int VERSION_3_EXT_8_BIT = 12;
103 private static final int VERSION_3_EXT_16_BIT = 13;
104 private static final int VERSION_3_EXT_24_BIT = 14;
105 private static final int VERSION_3_EXT_32_BIT = 15;
106
107 private static final int VERSION_4_1_BIT = 16;
108 private static final int VERSION_4_4_BIT = 17;
109 private static final int VERSION_4_8_BIT = 18;
110 private static final int VERSION_4_16_BIT = 19;
111 private static final int VERSION_4_24_BIT = 20;
112 private static final int VERSION_4_32_BIT = 21;
113
114 private static final int VERSION_3_XP_EMBEDDED = 22;
115 private static final int VERSION_3_EXT_EMBEDDED = 23;
116 private static final int VERSION_4_XP_EMBEDDED = 24;
117 private static final int VERSION_5_XP_EMBEDDED = 25;
118
119 // BMP variables
120 private long bitmapFileSize;
121 private long bitmapOffset;
122 private long bitmapStart;
123 private long compression;
124 private long imageSize;
125 private byte palette[];
126 private int imageType;
127 private int numBands;
128 private boolean isBottomUp;
129 private int bitsPerPixel;
130 private int redMask, greenMask, blueMask, alphaMask;
131
132 private SampleModel sampleModel, originalSampleModel;
133 private ColorModel colorModel, originalColorModel;
134
135 /** The input stream where reads from */
136 private ImageInputStream iis = null;
137
403 metadata.redMask = redMask;
404 metadata.greenMask = greenMask;
405 metadata.blueMask = blueMask;
406
407 if (colorsUsed != 0) {
408 // there is a palette
409 sizeOfPalette = (int)colorsUsed*4;
410 palette = new byte[sizeOfPalette];
411 iis.readFully(palette, 0, sizeOfPalette);
412
413 metadata.palette = palette;
414 metadata.paletteSize = (int)colorsUsed;
415 }
416 metadata.bmpVersion = VERSION_3_NT;
417
418 break;
419 default:
420 throw new
421 IIOException(I18N.getString("BMPImageReader2"));
422 }
423 } else if (size == 52 || size == 56) {
424 // BITMAPV2INFOHEADER or BITMAPV3INFOHEADER
425 redMask = (int)iis.readUnsignedInt();
426 greenMask = (int)iis.readUnsignedInt();
427 blueMask = (int)iis.readUnsignedInt();
428 if (size == 56) {
429 alphaMask = (int)iis.readUnsignedInt();
430 }
431
432 metadata.bmpVersion = VERSION_3_EXT;
433 // Read in the palette
434 int numberOfEntries = (int)((bitmapOffset-14-size) / 4);
435 int sizeOfPalette = numberOfEntries*4;
436 palette = new byte[sizeOfPalette];
437 iis.readFully(palette, 0, sizeOfPalette);
438 metadata.palette = palette;
439 metadata.paletteSize = numberOfEntries;
440
441 switch((int)compression) {
442
443 case BI_JPEG:
444 case BI_PNG:
445 imageType = VERSION_3_EXT_EMBEDDED;
446 break;
447 default:
448 if (bitsPerPixel == 1) {
449 imageType = VERSION_3_EXT_1_BIT;
450 } else if (bitsPerPixel == 4) {
451 imageType = VERSION_3_EXT_4_BIT;
452 } else if (bitsPerPixel == 8) {
453 imageType = VERSION_3_EXT_8_BIT;
454 } else if (bitsPerPixel == 16) {
455 imageType = VERSION_3_EXT_16_BIT;
456 if ((int)compression == BI_RGB) {
457 redMask = 0x7C00;
458 greenMask = 0x3E0;
459 blueMask = 0x1F;
460 }
461 } else if (bitsPerPixel == 24) {
462 imageType = VERSION_3_EXT_24_BIT;
463 } else if (bitsPerPixel == 32) {
464 imageType = VERSION_3_EXT_32_BIT;
465 if ((int)compression == BI_RGB) {
466 redMask = 0x00FF0000;
467 greenMask = 0x0000FF00;
468 blueMask = 0x000000FF;
469 }
470 } else {
471 throw new
472 IIOException(I18N.getString("BMPImageReader8"));
473 }
474
475 metadata.redMask = redMask;
476 metadata.greenMask = greenMask;
477 metadata.blueMask = blueMask;
478 metadata.alphaMask = alphaMask;
479 }
480 } else if (size == 108 || size == 124) {
481 // Windows 4.x BMP
482 if (size == 108)
483 metadata.bmpVersion = VERSION_4;
484 else if (size == 124)
485 metadata.bmpVersion = VERSION_5;
486
487 // rgb masks, valid only if comp is BI_BITFIELDS
488 redMask = (int)iis.readUnsignedInt();
489 greenMask = (int)iis.readUnsignedInt();
490 blueMask = (int)iis.readUnsignedInt();
491 // Only supported for 32bpp BI_RGB argb
492 alphaMask = (int)iis.readUnsignedInt();
493 long csType = iis.readUnsignedInt();
494 int redX = iis.readInt();
495 int redY = iis.readInt();
496 int redZ = iis.readInt();
497 int greenX = iis.readInt();
498 int greenY = iis.readInt();
499 int greenZ = iis.readInt();
959 throw new
960 IIOException(I18N.getString("BMPImageReader1"));
961 }
962
963 break;
964
965 case VERSION_3_24_BIT:
966 // 24-bit images are not compressed
967 read24Bit(bdata);
968 break;
969
970 case VERSION_3_NT_16_BIT:
971 read16Bit(sdata);
972 break;
973
974 case VERSION_3_NT_32_BIT:
975 read32Bit(idata);
976 break;
977
978 case VERSION_3_XP_EMBEDDED:
979 case VERSION_3_EXT_EMBEDDED:
980 case VERSION_4_XP_EMBEDDED:
981 case VERSION_5_XP_EMBEDDED:
982 bi = readEmbedded((int)compression, bi, param);
983 break;
984
985 case VERSION_3_EXT_1_BIT:
986 case VERSION_4_1_BIT:
987 read1Bit(bdata);
988 break;
989
990 case VERSION_3_EXT_4_BIT:
991 case VERSION_4_4_BIT:
992 switch((int)compression) {
993
994 case BI_RGB:
995 read4Bit(bdata);
996 break;
997
998 case BI_RLE4:
999 readRLE4(bdata);
1000 break;
1001
1002 default:
1003 throw new
1004 IIOException(I18N.getString("BMPImageReader1"));
1005 }
1006 break;
1007
1008 case VERSION_3_EXT_8_BIT:
1009 case VERSION_4_8_BIT:
1010 switch((int)compression) {
1011
1012 case BI_RGB:
1013 read8Bit(bdata);
1014 break;
1015
1016 case BI_RLE8:
1017 readRLE8(bdata);
1018 break;
1019
1020 default:
1021 throw new
1022 IIOException(I18N.getString("BMPImageReader1"));
1023 }
1024 break;
1025
1026 case VERSION_3_EXT_16_BIT:
1027 case VERSION_4_16_BIT:
1028 read16Bit(sdata);
1029 break;
1030
1031 case VERSION_3_EXT_24_BIT:
1032 case VERSION_4_24_BIT:
1033 read24Bit(bdata);
1034 break;
1035
1036 case VERSION_3_EXT_32_BIT:
1037 case VERSION_4_32_BIT:
1038 read32Bit(idata);
1039 break;
1040 }
1041
1042 if (abortRequested())
1043 processReadAborted();
1044 else
1045 processImageComplete();
1046
1047 return bi;
1048 }
1049
1050 public boolean canReadRaster() {
1051 return true;
1052 }
1053
1054 public Raster readRaster(int imageIndex,
1055 ImageReadParam param) throws IOException {
1056 BufferedImage bi = read(imageIndex, param);
2058 if (p[0] == '/') p[0] = '\\';
2059 if (p[1] == '/') p[1] = '\\';
2060 if (p[3] == '/') p[3] = '\\';
2061
2062
2063 if ((p[0] == '\\') && (p[1] == '\\')) {
2064 if ((p[2] == '?') && (p[3] == '\\')) {
2065 // long path: whether unc or local
2066 return ((p[4] == 'U' || p[4] == 'u') &&
2067 (p[5] == 'N' || p[5] == 'n') &&
2068 (p[6] == 'C' || p[6] == 'c'));
2069 } else {
2070 // device path or short unc notation
2071 return true;
2072 }
2073 } else {
2074 return false;
2075 }
2076 }
2077 }
2078
|