12 #pragma GCC diagnostic ignored "-Wold-style-cast"
14 #define SAVEPNG_SUCCESS 0
15 #define SAVEPNG_ERROR -1
17 #define USE_ROW_POINTERS
19 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
20 #define rmask 0xFF000000
21 #define gmask 0x00FF0000
22 #define bmask 0x0000FF00
23 #define amask 0x000000FF
25 #define rmask 0x000000FF
26 #define gmask 0x0000FF00
27 #define bmask 0x00FF0000
28 #define amask 0xFF000000
36 SDL_SetError(
"libpng: %s\n", str);
40 SDL_RWops *rw =
static_cast<SDL_RWops*
>(png_get_io_ptr(png_ptr));
41 SDL_RWwrite(rw, data,
sizeof(png_byte), length);
47 SDL_Rect rect = { 0 , 0 , 0 , 0 };
50 if (src->format->BitsPerPixel <= 24 || src->format->Amask) {
58 surf = SDL_CreateRGBSurface(src->flags, src->w, src->h, 24,
59 src->format->Rmask, src->format->Gmask, src->format->Bmask, 0);
60 SDL_LowerBlit(src, &rect, surf, &rect);
72 #ifdef USE_ROW_POINTERS
73 png_bytep *row_pointers;
78 SDL_SetError(
"Argument 2 to SDL_SavePNG_RW can't be nullptr, expecting SDL_RWops*\n");
83 SDL_SetError(
"Argument 1 to SDL_SavePNG_RW can't be nullptr, expecting SDL_Surface*\n");
84 if (freedst) SDL_RWclose(dst);
87 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
nullptr,
png_error_SDL,
nullptr);
90 SDL_SetError(
"Unable to png_create_write_struct on %s\n", PNG_LIBPNG_VER_STRING);
91 if (freedst) SDL_RWclose(dst);
94 info_ptr = png_create_info_struct(png_ptr);
97 SDL_SetError(
"Unable to png_create_info_struct\n");
98 png_destroy_write_struct(&png_ptr,
nullptr);
99 if (freedst) SDL_RWclose(dst);
102 if (setjmp(png_jmpbuf(png_ptr)))
104 png_destroy_write_struct(&png_ptr, &info_ptr);
105 if (freedst) SDL_RWclose(dst);
113 colortype = PNG_COLOR_MASK_COLOR;
114 if (surface->format->BytesPerPixel > 0
115 && surface->format->BytesPerPixel <= 8
116 && (pal = surface->format->palette))
118 colortype |= PNG_COLOR_MASK_PALETTE;
119 pal_ptr =
static_cast<png_colorp
>(malloc(pal->ncolors *
sizeof(png_color)));
120 for (i = 0; i < pal->ncolors; i++) {
121 pal_ptr[
i].red = pal->colors[
i].r;
122 pal_ptr[
i].green = pal->colors[
i].g;
123 pal_ptr[
i].blue = pal->colors[
i].b;
125 png_set_PLTE(png_ptr, info_ptr, pal_ptr, pal->ncolors);
128 else if (surface->format->BytesPerPixel > 3 || surface->format->Amask)
129 colortype |= PNG_COLOR_MASK_ALPHA;
131 png_set_IHDR(png_ptr, info_ptr, surface->w, surface->h, 8, colortype,
132 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
137 if (surface->format->Rmask ==
bmask
138 && surface->format->Gmask ==
gmask
139 && surface->format->Bmask ==
rmask)
140 png_set_bgr(png_ptr);
143 png_write_info(png_ptr, info_ptr);
144 #ifdef USE_ROW_POINTERS
145 row_pointers =
static_cast<png_bytep*
> (malloc(
sizeof(png_bytep)*surface->h));
146 for (i = 0; i < surface->h; i++)
147 row_pointers[i] = static_cast<png_bytep>(static_cast<Uint8*>(surface->pixels)) + i * surface->pitch;
148 png_write_image(png_ptr, row_pointers);
151 for (i = 0; i < surface->h; i++)
152 png_write_row(png_ptr, (png_bytep)(Uint8*)surface->pixels + i * surface->pitch);
154 png_write_end(png_ptr, info_ptr);
157 png_destroy_write_struct(&png_ptr, &info_ptr);
158 if (freedst) SDL_RWclose(dst);
static void png_write_SDL(png_structp png_ptr, png_bytep data, png_size_t length)
GLint GLenum GLsizei GLint GLsizei const GLvoid * data
GLuint GLsizei GLsizei * length
static void png_error_SDL(png_structp, png_const_charp str)
SDL_Surface * SDL_PNGFormatAlpha(SDL_Surface *src)
int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)