Movie.cpp revision 8451b25a4422656bbd6657a5855e69c0f4d53c74
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkMovie.h" 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkStream.h" 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "GraphicsJNI.h" 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkTemplates.h" 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkUtils.h" 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "CreateJavaOutputStreamAdaptor.h" 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Asset.h> 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/ResourceTypes.h> 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <netinet/in.h> 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #define TRACE_BITMAP(code) code 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project #define TRACE_BITMAP(code) 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass gMovie_class; 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID gMovie_constructorMethodID; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gMovie_nativeInstanceID; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjobject create_jmovie(JNIEnv* env, SkMovie* moov) { 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == moov) { 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject obj = env->AllocObject(gMovie_class); 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (obj) { 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->CallVoidMethod(obj, gMovie_constructorMethodID, (jint)moov); 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return obj; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic SkMovie* J2Movie(JNIEnv* env, jobject movie) { 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkASSERT(env); 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkASSERT(movie); 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkASSERT(env->IsInstanceOf(movie, gMovie_class)); 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkMovie* m = (SkMovie*)env->GetIntField(movie, gMovie_nativeInstanceID); 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkASSERT(m); 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return m; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/////////////////////////////////////////////////////////////////////////////// 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int movie_width(JNIEnv* env, jobject movie) { 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, movie); 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return J2Movie(env, movie)->width(); 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int movie_height(JNIEnv* env, jobject movie) { 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, movie); 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return J2Movie(env, movie)->height(); 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean movie_isOpaque(JNIEnv* env, jobject movie) { 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, movie); 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return J2Movie(env, movie)->isOpaque(); 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int movie_duration(JNIEnv* env, jobject movie) { 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, movie); 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return J2Movie(env, movie)->duration(); 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jboolean movie_setTime(JNIEnv* env, jobject movie, int ms) { 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, movie); 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return J2Movie(env, movie)->setTime(ms); 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void movie_draw(JNIEnv* env, jobject movie, jobject canvas, 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jfloat fx, jfloat fy, jobject jpaint) { 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_VOID(env, movie); 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_VOID(env, canvas); 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // its OK for paint to be null 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkMovie* m = J2Movie(env, movie); 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkCanvas* c = GraphicsJNI::getNativeCanvas(env, canvas); 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar sx = SkFloatToScalar(fx); 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkScalar sy = SkFloatToScalar(fy); 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SkBitmap& b = m->bitmap(); 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const SkPaint* p = jpaint ? GraphicsJNI::getNativePaint(env, jpaint) : NULL; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project c->drawBitmap(b, sx, sy, p); 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jobject movie_decodeStream(JNIEnv* env, jobject clazz, jobject istream) { 868451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, istream); 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // what is the lifetime of the array? Can the skstream hold onto it? 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyteArray byteArray = env->NewByteArray(16*1024); 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkStream* strm = CreateJavaInputStreamAdaptor(env, istream, byteArray); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == strm) { 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkMovie* moov = SkMovie::DecodeStream(strm); 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strm->unref(); 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return create_jmovie(env, moov); 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jobject movie_decodeByteArray(JNIEnv* env, jobject clazz, 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jbyteArray byteArray, 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int offset, int length) { 1048451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project NPE_CHECK_RETURN_ZERO(env, byteArray); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int totalLength = env->GetArrayLength(byteArray); 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((offset | length) < 0 || offset + length > totalLength) { 1098451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes doThrowAIOOBE(env); 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoJavaByteArray ar(env, byteArray); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SkMovie* moov = SkMovie::DecodeMemory(ar.ptr() + offset, length); 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return create_jmovie(env, moov); 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project////////////////////////////////////////////////////////////////////////////////////////////// 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <android_runtime/AndroidRuntime.h> 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMethods[] = { 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "width", "()I", (void*)movie_width }, 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "height", "()I", (void*)movie_height }, 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "isOpaque", "()Z", (void*)movie_isOpaque }, 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "duration", "()I", (void*)movie_duration }, 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "setTime", "(I)Z", (void*)movie_setTime }, 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "draw", "(Landroid/graphics/Canvas;FFLandroid/graphics/Paint;)V", 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)movie_draw }, 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "decodeStream", "(Ljava/io/InputStream;)Landroid/graphics/Movie;", 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)movie_decodeStream }, 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "decodeByteArray", "([BII)Landroid/graphics/Movie;", 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)movie_decodeByteArray }, 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define kClassPathName "android/graphics/Movie" 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define RETURN_ERR_IF_NULL(value) do { if (!(value)) { assert(0); return -1; } } while (false) 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_graphics_Movie(JNIEnv* env) 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gMovie_class = env->FindClass(kClassPathName); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RETURN_ERR_IF_NULL(gMovie_class); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gMovie_class = (jclass)env->NewGlobalRef(gMovie_class); 1458451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gMovie_constructorMethodID = env->GetMethodID(gMovie_class, "<init>", "(I)V"); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RETURN_ERR_IF_NULL(gMovie_constructorMethodID); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gMovie_nativeInstanceID = env->GetFieldID(gMovie_class, "mNativeMovie", "I"); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RETURN_ERR_IF_NULL(gMovie_nativeInstanceID); 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return android::AndroidRuntime::registerNativeMethods(env, kClassPathName, 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gMethods, SK_ARRAY_COUNT(gMethods)); 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 155