#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#define RUN_MAX 32767
void create_numbers_file( FILE *stream, char *outfile );
unsigned int encode_rle(unsigned char * fileArr, unsigned int filePos, unsigned int quantity, unsigned char value);
void
usage(void) {
printf("\nusage: setupdialog -i <image file> -oi <image output> -n <numbers file> -on <numbers output>\n");
printf("\nYou can supply a panic image file, a numbers file, or both. Input files\n");
printf("must be in RAW format where each pixel is represented by an index into the\n");
printf("MacOS X system CLUT. The first %d bytes must be the width, height, and depth\n", 3 * sizeof(short));
printf("(in that order, %d bytes each).\n", sizeof(short));
printf("\nThe output files are generated C structures in the format the panic ui code\n");
printf("expects (default output files are panic_image.c and rendered_numbers.c).\n\n");
}
int
main( int argc, char *argv[] )
{
int next;
char *file = NULL, *ptr, *out = NULL, *numsfile = NULL, *numsout = NULL;
FILE * stream, *out_stream;
int * data;
short width = 0, height = 0, depth = 0;
char word[2];
char byte;
unsigned int i, pixels, filePos;
int err;
unsigned char *fileArr;
unsigned char nextP;
unsigned int count;
int currP;
int fd;
int pairs_this_line;
for( next = 1; next < argc; next++ )
{
if (strcmp(argv[next], "-i") == 0) file = argv[++next];
else if (strcmp(argv[next], "-n") == 0) numsfile = argv[++next];
else if (strcmp(argv[next], "-oi") == 0) out = argv[++next];
else if (strcmp(argv[next], "-on") == 0) numsout = argv[++next];
}
if (!(numsfile || file)) {
usage();
exit(1);
}
if (!numsfile) {
printf("\nNo numbers file to process\n");
} else {
stream = fopen(numsfile, "r");
if (!stream) {
printf("bad nums infile.. bailing.\n");
exit(1);
}
create_numbers_file( stream, numsout );
fclose(stream);
}
if( file == NULL) {
printf("\nNo image file to process\n");
exit(1);
}
stream = fopen(file, "r");
if (!stream) {
printf("bad infile.. bailing.\n");
exit(1);
}
printf("\nReading image file...\n");
fread((void *) &width, sizeof(short), 1, stream);
printf("got width: %d\n", width);
fread((void *) &height, sizeof(short), 1, stream);
printf("got height: %d\n", height);
fread((void *) &depth, sizeof(short), 1, stream);
printf("got depth: %d\n", depth);
if (!(width && height && depth)) {
printf("Invalid image file header (width, height, or depth is 0)\n");
exit(1);
}
pixels = width * height;
if (!(fileArr = (unsigned char *) malloc(pixels))) {
printf("couldn't malloc fileArr (%d pixels)... bailing.\n", pixels);
exit(1);
}
currP = -1;
count = 0;
filePos = 0;
for (i=0; i < pixels; i++) {
nextP = fgetc(stream);
count++;
if (nextP == currP) {
if (count >= RUN_MAX) {
filePos += encode_rle(fileArr, filePos, count, (unsigned char) currP);
count = 0;
currP = -1;
}
} else {
if (currP != -1) {
filePos += encode_rle(fileArr, filePos, count-1, (unsigned char) currP);
}
currP = nextP; count = 1;
}
}
if (count > 0) {
filePos += encode_rle(fileArr, filePos, count, (unsigned char) currP);
}
fclose( stream );
if ( out == NULL)
out = "panic_image.c";
out_stream = fopen(out, "w");
if(out_stream == NULL) {
printf("couldn't open out file.. bailing\n");
exit(1);
}
pairs_this_line = 0;
fprintf( out_stream, "/* generated c file */\n\n");
fprintf( out_stream, "static const struct {\n");
fprintf( out_stream, " unsigned int pd_width;\n");
fprintf( out_stream, " unsigned int pd_height;\n");
fprintf( out_stream, " unsigned int bytes_per_pixel; /* 1: CLUT, 3:RGB, 4:RGBA */\n");
fprintf( out_stream, " unsigned char image_pixel_data[%#4.2x];\n", (filePos));
fprintf( out_stream, "} panic_dialog = {\n");
fprintf( out_stream, "\t%d, ", width);
fprintf( out_stream, "%d, ", height);
fprintf( out_stream, "1,\n");
for( i=0; i < filePos;) {
fprintf( out_stream, "0x%.2x,0x%.2x", fileArr[i], fileArr[i+1]);
i+=2;
pairs_this_line++;
if ((fileArr[i-2] >> 7) == 1) {
fprintf( out_stream, ",0x%.2x", fileArr[i++]);
pairs_this_line++;
}
if (i >= filePos) fprintf( out_stream, "\n};");
else fprintf( out_stream, ", ");
if(pairs_this_line > 8) {
fprintf( out_stream, "\n");
pairs_this_line = 0;
}
}
fclose( out_stream );
return 0;
}
void
create_numbers_file( FILE *stream, char *outfile )
{
int err;
short height, depth, totalwidth;
int numbers = 17;
int width[17] = {9,7,8,6,9,7,8,7,8,7,10,7,9,10,7,6,4};
int numPos[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int **pixmap;
int row, col, item, line=0, currWidth;
int nextP, currP;
int count, currNum;
FILE *out_stream;
printf("\nReading numbers file...\n");
fread((void *) &totalwidth, sizeof(short), 1, stream);
printf("got width: %d\n", totalwidth);
fread((void *) &height, sizeof(short), 1, stream);
printf("got height: %d\n", height);
fread((void *) &depth, sizeof(short), 1, stream);
printf("got depth: %d\n", depth);
if (!(width && height && depth)) {
printf("Invalid numbers file header (width, height, or depth is 0)\n");
return;
}
pixmap = (int **) malloc( 17 * sizeof(int *) );
for( item=0; item<17; item++)
pixmap[item] = (int *) malloc( 2*width[item]*height*sizeof(int) );
currP = -1;
count = 0;
currWidth = 0;
currNum = 0;
for( row=0; row < height; row++) {
for( item=0; item < numbers; item++) {
count = 0;
currP = -1; for( col=0; col < width[item]; col++) {
nextP = fgetc( stream );
if( nextP == currP) {
if( count == 127) { pixmap[item][numPos[item]] = count;
pixmap[item][numPos[item]+1] = currP;
numPos[item]+=2;
count = 0;
currP = -1;
} else count++; } else {
if( currP != -1) {
pixmap[item][numPos[item]] = count; pixmap[item][numPos[item]+1] = currP;
numPos[item]+=2;
}
currP = nextP; count = 1;
}
}
if( count > 0) {
pixmap[item][numPos[item]] = count;
pixmap[item][numPos[item]+1] = currP;
numPos[item]+=2;
}
}
}
if ( outfile == NULL)
outfile = "rendered_numbers.c";
out_stream = fopen(outfile, "w");
if(out_stream == NULL) {
printf("couldn't open numbers outfile.. bailing\n");
exit(1);
}
fprintf( out_stream, " /* generated c file */\n\n");
for( item=0; item<numbers; item++)
{
fprintf( out_stream, "static const struct {\n");
fprintf( out_stream, " unsigned int num_w;\n");
fprintf( out_stream, " unsigned int num_h;\n");
fprintf( out_stream, " unsigned char num_pixel_data[%#4.2x];\n", numPos[item]); item == 16 ? fprintf( out_stream, "} num_colon = {\n") : fprintf( out_stream, "} num_%x = {\n", item);
fprintf( out_stream, "/* w */ %d,\n", width[item]);
fprintf( out_stream, "/* h */ %d,\n", height);
fprintf( out_stream, "/* pixel_data */ \n");
for( col = 0; col < numPos[item];)
{
fprintf( out_stream, "0x%.2x,0x%.2x", pixmap[item][col], pixmap[item][col+1]);
if (col == (numPos[item] - 2)) fprintf( out_stream, "\n};\n\n");
else fprintf( out_stream, ", ");
line+=pixmap[item][col];
if( line >= width[item]) {
fprintf( out_stream, "\n");
line = 0;
}
col+=2;
}
}
fclose( out_stream );
}
unsigned int
encode_rle(unsigned char * fileArr, unsigned int filePos, unsigned int quantity, unsigned char value)
{
unsigned char single_mask = 0x00;
unsigned char double_mask = 0x80;
unsigned char slots_used = 0;
if (quantity < 128) {
fileArr[filePos] = single_mask | quantity;
slots_used = 1;
} else {
fileArr[filePos] = double_mask | (quantity >> 8); fileArr[filePos+1] = (unsigned char) quantity; slots_used = 2;
}
fileArr[filePos+slots_used] = value;
slots_used++;
return slots_used;
}