amiga_imgv

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