< prev index next >

src/java.desktop/share/classes/com/sun/imageio/plugins/gif/GIFImageReader.java

Print this page




 111 
 112     // The number of rows decoded
 113     int rowsDone = 0;
 114 
 115     // The current interlace pass, starting with 0.
 116     int interlacePass = 0;
 117 
 118     private byte[] fallbackColorTable = null;
 119 
 120     // End per-stream settings
 121 
 122     // Constants used to control interlacing.
 123     static final int[] interlaceIncrement = { 8, 8, 4, 2, -1 };
 124     static final int[] interlaceOffset = { 0, 4, 2, 1, -1 };
 125 
 126     public GIFImageReader(ImageReaderSpi originatingProvider) {
 127         super(originatingProvider);
 128     }
 129 
 130     // Take input from an ImageInputStream

 131     public void setInput(Object input,
 132                          boolean seekForwardOnly,
 133                          boolean ignoreMetadata) {
 134         super.setInput(input, seekForwardOnly, ignoreMetadata);
 135         if (input != null) {
 136             if (!(input instanceof ImageInputStream)) {
 137                 throw new IllegalArgumentException
 138                     ("input not an ImageInputStream!");
 139             }
 140             this.stream = (ImageInputStream)input;
 141         } else {
 142             this.stream = null;
 143         }
 144 
 145         // Clear all values based on the previous stream contents
 146         resetStreamSettings();
 147     }
 148 

 149     public int getNumImages(boolean allowSearch) throws IIOException {
 150         if (stream == null) {
 151             throw new IllegalStateException("Input not set!");
 152         }
 153         if (seekForwardOnly && allowSearch) {
 154             throw new IllegalStateException
 155                 ("seekForwardOnly and allowSearch can't both be true!");
 156         }
 157 
 158         if (numImages > 0) {
 159             return numImages;
 160         }
 161         if (allowSearch) {
 162             this.numImages = locateImage(Integer.MAX_VALUE) + 1;
 163         }
 164         return numImages;
 165     }
 166 
 167     // Throw an IndexOutOfBoundsException if index < minIndex,
 168     // and bump minIndex if required.
 169     private void checkIndex(int imageIndex) {
 170         if (imageIndex < minIndex) {
 171             throw new IndexOutOfBoundsException("imageIndex < minIndex!");
 172         }
 173         if (seekForwardOnly) {
 174             minIndex = imageIndex;
 175         }
 176     }
 177 

 178     public int getWidth(int imageIndex) throws IIOException {
 179         checkIndex(imageIndex);
 180 
 181         int index = locateImage(imageIndex);
 182         if (index != imageIndex) {
 183             throw new IndexOutOfBoundsException();
 184         }
 185         readMetadata();
 186         return imageMetadata.imageWidth;
 187     }
 188 

 189     public int getHeight(int imageIndex) throws IIOException {
 190         checkIndex(imageIndex);
 191 
 192         int index = locateImage(imageIndex);
 193         if (index != imageIndex) {
 194             throw new IndexOutOfBoundsException();
 195         }
 196         readMetadata();
 197         return imageMetadata.imageHeight;
 198     }
 199 
 200     // We don't check all parameters as ImageTypeSpecifier.createIndexed do
 201     // since this method is private and we pass consistent data here
 202     private ImageTypeSpecifier createIndexed(byte[] r, byte[] g, byte[] b,
 203                                              int bits) {
 204         ColorModel colorModel;
 205         if (imageMetadata.transparentColorFlag) {
 206             // Some files erroneously have a transparent color index
 207             // of 255 even though there are fewer than 256 colors.
 208             int idx = Math.min(imageMetadata.transparentColorIndex,


 210             colorModel = new IndexColorModel(bits, r.length, r, g, b, idx);
 211         } else {
 212             colorModel = new IndexColorModel(bits, r.length, r, g, b);
 213         }
 214 
 215         SampleModel sampleModel;
 216         if (bits == 8) {
 217             int[] bandOffsets = {0};
 218             sampleModel =
 219                     new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE,
 220                     1, 1, 1, 1,
 221                     bandOffsets);
 222         } else {
 223             sampleModel =
 224                     new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,
 225                     1, 1, bits);
 226         }
 227         return new ImageTypeSpecifier(colorModel, sampleModel);
 228     }
 229 

 230     public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex)
 231             throws IIOException {
 232         checkIndex(imageIndex);
 233 
 234         int index = locateImage(imageIndex);
 235         if (index != imageIndex) {
 236             throw new IndexOutOfBoundsException();
 237         }
 238         readMetadata();
 239 
 240         List<ImageTypeSpecifier> l = new ArrayList<>(1);
 241 
 242         byte[] colorTable;
 243         if (imageMetadata.localColorTable != null) {
 244             colorTable = imageMetadata.localColorTable;
 245             fallbackColorTable = imageMetadata.localColorTable;
 246         } else {
 247             colorTable = streamMetadata.globalColorTable;
 248         }
 249 


 272             // Bump to 8 bits
 273             bits = 8;
 274         }
 275         int lutLength = 1 << bits;
 276         byte[] r = new byte[lutLength];
 277         byte[] g = new byte[lutLength];
 278         byte[] b = new byte[lutLength];
 279 
 280         // Entries from length + 1 to lutLength - 1 will be 0
 281         int rgbIndex = 0;
 282         for (int i = 0; i < length; i++) {
 283             r[i] = colorTable[rgbIndex++];
 284             g[i] = colorTable[rgbIndex++];
 285             b[i] = colorTable[rgbIndex++];
 286         }
 287 
 288         l.add(createIndexed(r, g, b, bits));
 289         return l.iterator();
 290     }
 291 

 292     public ImageReadParam getDefaultReadParam() {
 293         return new ImageReadParam();
 294     }
 295 

 296     public IIOMetadata getStreamMetadata() throws IIOException {
 297         readHeader();
 298         return streamMetadata;
 299     }
 300 

 301     public IIOMetadata getImageMetadata(int imageIndex) throws IIOException {
 302         checkIndex(imageIndex);
 303 
 304         int index = locateImage(imageIndex);
 305         if (index != imageIndex) {
 306             throw new IndexOutOfBoundsException("Bad image index!");
 307         }
 308         readMetadata();
 309         return imageMetadata;
 310     }
 311 
 312     // BEGIN LZW STUFF
 313 
 314     private void initNext32Bits() {
 315         next32Bits = block[0] & 0xff;
 316         next32Bits |= (block[1] & 0xff) << 8;
 317         next32Bits |= (block[2] & 0xff) << 16;
 318         next32Bits |= block[3] << 24;
 319         nextByte = 4;
 320     }


 838                                  yStep);
 839 
 840         // Initialized updateMinY and updateYStep
 841         this.updateMinY = vals[1];
 842         this.updateYStep = vals[5];
 843 
 844         // Inform IIOReadUpdateListeners of new pass
 845         int[] bands = { 0 };
 846 
 847         processPassStarted(theImage,
 848                            interlacePass,
 849                            sourceMinProgressivePass,
 850                            sourceMaxProgressivePass,
 851                            0,
 852                            updateMinY,
 853                            1,
 854                            updateYStep,
 855                            bands);
 856     }
 857 

 858     public BufferedImage read(int imageIndex, ImageReadParam param)
 859         throws IIOException {
 860         if (stream == null) {
 861             throw new IllegalStateException("Input not set!");
 862         }
 863         checkIndex(imageIndex);
 864 
 865         int index = locateImage(imageIndex);
 866         if (index != imageIndex) {
 867             throw new IndexOutOfBoundsException("imageIndex out of bounds!");
 868         }
 869 
 870         readMetadata();
 871 
 872         // A null ImageReadParam means we use the default
 873         if (param == null) {
 874             param = getDefaultReadParam();
 875         }
 876 
 877         // Initialize the destination image


1020                 for (int i = len - 1; i >= 0; i--) {
1021                     string[i] = suffix[c];
1022                     c = prefix[c];
1023                 }
1024 
1025                 outputPixels(string, len);
1026                 oldCode = code;
1027             } while (!abortRequested());
1028 
1029             processReadAborted();
1030             return theImage;
1031         } catch (IOException e) {
1032             throw new IIOException("I/O error reading image!", e);
1033         }
1034     }
1035 
1036     /**
1037      * Remove all settings including global settings such as
1038      * {@code Locale}s and listeners, as well as stream settings.
1039      */

1040     public void reset() {
1041         super.reset();
1042         resetStreamSettings();
1043     }
1044 
1045     /**
1046      * Remove local settings based on parsing of a stream.
1047      */
1048     private void resetStreamSettings() {
1049         gotHeader = false;
1050         streamMetadata = null;
1051         currIndex = -1;
1052         imageMetadata = null;
1053         imageStartPosition = new ArrayList<>();
1054         numImages = -1;
1055 
1056         // No need to reinitialize 'block'
1057         blockLength = 0;
1058         bitPos = 0;
1059         nextByte = 0;




 111 
 112     // The number of rows decoded
 113     int rowsDone = 0;
 114 
 115     // The current interlace pass, starting with 0.
 116     int interlacePass = 0;
 117 
 118     private byte[] fallbackColorTable = null;
 119 
 120     // End per-stream settings
 121 
 122     // Constants used to control interlacing.
 123     static final int[] interlaceIncrement = { 8, 8, 4, 2, -1 };
 124     static final int[] interlaceOffset = { 0, 4, 2, 1, -1 };
 125 
 126     public GIFImageReader(ImageReaderSpi originatingProvider) {
 127         super(originatingProvider);
 128     }
 129 
 130     // Take input from an ImageInputStream
 131     @Override
 132     public void setInput(Object input,
 133                          boolean seekForwardOnly,
 134                          boolean ignoreMetadata) {
 135         super.setInput(input, seekForwardOnly, ignoreMetadata);
 136         if (input != null) {
 137             if (!(input instanceof ImageInputStream)) {
 138                 throw new IllegalArgumentException
 139                     ("input not an ImageInputStream!");
 140             }
 141             this.stream = (ImageInputStream)input;
 142         } else {
 143             this.stream = null;
 144         }
 145 
 146         // Clear all values based on the previous stream contents
 147         resetStreamSettings();
 148     }
 149 
 150     @Override
 151     public int getNumImages(boolean allowSearch) throws IIOException {
 152         if (stream == null) {
 153             throw new IllegalStateException("Input not set!");
 154         }
 155         if (seekForwardOnly && allowSearch) {
 156             throw new IllegalStateException
 157                 ("seekForwardOnly and allowSearch can't both be true!");
 158         }
 159 
 160         if (numImages > 0) {
 161             return numImages;
 162         }
 163         if (allowSearch) {
 164             this.numImages = locateImage(Integer.MAX_VALUE) + 1;
 165         }
 166         return numImages;
 167     }
 168 
 169     // Throw an IndexOutOfBoundsException if index < minIndex,
 170     // and bump minIndex if required.
 171     private void checkIndex(int imageIndex) {
 172         if (imageIndex < minIndex) {
 173             throw new IndexOutOfBoundsException("imageIndex < minIndex!");
 174         }
 175         if (seekForwardOnly) {
 176             minIndex = imageIndex;
 177         }
 178     }
 179 
 180     @Override
 181     public int getWidth(int imageIndex) throws IIOException {
 182         checkIndex(imageIndex);
 183 
 184         int index = locateImage(imageIndex);
 185         if (index != imageIndex) {
 186             throw new IndexOutOfBoundsException();
 187         }
 188         readMetadata();
 189         return imageMetadata.imageWidth;
 190     }
 191 
 192     @Override
 193     public int getHeight(int imageIndex) throws IIOException {
 194         checkIndex(imageIndex);
 195 
 196         int index = locateImage(imageIndex);
 197         if (index != imageIndex) {
 198             throw new IndexOutOfBoundsException();
 199         }
 200         readMetadata();
 201         return imageMetadata.imageHeight;
 202     }
 203 
 204     // We don't check all parameters as ImageTypeSpecifier.createIndexed do
 205     // since this method is private and we pass consistent data here
 206     private ImageTypeSpecifier createIndexed(byte[] r, byte[] g, byte[] b,
 207                                              int bits) {
 208         ColorModel colorModel;
 209         if (imageMetadata.transparentColorFlag) {
 210             // Some files erroneously have a transparent color index
 211             // of 255 even though there are fewer than 256 colors.
 212             int idx = Math.min(imageMetadata.transparentColorIndex,


 214             colorModel = new IndexColorModel(bits, r.length, r, g, b, idx);
 215         } else {
 216             colorModel = new IndexColorModel(bits, r.length, r, g, b);
 217         }
 218 
 219         SampleModel sampleModel;
 220         if (bits == 8) {
 221             int[] bandOffsets = {0};
 222             sampleModel =
 223                     new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE,
 224                     1, 1, 1, 1,
 225                     bandOffsets);
 226         } else {
 227             sampleModel =
 228                     new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,
 229                     1, 1, bits);
 230         }
 231         return new ImageTypeSpecifier(colorModel, sampleModel);
 232     }
 233 
 234     @Override
 235     public Iterator<ImageTypeSpecifier> getImageTypes(int imageIndex)
 236             throws IIOException {
 237         checkIndex(imageIndex);
 238 
 239         int index = locateImage(imageIndex);
 240         if (index != imageIndex) {
 241             throw new IndexOutOfBoundsException();
 242         }
 243         readMetadata();
 244 
 245         List<ImageTypeSpecifier> l = new ArrayList<>(1);
 246 
 247         byte[] colorTable;
 248         if (imageMetadata.localColorTable != null) {
 249             colorTable = imageMetadata.localColorTable;
 250             fallbackColorTable = imageMetadata.localColorTable;
 251         } else {
 252             colorTable = streamMetadata.globalColorTable;
 253         }
 254 


 277             // Bump to 8 bits
 278             bits = 8;
 279         }
 280         int lutLength = 1 << bits;
 281         byte[] r = new byte[lutLength];
 282         byte[] g = new byte[lutLength];
 283         byte[] b = new byte[lutLength];
 284 
 285         // Entries from length + 1 to lutLength - 1 will be 0
 286         int rgbIndex = 0;
 287         for (int i = 0; i < length; i++) {
 288             r[i] = colorTable[rgbIndex++];
 289             g[i] = colorTable[rgbIndex++];
 290             b[i] = colorTable[rgbIndex++];
 291         }
 292 
 293         l.add(createIndexed(r, g, b, bits));
 294         return l.iterator();
 295     }
 296 
 297     @Override
 298     public ImageReadParam getDefaultReadParam() {
 299         return new ImageReadParam();
 300     }
 301 
 302     @Override
 303     public IIOMetadata getStreamMetadata() throws IIOException {
 304         readHeader();
 305         return streamMetadata;
 306     }
 307 
 308     @Override
 309     public IIOMetadata getImageMetadata(int imageIndex) throws IIOException {
 310         checkIndex(imageIndex);
 311 
 312         int index = locateImage(imageIndex);
 313         if (index != imageIndex) {
 314             throw new IndexOutOfBoundsException("Bad image index!");
 315         }
 316         readMetadata();
 317         return imageMetadata;
 318     }
 319 
 320     // BEGIN LZW STUFF
 321 
 322     private void initNext32Bits() {
 323         next32Bits = block[0] & 0xff;
 324         next32Bits |= (block[1] & 0xff) << 8;
 325         next32Bits |= (block[2] & 0xff) << 16;
 326         next32Bits |= block[3] << 24;
 327         nextByte = 4;
 328     }


 846                                  yStep);
 847 
 848         // Initialized updateMinY and updateYStep
 849         this.updateMinY = vals[1];
 850         this.updateYStep = vals[5];
 851 
 852         // Inform IIOReadUpdateListeners of new pass
 853         int[] bands = { 0 };
 854 
 855         processPassStarted(theImage,
 856                            interlacePass,
 857                            sourceMinProgressivePass,
 858                            sourceMaxProgressivePass,
 859                            0,
 860                            updateMinY,
 861                            1,
 862                            updateYStep,
 863                            bands);
 864     }
 865 
 866     @Override
 867     public BufferedImage read(int imageIndex, ImageReadParam param)
 868         throws IIOException {
 869         if (stream == null) {
 870             throw new IllegalStateException("Input not set!");
 871         }
 872         checkIndex(imageIndex);
 873 
 874         int index = locateImage(imageIndex);
 875         if (index != imageIndex) {
 876             throw new IndexOutOfBoundsException("imageIndex out of bounds!");
 877         }
 878 
 879         readMetadata();
 880 
 881         // A null ImageReadParam means we use the default
 882         if (param == null) {
 883             param = getDefaultReadParam();
 884         }
 885 
 886         // Initialize the destination image


1029                 for (int i = len - 1; i >= 0; i--) {
1030                     string[i] = suffix[c];
1031                     c = prefix[c];
1032                 }
1033 
1034                 outputPixels(string, len);
1035                 oldCode = code;
1036             } while (!abortRequested());
1037 
1038             processReadAborted();
1039             return theImage;
1040         } catch (IOException e) {
1041             throw new IIOException("I/O error reading image!", e);
1042         }
1043     }
1044 
1045     /**
1046      * Remove all settings including global settings such as
1047      * {@code Locale}s and listeners, as well as stream settings.
1048      */
1049     @Override
1050     public void reset() {
1051         super.reset();
1052         resetStreamSettings();
1053     }
1054 
1055     /**
1056      * Remove local settings based on parsing of a stream.
1057      */
1058     private void resetStreamSettings() {
1059         gotHeader = false;
1060         streamMetadata = null;
1061         currIndex = -1;
1062         imageMetadata = null;
1063         imageStartPosition = new ArrayList<>();
1064         numImages = -1;
1065 
1066         // No need to reinitialize 'block'
1067         blockLength = 0;
1068         bitPos = 0;
1069         nextByte = 0;


< prev index next >