#include <string.h>
#include <android/log.h>
#include <android/bitmap.h>
#include <jni.h>
#include "SkCanvas.h"
#include "SkMovie.h"
#include "SkRect.h"
#include "SkTime.h"
#include "SkPaint.h"
#include "GraphicsJNI.h"
#define LOG_TAG "libglgif"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
extern "C" {
JNIEXPORT jlong JNICALL Java_com_zte_liaoxy_myGLRenderer_nativeCreateGif(JNIEnv* env, jobject thiz, jstring path);
JNIEXPORT void JNICALL Java_com_zte_liaoxy_myGLRenderer_nativeDrawGif(JNIEnv* env, jobject thiz, jobject canvas, jobject paint, jlong gifid, jint left, jint top);
JNIEXPORT void JNICALL Java_com_zte_liaoxy_myGLRenderer_nativeCopyToBitmap(JNIEnv* env, jobject thiz, jobject bitmap, jlong gifid, jint left, jint top);
JNIEXPORT void JNICALL Java_com_zte_liaoxy_myGLRenderer_nativeDeleteGif(JNIEnv* env, jobject thiz, jlong gif);
JNIEXPORT jint JNICALL Java_com_zte_liaoxy_myGLRenderer_getNativeGifWidth(JNIEnv* env, jobject thiz, jlong gif);
JNIEXPORT jint JNICALL Java_com_zte_liaoxy_myGLRenderer_getNativeGifHeigth(JNIEnv* env, jobject thiz, jlong gif);
}
JNIEXPORT jlong JNICALL Java_com_zte_liaoxy_myGLRenderer_nativeCreateGif(JNIEnv* env, jobject thiz, jstring path) {
jlong result = 0;
LOGE("create gif");
if (NULL != path) {
const char * const pathstr = env->GetStringUTFChars(path, NULL) ;
LOGE("create gif %s", pathstr);
const SkMovie* movie = SkMovie::DecodeFile(pathstr);
if (NULL != movie) {
result = reinterpret_cast<jlong>(movie);
LOGE("create gif %s done with %p (%lld)", pathstr, movie, result);
}
env->ReleaseStringUTFChars(path, pathstr);
}
return result;
}
JNIEXPORT void JNICALL Java_com_zte_liaoxy_myGLRenderer_nativeDeleteGif(JNIEnv* env, jobject thiz, jlong gifid) {
SkMovie* ptr = reinterpret_cast<SkMovie*>(gifid);
LOGE("delete gif %p (%lld)", ptr, gifid);
if (NULL != ptr) {
delete ptr;
}
}
JNIEXPORT jint JNICALL Java_com_zte_liaoxy_myGLRenderer_getNativeGifWidth(JNIEnv* env, jobject thiz, jlong gif){
SkMovie* ptr = reinterpret_cast<SkMovie*>(gif);
LOGE("getWidth gif %p (%lld)", ptr, gif);
int width = ptr->width();
LOGE("getWidth gif width %d", width);
return width;
}
JNIEXPORT jint JNICALL Java_com_zte_liaoxy_myGLRenderer_getNativeGifHeigth(JNIEnv* env, jobject thiz, jlong gif){
SkMovie* ptr = reinterpret_cast<SkMovie*>(gif);
LOGE("getHeigth gif %p (%lld)", ptr, gif);
int heigth = ptr->height();
LOGE("getHeigth gif heigth %d", heigth);
return heigth;
}
JNIEXPORT void JNICALL Java_com_zte_liaoxy_myGLRenderer_nativeCopyToBitmap(JNIEnv* env, jobject thiz, jobject bitmap, jlong gifid, jint left, jint top) {
SkMovie* movie = reinterpret_cast<SkMovie*>(gifid);
LOGE("draw gif %p (%lld)", movie, gifid);
if (NULL != bitmap && NULL != movie) {
SkMSec duration = movie->duration();
SkMSec time = 0;
if (duration) {
time = SkTime::GetMSecs() % duration;
movie->setTime(time);
} else {
movie->setTime(0);
}
AndroidBitmapInfo bitmapInfo;
void* bitmapPixels;
int ret = AndroidBitmap_getInfo(env, bitmap, &bitmapInfo);
if (0 > ret) {
LOGE("get bitmap %p info failed: %d", &bitmap, ret);
}
ret = AndroidBitmap_lockPixels(env, bitmap, &bitmapPixels);
if (0 > ret) {
LOGE("lock bitmap %p failed: %d", &bitmap, ret);
}
SkBitmap::Config config = SkBitmap::kNo_Config;
switch(bitmapInfo.format) {
case ANDROID_BITMAP_FORMAT_RGBA_8888:
config = SkBitmap::kARGB_8888_Config;
break;
case ANDROID_BITMAP_FORMAT_RGB_565:
config = SkBitmap::kRGB_565_Config;
break;
case ANDROID_BITMAP_FORMAT_RGBA_4444:
config = SkBitmap::kARGB_4444_Config;
break;
case ANDROID_BITMAP_FORMAT_A_8:
config = SkBitmap::kA8_Config;
break;
}
if (SkBitmap::kNo_Config == config || SkBitmap::kConfigCount <= config) {
LOGE("unsupported bitmap format %d", bitmapInfo.format);
return;
}
SkBitmap skBitmap;
skBitmap.setConfig(config, bitmapInfo.width, bitmapInfo.height, 0);
skBitmap.setPixels(bitmapPixels);
SkCanvas skCanvas(skBitmap);
LOGE(" begin drawing %d/%d on native canvas %p", time, duration, &skCanvas);
const SkBitmap& movieBitmap = movie->bitmap();
LOGE("nativeCopyToBitmap===========drawing bitmap %p to the native canvas at (%d, %d)", &movieBitmap, left, top);
skCanvas.drawBitmap(movieBitmap, SkIntToScalar(left), SkIntToScalar(top));
}
}
JNIEXPORT void JNICALL Java_com_zte_liaoxy_myGLRenderer_nativeDrawGif(JNIEnv* env, jobject thiz, jobject canvas, jobject paint, jlong gifid, jint left, jint top)
{
SkMovie* movie = reinterpret_cast<SkMovie*>(gifid);
LOGE("draw gif %p (%lld)", movie, gifid);
if (NULL != canvas && NULL != movie) {
SkMSec duration = movie->duration();
SkMSec time = 0;
if (duration) {
time = SkTime::GetMSecs() % duration;
movie->setTime(time);
} else {
movie->setTime(0);
}
SkCanvas *skCanvas = GraphicsJNI::getNativeCanvas(env, canvas);
SkPaint *skPaint = NULL;
if (NULL != paint) {
skPaint = GraphicsJNI::getNativePaint(env, paint);
} else {
LOGE(" !!NO Paint!!");
}
LOGE(" begin drawing %d/%d on native canvas %p", time, duration, skCanvas);
if (NULL != skCanvas) {
if (NULL != skPaint) {
skPaint->setColor(SK_ColorBLACK);
SkRect rect;
rect.set(10, 10, left, top);
skCanvas->drawRect(rect, *skPaint);
}
const SkBitmap& bitmap = movie->bitmap();
LOGE("=======nativeDrawGif drawing bitmap %p to the native canvas at (%d, %d)", &bitmap, left, top);
skCanvas->drawBitmap(bitmap, SkIntToScalar(left), SkIntToScalar(top), skPaint);
}
}
}