summaryrefslogtreecommitdiff
path: root/include/android/imagedecoder.h
blob: fb7d09c04d61a390cc3c283b573f61d740a66341 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @defgroup ImageDecoder Android Image Decoder
 *
 * Functions for converting encoded images into RGBA pixels.
 *
 * Similar to the Java counterpart android.graphics.ImageDecoder, it can be used
 * to decode images in the following formats:
 * - JPEG
 * - PNG
 * - GIF
 * - WebP
 * - BMP
 * - ICO
 * - WBMP
 * - HEIF
 * - Digital negatives (via the DNG SDK)
 * <p>It has similar options for scaling, cropping, and choosing the output format.
 * Unlike the Java API, which can create an android.graphics.Bitmap or
 * android.graphics.drawable.Drawable object, AImageDecoder decodes directly
 * into memory provided by the client. For more information, see the
 * <a href="https://developer.android.com/ndk/guides/image-decoder">Image decoder</a>
 * developer guide.
 * @{
 */

/**
 * @file imagedecoder.h
 * @brief API for decoding images.
 */

#ifndef ANDROID_IMAGE_DECODER_H
#define ANDROID_IMAGE_DECODER_H

#include "bitmap.h"
#include <android/rect.h>
#include <stdint.h>

#if !defined(__INTRODUCED_IN)
#define __INTRODUCED_IN(__api_level) /* nothing */
#endif

#ifdef __cplusplus
extern "C" {
#endif

struct AAsset;

/**
 *  {@link AImageDecoder} functions result code.
 *
 *  Introduced in API 30.
 *
 *  Many functions will return this to indicate success
 *  ({@link ANDROID_IMAGE_DECODER_SUCCESS}) or the reason for the failure. On
 *  failure, any out-parameters should be considered uninitialized, except where
 *  specified. Use {@link AImageDecoder_resultToString} for a readable
 *  version of the result code.
 */
enum {
    /**
     * Decoding was successful and complete.
     */
    ANDROID_IMAGE_DECODER_SUCCESS = 0,
    /**
     * The input is incomplete.
     */
    ANDROID_IMAGE_DECODER_INCOMPLETE = -1,
    /**
     * The input contained an error after decoding some lines.
     */
    ANDROID_IMAGE_DECODER_ERROR = -2,
    /**
     * Could not convert. For example, attempting to decode an image with
     * alpha to an opaque format.
     */
    ANDROID_IMAGE_DECODER_INVALID_CONVERSION = -3,
    /**
     * The scale is invalid. It may have overflowed, or it may be incompatible
     * with the current alpha setting.
     */
    ANDROID_IMAGE_DECODER_INVALID_SCALE = -4,
    /**
     * Some other parameter is invalid.
     */
    ANDROID_IMAGE_DECODER_BAD_PARAMETER = -5,
    /**
     * Input was invalid before decoding any pixels.
     */
    ANDROID_IMAGE_DECODER_INVALID_INPUT = -6,
    /**
     * A seek was required and it failed.
     */
    ANDROID_IMAGE_DECODER_SEEK_ERROR = -7,
    /**
     * Some other error. For example, an internal allocation failed.
     */
    ANDROID_IMAGE_DECODER_INTERNAL_ERROR = -8,
    /**
     * AImageDecoder did not recognize the format.
     */
    ANDROID_IMAGE_DECODER_UNSUPPORTED_FORMAT = -9,
    /**
     * The animation has reached the end.
     */
    ANDROID_IMAGE_DECODER_FINISHED = -10,
    /**
     * This method cannot be called while the AImageDecoder is in its current
     * state. For example, various setters (like {@link AImageDecoder_setTargetSize})
     * can only be called while the AImageDecoder is set to decode the first
     * frame of an animation. This ensures that any blending and/or restoring
     * prior frames works correctly.
     */
    ANDROID_IMAGE_DECODER_INVALID_STATE = -11,
};

/**
 * Return a constant string value representing the error code.
 *
 * Introduced in API 31.
 *
 * Pass the return value from an {@link AImageDecoder} method (e.g.
 * {@link AImageDecoder_decodeImage}) for a text string representing the error
 * code.
 *
 * Errors:
 * - Returns null for a value out of range.
 */
const char* _Nullable AImageDecoder_resultToString(int)__INTRODUCED_IN(31);

struct AImageDecoder;

/**
 * Opaque handle for decoding images.
 *
 * Introduced in API 30
 *
 * Create using one of the following:
 * - {@link AImageDecoder_createFromAAsset}
 * - {@link AImageDecoder_createFromFd}
 * - {@link AImageDecoder_createFromBuffer}
 *
 * After creation, {@link AImageDecoder_getHeaderInfo} can be used to retrieve
 * information about the encoded image. Other functions, like
 * {@link AImageDecoder_setTargetSize}, can be used to specify how to decode, and
 * {@link AImageDecoder_decodeImage} will decode into client provided memory.
 *
 * {@link AImageDecoder} objects are NOT thread-safe, and should not be shared across
 * threads.
 */
typedef struct AImageDecoder AImageDecoder;

/**
 * Create a new {@link AImageDecoder} from an {@link AAsset}.
 *
 * Available since API level 30.
 *
 * @param asset {@link AAsset} containing encoded image data. Client is still
 *              responsible for calling {@link AAsset_close} on it, which may be
 *              done after deleting the returned {@link AImageDecoder}.
 * @param outDecoder On success (i.e. return value is
 *                   {@link ANDROID_IMAGE_DECODER_SUCCESS}), this will be set to
 *                   a newly created {@link AImageDecoder}. Caller is
 *                   responsible for calling {@link AImageDecoder_delete} on it.
 * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
 *         indicating the reason for the failure.
 *
 * Errors:
 * - {@link ANDROID_IMAGE_DECODER_INCOMPLETE}: The asset was truncated before
 *   reading the image header.
 * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: One of the parameters is
 *   null.
 * - {@link ANDROID_IMAGE_DECODER_INVALID_INPUT}: There is an error in the
 *   header.
 * - {@link ANDROID_IMAGE_DECODER_SEEK_ERROR}: The asset failed to seek.
 * - {@link ANDROID_IMAGE_DECODER_INTERNAL_ERROR}: Some other error, like a
 *   failure to allocate memory.
 * - {@link ANDROID_IMAGE_DECODER_UNSUPPORTED_FORMAT}: The format is not
 *   supported.
 */
int AImageDecoder_createFromAAsset(struct AAsset* _Nonnull asset,
                                   AImageDecoder* _Nullable * _Nonnull outDecoder)
        __INTRODUCED_IN(30);

/**
 * Create a new {@link AImageDecoder} from a file descriptor.
 *
 * Available since API level 30.
 *
 * @param fd Seekable, readable, open file descriptor for encoded data.
 *           Client is still responsible for closing it, which may be done
 *           after deleting the returned {@link AImageDecoder}.
 * @param outDecoder On success (i.e. return value is
 *                   {@link ANDROID_IMAGE_DECODER_SUCCESS}), this will be set to
 *                   a newly created {@link AImageDecoder}. Caller is
 *                   responsible for calling {@link AImageDecoder_delete} on it.
 * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
 *         indicating the reason for the failure.
 *
 * Errors:
 * - {@link ANDROID_IMAGE_DECODER_INCOMPLETE}: The file was truncated before
 *   reading the image header.
 * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The {@link AImageDecoder} is
 *   null, or |fd| does not represent a valid, seekable file descriptor.
 * - {@link ANDROID_IMAGE_DECODER_INVALID_INPUT}: There is an error in the
 *   header.
 * - {@link ANDROID_IMAGE_DECODER_SEEK_ERROR}: The descriptor failed to seek.
 * - {@link ANDROID_IMAGE_DECODER_INTERNAL_ERROR}: Some other error, like a
 *   failure to allocate memory.
 * - {@link ANDROID_IMAGE_DECODER_UNSUPPORTED_FORMAT}: The format is not
 *   supported.
 */
int AImageDecoder_createFromFd(int fd, AImageDecoder* _Nullable * _Nonnull outDecoder)
        __INTRODUCED_IN(30);

/**
 * Create a new AImageDecoder from a buffer.
 *
 * Available since API level 30.
 *
 * @param buffer Pointer to encoded data. Must be valid for the entire time
 *               the {@link AImageDecoder} is used.
 * @param length Byte length of buffer.
 * @param outDecoder On success (i.e. return value is
 *                   {@link ANDROID_IMAGE_DECODER_SUCCESS}), this will be set to
 *                   a newly created {@link AImageDecoder}. Caller is
 *                   responsible for calling {@link AImageDecoder_delete} on it.
 * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
 *         indicating the reason for the failure.
 *
 * Errors:
 * - {@link ANDROID_IMAGE_DECODER_INCOMPLETE}: The encoded image was truncated before
 *   reading the image header.
 * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: One of the parameters is
 *   invalid.
 * - {@link ANDROID_IMAGE_DECODER_INVALID_INPUT}: There is an error in the
 *   header.
 * - {@link ANDROID_IMAGE_DECODER_INTERNAL_ERROR}: Some other error, like a
 *   failure to allocate memory.
 * - {@link ANDROID_IMAGE_DECODER_UNSUPPORTED_FORMAT}: The format is not
 *   supported.
 */
int AImageDecoder_createFromBuffer(const void* _Nonnull buffer, size_t length,
                                   AImageDecoder* _Nullable * _Nonnull outDecoder)
        __INTRODUCED_IN(30);

/**
 * Delete the AImageDecoder.
 * @param decoder {@link AImageDecoder} object created with one of AImageDecoder_createFrom...
 *        functions.
 * Available since API level 30.
 */
void AImageDecoder_delete(AImageDecoder* _Nullable decoder) __INTRODUCED_IN(30);

/**
 * Choose the desired output format.
 *
 * If the encoded image represents an animation, this must be called while on
 * the first frame (e.g. before calling {@link AImageDecoder_advanceFrame} or
 * after calling {@link AImageDecoder_rewind}).
 *
 * Available since API level 30.
 *
 * @param format {@link AndroidBitmapFormat} to use for the output.
 * @param decoder an {@link AImageDecoder} object.
 * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
 *         indicating the reason for the failure. On failure, the
 *         {@link AImageDecoder} uses the format it was already planning
 *         to use (either its default or a previously successful setting
 *         from this function).
 *
 * Errors:
 * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The
 *   {@link AImageDecoder} is null or |format| does not correspond to an
 *   {@link AndroidBitmapFormat}.
 * - {@link ANDROID_IMAGE_DECODER_INVALID_CONVERSION}: The
 *   {@link AndroidBitmapFormat} is incompatible with the image.
 * - {@link ANDROID_IMAGE_DECODER_INVALID_STATE}: The animation is not on
 *   the first frame.
 */
int AImageDecoder_setAndroidBitmapFormat(AImageDecoder* _Nonnull decoder,
        int32_t format) __INTRODUCED_IN(30);

/**
 * Specify whether the output's pixels should be unpremultiplied.
 *
 * By default, {@link AImageDecoder_decodeImage} will premultiply the pixels, if they have alpha.
 * Pass true to this method to leave them unpremultiplied. This has no effect on an
 * opaque image.
 *
 * If the encoded image represents an animation, this must be called while on
 * the first frame (e.g. before calling {@link AImageDecoder_advanceFrame} or
 * after calling {@link AImageDecoder_rewind}).
 *
 * Available since API level 30.
 *
 * @param decoder an {@link AImageDecoder} object.
 * @param unpremultipliedRequired Pass true to leave the pixels unpremultiplied.
 * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
 *         indicating the reason for the failure.
 *
 * Errors:
 * - {@link ANDROID_IMAGE_DECODER_INVALID_CONVERSION}: Unpremultiplied is not
 *   possible due to an existing scale set by
 *   {@link AImageDecoder_setTargetSize}.
 * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The
 *   {@link AImageDecoder} is null.
 * - {@link ANDROID_IMAGE_DECODER_INVALID_STATE}: The animation is not on
 *   the first frame.
 */
int AImageDecoder_setUnpremultipliedRequired(AImageDecoder* _Nonnull decoder,
                                             bool unpremultipliedRequired) __INTRODUCED_IN(30);

/**
 * Choose the dataspace for the output.
 *
 * Ignored by {@link ANDROID_BITMAP_FORMAT_A_8}, which does not support
 * an {@link ADataSpace}.
 *
 * If the encoded image represents an animation, this must be called while on
 * the first frame (e.g. before calling {@link AImageDecoder_advanceFrame} or
 * after calling {@link AImageDecoder_rewind}).
 *
 * Available since API level 30.
 *
 * @param decoder an {@link AImageDecoder} object.
 * @param dataspace The {@link ADataSpace} to decode into. An ADataSpace
 *                  specifies how to interpret the colors. By default,
 *                  AImageDecoder will decode into the ADataSpace specified by
 *                  {@link AImageDecoderHeaderInfo_getDataSpace}. If this
 *                  parameter is set to a different ADataSpace, AImageDecoder
 *                  will transform the output into the specified ADataSpace.
 * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
 *         indicating the reason for the failure.
 *
 * Errors:
 * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The
 *   {@link AImageDecoder} is null or |dataspace| does not correspond to an
 *   {@link ADataSpace} value.
 * - {@link ANDROID_IMAGE_DECODER_INVALID_STATE}: The animation is not on
 *   the first frame.
 */
int AImageDecoder_setDataSpace(AImageDecoder* _Nonnull decoder, int32_t dataspace)
        __INTRODUCED_IN(30);

/**
 * Specify the output size for a decoded image.
 *
 * Future calls to {@link AImageDecoder_decodeImage} will sample or scale the
 * encoded image to reach the desired size. If a crop rect is set (via
 * {@link AImageDecoder_setCrop}), it must be contained within the dimensions
 * specified by width and height, and the output image will be the size of the
 * crop rect.
 *
 * If the encoded image represents an animation, this must be called while on
 * the first frame (e.g. before calling {@link AImageDecoder_advanceFrame} or
 * after calling {@link AImageDecoder_rewind}).
 *
 * It is strongly recommended to use setTargetSize only for downscaling, as it
 * is often more efficient to scale-up when rendering than up-front due to
 * reduced overall memory.
 *
 * Available since API level 30.
 *
 * @param decoder an {@link AImageDecoder} object.
 * @param width Width of the output (prior to cropping).
 *              This will affect future calls to
 *              {@link AImageDecoder_getMinimumStride}, which will now return
 *              a value based on this width.
 * @param height Height of the output (prior to cropping).
 * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
 *         indicating the reason for the failure.
 *
 * Errors:
 * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The
 *   {@link AImageDecoder} is null.
 * - {@link ANDROID_IMAGE_DECODER_INVALID_SCALE}: |width| or |height| is <= 0,
 *   the size is too big, any existing crop is not contained by the new image
 *   dimensions, or the scale is incompatible with a previous call to
 *   {@link AImageDecoder_setUnpremultipliedRequired}(true).
 * - {@link ANDROID_IMAGE_DECODER_INVALID_STATE}: The animation is not on
 *   the first frame.
 */
int AImageDecoder_setTargetSize(AImageDecoder* _Nonnull decoder, int32_t width,
                                int32_t height) __INTRODUCED_IN(30);

/**
 * Compute the dimensions to use for a given sampleSize.
 *
 * Although AImageDecoder can scale to an arbitrary target size (see
 * {@link AImageDecoder_setTargetSize}), some sizes may be more efficient than
 * others. This computes the most efficient target size to use to reach a
 * particular sampleSize.
 *
 * Available since API level 30.
 *
 * @param decoder an {@link AImageDecoder} object.
 * @param sampleSize A subsampling rate of the original image. Must be greater
 *                   than or equal to 1. A sampleSize of 2 means to skip every
 *                   other pixel/line, resulting in a width and height that are
 *                   1/2 of the original dimensions, with 1/4 the number of
 *                   pixels.
 * @param width Out parameter for the width sampled by sampleSize, and rounded
 *              in the direction that the decoder can do most efficiently.
 * @param height Out parameter for the height sampled by sampleSize, and rounded
 *               in the direction that the decoder can do most efficiently.
 * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
 *         indicating the reason for the failure.
 *
 * Errors:
 * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The
 *   {@link AImageDecoder}, |width| or |height| is null or |sampleSize| is < 1.
 */
int AImageDecoder_computeSampledSize(const AImageDecoder* _Nonnull decoder, int sampleSize,
                                     int32_t* _Nonnull width, int32_t* _Nonnull height)
        __INTRODUCED_IN(30);

/**
 * Specify how to crop the output after scaling (if any).
 *
 * Future calls to {@link AImageDecoder_decodeImage} will crop their output to
 * the specified {@link ARect}. Clients will only need to allocate enough memory
 * for the cropped ARect.
 *
 * If the encoded image represents an animation, this must be called while on
 * the first frame (e.g. before calling {@link AImageDecoder_advanceFrame} or
 * after calling {@link AImageDecoder_rewind}).
 *
 * Available since API level 30.
 *
 * @param decoder an {@link AImageDecoder} object.
 * @param crop Rectangle describing a crop of the decode. It must be contained inside of
 *             the (possibly scaled, by {@link AImageDecoder_setTargetSize})
 *             image dimensions. This will affect future calls to
 *             {@link AImageDecoder_getMinimumStride}, which will now return a
 *             value based on the width of the crop. An empty ARect -
 *             specifically { 0, 0, 0, 0 } - may be used to remove the cropping
 *             behavior. Any other empty or unsorted ARects will result in
 *             returning {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}.
 * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
 *         indicating the reason for the failure.
 *
 * Errors:
 * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The
 *   {@link AImageDecoder} is null, or the crop is not contained by the
 *   (possibly scaled) image dimensions.
 * - {@link ANDROID_IMAGE_DECODER_INVALID_STATE}: The animation is not on
 *   the first frame.
 */
int AImageDecoder_setCrop(AImageDecoder* _Nonnull decoder, ARect crop) __INTRODUCED_IN(30);

struct AImageDecoderHeaderInfo;
/**
 * Opaque handle for representing information about the encoded image.
 *
 * Introduced in API 30
 *
 * Retrieved using {@link AImageDecoder_getHeaderInfo} and passed to methods
 * like {@link AImageDecoderHeaderInfo_getWidth} and
 * {@link AImageDecoderHeaderInfo_getHeight}.
 */
typedef struct AImageDecoderHeaderInfo AImageDecoderHeaderInfo;

/**
 * Return an opaque handle for reading header info.
 *
 * This is owned by the {@link AImageDecoder} and will be destroyed when the
 * AImageDecoder is destroyed via {@link AImageDecoder_delete}.
 *
 * @param decoder an {@link AImageDecoder} object.
 *
 * Available since API level 30.
 */
const AImageDecoderHeaderInfo* _Nonnull  AImageDecoder_getHeaderInfo(
        const AImageDecoder* _Nonnull decoder) __INTRODUCED_IN(30);

/**
 * Report the native width of the encoded image. This is also the logical
 * pixel width of the output, unless {@link AImageDecoder_setTargetSize} is
 * used to choose a different size or {@link AImageDecoder_setCrop} is used to
 * set a crop rect.
 *
 * Available since API level 30.
 */
int32_t AImageDecoderHeaderInfo_getWidth(const AImageDecoderHeaderInfo* _Nonnull)
        __INTRODUCED_IN(30);

/**
 * Report the native height of the encoded image. This is also the logical
 * pixel height of the output, unless {@link AImageDecoder_setTargetSize} is
 * used to choose a different size or {@link AImageDecoder_setCrop} is used to
 * set a crop rect.
 *
 * Available since API level 30.
 */
int32_t AImageDecoderHeaderInfo_getHeight(const AImageDecoderHeaderInfo* _Nonnull)
        __INTRODUCED_IN(30);

/**
 * Report the mimeType of the encoded image.
 *
 * Available since API level 30.
 *
 * @return a string literal describing the mime type.
 */
const char* _Nonnull  AImageDecoderHeaderInfo_getMimeType(
        const AImageDecoderHeaderInfo* _Nonnull) __INTRODUCED_IN(30);

/**
 * Report the {@link AndroidBitmapFormat} the AImageDecoder will decode to
 * by default. {@link AImageDecoder} will try to choose one that is sensible
 * for the image and the system. Note that this does not indicate the
 * encoded format of the image.
 *
 * Available since API level 30.
 */
int32_t AImageDecoderHeaderInfo_getAndroidBitmapFormat(
        const AImageDecoderHeaderInfo* _Nonnull) __INTRODUCED_IN(30);

/**
 * Report how the {@link AImageDecoder} will handle alpha by default. If the image
 * contains no alpha (according to its header), this will return
 * {@link ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE}. If the image may contain alpha,
 * this returns {@link ANDROID_BITMAP_FLAGS_ALPHA_PREMUL}, because
 * {@link AImageDecoder_decodeImage} will premultiply pixels by default.
 *
 * Available since API level 30.
 *
 * Starting in API level 31, an AImageDecoder may contain multiple frames of an
 * animation, but this method still only reports whether the first frame has
 * alpha.
 */
int AImageDecoderHeaderInfo_getAlphaFlags(
        const AImageDecoderHeaderInfo* _Nonnull) __INTRODUCED_IN(30);

/**
 * Report the dataspace the AImageDecoder will decode to by default.
 *
 * By default, {@link AImageDecoder_decodeImage} will not do any color
 * conversion.
 *
 * Available since API level 30.
 *
 * @return The {@link ADataSpace} representing the way the colors
 *         are encoded (or {@link ADATASPACE_UNKNOWN} if there is not a
 *         corresponding ADataSpace). This specifies how to interpret the colors
 *         in the decoded image, unless {@link AImageDecoder_setDataSpace} is
 *         called to decode to a different ADataSpace.
 *
 *         Note that ADataSpace only exposes a few values. This may return
 *         {@link ADATASPACE_UNKNOWN}, even for Named ColorSpaces, if they have
 *         no corresponding {@link ADataSpace}.
 */
int32_t AImageDecoderHeaderInfo_getDataSpace(
        const AImageDecoderHeaderInfo* _Nonnull) __INTRODUCED_IN(30);

/**
 * Return the minimum stride that can be used in
 * {@link AImageDecoder_decodeImage}.
 *
 * This stride provides no padding, meaning it will be exactly equal to the
 * width times the number of bytes per pixel for the {@link AndroidBitmapFormat}
 * being used.
 *
 * If the output is scaled (via {@link AImageDecoder_setTargetSize}) and/or
 * cropped (via {@link AImageDecoder_setCrop}), this takes those into account.
 *
 * @param decoder an {@link AImageDecoder} object.
 *
 * Available since API level 30.
 */
size_t AImageDecoder_getMinimumStride(AImageDecoder* _Nonnull decoder) __INTRODUCED_IN(30);

/**
 * Decode the image into pixels, using the settings of the {@link AImageDecoder}.
 *
 * Available since API level 30.
 *
 * Starting in API level 31, it can be used to decode all of the frames of an
 * animated image (i.e. GIF, WebP) using new APIs. Internally,
 * AImageDecoder keeps track of its "current frame" - that is, the frame that
 * will be decoded by a call to AImageDecoder_decodeImage. At creation time, the
 * current frame is always the first frame, and multiple calls to this method
 * will each decode the first frame. {@link AImageDecoder_advanceFrame} advances
 * the current frame to the following frame, so that future calls to this method
 * will decode that frame. Some frames may update only part of the image. They
 * may only update a sub-rectangle (see {@link
 * AImageDecoderFrameInfo_getFrameRect}), or they may have alpha (see
 * {@link AImageDecoderFrameInfo_hasAlphaWithinBounds}). In these cases, this
 * method assumes that the prior frame is still residing in the |pixels| buffer,
 * decodes only the new portion, and blends it with the buffer. Frames that change
 * the entire |pixels| buffer are "independent", and do not require the prior
 * frame to remain in the buffer. The first frame is always independent. A
 * sophisticated client can use information from the {@link AImageDecoderFrameInfo}
 * to determine whether other frames are independent, or what frames they rely on.
 *
 * If the current frame is marked {@link ANDROID_IMAGE_DECODER_DISPOSE_OP_PREVIOUS},
 * AImageDecoder_decodeImage will store the |pixels| buffer prior to decoding
 * (note: this only happens for the first in a string of consecutive
 * ANDROID_IMAGE_DECODER_DISPOSE_OP_PREVIOUS frames). After advancing to the
 * following frame, AImageDecoder_decodeImage will restore that buffer prior to
 * decoding that frame. This is the default behavior, but it can be disabled
 * by passing false to {@link AImageDecoder_setInternallyHandleDisposePrevious}.
 *
 * Ignoring timing information, display, etc, a client wishing to decode all
 * frames of an animated image may conceptually use code like the following:
 *
 * while (true) {
 *   int result = AImageDecoder_decodeImage(decoder, pixels, stride, size);
 *   if (result != ANDROID_IMAGE_DECODER_SUCCESS) break;
 *
 *   // Display or save the image in |pixels|, keeping the buffer intact for
 *   // AImageDecoder to decode the next frame correctly.
 *   Application_viewImage(pixels);
 *
 *   result = AImageDecoder_advanceFrame(decoder);
 *   if (result != ANDROID_IMAGE_DECODER_SUCCESS) break;
 * }
 *
 * @param decoder Opaque object representing the decoder.
 * @param pixels On success, will be filled with the result
 *               of the decode. Must be large enough to hold |size| bytes.
 * @param stride Width in bytes of a single row. Must be at least
 *               {@link AImageDecoder_getMinimumStride} and a multiple of the
 *               bytes per pixel of the {@link AndroidBitmapFormat}.
 * @param size Size of the pixel buffer in bytes. Must be at least
 *             stride * (height - 1) +
 *             {@link AImageDecoder_getMinimumStride}.
 * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
 *         indicating the reason for the failure.
 *
 * Errors:
 * - {@link ANDROID_IMAGE_DECODER_INCOMPLETE}: The image was truncated. A
 *   partial image was decoded, and undecoded lines have been initialized to all
 *   zeroes.
 * - {@link ANDROID_IMAGE_DECODER_ERROR}: The image contained an error. A
 *   partial image was decoded, and undecoded lines have been initialized to all
 *   zeroes.
 * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The {@link AImageDecoder} or
 *   |pixels| is null, the stride is not large enough or not pixel aligned, or
 *   |size| is not large enough.
 * - {@link ANDROID_IMAGE_DECODER_SEEK_ERROR}: The asset or file descriptor
 *   failed to seek.
 * - {@link ANDROID_IMAGE_DECODER_INTERNAL_ERROR}: Some other error, like a
 *   failure to allocate memory.
 * - {@link ANDROID_IMAGE_DECODER_FINISHED}: The input contains no
 *   more frames. No decoding occurred. The client must call
 *   {@link AImageDecoder_rewind} before calling
 *   {@link AImageDecoder_decodeImage} again.
 */
int AImageDecoder_decodeImage(AImageDecoder* _Nonnull decoder,
                              void* _Nonnull pixels, size_t stride,
                              size_t size) __INTRODUCED_IN(30);

/**
 * Return true iff the image is animated - i.e. has multiple frames.
 *
 * Introduced in API 31.
 *
 * A single frame GIF is considered to *not* be animated. This may require
 * seeking past the first frame to verify whether there is a following frame.
 *
 * @param decoder an {@link AImageDecoder} object.
 *
 * Errors:
 * - returns false if |decoder| is null.
 */
bool AImageDecoder_isAnimated(AImageDecoder* _Nonnull decoder)
        __INTRODUCED_IN(31);

enum {
    /**
     * Reported by {@link AImageDecoder_getRepeatCount} if the
     * animation should repeat forever.
     *
     * Introduced in API 31
     */
    ANDROID_IMAGE_DECODER_INFINITE = INT32_MAX,
};

/**
 * Report how many times the animation should repeat.
 *
 * Introduced in API 31.
 *
 * This does not include the first play through. e.g. a repeat
 * count of 4 means that each frame is played 5 times.
 *
 * {@link ANDROID_IMAGE_DECODER_INFINITE} means to repeat forever.
 *
 * This may require seeking.
 *
 * For non-animated formats, this returns 0. It may return non-zero for
 * an image with only one frame (i.e. {@link AImageDecoder_isAnimated} returns
 * false) if the encoded image contains a repeat count.
 *
 * @param decoder an {@link AImageDecoder} object.
 * @return Number of times to repeat on success or a value
 *         indicating the reason for the failure.
 *
 * Errors:
 * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The AImageDecoder
 *   is null.
 */
int32_t AImageDecoder_getRepeatCount(AImageDecoder* _Nonnull decoder)
        __INTRODUCED_IN(31);

/**
 * Advance to the next frame in the animation.
 *
 * Introduced in API 31.
 *
 * The AImageDecoder keeps track internally which frame it is ready to decode
 * (the "current frame"). Initially it is set to decode the first frame, and
 * each call to {@link AImageDecoder_decodeImage} will continue to decode
 * the same frame until this method (or {@link AImageDecoder_rewind})
 * is called.
 *
 * Note that this can be used to skip a frame without decoding it. But
 * some frames depend on (i.e. blend with) prior frames, and
 * AImageDecoder_decodeImage assumes that the prior frame is in the
 * |pixels| buffer. In addition, AImageDecoder_decodeImage handles caching and
 * restoring frames (see {@link ANDROID_IMAGE_DECODER_DISPOSE_OP_PREVIOUS}), so
 * skipping frames in an image with such frames may not produce the correct
 * results.
 *
 * Only supported by {@link ANDROID_BITMAP_FORMAT_RGBA_8888} and
 * {@link ANDROID_BITMAP_FORMAT_RGBA_F16}.
 *
 * @param decoder an {@link AImageDecoder} object.
 * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
 *         indicating the reason for the failure.
 *
 * Errors:
 * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The AImageDecoder
 *   represents an image that is not animated (see
 *   {@link AImageDecoder_isAnimated}) or the AImageDecoder is null.
 * - {@link ANDROID_IMAGE_DECODER_INVALID_STATE): The requested
 *   {@link AndroidBitmapFormat} does not support animation.
 * - {@link ANDROID_IMAGE_DECODER_INCOMPLETE}: The input appears
 *   to be truncated. The client must call {@link AImageDecoder_rewind}
 *   before calling {@link AImageDecoder_decodeImage} again.
 * - {@link ANDROID_IMAGE_DECODER_ERROR}: The input contains an error.
 *   The client must call  {@link AImageDecoder_rewind} before
 *   calling {@link AImageDecoder_decodeImage} again.
 * - {@link ANDROID_IMAGE_DECODER_FINISHED}: The input contains no
 *   more frames. The client must call {@link AImageDecoder_rewind}
 *   before calling {@link AImageDecoder_decodeImage} again.
 */
int AImageDecoder_advanceFrame(AImageDecoder* _Nonnull decoder)
        __INTRODUCED_IN(31);

/**
 * Return to the beginning of the animation.
 *
 * Introduced in API 31.
 *
 * After this call, the AImageDecoder will be ready to decode the
 * first frame of the animation. This can be called after reaching
 * the end of the animation or an error or in the middle of the
 * animation.
 *
 * @param decoder an {@link AImageDecoder} object.
 * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
 *         indicating the reason for the failure.
 *
 * Errors:
 * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The AImageDecoder
 *   represents an image that is not animated (see
 *   {@link AImageDecoder_isAnimated}) or the AImageDecoder is
 *   null.
 * - {@link ANDROID_IMAGE_DECODER_SEEK_ERROR}: The asset or file
 *   descriptor failed to seek.
 */
int AImageDecoder_rewind(AImageDecoder* _Nonnull decoder)
        __INTRODUCED_IN(31);

struct AImageDecoderFrameInfo;

/**
 * Opaque handle to animation information about a single frame.
 *
 * Introduced in API 31
 *
 * The duration (retrieved with {@link AImageDecoderFrameInfo_getDuration}) is
 * necessary for clients to display the animation at the proper speed. The other
 * information is helpful for a client that wants to determine what frames are
 * independent (or what frames they depend on), but is unnecessary for
 * a simple client that wants to sequentially display all frames.
 */
typedef struct AImageDecoderFrameInfo AImageDecoderFrameInfo;

/**
 * Create an uninitialized AImageDecoderFrameInfo.
 *
 * Introduced in API 31.
 *
 * This can be passed to {@link AImageDecoder_getFrameInfo} to fill
 * in information about the current frame. It may be reused.
 *
 * Must be deleted with {@link AImageDecoderFrameInfo_delete}.
 */
AImageDecoderFrameInfo* _Nullable AImageDecoderFrameInfo_create()
        __INTRODUCED_IN(31);

/**
 * Delete an AImageDecoderFrameInfo.
 *
 * Introduced in API 31.
 */
void AImageDecoderFrameInfo_delete(
        AImageDecoderFrameInfo* _Nullable info) __INTRODUCED_IN(31);

/**
 * Fill |info| with information about the current frame.
 *
 * Introduced in API 31.
 *
 * Initially, this will return information about the first frame.
 * {@link AImageDecoder_advanceFrame} and
 * {@link AImageDecoder_rewind} can be used to change which frame
 * is the current frame.
 *
 * If the image only has one frame, this will fill the {@link
 * AImageDecoderFrameInfo} with the encoded info and reasonable
 * defaults.
 *
 * If {@link AImageDecoder_advanceFrame} succeeded, this will succeed as well.
 *
 * @param decoder Opaque object representing the decoder.
 * @param info Opaque object to hold frame information. On success, will be
 *             filled with information regarding the current frame.
 * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
 *         indicating the reason for the failure.
 *
 * Errors:
 * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: One of the parameters is null.
 * - {@link ANDROID_IMAGE_DECODER_FINISHED}: The input contains no
 *   more frames. The client must call {@link AImageDecoder_rewind} to reset the
 *   current frame to a valid frame (0).
 */
int AImageDecoder_getFrameInfo(AImageDecoder* _Nonnull decoder,
        AImageDecoderFrameInfo* _Nonnull info) __INTRODUCED_IN(31);

/**
 * Report the number of nanoseconds to show the current frame.
 *
 * Introduced in API 31.
 *
 * Errors:
 * - returns {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER} if |info| is null.
 */
int64_t AImageDecoderFrameInfo_getDuration(
        const AImageDecoderFrameInfo* _Nonnull info) __INTRODUCED_IN(31);

/**
 * The rectangle of the image (within 0, 0,
 * {@link AImageDecoderHeaderInfo_getWidth}, {@link AImageDecoderHeaderInfo_getHeight})
 * updated by this frame.
 *
 * Introduced in API 31.
 *
 * Note that this is unaffected by calls to
 * {@link AImageDecoder_setTargetSize} or
 * {@link AImageDecoder_setCrop}.
 *
 * A frame may update only part of the image. This will always be
 * contained by the image’s dimensions.
 *
 * This, along with other information in AImageDecoderFrameInfo,
 * can be useful for determining whether a frame is independent, but
 * the decoder handles blending frames, so a simple
 * sequential client does not need this.
 *
 * Errors:
 * - returns an empty ARect if |info| is null.
 */
ARect AImageDecoderFrameInfo_getFrameRect(
        const AImageDecoderFrameInfo* _Nonnull info) __INTRODUCED_IN(31);

/**
 * Whether the new portion of this frame may contain alpha.
 *
 * Introduced in API 31.
 *
 * Unless this frame is independent (see {@link AImageDecoder_decodeImage}),
 * a single call to {@link AImageDecoder_decodeImage} will decode an updated
 * rectangle of pixels and then blend it with the existing pixels in the
 * |pixels| buffer according to {@link AImageDecoderFrameInfo_getBlendOp}. This
 * method returns whether the updated rectangle has alpha, prior to blending.
 * The return value is conservative; for example, if a color-index-based frame
 * has a color with alpha but does not use it, this will still return true.
 *
 * This, along with other information in AImageDecoderFrameInfo,
 * can be useful for determining whether a frame is independent, but
 * the decoder handles blending frames, so a simple
 * sequential client does not need this.
 *
 * Note that this may differ from whether the composed frame (that is, the
 * resulting image after blending) has alpha. If this frame does not fill the
 * entire image dimensions (see {@link AImageDecoderFrameInfo_getFrameRect})
 * or it blends with an opaque frame, for example, the composed frame’s alpha
 * may not match.
 *
 * Errors:
 * - returns false if |info| is null.
 */
bool AImageDecoderFrameInfo_hasAlphaWithinBounds(
        const AImageDecoderFrameInfo* _Nonnull info) __INTRODUCED_IN(31);

/**
 * How a frame is “disposed” before showing the next one.
 *
 * Introduced in API 31.
 *
 * This, along with other information in AImageDecoderFrameInfo,
 * can be useful for determining whether a frame is independent, but
 * the decoder handles disposing of frames, so a simple
 * sequential client does not need this.
 */
enum {
    /// No disposal. The following frame will be drawn directly
    /// on top of this one.
    ANDROID_IMAGE_DECODER_DISPOSE_OP_NONE = 1,
    /// The frame’s rectangle is cleared to transparent (by AImageDecoder)
    /// before decoding the next frame.
    ANDROID_IMAGE_DECODER_DISPOSE_OP_BACKGROUND = 2,
    /// The frame’s rectangle is reverted to the prior frame before decoding
    /// the next frame. This is handled by AImageDecoder, unless
    /// {@link AImageDecoder_setInternallyHandleDisposePrevious} is set to false.
    ANDROID_IMAGE_DECODER_DISPOSE_OP_PREVIOUS = 3,
};

/**
 * Return how this frame is “disposed” before showing the next one.
 *
 * Introduced in API 31.
 *
 * This, along with other information in AImageDecoderFrameInfo,
 * can be useful for determining whether a frame is independent, but
 * the decoder handles disposing of frames, so a simple
 * sequential client does not need this.
 *
 * @return one of:
 * - {@link ANDROID_IMAGE_DECODER_DISPOSE_OP_NONE}
 * - {@link ANDROID_IMAGE_DECODER_DISPOSE_OP_BACKGROUND}
 * - {@link ANDROID_IMAGE_DECODER_DISPOSE_OP_PREVIOUS}
 * Errors:
 * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER} if |info| is null.
 */
int32_t AImageDecoderFrameInfo_getDisposeOp(
        const AImageDecoderFrameInfo* _Nonnull info) __INTRODUCED_IN(31);

/**
 * How a frame is blended with the previous frame.
 *
 * Introduced in API 31.
 *
 * This, along with other information in AImageDecoderFrameInfo,
 * can be useful for determining whether a frame is independent, but
 * the decoder handles blending frames, so a simple
 * sequential client does not need this.
 */
enum {
    /// This frame replaces existing content. This corresponds
    /// to webp’s “do not blend”.
    ANDROID_IMAGE_DECODER_BLEND_OP_SRC = 1,
    /// This frame blends with the previous frame.
    ANDROID_IMAGE_DECODER_BLEND_OP_SRC_OVER = 2,
};

/**
 * Return how this frame is blended with the previous frame.
 *
 * Introduced in API 31.
 *
 * This, along with other information in AImageDecoderFrameInfo,
 * can be useful for determining whether a frame is independent, but
 * the decoder handles blending frames, so a simple
 * sequential client does not need this.
 *
 * @return one of:
 * - {@link ANDROID_IMAGE_DECODER_BLEND_OP_SRC}
 * - {@link ANDROID_IMAGE_DECODER_BLEND_OP_SRC_OVER}
 * Errors:
 * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER} if |info| is null.
 */
int32_t AImageDecoderFrameInfo_getBlendOp(
        const AImageDecoderFrameInfo* _Nonnull info)
        __INTRODUCED_IN(31);

/**
 * Whether to have AImageDecoder store the frame prior to a
 * frame marked {@link ANDROID_IMAGE_DECODER_DISPOSE_OP_PREVIOUS}.
 *
 * Introduced in API 31.
 *
 * The default is true. Many images will not have such a frame (it
 * is not supported by WebP, and only some GIFs use it). But
 * if frame i is ANDROID_IMAGE_DECODER_DISPOSE_OP_PREVIOUS, then i+1
 * may depend on i-1. When this setting is true, AImageDecoder will
 * defensively copy frame i-1 (i.e. the contents of |pixels| in
 * {@link AImageDecoder_decodeImage}) into an internal buffer so that
 * it can be used to decode i+1.
 *
 * AImageDecoder will only store a single frame, at the size specified
 * by {@link AImageDecoder_setTargetSize} (or the original dimensions
 * if that method has not been called), and will discard it when it is
 * no longer necessary.
 *
 * A client that desires to manually store such frames may set this to
 * false, so that AImageDecoder does not need to store this extra
 * frame. Instead, when decoding the same
 * ANDROID_IMAGE_DECODER_DISPOSE_OP_PREVIOUS frame i, AImageDecoder
 * will decode directly into |pixels|, assuming the client stored i-1.
 * When asked to decode frame i+1, AImageDecoder will now assume that
 * the client provided i-1 in |pixels|.
 *
 * @param decoder an {@link AImageDecoder} object.
 * @param handleInternally Whether AImageDecoder will internally
 *               handle ANDROID_IMAGE_DECODER_DISPOSE_OP_PREVIOUS
 *               frames.
 */
void AImageDecoder_setInternallyHandleDisposePrevious(
        AImageDecoder* _Nonnull decoder, bool handleInternally)
        __INTRODUCED_IN(31);


#ifdef __cplusplus
}
#endif

#endif // ANDROID_IMAGE_DECODER_H

/** @} */