23 auto chkString = [](
const std::string &filename) ->
bool {
25 for(
size_t i = 0; i < filename.length(); ++i)
26 lwr += tolower(filename[i]);
27 if(lwr.find(
".png") == std::string::npos)
33 if(chkString(file) ==
false)
38 errno_t err = fopen_s(&fp, file,
"rb");
39 if (!(err == 0 && file != NULL)) {
44 FILE* fp = fopen(file,
"rb");
50 png_structp
png = png_create_read_struct(PNG_LIBPNG_VER_STRING,
nullptr,
nullptr,
nullptr);
56 png_infop info = png_create_info_struct(
png);
58 png_destroy_read_struct(&
png,
nullptr,
nullptr);
63 if (setjmp(png_jmpbuf(
png))) {
64 png_destroy_read_struct(&
png, &info,
nullptr);
70 png_read_info(
png, info);
72 int width = png_get_image_width(
png, info);
73 int height = png_get_image_height(
png, info);
74 png_byte color_type = png_get_color_type(
png, info);
75 png_byte bit_depth = png_get_bit_depth(
png, info);
77 if (bit_depth == 16) {
78 png_set_strip_16(
png);
81 if (color_type == PNG_COLOR_TYPE_PALETTE) {
82 png_set_palette_to_rgb(
png);
85 if (png_get_valid(
png, info, PNG_INFO_tRNS)) {
86 png_set_tRNS_to_alpha(
png);
89 if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
90 png_set_gray_to_rgb(
png);
93 if (color_type == PNG_COLOR_TYPE_RGB) {
94 png_set_add_alpha(
png, 0xFF, PNG_FILLER_AFTER);
97 png_read_update_info(
png, info);
99 int pitch = png_get_rowbytes(
png, info);
100 Uint32 rmask, gmask, bmask, amask;
102 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
114 SDL_Surface* surface = SDL_CreateRGBSurface(0, width, height, 32, rmask, gmask, bmask, amask);
116 png_destroy_read_struct(&
png, &info,
nullptr);
121 png_bytep* row_pointers = (png_bytep*) malloc(
sizeof(png_bytep) * height);
122 if(row_pointers == NULL) {
123 fprintf(stderr,
"Error memory allocation error.\n");
125 SDL_FreeSurface(surface);
127 png_destroy_read_struct(&
png, &info,
nullptr);
132 Uint8* pixels = (Uint8*) surface->pixels;
134 for (
int y = 0; y < height; ++y) {
135 row_pointers[y] = pixels + y * pitch;
138 png_read_image(
png, row_pointers);
139 png_read_end(
png,
nullptr);
142 png_destroy_read_struct(&
png, &info,
nullptr);
148 bool SavePNG(SDL_Texture* texture, SDL_Renderer* renderer,
const char* filename) {
150 SDL_QueryTexture(texture,
nullptr,
nullptr, &width, &height);
151 SDL_Surface* surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 32, SDL_PIXELFORMAT_RGBA32);
153 mx::system_err <<
"mx: Failed to create SDL_Surface: " << SDL_GetError() <<
"\n";
157 SDL_Texture *old = SDL_GetRenderTarget(renderer);
159 SDL_SetRenderTarget(renderer, texture);
160 if (SDL_RenderReadPixels(renderer,
nullptr, surface->format->format, surface->pixels, surface->pitch) != 0) {
161 std::cerr <<
"mx: Failed to read pixels from renderer: " << SDL_GetError() <<
"\n";
162 SDL_FreeSurface(surface);
165 SDL_SetRenderTarget(renderer,
nullptr);
166 FILE* fp = fopen(filename,
"wb");
168 mx::system_err <<
"mx: Failed to open file for writing: " << filename <<
"\n";
169 SDL_FreeSurface(surface);
173 png_structp
png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
nullptr,
nullptr,
nullptr);
175 mx::system_err <<
"mx: Failed to create PNG write struct." <<
"\n";
177 SDL_FreeSurface(surface);
181 png_infop info = png_create_info_struct(
png);
183 mx::system_err <<
"mx: Failed to create PNG info struct." <<
"\n";
184 png_destroy_write_struct(&
png,
nullptr);
186 SDL_FreeSurface(surface);
190 if (setjmp(png_jmpbuf(
png))) {
192 png_destroy_write_struct(&
png, &info);
194 SDL_FreeSurface(surface);
198 png_init_io(
png, fp);
199 png_set_IHDR(
png, info, surface->w, surface->h, 8, PNG_COLOR_TYPE_RGBA,
200 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
201 png_write_info(
png, info);
203 uint8_t* pixels =
static_cast<uint8_t*
>(surface->pixels);
204 png_bytep* row_pointers =
new png_bytep[surface->h];
205 for (
int y = 0; y < surface->h; ++y) {
206 row_pointers[y] = pixels + y * surface->pitch;
209 png_write_image(
png, row_pointers);
210 png_write_end(
png,
nullptr);
212 delete[] row_pointers;
213 png_destroy_write_struct(&
png, &info);
215 SDL_FreeSurface(surface);
216 SDL_SetRenderTarget(renderer, old);
222 FILE* fp = fopen(filename,
"wb");
224 mx::system_err <<
"mx: Failed to open file for writing: " << filename <<
"\n";
227 png_structp
png = png_create_write_struct(PNG_LIBPNG_VER_STRING,
nullptr,
nullptr,
nullptr);
229 mx::system_err <<
"mx: Failed to create PNG write struct." <<
"\n";
233 png_infop info = png_create_info_struct(
png);
235 mx::system_err <<
"mx: Failed to create PNG info struct." <<
"\n";
236 png_destroy_write_struct(&
png,
nullptr);
240 if (setjmp(png_jmpbuf(
png))) {
242 png_destroy_write_struct(&
png, &info);
246 png_init_io(
png, fp);
247 png_set_IHDR(
png, info, w, h, 8, PNG_COLOR_TYPE_RGBA,
248 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
249 png_write_info(
png, info);
251 uint8_t* pixels =
static_cast<uint8_t*
>(buffer);
252 png_bytep* row_pointers =
new png_bytep[h];
253 for (
int y = 0; y < h; ++y) {
254 row_pointers[y] = pixels + y * pitch;
257 png_write_image(
png, row_pointers);
258 png_write_end(
png,
nullptr);
260 delete[] row_pointers;
261 png_destroy_write_struct(&
png, &info);