amiga_imgv

view src/image.c @ 6:ae0ada629b03

wohooo it works :)
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 27 Oct 2017 15:42:58 +0300
parents 0d3d7b020e6a
children 4c36d0f44aa6
line source
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include "image.h"
6 #include "logger.h"
8 #ifdef __unix__
9 #include <arpa/inet.h>
10 #define HAVE_NTOHS
11 #else
12 static int bigendian(void);
13 static uint16_t swap16(uint16_t x);
14 static uint16_t nop16(uint16_t x);
15 static uint16_t (*ntohs)(uint16_t);
16 #endif
19 #ifdef __GNUC__
20 #define PACKED __attribute__((packed))
21 #else
22 #define PACKED
23 #endif
25 struct ham_image_header {
26 char magic[4];
27 uint16_t width, height;
28 unsigned char nbitplanes, padding;
29 uint16_t nchg;
30 uint16_t palette[16];
31 } PACKED;
33 struct ham_image *load_ham_image(const char *fname)
34 {
35 int i, num;
36 unsigned long imgsz;
37 struct ham_image_header hdr;
38 struct ham_image *img = 0;
39 struct palchange *tail = 0;
40 FILE *fp;
42 #ifndef HAVE_NTOHS
43 ntohs = bigendian() ? nop16 : swap16;
44 #endif
46 logmsg("opening file: %s\n", fname);
47 if(!(fp = fopen(fname, "rb"))) {
48 logmsg("failed to open %s: %s\n", fname, strerror(errno));
49 return 0;
50 }
52 if(fread(&hdr, sizeof hdr, 1, fp) < 1) {
53 logmsg("unexpected eof while reading image header\n");
54 goto err;
55 }
56 if(memcmp(hdr.magic, "HAAM", 4) != 0) {
57 logmsg("failed to load image: %s: unknown file type\n", fname);
58 goto err;
59 }
61 if(!(img = malloc(sizeof *img))) {
62 logmsg("failed to allocate image structure\n");
63 goto err;
64 }
65 img->width = ntohs(hdr.width);
66 img->height = ntohs(hdr.height);
67 img->nbitplanes = hdr.nbitplanes;
69 imgsz = img->width * img->height / 8 * img->nbitplanes;
71 logmsg("header info: %dx%d, %d bpl, size: %lu\n", img->width, img->height, (int)img->nbitplanes, imgsz);
73 if(!(img->pixels = malloc(imgsz))) {
74 logmsg("failed to allocate %dx%d (%d bitplane) image\n", img->width, img->height, img->nbitplanes);
75 goto err;
76 }
78 for(i=0; i<16; i++) {
79 img->palette[i] = ntohs(hdr.palette[i]);
80 }
82 num = ntohs(hdr.nchg);
83 for(i=0; i<num; i++) {
84 struct palchange *chg;
86 if(!(chg = malloc(sizeof *chg))) {
87 logmsg("failed to allocate palchange structure\n");
88 goto err;
89 }
91 if(fread(&chg->line, 2, 1, fp) < 1 || fread(&chg->entry, 2, 1, fp) < 1) {
92 logmsg("unexpected end of file while reading palette changelist\n");
93 goto err;
94 }
95 chg->line = ntohs(chg->line);
96 chg->entry = ntohs(chg->entry);
97 chg->next = 0;
99 if(tail) {
100 tail->next = chg;
101 tail = chg;
102 } else {
103 img->chglist = tail = chg;
104 }
105 }
107 if(fread(img->pixels, 1, imgsz, fp) < imgsz) {
108 logmsg("unexpected end of file while reading image pixels\n");
109 goto err;
110 }
112 fclose(fp);
113 return img;
115 err:
116 if(img) {
117 while(img->chglist) {
118 void *tmp = img->chglist;
119 img->chglist = img->chglist->next;
120 free(tmp);
121 }
122 free(img->pixels);
123 free(img);
124 }
125 if(fp) fclose(fp);
126 return 0;
127 }
129 struct ham_image *gen_ham_image(int w, int h, int nbpl)
130 {
131 int i, x, y;
132 struct ham_image *img;
133 unsigned char *pptr;
134 unsigned char pixval;
135 /*static const uint16_t defpal[] = {
136 0x000, 0xf00, 0xff0, 0x0f0, 0x0ff, 0x00f, 0xf0f, 0xfff,
137 0x444, 0x800, 0x880, 0x080, 0x088, 0x008, 0x808, 0x888
138 };*/
140 if(!(img = malloc(sizeof *img))) {
141 return 0;
142 }
143 if(!(img->pixels = calloc(w * h / 8 * nbpl, 1))) {
144 free(img);
145 return 0;
146 }
147 img->width = w;
148 img->height = h;
149 img->chglist = 0;
151 img->nbitplanes = nbpl;
152 /*memcpy(img->palette, defpal, sizeof defpal);*/
153 for(i=0; i<16; i++) {
154 img->palette[i] = i | (i << 4) | (i << 8);
155 }
157 for(i=0; i<nbpl; i++) {
158 pptr = img->pixels + i * w / 8;
159 for(y=0; y<h; y++) {
160 pixval = 0;
161 for(x=0; x<w; x++) {
162 if(i < 4) {
163 unsigned char val = ((y >> 3) & 1) == ((x >> 3) & 1) ? 0 : 0xff;
164 pixval = (pixval >> 1) | (val & 0x80);
165 }
166 if((x & 7) == 7) {
167 *pptr++ = pixval;
168 pixval = 0;
169 }
170 }
171 pptr += w / 8 * (nbpl - 1);
172 }
173 }
175 return img;
176 }
178 #ifndef HAVE_NTOHS
179 static int bigendian(void)
180 {
181 static const uint16_t x = 0xaabb;
182 return *(unsigned char*)&x == 0xaa;
183 }
185 static uint16_t swap16(uint16_t x)
186 {
187 return (x << 8) | (x >> 8);
188 }
190 static uint16_t nop16(uint16_t x)
191 {
192 return x;
193 }
194 #endif