160 * defined 161 */ 162 private boolean noTransform = true; 163 164 /** Indicates whether subband is selected. */ 165 private boolean seleBand = false; 166 167 /** The scaling factors. */ 168 private int scaleX, scaleY; 169 170 /** source and destination bands. */ 171 private int[] sourceBands, destBands; 172 173 /** Constructs {@code BMPImageReader} from the provided 174 * {@code ImageReaderSpi}. 175 */ 176 public BMPImageReader(ImageReaderSpi originator) { 177 super(originator); 178 } 179 180 /** Overrides the method defined in the superclass. */ 181 public void setInput(Object input, 182 boolean seekForwardOnly, 183 boolean ignoreMetadata) { 184 super.setInput(input, seekForwardOnly, ignoreMetadata); 185 iis = (ImageInputStream) input; // Always works 186 if(iis != null) 187 iis.setByteOrder(ByteOrder.LITTLE_ENDIAN); 188 resetHeaderInfo(); 189 } 190 191 /** Overrides the method defined in the superclass. */ 192 public int getNumImages(boolean allowSearch) throws IOException { 193 if (iis == null) { 194 throw new IllegalStateException(I18N.getString("GetNumImages0")); 195 } 196 if (seekForwardOnly && allowSearch) { 197 throw new IllegalStateException(I18N.getString("GetNumImages1")); 198 } 199 return 1; 200 } 201 202 @Override 203 public int getWidth(int imageIndex) throws IOException { 204 checkIndex(imageIndex); 205 try { 206 readHeader(); 207 } catch (IllegalArgumentException e) { 208 throw new IIOException(I18N.getString("BMPImageReader6"), e); 209 } 210 return width; 211 } 212 213 public int getHeight(int imageIndex) throws IOException { 214 checkIndex(imageIndex); 215 try { 216 readHeader(); 217 } catch (IllegalArgumentException e) { 218 throw new IIOException(I18N.getString("BMPImageReader6"), e); 219 } 220 return height; 221 } 222 223 private void checkIndex(int imageIndex) { 224 if (imageIndex != 0) { 225 throw new IndexOutOfBoundsException(I18N.getString("BMPImageReader0")); 226 } 227 } 228 229 /** 230 * Process the image header. 231 * 232 * @exception IllegalStateException if source stream is not set. 745 numBands, 746 numBands * width, 747 bandOffsets); 748 749 colorModel = 750 ImageUtil.createColorModel(colorSpace, sampleModel); 751 } 752 753 originalSampleModel = sampleModel; 754 originalColorModel = colorModel; 755 756 // Reset to the start of bitmap; then jump to the 757 //start of image data 758 iis.reset(); 759 iis.skipBytes(bitmapOffset); 760 bitmapStart = iis.getStreamPosition(); 761 762 gotHeader = true; 763 } 764 765 public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) 766 throws IOException { 767 checkIndex(imageIndex); 768 try { 769 readHeader(); 770 } catch (IllegalArgumentException e) { 771 throw new IIOException(I18N.getString("BMPImageReader6"), e); 772 } 773 ArrayList<ImageTypeSpecifier> list = new ArrayList<>(1); 774 list.add(new ImageTypeSpecifier(originalColorModel, 775 originalSampleModel)); 776 return list.iterator(); 777 } 778 779 public ImageReadParam getDefaultReadParam() { 780 return new ImageReadParam(); 781 } 782 783 public IIOMetadata getImageMetadata(int imageIndex) 784 throws IOException { 785 checkIndex(imageIndex); 786 if (metadata == null) { 787 try { 788 readHeader(); 789 } catch (IllegalArgumentException e) { 790 throw new IIOException(I18N.getString("BMPImageReader6"), e); 791 } 792 } 793 return metadata; 794 } 795 796 public IIOMetadata getStreamMetadata() throws IOException { 797 return null; 798 } 799 800 public boolean isRandomAccessEasy(int imageIndex) throws IOException { 801 checkIndex(imageIndex); 802 try { 803 readHeader(); 804 } catch (IllegalArgumentException e) { 805 throw new IIOException(I18N.getString("BMPImageReader6"), e); 806 } 807 return metadata.compression == BI_RGB; 808 } 809 810 public BufferedImage read(int imageIndex, ImageReadParam param) 811 throws IOException { 812 813 if (iis == null) { 814 throw new IllegalStateException(I18N.getString("BMPImageReader5")); 815 } 816 817 checkIndex(imageIndex); 818 clearAbortRequest(); 819 processImageStarted(imageIndex); 820 if (abortRequested()) { 821 processReadAborted(); 822 return bi; 823 } 824 825 if (param == null) 826 param = getDefaultReadParam(); 827 828 //read header 829 try { 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); 1057 return bi.getData(); 1058 } 1059 1060 private void resetHeaderInfo() { 1061 gotHeader = false; 1062 bi = null; 1063 sampleModel = originalSampleModel = null; 1064 colorModel = originalColorModel = null; 1065 } 1066 1067 public void reset() { 1068 super.reset(); 1069 iis = null; 1070 resetHeaderInfo(); 1071 } 1072 1073 // Deal with 1 Bit images using IndexColorModels 1074 private void read1Bit(byte[] bdata) throws IOException { 1075 int bytesPerScanline = (width + 7) / 8; 1076 int padding = bytesPerScanline % 4; 1077 if (padding != 0) { 1078 padding = 4 - padding; 1079 } 1080 1081 int lineLength = bytesPerScanline + padding; 1082 1083 if (noTransform) { 1084 int j = isBottomUp ? (height -1)*bytesPerScanline : 0; 1085 1086 for (int i=0; i<height; i++) { 1907 } 1908 ImageReader reader = 1909 ImageIO.getImageReadersByFormatName(format).next(); 1910 if (reader == null) { 1911 throw new RuntimeException(I18N.getString("BMPImageReader4") + 1912 " " + format); 1913 } 1914 // prepare input 1915 byte[] buff = new byte[(int)imageSize]; 1916 iis.read(buff); 1917 reader.setInput(ImageIO.createImageInputStream(new ByteArrayInputStream(buff))); 1918 if (bi == null) { 1919 ImageTypeSpecifier embType = reader.getImageTypes(0).next(); 1920 bi = embType.createBufferedImage(destinationRegion.x + 1921 destinationRegion.width, 1922 destinationRegion.y + 1923 destinationRegion.height); 1924 } 1925 1926 reader.addIIOReadProgressListener(new EmbeddedProgressAdapter() { 1927 public void imageProgress(ImageReader source, 1928 float percentageDone) 1929 { 1930 processImageProgress(percentageDone); 1931 } 1932 }); 1933 1934 reader.addIIOReadUpdateListener(new IIOReadUpdateListener() { 1935 public void imageUpdate(ImageReader source, 1936 BufferedImage theImage, 1937 int minX, int minY, 1938 int width, int height, 1939 int periodX, int periodY, 1940 int[] bands) 1941 { 1942 processImageUpdate(theImage, minX, minY, 1943 width, height, 1944 periodX, periodY, bands); 1945 } 1946 public void passComplete(ImageReader source, 1947 BufferedImage theImage) 1948 { 1949 processPassComplete(theImage); 1950 } 1951 public void passStarted(ImageReader source, 1952 BufferedImage theImage, 1953 int pass, 1954 int minPass, int maxPass, 1955 int minX, int minY, 1956 int periodX, int periodY, 1957 int[] bands) 1958 { 1959 processPassStarted(theImage, pass, minPass, maxPass, 1960 minX, minY, periodX, periodY, 1961 bands); 1962 } 1963 public void thumbnailPassComplete(ImageReader source, 1964 BufferedImage thumb) {} 1965 public void thumbnailPassStarted(ImageReader source, 1966 BufferedImage thumb, 1967 int pass, 1968 int minPass, int maxPass, 1969 int minX, int minY, 1970 int periodX, int periodY, 1971 int[] bands) {} 1972 public void thumbnailUpdate(ImageReader source, 1973 BufferedImage theThumbnail, 1974 int minX, int minY, 1975 int width, int height, 1976 int periodX, int periodY, 1977 int[] bands) {} 1978 }); 1979 1980 reader.addIIOReadWarningListener(new IIOReadWarningListener() { 1981 public void warningOccurred(ImageReader source, String warning) 1982 { 1983 processWarningOccurred(warning); 1984 } 1985 }); 1986 1987 ImageReadParam param = reader.getDefaultReadParam(); 1988 param.setDestination(bi); 1989 param.setDestinationBands(bmpParam.getDestinationBands()); 1990 param.setDestinationOffset(bmpParam.getDestinationOffset()); 1991 param.setSourceBands(bmpParam.getSourceBands()); 1992 param.setSourceRegion(bmpParam.getSourceRegion()); 1993 param.setSourceSubsampling(bmpParam.getSourceXSubsampling(), 1994 bmpParam.getSourceYSubsampling(), 1995 bmpParam.getSubsamplingXOffset(), 1996 bmpParam.getSubsamplingYOffset()); 1997 reader.read(0, param); 1998 return bi; 1999 } 2000 2001 private class EmbeddedProgressAdapter implements IIOReadProgressListener { 2002 public void imageComplete(ImageReader src) {} 2003 public void imageProgress(ImageReader src, float percentageDone) {} 2004 public void imageStarted(ImageReader src, int imageIndex) {} 2005 public void thumbnailComplete(ImageReader src) {} 2006 public void thumbnailProgress(ImageReader src, float percentageDone) {} 2007 public void thumbnailStarted(ImageReader src, int iIdx, int tIdx) {} 2008 public void sequenceComplete(ImageReader src) {} 2009 public void sequenceStarted(ImageReader src, int minIndex) {} 2010 public void readAborted(ImageReader src) {} 2011 } 2012 2013 private static Boolean isLinkedProfileDisabled = null; 2014 2015 private static boolean isLinkedProfileAllowed() { 2016 if (isLinkedProfileDisabled == null) { 2017 PrivilegedAction<Boolean> a = new PrivilegedAction<Boolean>() { 2018 public Boolean run() { 2019 return Boolean.getBoolean("sun.imageio.plugins.bmp.disableLinkedProfiles"); 2020 } 2021 }; 2022 isLinkedProfileDisabled = AccessController.doPrivileged(a); 2023 } 2024 return !isLinkedProfileDisabled; 2025 } 2026 2027 private static Boolean isWindowsPlatform = null; 2028 2029 /** | 160 * defined 161 */ 162 private boolean noTransform = true; 163 164 /** Indicates whether subband is selected. */ 165 private boolean seleBand = false; 166 167 /** The scaling factors. */ 168 private int scaleX, scaleY; 169 170 /** source and destination bands. */ 171 private int[] sourceBands, destBands; 172 173 /** Constructs {@code BMPImageReader} from the provided 174 * {@code ImageReaderSpi}. 175 */ 176 public BMPImageReader(ImageReaderSpi originator) { 177 super(originator); 178 } 179 180 @Override 181 public void setInput(Object input, 182 boolean seekForwardOnly, 183 boolean ignoreMetadata) { 184 super.setInput(input, seekForwardOnly, ignoreMetadata); 185 iis = (ImageInputStream) input; // Always works 186 if(iis != null) 187 iis.setByteOrder(ByteOrder.LITTLE_ENDIAN); 188 resetHeaderInfo(); 189 } 190 191 @Override 192 public int getNumImages(boolean allowSearch) throws IOException { 193 if (iis == null) { 194 throw new IllegalStateException(I18N.getString("GetNumImages0")); 195 } 196 if (seekForwardOnly && allowSearch) { 197 throw new IllegalStateException(I18N.getString("GetNumImages1")); 198 } 199 return 1; 200 } 201 202 @Override 203 public int getWidth(int imageIndex) throws IOException { 204 checkIndex(imageIndex); 205 try { 206 readHeader(); 207 } catch (IllegalArgumentException e) { 208 throw new IIOException(I18N.getString("BMPImageReader6"), e); 209 } 210 return width; 211 } 212 213 @Override 214 public int getHeight(int imageIndex) throws IOException { 215 checkIndex(imageIndex); 216 try { 217 readHeader(); 218 } catch (IllegalArgumentException e) { 219 throw new IIOException(I18N.getString("BMPImageReader6"), e); 220 } 221 return height; 222 } 223 224 private void checkIndex(int imageIndex) { 225 if (imageIndex != 0) { 226 throw new IndexOutOfBoundsException(I18N.getString("BMPImageReader0")); 227 } 228 } 229 230 /** 231 * Process the image header. 232 * 233 * @exception IllegalStateException if source stream is not set. 746 numBands, 747 numBands * width, 748 bandOffsets); 749 750 colorModel = 751 ImageUtil.createColorModel(colorSpace, sampleModel); 752 } 753 754 originalSampleModel = sampleModel; 755 originalColorModel = colorModel; 756 757 // Reset to the start of bitmap; then jump to the 758 //start of image data 759 iis.reset(); 760 iis.skipBytes(bitmapOffset); 761 bitmapStart = iis.getStreamPosition(); 762 763 gotHeader = true; 764 } 765 766 @Override 767 public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex) 768 throws IOException { 769 checkIndex(imageIndex); 770 try { 771 readHeader(); 772 } catch (IllegalArgumentException e) { 773 throw new IIOException(I18N.getString("BMPImageReader6"), e); 774 } 775 ArrayList<ImageTypeSpecifier> list = new ArrayList<>(1); 776 list.add(new ImageTypeSpecifier(originalColorModel, 777 originalSampleModel)); 778 return list.iterator(); 779 } 780 781 @Override 782 public ImageReadParam getDefaultReadParam() { 783 return new ImageReadParam(); 784 } 785 786 @Override 787 public IIOMetadata getImageMetadata(int imageIndex) 788 throws IOException { 789 checkIndex(imageIndex); 790 if (metadata == null) { 791 try { 792 readHeader(); 793 } catch (IllegalArgumentException e) { 794 throw new IIOException(I18N.getString("BMPImageReader6"), e); 795 } 796 } 797 return metadata; 798 } 799 800 @Override 801 public IIOMetadata getStreamMetadata() throws IOException { 802 return null; 803 } 804 805 @Override 806 public boolean isRandomAccessEasy(int imageIndex) throws IOException { 807 checkIndex(imageIndex); 808 try { 809 readHeader(); 810 } catch (IllegalArgumentException e) { 811 throw new IIOException(I18N.getString("BMPImageReader6"), e); 812 } 813 return metadata.compression == BI_RGB; 814 } 815 816 @Override 817 public BufferedImage read(int imageIndex, ImageReadParam param) 818 throws IOException { 819 820 if (iis == null) { 821 throw new IllegalStateException(I18N.getString("BMPImageReader5")); 822 } 823 824 checkIndex(imageIndex); 825 clearAbortRequest(); 826 processImageStarted(imageIndex); 827 if (abortRequested()) { 828 processReadAborted(); 829 return bi; 830 } 831 832 if (param == null) 833 param = getDefaultReadParam(); 834 835 //read header 836 try { 1037 1038 case VERSION_3_EXT_24_BIT: 1039 case VERSION_4_24_BIT: 1040 read24Bit(bdata); 1041 break; 1042 1043 case VERSION_3_EXT_32_BIT: 1044 case VERSION_4_32_BIT: 1045 read32Bit(idata); 1046 break; 1047 } 1048 1049 if (abortRequested()) 1050 processReadAborted(); 1051 else 1052 processImageComplete(); 1053 1054 return bi; 1055 } 1056 1057 @Override 1058 public boolean canReadRaster() { 1059 return true; 1060 } 1061 1062 @Override 1063 public Raster readRaster(int imageIndex, 1064 ImageReadParam param) throws IOException { 1065 BufferedImage bi = read(imageIndex, param); 1066 return bi.getData(); 1067 } 1068 1069 private void resetHeaderInfo() { 1070 gotHeader = false; 1071 bi = null; 1072 sampleModel = originalSampleModel = null; 1073 colorModel = originalColorModel = null; 1074 } 1075 1076 @Override 1077 public void reset() { 1078 super.reset(); 1079 iis = null; 1080 resetHeaderInfo(); 1081 } 1082 1083 // Deal with 1 Bit images using IndexColorModels 1084 private void read1Bit(byte[] bdata) throws IOException { 1085 int bytesPerScanline = (width + 7) / 8; 1086 int padding = bytesPerScanline % 4; 1087 if (padding != 0) { 1088 padding = 4 - padding; 1089 } 1090 1091 int lineLength = bytesPerScanline + padding; 1092 1093 if (noTransform) { 1094 int j = isBottomUp ? (height -1)*bytesPerScanline : 0; 1095 1096 for (int i=0; i<height; i++) { 1917 } 1918 ImageReader reader = 1919 ImageIO.getImageReadersByFormatName(format).next(); 1920 if (reader == null) { 1921 throw new RuntimeException(I18N.getString("BMPImageReader4") + 1922 " " + format); 1923 } 1924 // prepare input 1925 byte[] buff = new byte[(int)imageSize]; 1926 iis.read(buff); 1927 reader.setInput(ImageIO.createImageInputStream(new ByteArrayInputStream(buff))); 1928 if (bi == null) { 1929 ImageTypeSpecifier embType = reader.getImageTypes(0).next(); 1930 bi = embType.createBufferedImage(destinationRegion.x + 1931 destinationRegion.width, 1932 destinationRegion.y + 1933 destinationRegion.height); 1934 } 1935 1936 reader.addIIOReadProgressListener(new EmbeddedProgressAdapter() { 1937 @Override 1938 public void imageProgress(ImageReader source, 1939 float percentageDone) 1940 { 1941 processImageProgress(percentageDone); 1942 } 1943 }); 1944 1945 reader.addIIOReadUpdateListener(new IIOReadUpdateListener() { 1946 @Override 1947 public void imageUpdate(ImageReader source, 1948 BufferedImage theImage, 1949 int minX, int minY, 1950 int width, int height, 1951 int periodX, int periodY, 1952 int[] bands) 1953 { 1954 processImageUpdate(theImage, minX, minY, 1955 width, height, 1956 periodX, periodY, bands); 1957 } 1958 @Override 1959 public void passComplete(ImageReader source, 1960 BufferedImage theImage) 1961 { 1962 processPassComplete(theImage); 1963 } 1964 @Override 1965 public void passStarted(ImageReader source, 1966 BufferedImage theImage, 1967 int pass, 1968 int minPass, int maxPass, 1969 int minX, int minY, 1970 int periodX, int periodY, 1971 int[] bands) 1972 { 1973 processPassStarted(theImage, pass, minPass, maxPass, 1974 minX, minY, periodX, periodY, 1975 bands); 1976 } 1977 @Override 1978 public void thumbnailPassComplete(ImageReader source, 1979 BufferedImage thumb) {} 1980 @Override 1981 public void thumbnailPassStarted(ImageReader source, 1982 BufferedImage thumb, 1983 int pass, 1984 int minPass, int maxPass, 1985 int minX, int minY, 1986 int periodX, int periodY, 1987 int[] bands) {} 1988 @Override 1989 public void thumbnailUpdate(ImageReader source, 1990 BufferedImage theThumbnail, 1991 int minX, int minY, 1992 int width, int height, 1993 int periodX, int periodY, 1994 int[] bands) {} 1995 }); 1996 1997 reader.addIIOReadWarningListener(new IIOReadWarningListener() { 1998 @Override 1999 public void warningOccurred(ImageReader source, String warning) 2000 { 2001 processWarningOccurred(warning); 2002 } 2003 }); 2004 2005 ImageReadParam param = reader.getDefaultReadParam(); 2006 param.setDestination(bi); 2007 param.setDestinationBands(bmpParam.getDestinationBands()); 2008 param.setDestinationOffset(bmpParam.getDestinationOffset()); 2009 param.setSourceBands(bmpParam.getSourceBands()); 2010 param.setSourceRegion(bmpParam.getSourceRegion()); 2011 param.setSourceSubsampling(bmpParam.getSourceXSubsampling(), 2012 bmpParam.getSourceYSubsampling(), 2013 bmpParam.getSubsamplingXOffset(), 2014 bmpParam.getSubsamplingYOffset()); 2015 reader.read(0, param); 2016 return bi; 2017 } 2018 2019 private class EmbeddedProgressAdapter implements IIOReadProgressListener { 2020 @Override 2021 public void imageComplete(ImageReader src) {} 2022 @Override 2023 public void imageProgress(ImageReader src, float percentageDone) {} 2024 @Override 2025 public void imageStarted(ImageReader src, int imageIndex) {} 2026 @Override 2027 public void thumbnailComplete(ImageReader src) {} 2028 @Override 2029 public void thumbnailProgress(ImageReader src, float percentageDone) {} 2030 @Override 2031 public void thumbnailStarted(ImageReader src, int iIdx, int tIdx) {} 2032 @Override 2033 public void sequenceComplete(ImageReader src) {} 2034 @Override 2035 public void sequenceStarted(ImageReader src, int minIndex) {} 2036 @Override 2037 public void readAborted(ImageReader src) {} 2038 } 2039 2040 private static Boolean isLinkedProfileDisabled = null; 2041 2042 private static boolean isLinkedProfileAllowed() { 2043 if (isLinkedProfileDisabled == null) { 2044 PrivilegedAction<Boolean> a = new PrivilegedAction<Boolean>() { 2045 public Boolean run() { 2046 return Boolean.getBoolean("sun.imageio.plugins.bmp.disableLinkedProfiles"); 2047 } 2048 }; 2049 isLinkedProfileDisabled = AccessController.doPrivileged(a); 2050 } 2051 return !isLinkedProfileDisabled; 2052 } 2053 2054 private static Boolean isWindowsPlatform = null; 2055 2056 /** |