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: class PngPlteChunk extends PngChunk {
016:
017: int paletteSize;
018:
019: PngPlteChunk(PaletteData palette) {
020: super (palette.getRGBs().length * 3);
021: paletteSize = length / 3;
022: setType(TYPE_PLTE);
023: setPaletteData(palette);
024: setCRC(computeCRC());
025: }
026:
027: PngPlteChunk(byte[] reference) {
028: super (reference);
029: paletteSize = length / 3;
030: }
031:
032: int getChunkType() {
033: return CHUNK_PLTE;
034: }
035:
036: /**
037: * Get the number of colors in this palette.
038: */
039: int getPaletteSize() {
040: return paletteSize;
041: }
042:
043: /**
044: * Get a PaletteData object representing the colors
045: * stored in this PLTE chunk.
046: * The result should be cached as the PLTE chunk
047: * does not store the palette data created.
048: */
049: PaletteData getPaletteData() {
050: RGB[] rgbs = new RGB[paletteSize];
051: // int start = DATA_OFFSET;
052: // int end = DATA_OFFSET + length;
053: for (int i = 0; i < rgbs.length; i++) {
054: int offset = DATA_OFFSET + (i * 3);
055: int red = reference[offset] & 0xFF;
056: int green = reference[offset + 1] & 0xFF;
057: int blue = reference[offset + 2] & 0xFF;
058: rgbs[i] = new RGB(red, green, blue);
059: }
060: return new PaletteData(rgbs);
061: }
062:
063: /**
064: * Set the data of a PLTE chunk to the colors
065: * stored in the specified PaletteData object.
066: */
067: void setPaletteData(PaletteData palette) {
068: RGB[] rgbs = palette.getRGBs();
069: for (int i = 0; i < rgbs.length; i++) {
070: int offset = DATA_OFFSET + (i * 3);
071: reference[offset] = (byte) rgbs[i].red;
072: reference[offset + 1] = (byte) rgbs[i].green;
073: reference[offset + 2] = (byte) rgbs[i].blue;
074: }
075: }
076:
077: /**
078: * Answer whether the chunk is a valid PLTE chunk.
079: */
080: void validate(PngFileReadState readState, PngIhdrChunk headerChunk) {
081: // A PLTE chunk is invalid if no IHDR has been read or if any PLTE,
082: // IDAT, or IEND chunk has been read.
083: if (!readState.readIHDR || readState.readPLTE
084: || readState.readTRNS || readState.readIDAT
085: || readState.readIEND) {
086: SWT.error(SWT.ERROR_INVALID_IMAGE);
087: } else {
088: readState.readPLTE = true;
089: }
090:
091: super .validate(readState, headerChunk);
092:
093: // Palettes cannot be included in grayscale images.
094: //
095: // Note: just ignore the palette.
096: // if (!headerChunk.getCanHavePalette()) SWT.error(SWT.ERROR_INVALID_IMAGE);
097:
098: // Palette chunks' data fields must be event multiples
099: // of 3. Each 3-byte group represents an RGB value.
100: if (getLength() % 3 != 0)
101: SWT.error(SWT.ERROR_INVALID_IMAGE);
102:
103: // Palettes cannot have more entries than 2^bitDepth
104: // where bitDepth is the bit depth of the image given
105: // in the IHDR chunk.
106: if (1 << headerChunk.getBitDepth() < paletteSize) {
107: SWT.error(SWT.ERROR_INVALID_IMAGE);
108: }
109:
110: // Palettes cannot have more than 256 entries.
111: if (256 < paletteSize)
112: SWT.error(SWT.ERROR_INVALID_IMAGE);
113: }
114:
115: void contributeToString(StringBuffer buffer) {
116: buffer.append("\n\tPalette size:");
117: buffer.append(paletteSize);
118: }
119:
120: }
|