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 +}