lbm2bin

diff src/main.c @ 4:0b96363742d3

added palette export, and fixed a planar pixel output bug
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 16 Jul 2017 21:30:23 +0300
parents bfd8aa2ca393
children 89fd62196739
line diff
     1.1 --- a/src/main.c	Sat Jul 15 13:32:49 2017 +0300
     1.2 +++ b/src/main.c	Sun Jul 16 21:30:23 2017 +0300
     1.3 @@ -1,15 +1,19 @@
     1.4  #include <stdio.h>
     1.5  #include <stdlib.h>
     1.6  #include <string.h>
     1.7 +#include <assert.h>
     1.8  #include <errno.h>
     1.9  #include "image.h"
    1.10  
    1.11  static int proc_image(const char *fname);
    1.12  static const char *modestr(int cmode);
    1.13  static void output_planar(FILE *fp, struct image *img);
    1.14 -static void output_chunky(FILE *fp, struct image *img);
    1.15 +static void output_linear(FILE *fp, struct image *img);
    1.16 +static void output_palette(FILE *fp, struct image *img, int pcol_bits);
    1.17  
    1.18  static int planar = 0;
    1.19 +static int pcol_bits = 8;
    1.20 +static int verbose = 0;
    1.21  
    1.22  int main(int argc, char **argv)
    1.23  {
    1.24 @@ -19,19 +23,30 @@
    1.25  		if(argv[i][0] == '-') {
    1.26  			if(argv[i][2] == 0) {
    1.27  				switch(argv[i][1]) {
    1.28 +				case 'a':
    1.29 +					planar = 1;
    1.30 +					pcol_bits = 4;
    1.31 +					break;
    1.32 +
    1.33  				case 'p':
    1.34  					planar = 1;
    1.35  					break;
    1.36  
    1.37 -				case 'c':
    1.38 +				case 'l':
    1.39  					planar = 0;
    1.40  					break;
    1.41  
    1.42 +				case 'v':
    1.43 +					verbose = 1;
    1.44 +					break;
    1.45 +
    1.46  				case 'h':
    1.47  					printf("usage: %s [options] <file 1> <file 2> ... <file n>\n", argv[0]);
    1.48  					printf("Options:\n");
    1.49 -					printf(" -p: output image in planar format (default)\n");
    1.50 -					printf(" -c: output image in chunky format\n");
    1.51 +					printf(" -a: amiga mode (4bit palette colors & planar format)\n");
    1.52 +					printf(" -p: output image in planar format\n");
    1.53 +					printf(" -c: output image in linear (chunky) format\n");
    1.54 +					printf(" -v: verbose output\n");
    1.55  					printf(" -h: print usage and exit\n");
    1.56  					return 0;
    1.57  
    1.58 @@ -71,9 +86,11 @@
    1.59  	if(!(suffix = strrchr(outfname, '.'))) {
    1.60  		suffix = outfname + strlen(outfname);
    1.61  	}
    1.62 -	strcpy(suffix, ".bin");
    1.63 +	strcpy(suffix, ".img");
    1.64  
    1.65 -	printf("processing %s -> %s\n", fname, outfname);
    1.66 +	if(verbose) {
    1.67 +		printf("processing %s -> %s\n", fname, outfname);
    1.68 +	}
    1.69  
    1.70  	if(!(fp = fopen(outfname, "wb"))) {
    1.71  		fprintf(stderr, "failed to open output file: %s: %s\n", outfname, strerror(errno));
    1.72 @@ -82,23 +99,48 @@
    1.73  		return -1;
    1.74  	}
    1.75  
    1.76 -	printf("  bits per pixel: %d\n", img.bpp);
    1.77 -	if(img.num_ranges) {
    1.78 -		printf("  color ranges:\n");
    1.79 -		for(i=0; i<img.num_ranges; i++) {
    1.80 -			printf("    [%d]: %d - %d, rate: %u, mode: %s\n", i, img.range[i].low, img.range[i].high,
    1.81 -					img.range[i].rate, modestr(img.range[i].cmode));
    1.82 +	if(verbose) {
    1.83 +		printf("  bits per pixel: %d (%d colors)\n", img.bpp, 1 << img.bpp);
    1.84 +		if(img.num_ranges) {
    1.85 +			printf("  color ranges:\n");
    1.86 +			for(i=0; i<img.num_ranges; i++) {
    1.87 +				printf("    [%d]: %d - %d, rate: %u, mode: %s\n", i, img.range[i].low, img.range[i].high,
    1.88 +						img.range[i].rate, modestr(img.range[i].cmode));
    1.89 +			}
    1.90  		}
    1.91  	}
    1.92  
    1.93  	if(planar) {
    1.94 +		if(verbose) printf("  writing planar pixels\n");
    1.95  		output_planar(fp, &img);
    1.96  	} else {
    1.97 -		output_chunky(fp, &img);
    1.98 +		if(verbose) printf("  writing linear pixels\n");
    1.99 +		output_linear(fp, &img);
   1.100 +	}
   1.101 +	fclose(fp);
   1.102 +
   1.103 +	/* open fname.pal */
   1.104 +	strcpy(outfname, fname);
   1.105 +	if(!(suffix = strrchr(outfname, '.'))) {
   1.106 +		suffix = outfname + strlen(outfname);
   1.107 +	}
   1.108 +	strcpy(suffix, ".pal");
   1.109 +
   1.110 +	if(!(fp = fopen(outfname, "wb"))) {
   1.111 +		fprintf(stderr, "failed to open palette file %s for writing: %s\n",
   1.112 +				outfname, strerror(errno));
   1.113 +		free(outfname);
   1.114 +		destroy_image(&img);
   1.115 +		return -1;
   1.116  	}
   1.117  
   1.118 +	if(verbose) {
   1.119 +		printf("  writing %d bit palette colors\n", pcol_bits);
   1.120 +		output_palette(fp, &img, pcol_bits);
   1.121 +	}
   1.122 +
   1.123 +	fclose(fp);
   1.124  	free(outfname);
   1.125 -	fclose(fp);
   1.126  	destroy_image(&img);
   1.127  	return 0;
   1.128  }
   1.129 @@ -113,18 +155,19 @@
   1.130  	for(i=0; i<img->bpp; i++) {
   1.131  		for(y=0; y<img->height; y++) {
   1.132  			for(x=0; x<img->width; x++) {
   1.133 -				acc |= (((*pptr++ >> i) & 1) << acc_bit);
   1.134 +				acc |= (((*pptr >> i) & 1) << acc_bit);
   1.135  				if(--acc_bit == 0) {
   1.136  					fputc(acc, fp);
   1.137  					acc_bit = 7;
   1.138  					acc = 0;
   1.139 +					++pptr;
   1.140  				}
   1.141  			}
   1.142  		}
   1.143  	}
   1.144  }
   1.145  
   1.146 -static void output_chunky(FILE *fp, struct image *img)
   1.147 +static void output_linear(FILE *fp, struct image *img)
   1.148  {
   1.149  	int i, j;
   1.150  	unsigned char *pptr = img->pixels;
   1.151 @@ -136,6 +179,29 @@
   1.152  	}
   1.153  }
   1.154  
   1.155 +static void output_palette(FILE *fp, struct image *img, int pcol_bits)
   1.156 +{
   1.157 +	int i, num_colors;
   1.158 +
   1.159 +	num_colors = 1 << img->bpp;
   1.160 +
   1.161 +	assert(pcol_bits == 8 || pcol_bits == 4);
   1.162 +
   1.163 +	if(pcol_bits == 8) {
   1.164 +		for(i=0; i<num_colors; i++) {
   1.165 +			fputc(img->palette[i].r, fp);
   1.166 +			fputc(img->palette[i].g, fp);
   1.167 +			fputc(img->palette[i].b, fp);
   1.168 +		}
   1.169 +	} else {
   1.170 +		/* nibble colors */
   1.171 +		for(i=0; i<num_colors; i++) {
   1.172 +			fputc(img->palette[i].b | (img->palette[i].g << 4), fp);
   1.173 +			fputc(img->palette[i].r, fp);
   1.174 +		}
   1.175 +	}
   1.176 +}
   1.177 +
   1.178  static const char *modestr(int cmode)
   1.179  {
   1.180  	switch(cmode) {