use SDL2_image instead of libpng
This commit is contained in:
parent
da421e2ddf
commit
f3eb06e12a
5 changed files with 38 additions and 445 deletions
|
@ -623,6 +623,7 @@ find_package(Lua51 REQUIRED)
|
|||
find_package(PNG REQUIRED)
|
||||
find_package(SDL2 REQUIRED)
|
||||
find_package(SDL2_mixer REQUIRED)
|
||||
find_package(SDL2_image REQUIRED)
|
||||
find_package(Tolua++ REQUIRED)
|
||||
find_package(ZLIB REQUIRED)
|
||||
|
||||
|
@ -701,9 +702,9 @@ endif()
|
|||
|
||||
# Stratagus definitions
|
||||
|
||||
add_definitions(${PNG_DEFINITIONS} -DUSE_ZLIB -DPIXMAPS=\"${PIXMAPSDIRABS}\")
|
||||
include_directories(${LUA_INCLUDE_DIR} ${PNG_INCLUDE_DIR} ${SDL2_INCLUDE_DIR} ${SDL2_MIXER_INCLUDE_DIR} ${TOLUA++_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS})
|
||||
set(stratagus_LIBS ${stratagus_LIBS} ${LUA_LIBRARIES} ${PNG_LIBRARIES} ${SDL2_LIBRARY} ${SDL2_MIXER_LIBRARY} ${TOLUA++_LIBRARY} ${ZLIB_LIBRARIES})
|
||||
add_definitions(-DUSE_ZLIB -DPIXMAPS=\"${PIXMAPSDIRABS}\")
|
||||
include_directories(${LUA_INCLUDE_DIR} ${SDL2_INCLUDE_DIR} ${SDL2_MIXER_INCLUDE_DIRS} ${SDL2_IMAGE_INCLUDE_DIRS} ${TOLUA++_INCLUDE_DIR} ${ZLIB_INCLUDE_DIRS})
|
||||
set(stratagus_LIBS ${stratagus_LIBS} ${LUA_LIBRARIES} ${SDL2_LIBRARY} ${SDL2_MIXER_LIBRARIES} ${SDL2_IMAGE_LIBRARIES} ${TOLUA++_LIBRARY} ${ZLIB_LIBRARIES})
|
||||
|
||||
if(WIN32 AND NOT ENABLE_STDIO_REDIRECT)
|
||||
add_definitions(-DNO_STDIO_REDIRECT)
|
||||
|
@ -1021,7 +1022,7 @@ if(WIN32 AND MINGW AND ENABLE_STATIC)
|
|||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set_target_properties(stratagus PROPERTIES LINK_FLAGS "${LINK_FLAGS} -framework libpng -lSDL2main")
|
||||
set_target_properties(stratagus PROPERTIES LINK_FLAGS "${LINK_FLAGS} -lSDL2main")
|
||||
endif()
|
||||
|
||||
########### next target ###############
|
||||
|
@ -1068,6 +1069,9 @@ set(png2stratagus_SRCS
|
|||
)
|
||||
source_group(png2stratagus FILES ${png2stratagus_SRCS})
|
||||
|
||||
set_source_files_properties(png2stratagus_SRCS PROPERTIES INCLUDE_DIRECTORIES "${PNG_INCLUDE_DIR}")
|
||||
set_source_files_properties(png2stratagus_SRCS PROPERTIES COMPILE_DEFINITIONS "${PNG_DEFINITIONS}")
|
||||
|
||||
add_executable(png2stratagus ${png2stratagus_SRCS})
|
||||
target_link_libraries(png2stratagus ${PNG_LIBRARY} ${ZLIB_LIBRARIES})
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
-- Includes
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
#include <png.h>
|
||||
#include "SDL_image.h"
|
||||
|
||||
#include "stratagus.h"
|
||||
|
||||
|
@ -263,42 +263,7 @@ static void LoadStratagusMap(const std::string &smpname, const std::string &mapn
|
|||
// Write a small image of map preview
|
||||
static void WriteMapPreview(const char *mapname, CMap &map)
|
||||
{
|
||||
FILE *fp = fopen(mapname, "wb");
|
||||
if (fp == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (png_ptr == NULL) {
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (info_ptr == NULL) {
|
||||
fclose(fp);
|
||||
png_destroy_write_struct(&png_ptr, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
/* If we get here, we had a problem reading the file */
|
||||
fclose(fp);
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* set up the output control if you are using standard C streams */
|
||||
png_init_io(png_ptr, fp);
|
||||
|
||||
png_set_IHDR(png_ptr, info_ptr, UI.Minimap.W, UI.Minimap.H, 8,
|
||||
PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
|
||||
PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
|
||||
const int rectSize = 5; // size of rectange used for player start spots
|
||||
unsigned char *row = new unsigned char[UI.Minimap.W * 3];
|
||||
const SDL_PixelFormat *fmt = MinimapSurface->format;
|
||||
SDL_Surface *preview = SDL_CreateRGBSurface(SDL_SWSURFACE,
|
||||
UI.Minimap.W, UI.Minimap.H, 32, fmt->Rmask, fmt->Gmask, fmt->Bmask, 0);
|
||||
|
@ -316,41 +281,9 @@ static void WriteMapPreview(const char *mapname, CMap &map)
|
|||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < UI.Minimap.H; ++i) {
|
||||
switch (preview->format->BytesPerPixel) {
|
||||
case 1:
|
||||
for (int j = 0; j < UI.Minimap.W; ++j) {
|
||||
Uint8 c = ((Uint8 *)preview->pixels)[j + i * UI.Minimap.W];
|
||||
row[j * 3 + 0] = fmt->palette->colors[c].r;
|
||||
row[j * 3 + 1] = fmt->palette->colors[c].g;
|
||||
row[j * 3 + 2] = fmt->palette->colors[c].b;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
memcpy(row, (char *)preview->pixels + i * UI.Minimap.W, UI.Minimap.W * 3);
|
||||
break;
|
||||
case 4:
|
||||
for (int j = 0; j < UI.Minimap.W; ++j) {
|
||||
Uint32 c = ((Uint32 *)preview->pixels)[j + i * UI.Minimap.W];
|
||||
row[j * 3 + 0] = ((c & fmt->Rmask) >> fmt->Rshift);
|
||||
row[j * 3 + 1] = ((c & fmt->Gmask) >> fmt->Gshift);
|
||||
row[j * 3 + 2] = ((c & fmt->Bmask) >> fmt->Bshift);
|
||||
}
|
||||
break;
|
||||
}
|
||||
png_write_row(png_ptr, row);
|
||||
}
|
||||
delete[] row;
|
||||
|
||||
SDL_UnlockSurface(preview);
|
||||
IMG_SavePNG(preview, mapname);
|
||||
SDL_FreeSurface(preview);
|
||||
|
||||
png_write_end(png_ptr, info_ptr);
|
||||
|
||||
/* clean up after the write, and free any memory allocated */
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -340,9 +340,6 @@ void DeInitVideo();
|
|||
/// Check if a resolution is valid
|
||||
extern int VideoValidResolution(int w, int h);
|
||||
|
||||
/// Load graphic from PNG file
|
||||
extern int LoadGraphicPNG(CGraphic *g);
|
||||
|
||||
/// Initializes video synchronization.
|
||||
extern void SetVideoSync();
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
#include <map>
|
||||
#include <list>
|
||||
|
||||
#include "SDL_image.h"
|
||||
|
||||
#include "video.h"
|
||||
#include "player.h"
|
||||
#include "intern_video.h"
|
||||
|
@ -564,11 +566,25 @@ void CGraphic::Load(bool grayscale)
|
|||
return;
|
||||
}
|
||||
|
||||
// TODO: More formats?
|
||||
if (LoadGraphicPNG(this) == -1) {
|
||||
fprintf(stderr, "Can't load the graphic '%s'\n", File.c_str());
|
||||
ExitFatal(-1);
|
||||
CFile fp;
|
||||
const std::string name = LibraryFileName(File.c_str());
|
||||
if (name.empty()) {
|
||||
perror("Cannot find file");
|
||||
goto error;
|
||||
}
|
||||
if (fp.open(name.c_str(), CL_OPEN_READ) == -1) {
|
||||
perror("Can't open file");
|
||||
goto error;
|
||||
}
|
||||
Surface = IMG_Load_RW(fp.as_SDL_RWops(), 0);
|
||||
if (Surface == NULL) {
|
||||
fprintf(stderr, "Couldn't load file %s: %s", name.c_str(), IMG_GetError());
|
||||
goto error;
|
||||
}
|
||||
|
||||
GraphicWidth = Surface->w;
|
||||
GraphicHeight = Surface->h;
|
||||
fp.close();
|
||||
|
||||
if (Surface->format->BytesPerPixel == 1) {
|
||||
VideoPaletteListAdd(Surface);
|
||||
|
@ -598,6 +614,11 @@ void CGraphic::Load(bool grayscale)
|
|||
}
|
||||
|
||||
GenFramesMap();
|
||||
return;
|
||||
|
||||
error:
|
||||
fprintf(stderr, "Can't load the graphic '%s'\n", File.c_str());
|
||||
ExitFatal(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
-- Includes
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
#include <png.h>
|
||||
#include "SDL_image.h"
|
||||
|
||||
#include "stratagus.h"
|
||||
#include "map.h"
|
||||
|
@ -49,242 +49,6 @@
|
|||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
** png read callback for CL-IO.
|
||||
**
|
||||
** @param png_ptr png struct pointer.
|
||||
** @param data byte address to read to.
|
||||
** @param length number of bytes to read.
|
||||
*/
|
||||
static void CL_png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
|
||||
{
|
||||
CFile *f = (CFile *)png_get_io_ptr(png_ptr);
|
||||
png_size_t check = (png_size_t)f->read(data, (size_t)length);
|
||||
|
||||
if (check != length) {
|
||||
png_error(png_ptr, "Read Error");
|
||||
}
|
||||
}
|
||||
|
||||
class AutoPng_read_structp
|
||||
{
|
||||
public:
|
||||
explicit AutoPng_read_structp(png_structp png_ptr) : png_ptr(png_ptr), info_ptr(NULL) {}
|
||||
~AutoPng_read_structp() { png_destroy_read_struct(&png_ptr, info_ptr ? &info_ptr : (png_infopp)0, (png_infopp)0); }
|
||||
void setInfo(png_infop info_ptr) { this->info_ptr = info_ptr; }
|
||||
private:
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
};
|
||||
|
||||
/**
|
||||
** Load a png graphic file.
|
||||
** Modified function from SDL_Image
|
||||
**
|
||||
** @param g graphic to load.
|
||||
**
|
||||
** @return 0 for success, -1 for error.
|
||||
*/
|
||||
int LoadGraphicPNG(CGraphic *g)
|
||||
{
|
||||
if (g->File.empty()) {
|
||||
return -1;
|
||||
}
|
||||
const std::string name = LibraryFileName(g->File.c_str());
|
||||
if (name.empty()) {
|
||||
return -1;
|
||||
}
|
||||
CFile fp;
|
||||
|
||||
if (fp.open(name.c_str(), CL_OPEN_READ) == -1) {
|
||||
perror("Can't open file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create the PNG loading context structure
|
||||
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (png_ptr == NULL) {
|
||||
fprintf(stderr, "Couldn't allocate memory for PNG file");
|
||||
return -1;
|
||||
}
|
||||
// Clean png_ptr on exit
|
||||
AutoPng_read_structp pngRaii(png_ptr);
|
||||
|
||||
// Allocate/initialize the memory for image information. REQUIRED.
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (info_ptr == NULL) {
|
||||
fprintf(stderr, "Couldn't create image information for PNG file");
|
||||
return -1;
|
||||
}
|
||||
pngRaii.setInfo(info_ptr);
|
||||
|
||||
/* Set error handling if you are using setjmp/longjmp method (this is
|
||||
* the normal method of doing things with libpng). REQUIRED unless you
|
||||
* set up your own error handlers in png_create_read_struct() earlier.
|
||||
*/
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
fprintf(stderr, "Error reading the PNG file.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Set up the input control */
|
||||
png_set_read_fn(png_ptr, &fp, CL_png_read_data);
|
||||
|
||||
/* Read PNG header info */
|
||||
png_uint_32 width;
|
||||
png_uint_32 height;
|
||||
int bit_depth;
|
||||
int color_type;
|
||||
int interlace_type;
|
||||
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth,
|
||||
&color_type, &interlace_type, NULL, NULL);
|
||||
|
||||
/* tell libpng to strip 16 bit/color files down to 8 bits/color */
|
||||
png_set_strip_16(png_ptr) ;
|
||||
|
||||
/* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
|
||||
* byte into separate bytes (useful for paletted and grayscale images).
|
||||
*/
|
||||
png_set_packing(png_ptr);
|
||||
|
||||
/* scale greyscale values to the range 0..255 */
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY) {
|
||||
png_set_expand(png_ptr);
|
||||
}
|
||||
|
||||
/* For images with a single "transparent colour", set colour key;
|
||||
if more than one index has transparency, or if partially transparent
|
||||
entries exist, use full alpha channel */
|
||||
png_color_16 *transv = NULL;
|
||||
volatile int ckey = -1;
|
||||
|
||||
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
|
||||
int num_trans;
|
||||
png_bytep trans;
|
||||
|
||||
png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &transv);
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||
/* Check if all tRNS entries are opaque except one */
|
||||
int i;
|
||||
int t = -1;
|
||||
for (i = 0; i < num_trans; ++i) {
|
||||
if (trans[i] == 0) {
|
||||
if (t >= 0) {
|
||||
break;
|
||||
}
|
||||
t = i;
|
||||
} else if (trans[i] != 255) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == num_trans) {
|
||||
/* exactly one transparent index */
|
||||
ckey = t;
|
||||
} else {
|
||||
/* more than one transparent index, or translucency */
|
||||
png_set_expand(png_ptr);
|
||||
}
|
||||
} else {
|
||||
ckey = 0; /* actual value will be set later */
|
||||
}
|
||||
}
|
||||
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
|
||||
png_set_gray_to_rgb(png_ptr);
|
||||
}
|
||||
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth,
|
||||
&color_type, &interlace_type, NULL, NULL);
|
||||
|
||||
/* Allocate the SDL surface to hold the image */
|
||||
Uint32 Rmask = 0;
|
||||
Uint32 Gmask = 0;
|
||||
Uint32 Bmask = 0;
|
||||
Uint32 Amask = 0;
|
||||
|
||||
if (color_type != PNG_COLOR_TYPE_PALETTE) {
|
||||
if (SDL_BYTEORDER == SDL_LIL_ENDIAN) {
|
||||
Rmask = 0x000000FF;
|
||||
Gmask = 0x0000FF00;
|
||||
Bmask = 0x00FF0000;
|
||||
Amask = (png_get_channels(png_ptr, info_ptr) == 4) ? 0xFF000000 : 0;
|
||||
} else {
|
||||
const int s = (png_get_channels(png_ptr, info_ptr) == 4) ? 0 : 8;
|
||||
Rmask = 0xFF000000 >> s;
|
||||
Gmask = 0x00FF0000 >> s;
|
||||
Bmask = 0x0000FF00 >> s;
|
||||
Amask = 0x000000FF >> s;
|
||||
}
|
||||
}
|
||||
SDL_Surface *surface =
|
||||
SDL_CreateRGBSurface(SDL_SWSURFACE, width, height,
|
||||
bit_depth * png_get_channels(png_ptr, info_ptr), Rmask, Gmask, Bmask, Amask);
|
||||
if (surface == NULL) {
|
||||
fprintf(stderr, "Out of memory");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create the array of pointers to image data */
|
||||
std::vector<png_bytep> row_pointers;
|
||||
row_pointers.resize(height);
|
||||
|
||||
for (int i = 0; i < (int)height; ++i) {
|
||||
row_pointers[i] = (png_bytep)(Uint8 *)surface->pixels + i * surface->pitch;
|
||||
}
|
||||
|
||||
/* Read the entire image in one go */
|
||||
png_read_image(png_ptr, &row_pointers[0]);
|
||||
|
||||
/* read rest of file, get additional chunks in info_ptr - REQUIRED */
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
|
||||
/* Load the palette, if any */
|
||||
SDL_Palette *palette = surface->format->palette;
|
||||
if (palette) {
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY) {
|
||||
palette->ncolors = 256;
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
palette->colors[i].r = i;
|
||||
palette->colors[i].g = i;
|
||||
palette->colors[i].b = i;
|
||||
palette->colors[i].a = 0xff;
|
||||
}
|
||||
} else {
|
||||
png_colorp pngpalette;
|
||||
int num_palette;
|
||||
png_get_PLTE(png_ptr, info_ptr, &pngpalette, &num_palette);
|
||||
if (num_palette > 0) {
|
||||
palette->ncolors = num_palette;
|
||||
for (int i = 0; i < num_palette; ++i) {
|
||||
palette->colors[i].b = pngpalette[i].blue;
|
||||
palette->colors[i].g = pngpalette[i].green;
|
||||
palette->colors[i].r = pngpalette[i].red;
|
||||
palette->colors[i].a = 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ckey != -1) {
|
||||
if (color_type != PNG_COLOR_TYPE_PALETTE) {
|
||||
/* FIXME: Should these be truncated or shifted down? */
|
||||
ckey = SDL_MapRGB(surface->format, (Uint8)transv->red, (Uint8)transv->green, (Uint8)transv->blue);
|
||||
}
|
||||
SDL_SetColorKey(surface, SDL_TRUE, ckey);
|
||||
}
|
||||
|
||||
g->Surface = surface;
|
||||
g->GraphicWidth = surface->w;
|
||||
g->GraphicHeight = surface->h;
|
||||
|
||||
fp.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
** Save a screenshot to a PNG file.
|
||||
**
|
||||
|
@ -292,86 +56,7 @@ int LoadGraphicPNG(CGraphic *g)
|
|||
*/
|
||||
void SaveScreenshotPNG(const char *name)
|
||||
{
|
||||
FILE *fp = fopen(name, "wb");
|
||||
if (fp == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (png_ptr == NULL) {
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (info_ptr == NULL) {
|
||||
fclose(fp);
|
||||
png_destroy_write_struct(&png_ptr, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
/* If we get here, we had a problem reading the file */
|
||||
fclose(fp);
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* set up the output control if you are using standard C streams */
|
||||
png_init_io(png_ptr, fp);
|
||||
|
||||
int pngw, pngh;
|
||||
pngw = Video.Width;
|
||||
pngh = Video.Height;
|
||||
png_set_IHDR(png_ptr, info_ptr, pngw, pngh, 8,
|
||||
PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
|
||||
PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
Video.LockScreen();
|
||||
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
|
||||
std::vector<unsigned char> row;
|
||||
SDL_PixelFormat *fmt = TheScreen->format;
|
||||
|
||||
row.resize(Video.Width * 3);
|
||||
for (int i = 0; i < Video.Height; ++i) {
|
||||
switch (Video.Depth) {
|
||||
case 15:
|
||||
case 16: {
|
||||
for (int j = 0; j < Video.Width; ++j) {
|
||||
Uint16 c = ((Uint16 *)TheScreen->pixels)[j + i * Video.Width];
|
||||
row[j * 3 + 0] = ((c & fmt->Rmask) >> fmt->Rshift) << fmt->Rloss;
|
||||
row[j * 3 + 1] = ((c & fmt->Gmask) >> fmt->Gshift) << fmt->Gloss;
|
||||
row[j * 3 + 2] = ((c & fmt->Bmask) >> fmt->Bshift) << fmt->Bloss;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 24: {
|
||||
memcpy(&row[0], (char *)TheScreen->pixels + i * Video.Width, Video.Width * 3);
|
||||
break;
|
||||
}
|
||||
case 32: {
|
||||
for (int j = 0; j < Video.Width; ++j) {
|
||||
Uint32 c = ((Uint32 *)TheScreen->pixels)[j + i * Video.Width];
|
||||
row[j * 3 + 0] = ((c & fmt->Rmask) >> fmt->Rshift);
|
||||
row[j * 3 + 1] = ((c & fmt->Gmask) >> fmt->Gshift);
|
||||
row[j * 3 + 2] = ((c & fmt->Bmask) >> fmt->Bshift);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
png_write_row(png_ptr, &row[0]);
|
||||
}
|
||||
|
||||
png_write_end(png_ptr, info_ptr);
|
||||
|
||||
Video.UnlockScreen();
|
||||
|
||||
/* clean up after the write, and free any memory allocated */
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
|
||||
fclose(fp);
|
||||
IMG_SavePNG(TheScreen, name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -386,38 +71,9 @@ void SaveMapPNG(const char *name)
|
|||
return;
|
||||
}
|
||||
|
||||
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (png_ptr == NULL) {
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (info_ptr == NULL) {
|
||||
fclose(fp);
|
||||
png_destroy_write_struct(&png_ptr, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png_ptr))) {
|
||||
/* If we get here, we had a problem reading the file */
|
||||
fclose(fp);
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t imageWidth = Map.Info.MapWidth * PixelTileSize.x;
|
||||
const size_t imageHeight = Map.Info.MapHeight * PixelTileSize.y;
|
||||
|
||||
/* set up the output control if you are using standard C streams */
|
||||
png_init_io(png_ptr, fp);
|
||||
|
||||
png_set_IHDR(png_ptr, info_ptr, imageWidth, imageHeight, 8,
|
||||
PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
|
||||
PNG_FILTER_TYPE_DEFAULT);
|
||||
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
|
||||
SDL_Surface *mapImage = SDL_CreateRGBSurface(SDL_SWSURFACE,
|
||||
imageWidth, imageHeight, 32, RMASK, GMASK, BMASK, 0);
|
||||
|
||||
|
@ -437,26 +93,8 @@ void SaveMapPNG(const char *name)
|
|||
}
|
||||
}
|
||||
|
||||
SDL_LockSurface(mapImage);
|
||||
unsigned char *row = new unsigned char[imageWidth * 3];
|
||||
for (size_t i = 0; i < imageHeight; ++i) {
|
||||
for (size_t j = 0; j < imageWidth; ++j) {
|
||||
Uint32 c = ((Uint32 *)mapImage->pixels)[j + i * imageWidth];
|
||||
row[j * 3 + 0] = ((c & RMASK) >> RSHIFT);
|
||||
row[j * 3 + 1] = ((c & GMASK) >> GSHIFT);
|
||||
row[j * 3 + 2] = ((c & BMASK) >> BSHIFT);
|
||||
}
|
||||
png_write_row(png_ptr, row);
|
||||
}
|
||||
delete[] row;
|
||||
|
||||
png_write_end(png_ptr, info_ptr);
|
||||
|
||||
/* clean up after the write, and free any memory allocated */
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
SDL_UnlockSurface(mapImage);
|
||||
IMG_SavePNG(mapImage, name);
|
||||
SDL_FreeSurface(mapImage);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue