summaryrefslogtreecommitdiffstats
path: root/awt/org/apache/harmony/awt/gl/image/GifDecoder.java
diff options
context:
space:
mode:
Diffstat (limited to 'awt/org/apache/harmony/awt/gl/image/GifDecoder.java')
-rw-r--r--awt/org/apache/harmony/awt/gl/image/GifDecoder.java692
1 files changed, 0 insertions, 692 deletions
diff --git a/awt/org/apache/harmony/awt/gl/image/GifDecoder.java b/awt/org/apache/harmony/awt/gl/image/GifDecoder.java
deleted file mode 100644
index 7ecb15b..0000000
--- a/awt/org/apache/harmony/awt/gl/image/GifDecoder.java
+++ /dev/null
@@ -1,692 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
- * @author Oleg V. Khaschansky
- * @version $Revision$
- */
-/*
-* Created on 27.01.2005
-*/
-package org.apache.harmony.awt.gl.image;
-
-import java.awt.image.ColorModel;
-import java.awt.image.ImageConsumer;
-import java.awt.image.IndexColorModel;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Hashtable;
-import java.util.List;
-
-public class GifDecoder extends ImageDecoder {
- // initializes proper field IDs
- private static native void initIDs();
-
- static {
- System.loadLibrary("gl"); //$NON-NLS-1$
- initIDs();
- }
-
- // ImageConsumer hints: common
- private static final int baseHints =
- ImageConsumer.SINGLEPASS | ImageConsumer.COMPLETESCANLINES |
- ImageConsumer.SINGLEFRAME;
- // ImageConsumer hints: interlaced
- private static final int interlacedHints =
- baseHints | ImageConsumer.RANDOMPIXELORDER;
-
- // Impossible color value - no translucent pixels allowed
- static final int IMPOSSIBLE_VALUE = 0x0FFFFFFF;
-
- // I/O buffer
- private static final int BUFFER_SIZE = 1024;
- private byte buffer[] = new byte[BUFFER_SIZE];
-
- GifDataStream gifDataStream = new GifDataStream();
- GifGraphicBlock currBlock;
-
- // Pointer to native structure which store decoding state
- // between subsequent decoding/IO-suspension cycles
- private long hNativeDecoder; // NULL initially
-
- // Number of bytes eaten by the native decoder
- private int bytesConsumed;
-
- private boolean consumersPrepared;
- private Hashtable<String, String> properties = new Hashtable<String, String>();
-
- // Could be set up by java code or native method when
- // transparent pixel index changes or local color table encountered
- private boolean forceRGB;
-
- private byte screenBuffer[];
- private int screenRGBBuffer[];
-
- public GifDecoder(DecodingImageSource src, InputStream is) {
- super(src, is);
- }
-
- private static native int[] toRGB(byte imageData[], byte colormap[], int transparentColor);
-
- private static native void releaseNativeDecoder(long hDecoder);
-
- private native int decode(
- byte input[],
- int bytesInBuffer,
- long hDecoder,
- GifDataStream dataStream,
- GifGraphicBlock currBlock
- );
-
- private int[] getScreenRGBBuffer() {
- if (screenRGBBuffer == null) {
- if (screenBuffer != null) {
- int transparentColor =
- gifDataStream.logicalScreen.globalColorTable.cm.getTransparentPixel();
- transparentColor = transparentColor > 0 ? transparentColor : IMPOSSIBLE_VALUE;
- screenRGBBuffer =
- toRGB(
- screenBuffer,
- gifDataStream.logicalScreen.globalColorTable.colors,
- transparentColor
- );
- } else {
- int size = gifDataStream.logicalScreen.logicalScreenHeight *
- gifDataStream.logicalScreen.logicalScreenWidth;
- screenRGBBuffer = new int[size];
- }
- }
-
- return screenRGBBuffer;
- }
-
- private void prepareConsumers() {
- GifLogicalScreen gls = gifDataStream.logicalScreen;
- setDimensions(gls.logicalScreenWidth,
- gls.logicalScreenHeight);
- setProperties(properties);
-
- currBlock = gifDataStream.graphicBlocks.get(0);
- if (forceRGB) {
- setColorModel(ColorModel.getRGBdefault());
- } else {
- setColorModel(gls.globalColorTable.getColorModel(currBlock.transparentColor));
- }
-
- // Fill screen buffer with the background or transparent color
- if (forceRGB) {
- int fillColor = 0xFF000000;
- if (gls.backgroundColor != IMPOSSIBLE_VALUE) {
- fillColor = gls.backgroundColor;
- }
-
- Arrays.fill(getScreenRGBBuffer(), fillColor);
- } else {
- int fillColor = 0;
-
- if (gls.backgroundColor != IMPOSSIBLE_VALUE) {
- fillColor = gls.backgroundColor;
- } else {
- fillColor = gls.globalColorTable.cm.getTransparentPixel();
- }
-
- screenBuffer = new byte[gls.logicalScreenHeight*gls.logicalScreenWidth];
- Arrays.fill(screenBuffer, (byte) fillColor);
- }
-
- setHints(interlacedHints); // XXX - always random pixel order
- }
-
- @Override
- public void decodeImage() throws IOException {
- try {
- int bytesRead = 0;
- int needBytes, offset, bytesInBuffer = 0;
- boolean eosReached = false;
- GifGraphicBlock blockToDispose = null;
-
- // Create new graphic block
- if (currBlock == null) {
- currBlock = new GifGraphicBlock();
- gifDataStream.graphicBlocks.add(currBlock);
- }
-
- // Read from the input stream
- for (;;) {
- needBytes = BUFFER_SIZE - bytesInBuffer;
- offset = bytesInBuffer;
-
- bytesRead = inputStream.read(buffer, offset, needBytes);
-
- if (bytesRead < 0) {
- eosReached = true;
- bytesRead = 0;
- } // Don't break, maybe something left in buffer
-
- // Keep track on how much bytes left in buffer
- bytesInBuffer += bytesRead;
-
- // Here we pass number of new bytes read from the input stream (bytesRead)
- // since native decoder uses java buffer and doesn't have its own
- // buffer. So it adds this number to the number of bytes left
- // in buffer from the previous call.
- int numLines = decode(
- buffer,
- bytesRead,
- hNativeDecoder,
- gifDataStream,
- currBlock);
-
- // Keep track on how much bytes left in buffer
- bytesInBuffer -= bytesConsumed;
-
- if (
- !consumersPrepared &&
- gifDataStream.logicalScreen.completed &&
- gifDataStream.logicalScreen.globalColorTable.completed &&
- (currBlock.imageData != null || // Have transparent pixel filled
- currBlock.rgbImageData != null)
- ) {
- prepareConsumers();
- consumersPrepared = true;
- }
-
- if (bytesConsumed < 0) {
- break; // Error exit
- }
-
- if (currBlock != null) {
- if (numLines != 0) {
- // Dispose previous image only before showing next
- if (blockToDispose != null) {
- blockToDispose.dispose();
- blockToDispose = null;
- }
-
- currBlock.sendNewData(this, numLines);
- }
-
- if (currBlock.completed && hNativeDecoder != 0) {
- blockToDispose = currBlock; // Dispose only before showing new pixels
- currBlock = new GifGraphicBlock();
- gifDataStream.graphicBlocks.add(currBlock);
- }
- }
-
- if (hNativeDecoder == 0) {
- break;
- }
-
- if (eosReached && numLines == 0) { // Maybe image is truncated...
- releaseNativeDecoder(hNativeDecoder);
- break;
- }
- }
- } finally {
- closeStream();
- }
-
- // Here all animation goes
- // Repeat image loopCount-1 times or infinitely if loopCount = 0
- if (gifDataStream.loopCount != 1) {
- if (currBlock.completed == false) {
- gifDataStream.graphicBlocks.remove(currBlock);
- }
-
- int numFrames = gifDataStream.graphicBlocks.size();
- // At first last block will be disposed
- GifGraphicBlock gb =
- gifDataStream.graphicBlocks.get(numFrames-1);
-
- ImageLoader.beginAnimation();
-
- while (gifDataStream.loopCount != 1) {
- if (gifDataStream.loopCount != 0) {
- gifDataStream.loopCount--;
- }
-
- // Show all frames
- for (int i=0; i<numFrames; i++) {
- gb.dispose();
- gb = gifDataStream.graphicBlocks.get(i);
-
- // Show one frame
- if (forceRGB) {
- setPixels(
- gb.imageLeft,
- gb.imageTop,
- gb.imageWidth,
- gb.imageHeight,
- ColorModel.getRGBdefault(),
- gb.getRgbImageData(),
- 0,
- gb.imageWidth
- );
- } else {
- setPixels(
- gb.imageLeft,
- gb.imageTop,
- gb.imageWidth,
- gb.imageHeight,
- null,
- gb.imageData,
- 0,
- gb.imageWidth
- );
- }
- }
- }
- ImageLoader.endAnimation();
- }
-
- imageComplete(ImageConsumer.STATICIMAGEDONE);
- }
-
- void setComment(String newComment) {
- Object currComment = properties.get("comment"); //$NON-NLS-1$
-
- if (currComment == null) {
- properties.put("comment", newComment); //$NON-NLS-1$
- } else {
- properties.put("comment", (String) currComment + "\n" + newComment); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- setProperties(properties);
- }
-
- class GifDataStream {
- // Indicates that reading of the whole data stream accomplished
- boolean completed = false;
-
- // Added to support Netscape 2.0 application
- // extension block.
- int loopCount = 1;
-
- GifLogicalScreen logicalScreen = new GifLogicalScreen();
- List<GifGraphicBlock> graphicBlocks = new ArrayList<GifGraphicBlock>(10); // Of GifGraphicBlocks
-
- // Comments from the image
- String comments[];
- }
-
- class GifLogicalScreen {
- // Indicates that reading of this block accomplished
- boolean completed = false;
-
- int logicalScreenWidth;
- int logicalScreenHeight;
-
- int backgroundColor = IMPOSSIBLE_VALUE;
-
- GifColorTable globalColorTable = new GifColorTable();
- }
-
- class GifGraphicBlock {
- // Indicates that reading of this block accomplished
- boolean completed = false;
-
- final static int DISPOSAL_NONE = 0;
- final static int DISPOSAL_NODISPOSAL = 1;
- final static int DISPOSAL_BACKGROUND = 2;
- final static int DISPOSAL_RESTORE = 3;
-
- int disposalMethod;
- int delayTime; // Multiplied by 10 already
- int transparentColor = IMPOSSIBLE_VALUE;
-
- int imageLeft;
- int imageTop;
- int imageWidth;
- int imageHeight;
-
- // Auxilliary variables to minimize computations
- int imageRight;
- int imageBottom;
-
- boolean interlace;
-
- // Don't need local color table - if it is specified
- // image data are converted to RGB in the native code
-
- byte imageData[] = null;
- int rgbImageData[] = null;
-
- private int currY = 0; // Current output scanline
-
- int[] getRgbImageData() {
- if (rgbImageData == null) {
- rgbImageData =
- toRGB(
- imageData,
- gifDataStream.logicalScreen.globalColorTable.colors,
- transparentColor
- );
- if (transparentColor != IMPOSSIBLE_VALUE) {
- transparentColor =
- gifDataStream.logicalScreen.globalColorTable.cm.getRGB(transparentColor);
- transparentColor &= 0x00FFFFFF;
- }
- }
- return rgbImageData;
- }
-
- private void replaceTransparentPixels(int numLines) {
- List<GifGraphicBlock> graphicBlocks = gifDataStream.graphicBlocks;
- int prevBlockIndex = graphicBlocks.indexOf(this) - 1;
-
- if (prevBlockIndex >= 0) {
- int maxY = currY + numLines + imageTop;
- int offset = currY * imageWidth;
-
- // Update right and bottom coordinates
- imageRight = imageLeft + imageWidth;
- imageBottom = imageTop + imageHeight;
-
- int globalWidth = gifDataStream.logicalScreen.logicalScreenWidth;
- int pixelValue, imageOffset;
- int rgbData[] = forceRGB ? getRgbImageData() : null;
-
- for (int y = currY + imageTop; y < maxY; y++) {
- imageOffset = globalWidth * y + imageLeft;
- for (int x = imageLeft; x < imageRight; x++) {
- pixelValue = forceRGB ?
- rgbData[offset] :
- imageData[offset] & 0xFF;
- if (pixelValue == transparentColor) {
- if (forceRGB) {
- pixelValue = getScreenRGBBuffer() [imageOffset];
- rgbData[offset] = pixelValue;
- } else {
- pixelValue = screenBuffer [imageOffset];
- imageData[offset] = (byte) pixelValue;
- }
- }
- offset++;
- imageOffset++;
- } // for
- } // for
-
- } // if (prevBlockIndex >= 0)
- }
-
- public void sendNewData(GifDecoder decoder, int numLines) {
- // Get values for transparent pixels
- // from the perevious frames
- if (transparentColor != IMPOSSIBLE_VALUE) {
- replaceTransparentPixels(numLines);
- }
-
- if (forceRGB) {
- decoder.setPixels(
- imageLeft,
- imageTop + currY,
- imageWidth,
- numLines,
- ColorModel.getRGBdefault(),
- getRgbImageData(),
- currY*imageWidth,
- imageWidth
- );
- } else {
- decoder.setPixels(
- imageLeft,
- imageTop + currY,
- imageWidth,
- numLines,
- null,
- imageData,
- currY*imageWidth,
- imageWidth
- );
- }
-
- currY += numLines;
- }
-
- public void dispose() {
- imageComplete(ImageConsumer.SINGLEFRAMEDONE);
-
- // Show current frame until delayInterval will not elapse
- if (delayTime > 0) {
- try {
- Thread.sleep(delayTime);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- } else {
- Thread.yield(); // Allow consumers to consume data
- }
-
- // Don't dispose if image is outside of the visible area
- if (imageLeft > gifDataStream.logicalScreen.logicalScreenWidth ||
- imageTop > gifDataStream.logicalScreen.logicalScreenHeight) {
- disposalMethod = DISPOSAL_NONE;
- }
-
- switch(disposalMethod) {
- case DISPOSAL_BACKGROUND: {
- if (forceRGB) {
- getRgbImageData(); // Ensure that transparentColor is RGB, not index
-
- int data[] = new int[imageWidth*imageHeight];
-
- // Compatibility: Fill with transparent color if we have one
- if (transparentColor != IMPOSSIBLE_VALUE) {
- Arrays.fill(
- data,
- transparentColor
- );
- } else {
- Arrays.fill(
- data,
- gifDataStream.logicalScreen.backgroundColor
- );
- }
-
- setPixels(
- imageLeft,
- imageTop,
- imageWidth,
- imageHeight,
- ColorModel.getRGBdefault(),
- data,
- 0,
- imageWidth
- );
-
- sendToScreenBuffer(data);
- } else {
- byte data[] = new byte[imageWidth*imageHeight];
-
- // Compatibility: Fill with transparent color if we have one
- if (transparentColor != IMPOSSIBLE_VALUE) {
- Arrays.fill(
- data,
- (byte) transparentColor
- );
- } else {
- Arrays.fill(
- data,
- (byte) gifDataStream.logicalScreen.backgroundColor
- );
- }
-
- setPixels(
- imageLeft,
- imageTop,
- imageWidth,
- imageHeight,
- null,
- data,
- 0,
- imageWidth
- );
-
- sendToScreenBuffer(data);
- }
- break;
- }
- case DISPOSAL_RESTORE: {
- screenBufferToScreen();
- break;
- }
- case DISPOSAL_NONE:
- case DISPOSAL_NODISPOSAL:
- default: {
- // Copy transmitted data to the screen buffer
- Object data = forceRGB ? (Object) getRgbImageData() : imageData;
- sendToScreenBuffer(data);
- break;
- }
- }
- }
-
- private void sendToScreenBuffer(Object data) {
- int dataInt[];
- byte dataByte[];
-
- int width = gifDataStream.logicalScreen.logicalScreenWidth;
-
-
- if (forceRGB) {
- dataInt = (int[]) data;
-
- if (imageWidth == width) {
- System.arraycopy(dataInt,
- 0,
- getScreenRGBBuffer(),
- imageLeft + imageTop*width,
- dataInt.length
- );
- } else { // Each scanline
- copyScanlines(dataInt, getScreenRGBBuffer(), width);
- }
- } else {
- dataByte = (byte[]) data;
-
- if (imageWidth == width) {
- System.arraycopy(dataByte,
- 0,
- screenBuffer,
- imageLeft + imageTop*width,
- dataByte.length
- );
- } else { // Each scanline
- copyScanlines(dataByte, screenBuffer, width);
- }
- }
- } // sendToScreenBuffer
-
- private void copyScanlines(Object src, Object dst, int width) {
- for (int i=0; i<imageHeight; i++) {
- System.arraycopy(src,
- i*imageWidth,
- dst,
- imageLeft + i*width + imageTop*width,
- imageWidth
- );
- } // for
- }
-
- private void screenBufferToScreen() {
- int width = gifDataStream.logicalScreen.logicalScreenWidth;
-
- Object dst = forceRGB ?
- (Object) new int[imageWidth*imageHeight] :
- new byte[imageWidth*imageHeight];
-
- Object src = forceRGB ?
- getScreenRGBBuffer() :
- (Object) screenBuffer;
-
- int offset = 0;
- Object toSend;
-
- if (width == imageWidth) {
- offset = imageWidth * imageTop;
- toSend = src;
- } else {
- for (int i=0; i<imageHeight; i++) {
- System.arraycopy(src,
- imageLeft + i*width + imageTop*width,
- dst,
- i*imageWidth,
- imageWidth
- );
- } // for
- toSend = dst;
- }
-
- if (forceRGB) {
- setPixels(
- imageLeft,
- imageTop,
- imageWidth,
- imageHeight,
- ColorModel.getRGBdefault(),
- (int [])toSend,
- offset,
- imageWidth
- );
- } else {
- setPixels(
- imageLeft,
- imageTop,
- imageWidth,
- imageHeight,
- null,
- (byte [])toSend,
- offset,
- imageWidth
- );
- }
- }
- }
-
- class GifColorTable {
- // Indicates that reading of this block accomplished
- boolean completed = false;
-
- IndexColorModel cm = null;
- int size = 0; // Actual number of colors in the color table
- byte colors[] = new byte[256*3];
-
- IndexColorModel getColorModel(int transparentColor) {
- if (cm != null) {
- if (transparentColor != cm.getTransparentPixel()) {
- return cm = null; // Force default ARGB color model
- }
- return cm;
- } else
- if (completed && size > 0) {
- if (transparentColor == IMPOSSIBLE_VALUE) {
- return cm =
- new IndexColorModel(8, size, colors, 0, false);
- }
-
- if (transparentColor > size) {
- size = transparentColor + 1;
- }
- return cm =
- new IndexColorModel(8, size, colors, 0, false, transparentColor);
- }
-
- return cm = null; // Force default ARGB color model
- }
- }
-}