mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-28 04:23:36 +01:00
image: flips, including in-place
This commit is contained in:
parent
9468a8d725
commit
818f950fff
9 changed files with 165 additions and 24 deletions
|
@ -159,6 +159,7 @@ set(SOURCES_CG
|
|||
src/r61524/r61524.c
|
||||
# Image library
|
||||
src/image/image_alloc.c
|
||||
src/image/image_alloc_palette.c
|
||||
src/image/image_alpha.c
|
||||
src/image/image_clear.c
|
||||
src/image/image_copy.c
|
||||
|
@ -171,11 +172,15 @@ set(SOURCES_CG
|
|||
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_hflip.c
|
||||
src/image/image_hflip_alloc.c
|
||||
src/image/image_set_palette.c
|
||||
src/image/image_set_pixel.c
|
||||
src/image/image_sub.c
|
||||
src/image/image_target.c
|
||||
src/image/image_valid.c
|
||||
src/image/image_vflip.c
|
||||
src/image/image_vflip_alloc.c
|
||||
# Rendering
|
||||
src/render-cg/dclear.c
|
||||
src/render-cg/dpixel.c
|
||||
|
|
|
@ -314,11 +314,6 @@ int image_decode_pixel(image_t const *img, int pixel);
|
|||
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
|
||||
//---
|
||||
|
@ -457,6 +452,10 @@ image_t *image_sub(image_t const *src, int x, int y, int w, int h,
|
|||
void image_hflip(image_t const *src, image_t *dst);
|
||||
image_t *image_hflip_alloc(image_t const *src);
|
||||
|
||||
/* image_vflip(): Flip vertically (supports in-place) */
|
||||
void image_vflip(image_t const *src, image_t *dst);
|
||||
image_t *image_vflip_alloc(image_t const *src);
|
||||
|
||||
/* TODO: Geometric transforms */
|
||||
|
||||
//---
|
||||
|
|
|
@ -1,30 +1,31 @@
|
|||
#include <gint/image.h>
|
||||
#include <gint/defs/util.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
bool image_alloc_palette(image_t *img, int size)
|
||||
{
|
||||
if(!img || !IMAGE_IS_INDEXED(img))
|
||||
return;
|
||||
if(img->flags & IMAGE_FLAGS_PALETTE_OWN)
|
||||
if(!img || !IMAGE_IS_INDEXED(img->format))
|
||||
return false;
|
||||
if(img->flags & IMAGE_FLAGS_PALETTE_ALLOC)
|
||||
free(img->palette);
|
||||
|
||||
if(IMAGE_IS_P8(img)) {
|
||||
if(IMAGE_IS_P8(img->format)) {
|
||||
size = (size <= 0) ? 256 : min(size, 256);
|
||||
}
|
||||
if(IMAGE_IS_P4(img)) {
|
||||
if(IMAGE_IS_P4(img->format)) {
|
||||
size = 16;
|
||||
}
|
||||
|
||||
img->palette = calloc(size, 2);
|
||||
img->color_count = 0;
|
||||
img->flags &= ~IMAGE_FLAGS_PALETTE_OWN;
|
||||
img->flags &= ~IMAGE_FLAGS_PALETTE_ALLOC;
|
||||
|
||||
if(!img->palette)
|
||||
return false;
|
||||
|
||||
memset(img->palette, 0, 2*size);
|
||||
img->color_count = size;
|
||||
img->flags |= IMAGE_FLAGS_PALETTE_OWN;
|
||||
img->flags |= IMAGE_FLAGS_PALETTE_ALLOC;
|
||||
return true;
|
||||
}
|
||||
|
|
47
src/image/image_hflip.c
Normal file
47
src/image/image_hflip.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
#include <gint/image.h>
|
||||
|
||||
void image_hflip(image_t const *src, image_t *dst)
|
||||
{
|
||||
if(!image_target(src, dst, DATA_RW, SAME_DEPTH, SAME_SIZE))
|
||||
return;
|
||||
|
||||
void *src_px = src->data;
|
||||
void *dst_px = dst->data;
|
||||
int src_alpha = image_alpha(src->format);
|
||||
int dst_alpha = image_alpha(dst->format);
|
||||
int h = src->height;
|
||||
|
||||
if(IMAGE_IS_RGB16(src->format)) {
|
||||
while(h-- > 0) {
|
||||
for(int x1 = 0; x1 < (src->width + 1) >> 1; x1++) {
|
||||
int x2 = src->width - 1 - x1;
|
||||
int px1 = ((uint16_t *)src_px)[x1];
|
||||
int px2 = ((uint16_t *)src_px)[x2];
|
||||
|
||||
if(px1 != src_alpha)
|
||||
((uint16_t *)dst_px)[x2] = px1 - (px1 == dst_alpha);
|
||||
if(px2 != src_alpha)
|
||||
((uint16_t *)dst_px)[x1] = px2 - (px2 == dst_alpha);
|
||||
}
|
||||
src_px += src->stride;
|
||||
dst_px += dst->stride;
|
||||
}
|
||||
}
|
||||
else if(IMAGE_IS_P8(src->format)) {
|
||||
while(h-- > 0) {
|
||||
for(int x1 = 0; x1 < (src->width + 1) >> 1; x1++) {
|
||||
int x2 = src->width - 1 - x1;
|
||||
|
||||
int px1 = ((int8_t *)src_px)[x1];
|
||||
int px2 = ((int8_t *)src_px)[x2];
|
||||
|
||||
if(px1 != src_alpha)
|
||||
((int8_t *)dst_px)[x2] = px1;
|
||||
if(px2 != src_alpha)
|
||||
((int8_t *)dst_px)[x1] = px2;
|
||||
}
|
||||
src_px += src->stride;
|
||||
dst_px += dst->stride;
|
||||
}
|
||||
}
|
||||
}
|
17
src/image/image_hflip_alloc.c
Normal file
17
src/image/image_hflip_alloc.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include <gint/image.h>
|
||||
|
||||
image_t *image_hflip_alloc(image_t const *src)
|
||||
{
|
||||
if(!image_valid(src))
|
||||
return NULL;
|
||||
|
||||
image_t *dst = image_alloc(src->width, src->height, src->format);
|
||||
if(!dst || !image_copy_palette(src, dst, -1)) {
|
||||
image_free(dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
image_clear(dst);
|
||||
image_hflip(src, dst);
|
||||
return dst;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
#include <gint/image.h>
|
||||
|
||||
int image_palette_size(image_t const *img)
|
||||
{
|
||||
return (img->color_count >= 0) ? img->color_count* 2 : -1;
|
||||
}
|
||||
|
|
@ -3,16 +3,16 @@
|
|||
|
||||
void image_set_palette(image_t *img, uint16_t *palette, int size, bool owns)
|
||||
{
|
||||
if(!img || !IMAGE_IS_INDEXED(img))
|
||||
if(!img || !IMAGE_IS_INDEXED(img->format))
|
||||
return;
|
||||
if(img->flags & IMAGE_FLAGS_PALETTE_OWN)
|
||||
if(img->flags & IMAGE_FLAGS_PALETTE_ALLOC)
|
||||
free(img->palette);
|
||||
|
||||
img->palette = palette;
|
||||
img->color_count = size;
|
||||
|
||||
if(owns)
|
||||
img->flags |= IMAGE_FLAGS_PALETTE_OWN;
|
||||
img->flags |= IMAGE_FLAGS_PALETTE_ALLOC;
|
||||
else
|
||||
img->flags &= ~IMAGE_FLAGS_PALETTE_OWN;
|
||||
img->flags &= ~IMAGE_FLAGS_PALETTE_ALLOC;
|
||||
}
|
||||
|
|
62
src/image/image_vflip.c
Normal file
62
src/image/image_vflip.c
Normal file
|
@ -0,0 +1,62 @@
|
|||
#include <gint/image.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void copy_row_rgb16(uint16_t *src, uint16_t *dst, int src_alpha,
|
||||
int dst_alpha, int width)
|
||||
{
|
||||
for(int x = 0; x < width; x++) {
|
||||
int px = src[x];
|
||||
if(px != src_alpha)
|
||||
dst[x] = px - (px == dst_alpha);
|
||||
}
|
||||
}
|
||||
|
||||
static void copy_row_p8(int8_t *src, int8_t *dst, int src_alpha, int width)
|
||||
{
|
||||
for(int x = 0; x < width; x++) {
|
||||
int px = src[x];
|
||||
if(px != src_alpha)
|
||||
dst[x] = px;
|
||||
}
|
||||
}
|
||||
|
||||
void image_vflip(image_t const *src, image_t *dst)
|
||||
{
|
||||
if(!image_target(src, dst, DATA_RW, SAME_DEPTH, SAME_SIZE))
|
||||
return;
|
||||
|
||||
int h = src->height;
|
||||
void *src_top = src->data;
|
||||
void *src_bot = src->data + (h - 1) * src->stride;
|
||||
void *dst_top = dst->data;
|
||||
void *dst_bot = dst->data + (h - 1) * dst->stride;
|
||||
|
||||
int src_alpha = image_alpha(src->format);
|
||||
int dst_alpha = image_alpha(dst->format);
|
||||
|
||||
int row_length = src->stride;
|
||||
void *row = malloc(row_length);
|
||||
if(!row)
|
||||
return;
|
||||
|
||||
for(int y = 0; y < (h + 1) >> 1; y++) {
|
||||
memcpy(row, src_top, row_length);
|
||||
|
||||
if(IMAGE_IS_RGB16(src->format)) {
|
||||
copy_row_rgb16(src_bot, dst_top, src_alpha, dst_alpha, src->width);
|
||||
copy_row_rgb16(row, dst_bot, src_alpha, dst_alpha, src->width);
|
||||
}
|
||||
else {
|
||||
copy_row_p8(src_bot, dst_top, src_alpha, src->width);
|
||||
copy_row_p8(row, dst_bot, src_alpha, src->width);
|
||||
}
|
||||
|
||||
src_top += src->stride;
|
||||
src_bot -= src->stride;
|
||||
dst_top += dst->stride;
|
||||
dst_bot -= dst->stride;
|
||||
}
|
||||
|
||||
free(row);
|
||||
}
|
17
src/image/image_vflip_alloc.c
Normal file
17
src/image/image_vflip_alloc.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include <gint/image.h>
|
||||
|
||||
image_t *image_vflip_alloc(image_t const *src)
|
||||
{
|
||||
if(!image_valid(src))
|
||||
return NULL;
|
||||
|
||||
image_t *dst = image_alloc(src->width, src->height, src->format);
|
||||
if(!dst || !image_copy_palette(src, dst, -1)) {
|
||||
image_free(dst);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
image_clear(dst);
|
||||
image_vflip(src, dst);
|
||||
return dst;
|
||||
}
|
Loading…
Reference in a new issue