1: // encode -- Steganographically encode a message into 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 encode <seed> <ciphertext_file> <raster_file> <stega_file>
 17: //
 18: int encode(int nargs, char* args[]) {

 20:   // Get the parameters.

 22:   if (nargs != 6) return -1;                      // check number of parameters
 23:   
 24:   char* SEED = args[2];
 25:   char* CIPHERTEXT = args[3];
 26:   char* RASTER_FILE = args[4];
 27:   char* STEGA_FILE = args[5];

 29:   // Read in the fax raster.

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

 43:   // Read in the ciphertext.

 45:   struct stat statbfr;                            // get length of ciphertext file
 46:   stat(CIPHERTEXT, &statbfr);
 47:   long ciphertext_bytes = statbfr.st_size;
 48:   long ciphertext_length = 8*ciphertext_bytes;

 50:   ifstream ciphertext_file(CIPHERTEXT);           // open the ciphertext file
 51:   bit_array ciphertext(ciphertext_length);        // make a bit array to hold it
 52:   ciphertext_file.read(ciphertext.bytes, ciphertext_length); // then read the ciphertext into it

 54:   // Stuff cyphertext length as last 32 bits in the raster.

 56:   long len;
 57:   long i;
 58:   for (len = ciphertext_length,
 59:          i = 1;  
 60:        i <= 32;
 61:        len /= 2,
 62:          i++) {
 63:     raster.set(npixels - i, len % 2);
 64:   }

 66:   // Instantiate a random number generator.

 68:   int seed = atoi(SEED);
 69:   prng rand(seed);

 71:   // Generate the spots where the ciphertext will be mingled.

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

 75:   // Mingle the ciphertext into the raster.

 77:   for (i = 0; i < ciphertext_length; i++ ) {
 78:     raster.set(spot(i), ciphertext(i));           // stuff the ciphertext bit in place of the pixel
 79:   }

 81:   // Output the stegafax raster.

 83:   ofstream stega_file(STEGA_FILE);
 84:   stega_file << "P4\n";                           // pbm magic number
 85:   stega_file << rows << " " << cols << "\n";;
 86:   stega_file.write(raster.bytes, nbytes);         // output stegafax raster

 88:   return 0;
 89: }