Created
July 27, 2023 13:17
-
-
Save marendowski/8aeff776caae41be9e96a7c3a2380b36 to your computer and use it in GitHub Desktop.
C demo displaying a PNG image on X server using Xlib and libspng libraries
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* requires Xlib and libspng * | |
* gcc -o demo demo.c -l X11 -l spng -g */ | |
#include <stdio.h> | |
#include <string.h> | |
#include <X11/Xlib.h> | |
#include <spng.h> | |
unsigned char *process_png_image(char *filename); | |
int main(void) | |
{ | |
XImage *ximage; | |
/* defaults */ | |
int width = 64; | |
int height = 64; | |
char *filename = "firefox.png"; | |
char *path = "/usr/share/icons/hicolor/64x64/apps/"; | |
char full_path[strlen(path) + strlen(filename) + 1]; | |
strcpy(full_path, path); | |
strcat(full_path, filename); | |
/* get everything set up */ | |
Display *display = XOpenDisplay(NULL); | |
Visual *visual = DefaultVisual(display, 0); | |
Window window = XCreateSimpleWindow(display, RootWindow(display, 0), 0, 0, width, height, 1, 0, 0); | |
/* get image */ | |
ximage = XCreateImage(display, visual, DefaultDepth(display,DefaultScreen(display)), ZPixmap, 0, process_png_image(full_path), width, height, 32, 0); | |
XMapWindow(display, window); | |
while (1) { | |
/* draw image */ | |
XPutImage(display, window, DefaultGC(display, 0), ximage, 0, 0, 0, 20, width, height); | |
/* draw text */ | |
XSetForeground(display, DefaultGC(display, 0), 0xffffffff); /* set white foreground for text */ | |
XDrawString(display, window, DefaultGC(display, 0), 10, 15, full_path, strlen(full_path)); | |
} | |
return 0; | |
} | |
unsigned char *process_png_image(char *filename) | |
{ | |
FILE *png; | |
int i; | |
spng_ctx *ctx = NULL; | |
unsigned char *image32 = NULL, *p, temp; | |
size_t image_size; | |
png = fopen(filename, "rb"); | |
if (png == NULL) | |
fprintf(stderr, "error while opening %s\n", filename); | |
ctx = spng_ctx_new(0); | |
if (ctx == NULL) | |
fprintf(stderr, "spng_ctx_new() failed\n"); | |
/* Ignore and don't calculate chunk CRC's */ | |
spng_set_crc_action(ctx, SPNG_CRC_USE, SPNG_CRC_USE); | |
/* Set memory usage limits for storing standard and unknown chunks, | |
this is important when reading untrusted files! */ | |
size_t limit = 1024 * 1024 * 32; | |
spng_set_chunk_limits(ctx, limit, limit); | |
/* Set source PNG */ | |
spng_set_png_file(ctx, png); /* or _buffer(), _stream() */ | |
/* Get image header | |
* return non-zero if fail */ | |
struct spng_ihdr ihdr; | |
if (spng_get_ihdr(ctx, &ihdr)) | |
fprintf(stderr, "spng_get_ihdr() error\n"); | |
/* get image size */ | |
if (spng_decoded_image_size(ctx, SPNG_FMT_RGBA8, &image_size)) | |
fprintf(stderr, "spng_decoded_image_size() error\n"); | |
/* allocate image */ | |
image32 = malloc(image_size); | |
/* Decode the image in one go | |
* return non-zero if fail */ | |
if (spng_decode_image(ctx, image32, image_size, SPNG_FMT_PNG, 0)) | |
fprintf(stderr, "spng_decode_image() error\n"); | |
/* perform a byteswap to swap red and blue colors | |
* every pixel is 4 bytes long (RGBA) */ | |
p = image32; | |
for (i = 0; i < image_size; i += 4) | |
{ | |
temp = p[i]; | |
p[i] = p[i + 2]; /* replace the red byte with the blue byte */ | |
p[i + 2] = temp; /* replace the blue byte with the red byte */ | |
} | |
return image32; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment