blob: c1acaa3e468364ba264ab307a4966d126eb7550d [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 }
Elliott Hughescf6f7a02011-04-12 17:50:45 -070026 return env->NewObject(gMovie_class, gMovie_constructorMethodID,
27 static_cast<jint>(reinterpret_cast<uintptr_t>(moov)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028}
29
30static SkMovie* J2Movie(JNIEnv* env, jobject movie) {
31 SkASSERT(env);
32 SkASSERT(movie);
33 SkASSERT(env->IsInstanceOf(movie, gMovie_class));
34 SkMovie* m = (SkMovie*)env->GetIntField(movie, gMovie_nativeInstanceID);
35 SkASSERT(m);
36 return m;
37}
38
39///////////////////////////////////////////////////////////////////////////////
40
41static int movie_width(JNIEnv* env, jobject movie) {
42 NPE_CHECK_RETURN_ZERO(env, movie);
43 return J2Movie(env, movie)->width();
44}
45
46static int movie_height(JNIEnv* env, jobject movie) {
47 NPE_CHECK_RETURN_ZERO(env, movie);
48 return J2Movie(env, movie)->height();
49}
50
51static jboolean movie_isOpaque(JNIEnv* env, jobject movie) {
52 NPE_CHECK_RETURN_ZERO(env, movie);
53 return J2Movie(env, movie)->isOpaque();
54}
55
56static int movie_duration(JNIEnv* env, jobject movie) {
57 NPE_CHECK_RETURN_ZERO(env, movie);
58 return J2Movie(env, movie)->duration();
59}
60
61static jboolean movie_setTime(JNIEnv* env, jobject movie, int ms) {
62 NPE_CHECK_RETURN_ZERO(env, movie);
63 return J2Movie(env, movie)->setTime(ms);
64}
65
66static void movie_draw(JNIEnv* env, jobject movie, jobject canvas,
67 jfloat fx, jfloat fy, jobject jpaint) {
68 NPE_CHECK_RETURN_VOID(env, movie);
69 NPE_CHECK_RETURN_VOID(env, canvas);
70 // its OK for paint to be null
71
72 SkMovie* m = J2Movie(env, movie);
73 SkCanvas* c = GraphicsJNI::getNativeCanvas(env, canvas);
74 SkScalar sx = SkFloatToScalar(fx);
75 SkScalar sy = SkFloatToScalar(fy);
76 const SkBitmap& b = m->bitmap();
77 const SkPaint* p = jpaint ? GraphicsJNI::getNativePaint(env, jpaint) : NULL;
78
79 c->drawBitmap(b, sx, sy, p);
80}
81
82static jobject movie_decodeStream(JNIEnv* env, jobject clazz, jobject istream) {
Elliott Hughes8451b252011-04-07 19:17:57 -070083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084 NPE_CHECK_RETURN_ZERO(env, istream);
85
86 // what is the lifetime of the array? Can the skstream hold onto it?
87 jbyteArray byteArray = env->NewByteArray(16*1024);
88 SkStream* strm = CreateJavaInputStreamAdaptor(env, istream, byteArray);
89 if (NULL == strm) {
90 return 0;
91 }
92
93 SkMovie* moov = SkMovie::DecodeStream(strm);
94 strm->unref();
95 return create_jmovie(env, moov);
96}
97
98static jobject movie_decodeByteArray(JNIEnv* env, jobject clazz,
99 jbyteArray byteArray,
100 int offset, int length) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700101
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102 NPE_CHECK_RETURN_ZERO(env, byteArray);
103
104 int totalLength = env->GetArrayLength(byteArray);
105 if ((offset | length) < 0 || offset + length > totalLength) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700106 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107 return 0;
108 }
109
110 AutoJavaByteArray ar(env, byteArray);
111 SkMovie* moov = SkMovie::DecodeMemory(ar.ptr() + offset, length);
112 return create_jmovie(env, moov);
113}
114
Kimiyoshi Kusaka08d77782011-03-28 11:58:51 +0900115static void movie_destructor(JNIEnv* env, jobject, SkMovie* movie) {
116 delete movie;
117}
118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119//////////////////////////////////////////////////////////////////////////////////////////////
120
121#include <android_runtime/AndroidRuntime.h>
122
123static JNINativeMethod gMethods[] = {
124 { "width", "()I", (void*)movie_width },
125 { "height", "()I", (void*)movie_height },
126 { "isOpaque", "()Z", (void*)movie_isOpaque },
127 { "duration", "()I", (void*)movie_duration },
128 { "setTime", "(I)Z", (void*)movie_setTime },
129 { "draw", "(Landroid/graphics/Canvas;FFLandroid/graphics/Paint;)V",
130 (void*)movie_draw },
131 { "decodeStream", "(Ljava/io/InputStream;)Landroid/graphics/Movie;",
132 (void*)movie_decodeStream },
Kimiyoshi Kusaka08d77782011-03-28 11:58:51 +0900133 { "nativeDestructor","(I)V", (void*)movie_destructor },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 { "decodeByteArray", "([BII)Landroid/graphics/Movie;",
135 (void*)movie_decodeByteArray },
136};
137
138#define kClassPathName "android/graphics/Movie"
139
140#define RETURN_ERR_IF_NULL(value) do { if (!(value)) { assert(0); return -1; } } while (false)
141
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142int register_android_graphics_Movie(JNIEnv* env)
143{
144 gMovie_class = env->FindClass(kClassPathName);
145 RETURN_ERR_IF_NULL(gMovie_class);
146 gMovie_class = (jclass)env->NewGlobalRef(gMovie_class);
Elliott Hughes8451b252011-04-07 19:17:57 -0700147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148 gMovie_constructorMethodID = env->GetMethodID(gMovie_class, "<init>", "(I)V");
149 RETURN_ERR_IF_NULL(gMovie_constructorMethodID);
150
151 gMovie_nativeInstanceID = env->GetFieldID(gMovie_class, "mNativeMovie", "I");
152 RETURN_ERR_IF_NULL(gMovie_nativeInstanceID);
153
154 return android::AndroidRuntime::registerNativeMethods(env, kClassPathName,
155 gMethods, SK_ARRAY_COUNT(gMethods));
156}