sprite.c (1773B)
1 #include <err.h> 2 #include <stdio.h> 3 #include <math.h> 4 5 #define STB_IMAGE_IMPLEMENTATION 6 #include "stb_image.h" 7 #define STB_IMAGE_WRITE_IMPLEMENTATION 8 #include "stb_image_write.h" 9 10 struct rect { 11 int x; 12 int y; 13 }; 14 15 int main(int argc, char *argv[]) { 16 if (argc < 3) { 17 fprintf(stderr, "usage: %s out.png file [...]\n", argv[0]); 18 exit(2); 19 } 20 21 int n = argc - 2; 22 unsigned char **images = calloc(n, sizeof(*images)); 23 struct rect *rects = calloc(n, sizeof(struct rect)); 24 25 int width = 0; 26 int height = 0; 27 for (int i = 0; i < n; i++) { 28 int bits; 29 char *fname = argv[i + 2]; 30 images[i] = stbi_load(fname, &rects[i].x, &rects[i].y, &bits, 4); 31 if (!images[i]) 32 err(1, "load %s: %s", fname, stbi_failure_reason()); 33 width += rects[i].x; 34 if (rects[i].y > height) 35 height = rects[i].y; 36 } 37 38 unsigned char *sheet = calloc(width * height * 4, 1); 39 if (!sheet) 40 err(1, "allocate sheet"); 41 42 int xoff = 0; 43 for (int i = 0; i < n; i++) { 44 for (int rownum = 0; rownum < rects[i].y; rownum++) { 45 size_t rowlen = rects[i].x*4; 46 unsigned char *row = images[i] + rowlen * rownum; 47 unsigned char *dst = sheet + ((size_t)width * rownum + xoff) * 4; 48 memcpy(dst, row, rowlen); 49 } 50 xoff += rects[i].x; 51 } 52 53 int ok = stbi_write_png(argv[1], width, height, 4, sheet, width*4); 54 if (!ok) 55 err(1, "write %s", argv[1]); 56 return 0; 57 }