amiga_imgv

annotate src/image.c @ 11:3d9aaefb8ba6

interlace mode
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 30 Oct 2017 15:24:23 +0200
parents ae0ada629b03
children
rev   line source
nuclear@3 1 #include <stdio.h>
nuclear@0 2 #include <stdlib.h>
nuclear@0 3 #include <string.h>
nuclear@3 4 #include <errno.h>
nuclear@0 5 #include "image.h"
nuclear@3 6 #include "logger.h"
nuclear@7 7 #include "endian.h"
nuclear@6 8
nuclear@6 9 #ifdef __GNUC__
nuclear@6 10 #define PACKED __attribute__((packed))
nuclear@6 11 #else
nuclear@6 12 #define PACKED
nuclear@6 13 #endif
nuclear@6 14
nuclear@3 15 struct ham_image_header {
nuclear@3 16 char magic[4];
nuclear@3 17 uint16_t width, height;
nuclear@3 18 unsigned char nbitplanes, padding;
nuclear@3 19 uint16_t nchg;
nuclear@3 20 uint16_t palette[16];
nuclear@6 21 } PACKED;
nuclear@0 22
nuclear@0 23 struct ham_image *load_ham_image(const char *fname)
nuclear@0 24 {
nuclear@3 25 int i, num;
nuclear@3 26 unsigned long imgsz;
nuclear@3 27 struct ham_image_header hdr;
nuclear@3 28 struct ham_image *img = 0;
nuclear@3 29 struct palchange *tail = 0;
nuclear@3 30 FILE *fp;
nuclear@3 31
nuclear@3 32 logmsg("opening file: %s\n", fname);
nuclear@3 33 if(!(fp = fopen(fname, "rb"))) {
nuclear@3 34 logmsg("failed to open %s: %s\n", fname, strerror(errno));
nuclear@3 35 return 0;
nuclear@3 36 }
nuclear@3 37
nuclear@3 38 if(fread(&hdr, sizeof hdr, 1, fp) < 1) {
nuclear@3 39 logmsg("unexpected eof while reading image header\n");
nuclear@3 40 goto err;
nuclear@3 41 }
nuclear@3 42 if(memcmp(hdr.magic, "HAAM", 4) != 0) {
nuclear@3 43 logmsg("failed to load image: %s: unknown file type\n", fname);
nuclear@3 44 goto err;
nuclear@3 45 }
nuclear@3 46
nuclear@3 47 if(!(img = malloc(sizeof *img))) {
nuclear@3 48 logmsg("failed to allocate image structure\n");
nuclear@3 49 goto err;
nuclear@3 50 }
nuclear@3 51 img->width = ntohs(hdr.width);
nuclear@3 52 img->height = ntohs(hdr.height);
nuclear@3 53 img->nbitplanes = hdr.nbitplanes;
nuclear@7 54 img->ham = 1;
nuclear@3 55
nuclear@3 56 imgsz = img->width * img->height / 8 * img->nbitplanes;
nuclear@3 57
nuclear@3 58 logmsg("header info: %dx%d, %d bpl, size: %lu\n", img->width, img->height, (int)img->nbitplanes, imgsz);
nuclear@3 59
nuclear@3 60 if(!(img->pixels = malloc(imgsz))) {
nuclear@3 61 logmsg("failed to allocate %dx%d (%d bitplane) image\n", img->width, img->height, img->nbitplanes);
nuclear@3 62 goto err;
nuclear@3 63 }
nuclear@3 64
nuclear@3 65 for(i=0; i<16; i++) {
nuclear@3 66 img->palette[i] = ntohs(hdr.palette[i]);
nuclear@3 67 }
nuclear@3 68
nuclear@3 69 num = ntohs(hdr.nchg);
nuclear@3 70 for(i=0; i<num; i++) {
nuclear@3 71 struct palchange *chg;
nuclear@3 72
nuclear@3 73 if(!(chg = malloc(sizeof *chg))) {
nuclear@3 74 logmsg("failed to allocate palchange structure\n");
nuclear@3 75 goto err;
nuclear@3 76 }
nuclear@3 77
nuclear@3 78 if(fread(&chg->line, 2, 1, fp) < 1 || fread(&chg->entry, 2, 1, fp) < 1) {
nuclear@3 79 logmsg("unexpected end of file while reading palette changelist\n");
nuclear@3 80 goto err;
nuclear@3 81 }
nuclear@3 82 chg->line = ntohs(chg->line);
nuclear@3 83 chg->entry = ntohs(chg->entry);
nuclear@3 84 chg->next = 0;
nuclear@3 85
nuclear@3 86 if(tail) {
nuclear@3 87 tail->next = chg;
nuclear@3 88 tail = chg;
nuclear@3 89 } else {
nuclear@3 90 img->chglist = tail = chg;
nuclear@3 91 }
nuclear@3 92 }
nuclear@3 93
nuclear@3 94 if(fread(img->pixels, 1, imgsz, fp) < imgsz) {
nuclear@3 95 logmsg("unexpected end of file while reading image pixels\n");
nuclear@3 96 goto err;
nuclear@3 97 }
nuclear@3 98
nuclear@3 99 fclose(fp);
nuclear@3 100 return img;
nuclear@3 101
nuclear@3 102 err:
nuclear@3 103 if(img) {
nuclear@3 104 while(img->chglist) {
nuclear@3 105 void *tmp = img->chglist;
nuclear@3 106 img->chglist = img->chglist->next;
nuclear@3 107 free(tmp);
nuclear@3 108 }
nuclear@3 109 free(img->pixels);
nuclear@3 110 free(img);
nuclear@3 111 }
nuclear@3 112 if(fp) fclose(fp);
nuclear@3 113 return 0;
nuclear@0 114 }
nuclear@0 115
nuclear@0 116 struct ham_image *gen_ham_image(int w, int h, int nbpl)
nuclear@0 117 {
nuclear@0 118 int i, x, y;
nuclear@0 119 struct ham_image *img;
nuclear@0 120 unsigned char *pptr;
nuclear@0 121 unsigned char pixval;
nuclear@0 122 /*static const uint16_t defpal[] = {
nuclear@0 123 0x000, 0xf00, 0xff0, 0x0f0, 0x0ff, 0x00f, 0xf0f, 0xfff,
nuclear@0 124 0x444, 0x800, 0x880, 0x080, 0x088, 0x008, 0x808, 0x888
nuclear@0 125 };*/
nuclear@0 126
nuclear@0 127 if(!(img = malloc(sizeof *img))) {
nuclear@0 128 return 0;
nuclear@0 129 }
nuclear@0 130 if(!(img->pixels = calloc(w * h / 8 * nbpl, 1))) {
nuclear@0 131 free(img);
nuclear@0 132 return 0;
nuclear@0 133 }
nuclear@0 134 img->width = w;
nuclear@0 135 img->height = h;
nuclear@0 136 img->chglist = 0;
nuclear@0 137
nuclear@0 138 img->nbitplanes = nbpl;
nuclear@0 139 /*memcpy(img->palette, defpal, sizeof defpal);*/
nuclear@0 140 for(i=0; i<16; i++) {
nuclear@0 141 img->palette[i] = i | (i << 4) | (i << 8);
nuclear@0 142 }
nuclear@0 143
nuclear@4 144 for(i=0; i<nbpl; i++) {
nuclear@0 145 pptr = img->pixels + i * w / 8;
nuclear@0 146 for(y=0; y<h; y++) {
nuclear@0 147 pixval = 0;
nuclear@0 148 for(x=0; x<w; x++) {
nuclear@4 149 if(i < 4) {
nuclear@5 150 unsigned char val = ((y >> 3) & 1) == ((x >> 3) & 1) ? 0 : 0xff;
nuclear@5 151 pixval = (pixval >> 1) | (val & 0x80);
nuclear@4 152 }
nuclear@0 153 if((x & 7) == 7) {
nuclear@0 154 *pptr++ = pixval;
nuclear@0 155 pixval = 0;
nuclear@0 156 }
nuclear@0 157 }
nuclear@5 158 pptr += w / 8 * (nbpl - 1);
nuclear@0 159 }
nuclear@0 160 }
nuclear@0 161
nuclear@0 162 return img;
nuclear@0 163 }