private static double decodeWord(byte[] plane, int index, int pixelType, boolean little) { final double value; switch (pixelType) { case FormatTools.UINT8: value = plane[index] & 0xff; break; case FormatTools.INT8: value = plane[index]; break; case FormatTools.UINT16: value = DataTools.bytesToShort(plane, 2 * index, 2, little) & 0xffff; break; case FormatTools.INT16: value = DataTools.bytesToShort(plane, 2 * index, 2, little); break; case FormatTools.UINT32: value = DataTools.bytesToInt(plane, 4 * index, 4, little) & 0xffffffffL; break; case FormatTools.INT32: value = DataTools.bytesToInt(plane, 4 * index, 4, little); break; case FormatTools.FLOAT: value = DataTools.bytesToFloat(plane, 4 * index, 4, little); break; case FormatTools.DOUBLE: value = DataTools.bytesToDouble(plane, 8 * index, 8, little); break; default: value = Double.NaN; } return value; }
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)); }