blob: ede0ca8cda5bfc4ad8c69f3df8a9dcbda19955a8 [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"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009
Mathias Agopianb13b9bd2012-02-17 18:27:36 -080010#include <androidfw/Asset.h>
11#include <androidfw/ResourceTypes.h>
sergeyvdccca442016-03-21 15:38:21 -070012#include <hwui/Canvas.h>
13#include <hwui/Paint.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014#include <netinet/in.h>
15
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080016static jclass gMovie_class;
17static jmethodID gMovie_constructorMethodID;
18static jfieldID gMovie_nativeInstanceID;
19
Leon Scroggins IIIb5e74b92016-10-26 09:45:45 -040020jobject create_jmovie(JNIEnv* env, Movie* moov) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021 if (NULL == moov) {
22 return NULL;
23 }
Elliott Hughescf6f7a02011-04-12 17:50:45 -070024 return env->NewObject(gMovie_class, gMovie_constructorMethodID,
Ashok Bhatdcaf5592014-01-08 16:47:08 +000025 static_cast<jlong>(reinterpret_cast<uintptr_t>(moov)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026}
27
Leon Scroggins IIIb5e74b92016-10-26 09:45:45 -040028static Movie* J2Movie(JNIEnv* env, jobject movie) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029 SkASSERT(env);
30 SkASSERT(movie);
31 SkASSERT(env->IsInstanceOf(movie, gMovie_class));
Leon Scroggins IIIb5e74b92016-10-26 09:45:45 -040032 Movie* m = (Movie*)env->GetLongField(movie, gMovie_nativeInstanceID);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033 SkASSERT(m);
34 return m;
35}
36
37///////////////////////////////////////////////////////////////////////////////
38
Ashok Bhatdcaf5592014-01-08 16:47:08 +000039static jint movie_width(JNIEnv* env, jobject movie) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040 NPE_CHECK_RETURN_ZERO(env, movie);
Ashok Bhatdcaf5592014-01-08 16:47:08 +000041 return static_cast<jint>(J2Movie(env, movie)->width());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042}
43
Ashok Bhatdcaf5592014-01-08 16:47:08 +000044static jint movie_height(JNIEnv* env, jobject movie) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045 NPE_CHECK_RETURN_ZERO(env, movie);
Ashok Bhatdcaf5592014-01-08 16:47:08 +000046 return static_cast<jint>(J2Movie(env, movie)->height());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047}
48
49static jboolean movie_isOpaque(JNIEnv* env, jobject movie) {
50 NPE_CHECK_RETURN_ZERO(env, movie);
Ashok Bhatdcaf5592014-01-08 16:47:08 +000051 return J2Movie(env, movie)->isOpaque() ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052}
53
Ashok Bhatdcaf5592014-01-08 16:47:08 +000054static jint movie_duration(JNIEnv* env, jobject movie) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055 NPE_CHECK_RETURN_ZERO(env, movie);
Ashok Bhatdcaf5592014-01-08 16:47:08 +000056 return static_cast<jint>(J2Movie(env, movie)->duration());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057}
58
Ashok Bhatdcaf5592014-01-08 16:47:08 +000059static jboolean movie_setTime(JNIEnv* env, jobject movie, jint ms) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060 NPE_CHECK_RETURN_ZERO(env, movie);
Ashok Bhatdcaf5592014-01-08 16:47:08 +000061 return J2Movie(env, movie)->setTime(ms) ? JNI_TRUE : JNI_FALSE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062}
63
Derek Sollenberger304cc532015-01-08 16:31:53 -050064static void movie_draw(JNIEnv* env, jobject movie, jlong canvasHandle,
Derek Sollenbergerab22c1c2014-09-03 14:12:47 -040065 jfloat fx, jfloat fy, jlong paintHandle) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066 NPE_CHECK_RETURN_VOID(env, movie);
Derek Sollenberger304cc532015-01-08 16:31:53 -050067
68 android::Canvas* c = reinterpret_cast<android::Canvas*>(canvasHandle);
69 const android::Paint* p = reinterpret_cast<android::Paint*>(paintHandle);
70
71 // Canvas should never be NULL. However paint is an optional parameter and
72 // therefore may be NULL.
73 SkASSERT(c != NULL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074
Leon Scroggins IIIb5e74b92016-10-26 09:45:45 -040075 Movie* m = J2Movie(env, movie);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076 const SkBitmap& b = m->bitmap();
sergeyvaed7f582016-10-14 16:30:21 -070077 sk_sp<android::Bitmap> wrapper = android::Bitmap::createFrom(b.info(), *b.pixelRef());
78 c->drawBitmap(*wrapper, fx, fy, p);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079}
80
Ashok Bhatdcaf5592014-01-08 16:47:08 +000081static jobject movie_decodeAsset(JNIEnv* env, jobject clazz, jlong native_asset) {
Leon Scroggins III7315f1b2013-09-10 20:26:05 -040082 android::Asset* asset = reinterpret_cast<android::Asset*>(native_asset);
83 if (asset == NULL) return NULL;
Ben Wagner60126ef2015-08-07 12:13:48 -040084 android::AssetStreamAdaptor stream(asset);
Leon Scroggins IIIb5e74b92016-10-26 09:45:45 -040085 Movie* moov = Movie::DecodeStream(&stream);
Leon Scroggins III7315f1b2013-09-10 20:26:05 -040086 return create_jmovie(env, moov);
87}
88
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089static jobject movie_decodeStream(JNIEnv* env, jobject clazz, jobject istream) {
Elliott Hughes8451b252011-04-07 19:17:57 -070090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 NPE_CHECK_RETURN_ZERO(env, istream);
92
Leon Scroggins III7315f1b2013-09-10 20:26:05 -040093 jbyteArray byteArray = env->NewByteArray(16*1024);
94 ScopedLocalRef<jbyteArray> scoper(env, byteArray);
95 SkStream* strm = CreateJavaInputStreamAdaptor(env, istream, byteArray);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096 if (NULL == strm) {
97 return 0;
98 }
99
Leon Scroggins III7315f1b2013-09-10 20:26:05 -0400100 // Need to buffer enough input to be able to rewind as much as might be read by a decoder
101 // trying to determine the stream's format. The only decoder for movies is GIF, which
102 // will only read 6.
103 // FIXME: Get this number from SkImageDecoder
Leon Scroggins III34497892015-01-20 15:52:43 -0500104 // bufferedStream takes ownership of strm
Mike Reedbe896ed2017-09-19 17:01:30 -0400105 std::unique_ptr<SkStreamRewindable> bufferedStream(SkFrontBufferedStream::Make(
106 std::unique_ptr<SkStream>(strm), 6));
Leon Scroggins III7315f1b2013-09-10 20:26:05 -0400107 SkASSERT(bufferedStream.get() != NULL);
108
Leon Scroggins IIIb5e74b92016-10-26 09:45:45 -0400109 Movie* moov = Movie::DecodeStream(bufferedStream.get());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110 return create_jmovie(env, moov);
111}
112
113static jobject movie_decodeByteArray(JNIEnv* env, jobject clazz,
114 jbyteArray byteArray,
Ashok Bhatdcaf5592014-01-08 16:47:08 +0000115 jint offset, jint length) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 NPE_CHECK_RETURN_ZERO(env, byteArray);
118
119 int totalLength = env->GetArrayLength(byteArray);
120 if ((offset | length) < 0 || offset + length > totalLength) {
Elliott Hughes8451b252011-04-07 19:17:57 -0700121 doThrowAIOOBE(env);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122 return 0;
123 }
124
125 AutoJavaByteArray ar(env, byteArray);
Leon Scroggins IIIb5e74b92016-10-26 09:45:45 -0400126 Movie* moov = Movie::DecodeMemory(ar.ptr() + offset, length);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127 return create_jmovie(env, moov);
128}
129
Ashok Bhatdcaf5592014-01-08 16:47:08 +0000130static void movie_destructor(JNIEnv* env, jobject, jlong movieHandle) {
Leon Scroggins IIIb5e74b92016-10-26 09:45:45 -0400131 Movie* movie = (Movie*) movieHandle;
Kimiyoshi Kusaka08d77782011-03-28 11:58:51 +0900132 delete movie;
133}
134
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135//////////////////////////////////////////////////////////////////////////////////////////////
136
Daniel Micay76f6a862015-09-19 17:31:01 -0400137static const JNINativeMethod gMethods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 { "width", "()I", (void*)movie_width },
139 { "height", "()I", (void*)movie_height },
140 { "isOpaque", "()Z", (void*)movie_isOpaque },
141 { "duration", "()I", (void*)movie_duration },
142 { "setTime", "(I)Z", (void*)movie_setTime },
Derek Sollenberger304cc532015-01-08 16:31:53 -0500143 { "nDraw", "(JFFJ)V",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144 (void*)movie_draw },
Ashok Bhatdcaf5592014-01-08 16:47:08 +0000145 { "nativeDecodeAsset", "(J)Landroid/graphics/Movie;",
Leon Scroggins III7315f1b2013-09-10 20:26:05 -0400146 (void*)movie_decodeAsset },
147 { "nativeDecodeStream", "(Ljava/io/InputStream;)Landroid/graphics/Movie;",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148 (void*)movie_decodeStream },
Ashok Bhatdcaf5592014-01-08 16:47:08 +0000149 { "nativeDestructor","(J)V", (void*)movie_destructor },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 { "decodeByteArray", "([BII)Landroid/graphics/Movie;",
151 (void*)movie_decodeByteArray },
152};
153
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154int register_android_graphics_Movie(JNIEnv* env)
155{
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800156 gMovie_class = android::FindClassOrDie(env, "android/graphics/Movie");
157 gMovie_class = android::MakeGlobalRefOrDie(env, gMovie_class);
Elliott Hughes8451b252011-04-07 19:17:57 -0700158
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800159 gMovie_constructorMethodID = android::GetMethodIDOrDie(env, gMovie_class, "<init>", "(J)V");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800161 gMovie_nativeInstanceID = android::GetFieldIDOrDie(env, gMovie_class, "mNativeMovie", "J");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800163 return android::RegisterMethodsOrDie(env, "android/graphics/Movie", gMethods, NELEM(gMethods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164}