package com.bumptech.glide.gifdecoder;
import android.graphics.Bitmap;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import java.io.InputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
/**
* Shared interface for GIF decoders.
*/
public interface GifDecoder {
/** File read status: No errors. */
int STATUS_OK = 0;
/** File read status: Error decoding file (may be partially decoded). */
int STATUS_FORMAT_ERROR = 1;
/** File read status: Unable to open source. */
int STATUS_OPEN_ERROR = 2;
/** Unable to fully decode the current frame. */
int STATUS_PARTIAL_DECODE = 3;
/** The total iteration count which means repeat forever. */
int TOTAL_ITERATION_COUNT_FOREVER = 0;
/** Android Lint annotation for status codes that can be used with a GIF decoder. */
@Retention(RetentionPolicy.SOURCE)
@IntDef(value = {STATUS_OK, STATUS_FORMAT_ERROR, STATUS_OPEN_ERROR, STATUS_PARTIAL_DECODE})
@interface GifDecodeStatus {
}
/**
* An interface that can be used to provide reused {@link android.graphics.Bitmap}s to avoid GCs
* from constantly allocating {@link android.graphics.Bitmap}s for every frame.
*/
public interface BitmapProvider {
/**
* Returns an {@link Bitmap} with exactly the given dimensions and config.
*
* @param width The width in pixels of the desired {@link android.graphics.Bitmap}.
* @param height The height in pixels of the desired {@link android.graphics.Bitmap}.
* @param config The {@link android.graphics.Bitmap.Config} of the desired {@link
* android.graphics.Bitmap}.
*/
@NonNull
Bitmap obtain(int width, int height, Bitmap.Config config);
/**
* Releases the given Bitmap back to the pool.
*/
void release(Bitmap bitmap);
/**
* Returns a byte array used for decoding and generating the frame bitmap.
*
* @param size the size of the byte array to obtain
*/
byte[] obtainByteArray(int size);
/**
* Releases the given byte array back to the pool.
*/
void release(byte[] bytes);
/**
* Returns an int array used for decoding/generating the frame bitmaps.
*/
int[] obtainIntArray(int size);
/**
* Release the given array back to the pool.
*/
void release(int[] array);
}
int getWidth();
int getHeight();
ByteBuffer getData();
/**
* Returns the current status of the decoder.
*
* <p> Status will update per frame to allow the caller to tell whether or not the current frame
* was decoded successfully and/or completely. Format and open failures persist across frames.
* </p>
*/
@GifDecodeStatus
int getStatus();
/**
* Move the animation frame counter forward.
*/
void advance();
/**
* Gets display duration for specified frame.
*
* @param n int index of frame.
* @return delay in milliseconds.
*/
int getDelay(int n);
/**
* Gets display duration for the upcoming frame in ms.
*/
int getNextDelay();
/**
* Gets the number of frames read from file.
*
* @return frame count.
*/
int getFrameCount();
/**
* Gets the current index of the animation frame, or -1 if animation hasn't not yet started.
*
* @return frame index.
*/
int getCurrentFrameIndex();
/**
* Resets the frame pointer to before the 0th frame, as if we'd never used this decoder to
* decode any frames.
*/
void resetFrameIndex();
/**
* Gets the "Netscape" loop count, if any. A count of 0 means repeat indefinitely.
*
* @deprecated Use {@link #getNetscapeLoopCount()} instead.
* This method cannot distinguish whether the loop count is 1 or doesn't exist.
* @return loop count if one was specified, else 1.
*/
@Deprecated
int getLoopCount();
/**
* Gets the "Netscape" loop count, if any.
* A count of 0 ({@link GifHeader#NETSCAPE_LOOP_COUNT_FOREVER}) means repeat indefinitely.
* It must not be a negative value.
* <br>
* Use {@link #getTotalIterationCount()}
* to know how many times the animation sequence should be displayed.
*
* @return loop count if one was specified,
* else -1 ({@link GifHeader#NETSCAPE_LOOP_COUNT_DOES_NOT_EXIST}).
*/
int getNetscapeLoopCount();
/**
* Gets the total count
* which represents how many times the animation sequence should be displayed.
* A count of 0 ({@link #TOTAL_ITERATION_COUNT_FOREVER}) means repeat indefinitely.
* It must not be a negative value.
* <p>
* The total count is calculated as follows by using {@link #getNetscapeLoopCount()}.
* This behavior is the same as most web browsers.
* <table border='1'>
* <tr class='tableSubHeadingColor'><th>{@code getNetscapeLoopCount()}</th>
* <th>The total count</th></tr>
* <tr><td>{@link GifHeader#NETSCAPE_LOOP_COUNT_FOREVER}</td>
* <td>{@link #TOTAL_ITERATION_COUNT_FOREVER}</td></tr>
* <tr><td>{@link GifHeader#NETSCAPE_LOOP_COUNT_DOES_NOT_EXIST}</td>
* <td>{@code 1}</td></tr>
* <tr><td>{@code n (n > 0)}</td>
* <td>{@code n + 1}</td></tr>
* </table>
* </p>
*
* @see <a href="https://bugs.chromium.org/p/chromium/issues/detail?id=592735#c5">Discussion about
* the iteration count of animated GIFs (Chromium Issue 592735)</a>
*
* @return total iteration count calculated from "Netscape" loop count.
*/
int getTotalIterationCount();
/**
* Returns an estimated byte size for this decoder based on the data provided to {@link
* #setData(GifHeader, byte[])}, as well as internal buffers.
*/
int getByteSize();
/**
* Get the next frame in the animation sequence.
*
* @return Bitmap representation of frame.
*/
Bitmap getNextFrame();
/**
* Reads GIF image from stream.
*
* @param is containing GIF file.
* @return read status code (0 = no errors).
*/
@GifDecodeStatus
int read(InputStream is, int contentLength);
void clear();
void setData(GifHeader header, byte[] data);
void setData(GifHeader header, ByteBuffer buffer);
void setData(GifHeader header, ByteBuffer buffer, int sampleSize);
/**
* Reads GIF image from byte array.
*
* @param data containing GIF file.
* @return read status code (0 = no errors).
*/
@GifDecodeStatus
int read(byte[] data);
}