#include #include #include #define expect(x) do {if (!(x)) {printf("\033[1munexpected %d\033[0m ", __LINE__);}} while(0) void bmx_dump(char * filename, int dumpbitmap) { FILE * fp, *ofp; long filesize; int version, width, height, colors, c; long datasize; unsigned char buffer[16]; printf("%-40s ", filename); fp = fopen(filename, "r"); if (!fp) { perror("fopen"); return; } fseek(fp, 0, SEEK_END); filesize = ftell(fp); fseek(fp, 0, SEEK_SET); fread(buffer, 1, sizeof buffer, fp); expect(buffer[0] == 'B'); expect(buffer[1] == 'M'); expect(buffer[2] == 'X'); expect(buffer[3] == ' '); version = buffer[4] + (buffer[5] << 8); width = buffer[6] + (buffer[7] << 8); height = buffer[8] + (buffer[9] << 8); colors = buffer[10] + (buffer[11] << 8); datasize = buffer[12] + (buffer[13] << 8) + (buffer[14] << 16) + (buffer[15] << 24); expect(version == 1); expect(colors == 256); expect(filesize == datasize + 1040); printf("%4dx%4d\tfs=%5ld\tds=%8ld\n", width, height, filesize, datasize); if (dumpbitmap) { int bytes; int done = 0; int i; int row = height - 1; unsigned char * image; unsigned char * p; unsigned char colors[256][4]; image = calloc(width, height); if (!image) { printf("Couldn't allocate memory\n"); return; } p = image + row * width; fread(colors, 1, sizeof colors, fp); while (!done && (c = fgetc(fp)) != EOF) { switch(c) { case 0: c = fgetc(fp); switch(c) { case 0: row--; p = image + row * width; /* XXX what should the rest of the row be filled with, if we aren't at the end? */ break; case 1: done = 1; break; case 2: /* XXX doesn't handle delta */ printf("Delta! %d", fgetc(fp)); printf(",%d\n", fgetc(fp)); break; default: { int bytes = c; int i; for (i = 0; i < bytes; i++) { c = fgetc(fp); *p++ = c; } if (bytes % 2) fgetc(fp); } } break; default: { int bytes = c; int i; c = fgetc(fp); for (i = 0; i < bytes; i++) { *p++ = c; } } } } expect(ftell(fp) == filesize); { char * dst; size_t fnl; dst = strdup(filename); fnl = strlen(dst); strcpy(dst + fnl - 3, "ppm"); ofp = fopen(dst, "w"); if (!ofp) { perror("fopen write"); return; } fprintf(ofp, "P6 %d %d 255\n", width, height); p = image; for (i = 0; i < height * width; i++) { fputc(colors[*p][3], ofp); fputc(colors[*p][2], ofp); fputc(colors[*p][1], ofp); p++; } } } } int main(int argc, char ** argv) { int i; for (i = 1; i < argc; i++) { bmx_dump(argv[i], 1); } return 0; }