1/*
2 * Copyright (c) 1995, 2019, 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 jboolean 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