amiga_imgv

view tools/convhammer/main.c @ 3:663471a80c21

broken + sdl emu
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 26 Oct 2017 15:49:56 +0300
parents f75893a33234
children ae0ada629b03
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <arpa/inet.h>
6 #include "image.h"
8 /* hammer dump format (input)
9 * byte order: little endian
10 *
11 * 4 bytes: palette changes per scanline (cps)
12 * 256 * cps * 2 bytes: [ idx | r | g | b ]
13 * 320 * 256 bytes: linear HAM pixels
14 */
16 /* interleaved ham format (output)
17 * byte order: big endian
18 *
19 * 4 bytes: magic: "HAAM"
20 * 2 bytes: width
21 * 2 bytes: height
22 * 1 byte: number of bitplanes
23 * 1 byte: padding
24 * 2 bytes: number of palette change descriptors (nchg)
25 * 16 * 2 bytes: initial palette [ x | r | g | b ]
26 * nchg * 4 bytes: [ scanline ] [ idx | r | g | b ]
27 * width * height / 8 * bitplanes bytes: pixels interleaved scanlines
28 * [ row0 bpl0 ] ... [ row0 bplN ] [ row1 bpl0 ] ... [ row1 bplN ] ...
29 */
31 struct ham_image *load_hammer(const char *fname);
32 int save_ham(struct ham_image *img, const char *fname);
33 void free_image(struct ham_image *img);
35 int main(int argc, char **argv)
36 {
37 int i;
38 struct ham_image *img;
39 char *name, *dot;
41 for(i=1; i<argc; i++) {
42 if(!(img = load_hammer(argv[i]))) {
43 fprintf(stderr, "failed to load hammer dump: %s\n", argv[i]);
44 continue;
45 }
47 if(!(name = malloc(strlen(argv[i] + 8)))) {
48 perror("failed to allocate output name buffer");
49 abort();
50 }
51 strcpy(name, argv[i]);
53 if((dot = strrchr(name, '.'))) {
54 *dot = 0;
55 }
56 strcat(name, ".ham");
58 if(save_ham(img, name) == -1) {
59 fprintf(stderr, "failed to save ham image: %s\n", name);
60 free_image(img);
61 continue;
62 }
63 }
64 return 0;
65 }
67 static uint16_t nops(uint16_t x) { return x; }
68 static uint16_t swaps(uint16_t x) { return (x >> 8) | (x << 8); }
70 struct ham_image *load_hammer(const char *fname)
71 {
72 int i, x, y, pstart, numpix = 320 * 256;
73 FILE *fp = 0;
74 uint32_t cps, npalent;
75 struct ham_image *img = 0;
76 struct palchange *tail = 0;
77 unsigned char *inpixels = 0;
78 unsigned char *srcptr, *destptr;
79 uint16_t endtest = 0xaabb;
80 uint16_t (*letohs)(uint16_t);
82 letohs = (*(unsigned char*)&endtest == 0xaa) ? swaps : nops;
84 if(!(fp = fopen(fname, "rb"))) {
85 fprintf(stderr, "failed to open %s: %s\n", fname, strerror(errno));
86 return 0;
87 }
89 if(!(img = malloc(sizeof *img))) {
90 perror("failed to allocate image");
91 goto err;
92 }
93 img->width = 320;
94 img->height = 256;
95 img->nbitplanes = 6;
96 img->chglist = 0;
98 if(!(img->pixels = malloc(img->width * img->height / 8 * img->nbitplanes))) {
99 perror("failed to allocate pixels");
100 goto err;
101 }
103 if(fread(&cps, 4, 1, fp) < 1) goto err;
104 cps = letohs(cps);
105 if(cps <= 0 || cps > 16) {
106 fprintf(stderr, "invalid changes-per-line value: %u\n", (unsigned int)cps);
107 goto err;
108 }
110 /* read palette changes and palette */
112 npalent = cps * 256;
113 pstart = npalent - 16;
115 for(i=0; i<npalent; i++) {
116 uint16_t palent;
117 struct palchange *chg;
119 if(fread(&palent, 2, 1, fp) < 1) {
120 perror("unexpected end of file");
121 goto err;
122 }
123 palent = letohs(palent);
125 if(!(chg = malloc(sizeof *chg))) {
126 perror("failed to allocate palchange node");
127 goto err;
128 }
129 chg->line = i / cps;
130 chg->entry = palent;
131 chg->next = 0;
132 if(tail) {
133 tail->next = chg;
134 tail = chg;
135 } else {
136 img->chglist = tail = chg;
137 }
139 if(i >= pstart) {
140 img->palette[i - pstart] = palent & 0xfff;
141 }
142 }
144 /* read pixels */
145 if(!(inpixels = malloc(numpix))) {
146 perror("failed to allocate pixel buffer");
147 goto err;
148 }
149 if(fread(inpixels, 1, numpix, fp) < numpix) {
150 perror("unexpected end of file while reading pixels");
151 goto err;
152 }
154 for(i=0; i<img->nbitplanes; i++) {
155 srcptr = inpixels;
156 destptr = img->pixels + i * img->width / 8;
157 for(y=0; y<img->height; y++) {
158 unsigned char pixval = 0;
159 for(x=0; x<img->width; x++) {
160 pixval = (pixval << 1) | ((*srcptr++ >> i) & 1);
161 if((x & 7) == 7) {
162 *destptr++ = pixval;
163 pixval = 0;
164 }
165 }
166 destptr += img->width / 8 * (img->nbitplanes - 1);
167 }
168 }
170 free(inpixels);
171 fclose(fp);
172 return img;
174 err:
175 free(inpixels);
176 if(img) {
177 while(img->chglist) {
178 void *tmp = img->chglist;
179 img->chglist = img->chglist->next;
180 free(tmp);
181 }
182 free(img->pixels);
183 free(img);
184 }
185 if(fp) fclose(fp);
186 return 0;
187 }
189 int save_ham(struct ham_image *img, const char *fname)
190 {
191 int i, num;
192 unsigned char c, *pptr;
193 uint16_t val;
194 FILE *fp;
195 struct palchange *chg;
197 if(!(fp = fopen(fname, "wb"))) {
198 fprintf(stderr, "failed to open %s for writing: %s\n", fname, strerror(errno));
199 return -1;
200 }
201 fprintf(fp, "HAAM");
203 val = htons(img->width);
204 fwrite(&val, 2, 1, fp);
205 val = htons(img->height);
206 fwrite(&val, 2, 1, fp);
207 c = img->nbitplanes;
208 fwrite(&c, 1, 1, fp);
209 fwrite(&c, 1, 1, fp); /* padding */
211 num = 0;
212 chg = img->chglist;
213 while(chg) {
214 ++num;
215 chg = chg->next;
216 }
217 num = htons(num);
218 fwrite(&num, 2, 1, fp);
220 for(i=0; i<16; i++) {
221 val = htons(img->palette[i]);
222 fwrite(&val, 2, 1, fp);
223 }
225 chg = img->chglist;
226 while(chg) {
227 val = htons(chg->line);
228 fwrite(&val, 2, 1, fp);
229 val = htons(chg->entry);
230 fwrite(&val, 2, 1, fp);
231 chg = chg->next;
232 }
234 pptr = img->pixels;
235 num = img->width * img->height / 8 * img->nbitplanes;
236 for(i=0; i<num; i++) {
237 val = htons(*pptr);
238 ++pptr;
240 fwrite(&val, 2, 1, fp);
241 }
242 fclose(fp);
243 return 0;
244 }
246 void free_image(struct ham_image *img)
247 {
248 if(img) {
249 free(img->pixels);
250 while(img->chglist) {
251 void *tmp = img->chglist;
252 img->chglist = img->chglist->next;
253 free(tmp);
254 }
255 free(img);
256 }
257 }