library, so we can have several or none of them at some time. * sdl.c imlib.c: allow to save images that weren't created using the current codec. git-svn-id: file:///srv/caca.zoy.org/var/lib/svn/libpipi/trunk@2629 92316355-f0b4-4df1-b90c-862c8a59935fremotes/tiles
@@ -38,32 +38,23 @@ pipi_image_t *pipi_load(const char *name) | |||||
#endif | #endif | ||||
} | } | ||||
pipi_image_t *pipi_new(int width, int height) | |||||
{ | |||||
#if USE_SDL | |||||
return pipi_new_sdl(width, height); | |||||
#elif USE_IMLIB2 | |||||
return pipi_new_imlib2(width, height); | |||||
#elif USE_OPENCV | |||||
return pipi_new_opencv(width, height); | |||||
#endif | |||||
} | |||||
void pipi_free(pipi_image_t *img) | void pipi_free(pipi_image_t *img) | ||||
{ | { | ||||
unsigned int i; | int i; | ||||
for(i = 0; i < PIPI_PIXELS_MAX; i++) | for(i = 0; i < PIPI_PIXELS_MAX; i++) | ||||
if(i != img->codec_format && img->p[i].pixels) | if(i != img->codec_format && img->p[i].pixels) | ||||
free(img->p[i].pixels); | free(img->p[i].pixels); | ||||
#if USE_SDL | #if USE_SDL | ||||
return pipi_free_sdl(img); | pipi_free_sdl(img); | ||||
#elif USE_IMLIB2 | #elif USE_IMLIB2 | ||||
return pipi_free_imlib2(img); | pipi_free_imlib2(img); | ||||
#elif USE_OPENCV | #elif USE_OPENCV | ||||
return pipi_free_opencv(img); | pipi_free_opencv(img); | ||||
#endif | #endif | ||||
free(img); | |||||
} | } | ||||
void pipi_save(pipi_image_t *img, const char *name) | void pipi_save(pipi_image_t *img, const char *name) | ||||
@@ -36,44 +36,13 @@ pipi_image_t *pipi_load_imlib2(const char *name) | |||||
if(!priv) | if(!priv) | ||||
return NULL; | return NULL; | ||||
img = (pipi_image_t *)malloc(sizeof(pipi_image_t)); | |||||
memset(img, 0, sizeof(pipi_image_t)); | |||||
imlib_context_set_image(priv); | imlib_context_set_image(priv); | ||||
img->w = imlib_image_get_width(); | img = pipi_new(imlib_image_get_width(), imlib_image_get_height()); | ||||
img->h = imlib_image_get_height(); | |||||
img->p[PIPI_PIXELS_RGBA32].pixels = imlib_image_get_data(); | img->p[PIPI_PIXELS_RGBA32].pixels = imlib_image_get_data(); | ||||
img->p[PIPI_PIXELS_RGBA32].w = imlib_image_get_width(); | img->p[PIPI_PIXELS_RGBA32].w = img->w; | ||||
img->p[PIPI_PIXELS_RGBA32].h = imlib_image_get_height(); | img->p[PIPI_PIXELS_RGBA32].h = img->h; | ||||
img->p[PIPI_PIXELS_RGBA32].pitch = 4 * imlib_image_get_width(); | img->p[PIPI_PIXELS_RGBA32].pitch = 4 * img->w; | ||||
img->last_modified = PIPI_PIXELS_RGBA32; | |||||
img->codec_priv = (void *)priv; | |||||
img->codec_format = PIPI_PIXELS_RGBA32; | |||||
return img; | |||||
} | |||||
pipi_image_t *pipi_new_imlib2(int width, int height) | |||||
{ | |||||
pipi_image_t *img; | |||||
Imlib_Image priv = imlib_create_image(width, height); | |||||
if(!priv) | |||||
return NULL; | |||||
img = (pipi_image_t *)malloc(sizeof(pipi_image_t)); | |||||
memset(img, 0, sizeof(pipi_image_t)); | |||||
imlib_context_set_image(priv); | |||||
img->w = imlib_image_get_width(); | |||||
img->h = imlib_image_get_height(); | |||||
img->p[PIPI_PIXELS_RGBA32].pixels = imlib_image_get_data(); | |||||
img->p[PIPI_PIXELS_RGBA32].w = imlib_image_get_width(); | |||||
img->p[PIPI_PIXELS_RGBA32].h = imlib_image_get_height(); | |||||
img->p[PIPI_PIXELS_RGBA32].pitch = 4 * imlib_image_get_width(); | |||||
img->last_modified = PIPI_PIXELS_RGBA32; | img->last_modified = PIPI_PIXELS_RGBA32; | ||||
img->codec_priv = (void *)priv; | img->codec_priv = (void *)priv; | ||||
@@ -86,12 +55,35 @@ void pipi_free_imlib2(pipi_image_t *img) | |||||
{ | { | ||||
imlib_context_set_image(img->codec_priv); | imlib_context_set_image(img->codec_priv); | ||||
imlib_free_image(); | imlib_free_image(); | ||||
free(img); | |||||
} | } | ||||
void pipi_save_imlib2(pipi_image_t *img, const char *name) | void pipi_save_imlib2(pipi_image_t *img, const char *name) | ||||
{ | { | ||||
if(!img->codec_priv) | |||||
{ | |||||
Imlib_Image priv = imlib_create_image(img->w, img->h); | |||||
void *data; | |||||
imlib_context_set_image(priv); | |||||
data = imlib_image_get_data(); | |||||
/* FIXME: check pitch differences here */ | |||||
if(img->last_modified == PIPI_PIXELS_RGBA32) | |||||
{ | |||||
memcpy(data, img->p[PIPI_PIXELS_RGBA32].pixels, | |||||
4 * img->w * img->h); | |||||
free(img->p[PIPI_PIXELS_RGBA32].pixels); | |||||
} | |||||
img->p[PIPI_PIXELS_RGBA32].pixels = data; | |||||
img->p[PIPI_PIXELS_RGBA32].w = imlib_image_get_width(); | |||||
img->p[PIPI_PIXELS_RGBA32].h = imlib_image_get_height(); | |||||
img->p[PIPI_PIXELS_RGBA32].pitch = 4 * imlib_image_get_width(); | |||||
img->codec_priv = (void *)priv; | |||||
img->codec_format = PIPI_PIXELS_RGBA32; | |||||
} | |||||
pipi_getpixels(img, img->codec_format); | pipi_getpixels(img, img->codec_format); | ||||
imlib_context_set_image(img->codec_priv); | imlib_context_set_image(img->codec_priv); | ||||
imlib_save_image(name); | imlib_save_image(name); | ||||
@@ -29,6 +29,8 @@ | |||||
#include "pipi.h" | #include "pipi.h" | ||||
#include "pipi_internals.h" | #include "pipi_internals.h" | ||||
/* FIXME: this whole file is broken until we support BGR24 images */ | |||||
pipi_image_t *pipi_load_opencv(const char *name) | pipi_image_t *pipi_load_opencv(const char *name) | ||||
{ | { | ||||
pipi_image_t *img; | pipi_image_t *img; | ||||
@@ -58,7 +60,7 @@ pipi_image_t *pipi_load_opencv(const char *name) | |||||
pipi_image_t *pipi_new_opencv(int width, int height) | pipi_image_t *pipi_new_opencv(int width, int height) | ||||
{ | { | ||||
pipi_image_t *img; | pipi_image_t *img; | ||||
IplImage *priv = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3); | IplImage *priv = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 4); | ||||
if(!priv) | if(!priv) | ||||
return NULL; | return NULL; | ||||
@@ -28,6 +28,8 @@ | |||||
#include "pipi.h" | #include "pipi.h" | ||||
#include "pipi_internals.h" | #include "pipi_internals.h" | ||||
static SDL_Surface *create_32bpp_surface(int w, int h); | |||||
pipi_image_t *pipi_load_sdl(const char *name) | pipi_image_t *pipi_load_sdl(const char *name) | ||||
{ | { | ||||
pipi_image_t *img; | pipi_image_t *img; | ||||
@@ -38,17 +40,13 @@ pipi_image_t *pipi_load_sdl(const char *name) | |||||
if(priv->format->BytesPerPixel != 4) | if(priv->format->BytesPerPixel != 4) | ||||
{ | { | ||||
img = pipi_new(priv->w, priv->h); | SDL_Surface *tmp = create_32bpp_surface(priv->w, priv->h); | ||||
SDL_BlitSurface(priv, NULL, img->codec_priv, NULL); | SDL_BlitSurface(priv, NULL, tmp, NULL); | ||||
SDL_FreeSurface(priv); | SDL_FreeSurface(priv); | ||||
return img; | priv = tmp; | ||||
} | } | ||||
img = (pipi_image_t *)malloc(sizeof(pipi_image_t)); | img = pipi_new(priv->w, priv->h); | ||||
memset(img, 0, sizeof(pipi_image_t)); | |||||
img->w = priv->w; | |||||
img->h = priv->h; | |||||
img->p[PIPI_PIXELS_RGBA32].pixels = priv->pixels; | img->p[PIPI_PIXELS_RGBA32].pixels = priv->pixels; | ||||
img->p[PIPI_PIXELS_RGBA32].w = priv->w; | img->p[PIPI_PIXELS_RGBA32].w = priv->w; | ||||
@@ -62,10 +60,44 @@ pipi_image_t *pipi_load_sdl(const char *name) | |||||
return img; | return img; | ||||
} | } | ||||
pipi_image_t *pipi_new_sdl(int width, int height) | void pipi_free_sdl(pipi_image_t *img) | ||||
{ | |||||
SDL_FreeSurface(img->codec_priv); | |||||
} | |||||
void pipi_save_sdl(pipi_image_t *img, const char *name) | |||||
{ | |||||
if(!img->codec_priv) | |||||
{ | |||||
SDL_Surface *priv = create_32bpp_surface(img->w, img->h); | |||||
/* FIXME: check pitch differences here */ | |||||
if(img->last_modified == PIPI_PIXELS_RGBA32) | |||||
{ | |||||
memcpy(priv->pixels, img->p[PIPI_PIXELS_RGBA32].pixels, | |||||
priv->pitch * priv->h); | |||||
free(img->p[PIPI_PIXELS_RGBA32].pixels); | |||||
} | |||||
img->p[PIPI_PIXELS_RGBA32].pixels = priv->pixels; | |||||
img->p[PIPI_PIXELS_RGBA32].w = priv->w; | |||||
img->p[PIPI_PIXELS_RGBA32].h = priv->h; | |||||
img->p[PIPI_PIXELS_RGBA32].pitch = priv->pitch; | |||||
img->codec_priv = (void *)priv; | |||||
img->codec_format = PIPI_PIXELS_RGBA32; | |||||
} | |||||
pipi_getpixels(img, img->codec_format); | |||||
SDL_SaveBMP(img->codec_priv, name); | |||||
} | |||||
/* | |||||
* The following functions are local. | |||||
*/ | |||||
static SDL_Surface *create_32bpp_surface(int w, int h) | |||||
{ | { | ||||
pipi_image_t *img; | |||||
SDL_Surface *priv; | |||||
Uint32 rmask, gmask, bmask, amask; | Uint32 rmask, gmask, bmask, amask; | ||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN | #if SDL_BYTEORDER == SDL_BIG_ENDIAN | ||||
rmask = 0xff000000; | rmask = 0xff000000; | ||||
@@ -78,40 +110,8 @@ pipi_image_t *pipi_new_sdl(int width, int height) | |||||
bmask = 0x00ff0000; | bmask = 0x00ff0000; | ||||
amask = 0x00000000; | amask = 0x00000000; | ||||
#endif | #endif | ||||
priv = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, | |||||
rmask, gmask, bmask, amask); | |||||
if(!priv) | |||||
return NULL; | |||||
img = (pipi_image_t *)malloc(sizeof(pipi_image_t)); | |||||
memset(img, 0, sizeof(pipi_image_t)); | |||||
img->w = priv->w; | return SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, | ||||
img->h = priv->h; | rmask, gmask, bmask, amask); | ||||
img->p[PIPI_PIXELS_RGBA32].pixels = priv->pixels; | |||||
img->p[PIPI_PIXELS_RGBA32].w = priv->w; | |||||
img->p[PIPI_PIXELS_RGBA32].h = priv->h; | |||||
img->p[PIPI_PIXELS_RGBA32].pitch = priv->pitch; | |||||
img->last_modified = PIPI_PIXELS_RGBA32; | |||||
img->codec_priv = (void *)priv; | |||||
img->codec_format = PIPI_PIXELS_RGBA32; | |||||
return img; | |||||
} | |||||
void pipi_free_sdl(pipi_image_t *img) | |||||
{ | |||||
SDL_FreeSurface(img->codec_priv); | |||||
free(img); | |||||
} | |||||
void pipi_save_sdl(pipi_image_t *img, const char *name) | |||||
{ | |||||
pipi_getpixels(img, img->codec_format); | |||||
SDL_SaveBMP(img->codec_priv, name); | |||||
} | } | ||||
@@ -38,3 +38,17 @@ void _pipi_init(void) | |||||
} | } | ||||
*/ | */ | ||||
pipi_image_t *pipi_new(int w, int h) | |||||
{ | |||||
pipi_image_t *img; | |||||
img = malloc(sizeof(pipi_image_t)); | |||||
memset(img, 0, sizeof(pipi_image_t)); | |||||
img->w = w; | |||||
img->h = h; | |||||
img->last_modified = PIPI_PIXELS_UNINITIALISED; | |||||
return img; | |||||
} | |||||
@@ -29,6 +29,8 @@ extern "C" | |||||
* just been loaded, but RGBA_F is a lot better for complex operations. */ | * just been loaded, but RGBA_F is a lot better for complex operations. */ | ||||
typedef enum | typedef enum | ||||
{ | { | ||||
PIPI_PIXELS_UNINITIALISED = -1, | |||||
PIPI_PIXELS_RGBA32 = 0, | PIPI_PIXELS_RGBA32 = 0, | ||||
PIPI_PIXELS_RGBA_F = 1, | PIPI_PIXELS_RGBA_F = 1, | ||||