< prev index next >

src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java

Print this page


   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


 199 
 200     private int minProgressivePass = 0;
 201     private int maxProgressivePass = Integer.MAX_VALUE;
 202 
 203     /**
 204      * Variables used by progress monitoring.
 205      */
 206     private static final int UNKNOWN = -1;  // Number of passes
 207     private static final int MIN_ESTIMATED_PASSES = 10; // IJG default
 208     private int knownPassCount = UNKNOWN;
 209     private int pass = 0;
 210     private float percentToDate = 0.0F;
 211     private float previousPassPercentage = 0.0F;
 212     private int progInterval = 0;
 213 
 214     /**
 215      * Set to true once stream has been checked for stream metadata
 216      */
 217     private boolean tablesOnlyChecked = false;
 218 





 219     /** The referent to be registered with the Disposer. */
 220     private Object disposerReferent = new Object();
 221 
 222     /** The DisposerRecord that handles the actual disposal of this reader. */
 223     private DisposerRecord disposerRecord;
 224 
 225     /** Sets up static C structures. */
 226     private static native void initReaderIDs(Class<?> iisClass,
 227                                              Class<?> qTableClass,
 228                                              Class<?> huffClass);
 229 
 230     public JPEGImageReader(ImageReaderSpi originator) {
 231         super(originator);
 232         structPointer = initJPEGImageReader();
 233         disposerRecord = new JPEGReaderDisposerRecord(structPointer);
 234         Disposer.addRecord(disposerReferent, disposerRecord);
 235     }
 236 
 237     /** Sets up per-reader C structure and returns a pointer to it. */
 238     private native long initJPEGImageReader();


 274         try {
 275             processWarningOccurred(msg);
 276         } finally {
 277             cbLock.unlock();
 278         }
 279     }
 280 
 281     public void setInput(Object input,
 282                          boolean seekForwardOnly,
 283                          boolean ignoreMetadata)
 284     {
 285         setThreadLock();
 286         try {
 287             cbLock.check();
 288 
 289             super.setInput(input, seekForwardOnly, ignoreMetadata);
 290             this.ignoreMetadata = ignoreMetadata;
 291             resetInternalState();
 292             iis = (ImageInputStream) input; // Always works
 293             setSource(structPointer);

 294         } finally {
 295             clearThreadLock();
 296         }
 297     }
 298 
 299     /**
 300      * This method is called from native code in order to fill
 301      * native input buffer.
 302      *
 303      * We block any attempt to change the reading state during this
 304      * method, in order to prevent a corruption of the native decoder
 305      * state.
 306      *
 307      * @return number of bytes read from the stream.
 308      */
 309     private int readInputData(byte[] buf, int off, int len) throws IOException {
 310         cbLock.lock();
 311         try {
 312             return iis.read(buf, off, len);
 313         } finally {


 347         boolean tablesOnly = readNativeHeader(true);
 348         if (tablesOnly) {
 349             if (debug) {
 350                 System.out.println("tables-only image found");
 351                 long pos = iis.getStreamPosition();
 352                 System.out.println("pos after return from native is " + pos);
 353             }
 354             // This reads the tables-only image twice, once from C
 355             // and once from Java, but only if ignoreMetadata is false
 356             if (ignoreMetadata == false) {
 357                 iis.seek(savePos);
 358                 haveSeeked = true;
 359                 streamMetadata = new JPEGMetadata(true, false,
 360                                                   iis, this);
 361                 long pos = iis.getStreamPosition();
 362                 if (debug) {
 363                     System.out.println
 364                         ("pos after constructing stream metadata is " + pos);
 365                 }
 366             }
 367             // Now we are at the first image if there are any, so add it
 368             // to the list

 369             if (hasNextImage()) {
 370                 imagePositions.add(iis.getStreamPosition());








 371             }
 372         } else { // Not tables only, so add original pos to the list
 373             imagePositions.add(savePos);
 374             // And set current image since we've read it now
 375             currentImage = 0;
 376         }
 377         if (seekForwardOnly) {






 378             Long pos = imagePositions.get(imagePositions.size()-1);
 379             iis.flushBefore(pos.longValue());
 380         }
 381         tablesOnlyChecked = true;
 382     }
 383 
 384     public int getNumImages(boolean allowSearch) throws IOException {
 385         setThreadLock();
 386         try { // locked thread
 387             cbLock.check();
 388 
 389             return getNumImagesOnThread(allowSearch);
 390         } finally {
 391             clearThreadLock();
 392         }
 393     }
 394 
 395     private void skipPastImage(int imageIndex) {
 396         cbLock.lock();
 397         try {


 474     }
 475 
 476     /**
 477      * Sets the input stream to the start of the requested image.
 478      * <pre>
 479      * @exception IllegalStateException if the input source has not been
 480      * set.
 481      * @exception IndexOutOfBoundsException if the supplied index is
 482      * out of bounds.
 483      * </pre>
 484      */
 485     private void gotoImage(int imageIndex) throws IOException {
 486         if (iis == null) {
 487             throw new IllegalStateException("Input not set");
 488         }
 489         if (imageIndex < minIndex) {
 490             throw new IndexOutOfBoundsException();
 491         }
 492         if (!tablesOnlyChecked) {
 493             checkTablesOnly();







 494         }
 495         if (imageIndex < imagePositions.size()) {
 496             iis.seek(imagePositions.get(imageIndex).longValue());
 497         } else {
 498             // read to start of image, saving positions
 499             // First seek to the last position we already have, and skip the
 500             // entire image
 501             Long pos = imagePositions.get(imagePositions.size()-1);
 502             iis.seek(pos.longValue());
 503             skipImage();
 504             // Now add all intervening positions, skipping images
 505             for (int index = imagePositions.size();
 506                  index <= imageIndex;
 507                  index++) {
 508                 // Is there an image?
 509                 if (!hasNextImage()) {
 510                     throw new IndexOutOfBoundsException();
 511                 }
 512                 pos = iis.getStreamPosition();
 513                 imagePositions.add(pos);


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


 199 
 200     private int minProgressivePass = 0;
 201     private int maxProgressivePass = Integer.MAX_VALUE;
 202 
 203     /**
 204      * Variables used by progress monitoring.
 205      */
 206     private static final int UNKNOWN = -1;  // Number of passes
 207     private static final int MIN_ESTIMATED_PASSES = 10; // IJG default
 208     private int knownPassCount = UNKNOWN;
 209     private int pass = 0;
 210     private float percentToDate = 0.0F;
 211     private float previousPassPercentage = 0.0F;
 212     private int progInterval = 0;
 213 
 214     /**
 215      * Set to true once stream has been checked for stream metadata
 216      */
 217     private boolean tablesOnlyChecked = false;
 218 
 219     /**
 220      * Set to true if the input stream contains only a tables-only image.
 221      */
 222     private boolean tablesOnlyStream = false;
 223 
 224     /** The referent to be registered with the Disposer. */
 225     private Object disposerReferent = new Object();
 226 
 227     /** The DisposerRecord that handles the actual disposal of this reader. */
 228     private DisposerRecord disposerRecord;
 229 
 230     /** Sets up static C structures. */
 231     private static native void initReaderIDs(Class<?> iisClass,
 232                                              Class<?> qTableClass,
 233                                              Class<?> huffClass);
 234 
 235     public JPEGImageReader(ImageReaderSpi originator) {
 236         super(originator);
 237         structPointer = initJPEGImageReader();
 238         disposerRecord = new JPEGReaderDisposerRecord(structPointer);
 239         Disposer.addRecord(disposerReferent, disposerRecord);
 240     }
 241 
 242     /** Sets up per-reader C structure and returns a pointer to it. */
 243     private native long initJPEGImageReader();


 279         try {
 280             processWarningOccurred(msg);
 281         } finally {
 282             cbLock.unlock();
 283         }
 284     }
 285 
 286     public void setInput(Object input,
 287                          boolean seekForwardOnly,
 288                          boolean ignoreMetadata)
 289     {
 290         setThreadLock();
 291         try {
 292             cbLock.check();
 293 
 294             super.setInput(input, seekForwardOnly, ignoreMetadata);
 295             this.ignoreMetadata = ignoreMetadata;
 296             resetInternalState();
 297             iis = (ImageInputStream) input; // Always works
 298             setSource(structPointer);
 299             tablesOnlyStream = false;
 300         } finally {
 301             clearThreadLock();
 302         }
 303     }
 304 
 305     /**
 306      * This method is called from native code in order to fill
 307      * native input buffer.
 308      *
 309      * We block any attempt to change the reading state during this
 310      * method, in order to prevent a corruption of the native decoder
 311      * state.
 312      *
 313      * @return number of bytes read from the stream.
 314      */
 315     private int readInputData(byte[] buf, int off, int len) throws IOException {
 316         cbLock.lock();
 317         try {
 318             return iis.read(buf, off, len);
 319         } finally {


 353         boolean tablesOnly = readNativeHeader(true);
 354         if (tablesOnly) {
 355             if (debug) {
 356                 System.out.println("tables-only image found");
 357                 long pos = iis.getStreamPosition();
 358                 System.out.println("pos after return from native is " + pos);
 359             }
 360             // This reads the tables-only image twice, once from C
 361             // and once from Java, but only if ignoreMetadata is false
 362             if (ignoreMetadata == false) {
 363                 iis.seek(savePos);
 364                 haveSeeked = true;
 365                 streamMetadata = new JPEGMetadata(true, false,
 366                                                   iis, this);
 367                 long pos = iis.getStreamPosition();
 368                 if (debug) {
 369                     System.out.println
 370                         ("pos after constructing stream metadata is " + pos);
 371                 }
 372             }
 373             /* Now we are at the first image if there are any, so add it
 374              * to the list.
 375              */
 376             if (hasNextImage()) {
 377                 imagePositions.add(iis.getStreamPosition());
 378             } else {
 379                 /*
 380                  * if there is no image data after reading the first tables-only
 381                  * image, we should store this state so that if user tries
 382                  * to read image data from this input stream we should throw
 383                  * an IIOException in gotoImage(int) function.
 384                  */
 385                 tablesOnlyStream = true;
 386             }
 387         } else { // Not tables only, so add original pos to the list
 388             imagePositions.add(savePos);
 389             // And set current image since we've read it now
 390             currentImage = 0;
 391         }
 392         /*
 393          * If imagePositions list doesn't contain any image stream starting
 394          * position(i.e tables-only image) we should not try to access
 395          * imagePositions.size() as it done below because it will lead to
 396          * IndexOutOfBoundsException for imagePositions list.
 397          */
 398         if (seekForwardOnly && (!(imagePositions.isEmpty()))) {
 399             Long pos = imagePositions.get(imagePositions.size()-1);
 400             iis.flushBefore(pos.longValue());
 401         }
 402         tablesOnlyChecked = true;
 403     }
 404 
 405     public int getNumImages(boolean allowSearch) throws IOException {
 406         setThreadLock();
 407         try { // locked thread
 408             cbLock.check();
 409 
 410             return getNumImagesOnThread(allowSearch);
 411         } finally {
 412             clearThreadLock();
 413         }
 414     }
 415 
 416     private void skipPastImage(int imageIndex) {
 417         cbLock.lock();
 418         try {


 495     }
 496 
 497     /**
 498      * Sets the input stream to the start of the requested image.
 499      * <pre>
 500      * @exception IllegalStateException if the input source has not been
 501      * set.
 502      * @exception IndexOutOfBoundsException if the supplied index is
 503      * out of bounds.
 504      * </pre>
 505      */
 506     private void gotoImage(int imageIndex) throws IOException {
 507         if (iis == null) {
 508             throw new IllegalStateException("Input not set");
 509         }
 510         if (imageIndex < minIndex) {
 511             throw new IndexOutOfBoundsException();
 512         }
 513         if (!tablesOnlyChecked) {
 514             checkTablesOnly();
 515         }
 516         /*
 517          * We should not try to read image information from an input stream
 518          * which only contains tables-only(StreamMetadata) information.
 519          */
 520         if (tablesOnlyStream) {
 521             throw new IIOException("No image data present to read");
 522         }
 523         if (imageIndex < imagePositions.size()) {
 524             iis.seek(imagePositions.get(imageIndex).longValue());
 525         } else {
 526             // read to start of image, saving positions
 527             // First seek to the last position we already have, and skip the
 528             // entire image
 529             Long pos = imagePositions.get(imagePositions.size()-1);
 530             iis.seek(pos.longValue());
 531             skipImage();
 532             // Now add all intervening positions, skipping images
 533             for (int index = imagePositions.size();
 534                  index <= imageIndex;
 535                  index++) {
 536                 // Is there an image?
 537                 if (!hasNextImage()) {
 538                     throw new IndexOutOfBoundsException();
 539                 }
 540                 pos = iis.getStreamPosition();
 541                 imagePositions.add(pos);


< prev index next >