📄 jpegimagereader.java
字号:
knownPassCount++; } } } progInterval = Math.max((target.getHeight()-1) / 20, 1); if (knownPassCount > 0) { progInterval *= knownPassCount; } else if (maxProgressivePass != Integer.MAX_VALUE) { progInterval *= (maxProgressivePass - minProgressivePass + 1); } if (debug) { System.out.println("**** Read Data *****"); System.out.println("numRasterBands is " + numRasterBands); System.out.print("srcBands:"); for (int i = 0; i<srcBands.length;i++) System.out.print(" " + srcBands[i]); System.out.println(); System.out.println("destination bands is " + destinationBands); if (destinationBands != null) { for (int i = 0; i < destinationBands.length; i++) { System.out.print(" " + destinationBands[i]); } System.out.println(); } System.out.println("sourceROI is " + srcROI); System.out.println("destROI is " + destROI); System.out.println("periodX is " + periodX); System.out.println("periodY is " + periodY); System.out.println("minProgressivePass is " + minProgressivePass); System.out.println("maxProgressivePass is " + maxProgressivePass); System.out.println("callbackUpdates is " + callbackUpdates); } // Finally, we are ready to read processImageStarted(currentImage); boolean aborted = false; aborted = readImage(structPointer, buffer.getData(), numRasterBands, srcBands, bandSizes, srcROI.x, srcROI.y, srcROI.width, srcROI.height, periodX, periodY, abbrevQTables, abbrevDCHuffmanTables, abbrevACHuffmanTables, minProgressivePass, maxProgressivePass, callbackUpdates); if (aborted) { processReadAborted(); } else { processImageComplete(); } return target; } /** * This method is called back from C when the intermediate Raster * is full. The parameter indicates the scanline in the target * Raster to which the intermediate Raster should be copied. * After the copy, we notify update listeners. */ private void acceptPixels(int y, boolean progressive) { if (convert != null) { convert.filter(raster, raster); } target.setRect(destROI.x, destROI.y + y, raster); processImageUpdate(image, destROI.x, destROI.y+y, raster.getWidth(), 1, 1, 1, destinationBands); if ((y > 0) && (y%progInterval == 0)) { int height = target.getHeight()-1; float percentOfPass = ((float)y)/height; if (progressive) { if (knownPassCount != UNKNOWN) { processImageProgress((pass + percentOfPass)*100.0F / knownPassCount); } else if (maxProgressivePass != Integer.MAX_VALUE) { // Use the range of allowed progressive passes processImageProgress((pass + percentOfPass)*100.0F / (maxProgressivePass - minProgressivePass + 1)); } else { // Assume there are a minimum of MIN_ESTIMATED_PASSES // and that there is always one more pass // Compute the percentage as the percentage at the end // of the previous pass, plus the percentage of this // pass scaled to be the percentage of the total remaining, // assuming a minimum of MIN_ESTIMATED_PASSES passes and // that there is always one more pass. This is monotonic // and asymptotic to 1.0, which is what we need. int remainingPasses = // including this one Math.max(2, MIN_ESTIMATED_PASSES-pass); int totalPasses = pass + remainingPasses-1; progInterval = Math.max(height/20*totalPasses, totalPasses); if (y%progInterval == 0) { percentToDate = previousPassPercentage + (1.0F - previousPassPercentage) * (percentOfPass)/remainingPasses; if (debug) { System.out.print("pass= " + pass); System.out.print(", y= " + y); System.out.print(", progInt= " + progInterval); System.out.print(", % of pass: " + percentOfPass); System.out.print(", rem. passes: " + remainingPasses); System.out.print(", prev%: " + previousPassPercentage); System.out.print(", %ToDate: " + percentToDate); System.out.print(" "); } processImageProgress(percentToDate*100.0F); } } } else { processImageProgress(percentOfPass * 100.0F); } } } private void initProgressData() { knownPassCount = UNKNOWN; pass = 0; percentToDate = 0.0F; previousPassPercentage = 0.0F; progInterval = 0; } private void passStarted (int pass) { this.pass = pass; previousPassPercentage = percentToDate; processPassStarted(image, pass, minProgressivePass, maxProgressivePass, 0, 0, 1,1, destinationBands); } private void passComplete () { processPassComplete(image); } void thumbnailStarted(int thumbnailIndex) { processThumbnailStarted(currentImage, thumbnailIndex); } // Provide access to protected superclass method void thumbnailProgress(float percentageDone) { processThumbnailProgress(percentageDone); } // Provide access to protected superclass method void thumbnailComplete() { processThumbnailComplete(); } /** * Returns <code>true</code> if the read was aborted. */ private native boolean readImage(long structPointer, byte [] buffer, int numRasterBands, int [] srcBands, int [] bandSizes, int sourceXOffset, int sourceYOffset, int sourceWidth, int sourceHeight, int periodX, int periodY, JPEGQTable [] abbrevQTables, JPEGHuffmanTable [] abbrevDCHuffmanTables, JPEGHuffmanTable [] abbrevACHuffmanTables, int minProgressivePass, int maxProgressivePass, boolean wantUpdates); public void abort() { super.abort(); abortRead(structPointer); } /** Set the C level abort flag. Keep it atomic for thread safety. */ private native void abortRead(long structPointer); /** Resets library state when an exception occurred during a read. */ private native void resetLibraryState(long structPointer); public boolean canReadRaster() { return true; } public Raster readRaster(int imageIndex, ImageReadParam param) throws IOException { Raster retval = null; try { /* * This could be further optimized by not resetting the dest. * offset and creating a translated raster in readInternal() * (see bug 4994702 for more info). */ // For Rasters, destination offset is logical, not physical, so // set it to 0 before calling computeRegions, so that the destination // region is not clipped. Point saveDestOffset = null; if (param != null) { saveDestOffset = param.getDestinationOffset(); param.setDestinationOffset(new Point(0, 0)); } retval = readInternal(imageIndex, param, true); // Apply the destination offset, if any, as a logical offset if (saveDestOffset != null) { target = target.createWritableTranslatedChild(saveDestOffset.x, saveDestOffset.y); } } catch (RuntimeException e) { resetLibraryState(structPointer); throw e; } catch (IOException e) { resetLibraryState(structPointer); throw e; } return retval; } public boolean readerSupportsThumbnails() { return true; } public int getNumThumbnails(int imageIndex) throws IOException { getImageMetadata(imageIndex); // checks iis state for us // Now check the jfif segments JFIFMarkerSegment jfif = (JFIFMarkerSegment) imageMetadata.findMarkerSegment (JFIFMarkerSegment.class, true); int retval = 0; if (jfif != null) { retval = (jfif.thumb == null) ? 0 : 1; retval += jfif.extSegments.size(); } return retval; } public int getThumbnailWidth(int imageIndex, int thumbnailIndex) throws IOException { if ((thumbnailIndex < 0) || (thumbnailIndex >= getNumThumbnails(imageIndex))) { throw new IndexOutOfBoundsException("No such thumbnail"); } // Now we know that there is a jfif segment JFIFMarkerSegment jfif = (JFIFMarkerSegment) imageMetadata.findMarkerSegment (JFIFMarkerSegment.class, true); return jfif.getThumbnailWidth(thumbnailIndex); } public int getThumbnailHeight(int imageIndex, int thumbnailIndex) throws IOException { if ((thumbnailIndex < 0) || (thumbnailIndex >= getNumThumbnails(imageIndex))) { throw new IndexOutOfBoundsException("No such thumbnail"); } // Now we know that there is a jfif segment JFIFMarkerSegment jfif = (JFIFMarkerSegment) imageMetadata.findMarkerSegment (JFIFMarkerSegment.class, true); return jfif.getThumbnailHeight(thumbnailIndex); } public BufferedImage readThumbnail(int imageIndex, int thumbnailIndex) throws IOException { if ((thumbnailIndex < 0) || (thumbnailIndex >= getNumThumbnails(imageIndex))) { throw new IndexOutOfBoundsException("No such thumbnail"); } // Now we know that there is a jfif segment and that iis is good JFIFMarkerSegment jfif = (JFIFMarkerSegment) imageMetadata.findMarkerSegment (JFIFMarkerSegment.class, true); return jfif.getThumbnail(iis, thumbnailIndex, this); } private void resetInternalState() { // reset C structures resetReader(structPointer); // reset local Java structures numImages = 0; imagePositions = new ArrayList(); currentImage = -1; image = null; raster = null; target = null; buffer = null; destROI = null; destinationBands = null; streamMetadata = null; imageMetadata = null; imageMetadataIndex = -1; haveSeeked = false; tablesOnlyChecked = false; iccCS = null; initProgressData(); } /** * Note that there is no need to override reset() here, as the default * implementation will call setInput(null, false, false), which will * invoke resetInternalState(). */ private native void resetReader(long structPointer); public void dispose() { if (structPointer != 0) { disposerRecord.dispose(); structPointer = 0; } } private static native void disposeReader(long structPointer); private static class JPEGReaderDisposerRecord implements DisposerRecord { private long pData; public JPEGReaderDisposerRecord(long pData) { this.pData = pData; } public synchronized void dispose() { if (pData != 0) { disposeReader(pData); pData = 0; } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -