blob: d67ed10e9ef1e84feb029d030794472dc3c973bf [file] [log] [blame]
Derek Sollenberger304cc532015-01-08 16:31:53 -05001#include "Canvas.h"
Ben Wagner60126ef2015-08-07 12:13:48 -04002#include "CreateJavaOutputStreamAdaptor.h"
3#include "GraphicsJNI.h"
4#include "Paint.h"
Leon Scroggins IIIca320212013-08-20 17:59:39 -04005#include "ScopedLocalRef.h"
Leon Scroggins III7315f1b2013-09-10 20:26:05 -04006#include "SkFrontBufferedStream.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007#include "SkMovie.h"
8#include "SkStream.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009#include "SkUtils.h"
Leon Scroggins IIIca320212013-08-20 17:59:39 -040010#include "Utils.h"
Ben Wagner60126ef2015-08-07 12:13:48 -040011#include "core_jni_helpers.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012
Mathias Agopianb13b9bd2012-02-17 18:27:36 -080013#include <androidfw/Asset.h>
14#include <androidfw/ResourceTypes.h>
Ben Wagner60126ef2015-08-07 12:13:48 -040015#include <jni.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080016#include <netinet/in.h>
17
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018static 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,
Ashok Bhatdcaf5592014-01-08 16:47:08 +000027 static_cast<jlong>(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));
Ashok Bhatdcaf5592014-01-08 16:47:08 +000034 SkMovie* m = (SkMovie*)env->GetLongField(movie, gMovie_nativeInstanceID);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035 SkASSERT(m);
36 return m;
37}
38
39///////////////////////////////////////////////////////////////////////////////
40
Ashok Bhatdcaf5592014-01-08 16:47:08 +000041static jint movie_width(JNIEnv* env, jobject movie) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042 NPE_CHECK_RETURN_ZERO(env, movie);
Ashok Bhatdcaf5592014-01-08 16:47:08 +000043 return static_cast<jint>(J2Movie(env, movie)->width());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044}
45
Ashok Bhatdcaf5592014-01-08 16:47:08 +000046static jint movie_height(JNIEnv* env, jobject movie) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047 NPE_CHECK_RETURN_ZERO(env, movie);
Ashok Bhatdcaf5592014-01-08 16:47:08 +000048 return static_cast<jint>(J2Movie(env, movie)->height());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049}
50
51static jboolean movie_isOpaque(JNIEnv* env, jobject movie) {
52 NPE_CHECK_RETURN_ZERO(env, movie);
Ashok Bhatdcaf5592014-01-08 16:47:08 +000053 return J2Movie(env, movie)->isOpaque() ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054}
55
Ashok Bhatdcaf5592014-01-08 16:47:08 +000056static jint movie_duration(JNIEnv* env, jobject movie) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057 NPE_CHECK_RETURN_ZERO(env, movie);
Ashok Bhatdcaf5592014-01-08 16:47:08 +000058 return static_cast<jint>(J2Movie(env, movie)->duration());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059}
60
Ashok Bhatdcaf5592014-01-08 16:47:08 +000061static jboolean movie_setTime(JNIEnv* env, jobject movie, jint ms) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062 NPE_CHECK_RETURN_ZERO(env, movie);
Ashok Bhatdcaf5592014-01-08 16:47:08 +000063 return J2Movie(env, movie)->setTime(ms) ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064}
65
Derek Sollenberger304cc532015-01-08 16:31:53 -050066static void movie_draw(JNIEnv* env, jobject movie, jlong canvasHandle,
Derek Sollenbergerab22c1c2014-09-03 14:12:47 -040067 jfloat fx, jfloat fy, jlong paintHandle) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068 NPE_CHECK_RETURN_VOID(env, movie);
Derek Sollenberger304cc532015-01-08 16:31:53 -050069
70 android::Canvas* c = reinterpret_cast<android::Canvas*>(canvasHandle);
71 const android::Paint* p = reinterpret_cast<android::Paint*>(paintHandle);
72
73 // Canvas should never be NULL. However paint is an optional parameter and
74 // therefore may be NULL.
75 SkASSERT(c != NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076
77 SkMovie* m = J2Movie(env, movie);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078 const SkBitmap& b = m->bitmap();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079
Leon Scroggins III2e0103e2014-04-04 17:05:24 -040080 c->drawBitmap(b, fx, fy, p);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081}
82
Ashok Bhatdcaf5592014-01-08 16:47:08 +000083static jobject movie_decodeAsset(JNIEnv* env, jobject clazz, jlong native_asset) {
Leon Scroggins III7315f1b2013-09-10 20:26:05 -040084 android::Asset* asset = reinterpret_cast<android::Asset*>(native_asset);
85 if (asset == NULL) return NULL;
Ben Wagner60126ef2015-08-07 12:13:48 -040086 android::AssetStreamAdaptor stream(asset);
87 SkMovie* moov = SkMovie::DecodeStream(&stream);
Leon Scroggins III7315f1b2013-09-10 20:26:05 -040088 return create_jmovie(env, moov);
89}
90
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091static jobject movie_decodeStream(JNIEnv* env, jobject clazz, jobject istream) {
Elliott Hughes8451b252011-04-07 19:17:57 -070092
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 NPE_CHECK_RETURN_ZERO(env, istream);
94
Leon Scroggins III7315f1b2013-09-10 20:26:05 -040095 jbyteArray byteArray = env->NewByteArray(16*1024);
96 ScopedLocalRef<jbyteArray> scoper(env, byteArray);
97 SkStream* strm = CreateJavaInputStreamAdaptor(env, istream, byteArray);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 if (NULL == strm) {
99 return 0;
100 }
101
Leon Scroggins III7315f1b2013-09-10 20:26:05 -0400102 // Need to buffer enough input to be able to rewind as much as might be read by a decoder
103 // trying to determine the stream's format. The only decoder for movies is GIF, which
104 // will only read 6.
105 // FIXME: Get this number from SkImageDecoder
Leon Scroggins III34497892015-01-20 15:52:43 -0500106 // bufferedStream takes ownership of strm
Ben Wagner60126ef2015-08-07 12:13:48 -0400107 std::unique_ptr<SkStreamRewindable> bufferedStream(SkFrontBufferedStream::Create(strm, 6));
Leon Scroggins III7315f1b2013-09-10 20:26:05 -0400108 SkASSERT(bufferedStream.get() != NULL);
109
Ben Wagner60126ef2015-08-07 12:13:48 -0400110 SkMovie* moov = SkMovie::DecodeStream(bufferedStream.get());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111 return create_jmovie(env, moov);
112}
113
114static jobject movie_decodeByteArray(JNIEnv* env, jobject clazz,
115 jbyteArray byteArray,
Ashok Bhatdcaf5592014-01-08 16:47:08 +0000116 jint offset, jint length) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118 NPE_CHECK_RETURN_ZERO(env, byteArray);
119
120 int totalLength = env->GetArrayLength(byteArray);
121 if ((offset | length) < 0 || offset + length > totalLength) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700122 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123 return 0;
124 }
125
126 AutoJavaByteArray ar(env, byteArray);
127 SkMovie* moov = SkMovie::DecodeMemory(ar.ptr() + offset, length);
128 return create_jmovie(env, moov);
129}
130
Ashok Bhatdcaf5592014-01-08 16:47:08 +0000131static void movie_destructor(JNIEnv* env, jobject, jlong movieHandle) {
132 SkMovie* movie = (SkMovie*) movieHandle;
Kimiyoshi Kusaka08d77782011-03-28 11:58:51 +0900133 delete movie;
134}
135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136//////////////////////////////////////////////////////////////////////////////////////////////
137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138static JNINativeMethod gMethods[] = {
139 { "width", "()I", (void*)movie_width },
140 { "height", "()I", (void*)movie_height },
141 { "isOpaque", "()Z", (void*)movie_isOpaque },
142 { "duration", "()I", (void*)movie_duration },
143 { "setTime", "(I)Z", (void*)movie_setTime },
Derek Sollenberger304cc532015-01-08 16:31:53 -0500144 { "nDraw", "(JFFJ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 (void*)movie_draw },
Ashok Bhatdcaf5592014-01-08 16:47:08 +0000146 { "nativeDecodeAsset", "(J)Landroid/graphics/Movie;",
Leon Scroggins III7315f1b2013-09-10 20:26:05 -0400147 (void*)movie_decodeAsset },
148 { "nativeDecodeStream", "(Ljava/io/InputStream;)Landroid/graphics/Movie;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 (void*)movie_decodeStream },
Ashok Bhatdcaf5592014-01-08 16:47:08 +0000150 { "nativeDestructor","(J)V", (void*)movie_destructor },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 { "decodeByteArray", "([BII)Landroid/graphics/Movie;",
152 (void*)movie_decodeByteArray },
153};
154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155int register_android_graphics_Movie(JNIEnv* env)
156{
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800157 gMovie_class = android::FindClassOrDie(env, "android/graphics/Movie");
158 gMovie_class = android::MakeGlobalRefOrDie(env, gMovie_class);
Elliott Hughes8451b252011-04-07 19:17:57 -0700159
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800160 gMovie_constructorMethodID = android::GetMethodIDOrDie(env, gMovie_class, "<init>", "(J)V");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800162 gMovie_nativeInstanceID = android::GetFieldIDOrDie(env, gMovie_class, "mNativeMovie", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800164 return android::RegisterMethodsOrDie(env, "android/graphics/Movie", gMethods, NELEM(gMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165}