git.strcat.st

/strcat/ss.git/ - summarytreelogarchive

subject
add libpng patch
commit
bf54fa744531a7f2f34de98e07d4a0052e6dcb20
date
2026-04-21T03:08:46Z
message
diff
 patches/libpng.patch | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 152 insertions(+)

diff --git a/patches/libpng.patch b/patches/libpng.patch
new file mode 100644
index 0000000..20ce87f
--- /dev/null
+++ b/patches/libpng.patch
@@ -0,0 +1,152 @@
+--- a/ss.c
++++ b/ss.c
+@@ -1,8 +1,11 @@
+ #include <X11/Xlib.h>
+ #include <X11/Xutil.h>
+ 
++#include <png.h>
++
+ #include <stdio.h>
+ #include <stdlib.h>
++#include <string.h>
+ 
+ static unsigned long
+ lowbit(unsigned long x)
+@@ -27,6 +30,69 @@
+ 	return (unsigned char)((v * 255UL + (max / 2UL)) / max);
+ }
+ 
++static int
++haspngext(const char *path)
++{
++	size_t n;
++
++	n = strlen(path);
++	if (n < 4)
++	    return 0;
++	return !strcmp(path + n - 4, ".png");
++}
++
++static int
++writepng(FILE *f, XImage *img, unsigned int w, unsigned int h)
++{
++	png_structp png;
++	png_infop info;
++	unsigned char *row;
++	int ix;
++	int iy;
++
++	png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
++	if (png == NULL)
++	    return 0;
++	info = png_create_info_struct(png);
++	if (info == NULL) {
++	    png_destroy_write_struct(&png, NULL);
++	    return 0;
++	}
++	if (setjmp(png_jmpbuf(png))) {
++	    png_destroy_write_struct(&png, &info);
++	    return 0;
++	}
++
++	png_init_io(png, f);
++	png_set_IHDR(png, info, w, h, 8,
++	    PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
++	    PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
++	png_write_info(png, info);
++
++	row = malloc((size_t)w * 3U);
++	if (row == NULL) {
++	    png_destroy_write_struct(&png, &info);
++	    return 0;
++	}
++
++	for (iy = 0; iy < (int)h; iy++) {
++	    for (ix = 0; ix < (int)w; ix++) {
++	        unsigned long p;
++
++	        p = XGetPixel(img, ix, iy);
++	        row[ix * 3 + 0] = chan(p, img->red_mask);
++	        row[ix * 3 + 1] = chan(p, img->green_mask);
++	        row[ix * 3 + 2] = chan(p, img->blue_mask);
++	    }
++	    png_write_row(png, row);
++	}
++
++	png_write_end(png, info);
++	free(row);
++	png_destroy_write_struct(&png, &info);
++	return 1;
++}
++
+ int
+ main(int argc, char **argv)
+ {
+@@ -45,7 +111,7 @@
+ 	char tail;
+ 
+ 	if (argc != 3) {
+-	    fprintf(stderr, "usage: ss WIDTHxHEIGHT+X+Y file.ppm\n");
++	    fprintf(stderr, "usage: ss WIDTHxHEIGHT+X+Y file.(ppm|png)\n");
+ 	    return 1;
+ 	}
+ 	if (sscanf(argv[1], "%ux%u+%d+%d%c", &w, &h, &x, &y, &tail) != 4 || w == 0 || h == 0) {
+@@ -81,22 +147,32 @@
+ 	    return 1;
+ 	}
+ 
+-	fprintf(f, "P6\n%u %u\n255\n", w, h);
+-	for (iy = 0; iy < (int)h; iy++) {
+-	    for (ix = 0; ix < (int)w; ix++) {
+-	        unsigned long p;
+-	        unsigned char rgb[3];
++	if (haspngext(argv[2])) {
++	    if (!writepng(f, img, w, h)) {
++	        fprintf(stderr, "png write failed: %s\n", argv[2]);
++	        fclose(f);
++	        XDestroyImage(img);
++	        XCloseDisplay(dpy);
++	        return 1;
++	    }
++	} else {
++	    fprintf(f, "P6\n%u %u\n255\n", w, h);
++	    for (iy = 0; iy < (int)h; iy++) {
++	        for (ix = 0; ix < (int)w; ix++) {
++	            unsigned long p;
++	            unsigned char rgb[3];
+ 
+-	        p = XGetPixel(img, ix, iy);
+-	        rgb[0] = chan(p, img->red_mask);
+-	        rgb[1] = chan(p, img->green_mask);
+-	        rgb[2] = chan(p, img->blue_mask);
+-	        if (fwrite(rgb, 1, 3, f) != 3) {
+-	            fprintf(stderr, "write failed: %s\n", argv[2]);
+-	            fclose(f);
+-	            XDestroyImage(img);
+-	            XCloseDisplay(dpy);
+-	            return 1;
++	            p = XGetPixel(img, ix, iy);
++	            rgb[0] = chan(p, img->red_mask);
++	            rgb[1] = chan(p, img->green_mask);
++	            rgb[2] = chan(p, img->blue_mask);
++	            if (fwrite(rgb, 1, 3, f) != 3) {
++	                fprintf(stderr, "write failed: %s\n", argv[2]);
++	                fclose(f);
++	                XDestroyImage(img);
++	                XCloseDisplay(dpy);
++	                return 1;
++	            }
+ 	        }
+ 	    }
+ 	}
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ CFLAGS   = -std=c89 -Wall -Wextra -Werror -pedantic
+ CPPFLAGS = -I/usr/X11R6/include
+ LDFLAGS  = -L/usr/X11R6/lib
+-LDLIBS   = -lX11
++LDLIBS   = -lX11 -lpng
+ 
+ all: ss 
+