1: // noise -- Inject white noise into a fax image. 3: #include <iostream.h> 4: #include <fstream.h> 5: #include <sys/stat.h> 6: #include <stdlib.h> 7: #include <stdio.h> 9: #include "bit_array.H" 10: #include "random_sample.H" 13: // Calling sequence: 14: // 15: // stegafax noise <seed> <percent> <input_file> <output_file> 16: // 17: // This entry point injects noise into a fax raster as a pbm file. 18: // This has the effect of lowering the contrast of the fax image, and 19: // also acting as "cover" for the steganographic message bits, which 20: // otherwise likewise introduce a "graying" of the background white 21: // space. 22: // 23: int noise(int nargs, char* args[]) { 25: // Get the parameters. 27: if (nargs != 6) return -1; // check number of parameters 29: char* SEED = args[2]; 30: char* PERCENT = args[3]; 31: char* INPUT_FILE = args[4]; 32: char* OUTPUT_FILE = args[5]; 34: double percent = atof(PERCENT); 35: if (percent > (double)100 // sanity checks 36: || percent < (double)0) { 37: printf("Noise percentage must be between 0%% and 100%%.\n"); 39: return -1; 40: } 42: // Note that an inversion of 100% of the bits will produce a 43: // negative of the fax image. Therefore, inverting 50% of the bits 44: // produces maximum entropy -- pure noise. 46: percent /= (double)200; // fudge factor :->~ 48: // Instantiate a random number generator. 50: int seed = atoi(SEED); 51: prng rand(seed); 53: // Read in the fax raster from stdin. 55: ifstream input_file(INPUT_FILE); 56: input_file.ignore(3); // trash the raster's magic number 57: long rows; // number of rows in raster 58: input_file >> rows; // get number of rows from pbm file 59: long cols; // number of collums in raster 60: input_file >> cols; // get number of cols from pbm file 61: input_file.ignore(1); // discard terminal newline 62: long npixels = rows*cols; // number of pixels in raster 63: long nbytes = (npixels + 7)/8; // number of bytes in raster 64: bit_array raster(rows, cols); // make a bit array to hold the pbm raster 65: input_file.read(raster.bytes, nbytes); // read the pbm raster file into it 67: // Take a random sample of the bits in the image. 69: long N = npixels; 70: long n = (long)((double)N*percent); // number of bits we're going to hit 71: random_sample spot(rand, n, N); // all the spots in the image we're going to clobber 73: // Invert the sampled bits. 75: long i; 76: for (i = 0; i < n; i++) { 77: raster.set(spot(i), !raster(spot(i))); // compliment the selected bits 78: } 80: // Output the stegafax raster. 82: ofstream output_file(OUTPUT_FILE); 83: output_file << "P4\n"; // pbm magic number 84: output_file << rows << " " << cols << "\n"; 85: output_file.write(raster.bytes, nbytes); // output stegafax raster to stdout 87: return 0; 88: }