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: }