PngIhdrChunk(int width, int height, byte bitDepth, byte colorType, byte compressionMethod, byte filterMethod, byte interlaceMethod) { super(IHDR_DATA_LENGTH); setType(TYPE_IHDR); setWidth(width); setHeight(height); setBitDepth(bitDepth); setColorType(colorType); setCompressionMethod(compressionMethod); setFilterMethod(filterMethod); setInterlaceMethod(interlaceMethod); setCRC(computeCRC()); }
PaletteData getPaletteData() { switch (colorType) { case COLOR_TYPE_GRAYSCALE: return createGrayscalePalette(); case COLOR_TYPE_GRAYSCALE_WITH_ALPHA: case COLOR_TYPE_RGB: case COLOR_TYPE_RGB_WITH_ALPHA: return new PaletteData(0xFF0000, 0xFF00, 0xFF); default: return null; } }
/** * Answer the number of bytes needed to represent a pixel. * This value depends on the image's color type and bit * depth. * Note that this method rounds up if an image's pixel size * isn't byte-aligned. */ int getBytesPerPixel() { int bitsPerPixel = headerChunk.getBitsPerPixel(); return (bitsPerPixel + 7) / 8; } /**
void contributeToString(StringBuffer buffer) { buffer.append("\n\tWidth: "); buffer.append(width); buffer.append("\n\tHeight: "); buffer.append(height); buffer.append("\n\tBit Depth: "); buffer.append(bitDepth); buffer.append("\n\tColor Type: "); buffer.append(getColorTypeString()); buffer.append("\n\tCompression Method: "); buffer.append(compressionMethod); buffer.append("\n\tFilter Method: "); buffer.append(getFilterMethodString()); buffer.append("\n\tInterlace Method: "); buffer.append(getInterlaceMethodString()); }
PngChunkReader chunkReader = new PngChunkReader(inputStream); headerChunk = chunkReader.getIhdrChunk(); int width = headerChunk.getWidth(), height = headerChunk.getHeight(); if (width <= 0 || height <= 0) SWT.error(SWT.ERROR_INVALID_IMAGE); int imageSize = getAlignedBytesPerRow() * height; width, height, headerChunk.getSwtBitsPerPixel(), new PaletteData(0, 0, 0), 4, 0); if (headerChunk.usesDirectColor()) { imageData.palette = headerChunk.getPaletteData();
int frameCount) throws IOException int width = headerChunk.getWidth(); int alignedBytesPerRow = getAlignedBytesPerRow(); int height = headerChunk.getHeight(); if (startRow >= height || startColumn >= width) return; if (headerChunk.getBitDepth() >= 8) { int bytesPerPixel = getBytesPerPixel(); int dataOffset = (row * alignedBytesPerRow) + (startColumn * bytesPerPixel); int bitsPerPixel = headerChunk.getBitDepth(); int pixelsPerByte = 8 / bitsPerPixel; int column = startColumn;
switch (header.getColorType()) { case PngIhdrChunk.COLOR_TYPE_GRAYSCALE: int gray = ((reference[DATA_OFFSET] & 0xFF) << 8) + (reference[DATA_OFFSET + 1] & 0xFF); if (header.getBitDepth() > 8) { return PNGFileFormat.compress16BitDepthTo8BitDepth(gray); int blue = ((reference[DATA_OFFSET + 4] & 0xFF) << 8) | (reference[DATA_OFFSET + 5] & 0xFF); if (header.getBitDepth() > 8) { red = PNGFileFormat.compress16BitDepthTo8BitDepth(red); green = PNGFileFormat.compress16BitDepthTo8BitDepth(green);
int getTransparencyType(PngIhdrChunk header) { if (header.getColorType() == PngIhdrChunk.COLOR_TYPE_PALETTE) { return TRANSPARENCY_TYPE_ALPHAS; } return TRANSPARENCY_TYPE_PIXEL; }
/** * SWT does not support 16-bit depths. If this image uses * 16-bit depths, convert the data to an 8-bit depth. */ byte[] validateBitDepth(byte[] data) { if (headerChunk.getBitDepth() > 8) { byte[] result = new byte[data.length / 2]; compress16BitDepthTo8BitDepth(data, 0, result, 0, result.length); return result; } else { return data; } } /**
/** * Read the pixel data for a non-interlaced image from the * data stream. * Update the imageData to reflect the new data. */ void readNonInterlacedImage(InputStream inputStream) throws IOException { int dataOffset = 0; int alignedBytesPerRow = getAlignedBytesPerRow(); int bytesPerRow = getBytesPerRow(); byte[] row1 = new byte[bytesPerRow]; byte[] row2 = new byte[bytesPerRow]; byte[] currentRow = row1; byte[] lastRow = row2; int height = headerChunk.getHeight(); for (int row = 0; row < height; row++) { byte filterType = (byte)inputStream.read(); int read = 0; while (read != bytesPerRow) { read += inputStream.read(currentRow, read, bytesPerRow - read); } filterRow(currentRow, lastRow, filterType); System.arraycopy(currentRow, 0, data, dataOffset, bytesPerRow); dataOffset += alignedBytesPerRow; currentRow = (currentRow == row1) ? row2 : row1; lastRow = (lastRow == row1) ? row2 : row1; } setImageDataValues(data, imageData); } /**
return new PngIhdrChunk(chunk); case CHUNK_PLTE: return new PngPlteChunk(chunk);
int byteOffset = headerChunk.getFilterByteOffset(); switch (filterType) { case PngIhdrChunk.FILTER_NONE:
PngChunkReader chunkReader = new PngChunkReader(inputStream); headerChunk = chunkReader.getIhdrChunk(); int width = headerChunk.getWidth(), height = headerChunk.getHeight(); if (width <= 0 || height <= 0) SWT.error(SWT.ERROR_INVALID_IMAGE); int imageSize = getAlignedBytesPerRow() * height; width, height, headerChunk.getSwtBitsPerPixel(), new PaletteData(0, 0, 0), 4, 0); if (headerChunk.usesDirectColor()) { imageData.palette = headerChunk.getPaletteData();
@Override void contributeToString(StringBuffer buffer) { buffer.append("\n\tWidth: "); buffer.append(width); buffer.append("\n\tHeight: "); buffer.append(height); buffer.append("\n\tBit Depth: "); buffer.append(bitDepth); buffer.append("\n\tColor Type: "); buffer.append(getColorTypeString()); buffer.append("\n\tCompression Method: "); buffer.append(compressionMethod); buffer.append("\n\tFilter Method: "); buffer.append(getFilterMethodString()); buffer.append("\n\tInterlace Method: "); buffer.append(getInterlaceMethodString()); }
int frameCount) throws IOException int width = headerChunk.getWidth(); int alignedBytesPerRow = getAlignedBytesPerRow(); int height = headerChunk.getHeight(); if (startRow >= height || startColumn >= width) return; if (headerChunk.getBitDepth() >= 8) { int bytesPerPixel = getBytesPerPixel(); int dataOffset = (row * alignedBytesPerRow) + (startColumn * bytesPerPixel); int bitsPerPixel = headerChunk.getBitDepth(); int pixelsPerByte = 8 / bitsPerPixel; int column = startColumn;
switch (header.getColorType()) { case PngIhdrChunk.COLOR_TYPE_GRAYSCALE: int gray = ((reference[DATA_OFFSET] & 0xFF) << 8) + (reference[DATA_OFFSET + 1] & 0xFF); if (header.getBitDepth() > 8) { return PNGFileFormat.compress16BitDepthTo8BitDepth(gray); int blue = ((reference[DATA_OFFSET + 4] & 0xFF) << 8) | (reference[DATA_OFFSET + 5] & 0xFF); if (header.getBitDepth() > 8) { red = PNGFileFormat.compress16BitDepthTo8BitDepth(red); green = PNGFileFormat.compress16BitDepthTo8BitDepth(green);
int getTransparencyType(PngIhdrChunk header) { if (header.getColorType() == PngIhdrChunk.COLOR_TYPE_PALETTE) { return TRANSPARENCY_TYPE_ALPHAS; } return TRANSPARENCY_TYPE_PIXEL; }
/** * SWT does not support 16-bit depths. If this image uses * 16-bit depths, convert the data to an 8-bit depth. */ byte[] validateBitDepth(byte[] data) { if (headerChunk.getBitDepth() > 8) { byte[] result = new byte[data.length / 2]; compress16BitDepthTo8BitDepth(data, 0, result, 0, result.length); return result; } else { return data; } } /**
/** * Read the pixel data for a non-interlaced image from the * data stream. * Update the imageData to reflect the new data. */ void readNonInterlacedImage(InputStream inputStream) throws IOException { int dataOffset = 0; int alignedBytesPerRow = getAlignedBytesPerRow(); int bytesPerRow = getBytesPerRow(); byte[] row1 = new byte[bytesPerRow]; byte[] row2 = new byte[bytesPerRow]; byte[] currentRow = row1; byte[] lastRow = row2; int height = headerChunk.getHeight(); for (int row = 0; row < height; row++) { byte filterType = (byte)inputStream.read(); int read = 0; while (read != bytesPerRow) { read += inputStream.read(currentRow, read, bytesPerRow - read); } filterRow(currentRow, lastRow, filterType); System.arraycopy(currentRow, 0, data, dataOffset, bytesPerRow); dataOffset += alignedBytesPerRow; currentRow = (currentRow == row1) ? row2 : row1; lastRow = (lastRow == row1) ? row2 : row1; } setImageDataValues(data, imageData); } /**
return new PngIhdrChunk(chunk); case CHUNK_PLTE: return new PngPlteChunk(chunk);