1/*
2 * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26#include <stdio.h>
27#include "jni.h"
28#include "jni_util.h"
29
30#define OUTCODELENGTH 4097
31
32/* We use Get/ReleasePrimitiveArrayCritical functions to avoid
33 * the need to copy buffer elements.
34 *
35 * MAKE SURE TO:
36 *
37 * - carefully insert pairs of RELEASE_ARRAYS and GET_ARRAYS around
38 *   callbacks to Java.
39 * - call RELEASE_ARRAYS before returning to Java.
40 *
41 * Otherwise things will go horribly wrong. There may be memory leaks,
42 * excessive pinning, or even VM crashes!
43 *
44 * Note that GetPrimitiveArrayCritical may fail!
45 */
46
47#define GET_ARRAYS() \
48    prefix  = (short *) \
49        (*env)->GetPrimitiveArrayCritical(env, prefixh, 0); \
50    if (prefix == 0) \
51        goto out_of_memory; \
52    suffix  = (unsigned char *) \
53        (*env)->GetPrimitiveArrayCritical(env, suffixh, 0); \
54    if (suffix == 0) \
55        goto out_of_memory; \
56    outCode = (unsigned char *) \
57        (*env)->GetPrimitiveArrayCritical(env, outCodeh, 0); \
58    if (outCode == 0) \
59        goto out_of_memory; \
60    rasline = (unsigned char *) \
61        (*env)->GetPrimitiveArrayCritical(env, raslineh, 0); \
62    if (rasline == 0) \
63        goto out_of_memory; \
64    block = (unsigned char *) \
65        (*env)->GetPrimitiveArrayCritical(env, blockh, 0); \
66    if (block == 0) \
67        goto out_of_memory
68
69/*
70 * Note that it is important to check whether the arrays are NULL,
71 * because GetPrimitiveArrayCritical might have failed.
72 */
73#define RELEASE_ARRAYS() \
74if (prefix) \
75    (*env)->ReleasePrimitiveArrayCritical(env, prefixh, prefix, 0); \
76if (suffix) \
77    (*env)->ReleasePrimitiveArrayCritical(env, suffixh, suffix, 0); \
78if (outCode) \
79    (*env)->ReleasePrimitiveArrayCritical(env, outCodeh, outCode, 0); \
80if (rasline) \
81    (*env)->ReleasePrimitiveArrayCritical(env, raslineh, rasline, 0); \
82if (block) \
83    (*env)->ReleasePrimitiveArrayCritical(env, blockh, block, 0)
84
85/* Place holders for the old native interface. */
86
87long
88sun_awt_image_GifImageDecoder_parseImage()
89{
90  return 0;
91}
92
93void
94sun_awt_image_GifImageDecoder_initIDs()
95{
96}
97
98static jmethodID readID;
99static jmethodID sendID;
100static jfieldID prefixID;
101static jfieldID suffixID;
102static jfieldID outCodeID;
103
104JNIEXPORT void JNICALL
105Java_sun_awt_image_GifImageDecoder_initIDs(JNIEnv *env, jclass this)
106{
107    CHECK_NULL(readID = (*env)->GetMethodID(env, this, "readBytes", "([BII)I"));
108    CHECK_NULL(sendID = (*env)->GetMethodID(env, this, "sendPixels",
109                                 "(IIII[BLjava/awt/image/ColorModel;)I"));
110    CHECK_NULL(prefixID = (*env)->GetFieldID(env, this, "prefix", "[S"));
111    CHECK_NULL(suffixID = (*env)->GetFieldID(env, this, "suffix", "[B"));
112    CHECK_NULL(outCodeID = (*env)->GetFieldID(env, this, "outCode", "[B"));
113}
114
115JNIEXPORT jboolean JNICALL
116Java_sun_awt_image_GifImageDecoder_parseImage(JNIEnv *env,
117                                              jobject this,
118                                              jint relx, jint rely,
119                                              jint width, jint height,
120                                              jint interlace,
121                                              jint initCodeSize,
122                                              jbyteArray blockh,
123                                              jbyteArray raslineh,
124                                              jobject cmh)
125{
126    /* Patrick Naughton:
127     * Note that I ignore the possible existence of a local color map.
128     * I'm told there aren't many files around that use them, and the
129     * spec says it's defined for future use.  This could lead to an
130     * error reading some files.
131     *
132     * Start reading the image data. First we get the intial code size
133     * and compute decompressor constant values, based on this code
134     * size.
135     *
136     * The GIF spec has it that the code size is the code size used to
137     * compute the above values is the code size given in the file,
138     * but the code size used in compression/decompression is the code
139     * size given in the file plus one. (thus the ++).
140     *
141     * Arthur van Hoff:
142     * The following narly code reads LZW compressed data blocks and
143     * dumps it into the image data. The input stream is broken up into
144     * blocks of 1-255 characters, each preceded by a length byte.
145     * 3-12 bit codes are read from these blocks. The codes correspond to
146     * entry is the hashtable (the prefix, suffix stuff), and the appropriate
147     * pixels are written to the image.
148     */
149    static int verbose = 0;
150
151    int clearCode = (1 << initCodeSize);
152    int eofCode = clearCode + 1;
153    int bitMask;
154    int curCode;
155    int outCount;
156
157    /* Variables used to form reading data */
158    int blockEnd = 0;
159    int remain = 0;
160    int byteoff = 0;
161    int accumbits = 0;
162    int accumdata = 0;
163
164    /* Variables used to decompress the data */
165    int codeSize = initCodeSize + 1;
166    int maxCode = 1 << codeSize;
167    int codeMask = maxCode - 1;
168    int freeCode = clearCode + 2;
169    int code = 0;
170    int oldCode = 0;
171    unsigned char prevChar = 0;
172
173    /* Temproray storage for decompression */
174    short *prefix;
175    unsigned char *suffix = NULL;
176    unsigned char *outCode = NULL;
177    unsigned char *rasline = NULL;
178    unsigned char *block = NULL;
179
180    jshortArray prefixh = (*env)->GetObjectField(env, this, prefixID);
181    jbyteArray suffixh = (*env)->GetObjectField(env, this, suffixID);
182    jbyteArray outCodeh = (*env)->GetObjectField(env, this, outCodeID);
183
184    int blockLength = 0;
185
186    /* Variables used for writing pixels */
187    int x = width;
188    int y = 0;
189    int off = 0;
190    int passinc = interlace ? 8 : 1;
191    int passht = passinc;
192    int len;
193
194    /* We have verified the initial code size on the java layer.
195     * Here we just check bounds for particular indexes. */
196    if (freeCode >= 4096 || maxCode >= 4096) {
197        return 0;
198    }
199    if (blockh == 0 || raslineh == 0
200        || prefixh == 0 || suffixh == 0
201        || outCodeh == 0)
202    {
203        JNU_ThrowNullPointerException(env, 0);
204        return 0;
205    }
206    if (((*env)->GetArrayLength(env, prefixh) != 4096) ||
207        ((*env)->GetArrayLength(env, suffixh) != 4096) ||
208        ((*env)->GetArrayLength(env, outCodeh) != OUTCODELENGTH))
209    {
210        JNU_ThrowArrayIndexOutOfBoundsException(env, 0);
211        return 0;
212    }
213
214    if (verbose) {
215        fprintf(stdout, "Decompressing...");
216    }
217
218    /* Fix for bugid 4216605 Some animated GIFs display corrupted. */
219    bitMask = clearCode - 1;
220
221    GET_ARRAYS();
222
223    /* Read codes until the eofCode is encountered */
224    for (;;) {
225        if (accumbits < codeSize) {
226            /* fill the buffer if needed */
227            while (remain < 2) {
228                if (blockEnd) {
229                    /* Sometimes we have one last byte to process... */
230                    if (remain == 1 && accumbits + 8 >= codeSize) {
231                        remain--;
232                        goto last_byte;
233                    }
234                    RELEASE_ARRAYS();
235                    if (off > 0) {
236                        (*env)->CallIntMethod(env, this, sendID,
237                                              relx, rely + y,
238                                              width, passht,
239                                              raslineh, cmh);
240                    }
241                    /* quietly accept truncated GIF images */
242                    return 1;
243                }
244                /* move remaining bytes to the beginning of the buffer */
245                block[0] = block[byteoff];
246                byteoff = 0;
247
248                RELEASE_ARRAYS();
249                /* fill the block */
250                len = (*env)->CallIntMethod(env, this, readID,
251                                            blockh, remain, blockLength + 1);
252                if (len > blockLength + 1) len = blockLength + 1;
253                if ((*env)->ExceptionOccurred(env)) {
254                    return 0;
255                }
256                GET_ARRAYS();
257
258                remain += blockLength;
259                if (len > 0) {
260                    remain -= (len - 1);
261                    blockLength = 0;
262                } else {
263                    blockLength = block[remain];
264                }
265                if (blockLength == 0) {
266                    blockEnd = 1;
267                }
268            }
269            remain -= 2;
270
271            /* 2 bytes at a time saves checking for accumbits < codeSize.
272             * We know we'll get enough and also that we can't overflow
273             * since codeSize <= 12.
274             */
275            accumdata += (block[byteoff++] & 0xff) << accumbits;
276            accumbits += 8;
277        last_byte:
278            accumdata += (block[byteoff++] & 0xff) << accumbits;
279            accumbits += 8;
280        }
281
282        /* Compute the code */
283        code = accumdata & codeMask;
284        accumdata >>= codeSize;
285        accumbits -= codeSize;
286
287        /*
288         * Interpret the code
289         */
290        if (code == clearCode) {
291            /* Clear code sets everything back to its initial value, then
292             * reads the immediately subsequent code as uncompressed data.
293             */
294            if (verbose) {
295                RELEASE_ARRAYS();
296                fprintf(stdout, ".");
297                fflush(stdout);
298                GET_ARRAYS();
299            }
300
301            /* Note that freeCode is one less than it is supposed to be,
302             * this is because it will be incremented next time round the loop
303             */
304            freeCode = clearCode + 1;
305            codeSize = initCodeSize + 1;
306            maxCode = 1 << codeSize;
307            codeMask = maxCode - 1;
308
309            /* Continue if we've NOT reached the end, some Gif images
310             * contain bogus codes after the last clear code.
311             */
312            if (y < height) {
313                continue;
314            }
315
316            /* pretend we've reached the end of the data */
317            code = eofCode;
318        }
319
320        if (code == eofCode) {
321            /* make sure we read the whole block of pixels. */
322        flushit:
323            while (!blockEnd) {
324                RELEASE_ARRAYS();
325                if (verbose) {
326                    fprintf(stdout, "flushing %d bytes\n", blockLength);
327                }
328                if ((*env)->CallIntMethod(env, this, readID,
329                                          blockh, 0, blockLength + 1) != 0
330                    || (*env)->ExceptionOccurred(env))
331                {
332                    /* quietly accept truncated GIF images */
333                    return (!(*env)->ExceptionOccurred(env));
334                }
335                GET_ARRAYS();
336                blockLength = block[blockLength];
337                blockEnd = (blockLength == 0);
338            }
339            RELEASE_ARRAYS();
340            return 1;
341        }
342
343        /* It must be data: save code in CurCode */
344        curCode = code;
345        outCount = OUTCODELENGTH;
346
347        /* If greater or equal to freeCode, not in the hash table
348         * yet; repeat the last character decoded
349         */
350        if (curCode >= freeCode) {
351            if (curCode > freeCode) {
352                /*
353                 * if we get a code too far outside our range, it
354                 * could case the parser to start traversing parts
355                 * of our data structure that are out of range...
356                 */
357                goto flushit;
358            }
359            curCode = oldCode;
360            outCode[--outCount] = prevChar;
361        }
362
363        /* Unless this code is raw data, pursue the chain pointed
364         * to by curCode through the hash table to its end; each
365         * code in the chain puts its associated output code on
366         * the output queue.
367         */
368         while (curCode > bitMask) {
369             outCode[--outCount] = suffix[curCode];
370             if (outCount == 0) {
371                 /*
372                  * In theory this should never happen since our
373                  * prefix and suffix arrays are monotonically
374                  * decreasing and so outCode will only be filled
375                  * as much as those arrays, but I don't want to
376                  * take that chance and the test is probably
377                  * cheap compared to the read and write operations.
378                  * If we ever do overflow the array, we will just
379                  * flush the rest of the data and quietly accept
380                  * the GIF as truncated here.
381                  */
382                 goto flushit;
383             }
384             curCode = prefix[curCode];
385         }
386
387        /* The last code in the chain is treated as raw data. */
388        prevChar = (unsigned char)curCode;
389        outCode[--outCount] = prevChar;
390
391        /* Now we put the data out to the Output routine. It's
392         * been stacked LIFO, so deal with it that way...
393         *
394         * Note that for some malformed images we have to skip
395         * current frame and continue with rest of data
396         * because we may have not enough info to interpret
397         * corrupted frame correctly.
398         * However, we can not skip frame without decoding it
399         * and therefore we have to continue looping through data
400         * but skip internal output loop.
401         *
402         * In particular this is possible when
403         * width of the frame is set to zero. If
404         * global width (i.e. width of the logical screen)
405         * is zero too then zero-length scanline buffer
406         * is allocated in java code and we have no buffer to
407         * store decoded data in.
408         */
409        len = OUTCODELENGTH - outCount;
410        while ((width > 0) && (--len >= 0)) {
411            rasline[off++] = outCode[outCount++];
412
413            /* Update the X-coordinate, and if it overflows, update the
414             * Y-coordinate
415             */
416            if (--x == 0) {
417                /* If a non-interlaced picture, just increment y to the next
418                 * scan line.  If it's interlaced, deal with the interlace as
419                 * described in the GIF spec.  Put the decoded scan line out
420                 * to the screen if we haven't gone past the bottom of it
421                 */
422                int count;
423                RELEASE_ARRAYS();
424                count = (*env)->CallIntMethod(env, this, sendID,
425                                              relx, rely + y,
426                                              width, passht,
427                                              raslineh, cmh);
428                if (count <= 0 || (*env)->ExceptionOccurred(env)) {
429                    /* Nobody is listening any more. */
430                    if (verbose) {
431                        fprintf(stdout, "Orphan gif decoder quitting\n");
432                    }
433                    return 0;
434                }
435                GET_ARRAYS();
436                x = width;
437                off = 0;
438                /*  pass        inc     ht      ystart */
439                /*   0           8      8          0   */
440                /*   1           8      4          4   */
441                /*   2           4      2          2   */
442                /*   3           2      1          1   */
443                y += passinc;
444                while (y >= height) {
445                    passinc = passht;
446                    passht >>= 1;
447                    y = passht;
448                    if (passht == 0) {
449                        goto flushit;
450                    }
451                }
452            }
453        }
454
455        /* Build the hash table on-the-fly. No table is stored in the file. */
456        prefix[freeCode] = (short)oldCode;
457        suffix[freeCode] = prevChar;
458        oldCode = code;
459
460        /* Point to the next slot in the table.  If we exceed the
461         * maxCode, increment the code size unless
462         * it's already 12.  If it is, do nothing: the next code
463         * decompressed better be CLEAR
464         */
465        if (++freeCode >= maxCode) {
466            if (codeSize < 12) {
467                codeSize++;
468                maxCode <<= 1;
469                codeMask = maxCode - 1;
470            } else {
471                /* Just in case */
472                freeCode = maxCode - 1;
473            }
474        }
475    }
476out_of_memory:
477    RELEASE_ARRAYS();
478    return 0;
479}
480