blob: cb95bcf5d2b1f5ac1192e61a0c110356be30481b [file] [log] [blame]
Leon Scroggins III407b5442019-11-22 17:10:20 -05001/*
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
Derek Sollenberger2173ea22020-02-19 15:37:29 -050017#include <MimeType.h>
Kevin Lubick08409e22023-02-14 14:29:25 +000018#include <SkAlphaType.h>
Alec Mouri0ba21a72024-10-10 22:45:08 +000019#include <SkAndroidCodec.h>
Kevin Lubick1175dc02022-02-28 12:41:27 -050020#include <SkCodec.h>
Kevin Lubick08409e22023-02-14 14:29:25 +000021#include <SkCodecAnimation.h>
Kevin Lubick1175dc02022-02-28 12:41:27 -050022#include <SkColorSpace.h>
Kevin Lubick08409e22023-02-14 14:29:25 +000023#include <SkColorType.h>
Kevin Lubick1175dc02022-02-28 12:41:27 -050024#include <SkImageInfo.h>
25#include <SkRect.h>
Kevin Lubick08409e22023-02-14 14:29:25 +000026#include <SkRefCnt.h>
Kevin Lubick1175dc02022-02-28 12:41:27 -050027#include <SkSize.h>
28#include <SkStream.h>
Alec Mouri0ba21a72024-10-10 22:45:08 +000029#include <android/asset_manager.h>
30#include <android/bitmap.h>
31#include <android/data_space.h>
32#include <android/imagedecoder.h>
33#include <android/rect.h>
Leon Scroggins III407b5442019-11-22 17:10:20 -050034#include <fcntl.h>
Alec Mouri0ba21a72024-10-10 22:45:08 +000035#include <hwui/ImageDecoder.h>
36#include <log/log.h>
Leon Scroggins III407b5442019-11-22 17:10:20 -050037#include <sys/stat.h>
38#include <sys/types.h>
39#include <unistd.h>
Alec Mouri0ba21a72024-10-10 22:45:08 +000040#include <utils/Color.h>
41#include <utils/StatsUtils.h>
42
43#include <limits>
44#include <optional>
45
46#include "aassetstreamadaptor.h"
Leon Scroggins III407b5442019-11-22 17:10:20 -050047
48using namespace android;
49
50int ResultToErrorCode(SkCodec::Result result) {
51 switch (result) {
52 case SkCodec::kIncompleteInput:
53 return ANDROID_IMAGE_DECODER_INCOMPLETE;
54 case SkCodec::kErrorInInput:
55 return ANDROID_IMAGE_DECODER_ERROR;
56 case SkCodec::kInvalidInput:
57 return ANDROID_IMAGE_DECODER_INVALID_INPUT;
58 case SkCodec::kCouldNotRewind:
59 return ANDROID_IMAGE_DECODER_SEEK_ERROR;
60 case SkCodec::kUnimplemented:
61 return ANDROID_IMAGE_DECODER_UNSUPPORTED_FORMAT;
62 case SkCodec::kInvalidConversion:
63 return ANDROID_IMAGE_DECODER_INVALID_CONVERSION;
64 case SkCodec::kInvalidParameters:
65 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
66 case SkCodec::kSuccess:
67 return ANDROID_IMAGE_DECODER_SUCCESS;
68 case SkCodec::kInvalidScale:
69 return ANDROID_IMAGE_DECODER_INVALID_SCALE;
70 case SkCodec::kInternalError:
71 return ANDROID_IMAGE_DECODER_INTERNAL_ERROR;
72 }
73}
74
Leon Scroggins III946f8d42020-12-02 14:05:44 -050075const char* AImageDecoder_resultToString(int result) {
76 switch (result) {
77 case ANDROID_IMAGE_DECODER_SUCCESS:
78 return "ANDROID_IMAGE_DECODER_SUCCESS";
79 case ANDROID_IMAGE_DECODER_INCOMPLETE:
80 return "ANDROID_IMAGE_DECODER_INCOMPLETE";
81 case ANDROID_IMAGE_DECODER_ERROR:
82 return "ANDROID_IMAGE_DECODER_ERROR";
83 case ANDROID_IMAGE_DECODER_INVALID_CONVERSION:
84 return "ANDROID_IMAGE_DECODER_INVALID_CONVERSION";
85 case ANDROID_IMAGE_DECODER_INVALID_SCALE:
86 return "ANDROID_IMAGE_DECODER_INVALID_SCALE";
87 case ANDROID_IMAGE_DECODER_BAD_PARAMETER:
88 return "ANDROID_IMAGE_DECODER_BAD_PARAMETER";
89 case ANDROID_IMAGE_DECODER_INVALID_INPUT:
90 return "ANDROID_IMAGE_DECODER_INVALID_INPUT";
91 case ANDROID_IMAGE_DECODER_SEEK_ERROR:
92 return "ANDROID_IMAGE_DECODER_SEEK_ERROR";
93 case ANDROID_IMAGE_DECODER_INTERNAL_ERROR:
94 return "ANDROID_IMAGE_DECODER_INTERNAL_ERROR";
95 case ANDROID_IMAGE_DECODER_UNSUPPORTED_FORMAT:
96 return "ANDROID_IMAGE_DECODER_UNSUPPORTED_FORMAT";
97 case ANDROID_IMAGE_DECODER_FINISHED:
98 return "ANDROID_IMAGE_DECODER_FINISHED";
99 case ANDROID_IMAGE_DECODER_INVALID_STATE:
100 return "ANDROID_IMAGE_DECODER_INVALID_STATE";
101 default:
102 return nullptr;
103 }
104}
105
Leon Scroggins III407b5442019-11-22 17:10:20 -0500106static int createFromStream(std::unique_ptr<SkStreamRewindable> stream, AImageDecoder** outDecoder) {
107 SkCodec::Result result;
108 auto codec = SkCodec::MakeFromStream(std::move(stream), &result, nullptr,
109 SkCodec::SelectionPolicy::kPreferAnimation);
Leon Scroggins III139145b2020-12-17 15:43:54 -0500110 // These may be swapped due to the SkEncodedOrigin, but we're just checking
111 // them to make sure they fit in int32_t.
112 auto dimensions = codec->dimensions();
113 auto androidCodec = SkAndroidCodec::MakeFromCodec(std::move(codec));
Leon Scroggins III407b5442019-11-22 17:10:20 -0500114 if (!androidCodec) {
115 return ResultToErrorCode(result);
116 }
117
Leon Scroggins III2e6bedf2020-02-11 16:31:21 -0500118 // AImageDecoderHeaderInfo_getWidth/Height return an int32_t. Ensure that
119 // the conversion is safe.
Leon Scroggins III139145b2020-12-17 15:43:54 -0500120 if (dimensions.width() > std::numeric_limits<int32_t>::max() ||
121 dimensions.height() > std::numeric_limits<int32_t>::max()) {
Leon Scroggins III2e6bedf2020-02-11 16:31:21 -0500122 return ANDROID_IMAGE_DECODER_INVALID_INPUT;
123 }
124
Leon Scroggins III407b5442019-11-22 17:10:20 -0500125 *outDecoder = reinterpret_cast<AImageDecoder*>(new ImageDecoder(std::move(androidCodec)));
126 return ANDROID_IMAGE_DECODER_SUCCESS;
127}
128
129int AImageDecoder_createFromAAsset(AAsset* asset, AImageDecoder** outDecoder) {
130 if (!asset || !outDecoder) {
131 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
132 }
133 *outDecoder = nullptr;
134
Leon Scroggins IIIc72d0fb2020-12-30 16:38:23 -0500135#ifdef __ANDROID__
Leon Scroggins III407b5442019-11-22 17:10:20 -0500136 auto stream = std::make_unique<AAssetStreamAdaptor>(asset);
137 return createFromStream(std::move(stream), outDecoder);
Leon Scroggins IIIc72d0fb2020-12-30 16:38:23 -0500138#else
139 return ANDROID_IMAGE_DECODER_INTERNAL_ERROR;
140#endif
Leon Scroggins III407b5442019-11-22 17:10:20 -0500141}
142
143static bool isSeekable(int descriptor) {
144 return ::lseek64(descriptor, 0, SEEK_CUR) != -1;
145}
146
147int AImageDecoder_createFromFd(int fd, AImageDecoder** outDecoder) {
148 if (fd <= 0 || !outDecoder) {
149 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
150 }
151
152 struct stat fdStat;
153 if (fstat(fd, &fdStat) == -1) {
154 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
155 }
156
157 if (!isSeekable(fd)) {
158 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
159 }
160
161 // SkFILEStream will close its descriptor. Duplicate it so the client will
162 // still be responsible for closing the original.
163 int dupDescriptor = fcntl(fd, F_DUPFD_CLOEXEC, 0);
164 FILE* file = fdopen(dupDescriptor, "r");
165 if (!file) {
166 close(dupDescriptor);
167 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
168 }
169
170 auto stream = std::unique_ptr<SkStreamRewindable>(new SkFILEStream(file));
171 return createFromStream(std::move(stream), outDecoder);
172}
173
174int AImageDecoder_createFromBuffer(const void* buffer, size_t length,
175 AImageDecoder** outDecoder) {
176 if (!buffer || !length || !outDecoder) {
177 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
178 }
179 *outDecoder = nullptr;
180
181 // The client is expected to keep the buffer alive as long as the
182 // AImageDecoder, so we do not need to copy the buffer.
183 auto stream = std::unique_ptr<SkStreamRewindable>(
184 new SkMemoryStream(buffer, length, false /* copyData */));
185 return createFromStream(std::move(stream), outDecoder);
186}
187
188static ImageDecoder* toDecoder(AImageDecoder* d) {
189 return reinterpret_cast<ImageDecoder*>(d);
190}
191
Leon Scroggins IIIf89de632020-01-19 21:22:18 -0500192static const ImageDecoder* toDecoder(const AImageDecoder* d) {
193 return reinterpret_cast<const ImageDecoder*>(d);
194}
195
Leon Scroggins III407b5442019-11-22 17:10:20 -0500196// Note: This differs from the version in android_bitmap.cpp in that this
197// version returns kGray_8_SkColorType for ANDROID_BITMAP_FORMAT_A_8. SkCodec
198// allows decoding single channel images to gray, which Android then treats
199// as A_8/ALPHA_8.
200static SkColorType getColorType(AndroidBitmapFormat format) {
201 switch (format) {
202 case ANDROID_BITMAP_FORMAT_RGBA_8888:
203 return kN32_SkColorType;
204 case ANDROID_BITMAP_FORMAT_RGB_565:
205 return kRGB_565_SkColorType;
206 case ANDROID_BITMAP_FORMAT_RGBA_4444:
207 return kARGB_4444_SkColorType;
208 case ANDROID_BITMAP_FORMAT_A_8:
209 return kGray_8_SkColorType;
210 case ANDROID_BITMAP_FORMAT_RGBA_F16:
211 return kRGBA_F16_SkColorType;
Alec Mouri1efd0a52022-01-20 13:58:23 -0800212 case ANDROID_BITMAP_FORMAT_RGBA_1010102:
213 return kRGBA_1010102_SkColorType;
Leon Scroggins III407b5442019-11-22 17:10:20 -0500214 default:
215 return kUnknown_SkColorType;
216 }
217}
218
219int AImageDecoder_setAndroidBitmapFormat(AImageDecoder* decoder, int32_t format) {
Alec Mouri1efd0a52022-01-20 13:58:23 -0800220 if (!decoder || format < ANDROID_BITMAP_FORMAT_NONE ||
221 format > ANDROID_BITMAP_FORMAT_RGBA_1010102) {
Leon Scroggins III407b5442019-11-22 17:10:20 -0500222 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
223 }
Leon Scroggins IIIb26aebc2020-12-21 14:55:22 -0500224
225 auto* imageDecoder = toDecoder(decoder);
226 if (imageDecoder->currentFrame() != 0) {
227 return ANDROID_IMAGE_DECODER_INVALID_STATE;
228 }
229
230 return imageDecoder->setOutColorType(getColorType((AndroidBitmapFormat) format))
Leon Scroggins III407b5442019-11-22 17:10:20 -0500231 ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_CONVERSION;
232}
233
Leon Scroggins IIIe5ace3f2020-01-15 15:31:40 -0500234int AImageDecoder_setDataSpace(AImageDecoder* decoder, int32_t dataspace) {
235 sk_sp<SkColorSpace> cs = uirenderer::DataSpaceToColorSpace((android_dataspace)dataspace);
236 // 0 is ADATASPACE_UNKNOWN. We need an explicit request for an ADataSpace.
237 if (!decoder || !dataspace || !cs) {
238 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
239 }
240
241 ImageDecoder* imageDecoder = toDecoder(decoder);
Leon Scroggins IIIb26aebc2020-12-21 14:55:22 -0500242 if (imageDecoder->currentFrame() != 0) {
243 return ANDROID_IMAGE_DECODER_INVALID_STATE;
244 }
245
Leon Scroggins IIIe5ace3f2020-01-15 15:31:40 -0500246 imageDecoder->setOutColorSpace(std::move(cs));
247 return ANDROID_IMAGE_DECODER_SUCCESS;
248}
249
Leon Scroggins III407b5442019-11-22 17:10:20 -0500250const AImageDecoderHeaderInfo* AImageDecoder_getHeaderInfo(const AImageDecoder* decoder) {
251 return reinterpret_cast<const AImageDecoderHeaderInfo*>(decoder);
252}
253
254static const ImageDecoder* toDecoder(const AImageDecoderHeaderInfo* info) {
255 return reinterpret_cast<const ImageDecoder*>(info);
256}
257
258int32_t AImageDecoderHeaderInfo_getWidth(const AImageDecoderHeaderInfo* info) {
259 if (!info) {
260 return 0;
261 }
Leon Scroggins III139145b2020-12-17 15:43:54 -0500262 return toDecoder(info)->width();
Leon Scroggins III407b5442019-11-22 17:10:20 -0500263}
264
265int32_t AImageDecoderHeaderInfo_getHeight(const AImageDecoderHeaderInfo* info) {
266 if (!info) {
267 return 0;
268 }
Leon Scroggins III139145b2020-12-17 15:43:54 -0500269 return toDecoder(info)->height();
Leon Scroggins III407b5442019-11-22 17:10:20 -0500270}
271
272const char* AImageDecoderHeaderInfo_getMimeType(const AImageDecoderHeaderInfo* info) {
273 if (!info) {
274 return nullptr;
275 }
276 return getMimeType(toDecoder(info)->mCodec->getEncodedFormat());
277}
278
Leon Scroggins IIIe5ace3f2020-01-15 15:31:40 -0500279int32_t AImageDecoderHeaderInfo_getDataSpace(const AImageDecoderHeaderInfo* info) {
280 if (!info) {
281 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
282 }
283
Leon Scroggins III6eeca5c2020-01-30 13:59:50 -0500284 // Note: This recomputes the color type because it's possible the client has
285 // changed the output color type, so we cannot rely on it. Alternatively,
Leon Scroggins IIIe5ace3f2020-01-15 15:31:40 -0500286 // we could store the ADataSpace in the ImageDecoder.
287 const ImageDecoder* imageDecoder = toDecoder(info);
288 SkColorType colorType = imageDecoder->mCodec->computeOutputColorType(kN32_SkColorType);
Leon Scroggins III6eeca5c2020-01-30 13:59:50 -0500289 sk_sp<SkColorSpace> colorSpace = imageDecoder->getDefaultColorSpace();
Leon Scroggins IIIe5ace3f2020-01-15 15:31:40 -0500290 return uirenderer::ColorSpaceToADataSpace(colorSpace.get(), colorType);
291}
292
Leon Scroggins III407b5442019-11-22 17:10:20 -0500293// FIXME: Share with getFormat in android_bitmap.cpp?
294static AndroidBitmapFormat getFormat(SkColorType colorType) {
295 switch (colorType) {
296 case kN32_SkColorType:
297 return ANDROID_BITMAP_FORMAT_RGBA_8888;
298 case kRGB_565_SkColorType:
299 return ANDROID_BITMAP_FORMAT_RGB_565;
300 case kARGB_4444_SkColorType:
301 return ANDROID_BITMAP_FORMAT_RGBA_4444;
302 case kAlpha_8_SkColorType:
303 return ANDROID_BITMAP_FORMAT_A_8;
304 case kRGBA_F16_SkColorType:
305 return ANDROID_BITMAP_FORMAT_RGBA_F16;
Alec Mouri1efd0a52022-01-20 13:58:23 -0800306 case kRGBA_1010102_SkColorType:
307 return ANDROID_BITMAP_FORMAT_RGBA_1010102;
Leon Scroggins III407b5442019-11-22 17:10:20 -0500308 default:
309 return ANDROID_BITMAP_FORMAT_NONE;
310 }
311}
312
Leon Scroggins III64301cb2020-01-23 09:47:47 -0500313int32_t AImageDecoderHeaderInfo_getAndroidBitmapFormat(const AImageDecoderHeaderInfo* info) {
Leon Scroggins III407b5442019-11-22 17:10:20 -0500314 if (!info) {
315 return ANDROID_BITMAP_FORMAT_NONE;
316 }
317 return getFormat(toDecoder(info)->mCodec->computeOutputColorType(kN32_SkColorType));
318}
319
320int AImageDecoderHeaderInfo_getAlphaFlags(const AImageDecoderHeaderInfo* info) {
321 if (!info) {
Leon Scroggins IIId8840bd2020-01-15 04:09:48 -0500322 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
Leon Scroggins III407b5442019-11-22 17:10:20 -0500323 }
324 switch (toDecoder(info)->mCodec->getInfo().alphaType()) {
325 case kUnknown_SkAlphaType:
326 LOG_ALWAYS_FATAL("Invalid alpha type");
Leon Scroggins IIId8840bd2020-01-15 04:09:48 -0500327 return ANDROID_IMAGE_DECODER_INTERNAL_ERROR;
Leon Scroggins III407b5442019-11-22 17:10:20 -0500328 case kUnpremul_SkAlphaType:
329 // fall through. premul is the default.
330 case kPremul_SkAlphaType:
331 return ANDROID_BITMAP_FLAGS_ALPHA_PREMUL;
332 case kOpaque_SkAlphaType:
333 return ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE;
334 }
335}
336
Leon Scroggins III1ade46d2020-01-15 05:41:06 -0500337int AImageDecoder_setUnpremultipliedRequired(AImageDecoder* decoder, bool required) {
338 if (!decoder) {
Leon Scroggins III407b5442019-11-22 17:10:20 -0500339 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
340 }
341
Leon Scroggins IIIb26aebc2020-12-21 14:55:22 -0500342 auto* imageDecoder = toDecoder(decoder);
343 if (imageDecoder->currentFrame() != 0) {
344 return ANDROID_IMAGE_DECODER_INVALID_STATE;
345 }
346
347 return imageDecoder->setUnpremultipliedRequired(required)
Leon Scroggins III407b5442019-11-22 17:10:20 -0500348 ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_CONVERSION;
349}
350
Leon Scroggins III64301cb2020-01-23 09:47:47 -0500351int AImageDecoder_setTargetSize(AImageDecoder* decoder, int32_t width, int32_t height) {
Leon Scroggins III407b5442019-11-22 17:10:20 -0500352 if (!decoder) {
353 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
354 }
355
Leon Scroggins IIIb26aebc2020-12-21 14:55:22 -0500356 auto* imageDecoder = toDecoder(decoder);
357 if (imageDecoder->currentFrame() != 0) {
358 return ANDROID_IMAGE_DECODER_INVALID_STATE;
359 }
360
361 return imageDecoder->setTargetSize(width, height)
Leon Scroggins III407b5442019-11-22 17:10:20 -0500362 ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_INVALID_SCALE;
363}
364
Leon Scroggins IIIf89de632020-01-19 21:22:18 -0500365int AImageDecoder_computeSampledSize(const AImageDecoder* decoder, int sampleSize,
Leon Scroggins III64301cb2020-01-23 09:47:47 -0500366 int32_t* width, int32_t* height) {
Leon Scroggins IIIf89de632020-01-19 21:22:18 -0500367 if (!decoder || !width || !height || sampleSize < 1) {
368 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
369 }
370
Leon Scroggins III5a5c2ce2021-01-15 14:09:13 -0500371 SkISize size = toDecoder(decoder)->getSampledDimensions(sampleSize);
Leon Scroggins IIIf89de632020-01-19 21:22:18 -0500372 *width = size.width();
373 *height = size.height();
374 return ANDROID_IMAGE_DECODER_SUCCESS;
375}
376
Leon Scroggins III407b5442019-11-22 17:10:20 -0500377int AImageDecoder_setCrop(AImageDecoder* decoder, ARect crop) {
378 if (!decoder) {
379 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
380 }
381
Leon Scroggins IIIb26aebc2020-12-21 14:55:22 -0500382 auto* imageDecoder = toDecoder(decoder);
383 if (imageDecoder->currentFrame() != 0) {
384 return ANDROID_IMAGE_DECODER_INVALID_STATE;
385 }
386
Leon Scroggins III407b5442019-11-22 17:10:20 -0500387 SkIRect cropIRect;
388 cropIRect.setLTRB(crop.left, crop.top, crop.right, crop.bottom);
Leon Scrogginsad70c8a2022-08-29 16:02:02 +0000389 SkIRect* cropPtr = cropIRect == SkIRect::MakeEmpty() ? nullptr : &cropIRect;
Leon Scroggins IIIb26aebc2020-12-21 14:55:22 -0500390 return imageDecoder->setCropRect(cropPtr)
Leon Scroggins III407b5442019-11-22 17:10:20 -0500391 ? ANDROID_IMAGE_DECODER_SUCCESS : ANDROID_IMAGE_DECODER_BAD_PARAMETER;
392}
393
394
395size_t AImageDecoder_getMinimumStride(AImageDecoder* decoder) {
396 if (!decoder) {
397 return 0;
398 }
399
400 SkImageInfo info = toDecoder(decoder)->getOutputInfo();
401 return info.minRowBytes();
402}
403
Alec Mouri0ba21a72024-10-10 22:45:08 +0000404int AImageDecoder_decodeImage(AImageDecoder* decoder, void* pixels, size_t stride, size_t size) {
Leon Scroggins III407b5442019-11-22 17:10:20 -0500405 if (!decoder || !pixels || !stride) {
406 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
407 }
408
409 ImageDecoder* imageDecoder = toDecoder(decoder);
410
Leon Scroggins IIId894c592020-01-22 14:18:12 -0500411 SkImageInfo info = imageDecoder->getOutputInfo();
412 size_t minSize = info.computeByteSize(stride);
413 if (SkImageInfo::ByteSizeOverflowed(minSize) || size < minSize || !info.validRowBytes(stride)) {
Leon Scroggins III407b5442019-11-22 17:10:20 -0500414 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
415 }
416
Leon Scroggins IIIb26aebc2020-12-21 14:55:22 -0500417 if (imageDecoder->finished()) {
418 return ANDROID_IMAGE_DECODER_FINISHED;
419 }
420
Alec Mouri0ba21a72024-10-10 22:45:08 +0000421 const auto result = ResultToErrorCode(imageDecoder->decode(pixels, stride));
422
423 if (result == ANDROID_IMAGE_DECODER_SUCCESS) {
424 uirenderer::logBitmapDecode(imageDecoder->getOutputInfo(), false);
425 }
426
427 return result;
Leon Scroggins III407b5442019-11-22 17:10:20 -0500428}
429
430void AImageDecoder_delete(AImageDecoder* decoder) {
431 delete toDecoder(decoder);
432}
Leon Scroggins III24ae7d72020-10-09 13:14:35 -0400433
434bool AImageDecoder_isAnimated(AImageDecoder* decoder) {
435 if (!decoder) return false;
436
437 ImageDecoder* imageDecoder = toDecoder(decoder);
Leon Scroggins IIIb26aebc2020-12-21 14:55:22 -0500438 return imageDecoder->isAnimated();
Leon Scroggins III24ae7d72020-10-09 13:14:35 -0400439}
Leon Scroggins III3ad12c42020-10-12 10:56:42 -0400440
441int32_t AImageDecoder_getRepeatCount(AImageDecoder* decoder) {
442 if (!decoder) return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
443
444 ImageDecoder* imageDecoder = toDecoder(decoder);
445 const int count = imageDecoder->mCodec->codec()->getRepetitionCount();
446
447 // Skia should not report anything out of range, but defensively treat
448 // negative and too big as INFINITE.
449 if (count == SkCodec::kRepetitionCountInfinite || count < 0
450 || count > std::numeric_limits<int32_t>::max()) {
451 return ANDROID_IMAGE_DECODER_INFINITE;
452 }
453 return count;
454}
Leon Scroggins IIIb26aebc2020-12-21 14:55:22 -0500455
456int AImageDecoder_advanceFrame(AImageDecoder* decoder) {
457 if (!decoder) return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
458
459 ImageDecoder* imageDecoder = toDecoder(decoder);
460 if (!imageDecoder->isAnimated()) {
461 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
462 }
463
Leon Scroggins IIIdf33b952021-04-26 15:35:56 -0400464 const auto colorType = imageDecoder->getOutputInfo().colorType();
465 switch (colorType) {
466 case kN32_SkColorType:
467 case kRGBA_F16_SkColorType:
468 break;
469 default:
470 return ANDROID_IMAGE_DECODER_INVALID_STATE;
471 }
472
Leon Scroggins IIIb26aebc2020-12-21 14:55:22 -0500473 if (imageDecoder->advanceFrame()) {
474 return ANDROID_IMAGE_DECODER_SUCCESS;
475 }
476
477 if (imageDecoder->finished()) {
478 return ANDROID_IMAGE_DECODER_FINISHED;
479 }
480
481 return ANDROID_IMAGE_DECODER_INCOMPLETE;
482}
483
484int AImageDecoder_rewind(AImageDecoder* decoder) {
485 if (!decoder) return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
486
487 ImageDecoder* imageDecoder = toDecoder(decoder);
488 if (!imageDecoder->isAnimated()) {
489 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
490 }
491
492 return imageDecoder->rewind() ? ANDROID_IMAGE_DECODER_SUCCESS
493 : ANDROID_IMAGE_DECODER_SEEK_ERROR;
494}
Leon Scroggins III06213132020-12-28 15:31:48 -0500495
496AImageDecoderFrameInfo* AImageDecoderFrameInfo_create() {
497 return reinterpret_cast<AImageDecoderFrameInfo*>(new SkCodec::FrameInfo);
498}
499
500static SkCodec::FrameInfo* toFrameInfo(AImageDecoderFrameInfo* info) {
501 return reinterpret_cast<SkCodec::FrameInfo*>(info);
502}
503
504static const SkCodec::FrameInfo* toFrameInfo(const AImageDecoderFrameInfo* info) {
505 return reinterpret_cast<const SkCodec::FrameInfo*>(info);
506}
507
508void AImageDecoderFrameInfo_delete(AImageDecoderFrameInfo* info) {
509 delete toFrameInfo(info);
510}
511
512int AImageDecoder_getFrameInfo(AImageDecoder* decoder,
513 AImageDecoderFrameInfo* info) {
514 if (!decoder || !info) {
515 return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
516 }
517
518 auto* imageDecoder = toDecoder(decoder);
519 if (imageDecoder->finished()) {
520 return ANDROID_IMAGE_DECODER_FINISHED;
521 }
522
523 *toFrameInfo(info) = imageDecoder->getCurrentFrameInfo();
524 return ANDROID_IMAGE_DECODER_SUCCESS;
525}
526
527int64_t AImageDecoderFrameInfo_getDuration(const AImageDecoderFrameInfo* info) {
Leon Scroggins III6116e5c2021-05-03 11:34:34 -0400528 if (!info) return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
Leon Scroggins III06213132020-12-28 15:31:48 -0500529
530 return toFrameInfo(info)->fDuration * 1'000'000;
531}
532
533ARect AImageDecoderFrameInfo_getFrameRect(const AImageDecoderFrameInfo* info) {
534 if (!info) {
535 return { 0, 0, 0, 0};
536 }
537
538 const SkIRect& r = toFrameInfo(info)->fFrameRect;
539 return { r.left(), r.top(), r.right(), r.bottom() };
540}
541
542bool AImageDecoderFrameInfo_hasAlphaWithinBounds(const AImageDecoderFrameInfo* info) {
543 if (!info) return false;
544
545 return toFrameInfo(info)->fHasAlphaWithinBounds;
546}
547
548int32_t AImageDecoderFrameInfo_getDisposeOp(const AImageDecoderFrameInfo* info) {
549 if (!info) return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
550
551 static_assert(static_cast<int>(SkCodecAnimation::DisposalMethod::kKeep)
552 == ANDROID_IMAGE_DECODER_DISPOSE_OP_NONE);
553 static_assert(static_cast<int>(SkCodecAnimation::DisposalMethod::kRestoreBGColor)
554 == ANDROID_IMAGE_DECODER_DISPOSE_OP_BACKGROUND);
555 static_assert(static_cast<int>(SkCodecAnimation::DisposalMethod::kRestorePrevious)
556 == ANDROID_IMAGE_DECODER_DISPOSE_OP_PREVIOUS);
557 return static_cast<int>(toFrameInfo(info)->fDisposalMethod);
558}
559
560int32_t AImageDecoderFrameInfo_getBlendOp(const AImageDecoderFrameInfo* info) {
561 if (!info) return ANDROID_IMAGE_DECODER_BAD_PARAMETER;
562
563 switch (toFrameInfo(info)->fBlend) {
564 case SkCodecAnimation::Blend::kSrc:
565 return ANDROID_IMAGE_DECODER_BLEND_OP_SRC;
566 case SkCodecAnimation::Blend::kSrcOver:
567 return ANDROID_IMAGE_DECODER_BLEND_OP_SRC_OVER;
568 }
569}
Leon Scroggins IIIc2ebc2b2021-01-13 09:46:06 -0500570
571void AImageDecoder_setInternallyHandleDisposePrevious(AImageDecoder* decoder, bool handle) {
572 if (decoder) {
573 toDecoder(decoder)->setHandleRestorePrevious(handle);
574 }
575}