amiga_imgv

changeset 12:20c7238c60be tip

img2ham unfinished
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 20 Nov 2017 08:36:16 +0200
parents 3d9aaefb8ba6
children
files tools/img2ham/Makefile tools/img2ham/main.c
diffstat 2 files changed, 239 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/tools/img2ham/Makefile	Mon Nov 20 08:36:16 2017 +0200
     1.3 @@ -0,0 +1,13 @@
     1.4 +src = $(wildcard *.c)
     1.5 +obj = $(src:.c=.o)
     1.6 +bin = img2ham
     1.7 +
     1.8 +CFLAGS = -pedantic -Wall -g -I../../src
     1.9 +LDFLAGS = -limago
    1.10 +
    1.11 +$(bin): $(obj)
    1.12 +	$(CC) -o $@ $(obj) $(LDFLAGS)
    1.13 +
    1.14 +.PHONY: clean
    1.15 +clean:
    1.16 +	rm -f $(obj) $(bin)
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/tools/img2ham/main.c	Mon Nov 20 08:36:16 2017 +0200
     2.3 @@ -0,0 +1,226 @@
     2.4 +#include <stdio.h>
     2.5 +#include <stdlib.h>
     2.6 +#include <string.h>
     2.7 +#include <limits.h>
     2.8 +#include <errno.h>
     2.9 +#include <imago2.h>
    2.10 +#include <arpa/inet.h>
    2.11 +#include "image.h"
    2.12 +
    2.13 +static int convert(struct ham_image *img, unsigned char *pixels, int xsz, int ysz);
    2.14 +static int save_ham(struct ham_image *img, const char *fname);
    2.15 +static void destroy_image(struct ham_image *img);
    2.16 +
    2.17 +int main(int argc, char **argv)
    2.18 +{
    2.19 +	int i, width, height, len;
    2.20 +	unsigned char *pixels;
    2.21 +	char *out_fname, *suffix;
    2.22 +	struct ham_image img;
    2.23 +
    2.24 +	for(i=1; i<argc; i++) {
    2.25 +		if(!(pixels = img_load_pixels(argv[i], &width, &height, IMG_FMT_RGB24))) {
    2.26 +			fprintf(stderr, "failed to load image: %s\n", argv[i]);
    2.27 +			continue;
    2.28 +		}
    2.29 +		convert(&img, pixels, width, height);
    2.30 +
    2.31 +		len = strlen(argv[i]) + 4;
    2.32 +		if(!(out_fname = malloc(len + 1))) {
    2.33 +			perror("failed to allocate memory");
    2.34 +			abort();
    2.35 +		}
    2.36 +		memcpy(out_fname, argv[i], len + 1);
    2.37 +		if(!(suffix = strrchr(out_fname, '.'))) {
    2.38 +			suffix = out_fname + len;
    2.39 +		}
    2.40 +		memcpy(suffix, ".ham", 5);
    2.41 +
    2.42 +		save_ham(&img, out_fname);
    2.43 +		destroy_image(&img);
    2.44 +
    2.45 +		free(out_fname);
    2.46 +	}
    2.47 +
    2.48 +	return 0;
    2.49 +}
    2.50 +
    2.51 +struct fringe {
    2.52 +	int pixel, score;
    2.53 +};
    2.54 +
    2.55 +static int detect_fringes(int *flist, int num, unsigned char *scanline, int width, int pr, int pg, int pb)
    2.56 +{
    2.57 +	int i, j, fcount = 0;
    2.58 +	struct fringe fringes[16] = {{0, 0}};
    2.59 +
    2.60 +	if(num > 16) num = 16;
    2.61 +
    2.62 +	for(i=0; i<width; i++) {
    2.63 +		int r = *scanline++;
    2.64 +		int g = *scanline++;
    2.65 +		int b = *scanline++;
    2.66 +		int dr = r - pr;
    2.67 +		int dg = g - pg;
    2.68 +		int db = b - pb;
    2.69 +		int max = dr > dg ? (dr > db ? dr : db) : (dg > db ? dg : db);
    2.70 +		int score = dr + dg + db - max;
    2.71 +
    2.72 +		if(score > 0) {
    2.73 +			int min = fringes[0].score, min_idx = 0;
    2.74 +			for(j=1; j<fcount; j++) {
    2.75 +				if(fringes[j].score < min) {
    2.76 +					min = fringes[j].score;
    2.77 +					min_idx = j;
    2.78 +				}
    2.79 +			}
    2.80 +			if(score > min) {
    2.81 +				fringes[min_idx].score = score;
    2.82 +				fringes[min_idx].pixel = i;
    2.83 +			}
    2.84 +		}
    2.85 +	}
    2.86 +}
    2.87 +
    2.88 +static int convert(struct ham_image *img, unsigned char *pixels, int xsz, int ysz)
    2.89 +{
    2.90 +	int i, j, x, y, pstart, numpix = xsz * ysz;
    2.91 +	FILE *fp = 0;
    2.92 +	uint32_t cps, npalent;
    2.93 +	struct palchange *tail = 0;
    2.94 +	unsigned char *inpixels = 0;
    2.95 +	unsigned char *srcptr, *destptr;
    2.96 +
    2.97 +	/* convert RGB to HAM in-place */
    2.98 +	for(i=0; i<ysz; i++) {
    2.99 +		for(j=0; j<xsz; j++) {
   2.100 +		}
   2.101 +	}
   2.102 +
   2.103 +	img->width = xsz;
   2.104 +	img->height = ysz;
   2.105 +	img->nbitplanes = 6;
   2.106 +	img->ham = 1;
   2.107 +	img->chglist = 0;
   2.108 +
   2.109 +	if(!(img->pixels = malloc(img->width * img->height / 8 * img->nbitplanes))) {
   2.110 +		perror("failed to allocate pixels");
   2.111 +		goto err;
   2.112 +	}
   2.113 +
   2.114 +	for(i=0; i<img->nbitplanes; i++) {
   2.115 +		srcptr = inpixels;
   2.116 +		destptr = img->pixels + i * img->width / 8;
   2.117 +		for(y=0; y<img->height; y++) {
   2.118 +			unsigned char pixval = 0;
   2.119 +			for(x=0; x<img->width; x++) {
   2.120 +				pixval = (pixval << 1) | ((*srcptr++ >> i) & 1);
   2.121 +				if((x & 7) == 7) {
   2.122 +					*destptr++ = pixval;
   2.123 +					pixval = 0;
   2.124 +				}
   2.125 +			}
   2.126 +			destptr += img->width / 8 * (img->nbitplanes - 1);
   2.127 +		}
   2.128 +	}
   2.129 +
   2.130 +	free(inpixels);
   2.131 +	fclose(fp);
   2.132 +	return img;
   2.133 +
   2.134 +err:
   2.135 +	free(inpixels);
   2.136 +	if(img) {
   2.137 +		while(img->chglist) {
   2.138 +			void *tmp = img->chglist;
   2.139 +			img->chglist = img->chglist->next;
   2.140 +			free(tmp);
   2.141 +		}
   2.142 +		free(img->pixels);
   2.143 +		free(img);
   2.144 +	}
   2.145 +	if(fp) fclose(fp);
   2.146 +	return 0;
   2.147 +}
   2.148 +
   2.149 +
   2.150 +/* interleaved ham format (output)
   2.151 + * byte order: big endian
   2.152 + *
   2.153 + * 4 bytes: magic: "HAAM"
   2.154 + * 2 bytes: width
   2.155 + * 2 bytes: height
   2.156 + * 1 byte: number of bitplanes
   2.157 + * 1 byte: padding
   2.158 + * 2 bytes: number of palette change descriptors (nchg)
   2.159 + * 16 * 2 bytes: initial palette [ x | r | g | b ]
   2.160 + * nchg * 4 bytes: [ scanline ] [ idx | r | g | b ]
   2.161 + * width * height / 8 * bitplanes bytes: pixels interleaved scanlines
   2.162 + *     [ row0 bpl0 ] ... [ row0 bplN ] [ row1 bpl0 ] ... [ row1 bplN ] ...
   2.163 + */
   2.164 +static int save_ham(struct ham_image *img, const char *fname)
   2.165 +{
   2.166 +	int i, num;
   2.167 +	unsigned char c, *pptr;
   2.168 +	uint16_t val;
   2.169 +	FILE *fp;
   2.170 +	struct palchange *chg;
   2.171 +
   2.172 +	if(!(fp = fopen(fname, "wb"))) {
   2.173 +		fprintf(stderr, "failed to open %s for writing: %s\n", fname, strerror(errno));
   2.174 +		return -1;
   2.175 +	}
   2.176 +	fprintf(fp, "HAAM");
   2.177 +
   2.178 +	val = htons(img->width);
   2.179 +	fwrite(&val, 2, 1, fp);
   2.180 +	val = htons(img->height);
   2.181 +	fwrite(&val, 2, 1, fp);
   2.182 +	c = img->nbitplanes;
   2.183 +	fwrite(&c, 1, 1, fp);
   2.184 +	fwrite(&c, 1, 1, fp);	/* padding */
   2.185 +
   2.186 +	num = 0;
   2.187 +	chg = img->chglist;
   2.188 +	while(chg) {
   2.189 +		++num;
   2.190 +		chg = chg->next;
   2.191 +	}
   2.192 +	num = htons(num);
   2.193 +	fwrite(&num, 2, 1, fp);
   2.194 +
   2.195 +	for(i=0; i<16; i++) {
   2.196 +		val = htons(img->palette[i]);
   2.197 +		fwrite(&val, 2, 1, fp);
   2.198 +	}
   2.199 +
   2.200 +	chg = img->chglist;
   2.201 +	while(chg) {
   2.202 +		val = htons(chg->line);
   2.203 +		fwrite(&val, 2, 1, fp);
   2.204 +		val = htons(chg->entry);
   2.205 +		fwrite(&val, 2, 1, fp);
   2.206 +		chg = chg->next;
   2.207 +	}
   2.208 +
   2.209 +	pptr = img->pixels;
   2.210 +	num = img->width * img->height / 8 * img->nbitplanes;
   2.211 +	for(i=0; i<num; i++) {
   2.212 +		fwrite(pptr, 1, 1, fp);
   2.213 +		++pptr;
   2.214 +	}
   2.215 +	fclose(fp);
   2.216 +	return 0;
   2.217 +}
   2.218 +
   2.219 +void destroy_image(struct ham_image *img)
   2.220 +{
   2.221 +	if(img) {
   2.222 +		free(img->pixels);
   2.223 +		while(img->chglist) {
   2.224 +			void *tmp = img->chglist;
   2.225 +			img->chglist = img->chglist->next;
   2.226 +			free(tmp);
   2.227 +		}
   2.228 +	}
   2.229 +}