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-862c8a59935f
remotes/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, | |||