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
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 +}