GIFLoader (InputStream& in) : input (in), dataBlockIsZero (false), fresh (false), finished (false), currentBit (0), lastBit (0), lastByteIndex (0), codeSize (0), setCodeSize (0), maxCode (0), maxCodeSize (0), firstcode (0), oldcode (0), clearCode (0), endCode (0) { int imageWidth, imageHeight; if (! getSizeFromHeader (imageWidth, imageHeight)) return; uint8 buf [16]; if (in.read (buf, 3) != 3) return; int numColours = 2 << (buf[0] & 7); int transparent = -1; if ((buf[0] & 0x80) != 0) readPalette (numColours); for (;;) { if (input.read (buf, 1) != 1 || buf[0] == ';') break; if (buf[0] == '!') { if (readExtension (transparent)) continue; break; } if (buf[0] != ',') continue; if (input.read (buf, 9) == 9) { imageWidth = (int) ByteOrder::littleEndianShort (buf + 4); imageHeight = (int) ByteOrder::littleEndianShort (buf + 6); numColours = 2 << (buf[8] & 7); if ((buf[8] & 0x80) != 0) if (! readPalette (numColours)) break; image = Image (transparent >= 0 ? Image::ARGB : Image::RGB, imageWidth, imageHeight, transparent >= 0); image.getProperties()->set ("originalImageHadAlpha", transparent >= 0); readImage ((buf[8] & 0x40) != 0, transparent); } break; } }
/* * Class: org_apache_harmony_awt_gl_image_GifDecoder * Method: decode * Signature: ([BIJLorg/apache/harmony/awt/gl/image/GifDecoder$GifDataStream;Lorg/apache/harmony/awt/gl/image/GifDecoder$GifGraphicBlock;)I */ JNIEXPORT jint JNICALL Java_org_apache_harmony_awt_gl_image_GifDecoder_decode (JNIEnv *env, jobject obj, jbyteArray jInput, jint bytesInBuffer, jlong hDecoder, jobject dataStream, jobject currBlock) { GIF_RETVAL retval = STATUS_OK; GifDecoder *decoder = getDecoder(env, obj, dataStream, (GifDecoder*) ((IDATA)hDecoder)); int scanlinesDecoded; decoder->input = decoder->inputPtr = (*env)->GetPrimitiveArrayCritical(env, jInput, 0); decoder->bytesInBuffer += bytesInBuffer; bytesInBuffer = decoder->bytesInBuffer; while(retval == STATUS_OK && decoder->bytesInBuffer > 0) { switch(decoder->state) { case STATE_INIT: { retval = readHeader(env, decoder); break; } case STATE_AT_GLOBAL_COLOR_TABLE: { retval = loadColorTable(env, decoder->jGlobalColorTable, decoder); break; } case STATE_AT_LOCAL_COLOR_TABLE: { retval = loadColorTable(env, NULL, decoder); break; } case STATE_BLOCK_BEGINNING: { unsigned char blockLabel = *(decoder->inputPtr); switch(blockLabel) { case EXTENSION_INTRODUCER: retval = readExtension(env, decoder, currBlock); break; case IMAGE_SEPARATOR: retval = readImageDescriptor(env, currBlock, decoder); break; case GIF_TRAILER: retval = STATUS_EOF; break; } break; } case STATE_STARTING_DECOMPRESSION: { retval = initDecompression(env, decoder, currBlock); break; } case STATE_DECOMPRESSING: { if(!decoder->interlace) retval = decompress(env, currBlock, decoder); else retval = decompressInterlaced(env, currBlock, decoder); break; } case STATE_READING_COMMENT: { retval = readComment(env, decoder); break; } case STATE_SKIPPING_BLOCKS: { retval = skipData(decoder); break; } default: // Should never execute this! break; } } // Copy unconsumed data to the start of the input buffer if(decoder->bytesInBuffer > 0) { memmove(decoder->input, decoder->inputPtr, decoder->bytesInBuffer); } (*env)->ReleasePrimitiveArrayCritical(env, jInput, decoder->input, 0); (*env)->SetIntField( env, obj, img_GIF_bytesConsumedID, bytesInBuffer - decoder->bytesInBuffer ); if(decoder->stateVars.imageDataStarted) { if(!decoder->interlace) { scanlinesDecoded = decoder->pixelsDecoded / decoder->currentWidth - decoder->oldPixelsDecoded / decoder->currentWidth; decoder->oldPixelsDecoded = decoder->pixelsDecoded; } else { if(retval == STATUS_LINE_COMPLETED && decoder->pass < MAX_PASS) { scanlinesDecoded = 1; if(decoder->currScanline >= 0) (*env)->SetIntField(env, currBlock, img_GIF_gb_currYID, decoder->currScanline); decoder->scanlineOffset = 0; } else { scanlinesDecoded = 0; } } } else { scanlinesDecoded = 0; } if(retval == STATUS_FRAME_COMPLETED) { decoder->oldPixelsDecoded = decoder->pixelsDecoded = 0; } // Free the decoder if decoding is finished if(retval == STATUS_EOF) { free(decoder); decoder = NULL; } (*env)->SetLongField(env, obj, img_GIF_hNativeDecoderID, (jlong) ((IDATA)decoder)); return scanlinesDecoded; }