• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #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 
18 static jclass       gMovie_class;
19 static jmethodID    gMovie_constructorMethodID;
20 static jfieldID     gMovie_nativeInstanceID;
21 
create_jmovie(JNIEnv * env,SkMovie * moov)22 jobject 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 
J2Movie(JNIEnv * env,jobject movie)33 static 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 
movie_width(JNIEnv * env,jobject movie)44 static int movie_width(JNIEnv* env, jobject movie) {
45     NPE_CHECK_RETURN_ZERO(env, movie);
46     return J2Movie(env, movie)->width();
47 }
48 
movie_height(JNIEnv * env,jobject movie)49 static int movie_height(JNIEnv* env, jobject movie) {
50     NPE_CHECK_RETURN_ZERO(env, movie);
51     return J2Movie(env, movie)->height();
52 }
53 
movie_isOpaque(JNIEnv * env,jobject movie)54 static jboolean movie_isOpaque(JNIEnv* env, jobject movie) {
55     NPE_CHECK_RETURN_ZERO(env, movie);
56     return J2Movie(env, movie)->isOpaque();
57 }
58 
movie_duration(JNIEnv * env,jobject movie)59 static int movie_duration(JNIEnv* env, jobject movie) {
60     NPE_CHECK_RETURN_ZERO(env, movie);
61     return J2Movie(env, movie)->duration();
62 }
63 
movie_setTime(JNIEnv * env,jobject movie,int ms)64 static 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 
movie_draw(JNIEnv * env,jobject movie,jobject canvas,jfloat fx,jfloat fy,jobject jpaint)69 static 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 
movie_decodeStream(JNIEnv * env,jobject clazz,jobject istream)85 static 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 
movie_decodeByteArray(JNIEnv * env,jobject clazz,jbyteArray byteArray,int offset,int length)101 static 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 
118 //////////////////////////////////////////////////////////////////////////////////////////////
119 
120 #include <android_runtime/AndroidRuntime.h>
121 
122 static JNINativeMethod gMethods[] = {
123     {   "width",    "()I",  (void*)movie_width  },
124     {   "height",   "()I",  (void*)movie_height  },
125     {   "isOpaque", "()Z",  (void*)movie_isOpaque  },
126     {   "duration", "()I",  (void*)movie_duration  },
127     {   "setTime",  "(I)Z", (void*)movie_setTime  },
128     {   "draw",     "(Landroid/graphics/Canvas;FFLandroid/graphics/Paint;)V",
129                             (void*)movie_draw  },
130     { "decodeStream", "(Ljava/io/InputStream;)Landroid/graphics/Movie;",
131                             (void*)movie_decodeStream },
132     { "decodeByteArray", "([BII)Landroid/graphics/Movie;",
133                             (void*)movie_decodeByteArray },
134 };
135 
136 #define kClassPathName  "android/graphics/Movie"
137 
138 #define RETURN_ERR_IF_NULL(value)   do { if (!(value)) { assert(0); return -1; } } while (false)
139 
140 int register_android_graphics_Movie(JNIEnv* env);
register_android_graphics_Movie(JNIEnv * env)141 int register_android_graphics_Movie(JNIEnv* env)
142 {
143     gMovie_class = env->FindClass(kClassPathName);
144     RETURN_ERR_IF_NULL(gMovie_class);
145     gMovie_class = (jclass)env->NewGlobalRef(gMovie_class);
146 
147     gMovie_constructorMethodID = env->GetMethodID(gMovie_class, "<init>", "(I)V");
148     RETURN_ERR_IF_NULL(gMovie_constructorMethodID);
149 
150     gMovie_nativeInstanceID = env->GetFieldID(gMovie_class, "mNativeMovie", "I");
151     RETURN_ERR_IF_NULL(gMovie_nativeInstanceID);
152 
153     return android::AndroidRuntime::registerNativeMethods(env, kClassPathName,
154                                                        gMethods, SK_ARRAY_COUNT(gMethods));
155 }
156