rev |
line source |
nuclear@0
|
1 #include <stdio.h>
|
nuclear@0
|
2 #include <stdlib.h>
|
nuclear@0
|
3 #include <string.h>
|
nuclear@0
|
4 #include <errno.h>
|
nuclear@0
|
5 #include "image.h"
|
nuclear@0
|
6
|
nuclear@0
|
7 static int proc_image(const char *fname);
|
nuclear@0
|
8 static const char *modestr(int cmode);
|
nuclear@0
|
9 static void output_planar(FILE *fp, struct image *img);
|
nuclear@0
|
10 static void output_chunky(FILE *fp, struct image *img);
|
nuclear@0
|
11
|
nuclear@0
|
12 static int planar = 0;
|
nuclear@0
|
13
|
nuclear@0
|
14 int main(int argc, char **argv)
|
nuclear@0
|
15 {
|
nuclear@0
|
16 int i;
|
nuclear@0
|
17
|
nuclear@0
|
18 for(i=1; i<argc; i++) {
|
nuclear@0
|
19 if(argv[i][0] == '-') {
|
nuclear@0
|
20 if(argv[i][2] == 0) {
|
nuclear@0
|
21 switch(argv[i][1]) {
|
nuclear@0
|
22 case 'p':
|
nuclear@0
|
23 planar = 1;
|
nuclear@0
|
24 break;
|
nuclear@0
|
25
|
nuclear@0
|
26 case 'c':
|
nuclear@0
|
27 planar = 0;
|
nuclear@0
|
28 break;
|
nuclear@0
|
29
|
nuclear@0
|
30 case 'h':
|
nuclear@0
|
31 printf("usage: %s [options] <file 1> <file 2> ... <file n>\n", argv[0]);
|
nuclear@0
|
32 printf("Options:\n");
|
nuclear@0
|
33 printf(" -p: output image in planar format (default)\n");
|
nuclear@0
|
34 printf(" -c: output image in chunky format\n");
|
nuclear@0
|
35 printf(" -h: print usage and exit\n");
|
nuclear@0
|
36 return 0;
|
nuclear@0
|
37
|
nuclear@0
|
38 default:
|
nuclear@0
|
39 fprintf(stderr, "invalid option: %s\n", argv[i]);
|
nuclear@0
|
40 return 1;
|
nuclear@0
|
41 }
|
nuclear@0
|
42 } else {
|
nuclear@0
|
43 fprintf(stderr, "invalid option: %s\n", argv[i]);
|
nuclear@0
|
44 }
|
nuclear@0
|
45 } else {
|
nuclear@0
|
46 if(proc_image(argv[i]) == -1) {
|
nuclear@0
|
47 return 1;
|
nuclear@0
|
48 }
|
nuclear@0
|
49 }
|
nuclear@0
|
50 }
|
nuclear@0
|
51 return 0;
|
nuclear@0
|
52 }
|
nuclear@0
|
53
|
nuclear@0
|
54 static int proc_image(const char *fname)
|
nuclear@0
|
55 {
|
nuclear@0
|
56 int i;
|
nuclear@0
|
57 struct image img;
|
nuclear@0
|
58 char *outfname, *suffix;
|
nuclear@0
|
59 FILE *fp;
|
nuclear@0
|
60
|
nuclear@0
|
61 if(load_image(&img, fname) == -1) {
|
nuclear@0
|
62 fprintf(stderr, "failed to load image: %s\n", fname);
|
nuclear@0
|
63 return -1;
|
nuclear@0
|
64 }
|
nuclear@0
|
65
|
nuclear@0
|
66 if(!(outfname = malloc(strlen(fname) + 4))) {
|
nuclear@0
|
67 perror("failed to allocate output filename");
|
nuclear@0
|
68 return -1;
|
nuclear@0
|
69 }
|
nuclear@0
|
70 strcpy(outfname, fname);
|
nuclear@0
|
71 if(!(suffix = strrchr(outfname, '.'))) {
|
nuclear@0
|
72 suffix = outfname + strlen(outfname);
|
nuclear@0
|
73 }
|
nuclear@0
|
74 strcpy(suffix, ".bin");
|
nuclear@0
|
75
|
nuclear@0
|
76 printf("processing %s -> %s\n", fname, outfname);
|
nuclear@0
|
77
|
nuclear@0
|
78 if(!(fp = fopen(outfname, "wb"))) {
|
nuclear@0
|
79 fprintf(stderr, "failed to open output file: %s: %s\n", outfname, strerror(errno));
|
nuclear@0
|
80 destroy_image(&img);
|
nuclear@0
|
81 free(outfname);
|
nuclear@0
|
82 return -1;
|
nuclear@0
|
83 }
|
nuclear@0
|
84
|
nuclear@0
|
85 printf(" bits per pixel: %d\n", img.bpp);
|
nuclear@0
|
86 if(img.num_ranges) {
|
nuclear@0
|
87 printf(" color ranges:\n");
|
nuclear@0
|
88 for(i=0; i<img.num_ranges; i++) {
|
nuclear@0
|
89 printf(" [%d]: %d - %d, rate: %u, mode: %s\n", i, img.range[i].low, img.range[i].high,
|
nuclear@0
|
90 img.range[i].rate, modestr(img.range[i].cmode));
|
nuclear@0
|
91 }
|
nuclear@0
|
92 }
|
nuclear@0
|
93
|
nuclear@0
|
94 if(planar) {
|
nuclear@0
|
95 output_planar(fp, &img);
|
nuclear@0
|
96 } else {
|
nuclear@0
|
97 output_chunky(fp, &img);
|
nuclear@0
|
98 }
|
nuclear@0
|
99
|
nuclear@0
|
100 free(outfname);
|
nuclear@0
|
101 fclose(fp);
|
nuclear@0
|
102 destroy_image(&img);
|
nuclear@0
|
103 return 0;
|
nuclear@0
|
104 }
|
nuclear@0
|
105
|
nuclear@0
|
106 static void output_planar(FILE *fp, struct image *img)
|
nuclear@0
|
107 {
|
nuclear@0
|
108 int i, x, y;
|
nuclear@0
|
109 unsigned char acc = 0;
|
nuclear@0
|
110 int acc_bit = 7;
|
nuclear@0
|
111 unsigned char *pptr = img->pixels;
|
nuclear@0
|
112
|
nuclear@0
|
113 for(i=0; i<img->bpp; i++) {
|
nuclear@0
|
114 for(y=0; y<img->height; y++) {
|
nuclear@0
|
115 for(x=0; x<img->width; x++) {
|
nuclear@0
|
116 acc |= (((*pptr++ >> i) & 1) << acc_bit);
|
nuclear@0
|
117 if(--acc_bit == 0) {
|
nuclear@0
|
118 fputc(acc, fp);
|
nuclear@0
|
119 acc_bit = 7;
|
nuclear@0
|
120 acc = 0;
|
nuclear@0
|
121 }
|
nuclear@0
|
122 }
|
nuclear@0
|
123 }
|
nuclear@0
|
124 }
|
nuclear@0
|
125 }
|
nuclear@0
|
126
|
nuclear@0
|
127 static void output_chunky(FILE *fp, struct image *img)
|
nuclear@0
|
128 {
|
nuclear@0
|
129 int i, j;
|
nuclear@0
|
130 unsigned char *pptr = img->pixels;
|
nuclear@0
|
131
|
nuclear@0
|
132 for(i=0; i<img->height; i++) {
|
nuclear@0
|
133 for(j=0; j<img->width; j++) {
|
nuclear@0
|
134 fputc(*pptr++, fp);
|
nuclear@0
|
135 }
|
nuclear@0
|
136 }
|
nuclear@0
|
137 }
|
nuclear@0
|
138
|
nuclear@0
|
139 static const char *modestr(int cmode)
|
nuclear@0
|
140 {
|
nuclear@0
|
141 switch(cmode) {
|
nuclear@0
|
142 case CYCLE_NORMAL:
|
nuclear@0
|
143 return "forward";
|
nuclear@0
|
144 case CYCLE_REVERSE:
|
nuclear@0
|
145 return "reverse";
|
nuclear@0
|
146 case CYCLE_PINGPONG:
|
nuclear@0
|
147 return "ping-pong";
|
nuclear@0
|
148 case CYCLE_SINE_HALF:
|
nuclear@0
|
149 return "half-sine";
|
nuclear@0
|
150 case CYCLE_SINE:
|
nuclear@0
|
151 return "sine";
|
nuclear@0
|
152 default:
|
nuclear@0
|
153 break;
|
nuclear@0
|
154 }
|
nuclear@0
|
155 return "unknown";
|
nuclear@0
|
156 }
|