| 0 | 1 #include "wm.h" | 
|  | 2 | 
|  | 3 char *progname; | 
|  | 4 | 
|  | 5 void usage(void) { | 
|  | 6   fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); | 
|  | 7   fprintf(stderr, "\t-C\t\toutput correlation only\n"); | 
|  | 8   fprintf(stderr, "\t-h\t\tprint usage\n"); | 
|  | 9   fprintf(stderr, "\t-o file\t\toutput file\n"); | 
|  | 10   fprintf(stderr, "\t-v n\t\tverbosity level\n"); | 
|  | 11   fprintf(stderr, "\t-s file\t\toriginal signature file\n"); | 
|  | 12   exit(0); | 
|  | 13 } | 
|  | 14 | 
|  | 15 int main(int argc, char *argv[]) { | 
|  | 16 | 
|  | 17   FILE *in = stdin; | 
|  | 18   FILE *out = stdout; | 
|  | 19   FILE *sig = NULL; | 
|  | 20 | 
|  | 21   char signature_name[MAXPATHLEN]; | 
|  | 22   char output_name[MAXPATHLEN] = "(stdout)"; | 
|  | 23   char input_name[MAXPATHLEN] = "(stdin)"; | 
|  | 24 | 
|  | 25   int c, i, j, n; | 
|  | 26   int in_level; | 
|  | 27   double *cumul_watermark, *orig_watermark; | 
|  | 28   int *cumul_watermark_count; | 
|  | 29   int sig_n, in_n; | 
|  | 30   double sig_a; | 
|  | 31   int sig_l; | 
|  | 32   int sig_e, sig_f; | 
|  | 33   char line[32]; | 
|  | 34   double correlation, maxcorrelation; | 
|  | 35   double s1, s2, s3; | 
|  | 36 | 
|  | 37   int verbose = 0; | 
|  | 38   int correlation_only = 0; | 
|  | 39 | 
|  | 40   progname = argv[0]; | 
|  | 41 | 
|  | 42   while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { | 
|  | 43     switch (c) { | 
|  | 44       case 'h': | 
|  | 45       case '?': | 
|  | 46         usage(); | 
|  | 47         break; | 
|  | 48       case 'C': | 
|  | 49         correlation_only = 1; | 
|  | 50         break; | 
|  | 51       case 'o': | 
|  | 52         if ((out = fopen(optarg, "w")) == NULL) { | 
|  | 53           fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); | 
|  | 54           exit(1); | 
|  | 55         } | 
|  | 56         strcpy(output_name, optarg); | 
|  | 57         break; | 
|  | 58       case 's': | 
|  | 59         if ((sig = fopen(optarg, "r")) == NULL) { | 
|  | 60           fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); | 
|  | 61           exit(1); | 
|  | 62         } | 
|  | 63         strcpy(signature_name, optarg); | 
|  | 64         break; | 
|  | 65      case 'v': | 
|  | 66         verbose = atoi(optarg); | 
|  | 67         if (verbose < 0) { | 
|  | 68           fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); | 
|  | 69           exit(1); | 
|  | 70         } | 
|  | 71         break; | 
|  | 72     } | 
|  | 73   } | 
|  | 74 | 
|  | 75   argc -= optind; | 
|  | 76   argv += optind; | 
|  | 77 | 
|  | 78   if (argc > 1) { | 
|  | 79     usage(); | 
|  | 80     exit(1); | 
|  | 81   } | 
|  | 82 | 
| 8 | 83   if (argc == 1 && *argv[0] != '-') { | 
| 0 | 84     if ((in = fopen(argv[0], "r")) == NULL) { | 
|  | 85       fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); | 
|  | 86       exit(1); | 
|  | 87     } | 
|  | 88     else | 
|  | 89       strcpy(input_name, argv[0]); | 
| 8 | 90   } | 
|  | 91 | 
| 0 | 92   if (!sig) { | 
|  | 93     fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); | 
|  | 94     exit(1); | 
|  | 95   } | 
|  | 96 | 
|  | 97   fgets(line, sizeof(line), sig); | 
|  | 98   if (strspn(line, "ZHSG") < 4) { | 
|  | 99     fprintf(stderr, "%s: original signature file %s invalid\n", progname, signature_name); | 
|  | 100     exit(1); | 
|  | 101   } | 
|  | 102 | 
|  | 103   fgets(line, sizeof(line), in); | 
|  | 104   if (strspn(line, "ZHWM") < 4) { | 
|  | 105     fprintf(stderr, "%s: watermark file %s invalid\n", progname, input_name); | 
|  | 106     exit(1); | 
|  | 107   } | 
|  | 108 | 
|  | 109   fscanf(sig, "%d\n", &sig_n); | 
|  | 110   fscanf(in, "%d\n", &in_n); | 
|  | 111   if (sig_n != in_n) { | 
|  | 112     fprintf(stderr, "%s: watermark length mismatch (original %d, input %d)\n", progname, sig_n, in_n); | 
|  | 113     exit(1); | 
|  | 114   } | 
|  | 115   if (sig_n <= 0 || sig_n > 32000) { | 
|  | 116     fprintf(stderr, "%s: invalid original watermark length %d\n", progname, sig_n); | 
|  | 117     exit(1); | 
|  | 118   } | 
|  | 119   if (in_n != sig_n) { | 
|  | 120     fprintf(stderr, "%s: invalid watermark length %d, does not match signature length\n", progname, in_n); | 
|  | 121     exit(1); | 
|  | 122   } | 
|  | 123 | 
|  | 124   fscanf(sig, "%lf\n", &sig_a); | 
|  | 125   fscanf(sig, "%d\n", &sig_l); | 
|  | 126   fscanf(sig, "%d\n", &sig_e); | 
|  | 127   fscanf(sig, "%d\n", &sig_f); | 
|  | 128   fscanf(sig, "%*[^\n\r]\n"); | 
|  | 129 | 
|  | 130   orig_watermark = malloc(sig_n * sizeof(double)); | 
|  | 131   for (i = 0; i < sig_n; i++) | 
|  | 132     fscanf(sig, "%lf\n", &orig_watermark[i]); | 
|  | 133   fclose(sig); | 
|  | 134 | 
|  | 135   fscanf(in, "%d\n", &in_level); | 
|  | 136 | 
|  | 137   cumul_watermark = malloc(in_n * sizeof(double)); | 
|  | 138   cumul_watermark_count = malloc(in_n * sizeof(int)); | 
|  | 139 | 
|  | 140   for (i = 0; i < in_n; i++) { | 
|  | 141     cumul_watermark_count[i] = 0; | 
|  | 142     cumul_watermark[i] = 0.0; | 
|  | 143   } | 
|  | 144 | 
|  | 145   /* | 
|  | 146    * normalized correlation | 
|  | 147    * Craver, S., "Can Invisible Watermarks Resolve Rightful Ownership?", IBM Research Report, 1996, p. 5 | 
|  | 148    */ | 
|  | 149   maxcorrelation = -10000.0; | 
|  | 150   for (i = 0; i < in_level; i++) { | 
|  | 151     fscanf(in, "%d\n", &n); | 
|  | 152 | 
|  | 153     s1 = s2 = s3 = 0.0; | 
|  | 154     for (j = 0; j < n; j++) { | 
|  | 155       double in_x, sig_x; | 
|  | 156 | 
|  | 157       sig_x = orig_watermark[j]; | 
|  | 158       fscanf(in, "%lf\n", &in_x); | 
|  | 159 | 
|  | 160       s1 += sig_x * in_x; | 
|  | 161       s2 += in_x * in_x; | 
|  | 162       s3 += sig_x * sig_x; | 
|  | 163 | 
|  | 164       if (verbose > 2) | 
|  | 165         fprintf(stderr, "%s: level %d; orig %f input %f\n", progname, i, sig_x, in_x); | 
|  | 166 | 
|  | 167       cumul_watermark[j % in_n] += in_x; | 
|  | 168       cumul_watermark_count[j % in_n]++; | 
|  | 169     } | 
|  | 170 | 
|  | 171     correlation = s1 / sqrt(s2 * s3); | 
|  | 172     if (correlation > maxcorrelation) | 
|  | 173       maxcorrelation = correlation; | 
|  | 174 | 
|  | 175     if (!correlation_only) | 
|  | 176       fprintf(out, "%s: correlation level %d: %f\n", progname, i, correlation); | 
|  | 177   } | 
|  | 178 | 
|  | 179   s1 = s2 = s3 = 0.0; | 
|  | 180   for (i = 0; i < in_n; i++) { | 
|  | 181     double in_x, sig_x; | 
|  | 182 | 
|  | 183     in_x = cumul_watermark[i] / (double) cumul_watermark_count[i]; | 
|  | 184     sig_x = orig_watermark[i]; | 
|  | 185 | 
|  | 186     s1 += sig_x * in_x; | 
|  | 187     s2 += in_x * in_x; | 
|  | 188     s3 += sig_x * sig_x; | 
|  | 189   } | 
|  | 190 | 
|  | 191   correlation = s1 / sqrt(s2 * s3); | 
|  | 192   if (!correlation_only) | 
|  | 193     fprintf(out, "%s: cumultative correlation: %f\n", progname, correlation); | 
|  | 194 | 
|  | 195   if (correlation > maxcorrelation) | 
|  | 196     maxcorrelation = correlation; | 
|  | 197 | 
|  | 198   if (!correlation_only) | 
|  | 199     fprintf(out, "%s: max. correlation: %f\n", progname, maxcorrelation); | 
|  | 200   else | 
|  | 201     fprintf(out, "%f\n", maxcorrelation); | 
|  | 202 | 
|  | 203   fclose(out); | 
|  | 204   fclose(in); | 
|  | 205 | 
|  | 206   free(orig_watermark); | 
|  | 207   free(cumul_watermark); | 
|  | 208   free(cumul_watermark_count); | 
|  | 209 | 
|  | 210   exit(0); | 
|  | 211 } |