blob: b243817803ad915d958b85a04b1bdf8030cf0f8d [file] [log] [blame]
Ben Wagner60126ef2015-08-07 12:13:48 -04001#include "CreateJavaOutputStreamAdaptor.h"
2#include "GraphicsJNI.h"
Steven Moreland2279b252017-07-19 09:50:45 -07003#include <nativehelper/ScopedLocalRef.h>
Leon Scroggins III7315f1b2013-09-10 20:26:05 -04004#include "SkFrontBufferedStream.h"
Leon Scroggins IIIb5e74b92016-10-26 09:45:45 -04005#include "Movie.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006#include "SkStream.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007#include "SkUtils.h"
Leon Scroggins IIIca320212013-08-20 17:59:39 -04008#include "Utils.h"
Ben Wagner60126ef2015-08-07 12:13:48 -04009#include "core_jni_helpers.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010
Mathias Agopianb13b9bd2012-02-17 18:27:36 -080011#include <androidfw/Asset.h>
12#include <androidfw/ResourceTypes.h>
sergeyvdccca442016-03-21 15:38:21 -070013#include <hwui/Canvas.h>
14#include <hwui/Paint.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
Leon Scroggins IIIb5e74b92016-10-26 09:45:45 -040022jobject create_jmovie(JNIEnv* env, Movie* moov) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023 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
Leon Scroggins IIIb5e74b92016-10-26 09:45:45 -040030static Movie* J2Movie(JNIEnv* env, jobject movie) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031 SkASSERT(env);
32 SkASSERT(movie);
33 SkASSERT(env->IsInstanceOf(movie, gMovie_class));
Leon Scroggins IIIb5e74b92016-10-26 09:45:45 -040034 Movie* m = (Movie*)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
Leon Scroggins IIIb5e74b92016-10-26 09:45:45 -040077 Movie* m = J2Movie(env, movie);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078 const SkBitmap& b = m->bitmap();
sergeyvaed7f582016-10-14 16:30:21 -070079 sk_sp<android::Bitmap> wrapper = android::Bitmap::createFrom(b.info(), *b.pixelRef());
80 c->drawBitmap(*wrapper, 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);
Leon Scroggins IIIb5e74b92016-10-26 09:45:45 -040087 Movie* moov = Movie::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
Leon Scroggins IIIb5e74b92016-10-26 09:45:45 -0400110 Movie* moov = Movie::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);
Leon Scroggins IIIb5e74b92016-10-26 09:45:45 -0400127 Movie* moov = Movie::DecodeMemory(ar.ptr() + offset, length);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128 return create_jmovie(env, moov);
129}
130
Ashok Bhatdcaf5592014-01-08 16:47:08 +0000131static void movie_destructor(JNIEnv* env, jobject, jlong movieHandle) {
Leon Scroggins IIIb5e74b92016-10-26 09:45:45 -0400132 Movie* movie = (Movie*) 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
Daniel Micay76f6a862015-09-19 17:31:01 -0400138static const JNINativeMethod gMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 { "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}