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 | |||
} | |||
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) | |||
{ | |||
unsigned int i; | |||
int i; | |||
for(i = 0; i < PIPI_PIXELS_MAX; i++) | |||
if(i != img->codec_format && img->p[i].pixels) | |||
free(img->p[i].pixels); | |||
#if USE_SDL | |||
return pipi_free_sdl(img); | |||
pipi_free_sdl(img); | |||
#elif USE_IMLIB2 | |||
return pipi_free_imlib2(img); | |||
pipi_free_imlib2(img); | |||
#elif USE_OPENCV | |||
return pipi_free_opencv(img); | |||
pipi_free_opencv(img); | |||
#endif | |||
free(img); | |||
} | |||
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) | |||
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 = pipi_new(imlib_image_get_width(), 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->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->p[PIPI_PIXELS_RGBA32].w = img->w; | |||
img->p[PIPI_PIXELS_RGBA32].h = img->h; | |||
img->p[PIPI_PIXELS_RGBA32].pitch = 4 * img->w; | |||
img->last_modified = PIPI_PIXELS_RGBA32; | |||
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_free_image(); | |||
free(img); | |||
} | |||
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); | |||
imlib_context_set_image(img->codec_priv); | |||
imlib_save_image(name); | |||
@@ -29,6 +29,8 @@ | |||
#include "pipi.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 *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 *img; | |||
IplImage *priv = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3); | |||
IplImage *priv = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 4); | |||
if(!priv) | |||
return NULL; | |||
@@ -28,6 +28,8 @@ | |||
#include "pipi.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 *img; | |||
@@ -38,17 +40,13 @@ pipi_image_t *pipi_load_sdl(const char *name) | |||
if(priv->format->BytesPerPixel != 4) | |||
{ | |||
img = pipi_new(priv->w, priv->h); | |||
SDL_BlitSurface(priv, NULL, img->codec_priv, NULL); | |||
SDL_Surface *tmp = create_32bpp_surface(priv->w, priv->h); | |||
SDL_BlitSurface(priv, NULL, tmp, NULL); | |||
SDL_FreeSurface(priv); | |||
return img; | |||
priv = tmp; | |||
} | |||
img = (pipi_image_t *)malloc(sizeof(pipi_image_t)); | |||
memset(img, 0, sizeof(pipi_image_t)); | |||
img->w = priv->w; | |||
img->h = priv->h; | |||
img = pipi_new(priv->w, priv->h); | |||
img->p[PIPI_PIXELS_RGBA32].pixels = priv->pixels; | |||
img->p[PIPI_PIXELS_RGBA32].w = priv->w; | |||
@@ -62,10 +60,44 @@ pipi_image_t *pipi_load_sdl(const char *name) | |||
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; | |||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN | |||
rmask = 0xff000000; | |||
@@ -78,40 +110,8 @@ pipi_image_t *pipi_new_sdl(int width, int height) | |||
bmask = 0x00ff0000; | |||
amask = 0x00000000; | |||
#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; | |||
img->h = priv->h; | |||
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); | |||
return SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, | |||
rmask, gmask, bmask, amask); | |||
} | |||
@@ -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. */ | |||
typedef enum | |||
{ | |||
PIPI_PIXELS_UNINITIALISED = -1, | |||
PIPI_PIXELS_RGBA32 = 0, | |||
PIPI_PIXELS_RGBA_F = 1, | |||