예제 #1
0
__unused JNIEXPORT jlong JNICALL
Java_pl_droidsonroids_gif_GifInfoHandle_renderFrame(JNIEnv *env, jclass __unused handleClass,
                                                    jlong gifInfo, jobject jbitmap) {
    GifInfo *info = (GifInfo *) (intptr_t) gifInfo;
    if (info == NULL)
        return -1;

    time_t renderStartTime = getRealTime();
    void *pixels;
    if (lockPixels(env, jbitmap, info, &pixels) != 0) {
        return 0;
    }
    DDGifSlurp(info, true);
    const uint_fast16_t frameDuration = getBitmap((argb *) pixels, info);
    unlockPixels(env, jbitmap);
    return calculateInvalidationDelay(info, renderStartTime, frameDuration);
}
예제 #2
0
파일: surface.c 프로젝트: zetbrush/Stuff
static void *slurp(void *pVoidInfo) {
    GifInfo *info = pVoidInfo;
    while (1) {
        pthread_mutex_lock(&info->surfaceDescriptor->slurpMutex);
        while (info->surfaceDescriptor->slurpHelper == 0)
            pthread_cond_wait(&info->surfaceDescriptor->slurpCond, &info->surfaceDescriptor->slurpMutex);

        if (info->surfaceDescriptor->slurpHelper == 2) {
            pthread_mutex_unlock(&info->surfaceDescriptor->slurpMutex);
            break;
        }
        info->surfaceDescriptor->slurpHelper = 0;
        pthread_mutex_unlock(&info->surfaceDescriptor->slurpMutex);
        DDGifSlurp(info, true);
        pthread_mutex_lock(&info->surfaceDescriptor->renderMutex);
        info->surfaceDescriptor->renderHelper = 1;
        pthread_cond_signal(&info->surfaceDescriptor->renderCond);
        pthread_mutex_unlock(&info->surfaceDescriptor->renderMutex);
    }

    DetachCurrentThread();
    return NULL;
}
예제 #3
0
static void *slurp(void *pVoidInfo) {
	GifInfo *info = pVoidInfo;
	SurfaceDescriptor *descriptor = info->frameBufferDescriptor;
	while (1) {
		pthread_mutex_lock(&descriptor->slurpMutex);
		while (descriptor->slurpHelper == 0) {
			pthread_cond_wait(&descriptor->slurpCond, &descriptor->slurpMutex);
		}

		if (descriptor->slurpHelper == 2) {
			pthread_mutex_unlock(&descriptor->slurpMutex);
			DetachCurrentThread();
			return NULL;
		}
		descriptor->slurpHelper = 0;
		pthread_mutex_unlock(&descriptor->slurpMutex);
		DDGifSlurp(info, true, false);
		pthread_mutex_lock(&descriptor->renderMutex);
		descriptor->renderHelper = 1;
		pthread_cond_signal(&descriptor->renderCond);
		pthread_mutex_unlock(&descriptor->renderMutex);
	}
}
예제 #4
0
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;
}
예제 #5
0
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);
}