From e4e7bf4b17974414383f5fd018cb39597138d12e Mon Sep 17 00:00:00 2001 From: Allanis Date: Thu, 11 Jul 2013 16:42:18 +0100 Subject: [PATCH] [Add] save png method to save a surface to a file as png. --- src/opengl.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++- src/opengl.h | 3 +- src/perlin.c | 2 +- 3 files changed, 81 insertions(+), 3 deletions(-) diff --git a/src/opengl.c b/src/opengl.c index cce5504..6840bb7 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -157,6 +157,83 @@ void gl_screenshot(const char* filename) { gl_checkErr(); } +/* Save a surface to a file as a png. */ +int SDL_savePNG(SDL_Surface* surface, const char* file) { + static unsigned char** ss_rows; + static int ss_size; + static int ss_w, ss_h; + SDL_Surface* ss_surface; + SDL_Rect ss_rect; + int r, i; + int alpha = 0; + int pixel_bits = 32; + + unsigned surf_flags; + unsigned surf_alpha; + + ss_rows = 0; + ss_size = 0; + ss_surface = 0; + + ss_w = surface->w; + ss_h = surface->h; + + if(surface->format->Amask) { + alpha = 1; + pixel_bits = 32; + } else { + pixel_bits = 24; + } + + ss_surface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, ss_w, ss_h, + pixel_bits, RGBAMASK); + + if(ss_surface == 0) { + return -1; + } + + surf_flags = surface->flags & (SDL_SRCALPHA | SDL_SRCCOLORKEY); + surf_alpha = surface->format->alpha; + if(surf_flags & SDL_SRCALPHA) + SDL_SetAlpha(surface, 0, SDL_ALPHA_OPAQUE); + if(surf_flags & SDL_SRCCOLORKEY) + SDL_SetColorKey(surface, 0, surface->format->colorkey); + + ss_rect.x = 0; + ss_rect.y = 0; + ss_rect.w = ss_w; + ss_rect.h = ss_h; + SDL_BlitSurface(surface, &ss_rect, ss_surface, 0); + + if(ss_size == 0) { + ss_size = ss_h; + ss_rows = (unsigned char**)malloc(sizeof(unsigned char*)*ss_size); + if(ss_rows == 0) { + return -1; + } + } + if(surf_flags & SDL_SRCALPHA) + SDL_SetAlpha(surface, SDL_SRCALPHA, (Uint8)surf_alpha); + if(surf_flags & SDL_SRCCOLORKEY) + SDL_SetColorKey(surface, SDL_SRCCOLORKEY, surface->format->colorkey); + + for(i = 0; i < ss_h; i++) { + ss_rows[i] = ((unsigned char*)ss_surface->pixels) + i * ss_surface->pitch; + } + + if(alpha) { + r = write_png(file, ss_rows, surface->w, surface->h, PNG_COLOR_TYPE_RGB_ALPHA, 8); + } else { + r = write_png(file, ss_rows, surface->w, surface->h, PNG_COLOR_TYPE_RGB, 8); + } + + free(ss_rows); + SDL_FreeSurface(ss_surface); + ss_surface = NULL; + + return r; +} + /* ================ */ /* TEXTURE! */ /* ================ */ @@ -191,7 +268,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) { /* Create the temp POT surface. */ tmp = SDL_CreateRGBSurface(SDL_SRCCOLORKEY, - potw, poth, surface->format->BytesPerPixel*8, RGBMASK); + potw, poth, surface->format->BytesPerPixel*8, RGBAMASK); if(tmp == NULL) { WARN("Unable to create POT surface: %s", SDL_GetError()); return 0; diff --git a/src/opengl.h b/src/opengl.h index f32ca4d..0b35ff7 100644 --- a/src/opengl.h +++ b/src/opengl.h @@ -17,7 +17,7 @@ # define BMASK 0x00ff0000 # define AMASK 0xff000000 #endif -#define RGBMASK RMASK,GMASK,BMASK,AMASK +#define RGBAMASK RMASK,GMASK,BMASK,AMASK /* Info about opengl screen. */ #define OPENGL_FULLSCREEN (1<<0) @@ -105,6 +105,7 @@ void gl_exit(void); int gl_isTrans(const glTexture* t, const int x, const int y); void gl_getSpriteFromDir(int* x, int* y, const glTexture* t, const double dir); void gl_screenshot(const char* filename); +int SDL_SavePNG(SDL_Surface* surface, const char* file); /*#if DEBUG == 1 */ void gl_checkErr(void); /*#else */ diff --git a/src/perlin.c b/src/perlin.c index 7955e9d..8c2c5c8 100644 --- a/src/perlin.c +++ b/src/perlin.c @@ -287,7 +287,7 @@ glTexture* noise_genCloud(const int w, const int h, double rug) { map = noise_genNebulae(w, h, 1, rug); - sur = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RGBMASK); + sur = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, RGBAMASK); pix = sur->pixels; /* Convert from mapping to actual colours. */