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     return env->NewObject(gMovie_class, gMovie_constructorMethodID,
     27             static_cast<jint>(reinterpret_cast<uintptr_t>(moov)));
     28 }
     29 
     30 static 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 
     41 static int movie_width(JNIEnv* env, jobject movie) {
     42     NPE_CHECK_RETURN_ZERO(env, movie);
     43     return J2Movie(env, movie)->width();
     44 }
     45 
     46 static int movie_height(JNIEnv* env, jobject movie) {
     47     NPE_CHECK_RETURN_ZERO(env, movie);
     48     return J2Movie(env, movie)->height();
     49 }
     50 
     51 static jboolean movie_isOpaque(JNIEnv* env, jobject movie) {
     52     NPE_CHECK_RETURN_ZERO(env, movie);
     53     return J2Movie(env, movie)->isOpaque();
     54 }
     55 
     56 static int movie_duration(JNIEnv* env, jobject movie) {
     57     NPE_CHECK_RETURN_ZERO(env, movie);
     58     return J2Movie(env, movie)->duration();
     59 }
     60 
     61 static 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 
     66 static 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 
     82 static jobject movie_decodeStream(JNIEnv* env, jobject clazz, jobject istream) {
     83 
     84     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 
     98 static jobject movie_decodeByteArray(JNIEnv* env, jobject clazz,
     99                                      jbyteArray byteArray,
    100                                      int offset, int length) {
    101 
    102     NPE_CHECK_RETURN_ZERO(env, byteArray);
    103 
    104     int totalLength = env->GetArrayLength(byteArray);
    105     if ((offset | length) < 0 || offset + length > totalLength) {
    106         doThrowAIOOBE(env);
    107         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 
    115 static void movie_destructor(JNIEnv* env, jobject, SkMovie* movie) {
    116     delete movie;
    117 }
    118 
    119 //////////////////////////////////////////////////////////////////////////////////////////////
    120 
    121 #include <android_runtime/AndroidRuntime.h>
    122 
    123 static 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 },
    133     { "nativeDestructor","(I)V", (void*)movie_destructor },
    134     { "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 
    142 int 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);
    147 
    148     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 }
    157