amiga_imgv
view src/image.c @ 4:0fd37effde29
progress
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 27 Oct 2017 11:36:18 +0300 |
parents | 663471a80c21 |
children | 0d3d7b020e6a |
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
18 struct ham_image_header {
19 char magic[4];
20 uint16_t width, height;
21 unsigned char nbitplanes, padding;
22 uint16_t nchg;
23 uint16_t palette[16];
24 };
26 struct ham_image *load_ham_image(const char *fname)
27 {
28 int i, num;
29 unsigned long imgsz;
30 struct ham_image_header hdr;
31 struct ham_image *img = 0;
32 struct palchange *tail = 0;
33 FILE *fp;
35 #ifndef HAVE_NTOHS
36 ntohs = bigendian() ? nop16 : swap16;
37 #endif
39 logmsg("opening file: %s\n", fname);
40 if(!(fp = fopen(fname, "rb"))) {
41 logmsg("failed to open %s: %s\n", fname, strerror(errno));
42 return 0;
43 }
45 if(fread(&hdr, sizeof hdr, 1, fp) < 1) {
46 logmsg("unexpected eof while reading image header\n");
47 goto err;
48 }
49 if(memcmp(hdr.magic, "HAAM", 4) != 0) {
50 logmsg("failed to load image: %s: unknown file type\n", fname);
51 goto err;
52 }
54 if(!(img = malloc(sizeof *img))) {
55 logmsg("failed to allocate image structure\n");
56 goto err;
57 }
58 img->width = ntohs(hdr.width);
59 img->height = ntohs(hdr.height);
60 img->nbitplanes = hdr.nbitplanes;
62 imgsz = img->width * img->height / 8 * img->nbitplanes;
64 logmsg("header info: %dx%d, %d bpl, size: %lu\n", img->width, img->height, (int)img->nbitplanes, imgsz);
66 if(!(img->pixels = malloc(imgsz))) {
67 logmsg("failed to allocate %dx%d (%d bitplane) image\n", img->width, img->height, img->nbitplanes);
68 goto err;
69 }
71 for(i=0; i<16; i++) {
72 img->palette[i] = ntohs(hdr.palette[i]);
73 }
75 num = ntohs(hdr.nchg);
76 for(i=0; i<num; i++) {
77 struct palchange *chg;
79 if(!(chg = malloc(sizeof *chg))) {
80 logmsg("failed to allocate palchange structure\n");
81 goto err;
82 }
84 if(fread(&chg->line, 2, 1, fp) < 1 || fread(&chg->entry, 2, 1, fp) < 1) {
85 logmsg("unexpected end of file while reading palette changelist\n");
86 goto err;
87 }
88 chg->line = ntohs(chg->line);
89 chg->entry = ntohs(chg->entry);
90 chg->next = 0;
92 if(tail) {
93 tail->next = chg;
94 tail = chg;
95 } else {
96 img->chglist = tail = chg;
97 }
98 }
100 if(fread(img->pixels, 1, imgsz, fp) < imgsz) {
101 logmsg("unexpected end of file while reading image pixels\n");
102 goto err;
103 }
105 fclose(fp);
106 return img;
108 err:
109 if(img) {
110 while(img->chglist) {
111 void *tmp = img->chglist;
112 img->chglist = img->chglist->next;
113 free(tmp);
114 }
115 free(img->pixels);
116 free(img);
117 }
118 if(fp) fclose(fp);
119 return 0;
120 }
122 struct ham_image *gen_ham_image(int w, int h, int nbpl)
123 {
124 int i, x, y;
125 struct ham_image *img;
126 unsigned char *pptr;
127 unsigned char pixval;
128 /*static const uint16_t defpal[] = {
129 0x000, 0xf00, 0xff0, 0x0f0, 0x0ff, 0x00f, 0xf0f, 0xfff,
130 0x444, 0x800, 0x880, 0x080, 0x088, 0x008, 0x808, 0x888
131 };*/
133 if(!(img = malloc(sizeof *img))) {
134 return 0;
135 }
136 if(!(img->pixels = calloc(w * h / 8 * nbpl, 1))) {
137 free(img);
138 return 0;
139 }
140 img->width = w;
141 img->height = h;
142 img->chglist = 0;
144 img->nbitplanes = nbpl;
145 /*memcpy(img->palette, defpal, sizeof defpal);*/
146 for(i=0; i<16; i++) {
147 img->palette[i] = i | (i << 4) | (i << 8);
148 }
150 for(i=0; i<nbpl; i++) {
151 pptr = img->pixels + i * w / 8;
152 for(y=0; y<h; y++) {
153 pixval = 0;
154 for(x=0; x<w; x++) {
155 if(i < 4) {
156 unsigned char val = (y & 1) ? 0 : 0xff;
157 pixval = (pixval >> 1) | (((val >> i) & 1) ? 0x80 : 0);
158 }
159 if((x & 7) == 7) {
160 *pptr++ = pixval;
161 pixval = 0;
162 }
163 }
164 pptr += w / 8 * (img->nbitplanes - 1);
165 }
166 }
168 return img;
169 }
171 #ifndef HAVE_NTOHS
172 static int bigendian(void)
173 {
174 static const uint16_t x = 0xaabb;
175 return *(unsigned char*)&x == 0xaa;
176 }
178 static uint16_t swap16(uint16_t x)
179 {
180 return (x << 8) | (x >> 8);
181 }
183 static uint16_t nop16(uint16_t x)
184 {
185 return x;
186 }
187 #endif