amiga_imgv

changeset 2:f75893a33234

hammer -> ham image converter
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 26 Oct 2017 10:04:29 +0300
parents 6320a20f17c5
children 663471a80c21
files src/image.h tools/convhammer/main.c
diffstat 2 files changed, 156 insertions(+), 5 deletions(-) [+]
line diff
     1.1 --- a/src/image.h	Wed Oct 25 21:05:24 2017 +0300
     1.2 +++ b/src/image.h	Thu Oct 26 10:04:29 2017 +0300
     1.3 @@ -4,7 +4,7 @@
     1.4  #include "inttypes.h"
     1.5  
     1.6  struct palchange {
     1.7 -	int line;
     1.8 +	uint16_t line;
     1.9  	uint16_t entry;	/* [ idx | r | g | b ] */
    1.10  	struct palchange *next;
    1.11  };
     2.1 --- a/tools/convhammer/main.c	Wed Oct 25 21:05:24 2017 +0300
     2.2 +++ b/tools/convhammer/main.c	Thu Oct 26 10:04:29 2017 +0300
     2.3 @@ -1,6 +1,7 @@
     2.4  #include <stdio.h>
     2.5  #include <stdlib.h>
     2.6  #include <string.h>
     2.7 +#include <errno.h>
     2.8  #include <arpa/inet.h>
     2.9  #include "image.h"
    2.10  
    2.11 @@ -54,7 +55,7 @@
    2.12  		}
    2.13  		strcat(name, ".ham");
    2.14  
    2.15 -		if(save_ham(name, img) == -1) {
    2.16 +		if(save_ham(img, name) == -1) {
    2.17  			fprintf(stderr, "failed to save ham image: %s\n", name);
    2.18  			free_image(img);
    2.19  			continue;
    2.20 @@ -63,14 +64,133 @@
    2.21  	return 0;
    2.22  }
    2.23  
    2.24 +static uint16_t nops(uint16_t x) { return x; }
    2.25 +static uint16_t swaps(uint16_t x) { return (x >> 8) | (x << 8); }
    2.26 +
    2.27  struct ham_image *load_hammer(const char *fname)
    2.28  {
    2.29 +	int i, x, y, pstart, numpix = 320 * 256;
    2.30 +	FILE *fp = 0;
    2.31 +	uint32_t cps, npalent;
    2.32 +	struct ham_image *img = 0;
    2.33 +	struct palchange *tail = 0;
    2.34 +	unsigned char *inpixels = 0;
    2.35 +	unsigned char *srcptr, *destptr;
    2.36 +	uint16_t endtest = 0xaabb;
    2.37 +	uint16_t (*letohs)(uint16_t);
    2.38 +
    2.39 +	letohs = (*(unsigned char*)&endtest == 0xaa) ? swaps : nops;
    2.40 +
    2.41 +	if(!(fp = fopen(fname, "rb"))) {
    2.42 +		fprintf(stderr, "failed to open %s: %s\n", fname, strerror(errno));
    2.43 +		return 0;
    2.44 +	}
    2.45 +
    2.46 +	if(!(img = malloc(sizeof *img))) {
    2.47 +		perror("failed to allocate image");
    2.48 +		goto err;
    2.49 +	}
    2.50 +	img->width = 320;
    2.51 +	img->height = 256;
    2.52 +	img->nbitplanes = 6;
    2.53 +	img->chglist = 0;
    2.54 +
    2.55 +	if(!(img->pixels = malloc(img->width * img->height / 8 * img->nbitplanes))) {
    2.56 +		perror("failed to allocate pixels");
    2.57 +		goto err;
    2.58 +	}
    2.59 +
    2.60 +	if(fread(&cps, 4, 1, fp) < 1) goto err;
    2.61 +	cps = letohs(cps);
    2.62 +	if(cps <= 0 || cps > 16) {
    2.63 +		fprintf(stderr, "invalid changes-per-line value: %u\n", (unsigned int)cps);
    2.64 +		goto err;
    2.65 +	}
    2.66 +
    2.67 +	/* read palette changes and palette */
    2.68 +
    2.69 +	npalent = cps * 256;
    2.70 +	pstart = npalent - 16;
    2.71 +
    2.72 +	for(i=0; i<npalent; i++) {
    2.73 +		uint16_t palent;
    2.74 +		struct palchange *chg;
    2.75 +
    2.76 +		if(fread(&palent, 2, 1, fp) < 1) {
    2.77 +			perror("unexpected end of file");
    2.78 +			goto err;
    2.79 +		}
    2.80 +		palent = letohs(palent);
    2.81 +
    2.82 +		if(!(chg = malloc(sizeof *chg))) {
    2.83 +			perror("failed to allocate palchange node");
    2.84 +			goto err;
    2.85 +		}
    2.86 +		chg->line = i / cps;
    2.87 +		chg->entry = palent;
    2.88 +		chg->next = 0;
    2.89 +		if(tail) {
    2.90 +			tail->next = chg;
    2.91 +			tail = chg;
    2.92 +		} else {
    2.93 +			img->chglist = tail = chg;
    2.94 +		}
    2.95 +
    2.96 +		if(i >= pstart) {
    2.97 +			img->palette[i - pstart] = palent & 0xfff;
    2.98 +		}
    2.99 +	}
   2.100 +
   2.101 +	/* read pixels */
   2.102 +	if(!(inpixels = malloc(numpix))) {
   2.103 +		perror("failed to allocate pixel buffer");
   2.104 +		goto err;
   2.105 +	}
   2.106 +	if(fread(inpixels, 1, numpix, fp) < numpix) {
   2.107 +		perror("unexpected end of file while reading pixels");
   2.108 +		goto err;
   2.109 +	}
   2.110 +
   2.111 +	for(i=0; i<img->nbitplanes; i++) {
   2.112 +		srcptr = inpixels;
   2.113 +		destptr = img->pixels + i * img->width / 8;
   2.114 +		for(y=0; y<img->height; y++) {
   2.115 +			unsigned char pixval = 0;
   2.116 +			for(x=0; x<img->width; x++) {
   2.117 +				pixval = (pixval << 1) | ((*srcptr++ >> i) & 1);
   2.118 +				if((x & 7) == 7) {
   2.119 +					*destptr++ = pixval;
   2.120 +					pixval = 0;
   2.121 +				}
   2.122 +			}
   2.123 +			destptr += img->width / 8 * (img->nbitplanes - 1);
   2.124 +		}
   2.125 +	}
   2.126 +
   2.127 +	return img;
   2.128 +
   2.129 +err:
   2.130 +	free(inpixels);
   2.131 +	if(img) {
   2.132 +		while(img->chglist) {
   2.133 +			void *tmp = img->chglist;
   2.134 +			img->chglist = img->chglist->next;
   2.135 +			free(tmp);
   2.136 +		}
   2.137 +		free(img->pixels);
   2.138 +		free(img);
   2.139 +	}
   2.140 +	if(fp) fclose(fp);
   2.141 +	return 0;
   2.142  }
   2.143  
   2.144  int save_ham(struct ham_image *img, const char *fname)
   2.145  {
   2.146 +	int i, num;
   2.147 +	unsigned char c, *pptr;
   2.148  	uint16_t val;
   2.149  	FILE *fp;
   2.150 +	struct palchange *chg;
   2.151  
   2.152  	if(!(fp = fopen(fname, "wb"))) {
   2.153  		fprintf(stderr, "failed to open %s for writing: %s\n", fname, strerror(errno));
   2.154 @@ -79,10 +199,41 @@
   2.155  	fprintf(fp, "HAAM");
   2.156  
   2.157  	val = htons(img->width);
   2.158 -	fwrite(fp, 2, 1, &val);
   2.159 +	fwrite(&val, 2, 1, fp);
   2.160  	val = htons(img->height);
   2.161 -	fwrite(fp, 2, 1, &val);
   2.162 -	/* TODO: continue */
   2.163 +	fwrite(&val, 2, 1, fp);
   2.164 +	c = img->nbitplanes;
   2.165 +	fwrite(&c, 1, 1, fp);
   2.166 +	fwrite(&c, 1, 1, fp);	/* padding */
   2.167 +
   2.168 +	num = 0;
   2.169 +	chg = img->chglist;
   2.170 +	while(chg) {
   2.171 +		++num;
   2.172 +		chg = chg->next;
   2.173 +	}
   2.174 +	num = htons(num);
   2.175 +	fwrite(&num, 2, 1, fp);
   2.176 +
   2.177 +	chg = img->chglist;
   2.178 +	while(chg) {
   2.179 +		val = htons(chg->line);
   2.180 +		fwrite(&val, 2, 1, fp);
   2.181 +		val = htons(chg->entry);
   2.182 +		fwrite(&val, 2, 1, fp);
   2.183 +		chg = chg->next;
   2.184 +	}
   2.185 +
   2.186 +	pptr = img->pixels;
   2.187 +	num = img->width * img->height / 8 * img->nbitplanes;
   2.188 +	for(i=0; i<num; i++) {
   2.189 +		val = htons(*pptr);
   2.190 +		++pptr;
   2.191 +
   2.192 +		fwrite(&val, 2, 1, fp);
   2.193 +	}
   2.194 +	fclose(fp);
   2.195 +	return 0;
   2.196  }
   2.197  
   2.198  void free_image(struct ham_image *img)