private void writePixels(String chunk, byte[] stream, int x, int y, int width, int height) throws FormatException, IOException { MetadataRetrieve r = getMetadataRetrieve(); int sizeC = getSamplesPerPixel(); String type = r.getPixelsType(series).toString(); int pixelType = FormatTools.pixelTypeFromString(type); boolean signed = FormatTools.isSigned(pixelType); if (!isFullPlane(x, y, width, height)) { throw new FormatException("APNGWriter does not support writing tiles."); } ByteArrayOutputStream s = new ByteArrayOutputStream(); s.write(chunk.getBytes()); if (chunk.equals("fdAT")) { s.write(DataTools.intToBytes(nextSequenceNumber++, false)); } DeflaterOutputStream deflater = new DeflaterOutputStream(s); int planeSize = stream.length / sizeC; int rowLen = stream.length / height; int bytesPerPixel = stream.length / (width * height * sizeC); byte[] rowBuf = new byte[rowLen]; for (int i = 0; i < height; i++) { deflater.write(0); if (interleaved) { if (littleEndian) { for (int col = 0; col < width * sizeC; col++) { int offset = (i * sizeC * width + col) * bytesPerPixel; int pixel = DataTools.bytesToInt(stream, offset, bytesPerPixel, littleEndian); DataTools.unpackBytes(pixel, rowBuf, col * bytesPerPixel, bytesPerPixel, false); } } else System.arraycopy(stream, i * rowLen, rowBuf, 0, rowLen); } else { int max = (int) Math.pow(2, bytesPerPixel * 8 - 1); for (int col = 0; col < width; col++) { for (int c = 0; c < sizeC; c++) { int offset = c * planeSize + (i * width + col) * bytesPerPixel; int pixel = DataTools.bytesToInt(stream, offset, bytesPerPixel, littleEndian); if (signed) { if (pixel < max) pixel += max; else pixel -= max; } int output = (col * sizeC + c) * bytesPerPixel; DataTools.unpackBytes(pixel, rowBuf, output, bytesPerPixel, false); } } } deflater.write(rowBuf); } deflater.finish(); byte[] b = s.toByteArray(); // write chunk length out.writeInt(b.length - 4); out.write(b); // write checksum out.writeInt(crc(b)); }
/* @see loci.formats.IFormatHandler#setId(String) */ public void setId(String id) throws FormatException, IOException { super.setId(id); if (out.length() == 0) { MetadataRetrieve r = getMetadataRetrieve(); int width = r.getPixelsSizeX(series).getValue().intValue(); int height = r.getPixelsSizeY(series).getValue().intValue(); int bytesPerPixel = FormatTools.getBytesPerPixel(r.getPixelsType(series).toString()); int nChannels = getSamplesPerPixel(); boolean indexed = getColorModel() != null && (getColorModel() instanceof IndexColorModel); littleEndian = !r.getPixelsBinDataBigEndian(series, 0); // write 8-byte PNG signature out.write(PNG_SIG); // write IHDR chunk out.writeInt(13); byte[] b = new byte[17]; b[0] = 'I'; b[1] = 'H'; b[2] = 'D'; b[3] = 'R'; DataTools.unpackBytes(width, b, 4, 4, false); DataTools.unpackBytes(height, b, 8, 4, false); b[12] = (byte) (bytesPerPixel * 8); if (indexed) b[13] = (byte) 3; else if (nChannels == 1) b[13] = (byte) 0; else if (nChannels == 2) b[13] = (byte) 4; else if (nChannels == 3) b[13] = (byte) 2; else if (nChannels == 4) b[13] = (byte) 6; b[14] = (byte) 0; b[15] = (byte) 0; b[16] = (byte) 0; out.write(b); out.writeInt(crc(b)); // write acTL chunk out.writeInt(8); out.writeBytes("acTL"); numFramesPointer = out.getFilePointer(); out.writeInt(0); out.writeInt(0); out.writeInt(0); // save a place for the CRC } }
private void writeFooter() throws IOException { // write IEND chunk out.writeInt(0); out.writeBytes("IEND"); out.writeInt(crc("IEND".getBytes())); // update frame count out.seek(numFramesPointer); out.writeInt(numFrames); out.skipBytes(4); byte[] b = new byte[12]; b[0] = 'a'; b[1] = 'c'; b[2] = 'T'; b[3] = 'L'; DataTools.unpackBytes(numFrames, b, 4, 4, false); DataTools.unpackBytes(0, b, 8, 4, false); out.writeInt(crc(b)); }
private void writeFCTL(int width, int height) throws IOException { out.writeInt(26); byte[] b = new byte[30]; b[0] = 'f'; b[1] = 'c'; b[2] = 'T'; b[3] = 'L'; DataTools.unpackBytes(nextSequenceNumber++, b, 4, 4, false); DataTools.unpackBytes(width, b, 8, 4, false); DataTools.unpackBytes(height, b, 12, 4, false); DataTools.unpackBytes(0, b, 16, 4, false); DataTools.unpackBytes(0, b, 20, 4, false); DataTools.unpackBytes(1, b, 24, 2, false); DataTools.unpackBytes(fps, b, 26, 2, false); b[28] = (byte) 1; b[29] = (byte) 0; out.write(b); out.writeInt(crc(b)); }