Add NDK Apis for image decoding
Bug: 135133301
Test: Ib84462ea5fa8a7779eaa44494775e182e52ecaca
Change-Id: I8fd341c538f6b0d96f7abed77d58b003a3aefd12
diff --git a/include/android/imagedecoder.h b/include/android/imagedecoder.h
new file mode 100644
index 0000000..50daaba
--- /dev/null
+++ b/include/android/imagedecoder.h
@@ -0,0 +1,299 @@
+/*
+ * 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.
+ */
+
+/**
+ * @addtogroup ImageDecoder
+ * @{
+ */
+
+/**
+ * @file imageDecoder.h
+ */
+
+#ifndef ANDROID_IMAGE_DECODER_H
+#define ANDROID_IMAGE_DECODER_H
+
+#include "bitmap.h"
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct AAsset;
+struct ARect;
+
+#if __ANDROID_API__ >= 30
+
+/** AImageDecoder functions result code. */
+enum {
+ // Decoding was successful and complete.
+ ANDROID_IMAGE_DECODER_SUCCESS = 0,
+ // The input was incomplete. In decodeImage, this means a partial
+ // image was decoded. Undecoded lines are all zeroes.
+ // In AImageDecoder_create*, no AImageDecoder was created.
+ ANDROID_IMAGE_DECODER_INCOMPLETE = -1,
+ // The input contained an error after decoding some lines. Similar to
+ // INCOMPLETE, above.
+ ANDROID_IMAGE_DECODER_ERROR = -2,
+ // Could not convert, e.g. 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 was bad (e.g. pixels)
+ ANDROID_IMAGE_DECODER_BAD_PARAMETER = -5,
+ // Input was invalid i.e. broken before decoding any pixels.
+ ANDROID_IMAGE_DECODER_INVALID_INPUT = -6,
+ // A seek was required, and failed.
+ ANDROID_IMAGE_DECODER_SEEK_ERROR = -7,
+ // Some other error (e.g. OOM)
+ ANDROID_IMAGE_DECODER_INTERNAL_ERROR = -8,
+ // We did not recognize the format
+ ANDROID_IMAGE_DECODER_UNSUPPORTED_FORMAT = -9
+};
+
+struct AImageDecoder;
+
+/**
+ * Opaque handle for decoding images.
+ *
+ * Create using one of the following:
+ * - {@link AImageDecoder_createFromAAsset}
+ * - {@link AImageDecoder_createFromFd}
+ * - {@link AImageDecoder_createFromBuffer}
+ */
+typedef struct AImageDecoder AImageDecoder;
+
+/**
+ * Create a new AImageDecoder from an AAsset.
+ *
+ * @param asset {@link AAsset} containing encoded image data. Client is still
+ * responsible for calling {@link AAsset_close} on it.
+ * @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 reason for the failure.
+ */
+int AImageDecoder_createFromAAsset(AAsset* asset, AImageDecoder** outDecoder) __INTRODUCED_IN(30);
+
+/**
+ * Create a new AImageDecoder from a file descriptor.
+ *
+ * @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 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 reason for the failure.
+ */
+int AImageDecoder_createFromFd(int fd, AImageDecoder** outDecoder) __INTRODUCED_IN(30);
+
+/**
+ * Create a new AImageDecoder from a buffer.
+ *
+ * @param buffer Pointer to encoded data. Must be valid for the entire time
+ * the 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 reason for the failure.
+ */
+int AImageDecoder_createFromBuffer(const void* buffer, size_t length,
+ AImageDecoder** outDecoder) __INTRODUCED_IN(30);
+
+/**
+ * Delete the AImageDecoder.
+ */
+void AImageDecoder_delete(AImageDecoder* decoder) __INTRODUCED_IN(30);
+
+/**
+ * Choose the desired output format.
+ *
+ * @param format AndroidBitmapFormat to use
+ * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} if the format is compatible
+ * with the image and {@link ANDROID_IMAGE_DECODER_INVALID_CONVERSION}
+ * otherwise. In the latter case, the AImageDecoder uses the
+ * format it was already planning to use (either its default
+ * or a previously successful setting from this function).
+ */
+int AImageDecoder_setAndroidBitmapFormat(AImageDecoder*,
+ int32_t format) __INTRODUCED_IN(30);
+
+/*
+ * Choose the desired output format.
+ *
+ * Must be one of:
+ * {@link ANDROID_BITMAP_FLAGS_ALPHA_PREMUL}
+ * {@link ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE}
+ * {@link ANDROID_BITMAP_FLAGS_ALPHA_UNPREMUL}
+ *
+ * Note: An OPAQUE image may be set to any of them.
+ * A non-OPAQUE image may not be set to OPAQUE
+ *
+ * @return - {@link ANDROID_IMAGE_DECODER_SUCCESS} on success
+ * - {@link ANDROID_IMAGE_DECODER_INVALID_CONVERSION} if the conversion
+ * is not possible
+ * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER} for bad parameters
+ */
+int AImageDecoder_setAlphaFlags(AImageDecoder*, int alphaFlags) __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.
+ *
+ * @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
+ * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER} if the AImageDecoder
+ * pointer is null, width or height is <= 0, or any existing crop is
+ * not contained by the image dimensions.
+ */
+int AImageDecoder_setTargetSize(AImageDecoder*, int width, int 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.
+ *
+ * @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 ANDROID_IMAGE_DECODER_BAD_PARAMETER.
+ * @return - {@link ANDROID_IMAGE_DECODER_SUCCESS} on success
+ * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER} if the AImageDecoder
+ * pointer is null or the crop is not contained by the image
+ * dimensions.
+ */
+int AImageDecoder_setCrop(AImageDecoder*, ARect crop) __INTRODUCED_IN(30);
+
+/**
+ * Opaque handle for reading header info.
+ */
+struct AImageDecoderHeaderInfo;
+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}.
+ */
+const AImageDecoderHeaderInfo* AImageDecoder_getHeaderInfo(
+ const AImageDecoder*) __INTRODUCED_IN(30);
+
+/**
+ * Report the native width of the encoded image.
+ */
+int32_t AImageDecoderHeaderInfo_getWidth(const AImageDecoderHeaderInfo*) __INTRODUCED_IN(30);
+
+/**
+ * Report the native height of the encoded image.
+ */
+int32_t AImageDecoderHeaderInfo_getHeight(const AImageDecoderHeaderInfo*) __INTRODUCED_IN(30);
+
+/**
+ * Report the mimeType of the encoded image.
+ *
+ * @return a string literal describing the mime type.
+ */
+const char* AImageDecoderHeaderInfo_getMimeType(
+ const AImageDecoderHeaderInfo*) __INTRODUCED_IN(30);
+
+/**
+ * Report whether the encoded image represents an animation.
+ */
+bool AImageDecoderHeaderInfo_isAnimated(
+ const AImageDecoderHeaderInfo*) __INTRODUCED_IN(30);
+
+/**
+ * Report the AndroidBitmapFormat the AImageDecoder will decode to
+ * by default. 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.
+ */
+AndroidBitmapFormat AImageDecoderHeaderInfo_getAndroidBitmapFormat(
+ const AImageDecoderHeaderInfo*) __INTRODUCED_IN(30);
+
+/**
+ * Report how the 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}.
+ *
+ * For animated images only the opacity of the first frame is reported.
+ */
+int AImageDecoderHeaderInfo_getAlphaFlags(
+ const AImageDecoderHeaderInfo*) __INTRODUCED_IN(30);
+
+/**
+ * Return the minimum stride that can be used, taking the specified
+ * (or default) (possibly scaled) width, crop rect and
+ * {@link AndroidBitmapFormat} into account.
+ */
+size_t AImageDecoder_getMinimumStride(AImageDecoder*) __INTRODUCED_IN(30);
+
+/**
+ * Decode the image into pixels, using the settings of the AImageDecoder.
+ *
+ * @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 fit |size| bytes.
+ * @param stride Width in bytes of a single row. Must be at least
+ * {@link AImageDecoder_getMinimumStride}.
+ * @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 an error code
+ * from the same enum describing the failure.
+ */
+int AImageDecoder_decodeImage(AImageDecoder* decoder,
+ void* pixels, size_t stride,
+ size_t size) __INTRODUCED_IN(30);
+
+#endif // __ANDROID_API__ >= 30
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANDROID_IMAGE_DECODER_H
+
+/** @} */