amiga_imgv

annotate tools/convhammer/main.c @ 3:663471a80c21

broken + sdl emu
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 26 Oct 2017 15:49:56 +0300
parents f75893a33234
children ae0ada629b03
rev   line source
nuclear@0 1 #include <stdio.h>
nuclear@0 2 #include <stdlib.h>
nuclear@1 3 #include <string.h>
nuclear@2 4 #include <errno.h>
nuclear@1 5 #include <arpa/inet.h>
nuclear@0 6 #include "image.h"
nuclear@0 7
nuclear@1 8 /* hammer dump format (input)
nuclear@1 9 * byte order: little endian
nuclear@1 10 *
nuclear@1 11 * 4 bytes: palette changes per scanline (cps)
nuclear@1 12 * 256 * cps * 2 bytes: [ idx | r | g | b ]
nuclear@1 13 * 320 * 256 bytes: linear HAM pixels
nuclear@1 14 */
nuclear@1 15
nuclear@1 16 /* interleaved ham format (output)
nuclear@1 17 * byte order: big endian
nuclear@1 18 *
nuclear@1 19 * 4 bytes: magic: "HAAM"
nuclear@1 20 * 2 bytes: width
nuclear@1 21 * 2 bytes: height
nuclear@1 22 * 1 byte: number of bitplanes
nuclear@1 23 * 1 byte: padding
nuclear@1 24 * 2 bytes: number of palette change descriptors (nchg)
nuclear@1 25 * 16 * 2 bytes: initial palette [ x | r | g | b ]
nuclear@1 26 * nchg * 4 bytes: [ scanline ] [ idx | r | g | b ]
nuclear@1 27 * width * height / 8 * bitplanes bytes: pixels interleaved scanlines
nuclear@1 28 * [ row0 bpl0 ] ... [ row0 bplN ] [ row1 bpl0 ] ... [ row1 bplN ] ...
nuclear@1 29 */
nuclear@1 30
nuclear@0 31 struct ham_image *load_hammer(const char *fname);
nuclear@0 32 int save_ham(struct ham_image *img, const char *fname);
nuclear@1 33 void free_image(struct ham_image *img);
nuclear@0 34
nuclear@0 35 int main(int argc, char **argv)
nuclear@0 36 {
nuclear@1 37 int i;
nuclear@1 38 struct ham_image *img;
nuclear@1 39 char *name, *dot;
nuclear@1 40
nuclear@1 41 for(i=1; i<argc; i++) {
nuclear@1 42 if(!(img = load_hammer(argv[i]))) {
nuclear@1 43 fprintf(stderr, "failed to load hammer dump: %s\n", argv[i]);
nuclear@1 44 continue;
nuclear@1 45 }
nuclear@1 46
nuclear@1 47 if(!(name = malloc(strlen(argv[i] + 8)))) {
nuclear@1 48 perror("failed to allocate output name buffer");
nuclear@1 49 abort();
nuclear@1 50 }
nuclear@1 51 strcpy(name, argv[i]);
nuclear@1 52
nuclear@1 53 if((dot = strrchr(name, '.'))) {
nuclear@1 54 *dot = 0;
nuclear@1 55 }
nuclear@1 56 strcat(name, ".ham");
nuclear@1 57
nuclear@2 58 if(save_ham(img, name) == -1) {
nuclear@1 59 fprintf(stderr, "failed to save ham image: %s\n", name);
nuclear@1 60 free_image(img);
nuclear@1 61 continue;
nuclear@1 62 }
nuclear@1 63 }
nuclear@1 64 return 0;
nuclear@0 65 }
nuclear@1 66
nuclear@2 67 static uint16_t nops(uint16_t x) { return x; }
nuclear@2 68 static uint16_t swaps(uint16_t x) { return (x >> 8) | (x << 8); }
nuclear@2 69
nuclear@1 70 struct ham_image *load_hammer(const char *fname)
nuclear@1 71 {
nuclear@2 72 int i, x, y, pstart, numpix = 320 * 256;
nuclear@2 73 FILE *fp = 0;
nuclear@2 74 uint32_t cps, npalent;
nuclear@2 75 struct ham_image *img = 0;
nuclear@2 76 struct palchange *tail = 0;
nuclear@2 77 unsigned char *inpixels = 0;
nuclear@2 78 unsigned char *srcptr, *destptr;
nuclear@2 79 uint16_t endtest = 0xaabb;
nuclear@2 80 uint16_t (*letohs)(uint16_t);
nuclear@2 81
nuclear@2 82 letohs = (*(unsigned char*)&endtest == 0xaa) ? swaps : nops;
nuclear@2 83
nuclear@2 84 if(!(fp = fopen(fname, "rb"))) {
nuclear@2 85 fprintf(stderr, "failed to open %s: %s\n", fname, strerror(errno));
nuclear@2 86 return 0;
nuclear@2 87 }
nuclear@2 88
nuclear@2 89 if(!(img = malloc(sizeof *img))) {
nuclear@2 90 perror("failed to allocate image");
nuclear@2 91 goto err;
nuclear@2 92 }
nuclear@2 93 img->width = 320;
nuclear@2 94 img->height = 256;
nuclear@2 95 img->nbitplanes = 6;
nuclear@2 96 img->chglist = 0;
nuclear@2 97
nuclear@2 98 if(!(img->pixels = malloc(img->width * img->height / 8 * img->nbitplanes))) {
nuclear@2 99 perror("failed to allocate pixels");
nuclear@2 100 goto err;
nuclear@2 101 }
nuclear@2 102
nuclear@2 103 if(fread(&cps, 4, 1, fp) < 1) goto err;
nuclear@2 104 cps = letohs(cps);
nuclear@2 105 if(cps <= 0 || cps > 16) {
nuclear@2 106 fprintf(stderr, "invalid changes-per-line value: %u\n", (unsigned int)cps);
nuclear@2 107 goto err;
nuclear@2 108 }
nuclear@2 109
nuclear@2 110 /* read palette changes and palette */
nuclear@2 111
nuclear@2 112 npalent = cps * 256;
nuclear@2 113 pstart = npalent - 16;
nuclear@2 114
nuclear@2 115 for(i=0; i<npalent; i++) {
nuclear@2 116 uint16_t palent;
nuclear@2 117 struct palchange *chg;
nuclear@2 118
nuclear@2 119 if(fread(&palent, 2, 1, fp) < 1) {
nuclear@2 120 perror("unexpected end of file");
nuclear@2 121 goto err;
nuclear@2 122 }
nuclear@2 123 palent = letohs(palent);
nuclear@2 124
nuclear@2 125 if(!(chg = malloc(sizeof *chg))) {
nuclear@2 126 perror("failed to allocate palchange node");
nuclear@2 127 goto err;
nuclear@2 128 }
nuclear@2 129 chg->line = i / cps;
nuclear@2 130 chg->entry = palent;
nuclear@2 131 chg->next = 0;
nuclear@2 132 if(tail) {
nuclear@2 133 tail->next = chg;
nuclear@2 134 tail = chg;
nuclear@2 135 } else {
nuclear@2 136 img->chglist = tail = chg;
nuclear@2 137 }
nuclear@2 138
nuclear@2 139 if(i >= pstart) {
nuclear@2 140 img->palette[i - pstart] = palent & 0xfff;
nuclear@2 141 }
nuclear@2 142 }
nuclear@2 143
nuclear@2 144 /* read pixels */
nuclear@2 145 if(!(inpixels = malloc(numpix))) {
nuclear@2 146 perror("failed to allocate pixel buffer");
nuclear@2 147 goto err;
nuclear@2 148 }
nuclear@2 149 if(fread(inpixels, 1, numpix, fp) < numpix) {
nuclear@2 150 perror("unexpected end of file while reading pixels");
nuclear@2 151 goto err;
nuclear@2 152 }
nuclear@2 153
nuclear@2 154 for(i=0; i<img->nbitplanes; i++) {
nuclear@2 155 srcptr = inpixels;
nuclear@2 156 destptr = img->pixels + i * img->width / 8;
nuclear@2 157 for(y=0; y<img->height; y++) {
nuclear@2 158 unsigned char pixval = 0;
nuclear@2 159 for(x=0; x<img->width; x++) {
nuclear@2 160 pixval = (pixval << 1) | ((*srcptr++ >> i) & 1);
nuclear@2 161 if((x & 7) == 7) {
nuclear@2 162 *destptr++ = pixval;
nuclear@2 163 pixval = 0;
nuclear@2 164 }
nuclear@2 165 }
nuclear@2 166 destptr += img->width / 8 * (img->nbitplanes - 1);
nuclear@2 167 }
nuclear@2 168 }
nuclear@2 169
nuclear@3 170 free(inpixels);
nuclear@3 171 fclose(fp);
nuclear@2 172 return img;
nuclear@2 173
nuclear@2 174 err:
nuclear@2 175 free(inpixels);
nuclear@2 176 if(img) {
nuclear@2 177 while(img->chglist) {
nuclear@2 178 void *tmp = img->chglist;
nuclear@2 179 img->chglist = img->chglist->next;
nuclear@2 180 free(tmp);
nuclear@2 181 }
nuclear@2 182 free(img->pixels);
nuclear@2 183 free(img);
nuclear@2 184 }
nuclear@2 185 if(fp) fclose(fp);
nuclear@2 186 return 0;
nuclear@1 187 }
nuclear@1 188
nuclear@1 189 int save_ham(struct ham_image *img, const char *fname)
nuclear@1 190 {
nuclear@2 191 int i, num;
nuclear@2 192 unsigned char c, *pptr;
nuclear@1 193 uint16_t val;
nuclear@1 194 FILE *fp;
nuclear@2 195 struct palchange *chg;
nuclear@1 196
nuclear@1 197 if(!(fp = fopen(fname, "wb"))) {
nuclear@1 198 fprintf(stderr, "failed to open %s for writing: %s\n", fname, strerror(errno));
nuclear@1 199 return -1;
nuclear@1 200 }
nuclear@1 201 fprintf(fp, "HAAM");
nuclear@1 202
nuclear@1 203 val = htons(img->width);
nuclear@2 204 fwrite(&val, 2, 1, fp);
nuclear@1 205 val = htons(img->height);
nuclear@2 206 fwrite(&val, 2, 1, fp);
nuclear@2 207 c = img->nbitplanes;
nuclear@2 208 fwrite(&c, 1, 1, fp);
nuclear@2 209 fwrite(&c, 1, 1, fp); /* padding */
nuclear@2 210
nuclear@2 211 num = 0;
nuclear@2 212 chg = img->chglist;
nuclear@2 213 while(chg) {
nuclear@2 214 ++num;
nuclear@2 215 chg = chg->next;
nuclear@2 216 }
nuclear@2 217 num = htons(num);
nuclear@2 218 fwrite(&num, 2, 1, fp);
nuclear@2 219
nuclear@3 220 for(i=0; i<16; i++) {
nuclear@3 221 val = htons(img->palette[i]);
nuclear@3 222 fwrite(&val, 2, 1, fp);
nuclear@3 223 }
nuclear@3 224
nuclear@2 225 chg = img->chglist;
nuclear@2 226 while(chg) {
nuclear@2 227 val = htons(chg->line);
nuclear@2 228 fwrite(&val, 2, 1, fp);
nuclear@2 229 val = htons(chg->entry);
nuclear@2 230 fwrite(&val, 2, 1, fp);
nuclear@2 231 chg = chg->next;
nuclear@2 232 }
nuclear@2 233
nuclear@2 234 pptr = img->pixels;
nuclear@2 235 num = img->width * img->height / 8 * img->nbitplanes;
nuclear@2 236 for(i=0; i<num; i++) {
nuclear@2 237 val = htons(*pptr);
nuclear@2 238 ++pptr;
nuclear@2 239
nuclear@2 240 fwrite(&val, 2, 1, fp);
nuclear@2 241 }
nuclear@2 242 fclose(fp);
nuclear@2 243 return 0;
nuclear@1 244 }
nuclear@1 245
nuclear@1 246 void free_image(struct ham_image *img)
nuclear@1 247 {
nuclear@1 248 if(img) {
nuclear@1 249 free(img->pixels);
nuclear@1 250 while(img->chglist) {
nuclear@1 251 void *tmp = img->chglist;
nuclear@1 252 img->chglist = img->chglist->next;
nuclear@1 253 free(tmp);
nuclear@1 254 }
nuclear@1 255 free(img);
nuclear@1 256 }
nuclear@1 257 }