📄 giffileformat.java
字号:
/******************************************************************************* * 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 Common Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/package org.eclipse.swt.internal.image;import org.eclipse.swt.*;import org.eclipse.swt.graphics.*;import java.io.*;final class GIFFileFormat extends FileFormat { String signature, version; boolean sorted; int screenWidth, screenHeight, backgroundPixel, aspect, bitsPerPixel, defaultDepth; boolean userInput = false; int disposalMethod = 0; int delayTime = 0; int transparentPixel = -1; int repeatCount = 1; static final int GIF_APPLICATION_EXTENSION_BLOCK_ID = 0xFF; static final int GIF_GRAPHICS_CONTROL_BLOCK_ID = 0xF9; static final int GIF_PLAIN_TEXT_BLOCK_ID = 0x01; static final int GIF_COMMENT_BLOCK_ID = 0xFE; static final int GIF_EXTENSION_BLOCK_ID = 0x21; static final int GIF_IMAGE_BLOCK_ID = 0x2C; static final int GIF_TRAILER_ID = 0x3B; /** * Answer a palette containing numGrays * shades of gray, ranging from black to white. */ static PaletteData grayRamp(int numGrays) { int n = numGrays - 1; RGB[] colors = new RGB[numGrays]; for (int i = 0; i < numGrays; i++) { int intensity = (byte)((i * 3) * 256 / n); colors[i] = new RGB(intensity, intensity, intensity); } return new PaletteData(colors); } boolean isFileFormat(LEDataInputStream stream) { try { byte[] signature = new byte[3]; stream.read(signature); stream.unread(signature); return new String(signature).equals("GIF"); //$NON-NLS-1$ } catch (Exception e) { return false; } } /** * Load the GIF image(s) stored in the input stream. * Return an array of ImageData representing the image(s). */ ImageData[] loadFromByteStream() { byte[] signatureBytes = new byte[3]; byte[] versionBytes = new byte[3]; byte[] block = new byte[7]; try { inputStream.read(signatureBytes); signature = new String(signatureBytes); if (!signature.equals("GIF")) //$NON-NLS-1$ SWT.error(SWT.ERROR_INVALID_IMAGE); inputStream.read(versionBytes); version = new String(versionBytes); inputStream.read(block); } catch (IOException e) { SWT.error(SWT.ERROR_IO, e); } screenWidth = (block[0] & 0xFF) | ((block[1] & 0xFF) << 8); loader.logicalScreenWidth = screenWidth; screenHeight = (block[2] & 0xFF) | ((block[3] & 0xFF) << 8); loader.logicalScreenHeight = screenHeight; byte bitField = block[4]; backgroundPixel = block[5] & 0xFF; aspect = block[6] & 0xFF; bitsPerPixel = ((bitField >> 4) & 0x07) + 1; defaultDepth = (bitField & 0x7) + 1; PaletteData palette = null; if ((bitField & 0x80) != 0) { // Global palette. sorted = (bitField & 0x8) != 0; palette = readPalette(1 << defaultDepth); } else { // No global palette. sorted = false; backgroundPixel = -1; defaultDepth = bitsPerPixel; } loader.backgroundPixel = backgroundPixel; getExtensions(); int id = readID(); ImageData[] images = new ImageData[0]; while (id == GIF_IMAGE_BLOCK_ID) { ImageData image = readImageBlock(palette); if (loader.hasListeners()) { loader.notifyListeners(new ImageLoaderEvent(loader, image, 3, true)); } ImageData[] oldImages = images; images = new ImageData[oldImages.length + 1]; System.arraycopy(oldImages, 0, images, 0, oldImages.length); images[images.length - 1] = image; try { /* Read the 0-byte terminator at the end of the image. */ id = inputStream.read(); if (id > 0) { /* We read the terminator earlier. */ inputStream.unread(new byte[] {(byte)id}); } } catch (IOException e) { SWT.error(SWT.ERROR_IO, e); } getExtensions(); id = readID(); } return images; } /** * Read and return the next block or extension identifier from the file. */ int readID() { try { return inputStream.read(); } catch (IOException e) { SWT.error(SWT.ERROR_IO, e); } return -1; } /** * Read extensions until an image descriptor appears. * In the future, if we care about the extensions, they * should be properly grouped with the image data before * which they appeared. Right now, the interesting parts * of some extensions are kept, but the rest is discarded. * Throw an error if an error occurs. */ void getExtensions() { int id = readID(); while (id != GIF_IMAGE_BLOCK_ID && id != GIF_TRAILER_ID && id > 0) { if (id == GIF_EXTENSION_BLOCK_ID) { readExtension(); } else { SWT.error(SWT.ERROR_INVALID_IMAGE); } id = readID(); } if (id == GIF_IMAGE_BLOCK_ID || id == GIF_TRAILER_ID) { try { inputStream.unread(new byte[] {(byte)id}); } catch (IOException e) { SWT.error(SWT.ERROR_IO, e); } } } /** * Read a control extension. * Return the extension block data. */ byte[] readExtension() { int extensionID = readID(); if (extensionID == GIF_COMMENT_BLOCK_ID) return readCommentExtension(); if (extensionID == GIF_PLAIN_TEXT_BLOCK_ID) return readPlainTextExtension(); if (extensionID == GIF_GRAPHICS_CONTROL_BLOCK_ID) return readGraphicsControlExtension(); if (extensionID == GIF_APPLICATION_EXTENSION_BLOCK_ID) return readApplicationExtension(); // Otherwise, we don't recognize the block. If the // field size is correct, we can just skip over // the block contents. try { int extSize = inputStream.read(); if (extSize < 0) { SWT.error(SWT.ERROR_INVALID_IMAGE); } byte[] ext = new byte[extSize]; inputStream.read(ext, 0, extSize); return ext; } catch (IOException e) { SWT.error(SWT.ERROR_IO, e); return null; } } /** * We have just read the Comment extension identifier * from the input stream. Read in the rest of the comment * and return it. GIF comment blocks are variable size. */ byte[] readCommentExtension() { try { byte[] comment = new byte[0]; byte[] block = new byte[255]; int size = inputStream.read(); while ((size > 0) && (inputStream.read(block, 0, size) != -1)) { byte[] oldComment = comment; comment = new byte[oldComment.length + size]; System.arraycopy(oldComment, 0, comment, 0, oldComment.length); System.arraycopy(block, 0, comment, oldComment.length, size); size = inputStream.read(); } return comment; } catch (Exception e) { SWT.error(SWT.ERROR_IO, e); return null; } } /** * We have just read the PlainText extension identifier * from the input stream. Read in the plain text info and text, * and return the text. GIF plain text blocks are variable size. */ byte[] readPlainTextExtension() { try { // Read size of block = 0x0C. inputStream.read(); // Read the text information (x, y, width, height, colors). byte[] info = new byte[12]; inputStream.read(info); // Read the text. byte[] text = new byte[0]; byte[] block = new byte[255]; int size = inputStream.read(); while ((size > 0) && (inputStream.read(block, 0, size) != -1)) { byte[] oldText = text; text = new byte[oldText.length + size]; System.arraycopy(oldText, 0, text, 0, oldText.length); System.arraycopy(block, 0, text, oldText.length, size); size = inputStream.read(); } return text; } catch (Exception e) { SWT.error(SWT.ERROR_IO, e); return null; } } /** * We have just read the GraphicsControl extension identifier * from the input stream. Read in the control information, store * it, and return it. */ byte[] readGraphicsControlExtension() { try { // Read size of block = 0x04. inputStream.read(); // Read the control block. byte[] controlBlock = new byte[4]; inputStream.read(controlBlock); byte bitField = controlBlock[0]; // Store the user input field.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -