rev |
line source |
nuclear@0
|
1 #include <stdio.h>
|
nuclear@0
|
2 #include <stdlib.h>
|
nuclear@0
|
3 #include <string.h>
|
nuclear@4
|
4 #include <assert.h>
|
nuclear@0
|
5 #include <errno.h>
|
nuclear@0
|
6 #include "image.h"
|
nuclear@0
|
7
|
nuclear@0
|
8 static int proc_image(const char *fname);
|
nuclear@0
|
9 static const char *modestr(int cmode);
|
nuclear@0
|
10 static void output_planar(FILE *fp, struct image *img);
|
nuclear@4
|
11 static void output_linear(FILE *fp, struct image *img);
|
nuclear@4
|
12 static void output_palette(FILE *fp, struct image *img, int pcol_bits);
|
nuclear@0
|
13
|
nuclear@0
|
14 static int planar = 0;
|
nuclear@4
|
15 static int pcol_bits = 8;
|
nuclear@4
|
16 static int verbose = 0;
|
nuclear@0
|
17
|
nuclear@0
|
18 int main(int argc, char **argv)
|
nuclear@0
|
19 {
|
nuclear@0
|
20 int i;
|
nuclear@0
|
21
|
nuclear@0
|
22 for(i=1; i<argc; i++) {
|
nuclear@0
|
23 if(argv[i][0] == '-') {
|
nuclear@0
|
24 if(argv[i][2] == 0) {
|
nuclear@0
|
25 switch(argv[i][1]) {
|
nuclear@4
|
26 case 'a':
|
nuclear@4
|
27 planar = 1;
|
nuclear@4
|
28 pcol_bits = 4;
|
nuclear@4
|
29 break;
|
nuclear@4
|
30
|
nuclear@0
|
31 case 'p':
|
nuclear@0
|
32 planar = 1;
|
nuclear@0
|
33 break;
|
nuclear@0
|
34
|
nuclear@4
|
35 case 'l':
|
nuclear@0
|
36 planar = 0;
|
nuclear@0
|
37 break;
|
nuclear@0
|
38
|
nuclear@4
|
39 case 'v':
|
nuclear@4
|
40 verbose = 1;
|
nuclear@4
|
41 break;
|
nuclear@4
|
42
|
nuclear@0
|
43 case 'h':
|
nuclear@0
|
44 printf("usage: %s [options] <file 1> <file 2> ... <file n>\n", argv[0]);
|
nuclear@0
|
45 printf("Options:\n");
|
nuclear@4
|
46 printf(" -a: amiga mode (4bit palette colors & planar format)\n");
|
nuclear@4
|
47 printf(" -p: output image in planar format\n");
|
nuclear@4
|
48 printf(" -c: output image in linear (chunky) format\n");
|
nuclear@4
|
49 printf(" -v: verbose output\n");
|
nuclear@0
|
50 printf(" -h: print usage and exit\n");
|
nuclear@0
|
51 return 0;
|
nuclear@0
|
52
|
nuclear@0
|
53 default:
|
nuclear@0
|
54 fprintf(stderr, "invalid option: %s\n", argv[i]);
|
nuclear@0
|
55 return 1;
|
nuclear@0
|
56 }
|
nuclear@0
|
57 } else {
|
nuclear@0
|
58 fprintf(stderr, "invalid option: %s\n", argv[i]);
|
nuclear@0
|
59 }
|
nuclear@0
|
60 } else {
|
nuclear@0
|
61 if(proc_image(argv[i]) == -1) {
|
nuclear@0
|
62 return 1;
|
nuclear@0
|
63 }
|
nuclear@0
|
64 }
|
nuclear@0
|
65 }
|
nuclear@0
|
66 return 0;
|
nuclear@0
|
67 }
|
nuclear@0
|
68
|
nuclear@0
|
69 static int proc_image(const char *fname)
|
nuclear@0
|
70 {
|
nuclear@0
|
71 int i;
|
nuclear@0
|
72 struct image img;
|
nuclear@0
|
73 char *outfname, *suffix;
|
nuclear@0
|
74 FILE *fp;
|
nuclear@0
|
75
|
nuclear@0
|
76 if(load_image(&img, fname) == -1) {
|
nuclear@0
|
77 fprintf(stderr, "failed to load image: %s\n", fname);
|
nuclear@0
|
78 return -1;
|
nuclear@0
|
79 }
|
nuclear@0
|
80
|
nuclear@0
|
81 if(!(outfname = malloc(strlen(fname) + 4))) {
|
nuclear@0
|
82 perror("failed to allocate output filename");
|
nuclear@0
|
83 return -1;
|
nuclear@0
|
84 }
|
nuclear@0
|
85 strcpy(outfname, fname);
|
nuclear@0
|
86 if(!(suffix = strrchr(outfname, '.'))) {
|
nuclear@0
|
87 suffix = outfname + strlen(outfname);
|
nuclear@0
|
88 }
|
nuclear@4
|
89 strcpy(suffix, ".img");
|
nuclear@0
|
90
|
nuclear@4
|
91 if(verbose) {
|
nuclear@4
|
92 printf("processing %s -> %s\n", fname, outfname);
|
nuclear@4
|
93 }
|
nuclear@0
|
94
|
nuclear@0
|
95 if(!(fp = fopen(outfname, "wb"))) {
|
nuclear@0
|
96 fprintf(stderr, "failed to open output file: %s: %s\n", outfname, strerror(errno));
|
nuclear@0
|
97 destroy_image(&img);
|
nuclear@0
|
98 free(outfname);
|
nuclear@0
|
99 return -1;
|
nuclear@0
|
100 }
|
nuclear@0
|
101
|
nuclear@4
|
102 if(verbose) {
|
nuclear@6
|
103 printf(" size: %dx%d\n", img.width, img.height);
|
nuclear@4
|
104 printf(" bits per pixel: %d (%d colors)\n", img.bpp, 1 << img.bpp);
|
nuclear@4
|
105 if(img.num_ranges) {
|
nuclear@4
|
106 printf(" color ranges:\n");
|
nuclear@4
|
107 for(i=0; i<img.num_ranges; i++) {
|
nuclear@4
|
108 printf(" [%d]: %d - %d, rate: %u, mode: %s\n", i, img.range[i].low, img.range[i].high,
|
nuclear@4
|
109 img.range[i].rate, modestr(img.range[i].cmode));
|
nuclear@4
|
110 }
|
nuclear@0
|
111 }
|
nuclear@0
|
112 }
|
nuclear@0
|
113
|
nuclear@0
|
114 if(planar) {
|
nuclear@4
|
115 if(verbose) printf(" writing planar pixels\n");
|
nuclear@0
|
116 output_planar(fp, &img);
|
nuclear@0
|
117 } else {
|
nuclear@4
|
118 if(verbose) printf(" writing linear pixels\n");
|
nuclear@4
|
119 output_linear(fp, &img);
|
nuclear@4
|
120 }
|
nuclear@4
|
121 fclose(fp);
|
nuclear@4
|
122
|
nuclear@4
|
123 /* open fname.pal */
|
nuclear@4
|
124 strcpy(outfname, fname);
|
nuclear@4
|
125 if(!(suffix = strrchr(outfname, '.'))) {
|
nuclear@4
|
126 suffix = outfname + strlen(outfname);
|
nuclear@4
|
127 }
|
nuclear@4
|
128 strcpy(suffix, ".pal");
|
nuclear@4
|
129
|
nuclear@4
|
130 if(!(fp = fopen(outfname, "wb"))) {
|
nuclear@4
|
131 fprintf(stderr, "failed to open palette file %s for writing: %s\n",
|
nuclear@4
|
132 outfname, strerror(errno));
|
nuclear@4
|
133 free(outfname);
|
nuclear@4
|
134 destroy_image(&img);
|
nuclear@4
|
135 return -1;
|
nuclear@0
|
136 }
|
nuclear@0
|
137
|
nuclear@4
|
138 if(verbose) {
|
nuclear@4
|
139 printf(" writing %d bit palette colors\n", pcol_bits);
|
nuclear@4
|
140 output_palette(fp, &img, pcol_bits);
|
nuclear@4
|
141 }
|
nuclear@4
|
142
|
nuclear@4
|
143 fclose(fp);
|
nuclear@0
|
144 free(outfname);
|
nuclear@0
|
145 destroy_image(&img);
|
nuclear@0
|
146 return 0;
|
nuclear@0
|
147 }
|
nuclear@0
|
148
|
nuclear@0
|
149 static void output_planar(FILE *fp, struct image *img)
|
nuclear@0
|
150 {
|
nuclear@0
|
151 int i, x, y;
|
nuclear@0
|
152 unsigned char acc = 0;
|
nuclear@0
|
153 int acc_bit = 7;
|
nuclear@0
|
154 unsigned char *pptr = img->pixels;
|
nuclear@0
|
155
|
nuclear@0
|
156 for(i=0; i<img->bpp; i++) {
|
nuclear@0
|
157 for(y=0; y<img->height; y++) {
|
nuclear@0
|
158 for(x=0; x<img->width; x++) {
|
nuclear@4
|
159 acc |= (((*pptr >> i) & 1) << acc_bit);
|
nuclear@0
|
160 if(--acc_bit == 0) {
|
nuclear@0
|
161 fputc(acc, fp);
|
nuclear@0
|
162 acc_bit = 7;
|
nuclear@0
|
163 acc = 0;
|
nuclear@4
|
164 ++pptr;
|
nuclear@0
|
165 }
|
nuclear@0
|
166 }
|
nuclear@0
|
167 }
|
nuclear@0
|
168 }
|
nuclear@0
|
169 }
|
nuclear@0
|
170
|
nuclear@4
|
171 static void output_linear(FILE *fp, struct image *img)
|
nuclear@0
|
172 {
|
nuclear@0
|
173 int i, j;
|
nuclear@0
|
174 unsigned char *pptr = img->pixels;
|
nuclear@0
|
175
|
nuclear@0
|
176 for(i=0; i<img->height; i++) {
|
nuclear@0
|
177 for(j=0; j<img->width; j++) {
|
nuclear@0
|
178 fputc(*pptr++, fp);
|
nuclear@0
|
179 }
|
nuclear@0
|
180 }
|
nuclear@0
|
181 }
|
nuclear@0
|
182
|
nuclear@4
|
183 static void output_palette(FILE *fp, struct image *img, int pcol_bits)
|
nuclear@4
|
184 {
|
nuclear@4
|
185 int i, num_colors;
|
nuclear@4
|
186
|
nuclear@4
|
187 num_colors = 1 << img->bpp;
|
nuclear@4
|
188
|
nuclear@4
|
189 assert(pcol_bits == 8 || pcol_bits == 4);
|
nuclear@4
|
190
|
nuclear@4
|
191 if(pcol_bits == 8) {
|
nuclear@4
|
192 for(i=0; i<num_colors; i++) {
|
nuclear@4
|
193 fputc(img->palette[i].r, fp);
|
nuclear@4
|
194 fputc(img->palette[i].g, fp);
|
nuclear@4
|
195 fputc(img->palette[i].b, fp);
|
nuclear@4
|
196 }
|
nuclear@4
|
197 } else {
|
nuclear@4
|
198 /* nibble colors */
|
nuclear@4
|
199 for(i=0; i<num_colors; i++) {
|
nuclear@4
|
200 fputc(img->palette[i].b | (img->palette[i].g << 4), fp);
|
nuclear@4
|
201 fputc(img->palette[i].r, fp);
|
nuclear@4
|
202 }
|
nuclear@4
|
203 }
|
nuclear@4
|
204 }
|
nuclear@4
|
205
|
nuclear@0
|
206 static const char *modestr(int cmode)
|
nuclear@0
|
207 {
|
nuclear@0
|
208 switch(cmode) {
|
nuclear@0
|
209 case CYCLE_NORMAL:
|
nuclear@0
|
210 return "forward";
|
nuclear@0
|
211 case CYCLE_REVERSE:
|
nuclear@0
|
212 return "reverse";
|
nuclear@0
|
213 case CYCLE_PINGPONG:
|
nuclear@0
|
214 return "ping-pong";
|
nuclear@0
|
215 case CYCLE_SINE_HALF:
|
nuclear@0
|
216 return "half-sine";
|
nuclear@0
|
217 case CYCLE_SINE:
|
nuclear@0
|
218 return "sine";
|
nuclear@0
|
219 default:
|
nuclear@0
|
220 break;
|
nuclear@0
|
221 }
|
nuclear@0
|
222 return "unknown";
|
nuclear@0
|
223 }
|