lbm2bin

annotate src/main.c @ 0:bfd8aa2ca393

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 15 Jul 2017 13:26:32 +0300
parents
children 0b96363742d3
rev   line source
nuclear@0 1 #include <stdio.h>
nuclear@0 2 #include <stdlib.h>
nuclear@0 3 #include <string.h>
nuclear@0 4 #include <errno.h>
nuclear@0 5 #include "image.h"
nuclear@0 6
nuclear@0 7 static int proc_image(const char *fname);
nuclear@0 8 static const char *modestr(int cmode);
nuclear@0 9 static void output_planar(FILE *fp, struct image *img);
nuclear@0 10 static void output_chunky(FILE *fp, struct image *img);
nuclear@0 11
nuclear@0 12 static int planar = 0;
nuclear@0 13
nuclear@0 14 int main(int argc, char **argv)
nuclear@0 15 {
nuclear@0 16 int i;
nuclear@0 17
nuclear@0 18 for(i=1; i<argc; i++) {
nuclear@0 19 if(argv[i][0] == '-') {
nuclear@0 20 if(argv[i][2] == 0) {
nuclear@0 21 switch(argv[i][1]) {
nuclear@0 22 case 'p':
nuclear@0 23 planar = 1;
nuclear@0 24 break;
nuclear@0 25
nuclear@0 26 case 'c':
nuclear@0 27 planar = 0;
nuclear@0 28 break;
nuclear@0 29
nuclear@0 30 case 'h':
nuclear@0 31 printf("usage: %s [options] <file 1> <file 2> ... <file n>\n", argv[0]);
nuclear@0 32 printf("Options:\n");
nuclear@0 33 printf(" -p: output image in planar format (default)\n");
nuclear@0 34 printf(" -c: output image in chunky format\n");
nuclear@0 35 printf(" -h: print usage and exit\n");
nuclear@0 36 return 0;
nuclear@0 37
nuclear@0 38 default:
nuclear@0 39 fprintf(stderr, "invalid option: %s\n", argv[i]);
nuclear@0 40 return 1;
nuclear@0 41 }
nuclear@0 42 } else {
nuclear@0 43 fprintf(stderr, "invalid option: %s\n", argv[i]);
nuclear@0 44 }
nuclear@0 45 } else {
nuclear@0 46 if(proc_image(argv[i]) == -1) {
nuclear@0 47 return 1;
nuclear@0 48 }
nuclear@0 49 }
nuclear@0 50 }
nuclear@0 51 return 0;
nuclear@0 52 }
nuclear@0 53
nuclear@0 54 static int proc_image(const char *fname)
nuclear@0 55 {
nuclear@0 56 int i;
nuclear@0 57 struct image img;
nuclear@0 58 char *outfname, *suffix;
nuclear@0 59 FILE *fp;
nuclear@0 60
nuclear@0 61 if(load_image(&img, fname) == -1) {
nuclear@0 62 fprintf(stderr, "failed to load image: %s\n", fname);
nuclear@0 63 return -1;
nuclear@0 64 }
nuclear@0 65
nuclear@0 66 if(!(outfname = malloc(strlen(fname) + 4))) {
nuclear@0 67 perror("failed to allocate output filename");
nuclear@0 68 return -1;
nuclear@0 69 }
nuclear@0 70 strcpy(outfname, fname);
nuclear@0 71 if(!(suffix = strrchr(outfname, '.'))) {
nuclear@0 72 suffix = outfname + strlen(outfname);
nuclear@0 73 }
nuclear@0 74 strcpy(suffix, ".bin");
nuclear@0 75
nuclear@0 76 printf("processing %s -> %s\n", fname, outfname);
nuclear@0 77
nuclear@0 78 if(!(fp = fopen(outfname, "wb"))) {
nuclear@0 79 fprintf(stderr, "failed to open output file: %s: %s\n", outfname, strerror(errno));
nuclear@0 80 destroy_image(&img);
nuclear@0 81 free(outfname);
nuclear@0 82 return -1;
nuclear@0 83 }
nuclear@0 84
nuclear@0 85 printf(" bits per pixel: %d\n", img.bpp);
nuclear@0 86 if(img.num_ranges) {
nuclear@0 87 printf(" color ranges:\n");
nuclear@0 88 for(i=0; i<img.num_ranges; i++) {
nuclear@0 89 printf(" [%d]: %d - %d, rate: %u, mode: %s\n", i, img.range[i].low, img.range[i].high,
nuclear@0 90 img.range[i].rate, modestr(img.range[i].cmode));
nuclear@0 91 }
nuclear@0 92 }
nuclear@0 93
nuclear@0 94 if(planar) {
nuclear@0 95 output_planar(fp, &img);
nuclear@0 96 } else {
nuclear@0 97 output_chunky(fp, &img);
nuclear@0 98 }
nuclear@0 99
nuclear@0 100 free(outfname);
nuclear@0 101 fclose(fp);
nuclear@0 102 destroy_image(&img);
nuclear@0 103 return 0;
nuclear@0 104 }
nuclear@0 105
nuclear@0 106 static void output_planar(FILE *fp, struct image *img)
nuclear@0 107 {
nuclear@0 108 int i, x, y;
nuclear@0 109 unsigned char acc = 0;
nuclear@0 110 int acc_bit = 7;
nuclear@0 111 unsigned char *pptr = img->pixels;
nuclear@0 112
nuclear@0 113 for(i=0; i<img->bpp; i++) {
nuclear@0 114 for(y=0; y<img->height; y++) {
nuclear@0 115 for(x=0; x<img->width; x++) {
nuclear@0 116 acc |= (((*pptr++ >> i) & 1) << acc_bit);
nuclear@0 117 if(--acc_bit == 0) {
nuclear@0 118 fputc(acc, fp);
nuclear@0 119 acc_bit = 7;
nuclear@0 120 acc = 0;
nuclear@0 121 }
nuclear@0 122 }
nuclear@0 123 }
nuclear@0 124 }
nuclear@0 125 }
nuclear@0 126
nuclear@0 127 static void output_chunky(FILE *fp, struct image *img)
nuclear@0 128 {
nuclear@0 129 int i, j;
nuclear@0 130 unsigned char *pptr = img->pixels;
nuclear@0 131
nuclear@0 132 for(i=0; i<img->height; i++) {
nuclear@0 133 for(j=0; j<img->width; j++) {
nuclear@0 134 fputc(*pptr++, fp);
nuclear@0 135 }
nuclear@0 136 }
nuclear@0 137 }
nuclear@0 138
nuclear@0 139 static const char *modestr(int cmode)
nuclear@0 140 {
nuclear@0 141 switch(cmode) {
nuclear@0 142 case CYCLE_NORMAL:
nuclear@0 143 return "forward";
nuclear@0 144 case CYCLE_REVERSE:
nuclear@0 145 return "reverse";
nuclear@0 146 case CYCLE_PINGPONG:
nuclear@0 147 return "ping-pong";
nuclear@0 148 case CYCLE_SINE_HALF:
nuclear@0 149 return "half-sine";
nuclear@0 150 case CYCLE_SINE:
nuclear@0 151 return "sine";
nuclear@0 152 default:
nuclear@0 153 break;
nuclear@0 154 }
nuclear@0 155 return "unknown";
nuclear@0 156 }