Home | History | Annotate | Download | only in graphics
      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 
     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 
     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 
     44 static int movie_width(JNIEnv* env, jobject movie) {
     45     NPE_CHECK_RETURN_ZERO(env, movie);
     46     return J2Movie(env, movie)->width();
     47 }
     48 
     49 static int movie_height(JNIEnv* env, jobject movie) {
     50     NPE_CHECK_RETURN_ZERO(env, movie);
     51     return J2Movie(env, movie)->height();
     52 }
     53 
     54 static jboolean movie_isOpaque(JNIEnv* env, jobject movie) {
     55     NPE_CHECK_RETURN_ZERO(env, movie);
     56     return J2Movie(env, movie)->isOpaque();
     57 }
     58 
     59 static int movie_duration(JNIEnv* env, jobject movie) {
     60     NPE_CHECK_RETURN_ZERO(env, movie);
     61     return J2Movie(env, movie)->duration();
     62 }
     63 
     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 
     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 
     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 
    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);
    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