001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.swt.internal.image;
011:
012: import org.eclipse.swt.*;
013: import org.eclipse.swt.graphics.*;
014:
015: public class PngTrnsChunk extends PngChunk {
016: static final int TRANSPARENCY_TYPE_PIXEL = 0;
017: static final int TRANSPARENCY_TYPE_ALPHAS = 1;
018: static final int RGB_DATA_LENGTH = 6;
019:
020: PngTrnsChunk(RGB rgb) {
021: super (RGB_DATA_LENGTH);
022: setType(TYPE_tRNS);
023: setInt16(DATA_OFFSET, rgb.red);
024: setInt16(DATA_OFFSET + 2, rgb.green);
025: setInt16(DATA_OFFSET + 4, rgb.blue);
026: setCRC(computeCRC());
027: }
028:
029: PngTrnsChunk(byte[] reference) {
030: super (reference);
031: }
032:
033: int getChunkType() {
034: return CHUNK_tRNS;
035: }
036:
037: void validateLength(PngIhdrChunk header, PngPlteChunk paletteChunk) {
038: boolean valid;
039: switch (header.getColorType()) {
040: case PngIhdrChunk.COLOR_TYPE_RGB:
041: // Three 2-byte values (RGB)
042: valid = getLength() == 6;
043: break;
044: case PngIhdrChunk.COLOR_TYPE_PALETTE:
045: // Three 2-byte values (RGB)
046: valid = getLength() <= paletteChunk.getLength();
047: break;
048: case PngIhdrChunk.COLOR_TYPE_GRAYSCALE:
049: // One 2-byte value
050: valid = getLength() == 2;
051: break;
052: // Cannot use both Alpha and tRNS
053: case PngIhdrChunk.COLOR_TYPE_RGB_WITH_ALPHA:
054: case PngIhdrChunk.COLOR_TYPE_GRAYSCALE_WITH_ALPHA:
055: default:
056: valid = false;
057: }
058: if (!valid) {
059: SWT.error(SWT.ERROR_INVALID_IMAGE);
060: }
061: }
062:
063: /**
064: * Answer whether the chunk is a valid tRNS chunk.
065: */
066: void validate(PngFileReadState readState, PngIhdrChunk headerChunk,
067: PngPlteChunk paletteChunk) {
068: if (!readState.readIHDR
069: || (headerChunk.getMustHavePalette() && !readState.readPLTE)
070: || readState.readIDAT || readState.readIEND) {
071: SWT.error(SWT.ERROR_INVALID_IMAGE);
072: } else {
073: readState.readTRNS = true;
074: }
075:
076: validateLength(headerChunk, paletteChunk);
077:
078: super .validate(readState, headerChunk);
079: }
080:
081: int getTransparencyType(PngIhdrChunk header) {
082: if (header.getColorType() == PngIhdrChunk.COLOR_TYPE_PALETTE) {
083: return TRANSPARENCY_TYPE_ALPHAS;
084: }
085: return TRANSPARENCY_TYPE_PIXEL;
086: }
087:
088: /**
089: * Answer the transparent pixel RGB value.
090: * This is not valid for palette color types.
091: * This is not valid for alpha color types.
092: * This will convert a grayscale value into
093: * a palette index.
094: * It will compress a 6 byte RGB into a 3 byte
095: * RGB.
096: */
097: int getSwtTransparentPixel(PngIhdrChunk header) {
098: switch (header.getColorType()) {
099: case PngIhdrChunk.COLOR_TYPE_GRAYSCALE:
100: int gray = ((reference[DATA_OFFSET] & 0xFF) << 8)
101: + (reference[DATA_OFFSET + 1] & 0xFF);
102: if (header.getBitDepth() > 8) {
103: return PNGFileFormat
104: .compress16BitDepthTo8BitDepth(gray);
105: }
106: return gray & 0xFF;
107: case PngIhdrChunk.COLOR_TYPE_RGB:
108: int red = ((reference[DATA_OFFSET] & 0xFF) << 8)
109: | (reference[DATA_OFFSET + 1] & 0xFF);
110: int green = ((reference[DATA_OFFSET + 2] & 0xFF) << 8)
111: | (reference[DATA_OFFSET + 3] & 0xFF);
112: int blue = ((reference[DATA_OFFSET + 4] & 0xFF) << 8)
113: | (reference[DATA_OFFSET + 5] & 0xFF);
114: if (header.getBitDepth() > 8) {
115: red = PNGFileFormat.compress16BitDepthTo8BitDepth(red);
116: green = PNGFileFormat
117: .compress16BitDepthTo8BitDepth(green);
118: blue = PNGFileFormat
119: .compress16BitDepthTo8BitDepth(blue);
120: }
121: return (red << 16) | (green << 8) | blue;
122: default:
123: SWT.error(SWT.ERROR_INVALID_IMAGE);
124: return -1;
125: }
126: }
127:
128: /**
129: * Answer an array of Alpha values that correspond to the
130: * colors in the palette.
131: * This is only valid for the COLOR_TYPE_PALETTE color type.
132: */
133: byte[] getAlphaValues(PngIhdrChunk header, PngPlteChunk paletteChunk) {
134: if (header.getColorType() != PngIhdrChunk.COLOR_TYPE_PALETTE) {
135: SWT.error(SWT.ERROR_INVALID_IMAGE);
136: }
137: byte[] alphas = new byte[paletteChunk.getPaletteSize()];
138: int dataLength = getLength();
139: int i = 0;
140: for (i = 0; i < dataLength; i++) {
141: alphas[i] = reference[DATA_OFFSET + i];
142: }
143: /**
144: * Any palette entries which do not have a corresponding
145: * alpha value in the tRNS chunk are spec'd to have an
146: * alpha of 255.
147: */
148: for (int j = i; j < alphas.length; j++) {
149: alphas[j] = (byte) 255;
150: }
151: return alphas;
152: }
153: }
|