blob: d1a5546b1bcd9e1f8add8a04be3a1bb0f67da71b [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001#include "SkMovie.h"
2#include "SkStream.h"
3#include "GraphicsJNI.h"
4#include "SkTemplates.h"
5#include "SkUtils.h"
6#include "CreateJavaOutputStreamAdaptor.h"
7
8#include <utils/Asset.h>
9#include <utils/ResourceTypes.h>
10#include <netinet/in.h>
11
12#if 0
13 #define TRACE_BITMAP(code) code
14#else
15 #define TRACE_BITMAP(code)
16#endif
17
18static jclass gMovie_class;
19static jmethodID gMovie_constructorMethodID;
20static jfieldID gMovie_nativeInstanceID;
21
22jobject create_jmovie(JNIEnv* env, SkMovie* moov) {
23 if (NULL == moov) {
24 return NULL;
25 }
26 jobject obj = env->AllocObject(gMovie_class);
27 if (obj) {
28 env->CallVoidMethod(obj, gMovie_constructorMethodID, (jint)moov);
29 }
30 return obj;
31}
32
33static SkMovie* J2Movie(JNIEnv* env, jobject movie) {
34 SkASSERT(env);
35 SkASSERT(movie);
36 SkASSERT(env->IsInstanceOf(movie, gMovie_class));
37 SkMovie* m = (SkMovie*)env->GetIntField(movie, gMovie_nativeInstanceID);
38 SkASSERT(m);
39 return m;
40}
41
42///////////////////////////////////////////////////////////////////////////////
43
44static int movie_width(JNIEnv* env, jobject movie) {
45 NPE_CHECK_RETURN_ZERO(env, movie);
46 return J2Movie(env, movie)->width();
47}
48
49static int movie_height(JNIEnv* env, jobject movie) {
50 NPE_CHECK_RETURN_ZERO(env, movie);
51 return J2Movie(env, movie)->height();
52}
53
54static jboolean movie_isOpaque(JNIEnv* env, jobject movie) {
55 NPE_CHECK_RETURN_ZERO(env, movie);
56 return J2Movie(env, movie)->isOpaque();
57}
58
59static int movie_duration(JNIEnv* env, jobject movie) {
60 NPE_CHECK_RETURN_ZERO(env, movie);
61 return J2Movie(env, movie)->duration();
62}
63
64static jboolean movie_setTime(JNIEnv* env, jobject movie, int ms) {
65 NPE_CHECK_RETURN_ZERO(env, movie);
66 return J2Movie(env, movie)->setTime(ms);
67}
68
69static void movie_draw(JNIEnv* env, jobject movie, jobject canvas,
70 jfloat fx, jfloat fy, jobject jpaint) {
71 NPE_CHECK_RETURN_VOID(env, movie);
72 NPE_CHECK_RETURN_VOID(env, canvas);
73 // its OK for paint to be null
74
75 SkMovie* m = J2Movie(env, movie);
76 SkCanvas* c = GraphicsJNI::getNativeCanvas(env, canvas);
77 SkScalar sx = SkFloatToScalar(fx);
78 SkScalar sy = SkFloatToScalar(fy);
79 const SkBitmap& b = m->bitmap();
80 const SkPaint* p = jpaint ? GraphicsJNI::getNativePaint(env, jpaint) : NULL;
81
82 c->drawBitmap(b, sx, sy, p);
83}
84
85static jobject movie_decodeStream(JNIEnv* env, jobject clazz, jobject istream) {
86
87 NPE_CHECK_RETURN_ZERO(env, istream);
88
89 // what is the lifetime of the array? Can the skstream hold onto it?
90 jbyteArray byteArray = env->NewByteArray(16*1024);
91 SkStream* strm = CreateJavaInputStreamAdaptor(env, istream, byteArray);
92 if (NULL == strm) {
93 return 0;
94 }
95
96 SkMovie* moov = SkMovie::DecodeStream(strm);
97 strm->unref();
98 return create_jmovie(env, moov);
99}
100
101static jobject movie_decodeByteArray(JNIEnv* env, jobject clazz,
102 jbyteArray byteArray,
103 int offset, int length) {
104
105 NPE_CHECK_RETURN_ZERO(env, byteArray);
106
107 int totalLength = env->GetArrayLength(byteArray);
108 if ((offset | length) < 0 || offset + length > totalLength) {
109 doThrow(env, "java/lang/ArrayIndexOutOfBoundsException");
110 return 0;
111 }
112
113 AutoJavaByteArray ar(env, byteArray);
114 SkMovie* moov = SkMovie::DecodeMemory(ar.ptr() + offset, length);
115 return create_jmovie(env, moov);
116}
117
Kimiyoshi Kusaka08d77782011-03-28 11:58:51 +0900118static void movie_destructor(JNIEnv* env, jobject, SkMovie* movie) {
119 delete movie;
120}
121
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122//////////////////////////////////////////////////////////////////////////////////////////////
123
124#include <android_runtime/AndroidRuntime.h>
125
126static JNINativeMethod gMethods[] = {
127 { "width", "()I", (void*)movie_width },
128 { "height", "()I", (void*)movie_height },
129 { "isOpaque", "()Z", (void*)movie_isOpaque },
130 { "duration", "()I", (void*)movie_duration },
131 { "setTime", "(I)Z", (void*)movie_setTime },
132 { "draw", "(Landroid/graphics/Canvas;FFLandroid/graphics/Paint;)V",
133 (void*)movie_draw },
134 { "decodeStream", "(Ljava/io/InputStream;)Landroid/graphics/Movie;",
135 (void*)movie_decodeStream },
Kimiyoshi Kusaka08d77782011-03-28 11:58:51 +0900136 { "nativeDestructor","(I)V", (void*)movie_destructor },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 { "decodeByteArray", "([BII)Landroid/graphics/Movie;",
138 (void*)movie_decodeByteArray },
139};
140
141#define kClassPathName "android/graphics/Movie"
142
143#define RETURN_ERR_IF_NULL(value) do { if (!(value)) { assert(0); return -1; } } while (false)
144
145int register_android_graphics_Movie(JNIEnv* env);
146int register_android_graphics_Movie(JNIEnv* env)
147{
148 gMovie_class = env->FindClass(kClassPathName);
149 RETURN_ERR_IF_NULL(gMovie_class);
150 gMovie_class = (jclass)env->NewGlobalRef(gMovie_class);
151
152 gMovie_constructorMethodID = env->GetMethodID(gMovie_class, "<init>", "(I)V");
153 RETURN_ERR_IF_NULL(gMovie_constructorMethodID);
154
155 gMovie_nativeInstanceID = env->GetFieldID(gMovie_class, "mNativeMovie", "I");
156 RETURN_ERR_IF_NULL(gMovie_nativeInstanceID);
157
158 return android::AndroidRuntime::registerNativeMethods(env, kClassPathName,
159 gMethods, SK_ARRAY_COUNT(gMethods));
160}