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

Print this page
rev 9292 : 8033716: Fix raw and unchecked lint warnings in com.sun.imageio
Reviewed-by: darcy, prr


  55     // The current ImageInputStream source.
  56     ImageInputStream stream = null;
  57 
  58     // Per-stream settings
  59 
  60     // True if the file header including stream metadata has been read.
  61     boolean gotHeader = false;
  62 
  63     // Global metadata, read once per input setting.
  64     GIFStreamMetadata streamMetadata = null;
  65 
  66     // The current image index
  67     int currIndex = -1;
  68 
  69     // Metadata for image at 'currIndex', or null.
  70     GIFImageMetadata imageMetadata = null;
  71 
  72     // A List of Longs indicating the stream positions of the
  73     // start of the metadata for each image.  Entries are added
  74     // as needed.
  75     List imageStartPosition = new ArrayList();
  76 
  77     // Length of metadata for image at 'currIndex', valid only if
  78     // imageMetadata != null.
  79     int imageMetadataLength;
  80 
  81     // The number of images in the stream, if known, otherwise -1.
  82     int numImages = -1;
  83 
  84     // Variables used by the LZW decoding process
  85     byte[] block = new byte[255];
  86     int blockLength = 0;
  87     int bitPos = 0;
  88     int nextByte = 0;
  89     int initCodeSize;
  90     int clearCode;
  91     int eofCode;
  92 
  93     // 32-bit lookahead buffer
  94     int next32Bits = 0;
  95 


 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 getImageTypes(int imageIndex) throws IIOException {
 231         checkIndex(imageIndex);
 232 
 233         int index = locateImage(imageIndex);
 234         if (index != imageIndex) {
 235             throw new IndexOutOfBoundsException();
 236         }
 237         readMetadata();
 238 
 239         List l = new ArrayList(1);
 240 
 241         byte[] colorTable;
 242         if (imageMetadata.localColorTable != null) {
 243             colorTable = imageMetadata.localColorTable;
 244             fallbackColorTable = imageMetadata.localColorTable;
 245         } else {
 246             colorTable = streamMetadata.globalColorTable;
 247         }
 248 
 249         if (colorTable == null) {
 250             if (fallbackColorTable == null) {
 251                 this.processWarningOccurred("Use default color table.");
 252 
 253                 // no color table, the spec allows to use any palette.
 254                 fallbackColorTable = getDefaultPalette();
 255             }
 256 
 257             colorTable = fallbackColorTable;
 258         }
 259 


 588                         length = stream.readUnsignedByte();
 589                         stream.skipBytes(length);
 590                     } while (length > 0);
 591                 }
 592             }
 593         } catch (EOFException e) {
 594             return false;
 595         } catch (IOException e) {
 596             throw new IIOException("I/O error locating image!", e);
 597         }
 598     }
 599 
 600     private int locateImage(int imageIndex) throws IIOException {
 601         readHeader();
 602 
 603         try {
 604             // Find closest known index
 605             int index = Math.min(imageIndex, imageStartPosition.size() - 1);
 606 
 607             // Seek to that position
 608             Long l = (Long)imageStartPosition.get(index);
 609             stream.seek(l.longValue());
 610 
 611             // Skip images until at desired index or last image found
 612             while (index < imageIndex) {
 613                 if (!skipImage()) {
 614                     --index;
 615                     return index;
 616                 }
 617 
 618                 Long l1 = new Long(stream.getStreamPosition());
 619                 imageStartPosition.add(l1);
 620                 ++index;
 621             }
 622         } catch (IOException e) {
 623             throw new IIOException("Couldn't seek!", e);
 624         }
 625 
 626         if (currIndex != imageIndex) {
 627             imageMetadata = null;
 628         }


 714                         imageMetadata.textGridLeft =
 715                             stream.readUnsignedShort();
 716                         imageMetadata.textGridTop =
 717                             stream.readUnsignedShort();
 718                         imageMetadata.textGridWidth =
 719                             stream.readUnsignedShort();
 720                         imageMetadata.textGridHeight =
 721                             stream.readUnsignedShort();
 722                         imageMetadata.characterCellWidth =
 723                             stream.readUnsignedByte();
 724                         imageMetadata.characterCellHeight =
 725                             stream.readUnsignedByte();
 726                         imageMetadata.textForegroundColor =
 727                             stream.readUnsignedByte();
 728                         imageMetadata.textBackgroundColor =
 729                             stream.readUnsignedByte();
 730                         imageMetadata.text = concatenateBlocks();
 731                     } else if (label == 0xfe) { // Comment extension
 732                         byte[] comment = concatenateBlocks();
 733                         if (imageMetadata.comments == null) {
 734                             imageMetadata.comments = new ArrayList();
 735                         }
 736                         imageMetadata.comments.add(comment);
 737                     } else if (label == 0xff) { // Application extension
 738                         int blockSize = stream.readUnsignedByte();
 739                         byte[] applicationID = new byte[8];
 740                         byte[] authCode = new byte[3];
 741 
 742                         // read available data
 743                         byte[] blockData = new byte[blockSize];
 744                         stream.readFully(blockData);
 745 
 746                         int offset = copyData(blockData, 0, applicationID);
 747                         offset = copyData(blockData, offset, authCode);
 748 
 749                         byte[] applicationData = concatenateBlocks();
 750 
 751                         if (offset < blockSize) {
 752                             int len = blockSize - offset;
 753                             byte[] data =
 754                                 new byte[len + applicationData.length];
 755 
 756                             System.arraycopy(blockData, offset, data, 0, len);
 757                             System.arraycopy(applicationData, 0, data, len,
 758                                              applicationData.length);
 759 
 760                             applicationData = data;
 761                         }
 762 
 763                         // Init lists if necessary
 764                         if (imageMetadata.applicationIDs == null) {
 765                             imageMetadata.applicationIDs = new ArrayList();
 766                             imageMetadata.authenticationCodes =
 767                                 new ArrayList();
 768                             imageMetadata.applicationData = new ArrayList();
 769                         }
 770                         imageMetadata.applicationIDs.add(applicationID);
 771                         imageMetadata.authenticationCodes.add(authCode);
 772                         imageMetadata.applicationData.add(applicationData);
 773                     } else {
 774                         // Skip over unknown extension blocks
 775                         int length = 0;
 776                         do {
 777                             length = stream.readUnsignedByte();
 778                             stream.skipBytes(length);
 779                         } while (length > 0);
 780                     }
 781                 } else if (blockType == 0x3b) { // Trailer
 782                     throw new IndexOutOfBoundsException
 783                         ("Attempt to read past end of image sequence!");
 784                 } else {
 785                     throw new IIOException("Unexpected block type " +
 786                                            blockType + "!");
 787                 }
 788             }


 851         throws IIOException {
 852         if (stream == null) {
 853             throw new IllegalStateException("Input not set!");
 854         }
 855         checkIndex(imageIndex);
 856 
 857         int index = locateImage(imageIndex);
 858         if (index != imageIndex) {
 859             throw new IndexOutOfBoundsException("imageIndex out of bounds!");
 860         }
 861 
 862         clearAbortRequest();
 863         readMetadata();
 864 
 865         // A null ImageReadParam means we use the default
 866         if (param == null) {
 867             param = getDefaultReadParam();
 868         }
 869 
 870         // Initialize the destination image
 871         Iterator imageTypes = getImageTypes(imageIndex);
 872         this.theImage = getDestination(param,
 873                                        imageTypes,
 874                                        imageMetadata.imageWidth,
 875                                        imageMetadata.imageHeight);
 876         this.theTile = theImage.getWritableTile(0, 0);
 877         this.width = imageMetadata.imageWidth;
 878         this.height = imageMetadata.imageHeight;
 879         this.streamX = 0;
 880         this.streamY = 0;
 881         this.rowsDone = 0;
 882         this.interlacePass = 0;
 883 
 884         // Get source region, taking subsampling offsets into account,
 885         // and clipping against the true source bounds
 886 
 887         this.sourceRegion = new Rectangle(0, 0, 0, 0);
 888         this.destinationRegion = new Rectangle(0, 0, 0, 0);
 889         computeRegions(param, width, height, theImage,
 890                        sourceRegion, destinationRegion);
 891         this.destinationOffset = new Point(destinationRegion.x,


1014         }
1015     }
1016 
1017     /**
1018      * Remove all settings including global settings such as
1019      * <code>Locale</code>s and listeners, as well as stream settings.
1020      */
1021     public void reset() {
1022         super.reset();
1023         resetStreamSettings();
1024     }
1025 
1026     /**
1027      * Remove local settings based on parsing of a stream.
1028      */
1029     private void resetStreamSettings() {
1030         gotHeader = false;
1031         streamMetadata = null;
1032         currIndex = -1;
1033         imageMetadata = null;
1034         imageStartPosition = new ArrayList();
1035         numImages = -1;
1036 
1037         // No need to reinitialize 'block'
1038         blockLength = 0;
1039         bitPos = 0;
1040         nextByte = 0;
1041 
1042         next32Bits = 0;
1043         lastBlockFound = false;
1044 
1045         theImage = null;
1046         theTile = null;
1047         width = -1;
1048         height = -1;
1049         streamX = -1;
1050         streamY = -1;
1051         rowsDone = 0;
1052         interlacePass = 0;
1053 
1054         fallbackColorTable = null;




  55     // The current ImageInputStream source.
  56     ImageInputStream stream = null;
  57 
  58     // Per-stream settings
  59 
  60     // True if the file header including stream metadata has been read.
  61     boolean gotHeader = false;
  62 
  63     // Global metadata, read once per input setting.
  64     GIFStreamMetadata streamMetadata = null;
  65 
  66     // The current image index
  67     int currIndex = -1;
  68 
  69     // Metadata for image at 'currIndex', or null.
  70     GIFImageMetadata imageMetadata = null;
  71 
  72     // A List of Longs indicating the stream positions of the
  73     // start of the metadata for each image.  Entries are added
  74     // as needed.
  75     List<Long> imageStartPosition = new ArrayList<>();
  76 
  77     // Length of metadata for image at 'currIndex', valid only if
  78     // imageMetadata != null.
  79     int imageMetadataLength;
  80 
  81     // The number of images in the stream, if known, otherwise -1.
  82     int numImages = -1;
  83 
  84     // Variables used by the LZW decoding process
  85     byte[] block = new byte[255];
  86     int blockLength = 0;
  87     int bitPos = 0;
  88     int nextByte = 0;
  89     int initCodeSize;
  90     int clearCode;
  91     int eofCode;
  92 
  93     // 32-bit lookahead buffer
  94     int next32Bits = 0;
  95 


 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) throws IIOException {
 231         checkIndex(imageIndex);
 232 
 233         int index = locateImage(imageIndex);
 234         if (index != imageIndex) {
 235             throw new IndexOutOfBoundsException();
 236         }
 237         readMetadata();
 238 
 239         List<ImageTypeSpecifier> l = new ArrayList<>(1);
 240 
 241         byte[] colorTable;
 242         if (imageMetadata.localColorTable != null) {
 243             colorTable = imageMetadata.localColorTable;
 244             fallbackColorTable = imageMetadata.localColorTable;
 245         } else {
 246             colorTable = streamMetadata.globalColorTable;
 247         }
 248 
 249         if (colorTable == null) {
 250             if (fallbackColorTable == null) {
 251                 this.processWarningOccurred("Use default color table.");
 252 
 253                 // no color table, the spec allows to use any palette.
 254                 fallbackColorTable = getDefaultPalette();
 255             }
 256 
 257             colorTable = fallbackColorTable;
 258         }
 259 


 588                         length = stream.readUnsignedByte();
 589                         stream.skipBytes(length);
 590                     } while (length > 0);
 591                 }
 592             }
 593         } catch (EOFException e) {
 594             return false;
 595         } catch (IOException e) {
 596             throw new IIOException("I/O error locating image!", e);
 597         }
 598     }
 599 
 600     private int locateImage(int imageIndex) throws IIOException {
 601         readHeader();
 602 
 603         try {
 604             // Find closest known index
 605             int index = Math.min(imageIndex, imageStartPosition.size() - 1);
 606 
 607             // Seek to that position
 608             Long l = imageStartPosition.get(index);
 609             stream.seek(l.longValue());
 610 
 611             // Skip images until at desired index or last image found
 612             while (index < imageIndex) {
 613                 if (!skipImage()) {
 614                     --index;
 615                     return index;
 616                 }
 617 
 618                 Long l1 = new Long(stream.getStreamPosition());
 619                 imageStartPosition.add(l1);
 620                 ++index;
 621             }
 622         } catch (IOException e) {
 623             throw new IIOException("Couldn't seek!", e);
 624         }
 625 
 626         if (currIndex != imageIndex) {
 627             imageMetadata = null;
 628         }


 714                         imageMetadata.textGridLeft =
 715                             stream.readUnsignedShort();
 716                         imageMetadata.textGridTop =
 717                             stream.readUnsignedShort();
 718                         imageMetadata.textGridWidth =
 719                             stream.readUnsignedShort();
 720                         imageMetadata.textGridHeight =
 721                             stream.readUnsignedShort();
 722                         imageMetadata.characterCellWidth =
 723                             stream.readUnsignedByte();
 724                         imageMetadata.characterCellHeight =
 725                             stream.readUnsignedByte();
 726                         imageMetadata.textForegroundColor =
 727                             stream.readUnsignedByte();
 728                         imageMetadata.textBackgroundColor =
 729                             stream.readUnsignedByte();
 730                         imageMetadata.text = concatenateBlocks();
 731                     } else if (label == 0xfe) { // Comment extension
 732                         byte[] comment = concatenateBlocks();
 733                         if (imageMetadata.comments == null) {
 734                             imageMetadata.comments = new ArrayList<>();
 735                         }
 736                         imageMetadata.comments.add(comment);
 737                     } else if (label == 0xff) { // Application extension
 738                         int blockSize = stream.readUnsignedByte();
 739                         byte[] applicationID = new byte[8];
 740                         byte[] authCode = new byte[3];
 741 
 742                         // read available data
 743                         byte[] blockData = new byte[blockSize];
 744                         stream.readFully(blockData);
 745 
 746                         int offset = copyData(blockData, 0, applicationID);
 747                         offset = copyData(blockData, offset, authCode);
 748 
 749                         byte[] applicationData = concatenateBlocks();
 750 
 751                         if (offset < blockSize) {
 752                             int len = blockSize - offset;
 753                             byte[] data =
 754                                 new byte[len + applicationData.length];
 755 
 756                             System.arraycopy(blockData, offset, data, 0, len);
 757                             System.arraycopy(applicationData, 0, data, len,
 758                                              applicationData.length);
 759 
 760                             applicationData = data;
 761                         }
 762 
 763                         // Init lists if necessary
 764                         if (imageMetadata.applicationIDs == null) {
 765                             imageMetadata.applicationIDs = new ArrayList<>();
 766                             imageMetadata.authenticationCodes =
 767                                 new ArrayList<>();
 768                             imageMetadata.applicationData = new ArrayList<>();
 769                         }
 770                         imageMetadata.applicationIDs.add(applicationID);
 771                         imageMetadata.authenticationCodes.add(authCode);
 772                         imageMetadata.applicationData.add(applicationData);
 773                     } else {
 774                         // Skip over unknown extension blocks
 775                         int length = 0;
 776                         do {
 777                             length = stream.readUnsignedByte();
 778                             stream.skipBytes(length);
 779                         } while (length > 0);
 780                     }
 781                 } else if (blockType == 0x3b) { // Trailer
 782                     throw new IndexOutOfBoundsException
 783                         ("Attempt to read past end of image sequence!");
 784                 } else {
 785                     throw new IIOException("Unexpected block type " +
 786                                            blockType + "!");
 787                 }
 788             }


 851         throws IIOException {
 852         if (stream == null) {
 853             throw new IllegalStateException("Input not set!");
 854         }
 855         checkIndex(imageIndex);
 856 
 857         int index = locateImage(imageIndex);
 858         if (index != imageIndex) {
 859             throw new IndexOutOfBoundsException("imageIndex out of bounds!");
 860         }
 861 
 862         clearAbortRequest();
 863         readMetadata();
 864 
 865         // A null ImageReadParam means we use the default
 866         if (param == null) {
 867             param = getDefaultReadParam();
 868         }
 869 
 870         // Initialize the destination image
 871         Iterator<ImageTypeSpecifier> imageTypes = getImageTypes(imageIndex);
 872         this.theImage = getDestination(param,
 873                                        imageTypes,
 874                                        imageMetadata.imageWidth,
 875                                        imageMetadata.imageHeight);
 876         this.theTile = theImage.getWritableTile(0, 0);
 877         this.width = imageMetadata.imageWidth;
 878         this.height = imageMetadata.imageHeight;
 879         this.streamX = 0;
 880         this.streamY = 0;
 881         this.rowsDone = 0;
 882         this.interlacePass = 0;
 883 
 884         // Get source region, taking subsampling offsets into account,
 885         // and clipping against the true source bounds
 886 
 887         this.sourceRegion = new Rectangle(0, 0, 0, 0);
 888         this.destinationRegion = new Rectangle(0, 0, 0, 0);
 889         computeRegions(param, width, height, theImage,
 890                        sourceRegion, destinationRegion);
 891         this.destinationOffset = new Point(destinationRegion.x,


1014         }
1015     }
1016 
1017     /**
1018      * Remove all settings including global settings such as
1019      * <code>Locale</code>s and listeners, as well as stream settings.
1020      */
1021     public void reset() {
1022         super.reset();
1023         resetStreamSettings();
1024     }
1025 
1026     /**
1027      * Remove local settings based on parsing of a stream.
1028      */
1029     private void resetStreamSettings() {
1030         gotHeader = false;
1031         streamMetadata = null;
1032         currIndex = -1;
1033         imageMetadata = null;
1034         imageStartPosition = new ArrayList<>();
1035         numImages = -1;
1036 
1037         // No need to reinitialize 'block'
1038         blockLength = 0;
1039         bitPos = 0;
1040         nextByte = 0;
1041 
1042         next32Bits = 0;
1043         lastBlockFound = false;
1044 
1045         theImage = null;
1046         theTile = null;
1047         width = -1;
1048         height = -1;
1049         streamX = -1;
1050         streamY = -1;
1051         rowsDone = 0;
1052         interlacePass = 0;
1053 
1054         fallbackColorTable = null;