mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2025-07-04 19:46:36 +02:00
image: new image format and base for the image library
This commit is contained in:
parent
7822899b1f
commit
5a69e44078
25 changed files with 847 additions and 153 deletions
|
@ -157,6 +157,23 @@ set(SOURCES_FX
|
||||||
set(SOURCES_CG
|
set(SOURCES_CG
|
||||||
# R61524 driver
|
# R61524 driver
|
||||||
src/r61524/r61524.c
|
src/r61524/r61524.c
|
||||||
|
# Image library
|
||||||
|
src/image/image_alloc.c
|
||||||
|
src/image/image_clear.c
|
||||||
|
src/image/image_copy.c
|
||||||
|
src/image/image_copy_palette.c
|
||||||
|
src/image/image_create.c
|
||||||
|
src/image/image_create_vram.c
|
||||||
|
src/image/image_data_size.c
|
||||||
|
src/image/image_decode_pixel.c
|
||||||
|
src/image/image_fill.c
|
||||||
|
src/image/image_free.c
|
||||||
|
src/image/image_get_pixel.c
|
||||||
|
src/image/image_palette_size.c
|
||||||
|
src/image/image_set_pixel.c
|
||||||
|
src/image/image_sub.c
|
||||||
|
src/image/image_target.c
|
||||||
|
src/image/image_valid.c
|
||||||
# Rendering
|
# Rendering
|
||||||
src/render-cg/dclear.c
|
src/render-cg/dclear.c
|
||||||
src/render-cg/dpixel.c
|
src/render-cg/dpixel.c
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
// often the bottleneck, and image rendering is much faster in Azur (which is
|
// often the bottleneck, and image rendering is much faster in Azur (which is
|
||||||
// what the renderer was initially designed for).
|
// what the renderer was initially designed for).
|
||||||
//
|
//
|
||||||
// We support 3 bit depths: full-color 16-bit (RGB565), indexed 8-bit (P8) and
|
// This module supports 3 bit depths: full-color 16-bit (RGB565), indexed 8-bit
|
||||||
// indexed 4-bit (P4). All three have an "alpha" variation where one color is
|
// (P8) and indexed 4-bit (P4). All three have an "alpha" variation where one
|
||||||
// treated as transparent, leading to 6 total formats.
|
// color is treated as transparent, leading to 6 total formats.
|
||||||
//
|
//
|
||||||
// The image renderers support so-called *dynamic effects*, which are image
|
// The image renderers support so-called *dynamic effects*, which are image
|
||||||
// transformations performed on-the-fly while rendering, without generating an
|
// transformations performed on-the-fly while rendering, without generating an
|
||||||
|
@ -20,7 +20,11 @@
|
||||||
// achieve similar performance to straight rendering and can be combined to
|
// achieve similar performance to straight rendering and can be combined to
|
||||||
// some extent, which makes them reliable whenever applicable.
|
// some extent, which makes them reliable whenever applicable.
|
||||||
//
|
//
|
||||||
// TODO: Switch to libimg-style image refs.
|
// For images of the RGB16 and P8 bit depths, the module supports a rich API
|
||||||
|
// with image subsurfaces and a fairly large sets of geometric and color
|
||||||
|
// transforms, including some in-place. P4 is not supported in most of these
|
||||||
|
// functions because the dense bit packing is both impractical and slower for
|
||||||
|
// these applications.
|
||||||
//---
|
//---
|
||||||
|
|
||||||
#ifndef GINT_IMAGE
|
#ifndef GINT_IMAGE
|
||||||
|
@ -55,36 +59,66 @@ enum {
|
||||||
IMAGE_DEPRECATED_P8 = 2,
|
IMAGE_DEPRECATED_P8 = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Quick macros to compare formats by storage size */
|
||||||
|
#define IMAGE_IS_RGB16(format) \
|
||||||
|
((format) == IMAGE_RGB565 || (format) == IMAGE_RGB565A)
|
||||||
|
#define IMAGE_IS_P8(format) \
|
||||||
|
((format) == IMAGE_P8_RGB565 || (format) == IMAGE_P8_RGB565A)
|
||||||
|
#define IMAGE_IS_P4(format) \
|
||||||
|
((format) == IMAGE_P4_RGB565 || (format) == IMAGE_P4_RGB565A)
|
||||||
|
/* Check whether image format has an alpha color */
|
||||||
|
#define IMAGE_IS_ALPHA(format) \
|
||||||
|
((format) == IMAGE_RGB565A || \
|
||||||
|
(format) == IMAGE_P8_RGB565A || \
|
||||||
|
(format) == IMAGE_P4_RGB565A)
|
||||||
|
/* Check whether image format uses a palette */
|
||||||
|
#define IMAGE_IS_INDEXED(format) \
|
||||||
|
(IMAGE_IS_P8(format) || IMAGE_IS_P4(format))
|
||||||
|
|
||||||
|
/* Image flags. These are used for memory management, mostly. */
|
||||||
|
enum {
|
||||||
|
IMAGE_FLAGS_DATA_RO = 0x01, /* Data is read-only */
|
||||||
|
IMAGE_FLAGS_PALETTE_RO = 0x02, /* Palette is read-only */
|
||||||
|
IMAGE_FLAGS_DATA_ALLOC = 0x04, /* Data is malloc()'d */
|
||||||
|
IMAGE_FLAGS_PALETTE_ALLOC = 0x08, /* Palette is malloc()'d */
|
||||||
|
};
|
||||||
|
|
||||||
/* image_t: gint's native bitmap image format
|
/* image_t: gint's native bitmap image format
|
||||||
Images of this format can be created through this header's API but also by
|
Images of this format can be created through this header's API but also by
|
||||||
using the fxSDK's built-in image converters with fxconv. */
|
using the fxSDK's built-in image converters with fxconv. */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
/* Color format, one of the IMAGE_* values defined above. */
|
/* Color format, one of the IMAGE_* values defined above */
|
||||||
uint16_t profile;
|
uint8_t format;
|
||||||
/* For formats with alpha, value or index used for transparency. */
|
/* Additional flags, a combination of IMAGE_FLAGS_* values */
|
||||||
|
uint8_t flags;
|
||||||
|
/* For formats with alpha, value or index used for transparency */
|
||||||
uint16_t alpha;
|
uint16_t alpha;
|
||||||
/* Full width and height, in pixels */
|
/* Full width and height, in pixels */
|
||||||
uint16_t width;
|
uint16_t width;
|
||||||
uint16_t height;
|
uint16_t height;
|
||||||
|
/* Byte stride between lines */
|
||||||
|
int stride;
|
||||||
|
|
||||||
/* Here we lose structure because of the flexible array.
|
/* Pixel data in row-major order, left to right.
|
||||||
|
|
||||||
RGB565, RGB565A:
|
RGB16:
|
||||||
* Pixels in row-major order, 16 bits per pixel
|
- 2 bytes per entry, each row padded to 4 bytes for alignment
|
||||||
|
- Each 2-byte value is an RGB565 color
|
||||||
P8:
|
P8:
|
||||||
* Palette with 256 entries (512 bytes total)
|
- 1 byte per entry
|
||||||
* Pixels in row-major order, 8 bits per pixel
|
- Each byte is a shifted palette index (to access the palette, use:
|
||||||
P8_RGB565A, P8_RGB565:
|
palette.colors[<value>+128])
|
||||||
* Number of entries in palette, N (2 bytes)
|
P4:
|
||||||
* Palette with N entries (2N bytes)
|
- 4 bits per entry, each row padded to a full byte
|
||||||
* Pixels in row-major order, 8 bits per pixel (signed indices in
|
- Each entry is a palette index (0...15) */
|
||||||
an uint16_t array starting at <palette>+<256 bytes>)
|
void *data;
|
||||||
P4/P4_RGB565A, P4_RGB565:
|
|
||||||
* Palette with 16 entries (32 bytes total)
|
/* For P8 and P4, palette. The color count does not account for alpha
|
||||||
* Pixels in row-major order, 4 bits per pixel, each row
|
(which is usually the last entry, but not materialized) and instead
|
||||||
byte-padded */
|
indicates how much memory is allocated. */
|
||||||
uint16_t data[];
|
int color_count;
|
||||||
|
uint16_t *palette;
|
||||||
|
|
||||||
} GPACKED(4) image_t;
|
} GPACKED(4) image_t;
|
||||||
|
|
||||||
|
@ -133,15 +167,239 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Image access and information
|
// Image creation and destruction
|
||||||
//---
|
//---
|
||||||
|
|
||||||
/* TODO: Expand */
|
/* image_alloc(): Create a new (uninitialized) image
|
||||||
|
|
||||||
|
This function allocates a new image of the specified dimensions and format.
|
||||||
|
It always allocates a new data array, though a palette from another image
|
||||||
|
can be reused. (If you need to reuse a data array, see image_create() below
|
||||||
|
or use img_create_sub().)
|
||||||
|
|
||||||
|
The first parameters [width] and [height] specify the dimensions of the new
|
||||||
|
image in pixels. The [format] should be one of the IMAGE_* formats, for
|
||||||
|
example IMAGE_RGB565A or IMAGE_P4_RGB565.
|
||||||
|
|
||||||
|
By default, a new palette is allocated for formats with palettes; the new
|
||||||
|
image owns the palette and frees it when freed. This can be overriden by
|
||||||
|
setting the [palette] pointer to the desired palette; in this case, the new
|
||||||
|
image does not own the palette and does not free it when freed.
|
||||||
|
|
||||||
|
Regardless of whether the palette is allocated or specified by hand, for P8
|
||||||
|
the palette size must be indicated. A value of -1 can be specified to use
|
||||||
|
the default (256 colors). For all other formats, set a value of -1.
|
||||||
|
|
||||||
|
For images with alpha, the last parameter [alpha] indicates the palette
|
||||||
|
index or color value that denotes transparent pixels.
|
||||||
|
|
||||||
|
The returned image structure must be freed with image_free() after use.
|
||||||
|
|
||||||
|
@width Width of the new image
|
||||||
|
@height Height of the new image
|
||||||
|
@format Pixel format; one of the IMAGE_* formats defined above
|
||||||
|
@palette If not NULL, specifies the palette instead of allocating it
|
||||||
|
@palette_size For P8, indicates the palette size to use
|
||||||
|
@alpha For formats with alpha, color or index denoting alpha */
|
||||||
|
image_t *image_alloc(int width, int height, int format,
|
||||||
|
void *palette, int palette_size, int alpha);
|
||||||
|
|
||||||
|
/* image_create(): Create a bare image with no data/palette
|
||||||
|
|
||||||
|
This function allocates a new image structure but without data or palette.
|
||||||
|
The [data] and [palette] members are NULL, and [color_count] is either 0 or
|
||||||
|
-1 depending on whether the format normally has a palette.
|
||||||
|
|
||||||
|
This function is useful to create images that reuse externally-provided
|
||||||
|
information. It is intended that the user of this function sets the [data],
|
||||||
|
[stride] and [palette] and [color_count] members themselves. The
|
||||||
|
IMAGE_FLAGS_DATA_ALLOC and the IMAGE_FLAGS_PALETTE_ALLOC flags can be set on
|
||||||
|
the image if the user wishes for the image to free its data and palette when
|
||||||
|
freed.
|
||||||
|
|
||||||
|
For images with alpha, the last parameter [alpha] indicates the palette
|
||||||
|
index or color value that denotes transparent pixels.
|
||||||
|
|
||||||
|
The returned image structure must be freed with image_free() after use. */
|
||||||
|
image_t *image_create(int width, int height, int format, int alpha);
|
||||||
|
|
||||||
|
/* image_create_vram(): Create a reference to gint_vram
|
||||||
|
|
||||||
|
This function creates a new RGB565 image that references gint_vram. Using
|
||||||
|
this image as target for transformation functions can effectively render
|
||||||
|
transformed images to VRAM.
|
||||||
|
|
||||||
|
The value of gint_vram is captured when this function is called, and does
|
||||||
|
not update after dupdate() when triple-buffering is used. The user should
|
||||||
|
account for this option. (Using this function twice then replacing one of
|
||||||
|
the [data] pointers is allowed.)
|
||||||
|
|
||||||
|
The VRAM image ows no data but it does own its own structure so it must
|
||||||
|
still be freed with image_free() after use. */
|
||||||
|
image_t *image_create_vram(void);
|
||||||
|
|
||||||
|
/* image_free(): Free and image and the data it owns
|
||||||
|
|
||||||
|
This function frees the provided image structure and the data that it owns.
|
||||||
|
Images converted by fxconv should not be freed; nonetheless, this functions
|
||||||
|
distinguishes them and should work. Images are not expected to be created on
|
||||||
|
the stack.
|
||||||
|
|
||||||
|
If the image has the IMAGE_FLAGS_DATA_ALLOC flag, the data pointer is also
|
||||||
|
freed. Similarly, the image has the IMAGE_FLAGS_PALETTE_ALLOC flag, the
|
||||||
|
palette is freed. Make sure to not free images when references to them still
|
||||||
|
exist, as this could cause the reference's pointers to become dangling. */
|
||||||
|
void image_free(image_t *img);
|
||||||
|
|
||||||
|
/* image_copy_palette(): Duplicate an image's palette
|
||||||
|
|
||||||
|
This function duplicates the palette and returns a new one allocated with
|
||||||
|
malloc(). If the input image is not in a palette format or has no palette
|
||||||
|
assigned, returns NULL. If the returned pointer is not NULL, free() after
|
||||||
|
use or set the IMAGE_FLAGS_PALETTE_ALLOC flag on the image holding it so
|
||||||
|
that free() is automatically called when the image is freed. */
|
||||||
|
uint16_t *image_copy_palette(image_t const *img);
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Basic image access and information
|
||||||
|
//---
|
||||||
|
|
||||||
|
/* image_valid(): Check if an image is valid
|
||||||
|
An image is considered valid if it has a valid profile, a non-NULL data
|
||||||
|
pointer, and for palette formats a valid palette pointer. */
|
||||||
|
bool image_valid(image_t const *img);
|
||||||
|
|
||||||
|
/* image_get_pixel(): Read a pixel from the data array
|
||||||
|
|
||||||
|
This function reads a pixel from the image's data array at position (x,y).
|
||||||
|
It returns the pixel's value, which is either a full-color value (RGB16) or
|
||||||
|
a possibly-negative palette index (P8/P4). See the description of the [data]
|
||||||
|
field of image_t for more details. The value of the pixel can be decoded
|
||||||
|
into a 16-bit color either manually or by using the image_decode_pixel()
|
||||||
|
function.
|
||||||
|
|
||||||
|
Note that reading large amounts of image data with this function will be
|
||||||
|
slow; if you need reasonable performance, consider iterating on the data
|
||||||
|
array manually. */
|
||||||
int image_get_pixel(image_t const *img, int x, int y);
|
int image_get_pixel(image_t const *img, int x, int y);
|
||||||
|
|
||||||
|
/* image_decode_pixel(): Decode a pixel value
|
||||||
|
|
||||||
|
This function decodes a pixel's value obtained from the data array (for
|
||||||
|
instance with image_get_pixel()). For RGB16 formats this does nothing, but
|
||||||
|
for palette formats this accesses the palette at a suitable position.
|
||||||
|
|
||||||
|
Note that reading large amounts of data with this function will be slow; if
|
||||||
|
you need reasonable performance, consider inlining the format-specific
|
||||||
|
method or iterating on the data array manually. */
|
||||||
int image_decode_pixel(image_t const *img, int pixel);
|
int image_decode_pixel(image_t const *img, int pixel);
|
||||||
|
|
||||||
|
/* image_data_size(): Compute the size of the [data] array
|
||||||
|
This function returns the size of the data array, in bytes. This can be used
|
||||||
|
to duplicate it. Note that for sub-images this is a subsection of another
|
||||||
|
image's data array, and might be much larger than the sub-image. */
|
||||||
|
int image_data_size(image_t const *img);
|
||||||
|
|
||||||
|
/* image_palette_size(): Compute the size of the [palette] array
|
||||||
|
This function returns the size of the palette array, in bytes. This can be
|
||||||
|
used to duplicate the palette. For images without a palette, returns -1. */
|
||||||
|
int image_palette_size(image_t const *img);
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Basic image modifications
|
||||||
|
//---
|
||||||
|
|
||||||
|
/* image_set_pixel(): Set a pixel in the data array
|
||||||
|
|
||||||
|
This function writes a pixel into the image's data array at position (x,y).
|
||||||
|
The pixel value must be of the proper format, as specified in the definition
|
||||||
|
of the [data] field of image_t.
|
||||||
|
|
||||||
|
Formats: RGB16, P8, P4 */
|
||||||
|
void image_set_pixel(image_t const *img, int x, int y, int value);
|
||||||
|
|
||||||
|
/* image_copy(): Copy an image into another one
|
||||||
|
|
||||||
|
This function copies an image into another image. The target must be a valid
|
||||||
|
image with the same format as the source, otherwise this function is a
|
||||||
|
no-op. Unlike transforms, this function does clip, so there are no
|
||||||
|
conditions on the size of the target.
|
||||||
|
|
||||||
|
If [copy_alpha] is true, transparent pixels are copied verbatim, which
|
||||||
|
effectively replaces the top-left corner of [dst] with [src]. If it's false,
|
||||||
|
transparent pixels of [src] are skipped, effectively rendering [src] over
|
||||||
|
the top-left corner of [src].
|
||||||
|
|
||||||
|
The color scheme of src and dst should normally match. In RGB16, if
|
||||||
|
src->alpha and dst->alpha differ, this function adopts a resonable behavior;
|
||||||
|
inputs of value src->alpha are turned into dst->alpha if copy_alpha is true,
|
||||||
|
ignored otherwise; and opaque inputs of value dst->alpha are turned into
|
||||||
|
[dst->alpha ^ 1] to keep the visuals consistent. In P8, no attempt is made
|
||||||
|
to merge the palettes.
|
||||||
|
|
||||||
|
Formats: RGB16, P8 */
|
||||||
|
void image_copy(image_t const *src, image_t *dst, bool copy_alpha);
|
||||||
|
|
||||||
|
/* image_fill(): Fill an image with a single pixel value */
|
||||||
|
void image_fill(image_t *img, int value);
|
||||||
|
|
||||||
|
/* image_clear(): Fill a transparent image with its transparent value */
|
||||||
|
void image_clear(image_t *img);
|
||||||
|
|
||||||
|
/* TODO: Expand by taking from libimg */
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Sub-image extraction
|
||||||
|
//---
|
||||||
|
|
||||||
|
/* image_sub(): Build a reference to a sub-image
|
||||||
|
|
||||||
|
This function is used to create references to sub-images of RGB16 and P8
|
||||||
|
images. The [data] pointer of the sub-image points somewhere within the data
|
||||||
|
array of the source, and its [palette] pointer is identical to the source's.
|
||||||
|
|
||||||
|
The last parameter is a pointer to a preallocated image_t structure (usually
|
||||||
|
on the stack) that gets filled with the data. Doing this instead of
|
||||||
|
allocating a new object with malloc() means that there is no need to
|
||||||
|
image_free() the sub-image, and thus it can be used inline:
|
||||||
|
|
||||||
|
image_t tmp;
|
||||||
|
image_hflip(src, image_sub(dst, x, y, w, h, &tmp));
|
||||||
|
|
||||||
|
A preprocessor macro is used to make the last parameter optional. If it's
|
||||||
|
not specified, a pointer to a static image_t will be returned instead. This
|
||||||
|
is useful in inline calls as shown above, which then simplify to:
|
||||||
|
|
||||||
|
image_hflip(src, image_sub(dst, x, y, w, h));
|
||||||
|
|
||||||
|
However, another call to image_sub() or image_at() will override the
|
||||||
|
sub-image, so you should only use this in such temporary settings.
|
||||||
|
|
||||||
|
If the requested rectangle does not intersect the source, the sub-image will
|
||||||
|
be of dimension 0x0. If the image format does not support sub-images (P4),
|
||||||
|
the sub-image will test invalid with image_valid(). */
|
||||||
|
image_t *image_sub(image_t const *src, int x, int y, int w, int h,
|
||||||
|
image_t *dst);
|
||||||
|
|
||||||
|
/* Make the last parameter optional */
|
||||||
|
#define image_sub1(src, x, y, w, h, dst, ...) image_sub(src, x, y, w, h, dst)
|
||||||
|
#define image_sub(...) image_sub(__VA_ARGS__, NULL)
|
||||||
|
|
||||||
|
/* image_at(): Build a reference to a position within a sub-image */
|
||||||
|
#define image_at(img, x, y) image_sub(img, x, y, -1, -1)
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Geometric image transforms
|
||||||
|
//---
|
||||||
|
|
||||||
|
/* TODO: Geometric transforms */
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Color transforms
|
||||||
|
//---
|
||||||
|
|
||||||
|
/* TODO: Color transforms */
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Image rendering functions
|
// Image rendering functions
|
||||||
//
|
//
|
||||||
|
@ -362,6 +620,55 @@ void gint_image_p4_clearbg_alt(void);
|
||||||
void gint_image_p4_swapcolor(void);
|
void gint_image_p4_swapcolor(void);
|
||||||
void gint_image_p4_dye(void);
|
void gint_image_p4_dye(void);
|
||||||
|
|
||||||
|
//---
|
||||||
|
// Image library utilities
|
||||||
|
//
|
||||||
|
// The following functions and macros are mostly internal utilities; they are
|
||||||
|
// exposed here in case user applications want to extend the set of image
|
||||||
|
// transforms with custom additions.
|
||||||
|
//---
|
||||||
|
|
||||||
|
/* image_target(): Check if an image can be used as target for a transform
|
||||||
|
|
||||||
|
This function is used to quickly check whether a transform from [src] to
|
||||||
|
[dst] is possible. It requires image_valid(src) and image_valid(dst), plus
|
||||||
|
any optional constraints specified as variadic arguments. These constraints
|
||||||
|
can be:
|
||||||
|
|
||||||
|
* NOT_P4: fails if [dst] is P4.
|
||||||
|
* DATA_RW: fails if [dst] is not data-writable.
|
||||||
|
* PALETTE_RW: fails if [dst] is not palette-writable.
|
||||||
|
* SAME_SIZE: fails if [dst] is not at least as large as [src].
|
||||||
|
|
||||||
|
For example, in image_hflip(), we write:
|
||||||
|
if(!image_target(src, dst, NOT_P4, DATA_RW, SAME_SIZE)) return; */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
IMAGE_TARGET_NONE,
|
||||||
|
IMAGE_TARGET_NOT_P4,
|
||||||
|
IMAGE_TARGET_DATA_RW,
|
||||||
|
IMAGE_TARGET_PALETTE_RW,
|
||||||
|
IMAGE_TARGET_SAME_SIZE,
|
||||||
|
IMAGE_TARGET_SAME_FORMAT,
|
||||||
|
IMAGE_TARGET_SAME_DEPTH,
|
||||||
|
};
|
||||||
|
bool image_target(image_t const *src, image_t *dst, ...);
|
||||||
|
|
||||||
|
#define image_target(src, dst, ...) \
|
||||||
|
image_target(src, dst, image_target_arg1(__VA_ARGS__ __VA_OPT__(,) NONE))
|
||||||
|
#define image_target_arg1(c, ...) \
|
||||||
|
IMAGE_TARGET_ ## c __VA_OPT__(, image_target_arg2(__VA_ARGS__))
|
||||||
|
#define image_target_arg2(c, ...) \
|
||||||
|
IMAGE_TARGET_ ## c __VA_OPT__(, image_target_arg3(__VA_ARGS__))
|
||||||
|
#define image_target_arg3(c, ...) \
|
||||||
|
IMAGE_TARGET_ ## c __VA_OPT__(, image_target_arg4(__VA_ARGS__))
|
||||||
|
#define image_target_arg4(c, ...) \
|
||||||
|
IMAGE_TARGET_ ## c __VA_OPT__(, image_target_arg5(__VA_ARGS__))
|
||||||
|
#define image_target_arg5(c, ...) \
|
||||||
|
IMAGE_TARGET_ ## c __VA_OPT__(, image_target_arg6(__VA_ARGS__))
|
||||||
|
#define image_target_arg6(c, ...) \
|
||||||
|
IMAGE_TARGET_ ## c __VA_OPT__(, image_target_too_many_args(__VA_ARGS__))
|
||||||
|
|
||||||
#endif /* FXCG50 */
|
#endif /* FXCG50 */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
45
src/image/image_alloc.c
Normal file
45
src/image/image_alloc.c
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
#include <gint/image.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <gint/defs/util.h>
|
||||||
|
|
||||||
|
image_t *image_alloc(int width, int height, int format,
|
||||||
|
void *palette, int palette_size, int alpha)
|
||||||
|
{
|
||||||
|
image_t *img = image_create(width, height, format, alpha);
|
||||||
|
if(!img)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(IMAGE_IS_RGB16(format)) {
|
||||||
|
img->stride = ((width + 1) >> 1) * 4;
|
||||||
|
palette_size = -1;
|
||||||
|
}
|
||||||
|
else if(IMAGE_IS_P8(format)) {
|
||||||
|
img->stride = width;
|
||||||
|
palette_size = max(0, min(256, palette_size));
|
||||||
|
}
|
||||||
|
else if(IMAGE_IS_P4(format)) {
|
||||||
|
img->stride = ((width + 1) >> 1);
|
||||||
|
palette_size = 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *data = malloc(height * img->stride);
|
||||||
|
if(!data) {
|
||||||
|
image_free(img);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
img->data = data;
|
||||||
|
img->flags |= IMAGE_FLAGS_DATA_ALLOC;
|
||||||
|
|
||||||
|
if(!palette && palette_size > 0) {
|
||||||
|
palette = malloc(palette_size * 2);
|
||||||
|
if(!palette) {
|
||||||
|
image_free(img);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img->palette = palette;
|
||||||
|
img->color_count = palette_size;
|
||||||
|
return img;
|
||||||
|
}
|
9
src/image/image_clear.c
Normal file
9
src/image/image_clear.c
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#include <gint/image.h>
|
||||||
|
|
||||||
|
void image_clear(image_t *img)
|
||||||
|
{
|
||||||
|
if(!IMAGE_IS_ALPHA(img->format))
|
||||||
|
return;
|
||||||
|
|
||||||
|
image_fill(img, img->alpha);
|
||||||
|
}
|
49
src/image/image_copy.c
Normal file
49
src/image/image_copy.c
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
#include <gint/image.h>
|
||||||
|
#include <gint/defs/util.h>
|
||||||
|
|
||||||
|
void image_copy(image_t const *src, image_t *dst, bool copy_alpha)
|
||||||
|
{
|
||||||
|
if(!image_target(src, dst, NOT_P4, DATA_RW, SAME_DEPTH))
|
||||||
|
return;
|
||||||
|
if(!IMAGE_IS_ALPHA(src->format))
|
||||||
|
copy_alpha = true;
|
||||||
|
|
||||||
|
/* Clip the input to match the size of the output */
|
||||||
|
int w = min(src->width, dst->width);
|
||||||
|
int h = min(src->height, dst->height);
|
||||||
|
if(w <= 0 || h <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
void *src_px = src->data;
|
||||||
|
void *dst_px = dst->data;
|
||||||
|
|
||||||
|
if(IMAGE_IS_RGB16(src->format)) {
|
||||||
|
int src_alpha = copy_alpha ? -1 : src->alpha;
|
||||||
|
int dst_alpha = IMAGE_IS_ALPHA(dst->format) ? -1 : dst->alpha;
|
||||||
|
|
||||||
|
do {
|
||||||
|
for(int x = 0; x < w; x++) {
|
||||||
|
int px = ((uint16_t *)src_px)[x];
|
||||||
|
if(px != src_alpha) {
|
||||||
|
px ^= (px == dst_alpha);
|
||||||
|
((uint16_t *)dst_px)[x] = px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
src_px += src->stride;
|
||||||
|
dst_px += dst->stride;
|
||||||
|
} while(--h > 0);
|
||||||
|
}
|
||||||
|
else if(IMAGE_IS_P8(src->format)) {
|
||||||
|
int src_alpha = copy_alpha ? 256 : src->alpha;
|
||||||
|
|
||||||
|
do {
|
||||||
|
for(int x = 0; x < w; x++) {
|
||||||
|
int px = ((int8_t *)src_px)[x];
|
||||||
|
if(px != src_alpha)
|
||||||
|
((int8_t *)dst_px)[x] = px;
|
||||||
|
}
|
||||||
|
src_px += src->stride;
|
||||||
|
dst_px += dst->stride;
|
||||||
|
} while(--h > 0);
|
||||||
|
}
|
||||||
|
}
|
16
src/image/image_copy_palette.c
Normal file
16
src/image/image_copy_palette.c
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#include <gint/image.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
uint16_t *image_copy_palette(image_t const *img)
|
||||||
|
{
|
||||||
|
int size = image_palette_size(img);
|
||||||
|
if(size < 0 || !img->palette)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
void *palette = malloc(size);
|
||||||
|
if(!palette)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return memcpy(palette, img->palette, size);
|
||||||
|
}
|
28
src/image/image_create.c
Normal file
28
src/image/image_create.c
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
#include <gint/image.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
image_t *image_create(int width, int height, int format, int alpha)
|
||||||
|
{
|
||||||
|
if(!IMAGE_IS_RGB16(format) && !IMAGE_IS_P8(format) && !IMAGE_IS_P4(format))
|
||||||
|
return NULL;
|
||||||
|
if(width <= 0 || width > 0xffff || height <= 0 || height > 0xffff)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
image_t *img = malloc(sizeof *img);
|
||||||
|
if(!img)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
img->format = format;
|
||||||
|
img->flags = 0;
|
||||||
|
img->alpha = alpha;
|
||||||
|
|
||||||
|
img->width = width;
|
||||||
|
img->height = height;
|
||||||
|
|
||||||
|
img->stride = 0;
|
||||||
|
img->data = NULL;
|
||||||
|
img->color_count = IMAGE_IS_INDEXED(format) ? 0 : -1;
|
||||||
|
img->palette = NULL;
|
||||||
|
|
||||||
|
return img;
|
||||||
|
}
|
13
src/image/image_create_vram.c
Normal file
13
src/image/image_create_vram.c
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include <gint/image.h>
|
||||||
|
#include <gint/display.h>
|
||||||
|
|
||||||
|
image_t *image_create_vram(void)
|
||||||
|
{
|
||||||
|
image_t *img = image_create(DWIDTH, DHEIGHT, IMAGE_RGB565, 0);
|
||||||
|
if(!img)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
img->stride = 2 * DWIDTH;
|
||||||
|
img->data = gint_vram;
|
||||||
|
return img;
|
||||||
|
}
|
6
src/image/image_data_size.c
Normal file
6
src/image/image_data_size.c
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#include <gint/image.h>
|
||||||
|
|
||||||
|
int image_data_size(image_t const *img)
|
||||||
|
{
|
||||||
|
return img->stride * img->height;
|
||||||
|
}
|
12
src/image/image_decode_pixel.c
Normal file
12
src/image/image_decode_pixel.c
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#include <gint/image.h>
|
||||||
|
|
||||||
|
int image_decode_pixel(image_t const *img, int pixel)
|
||||||
|
{
|
||||||
|
if(IMAGE_IS_RGB16(img->format))
|
||||||
|
return pixel;
|
||||||
|
else if(IMAGE_IS_P8(img->format))
|
||||||
|
return img->palette[pixel+128];
|
||||||
|
else if(IMAGE_IS_P4(img->format))
|
||||||
|
return img->palette[pixel];
|
||||||
|
return -1;
|
||||||
|
}
|
26
src/image/image_fill.c
Normal file
26
src/image/image_fill.c
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include <gint/image.h>
|
||||||
|
|
||||||
|
void image_fill(image_t *img, int value)
|
||||||
|
{
|
||||||
|
if(!image_target(img, img, NOT_P4, DATA_RW))
|
||||||
|
return;
|
||||||
|
|
||||||
|
void *img_px = img->data;
|
||||||
|
|
||||||
|
if(IMAGE_IS_RGB16(img->format)) {
|
||||||
|
for(int y = 0; y < img->height; y++) {
|
||||||
|
for(int x = 0; x < img->width; x++) {
|
||||||
|
((uint16_t *)img_px)[x] = value;
|
||||||
|
}
|
||||||
|
img_px += img->stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(IMAGE_IS_P8(img->format)) {
|
||||||
|
for(int y = 0; y < img->height; y++) {
|
||||||
|
for(int x = 0; x < img->width; x++) {
|
||||||
|
((int8_t *)img_px)[x] = value;
|
||||||
|
}
|
||||||
|
img_px += img->stride;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
src/image/image_free.c
Normal file
16
src/image/image_free.c
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#include <gint/image.h>
|
||||||
|
#include <gint/mmu.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void image_free(image_t *img)
|
||||||
|
{
|
||||||
|
if(!img || mmu_is_rom(img))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(img->flags & IMAGE_FLAGS_DATA_ALLOC)
|
||||||
|
free(img->data);
|
||||||
|
if(img->flags & IMAGE_FLAGS_PALETTE_ALLOC)
|
||||||
|
free(img->palette);
|
||||||
|
|
||||||
|
free(img);
|
||||||
|
}
|
25
src/image/image_get_pixel.c
Normal file
25
src/image/image_get_pixel.c
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#include <gint/image.h>
|
||||||
|
|
||||||
|
int image_get_pixel(image_t const *img, int x, int y)
|
||||||
|
{
|
||||||
|
if((unsigned)x >= img->width || (unsigned)y >= img->height)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
void *data = img->data + y * img->stride;
|
||||||
|
uint8_t *data_u8 = data;
|
||||||
|
uint16_t *data_u16 = data;
|
||||||
|
|
||||||
|
if(IMAGE_IS_RGB16(img->format)) {
|
||||||
|
return data_u16[x];
|
||||||
|
}
|
||||||
|
else if(IMAGE_IS_P8(img->format)) {
|
||||||
|
return data_u8[x];
|
||||||
|
}
|
||||||
|
else if(IMAGE_IS_P4(img->format)) {
|
||||||
|
if(x & 1)
|
||||||
|
return data_u8[x >> 1] & 0x0f;
|
||||||
|
else
|
||||||
|
return data_u8[x >> 1] >> 4;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
7
src/image/image_palette_size.c
Normal file
7
src/image/image_palette_size.c
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#include <gint/image.h>
|
||||||
|
|
||||||
|
int image_palette_size(image_t const *img)
|
||||||
|
{
|
||||||
|
return (img->color_count >= 0) ? img->color_count* 2 : -1;
|
||||||
|
}
|
||||||
|
|
26
src/image/image_set_pixel.c
Normal file
26
src/image/image_set_pixel.c
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include <gint/image.h>
|
||||||
|
|
||||||
|
void image_set_pixel(image_t const *img, int x, int y, int value)
|
||||||
|
{
|
||||||
|
if(!image_valid(img))
|
||||||
|
return;
|
||||||
|
if((unsigned)x >= img->width || (unsigned)y >= img->height)
|
||||||
|
return;
|
||||||
|
|
||||||
|
void *data = img->data + y * img->stride;
|
||||||
|
uint8_t *data_u8 = data;
|
||||||
|
uint16_t *data_u16 = data;
|
||||||
|
|
||||||
|
if(IMAGE_IS_RGB16(img->format)) {
|
||||||
|
data_u16[x] = value;
|
||||||
|
}
|
||||||
|
else if(IMAGE_IS_P8(img->format)) {
|
||||||
|
data_u8[x] = value;
|
||||||
|
}
|
||||||
|
else if(IMAGE_IS_P4(img->format)) {
|
||||||
|
if(x & 1)
|
||||||
|
data_u8[x >> 1] = (data_u8[x >> 1] & 0xf0) | (value & 0x0f);
|
||||||
|
else
|
||||||
|
data_u8[x >> 1] = (data_u8[x >> 1] & 0x0f) | (value << 4);
|
||||||
|
}
|
||||||
|
}
|
40
src/image/image_sub.c
Normal file
40
src/image/image_sub.c
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#include <gint/image.h>
|
||||||
|
#include <string.h>
|
||||||
|
#undef image_sub
|
||||||
|
|
||||||
|
static image_t image_sub_default;
|
||||||
|
|
||||||
|
image_t *image_sub(image_t const *src, int left, int top, int w, int h,
|
||||||
|
image_t *dst)
|
||||||
|
{
|
||||||
|
if(!dst)
|
||||||
|
dst = &image_sub_default;
|
||||||
|
if(w < 0)
|
||||||
|
w = src->width - left;
|
||||||
|
if(h < 0)
|
||||||
|
h = src->height - top;
|
||||||
|
|
||||||
|
struct gint_image_box box = { 0, 0, w, h, left, top };
|
||||||
|
if(!image_valid(src) || IMAGE_IS_P4(src->format) ||
|
||||||
|
!gint_image_clip_input(src, &box, w, h)) {
|
||||||
|
memset(dst, 0, sizeof *dst);
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
int const ro_flags = IMAGE_FLAGS_DATA_RO | IMAGE_FLAGS_PALETTE_RO;
|
||||||
|
dst->format = src->format;
|
||||||
|
dst->flags = src->flags & ro_flags;
|
||||||
|
dst->alpha = src->alpha;
|
||||||
|
dst->stride = src->stride;
|
||||||
|
dst->width = box.w;
|
||||||
|
dst->height = box.h;
|
||||||
|
|
||||||
|
if(IMAGE_IS_RGB16(src->format))
|
||||||
|
dst->data = src->data + box.top * src->stride + 2 * box.left;
|
||||||
|
else if(IMAGE_IS_P8(src->format))
|
||||||
|
dst->data = src->data + box.top * src->stride + box.left;
|
||||||
|
|
||||||
|
dst->color_count = src->color_count;
|
||||||
|
dst->palette = src->palette;
|
||||||
|
return dst;
|
||||||
|
}
|
39
src/image/image_target.c
Normal file
39
src/image/image_target.c
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#include <gint/image.h>
|
||||||
|
#undef image_target
|
||||||
|
|
||||||
|
bool image_target(image_t const *src, image_t *dst, ...)
|
||||||
|
{
|
||||||
|
if(!image_valid(src) || !image_valid(dst))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, dst);
|
||||||
|
|
||||||
|
int req = -1;
|
||||||
|
while((req = va_arg(args, int)) != IMAGE_TARGET_NONE) {
|
||||||
|
if(req == IMAGE_TARGET_NOT_P4 && IMAGE_IS_P4(dst->format))
|
||||||
|
return false;
|
||||||
|
if(req == IMAGE_TARGET_DATA_RW && (dst->flags & IMAGE_FLAGS_DATA_RO))
|
||||||
|
return false;
|
||||||
|
if(req == IMAGE_TARGET_PALETTE_RW && (dst->flags &
|
||||||
|
IMAGE_FLAGS_PALETTE_RO))
|
||||||
|
return false;
|
||||||
|
if(req == IMAGE_TARGET_SAME_SIZE &&
|
||||||
|
(dst->width < src->width || dst->height < src->height))
|
||||||
|
return false;
|
||||||
|
if(req == IMAGE_TARGET_SAME_FORMAT && src->format != dst->format)
|
||||||
|
return false;
|
||||||
|
if(req == IMAGE_TARGET_SAME_DEPTH) {
|
||||||
|
if(IMAGE_IS_RGB16(src->format) && IMAGE_IS_RGB16(dst->format))
|
||||||
|
continue;
|
||||||
|
if(IMAGE_IS_P8(src->format) && IMAGE_IS_P8(dst->format))
|
||||||
|
continue;
|
||||||
|
if(IMAGE_IS_P4(src->format) && IMAGE_IS_P4(dst->format))
|
||||||
|
continue;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
return true;
|
||||||
|
}
|
17
src/image/image_valid.c
Normal file
17
src/image/image_valid.c
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#include <gint/image.h>
|
||||||
|
|
||||||
|
bool image_valid(image_t const *img)
|
||||||
|
{
|
||||||
|
if(!img)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(IMAGE_IS_RGB16(img->format)) {
|
||||||
|
return (img->data != NULL);
|
||||||
|
}
|
||||||
|
if(IMAGE_IS_P8(img->format) || IMAGE_IS_P4(img->format)) {
|
||||||
|
return (img->data != NULL) && (img->palette != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Invalid format */
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -4,11 +4,10 @@
|
||||||
void dsubimage(int x, int y, image_t const *img, int left, int top,
|
void dsubimage(int x, int y, image_t const *img, int left, int top,
|
||||||
int w, int h, int flags)
|
int w, int h, int flags)
|
||||||
{
|
{
|
||||||
int p = img->profile;
|
if(IMAGE_IS_RGB16(img->format))
|
||||||
if(p == IMAGE_RGB565 || p == IMAGE_RGB565A)
|
|
||||||
return dsubimage_rgb16(x, y, img, left, top, w, h, flags);
|
return dsubimage_rgb16(x, y, img, left, top, w, h, flags);
|
||||||
if(p == IMAGE_P8_RGB565 || p == IMAGE_P8_RGB565A)
|
else if(IMAGE_IS_P8(img->format))
|
||||||
return dsubimage_p8(x, y, img, left, top, w, h, flags);
|
return dsubimage_p8(x, y, img, left, top, w, h, flags);
|
||||||
if(p == IMAGE_P4_RGB565 || p == IMAGE_P4_RGB565A)
|
else if(IMAGE_IS_P4(img->format))
|
||||||
return dsubimage_p4(x, y, img, left, top, w, h, flags);
|
return dsubimage_p4(x, y, img, left, top, w, h, flags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,28 +47,28 @@ bool gint_image_mkcmd(struct gint_image_box *box, image_t const *img,
|
||||||
|
|
||||||
cmd->effect = (effects & (IMAGE_VFLIP | IMAGE_HFLIP)) >> 8;
|
cmd->effect = (effects & (IMAGE_VFLIP | IMAGE_HFLIP)) >> 8;
|
||||||
cmd->columns = box->w;
|
cmd->columns = box->w;
|
||||||
cmd->input_stride = img->width;
|
cmd->input_stride = img->stride;
|
||||||
cmd->x = box->x;
|
cmd->x = box->x;
|
||||||
cmd->edge_1 = -1;
|
cmd->edge_1 = -1;
|
||||||
cmd->edge_2 = -1;
|
cmd->edge_2 = -1;
|
||||||
|
|
||||||
int p = img->profile;
|
int f = img->format;
|
||||||
int input_row = (effects & IMAGE_VFLIP) ? box->top+box->h-1 : box->top;
|
int input_row = (effects & IMAGE_VFLIP) ? box->top+box->h-1 : box->top;
|
||||||
|
|
||||||
if(p == IMAGE_RGB565 || p == IMAGE_RGB565A) {
|
if(IMAGE_IS_RGB16(f)) {
|
||||||
cmd->input_stride += (cmd->input_stride & 1);
|
cmd->input_stride += (cmd->input_stride & 1);
|
||||||
cmd->input = (void *)img->data +
|
cmd->input = (void *)img->data +
|
||||||
(input_row * cmd->input_stride + box->left) * 2;
|
input_row * img->stride + (box->left * 2);
|
||||||
}
|
}
|
||||||
else if(p == IMAGE_P8_RGB565 || p == IMAGE_P8_RGB565A) {
|
else if(IMAGE_IS_P8(f)) {
|
||||||
cmd->input = (void *)img->data + img->data[0] * 2 + 2 +
|
cmd->input = (void *)img->data +
|
||||||
(input_row * img->width + box->left);
|
(input_row * img->stride) + box->left;
|
||||||
cmd->palette = (void *)img->data + 258;
|
cmd->palette = (void *)img->palette + 256;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cmd->input = (void *)img->data + 32 +
|
cmd->input = (void *)img->data +
|
||||||
input_row * ((img->width + 1) >> 1) + (box->left >> 1);
|
input_row * img->stride + (box->left >> 1);
|
||||||
cmd->palette = img->data;
|
cmd->palette = (void *)img->palette;
|
||||||
/* By default, use edge_1 to indicate (box->left & 1), so that
|
/* By default, use edge_1 to indicate (box->left & 1), so that
|
||||||
functions that don't use edge_1 can still work properly */
|
functions that don't use edge_1 can still work properly */
|
||||||
if(!left_edge)
|
if(!left_edge)
|
||||||
|
|
|
@ -54,7 +54,7 @@ _gint_image_p4_loop:
|
||||||
add r6, r6
|
add r6, r6
|
||||||
|
|
||||||
mov.b @r8+, r1 /* cmd.lines */
|
mov.b @r8+, r1 /* cmd.lines */
|
||||||
shlr r4
|
nop
|
||||||
|
|
||||||
mov.l r10, @-r15
|
mov.l r10, @-r15
|
||||||
extu.b r1, r1
|
extu.b r1, r1
|
||||||
|
@ -62,9 +62,6 @@ _gint_image_p4_loop:
|
||||||
mov.b @r8+, r10 /* cmd.edge_1 */
|
mov.b @r8+, r10 /* cmd.edge_1 */
|
||||||
nop
|
nop
|
||||||
|
|
||||||
mov #0, r9
|
|
||||||
addc r9, r4 /* r4 = (img.width + 1) >> 1 */
|
|
||||||
|
|
||||||
mov.l @r8+, r9
|
mov.l @r8+, r9
|
||||||
shlr r0 /* T bit is now VFLIP */
|
shlr r0 /* T bit is now VFLIP */
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ void dimage_p4(int x, int y, image_t const *img, int eff)
|
||||||
void dsubimage_p4(int x, int y, image_t const *img,
|
void dsubimage_p4(int x, int y, image_t const *img,
|
||||||
int left, int top, int w, int h, int eff)
|
int left, int top, int w, int h, int eff)
|
||||||
{
|
{
|
||||||
if(img->profile == IMAGE_P4_RGB565A)
|
if(img->format == IMAGE_P4_RGB565A)
|
||||||
return dsubimage_p4_clearbg(x, y, img, left, top, w, h, eff,
|
return dsubimage_p4_clearbg(x, y, img, left, top, w, h, eff,
|
||||||
img->alpha);
|
img->alpha);
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ void dimage_p8(int x, int y, image_t const *img, int eff)
|
||||||
void dsubimage_p8(int x, int y, image_t const *img,
|
void dsubimage_p8(int x, int y, image_t const *img,
|
||||||
int left, int top, int w, int h, int eff)
|
int left, int top, int w, int h, int eff)
|
||||||
{
|
{
|
||||||
if(img->profile == IMAGE_P8_RGB565A)
|
if(img->format == IMAGE_P8_RGB565A)
|
||||||
return dsubimage_p8_clearbg(x, y, img, left, top, w, h, eff,
|
return dsubimage_p8_clearbg(x, y, img, left, top, w, h, eff,
|
||||||
img->alpha);
|
img->alpha);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.global _gint_image_rgb16_loop
|
.global _gint_image_rgb16_loop
|
||||||
|
|
||||||
/* gint's image renderer: 16-bit RGB entry piont
|
/* gint's image renderer: 16-bit RGB entry point
|
||||||
|
|
||||||
These formats are the simplest of the bunch. RGB565 can use longword access
|
These formats are the simplest of the bunch. RGB565 can use longword access
|
||||||
in cases when alignment is favorable and no geometric effect is applied. In
|
in cases when alignment is favorable and no geometric effect is applied. In
|
||||||
|
@ -52,10 +52,10 @@ _gint_image_rgb16_loop:
|
||||||
nop
|
nop
|
||||||
|
|
||||||
mov.l @r8+, r3 /* cmd.input */
|
mov.l @r8+, r3 /* cmd.input */
|
||||||
nop
|
add #4, r8 /* cmd.palette (don't care) */
|
||||||
|
|
||||||
bf.s _NO_VFLIP
|
bf.s _NO_VFLIP
|
||||||
add #4, r8 /* cmd.palette (don't care) */
|
shlr r4
|
||||||
|
|
||||||
_VFLIP:
|
_VFLIP:
|
||||||
neg r4, r4
|
neg r4, r4
|
||||||
|
|
|
@ -9,7 +9,7 @@ void dimage_rgb16(int x, int y, image_t const *img, int eff)
|
||||||
void dsubimage_rgb16(int x, int y, image_t const *img,
|
void dsubimage_rgb16(int x, int y, image_t const *img,
|
||||||
int left, int top, int w, int h, int eff)
|
int left, int top, int w, int h, int eff)
|
||||||
{
|
{
|
||||||
if(img->profile == IMAGE_RGB565A)
|
if(img->format == IMAGE_RGB565A)
|
||||||
return dsubimage_rgb16_clearbg(x, y, img, left, top, w, h, eff,
|
return dsubimage_rgb16_clearbg(x, y, img, left, top, w, h, eff,
|
||||||
img->alpha);
|
img->alpha);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue