# HG changeset patch # User John Tsiombikas # Date 1511159776 -7200 # Node ID 20c7238c60be6df3e35c14c2d3de6a66c2d5abc7 # Parent 3d9aaefb8ba6624cc830c0ac9ad15ff44cb83614 img2ham unfinished diff -r 3d9aaefb8ba6 -r 20c7238c60be tools/img2ham/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/img2ham/Makefile Mon Nov 20 08:36:16 2017 +0200 @@ -0,0 +1,13 @@ +src = $(wildcard *.c) +obj = $(src:.c=.o) +bin = img2ham + +CFLAGS = -pedantic -Wall -g -I../../src +LDFLAGS = -limago + +$(bin): $(obj) + $(CC) -o $@ $(obj) $(LDFLAGS) + +.PHONY: clean +clean: + rm -f $(obj) $(bin) diff -r 3d9aaefb8ba6 -r 20c7238c60be tools/img2ham/main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/img2ham/main.c Mon Nov 20 08:36:16 2017 +0200 @@ -0,0 +1,226 @@ +#include +#include +#include +#include +#include +#include +#include +#include "image.h" + +static int convert(struct ham_image *img, unsigned char *pixels, int xsz, int ysz); +static int save_ham(struct ham_image *img, const char *fname); +static void destroy_image(struct ham_image *img); + +int main(int argc, char **argv) +{ + int i, width, height, len; + unsigned char *pixels; + char *out_fname, *suffix; + struct ham_image img; + + for(i=1; i 16) num = 16; + + for(i=0; i dg ? (dr > db ? dr : db) : (dg > db ? dg : db); + int score = dr + dg + db - max; + + if(score > 0) { + int min = fringes[0].score, min_idx = 0; + for(j=1; j min) { + fringes[min_idx].score = score; + fringes[min_idx].pixel = i; + } + } + } +} + +static int convert(struct ham_image *img, unsigned char *pixels, int xsz, int ysz) +{ + int i, j, x, y, pstart, numpix = xsz * ysz; + FILE *fp = 0; + uint32_t cps, npalent; + struct palchange *tail = 0; + unsigned char *inpixels = 0; + unsigned char *srcptr, *destptr; + + /* convert RGB to HAM in-place */ + for(i=0; iwidth = xsz; + img->height = ysz; + img->nbitplanes = 6; + img->ham = 1; + img->chglist = 0; + + if(!(img->pixels = malloc(img->width * img->height / 8 * img->nbitplanes))) { + perror("failed to allocate pixels"); + goto err; + } + + for(i=0; inbitplanes; i++) { + srcptr = inpixels; + destptr = img->pixels + i * img->width / 8; + for(y=0; yheight; y++) { + unsigned char pixval = 0; + for(x=0; xwidth; x++) { + pixval = (pixval << 1) | ((*srcptr++ >> i) & 1); + if((x & 7) == 7) { + *destptr++ = pixval; + pixval = 0; + } + } + destptr += img->width / 8 * (img->nbitplanes - 1); + } + } + + free(inpixels); + fclose(fp); + return img; + +err: + free(inpixels); + if(img) { + while(img->chglist) { + void *tmp = img->chglist; + img->chglist = img->chglist->next; + free(tmp); + } + free(img->pixels); + free(img); + } + if(fp) fclose(fp); + return 0; +} + + +/* interleaved ham format (output) + * byte order: big endian + * + * 4 bytes: magic: "HAAM" + * 2 bytes: width + * 2 bytes: height + * 1 byte: number of bitplanes + * 1 byte: padding + * 2 bytes: number of palette change descriptors (nchg) + * 16 * 2 bytes: initial palette [ x | r | g | b ] + * nchg * 4 bytes: [ scanline ] [ idx | r | g | b ] + * width * height / 8 * bitplanes bytes: pixels interleaved scanlines + * [ row0 bpl0 ] ... [ row0 bplN ] [ row1 bpl0 ] ... [ row1 bplN ] ... + */ +static int save_ham(struct ham_image *img, const char *fname) +{ + int i, num; + unsigned char c, *pptr; + uint16_t val; + FILE *fp; + struct palchange *chg; + + if(!(fp = fopen(fname, "wb"))) { + fprintf(stderr, "failed to open %s for writing: %s\n", fname, strerror(errno)); + return -1; + } + fprintf(fp, "HAAM"); + + val = htons(img->width); + fwrite(&val, 2, 1, fp); + val = htons(img->height); + fwrite(&val, 2, 1, fp); + c = img->nbitplanes; + fwrite(&c, 1, 1, fp); + fwrite(&c, 1, 1, fp); /* padding */ + + num = 0; + chg = img->chglist; + while(chg) { + ++num; + chg = chg->next; + } + num = htons(num); + fwrite(&num, 2, 1, fp); + + for(i=0; i<16; i++) { + val = htons(img->palette[i]); + fwrite(&val, 2, 1, fp); + } + + chg = img->chglist; + while(chg) { + val = htons(chg->line); + fwrite(&val, 2, 1, fp); + val = htons(chg->entry); + fwrite(&val, 2, 1, fp); + chg = chg->next; + } + + pptr = img->pixels; + num = img->width * img->height / 8 * img->nbitplanes; + for(i=0; ipixels); + while(img->chglist) { + void *tmp = img->chglist; + img->chglist = img->chglist->next; + free(tmp); + } + } +}