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