1 // Tencent is pleased to support the open source community by making ncnn available.
2 //
3 // Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
4 //
5 // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 // in compliance with the License. You may obtain a copy of the License at
7 //
8 // https://opensource.org/licenses/BSD-3-Clause
9 //
10 // Unless required by applicable law or agreed to in writing, software distributed
11 // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 // specific language governing permissions and limitations under the License.
14
15 #include "mat.h"
16
17 #if NCNN_PIXEL
18
19 #if NCNN_PLATFORM_API
20 #if __ANDROID_API__ >= 9
21 #include <android/bitmap.h>
22 #include <jni.h>
23 #endif // __ANDROID_API__ >= 9
24 #endif // NCNN_PLATFORM_API
25
26 namespace ncnn {
27
28 #if NCNN_PLATFORM_API
29 #if __ANDROID_API__ >= 9
from_android_bitmap(JNIEnv * env,jobject bitmap,int type_to,Allocator * allocator)30 Mat Mat::from_android_bitmap(JNIEnv* env, jobject bitmap, int type_to, Allocator* allocator)
31 {
32 AndroidBitmapInfo info;
33 AndroidBitmap_getInfo(env, bitmap, &info);
34
35 int type_from;
36 int elempack;
37
38 if (info.format == ANDROID_BITMAP_FORMAT_A_8)
39 {
40 type_from = PIXEL_GRAY;
41 elempack = 1;
42 }
43 else if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888)
44 {
45 type_from = PIXEL_RGBA;
46 elempack = 4;
47 }
48 else
49 {
50 // unsuppored android bitmap format
51 return Mat();
52 }
53
54 // let PIXEL_RGBA2XXX become PIXEL_XXX
55 type_to = (type_to & PIXEL_CONVERT_MASK) ? (type_to >> PIXEL_CONVERT_SHIFT) : (type_to & PIXEL_FORMAT_MASK);
56
57 void* data;
58 AndroidBitmap_lockPixels(env, bitmap, &data);
59
60 int type = type_to == type_from ? type_from : (type_from | (type_to << PIXEL_CONVERT_SHIFT));
61
62 Mat m = Mat::from_pixels((const unsigned char*)data, type, info.width, info.height, info.stride, allocator);
63
64 AndroidBitmap_unlockPixels(env, bitmap);
65
66 return m;
67 }
68
from_android_bitmap_resize(JNIEnv * env,jobject bitmap,int type_to,int target_width,int target_height,Allocator * allocator)69 Mat Mat::from_android_bitmap_resize(JNIEnv* env, jobject bitmap, int type_to, int target_width, int target_height, Allocator* allocator)
70 {
71 AndroidBitmapInfo info;
72 AndroidBitmap_getInfo(env, bitmap, &info);
73
74 int type_from;
75 int elempack;
76
77 if (info.format == ANDROID_BITMAP_FORMAT_A_8)
78 {
79 type_from = PIXEL_GRAY;
80 elempack = 1;
81 }
82 else if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888)
83 {
84 type_from = PIXEL_RGBA;
85 elempack = 4;
86 }
87 else
88 {
89 // unsuppored android bitmap format
90 return Mat();
91 }
92
93 // let PIXEL_RGBA2XXX become PIXEL_XXX
94 type_to = (type_to & PIXEL_CONVERT_MASK) ? (type_to >> PIXEL_CONVERT_SHIFT) : (type_to & PIXEL_FORMAT_MASK);
95
96 void* data;
97 AndroidBitmap_lockPixels(env, bitmap, &data);
98
99 int type = type_to == type_from ? type_from : (type_from | (type_to << PIXEL_CONVERT_SHIFT));
100
101 Mat m = Mat::from_pixels_resize((const unsigned char*)data, type, info.width, info.height, info.stride, target_width, target_height, allocator);
102
103 AndroidBitmap_unlockPixels(env, bitmap);
104
105 return m;
106 }
107
from_android_bitmap_roi(JNIEnv * env,jobject bitmap,int type_to,int roix,int roiy,int roiw,int roih,Allocator * allocator)108 Mat Mat::from_android_bitmap_roi(JNIEnv* env, jobject bitmap, int type_to, int roix, int roiy, int roiw, int roih, Allocator* allocator)
109 {
110 AndroidBitmapInfo info;
111 AndroidBitmap_getInfo(env, bitmap, &info);
112
113 int type_from;
114 int elempack;
115
116 if (info.format == ANDROID_BITMAP_FORMAT_A_8)
117 {
118 type_from = PIXEL_GRAY;
119 elempack = 1;
120 }
121 else if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888)
122 {
123 type_from = PIXEL_RGBA;
124 elempack = 4;
125 }
126 else
127 {
128 // unsuppored android bitmap format
129 return Mat();
130 }
131
132 // let PIXEL_RGBA2XXX become PIXEL_XXX
133 type_to = (type_to & PIXEL_CONVERT_MASK) ? (type_to >> PIXEL_CONVERT_SHIFT) : (type_to & PIXEL_FORMAT_MASK);
134
135 void* data;
136 AndroidBitmap_lockPixels(env, bitmap, &data);
137
138 int type = type_to == type_from ? type_from : (type_from | (type_to << PIXEL_CONVERT_SHIFT));
139
140 Mat m = Mat::from_pixels_roi((const unsigned char*)data, type, info.width, info.height, info.stride, roix, roiy, roiw, roih, allocator);
141
142 AndroidBitmap_unlockPixels(env, bitmap);
143
144 return m;
145 }
146
from_android_bitmap_roi_resize(JNIEnv * env,jobject bitmap,int type_to,int roix,int roiy,int roiw,int roih,int target_width,int target_height,Allocator * allocator)147 Mat Mat::from_android_bitmap_roi_resize(JNIEnv* env, jobject bitmap, int type_to, int roix, int roiy, int roiw, int roih, int target_width, int target_height, Allocator* allocator)
148 {
149 AndroidBitmapInfo info;
150 AndroidBitmap_getInfo(env, bitmap, &info);
151
152 int type_from;
153 int elempack;
154
155 if (info.format == ANDROID_BITMAP_FORMAT_A_8)
156 {
157 type_from = PIXEL_GRAY;
158 elempack = 1;
159 }
160 else if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888)
161 {
162 type_from = PIXEL_RGBA;
163 elempack = 4;
164 }
165 else
166 {
167 // unsuppored android bitmap format
168 return Mat();
169 }
170
171 // let PIXEL_RGBA2XXX become PIXEL_XXX
172 type_to = (type_to & PIXEL_CONVERT_MASK) ? (type_to >> PIXEL_CONVERT_SHIFT) : (type_to & PIXEL_FORMAT_MASK);
173
174 void* data;
175 AndroidBitmap_lockPixels(env, bitmap, &data);
176
177 int type = type_to == type_from ? type_from : (type_from | (type_to << PIXEL_CONVERT_SHIFT));
178
179 Mat m = Mat::from_pixels_roi_resize((const unsigned char*)data, type, info.width, info.height, info.stride, roix, roiy, roiw, roih, target_width, target_height, allocator);
180
181 AndroidBitmap_unlockPixels(env, bitmap);
182
183 return m;
184 }
185
to_android_bitmap(JNIEnv * env,jobject bitmap,int type_from) const186 void Mat::to_android_bitmap(JNIEnv* env, jobject bitmap, int type_from) const
187 {
188 AndroidBitmapInfo info;
189 AndroidBitmap_getInfo(env, bitmap, &info);
190
191 int type_to;
192
193 if (info.format == ANDROID_BITMAP_FORMAT_A_8)
194 {
195 type_to = PIXEL_GRAY;
196 }
197 else if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888)
198 {
199 type_to = PIXEL_RGBA;
200 }
201 else
202 {
203 // unsuppored android bitmap format
204 return;
205 }
206
207 // let PIXEL_XXX2RGBA become PIXEL_XXX
208 type_from = (type_from & PIXEL_CONVERT_MASK) ? (type_from & PIXEL_FORMAT_MASK) : type_from;
209
210 void* _data;
211 AndroidBitmap_lockPixels(env, bitmap, &_data);
212
213 int type = type_from == type_to ? type_to : (type_from | (type_to << PIXEL_CONVERT_SHIFT));
214
215 to_pixels_resize((unsigned char*)_data, type, info.width, info.height, info.stride);
216
217 AndroidBitmap_unlockPixels(env, bitmap);
218 }
219 #endif // __ANDROID_API__ >= 9
220 #endif // NCNN_PLATFORM_API
221
222 } // namespace ncnn
223
224 #endif // NCNN_PIXEL
225