ref: 7215d13b6c4f253b6d1752a0fa2d0b9a0d16fc1f
parent: ca0e7776d0048f635d68e3b05313c7bc7898ab3b
author: Jonathan Dowland <[email protected]>
date: Thu Jul 14 19:44:16 EDT 2016
Revert using SDL_Image for PNG screenshots This reverts commits 901ee2fe7588fd9dbe62f40b187bcaf364c0fce1 and 07afb7749ff807118431ea356ab56364ef8cfee8. This change broke PNG screenshots on OS X and resulted in 32bit PNGs on other platforms (large file sizes). The former might be a SDL_Image bug, the latter definitely is. Fixes #752
--- a/configure.ac
+++ b/configure.ac
@@ -37,7 +37,6 @@
PKG_CHECK_MODULES(SDL, [sdl2 >= 2.0.1])
PKG_CHECK_MODULES(SDLMIXER, [SDL2_mixer >= 2.0.0])
PKG_CHECK_MODULES(SDLNET, [SDL2_net >= 2.0.0])
-PKG_CHECK_MODULES(SDLIMAGE, [SDL2_image >= 2.0.0])
# Check for libsamplerate.
AC_ARG_WITH([libsamplerate],
@@ -57,10 +56,28 @@
])
])
+# Check for libpng.
+AC_ARG_WITH([libpng],
+AS_HELP_STRING([--without-libpng],
+ [Build without libpng @<:@default=check@:>@]),
+[],
+[
+ [with_libpng=check]
+])
+AS_IF([test "x$with_libpng" != xno], [
+ PKG_CHECK_MODULES(PNG, libpng >= 1.6.10, [
+ AC_DEFINE([HAVE_LIBPNG], [1], [libpng installed])
+ ], [
+ AS_IF([test "x$with_libpng" != xcheck], [AC_MSG_FAILURE(
+ [--with-libpng was given, but test for libpng failed])
+ ])
+ ])
+])
+
# TODO: We currently link everything against libraries that don't need it.
# Use the specific library CFLAGS/LIBS variables instead of setting them here.
-CFLAGS="$CFLAGS $SDL_CFLAGS ${SAMPLERATE_CFLAGS:-}"
-LDFLAGS="$LDFLAGS $SDL_LIBS ${SAMPLERATE_LIBS:-}"
+CFLAGS="$CFLAGS $SDL_CFLAGS ${SAMPLERATE_CFLAGS:-} ${PNG_CFLAGS:-}"
+LDFLAGS="$LDFLAGS $SDL_LIBS ${SAMPLERATE_LIBS:-} ${PNG_LIBS:-}"
AC_CHECK_LIB(m, log)
AC_CHECK_HEADERS([linux/kd.h dev/isa/spkrio.h dev/speaker/speaker.h])
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -21,8 +21,7 @@
AM_CFLAGS = -I$(top_srcdir)/textscreen \
-I$(top_srcdir)/opl \
-I$(top_srcdir)/pcsound \
- @SDLMIXER_CFLAGS@ @SDLNET_CFLAGS@ \
- @SDLIMAGE_CFLAGS@
+ @SDLMIXER_CFLAGS@ @SDLNET_CFLAGS@
# Common source files used by absolutely everything:
@@ -152,8 +151,7 @@
@LDFLAGS@ \
@SDL_LIBS@ \
@SDLMIXER_LIBS@ \
- @SDLNET_LIBS@ \
- @SDLIMAGE_LIBS@
+ @SDLNET_LIBS@
if HAVE_WINDRES
@PROGRAM_PREFIX@doom_SOURCES=$(SOURCE_FILES_WITH_DEH) resource.rc
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -18,7 +18,6 @@
#include "SDL.h"
-#include "SDL_image.h"
#include "SDL_opengl.h"
#ifdef _WIN32
@@ -1283,28 +1282,4 @@
M_BindStringVariable("window_position", &window_position);
M_BindIntVariable("usegamma", &usegamma);
M_BindIntVariable("png_screenshots", &png_screenshots);
-}
-
-void I_SavePNGScreenshot (char *filename)
-{
- if (aspect_ratio_correct)
- {
- const int width = 1600, height = 1200;
- SDL_Surface *shotbuffer;
-
- shotbuffer = SDL_CreateRGBSurface(0, width, height, 32,
- 0x00ff0000,
- 0x0000ff00,
- 0x000000ff,
- 0xff000000);
-
- SDL_BlitScaled(rgbabuffer, NULL, shotbuffer, NULL);
- IMG_SavePNG(shotbuffer, filename);
-
- SDL_FreeSurface(shotbuffer);
- }
- else
- {
- IMG_SavePNG(rgbabuffer, filename);
- }
}
--- a/src/i_video.h
+++ b/src/i_video.h
@@ -78,8 +78,6 @@
void I_EnableLoadingDisk(int xoffs, int yoffs);
-void I_SavePNGScreenshot (char *filename);
-
extern char *video_driver;
extern boolean screenvisible;
--- a/src/setup/display.c
+++ b/src/setup/display.c
@@ -200,8 +200,10 @@
|| gamemission == strife,
TXT_NewCheckBox("Show ENDOOM screen on exit",
&show_endoom)),
+#ifdef HAVE_LIBPNG
TXT_NewCheckBox("Save screenshots in PNG format",
&png_screenshots),
+#endif
NULL);
TXT_SignalConnect(ar_checkbox, "changed", GenerateSizesTable, sizes_table);
--- a/src/v_video.c
+++ b/src/v_video.c
@@ -38,6 +38,9 @@
#include "z_zone.h"
#include "config.h"
+#ifdef HAVE_LIBPNG
+#include <png.h>
+#endif
// TODO: There are separate RANGECHECK defines for different games, but this
// is common code. Fix this.
@@ -701,7 +704,111 @@
Z_Free (pcx);
}
+#ifdef HAVE_LIBPNG
//
+// WritePNGfile
+//
+
+static void error_fn(png_structp p, png_const_charp s)
+{
+ printf("libpng error: %s\n", s);
+}
+
+static void warning_fn(png_structp p, png_const_charp s)
+{
+ printf("libpng warning: %s\n", s);
+}
+
+void WritePNGfile(char *filename, byte *data,
+ int inwidth, int inheight,
+ byte *palette)
+{
+ png_structp ppng;
+ png_infop pinfo;
+ png_colorp pcolor;
+ FILE *handle;
+ int i, j;
+ int width, height;
+ byte *rowbuf;
+
+ // scale up to accommodate aspect ratio correction
+ width = inwidth * 5;
+ height = inheight * 6;
+
+ handle = fopen(filename, "wb");
+ if (!handle)
+ {
+ return;
+ }
+
+ ppng = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,
+ error_fn, warning_fn);
+ if (!ppng)
+ {
+ return;
+ }
+
+ pinfo = png_create_info_struct(ppng);
+ if (!pinfo)
+ {
+ png_destroy_write_struct(&ppng, NULL);
+ return;
+ }
+
+ png_init_io(ppng, handle);
+
+ png_set_IHDR(ppng, pinfo, width, height,
+ 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+
+ pcolor = malloc(sizeof(*pcolor) * 256);
+ if (!pcolor)
+ {
+ png_destroy_write_struct(&ppng, &pinfo);
+ return;
+ }
+
+ for (i = 0; i < 256; i++)
+ {
+ pcolor[i].red = *(palette + 3 * i);
+ pcolor[i].green = *(palette + 3 * i + 1);
+ pcolor[i].blue = *(palette + 3 * i + 2);
+ }
+
+ png_set_PLTE(ppng, pinfo, pcolor, 256);
+ free(pcolor);
+
+ png_write_info(ppng, pinfo);
+
+ rowbuf = malloc(width);
+
+ if (rowbuf)
+ {
+ for (i = 0; i < SCREENHEIGHT; i++)
+ {
+ // expand the row 5x
+ for (j = 0; j < SCREENWIDTH; j++)
+ {
+ memset(rowbuf + j * 5, *(data + i*SCREENWIDTH + j), 5);
+ }
+
+ // write the row 6 times
+ for (j = 0; j < 6; j++)
+ {
+ png_write_row(ppng, rowbuf);
+ }
+ }
+
+ free(rowbuf);
+ }
+
+ png_write_end(ppng, pinfo);
+ png_destroy_write_struct(&ppng, &pinfo);
+ fclose(handle);
+}
+#endif
+
+//
// V_ScreenShot
//
@@ -713,6 +820,7 @@
// find a file name to save it to
+#ifdef HAVE_LIBPNG
extern int png_screenshots;
if (png_screenshots)
{
@@ -719,6 +827,7 @@
ext = "png";
}
else
+#endif
{
ext = "pcx";
}
@@ -738,11 +847,15 @@
I_Error ("V_ScreenShot: Couldn't create a PCX");
}
+#ifdef HAVE_LIBPNG
if (png_screenshots)
{
- I_SavePNGScreenshot(lbmname);
+ WritePNGfile(lbmname, I_VideoBuffer,
+ SCREENWIDTH, SCREENHEIGHT,
+ W_CacheLumpName (DEH_String("PLAYPAL"), PU_CACHE));
}
else
+#endif
{
// save the pcx file
WritePCXfile(lbmname, I_VideoBuffer,