/* Copyright (C) 2010 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.
 */

package android.graphics;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.res.AssetManager;
import android.os.Build;
import android.os.ParcelFileDescriptor;

import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * BitmapRegionDecoder can be used to decode a rectangle region from an image.
 * BitmapRegionDecoder is particularly useful when an original image is large and
 * you only need parts of the image.
 *
 * <p>To create a BitmapRegionDecoder, call newInstance(...).
 * Given a BitmapRegionDecoder, users can call decodeRegion() repeatedly
 * to get a decoded Bitmap of the specified region.
 *
 */
public final class BitmapRegionDecoder {
    private long mNativeBitmapRegionDecoder;
    private boolean mRecycled;
    // ensures that the native decoder object exists and that only one decode can
    // occur at a time.
    private final Object mNativeLock = new Object();

    /**
     * Create a BitmapRegionDecoder from the specified byte array.
     * Currently only the JPEG, PNG, WebP and HEIF formats are supported.
     *
     * @param data byte array of compressed image data.
     * @param offset offset into data for where the decoder should begin
     *               parsing.
     * @param length the number of bytes, beginning at offset, to parse
     * @param isShareable This field has been ignored since
     *                    {@link Build.VERSION_CODES#GINGERBREAD}.
     * @throws IOException if the image format is not supported or can not be decoded.
     * @deprecated In favor of {@link #newInstance(byte[], int, int)}
     */
    @Deprecated
    @NonNull
    public static BitmapRegionDecoder newInstance(@NonNull byte[] data,
            int offset, int length, boolean isShareable) throws IOException {
        return newInstance(data, offset, length);
    }

    /**
     * Create a BitmapRegionDecoder from the specified byte array.
     * Currently only the JPEG, PNG, WebP and HEIF formats are supported.
     *
     * @param data byte array of compressed image data.
     * @param offset offset into data for where the decoder should begin
     *               parsing.
     * @param length the number of bytes, beginning at offset, to parse
     * @throws IOException if the image format is not supported or can not be decoded.
     */
    @NonNull
    public static BitmapRegionDecoder newInstance(@NonNull byte[] data,
            int offset, int length) throws IOException {
        if ((offset | length) < 0 || data.length < offset + length) {
            throw new ArrayIndexOutOfBoundsException();
        }
        return nativeNewInstance(data, offset, length);
    }

    /**
     * Create a BitmapRegionDecoder from the file descriptor.
     * The position within the descriptor will not be changed when
     * this returns, so the descriptor can be used again as is.
     * Currently only the JPEG, PNG, WebP and HEIF formats are supported.
     *
     * @param fd The file descriptor containing the data to decode
     * @param isShareable This field has been ignored since
     *                    {@link Build.VERSION_CODES#KITKAT}.
     * @throws IOException if the image format is not supported or can not be decoded.
     * @deprecated In favor of {@link #newInstance(ParcelFileDescriptor)}
     */
    @Deprecated
    @NonNull
    public static BitmapRegionDecoder newInstance(
            @NonNull FileDescriptor fd, boolean isShareable) throws IOException {
        return nativeNewInstance(fd);
    }

    /**
     * Create a BitmapRegionDecoder from the file descriptor.
     * The position within the descriptor will not be changed when
     * this returns, so the descriptor can be used again as is.
     * Currently only the JPEG, PNG, WebP and HEIF formats are supported.
     *
     * @param pfd The parcel file descriptor containing the data to decode
     * @throws IOException if the image format is not supported or can not be decoded.
     */
    @NonNull
    public static BitmapRegionDecoder newInstance(
            @NonNull ParcelFileDescriptor pfd) throws IOException {
        return nativeNewInstance(pfd.getFileDescriptor());
    }

    /**
     * Create a BitmapRegionDecoder from an input stream.
     * The stream's position will be where ever it was after the encoded data
     * was read.
     * Currently only the JPEG, PNG, WebP and HEIF formats are supported.
     *
     * @param is The input stream that holds the raw data to be decoded into a
     *           BitmapRegionDecoder.
     * @param isShareable This field has always been ignored.
     * @return A new BitmapRegionDecoder, or {@code null} if {@code is} is {@code null}.
     * @throws IOException if the image format is not supported or can not be decoded.
     * @deprecated In favor of {@link #newInstance(InputStream)}
     *
     * <p class="note">Prior to {@link Build.VERSION_CODES#KITKAT},
     * if {@link InputStream#markSupported is.markSupported()} returns true,
     * <code>is.mark(1024)</code> would be called. As of
     * {@link Build.VERSION_CODES#KITKAT}, this is no longer the case.</p>
     */
    @Deprecated
    @Nullable
    public static BitmapRegionDecoder newInstance(@NonNull InputStream is,
            boolean isShareable) throws IOException {
        return newInstance(is);
    }

    /**
     * Create a BitmapRegionDecoder from an input stream.
     * The stream's position will be where ever it was after the encoded data
     * was read.
     * Currently only the JPEG, PNG, WebP and HEIF formats are supported.
     *
     * @param is The input stream that holds the raw data to be decoded into a
     *           BitmapRegionDecoder.
     * @return A new BitmapRegionDecoder, or {@code null} if {@code is} is {@code null}.
     * @throws IOException if the image format is not supported or can not be decoded.
     */
    @Nullable
    public static BitmapRegionDecoder newInstance(@NonNull InputStream is) throws IOException {
        if (is instanceof AssetManager.AssetInputStream) {
            return nativeNewInstance(
                    ((AssetManager.AssetInputStream) is).getNativeAsset());
        } else {
            // pass some temp storage down to the native code. 1024 is made up,
            // but should be large enough to avoid too many small calls back
            // into is.read(...).
            byte [] tempStorage = new byte[16 * 1024];
            return nativeNewInstance(is, tempStorage);
        }
    }

    /**
     * Create a BitmapRegionDecoder from a file path.
     * Currently only the JPEG, PNG, WebP and HEIF formats are supported.
     *
     * @param pathName complete path name for the file to be decoded.
     * @param isShareable This field has always been ignored.
     * @throws IOException if the image format is not supported or can not be decoded.
     * @deprecated In favor of {@link #newInstance(String)}
     */
    @Deprecated
    @NonNull
    public static BitmapRegionDecoder newInstance(@NonNull String pathName,
            boolean isShareable) throws IOException {
        return newInstance(pathName);
    }

    /**
     * Create a BitmapRegionDecoder from a file path.
     * Currently only the JPEG, PNG, WebP and HEIF formats are supported.
     *
     * @param pathName complete path name for the file to be decoded.
     * @throws IOException if the image format is not supported or can not be decoded.
     */
    @NonNull
    public static BitmapRegionDecoder newInstance(@NonNull String pathName) throws IOException {
        BitmapRegionDecoder decoder = null;
        InputStream stream = null;

        try {
            stream = new FileInputStream(pathName);
            decoder = newInstance(stream);
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                } catch (IOException e) {
                    // do nothing here
                }
            }
        }
        return decoder;
    }

    /*  Private constructor that must receive an already allocated native
        region decoder int (pointer).

        This can be called from JNI code.
    */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private BitmapRegionDecoder(long decoder) {
        mNativeBitmapRegionDecoder = decoder;
        mRecycled = false;
    }

    /**
     * Decodes a rectangle region in the image specified by rect.
     *
     * @param rect The rectangle that specified the region to be decode.
     * @param options null-ok; Options that control downsampling.
     *             inPurgeable is not supported.
     * @return The decoded bitmap, or null if the image data could not be
     *         decoded.
     * @throws IllegalArgumentException if {@link BitmapFactory.Options#inPreferredConfig}
     *         is {@link android.graphics.Bitmap.Config#HARDWARE}
     *         and {@link BitmapFactory.Options#inMutable} is set, if the specified color space
     *         is not {@link ColorSpace.Model#RGB RGB}, or if the specified color space's transfer
     *         function is not an {@link ColorSpace.Rgb.TransferParameters ICC parametric curve}
     */
    public Bitmap decodeRegion(Rect rect, BitmapFactory.Options options) {
        BitmapFactory.Options.validate(options);
        synchronized (mNativeLock) {
            checkRecycled("decodeRegion called on recycled region decoder");
            if (rect.right <= 0 || rect.bottom <= 0 || rect.left >= getWidth()
                    || rect.top >= getHeight())
                throw new IllegalArgumentException("rectangle is outside the image");
            return nativeDecodeRegion(mNativeBitmapRegionDecoder, rect.left, rect.top,
                    rect.right - rect.left, rect.bottom - rect.top, options,
                    BitmapFactory.Options.nativeInBitmap(options),
                    BitmapFactory.Options.nativeColorSpace(options));
        }
    }

    /** Returns the original image's width */
    public int getWidth() {
        synchronized (mNativeLock) {
            checkRecycled("getWidth called on recycled region decoder");
            return nativeGetWidth(mNativeBitmapRegionDecoder);
        }
    }

    /** Returns the original image's height */
    public int getHeight() {
        synchronized (mNativeLock) {
            checkRecycled("getHeight called on recycled region decoder");
            return nativeGetHeight(mNativeBitmapRegionDecoder);
        }
    }

    /**
     * Frees up the memory associated with this region decoder, and mark the
     * region decoder as "dead", meaning it will throw an exception if decodeRegion(),
     * getWidth() or getHeight() is called.
     *
     * <p>This operation cannot be reversed, so it should only be called if you are
     * sure there are no further uses for the region decoder. This is an advanced call,
     * and normally need not be called, since the normal GC process will free up this
     * memory when there are no more references to this region decoder.
     */
    public void recycle() {
        synchronized (mNativeLock) {
            if (!mRecycled) {
                nativeClean(mNativeBitmapRegionDecoder);
                mRecycled = true;
            }
        }
    }

    /**
     * Returns true if this region decoder has been recycled.
     * If so, then it is an error to try use its method.
     *
     * @return true if the region decoder has been recycled
     */
    public final boolean isRecycled() {
        return mRecycled;
    }

    /**
     * Called by methods that want to throw an exception if the region decoder
     * has already been recycled.
     */
    private void checkRecycled(String errorMessage) {
        if (mRecycled) {
            throw new IllegalStateException(errorMessage);
        }
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            recycle();
        } finally {
            super.finalize();
        }
    }

    private static native Bitmap nativeDecodeRegion(long lbm,
            int start_x, int start_y, int width, int height,
            BitmapFactory.Options options, long inBitmapHandle,
            long colorSpaceHandle);
    private static native int nativeGetWidth(long lbm);
    private static native int nativeGetHeight(long lbm);
    private static native void nativeClean(long lbm);

    private static native BitmapRegionDecoder nativeNewInstance(
            byte[] data, int offset, int length);
    private static native BitmapRegionDecoder nativeNewInstance(
            FileDescriptor fd);
    private static native BitmapRegionDecoder nativeNewInstance(
            InputStream is, byte[] storage);
    private static native BitmapRegionDecoder nativeNewInstance(
            long asset);
}
