amiga_imgv

view tools/img2ham/main.c @ 12:20c7238c60be

img2ham unfinished
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 20 Nov 2017 08:36:16 +0200
parents
children
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <limits.h>
5 #include <errno.h>
6 #include <imago2.h>
7 #include <arpa/inet.h>
8 #include "image.h"
10 static int convert(struct ham_image *img, unsigned char *pixels, int xsz, int ysz);
11 static int save_ham(struct ham_image *img, const char *fname);
12 static void destroy_image(struct ham_image *img);
14 int main(int argc, char **argv)
15 {
16 int i, width, height, len;
17 unsigned char *pixels;
18 char *out_fname, *suffix;
19 struct ham_image img;
21 for(i=1; i<argc; i++) {
22 if(!(pixels = img_load_pixels(argv[i], &width, &height, IMG_FMT_RGB24))) {
23 fprintf(stderr, "failed to load image: %s\n", argv[i]);
24 continue;
25 }
26 convert(&img, pixels, width, height);
28 len = strlen(argv[i]) + 4;
29 if(!(out_fname = malloc(len + 1))) {
30 perror("failed to allocate memory");
31 abort();
32 }
33 memcpy(out_fname, argv[i], len + 1);
34 if(!(suffix = strrchr(out_fname, '.'))) {
35 suffix = out_fname + len;
36 }
37 memcpy(suffix, ".ham", 5);
39 save_ham(&img, out_fname);
40 destroy_image(&img);
42 free(out_fname);
43 }
45 return 0;
46 }
48 struct fringe {
49 int pixel, score;
50 };
52 static int detect_fringes(int *flist, int num, unsigned char *scanline, int width, int pr, int pg, int pb)
53 {
54 int i, j, fcount = 0;
55 struct fringe fringes[16] = {{0, 0}};
57 if(num > 16) num = 16;
59 for(i=0; i<width; i++) {
60 int r = *scanline++;
61 int g = *scanline++;
62 int b = *scanline++;
63 int dr = r - pr;
64 int dg = g - pg;
65 int db = b - pb;
66 int max = dr > dg ? (dr > db ? dr : db) : (dg > db ? dg : db);
67 int score = dr + dg + db - max;
69 if(score > 0) {
70 int min = fringes[0].score, min_idx = 0;
71 for(j=1; j<fcount; j++) {
72 if(fringes[j].score < min) {
73 min = fringes[j].score;
74 min_idx = j;
75 }
76 }
77 if(score > min) {
78 fringes[min_idx].score = score;
79 fringes[min_idx].pixel = i;
80 }
81 }
82 }
83 }
85 static int convert(struct ham_image *img, unsigned char *pixels, int xsz, int ysz)
86 {
87 int i, j, x, y, pstart, numpix = xsz * ysz;
88 FILE *fp = 0;
89 uint32_t cps, npalent;
90 struct palchange *tail = 0;
91 unsigned char *inpixels = 0;
92 unsigned char *srcptr, *destptr;
94 /* convert RGB to HAM in-place */
95 for(i=0; i<ysz; i++) {
96 for(j=0; j<xsz; j++) {
97 }
98 }
100 img->width = xsz;
101 img->height = ysz;
102 img->nbitplanes = 6;
103 img->ham = 1;
104 img->chglist = 0;
106 if(!(img->pixels = malloc(img->width * img->height / 8 * img->nbitplanes))) {
107 perror("failed to allocate pixels");
108 goto err;
109 }
111 for(i=0; i<img->nbitplanes; i++) {
112 srcptr = inpixels;
113 destptr = img->pixels + i * img->width / 8;
114 for(y=0; y<img->height; y++) {
115 unsigned char pixval = 0;
116 for(x=0; x<img->width; x++) {
117 pixval = (pixval << 1) | ((*srcptr++ >> i) & 1);
118 if((x & 7) == 7) {
119 *destptr++ = pixval;
120 pixval = 0;
121 }
122 }
123 destptr += img->width / 8 * (img->nbitplanes - 1);
124 }
125 }
127 free(inpixels);
128 fclose(fp);
129 return img;
131 err:
132 free(inpixels);
133 if(img) {
134 while(img->chglist) {
135 void *tmp = img->chglist;
136 img->chglist = img->chglist->next;
137 free(tmp);
138 }
139 free(img->pixels);
140 free(img);
141 }
142 if(fp) fclose(fp);
143 return 0;
144 }
147 /* interleaved ham format (output)
148 * byte order: big endian
149 *
150 * 4 bytes: magic: "HAAM"
151 * 2 bytes: width
152 * 2 bytes: height
153 * 1 byte: number of bitplanes
154 * 1 byte: padding
155 * 2 bytes: number of palette change descriptors (nchg)
156 * 16 * 2 bytes: initial palette [ x | r | g | b ]
157 * nchg * 4 bytes: [ scanline ] [ idx | r | g | b ]
158 * width * height / 8 * bitplanes bytes: pixels interleaved scanlines
159 * [ row0 bpl0 ] ... [ row0 bplN ] [ row1 bpl0 ] ... [ row1 bplN ] ...
160 */
161 static int save_ham(struct ham_image *img, const char *fname)
162 {
163 int i, num;
164 unsigned char c, *pptr;
165 uint16_t val;
166 FILE *fp;
167 struct palchange *chg;
169 if(!(fp = fopen(fname, "wb"))) {
170 fprintf(stderr, "failed to open %s for writing: %s\n", fname, strerror(errno));
171 return -1;
172 }
173 fprintf(fp, "HAAM");
175 val = htons(img->width);
176 fwrite(&val, 2, 1, fp);
177 val = htons(img->height);
178 fwrite(&val, 2, 1, fp);
179 c = img->nbitplanes;
180 fwrite(&c, 1, 1, fp);
181 fwrite(&c, 1, 1, fp); /* padding */
183 num = 0;
184 chg = img->chglist;
185 while(chg) {
186 ++num;
187 chg = chg->next;
188 }
189 num = htons(num);
190 fwrite(&num, 2, 1, fp);
192 for(i=0; i<16; i++) {
193 val = htons(img->palette[i]);
194 fwrite(&val, 2, 1, fp);
195 }
197 chg = img->chglist;
198 while(chg) {
199 val = htons(chg->line);
200 fwrite(&val, 2, 1, fp);
201 val = htons(chg->entry);
202 fwrite(&val, 2, 1, fp);
203 chg = chg->next;
204 }
206 pptr = img->pixels;
207 num = img->width * img->height / 8 * img->nbitplanes;
208 for(i=0; i<num; i++) {
209 fwrite(pptr, 1, 1, fp);
210 ++pptr;
211 }
212 fclose(fp);
213 return 0;
214 }
216 void destroy_image(struct ham_image *img)
217 {
218 if(img) {
219 free(img->pixels);
220 while(img->chglist) {
221 void *tmp = img->chglist;
222 img->chglist = img->chglist->next;
223 free(tmp);
224 }
225 }
226 }