| /******************************************************************************* |
| * Copyright (c) 2000, 2003 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.swt.internal.image; |
| |
| |
| import org.eclipse.swt.*; |
| |
| public class PngTrnsChunk extends PngChunk { |
| static final int TRANSPARENCY_TYPE_PIXEL = 0; |
| static final int TRANSPARENCY_TYPE_ALPHAS = 1; |
| |
| PngTrnsChunk(byte[] reference){ |
| super(reference); |
| } |
| |
| void validateLength(PngIhdrChunk header, PngPlteChunk paletteChunk) { |
| boolean valid; |
| switch (header.getColorType()) { |
| case PngIhdrChunk.COLOR_TYPE_RGB: |
| // Three 2-byte values (RGB) |
| valid = getLength() == 6; |
| break; |
| case PngIhdrChunk.COLOR_TYPE_PALETTE: |
| // Three 2-byte values (RGB) |
| valid = getLength() <= paletteChunk.getLength(); |
| break; |
| case PngIhdrChunk.COLOR_TYPE_GRAYSCALE: |
| // One 2-byte value |
| valid = getLength() == 2; |
| break; |
| // Cannot use both Alpha and tRNS |
| case PngIhdrChunk.COLOR_TYPE_RGB_WITH_ALPHA: |
| case PngIhdrChunk.COLOR_TYPE_GRAYSCALE_WITH_ALPHA: |
| default: |
| valid = false; |
| } |
| if (!valid) { |
| SWT.error(SWT.ERROR_INVALID_IMAGE); |
| } |
| } |
| |
| /** |
| * Answer whether the chunk is a valid tRNS chunk. |
| */ |
| void validate(PngFileReadState readState, PngIhdrChunk headerChunk, PngPlteChunk paletteChunk) { |
| if (!readState.readIHDR |
| || (headerChunk.getMustHavePalette() && !readState.readPLTE) |
| || readState.readIDAT |
| || readState.readIEND) |
| { |
| SWT.error(SWT.ERROR_INVALID_IMAGE); |
| } else { |
| readState.readTRNS = true; |
| } |
| |
| validateLength(headerChunk, paletteChunk); |
| |
| super.validate(readState, headerChunk); |
| } |
| |
| |
| int getTransparencyType(PngIhdrChunk header) { |
| if (header.getColorType() == PngIhdrChunk.COLOR_TYPE_PALETTE) { |
| return TRANSPARENCY_TYPE_ALPHAS; |
| } |
| return TRANSPARENCY_TYPE_PIXEL; |
| } |
| |
| /** |
| * Answer the transparent pixel RGB value. |
| * This is not valid for palette color types. |
| * This is not valid for alpha color types. |
| * This will convert a grayscale value into |
| * a palette index. |
| * It will compress a 6 byte RGB into a 3 byte |
| * RGB. |
| */ |
| int getSwtTransparentPixel(PngIhdrChunk header) { |
| 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); |
| } |
| return gray & 0xFF; |
| case PngIhdrChunk.COLOR_TYPE_RGB: |
| int red = ((reference[DATA_OFFSET] & 0xFF) << 8) |
| | (reference[DATA_OFFSET + 1] & 0xFF); |
| int green = ((reference[DATA_OFFSET + 2] & 0xFF) << 8) |
| | (reference[DATA_OFFSET + 3] & 0xFF); |
| 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); |
| blue = PNGFileFormat.compress16BitDepthTo8BitDepth(blue); |
| } |
| return (red << 16) | (green << 8) | blue; |
| default: |
| SWT.error(SWT.ERROR_INVALID_IMAGE); |
| return -1; |
| } |
| } |
| |
| /** |
| * Answer an array of Alpha values that correspond to the |
| * colors in the palette. |
| * This is only valid for the COLOR_TYPE_PALETTE color type. |
| */ |
| byte[] getAlphaValues(PngIhdrChunk header, PngPlteChunk paletteChunk) { |
| if (header.getColorType() != PngIhdrChunk.COLOR_TYPE_PALETTE) { |
| SWT.error(SWT.ERROR_INVALID_IMAGE); |
| } |
| byte[] alphas = new byte[paletteChunk.getPaletteSize()]; |
| int dataLength = getLength(); |
| int i = 0; |
| for (i = 0; i < dataLength; i++) { |
| alphas[i] = reference[DATA_OFFSET + i]; |
| } |
| /** |
| * Any palette entries which do not have a corresponding |
| * alpha value in the tRNS chunk are spec'd to have an |
| * alpha of 255. |
| */ |
| for (int j = i; j < alphas.length; j++) { |
| alphas[j] = (byte) 255; |
| } |
| return alphas; |
| } |
| } |