amiga_imgv

annotate tools/img2ham/main.c @ 12:20c7238c60be

img2ham unfinished
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 20 Nov 2017 08:36:16 +0200
parents
children
rev   line source
nuclear@12 1 #include <stdio.h>
nuclear@12 2 #include <stdlib.h>
nuclear@12 3 #include <string.h>
nuclear@12 4 #include <limits.h>
nuclear@12 5 #include <errno.h>
nuclear@12 6 #include <imago2.h>
nuclear@12 7 #include <arpa/inet.h>
nuclear@12 8 #include "image.h"
nuclear@12 9
nuclear@12 10 static int convert(struct ham_image *img, unsigned char *pixels, int xsz, int ysz);
nuclear@12 11 static int save_ham(struct ham_image *img, const char *fname);
nuclear@12 12 static void destroy_image(struct ham_image *img);
nuclear@12 13
nuclear@12 14 int main(int argc, char **argv)
nuclear@12 15 {
nuclear@12 16 int i, width, height, len;
nuclear@12 17 unsigned char *pixels;
nuclear@12 18 char *out_fname, *suffix;
nuclear@12 19 struct ham_image img;
nuclear@12 20
nuclear@12 21 for(i=1; i<argc; i++) {
nuclear@12 22 if(!(pixels = img_load_pixels(argv[i], &width, &height, IMG_FMT_RGB24))) {
nuclear@12 23 fprintf(stderr, "failed to load image: %s\n", argv[i]);
nuclear@12 24 continue;
nuclear@12 25 }
nuclear@12 26 convert(&img, pixels, width, height);
nuclear@12 27
nuclear@12 28 len = strlen(argv[i]) + 4;
nuclear@12 29 if(!(out_fname = malloc(len + 1))) {
nuclear@12 30 perror("failed to allocate memory");
nuclear@12 31 abort();
nuclear@12 32 }
nuclear@12 33 memcpy(out_fname, argv[i], len + 1);
nuclear@12 34 if(!(suffix = strrchr(out_fname, '.'))) {
nuclear@12 35 suffix = out_fname + len;
nuclear@12 36 }
nuclear@12 37 memcpy(suffix, ".ham", 5);
nuclear@12 38
nuclear@12 39 save_ham(&img, out_fname);
nuclear@12 40 destroy_image(&img);
nuclear@12 41
nuclear@12 42 free(out_fname);
nuclear@12 43 }
nuclear@12 44
nuclear@12 45 return 0;
nuclear@12 46 }
nuclear@12 47
nuclear@12 48 struct fringe {
nuclear@12 49 int pixel, score;
nuclear@12 50 };
nuclear@12 51
nuclear@12 52 static int detect_fringes(int *flist, int num, unsigned char *scanline, int width, int pr, int pg, int pb)
nuclear@12 53 {
nuclear@12 54 int i, j, fcount = 0;
nuclear@12 55 struct fringe fringes[16] = {{0, 0}};
nuclear@12 56
nuclear@12 57 if(num > 16) num = 16;
nuclear@12 58
nuclear@12 59 for(i=0; i<width; i++) {
nuclear@12 60 int r = *scanline++;
nuclear@12 61 int g = *scanline++;
nuclear@12 62 int b = *scanline++;
nuclear@12 63 int dr = r - pr;
nuclear@12 64 int dg = g - pg;
nuclear@12 65 int db = b - pb;
nuclear@12 66 int max = dr > dg ? (dr > db ? dr : db) : (dg > db ? dg : db);
nuclear@12 67 int score = dr + dg + db - max;
nuclear@12 68
nuclear@12 69 if(score > 0) {
nuclear@12 70 int min = fringes[0].score, min_idx = 0;
nuclear@12 71 for(j=1; j<fcount; j++) {
nuclear@12 72 if(fringes[j].score < min) {
nuclear@12 73 min = fringes[j].score;
nuclear@12 74 min_idx = j;
nuclear@12 75 }
nuclear@12 76 }
nuclear@12 77 if(score > min) {
nuclear@12 78 fringes[min_idx].score = score;
nuclear@12 79 fringes[min_idx].pixel = i;
nuclear@12 80 }
nuclear@12 81 }
nuclear@12 82 }
nuclear@12 83 }
nuclear@12 84
nuclear@12 85 static int convert(struct ham_image *img, unsigned char *pixels, int xsz, int ysz)
nuclear@12 86 {
nuclear@12 87 int i, j, x, y, pstart, numpix = xsz * ysz;
nuclear@12 88 FILE *fp = 0;
nuclear@12 89 uint32_t cps, npalent;
nuclear@12 90 struct palchange *tail = 0;
nuclear@12 91 unsigned char *inpixels = 0;
nuclear@12 92 unsigned char *srcptr, *destptr;
nuclear@12 93
nuclear@12 94 /* convert RGB to HAM in-place */
nuclear@12 95 for(i=0; i<ysz; i++) {
nuclear@12 96 for(j=0; j<xsz; j++) {
nuclear@12 97 }
nuclear@12 98 }
nuclear@12 99
nuclear@12 100 img->width = xsz;
nuclear@12 101 img->height = ysz;
nuclear@12 102 img->nbitplanes = 6;
nuclear@12 103 img->ham = 1;
nuclear@12 104 img->chglist = 0;
nuclear@12 105
nuclear@12 106 if(!(img->pixels = malloc(img->width * img->height / 8 * img->nbitplanes))) {
nuclear@12 107 perror("failed to allocate pixels");
nuclear@12 108 goto err;
nuclear@12 109 }
nuclear@12 110
nuclear@12 111 for(i=0; i<img->nbitplanes; i++) {
nuclear@12 112 srcptr = inpixels;
nuclear@12 113 destptr = img->pixels + i * img->width / 8;
nuclear@12 114 for(y=0; y<img->height; y++) {
nuclear@12 115 unsigned char pixval = 0;
nuclear@12 116 for(x=0; x<img->width; x++) {
nuclear@12 117 pixval = (pixval << 1) | ((*srcptr++ >> i) & 1);
nuclear@12 118 if((x & 7) == 7) {
nuclear@12 119 *destptr++ = pixval;
nuclear@12 120 pixval = 0;
nuclear@12 121 }
nuclear@12 122 }
nuclear@12 123 destptr += img->width / 8 * (img->nbitplanes - 1);
nuclear@12 124 }
nuclear@12 125 }
nuclear@12 126
nuclear@12 127 free(inpixels);
nuclear@12 128 fclose(fp);
nuclear@12 129 return img;
nuclear@12 130
nuclear@12 131 err:
nuclear@12 132 free(inpixels);
nuclear@12 133 if(img) {
nuclear@12 134 while(img->chglist) {
nuclear@12 135 void *tmp = img->chglist;
nuclear@12 136 img->chglist = img->chglist->next;
nuclear@12 137 free(tmp);
nuclear@12 138 }
nuclear@12 139 free(img->pixels);
nuclear@12 140 free(img);
nuclear@12 141 }
nuclear@12 142 if(fp) fclose(fp);
nuclear@12 143 return 0;
nuclear@12 144 }
nuclear@12 145
nuclear@12 146
nuclear@12 147 /* interleaved ham format (output)
nuclear@12 148 * byte order: big endian
nuclear@12 149 *
nuclear@12 150 * 4 bytes: magic: "HAAM"
nuclear@12 151 * 2 bytes: width
nuclear@12 152 * 2 bytes: height
nuclear@12 153 * 1 byte: number of bitplanes
nuclear@12 154 * 1 byte: padding
nuclear@12 155 * 2 bytes: number of palette change descriptors (nchg)
nuclear@12 156 * 16 * 2 bytes: initial palette [ x | r | g | b ]
nuclear@12 157 * nchg * 4 bytes: [ scanline ] [ idx | r | g | b ]
nuclear@12 158 * width * height / 8 * bitplanes bytes: pixels interleaved scanlines
nuclear@12 159 * [ row0 bpl0 ] ... [ row0 bplN ] [ row1 bpl0 ] ... [ row1 bplN ] ...
nuclear@12 160 */
nuclear@12 161 static int save_ham(struct ham_image *img, const char *fname)
nuclear@12 162 {
nuclear@12 163 int i, num;
nuclear@12 164 unsigned char c, *pptr;
nuclear@12 165 uint16_t val;
nuclear@12 166 FILE *fp;
nuclear@12 167 struct palchange *chg;
nuclear@12 168
nuclear@12 169 if(!(fp = fopen(fname, "wb"))) {
nuclear@12 170 fprintf(stderr, "failed to open %s for writing: %s\n", fname, strerror(errno));
nuclear@12 171 return -1;
nuclear@12 172 }
nuclear@12 173 fprintf(fp, "HAAM");
nuclear@12 174
nuclear@12 175 val = htons(img->width);
nuclear@12 176 fwrite(&val, 2, 1, fp);
nuclear@12 177 val = htons(img->height);
nuclear@12 178 fwrite(&val, 2, 1, fp);
nuclear@12 179 c = img->nbitplanes;
nuclear@12 180 fwrite(&c, 1, 1, fp);
nuclear@12 181 fwrite(&c, 1, 1, fp); /* padding */
nuclear@12 182
nuclear@12 183 num = 0;
nuclear@12 184 chg = img->chglist;
nuclear@12 185 while(chg) {
nuclear@12 186 ++num;
nuclear@12 187 chg = chg->next;
nuclear@12 188 }
nuclear@12 189 num = htons(num);
nuclear@12 190 fwrite(&num, 2, 1, fp);
nuclear@12 191
nuclear@12 192 for(i=0; i<16; i++) {
nuclear@12 193 val = htons(img->palette[i]);
nuclear@12 194 fwrite(&val, 2, 1, fp);
nuclear@12 195 }
nuclear@12 196
nuclear@12 197 chg = img->chglist;
nuclear@12 198 while(chg) {
nuclear@12 199 val = htons(chg->line);
nuclear@12 200 fwrite(&val, 2, 1, fp);
nuclear@12 201 val = htons(chg->entry);
nuclear@12 202 fwrite(&val, 2, 1, fp);
nuclear@12 203 chg = chg->next;
nuclear@12 204 }
nuclear@12 205
nuclear@12 206 pptr = img->pixels;
nuclear@12 207 num = img->width * img->height / 8 * img->nbitplanes;
nuclear@12 208 for(i=0; i<num; i++) {
nuclear@12 209 fwrite(pptr, 1, 1, fp);
nuclear@12 210 ++pptr;
nuclear@12 211 }
nuclear@12 212 fclose(fp);
nuclear@12 213 return 0;
nuclear@12 214 }
nuclear@12 215
nuclear@12 216 void destroy_image(struct ham_image *img)
nuclear@12 217 {
nuclear@12 218 if(img) {
nuclear@12 219 free(img->pixels);
nuclear@12 220 while(img->chglist) {
nuclear@12 221 void *tmp = img->chglist;
nuclear@12 222 img->chglist = img->chglist->next;
nuclear@12 223 free(tmp);
nuclear@12 224 }
nuclear@12 225 }
nuclear@12 226 }