Path: blob/master/src/java.desktop/share/native/libawt/awt/image/gif/gifdecoder.c
41161 views
/*1* Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include <stdio.h>26#include "jni.h"27#include "jni_util.h"2829#define OUTCODELENGTH 40973031/* We use Get/ReleasePrimitiveArrayCritical functions to avoid32* the need to copy buffer elements.33*34* MAKE SURE TO:35*36* - carefully insert pairs of RELEASE_ARRAYS and GET_ARRAYS around37* callbacks to Java.38* - call RELEASE_ARRAYS before returning to Java.39*40* Otherwise things will go horribly wrong. There may be memory leaks,41* excessive pinning, or even VM crashes!42*43* Note that GetPrimitiveArrayCritical may fail!44*/4546#define GET_ARRAYS() \47prefix = (short *) \48(*env)->GetPrimitiveArrayCritical(env, prefixh, 0); \49if (prefix == 0) \50goto out_of_memory; \51suffix = (unsigned char *) \52(*env)->GetPrimitiveArrayCritical(env, suffixh, 0); \53if (suffix == 0) \54goto out_of_memory; \55outCode = (unsigned char *) \56(*env)->GetPrimitiveArrayCritical(env, outCodeh, 0); \57if (outCode == 0) \58goto out_of_memory; \59rasline = (unsigned char *) \60(*env)->GetPrimitiveArrayCritical(env, raslineh, 0); \61if (rasline == 0) \62goto out_of_memory; \63block = (unsigned char *) \64(*env)->GetPrimitiveArrayCritical(env, blockh, 0); \65if (block == 0) \66goto out_of_memory6768/*69* Note that it is important to check whether the arrays are NULL,70* because GetPrimitiveArrayCritical might have failed.71*/72#define RELEASE_ARRAYS() \73if (prefix) \74(*env)->ReleasePrimitiveArrayCritical(env, prefixh, prefix, 0); \75if (suffix) \76(*env)->ReleasePrimitiveArrayCritical(env, suffixh, suffix, 0); \77if (outCode) \78(*env)->ReleasePrimitiveArrayCritical(env, outCodeh, outCode, 0); \79if (rasline) \80(*env)->ReleasePrimitiveArrayCritical(env, raslineh, rasline, 0); \81if (block) \82(*env)->ReleasePrimitiveArrayCritical(env, blockh, block, 0)8384/* Place holders for the old native interface. */8586long87sun_awt_image_GifImageDecoder_parseImage()88{89return 0;90}9192void93sun_awt_image_GifImageDecoder_initIDs()94{95}9697static jmethodID readID;98static jmethodID sendID;99static jfieldID prefixID;100static jfieldID suffixID;101static jfieldID outCodeID;102103JNIEXPORT void JNICALL104Java_sun_awt_image_GifImageDecoder_initIDs(JNIEnv *env, jclass this)105{106CHECK_NULL(readID = (*env)->GetMethodID(env, this, "readBytes", "([BII)I"));107CHECK_NULL(sendID = (*env)->GetMethodID(env, this, "sendPixels",108"(IIII[BLjava/awt/image/ColorModel;)I"));109CHECK_NULL(prefixID = (*env)->GetFieldID(env, this, "prefix", "[S"));110CHECK_NULL(suffixID = (*env)->GetFieldID(env, this, "suffix", "[B"));111CHECK_NULL(outCodeID = (*env)->GetFieldID(env, this, "outCode", "[B"));112}113114JNIEXPORT jboolean JNICALL115Java_sun_awt_image_GifImageDecoder_parseImage(JNIEnv *env,116jobject this,117jint relx, jint rely,118jint width, jint height,119jboolean interlace,120jint initCodeSize,121jbyteArray blockh,122jbyteArray raslineh,123jobject cmh)124{125/* Patrick Naughton:126* Note that I ignore the possible existence of a local color map.127* I'm told there aren't many files around that use them, and the128* spec says it's defined for future use. This could lead to an129* error reading some files.130*131* Start reading the image data. First we get the intial code size132* and compute decompressor constant values, based on this code133* size.134*135* The GIF spec has it that the code size is the code size used to136* compute the above values is the code size given in the file,137* but the code size used in compression/decompression is the code138* size given in the file plus one. (thus the ++).139*140* Arthur van Hoff:141* The following narly code reads LZW compressed data blocks and142* dumps it into the image data. The input stream is broken up into143* blocks of 1-255 characters, each preceded by a length byte.144* 3-12 bit codes are read from these blocks. The codes correspond to145* entry is the hashtable (the prefix, suffix stuff), and the appropriate146* pixels are written to the image.147*/148static int verbose = 0;149150int clearCode = (1 << initCodeSize);151int eofCode = clearCode + 1;152int bitMask;153int curCode;154int outCount;155156/* Variables used to form reading data */157int blockEnd = 0;158int remain = 0;159int byteoff = 0;160int accumbits = 0;161int accumdata = 0;162163/* Variables used to decompress the data */164int codeSize = initCodeSize + 1;165int maxCode = 1 << codeSize;166int codeMask = maxCode - 1;167int freeCode = clearCode + 2;168int code = 0;169int oldCode = 0;170unsigned char prevChar = 0;171172/* Temproray storage for decompression */173short *prefix;174unsigned char *suffix = NULL;175unsigned char *outCode = NULL;176unsigned char *rasline = NULL;177unsigned char *block = NULL;178179jshortArray prefixh = (*env)->GetObjectField(env, this, prefixID);180jbyteArray suffixh = (*env)->GetObjectField(env, this, suffixID);181jbyteArray outCodeh = (*env)->GetObjectField(env, this, outCodeID);182183int blockLength = 0;184185/* Variables used for writing pixels */186int x = width;187int y = 0;188int off = 0;189int passinc = interlace ? 8 : 1;190int passht = passinc;191int len;192193/* We have verified the initial code size on the java layer.194* Here we just check bounds for particular indexes. */195if (freeCode >= 4096 || maxCode >= 4096) {196return 0;197}198if (blockh == 0 || raslineh == 0199|| prefixh == 0 || suffixh == 0200|| outCodeh == 0)201{202JNU_ThrowNullPointerException(env, 0);203return 0;204}205if (((*env)->GetArrayLength(env, prefixh) != 4096) ||206((*env)->GetArrayLength(env, suffixh) != 4096) ||207((*env)->GetArrayLength(env, outCodeh) != OUTCODELENGTH))208{209JNU_ThrowArrayIndexOutOfBoundsException(env, 0);210return 0;211}212213if (verbose) {214fprintf(stdout, "Decompressing...");215}216217/* Fix for bugid 4216605 Some animated GIFs display corrupted. */218bitMask = clearCode - 1;219220GET_ARRAYS();221222/* Read codes until the eofCode is encountered */223for (;;) {224if (accumbits < codeSize) {225/* fill the buffer if needed */226while (remain < 2) {227if (blockEnd) {228/* Sometimes we have one last byte to process... */229if (remain == 1 && accumbits + 8 >= codeSize) {230remain--;231goto last_byte;232}233RELEASE_ARRAYS();234if (off > 0) {235(*env)->CallIntMethod(env, this, sendID,236relx, rely + y,237width, passht,238raslineh, cmh);239}240/* quietly accept truncated GIF images */241return 1;242}243/* move remaining bytes to the beginning of the buffer */244block[0] = block[byteoff];245byteoff = 0;246247RELEASE_ARRAYS();248/* fill the block */249len = (*env)->CallIntMethod(env, this, readID,250blockh, remain, blockLength + 1);251if (len > blockLength + 1) len = blockLength + 1;252if ((*env)->ExceptionOccurred(env)) {253return 0;254}255GET_ARRAYS();256257remain += blockLength;258if (len > 0) {259remain -= (len - 1);260blockLength = 0;261} else {262blockLength = block[remain];263}264if (blockLength == 0) {265blockEnd = 1;266}267}268remain -= 2;269270/* 2 bytes at a time saves checking for accumbits < codeSize.271* We know we'll get enough and also that we can't overflow272* since codeSize <= 12.273*/274accumdata += (block[byteoff++] & 0xff) << accumbits;275accumbits += 8;276last_byte:277accumdata += (block[byteoff++] & 0xff) << accumbits;278accumbits += 8;279}280281/* Compute the code */282code = accumdata & codeMask;283accumdata >>= codeSize;284accumbits -= codeSize;285286/*287* Interpret the code288*/289if (code == clearCode) {290/* Clear code sets everything back to its initial value, then291* reads the immediately subsequent code as uncompressed data.292*/293if (verbose) {294RELEASE_ARRAYS();295fprintf(stdout, ".");296fflush(stdout);297GET_ARRAYS();298}299300/* Note that freeCode is one less than it is supposed to be,301* this is because it will be incremented next time round the loop302*/303freeCode = clearCode + 1;304codeSize = initCodeSize + 1;305maxCode = 1 << codeSize;306codeMask = maxCode - 1;307308/* Continue if we've NOT reached the end, some Gif images309* contain bogus codes after the last clear code.310*/311if (y < height) {312continue;313}314315/* pretend we've reached the end of the data */316code = eofCode;317}318319if (code == eofCode) {320/* make sure we read the whole block of pixels. */321flushit:322while (!blockEnd) {323RELEASE_ARRAYS();324if (verbose) {325fprintf(stdout, "flushing %d bytes\n", blockLength);326}327if ((*env)->CallIntMethod(env, this, readID,328blockh, 0, blockLength + 1) != 0329|| (*env)->ExceptionOccurred(env))330{331/* quietly accept truncated GIF images */332return (!(*env)->ExceptionOccurred(env));333}334GET_ARRAYS();335blockLength = block[blockLength];336blockEnd = (blockLength == 0);337}338RELEASE_ARRAYS();339return 1;340}341342/* It must be data: save code in CurCode */343curCode = code;344outCount = OUTCODELENGTH;345346/* If greater or equal to freeCode, not in the hash table347* yet; repeat the last character decoded348*/349if (curCode >= freeCode) {350if (curCode > freeCode) {351/*352* if we get a code too far outside our range, it353* could case the parser to start traversing parts354* of our data structure that are out of range...355*/356goto flushit;357}358curCode = oldCode;359outCode[--outCount] = prevChar;360}361362/* Unless this code is raw data, pursue the chain pointed363* to by curCode through the hash table to its end; each364* code in the chain puts its associated output code on365* the output queue.366*/367while (curCode > bitMask) {368outCode[--outCount] = suffix[curCode];369if (outCount == 0) {370/*371* In theory this should never happen since our372* prefix and suffix arrays are monotonically373* decreasing and so outCode will only be filled374* as much as those arrays, but I don't want to375* take that chance and the test is probably376* cheap compared to the read and write operations.377* If we ever do overflow the array, we will just378* flush the rest of the data and quietly accept379* the GIF as truncated here.380*/381goto flushit;382}383curCode = prefix[curCode];384}385386/* The last code in the chain is treated as raw data. */387prevChar = (unsigned char)curCode;388outCode[--outCount] = prevChar;389390/* Now we put the data out to the Output routine. It's391* been stacked LIFO, so deal with it that way...392*393* Note that for some malformed images we have to skip394* current frame and continue with rest of data395* because we may have not enough info to interpret396* corrupted frame correctly.397* However, we can not skip frame without decoding it398* and therefore we have to continue looping through data399* but skip internal output loop.400*401* In particular this is possible when402* width of the frame is set to zero. If403* global width (i.e. width of the logical screen)404* is zero too then zero-length scanline buffer405* is allocated in java code and we have no buffer to406* store decoded data in.407*/408len = OUTCODELENGTH - outCount;409while ((width > 0) && (--len >= 0)) {410rasline[off++] = outCode[outCount++];411412/* Update the X-coordinate, and if it overflows, update the413* Y-coordinate414*/415if (--x == 0) {416/* If a non-interlaced picture, just increment y to the next417* scan line. If it's interlaced, deal with the interlace as418* described in the GIF spec. Put the decoded scan line out419* to the screen if we haven't gone past the bottom of it420*/421int count;422RELEASE_ARRAYS();423count = (*env)->CallIntMethod(env, this, sendID,424relx, rely + y,425width, passht,426raslineh, cmh);427if (count <= 0 || (*env)->ExceptionOccurred(env)) {428/* Nobody is listening any more. */429if (verbose) {430fprintf(stdout, "Orphan gif decoder quitting\n");431}432return 0;433}434GET_ARRAYS();435x = width;436off = 0;437/* pass inc ht ystart */438/* 0 8 8 0 */439/* 1 8 4 4 */440/* 2 4 2 2 */441/* 3 2 1 1 */442y += passinc;443while (y >= height) {444passinc = passht;445passht >>= 1;446y = passht;447if (passht == 0) {448goto flushit;449}450}451}452}453454/* Build the hash table on-the-fly. No table is stored in the file. */455prefix[freeCode] = (short)oldCode;456suffix[freeCode] = prevChar;457oldCode = code;458459/* Point to the next slot in the table. If we exceed the460* maxCode, increment the code size unless461* it's already 12. If it is, do nothing: the next code462* decompressed better be CLEAR463*/464if (++freeCode >= maxCode) {465if (codeSize < 12) {466codeSize++;467maxCode <<= 1;468codeMask = maxCode - 1;469} else {470/* Just in case */471freeCode = maxCode - 1;472}473}474}475out_of_memory:476RELEASE_ARRAYS();477return 0;478}479480481