eobish
diff src/image.c @ 4:ce0548d24918
mostly works
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sun, 18 Jan 2015 13:30:30 +0200 (2015-01-18) |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/image.c Sun Jan 18 13:30:30 2015 +0200 1.3 @@ -0,0 +1,138 @@ 1.4 +#include <stdio.h> 1.5 +#include <stdlib.h> 1.6 +#include <string.h> 1.7 +#include <errno.h> 1.8 +#include "image.h" 1.9 + 1.10 +#define LOADFAIL(f, m) fprintf(stderr, "failed to load image: %s: %s\n", f, m) 1.11 + 1.12 +int load_image(struct image *img, const char *fname) 1.13 +{ 1.14 + static const char *magic = "TILEIMAG"; 1.15 + FILE *fp; 1.16 + char sig[8]; 1.17 + 1.18 + if(!(fp = fopen(fname, "rb"))) { 1.19 + LOADFAIL(fname, strerror(errno)); 1.20 + return -1; 1.21 + } 1.22 + if(fread(sig, sizeof sig, 1, fp) <= 0 || memcmp(sig, magic, 8) != 0) { 1.23 + LOADFAIL(fname, "corrupted or empty file"); 1.24 + fclose(fp); 1.25 + return -1; 1.26 + } 1.27 + if(fread(&img->xsz, 4, 1, fp) <= 0 || fread(&img->ysz, 4, 1, fp) <= 0) { 1.28 + LOADFAIL(fname, "failed to read file header"); 1.29 + fclose(fp); 1.30 + return -1; 1.31 + } 1.32 + 1.33 + if(!(img->pixels = malloc(img->xsz * img->ysz))) { 1.34 + LOADFAIL(fname, "failed to allocate pixel buffer"); 1.35 + fclose(fp); 1.36 + return -1; 1.37 + } 1.38 + if(fread(img->pixels, 1, img->xsz * img->ysz, fp) < img->xsz * img->ysz) { 1.39 + LOADFAIL(fname, "unexpected end of file while reading pixels"); 1.40 + fclose(fp); 1.41 + return -1; 1.42 + } 1.43 + fclose(fp); 1.44 + return 0; 1.45 +} 1.46 + 1.47 +void destroy_image(struct image *img) 1.48 +{ 1.49 + if(img) { 1.50 + free(img->pixels); 1.51 + img->pixels = 0; 1.52 + } 1.53 +} 1.54 + 1.55 +int load_palette(struct color *col, const char *fname) 1.56 +{ 1.57 + FILE *fp; 1.58 + char buf[128]; 1.59 + int nent = 0; 1.60 + 1.61 + if(!(fp = fopen(fname, "r"))) { 1.62 + fprintf(stderr, "failed to open palette file: %s: %s\n", fname, strerror(errno)); 1.63 + return -1; 1.64 + } 1.65 + 1.66 + while(fgets(buf, sizeof buf, fp)) { 1.67 + char *endp, *line = buf; 1.68 + int r, g, b; 1.69 + 1.70 + if(!line || !*line) continue; 1.71 + 1.72 + if(*line == '#') { /* hex html-like values */ 1.73 + unsigned int val = strtol(line + 1, &endp, 16); 1.74 + if(endp == line) { 1.75 + fprintf(stderr, "unrecognized line \"%s\" in palette file: %s\n", line, fname); 1.76 + fclose(fp); 1.77 + return -1; 1.78 + } 1.79 + 1.80 + r = (val >> 16) & 0xff; 1.81 + g = (val >> 8) & 0xff; 1.82 + b = val & 0xff; 1.83 + } else { 1.84 + fprintf(stderr, "unrecognized line \"%s\" in palette file: %s\n", line, fname); 1.85 + fclose(fp); 1.86 + return -1; 1.87 + } 1.88 + 1.89 + if(nent >= 256) { 1.90 + fprintf(stderr, "palette file %s contains more than 256 entries ... skipping the rest\n", fname); 1.91 + break; 1.92 + } 1.93 + 1.94 + col[nent].r = r; 1.95 + col[nent].g = g; 1.96 + col[nent].b = b; 1.97 + nent++; 1.98 + } 1.99 + 1.100 + printf("loaded palette: %s (%d colors)\n", fname, nent); 1.101 + 1.102 + fclose(fp); 1.103 + return nent; 1.104 +} 1.105 + 1.106 +#define MIN(a, b) ((a) < (b) ? (a) : (b)) 1.107 +#define MAX(a, b) ((a) > (b) ? (a) : (b)) 1.108 + 1.109 +void blitkey(struct image *destimg, int dstx, int dsty, struct image *srcimg, int key) 1.110 +{ 1.111 + int srcx = 0, srcy = 0; 1.112 + int i, j, width, height; 1.113 + unsigned char *src, *dst; 1.114 + 1.115 + if(dstx < 0) { 1.116 + srcx += -dstx; 1.117 + dstx = 0; 1.118 + } 1.119 + if(dsty < 0) { 1.120 + srcy += -dsty; 1.121 + dsty = 0; 1.122 + } 1.123 + 1.124 + width = MIN(destimg->xsz - dstx, srcimg->xsz - srcx); 1.125 + height = MIN(destimg->ysz - dsty, srcimg->ysz - srcy); 1.126 + 1.127 + if(width <= 0 || height <= 0) return; /* ended up with a zero-area blit */ 1.128 + 1.129 + src = srcimg->pixels + srcy * srcimg->xsz + srcx; 1.130 + dst = destimg->pixels + dsty * destimg->xsz + dstx; 1.131 + 1.132 + for(i=0; i<height; i++) { 1.133 + for(j=0; j<width; j++) { 1.134 + if(src[j] != key) { 1.135 + dst[j] = src[j]; 1.136 + } 1.137 + } 1.138 + src += srcimg->xsz; 1.139 + dst += destimg->xsz; 1.140 + } 1.141 +}