amiga_imgv
diff src/image.c @ 3:663471a80c21
broken + sdl emu
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Thu, 26 Oct 2017 15:49:56 +0300 |
parents | a4788c959918 |
children | 0fd37effde29 |
line diff
1.1 --- a/src/image.c Thu Oct 26 10:04:29 2017 +0300 1.2 +++ b/src/image.c Thu Oct 26 15:49:56 2017 +0300 1.3 @@ -1,10 +1,122 @@ 1.4 +#include <stdio.h> 1.5 #include <stdlib.h> 1.6 #include <string.h> 1.7 +#include <errno.h> 1.8 #include "image.h" 1.9 +#include "logger.h" 1.10 + 1.11 +#ifdef __unix__ 1.12 +#include <arpa/inet.h> 1.13 +#define HAVE_NTOHS 1.14 +#else 1.15 +static int bigendian(void); 1.16 +static uint16_t swap16(uint16_t x); 1.17 +static uint16_t nop16(uint16_t x); 1.18 +static uint16_t (*ntohs)(uint16_t); 1.19 +#endif 1.20 + 1.21 +struct ham_image_header { 1.22 + char magic[4]; 1.23 + uint16_t width, height; 1.24 + unsigned char nbitplanes, padding; 1.25 + uint16_t nchg; 1.26 + uint16_t palette[16]; 1.27 +}; 1.28 1.29 struct ham_image *load_ham_image(const char *fname) 1.30 { 1.31 - return 0; /* TODO */ 1.32 + int i, num; 1.33 + unsigned long imgsz; 1.34 + struct ham_image_header hdr; 1.35 + struct ham_image *img = 0; 1.36 + struct palchange *tail = 0; 1.37 + FILE *fp; 1.38 + 1.39 +#ifndef HAVE_NTOHS 1.40 + ntohs = bigendian() ? nop16 : swap16; 1.41 +#endif 1.42 + 1.43 + logmsg("opening file: %s\n", fname); 1.44 + if(!(fp = fopen(fname, "rb"))) { 1.45 + logmsg("failed to open %s: %s\n", fname, strerror(errno)); 1.46 + return 0; 1.47 + } 1.48 + 1.49 + if(fread(&hdr, sizeof hdr, 1, fp) < 1) { 1.50 + logmsg("unexpected eof while reading image header\n"); 1.51 + goto err; 1.52 + } 1.53 + if(memcmp(hdr.magic, "HAAM", 4) != 0) { 1.54 + logmsg("failed to load image: %s: unknown file type\n", fname); 1.55 + goto err; 1.56 + } 1.57 + 1.58 + if(!(img = malloc(sizeof *img))) { 1.59 + logmsg("failed to allocate image structure\n"); 1.60 + goto err; 1.61 + } 1.62 + img->width = ntohs(hdr.width); 1.63 + img->height = ntohs(hdr.height); 1.64 + img->nbitplanes = hdr.nbitplanes; 1.65 + 1.66 + imgsz = img->width * img->height / 8 * img->nbitplanes; 1.67 + 1.68 + logmsg("header info: %dx%d, %d bpl, size: %lu\n", img->width, img->height, (int)img->nbitplanes, imgsz); 1.69 + 1.70 + if(!(img->pixels = malloc(imgsz))) { 1.71 + logmsg("failed to allocate %dx%d (%d bitplane) image\n", img->width, img->height, img->nbitplanes); 1.72 + goto err; 1.73 + } 1.74 + 1.75 + for(i=0; i<16; i++) { 1.76 + img->palette[i] = ntohs(hdr.palette[i]); 1.77 + } 1.78 + 1.79 + num = ntohs(hdr.nchg); 1.80 + for(i=0; i<num; i++) { 1.81 + struct palchange *chg; 1.82 + 1.83 + if(!(chg = malloc(sizeof *chg))) { 1.84 + logmsg("failed to allocate palchange structure\n"); 1.85 + goto err; 1.86 + } 1.87 + 1.88 + if(fread(&chg->line, 2, 1, fp) < 1 || fread(&chg->entry, 2, 1, fp) < 1) { 1.89 + logmsg("unexpected end of file while reading palette changelist\n"); 1.90 + goto err; 1.91 + } 1.92 + chg->line = ntohs(chg->line); 1.93 + chg->entry = ntohs(chg->entry); 1.94 + chg->next = 0; 1.95 + 1.96 + if(tail) { 1.97 + tail->next = chg; 1.98 + tail = chg; 1.99 + } else { 1.100 + img->chglist = tail = chg; 1.101 + } 1.102 + } 1.103 + 1.104 + if(fread(img->pixels, 1, imgsz, fp) < imgsz) { 1.105 + logmsg("unexpected end of file while reading image pixels\n"); 1.106 + goto err; 1.107 + } 1.108 + 1.109 + fclose(fp); 1.110 + return img; 1.111 + 1.112 +err: 1.113 + if(img) { 1.114 + while(img->chglist) { 1.115 + void *tmp = img->chglist; 1.116 + img->chglist = img->chglist->next; 1.117 + free(tmp); 1.118 + } 1.119 + free(img->pixels); 1.120 + free(img); 1.121 + } 1.122 + if(fp) fclose(fp); 1.123 + return 0; 1.124 } 1.125 1.126 struct ham_image *gen_ham_image(int w, int h, int nbpl) 1.127 @@ -53,3 +165,21 @@ 1.128 1.129 return img; 1.130 } 1.131 + 1.132 +#ifndef HAVE_NTOHS 1.133 +static int bigendian(void) 1.134 +{ 1.135 + static const uint16_t x = 0xaabb; 1.136 + return *(unsigned char*)&x == 0xaa; 1.137 +} 1.138 + 1.139 +static uint16_t swap16(uint16_t x) 1.140 +{ 1.141 + return (x << 8) | (x >> 8); 1.142 +} 1.143 + 1.144 +static uint16_t nop16(uint16_t x) 1.145 +{ 1.146 + return x; 1.147 +} 1.148 +#endif