GifInfo *createGifInfo(GifSourceDescriptor *descriptor, JNIEnv *env) { if (descriptor->startPos < 0) { descriptor->Error = D_GIF_ERR_NOT_READABLE; } if (descriptor->Error != 0 || descriptor->GifFileIn == NULL) { bool readErrno = descriptor->rewindFunc == fileRewind && (descriptor->Error == D_GIF_ERR_NOT_READABLE || descriptor->Error == D_GIF_ERR_READ_FAILED); throwGifIOException(descriptor->Error, env, readErrno); DGifCloseFile(descriptor->GifFileIn); return NULL; } GifInfo *info = malloc(sizeof(GifInfo)); if (info == NULL) { DGifCloseFile(descriptor->GifFileIn); throwException(env, OUT_OF_MEMORY_ERROR, OOME_MESSAGE); return NULL; } info->controlBlock = malloc(sizeof(GraphicsControlBlock)); if (info->controlBlock == NULL) { DGifCloseFile(descriptor->GifFileIn); throwException(env, OUT_OF_MEMORY_ERROR, OOME_MESSAGE); return NULL; } setGCBDefaults(info->controlBlock); info->destructor = NULL; info->gifFilePtr = descriptor->GifFileIn; info->startPos = descriptor->startPos; info->currentIndex = 0; info->nextStartTime = 0; info->lastFrameRemainder = -1; info->comment = NULL; info->loopCount = 1; info->currentLoop = 0; info->speedFactor = 1.0; info->sourceLength = descriptor->sourceLength; info->backupPtr = NULL; info->rewindFunction = descriptor->rewindFunc; info->frameBufferDescriptor = NULL; info->isOpaque = false; info->sampleSize = 1; DDGifSlurp(info, false, false); info->rasterBits = NULL; info->rasterSize = 0; info->originalHeight = info->gifFilePtr->SHeight; info->originalWidth = info->gifFilePtr->SWidth; if (descriptor->GifFileIn->SWidth < 1 || descriptor->GifFileIn->SHeight < 1) { DGifCloseFile(descriptor->GifFileIn); throwGifIOException(D_GIF_ERR_INVALID_SCR_DIMS, env, false); return NULL; } if (descriptor->GifFileIn->Error == D_GIF_ERR_NOT_ENOUGH_MEM) { cleanUp(info); throwException(env, OUT_OF_MEMORY_ERROR, OOME_MESSAGE); return NULL; } #if defined(STRICT_FORMAT_89A) descriptor->Error = descriptor->GifFileIn->Error; #endif if (descriptor->GifFileIn->ImageCount == 0) { descriptor->Error = D_GIF_ERR_NO_FRAMES; } else if (descriptor->GifFileIn->Error == D_GIF_ERR_REWIND_FAILED) { descriptor->Error = D_GIF_ERR_REWIND_FAILED; } if (descriptor->Error != 0) { cleanUp(info); throwGifIOException(descriptor->Error, env, false); return NULL; } return info; }
jobject createGifHandle(GifSourceDescriptor *descriptor, JNIEnv *env, jboolean justDecodeMetaData) { if (descriptor->startPos < 0) { descriptor->Error = D_GIF_ERR_NOT_READABLE; DGifCloseFile(descriptor->GifFileIn); } if (descriptor->Error != 0 || descriptor->GifFileIn == NULL) { throwGifIOException(descriptor->Error, env); return NULL; } GifInfo *info = malloc(sizeof(GifInfo)); if (info == NULL) { DGifCloseFile(descriptor->GifFileIn); throwException(env, OUT_OF_MEMORY_ERROR, OOME_MESSAGE); return NULL; } info->controlBlock = calloc(sizeof(GraphicsControlBlock), 1); info->controlBlock->DelayTime = DEFAULT_FRAME_DURATION_MS; if (info->controlBlock == NULL) { DGifCloseFile(descriptor->GifFileIn); throwException(env, OUT_OF_MEMORY_ERROR, OOME_MESSAGE); return NULL; } info->gifFilePtr = descriptor->GifFileIn; info->startPos = descriptor->startPos; info->currentIndex = 0; info->nextStartTime = 0; info->lastFrameRemainder = -1; info->comment = NULL; info->loopCount = 1; info->currentLoop = 0; info->speedFactor = 1.0; info->sourceLength = descriptor->sourceLength; info->backupPtr = NULL; info->rewindFunction = descriptor->rewindFunc; info->surfaceDescriptor = NULL; info->isOpaque = JNI_FALSE; DDGifSlurp(info, false); if (justDecodeMetaData == JNI_TRUE) info->rasterBits = NULL; else { info->rasterBits = malloc( descriptor->GifFileIn->SHeight * descriptor->GifFileIn->SWidth * sizeof(GifPixelType)); if (info->rasterBits == NULL) { descriptor->GifFileIn->Error = D_GIF_ERR_NOT_ENOUGH_MEM; } } if (descriptor->GifFileIn->SWidth < 1 || descriptor->GifFileIn->SHeight < 1) { DGifCloseFile(descriptor->GifFileIn); throwGifIOException(D_GIF_ERR_INVALID_SCR_DIMS, env); return NULL; } if (descriptor->GifFileIn->Error == D_GIF_ERR_NOT_ENOUGH_MEM) { cleanUp(info); throwException(env, OUT_OF_MEMORY_ERROR, OOME_MESSAGE); return NULL; } #if defined(STRICT_FORMAT_89A) descriptor->Error = descriptor->GifFileIn->Error; #endif if (descriptor->GifFileIn->ImageCount == 0) { descriptor->Error = D_GIF_ERR_NO_FRAMES; } else if (descriptor->GifFileIn->Error == D_GIF_ERR_REWIND_FAILED) { descriptor->Error = D_GIF_ERR_REWIND_FAILED; } if (descriptor->Error != 0) { cleanUp(info); throwGifIOException(descriptor->Error, env); return NULL; } jclass gifInfoHandleClass = (*env)->FindClass(env, "pl/droidsonroids/gif/GifInfoHandle"); if (gifInfoHandleClass == NULL) { cleanUp(info); return NULL; } jmethodID gifInfoHandleCtorMID = (*env)->GetMethodID(env, gifInfoHandleClass, "<init>", "(JIII)V"); if (gifInfoHandleCtorMID == NULL) { cleanUp(info); return NULL; } return (*env)->NewObject(env, gifInfoHandleClass, gifInfoHandleCtorMID, (jlong) (intptr_t) info, info->gifFilePtr->SWidth, info->gifFilePtr->SHeight, info->gifFilePtr->ImageCount); }