1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "aassetstreamadaptor.h"
18 
19 #include <android/asset_manager.h>
20 #include <android/bitmap.h>
21 #include <android/data_space.h>
22 #include <android/imagedecoder.h>
23 #include <MimeType.h>
24 #include <android/rect.h>
25 #include <hwui/ImageDecoder.h>
26 #include <log/log.h>
27 #include <SkAndroidCodec.h>
28 #include <utils/Color.h>
29 
30 #include <fcntl.h>
31 #include <limits>
32 #include <optional>
33 #include <sys/stat.h>
34 #include <sys/types.h>
35 #include <unistd.h>
36 
37 using namespace android;
38 
ResultToErrorCode(SkCodec::Result result)39 int ResultToErrorCode(SkCodec::Result result) {
40     switch (result) {
41         case SkCodec::kIncompleteInput:
42             return ANDROID_IMAGE_DECODER_INCOMPLETE;
43         case SkCodec::kErrorInInput:
44             return ANDROID_IMAGE_DECODER_ERROR;
45         case SkCodec::kInvalidInput:
46             return ANDROID_IMAGE_DECODER_INVALID_INPUT;
47         case SkCodec::kCouldNotRewind:
48             return ANDROID_IMAGE_DECODER_SEEK_ERROR;
49         case SkCodec::kUnimplemented:
50             return ANDROID_IMAGE_DECODER_UNSUPPORTED_FORMAT;
51         case SkCodec::kInvalidConversion:
52             return ANDROID_IMAGE_DECODER_INVALID_CONVERSION;
53         case SkCodec::kInvalidParameters:
54             return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
55         case SkCodec::kSuccess:
56             return ANDROID_IMAGE_DECODER_SUCCESS;
57         case SkCodec::kInvalidScale:
58             return ANDROID_IMAGE_DECODER_INVALID_SCALE;
59         case SkCodec::kInternalError:
60             return ANDROID_IMAGE_DECODER_INTERNAL_ERROR;
61     }
62 }
63 
createFromStream(std::unique_ptr<SkStreamRewindable> stream,AImageDecoder ** outDecoder)64 static int createFromStream(std::unique_ptr<SkStreamRewindable> stream, AImageDecoder** outDecoder) {
65     SkCodec::Result result;
66     auto codec = SkCodec::MakeFromStream(std::move(stream), &result, nullptr,
67                                          SkCodec::SelectionPolicy::kPreferAnimation);
68     auto androidCodec = SkAndroidCodec::MakeFromCodec(std::move(codec),
69             SkAndroidCodec::ExifOrientationBehavior::kRespect);
70     if (!androidCodec) {
71         return ResultToErrorCode(result);
72     }
73 
74     // AImageDecoderHeaderInfo_getWidth/Height return an int32_t. Ensure that
75     // the conversion is safe.
76     const auto& info = androidCodec->getInfo();
77     if (info.width() > std::numeric_limits<int32_t>::max()
78         || info.height() > std::numeric_limits<int32_t>::max()) {
79         return ANDROID_IMAGE_DECODER_INVALID_INPUT;
80     }
81 
82     *outDecoder = reinterpret_cast<AImageDecoder*>(new ImageDecoder(std::move(androidCodec)));
83     return ANDROID_IMAGE_DECODER_SUCCESS;
84 }
85 
AImageDecoder_createFromAAsset(AAsset * asset,AImageDecoder ** outDecoder)86 int AImageDecoder_createFromAAsset(AAsset* asset, AImageDecoder** outDecoder) {
87     if (!asset || !outDecoder) {
88         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
89     }
90     *outDecoder = nullptr;
91 
92     auto stream = std::make_unique<AAssetStreamAdaptor>(asset);
93     return createFromStream(std::move(stream), outDecoder);
94 }
95 
isSeekable(int descriptor)96 static bool isSeekable(int descriptor) {
97     return ::lseek64(descriptor, 0, SEEK_CUR) != -1;
98 }
99 
AImageDecoder_createFromFd(int fd,AImageDecoder ** outDecoder)100 int AImageDecoder_createFromFd(int fd, AImageDecoder** outDecoder) {
101     if (fd <= 0 || !outDecoder) {
102         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
103     }
104 
105     struct stat fdStat;
106     if (fstat(fd, &fdStat) == -1) {
107         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
108     }
109 
110     if (!isSeekable(fd)) {
111         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
112     }
113 
114     // SkFILEStream will close its descriptor. Duplicate it so the client will
115     // still be responsible for closing the original.
116     int dupDescriptor = fcntl(fd, F_DUPFD_CLOEXEC, 0);
117     FILE* file = fdopen(dupDescriptor, "r");
118     if (!file) {
119         close(dupDescriptor);
120         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
121     }
122 
123     auto stream = std::unique_ptr<SkStreamRewindable>(new SkFILEStream(file));
124     return createFromStream(std::move(stream), outDecoder);
125 }
126 
AImageDecoder_createFromBuffer(const void * buffer,size_t length,AImageDecoder ** outDecoder)127 int AImageDecoder_createFromBuffer(const void* buffer, size_t length,
128                                    AImageDecoder** outDecoder) {
129     if (!buffer || !length  || !outDecoder) {
130         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
131     }
132     *outDecoder = nullptr;
133 
134     // The client is expected to keep the buffer alive as long as the
135     // AImageDecoder, so we do not need to copy the buffer.
136     auto stream = std::unique_ptr<SkStreamRewindable>(
137             new SkMemoryStream(buffer, length, false /* copyData */));
138     return createFromStream(std::move(stream), outDecoder);
139 }
140 
toDecoder(AImageDecoder * d)141 static ImageDecoder* toDecoder(AImageDecoder* d) {
142     return reinterpret_cast<ImageDecoder*>(d);
143 }
144 
toDecoder(const AImageDecoder * d)145 static const ImageDecoder* toDecoder(const AImageDecoder* d) {
146     return reinterpret_cast<const ImageDecoder*>(d);
147 }
148 
149 // Note: This differs from the version in android_bitmap.cpp in that this
150 // version returns kGray_8_SkColorType for ANDROID_BITMAP_FORMAT_A_8. SkCodec
151 // allows decoding single channel images to gray, which Android then treats
152 // as A_8/ALPHA_8.
getColorType(AndroidBitmapFormat format)153 static SkColorType getColorType(AndroidBitmapFormat format) {
154     switch (format) {
155         case ANDROID_BITMAP_FORMAT_RGBA_8888:
156             return kN32_SkColorType;
157         case ANDROID_BITMAP_FORMAT_RGB_565:
158             return kRGB_565_SkColorType;
159         case ANDROID_BITMAP_FORMAT_RGBA_4444:
160             return kARGB_4444_SkColorType;
161         case ANDROID_BITMAP_FORMAT_A_8:
162             return kGray_8_SkColorType;
163         case ANDROID_BITMAP_FORMAT_RGBA_F16:
164             return kRGBA_F16_SkColorType;
165         default:
166             return kUnknown_SkColorType;
167     }
168 }
169 
AImageDecoder_setAndroidBitmapFormat(AImageDecoder * decoder,int32_t format)170 int AImageDecoder_setAndroidBitmapFormat(AImageDecoder* decoder, int32_t format) {
171     if (!decoder || format < ANDROID_BITMAP_FORMAT_NONE
172             || format > ANDROID_BITMAP_FORMAT_RGBA_F16) {
173         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
174     }
175     return toDecoder(decoder)->setOutColorType(getColorType((AndroidBitmapFormat) format))
176             ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_CONVERSION;
177 }
178 
AImageDecoder_setDataSpace(AImageDecoder * decoder,int32_t dataspace)179 int AImageDecoder_setDataSpace(AImageDecoder* decoder, int32_t dataspace) {
180     sk_sp<SkColorSpace> cs = uirenderer::DataSpaceToColorSpace((android_dataspace)dataspace);
181     // 0 is ADATASPACE_UNKNOWN. We need an explicit request for an ADataSpace.
182     if (!decoder || !dataspace || !cs) {
183         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
184     }
185 
186     ImageDecoder* imageDecoder = toDecoder(decoder);
187     imageDecoder->setOutColorSpace(std::move(cs));
188     return ANDROID_IMAGE_DECODER_SUCCESS;
189 }
190 
AImageDecoder_getHeaderInfo(const AImageDecoder * decoder)191 const AImageDecoderHeaderInfo* AImageDecoder_getHeaderInfo(const AImageDecoder* decoder) {
192     return reinterpret_cast<const AImageDecoderHeaderInfo*>(decoder);
193 }
194 
toDecoder(const AImageDecoderHeaderInfo * info)195 static const ImageDecoder* toDecoder(const AImageDecoderHeaderInfo* info) {
196     return reinterpret_cast<const ImageDecoder*>(info);
197 }
198 
AImageDecoderHeaderInfo_getWidth(const AImageDecoderHeaderInfo * info)199 int32_t AImageDecoderHeaderInfo_getWidth(const AImageDecoderHeaderInfo* info) {
200     if (!info) {
201         return 0;
202     }
203     return toDecoder(info)->mCodec->getInfo().width();
204 }
205 
AImageDecoderHeaderInfo_getHeight(const AImageDecoderHeaderInfo * info)206 int32_t AImageDecoderHeaderInfo_getHeight(const AImageDecoderHeaderInfo* info) {
207     if (!info) {
208         return 0;
209     }
210     return toDecoder(info)->mCodec->getInfo().height();
211 }
212 
AImageDecoderHeaderInfo_getMimeType(const AImageDecoderHeaderInfo * info)213 const char* AImageDecoderHeaderInfo_getMimeType(const AImageDecoderHeaderInfo* info) {
214     if (!info) {
215         return nullptr;
216     }
217     return getMimeType(toDecoder(info)->mCodec->getEncodedFormat());
218 }
219 
AImageDecoderHeaderInfo_getDataSpace(const AImageDecoderHeaderInfo * info)220 int32_t AImageDecoderHeaderInfo_getDataSpace(const AImageDecoderHeaderInfo* info) {
221     if (!info) {
222         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
223     }
224 
225     // Note: This recomputes the color type because it's possible the client has
226     // changed the output color type, so we cannot rely on it. Alternatively,
227     // we could store the ADataSpace in the ImageDecoder.
228     const ImageDecoder* imageDecoder = toDecoder(info);
229     SkColorType colorType = imageDecoder->mCodec->computeOutputColorType(kN32_SkColorType);
230     sk_sp<SkColorSpace> colorSpace = imageDecoder->getDefaultColorSpace();
231     return uirenderer::ColorSpaceToADataSpace(colorSpace.get(), colorType);
232 }
233 
234 // FIXME: Share with getFormat in android_bitmap.cpp?
getFormat(SkColorType colorType)235 static AndroidBitmapFormat getFormat(SkColorType colorType) {
236     switch (colorType) {
237         case kN32_SkColorType:
238             return ANDROID_BITMAP_FORMAT_RGBA_8888;
239         case kRGB_565_SkColorType:
240             return ANDROID_BITMAP_FORMAT_RGB_565;
241         case kARGB_4444_SkColorType:
242             return ANDROID_BITMAP_FORMAT_RGBA_4444;
243         case kAlpha_8_SkColorType:
244             return ANDROID_BITMAP_FORMAT_A_8;
245         case kRGBA_F16_SkColorType:
246             return ANDROID_BITMAP_FORMAT_RGBA_F16;
247         default:
248             return ANDROID_BITMAP_FORMAT_NONE;
249     }
250 }
251 
AImageDecoderHeaderInfo_getAndroidBitmapFormat(const AImageDecoderHeaderInfo * info)252 int32_t AImageDecoderHeaderInfo_getAndroidBitmapFormat(const AImageDecoderHeaderInfo* info) {
253     if (!info) {
254         return ANDROID_BITMAP_FORMAT_NONE;
255     }
256     return getFormat(toDecoder(info)->mCodec->computeOutputColorType(kN32_SkColorType));
257 }
258 
AImageDecoderHeaderInfo_getAlphaFlags(const AImageDecoderHeaderInfo * info)259 int AImageDecoderHeaderInfo_getAlphaFlags(const AImageDecoderHeaderInfo* info) {
260     if (!info) {
261         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
262     }
263     switch (toDecoder(info)->mCodec->getInfo().alphaType()) {
264         case kUnknown_SkAlphaType:
265             LOG_ALWAYS_FATAL("Invalid alpha type");
266             return ANDROID_IMAGE_DECODER_INTERNAL_ERROR;
267         case kUnpremul_SkAlphaType:
268             // fall through. premul is the default.
269         case kPremul_SkAlphaType:
270             return ANDROID_BITMAP_FLAGS_ALPHA_PREMUL;
271         case kOpaque_SkAlphaType:
272             return ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE;
273     }
274 }
275 
AImageDecoder_setUnpremultipliedRequired(AImageDecoder * decoder,bool required)276 int AImageDecoder_setUnpremultipliedRequired(AImageDecoder* decoder, bool required) {
277     if (!decoder) {
278         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
279     }
280 
281     return toDecoder(decoder)->setUnpremultipliedRequired(required)
282             ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_CONVERSION;
283 }
284 
AImageDecoder_setTargetSize(AImageDecoder * decoder,int32_t width,int32_t height)285 int AImageDecoder_setTargetSize(AImageDecoder* decoder, int32_t width, int32_t height) {
286     if (!decoder) {
287         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
288     }
289 
290     return toDecoder(decoder)->setTargetSize(width, height)
291             ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_SCALE;
292 }
293 
AImageDecoder_computeSampledSize(const AImageDecoder * decoder,int sampleSize,int32_t * width,int32_t * height)294 int AImageDecoder_computeSampledSize(const AImageDecoder* decoder, int sampleSize,
295                                      int32_t* width, int32_t* height) {
296     if (!decoder || !width || !height || sampleSize < 1) {
297         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
298     }
299 
300     SkISize size = toDecoder(decoder)->mCodec->getSampledDimensions(sampleSize);
301     *width = size.width();
302     *height = size.height();
303     return ANDROID_IMAGE_DECODER_SUCCESS;
304 }
305 
AImageDecoder_setCrop(AImageDecoder * decoder,ARect crop)306 int AImageDecoder_setCrop(AImageDecoder* decoder, ARect crop) {
307     if (!decoder) {
308         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
309     }
310 
311     SkIRect cropIRect;
312     cropIRect.setLTRB(crop.left, crop.top, crop.right, crop.bottom);
313     SkIRect* cropPtr = cropIRect == SkIRect::MakeEmpty() ? nullptr : &cropIRect;
314     return toDecoder(decoder)->setCropRect(cropPtr)
315             ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_BAD_PARAMETER;
316 }
317 
318 
AImageDecoder_getMinimumStride(AImageDecoder * decoder)319 size_t AImageDecoder_getMinimumStride(AImageDecoder* decoder) {
320     if (!decoder) {
321         return 0;
322     }
323 
324     SkImageInfo info = toDecoder(decoder)->getOutputInfo();
325     return info.minRowBytes();
326 }
327 
AImageDecoder_decodeImage(AImageDecoder * decoder,void * pixels,size_t stride,size_t size)328 int AImageDecoder_decodeImage(AImageDecoder* decoder,
329                               void* pixels, size_t stride,
330                               size_t size) {
331     if (!decoder || !pixels || !stride) {
332         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
333     }
334 
335     ImageDecoder* imageDecoder = toDecoder(decoder);
336 
337     SkImageInfo info = imageDecoder->getOutputInfo();
338     size_t minSize = info.computeByteSize(stride);
339     if (SkImageInfo::ByteSizeOverflowed(minSize) || size < minSize || !info.validRowBytes(stride)) {
340         return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
341     }
342 
343     return ResultToErrorCode(imageDecoder->decode(pixels, stride));
344 }
345 
AImageDecoder_delete(AImageDecoder * decoder)346 void AImageDecoder_delete(AImageDecoder* decoder) {
347     delete toDecoder(decoder);
348 }
349