/** * @file step0.c * @author Robert S Laramee * @version 1.0 * @see Announcement *

* start date 1 July 1999 * finish date 1 July 1999 *

* Description This is step 0 of 2 steps. Step 0 is to add 128-113 z * layers of 0 padding to the original head data set * or 128-64 z layers of 0 padding to the lobster data set. * But step 0 is really made up of many smaller steps: * i. uncompressing the data * ii. coverting the data from binary to ASCII * iii. padding the data with zeros * iv. Expanding the data rows, columns, and layers by 1 (use expand.c) * * This includes functions to see how many bytes certain data types like * short and int are on a pentium machine running Linux. Why? *

* The CThead data sets were written on a Digital Equipment Corporation * (DEC) VAX computer. Each file contains only pixels, stored in row major * order with 2-byte integers per pixel. To use the images on machines * that have normal byte order (DECs use reverse byte order), you should swap * alternate bytes, for example using the 'dd' command in UNIX. A sample * command that does this for the 3dknee data set is: * % dd if=3dknee of=3dknee.new conv=swab * * So, we would like to see which data type uses 2 bytes. * Note: To uncompress CThead.Z use the command: * % uncompress CThead.Z * * Note: using the unix 'od' (octal dump) utility: * % od -vi CThead * We dump the file as decimal shorts * * Note: * maximum of head data set = 2248 * minimum of head data set = -1117 */ #include #include /* dimensions constants -the original data set 'CThead' is * z-113 y-256 x-256 slices * lobster is 128 x 128 x 64 * knee is 256 x 256 x 127 (almost 128) * We're going to pad z-113 (z-127 for knee data) to a power of 2, i.e. * 128 (2 to the 7th) because the build_mr program expects data to * be a power of 2 (plus 1) */ #define ZHEADLAYERS 113 #define YHEADCOLUMNS 256 #define XHEADROWS 256 #define MAXIMUMHEAD 2248 #define MINIMUMHEAD -1117 #define ZLOBSTERLAYERS 128 /* the lobster is floats */ #define YLOBSTERCOLUMNS 128 #define XLOBSTERROWS 64 #define MAXIMUMLOBSTER 255 /* unknown */ #define MINIMUMLOBSTER 0 /* unknown */ #define ZKNEELAYERS 127 #define YKNEECOLUMNS 256 #define XKNEEROWS 256 #define MAXIMUMKNEE 4095 /* w/ swap 32,535 */ /* 4095 w/o swap */ #define MINIMUMKNEE 0 /* w/ swap -32,768 */ /* 0 w/o swap */ /** * The main() function starts the bytes program. We can see how many * bytes each data type takes by running the program and then: * % ls -l * Compile using:
* % gcc -Wall step0.c -Iinclude -lm -o step0.exe * * Start the program using: * % step0.exe [input file] > outputFile.ascii * e.g. * % step0.exe ~rlaramee/data/lobster.bin > * ~rlaramee/data/lobster.ascii */ int main (int argc, char *argv[]) { FILE *inputFile; FILE *outputFile; int i = 0; int x = 0; int y = 0; int z = 0; int integerNumber = 1; int maximum = 0; int minimum = 0; short shortNumber = 1; float floatNumber = 1.0; long longNumber = 1.0; double doubleNumber = 1.0; /* open a file for writing a single integer in binary * ------ */ if (( outputFile = fopen("1integerNumber" , "w")) == NULL) { perror("***Error, couldn't open output file"); exit(1); } /* write a single integer in binary */ if (fwrite(&integerNumber, sizeof(int), 1, outputFile) != 1) { perror("***Error saving integerNumber to a file."); exit(1); } if (fclose(outputFile)) perror("***Error closing output file."); /* open a file for writing a single short in binary * ----- */ if (( outputFile = fopen("1shortNumber" , "w")) == NULL) { perror("***Error, couldn't open output file"); exit(1); } /* write a single short in binary */ if (fwrite(&shortNumber, sizeof(short), 1, outputFile) != 1) { perror("***Error saving integerNumber to a file."); exit(1); } if (fclose(outputFile)) perror("***Error closing output file."); /* open a file for writing multiple shorts in binary * --------------- */ if (( outputFile = fopen("1shortNumbers" , "w")) == NULL) { perror("***Error, couldn't open output file"); exit(1); } /* write multiple shorts in binary */ for (i = 0; i < 10; i++) { shortNumber = i; if (fwrite(&shortNumber, sizeof(short), 1, outputFile) != 1) { perror("***Error saving integerNumber to a file."); exit(1); } } if (fclose(outputFile)) perror("***Error closing output file."); /* open a file for writing a single long in binary * ---- */ if (( outputFile = fopen("1longNumber" , "w")) == NULL) { perror("***Error, couldn't open output file"); exit(1); } /* write a single short in binary */ if (fwrite(&longNumber, sizeof(long), 1, outputFile) != 1) { perror("***Error saving integerNumber to a file."); exit(1); } if (fclose(outputFile)) perror("***Error closing output file."); /* open a file for writing a single double in binary * ------ */ if (( outputFile = fopen("1doubleNumber" , "w")) == NULL) { perror("***Error, couldn't open output file"); exit(1); } /* write a single double in binary */ if (fwrite(&doubleNumber, sizeof(double), 1, outputFile) != 1) { perror("***Error saving integerNumber to a file."); exit(1); } if (fclose(outputFile)) perror("***Error closing output file."); /** * Let's read the test file and print out the numbers (read binary) */ if (( inputFile = fopen("1shortNumbers" , "rb")) == NULL) { perror("***Error, couldn't open input file"); exit(1); } /** * Let's read the CThead file and print out the numbers (read binary) */ if (( inputFile = fopen(argv[1] , "rb")) == NULL) { fprintf(stderr, "***Error, couldn't open input file: %s", argv[1]); exit(1); } /** * Output that file in ASCII format, one number per line. * We'll also normalize the data by dividing each number by * the maximum yielding a range from 0.0 to 1.0 * helpful numbers: * 256 * 256 = 65,536 * 113 * 256 * 256 = 7,405,568 * 128 * 256 * 256 = 8,388,608 -for head (shorts) * 128 * 128 * 64 = 1,048,576 -for lobster (floats) * 256 * 256 * 127 = 1,048,576 -for knee (shorts) */ i = 0; for (z = 0; z < ZLOBSTERLAYERS; z++) { for (y = 0; y < YLOBSTERCOLUMNS; y++) { for (x = 0; x < XLOBSTERROWS; x++) { /* the lobster is floats */ i++; if (fread(&floatNumber, sizeof(float), 1, inputFile) != 1) { perror("***Error reading floatNumber to a file."); break; } if (floatNumber > maximum) maximum = floatNumber; if (floatNumber < minimum) minimum = floatNumber; printf("%f\n", ( (floatNumber - MINIMUMLOBSTER)/ (MAXIMUMLOBSTER - MINIMUMLOBSTER) ) ); } } } fprintf(stderr, " # The number of lines (w/o padding) is: %d \n", i); /* This is the part where we pad the data. The original data set * 'CThead' is * z-113 y-256 x-256 slices * '3dknee' is * 256 x 256 x 127 * We're going to pad z-113 to a power of 2, i.e. 128 (2 to the 7th) * because the build_mr program expects data to be a power of 2 (plus 1) */ for (z = 0; z < 128 - ZLOBSTERLAYERS; z++) { for (y = 0; y < YLOBSTERCOLUMNS; y++) { for (x = 0; x < XLOBSTERROWS; x++) { i++; printf("0.0\n"); } } } fprintf(stderr, " # The total number of lines (w/ padding) is: %d \n", i); fprintf(stderr, " # maximum number = %d \n", maximum); fprintf(stderr, " # minimum number = %d \n", minimum); if (fclose(inputFile)) perror("***Error closing input file."); return 0; }