⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pngimagereader.java

📁 java jdk 1.4的源码
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
            curr[i + coff] = (byte)(raw + paethPredictor(priorPixel,                                                         priorRow,                                                         priorRowPixel));        }    }    private static final int[][] bandOffsets = {        null,        { 0 }, // G        { 0, 1 }, // GA in GA order        { 0, 1, 2 }, // RGB in RGB order        { 0, 1, 2, 3 } // RGBA in RGBA order    };    private WritableRaster createRaster(int width, int height, int bands,                                        int scanlineStride,                                        int bitDepth) {        DataBuffer dataBuffer;        WritableRaster ras = null;        Point origin = new Point(0, 0);        if ((bitDepth < 8) && (bands == 1)) {            dataBuffer = new DataBufferByte(height*scanlineStride);            ras = Raster.createPackedRaster(dataBuffer,                                            width, height,                                            bitDepth,                                            origin);        } else if (bitDepth <= 8) {            dataBuffer = new DataBufferByte(height*scanlineStride);            ras = Raster.createInterleavedRaster(dataBuffer,                                                 width, height,                                                 scanlineStride,                                                 bands,                                                 bandOffsets[bands],                                                 origin);        } else {            dataBuffer = new DataBufferUShort(height*scanlineStride);            ras = Raster.createInterleavedRaster(dataBuffer,                                                 width, height,                                                 scanlineStride,                                                 bands,                                                 bandOffsets[bands],                                                 origin);        }        return ras;    }    private void skipPass(int passWidth, int passHeight)        throws IOException, IIOException  {        if ((passWidth == 0) || (passHeight == 0)) {            return;        }        int inputBands = inputBandsForColorType[metadata.IHDR_colorType];        int bytesPerRow = (inputBands*passWidth*metadata.IHDR_bitDepth + 7)/8;        byte[] curr = new byte[bytesPerRow];        // Read the image row-by-row        for (int srcY = 0; srcY < passHeight; srcY++) {            // Read the filter type byte and a row of data            int filter = pixelStream.read();            pixelStream.readFully(curr, 0, bytesPerRow);            // If read has been aborted, just return            // processReadAborted will be called later            if (abortRequested()) {                return;            }        }    }    // Helper for protected computeUpdatedPixels method    private static void computeUpdatedPixels(int sourceOffset,                                             int sourceExtent,                                             int destinationOffset,                                             int dstMin,                                             int dstMax,                                             int sourceSubsampling,                                             int passStart,                                             int passExtent,                                             int passPeriod,                                             int[] vals,                                             int offset) {        // We need to satisfy the congruences:        // dst = destinationOffset + (src - sourceOffset)/sourceSubsampling        //        // src - passStart == 0 (mod passPeriod)        // src - sourceOffset == 0 (mod sourceSubsampling)        //        // subject to the inequalities:        //        // src >= passStart        // src < passStart + passExtent        // src >= sourceOffset        // src < sourceOffset + sourceExtent        // dst >= dstMin        // dst <= dstmax        //        // where        //        // dst = destinationOffset + (src - sourceOffset)/sourceSubsampling        //        // For now we use a brute-force approach although we could        // attempt to analyze the congruences.  If passPeriod and        // sourceSubsamling are relatively prime, the period will be        // their product.  If they share a common factor, either the        // period will be equal to the larger value, or the sequences        // will be completely disjoint, depending on the relationship        // between passStart and sourceOffset.  Since we only have to do this        // twice per image (once each for X and Y), it seems cheap enough        // to do it the straightforward way.        boolean gotPixel = false;        int firstDst = -1;        int secondDst = -1;        int lastDst = -1;        for (int i = 0; i < passExtent; i++) {            int src = passStart + i*passPeriod;            if (src < sourceOffset) {                continue;            }            if ((src - sourceOffset) % sourceSubsampling != 0) {                continue;            }            if (src >= sourceOffset + sourceExtent) {                break;            }            int dst = destinationOffset +                (src - sourceOffset)/sourceSubsampling;            if (dst < dstMin) {                continue;            }            if (dst > dstMax) {                break;            }            if (!gotPixel) {                firstDst = dst; // Record smallest valid pixel                gotPixel = true;            } else if (secondDst == -1) {                secondDst = dst; // Record second smallest valid pixel            }            lastDst = dst; // Record largest valid pixel        }        vals[offset] = firstDst;        // If we never saw a valid pixel, set width to 0        if (!gotPixel) {            vals[offset + 2] = 0;        } else {            vals[offset + 2] = lastDst - firstDst + 1;        }        // The period is given by the difference of any two adjacent pixels        vals[offset + 4] = Math.max(secondDst - firstDst, 1);    }    /**     * A utility method that computes the exact set of destination     * pixels that will be written during a particular decoding pass.     * The intent is to simplify the work done by readers in combining     * the source region, source subsampling, and destination offset     * information obtained from the <code>ImageReadParam</code> with     * the offsets and periods of a progressive or interlaced decoding     * pass.     *     * @param sourceRegion a <code>Rectangle</code> containing the     * source region being read, offset by the source subsampling     * offsets, and clipped against the source bounds, as returned by     * the <code>getSourceRegion</code> method.     * @param destinationOffset a <code>Point</code> containing the     * coordinates of the upper-left pixel to be written in the     * destination.     * @param dstMinX the smallest X coordinate (inclusive) of the     * destination <code>Raster</code>.     * @param dstMinY the smallest Y coordinate (inclusive) of the     * destination <code>Raster</code>.     * @param dstMaxX the largest X coordinate (inclusive) of the destination     * <code>Raster</code>.     * @param dstMaxY the largest Y coordinate (inclusive) of the destination     * <code>Raster</code>.     * @param sourceXSubsampling the X subsampling factor.     * @param sourceYSubsampling the Y subsampling factor.     * @param passXStart the smallest source X coordinate (inclusive)     * of the current progressive pass.     * @param passYStart the smallest source Y coordinate (inclusive)     * of the current progressive pass.     * @param passWidth the width in pixels of the current progressive     * pass.     * @param passHeight the height in pixels of the current progressive     * pass.     * @param passPeriodX the X period (horizontal spacing between     * pixels) of the current progressive pass.     * @param passPeriodY the Y period (vertical spacing between     * pixels) of the current progressive pass.     *     * @return an array of 6 <code>int</code>s containing the     * destination min X, min Y, width, height, X period and Y period     * of the region that will be updated.     */    private static int[] computeUpdatedPixels(Rectangle sourceRegion,                                              Point destinationOffset,                                              int dstMinX,                                              int dstMinY,                                              int dstMaxX,                                              int dstMaxY,                                              int sourceXSubsampling,                                              int sourceYSubsampling,                                              int passXStart,                                              int passYStart,                                              int passWidth,                                              int passHeight,                                              int passPeriodX,                                              int passPeriodY) {        int[] vals = new int[6];        computeUpdatedPixels(sourceRegion.x, sourceRegion.width,                             destinationOffset.x,                             dstMinX, dstMaxX, sourceXSubsampling,                             passXStart, passWidth, passPeriodX,                             vals, 0);        computeUpdatedPixels(sourceRegion.y, sourceRegion.height,                             destinationOffset.y,                             dstMinY, dstMaxY, sourceYSubsampling,                             passYStart, passHeight, passPeriodY,                             vals, 1);        return vals;    }    private void updateImageProgress(int newPixels) {        pixelsDone += newPixels;        processImageProgress(100.0F*pixelsDone/totalPixels);    }    private void decodePass(int passNum,                            int xStart, int yStart,                            int xStep, int yStep,                            int passWidth, int passHeight) throws IOException {        if ((passWidth == 0) || (passHeight == 0)) {            return;        }        WritableRaster imRas = theImage.getWritableTile(0, 0);        int dstMinX = imRas.getMinX();        int dstMaxX = dstMinX + imRas.getWidth() - 1;        int dstMinY = imRas.getMinY();        int dstMaxY = dstMinY + imRas.getHeight() - 1;        // Determine which pixels will be updated in this pass        int[] vals = computeUpdatedPixels(sourceRegion,                                          destinationOffset,                                          dstMinX, dstMinY,                                          dstMaxX, dstMaxY,                                          sourceXSubsampling,                                          sourceYSubsampling,                                          xStart, yStart,                                          passWidth, passHeight,                                          xStep, yStep);        int updateMinX = vals[0];        int updateMinY = vals[1];        int updateWidth = vals[2];        int updateXStep = vals[4];        int updateYStep = vals[5];        int bitDepth = metadata.IHDR_bitDepth;        int inputBands = inputBandsForColorType[metadata.IHDR_colorType];        int bytesPerPixel = (bitDepth == 16) ? 2 : 1;         bytesPerPixel *= inputBands;                int bytesPerRow = (inputBands*passWidth*bitDepth + 7)/8;        int eltsPerRow = (bitDepth == 16) ? bytesPerRow/2 : bytesPerRow;        // If no pixels need updating, just skip the input data         if (updateWidth == 0) {            for (int srcY = 0; srcY < passHeight; srcY++) {                // Update count of pixels read                updateImageProgress(passWidth);                pixelStream.skipBytes(1 + bytesPerRow);            }            return;        }                // Backwards map from destination pixels        // (dstX = updateMinX + k*updateXStep)        // to source pixels (sourceX), and then        // to offset and skip in passRow (srcX and srcXStep)          int sourceX =             (updateMinX - destinationOffset.x)*sourceXSubsampling +            sourceRegion.x;        int srcX = (sourceX - xStart)/xStep;                // Compute the step factor in the source         int srcXStep = updateXStep*sourceXSubsampling/xStep;        byte[] byteData = null;        short[] shortData = null;        byte[] curr = new byte[bytesPerRow];        byte[] prior = new byte[bytesPerRow];        // Create a 1-row tall Raster to hold the data        WritableRaster passRow = createRaster(passWidth, 1, inputBands,                                              eltsPerRow,                                              bitDepth);                // Create an array suitable for holding one pixel        int[] ps = passRow.getPixel(0, 0, (int[])null);                DataBuffer dataBuffer = passRow.getDataBuffer();        int type = dataBuffer.getDataType();        if (type == DataBuffer.TYPE_BYTE) {            byteData = ((DataBufferByte)dataBuffer).getData();        } else {            shortData = ((DataBufferUShort)dataBuffer).getData();        }                processPassStarted(theImage,                           passNum,                           sourceMinProgressivePass,                           sourceMaxProgressivePass,                           updateMinX, updateMinY,                           updateXStep, updateYStep,                           destinationBands);                // Handle source and destination bands        if (sourceBands != null) {            passRow = passRow.createWritableChild(0, 0,                                                  passRow.getWidth(), 1,                                                  0, 0,                                                  sourceBands);        }        if (destinationBands != null) {            imRas = imRas.createWritableChild(0, 0,                                              imRas.getWidth(),                                              imRas.getHeight(),                                              0, 0,                                              destinationBands);        }        // Determine if all of the relevant output bands have the        // same bit depth as the source data        boolean adjustBitDepths = false;        int[] outputSampleSize = imRas.getSampleModel().getSampleSize();        int numBands = outputSampleSize.length;        for (int b = 0; b < numBands; b++) {            if (outputSampleSize[b] != bitDepth) {                adjustBitDepths = true;                break;            }        }        // If the bit depths differ, create a lookup table per band to perform        // the conversion        int[][] scale = null;        if (adjustBitDepths) {            int maxInSample = (1 << bitDepth) - 1;            int halfMaxInSample = maxInSample/2;            scale = new int[numBands][];            for (int b = 0; b < numBands; b++) {                int maxOutSample = (1 << outputSampleSize[b]) - 1;                scale[b] = new int[maxInSample + 1];                for (int s = 0; s <= maxInSample; s++) {                    scale[b][s] =                        (s*maxOutSample + halfMaxInSample)/maxInSample;                }            }        }        // Limit passRow to relevant area for the case where we        // will can setRect to copy a contiguous span        boolean useSetRect = srcXStep == 1 &&            updateXStep == 1 &&            !adjustBitDepths;        if (useSetRect) {            passRow = passRow.createWritableChild(srcX, 0,                                                  updateWidth, 1,                                                   0, 0,                                                  null);        }        // Decode the (sub)image row-by-row        for (int srcY = 0; srcY < passHeight; srcY++) {            // Update count of pixels read

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -