1: // decode -- Steganographically decode a message from a fax image.


  4: #include <iostream.h>
  5: #include <fstream.h>
  6: #include <sys/stat.h>
  7: #include <stdlib.h>
  8: #include <stdio.h>

 10: #include "bit_array.H"
 11: #include "permuted_sample.H"


 14: // Calling Sequence:
 15: //
 16: //   stegafax decode <seed> <stega_file> <ciphertext_file>
 17: //
 18: int decode(int nargs, char* args[]) {

 20:   // Get the parameeters.

 22:   char* SEED = args[2];
 23:   char* STEGA_FILE = args[3];
 24:   char* CIPHERTEXT_FILE = args[4];

 26:   // Read in the stega raster.

 28:   ifstream stega_file(STEGA_FILE);
 29:   stega_file.ignore(3);                                   // trash the raster's magic number
 30:   long rows;                                              // number of rows in raster
 31:   stega_file >> rows;                                     // get number of rows from pbm file
 32:   long cols;                                              // number of collums in raster
 33:   stega_file >> cols;                                     // get number of cols from pbm file
 34:   stega_file.ignore(1);                                   // discard terminal newline
 35:   long npixels = rows*cols;                               // number of pixels in raster
 36:   long nbytes = (npixels + 7)/8;                          // number of bytes in raster
 37:   bit_array raster(rows, cols);                           // make a bit array to hold the pbm raster
 38:   stega_file.read(raster.bytes, nbytes);                  // read the pbm raster file into it

 40:   // Extract the original cyphertext length from the last 32 bits of the stega raster.

 42:   long ciphertext_length = 0;
 43:   long i;
 44:   for (i = 32; i >= 1; i--) {
 45:     ciphertext_length = ciphertext_length*2 + raster(npixels - i);
 46:   }
 47:   bit_array ciphertext(ciphertext_length);                // make a bit array to hold the ciphertext

 49:   // Instantiate a random number generator.

 51:   int seed = atoi(SEED);
 52:   prng rand(seed);

 54:   // Generate the spots where the ciphertext was mingled.

 56:   permuted_sample spot(rand, ciphertext_length, npixels - 32); // reserve last 32 bits for cyphertext length

 58:   // Extract the ciphertext from the stega raster.

 60:   for (i = 0; i < ciphertext_length; i++ ) {
 61:     ciphertext.set(i, raster(spot(i)));                   // extract one bit of the hidden message
 62:   }

 64:   // Output the stegafax raster.

 66:   ofstream ciphertext_file(CIPHERTEXT_FILE);
 67:   ciphertext_file.write(ciphertext.bytes, nbytes);        // output ciphertext file

 69:   return 0;
 70: }