libimg/src/alloc.c

99 lines
1.9 KiB
C

#include <libimg.h>
#include "libimg-internal.h"
#include <gint/display.h>
#include <gint/std/stdlib.h>
#include <gint/std/string.h>
int img_target(img_t img, int w, int h)
{
if(img.flags & FLAG_RO) return 0;
if(img_null(img)) return 0;
if(img.width < w || img.height < h) return 0;
return 1;
}
img_t img_create(int w, int h)
{
if(w <= 0 || h <= 0 || w >= 0x10000 || h >= 0x10000)
return NULL_IMG;
img_t s = {
.width = w, .height = h, .stride = w,
.flags = FLAG_OWN,
.pixels = malloc(w * h * sizeof *s.pixels),
};
if(!s.pixels) return NULL_IMG;
return s;
}
img_t img_copy(img_t img)
{
int w = img.width, h = img.height;
img_t s = img_create(w, h);
if(img_null(s)) return s;
img_pixel_t *src_px = img.pixels;
img_pixel_t *dst_px = s.pixels;
for(int y = 0; y < img.height; y++)
{
memcpy(dst_px, src_px, w * sizeof *src_px);
src_px += img.stride;
dst_px += s.stride;
}
return s;
}
int img_null(img_t img)
{
return !img.width || !img.height || !img.pixels;
}
img_t img_sub(img_t img, int x, int y, int w, int h)
{
if(img_null(img)) return img;
/* If w or h is negative, use the full width and height (this formula
works even if x<0 or y<0) */
if(w < 0) w = img.width - x;
if(h < 0) h = img.height - y;
/* Clip in bounds */
if(x < 0) w += x, x = 0;
if(y < 0) h += y, y = 0;
if(x + w > img.width) w = img.width - x;
if(y + h > img.height) h = img.height - y;
if(w <= 0 || h <= 0) return NULL_IMG;
img_t s = {
.width = w, .height = h, .stride = img.stride,
.flags = 0,
.pixels = img.pixels + (y * img.stride) + x,
};
return s;
}
img_t img_at(img_t img, int x, int y)
{
return img_sub(img, x, y, -1, -1);
}
#ifdef FXCG50
img_t img_vram(void)
{
img_t vram = {
.width = 396, .height = 224, .stride = 396,
.flags = 0,
.pixels = gint_vram,
};
return vram;
}
#endif
void img_destroy(img_t img)
{
if(img.flags & FLAG_OWN && !(img.flags & FLAG_RO)) free(img.pixels);
}