public SerialColorModel(ComponentColorModel cmodel, ComponentSampleModel smodel) { cspace = cmodel.getColorSpace(); // is serializable pixelStride = smodel.getPixelStride(); scanlineStride = smodel.getScanlineStride(); bandOffsets = smodel.getBandOffsets(); hasAlpha = cmodel.hasAlpha(); alphaPre = cmodel.isAlphaPremultiplied(); transferType = cmodel.getTransferType(); transparency = cmodel.getTransparency(); }
/** * Encode the uncompressed source image stored in <code>srcImage</code> and output a YUV planar * image to the given destination buffer. See {@link #encodeYUV(byte[], int)} for more detail. * * @param srcImage a <code>BufferedImage</code> instance containing RGB or grayscale pixels to be * encoded * @param dstBuf buffer that will receive the YUV planar image. Use {@link TJ#bufSizeYUV} to * determine the appropriate size for this buffer based on the image width, height, and level * of chrominance subsampling. * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*} */ public void encodeYUV(BufferedImage srcImage, byte[] dstBuf, int flags) throws Exception { if (srcImage == null || dstBuf == null || flags < 0) throw new Exception("Invalid argument in encodeYUV()"); int width = srcImage.getWidth(); int height = srcImage.getHeight(); int pixelFormat; boolean intPixels = false; if (byteOrder == null) byteOrder = ByteOrder.nativeOrder(); switch (srcImage.getType()) { case BufferedImage.TYPE_3BYTE_BGR: pixelFormat = TJ.PF_BGR; break; case BufferedImage.TYPE_4BYTE_ABGR: case BufferedImage.TYPE_4BYTE_ABGR_PRE: pixelFormat = TJ.PF_XBGR; break; case BufferedImage.TYPE_BYTE_GRAY: pixelFormat = TJ.PF_GRAY; break; case BufferedImage.TYPE_INT_BGR: if (byteOrder == ByteOrder.BIG_ENDIAN) pixelFormat = TJ.PF_XBGR; else pixelFormat = TJ.PF_RGBX; intPixels = true; break; case BufferedImage.TYPE_INT_RGB: case BufferedImage.TYPE_INT_ARGB: case BufferedImage.TYPE_INT_ARGB_PRE: if (byteOrder == ByteOrder.BIG_ENDIAN) pixelFormat = TJ.PF_XRGB; else pixelFormat = TJ.PF_BGRX; intPixels = true; break; default: throw new Exception("Unsupported BufferedImage format"); } WritableRaster wr = srcImage.getRaster(); if (subsamp < 0) throw new Exception("Subsampling level not set"); if (intPixels) { SinglePixelPackedSampleModel sm = (SinglePixelPackedSampleModel) srcImage.getSampleModel(); int pitch = sm.getScanlineStride(); DataBufferInt db = (DataBufferInt) wr.getDataBuffer(); int[] buf = db.getData(); encodeYUV(buf, width, pitch, height, pixelFormat, dstBuf, subsamp, flags); } else { ComponentSampleModel sm = (ComponentSampleModel) srcImage.getSampleModel(); int pixelSize = sm.getPixelStride(); if (pixelSize != TJ.getPixelSize(pixelFormat)) throw new Exception("Inconsistency between pixel format and pixel size in BufferedImage"); int pitch = sm.getScanlineStride(); DataBufferByte db = (DataBufferByte) wr.getDataBuffer(); byte[] buf = db.getData(); encodeYUV(buf, width, pitch, height, pixelFormat, dstBuf, subsamp, flags); } compressedSize = TJ.bufSizeYUV(width, height, subsamp); }
protected static void divide_BYTE_COMP_Data(WritableRaster wr) { // System.out.println("Multiply Int: " + wr); ComponentSampleModel csm; csm = (ComponentSampleModel) wr.getSampleModel(); final int width = wr.getWidth(); final int scanStride = csm.getScanlineStride(); final int pixStride = csm.getPixelStride(); final int[] bandOff = csm.getBandOffsets(); DataBufferByte db = (DataBufferByte) wr.getDataBuffer(); final int base = (db.getOffset() + csm.getOffset( wr.getMinX() - wr.getSampleModelTranslateX(), wr.getMinY() - wr.getSampleModelTranslateY())); int a = 0; int aOff = bandOff[bandOff.length - 1]; int bands = bandOff.length - 1; int b, i; // Access the pixel data array final byte pixels[] = db.getBankData()[0]; for (int y = 0; y < wr.getHeight(); y++) { int sp = base + y * scanStride; final int end = sp + width * pixStride; while (sp < end) { a = pixels[sp + aOff] & 0xFF; if (a == 0) { for (b = 0; b < bands; b++) pixels[sp + bandOff[b]] = (byte) 0xFF; } else if (a < 255) { int aFP = (0x00FF0000 / a); for (b = 0; b < bands; b++) { i = sp + bandOff[b]; pixels[i] = (byte) (((pixels[i] & 0xFF) * aFP) >>> 16); } } sp += pixStride; } } }
private static void initImg(BufferedImage img, int pf, int flags) throws Exception { WritableRaster wr = img.getRaster(); int imgType = img.getType(); if (imgType == BufferedImage.TYPE_INT_RGB || imgType == BufferedImage.TYPE_INT_BGR || imgType == BufferedImage.TYPE_INT_ARGB || imgType == BufferedImage.TYPE_INT_ARGB_PRE) { SinglePixelPackedSampleModel sm = (SinglePixelPackedSampleModel) img.getSampleModel(); int pitch = sm.getScanlineStride(); DataBufferInt db = (DataBufferInt) wr.getDataBuffer(); int[] buf = db.getData(); initIntBuf(buf, img.getWidth(), pitch, img.getHeight(), pf, flags); } else { ComponentSampleModel sm = (ComponentSampleModel) img.getSampleModel(); int pitch = sm.getScanlineStride(); DataBufferByte db = (DataBufferByte) wr.getDataBuffer(); byte[] buf = db.getData(); initBuf(buf, img.getWidth(), pitch, img.getHeight(), pf, flags); } }
private Raster readSubsampledRaster(WritableRaster raster) throws IOException { if (raster == null) raster = Raster.createWritableRaster( sampleModel.createCompatibleSampleModel( destinationRegion.x + destinationRegion.width, destinationRegion.y + destinationRegion.height), new Point(destinationRegion.x, destinationRegion.y)); int numBands = sourceBands.length; int dataType = sampleModel.getDataType(); int sampleSizeBit = DataBuffer.getDataTypeSize(dataType); int sampleSizeByte = (sampleSizeBit + 7) / 8; Rectangle destRect = raster.getBounds().intersection(destinationRegion); int offx = destinationRegion.x; int offy = destinationRegion.y; int sourceSX = (destRect.x - offx) * scaleX + sourceOrigin.x; int sourceSY = (destRect.y - offy) * scaleY + sourceOrigin.y; int sourceEX = (destRect.width - 1) * scaleX + sourceSX; int sourceEY = (destRect.height - 1) * scaleY + sourceSY; int startXTile = sourceSX / tileWidth; int startYTile = sourceSY / tileHeight; int endXTile = sourceEX / tileWidth; int endYTile = sourceEY / tileHeight; startXTile = clip(startXTile, 0, maxXTile); startYTile = clip(startYTile, 0, maxYTile); endXTile = clip(endXTile, 0, maxXTile); endYTile = clip(endYTile, 0, maxYTile); int totalXTiles = getNumXTiles(); int totalYTiles = getNumYTiles(); int totalTiles = totalXTiles * totalYTiles; // The line buffer for the source byte[] pixbuf = null; // byte buffer for the decoded pixels. short[] spixbuf = null; // byte buffer for the decoded pixels. int[] ipixbuf = null; // byte buffer for the decoded pixels. float[] fpixbuf = null; // byte buffer for the decoded pixels. double[] dpixbuf = null; // byte buffer for the decoded pixels. // A flag to show the ComponentSampleModel has a single data bank boolean singleBank = true; int pixelStride = 0; int scanlineStride = 0; int bandStride = 0; int[] bandOffsets = null; int[] bankIndices = null; if (originalSampleModel instanceof ComponentSampleModel) { ComponentSampleModel csm = (ComponentSampleModel) originalSampleModel; bankIndices = csm.getBankIndices(); int maxBank = 0; for (int i = 0; i < bankIndices.length; i++) if (maxBank > bankIndices[i]) maxBank = bankIndices[i]; if (maxBank > 0) singleBank = false; pixelStride = csm.getPixelStride(); scanlineStride = csm.getScanlineStride(); bandOffsets = csm.getBandOffsets(); for (int i = 0; i < bandOffsets.length; i++) if (bandStride < bandOffsets[i]) bandStride = bandOffsets[i]; } else if (originalSampleModel instanceof MultiPixelPackedSampleModel) { scanlineStride = ((MultiPixelPackedSampleModel) originalSampleModel).getScanlineStride(); } else if (originalSampleModel instanceof SinglePixelPackedSampleModel) { pixelStride = 1; scanlineStride = ((SinglePixelPackedSampleModel) originalSampleModel).getScanlineStride(); } // The dstination buffer for the raster byte[] destPixbuf = null; // byte buffer for the decoded pixels. short[] destSPixbuf = null; // byte buffer for the decoded pixels. int[] destIPixbuf = null; // byte buffer for the decoded pixels. float[] destFPixbuf = null; // byte buffer for the decoded pixels. double[] destDPixbuf = null; // byte buffer for the decoded pixels. int[] destBandOffsets = null; int destPixelStride = 0; int destScanlineStride = 0; int destSX = 0; // The first pixel for the destionation if (raster.getSampleModel() instanceof ComponentSampleModel) { ComponentSampleModel csm = (ComponentSampleModel) raster.getSampleModel(); bankIndices = csm.getBankIndices(); destBandOffsets = csm.getBandOffsets(); destPixelStride = csm.getPixelStride(); destScanlineStride = csm.getScanlineStride(); destSX = csm.getOffset( raster.getMinX() - raster.getSampleModelTranslateX(), raster.getMinY() - raster.getSampleModelTranslateY()) - destBandOffsets[0]; switch (dataType) { case DataBuffer.TYPE_BYTE: destPixbuf = ((DataBufferByte) raster.getDataBuffer()).getData(); break; case DataBuffer.TYPE_SHORT: destSPixbuf = ((DataBufferShort) raster.getDataBuffer()).getData(); break; case DataBuffer.TYPE_USHORT: destSPixbuf = ((DataBufferUShort) raster.getDataBuffer()).getData(); break; case DataBuffer.TYPE_INT: destIPixbuf = ((DataBufferInt) raster.getDataBuffer()).getData(); break; case DataBuffer.TYPE_FLOAT: destFPixbuf = ((DataBufferFloat) raster.getDataBuffer()).getData(); break; case DataBuffer.TYPE_DOUBLE: destDPixbuf = ((DataBufferDouble) raster.getDataBuffer()).getData(); break; } } else if (raster.getSampleModel() instanceof SinglePixelPackedSampleModel) { numBands = 1; bankIndices = new int[] {0}; destBandOffsets = new int[numBands]; for (int i = 0; i < numBands; i++) destBandOffsets[i] = 0; destPixelStride = 1; destScanlineStride = ((SinglePixelPackedSampleModel) raster.getSampleModel()).getScanlineStride(); } // Start the data delivery to the cached consumers tile by tile for (int y = startYTile; y <= endYTile; y++) { if (reader.getAbortRequest()) break; // Loop on horizontal tiles for (int x = startXTile; x <= endXTile; x++) { if (reader.getAbortRequest()) break; long tilePosition = position + (y * originalNumXTiles + x) * tileDataSize; iis.seek(tilePosition); float percentage = (x - startXTile + y * totalXTiles) / totalXTiles; int startX = x * tileWidth; int startY = y * tileHeight; int cTileHeight = tileHeight; int cTileWidth = tileWidth; if (startY + cTileHeight >= originalDimension.height) cTileHeight = originalDimension.height - startY; if (startX + cTileWidth >= originalDimension.width) cTileWidth = originalDimension.width - startX; int tx = startX; int ty = startY; // If source start position calculated by taking subsampling // into account is after the tile's start X position, adjust // the start position accordingly if (sourceSX > startX) { cTileWidth += startX - sourceSX; tx = sourceSX; startX = sourceSX; } if (sourceSY > startY) { cTileHeight += startY - sourceSY; ty = sourceSY; startY = sourceSY; } // If source end position calculated by taking subsampling // into account is prior to the tile's end X position, adjust // the tile width to read accordingly if (sourceEX < startX + cTileWidth - 1) { cTileWidth += sourceEX - startX - cTileWidth + 1; } if (sourceEY < startY + cTileHeight - 1) { cTileHeight += sourceEY - startY - cTileHeight + 1; } // The start X in the destination int x1 = (startX + scaleX - 1 - sourceOrigin.x) / scaleX; int x2 = (startX + scaleX - 1 + cTileWidth - sourceOrigin.x) / scaleX; int lineLength = x2 - x1; x2 = (x2 - 1) * scaleX + sourceOrigin.x; int y1 = (startY + scaleY - 1 - sourceOrigin.y) / scaleY; startX = x1 * scaleX + sourceOrigin.x; startY = y1 * scaleY + sourceOrigin.y; // offx is destination.x x1 += offx; y1 += offy; tx -= x * tileWidth; ty -= y * tileHeight; if (sampleModel instanceof MultiPixelPackedSampleModel) { MultiPixelPackedSampleModel mppsm = (MultiPixelPackedSampleModel) originalSampleModel; iis.skipBytes(mppsm.getOffset(tx, ty) * sampleSizeByte); int readBytes = (mppsm.getOffset(x2, 0) - mppsm.getOffset(startX, 0) + 1) * sampleSizeByte; int skipLength = (scanlineStride * scaleY - readBytes) * sampleSizeByte; readBytes *= sampleSizeByte; if (pixbuf == null || pixbuf.length < readBytes) pixbuf = new byte[readBytes]; int bitoff = mppsm.getBitOffset(tx); for (int l = 0, m = y1; l < cTileHeight; l += scaleY, m++) { if (reader.getAbortRequest()) break; iis.readFully(pixbuf, 0, readBytes); if (scaleX == 1) { if (bitoff != 0) { int mask1 = (255 << bitoff) & 255; int mask2 = ~mask1 & 255; int shift = 8 - bitoff; int n = 0; for (; n < readBytes - 1; n++) pixbuf[n] = (byte) (((pixbuf[n] & mask2) << shift) | (pixbuf[n + 1] & mask1) >> bitoff); pixbuf[n] = (byte) ((pixbuf[n] & mask2) << shift); } } else { int bit = 7; int pos = 0; int mask = 128; for (int n = 0, n1 = startX & 7; n < lineLength; n++, n1 += scaleX) { pixbuf[pos] = (byte) ((pixbuf[pos] & ~(1 << bit)) | (((pixbuf[n1 >> 3] >> (7 - (n1 & 7))) & 1) << bit)); bit--; if (bit == -1) { bit = 7; pos++; } } } ImageUtil.setPackedBinaryData(pixbuf, raster, new Rectangle(x1, m, lineLength, 1)); iis.skipBytes(skipLength); if (destImage != null) reader.processImageUpdateWrapper( destImage, x1, m, cTileWidth, 1, 1, 1, destinationBands); reader.processImageProgressWrapper( percentage + (l - startY + 1.0F) / cTileHeight / totalTiles); } } else { int readLength, skipLength; if (pixelStride < scanlineStride) { readLength = cTileWidth * pixelStride; skipLength = (scanlineStride * scaleY - readLength) * sampleSizeByte; } else { readLength = cTileHeight * scanlineStride; skipLength = (pixelStride * scaleX - readLength) * sampleSizeByte; } // Allocate buffer for all the types switch (sampleModel.getDataType()) { case DataBuffer.TYPE_BYTE: if (pixbuf == null || pixbuf.length < readLength) pixbuf = new byte[readLength]; break; case DataBuffer.TYPE_SHORT: case DataBuffer.TYPE_USHORT: if (spixbuf == null || spixbuf.length < readLength) spixbuf = new short[readLength]; break; case DataBuffer.TYPE_INT: if (ipixbuf == null || ipixbuf.length < readLength) ipixbuf = new int[readLength]; break; case DataBuffer.TYPE_FLOAT: if (fpixbuf == null || fpixbuf.length < readLength) fpixbuf = new float[readLength]; break; case DataBuffer.TYPE_DOUBLE: if (dpixbuf == null || dpixbuf.length < readLength) dpixbuf = new double[readLength]; break; } if (sampleModel instanceof PixelInterleavedSampleModel) { iis.skipBytes((tx * pixelStride + ty * scanlineStride) * sampleSizeByte); // variables for ther loop int outerFirst, outerSecond, outerStep, outerBound; int innerStep, innerStep1, outerStep1; if (pixelStride < scanlineStride) { outerFirst = 0; outerSecond = y1; outerStep = scaleY; outerBound = cTileHeight; innerStep = scaleX * pixelStride; innerStep1 = destPixelStride; outerStep1 = destScanlineStride; } else { outerFirst = 0; outerSecond = x1; outerStep = scaleX; outerBound = cTileWidth; innerStep = scaleY * scanlineStride; innerStep1 = destScanlineStride; outerStep1 = destPixelStride; } int destPos = destSX + (y1 - raster.getSampleModelTranslateY()) * destScanlineStride + (x1 - raster.getSampleModelTranslateX()) * destPixelStride; for (int l = outerFirst, m = outerSecond; l < outerBound; l += outerStep, m++) { if (reader.getAbortRequest()) break; switch (dataType) { case DataBuffer.TYPE_BYTE: if (innerStep == numBands && innerStep1 == numBands) iis.readFully(destPixbuf, destPos, readLength); else iis.readFully(pixbuf, 0, readLength); break; case DataBuffer.TYPE_SHORT: case DataBuffer.TYPE_USHORT: if (innerStep == numBands && innerStep1 == numBands) { iis.readFully(destSPixbuf, destPos, readLength); } else iis.readFully(spixbuf, 0, readLength); break; case DataBuffer.TYPE_INT: if (innerStep == numBands && innerStep1 == numBands) iis.readFully(destIPixbuf, destPos, readLength); else iis.readFully(ipixbuf, 0, readLength); break; case DataBuffer.TYPE_FLOAT: if (innerStep == numBands && innerStep1 == numBands) iis.readFully(destFPixbuf, destPos, readLength); else iis.readFully(fpixbuf, 0, readLength); break; case DataBuffer.TYPE_DOUBLE: if (innerStep == numBands && innerStep1 == numBands) iis.readFully(destDPixbuf, destPos, readLength); else iis.readFully(dpixbuf, 0, readLength); break; } if (innerStep != numBands || innerStep1 != numBands) for (int b = 0; b < numBands; b++) { int destBandOffset = destBandOffsets[destinationBands[b]]; destPos += destBandOffset; int sourceBandOffset = bandOffsets[sourceBands[b]]; switch (dataType) { case DataBuffer.TYPE_BYTE: for (int m1 = 0, n = destPos; m1 < readLength; m1 += innerStep, n += innerStep1) { destPixbuf[n] = pixbuf[m1 + sourceBandOffset]; } break; case DataBuffer.TYPE_SHORT: case DataBuffer.TYPE_USHORT: for (int m1 = 0, n = destPos; m1 < readLength; m1 += innerStep, n += innerStep1) { destSPixbuf[n] = spixbuf[m1 + sourceBandOffset]; } break; case DataBuffer.TYPE_INT: for (int m1 = 0, n = destPos; m1 < readLength; m1 += innerStep, n += innerStep1) { destIPixbuf[n] = ipixbuf[m1 + sourceBandOffset]; } break; case DataBuffer.TYPE_FLOAT: for (int m1 = 0, n = destPos; m1 < readLength; m1 += innerStep, n += innerStep1) { destFPixbuf[n] = fpixbuf[m1 + sourceBandOffset]; } break; case DataBuffer.TYPE_DOUBLE: for (int m1 = 0, n = destPos; m1 < readLength; m1 += innerStep, n += innerStep1) { destDPixbuf[n] = dpixbuf[m1 + sourceBandOffset]; } break; } destPos -= destBandOffset; } iis.skipBytes(skipLength); destPos += outerStep1; if (destImage != null) if (pixelStride < scanlineStride) reader.processImageUpdateWrapper( destImage, x1, m, outerBound, 1, 1, 1, destinationBands); else reader.processImageUpdateWrapper( destImage, m, y1, 1, outerBound, 1, 1, destinationBands); reader.processImageProgressWrapper(percentage + (l + 1.0F) / outerBound / totalTiles); } } else if (sampleModel instanceof BandedSampleModel || sampleModel instanceof SinglePixelPackedSampleModel || bandStride == 0) { boolean isBanded = sampleModel instanceof BandedSampleModel; int bandSize = (int) ImageUtil.getBandSize(originalSampleModel); for (int b = 0; b < numBands; b++) { iis.seek(tilePosition + bandSize * sourceBands[b] * sampleSizeByte); int destBandOffset = destBandOffsets[destinationBands[b]]; iis.skipBytes((ty * scanlineStride + tx * pixelStride) * sampleSizeByte); // variables for ther loop int outerFirst, outerSecond, outerStep, outerBound; int innerStep, innerStep1, outerStep1; if (pixelStride < scanlineStride) { outerFirst = 0; outerSecond = y1; outerStep = scaleY; outerBound = cTileHeight; innerStep = scaleX * pixelStride; innerStep1 = destPixelStride; outerStep1 = destScanlineStride; } else { outerFirst = 0; outerSecond = x1; outerStep = scaleX; outerBound = cTileWidth; innerStep = scaleY * scanlineStride; innerStep1 = destScanlineStride; outerStep1 = destPixelStride; } int destPos = destSX + (y1 - raster.getSampleModelTranslateY()) * destScanlineStride + (x1 - raster.getSampleModelTranslateX()) * destPixelStride + destBandOffset; int bank = bankIndices[destinationBands[b]]; switch (dataType) { case DataBuffer.TYPE_BYTE: destPixbuf = ((DataBufferByte) raster.getDataBuffer()).getData(bank); break; case DataBuffer.TYPE_SHORT: destSPixbuf = ((DataBufferShort) raster.getDataBuffer()).getData(bank); break; case DataBuffer.TYPE_USHORT: destSPixbuf = ((DataBufferUShort) raster.getDataBuffer()).getData(bank); break; case DataBuffer.TYPE_INT: destIPixbuf = ((DataBufferInt) raster.getDataBuffer()).getData(bank); break; case DataBuffer.TYPE_FLOAT: destFPixbuf = ((DataBufferFloat) raster.getDataBuffer()).getData(bank); break; case DataBuffer.TYPE_DOUBLE: destDPixbuf = ((DataBufferDouble) raster.getDataBuffer()).getData(bank); break; } for (int l = outerFirst, m = outerSecond; l < outerBound; l += outerStep, m++) { if (reader.getAbortRequest()) break; switch (dataType) { case DataBuffer.TYPE_BYTE: if (innerStep == 1 && innerStep1 == 1) { iis.readFully(destPixbuf, destPos, readLength); } else { iis.readFully(pixbuf, 0, readLength); for (int m1 = 0, n = destPos; m1 < readLength; m1 += innerStep, n += innerStep1) { destPixbuf[n] = pixbuf[m1]; } } break; case DataBuffer.TYPE_SHORT: case DataBuffer.TYPE_USHORT: if (innerStep == 1 && innerStep1 == 1) { iis.readFully(destSPixbuf, destPos, readLength); } else { iis.readFully(spixbuf, 0, readLength); for (int m1 = 0, n = destPos; m1 < readLength; m1 += innerStep, n += innerStep1) { destSPixbuf[n] = spixbuf[m1]; } } break; case DataBuffer.TYPE_INT: if (innerStep == 1 && innerStep1 == 1) { iis.readFully(destIPixbuf, destPos, readLength); } else { iis.readFully(ipixbuf, 0, readLength); for (int m1 = 0, n = destPos; m1 < readLength; m1 += innerStep, n += innerStep1) { destIPixbuf[n] = ipixbuf[m1]; } } break; case DataBuffer.TYPE_FLOAT: if (innerStep == 1 && innerStep1 == 1) { iis.readFully(destFPixbuf, destPos, readLength); } else { iis.readFully(fpixbuf, 0, readLength); for (int m1 = 0, n = destPos; m1 < readLength; m1 += innerStep, n += innerStep1) { destFPixbuf[n] = fpixbuf[m1]; } } break; case DataBuffer.TYPE_DOUBLE: if (innerStep == 1 && innerStep1 == 1) { iis.readFully(destDPixbuf, destPos, readLength); } else { iis.readFully(dpixbuf, 0, readLength); for (int m1 = 0, n = destPos; m1 < readLength; m1 += innerStep, n += innerStep1) { destDPixbuf[n] = dpixbuf[m1]; } } break; } iis.skipBytes(skipLength); destPos += outerStep1; if (destImage != null) { int[] destBands = new int[] {destinationBands[b]}; if (pixelStride < scanlineStride) reader.processImageUpdateWrapper( destImage, x1, m, outerBound, 1, 1, 1, destBands); else reader.processImageUpdateWrapper( destImage, m, y1, 1, outerBound, 1, 1, destBands); } reader.processImageProgressWrapper( (percentage + (l + 1.0F) / outerBound / numBands / totalTiles) * 100.0F); } } } else if (sampleModel instanceof ComponentSampleModel) { // for the other case, may slow // Allocate buffer for all the types int bufferSize = (int) tileDataSize; switch (sampleModel.getDataType()) { case DataBuffer.TYPE_BYTE: if (pixbuf == null || pixbuf.length < tileDataSize) pixbuf = new byte[(int) tileDataSize]; iis.readFully(pixbuf, 0, (int) tileDataSize); break; case DataBuffer.TYPE_SHORT: case DataBuffer.TYPE_USHORT: bufferSize /= 2; if (spixbuf == null || spixbuf.length < bufferSize) spixbuf = new short[(int) bufferSize]; iis.readFully(spixbuf, 0, (int) bufferSize); break; case DataBuffer.TYPE_INT: bufferSize /= 4; if (ipixbuf == null || ipixbuf.length < bufferSize) ipixbuf = new int[(int) bufferSize]; iis.readFully(ipixbuf, 0, (int) bufferSize); break; case DataBuffer.TYPE_FLOAT: bufferSize /= 4; if (fpixbuf == null || fpixbuf.length < bufferSize) fpixbuf = new float[(int) bufferSize]; iis.readFully(fpixbuf, 0, (int) bufferSize); break; case DataBuffer.TYPE_DOUBLE: bufferSize /= 8; if (dpixbuf == null || dpixbuf.length < bufferSize) dpixbuf = new double[(int) bufferSize]; iis.readFully(dpixbuf, 0, (int) bufferSize); break; } for (int b = 0; b < numBands; b++) { int destBandOffset = destBandOffsets[destinationBands[b]]; int destPos = ((ComponentSampleModel) raster.getSampleModel()) .getOffset( x1 - raster.getSampleModelTranslateX(), y1 - raster.getSampleModelTranslateY(), destinationBands[b]); int bank = bankIndices[destinationBands[b]]; switch (dataType) { case DataBuffer.TYPE_BYTE: destPixbuf = ((DataBufferByte) raster.getDataBuffer()).getData(bank); break; case DataBuffer.TYPE_SHORT: destSPixbuf = ((DataBufferShort) raster.getDataBuffer()).getData(bank); break; case DataBuffer.TYPE_USHORT: destSPixbuf = ((DataBufferUShort) raster.getDataBuffer()).getData(bank); break; case DataBuffer.TYPE_INT: destIPixbuf = ((DataBufferInt) raster.getDataBuffer()).getData(bank); break; case DataBuffer.TYPE_FLOAT: destFPixbuf = ((DataBufferFloat) raster.getDataBuffer()).getData(bank); break; case DataBuffer.TYPE_DOUBLE: destDPixbuf = ((DataBufferDouble) raster.getDataBuffer()).getData(bank); break; } int srcPos = ((ComponentSampleModel) originalSampleModel).getOffset(tx, ty, sourceBands[b]); int skipX = scaleX * pixelStride; ; for (int l = 0, m = y1; l < cTileHeight; l += scaleY, m++) { if (reader.getAbortRequest()) break; switch (dataType) { case DataBuffer.TYPE_BYTE: for (int n = 0, m1 = srcPos, m2 = destPos; n < lineLength; n++, m1 += skipX, m2 += destPixelStride) destPixbuf[m2] = pixbuf[m1]; break; case DataBuffer.TYPE_SHORT: case DataBuffer.TYPE_USHORT: for (int n = 0, m1 = srcPos, m2 = destPos; n < lineLength; n++, m1 += skipX, m2 += destPixelStride) destSPixbuf[m2] = spixbuf[m1]; break; case DataBuffer.TYPE_INT: for (int n = 0, m1 = srcPos, m2 = destPos; n < lineLength; n++, m1 += skipX, m2 += destPixelStride) destIPixbuf[m2] = ipixbuf[m1]; break; case DataBuffer.TYPE_FLOAT: for (int n = 0, m1 = srcPos, m2 = destPos; n < lineLength; n++, m1 += skipX, m2 += destPixelStride) destFPixbuf[m2] = fpixbuf[m1]; break; case DataBuffer.TYPE_DOUBLE: for (int n = 0, m1 = srcPos, m2 = destPos; n < lineLength; n++, m1 += skipX, m2 += destPixelStride) destDPixbuf[m2] = dpixbuf[m1]; break; } destPos += destScanlineStride; srcPos += scanlineStride * scaleY; if (destImage != null) { int[] destBands = new int[] {destinationBands[b]}; reader.processImageUpdateWrapper( destImage, x1, m, cTileHeight, 1, 1, 1, destBands); } reader.processImageProgressWrapper( percentage + (l + 1.0F) / cTileHeight / numBands / totalTiles); } } } else { throw new IllegalArgumentException(I18N.getString("RawRenderedImage1")); } } } // End loop on horizontal tiles } // End loop on vertical tiles return raster; }
private void writeRasterData( RenderedImage image, Rectangle sourceBounds, Dimension destSize, ImageWriteParam param, boolean interlaceFlag) throws IOException { int sourceXOffset = sourceBounds.x; int sourceYOffset = sourceBounds.y; int sourceWidth = sourceBounds.width; int sourceHeight = sourceBounds.height; int destWidth = destSize.width; int destHeight = destSize.height; int periodX; int periodY; if (param == null) { periodX = 1; periodY = 1; } else { periodX = param.getSourceXSubsampling(); periodY = param.getSourceYSubsampling(); } SampleModel sampleModel = image.getSampleModel(); int bitsPerPixel = sampleModel.getSampleSize()[0]; int initCodeSize = bitsPerPixel; if (initCodeSize == 1) { initCodeSize++; } stream.write(initCodeSize); LZWCompressor compressor = new LZWCompressor(stream, initCodeSize, false); boolean isOptimizedCase = periodX == 1 && periodY == 1 && sampleModel instanceof ComponentSampleModel && image.getNumXTiles() == 1 && image.getNumYTiles() == 1 && image.getTile(0, 0).getDataBuffer() instanceof DataBufferByte; int numRowsWritten = 0; int progressReportRowPeriod = Math.max(destHeight / 20, 1); processImageStarted(imageIndex); if (interlaceFlag) { if (DEBUG) System.out.println("Writing interlaced"); if (isOptimizedCase) { Raster tile = image.getTile(0, 0); byte[] data = ((DataBufferByte) tile.getDataBuffer()).getData(); ComponentSampleModel csm = (ComponentSampleModel) tile.getSampleModel(); int offset = csm.getOffset( sourceXOffset - tile.getSampleModelTranslateX(), sourceYOffset - tile.getSampleModelTranslateY(), 0); int lineStride = csm.getScanlineStride(); writeRowsOpt( data, offset, lineStride, compressor, 0, 8, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); if (abortRequested()) { return; } numRowsWritten += destHeight / 8; writeRowsOpt( data, offset, lineStride, compressor, 4, 8, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); if (abortRequested()) { return; } numRowsWritten += (destHeight - 4) / 8; writeRowsOpt( data, offset, lineStride, compressor, 2, 4, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); if (abortRequested()) { return; } numRowsWritten += (destHeight - 2) / 4; writeRowsOpt( data, offset, lineStride, compressor, 1, 2, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); } else { writeRows( image, compressor, sourceXOffset, periodX, sourceYOffset, 8 * periodY, sourceWidth, 0, 8, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); if (abortRequested()) { return; } numRowsWritten += destHeight / 8; writeRows( image, compressor, sourceXOffset, periodX, sourceYOffset + 4 * periodY, 8 * periodY, sourceWidth, 4, 8, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); if (abortRequested()) { return; } numRowsWritten += (destHeight - 4) / 8; writeRows( image, compressor, sourceXOffset, periodX, sourceYOffset + 2 * periodY, 4 * periodY, sourceWidth, 2, 4, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); if (abortRequested()) { return; } numRowsWritten += (destHeight - 2) / 4; writeRows( image, compressor, sourceXOffset, periodX, sourceYOffset + periodY, 2 * periodY, sourceWidth, 1, 2, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); } } else { if (DEBUG) System.out.println("Writing non-interlaced"); if (isOptimizedCase) { Raster tile = image.getTile(0, 0); byte[] data = ((DataBufferByte) tile.getDataBuffer()).getData(); ComponentSampleModel csm = (ComponentSampleModel) tile.getSampleModel(); int offset = csm.getOffset( sourceXOffset - tile.getSampleModelTranslateX(), sourceYOffset - tile.getSampleModelTranslateY(), 0); int lineStride = csm.getScanlineStride(); writeRowsOpt( data, offset, lineStride, compressor, 0, 1, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); } else { writeRows( image, compressor, sourceXOffset, periodX, sourceYOffset, periodY, sourceWidth, 0, 1, destWidth, destHeight, numRowsWritten, progressReportRowPeriod); } } if (abortRequested()) { return; } processImageProgress(100.0F); compressor.flush(); stream.write(0x00); processImageComplete(); }
/** * Decompress the JPEG source image associated with this decompressor instance and output a * decompressed image to the given <code>BufferedImage</code> instance. * * @param dstImage a <code>BufferedImage</code> instance that will receive the decompressed image * @param flags the bitwise OR of one or more of {@link TJ TJ.FLAG_*} */ public void decompress(BufferedImage dstImage, int flags) throws Exception { if (dstImage == null || flags < 0) throw new Exception("Invalid argument in decompress()"); int desiredWidth = dstImage.getWidth(); int desiredHeight = dstImage.getHeight(); int scaledWidth = getScaledWidth(desiredWidth, desiredHeight); int scaledHeight = getScaledHeight(desiredWidth, desiredHeight); if (scaledWidth != desiredWidth || scaledHeight != desiredHeight) throw new Exception( "BufferedImage dimensions do not match a scaled image size that TurboJPEG is capable of generating."); int pixelFormat; boolean intPixels = false; if (byteOrder == null) byteOrder = ByteOrder.nativeOrder(); switch (dstImage.getType()) { case BufferedImage.TYPE_3BYTE_BGR: pixelFormat = TJ.PF_BGR; break; case BufferedImage.TYPE_4BYTE_ABGR: case BufferedImage.TYPE_4BYTE_ABGR_PRE: pixelFormat = TJ.PF_XBGR; break; case BufferedImage.TYPE_BYTE_GRAY: pixelFormat = TJ.PF_GRAY; break; case BufferedImage.TYPE_INT_BGR: if (byteOrder == ByteOrder.BIG_ENDIAN) pixelFormat = TJ.PF_XBGR; else pixelFormat = TJ.PF_RGBX; intPixels = true; break; case BufferedImage.TYPE_INT_RGB: if (byteOrder == ByteOrder.BIG_ENDIAN) pixelFormat = TJ.PF_XRGB; else pixelFormat = TJ.PF_BGRX; intPixels = true; break; case BufferedImage.TYPE_INT_ARGB: case BufferedImage.TYPE_INT_ARGB_PRE: if (byteOrder == ByteOrder.BIG_ENDIAN) pixelFormat = TJ.PF_ARGB; else pixelFormat = TJ.PF_BGRA; intPixels = true; break; default: throw new Exception("Unsupported BufferedImage format"); } WritableRaster wr = dstImage.getRaster(); if (intPixels) { SinglePixelPackedSampleModel sm = (SinglePixelPackedSampleModel) dstImage.getSampleModel(); int stride = sm.getScanlineStride(); DataBufferInt db = (DataBufferInt) wr.getDataBuffer(); int[] buf = db.getData(); if (jpegBuf == null) throw new Exception(NO_ASSOC_ERROR); decompress(jpegBuf, jpegBufSize, buf, scaledWidth, stride, scaledHeight, pixelFormat, flags); } else { ComponentSampleModel sm = (ComponentSampleModel) dstImage.getSampleModel(); int pixelSize = sm.getPixelStride(); if (pixelSize != TJ.getPixelSize(pixelFormat)) throw new Exception("Inconsistency between pixel format and pixel size in BufferedImage"); int pitch = sm.getScanlineStride(); DataBufferByte db = (DataBufferByte) wr.getDataBuffer(); byte[] buf = db.getData(); decompress(buf, scaledWidth, pitch, scaledHeight, pixelFormat, flags); } }