lbm2bin

view src/main.c @ 6:89fd62196739

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