diff --git a/pipi/codec.c b/pipi/codec.c index 2b31d31..c1683d1 100644 --- a/pipi/codec.c +++ b/pipi/codec.c @@ -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) diff --git a/pipi/codec/imlib.c b/pipi/codec/imlib.c index 49bf476..0288825 100644 --- a/pipi/codec/imlib.c +++ b/pipi/codec/imlib.c @@ -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); diff --git a/pipi/codec/opencv.c b/pipi/codec/opencv.c index e061dd0..c1a8284 100644 --- a/pipi/codec/opencv.c +++ b/pipi/codec/opencv.c @@ -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; diff --git a/pipi/codec/sdl.c b/pipi/codec/sdl.c index 010affe..6cf97c3 100644 --- a/pipi/codec/sdl.c +++ b/pipi/codec/sdl.c @@ -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); } diff --git a/pipi/pipi.c b/pipi/pipi.c index 24d1aa8..0c45ee2 100644 --- a/pipi/pipi.c +++ b/pipi/pipi.c @@ -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; +} + diff --git a/pipi/pipi.h b/pipi/pipi.h index 83fb0a4..ce52e60 100644 --- a/pipi/pipi.h +++ b/pipi/pipi.h @@ -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,