eobish
diff utils/tileproc.c @ 5:0baf4e98315e
depth cueing
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 19 Jan 2015 02:32:01 +0200 |
parents | 465ca72c9657 |
children |
line diff
1.1 --- a/utils/tileproc.c Sun Jan 18 13:30:30 2015 +0200 1.2 +++ b/utils/tileproc.c Mon Jan 19 02:32:01 2015 +0200 1.3 @@ -1,6 +1,7 @@ 1.4 #include <stdio.h> 1.5 #include <stdlib.h> 1.6 #include <string.h> 1.7 +#include <ctype.h> 1.8 #include <math.h> 1.9 #include <float.h> 1.10 #include <errno.h> 1.11 @@ -16,16 +17,22 @@ 1.12 struct palentry *next; 1.13 }; 1.14 1.15 +void print_usage(const char *argv0); 1.16 int load_palette(const char *fname); 1.17 +int save_palette(const char *fname); 1.18 int proc_tile(const char *fname); 1.19 float find_nearest(float r, float g, float b); 1.20 1.21 struct palentry *palette; 1.22 int palsize; 1.23 +float colscale[10] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; 1.24 +int scale_count = 0; 1.25 +int key = -1; 1.26 1.27 int main(int argc, char **argv) 1.28 { 1.29 int i; 1.30 + const char *outpalname = 0; 1.31 1.32 for(i=1; i<argc; i++) { 1.33 if(argv[i][0] == '-') { 1.34 @@ -36,8 +43,45 @@ 1.35 } 1.36 break; 1.37 1.38 + case 'P': 1.39 + outpalname = argv[++i]; 1.40 + break; 1.41 + 1.42 + case 'f': 1.43 + { 1.44 + int idx, maxcol; 1.45 + if(sscanf(argv[++i], "%d=%d", &idx, &maxcol) != 2) { 1.46 + fprintf(stderr, "-f option expects <Z>=<MAX COLOR> pairs\n"); 1.47 + return 1; 1.48 + } 1.49 + if(idx < 0 || idx >= 10) { 1.50 + fprintf(stderr, "-f expects a z value from 0 to 9\n"); 1.51 + return 1; 1.52 + } 1.53 + colscale[idx] = (float)maxcol / 255.0; 1.54 + if(idx >= scale_count) scale_count = idx + 1; 1.55 + } 1.56 + break; 1.57 + 1.58 + case 'k': 1.59 + { 1.60 + char *endp; 1.61 + long x = strtol(argv[++i], &endp, 10); 1.62 + if(endp == argv[i]) { 1.63 + fprintf(stderr, "-k must be followed by a palette index\n"); 1.64 + return 1; 1.65 + } 1.66 + key = x; 1.67 + } 1.68 + break; 1.69 + 1.70 + case 'h': 1.71 + print_usage(argv[0]); 1.72 + return 0; 1.73 + 1.74 default: 1.75 fprintf(stderr, "invalid option: %s\n", argv[i]); 1.76 + print_usage(argv[0]); 1.77 return 1; 1.78 } 1.79 } else { 1.80 @@ -46,9 +90,27 @@ 1.81 } 1.82 } 1.83 } 1.84 + 1.85 + if(outpalname) { 1.86 + if(save_palette(outpalname) == -1) { 1.87 + fprintf(stderr, "failed to write extended palette: %s\n", outpalname); 1.88 + return 1; 1.89 + } 1.90 + } 1.91 + 1.92 return 0; 1.93 } 1.94 1.95 +void print_usage(const char *argv0) 1.96 +{ 1.97 + printf("Usage: %s <options> [img1 img2 img3 ... imgN]\n", argv0); 1.98 + printf("Options:\n"); 1.99 + printf(" -p <file> use palette from file\n"); 1.100 + printf(" -f <z>=<b> darken the image (max brightness 'b') based on the digit (z) in its filename\n"); 1.101 + printf(" -k <idx> colorkey index (preserve this color regardless of depth cues)\n"); 1.102 + printf(" -h print usage and exit\n"); 1.103 +} 1.104 + 1.105 int load_palette(const char *fname) 1.106 { 1.107 FILE *fp; 1.108 @@ -133,6 +195,40 @@ 1.109 return -1; 1.110 } 1.111 1.112 +int save_palette(const char *fname) 1.113 +{ 1.114 + FILE *fp; 1.115 + int i, j; 1.116 + int extsize = palsize * scale_count; 1.117 + 1.118 + printf("saving extended palette: %s\n", fname); 1.119 + 1.120 + if(!(fp = fopen(fname, "w"))) { 1.121 + fprintf(stderr, "failed to save extended palette: %s: %s\n", fname, strerror(errno)); 1.122 + return -1; 1.123 + } 1.124 + 1.125 + if(extsize > 256) { 1.126 + fprintf(stderr, "warning: extended palette size too large (%d)\n", extsize); 1.127 + } 1.128 + 1.129 + for(i=0; i<scale_count; i++) { 1.130 + for(j=0; j<palsize; j++) { 1.131 + int r = (int)(palette[j].r * colscale[i] * 255.0); 1.132 + int g = (int)(palette[j].g * colscale[i] * 255.0); 1.133 + int b = (int)(palette[j].b * colscale[i] * 255.0); 1.134 + 1.135 + if(r > 255) r = 255; 1.136 + if(g > 255) g = 255; 1.137 + if(b > 255) b = 255; 1.138 + 1.139 + fprintf(fp, "#%02x%02x%02x\n", r, g, b); 1.140 + } 1.141 + } 1.142 + fclose(fp); 1.143 + return 0; 1.144 +} 1.145 + 1.146 int proc_tile(const char *fname) 1.147 { 1.148 int i; 1.149 @@ -141,6 +237,7 @@ 1.150 char *outfname, *cptr; 1.151 FILE *fp; 1.152 const char *magic = "TILEIMAG"; 1.153 + int zidx = -1; 1.154 1.155 outfname = alloca(strlen(fname) + 4); 1.156 strcpy(outfname, fname); 1.157 @@ -149,6 +246,12 @@ 1.158 } 1.159 strcat(outfname, ".til"); 1.160 1.161 + cptr = outfname + strlen(outfname) - 1; 1.162 + while(cptr >= outfname && !isdigit(*cptr)) --cptr; 1.163 + if(cptr >= outfname) { 1.164 + zidx = *cptr - '0'; 1.165 + } 1.166 + 1.167 printf("processing tile: %s -> %s\n", fname, outfname); 1.168 1.169 if(!(pixels = img_load_pixels(fname, &xsz, &ysz, IMG_FMT_RGB24))) { 1.170 @@ -168,6 +271,12 @@ 1.171 pptr = pixels; 1.172 for(i=0; i<xsz * ysz; i++) { 1.173 int idx = find_nearest(pptr[0] / 255.0, pptr[1] / 255.0, pptr[2] / 255.0); 1.174 + 1.175 + if(zidx > 0 && idx != key) { 1.176 + /* shift the indices to the appropriate copy of the palette */ 1.177 + idx += zidx * palsize; 1.178 + } 1.179 + 1.180 fputc(idx, fp); 1.181 pptr += 3; 1.182 }