amiga_imgv
view src/image.c @ 11:3d9aaefb8ba6
interlace mode
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 30 Oct 2017 15:24:23 +0200 |
parents | ae0ada629b03 |
children |
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"
7 #include "endian.h"
9 #ifdef __GNUC__
10 #define PACKED __attribute__((packed))
11 #else
12 #define PACKED
13 #endif
15 struct ham_image_header {
16 char magic[4];
17 uint16_t width, height;
18 unsigned char nbitplanes, padding;
19 uint16_t nchg;
20 uint16_t palette[16];
21 } PACKED;
23 struct ham_image *load_ham_image(const char *fname)
24 {
25 int i, num;
26 unsigned long imgsz;
27 struct ham_image_header hdr;
28 struct ham_image *img = 0;
29 struct palchange *tail = 0;
30 FILE *fp;
32 logmsg("opening file: %s\n", fname);
33 if(!(fp = fopen(fname, "rb"))) {
34 logmsg("failed to open %s: %s\n", fname, strerror(errno));
35 return 0;
36 }
38 if(fread(&hdr, sizeof hdr, 1, fp) < 1) {
39 logmsg("unexpected eof while reading image header\n");
40 goto err;
41 }
42 if(memcmp(hdr.magic, "HAAM", 4) != 0) {
43 logmsg("failed to load image: %s: unknown file type\n", fname);
44 goto err;
45 }
47 if(!(img = malloc(sizeof *img))) {
48 logmsg("failed to allocate image structure\n");
49 goto err;
50 }
51 img->width = ntohs(hdr.width);
52 img->height = ntohs(hdr.height);
53 img->nbitplanes = hdr.nbitplanes;
54 img->ham = 1;
56 imgsz = img->width * img->height / 8 * img->nbitplanes;
58 logmsg("header info: %dx%d, %d bpl, size: %lu\n", img->width, img->height, (int)img->nbitplanes, imgsz);
60 if(!(img->pixels = malloc(imgsz))) {
61 logmsg("failed to allocate %dx%d (%d bitplane) image\n", img->width, img->height, img->nbitplanes);
62 goto err;
63 }
65 for(i=0; i<16; i++) {
66 img->palette[i] = ntohs(hdr.palette[i]);
67 }
69 num = ntohs(hdr.nchg);
70 for(i=0; i<num; i++) {
71 struct palchange *chg;
73 if(!(chg = malloc(sizeof *chg))) {
74 logmsg("failed to allocate palchange structure\n");
75 goto err;
76 }
78 if(fread(&chg->line, 2, 1, fp) < 1 || fread(&chg->entry, 2, 1, fp) < 1) {
79 logmsg("unexpected end of file while reading palette changelist\n");
80 goto err;
81 }
82 chg->line = ntohs(chg->line);
83 chg->entry = ntohs(chg->entry);
84 chg->next = 0;
86 if(tail) {
87 tail->next = chg;
88 tail = chg;
89 } else {
90 img->chglist = tail = chg;
91 }
92 }
94 if(fread(img->pixels, 1, imgsz, fp) < imgsz) {
95 logmsg("unexpected end of file while reading image pixels\n");
96 goto err;
97 }
99 fclose(fp);
100 return img;
102 err:
103 if(img) {
104 while(img->chglist) {
105 void *tmp = img->chglist;
106 img->chglist = img->chglist->next;
107 free(tmp);
108 }
109 free(img->pixels);
110 free(img);
111 }
112 if(fp) fclose(fp);
113 return 0;
114 }
116 struct ham_image *gen_ham_image(int w, int h, int nbpl)
117 {
118 int i, x, y;
119 struct ham_image *img;
120 unsigned char *pptr;
121 unsigned char pixval;
122 /*static const uint16_t defpal[] = {
123 0x000, 0xf00, 0xff0, 0x0f0, 0x0ff, 0x00f, 0xf0f, 0xfff,
124 0x444, 0x800, 0x880, 0x080, 0x088, 0x008, 0x808, 0x888
125 };*/
127 if(!(img = malloc(sizeof *img))) {
128 return 0;
129 }
130 if(!(img->pixels = calloc(w * h / 8 * nbpl, 1))) {
131 free(img);
132 return 0;
133 }
134 img->width = w;
135 img->height = h;
136 img->chglist = 0;
138 img->nbitplanes = nbpl;
139 /*memcpy(img->palette, defpal, sizeof defpal);*/
140 for(i=0; i<16; i++) {
141 img->palette[i] = i | (i << 4) | (i << 8);
142 }
144 for(i=0; i<nbpl; i++) {
145 pptr = img->pixels + i * w / 8;
146 for(y=0; y<h; y++) {
147 pixval = 0;
148 for(x=0; x<w; x++) {
149 if(i < 4) {
150 unsigned char val = ((y >> 3) & 1) == ((x >> 3) & 1) ? 0 : 0xff;
151 pixval = (pixval >> 1) | (val & 0x80);
152 }
153 if((x & 7) == 7) {
154 *pptr++ = pixval;
155 pixval = 0;
156 }
157 }
158 pptr += w / 8 * (nbpl - 1);
159 }
160 }
162 return img;
163 }