| 0 | 1 #include "wm.h" | 
|  | 2 #include "signature.h" | 
|  | 3 #include "dwt.h" | 
|  | 4 #include "pgm.h" | 
|  | 5 | 
|  | 6 char *progname; | 
|  | 7 | 
|  | 8 // inverse watermarking transformation, extract embedded bit, check quantization boundaries | 
|  | 9 double wm_transform(double alpha, double f1, double f2, double f3) { | 
|  | 10   double s = alpha * (fabs(f3) - fabs(f1)) / 2.0; | 
|  | 11   double l = f1; | 
|  | 12   int x; | 
|  | 13 | 
|  | 14   x = 0; | 
|  | 15   while (l  < f2) { | 
|  | 16     l += s; | 
|  | 17     x++; | 
|  | 18   } | 
|  | 19 | 
|  | 20   if (fabs(l - s - f2) < fabs(l-f2)) | 
|  | 21     return (x+1) % 2; | 
|  | 22   else | 
|  | 23     return (x) % 2; | 
|  | 24 } | 
|  | 25 | 
|  | 26 void usage(void) { | 
|  | 27   fprintf(stderr, "usage: %s [-a n] [-e n] [-f n] [-F n] [-h] [-l n] [-o file] [-v n] -s file file\n\n", progname); | 
|  | 28   fprintf(stderr, "\t-a n\t\tembedding strength (default 0.05)\n"); | 
|  | 29   fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); | 
|  | 30   fprintf(stderr, "\t-f n\t\tfilter number\n"); | 
|  | 31   fprintf(stderr, "\t-F file\t\tfilter definition file\n"); | 
|  | 32   fprintf(stderr, "\t-l n\t\tembedding level\n"); | 
|  | 33   fprintf(stderr, "\t-h\t\tprint usage\n"); | 
|  | 34   fprintf(stderr, "\t-o file\t\textracted signature file\n"); | 
|  | 35   fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); | 
|  | 36   fprintf(stderr, "\t-v n\t\tverbosity level\n"); | 
|  | 37   exit(0); | 
|  | 38 } | 
|  | 39 | 
|  | 40 int main(int argc, char *argv[]) { | 
|  | 41 | 
|  | 42   FILE *in = stdin; | 
|  | 43   FILE *out = stdout; | 
|  | 44   FILE *sig = NULL; | 
|  | 45 | 
|  | 46   char output_name[MAXPATHLEN] = "(stdout)"; | 
|  | 47   char input_name[MAXPATHLEN] = "(stdin)"; | 
|  | 48   char signature_name[MAXPATHLEN]; | 
|  | 49 | 
|  | 50   int c, n; | 
|  | 51   int row, col; | 
|  | 52 | 
|  | 53   double alpha = 0.0; | 
|  | 54   int filter = 0; | 
|  | 55   int method = -1; | 
|  | 56   int level = 0; | 
|  | 57   char filter_name[MAXPATHLEN] = ""; | 
|  | 58 | 
|  | 59   int seed; | 
|  | 60   int verbose = 0; | 
|  | 61 | 
|  | 62   gray **image; | 
|  | 63   Image_tree dwts, p; | 
|  | 64 | 
|  | 65   gray maxval; | 
|  | 66   int rows, cols, colors, format; | 
|  | 67 | 
|  | 68   progname = argv[0]; | 
|  | 69 | 
|  | 70   pgm_init(&argc, argv); wm_init2(); | 
|  | 71 | 
|  | 72   while ((c = getopt(argc, argv, "a:e:f:F:h?l:o:s:v:")) != EOF) { | 
|  | 73     switch (c) { | 
|  | 74       case 'e': | 
|  | 75         method = atoi(optarg); | 
|  | 76         if (method < 0) { | 
|  | 77           fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); | 
|  | 78           exit(1); | 
|  | 79         } | 
|  | 80         break; | 
|  | 81       case 'f': | 
|  | 82         filter = atoi(optarg); | 
|  | 83         if (filter <= 0) { | 
|  | 84           fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); | 
|  | 85           exit(1); | 
|  | 86         } | 
|  | 87         break; | 
|  | 88       case 'F': | 
|  | 89         strcpy(filter_name, optarg); | 
|  | 90         break; | 
|  | 91       case 'h': | 
|  | 92       case '?': | 
|  | 93         usage(); | 
|  | 94         break; | 
|  | 95       case 'l': | 
|  | 96         level = atoi(optarg); | 
|  | 97         if (level < 1) { | 
|  | 98           fprintf(stderr, "%s: embedding level out of range\n", progname); | 
|  | 99           exit(1); | 
|  | 100         } | 
|  | 101         break; | 
|  | 102       case 'o': | 
|  | 103         if ((out = fopen(optarg, "wb")) == NULL) { | 
|  | 104           fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); | 
|  | 105           exit(1); | 
|  | 106         } | 
|  | 107         strcpy(output_name, optarg); | 
|  | 108         break; | 
|  | 109       case 'a': | 
|  | 110         alpha = atof(optarg); | 
|  | 111         if (alpha <= 0.0) { | 
|  | 112           fprintf(stderr, "%s: embedding strength factor %f out of range\n", progname, alpha); | 
|  | 113           exit(1); | 
|  | 114         } | 
|  | 115         break; | 
|  | 116       case 's': | 
|  | 117         if ((sig = fopen(optarg, "r")) == NULL) { | 
|  | 118           fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); | 
|  | 119           exit(1); | 
|  | 120         } | 
|  | 121         strcpy(signature_name, optarg); | 
|  | 122         break; | 
|  | 123       case 'v': | 
|  | 124         verbose = atoi(optarg); | 
|  | 125         if (verbose < 0) { | 
|  | 126           fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); | 
|  | 127           exit(1); | 
|  | 128         } | 
|  | 129         break; | 
|  | 130     } | 
|  | 131   } | 
|  | 132 | 
|  | 133   argc -= optind; | 
|  | 134   argv += optind; | 
|  | 135 | 
|  | 136   if (argc > 1) { | 
|  | 137     usage(); | 
|  | 138     exit(1); | 
|  | 139   } | 
|  | 140 | 
|  | 141   if (argc == 1 && *argv[0] != '-') | 
|  | 142     if ((in = fopen(argv[0], "rb")) == NULL) { | 
|  | 143       fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); | 
|  | 144       exit(1); | 
|  | 145     } | 
|  | 146     else | 
|  | 147       strcpy(input_name, argv[0]); | 
|  | 148 | 
|  | 149   if (sig) { | 
|  | 150     char line[32]; | 
|  | 151     fgets(line, sizeof(line), sig); | 
|  | 152     if (strspn(line, "XESG") >= 4) { | 
|  | 153       fscanf(sig, "%d\n", &nbit_signature); | 
|  | 154       if (alpha == 0.0) | 
|  | 155         fscanf(sig, "%lf\n", &alpha); | 
|  | 156       else | 
|  | 157         fscanf(sig, "%*lf\n"); | 
|  | 158       if (method < 0) | 
|  | 159         fscanf(sig, "%d\n", &method); | 
|  | 160       else | 
|  | 161         fscanf(sig, "%*d\n"); | 
|  | 162       if (filter == 0) | 
|  | 163         fscanf(sig, "%d\n", &filter); | 
|  | 164       else | 
|  | 165         fscanf(sig, "%*d\n"); | 
|  | 166       if (!strcmp(filter_name, "")) | 
|  | 167         fscanf(sig, "%[^\n\r]\n", &filter_name); | 
|  | 168       else | 
|  | 169         fscanf(sig, "%*[^\n\r]\n"); | 
|  | 170       if (level == 0) | 
|  | 171         fscanf(sig, "%d\n", &level); | 
|  | 172       else | 
|  | 173         fscanf(sig, "%*d\n"); | 
|  | 174       fscanf(sig, "%d\n", &seed); | 
|  | 175       srandom(seed); | 
|  | 176       n_signature = NBITSTOBYTES(nbit_signature); | 
|  | 177       fread(signature, sizeof(char), n_signature, sig); | 
|  | 178       fscanf(sig, "\n"); | 
|  | 179     } | 
|  | 180     else { | 
|  | 181       fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); | 
|  | 182       exit(1); | 
|  | 183     } | 
|  | 184     fclose(sig); | 
|  | 185   } | 
|  | 186   else { | 
|  | 187     fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); | 
|  | 188     exit(1); | 
|  | 189   } | 
|  | 190 | 
|  | 191   pgm_readpgminit(in, &cols, &rows, &maxval, &format); | 
|  | 192   if (verbose > 0) | 
|  | 193     fprintf(stderr, "%s: embedding %d bits with strength %f in\n" | 
|  | 194                     "  %d x %d host image, decomposition level %d\n", | 
|  | 195                     progname, nbit_signature, alpha, cols, rows, level); | 
|  | 196 | 
|  | 197   image = pgm_allocarray(cols, rows); | 
|  | 198   for (row = 0; row < rows; row++) | 
|  | 199     pgm_readpgmrow(in, image[row], cols, maxval, format); | 
|  | 200   fclose(in); | 
|  | 201 | 
|  | 202   // decomposition of image | 
|  | 203   init_dwt(cols, rows, filter_name, filter, level, method); | 
|  | 204 #ifdef POLLEN_STUFF | 
| 3 | 205 #include "pollen_stuff.c" | 
| 0 | 206 #endif | 
|  | 207 #ifdef PARAM_STUFF | 
| 3 | 208 #include "param_stuff.c" | 
| 0 | 209 #endif | 
|  | 210 | 
|  | 211   dwts = fdwt(image); | 
|  | 212 | 
|  | 213   p = dwts; | 
|  | 214 | 
|  | 215   // consider each resolution level | 
|  | 216   while (p->level < level) | 
|  | 217     // descend one level | 
|  | 218     p = p->coarse; | 
|  | 219 | 
|  | 220   // repeat binary watermark by sliding a 3-pixel window of approximation image | 
|  | 221   n = 0; | 
|  | 222   for (row = 0; row < p->image->height; row++) { | 
|  | 223     for (col = 0; col < p->image->width - 3; col += 3) { | 
|  | 224       double b1, b2, b3; | 
|  | 225       double *f1 = &b1, *f2 = &b2, *f3 = &b3; | 
|  | 226 | 
|  | 227       // get all three approximation pixels in window | 
|  | 228       b1 = get_pixel(p->image, col + 0, row); | 
|  | 229       b2 = get_pixel(p->image, col + 1, row); | 
|  | 230       b3 = get_pixel(p->image, col + 2, row); | 
|  | 231 | 
|  | 232       // bring selected pixels in ascending order | 
|  | 233 #define SWAP(A, B) {double *t = A; A = B; B = t;} | 
|  | 234       if (*f1 > *f2) SWAP(f1, f2); | 
|  | 235       if (*f2 > *f3) SWAP(f2, f3); | 
|  | 236       if (*f1 > *f2) SWAP(f1, f2); | 
|  | 237 | 
|  | 238       set_signature_bit(n, wm_transform(alpha, *f1, *f2, *f3)); | 
|  | 239 | 
|  | 240       if (verbose > 1) | 
|  | 241         fprintf(stderr, "%s: extracting #%d (= %d) at (%d/%d); %f < %f < %f\n", | 
|  | 242           progname, n, get_signature_bit(n % nbit_signature), col, row, *f1, *f2, *f3); | 
|  | 243 | 
|  | 244       n++; | 
|  | 245     } | 
|  | 246   } | 
|  | 247 | 
|  | 248   fprintf(out, "XEWM\n"); | 
|  | 249   fprintf(out, "%d\n", n); | 
|  | 250   fwrite(signature, sizeof(char), NBITSTOBYTES(n), out); | 
|  | 251   fprintf(out, "\n"); | 
|  | 252   fclose(out); | 
|  | 253 | 
|  | 254   pgm_freearray(image, rows); | 
|  | 255 | 
|  | 256   exit(0); | 
|  | 257 } |