eobish

annotate 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
rev   line source
nuclear@4 1 #include <stdio.h>
nuclear@4 2 #include <stdlib.h>
nuclear@4 3 #include <string.h>
nuclear@4 4 #include <errno.h>
nuclear@4 5 #include "image.h"
nuclear@4 6
nuclear@4 7 #define LOADFAIL(f, m) fprintf(stderr, "failed to load image: %s: %s\n", f, m)
nuclear@4 8
nuclear@4 9 int load_image(struct image *img, const char *fname)
nuclear@4 10 {
nuclear@4 11 static const char *magic = "TILEIMAG";
nuclear@4 12 FILE *fp;
nuclear@4 13 char sig[8];
nuclear@4 14
nuclear@4 15 if(!(fp = fopen(fname, "rb"))) {
nuclear@4 16 LOADFAIL(fname, strerror(errno));
nuclear@4 17 return -1;
nuclear@4 18 }
nuclear@4 19 if(fread(sig, sizeof sig, 1, fp) <= 0 || memcmp(sig, magic, 8) != 0) {
nuclear@4 20 LOADFAIL(fname, "corrupted or empty file");
nuclear@4 21 fclose(fp);
nuclear@4 22 return -1;
nuclear@4 23 }
nuclear@4 24 if(fread(&img->xsz, 4, 1, fp) <= 0 || fread(&img->ysz, 4, 1, fp) <= 0) {
nuclear@4 25 LOADFAIL(fname, "failed to read file header");
nuclear@4 26 fclose(fp);
nuclear@4 27 return -1;
nuclear@4 28 }
nuclear@4 29
nuclear@4 30 if(!(img->pixels = malloc(img->xsz * img->ysz))) {
nuclear@4 31 LOADFAIL(fname, "failed to allocate pixel buffer");
nuclear@4 32 fclose(fp);
nuclear@4 33 return -1;
nuclear@4 34 }
nuclear@4 35 if(fread(img->pixels, 1, img->xsz * img->ysz, fp) < img->xsz * img->ysz) {
nuclear@4 36 LOADFAIL(fname, "unexpected end of file while reading pixels");
nuclear@4 37 fclose(fp);
nuclear@4 38 return -1;
nuclear@4 39 }
nuclear@4 40 fclose(fp);
nuclear@4 41 return 0;
nuclear@4 42 }
nuclear@4 43
nuclear@4 44 void destroy_image(struct image *img)
nuclear@4 45 {
nuclear@4 46 if(img) {
nuclear@4 47 free(img->pixels);
nuclear@4 48 img->pixels = 0;
nuclear@4 49 }
nuclear@4 50 }
nuclear@4 51
nuclear@4 52 int load_palette(struct color *col, const char *fname)
nuclear@4 53 {
nuclear@4 54 FILE *fp;
nuclear@4 55 char buf[128];
nuclear@4 56 int nent = 0;
nuclear@4 57
nuclear@4 58 if(!(fp = fopen(fname, "r"))) {
nuclear@4 59 fprintf(stderr, "failed to open palette file: %s: %s\n", fname, strerror(errno));
nuclear@4 60 return -1;
nuclear@4 61 }
nuclear@4 62
nuclear@4 63 while(fgets(buf, sizeof buf, fp)) {
nuclear@4 64 char *endp, *line = buf;
nuclear@4 65 int r, g, b;
nuclear@4 66
nuclear@4 67 if(!line || !*line) continue;
nuclear@4 68
nuclear@4 69 if(*line == '#') { /* hex html-like values */
nuclear@4 70 unsigned int val = strtol(line + 1, &endp, 16);
nuclear@4 71 if(endp == line) {
nuclear@4 72 fprintf(stderr, "unrecognized line \"%s\" in palette file: %s\n", line, fname);
nuclear@4 73 fclose(fp);
nuclear@4 74 return -1;
nuclear@4 75 }
nuclear@4 76
nuclear@4 77 r = (val >> 16) & 0xff;
nuclear@4 78 g = (val >> 8) & 0xff;
nuclear@4 79 b = val & 0xff;
nuclear@4 80 } else {
nuclear@4 81 fprintf(stderr, "unrecognized line \"%s\" in palette file: %s\n", line, fname);
nuclear@4 82 fclose(fp);
nuclear@4 83 return -1;
nuclear@4 84 }
nuclear@4 85
nuclear@4 86 if(nent >= 256) {
nuclear@4 87 fprintf(stderr, "palette file %s contains more than 256 entries ... skipping the rest\n", fname);
nuclear@4 88 break;
nuclear@4 89 }
nuclear@4 90
nuclear@4 91 col[nent].r = r;
nuclear@4 92 col[nent].g = g;
nuclear@4 93 col[nent].b = b;
nuclear@4 94 nent++;
nuclear@4 95 }
nuclear@4 96
nuclear@4 97 printf("loaded palette: %s (%d colors)\n", fname, nent);
nuclear@4 98
nuclear@4 99 fclose(fp);
nuclear@4 100 return nent;
nuclear@4 101 }
nuclear@4 102
nuclear@4 103 #define MIN(a, b) ((a) < (b) ? (a) : (b))
nuclear@4 104 #define MAX(a, b) ((a) > (b) ? (a) : (b))
nuclear@4 105
nuclear@4 106 void blitkey(struct image *destimg, int dstx, int dsty, struct image *srcimg, int key)
nuclear@4 107 {
nuclear@4 108 int srcx = 0, srcy = 0;
nuclear@4 109 int i, j, width, height;
nuclear@4 110 unsigned char *src, *dst;
nuclear@4 111
nuclear@4 112 if(dstx < 0) {
nuclear@4 113 srcx += -dstx;
nuclear@4 114 dstx = 0;
nuclear@4 115 }
nuclear@4 116 if(dsty < 0) {
nuclear@4 117 srcy += -dsty;
nuclear@4 118 dsty = 0;
nuclear@4 119 }
nuclear@4 120
nuclear@4 121 width = MIN(destimg->xsz - dstx, srcimg->xsz - srcx);
nuclear@4 122 height = MIN(destimg->ysz - dsty, srcimg->ysz - srcy);
nuclear@4 123
nuclear@4 124 if(width <= 0 || height <= 0) return; /* ended up with a zero-area blit */
nuclear@4 125
nuclear@4 126 src = srcimg->pixels + srcy * srcimg->xsz + srcx;
nuclear@4 127 dst = destimg->pixels + dsty * destimg->xsz + dstx;
nuclear@4 128
nuclear@4 129 for(i=0; i<height; i++) {
nuclear@4 130 for(j=0; j<width; j++) {
nuclear@4 131 if(src[j] != key) {
nuclear@4 132 dst[j] = src[j];
nuclear@4 133 }
nuclear@4 134 }
nuclear@4 135 src += srcimg->xsz;
nuclear@4 136 dst += destimg->xsz;
nuclear@4 137 }
nuclear@4 138 }