Package icyllis.modernui.graphics

# Class Bitmap

java.lang.Object
icyllis.modernui.graphics.Bitmap

All Implemented Interfaces:
  `AutoCloseable`

public final class Bitmap extends Object implements AutoCloseable
Describes a 2D raster image (pixel map), with its pixels in native memory. This class can be used for CPU-side encoding, decoding and resampling; pixel transfer between CPU and GPU. You cannot use Canvas to draw content onto a Bitmap.

Bitmap is created with immutable width, height, row bytes, and memory allocation (memory address), its contents may be changed. You can allocate zero-initialized Bitmap via the static factory methods in this class, i.e. `createBitmap(int, int, Format)`. You can also obtain Bitmap from encoded data (PNG, TGA, BMP, JPEG, HDR, PSD, PBM, PGM, and PPM) via `BitmapFactory`.

The color space of Bitmap defaults to sRGB and can only be in RGB model space or null, color space may be changed via `setColorSpace(ColorSpace)`. The alpha defaults to non-premultiplied (independent of RGB channels), alpha type may be changed via `setPremultiplied(boolean)`. The Bitmap's format may also be changed via `setFormat(Format)`, as long as the bytes-per-pixel of the old and new formats are the same. For example, when using BitmapFactory to read a single channel image, the default format is GRAY_8. You can re-interpret it as ALPHA_8 type via `setFormat(Format)`, and the image data remains unchanged.

The Bitmap provides several methods for manipulating the pixel data, there are single pixel and bulk access methods, which may perform zero or more of the following transformations: pixel format (i.e. Format), alpha type (i.e. premultiplied or not), and color space.
The pixel data of a bitmap can be marked as immutable through `setImmutable()`. This way, only read-only operations are allowed in the future, avoiding the memory copy in some operations.

This class is not thread safe, but memory safe. Its internal state may be shared by multiple threads/owners. Nevertheless, it's recommended to call `close()` explicitly, or within a try-with-resource block.

See Also:
  - `Image`
  - `BitmapFactory`

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static enum`
  `Bitmap.Format`
  Describes a layout of pixel data in CPU memory.
  `static enum`
  `Bitmap.SaveFormat`
  List of supported formats a bitmap can be saved as (encoding or compressing).

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `static final com.ibm.icu.text.DateFormat`
  `DATE_FORMAT`
  `static final org.apache.logging.log4j.Marker`
  `MARKER`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `boolean`
  `clear(float[] color, Rect area)`
  Fills the bitmap's pixels with the specified color and rectangular area.
  `void`
  `close()`
  Clear the reference to the pixel data.
  `boolean`
  `copyPixelsFromBuffer(Buffer src, int rowBytes, int dstX, int dstY, int width, int height)`
  Copy the pixels from the specified buffer into bitmap.
  `boolean`
  `copyPixelsToBuffer(Buffer dst, int rowBytes, int srcX, int srcY, int width, int height)`
  Copy the bitmap's pixels into the specified buffer.
  `static Bitmap`
  `createBitmap(int width, int height, Bitmap.Format format)`
  Creates a mutable bitmap and its allocation, the content are initialized to zeros.
  `static Bitmap`
  `createBitmap(int width, int height, Bitmap.Format format, boolean isPremultiplied, ColorSpace colorSpace)`
  Creates a mutable bitmap and its allocation, the content are initialized to zeros.
  `long`
  `getAddress()`
  The address of `void *pixels` in native.
  `int`
  `getAlphaType()`
  `int`
  `getChannels()`
  Returns the number of channels.
  `float[]`
  `getColor4f(int x, int y, float[] dst)`
  Gets the pixel value at the specified location.
  `ColorSpace`
  `getColorSpace()`
  Returns the color space associated with this bitmap.
  `int`
  `getColorType()`
  `Bitmap.Format`
  `getFormat()`
  Returns the current pixel format used to interpret pixel data.
  `int`
  `getHeight()`
  Returns the height of the bitmap.
  `ImageInfo`
  `getInfo()`
  `int`
  `getPixelARGB(int x, int y)`
  Returns the `Color` at the specified location.
  `@RawPtr Pixels`
  `getPixels()`
  The ref of current pixel data, which may be shared across instances.
  `void`
  `getPixels(float[] dst, int offset, int stride, int srcX, int srcY, int width, int height)`
  Copies a Rect of pixels to dst.
  `void`
  `getPixels(int[] dst, int offset, int stride, int srcX, int srcY, int width, int height)`
  Copies a Rect of pixels to dst.
  `void`
  `getPixels(Bitmap dst, int dstX, int dstY, int srcX, int srcY, int width, int height)`
  Copies a Rect of pixels from this bitmap to dst bitmap at (dstX, dstY).
  `Pixmap`
  `getPixmap()`
  The current pixel map, which is usually paired with `Pixels`.
  `int`
  `getRowBytes()`
  Return the distance, in bytes, between the start of one pixel row and the next, including any unused space between them.
  `int`
  `getRowStride()`
  The distance, in bytes, between the start of one pixel row and the next, including any unused space between them.
  `long`
  `getSize()`
  Returns the number of bytes that can be used to store this bitmap's pixels.
  `int`
  `getWidth()`
  Returns the width of the bitmap.
  `boolean`
  `hasAlpha()`
  Returns true if the bitmap's format supports per-pixel alpha, and if the pixels may contain non-opaque alpha values.
  `boolean`
  `isClosed()`
  Returns true if this bitmap has been closed.
  `boolean`
  `isImmutable()`
  Returns true if the bitmap is marked as immutable.
  `boolean`
  `isPremultiplied()`
  Indicates whether pixels stored in this bitmaps are stored premultiplied.
  `boolean`
  `isRecycled()`
  `static String`
  `openDialogGet(Bitmap.SaveFormat format, CharSequence title, CharSequence defaultPathAndFile)`
  Display an OS file open dialog to select a supported image file.
  `static String[]`
  `openDialogGets(Bitmap.SaveFormat format, CharSequence title, CharSequence defaultPathAndFile)`
  Display an OS file open dialog to select multiple supported image files.
  `void`
  `recycle()`
  Same as `close()`.
  `boolean`
  `saveDialog(Bitmap.SaveFormat format, int quality, String name)`
  Save this bitmap to specified path as specified format.
  `static String`
  `saveDialogGet(Bitmap.SaveFormat format, CharSequence title, String name)`
  Display an OS file save dialog to select the path to save the bitmap.
  `void`
  `saveToChannel(Bitmap.SaveFormat format, int quality, WritableByteChannel channel)`
  Save this bitmap to specified channel with specified format.
  `void`
  `saveToFile(Bitmap.SaveFormat format, int quality, File file)`
  Save this bitmap to specified path with specified format.
  `void`
  `saveToPath(Bitmap.SaveFormat format, int quality, Path path)`
  Save this bitmap to specified path with specified format.
  `void`
  `saveToStream(Bitmap.SaveFormat format, int quality, OutputStream stream)`
  Save this bitmap to specified stream with specified format.
  `void`
  `setColor4f(int x, int y, float[] src)`
  Sets the pixel value at the specified location.
  `void`
  `setColorSpace(ColorSpace newColorSpace)`
  Modifies the bitmap to have the specified `ColorSpace`, without affecting the underlying allocation backing the bitmap.
  `void`
  `setFormat(Bitmap.Format format)`
  Modifies the bitmap to have a specified `Bitmap.Format`, without affecting the underlying allocation backing the bitmap.
  `void`
  `setImmutable()`
  Marks the Bitmap as immutable.
  `void`
  `setPixels(float[] src, int offset, int stride, int dstX, int dstY, int width, int height)`
  Copies a Rect of pixels from src.
  `void`
  `setPixels(int[] src, int offset, int stride, int dstX, int dstY, int width, int height)`
  Copies a Rect of pixels from src.
  `void`
  `setPixels(Bitmap src, int srcX, int srcY, int dstX, int dstY, int width, int height)`
  Copies a Rect of pixels from src bitmap at (srcX, srcY) to this bitmap.
  `void`
  `setPremultiplied(boolean premultiplied)`
  Sets whether the bitmap should treat its data as premultiplied or not.
  `String`
  `toString()`
  `static Bitmap`
  `wrap(long address, int rowBytes, LongConsumer freeFn, int width, int height, Bitmap.Format format, boolean isPremultiplied, ColorSpace colorSpace)`
  Create a mutable bitmap by wrapping an existing address in an unsafe manner.

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- ## Field Details

  - ### MARKER

    public static final org.apache.logging.log4j.Marker MARKER

  - ### DATE_FORMAT

    public static final com.ibm.icu.text.DateFormat DATE_FORMAT

- ## Method Details

  - ### createBitmap

    @NonNull public static Bitmap createBitmap(@Size(min=1L) int width, @Size(min=1L) int height, @NonNull Bitmap.Format format)
    Creates a mutable bitmap and its allocation, the content are initialized to zeros.

    The newly created bitmap will have non-premultiplied alpha if the format has an alpha channel. The newly created bitmap is in the `sRGB` color space, unless the format is alpha only, in which case the color space is null. You may change the format, alpha type, and color space after creating the bitmap.

    Parameters:
      `width` - width in pixels, must be > 0
      `height` - height in pixels, must be > 0
      `format` - the number of channels and the bit depth
    Throws:
      `IllegalArgumentException` - width or height out of range
      `OutOfMemoryError` - out of native memory

  - ### createBitmap

    @NonNull public static Bitmap createBitmap(@Size(min=1L) int width, @Size(min=1L) int height, @NonNull Bitmap.Format format, boolean isPremultiplied, @Nullable ColorSpace colorSpace)
    Creates a mutable bitmap and its allocation, the content are initialized to zeros.

    You may change the format, alpha type, and color space after creating the bitmap.

    Parameters:
      `width` - width in pixels, must be > 0
      `height` - height in pixels, must be > 0
      `format` - a color interpretation
      `isPremultiplied` - an alpha interpretation
      `colorSpace` - a color space describing the pixels
    Throws:
      `IllegalArgumentException` - width or height out of range
      `OutOfMemoryError` - out of native memory

  - ### wrap

    @Experimental @NonNull public static Bitmap wrap(long address, int rowBytes, @Nullable LongConsumer freeFn, @Size(min=1L) int width, @Size(min=1L) int height, @NonNull Bitmap.Format format, boolean isPremultiplied, @Nullable ColorSpace colorSpace)
    Create a mutable bitmap by wrapping an existing address in an unsafe manner.
    Parameters:
      `address` - base address
      `rowBytes` - size of one row of buffer; width times bpp, or larger
      `freeFn` - free function for address
      `width` - width of pixels
      `height` - height of pixels
      `format` - a color interpretation
      `isPremultiplied` - an alpha interpretation
      `colorSpace` - a color space describing the pixels
    Returns:
      a bitmap

  - ### openDialogGet

    @Nullable public static String openDialogGet(@Nullable Bitmap.SaveFormat format, @Nullable CharSequence title, @Nullable CharSequence defaultPathAndFile)
    Display an OS file open dialog to select a supported image file. The dialog will block the current thread until method return.
    Parameters:
      `format` - the specified image file format to open, or `null` to use all supported formats
      `title` - the dialog title or `null` to use OS default
      `defaultPathAndFile` - the default path and/or file or `null` to use OS default
    Returns:
      the selected path or `null` if selects nothing (dismissed or closed)

  - ### openDialogGets

    @Nullable public static String[] openDialogGets(@Nullable Bitmap.SaveFormat format, @Nullable CharSequence title, @Nullable CharSequence defaultPathAndFile)
    Display an OS file open dialog to select multiple supported image files. The dialog will block the current thread until method return.
    Parameters:
      `format` - the specified image file format to open, or `null` to use all supported formats
      `title` - the dialog title or `null` to use OS default
      `defaultPathAndFile` - the default path and/or file or `null` to use OS default
    Returns:
      the selected paths or `null` if selects nothing (dismissed or closed)

  - ### saveDialogGet

    @Nullable public static String saveDialogGet(@Nullable Bitmap.SaveFormat format, @Nullable CharSequence title, @Nullable String name)
    Display an OS file save dialog to select the path to save the bitmap. The dialog will block the current thread until method return.
    Parameters:
      `format` - the specified image file format to filter, or `null` to filter all supported formats
      `title` - the dialog title or `null` to use OS default
      `name` - the file name without extension name
    Returns:
      the path or `null` if selects nothing

  - ### getInfo

    @Internal @NonNull public ImageInfo getInfo()

  - ### getWidth

    public int getWidth()
    Returns the width of the bitmap.

  - ### getHeight

    public int getHeight()
    Returns the height of the bitmap.

  - ### getSize

    public long getSize()
    Returns the number of bytes that can be used to store this bitmap's pixels.

  - ### getColorType

    @Internal public int getColorType()

  - ### getAlphaType

    @Internal public int getAlphaType()

  - ### getFormat

    @NonNull public Bitmap.Format getFormat()
    Returns the current pixel format used to interpret pixel data. The bitmap's format can be changed using `setFormat(Format)`.
    Returns:
      the pixel format used to interpret colors

  - ### setFormat

    public void setFormat(@NonNull Bitmap.Format format)
    Modifies the bitmap to have a specified `Bitmap.Format`, without affecting the underlying allocation backing the bitmap. Bitmap pixel data is not re-initialized for the new format. By calling this method, further operations will reinterpret the colors using the specified color type.

    This method can be used to map a channel to another channel. For example, `Bitmap.Format.GRAY_8`, `Bitmap.Format.ALPHA_8`, `Bitmap.Format.R_8` have the same pixel layout and are interchangeable. If the bytes-per-pixel of new format and original format do not match, an `IllegalArgumentException` will be thrown and the bitmap will not be modified.

    Parameters:
      `format` - a new interpretation of existing pixel data
    Throws:
      `IllegalArgumentException` - bpp of new format is not equal to bpp of original format

  - ### getChannels

    public int getChannels()
    Returns the number of channels.

  - ### hasAlpha

    public boolean hasAlpha()
    Returns true if the bitmap's format supports per-pixel alpha, and if the pixels may contain non-opaque alpha values. For some formats, this is always false (e.g. `Bitmap.Format.RGB_888`), since they do not support per-pixel alpha. However, for formats that do, the bitmap may be flagged to be known that all of its pixels are opaque. In this case hasAlpha() will also return false. If a format such as `Bitmap.Format.RGBA_8888` is not so flagged, it will return true by default.

  - ### isPremultiplied

    public boolean isPremultiplied()

    Indicates whether pixels stored in this bitmaps are stored premultiplied. When a pixel is premultiplied, the RGB components have been multiplied by the alpha component. For instance, if the original color is a 50% translucent red `(128, 255, 0, 0)`, the premultiplied form is `(128, 128, 0, 0)`.

    This method only returns true if `hasAlpha()` returns true. A bitmap with no alpha channel can be used both as a premultiplied and as a non premultiplied bitmap.

    Returns:
      true if the underlying pixels have been premultiplied, false otherwise

  - ### setPremultiplied

    public void setPremultiplied(boolean premultiplied)
    Sets whether the bitmap should treat its data as premultiplied or not.

    By calling this method, further operations will reinterpret the colors using the specified alpha type, existing pixel data will remain unchanged.

    If the current format does not have an alpha channel (`hasAlpha()` returns false), then the specified alpha type is recorded and will work in the future, see `setFormat(Format)`.

    Parameters:
      `premultiplied` - whether premultiplied alpha type is requested

  - ### getColorSpace

    @Nullable public ColorSpace getColorSpace()
    Returns the color space associated with this bitmap. If the color space is unknown, this method returns null.

  - ### setColorSpace

    public void setColorSpace(@Nullable ColorSpace newColorSpace)

    Modifies the bitmap to have the specified `ColorSpace`, without affecting the underlying allocation backing the bitmap.

    This affects how the framework will interpret the color at each pixel.

    Parameters:
      `newColorSpace` - to assign to the bitmap
    Throws:
      `IllegalArgumentException` - If the specified color space is not `RGB`, has a transfer function that is not an `ICC parametric curve`, or whose components min/max values reduce the numerical range compared to the previously assigned color space.

  - ### getAddress

    @Internal public long getAddress()
    The address of `void *pixels` in native. The address is valid until bitmap closed.
    Returns:
      the pointer of pixel data, or NULL if released

  - ### getRowStride

    @Obsolete public int getRowStride()
    The distance, in bytes, between the start of one pixel row and the next, including any unused space between them.

    This method is obsolete in favor of `getRowBytes()`.

    Returns:
      the scanline size in bytes

  - ### getRowBytes

    public int getRowBytes()
    Return the distance, in bytes, between the start of one pixel row and the next, including any unused space between them.
    Returns:
      number of bytes between rows of the native bitmap pixels

  - ### isImmutable

    public boolean isImmutable()
    Returns true if the bitmap is marked as immutable.

  - ### setImmutable

    public void setImmutable()
    Marks the Bitmap as immutable. Further modifications to this Bitmap are disallowed. After this method is called, this Bitmap cannot be made mutable again.

  - ### getPixelARGB

    @ColorInt public int getPixelARGB(int x, int y)
    Returns the `Color` at the specified location. Throws an exception if x or y are out of bounds (negative or >= to the width or height respectively). The returned color is a non-premultiplied ARGB value in the `sRGB` color space, the format is the same as `Bitmap.Format.BGRA_8888_PACK32`.

    If the max bits per channel for the color type is greater than 8, or colors are premultiplied, then color precision may be lost in the conversion. Otherwise, precision will not be lost. If the color space is not sRGB, then this method will perform color space transformation, which can be slow.

    Batch version of this operation: `getPixels(int[], int, int, int, int, int, int)`.

    Parameters:
      `x` - The x coordinate (0...width-1) of the pixel to return
      `y` - The y coordinate (0...height-1) of the pixel to return
    Returns:
      The argb `Color` at the specified coordinate
    Throws:
      `IllegalArgumentException` - if x, y exceed the bitmap's bounds
    See Also:
      - `getColor4f(int, int, float[])`

  - ### getColor4f

    @NonNull @Size(4L) public float[] getColor4f(int x, int y, @NonNull @Size(4L) float[] dst)
    Gets the pixel value at the specified location. Throws an exception if x or y are out of bounds (negative or >= to the width or height respectively). This method won't perform alpha type or color space conversion, then the result color is converted to RGBA float color, and its color space and alpha type remain unchanged (see `getColorSpace()` and `isPremultiplied()`).

    Batch version of this operation: `getPixels(float[], int, int, int, int, int, int)`.

    Parameters:
      `x` - The x coordinate (0...width-1) of the pixel to return
      `y` - The y coordinate (0...height-1) of the pixel to return
      `dst` - The result RGBA float color at the specified coordinate
    Returns:
      the passed float array that contains r,g,b,a values
    Throws:
      `IllegalStateException` - the bitmap is released
      `IllegalArgumentException` - if x, y exceed the bitmap's bounds
    See Also:
      - `setColor4f(int, int, float[])`

  - ### setColor4f

    public void setColor4f(int x, int y, @NonNull @Size(4L) float[] src)
    Sets the pixel value at the specified location. The given float color will convert to bitmap's format. This method won't perform alpha type or color space conversion, then the given color must be in the bitmap's color space `getColorSpace()`, its alpha type must be the same as `isPremultiplied()`). This bitmap must be mutable, that is, `isImmutable()` must return false.

    Batch version of this operation: `setPixels(float[], int, int, int, int, int, int)`.

    Parameters:
      `x` - The x coordinate of the pixel to replace (0...width-1)
      `y` - The y coordinate of the pixel to replace (0...height-1)
      `src` - The RGBA float color to write into the bitmap
    Throws:
      `IllegalStateException` - the bitmap is released or immutable
      `IllegalArgumentException` - if x, y exceed the bitmap's bounds
    See Also:
      - `getColor4f(int, int, float[])`

  - ### getPixels

    public void getPixels(@NonNull @ColorInt int[] dst, int offset, int stride, int srcX, int srcY, int width, int height)
    Copies a Rect of pixels to dst. Copy starts at (srcX, srcY), and does not exceed (width, height). Each value is a packed int representing a `Color`. The stride parameter allows the caller to allow for gaps in the returned pixels array between rows. For normal packed results, just pass width for the stride value. The returned colors are non-premultiplied ARGB values in the `sRGB` color space, i.e. it has `Bitmap.Format.BGRA_8888_PACK32` pixel format.

    If the max bits per channel of `getFormat()` is greater than 8, or colors are premultiplied, then color precision may be lost in the conversion. See `getPixels(float[], int, int, int, int, int, int)`.

    Parameters:
      `dst` - The destination array to receive the bitmap's colors
      `offset` - The first index to write into dst
      `stride` - The number of entries in dst to skip between rows (must be >= width)
      `srcX` - The srcX coordinate of the first pixel to read from the bitmap
      `srcY` - The srcY coordinate of the first pixel to read from the bitmap
      `width` - The number of pixels to read from each row
      `height` - The number of rows to read
    Throws:
      `IllegalStateException` - the bitmap is released
      `IllegalArgumentException` - if srcX, srcY, width, height exceed the bounds of the bitmap, or if stride invalid input: '<' width
      `ArrayIndexOutOfBoundsException` - if the pixels array is too small to receive the specified number of pixels
    See Also:
      - `setPixels(int[], int, int, int, int, int, int)`

  - ### setPixels

    public void setPixels(@NonNull @ColorInt int[] src, int offset, int stride, int dstX, int dstY, int width, int height)
    Copies a Rect of pixels from src. Copy starts at (dstX, dstY), and does not exceed (width, height). Each element in the array is a packed int representing a non-premultiplied ARGB `Color` in the `sRGB` color space, i.e. it has `Bitmap.Format.BGRA_8888_PACK32` pixel format. The stride parameter allows the caller to allow for gaps in the source pixels array between rows. For normal packed pixels, just pass width for the stride value.

    See `setPixels(float[], int, int, int, int, int, int)`.

    Parameters:
      `src` - The source colors to write to the bitmap
      `offset` - The index of the first color to read from src
      `stride` - The number of colors in src to skip between rows Normally this value will be the same as the width of the bitmap, but it can be larger
      `dstX` - The x coordinate of the first pixel to write to in the bitmap.
      `dstY` - The y coordinate of the first pixel to write to in the bitmap.
      `width` - The number of colors to copy from src per row
      `height` - The number of rows to write to the bitmap
    See Also:
      - `getPixels(int[], int, int, int, int, int, int)`

  - ### getPixels

    public void getPixels(@NonNull @Size(multiple=4L) float[] dst, int offset, int stride, int srcX, int srcY, int width, int height)
    Copies a Rect of pixels to dst. Copy starts at (srcX, srcY), and does not exceed (width, height). The returned colors are (R,G,B,A) float color quadruples in the source color space `getColorSpace()`, in the source alpha type `isPremultiplied()`, in `Bitmap.Format.RGBA_F32` pixel format. The stride parameter allows the caller to allow for gaps in the returned pixels array between rows. For normal packed results, just pass width for the stride value.

    Throws `ArrayIndexOutOfBoundsException` if `(offset + (height - 1) * stride + width) * 4 > dst.length`.

    Parameters:
      `dst` - The destination array to receive the bitmap's colors
      `offset` - The first color to write into dst
      `stride` - The number of colors in dst to skip between rows (must be >= width)
      `srcX` - The srcX coordinate of the first pixel to read from the bitmap
      `srcY` - The srcY coordinate of the first pixel to read from the bitmap
      `width` - The number of pixels to read from each row
      `height` - The number of rows to read
    Throws:
      `IllegalStateException` - the bitmap is released
      `IllegalArgumentException` - if srcX, srcY, width, height exceed the bounds of the bitmap, or if stride invalid input: '<' width
      `ArrayIndexOutOfBoundsException` - if the pixels array is too small to receive the specified number of pixels
    See Also:
      - `setPixels(float[], int, int, int, int, int, int)`

  - ### setPixels

    public void setPixels(@NonNull @Size(multiple=4L) float[] src, int offset, int stride, int dstX, int dstY, int width, int height)
    Copies a Rect of pixels from src. Copy starts at (dstX, dstY), and does not exceed (width, height). Each element in the array is a quadruple that contains (R,G,B,A) float color components source color space `getColorSpace()`, in the source alpha type `isPremultiplied()`, in `Bitmap.Format.RGBA_F32` pixel format. The stride parameter allows the caller to allow for gaps in the source pixels array between rows. For normal packed pixels, just pass width for the stride value.

    Throws `ArrayIndexOutOfBoundsException` if `(offset + (height - 1) * stride + width) * 4 > dst.length`.

    Parameters:
      `src` - The source colors to write to the bitmap
      `offset` - The index of the first color to read from src
      `stride` - The number of colors in src to skip between rows Normally this value will be the same as the width of the bitmap, but it can be larger
      `dstX` - The x coordinate of the first pixel to write to in the bitmap.
      `dstY` - The y coordinate of the first pixel to write to in the bitmap.
      `width` - The number of colors to copy from src per row
      `height` - The number of rows to write to the bitmap
    See Also:
      - `getPixels(float[], int, int, int, int, int, int)`

  - ### getPixels

    public void getPixels(@NonNull Bitmap dst, int dstX, int dstY, int srcX, int srcY, int width, int height)
    Copies a Rect of pixels from this bitmap to dst bitmap at (dstX, dstY). Copy starts at (srcX, srcY), and does not exceed (width, height). This method will perform pixel format and alpha type conversion (see `getFormat()` and `isPremultiplied()`), and color space transformation (see `getColorSpace()`).

    The behavior is undefined if there is memory overlap between this bitmap and the destination bitmap.

    Parameters:
      `dst` - The destination bitmap to receive this bitmap's colors
      `dstX` - The dstX coordinate of the first pixel to write to the bitmap
      `dstY` - The dstY coordinate of the first pixel to write to the bitmap
      `srcX` - The srcX coordinate of the first pixel to read from the bitmap
      `srcY` - The srcY coordinate of the first pixel to read from the bitmap
      `width` - The number of pixels to read from each row
      `height` - The number of rows to read
    Throws:
      `IllegalStateException` - the bitmap is released or immutable
      `IllegalArgumentException` - if srcX, srcY, dstX, dstY, width, height exceed the bounds of the bitmap
    See Also:
      - `setPixels(Bitmap, int, int, int, int, int, int)`

  - ### setPixels

    public void setPixels(@NonNull Bitmap src, int srcX, int srcY, int dstX, int dstY, int width, int height)
    Copies a Rect of pixels from src bitmap at (srcX, srcY) to this bitmap. Copy starts at (dstX, dstY), and does not exceed (width, height). This method will perform pixel format and alpha type conversion (see `getFormat()` and `isPremultiplied()`), and color space transformation (see `getColorSpace()`).

    The behavior is undefined if there is memory overlap between this bitmap and the source bitmap.

    Parameters:
      `src` - The source bitmap to write to this bitmap
      `srcX` - The srcX coordinate of the first pixel to read from the bitmap
      `srcY` - The srcY coordinate of the first pixel to read from the bitmap
      `dstX` - The dstX coordinate of the first pixel to write to the bitmap
      `dstY` - The dstY coordinate of the first pixel to write to the bitmap
      `width` - The number of pixels to read from each row
      `height` - The number of rows to read
    Throws:
      `IllegalStateException` - the bitmap is released or immutable
      `IllegalArgumentException` - if srcX, srcY, dstX, dstY, width, height exceed the bounds of the bitmap
    See Also:
      - `getPixels(Bitmap, int, int, int, int, int, int)`

  - ### copyPixelsToBuffer

    public boolean copyPixelsToBuffer(@NonNull Buffer dst, int rowBytes, int srcX, int srcY, int width, int height)
    Copy the bitmap's pixels into the specified buffer. The buffer can be a heap buffer, a direct buffer, or a native buffer (by wrapping an address). Buffer's base array, address and position will be used, other properties like `Buffer.limit()` are ignored, this method always assumes the byte order is the host endianness, i.e. `ByteOrder.nativeOrder()`, and reinterpret the data to buffer's basic type.

    This method does not check for invalid, out of bounds, or misaligned addresses. If the memory is managed by Buffer (non-wrapped direct buffer), it will be guaranteed to be alive. Note `Buffer.isReadOnly()` must return false.

    The content of the bitmap is copied into the buffer as-is. This means that if this bitmap has premultiplied colors (see `isPremultiplied()`), the values in the buffer will also be premultiplied. The pixels remain in the `Bitmap.Format` and color space of the bitmap.

    After this method returns, the current position of the buffer remains unchanged.

    This method may return false if dst is nullptr or address it not aligned to the bytes-per-pixel or the size of basic data type (according to `Bitmap.Format`). May return false if rowBytes is less than the minRowBytes (width * bpp).

    Returns:
      true if pixels are copied to dst
    Throws:
      `IllegalStateException` - the bitmap is released
      `IllegalArgumentException` - if srcX, srcY, width, height exceed the bounds of the bitmap
    See Also:
      - `copyPixelsFromBuffer(java.nio.Buffer, int, int, int, int, int)`

  - ### copyPixelsFromBuffer

    public boolean copyPixelsFromBuffer(@NonNull Buffer src, int rowBytes, int dstX, int dstY, int width, int height)
    Copy the pixels from the specified buffer into bitmap. The buffer can be a heap buffer, a direct buffer, or a native buffer (by wrapping an address). Buffer's base array, address and position will be used, other properties like `Buffer.limit()` are ignored, this method always assumes the byte order is the host endianness, i.e. `ByteOrder.nativeOrder()`, and reinterpret the data from buffer's basic type.

    This method does not check for invalid, out of bounds, or misaligned addresses. If the memory is managed by Buffer (non-wrapped direct buffer), it will be guaranteed to be alive. Note `Buffer.isReadOnly()` must return false.

    The content of the buffer is copied into the bitmap as-is. This means that if this bitmap has premultiplied colors (see `isPremultiplied()`), the values in the buffer should also be premultiplied. The pixels remain in the `Bitmap.Format` and color space of the bitmap.

    After this method returns, the current position of the buffer remains unchanged.

    This method may return false if dst is nullptr or address it not aligned to the bytes-per-pixel or the size of basic data type (according to `Bitmap.Format`). May return false if rowBytes is less than the minRowBytes (width * bpp).

    Returns:
      true if src pixels are copied to bitmap
    Throws:
      `IllegalStateException` - the bitmap is released
      `IllegalArgumentException` - if dstX, dstY, width, height exceed the bounds of the bitmap
    See Also:
      - `copyPixelsToBuffer(java.nio.Buffer, int, int, int, int, int)`

  - ### clear

    public boolean clear(@NonNull @Size(4L) float[] color, @Nullable Rect area)
    Fills the bitmap's pixels with the specified color and rectangular area. The given float color is in the source color space `getColorSpace()`, in the source alpha type `isPremultiplied()`, in `Bitmap.Format.RGBA_F32` pixel format. That is, this method will only perform pixel format conversion, and will not perform alpha type or color space transformation.
    Parameters:
      `color` - the (R,G,B,A) color to fill
      `area` - bounding box of pixels to fill; null means full bitmap
    Returns:
      true if pixels are changed
    Throws:
      `IllegalStateException` - the bitmap is released or immutable

  - ### getPixmap

    @Internal @NonNull public Pixmap getPixmap()
    The current pixel map, which is usually paired with `Pixels`. This method is UNSAFE, use with caution!
    Returns:
      the current pixel map

  - ### getPixels

    @Internal @RawPtr @Nullable public @RawPtr Pixels getPixels()
    The ref of current pixel data, which may be shared across instances. Calling this method won't affect the ref cnt. Every bitmap object ref the `Pixels` on create, and unref on `close()`.

    This method is UNSAFE, use with caution!

    Returns:
      the ref of pixel data, or null if released

  - ### saveDialog

    @WorkerThread public boolean saveDialog(@NonNull Bitmap.SaveFormat format, int quality, @Nullable String name) throws IOException
    Save this bitmap to specified path as specified format. This will open a save dialog to select the path, block the current thread until the encoding is done.
    Parameters:
      `format` - the format of the saved image
      `quality` - the compress quality, 0-100, only work for JPEG format.
      `name` - the file name without extension name
    Returns:
      true if selected a path, otherwise canceled
    Throws:
      `IOException` - selected a path, but saving is not successful
      `IllegalArgumentException` - bad arguments
      `IllegalStateException` - failed to process

  - ### saveToFile

    @WorkerThread public void saveToFile(@NonNull Bitmap.SaveFormat format, int quality, @NonNull File file) throws IOException
    Save this bitmap to specified path with specified format.
    Parameters:
      `format` - the format of the saved image
      `quality` - the compress quality, 0-100, only work for JPEG format.
      `file` - the image file
    Throws:
      `IOException` - saving is not successful
      `IllegalArgumentException` - bad arguments
      `IllegalStateException` - failed to process

  - ### saveToPath

    @WorkerThread public void saveToPath(@NonNull Bitmap.SaveFormat format, int quality, @NonNull Path path) throws IOException
    Save this bitmap to specified path with specified format.
    Parameters:
      `format` - the format of the saved image
      `quality` - the compress quality, 0-100, only work for JPEG format.
      `path` - the image path
    Throws:
      `IOException` - saving is not successful
      `IllegalArgumentException` - bad arguments
      `IllegalStateException` - failed to process

  - ### saveToStream

    @WorkerThread public void saveToStream(@NonNull Bitmap.SaveFormat format, int quality, @NonNull OutputStream stream) throws IOException
    Save this bitmap to specified stream with specified format. The stream will NOT be closed by this method.
    Parameters:
      `format` - the format of the saved image
      `quality` - the compress quality, 0-100, only work for JPEG format
      `stream` - the stream to write image data
    Throws:
      `IOException` - saving is not successful
      `IllegalArgumentException` - bad arguments
      `IllegalStateException` - failed to process

  - ### saveToChannel

    @WorkerThread public void saveToChannel(@NonNull Bitmap.SaveFormat format, int quality, @NonNull WritableByteChannel channel) throws IOException
    Save this bitmap to specified channel with specified format. The channel will NOT be closed by this method.
    Parameters:
      `format` - the format of the saved image
      `quality` - the compress quality, 0-100, only work for JPEG format
      `channel` - the channel to write image data
    Throws:
      `IOException` - saving is not successful
      `IllegalArgumentException` - bad arguments
      `IllegalStateException` - failed to process

  - ### close

    public void close()
    Clear the reference to the pixel data. The bitmap is marked as "dead", and then it is an error to try to access its pixels.

    The system can ensure that the native allocation of a Bitmap to be released when the Bitmap object becomes phantom-reachable. However, it tends to take a very long time to perform automatic cleanup.

    Specified by:
      `close` in interface `AutoCloseable`

  - ### recycle

    public void recycle()
    Same as `close()`.

  - ### isClosed

    public boolean isClosed()
    Returns true if this bitmap has been closed. If so, then it is an error to try to access its pixels.
    Returns:
      true if the bitmap has been closed

  - ### isRecycled

    public boolean isRecycled()
    Returns:
      the same as `isClosed()`

  - ### toString

    @NonNull public String toString()
    Overrides:
      `toString` in class `Object`