mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-09-04 19:47:54 +00:00
migrated to SDL3
This commit is contained in:
91
savepng.cpp
91
savepng.cpp
@@ -5,17 +5,24 @@
|
||||
* http://www.libpng.org/pub/png/src/libpng-LICENSE.txt
|
||||
*/
|
||||
|
||||
#ifdef CAP_SDL2
|
||||
#if CAP_SDL2
|
||||
#define USE_SDL2
|
||||
#endif
|
||||
#ifndef SDLVER
|
||||
#define SDLVER 1
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDL2
|
||||
#include <SDL2/SDL.h>
|
||||
#else
|
||||
#if SDLVER == 1
|
||||
#include <SDL/SDL.h>
|
||||
#define SDL23(x,y) x
|
||||
#endif
|
||||
#if SDLVER == 2
|
||||
#include <SDL2/SDL.h>
|
||||
#define SDL23(x,y) x
|
||||
#endif
|
||||
#if SDLVER == 3
|
||||
#include <SDL3/SDL.h>
|
||||
#define SDL23(x,y) y
|
||||
#endif
|
||||
|
||||
#include <cstdlib>
|
||||
#include <png.h>
|
||||
|
||||
#define SUCCESS 0
|
||||
@@ -35,6 +42,18 @@
|
||||
#define amask 0xFF000000
|
||||
#endif
|
||||
|
||||
#if SDLVER >= 3
|
||||
struct pixformat { int BitsPerPixel; int BytesPerPixel; Uint32 Rmask, Gmask, Bmask, Amask; };
|
||||
|
||||
pixformat get_format(SDL_PixelFormat val) { pixformat pf; SDL_GetMasksForPixelFormat(val, &pf.BitsPerPixel, &pf.Rmask, &pf.Gmask, &pf.Bmask, &pf.Amask); pf.BytesPerPixel = (pf.BitsPerPixel+7) / 8; return pf; }
|
||||
|
||||
#else
|
||||
|
||||
SDL_PixelFormat get_format(SDL_PixelFormat *val) { return *val; }
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/* libpng callbacks */
|
||||
static void png_error_SDL(png_structp ctx, png_const_charp str)
|
||||
{
|
||||
@@ -42,8 +61,13 @@ static void png_error_SDL(png_structp ctx, png_const_charp str)
|
||||
}
|
||||
static void png_write_SDL(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
SDL_RWops *rw = (SDL_RWops*)png_get_io_ptr(png_ptr);
|
||||
#if SDLVER >= 3
|
||||
SDL_IOStream *rw = (SDL_IOStream*)png_get_io_ptr(png_ptr);
|
||||
SDL_WriteIO(rw, data, length);
|
||||
#else
|
||||
SDL_RWops *rw = (SDL_RWops*)png_get_io_ptr(png_ptr);
|
||||
SDL_RWwrite(rw, data, sizeof(png_byte), length);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -54,8 +78,10 @@ SDL_Surface *SDL_PNGFormatAlpha(SDL_Surface *src)
|
||||
SDL_Surface *surf;
|
||||
SDL_Rect rect = { 0, 0, 0, 0 };
|
||||
|
||||
auto pf = get_format(src->format);
|
||||
|
||||
/* NO-OP for images < 32bpp and 32bpp images that already have Alpha channel */
|
||||
if (src->format->BitsPerPixel <= 24 || src->format->Amask) {
|
||||
if (pf.BitsPerPixel <= 24 || pf.Amask) {
|
||||
src->refcount++;
|
||||
return src;
|
||||
}
|
||||
@@ -63,22 +89,31 @@ SDL_Surface *SDL_PNGFormatAlpha(SDL_Surface *src)
|
||||
/* Convert 32bpp alpha-less image to 24bpp alpha-less image */
|
||||
rect.w = src->w;
|
||||
rect.h = src->h;
|
||||
surf = SDL_CreateRGBSurface(src->flags, src->w, src->h, 24,
|
||||
src->format->Rmask, src->format->Gmask, src->format->Bmask, 0);
|
||||
#if SDLVER >= 3
|
||||
surf = SDL_CreateSurface(src->w, src->h, SDL_GetPixelFormatForMasks(24, pf.Rmask, pf.Gmask, pf.Bmask, 0));
|
||||
SDL_BlitSurfaceUnchecked(src, &rect, surf, &rect);
|
||||
#else
|
||||
surf = SDL_CreateRGBSurface(src->flags, src->w, src->h, 24, pf.Rmask, pf.Gmask, pf.Bmask, 0);
|
||||
SDL_LowerBlit(src, &rect, surf, &rect);
|
||||
#endif
|
||||
|
||||
return surf;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
|
||||
#define ERR SDL23(if (freedst) SDL_RWclose(dst); return (ERROR), if (freedst) SDL_CloseIO(dst); return (ERROR))
|
||||
|
||||
#endif
|
||||
int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
int SDL_SavePNG_RW(SDL_Surface *surface, SDL23(SDL_RWops, SDL_IOStream) *dst, int freedst)
|
||||
{
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
#if SDLVER <= 2
|
||||
png_colorp pal_ptr;
|
||||
SDL_Palette *pal;
|
||||
#endif
|
||||
int i, colortype;
|
||||
#ifdef USE_ROW_POINTERS
|
||||
png_bytep *row_pointers;
|
||||
@@ -92,29 +127,25 @@ int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
if (!surface)
|
||||
{
|
||||
SDL_SetError("Argument 1 to SDL_SavePNG_RW can't be NULL, expecting SDL_Surface*\n");
|
||||
if (freedst) SDL_RWclose(dst);
|
||||
return (ERROR);
|
||||
ERR;
|
||||
}
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, png_error_SDL, NULL); /* err_ptr, err_fn, warn_fn */
|
||||
if (!png_ptr)
|
||||
{
|
||||
SDL_SetError("Unable to png_create_write_struct on %s\n", PNG_LIBPNG_VER_STRING);
|
||||
if (freedst) SDL_RWclose(dst);
|
||||
return (ERROR);
|
||||
ERR;
|
||||
}
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr)
|
||||
{
|
||||
SDL_SetError("Unable to png_create_info_struct\n");
|
||||
png_destroy_write_struct(&png_ptr, NULL);
|
||||
if (freedst) SDL_RWclose(dst);
|
||||
return (ERROR);
|
||||
ERR;
|
||||
}
|
||||
if (setjmp(png_jmpbuf(png_ptr))) /* All other errors, see also "png_error_SDL" */
|
||||
{
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
if (freedst) SDL_RWclose(dst);
|
||||
return (ERROR);
|
||||
ERR;
|
||||
}
|
||||
|
||||
/* Setup our RWops writer */
|
||||
@@ -122,9 +153,10 @@ int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
|
||||
/* Prepare chunks */
|
||||
colortype = PNG_COLOR_MASK_COLOR;
|
||||
if (surface->format->BytesPerPixel > 0
|
||||
&& surface->format->BytesPerPixel <= 8
|
||||
&& (pal = surface->format->palette))
|
||||
auto pf = get_format(surface->format);
|
||||
|
||||
#if SDLVER <= 2
|
||||
if (pf.BytesPerPixel > 0 && pf.BytesPerPixel <= 8 && (pal = surface->format->palette))
|
||||
{
|
||||
colortype |= PNG_COLOR_MASK_PALETTE;
|
||||
pal_ptr = (png_colorp)malloc(pal->ncolors * sizeof(png_color));
|
||||
@@ -136,7 +168,10 @@ int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
png_set_PLTE(png_ptr, info_ptr, pal_ptr, pal->ncolors);
|
||||
free(pal_ptr);
|
||||
}
|
||||
else if (surface->format->BytesPerPixel > 3 || surface->format->Amask)
|
||||
#else
|
||||
if(false) ;
|
||||
#endif
|
||||
else if (pf.BytesPerPixel > 3 || pf.Amask)
|
||||
colortype |= PNG_COLOR_MASK_ALPHA;
|
||||
|
||||
png_set_IHDR(png_ptr, info_ptr, surface->w, surface->h, 8, colortype,
|
||||
@@ -145,9 +180,9 @@ int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
// png_set_packing(png_ptr);
|
||||
|
||||
/* Allow BGR surfaces */
|
||||
if (surface->format->Rmask == bmask
|
||||
&& surface->format->Gmask == gmask
|
||||
&& surface->format->Bmask == rmask)
|
||||
if (pf.Rmask == bmask
|
||||
&& pf.Gmask == gmask
|
||||
&& pf.Bmask == rmask)
|
||||
png_set_bgr(png_ptr);
|
||||
|
||||
/* Write everything */
|
||||
@@ -166,6 +201,6 @@ int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
|
||||
/* Done */
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
if (freedst) SDL_RWclose(dst);
|
||||
if (freedst) SDL23(SDL_RWclose, SDL_CloseIO)(dst);
|
||||
return (SUCCESS);
|
||||
}
|
||||
|
Reference in New Issue
Block a user