src/java.desktop/share/native/libawt/awt/image/gif/gifdecoder.c
changeset 47216 71c04702a3d5
parent 28059 e576535359cc
child 54398 62171da145f9
child 56230 489867818774
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     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() \
       
    74 if (prefix) \
       
    75     (*env)->ReleasePrimitiveArrayCritical(env, prefixh, prefix, 0); \
       
    76 if (suffix) \
       
    77     (*env)->ReleasePrimitiveArrayCritical(env, suffixh, suffix, 0); \
       
    78 if (outCode) \
       
    79     (*env)->ReleasePrimitiveArrayCritical(env, outCodeh, outCode, 0); \
       
    80 if (rasline) \
       
    81     (*env)->ReleasePrimitiveArrayCritical(env, raslineh, rasline, 0); \
       
    82 if (block) \
       
    83     (*env)->ReleasePrimitiveArrayCritical(env, blockh, block, 0)
       
    84 
       
    85 /* Place holders for the old native interface. */
       
    86 
       
    87 long
       
    88 sun_awt_image_GifImageDecoder_parseImage()
       
    89 {
       
    90   return 0;
       
    91 }
       
    92 
       
    93 void
       
    94 sun_awt_image_GifImageDecoder_initIDs()
       
    95 {
       
    96 }
       
    97 
       
    98 static jmethodID readID;
       
    99 static jmethodID sendID;
       
   100 static jfieldID prefixID;
       
   101 static jfieldID suffixID;
       
   102 static jfieldID outCodeID;
       
   103 
       
   104 JNIEXPORT void JNICALL
       
   105 Java_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 
       
   115 JNIEXPORT jboolean JNICALL
       
   116 Java_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     }
       
   476 out_of_memory:
       
   477     RELEASE_ARRAYS();
       
   478     return 0;
       
   479 }