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