foxygit / doom Log in
commit 787ab13a1e7fb5054a082cd0278c125f925e6664
Author:     Jonathan Dowland <jon+github@alcopop.org>
AuthorDate: Wed Jul 15 22:15:42 2015 +0100
Commit:     Jonathan Dowland <jon+github@alcopop.org>
CommitDate: Wed Jul 15 22:22:53 2015 +0100

    Write out aspect-corrected 1600x1200  PNGs

    When writing out PNG screenshots, write out a 1600x1200 PNG with
    aspect correction applied.

    1600x1200 is the smallest size necessary to do this losslessly:
    each pixel is repeated 5 times per row and each row is repeated
    6 times.

    The resulting shots are still smaller than their PCX equivalents.
    For the Doom 1 titlepic, 320x200 PCX is 77K, 1600x1200 PNG 65k.

    Thanks to Simon, Alex and Andrew for discussing the approach taken;
    Fabian, Mike and Alexandre-Xavier for further discussion.
---
 src/v_video.c | 31 +++++++++++++++++++++++++++----
 1 file changed, 27 insertions(+), 4 deletions(-)

diff --git a/src/v_video.c b/src/v_video.c
index 16350d82..30521c4a 100644
--- a/src/v_video.c
+++ b/src/v_video.c
@@ -719,14 +719,20 @@ static void warning_fn(png_structp p, png_const_charp s)
 }

 void WritePNGfile(char *filename, byte *data,
-                  int width, int height,
+                  int inwidth, int inheight,
                   byte *palette)
 {
     png_structp ppng;
     png_infop pinfo;
     png_colorp pcolor;
     FILE *handle;
-    int i;
+    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)
@@ -773,9 +779,26 @@ void WritePNGfile(char *filename, byte *data,

     png_write_info(ppng, pinfo);

-    for (i = 0; i < SCREENHEIGHT; i++)
+    rowbuf = malloc(width);
+
+    if (rowbuf)
     {
-        png_write_row(ppng, data + i*SCREENWIDTH);
+        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);