| 
0
 | 
     1 /* Watermarking program - Subband DCT Transform based	*/
 | 
| 
 | 
     2 /* Module	: Casting				*/
 | 
| 
 | 
     3 /* Author	: Vassilis Fotopoulos			*/
 | 
| 
 | 
     4 /* Date		: 25/4/2000				*/
 | 
| 
 | 
     5 /* Revision	: 7.0					*/
 | 
| 
 | 
     6 /* Developed at	: ELLAB                  		*/
 | 
| 
 | 
     7 /*                Electronics Laboratory           	*/
 | 
| 
 | 
     8 /*                Department of Physics             	*/
 | 
| 
 | 
     9 /*                University of Patras - GREECE      	*/
 | 
| 
 | 
    10 /*		  Copyleft (c) 1999	    		*/
 | 
| 
 | 
    11 /*------------------------------------------------------*/
 | 
| 
 | 
    12 /*	pseudorandom noise generator's code is		*/
 | 
| 
 | 
    13 /*	taken from "Numerical Recipes in C"		*/
 | 
| 
 | 
    14 /*	FCT implementation from University of Bath	*/
 | 
| 
 | 
    15 /*------------------------------------------------------*/
 | 
| 
 | 
    16 #include <stdio.h>
 | 
| 
 | 
    17 #include <stdlib.h>
 | 
| 
 | 
    18 #include <string.h>
 | 
| 
 | 
    19 #include <math.h>
 | 
| 
 | 
    20 #include <float.h>
 | 
| 
 | 
    21 #include <getopt.h>
 | 
| 
 | 
    22 #include "common.h"
 | 
| 
13
 | 
    23 #include "pgm.h"
 | 
| 
0
 | 
    24 
 | 
| 
 | 
    25 void add_hor_add_ver(double **in, int N, double **out);
 | 
| 
 | 
    26 void add_hor_sub_ver(double **in, int N, double **out);
 | 
| 
 | 
    27 void sub_hor_add_ver(double **in, int N, double **out);
 | 
| 
 | 
    28 void sub_hor_sub_ver(double **in, int N, double **out);
 | 
| 
 | 
    29 void band_synthesis(double **ll, double **lh, double **hl, double **hh, int N, double **s);
 | 
| 
 | 
    30 void watermark(double **i, int N, long key, long int L, long int M, double a);
 | 
| 
 | 
    31 
 | 
| 
 | 
    32 double cu[1024];
 | 
| 
 | 
    33 double cv[1024];
 | 
| 
 | 
    34 int height, width;
 | 
| 
 | 
    35 
 | 
| 
 | 
    36 //--------------------------------------------------------
 | 
| 
 | 
    37 void add_hor_add_ver(double **in, int N, double **out)
 | 
| 
 | 
    38 {
 | 
| 
 | 
    39   double **temp;
 | 
| 
 | 
    40   int r, c;
 | 
| 
 | 
    41   temp = dmatrix(N, N);
 | 
| 
 | 
    42   for (r = 0; r < N; r++)
 | 
| 
 | 
    43     for (c = 0; c < N / 2; c++)
 | 
| 
 | 
    44       temp[r][c] = (in[r][2 * c] + in[r][2 * c + 1]) / 2;
 | 
| 
 | 
    45   for (c = 0; c < N / 2; c++)
 | 
| 
 | 
    46     for (r = 0; r < N / 2; r++)
 | 
| 
 | 
    47       out[r][c] = (temp[2 * r][c] + temp[2 * r + 1][c]) / 2;
 | 
| 
 | 
    48   freematrix_d(temp, N);
 | 
| 
 | 
    49 }
 | 
| 
 | 
    50 //--------------------------------------------------------
 | 
| 
 | 
    51 void add_hor_sub_ver(double **in, int N, double **out)
 | 
| 
 | 
    52 {
 | 
| 
 | 
    53   double **temp;
 | 
| 
 | 
    54   int r, c;
 | 
| 
 | 
    55   temp = dmatrix(N, N);
 | 
| 
 | 
    56   for (r = 0; r < N; r++)
 | 
| 
 | 
    57     for (c = 0; c < N / 2; c++)
 | 
| 
 | 
    58       temp[r][c] = (in[r][2 * c] + in[r][2 * c + 1]) / 2;
 | 
| 
 | 
    59   for (c = 0; c < N / 2; c++)
 | 
| 
 | 
    60     for (r = 0; r < N / 2; r++)
 | 
| 
 | 
    61       out[r][c] = (temp[2 * r][c] - temp[2 * r + 1][c]) / 2;
 | 
| 
 | 
    62   freematrix_d(temp, N);
 | 
| 
 | 
    63 }
 | 
| 
 | 
    64 //--------------------------------------------------------
 | 
| 
 | 
    65 void sub_hor_add_ver(double **in, int N, double **out)
 | 
| 
 | 
    66 {
 | 
| 
 | 
    67   double **temp;
 | 
| 
 | 
    68   int r, c;
 | 
| 
 | 
    69   temp = dmatrix(N, N);
 | 
| 
 | 
    70   for (r = 0; r < N; r++)
 | 
| 
 | 
    71     for (c = 0; c < N / 2; c++)
 | 
| 
 | 
    72       temp[r][c] = (in[r][2 * c] - in[r][2 * c + 1]) / 2;
 | 
| 
 | 
    73   for (c = 0; c < N / 2; c++)
 | 
| 
 | 
    74     for (r = 0; r < N / 2; r++)
 | 
| 
 | 
    75       out[r][c] = (temp[2 * r][c] + temp[2 * r + 1][c]) / 2;
 | 
| 
 | 
    76   freematrix_d(temp, N);
 | 
| 
 | 
    77 }
 | 
| 
 | 
    78 //--------------------------------------------------------
 | 
| 
 | 
    79 void sub_hor_sub_ver(double **in, int N, double **out)
 | 
| 
 | 
    80 {
 | 
| 
 | 
    81   double **temp;
 | 
| 
 | 
    82   int r, c;
 | 
| 
 | 
    83   temp = dmatrix(N, N);
 | 
| 
 | 
    84   for (r = 0; r < N; r++)
 | 
| 
 | 
    85     for (c = 0; c < N / 2; c++)
 | 
| 
 | 
    86       temp[r][c] = (in[r][2 * c] - in[r][2 * c + 1]) / 2;
 | 
| 
 | 
    87   for (c = 0; c < N / 2; c++)
 | 
| 
 | 
    88     for (r = 0; r < N / 2; r++)
 | 
| 
 | 
    89       out[r][c] = (temp[2 * r][c] - temp[2 * r + 1][c]) / 2;
 | 
| 
 | 
    90   freematrix_d(temp, N);
 | 
| 
 | 
    91 }
 | 
| 
 | 
    92 //--------------------------------------------------------
 | 
| 
 | 
    93 void band_synthesis(double **ll, double **lh, double **hl, double **hh, int N, double **s)
 | 
| 
 | 
    94 {
 | 
| 
 | 
    95   int r, c;
 | 
| 
 | 
    96   double b1, b2, b3, b4;
 | 
| 
 | 
    97   for (r = 0; r < N; r++)
 | 
| 
 | 
    98     for (c = 0; c < N; c++) {
 | 
| 
 | 
    99       b1 = ll[r][c] + lh[r][c] + hl[r][c] + hh[r][c]; 	//Reconstruct each
 | 
| 
 | 
   100       b2 = ll[r][c] + lh[r][c] - hl[r][c] - hh[r][c]; 	//of the pixels
 | 
| 
 | 
   101       b3 = ll[r][c] - lh[r][c] + hl[r][c] - hh[r][c];
 | 
| 
 | 
   102       b4 = ll[r][c] - lh[r][c] - hl[r][c] + hh[r][c];
 | 
| 
 | 
   103       b1 = (b1 > 255.0) ? 255.0 : b1; 					//Check for positive...
 | 
| 
 | 
   104       b1 = (b1 < 0.0) ? 0.0 : b1; 						//or negative core!
 | 
| 
 | 
   105       b2 = (b2 > 255.0) ? 255.0 : b2;
 | 
| 
 | 
   106       b2 = (b2 < 0.0) ? 0.0 : b2;
 | 
| 
 | 
   107       b3 = (b3 > 255.0) ? 255.0 : b3;
 | 
| 
 | 
   108       b3 = (b3 < 0.0) ? 0.0 : b3;
 | 
| 
 | 
   109       b4 = (b4 > 255.0) ? 255.0 : b4;
 | 
| 
 | 
   110       b4 = (b4 < 0.0) ? 0.0 : b4;
 | 
| 
 | 
   111       s[2*r][2*c] = b1; 							//Put them back in
 | 
| 
 | 
   112       s[2*r][2*c + 1] = b2; 						//the right position
 | 
| 
 | 
   113       s[2*r + 1][2*c] = b3;
 | 
| 
 | 
   114       s[2*r + 1][2*c + 1] = b4;
 | 
| 
 | 
   115     }
 | 
| 
 | 
   116 }
 | 
| 
 | 
   117 
 | 
| 
 | 
   118 void watermark(double **i, int N, long key, long int L, long int M, double a)
 | 
| 
 | 
   119 {
 | 
| 
 | 
   120   int row, col, count;
 | 
| 
 | 
   121   long int elem, temp, seed;
 | 
| 
 | 
   122   double *v;
 | 
| 
 | 
   123   v = dvector(N * N);
 | 
| 
 | 
   124   put_matrix_2_vector(i, v, N);
 | 
| 
 | 
   125   fct2d(v, N, N);
 | 
| 
 | 
   126   seed = key;
 | 
| 
 | 
   127   count = 0;
 | 
| 
 | 
   128   elem = 0;
 | 
| 
 | 
   129   row = 2;
 | 
| 
 | 
   130   col = -1;
 | 
| 
 | 
   131   do {
 | 
| 
 | 
   132     do {
 | 
| 
 | 
   133       row--;
 | 
| 
 | 
   134       col++;
 | 
| 
 | 
   135       elem++;
 | 
| 
 | 
   136       if (col < N) {
 | 
| 
 | 
   137         if (elem > M) {
 | 
| 
 | 
   138           temp = row * N + col;
 | 
| 
 | 
   139           v[temp] += a * fabs(v[temp]) * gasdev(&seed);
 | 
| 
 | 
   140           count++;
 | 
| 
 | 
   141         }
 | 
| 
 | 
   142       }
 | 
| 
 | 
   143     } while (row > 0);
 | 
| 
 | 
   144     row = 2 + col;
 | 
| 
 | 
   145     col = -1;
 | 
| 
 | 
   146   } while (count < L);
 | 
| 
 | 
   147   ifct2d(v, N, N);
 | 
| 
 | 
   148   put_vector_2_matrix(v, i, N);
 | 
| 
 | 
   149   free(v);
 | 
| 
 | 
   150 }
 | 
| 
 | 
   151 
 | 
| 
 | 
   152 int main(int argc, char* argv[])
 | 
| 
 | 
   153 {
 | 
| 
 | 
   154   double **i;
 | 
| 
 | 
   155   double **o;
 | 
| 
 | 
   156   FILE *in;
 | 
| 
 | 
   157   FILE *out;
 | 
| 
 | 
   158   int N;
 | 
| 
 | 
   159   int c;
 | 
| 
 | 
   160   long int M1, L1, M2, L2;
 | 
| 
 | 
   161   int **image_i;
 | 
| 
 | 
   162   double **ll, **lh, **hl, **hh;
 | 
| 
 | 
   163   double a_ll = 0.1, a_other = 0.2;
 | 
| 
 | 
   164   int wm_length_1 = 10000, wm_length_ll = 10000, coeff_start_1 = 3000,
 | 
| 
 | 
   165                                           coeff_start_ll = 3000, wm_key = 123;
 | 
| 
 | 
   166 
 | 
| 
 | 
   167   pgm_init(&argc, argv); wm_init();
 | 
| 
 | 
   168 
 | 
| 
 | 
   169   while ((c = getopt(argc, argv, "a:b:t:m:s:l:k:")) != EOF) {
 | 
| 
 | 
   170     switch (c) {
 | 
| 
 | 
   171         case 'a':
 | 
| 
 | 
   172         a_ll = atof(optarg);
 | 
| 
 | 
   173         break;
 | 
| 
 | 
   174         case 'b':
 | 
| 
 | 
   175         a_other = atof(optarg);
 | 
| 
 | 
   176         break;
 | 
| 
 | 
   177         case 't':
 | 
| 
 | 
   178         coeff_start_1 = atoi(optarg);
 | 
| 
 | 
   179         break;
 | 
| 
 | 
   180         case 'm':
 | 
| 
 | 
   181         wm_length_1 = atoi(optarg);
 | 
| 
 | 
   182         break;
 | 
| 
 | 
   183         case 's':
 | 
| 
 | 
   184         coeff_start_ll = atoi(optarg);
 | 
| 
 | 
   185         break;
 | 
| 
 | 
   186         case 'l':
 | 
| 
 | 
   187         wm_length_ll = atoi(optarg);
 | 
| 
 | 
   188         break;
 | 
| 
 | 
   189         case 'k':
 | 
| 
 | 
   190         wm_key = atoi(optarg);
 | 
| 
 | 
   191         break;
 | 
| 
 | 
   192     }
 | 
| 
 | 
   193   }
 | 
| 
 | 
   194   argc -= optind;
 | 
| 
 | 
   195   argv += optind;
 | 
| 
 | 
   196 
 | 
| 
 | 
   197   in = stdin;
 | 
| 
 | 
   198   out = stdout;
 | 
| 
 | 
   199   open_image(in, &width, &height);
 | 
| 
 | 
   200   image_i = imatrix(height, width);
 | 
| 
 | 
   201   load_image(image_i, in, width, height);
 | 
| 
 | 
   202   if (height == width)
 | 
| 
 | 
   203     N = height;
 | 
| 
 | 
   204   else {
 | 
| 
 | 
   205     fprintf(stderr, "Cannot Proccess non-square images!\n");
 | 
| 
 | 
   206     exit( -11);
 | 
| 
 | 
   207   }
 | 
| 
 | 
   208   // starting coeff. for 1st level decomp.
 | 
| 
 | 
   209   M1 = coeff_start_1;
 | 
| 
 | 
   210   // number of coeffs to alter
 | 
| 
 | 
   211   L1 = wm_length_1;
 | 
| 
 | 
   212 
 | 
| 
 | 
   213   // now the LL band
 | 
| 
 | 
   214   M2 = coeff_start_ll;
 | 
| 
 | 
   215   L2 = wm_length_ll;
 | 
| 
 | 
   216 
 | 
| 
 | 
   217   i = dmatrix(N, N);
 | 
| 
 | 
   218   o = dmatrix(N, N);
 | 
| 
 | 
   219   ll = dmatrix(N / 2, N / 2);
 | 
| 
 | 
   220   lh = dmatrix(N / 2, N / 2);
 | 
| 
 | 
   221   hl = dmatrix(N / 2, N / 2);
 | 
| 
 | 
   222   hh = dmatrix(N / 2, N / 2);
 | 
| 
 | 
   223 
 | 
| 
 | 
   224   matrix_i2d(image_i, i, N);
 | 
| 
 | 
   225 
 | 
| 
 | 
   226   //---------------------1o decomposition-------------------
 | 
| 
 | 
   227   add_hor_add_ver(i, N, ll);
 | 
| 
 | 
   228   add_hor_sub_ver(i, N, lh);
 | 
| 
 | 
   229   sub_hor_add_ver(i, N, hl);
 | 
| 
 | 
   230   sub_hor_sub_ver(i, N, hh);
 | 
| 
 | 
   231   //---------------------Watermark medium frequency bands---
 | 
| 
 | 
   232   watermark(lh, N / 2, wm_key, L1, M1, a_other);
 | 
| 
 | 
   233   watermark(hl, N / 2, wm_key, L1, M1, a_other);
 | 
| 
 | 
   234   watermark(hh, N / 2, wm_key, L1, M1, a_other);
 | 
| 
 | 
   235   watermark(ll, N / 2, wm_key, L2, M2, a_ll);
 | 
| 
 | 
   236   //---------------------Synthesis stage--------------------
 | 
| 
 | 
   237   band_synthesis(ll, lh, hl, hh, N / 2, o);
 | 
| 
 | 
   238   //--------------------------------------------------------
 | 
| 
 | 
   239   matrix_d2i(o, image_i, N);
 | 
| 
 | 
   240   save_image(image_i, out, width, height);
 | 
| 
 | 
   241 
 | 
| 
 | 
   242   fclose(in);
 | 
| 
 | 
   243   fclose(out);
 | 
| 
13
 | 
   244 
 | 
| 
 | 
   245   exit(EXIT_SUCCESS);
 | 
| 
0
 | 
   246 }
 | 
| 
 | 
   247 
 | 
| 
 | 
   248 
 | 
| 
 | 
   249 
 | 
| 
 | 
   250 
 |