< prev index next >

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

Print this page


   1 /*
   2  * Copyright (c) 2000, 2013, 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


 439             (((streamY - sourceRegion.y) % sourceYSubsampling) == 0);
 440     }
 441 
 442     private void outputPixels(byte[] string, int len) {
 443         if (interlacePass < sourceMinProgressivePass ||
 444             interlacePass > sourceMaxProgressivePass) {
 445             return;
 446         }
 447 
 448         for (int i = 0; i < len; i++) {
 449             if (streamX >= sourceRegion.x) {
 450                 rowBuf[streamX - sourceRegion.x] = string[i];
 451             }
 452 
 453             // Process end-of-row
 454             ++streamX;
 455             if (streamX == width) {
 456                 // Update IIOReadProgressListeners
 457                 ++rowsDone;
 458                 processImageProgress(100.0F*rowsDone/height);



 459 
 460                 if (decodeThisRow) {
 461                     outputRow();
 462                 }
 463 
 464                 streamX = 0;
 465                 if (imageMetadata.interlaceFlag) {
 466                     streamY += interlaceIncrement[interlacePass];
 467                     if (streamY >= height) {
 468                         // Inform IIOReadUpdateListeners of end of pass
 469                         if (updateListeners != null) {
 470                             processPassComplete(theImage);
 471                         }
 472 
 473                         ++interlacePass;
 474                         if (interlacePass > sourceMaxProgressivePass) {
 475                             return;
 476                         }
 477                         streamY = interlaceOffset[interlacePass];
 478                         startPass(interlacePass);


 843                            sourceMaxProgressivePass,
 844                            0,
 845                            updateMinY,
 846                            1,
 847                            updateYStep,
 848                            bands);
 849     }
 850 
 851     public BufferedImage read(int imageIndex, ImageReadParam param)
 852         throws IIOException {
 853         if (stream == null) {
 854             throw new IllegalStateException("Input not set!");
 855         }
 856         checkIndex(imageIndex);
 857 
 858         int index = locateImage(imageIndex);
 859         if (index != imageIndex) {
 860             throw new IndexOutOfBoundsException("imageIndex out of bounds!");
 861         }
 862 
 863         clearAbortRequest();
 864         readMetadata();
 865 
 866         // A null ImageReadParam means we use the default
 867         if (param == null) {
 868             param = getDefaultReadParam();
 869         }
 870 
 871         // Initialize the destination image
 872         Iterator<ImageTypeSpecifier> imageTypes = getImageTypes(imageIndex);
 873         this.theImage = getDestination(param,
 874                                        imageTypes,
 875                                        imageMetadata.imageWidth,
 876                                        imageMetadata.imageHeight);
 877         this.theTile = theImage.getWritableTile(0, 0);
 878         this.width = imageMetadata.imageWidth;
 879         this.height = imageMetadata.imageHeight;
 880         this.streamX = 0;
 881         this.streamY = 0;
 882         this.rowsDone = 0;
 883         this.interlacePass = 0;


 886         // and clipping against the true source bounds
 887 
 888         this.sourceRegion = new Rectangle(0, 0, 0, 0);
 889         this.destinationRegion = new Rectangle(0, 0, 0, 0);
 890         computeRegions(param, width, height, theImage,
 891                        sourceRegion, destinationRegion);
 892         this.destinationOffset = new Point(destinationRegion.x,
 893                                            destinationRegion.y);
 894 
 895         this.sourceXSubsampling = param.getSourceXSubsampling();
 896         this.sourceYSubsampling = param.getSourceYSubsampling();
 897         this.sourceMinProgressivePass =
 898             Math.max(param.getSourceMinProgressivePass(), 0);
 899         this.sourceMaxProgressivePass =
 900             Math.min(param.getSourceMaxProgressivePass(), 3);
 901 
 902         this.destY = destinationRegion.y +
 903             (streamY - sourceRegion.y)/sourceYSubsampling;
 904         computeDecodeThisRow();
 905 

 906         // Inform IIOReadProgressListeners of start of image
 907         processImageStarted(imageIndex);




 908         startPass(0);
 909 
 910         this.rowBuf = new byte[width];
 911 
 912         try {
 913             // Read and decode the image data, fill in theImage
 914             this.initCodeSize = stream.readUnsignedByte();
 915 
 916             // Read first data block
 917             this.blockLength = stream.readUnsignedByte();
 918             int left = blockLength;
 919             int off = 0;
 920             while (left > 0) {
 921                 int nbytes = stream.read(block, off, left);
 922                 left -= nbytes;
 923                 off += nbytes;
 924             }
 925 
 926             this.bitPos = 0;
 927             this.nextByte = 0;


 930 
 931             // Init 32-bit buffer
 932             initNext32Bits();
 933 
 934             this.clearCode = 1 << initCodeSize;
 935             this.eofCode = clearCode + 1;
 936 
 937             int code, oldCode = 0;
 938 
 939             int[] prefix = new int[4096];
 940             byte[] suffix = new byte[4096];
 941             byte[] initial = new byte[4096];
 942             int[] length = new int[4096];
 943             byte[] string = new byte[4096];
 944 
 945             initializeStringTable(prefix, suffix, initial, length);
 946             int tableIndex = (1 << initCodeSize) + 2;
 947             int codeSize = initCodeSize + 1;
 948             int codeMask = (1 << codeSize) - 1;
 949 
 950             while (!abortRequested()) {
 951                 code = getCode(codeSize, codeMask);
 952 
 953                 if (code == clearCode) {
 954                     initializeStringTable(prefix, suffix, initial, length);
 955                     tableIndex = (1 << initCodeSize) + 2;
 956                     codeSize = initCodeSize + 1;
 957                     codeMask = (1 << codeSize) - 1;
 958 
 959                     code = getCode(codeSize, codeMask);
 960                     if (code == eofCode) {
 961                         // Inform IIOReadProgressListeners of end of image
 962                         processImageComplete();
 963                         return theImage;
 964                     }
 965                 } else if (code == eofCode) {
 966                     // Inform IIOReadProgressListeners of end of image
 967                     processImageComplete();
 968                     return theImage;
 969                 } else {
 970                     int newSuffixIndex;


 988                     length[ti] = length[oc] + 1;
 989 
 990                     ++tableIndex;
 991                     if ((tableIndex == (1 << codeSize)) &&
 992                         (tableIndex < 4096)) {
 993                         ++codeSize;
 994                         codeMask = (1 << codeSize) - 1;
 995                     }
 996                 }
 997 
 998                 // Reverse code
 999                 int c = code;
1000                 int len = length[c];
1001                 for (int i = len - 1; i >= 0; i--) {
1002                     string[i] = suffix[c];
1003                     c = prefix[c];
1004                 }
1005 
1006                 outputPixels(string, len);
1007                 oldCode = code;
1008             }
1009 
1010             processReadAborted();
1011             return theImage;
1012         } catch (IOException e) {
1013             e.printStackTrace();
1014             throw new IIOException("I/O error reading image!", e);
1015         }
1016     }
1017 
1018     /**
1019      * Remove all settings including global settings such as
1020      * {@code Locale}s and listeners, as well as stream settings.
1021      */
1022     public void reset() {
1023         super.reset();
1024         resetStreamSettings();
1025     }
1026 
1027     /**
1028      * Remove local settings based on parsing of a stream.


   1 /*
   2  * Copyright (c) 2000, 2016, 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


 439             (((streamY - sourceRegion.y) % sourceYSubsampling) == 0);
 440     }
 441 
 442     private void outputPixels(byte[] string, int len) {
 443         if (interlacePass < sourceMinProgressivePass ||
 444             interlacePass > sourceMaxProgressivePass) {
 445             return;
 446         }
 447 
 448         for (int i = 0; i < len; i++) {
 449             if (streamX >= sourceRegion.x) {
 450                 rowBuf[streamX - sourceRegion.x] = string[i];
 451             }
 452 
 453             // Process end-of-row
 454             ++streamX;
 455             if (streamX == width) {
 456                 // Update IIOReadProgressListeners
 457                 ++rowsDone;
 458                 processImageProgress(100.0F*rowsDone/height);
 459                 if (abortRequested()) {
 460                     return;
 461                 }
 462 
 463                 if (decodeThisRow) {
 464                     outputRow();
 465                 }
 466 
 467                 streamX = 0;
 468                 if (imageMetadata.interlaceFlag) {
 469                     streamY += interlaceIncrement[interlacePass];
 470                     if (streamY >= height) {
 471                         // Inform IIOReadUpdateListeners of end of pass
 472                         if (updateListeners != null) {
 473                             processPassComplete(theImage);
 474                         }
 475 
 476                         ++interlacePass;
 477                         if (interlacePass > sourceMaxProgressivePass) {
 478                             return;
 479                         }
 480                         streamY = interlaceOffset[interlacePass];
 481                         startPass(interlacePass);


 846                            sourceMaxProgressivePass,
 847                            0,
 848                            updateMinY,
 849                            1,
 850                            updateYStep,
 851                            bands);
 852     }
 853 
 854     public BufferedImage read(int imageIndex, ImageReadParam param)
 855         throws IIOException {
 856         if (stream == null) {
 857             throw new IllegalStateException("Input not set!");
 858         }
 859         checkIndex(imageIndex);
 860 
 861         int index = locateImage(imageIndex);
 862         if (index != imageIndex) {
 863             throw new IndexOutOfBoundsException("imageIndex out of bounds!");
 864         }
 865 

 866         readMetadata();
 867 
 868         // A null ImageReadParam means we use the default
 869         if (param == null) {
 870             param = getDefaultReadParam();
 871         }
 872 
 873         // Initialize the destination image
 874         Iterator<ImageTypeSpecifier> imageTypes = getImageTypes(imageIndex);
 875         this.theImage = getDestination(param,
 876                                        imageTypes,
 877                                        imageMetadata.imageWidth,
 878                                        imageMetadata.imageHeight);
 879         this.theTile = theImage.getWritableTile(0, 0);
 880         this.width = imageMetadata.imageWidth;
 881         this.height = imageMetadata.imageHeight;
 882         this.streamX = 0;
 883         this.streamY = 0;
 884         this.rowsDone = 0;
 885         this.interlacePass = 0;


 888         // and clipping against the true source bounds
 889 
 890         this.sourceRegion = new Rectangle(0, 0, 0, 0);
 891         this.destinationRegion = new Rectangle(0, 0, 0, 0);
 892         computeRegions(param, width, height, theImage,
 893                        sourceRegion, destinationRegion);
 894         this.destinationOffset = new Point(destinationRegion.x,
 895                                            destinationRegion.y);
 896 
 897         this.sourceXSubsampling = param.getSourceXSubsampling();
 898         this.sourceYSubsampling = param.getSourceYSubsampling();
 899         this.sourceMinProgressivePass =
 900             Math.max(param.getSourceMinProgressivePass(), 0);
 901         this.sourceMaxProgressivePass =
 902             Math.min(param.getSourceMaxProgressivePass(), 3);
 903 
 904         this.destY = destinationRegion.y +
 905             (streamY - sourceRegion.y)/sourceYSubsampling;
 906         computeDecodeThisRow();
 907 
 908         clearAbortRequest();
 909         // Inform IIOReadProgressListeners of start of image
 910         processImageStarted(imageIndex);
 911         if (abortRequested()) {
 912             processReadAborted();
 913             return theImage;
 914         }
 915         startPass(0);
 916 
 917         this.rowBuf = new byte[width];
 918 
 919         try {
 920             // Read and decode the image data, fill in theImage
 921             this.initCodeSize = stream.readUnsignedByte();
 922 
 923             // Read first data block
 924             this.blockLength = stream.readUnsignedByte();
 925             int left = blockLength;
 926             int off = 0;
 927             while (left > 0) {
 928                 int nbytes = stream.read(block, off, left);
 929                 left -= nbytes;
 930                 off += nbytes;
 931             }
 932 
 933             this.bitPos = 0;
 934             this.nextByte = 0;


 937 
 938             // Init 32-bit buffer
 939             initNext32Bits();
 940 
 941             this.clearCode = 1 << initCodeSize;
 942             this.eofCode = clearCode + 1;
 943 
 944             int code, oldCode = 0;
 945 
 946             int[] prefix = new int[4096];
 947             byte[] suffix = new byte[4096];
 948             byte[] initial = new byte[4096];
 949             int[] length = new int[4096];
 950             byte[] string = new byte[4096];
 951 
 952             initializeStringTable(prefix, suffix, initial, length);
 953             int tableIndex = (1 << initCodeSize) + 2;
 954             int codeSize = initCodeSize + 1;
 955             int codeMask = (1 << codeSize) - 1;
 956 
 957             do {
 958                 code = getCode(codeSize, codeMask);
 959 
 960                 if (code == clearCode) {
 961                     initializeStringTable(prefix, suffix, initial, length);
 962                     tableIndex = (1 << initCodeSize) + 2;
 963                     codeSize = initCodeSize + 1;
 964                     codeMask = (1 << codeSize) - 1;
 965 
 966                     code = getCode(codeSize, codeMask);
 967                     if (code == eofCode) {
 968                         // Inform IIOReadProgressListeners of end of image
 969                         processImageComplete();
 970                         return theImage;
 971                     }
 972                 } else if (code == eofCode) {
 973                     // Inform IIOReadProgressListeners of end of image
 974                     processImageComplete();
 975                     return theImage;
 976                 } else {
 977                     int newSuffixIndex;


 995                     length[ti] = length[oc] + 1;
 996 
 997                     ++tableIndex;
 998                     if ((tableIndex == (1 << codeSize)) &&
 999                         (tableIndex < 4096)) {
1000                         ++codeSize;
1001                         codeMask = (1 << codeSize) - 1;
1002                     }
1003                 }
1004 
1005                 // Reverse code
1006                 int c = code;
1007                 int len = length[c];
1008                 for (int i = len - 1; i >= 0; i--) {
1009                     string[i] = suffix[c];
1010                     c = prefix[c];
1011                 }
1012 
1013                 outputPixels(string, len);
1014                 oldCode = code;
1015             } while (!abortRequested());
1016 
1017             processReadAborted();
1018             return theImage;
1019         } catch (IOException e) {
1020             e.printStackTrace();
1021             throw new IIOException("I/O error reading image!", e);
1022         }
1023     }
1024 
1025     /**
1026      * Remove all settings including global settings such as
1027      * {@code Locale}s and listeners, as well as stream settings.
1028      */
1029     public void reset() {
1030         super.reset();
1031         resetStreamSettings();
1032     }
1033 
1034     /**
1035      * Remove local settings based on parsing of a stream.


< prev index next >