# HG changeset patch # User Peter Meerwald-Stadler # Date 1734696539 -3600 # Node ID 9f20bce6184ee2a5500ea72aa3f3c4084fbce0c8 # Parent 71dd4b96221b725d64f38b17a4fd5893edf5276f move directories, support netpbm 11 diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos-dir/CHANGES --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fotopoulos-dir/CHANGES Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,2 @@ +removed #include - it is not needed and MS VC++ does not have +it (Sarat Atluri) diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos-dir/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fotopoulos-dir/Makefile Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,44 @@ +# Makefile + +include ../make/make.config + +all: cast-pv$(EXE) cast-hart$(EXE) cast-sub$(EXE) test-pv$(EXE) test-hart$(EXE) test-sub$(EXE) + +.SUFFIXES: .c .o + +.c$(O): + $(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $< + +cast-pv$(EXE): cast-pv$(O) common$(O) + $(CC) $(LDFLAGS) -o $@ cast-pv$(O) common$(O) $(PGMLIBS) $(LIBS) + +cast-hart$(EXE): cast-hart$(O) common$(O) + $(CC) $(LDFLAGS) -o $@ cast-hart$(O) common$(O) $(PGMLIBS) $(LIBS) + +cast-sub$(EXE): cast-sub$(O) common$(O) + $(CC) $(LDFLAGS) -o $@ cast-sub$(O) common$(O) $(PGMLIBS) $(LIBS) + +test-pv$(EXE): test-pv$(O) common$(O) + $(CC) $(LDFLAGS) -o $@ test-pv$(O) common$(O) $(PGMLIBS) $(LIBS) + +test-hart$(EXE): test-hart$(O) common$(O) + $(CC) $(LDFLAGS) -o $@ test-hart$(O) common$(O) $(PGMLIBS) $(LIBS) + +test-sub$(EXE): test-sub$(O) common$(O) + $(CC) $(LDFLAGS) -o $@ test-sub$(O) common$(O) $(PGMLIBS) $(LIBS) + +test: cast-pv$(EXE) cast-hart$(EXE) cast-sub$(EXE) test-pv$(EXE) test-hart$(EXE) test-sub$(EXE) + cast-pv < ../images/lena.pgm > ../watermarked/foto-pv_lena.pgm + cast-hart < ../images/lena.pgm > ../watermarked/foto-hart_lena.pgm + cast-sub < ../images/lena.pgm > ../watermarked/foto-sub_lena.pgm + + test-pv < ../watermarked/foto-pv_lena.pgm > ../wms/foto-pv.wm + test-hart < ../watermarked/foto-hart_lena.pgm > ../wms/foto-hart.wm + test-sub < ../watermarked/foto-sub_lena.pgm > ../wms/foto-sub.wm + +install: cast-pv$(EXE) cast-hart$(EXE) cast-sub$(EXE) test-pv$(EXE) test-hart$(EXE) test-sub$(EXE) + $(CP) cast-pv$(EXE) cast-hart$(EXE) cast-sub$(EXE) test-pv$(EXE) test-hart$(EXE) test-sub$(EXE) $(INSTALLDIR) + +clean: + $(RM) *$(O) cast-pv$(EXE) cast-hart$(EXE) cast-sub$(EXE) test-pv$(EXE) test-hart$(EXE) test-sub$(EXE) + $(RM) ../watermarked/* ../wms/* diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos-dir/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fotopoulos-dir/README Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,21 @@ +M.Barni, F. Bartolini, V. Cappellini, A. Piva. "A DCT-Domain +System for Robust Image Watermarking", +Signal Processing, vol.66, pp 357-372, 1998. + +V. Fotopoulos, A.N. Skodras, "A Subband DCT approach to +image watermarking", X European Signal Processing Conference, +September 4-8, 2000, Tampere, Finland + +parameters: +for starting coefficient reasonable values for the dct and hartley schemes +and this kind of dimensions is around 5000-20000, for the watermark length 10000-50000, +and seed/key should be in the range 1-1000 so that the output file of the testing module +gives a right similarity diagram + +for the subband dct version, things change corresponding to coefficients +because the bands' sizes are 1/4 of the original image's size. +starting coef should be between 3000-5000 and length 10000-20000 +for the alpha parameter i use 0.2 for all bands except LL for which i use +0.1 + + diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos-dir/README_VASSILIS --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fotopoulos-dir/README_VASSILIS Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,67 @@ +These codes use the DCT,Hartley and Subband DCT +Transforms for watermarking purposes.All schemes +are blind,no original image is used for detection. +Each casting module is accompanied by a testing +module.Supposing that the watermark key that you +select during casting is in the range 1-1000,the +testing module will test all the keys in this range +to produce the well known similarity diagrams used +by Cox, Piva and many more with the peak being the +proof of the watermark existence. + +I do not include a detection module because this implies +the use of certain thresholds. Although the casting +methods are almost standardized (multiplicative formula) +there are still questions about this thresholding but +the testing modules can be easily changed to fit this +purpose. + +The DCT scheme does not use the visual masking improvement +that Barni and his team suggest in one of their later works. +In all casting programs we assume that the coefficients are +diagonaly scanned,and ordered as shown in the following example. + +---------------------- +| 1| 3| 6|10|15|... +---------------------- +| 2| 5| 9|14|... +---------------------- +| 4| 8|13|... +---------------------- +| 7|12|... +---------------------- +|11|... +---------------------- + +which is quite simple comparing to the zig zag scanning +pattern that we know from the JPEG standard but does not +affect at all the idea that we have of the middle +frequencies.Also the user should take care that + +starting_coefficient+number_of_coeffs_to_change<(N*N)/2 + +which means that we shouldn't exceed the matrix diagonal. +To do so the scanning scheme should be changed accordingly +but this doesn't seem important because in all of the +schemes we don't get out of the middle frequencies coefs. +With correctly selected parameters,the schemes perform in +the same way as if the coeffs were zig zag scanned. + +In the Subband DCT version,the first set of questions +about starting coefficient,number of coefficients to +alter and alpha parameter, refer to the LH,HL and HH +band while the second set of questions sets the parameters +about the LL band only. + +All schemes should not be used with the same set of parameters +because each of the transforms, possess certain specific +properties. This should be kept in mind for testing purposes. +To use the right set of parameters please refer to corresponding +bibliography. +All code has been tested in Visual C++ v6.0 + +Have some nice tests... +Vassilis Fotopoulos + +for more info,ideas or points of discussion +email vfotop1@physics.upatras.gr diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos-dir/cast-hart.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fotopoulos-dir/cast-hart.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,113 @@ +/* Watermarking program - Hartley Transform based */ +/* Module : Casting */ +/* Author : Vassilis Fotopoulos */ +/* Date : 26/7/1999 */ +/* Revision : 2.01a */ +/* Developed at : ELLAB */ +/* Electronics Laboratory */ +/* Department of Physics */ +/* University of Patras - GREECE */ +/* Copyleft (c) 1999 */ +/*------------------------------------------------------*/ +/* pseudorandom noise generator's code is */ +/* taken from "Numerical Recipes in C" */ +/*------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "netpbm/pgm.h" + +int height, width; + +void add_watermark(double **in, int N, int coeff_start, int wm_length, int wm_key, double wm_alpha) +{ + int row, col, count; + long int elem, L, M, seed; + double a; + count = 0; + elem = 0; + M = coeff_start; + L = wm_length; + seed = wm_key; + a = wm_alpha; + for (row = 0; row < N; row++) + for (col = 0; col < N; col++) { + elem++; + if (elem > M && count < L) { + in[row][col] += a * fabs(in[row][col]) * gasdev(&seed); + count++; + } + } + +} + +//-------------------------------------------------------- +int main(int argc, char* argv[]) +{ + FILE *in, *out; + int **image; + double **image_i; + double **image_d; + int c; + int N; + int coeff_start = 5000, wm_length = 10000, wm_key = 123; + double wm_alpha = 0.2; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "a:s:l:k:")) != EOF) { + switch (c) { + case 'a': + wm_alpha = atof(optarg); + break; + case 's': + coeff_start = atoi(optarg); + break; + case 'l': + wm_length = atoi(optarg); + break; + case 'k': + wm_key = atoi(optarg); + break; + } + } + argc -= optind; + argv += optind; + + in = stdin; + out = stdout; + + open_image(in, &width, &height); + image = imatrix(height, width); + load_image(image, in, width, height); + + if (height == width) + N = height; + else { + fprintf(stderr, "Cannot Proccess non-square images!\n"); + exit( -11); + } + + image_i = dmatrix(height, width); + image_d = dmatrix(height, width); + if (image_d == NULL) { + fprintf(stderr, "Unable to allocate the double array\n"); + exit(1); + } + matrix_i2d(image, image_i, N); + hartley(image_i, image_d, N); + add_watermark(image_d, N, coeff_start, wm_length, wm_key, wm_alpha); + hartley(image_d, image_i, N); + matrix_d2i(image_i, image, N); + save_image(image, out, width, height); + + freematrix_d(image_i, height); + freematrix_d(image_d, height); + fclose(in); + fclose(out); + exit(EXIT_SUCCESS); +} diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos-dir/cast-pv.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fotopoulos-dir/cast-pv.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,135 @@ +/* Watermarking program - Fast Cosine Transform based */ +/* Module : Casting */ +/* Author : Vassilis Fotopoulos */ +/* Date : 21/7/1999 */ +/* Revision : 2.01a */ +/* Developed at : ELLAB */ +/* Electronics Laboratory */ +/* Department of Physics */ +/* University of Patras - GREECE */ +/* Copyleft (c) 1999 */ +/* (without Visual Masking) */ +/*------------------------------------------------------*/ +/* pseudorandom noise generator's code is */ +/* taken from "Numerical Recipes in C" */ +/* FCT implementation from the University of Bath */ +/*------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "netpbm/pgm.h" + +double cu[1024]; +double cv[1024]; +int height, width; + +//-------------------------------------------------------- +void add_watermark(double *in, int N, int coeff_start, int wm_length, int wm_key, double wm_alpha) +{ + int row, col, count; + long int elem, L, M, temp, seed; + double a; + count = 0; + elem = 0; + row = 2; + col = -1; + M = coeff_start; + L = wm_length; + seed = wm_key; + a = wm_alpha; + do { + do { + row--; + col++; + elem++; + if (col < N) { + if (elem > M) { + temp = row * N + col; + in[temp] += a * fabs(in[temp]) * gasdev(&seed); + count++; + } + } + } while (row > 0); + row = 2 + col; + col = -1; + } while (count < L); +} +//-------------------------------------------------------- +void initialize_constants(void) +{ + int i; + cu[0] = cv[0] = 0.7071068; + for (i = 1; i < 1024; i++) + cu[i] = cv[i] = 1.0; +} + +//-------------------------------------------------------- +int main(int argc, char* argv[]) +{ + FILE *in, *out; + int **image_i; + double *image_f = NULL; + int N; + int c; + int coeff_start = 5000, wm_length = 10000, wm_key = 123; + double wm_alpha = 0.2; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "a:s:l:k:")) != EOF) { + switch (c) { + case 'a': + wm_alpha = atof(optarg); + break; + case 's': + coeff_start = atoi(optarg); + break; + case 'l': + wm_length = atoi(optarg); + break; + case 'k': + wm_key = atoi(optarg); + break; + } + } + argc -= optind; + argv += optind; + + in = stdin; + out = stdout; + + open_image(in, &width, &height); + image_i = imatrix(height, width); + load_image(image_i, in, width, height); + + if (height == width) + N = height; + else { + fprintf(stderr, "Cannot Proccess non-square images!\n"); + exit( -11); + } + + initialize_constants(); + image_f = (double *)calloc(N * N, sizeof(double)); + if (image_f == NULL) { + printf("Unable to allocate the float array\n"); + exit(1); + } + + put_image_from_int_2_double(image_i, image_f, N); + fct2d(image_f, N, N); + add_watermark(image_f, N, coeff_start, wm_length, wm_key, wm_alpha); + ifct2d(image_f, N, N); + put_image_from_double_2_int(image_f, image_i, N); + save_image(image_i, out, width, height); + freematrix(image_i, height); + free(image_f); + fclose(in); + fclose(out); + + exit(EXIT_SUCCESS); +} diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos-dir/cast-sub.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fotopoulos-dir/cast-sub.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,250 @@ +/* Watermarking program - Subband DCT Transform based */ +/* Module : Casting */ +/* Author : Vassilis Fotopoulos */ +/* Date : 25/4/2000 */ +/* Revision : 7.0 */ +/* Developed at : ELLAB */ +/* Electronics Laboratory */ +/* Department of Physics */ +/* University of Patras - GREECE */ +/* Copyleft (c) 1999 */ +/*------------------------------------------------------*/ +/* pseudorandom noise generator's code is */ +/* taken from "Numerical Recipes in C" */ +/* FCT implementation from University of Bath */ +/*------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "netpbm/pgm.h" + +void add_hor_add_ver(double **in, int N, double **out); +void add_hor_sub_ver(double **in, int N, double **out); +void sub_hor_add_ver(double **in, int N, double **out); +void sub_hor_sub_ver(double **in, int N, double **out); +void band_synthesis(double **ll, double **lh, double **hl, double **hh, int N, double **s); +void watermark(double **i, int N, long key, long int L, long int M, double a); + +double cu[1024]; +double cv[1024]; +int height, width; + +//-------------------------------------------------------- +void add_hor_add_ver(double **in, int N, double **out) +{ + double **temp; + int r, c; + temp = dmatrix(N, N); + for (r = 0; r < N; r++) + for (c = 0; c < N / 2; c++) + temp[r][c] = (in[r][2 * c] + in[r][2 * c + 1]) / 2; + for (c = 0; c < N / 2; c++) + for (r = 0; r < N / 2; r++) + out[r][c] = (temp[2 * r][c] + temp[2 * r + 1][c]) / 2; + freematrix_d(temp, N); +} +//-------------------------------------------------------- +void add_hor_sub_ver(double **in, int N, double **out) +{ + double **temp; + int r, c; + temp = dmatrix(N, N); + for (r = 0; r < N; r++) + for (c = 0; c < N / 2; c++) + temp[r][c] = (in[r][2 * c] + in[r][2 * c + 1]) / 2; + for (c = 0; c < N / 2; c++) + for (r = 0; r < N / 2; r++) + out[r][c] = (temp[2 * r][c] - temp[2 * r + 1][c]) / 2; + freematrix_d(temp, N); +} +//-------------------------------------------------------- +void sub_hor_add_ver(double **in, int N, double **out) +{ + double **temp; + int r, c; + temp = dmatrix(N, N); + for (r = 0; r < N; r++) + for (c = 0; c < N / 2; c++) + temp[r][c] = (in[r][2 * c] - in[r][2 * c + 1]) / 2; + for (c = 0; c < N / 2; c++) + for (r = 0; r < N / 2; r++) + out[r][c] = (temp[2 * r][c] + temp[2 * r + 1][c]) / 2; + freematrix_d(temp, N); +} +//-------------------------------------------------------- +void sub_hor_sub_ver(double **in, int N, double **out) +{ + double **temp; + int r, c; + temp = dmatrix(N, N); + for (r = 0; r < N; r++) + for (c = 0; c < N / 2; c++) + temp[r][c] = (in[r][2 * c] - in[r][2 * c + 1]) / 2; + for (c = 0; c < N / 2; c++) + for (r = 0; r < N / 2; r++) + out[r][c] = (temp[2 * r][c] - temp[2 * r + 1][c]) / 2; + freematrix_d(temp, N); +} +//-------------------------------------------------------- +void band_synthesis(double **ll, double **lh, double **hl, double **hh, int N, double **s) +{ + int r, c; + double b1, b2, b3, b4; + for (r = 0; r < N; r++) + for (c = 0; c < N; c++) { + b1 = ll[r][c] + lh[r][c] + hl[r][c] + hh[r][c]; //Reconstruct each + b2 = ll[r][c] + lh[r][c] - hl[r][c] - hh[r][c]; //of the pixels + b3 = ll[r][c] - lh[r][c] + hl[r][c] - hh[r][c]; + b4 = ll[r][c] - lh[r][c] - hl[r][c] + hh[r][c]; + b1 = (b1 > 255.0) ? 255.0 : b1; //Check for positive... + b1 = (b1 < 0.0) ? 0.0 : b1; //or negative core! + b2 = (b2 > 255.0) ? 255.0 : b2; + b2 = (b2 < 0.0) ? 0.0 : b2; + b3 = (b3 > 255.0) ? 255.0 : b3; + b3 = (b3 < 0.0) ? 0.0 : b3; + b4 = (b4 > 255.0) ? 255.0 : b4; + b4 = (b4 < 0.0) ? 0.0 : b4; + s[2*r][2*c] = b1; //Put them back in + s[2*r][2*c + 1] = b2; //the right position + s[2*r + 1][2*c] = b3; + s[2*r + 1][2*c + 1] = b4; + } +} + +void watermark(double **i, int N, long key, long int L, long int M, double a) +{ + int row, col, count; + long int elem, temp, seed; + double *v; + v = dvector(N * N); + put_matrix_2_vector(i, v, N); + fct2d(v, N, N); + seed = key; + count = 0; + elem = 0; + row = 2; + col = -1; + do { + do { + row--; + col++; + elem++; + if (col < N) { + if (elem > M) { + temp = row * N + col; + v[temp] += a * fabs(v[temp]) * gasdev(&seed); + count++; + } + } + } while (row > 0); + row = 2 + col; + col = -1; + } while (count < L); + ifct2d(v, N, N); + put_vector_2_matrix(v, i, N); + free(v); +} + +int main(int argc, char* argv[]) +{ + double **i; + double **o; + FILE *in; + FILE *out; + int N; + int c; + long int M1, L1, M2, L2; + int **image_i; + double **ll, **lh, **hl, **hh; + double a_ll = 0.1, a_other = 0.2; + int wm_length_1 = 10000, wm_length_ll = 10000, coeff_start_1 = 3000, + coeff_start_ll = 3000, wm_key = 123; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "a:b:t:m:s:l:k:")) != EOF) { + switch (c) { + case 'a': + a_ll = atof(optarg); + break; + case 'b': + a_other = atof(optarg); + break; + case 't': + coeff_start_1 = atoi(optarg); + break; + case 'm': + wm_length_1 = atoi(optarg); + break; + case 's': + coeff_start_ll = atoi(optarg); + break; + case 'l': + wm_length_ll = atoi(optarg); + break; + case 'k': + wm_key = atoi(optarg); + break; + } + } + argc -= optind; + argv += optind; + + in = stdin; + out = stdout; + open_image(in, &width, &height); + image_i = imatrix(height, width); + load_image(image_i, in, width, height); + if (height == width) + N = height; + else { + fprintf(stderr, "Cannot Proccess non-square images!\n"); + exit( -11); + } + // starting coeff. for 1st level decomp. + M1 = coeff_start_1; + // number of coeffs to alter + L1 = wm_length_1; + + // now the LL band + M2 = coeff_start_ll; + L2 = wm_length_ll; + + i = dmatrix(N, N); + o = dmatrix(N, N); + ll = dmatrix(N / 2, N / 2); + lh = dmatrix(N / 2, N / 2); + hl = dmatrix(N / 2, N / 2); + hh = dmatrix(N / 2, N / 2); + + matrix_i2d(image_i, i, N); + + //---------------------1o decomposition------------------- + add_hor_add_ver(i, N, ll); + add_hor_sub_ver(i, N, lh); + sub_hor_add_ver(i, N, hl); + sub_hor_sub_ver(i, N, hh); + //---------------------Watermark medium frequency bands--- + watermark(lh, N / 2, wm_key, L1, M1, a_other); + watermark(hl, N / 2, wm_key, L1, M1, a_other); + watermark(hh, N / 2, wm_key, L1, M1, a_other); + watermark(ll, N / 2, wm_key, L2, M2, a_ll); + //---------------------Synthesis stage-------------------- + band_synthesis(ll, lh, hl, hh, N / 2, o); + //-------------------------------------------------------- + matrix_d2i(o, image_i, N); + save_image(image_i, out, width, height); + + fclose(in); + fclose(out); + + exit(EXIT_SUCCESS); +} + + + + diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos-dir/common.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fotopoulos-dir/common.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,571 @@ +#include +#include +#include +#include +#include +#include "netpbm/pgm.h" +#include "common.h" + +#define IA 16807 +#define IM 2147483647 +#define AM (1.0/IM) +#define IQ 127773 +#define IR 2836 +#define MASK 123459876 + +static int NN = 0; +static int m = 0; +static double two_over_N = 0; +static double root2_over_rootN = 0; +static double *C = NULL; + +static gray maxval; +static int format; + +void open_image(FILE *in, int *width, int *height) +{ + + pgm_readpgminit(in, width, height, &maxval, &format); +} + +void load_image(int **im, FILE *in, int width, int height) +{ + int col, row; + gray *rowbuf; + + rowbuf = malloc(sizeof(gray) * width); + + for (row = 0; row < height; row++) { + pgm_readpgmrow(in, rowbuf, width, maxval, format); + for (col = 0; col < width; col++) + im[row][col] = rowbuf[col]; + } + + free(rowbuf); +} + +void save_image(int **im, FILE *out, int width, int height) +{ + int col, row; + gray *rowbuf; + + pgm_writepgminit(out, width, height, 255, 0); + + rowbuf = malloc(sizeof(gray) * width); + + for (row = 0; row < height; row++) { + for (col = 0; col < width; col++) + rowbuf[col] = im[row][col]; + pgm_writepgmrow(out, rowbuf, width, 255, 0); + } + + free(rowbuf); +} + +int ** imatrix(int nrows, int ncols) +{ + int **m; + int i, j; + m = (int **) malloc (nrows * sizeof(int *)); + for (i = 0; i < nrows; i++) { + m[i] = (int *) malloc (ncols * sizeof(int)); + if (!m[i]) fprintf(stderr, "\nIt's not working"); + } + for (i = 0; i < nrows; i++) + for (j = 0; j < ncols; j++) + m[i][j] = 0; + return m; +} + +void freematrix(int **I, int rows) +{ + int k; + for (k = 0; k < rows; k++) + free (I[k]); +} + +float ran0(long int *idum) +{ + long int k; + float ans; + *idum ^= MASK; + k = (*idum) / IQ; + *idum = IA * (*idum - k * IQ) - IR * k; + if (*idum < 0) *idum += IM; + ans = AM * (*idum); + *idum ^= MASK; + return ans; +} + +float gasdev(long int *idum) +{ + + float v1; + v1 = (float) sqrt( -2.0 * log(ran0(idum))) * cos(2 * PI * ran0(idum)); + return v1; +} + + +void put_image_from_int_2_double(int **i, double *f, int N) +{ + int l, j, k; + k = 0; + for (l = 0; l < N; l++) + for (j = 0; j < N; j++) + f[k++] = (double) i[l][j]; +} + +void put_image_from_double_2_int(double *f, int **i, int N) +{ + int l, j, k; + k = 0; + for (l = 0; l < N; l++) + for (j = 0; j < N; j++) + i[l][j] = (int) f[k++]; +} + + +void bitrev(double *f, int len) +{ + int i, j, m, halflen; + double temp; + + if (len <= 2) return ; /* No action necessary if n=1 or n=2 */ + halflen = len >> 1; + j = 1; + for (i = 1; i <= len; i++) { + if (i < j) { + temp = f[j - 1]; + f[j - 1] = f[i - 1]; + f[i - 1] = temp; + } + m = halflen; + while (j > m) { + j = j - m; + m = (m + 1) >> 1; + } + j = j + m; + } +} + +void inv_sums(double *f) +{ + int stepsize, stage, curptr, nthreads, thread, step, nsteps; + + for (stage = 1; stage <= m - 1; stage++) { + nthreads = 1 << (stage - 1); + stepsize = nthreads << 1; + nsteps = (1 << (m - stage)) - 1; + for (thread = 1; thread <= nthreads; thread++) { + curptr = NN - thread; + for (step = 1; step <= nsteps; step++) { + f[curptr] += f[curptr - stepsize]; + curptr -= stepsize; + } + } + } +} + +//-------------------------------------------------------- +//Foreign code - FCT from Bath Univerity +//-------------------------------------------------------- +void rarrwrt(double f[], int n) +{ + int i; + + for (i = 0; i <= n - 1; i++) { + fprintf(stderr, "%4d : %f\n", i, f[i]); + } +} + +/* fast DCT based on IEEE signal proc, 1992 #8, yugoslavian authors. */ + +void fwd_sums(double *f) +{ + int stepsize, stage, curptr, nthreads, thread, step, nsteps; + + for (stage = m - 1; stage >= 1; stage--) { + nthreads = 1 << (stage - 1); + stepsize = nthreads << 1; + nsteps = (1 << (m - stage)) - 1; + for (thread = 1; thread <= nthreads; thread++) { + curptr = nthreads + thread - 1; + for (step = 1; step <= nsteps; step++) { + f[curptr] += f[curptr + stepsize]; + curptr += stepsize; + } + } + } +} + +void scramble(double *f, int len) +{ + double temp; + int i, ii1, ii2, halflen, qtrlen; + + halflen = len >> 1; + qtrlen = halflen >> 1; + bitrev(f, len); + bitrev(&f[0], halflen); + bitrev(&f[halflen], halflen); + ii1 = len - 1; + ii2 = halflen; + for (i = 0; i <= qtrlen - 1; i++) { + temp = f[ii1]; + f[ii1] = f[ii2]; + f[ii2] = temp; + ii1--; + ii2++; + } +} + +void unscramble(double *f, int len) +{ + double temp; + int i, ii1, ii2, halflen, qtrlen; + + halflen = len >> 1; + qtrlen = halflen >> 1; + ii1 = len - 1; + ii2 = halflen; + for (i = 0; i <= qtrlen - 1; i++) { + temp = f[ii1]; + f[ii1] = f[ii2]; + f[ii2] = temp; + ii1--; + ii2++; + } + bitrev(&f[0], halflen); + bitrev(&f[halflen], halflen); + bitrev(f, len); +} + +void initcosarray(int length) +{ + int i, group, base, item, nitems, halfN; + double factor; + + m = -1; + do { + m++; + NN = 1 << m; + if (NN > length) { + fprintf(stderr, "ERROR in FCT-- length %d not a power of 2\n", length); + exit(1); + } + } while (NN < length); + if (C != NULL) free(C); + C = (double *)calloc(NN, sizeof(double)); + if (C == NULL) { + fprintf(stderr, "Unable to allocate C array\n"); + exit(1); + } + halfN = NN / 2; + two_over_N = 2.0 / (double)NN; + root2_over_rootN = sqrt(2.0 / (double)NN); + for (i = 0; i <= halfN - 1; i++) C[halfN + i] = 4 * i + 1; + for (group = 1; group <= m - 1; group++) { + base = 1 << (group - 1); + nitems = base; + factor = 1.0 * (1 << (m - group)); + for (item = 1; item <= nitems; item++) C[base + item - 1] = factor * C[halfN + item - 1]; + } + + //printf("before taking cos, C array =\n"); rarrwrt(C,N); + for (i = 1; i <= NN - 1; i++) C[i] = 1.0 / (2.0 * cos(C[i] * PI / (2.0 * NN))); + //printf("After taking cos, Carray = \n"); rarrwrt(C,N); +} + + +void inv_butterflies(double *f) +{ + int stage, ii1, ii2, butterfly, ngroups, group, wingspan, increment, baseptr; + double Cfac, T; + + for (stage = 1; stage <= m; stage++) { + ngroups = 1 << (m - stage); + wingspan = 1 << (stage - 1); + increment = wingspan << 1; + for (butterfly = 1; butterfly <= wingspan; butterfly++) { + Cfac = C[wingspan + butterfly - 1]; + baseptr = 0; + for (group = 1; group <= ngroups; group++) { + ii1 = baseptr + butterfly - 1; + ii2 = ii1 + wingspan; + T = Cfac * f[ii2]; + f[ii2] = f[ii1]-T; + f[ii1] = f[ii1] + T; + baseptr += increment; + } + } + } +} + +void fwd_butterflies(double *f) +{ + int stage, ii1, ii2, butterfly, ngroups, group, wingspan, increment, baseptr; + double Cfac, T; + + for (stage = m; stage >= 1; stage--) { + ngroups = 1 << (m - stage); + wingspan = 1 << (stage - 1); + increment = wingspan << 1; + for (butterfly = 1; butterfly <= wingspan; butterfly++) { + Cfac = C[wingspan + butterfly - 1]; + baseptr = 0; + for (group = 1; group <= ngroups; group++) { + ii1 = baseptr + butterfly - 1; + ii2 = ii1 + wingspan; + T = f[ii2]; + f[ii2] = Cfac * (f[ii1]-T); + f[ii1] = f[ii1] + T; + baseptr += increment; + } + } + } +} + +void ifct_noscale(double *f, int length) +{ + if (length != NN) initcosarray(length); + f[0] *= INVROOT2; + inv_sums(f); + bitrev(f, NN); + inv_butterflies(f); + unscramble(f, NN); +} + +void fct_noscale(double *f, int length) +{ + if (length != NN) initcosarray(length); + scramble(f, NN); + fwd_butterflies(f); + bitrev(f, NN); + fwd_sums(f); + f[0] *= INVROOT2; +} + +void ifct_defn_scaling(double *f, int length) +{ + ifct_noscale(f, length); +} + +void fct_defn_scaling(double *f, int length) +{ + int i; + + fct_noscale(f, length); + for (i = 0; i <= NN - 1; i++) f[i] *= two_over_N; +} + +void ifct(double *f, int length) +{ + /* CALL THIS FOR INVERSE 1D DCT DON-MONRO PREFERRED SCALING */ + int i; + + if (length != NN) initcosarray(length); /* BGS patch June 1997 */ + for (i = 0; i <= NN - 1; i++) f[i] *= root2_over_rootN; + ifct_noscale(f, length); +} + +void fct(double *f, int length) +{ + /* CALL THIS FOR FORWARD 1D DCT DON-MONRO PREFERRED SCALING */ + int i; + + fct_noscale(f, length); + for (i = 0; i <= NN - 1; i++) f[i] *= root2_over_rootN; +} + +/**************************************************************** + 2D FAST DCT SECTION +****************************************************************/ + +static double *g = NULL; +static double two_over_sqrtncolsnrows = 0.0; +static int ncolsvalue = 0; +static int nrowsvalue = 0; + +void initfct2d(int nrows, int ncols) +{ + if ((nrows <= 0) || (ncols < 0)) { + fprintf(stderr, "FCT2D -- ncols=%d or nrows=%d is <=0\n", nrows, ncols); + exit(1); + } + if (g != NULL) free(g); + g = (double *)calloc(nrows, sizeof(double)); + if (g == NULL) { + fprintf(stderr, "FCT2D -- Unable to allocate g array\n"); + exit(1); + } + ncolsvalue = ncols; + nrowsvalue = nrows; + two_over_sqrtncolsnrows = 2.0 / sqrt(ncols * 1.0 * nrows); +} + +void fct2d(double f[], int nrows, int ncols) +/* CALL THIS FOR FORWARD 2d DCT DON-MONRO PREFERRED SCALING */ +{ + int u, v; + + if ((ncols != ncolsvalue) || (nrows != nrowsvalue)){ + initfct2d(nrows, ncols); + } + for (u = 0; u <= nrows - 1; u++){ + fct_noscale(&f[u*ncols], ncols); + } + for (v = 0; v <= ncols - 1; v++){ + for (u = 0; u <= nrows - 1; u++) { + g[u] = f[u * ncols + v]; + } + fct_noscale(g, nrows); + for (u = 0; u <= nrows - 1; u++) { + f[u*ncols + v] = g[u] * two_over_sqrtncolsnrows; + } + } +} + +void ifct2d(double f[], int nrows, int ncols) +/* CALL THIS FOR INVERSE 2d DCT DON-MONRO PREFERRED SCALING */ +{ + int u, v; + + if ((ncols != ncolsvalue) || (nrows != nrowsvalue)){ + initfct2d(nrows, ncols); + } + for (u = 0; u <= nrows - 1; u++){ + ifct_noscale(&f[u*ncols], ncols); + } + for (v = 0; v <= ncols - 1; v++){ + for (u = 0; u <= nrows - 1; u++) { + g[u] = f[u * ncols + v]; + } + ifct_noscale(g, nrows); + for (u = 0; u <= nrows - 1; u++) { + f[u*ncols + v] = g[u] * two_over_sqrtncolsnrows; + } + } +} + +void matmul(double **a, double **b, double **r, int N) +{ + int i, j, k; + + for (i = 0; i < N; i++) + for (j = 0; j < N; j++) { + r[i][j] = 0.0; + for (k = 0; k < N; k++) + r[i][j] += a[i][k] * b[k][j]; + } +} + +void hartley(double **in, double **out, int N) +{ + int k, n; + double **h; + + h = dmatrix(N, N); + //Building up the transformation matrix + for (k = 0; k < N; k++) + for (n = 0; n < N; n++) + h[k][n] = (cos(2 * PI * k * n / N) + sin(2 * PI * k * n / N)) / sqrt(N); + + // Now we have to multiply the input with the transformation matrix + matmul(h, in, out, N); + freematrix_d(h, N); + return ; +} + +double ** dmatrix(int nrows, int ncols) +{ + double **m; + int i, j; + m = (double **) malloc (nrows * sizeof(double *)); + for (i = 0; i < nrows; i++) { + m[i] = (double *) malloc (ncols * sizeof(double)); + if (!m[i]) printf("\nIt's not working"); + } + for (i = 0; i < nrows; i++) + for (j = 0; j < ncols; j++) + m[i][j] = 0.0; + return m; +} + +void freematrix_d(double **I, int rows) +{ + int k; + for (k = 0; k < rows; k++) + free (I[k]); +} + +void matrix_i2d(int **i, double **d, int N) +{ + int x, y; + for (x = 0; x < N; x++) + for (y = 0; y < N; y++) + d[y][x] = i[y][x]; +} + +void matrix_d2i(double **d, int **i, int N) +{ + int x, y; + for (x = 0; x < N; x++) + for (y = 0; y < N; y++) + i[y][x] = d[y][x]; +} + +double * dvector(long int N) +{ + double *m; + m = (double *) malloc (N * sizeof(double)); + if (!m) printf("\nIt's not working"); + return m; +} + +void put_matrix_2_vector(double **i, double *f, int N) +{ + int l, j, k; + k = 0; + for (l = 0; l < N; l++) + for (j = 0; j < N; j++) + f[k++] = i[l][j]; +} + +void put_vector_2_matrix(double *f, double **i, int N) +{ + int l, j, k; + k = 0; + for (l = 0; l < N; l++) + for (j = 0; j < N; j++) + i[l][j] = f[k++]; +} + +void set_in_binary() { +#if defined(EMX) + _fsetmode(in, "b"); +#elif defined(MINGW) + setmode(STDIN_FILENO, O_BINARY); +#endif +} + +void set_out_binary() { +#if defined(EMX) + _fsetmode(out, "b"); +#elif defined(MINGW) + setmode(STDOUT_FILENO, O_BINARY); +#endif +} + +void wm_init2() { + set_out_binary(); +} + +void wm_init1() { + set_in_binary(); +} + +void wm_init() { + set_in_binary(); + set_out_binary(); +} + diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos-dir/common.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fotopoulos-dir/common.h Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,28 @@ +#define PI 3.1415926535897932 +#define INVROOT2 0.7071067814 + +void open_image(FILE *in, int *width, int *height); +void load_image(int **im, FILE *in, int width, int height); +void save_image(int **im, FILE *out, int width, int height); +int ** imatrix(int nrows, int ncols); +void freematrix(int **I, int rows); +float ran0(long int *idum); +float gasdev(long int *idum); +void put_image_from_int_2_double(int **i, double *f, int N); +void put_image_from_double_2_int(double *f, int **i, int N); +void fct2d(double f[], int nrows, int ncols); +void ifct2d(double f[], int nrows, int ncols); +void matmul(double **a, double **b, double **r, int N); +void hartley(double **in, double **out, int N); +double ** dmatrix(int nrows, int ncols); +void freematrix_d(double **I, int rows); +void hartley(double **in, double **out, int N); +void matrix_i2d(int **i, double **d, int N); +void matrix_d2i(double **d, int **i, int N); +void put_matrix_2_vector(double **i, double *f, int N); +void put_vector_2_matrix(double *f, double **i, int N); +double * dvector(long int N); + +void wm_init(); +void wm_init1(); +void wm_init2(); diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos-dir/test-hart.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fotopoulos-dir/test-hart.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,110 @@ +/* Watermarking program - Hartley Transform based */ +/* Module : Testing */ +/* Author : Vassilis Fotopoulos */ +/* Date : 26/7/1999 */ +/* Developed at : ELLAB */ +/* Electronics Laboratory */ +/* Department of Physics */ +/* University of Patras - GREECE */ +/* Copyleft (c) 1999 */ +/*------------------------------------------------------*/ +/* pseudorandom noise generator's code is */ +/* taken from "Numerical Recipes in C" */ +/*------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "netpbm/pgm.h" + +int height, width; + +void read_watermark(double **in, int N, int coeff_start, int wm_length, double wm_alpha) +{ + int row, col, count; + long int elem, L, M, seed, i; + double z; + M = coeff_start; + L = wm_length; + for (i = 1; i <= 1000; i++) { + seed = i; + z = 0.0; + count = 0; + elem = 0; + + for (row = 0; row < N; row++) + for (col = 0; col < N; col++) { + elem++; + if (elem > M && count < L) { + z += in[row][col] * gasdev(&seed); + count++; + } + } + + printf("%ld\t%f\n", i, z / L); + } + return ; +} + +int main(int argc, char* argv[]) +{ + FILE *in; + int **image; + double **image_i; + double **image_d; + int c; + int N; + int coeff_start = 5000, wm_length = 10000; + double wm_alpha = 0.2; + int width, height; + + pgm_init(&argc, argv); wm_init2(); + + while ((c = getopt(argc, argv, "a:s:l:")) != EOF) { + switch (c) { + case 'a': + wm_alpha = atof(optarg); + break; + case 's': + coeff_start = atoi(optarg); + break; + case 'l': + wm_length = atoi(optarg); + break; + } + } + argc -= optind; + argv += optind; + + in = stdin; + + open_image(in, &width, &height); + image = imatrix(height, width); + load_image(image, in, width, height); + + if (height == width) + N = height; + else { + fprintf(stderr, "Cannot Proccess non-square images!\n"); + exit( -11); + } + + image_i = dmatrix(height, width); + image_d = dmatrix(height, width); + if (image_d == NULL) { + fprintf(stderr, "Unable to allocate the double array\n"); + exit(1); + } + matrix_i2d(image, image_i, N); + hartley(image_i, image_d, N); + read_watermark(image_d, N, coeff_start, wm_length, wm_alpha); + + freematrix_d(image_i, height); + freematrix_d(image_d, height); + fclose(in); + + exit(EXIT_SUCCESS); +} diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos-dir/test-pv.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fotopoulos-dir/test-pv.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,127 @@ +/* Watermarking program - Fast Cosine Transform based */ +/* Module : Testing */ +/* Author : Vassilis Fotopoulos */ +/* Date : 21/7/1999 */ +/* Developed at : ELLAB */ +/* Electronics Laboratory */ +/* Department of Physics */ +/* University of Patras - GREECE */ +/* Copyleft (c) 1999 */ +/* Testing Program */ +/*------------------------------------------------------*/ +/* pseudorandom noise generator's code is */ +/* taken from "Numerical Recipes in C" */ +/* FCT implementation from the University of Bath */ +/*------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "netpbm/pgm.h" + +double cu[1024]; +double cv[1024]; +int height, width; + +void read_watermark(double *in, int N, int start_coeff, int wm_length, double wm_alpha) +{ + int row, col, count; + long int elem, L, M, temp, seed, i; + double z; + M = start_coeff; + L = wm_length; + for (i = 1; i <= 1000; i++) { + seed = i; + z = 0.0; + count = 0; + elem = 0; + row = 2; + col = -1; + do { + do { + row--; + col++; + elem++; + if (col < N) { + if (elem > M) { + temp = row * N + col; + z += in[temp] * gasdev(&seed); + count++; + } + } + } while (row > 0); + row = 2 + col; + col = -1; + } while (count < L); + printf("%ld\t%f\n", i, z / L); + } + return ; +} +//-------------------------------------------------------- +void initialize_constants(void) +{ + int i; + cu[0] = cv[0] = 0.7071068; + for (i = 1; i < 1024; i++) + cu[i] = cv[i] = 1.0; +} + +int main(int argc, char* argv[]) +{ + FILE *in; + int **image_i; + double *image_f = NULL; + int N; + int c; + int coeff_start = 5000, wm_length = 10000; + double wm_alpha = 0.2; + + pgm_init(&argc, argv); wm_init2(); + + while ((c = getopt(argc, argv, "a:s:l:")) != EOF) { + switch (c) { + case 'a': + wm_alpha = atof(optarg); + break; + case 's': + coeff_start = atoi(optarg); + break; + case 'l': + wm_length = atoi(optarg); + break; + } + } + argc -= optind; + argv += optind; + in = stdin; + + open_image(in, &width, &height); + image_i = imatrix(height, width); + load_image(image_i, in, width, height); + + if (height == width) + N = height; + else { + fprintf(stderr, "Cannot Proccess non-square images!\n"); + exit( -11); + } + + initialize_constants(); + image_f = (double *)calloc(N * N, sizeof(double)); + if (image_f == NULL) { + printf("Unable to allocate the float array\n"); + exit(1); + } + + put_image_from_int_2_double(image_i, image_f, N); + fct2d(image_f, N, N); + read_watermark(image_f, N, coeff_start, wm_length, wm_alpha); + fclose(in); + freematrix(image_i, height); + free(image_f); + + exit(EXIT_SUCCESS); +} diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos-dir/test-sub.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fotopoulos-dir/test-sub.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,240 @@ +/* Watermarking program - Subband DCT Transform based */ +/* Module : Testing */ +/* Author : Vassilis Fotopoulos */ +/* Date : 25/4/2000 */ +/* Revision : 6.0 */ +/* Developed at : ELLAB */ +/* Electronics Laboratory */ +/* Department of Physics */ +/* University of Patras - GREECE */ +/* Copyleft (c) 1999 */ +/*------------------------------------------------------*/ +/* pseudorandom noise generator's code is */ +/* taken from "Numerical Recipes in C" */ +/* FCT implementation from University of Bath */ +/*------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "netpbm/pgm.h" + +//-------------------------------------------------------- +void add_hor_add_ver(double **in, int N, double **out); +void add_hor_sub_ver(double **in, int N, double **out); +void sub_hor_add_ver(double **in, int N, double **out); +void sub_hor_sub_ver(double **in, int N, double **out); +double detect_mark(double *i, int N, long key, long int L, long int M, double a); + +//-------------------------------------------------------- +double cu[1024]; +double cv[1024]; +int height, width; +//-------------------------------------------------------- +void add_hor_add_ver(double **in, int N, double **out) +{ + double **temp; + int r, c; + temp = dmatrix(N, N); + for (r = 0; r < N; r++) + for (c = 0; c < N / 2; c++) + temp[r][c] = (in[r][2 * c] + in[r][2 * c + 1]) / 2; + for (c = 0; c < N / 2; c++) + for (r = 0; r < N / 2; r++) + out[r][c] = (temp[2 * r][c] + temp[2 * r + 1][c]) / 2; + freematrix_d(temp, N); +} +//-------------------------------------------------------- +void add_hor_sub_ver(double **in, int N, double **out) +{ + double **temp; + int r, c; + temp = dmatrix(N, N); + for (r = 0; r < N; r++) + for (c = 0; c < N / 2; c++) + temp[r][c] = (in[r][2 * c] + in[r][2 * c + 1]) / 2; + for (c = 0; c < N / 2; c++) + for (r = 0; r < N / 2; r++) + out[r][c] = (temp[2 * r][c] - temp[2 * r + 1][c]) / 2; + freematrix_d(temp, N); +} +//-------------------------------------------------------- +void sub_hor_add_ver(double **in, int N, double **out) +{ + double **temp; + int r, c; + temp = dmatrix(N, N); + for (r = 0; r < N; r++) + for (c = 0; c < N / 2; c++) + temp[r][c] = (in[r][2 * c] - in[r][2 * c + 1]) / 2; + for (c = 0; c < N / 2; c++) + for (r = 0; r < N / 2; r++) + out[r][c] = (temp[2 * r][c] + temp[2 * r + 1][c]) / 2; + freematrix_d(temp, N); +} +//-------------------------------------------------------- +void sub_hor_sub_ver(double **in, int N, double **out) +{ + double **temp; + int r, c; + temp = dmatrix(N, N); + for (r = 0; r < N; r++) + for (c = 0; c < N / 2; c++) + temp[r][c] = (in[r][2 * c] - in[r][2 * c + 1]) / 2; + for (c = 0; c < N / 2; c++) + for (r = 0; r < N / 2; r++) + out[r][c] = (temp[2 * r][c] - temp[2 * r + 1][c]) / 2; + freematrix_d(temp, N); +} + +//--------------------------------------------------------- +double detect_mark(double *i, int N, long key, long int L, long int M, double a) +{ + int row, col, count; + long int elem, temp, seed; + double z; + + + seed = key; + z = 0.0; + count = 0; + elem = 0; + row = 2; + col = -1; + do { + do { + row--; + col++; + elem++; + if (col < N) { + if (elem > M) { + temp = row * N + col; + z += i[temp] * gasdev(&seed); + count++; + } + } + } while (row > 0); + row = 2 + col; + col = -1; + } while (count < L); + + return (z / L); +} + +int main(int argc, char* argv[]) +{ + double **i; + FILE *in; + int N; + long int key, M1, L1, M2, L2; + double **ll, **lh, **hl, **hh; + double *v1, *v2, *v3, *v99; + double m1, m2, m3, detect_value, m99; + int ** image_i; + int c; + int wm_length_1 = 10000, wm_length_ll = 10000, coeff_start_1 = 3000, coeff_start_ll = 3000; + double a_ll = 0.1, a_other = 0.2; + + pgm_init(&argc, argv); wm_init2(); + + while ((c = getopt(argc, argv, "a:b:t:m:s:l:")) != EOF) { + switch (c) { + case 'a': + a_ll = atof(optarg); + break; + case 'b': + a_other = atof(optarg); + break; + case 't': + coeff_start_1 = atoi(optarg); + break; + case 'm': + wm_length_1 = atoi(optarg); + break; + case 's': + coeff_start_ll = atoi(optarg); + break; + case 'l': + wm_length_ll = atoi(optarg); + break; + } + } + argc -= optind; + argv += optind; + + in = stdin; + open_image(in, &width, &height); + image_i = imatrix(height, width); + load_image(image_i, in, width, height); + + if (height == width) + N = height; + else { + fprintf(stderr, "Cannot Proccess non-square images!\n"); + exit( -11); + } + // starting coeff. for 1st level decomp. + M1 = coeff_start_1; + // number of coeffs to alter + L1 = wm_length_1; + // alpha parameter + + // now the LL band + M2 = coeff_start_ll; + L2 = wm_length_ll; + + + i = dmatrix(N, N); + ll = dmatrix(N / 2, N / 2); + lh = dmatrix(N / 2, N / 2); + hl = dmatrix(N / 2, N / 2); + hh = dmatrix(N / 2, N / 2); + v1 = dvector(N * N / 4); + v2 = dvector(N * N / 4); + v3 = dvector(N * N / 4); + v99 = dvector(N * N / 4); + + matrix_i2d(image_i, i, N); + + //---------------------1o decomposition------------------- + add_hor_add_ver(i, N, ll); + add_hor_sub_ver(i, N, lh); + sub_hor_add_ver(i, N, hl); + sub_hor_sub_ver(i, N, hh); + //---------------------Detect Watermark from all bands---- + put_matrix_2_vector(lh, v1, N / 2); + put_matrix_2_vector(hl, v2, N / 2); + put_matrix_2_vector(hh, v3, N / 2); + put_matrix_2_vector(ll, v99, N / 2); + fct2d(v1, N / 2, N / 2); + fct2d(v2, N / 2, N / 2); + fct2d(v3, N / 2, N / 2); + fct2d(v99, N / 2, N / 2); + for (key = 1; key <= 1000; key++) { + m1 = detect_mark(v1, N / 2, key, L1, M1, a_other); + m2 = detect_mark(v2, N / 2, key, L1, M1, a_other); + m3 = detect_mark(v3, N / 2, key, L1, M1, a_other); + m99 = detect_mark(v99, N / 2, key, L2, M2, a_ll); + detect_value = (m1 + m2 + m3 + m99) / 4; + printf("%ld\t%f\t%f\t%f\t%f\t%f\n", key, m1, m2, m3, m99, detect_value); + } + //-------------------------------------------------------- + free(v1); + free(v2); + free(v3); + free(v99); + freematrix_d(ll, N / 2); + freematrix_d(hl, N / 2); + freematrix_d(lh, N / 2); + freematrix_d(hh, N / 2); + fclose(in); + + exit(EXIT_SUCCESS); +} + + + + diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos/CHANGES --- a/Fotopoulos/CHANGES Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -removed #include - it is not needed and MS VC++ does not have -it (Sarat Atluri) diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos/Makefile --- a/Fotopoulos/Makefile Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -# Makefile - -include ../make/make.config - -all: cast-pv$(EXE) cast-hart$(EXE) cast-sub$(EXE) test-pv$(EXE) test-hart$(EXE) test-sub$(EXE) - -.SUFFIXES: .c .o - -.c$(O): - $(CC) $(CFLAGS) $(INCLUDES) -o $@ -c $< - -cast-pv$(EXE): cast-pv$(O) common$(O) - $(CC) $(LDFLAGS) -o $@ cast-pv$(O) common$(O) $(PGMLIBS) $(LIBS) - -cast-hart$(EXE): cast-hart$(O) common$(O) - $(CC) $(LDFLAGS) -o $@ cast-hart$(O) common$(O) $(PGMLIBS) $(LIBS) - -cast-sub$(EXE): cast-sub$(O) common$(O) - $(CC) $(LDFLAGS) -o $@ cast-sub$(O) common$(O) $(PGMLIBS) $(LIBS) - -test-pv$(EXE): test-pv$(O) common$(O) - $(CC) $(LDFLAGS) -o $@ test-pv$(O) common$(O) $(PGMLIBS) $(LIBS) - -test-hart$(EXE): test-hart$(O) common$(O) - $(CC) $(LDFLAGS) -o $@ test-hart$(O) common$(O) $(PGMLIBS) $(LIBS) - -test-sub$(EXE): test-sub$(O) common$(O) - $(CC) $(LDFLAGS) -o $@ test-sub$(O) common$(O) $(PGMLIBS) $(LIBS) - -test: cast-pv$(EXE) cast-hart$(EXE) cast-sub$(EXE) test-pv$(EXE) test-hart$(EXE) test-sub$(EXE) - cast-pv < ../images/lena.pgm > ../watermarked/foto-pv_lena.pgm - cast-hart < ../images/lena.pgm > ../watermarked/foto-hart_lena.pgm - cast-sub < ../images/lena.pgm > ../watermarked/foto-sub_lena.pgm - - test-pv < ../watermarked/foto-pv_lena.pgm > ../wms/foto-pv.wm - test-hart < ../watermarked/foto-hart_lena.pgm > ../wms/foto-hart.wm - test-sub < ../watermarked/foto-sub_lena.pgm > ../wms/foto-sub.wm - -install: cast-pv$(EXE) cast-hart$(EXE) cast-sub$(EXE) test-pv$(EXE) test-hart$(EXE) test-sub$(EXE) - $(CP) cast-pv$(EXE) cast-hart$(EXE) cast-sub$(EXE) test-pv$(EXE) test-hart$(EXE) test-sub$(EXE) $(INSTALLDIR) - -clean: - $(RM) *$(O) cast-pv$(EXE) cast-hart$(EXE) cast-sub$(EXE) test-pv$(EXE) test-hart$(EXE) test-sub$(EXE) - $(RM) ../watermarked/* ../wms/* diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos/README --- a/Fotopoulos/README Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,21 +0,0 @@ -M.Barni, F. Bartolini, V. Cappellini, A. Piva. "A DCT-Domain -System for Robust Image Watermarking", -Signal Processing, vol.66, pp 357-372, 1998. - -V. Fotopoulos, A.N. Skodras, "A Subband DCT approach to -image watermarking", X European Signal Processing Conference, -September 4-8, 2000, Tampere, Finland - -parameters: -for starting coefficient reasonable values for the dct and hartley schemes -and this kind of dimensions is around 5000-20000, for the watermark length 10000-50000, -and seed/key should be in the range 1-1000 so that the output file of the testing module -gives a right similarity diagram - -for the subband dct version, things change corresponding to coefficients -because the bands' sizes are 1/4 of the original image's size. -starting coef should be between 3000-5000 and length 10000-20000 -for the alpha parameter i use 0.2 for all bands except LL for which i use -0.1 - - diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos/README_VASSILIS --- a/Fotopoulos/README_VASSILIS Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -These codes use the DCT,Hartley and Subband DCT -Transforms for watermarking purposes.All schemes -are blind,no original image is used for detection. -Each casting module is accompanied by a testing -module.Supposing that the watermark key that you -select during casting is in the range 1-1000,the -testing module will test all the keys in this range -to produce the well known similarity diagrams used -by Cox, Piva and many more with the peak being the -proof of the watermark existence. - -I do not include a detection module because this implies -the use of certain thresholds. Although the casting -methods are almost standardized (multiplicative formula) -there are still questions about this thresholding but -the testing modules can be easily changed to fit this -purpose. - -The DCT scheme does not use the visual masking improvement -that Barni and his team suggest in one of their later works. -In all casting programs we assume that the coefficients are -diagonaly scanned,and ordered as shown in the following example. - ----------------------- -| 1| 3| 6|10|15|... ----------------------- -| 2| 5| 9|14|... ----------------------- -| 4| 8|13|... ----------------------- -| 7|12|... ----------------------- -|11|... ----------------------- - -which is quite simple comparing to the zig zag scanning -pattern that we know from the JPEG standard but does not -affect at all the idea that we have of the middle -frequencies.Also the user should take care that - -starting_coefficient+number_of_coeffs_to_change<(N*N)/2 - -which means that we shouldn't exceed the matrix diagonal. -To do so the scanning scheme should be changed accordingly -but this doesn't seem important because in all of the -schemes we don't get out of the middle frequencies coefs. -With correctly selected parameters,the schemes perform in -the same way as if the coeffs were zig zag scanned. - -In the Subband DCT version,the first set of questions -about starting coefficient,number of coefficients to -alter and alpha parameter, refer to the LH,HL and HH -band while the second set of questions sets the parameters -about the LL band only. - -All schemes should not be used with the same set of parameters -because each of the transforms, possess certain specific -properties. This should be kept in mind for testing purposes. -To use the right set of parameters please refer to corresponding -bibliography. -All code has been tested in Visual C++ v6.0 - -Have some nice tests... -Vassilis Fotopoulos - -for more info,ideas or points of discussion -email vfotop1@physics.upatras.gr diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos/cast-hart.c --- a/Fotopoulos/cast-hart.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +0,0 @@ -/* Watermarking program - Hartley Transform based */ -/* Module : Casting */ -/* Author : Vassilis Fotopoulos */ -/* Date : 26/7/1999 */ -/* Revision : 2.01a */ -/* Developed at : ELLAB */ -/* Electronics Laboratory */ -/* Department of Physics */ -/* University of Patras - GREECE */ -/* Copyleft (c) 1999 */ -/*------------------------------------------------------*/ -/* pseudorandom noise generator's code is */ -/* taken from "Numerical Recipes in C" */ -/*------------------------------------------------------*/ -#include -#include -#include -#include -#include -#include -#include "common.h" -#include "pgm.h" - -int height, width; - -void add_watermark(double **in, int N, int coeff_start, int wm_length, int wm_key, double wm_alpha) -{ - int row, col, count; - long int elem, L, M, seed; - double a; - count = 0; - elem = 0; - M = coeff_start; - L = wm_length; - seed = wm_key; - a = wm_alpha; - for (row = 0; row < N; row++) - for (col = 0; col < N; col++) { - elem++; - if (elem > M && count < L) { - in[row][col] += a * fabs(in[row][col]) * gasdev(&seed); - count++; - } - } - -} - -//-------------------------------------------------------- -int main(int argc, char* argv[]) -{ - FILE *in, *out; - int **image; - double **image_i; - double **image_d; - int c; - int N; - int coeff_start = 5000, wm_length = 10000, wm_key = 123; - double wm_alpha = 0.2; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "a:s:l:k:")) != EOF) { - switch (c) { - case 'a': - wm_alpha = atof(optarg); - break; - case 's': - coeff_start = atoi(optarg); - break; - case 'l': - wm_length = atoi(optarg); - break; - case 'k': - wm_key = atoi(optarg); - break; - } - } - argc -= optind; - argv += optind; - - in = stdin; - out = stdout; - - open_image(in, &width, &height); - image = imatrix(height, width); - load_image(image, in, width, height); - - if (height == width) - N = height; - else { - fprintf(stderr, "Cannot Proccess non-square images!\n"); - exit( -11); - } - - image_i = dmatrix(height, width); - image_d = dmatrix(height, width); - if (image_d == NULL) { - fprintf(stderr, "Unable to allocate the double array\n"); - exit(1); - } - matrix_i2d(image, image_i, N); - hartley(image_i, image_d, N); - add_watermark(image_d, N, coeff_start, wm_length, wm_key, wm_alpha); - hartley(image_d, image_i, N); - matrix_d2i(image_i, image, N); - save_image(image, out, width, height); - - freematrix_d(image_i, height); - freematrix_d(image_d, height); - fclose(in); - fclose(out); - exit(EXIT_SUCCESS); -} diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos/cast-pv.c --- a/Fotopoulos/cast-pv.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,135 +0,0 @@ -/* Watermarking program - Fast Cosine Transform based */ -/* Module : Casting */ -/* Author : Vassilis Fotopoulos */ -/* Date : 21/7/1999 */ -/* Revision : 2.01a */ -/* Developed at : ELLAB */ -/* Electronics Laboratory */ -/* Department of Physics */ -/* University of Patras - GREECE */ -/* Copyleft (c) 1999 */ -/* (without Visual Masking) */ -/*------------------------------------------------------*/ -/* pseudorandom noise generator's code is */ -/* taken from "Numerical Recipes in C" */ -/* FCT implementation from the University of Bath */ -/*------------------------------------------------------*/ -#include -#include -#include -#include -#include -#include -#include "common.h" -#include "pgm.h" - -double cu[1024]; -double cv[1024]; -int height, width; - -//-------------------------------------------------------- -void add_watermark(double *in, int N, int coeff_start, int wm_length, int wm_key, double wm_alpha) -{ - int row, col, count; - long int elem, L, M, temp, seed; - double a; - count = 0; - elem = 0; - row = 2; - col = -1; - M = coeff_start; - L = wm_length; - seed = wm_key; - a = wm_alpha; - do { - do { - row--; - col++; - elem++; - if (col < N) { - if (elem > M) { - temp = row * N + col; - in[temp] += a * fabs(in[temp]) * gasdev(&seed); - count++; - } - } - } while (row > 0); - row = 2 + col; - col = -1; - } while (count < L); -} -//-------------------------------------------------------- -void initialize_constants(void) -{ - int i; - cu[0] = cv[0] = 0.7071068; - for (i = 1; i < 1024; i++) - cu[i] = cv[i] = 1.0; -} - -//-------------------------------------------------------- -int main(int argc, char* argv[]) -{ - FILE *in, *out; - int **image_i; - double *image_f = NULL; - int N; - int c; - int coeff_start = 5000, wm_length = 10000, wm_key = 123; - double wm_alpha = 0.2; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "a:s:l:k:")) != EOF) { - switch (c) { - case 'a': - wm_alpha = atof(optarg); - break; - case 's': - coeff_start = atoi(optarg); - break; - case 'l': - wm_length = atoi(optarg); - break; - case 'k': - wm_key = atoi(optarg); - break; - } - } - argc -= optind; - argv += optind; - - in = stdin; - out = stdout; - - open_image(in, &width, &height); - image_i = imatrix(height, width); - load_image(image_i, in, width, height); - - if (height == width) - N = height; - else { - fprintf(stderr, "Cannot Proccess non-square images!\n"); - exit( -11); - } - - initialize_constants(); - image_f = (double *)calloc(N * N, sizeof(double)); - if (image_f == NULL) { - printf("Unable to allocate the float array\n"); - exit(1); - } - - put_image_from_int_2_double(image_i, image_f, N); - fct2d(image_f, N, N); - add_watermark(image_f, N, coeff_start, wm_length, wm_key, wm_alpha); - ifct2d(image_f, N, N); - put_image_from_double_2_int(image_f, image_i, N); - save_image(image_i, out, width, height); - freematrix(image_i, height); - free(image_f); - fclose(in); - fclose(out); - - exit(EXIT_SUCCESS); -} diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos/cast-sub.c --- a/Fotopoulos/cast-sub.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,250 +0,0 @@ -/* Watermarking program - Subband DCT Transform based */ -/* Module : Casting */ -/* Author : Vassilis Fotopoulos */ -/* Date : 25/4/2000 */ -/* Revision : 7.0 */ -/* Developed at : ELLAB */ -/* Electronics Laboratory */ -/* Department of Physics */ -/* University of Patras - GREECE */ -/* Copyleft (c) 1999 */ -/*------------------------------------------------------*/ -/* pseudorandom noise generator's code is */ -/* taken from "Numerical Recipes in C" */ -/* FCT implementation from University of Bath */ -/*------------------------------------------------------*/ -#include -#include -#include -#include -#include -#include -#include "common.h" -#include "pgm.h" - -void add_hor_add_ver(double **in, int N, double **out); -void add_hor_sub_ver(double **in, int N, double **out); -void sub_hor_add_ver(double **in, int N, double **out); -void sub_hor_sub_ver(double **in, int N, double **out); -void band_synthesis(double **ll, double **lh, double **hl, double **hh, int N, double **s); -void watermark(double **i, int N, long key, long int L, long int M, double a); - -double cu[1024]; -double cv[1024]; -int height, width; - -//-------------------------------------------------------- -void add_hor_add_ver(double **in, int N, double **out) -{ - double **temp; - int r, c; - temp = dmatrix(N, N); - for (r = 0; r < N; r++) - for (c = 0; c < N / 2; c++) - temp[r][c] = (in[r][2 * c] + in[r][2 * c + 1]) / 2; - for (c = 0; c < N / 2; c++) - for (r = 0; r < N / 2; r++) - out[r][c] = (temp[2 * r][c] + temp[2 * r + 1][c]) / 2; - freematrix_d(temp, N); -} -//-------------------------------------------------------- -void add_hor_sub_ver(double **in, int N, double **out) -{ - double **temp; - int r, c; - temp = dmatrix(N, N); - for (r = 0; r < N; r++) - for (c = 0; c < N / 2; c++) - temp[r][c] = (in[r][2 * c] + in[r][2 * c + 1]) / 2; - for (c = 0; c < N / 2; c++) - for (r = 0; r < N / 2; r++) - out[r][c] = (temp[2 * r][c] - temp[2 * r + 1][c]) / 2; - freematrix_d(temp, N); -} -//-------------------------------------------------------- -void sub_hor_add_ver(double **in, int N, double **out) -{ - double **temp; - int r, c; - temp = dmatrix(N, N); - for (r = 0; r < N; r++) - for (c = 0; c < N / 2; c++) - temp[r][c] = (in[r][2 * c] - in[r][2 * c + 1]) / 2; - for (c = 0; c < N / 2; c++) - for (r = 0; r < N / 2; r++) - out[r][c] = (temp[2 * r][c] + temp[2 * r + 1][c]) / 2; - freematrix_d(temp, N); -} -//-------------------------------------------------------- -void sub_hor_sub_ver(double **in, int N, double **out) -{ - double **temp; - int r, c; - temp = dmatrix(N, N); - for (r = 0; r < N; r++) - for (c = 0; c < N / 2; c++) - temp[r][c] = (in[r][2 * c] - in[r][2 * c + 1]) / 2; - for (c = 0; c < N / 2; c++) - for (r = 0; r < N / 2; r++) - out[r][c] = (temp[2 * r][c] - temp[2 * r + 1][c]) / 2; - freematrix_d(temp, N); -} -//-------------------------------------------------------- -void band_synthesis(double **ll, double **lh, double **hl, double **hh, int N, double **s) -{ - int r, c; - double b1, b2, b3, b4; - for (r = 0; r < N; r++) - for (c = 0; c < N; c++) { - b1 = ll[r][c] + lh[r][c] + hl[r][c] + hh[r][c]; //Reconstruct each - b2 = ll[r][c] + lh[r][c] - hl[r][c] - hh[r][c]; //of the pixels - b3 = ll[r][c] - lh[r][c] + hl[r][c] - hh[r][c]; - b4 = ll[r][c] - lh[r][c] - hl[r][c] + hh[r][c]; - b1 = (b1 > 255.0) ? 255.0 : b1; //Check for positive... - b1 = (b1 < 0.0) ? 0.0 : b1; //or negative core! - b2 = (b2 > 255.0) ? 255.0 : b2; - b2 = (b2 < 0.0) ? 0.0 : b2; - b3 = (b3 > 255.0) ? 255.0 : b3; - b3 = (b3 < 0.0) ? 0.0 : b3; - b4 = (b4 > 255.0) ? 255.0 : b4; - b4 = (b4 < 0.0) ? 0.0 : b4; - s[2*r][2*c] = b1; //Put them back in - s[2*r][2*c + 1] = b2; //the right position - s[2*r + 1][2*c] = b3; - s[2*r + 1][2*c + 1] = b4; - } -} - -void watermark(double **i, int N, long key, long int L, long int M, double a) -{ - int row, col, count; - long int elem, temp, seed; - double *v; - v = dvector(N * N); - put_matrix_2_vector(i, v, N); - fct2d(v, N, N); - seed = key; - count = 0; - elem = 0; - row = 2; - col = -1; - do { - do { - row--; - col++; - elem++; - if (col < N) { - if (elem > M) { - temp = row * N + col; - v[temp] += a * fabs(v[temp]) * gasdev(&seed); - count++; - } - } - } while (row > 0); - row = 2 + col; - col = -1; - } while (count < L); - ifct2d(v, N, N); - put_vector_2_matrix(v, i, N); - free(v); -} - -int main(int argc, char* argv[]) -{ - double **i; - double **o; - FILE *in; - FILE *out; - int N; - int c; - long int M1, L1, M2, L2; - int **image_i; - double **ll, **lh, **hl, **hh; - double a_ll = 0.1, a_other = 0.2; - int wm_length_1 = 10000, wm_length_ll = 10000, coeff_start_1 = 3000, - coeff_start_ll = 3000, wm_key = 123; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "a:b:t:m:s:l:k:")) != EOF) { - switch (c) { - case 'a': - a_ll = atof(optarg); - break; - case 'b': - a_other = atof(optarg); - break; - case 't': - coeff_start_1 = atoi(optarg); - break; - case 'm': - wm_length_1 = atoi(optarg); - break; - case 's': - coeff_start_ll = atoi(optarg); - break; - case 'l': - wm_length_ll = atoi(optarg); - break; - case 'k': - wm_key = atoi(optarg); - break; - } - } - argc -= optind; - argv += optind; - - in = stdin; - out = stdout; - open_image(in, &width, &height); - image_i = imatrix(height, width); - load_image(image_i, in, width, height); - if (height == width) - N = height; - else { - fprintf(stderr, "Cannot Proccess non-square images!\n"); - exit( -11); - } - // starting coeff. for 1st level decomp. - M1 = coeff_start_1; - // number of coeffs to alter - L1 = wm_length_1; - - // now the LL band - M2 = coeff_start_ll; - L2 = wm_length_ll; - - i = dmatrix(N, N); - o = dmatrix(N, N); - ll = dmatrix(N / 2, N / 2); - lh = dmatrix(N / 2, N / 2); - hl = dmatrix(N / 2, N / 2); - hh = dmatrix(N / 2, N / 2); - - matrix_i2d(image_i, i, N); - - //---------------------1o decomposition------------------- - add_hor_add_ver(i, N, ll); - add_hor_sub_ver(i, N, lh); - sub_hor_add_ver(i, N, hl); - sub_hor_sub_ver(i, N, hh); - //---------------------Watermark medium frequency bands--- - watermark(lh, N / 2, wm_key, L1, M1, a_other); - watermark(hl, N / 2, wm_key, L1, M1, a_other); - watermark(hh, N / 2, wm_key, L1, M1, a_other); - watermark(ll, N / 2, wm_key, L2, M2, a_ll); - //---------------------Synthesis stage-------------------- - band_synthesis(ll, lh, hl, hh, N / 2, o); - //-------------------------------------------------------- - matrix_d2i(o, image_i, N); - save_image(image_i, out, width, height); - - fclose(in); - fclose(out); - - exit(EXIT_SUCCESS); -} - - - - diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos/common.c --- a/Fotopoulos/common.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,571 +0,0 @@ -#include -#include -#include -#include -#include -#include "pgm.h" -#include "common.h" - -#define IA 16807 -#define IM 2147483647 -#define AM (1.0/IM) -#define IQ 127773 -#define IR 2836 -#define MASK 123459876 - -static int NN = 0; -static int m = 0; -static double two_over_N = 0; -static double root2_over_rootN = 0; -static double *C = NULL; - -static gray maxval; -static int format; - -void open_image(FILE *in, int *width, int *height) -{ - - pgm_readpgminit(in, width, height, &maxval, &format); -} - -void load_image(int **im, FILE *in, int width, int height) -{ - int col, row; - gray *rowbuf; - - rowbuf = malloc(sizeof(gray) * width); - - for (row = 0; row < height; row++) { - pgm_readpgmrow(in, rowbuf, width, maxval, format); - for (col = 0; col < width; col++) - im[row][col] = rowbuf[col]; - } - - free(rowbuf); -} - -void save_image(int **im, FILE *out, int width, int height) -{ - int col, row; - gray *rowbuf; - - pgm_writepgminit(out, width, height, 255, 0); - - rowbuf = malloc(sizeof(gray) * width); - - for (row = 0; row < height; row++) { - for (col = 0; col < width; col++) - rowbuf[col] = im[row][col]; - pgm_writepgmrow(out, rowbuf, width, 255, 0); - } - - free(rowbuf); -} - -int ** imatrix(int nrows, int ncols) -{ - int **m; - int i, j; - m = (int **) malloc (nrows * sizeof(int *)); - for (i = 0; i < nrows; i++) { - m[i] = (int *) malloc (ncols * sizeof(int)); - if (!m[i]) fprintf(stderr, "\nIt's not working"); - } - for (i = 0; i < nrows; i++) - for (j = 0; j < ncols; j++) - m[i][j] = 0; - return m; -} - -void freematrix(int **I, int rows) -{ - int k; - for (k = 0; k < rows; k++) - free (I[k]); -} - -float ran0(long int *idum) -{ - long int k; - float ans; - *idum ^= MASK; - k = (*idum) / IQ; - *idum = IA * (*idum - k * IQ) - IR * k; - if (*idum < 0) *idum += IM; - ans = AM * (*idum); - *idum ^= MASK; - return ans; -} - -float gasdev(long int *idum) -{ - - float v1; - v1 = (float) sqrt( -2.0 * log(ran0(idum))) * cos(2 * PI * ran0(idum)); - return v1; -} - - -void put_image_from_int_2_double(int **i, double *f, int N) -{ - int l, j, k; - k = 0; - for (l = 0; l < N; l++) - for (j = 0; j < N; j++) - f[k++] = (double) i[l][j]; -} - -void put_image_from_double_2_int(double *f, int **i, int N) -{ - int l, j, k; - k = 0; - for (l = 0; l < N; l++) - for (j = 0; j < N; j++) - i[l][j] = (int) f[k++]; -} - - -void bitrev(double *f, int len) -{ - int i, j, m, halflen; - double temp; - - if (len <= 2) return ; /* No action necessary if n=1 or n=2 */ - halflen = len >> 1; - j = 1; - for (i = 1; i <= len; i++) { - if (i < j) { - temp = f[j - 1]; - f[j - 1] = f[i - 1]; - f[i - 1] = temp; - } - m = halflen; - while (j > m) { - j = j - m; - m = (m + 1) >> 1; - } - j = j + m; - } -} - -void inv_sums(double *f) -{ - int stepsize, stage, curptr, nthreads, thread, step, nsteps; - - for (stage = 1; stage <= m - 1; stage++) { - nthreads = 1 << (stage - 1); - stepsize = nthreads << 1; - nsteps = (1 << (m - stage)) - 1; - for (thread = 1; thread <= nthreads; thread++) { - curptr = NN - thread; - for (step = 1; step <= nsteps; step++) { - f[curptr] += f[curptr - stepsize]; - curptr -= stepsize; - } - } - } -} - -//-------------------------------------------------------- -//Foreign code - FCT from Bath Univerity -//-------------------------------------------------------- -void rarrwrt(double f[], int n) -{ - int i; - - for (i = 0; i <= n - 1; i++) { - fprintf(stderr, "%4d : %f\n", i, f[i]); - } -} - -/* fast DCT based on IEEE signal proc, 1992 #8, yugoslavian authors. */ - -void fwd_sums(double *f) -{ - int stepsize, stage, curptr, nthreads, thread, step, nsteps; - - for (stage = m - 1; stage >= 1; stage--) { - nthreads = 1 << (stage - 1); - stepsize = nthreads << 1; - nsteps = (1 << (m - stage)) - 1; - for (thread = 1; thread <= nthreads; thread++) { - curptr = nthreads + thread - 1; - for (step = 1; step <= nsteps; step++) { - f[curptr] += f[curptr + stepsize]; - curptr += stepsize; - } - } - } -} - -void scramble(double *f, int len) -{ - double temp; - int i, ii1, ii2, halflen, qtrlen; - - halflen = len >> 1; - qtrlen = halflen >> 1; - bitrev(f, len); - bitrev(&f[0], halflen); - bitrev(&f[halflen], halflen); - ii1 = len - 1; - ii2 = halflen; - for (i = 0; i <= qtrlen - 1; i++) { - temp = f[ii1]; - f[ii1] = f[ii2]; - f[ii2] = temp; - ii1--; - ii2++; - } -} - -void unscramble(double *f, int len) -{ - double temp; - int i, ii1, ii2, halflen, qtrlen; - - halflen = len >> 1; - qtrlen = halflen >> 1; - ii1 = len - 1; - ii2 = halflen; - for (i = 0; i <= qtrlen - 1; i++) { - temp = f[ii1]; - f[ii1] = f[ii2]; - f[ii2] = temp; - ii1--; - ii2++; - } - bitrev(&f[0], halflen); - bitrev(&f[halflen], halflen); - bitrev(f, len); -} - -void initcosarray(int length) -{ - int i, group, base, item, nitems, halfN; - double factor; - - m = -1; - do { - m++; - NN = 1 << m; - if (NN > length) { - fprintf(stderr, "ERROR in FCT-- length %d not a power of 2\n", length); - exit(1); - } - } while (NN < length); - if (C != NULL) free(C); - C = (double *)calloc(NN, sizeof(double)); - if (C == NULL) { - fprintf(stderr, "Unable to allocate C array\n"); - exit(1); - } - halfN = NN / 2; - two_over_N = 2.0 / (double)NN; - root2_over_rootN = sqrt(2.0 / (double)NN); - for (i = 0; i <= halfN - 1; i++) C[halfN + i] = 4 * i + 1; - for (group = 1; group <= m - 1; group++) { - base = 1 << (group - 1); - nitems = base; - factor = 1.0 * (1 << (m - group)); - for (item = 1; item <= nitems; item++) C[base + item - 1] = factor * C[halfN + item - 1]; - } - - //printf("before taking cos, C array =\n"); rarrwrt(C,N); - for (i = 1; i <= NN - 1; i++) C[i] = 1.0 / (2.0 * cos(C[i] * PI / (2.0 * NN))); - //printf("After taking cos, Carray = \n"); rarrwrt(C,N); -} - - -void inv_butterflies(double *f) -{ - int stage, ii1, ii2, butterfly, ngroups, group, wingspan, increment, baseptr; - double Cfac, T; - - for (stage = 1; stage <= m; stage++) { - ngroups = 1 << (m - stage); - wingspan = 1 << (stage - 1); - increment = wingspan << 1; - for (butterfly = 1; butterfly <= wingspan; butterfly++) { - Cfac = C[wingspan + butterfly - 1]; - baseptr = 0; - for (group = 1; group <= ngroups; group++) { - ii1 = baseptr + butterfly - 1; - ii2 = ii1 + wingspan; - T = Cfac * f[ii2]; - f[ii2] = f[ii1]-T; - f[ii1] = f[ii1] + T; - baseptr += increment; - } - } - } -} - -void fwd_butterflies(double *f) -{ - int stage, ii1, ii2, butterfly, ngroups, group, wingspan, increment, baseptr; - double Cfac, T; - - for (stage = m; stage >= 1; stage--) { - ngroups = 1 << (m - stage); - wingspan = 1 << (stage - 1); - increment = wingspan << 1; - for (butterfly = 1; butterfly <= wingspan; butterfly++) { - Cfac = C[wingspan + butterfly - 1]; - baseptr = 0; - for (group = 1; group <= ngroups; group++) { - ii1 = baseptr + butterfly - 1; - ii2 = ii1 + wingspan; - T = f[ii2]; - f[ii2] = Cfac * (f[ii1]-T); - f[ii1] = f[ii1] + T; - baseptr += increment; - } - } - } -} - -void ifct_noscale(double *f, int length) -{ - if (length != NN) initcosarray(length); - f[0] *= INVROOT2; - inv_sums(f); - bitrev(f, NN); - inv_butterflies(f); - unscramble(f, NN); -} - -void fct_noscale(double *f, int length) -{ - if (length != NN) initcosarray(length); - scramble(f, NN); - fwd_butterflies(f); - bitrev(f, NN); - fwd_sums(f); - f[0] *= INVROOT2; -} - -void ifct_defn_scaling(double *f, int length) -{ - ifct_noscale(f, length); -} - -void fct_defn_scaling(double *f, int length) -{ - int i; - - fct_noscale(f, length); - for (i = 0; i <= NN - 1; i++) f[i] *= two_over_N; -} - -void ifct(double *f, int length) -{ - /* CALL THIS FOR INVERSE 1D DCT DON-MONRO PREFERRED SCALING */ - int i; - - if (length != NN) initcosarray(length); /* BGS patch June 1997 */ - for (i = 0; i <= NN - 1; i++) f[i] *= root2_over_rootN; - ifct_noscale(f, length); -} - -void fct(double *f, int length) -{ - /* CALL THIS FOR FORWARD 1D DCT DON-MONRO PREFERRED SCALING */ - int i; - - fct_noscale(f, length); - for (i = 0; i <= NN - 1; i++) f[i] *= root2_over_rootN; -} - -/**************************************************************** - 2D FAST DCT SECTION -****************************************************************/ - -static double *g = NULL; -static double two_over_sqrtncolsnrows = 0.0; -static int ncolsvalue = 0; -static int nrowsvalue = 0; - -void initfct2d(int nrows, int ncols) -{ - if ((nrows <= 0) || (ncols < 0)) { - fprintf(stderr, "FCT2D -- ncols=%d or nrows=%d is <=0\n", nrows, ncols); - exit(1); - } - if (g != NULL) free(g); - g = (double *)calloc(nrows, sizeof(double)); - if (g == NULL) { - fprintf(stderr, "FCT2D -- Unable to allocate g array\n"); - exit(1); - } - ncolsvalue = ncols; - nrowsvalue = nrows; - two_over_sqrtncolsnrows = 2.0 / sqrt(ncols * 1.0 * nrows); -} - -void fct2d(double f[], int nrows, int ncols) -/* CALL THIS FOR FORWARD 2d DCT DON-MONRO PREFERRED SCALING */ -{ - int u, v; - - if ((ncols != ncolsvalue) || (nrows != nrowsvalue)){ - initfct2d(nrows, ncols); - } - for (u = 0; u <= nrows - 1; u++){ - fct_noscale(&f[u*ncols], ncols); - } - for (v = 0; v <= ncols - 1; v++){ - for (u = 0; u <= nrows - 1; u++) { - g[u] = f[u * ncols + v]; - } - fct_noscale(g, nrows); - for (u = 0; u <= nrows - 1; u++) { - f[u*ncols + v] = g[u] * two_over_sqrtncolsnrows; - } - } -} - -void ifct2d(double f[], int nrows, int ncols) -/* CALL THIS FOR INVERSE 2d DCT DON-MONRO PREFERRED SCALING */ -{ - int u, v; - - if ((ncols != ncolsvalue) || (nrows != nrowsvalue)){ - initfct2d(nrows, ncols); - } - for (u = 0; u <= nrows - 1; u++){ - ifct_noscale(&f[u*ncols], ncols); - } - for (v = 0; v <= ncols - 1; v++){ - for (u = 0; u <= nrows - 1; u++) { - g[u] = f[u * ncols + v]; - } - ifct_noscale(g, nrows); - for (u = 0; u <= nrows - 1; u++) { - f[u*ncols + v] = g[u] * two_over_sqrtncolsnrows; - } - } -} - -void matmul(double **a, double **b, double **r, int N) -{ - int i, j, k; - - for (i = 0; i < N; i++) - for (j = 0; j < N; j++) { - r[i][j] = 0.0; - for (k = 0; k < N; k++) - r[i][j] += a[i][k] * b[k][j]; - } -} - -void hartley(double **in, double **out, int N) -{ - int k, n; - double **h; - - h = dmatrix(N, N); - //Building up the transformation matrix - for (k = 0; k < N; k++) - for (n = 0; n < N; n++) - h[k][n] = (cos(2 * PI * k * n / N) + sin(2 * PI * k * n / N)) / sqrt(N); - - // Now we have to multiply the input with the transformation matrix - matmul(h, in, out, N); - freematrix_d(h, N); - return ; -} - -double ** dmatrix(int nrows, int ncols) -{ - double **m; - int i, j; - m = (double **) malloc (nrows * sizeof(double *)); - for (i = 0; i < nrows; i++) { - m[i] = (double *) malloc (ncols * sizeof(double)); - if (!m[i]) printf("\nIt's not working"); - } - for (i = 0; i < nrows; i++) - for (j = 0; j < ncols; j++) - m[i][j] = 0.0; - return m; -} - -void freematrix_d(double **I, int rows) -{ - int k; - for (k = 0; k < rows; k++) - free (I[k]); -} - -void matrix_i2d(int **i, double **d, int N) -{ - int x, y; - for (x = 0; x < N; x++) - for (y = 0; y < N; y++) - d[y][x] = i[y][x]; -} - -void matrix_d2i(double **d, int **i, int N) -{ - int x, y; - for (x = 0; x < N; x++) - for (y = 0; y < N; y++) - i[y][x] = d[y][x]; -} - -double * dvector(long int N) -{ - double *m; - m = (double *) malloc (N * sizeof(double)); - if (!m) printf("\nIt's not working"); - return m; -} - -void put_matrix_2_vector(double **i, double *f, int N) -{ - int l, j, k; - k = 0; - for (l = 0; l < N; l++) - for (j = 0; j < N; j++) - f[k++] = i[l][j]; -} - -void put_vector_2_matrix(double *f, double **i, int N) -{ - int l, j, k; - k = 0; - for (l = 0; l < N; l++) - for (j = 0; j < N; j++) - i[l][j] = f[k++]; -} - -void set_in_binary() { -#if defined(EMX) - _fsetmode(in, "b"); -#elif defined(MINGW) - setmode(STDIN_FILENO, O_BINARY); -#endif -} - -void set_out_binary() { -#if defined(EMX) - _fsetmode(out, "b"); -#elif defined(MINGW) - setmode(STDOUT_FILENO, O_BINARY); -#endif -} - -void wm_init2() { - set_out_binary(); -} - -void wm_init1() { - set_in_binary(); -} - -void wm_init() { - set_in_binary(); - set_out_binary(); -} - diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos/common.h --- a/Fotopoulos/common.h Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -#define PI 3.1415926535897932 -#define INVROOT2 0.7071067814 - -void open_image(FILE *in, int *width, int *height); -void load_image(int **im, FILE *in, int width, int height); -void save_image(int **im, FILE *out, int width, int height); -int ** imatrix(int nrows, int ncols); -void freematrix(int **I, int rows); -float ran0(long int *idum); -float gasdev(long int *idum); -void put_image_from_int_2_double(int **i, double *f, int N); -void put_image_from_double_2_int(double *f, int **i, int N); -void fct2d(double f[], int nrows, int ncols); -void ifct2d(double f[], int nrows, int ncols); -void matmul(double **a, double **b, double **r, int N); -void hartley(double **in, double **out, int N); -double ** dmatrix(int nrows, int ncols); -void freematrix_d(double **I, int rows); -void hartley(double **in, double **out, int N); -void matrix_i2d(int **i, double **d, int N); -void matrix_d2i(double **d, int **i, int N); -void put_matrix_2_vector(double **i, double *f, int N); -void put_vector_2_matrix(double *f, double **i, int N); -double * dvector(long int N); - -void wm_init(); -void wm_init1(); -void wm_init2(); diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos/test-hart.c --- a/Fotopoulos/test-hart.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -/* Watermarking program - Hartley Transform based */ -/* Module : Testing */ -/* Author : Vassilis Fotopoulos */ -/* Date : 26/7/1999 */ -/* Developed at : ELLAB */ -/* Electronics Laboratory */ -/* Department of Physics */ -/* University of Patras - GREECE */ -/* Copyleft (c) 1999 */ -/*------------------------------------------------------*/ -/* pseudorandom noise generator's code is */ -/* taken from "Numerical Recipes in C" */ -/*------------------------------------------------------*/ -#include -#include -#include -#include -#include -#include -#include "common.h" -#include "pgm.h" - -int height, width; - -void read_watermark(double **in, int N, int coeff_start, int wm_length, double wm_alpha) -{ - int row, col, count; - long int elem, L, M, seed, i; - double z; - M = coeff_start; - L = wm_length; - for (i = 1; i <= 1000; i++) { - seed = i; - z = 0.0; - count = 0; - elem = 0; - - for (row = 0; row < N; row++) - for (col = 0; col < N; col++) { - elem++; - if (elem > M && count < L) { - z += in[row][col] * gasdev(&seed); - count++; - } - } - - printf("%ld\t%f\n", i, z / L); - } - return ; -} - -int main(int argc, char* argv[]) -{ - FILE *in; - int **image; - double **image_i; - double **image_d; - int c; - int N; - int coeff_start = 5000, wm_length = 10000; - double wm_alpha = 0.2; - int width, height; - - pgm_init(&argc, argv); wm_init2(); - - while ((c = getopt(argc, argv, "a:s:l:")) != EOF) { - switch (c) { - case 'a': - wm_alpha = atof(optarg); - break; - case 's': - coeff_start = atoi(optarg); - break; - case 'l': - wm_length = atoi(optarg); - break; - } - } - argc -= optind; - argv += optind; - - in = stdin; - - open_image(in, &width, &height); - image = imatrix(height, width); - load_image(image, in, width, height); - - if (height == width) - N = height; - else { - fprintf(stderr, "Cannot Proccess non-square images!\n"); - exit( -11); - } - - image_i = dmatrix(height, width); - image_d = dmatrix(height, width); - if (image_d == NULL) { - fprintf(stderr, "Unable to allocate the double array\n"); - exit(1); - } - matrix_i2d(image, image_i, N); - hartley(image_i, image_d, N); - read_watermark(image_d, N, coeff_start, wm_length, wm_alpha); - - freematrix_d(image_i, height); - freematrix_d(image_d, height); - fclose(in); - - exit(EXIT_SUCCESS); -} diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos/test-pv.c --- a/Fotopoulos/test-pv.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/* Watermarking program - Fast Cosine Transform based */ -/* Module : Testing */ -/* Author : Vassilis Fotopoulos */ -/* Date : 21/7/1999 */ -/* Developed at : ELLAB */ -/* Electronics Laboratory */ -/* Department of Physics */ -/* University of Patras - GREECE */ -/* Copyleft (c) 1999 */ -/* Testing Program */ -/*------------------------------------------------------*/ -/* pseudorandom noise generator's code is */ -/* taken from "Numerical Recipes in C" */ -/* FCT implementation from the University of Bath */ -/*------------------------------------------------------*/ -#include -#include -#include -#include -#include -#include -#include "common.h" -#include "pgm.h" - -double cu[1024]; -double cv[1024]; -int height, width; - -void read_watermark(double *in, int N, int start_coeff, int wm_length, double wm_alpha) -{ - int row, col, count; - long int elem, L, M, temp, seed, i; - double z; - M = start_coeff; - L = wm_length; - for (i = 1; i <= 1000; i++) { - seed = i; - z = 0.0; - count = 0; - elem = 0; - row = 2; - col = -1; - do { - do { - row--; - col++; - elem++; - if (col < N) { - if (elem > M) { - temp = row * N + col; - z += in[temp] * gasdev(&seed); - count++; - } - } - } while (row > 0); - row = 2 + col; - col = -1; - } while (count < L); - printf("%ld\t%f\n", i, z / L); - } - return ; -} -//-------------------------------------------------------- -void initialize_constants(void) -{ - int i; - cu[0] = cv[0] = 0.7071068; - for (i = 1; i < 1024; i++) - cu[i] = cv[i] = 1.0; -} - -int main(int argc, char* argv[]) -{ - FILE *in; - int **image_i; - double *image_f = NULL; - int N; - int c; - int coeff_start = 5000, wm_length = 10000; - double wm_alpha = 0.2; - - pgm_init(&argc, argv); wm_init2(); - - while ((c = getopt(argc, argv, "a:s:l:")) != EOF) { - switch (c) { - case 'a': - wm_alpha = atof(optarg); - break; - case 's': - coeff_start = atoi(optarg); - break; - case 'l': - wm_length = atoi(optarg); - break; - } - } - argc -= optind; - argv += optind; - in = stdin; - - open_image(in, &width, &height); - image_i = imatrix(height, width); - load_image(image_i, in, width, height); - - if (height == width) - N = height; - else { - fprintf(stderr, "Cannot Proccess non-square images!\n"); - exit( -11); - } - - initialize_constants(); - image_f = (double *)calloc(N * N, sizeof(double)); - if (image_f == NULL) { - printf("Unable to allocate the float array\n"); - exit(1); - } - - put_image_from_int_2_double(image_i, image_f, N); - fct2d(image_f, N, N); - read_watermark(image_f, N, coeff_start, wm_length, wm_alpha); - fclose(in); - freematrix(image_i, height); - free(image_f); - - exit(EXIT_SUCCESS); -} diff -r 71dd4b96221b -r 9f20bce6184e Fotopoulos/test-sub.c --- a/Fotopoulos/test-sub.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,240 +0,0 @@ -/* Watermarking program - Subband DCT Transform based */ -/* Module : Testing */ -/* Author : Vassilis Fotopoulos */ -/* Date : 25/4/2000 */ -/* Revision : 6.0 */ -/* Developed at : ELLAB */ -/* Electronics Laboratory */ -/* Department of Physics */ -/* University of Patras - GREECE */ -/* Copyleft (c) 1999 */ -/*------------------------------------------------------*/ -/* pseudorandom noise generator's code is */ -/* taken from "Numerical Recipes in C" */ -/* FCT implementation from University of Bath */ -/*------------------------------------------------------*/ -#include -#include -#include -#include -#include -#include -#include "common.h" -#include "pgm.h" - -//-------------------------------------------------------- -void add_hor_add_ver(double **in, int N, double **out); -void add_hor_sub_ver(double **in, int N, double **out); -void sub_hor_add_ver(double **in, int N, double **out); -void sub_hor_sub_ver(double **in, int N, double **out); -double detect_mark(double *i, int N, long key, long int L, long int M, double a); - -//-------------------------------------------------------- -double cu[1024]; -double cv[1024]; -int height, width; -//-------------------------------------------------------- -void add_hor_add_ver(double **in, int N, double **out) -{ - double **temp; - int r, c; - temp = dmatrix(N, N); - for (r = 0; r < N; r++) - for (c = 0; c < N / 2; c++) - temp[r][c] = (in[r][2 * c] + in[r][2 * c + 1]) / 2; - for (c = 0; c < N / 2; c++) - for (r = 0; r < N / 2; r++) - out[r][c] = (temp[2 * r][c] + temp[2 * r + 1][c]) / 2; - freematrix_d(temp, N); -} -//-------------------------------------------------------- -void add_hor_sub_ver(double **in, int N, double **out) -{ - double **temp; - int r, c; - temp = dmatrix(N, N); - for (r = 0; r < N; r++) - for (c = 0; c < N / 2; c++) - temp[r][c] = (in[r][2 * c] + in[r][2 * c + 1]) / 2; - for (c = 0; c < N / 2; c++) - for (r = 0; r < N / 2; r++) - out[r][c] = (temp[2 * r][c] - temp[2 * r + 1][c]) / 2; - freematrix_d(temp, N); -} -//-------------------------------------------------------- -void sub_hor_add_ver(double **in, int N, double **out) -{ - double **temp; - int r, c; - temp = dmatrix(N, N); - for (r = 0; r < N; r++) - for (c = 0; c < N / 2; c++) - temp[r][c] = (in[r][2 * c] - in[r][2 * c + 1]) / 2; - for (c = 0; c < N / 2; c++) - for (r = 0; r < N / 2; r++) - out[r][c] = (temp[2 * r][c] + temp[2 * r + 1][c]) / 2; - freematrix_d(temp, N); -} -//-------------------------------------------------------- -void sub_hor_sub_ver(double **in, int N, double **out) -{ - double **temp; - int r, c; - temp = dmatrix(N, N); - for (r = 0; r < N; r++) - for (c = 0; c < N / 2; c++) - temp[r][c] = (in[r][2 * c] - in[r][2 * c + 1]) / 2; - for (c = 0; c < N / 2; c++) - for (r = 0; r < N / 2; r++) - out[r][c] = (temp[2 * r][c] - temp[2 * r + 1][c]) / 2; - freematrix_d(temp, N); -} - -//--------------------------------------------------------- -double detect_mark(double *i, int N, long key, long int L, long int M, double a) -{ - int row, col, count; - long int elem, temp, seed; - double z; - - - seed = key; - z = 0.0; - count = 0; - elem = 0; - row = 2; - col = -1; - do { - do { - row--; - col++; - elem++; - if (col < N) { - if (elem > M) { - temp = row * N + col; - z += i[temp] * gasdev(&seed); - count++; - } - } - } while (row > 0); - row = 2 + col; - col = -1; - } while (count < L); - - return (z / L); -} - -int main(int argc, char* argv[]) -{ - double **i; - FILE *in; - int N; - long int key, M1, L1, M2, L2; - double **ll, **lh, **hl, **hh; - double *v1, *v2, *v3, *v99; - double m1, m2, m3, detect_value, m99; - int ** image_i; - int c; - int wm_length_1 = 10000, wm_length_ll = 10000, coeff_start_1 = 3000, coeff_start_ll = 3000; - double a_ll = 0.1, a_other = 0.2; - - pgm_init(&argc, argv); wm_init2(); - - while ((c = getopt(argc, argv, "a:b:t:m:s:l:")) != EOF) { - switch (c) { - case 'a': - a_ll = atof(optarg); - break; - case 'b': - a_other = atof(optarg); - break; - case 't': - coeff_start_1 = atoi(optarg); - break; - case 'm': - wm_length_1 = atoi(optarg); - break; - case 's': - coeff_start_ll = atoi(optarg); - break; - case 'l': - wm_length_ll = atoi(optarg); - break; - } - } - argc -= optind; - argv += optind; - - in = stdin; - open_image(in, &width, &height); - image_i = imatrix(height, width); - load_image(image_i, in, width, height); - - if (height == width) - N = height; - else { - fprintf(stderr, "Cannot Proccess non-square images!\n"); - exit( -11); - } - // starting coeff. for 1st level decomp. - M1 = coeff_start_1; - // number of coeffs to alter - L1 = wm_length_1; - // alpha parameter - - // now the LL band - M2 = coeff_start_ll; - L2 = wm_length_ll; - - - i = dmatrix(N, N); - ll = dmatrix(N / 2, N / 2); - lh = dmatrix(N / 2, N / 2); - hl = dmatrix(N / 2, N / 2); - hh = dmatrix(N / 2, N / 2); - v1 = dvector(N * N / 4); - v2 = dvector(N * N / 4); - v3 = dvector(N * N / 4); - v99 = dvector(N * N / 4); - - matrix_i2d(image_i, i, N); - - //---------------------1o decomposition------------------- - add_hor_add_ver(i, N, ll); - add_hor_sub_ver(i, N, lh); - sub_hor_add_ver(i, N, hl); - sub_hor_sub_ver(i, N, hh); - //---------------------Detect Watermark from all bands---- - put_matrix_2_vector(lh, v1, N / 2); - put_matrix_2_vector(hl, v2, N / 2); - put_matrix_2_vector(hh, v3, N / 2); - put_matrix_2_vector(ll, v99, N / 2); - fct2d(v1, N / 2, N / 2); - fct2d(v2, N / 2, N / 2); - fct2d(v3, N / 2, N / 2); - fct2d(v99, N / 2, N / 2); - for (key = 1; key <= 1000; key++) { - m1 = detect_mark(v1, N / 2, key, L1, M1, a_other); - m2 = detect_mark(v2, N / 2, key, L1, M1, a_other); - m3 = detect_mark(v3, N / 2, key, L1, M1, a_other); - m99 = detect_mark(v99, N / 2, key, L2, M2, a_ll); - detect_value = (m1 + m2 + m3 + m99) / 4; - printf("%ld\t%f\t%f\t%f\t%f\t%f\n", key, m1, m2, m3, m99, detect_value); - } - //-------------------------------------------------------- - free(v1); - free(v2); - free(v3); - free(v99); - freematrix_d(ll, N / 2); - freematrix_d(hl, N / 2); - freematrix_d(lh, N / 2); - freematrix_d(hh, N / 2); - fclose(in); - - exit(EXIT_SUCCESS); -} - - - - diff -r 71dd4b96221b -r 9f20bce6184e Makefile --- a/Makefile Fri Dec 20 12:53:41 2024 +0100 +++ b/Makefile Fri Dec 20 13:08:59 2024 +0100 @@ -2,21 +2,21 @@ WEBDIR = /home/scicomp/pmeerw/public-www/Watermarking/source -all: meerwald fotopoulos +all: meerwald fotopoulos meerwald: - cd Meerwald ; make + cd Meerwald-dir ; make fotopoulos: - cd Fotopoulos ; make + cd Fotopoulos-dir ; make install: - cd Meerwald ; make install - cd Fotopoulos ; make install + cd Meerwald-dir ; make install + cd Fotopoulos-dir ; make install clean: - cd Meerwald ; make clean - cd Fotopoulos ; make clean + cd Meerwald-dir ; make clean + cd Fotopoulos-dir ; make clean dist: cp -v manual.pdf manual.ps $(WEBDIR) @@ -29,8 +29,8 @@ mv -v wm_source_bin.tar.gz $(WEBDIR) zip -9r wm_source_bin.zip * mv -v wm_source_bin.zip $(WEBDIR) - tar -czf wm_source.tar.gz ANNOUNCEMENT Fotopoulos/* Meerwald/* Makefile README images/* make/* manual.* sigs/.dummy watermarked/.dummy wms/.dummy win32_bin/.dummy linux_bin/.dummy + tar -czf wm_source.tar.gz ANNOUNCEMENT Fotopoulos-dir/* Meerwald-dir/* Makefile README images/* make/* manual.* sigs/.dummy watermarked/.dummy wms/.dummy win32_bin/.dummy linux_bin/.dummy mv -v wm_source.tar.gz $(WEBDIR) - zip -9r wm_source.zip ANNOUNCEMENT Fotopoulos/* Meerwald/* Makefile README images/* make/* manual.* sigs/.dummy watermarked/.dummy wms/.dummy linux_bin/.dummy win32_bin/.dummy + zip -9r wm_source.zip ANNOUNCEMENT Fotopoulos-dir/* Meerwald-dir/* Makefile README images/* make/* manual.* sigs/.dummy watermarked/.dummy wms/.dummy linux_bin/.dummy win32_bin/.dummy mv -v wm_source.zip $(WEBDIR) chmod a+r $(WEBDIR)/* diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/Makefile Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,520 @@ +# Makefile + +# chose build plattform +include ../make/make.config + +OPTIONS=-DPARAM_STUFF -DPOLLEN_STUFF + +all: tools \ + bruyn \ + koch \ + corvi \ + xia \ + xie \ + xie2 \ + cox \ + zhu \ + dugad \ + wang \ + frid2 \ + kim \ + kund2 \ + kund3 + +.SUFFIXES: .c .o .1 .ps + +.c$(O): + $(CC) $(CFLAGS) $(INCLUDES) $(OPTIONS) -o $@ -c $< + +.1.ps: + $(GROFF) $< > $@ + +# library containing general stuff + +$(LIBPREFIX)wm$(LIB): dct$(O) coeff$(O) gray$(O) sort$(O) signature-utils$(O) coord$(O) wm$(O) + $(RM) $@ + ar -rc $@ dct$(O) coeff$(O) gray$(O) sort$(O) signature-utils$(O) coord$(O) wm$(O) + +libraryclean: + $(RM) $(LIBPREFIX)wm$(LIB) + +# library containing wavelet transform stuff + +$(LIBPREFIX)wavelet$(LIB): wavelet$(O) dwt$(O) dwt_util$(O) + $(RM) $@ + ar -rc $@ wavelet$(O) dwt$(O) dwt_util$(O) + +waveletclean: + $(RM) $(LIBPREFIX)wavelet$(LIB) + +# some general tools to compute difference image, PSNR, ... + +tools: cmp_pgm$(EXE) cmp_dct8x8$(EXE) cmp_dct$(EXE) cmp_dwt$(EXE) cmp_ppm$(EXE) + +toolstest: + +toolsinstall: tools + $(CP) cmp_ppm$(EXE) cmp_pgm$(EXE) cmp_dct8x8$(EXE) cmp_dct$(EXE) cmp_dwt$(EXE) $(INSTALLDIR) + +toolsman: cmp_ppm.ps cmp_pgm.ps cmp_dct8x8.ps cmp_dct.ps + +toolsclean: + $(RM) cmp_ppm$(EXE) cmp_pgm$(EXE) cmp_dct$(EXE) cmp_dct8x8$(EXE) cmp_dwt$(EXE) + +cmp_pgm$(EXE): cmp_pgm$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ cmp_pgm$(O) $(WMLIB) $(PGMLIBS) $(LIBS) + +cmp_ppm$(EXE): cmp_ppm$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ cmp_ppm$(O) $(WMLIB) $(PGMLIBS) $(LIBS) + +cmp_dct$(EXE): cmp_dct$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ cmp_dct$(O) $(WMLIB) $(PGMLIBS) + +cmp_dwt$(EXE): cmp_dwt$(O) $(LIBPREFIX)wavelet$(LIB) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ cmp_dwt$(O) $(WAVELIB) $(WMLIB) $(PGMLIBS) + +cmp_dct8x8$(EXE): cmp_dct8x8$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ cmp_dct8x8$(O) $(WMLIB) $(PGMLIBS) + + +# Koch's algorithm (8x8 block DCT, blind, binary) + +koch: gen_koch_sig$(EXE) wm_koch_e$(EXE) wm_koch_d$(EXE) cmp_koch_sig$(EXE) + +kochtest: koch + gen_koch_sig$(EXE) -n 150 < gen_koch_sig.c > ../sigs/koch.sig + wm_koch_e$(EXE) -s ../sigs/koch.sig -o ../watermarked/koch_lena.pgm ../images/lena.pgm + wm_koch_d$(EXE) -s ../sigs/koch.sig -o ../wms/koch.wm ../watermarked/koch_lena.pgm + cmp_koch_sig$(EXE) -s ../sigs/koch.sig ../wms/koch.wm + +kochinstall: koch + $(CP) gen_koch_sig$(EXE) wm_koch_e$(EXE) wm_koch_d$(EXE) cmp_koch_sig$(EXE) $(INSTALLDIR) + +kochclean: + $(RM) gen_koch_sig$(EXE) wm_koch_e$(EXE) wm_koch_d$(EXE) cmp_koch_sig$(EXE) + +kochman: + +wm_koch_e$(EXE): wm_koch_e$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_koch_e$(O) $(WMLIB) $(LIBS) $(PGMLIBS) + +wm_koch_d$(EXE): wm_koch_d$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_koch_d$(O) $(WMLIB) $(LIBS) $(PGMLIBS) + +gen_koch_sig$(EXE): gen_koch_sig$(O) wm$(O) + $(CC) $(LDFLAGS) -o $@ gen_koch_sig$(O) wm$(O) $(LIBS) + +cmp_koch_sig$(EXE): cmp_koch_sig$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ cmp_koch_sig$(O) $(WMLIB) $(LIBS) + +# Fridrich's 2. scheme (full-frame DCT, blind, binary) + +frid2: gen_frid2_sig$(EXE) wm_frid2_e$(EXE) wm_frid2_d$(EXE) cmp_frid2_sig$(EXE) + +frid2test: frid2 + gen_frid2_sig$(EXE) -n 250 < gen_frid2_sig.c > ../sigs/frid2.sig + wm_frid2_e$(EXE) -s ../sigs/frid2.sig -o ../watermarked/frid2_lena.pgm ../images/lena.pgm + wm_frid2_d$(EXE) -s ../sigs/frid2.sig -o ../wms/frid2.wm ../watermarked/frid2_lena.pgm + cmp_frid2_sig$(EXE) -s ../sigs/frid2.sig ../wms/frid2.wm + +frid2install: frid2 + $(CP) gen_frid2_sig$(EXE) wm_frid2_e$(EXE) wm_frid2_d$(EXE) cmp_frid2_sig$(EXE) $(INSTALLDIR) + +frid2clean: + $(RM) gen_frid2_sig$(EXE) wm_frid2_e$(EXE) wm_frid2_d$(EXE) cmp_frid2_sig$(EXE) + +frid2man: + +wm_frid2_e$(EXE): wm_frid2_e$(O) $(LIBPREFIX)wm$(LIB) frid2_common$(O) + $(CC) $(LDFLAGS) -o $@ wm_frid2_e$(O) frid2_common$(O) $(WMLIB) $(LIBS) $(PGMLIBS) + +wm_frid2_d$(EXE): wm_frid2_d$(O) $(LIBPREFIX)wm$(LIB) frid2_common$(O) + $(CC) $(LDFLAGS) -o $@ wm_frid2_d$(O) frid2_common$(O) $(WMLIB) $(LIBS) $(PGMLIBS) + +gen_frid2_sig$(EXE): gen_frid2_sig$(O) wm$(O) + $(CC) $(LDFLAGS) -o $@ gen_frid2_sig$(O) wm$(O) $(LIBS) + +cmp_frid2_sig$(EXE): cmp_frid2_sig$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ cmp_frid2_sig$(O) $(WMLIB) $(LIBS) + + +# Bruyndonckx's algorithm (spatial domain, block classification, blind) + +bruyn: gen_bruyn_sig$(EXE) wm_bruyn_e$(EXE) wm_bruyn_d$(EXE) cmp_bruyn_sig$(EXE) + +bruyntest: bruyn + gen_bruyn_sig$(EXE) -n 400 < gen_bruyn_sig.c > ../sigs/bruyn.sig + wm_bruyn_e$(EXE) -s ../sigs/bruyn.sig -o ../watermarked/bruyn_lena.pgm ../images/lena.pgm + wm_bruyn_d$(EXE) -s ../sigs/bruyn.sig -o ../wms/bruyn.wm ../watermarked/bruyn_lena.pgm + cmp_bruyn_sig$(EXE) -s ../sigs/bruyn.sig ../wms/bruyn.wm + +bruyninstall: bruyn + $(CP) gen_bruyn_sig$(EXE) wm_bruyn_e$(EXE) wm_bruyn_d$(EXE) cmp_bruyn_sig$(EXE) $(INSTALLDIR) + +bruynclean: + $(RM) gen_bruyn_sig$(EXE) wm_bruyn_e$(EXE) wm_bruyn_d$(EXE) cmp_bruyn_sig$(EXE) + +bruynman: + +wm_bruyn_e$(EXE): wm_bruyn_e$(O) bruyn_common$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_bruyn_e$(O) bruyn_common$(O) $(WMLIB) $(LIBS) $(PGMLIBS) + +wm_bruyn_d$(EXE): wm_bruyn_d$(O) bruyn_common$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_bruyn_d$(O) bruyn_common$(O) $(WMLIB) $(LIBS) $(PGMLIBS) + +gen_bruyn_sig$(EXE): gen_bruyn_sig$(O) wm$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ gen_bruyn_sig$(O) wm$(O) $(WMLIB) + +cmp_bruyn_sig$(EXE): cmp_bruyn_sig$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ cmp_bruyn_sig$(O) $(WMLIB) $(LIBS) + + +# Cox's algorithm (full-frame DCT, non-blind, spread-spectrum) + +cox: gen_cox_sig$(EXE) wm_cox_e$(EXE) wm_cox_d$(EXE) cmp_cox_sig$(EXE) + +coxtest: cox + gen_cox_sig$(EXE) > ../sigs/cox.sig + wm_cox_e$(EXE) -s ../sigs/cox.sig -o ../watermarked/cox_lena.pgm ../images/lena.pgm + wm_cox_d$(EXE) -s ../sigs/cox.sig -o ../wms/cox.wm -i ../images/lena.pgm ../watermarked/cox_lena.pgm + cmp_cox_sig$(EXE) -s ../sigs/cox.sig ../wms/cox.wm + +coxinstall: cox + $(CP) gen_cox_sig$(EXE) wm_cox_e$(EXE) wm_cox_d$(EXE) cmp_cox_sig$(EXE) $(INSTALLDIR) + +coxman: gen_cox_sig.ps wm_cox_e.ps wm_cox_d.ps + +wm_cox_e$(EXE): wm_cox_e$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_cox_e$(O) $(WMLIB) $(LIBS) $(PGMLIBS) + +wm_cox_d$(EXE): wm_cox_d$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_cox_d$(O) $(WMLIB) $(LIBS) $(PGMLIBS) + +gen_cox_sig$(EXE): gen_cox_sig$(O) + $(CC) $(LDFLAGS) -o $@ gen_cox_sig$(O) $(LIBS) + +cmp_cox_sig$(EXE): cmp_cox_sig$(O) + $(CC) $(LDFLAGS) -o $@ cmp_cox_sig$(O) $(LIBS) + +coxclean: + $(RM) gen_cox_sig$(EXE) wm_cox_e$(EXE) wm_cox_d$(EXE) cmp_cox_sig$(EXE) + + +# Corvi's algorithm (DWT, non-blind, spread-spectrum, approximation image) + +corvi: gen_corvi_sig$(EXE) wm_corvi_e$(EXE) wm_corvi_d$(EXE) cmp_corvi_sig$(EXE) + +corvitest: corvi + gen_corvi_sig$(EXE) > ../sigs/corvi.sig + wm_corvi_e$(EXE) -s ../sigs/corvi.sig -o ../watermarked/corvi_lena.pgm ../images/lena.pgm + wm_corvi_d$(EXE) -s ../sigs/corvi.sig -o ../wms/corvi.wm -i ../images/lena.pgm ../watermarked/corvi_lena.pgm + cmp_corvi_sig$(EXE) -s ../sigs/corvi.sig ../wms/corvi.wm + +corviinstall: corvi + $(CP) gen_corvi_sig$(EXE) wm_corvi_e$(EXE) wm_corvi_d$(EXE) cmp_corvi_sig$(EXE) $(INSTALLDIR) + +corviman: gen_corvi_sig.ps wm_corvi_e.ps wm_corvi_d.ps + +wm_corvi_e$(EXE): wm_corvi_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_corvi_e$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +wm_corvi_d$(EXE): wm_corvi_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_corvi_d$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +gen_corvi_sig$(EXE): gen_corvi_sig$(O) + $(CC) $(LDFLAGS) -o $@ gen_corvi_sig$(O) $(LIBS) + +cmp_corvi_sig$(EXE): cmp_corvi_sig$(O) + $(CC) $(LDFLAGS) -o $@ cmp_corvi_sig$(O) $(LIBS) + +corviclean: + $(RM) gen_corvi_sig$(EXE) wm_corvi_e$(EXE) wm_corvi_d$(EXE) cmp_corvi_sig$(EXE) + + +# Xia's algorithm (DWT, non-blind, spread-spectrum, detail subbands) + +xia: gen_xia_sig$(EXE) wm_xia_e$(EXE) wm_xia_d$(EXE) cmp_xia_sig$(EXE) + +xiatest: xia + gen_xia_sig$(EXE) > ../sigs/xia.sig + wm_xia_e$(EXE) -s ../sigs/xia.sig -o ../watermarked/xia_lena.pgm ../images/lena.pgm + wm_xia_d$(EXE) -s ../sigs/xia.sig -o ../wms/xia.wm -i ../images/lena.pgm ../watermarked/xia_lena.pgm + cmp_xia_sig$(EXE) -s ../sigs/xia.sig ../wms/xia.wm + +xiainstall: xia + $(CP) gen_xia_sig$(EXE) wm_xia_e$(EXE) wm_xia_d$(EXE) cmp_xia_sig$(EXE) $(INSTALLDIR) + +xiaman: gen_xia_sig.ps wm_xia_e.ps wm_xia_d.ps + +wm_xia_e$(EXE): wm_xia_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_xia_e$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +wm_xia_d$(EXE): wm_xia_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_xia_d$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +gen_xia_sig$(EXE): gen_xia_sig$(O) + $(CC) $(LDFLAGS) -o $@ gen_xia_sig$(O) $(LIBS) + +cmp_xia_sig$(EXE): cmp_xia_sig$(O) + $(CC) $(LDFLAGS) -o $@ cmp_xia_sig$(O) $(LIBS) + +xiaclean: + $(RM) gen_xia_sig$(EXE) wm_xia_e$(EXE) wm_xia_d$(EXE) cmp_xia_sig$(EXE) + +# Wang's algorithm (DWT, non-blind, spread-spectrum, detail subbands) + +wang: gen_wang_sig$(EXE) wm_wang_e$(EXE) wm_wang_d$(EXE) cmp_wang_sig$(EXE) + +wangtest: wang + gen_wang_sig$(EXE) -n 1000 > ../sigs/wang.sig + wm_wang_e$(EXE) -s ../sigs/wang.sig -o ../watermarked/wang_lena.pgm ../images/lena.pgm + wm_wang_d$(EXE) -s ../sigs/wang.sig -o ../wms/wang.wm -i ../images/lena.pgm ../watermarked/wang_lena.pgm + cmp_wang_sig$(EXE) -s ../sigs/wang.sig ../wms/wang.wm + +wanginstall: wang + $(CP) gen_wang_sig$(EXE) wm_wang_e$(EXE) wm_wang_d$(EXE) cmp_wang_sig$(EXE) $(INSTALLDIR) + +wangman: gen_wang_sig.ps wm_wang_e.ps wm_wang_d.ps + +wm_wang_e$(EXE): wm_wang_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) wang_common$(O) + $(CC) $(LDFLAGS) -o $@ wm_wang_e$(O) wang_common$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +wm_wang_d$(EXE): wm_wang_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) wang_common$(O) + $(CC) $(LDFLAGS) -o $@ wm_wang_d$(O) wang_common$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +gen_wang_sig$(EXE): gen_wang_sig$(O) + $(CC) $(LDFLAGS) -o $@ gen_wang_sig$(O) $(LIBS) + +cmp_wang_sig$(EXE): cmp_wang_sig$(O) + $(CC) $(LDFLAGS) -o $@ cmp_wang_sig$(O) $(LIBS) + +wangclean: + $(RM) gen_wang_sig$(EXE) wm_wang_e$(EXE) wm_wang_d$(EXE) cmp_wang_sig$(EXE) + +# Kim's algorithm (DWT, non-blind, spread-spectrum, approx. & detail subbands) + +kim: gen_kim_sig$(EXE) wm_kim_e$(EXE) wm_kim_d$(EXE) cmp_kim_sig$(EXE) + +kimtest: kim + gen_kim_sig$(EXE) -n 1000 > ../sigs/kim.sig + wm_kim_e$(EXE) -s ../sigs/kim.sig -o ../watermarked/kim_lena.pgm ../images/lena.pgm + wm_kim_d$(EXE) -s ../sigs/kim.sig -o ../wms/kim.wm -i ../images/lena.pgm ../watermarked/kim_lena.pgm + cmp_kim_sig$(EXE) -s ../sigs/kim.sig ../wms/kim.wm + +kiminstall: kim + $(CP) gen_kim_sig$(EXE) wm_kim_e$(EXE) wm_kim_d$(EXE) cmp_kim_sig$(EXE) $(INSTALLDIR) + +kimman: gen_kim_sig.ps wm_kim_e.ps wm_kim_d.ps + +wm_kim_e$(EXE): wm_kim_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) kim_common$(O) + $(CC) $(LDFLAGS) -o $@ wm_kim_e$(O) kim_common$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +wm_kim_d$(EXE): wm_kim_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) kim_common$(O) + $(CC) $(LDFLAGS) -o $@ wm_kim_d$(O) kim_common$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +gen_kim_sig$(EXE): gen_kim_sig$(O) + $(CC) $(LDFLAGS) -o $@ gen_kim_sig$(O) $(LIBS) + +cmp_kim_sig$(EXE): cmp_kim_sig$(O) + $(CC) $(LDFLAGS) -o $@ cmp_kim_sig$(O) $(LIBS) + +kimclean: + $(RM) gen_kim_sig$(EXE) wm_kim_e$(EXE) wm_kim_d$(EXE) cmp_kim_sig$(EXE) + +# Zhu's algorithm (DWT, non-blind, spread-spectrum, detail subbands) + +zhu: gen_zhu_sig$(EXE) wm_zhu_e$(EXE) wm_zhu_d$(EXE) cmp_zhu_sig$(EXE) + +zhutest: zhu + gen_zhu_sig$(EXE) > ../sigs/zhu.sig + wm_zhu_e$(EXE) -s ../sigs/zhu.sig -o ../watermarked/zhu_lena.pgm ../images/lena.pgm + wm_zhu_d$(EXE) -s ../sigs/zhu.sig -o ../wms/zhu.wm -i ../images/lena.pgm ../watermarked/zhu_lena.pgm + cmp_zhu_sig$(EXE) -s ../sigs/zhu.sig ../wms/zhu.wm + +zhuinstall: zhu + $(CP) gen_zhu_sig$(EXE) wm_zhu_e$(EXE) wm_zhu_d$(EXE) cmp_zhu_sig$(EXE) $(INSTALLDIR) + +zhuman: gen_zhu_sig.ps wm_zhu_e.ps wm_zhu_d.ps + +wm_zhu_e$(EXE): wm_zhu_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_zhu_e$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +wm_zhu_d$(EXE): wm_zhu_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_zhu_d$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +gen_zhu_sig$(EXE): gen_zhu_sig$(O) + $(CC) $(LDFLAGS) -o $@ gen_zhu_sig$(O) $(LIBS) + +cmp_zhu_sig$(EXE): cmp_zhu_sig$(O) + $(CC) $(LDFLAGS) -o $@ cmp_zhu_sig$(O) $(LIBS) + +zhuclean: + $(RM) gen_zhu_sig$(EXE) wm_zhu_e$(EXE) wm_zhu_d$(EXE) cmp_zhu_sig$(EXE) + +# Xie's algorithm (DWT, blind, binary, quantization, approximation image) + +xie: gen_xie_sig$(EXE) wm_xie_e$(EXE) wm_xie_d$(EXE) cmp_xie_sig$(EXE) + +xietest: xie + gen_xie_sig$(EXE) -n 800 gen_xie_sig.c > ../sigs/xie.sig + wm_xie_e$(EXE) -s ../sigs/xie.sig -o ../watermarked/xie_lena.pgm ../images/lena.pgm + wm_xie_d$(EXE) -s ../sigs/xie.sig -o ../wms/xie.wm ../watermarked/xie_lena.pgm + cmp_xie_sig$(EXE) -s ../sigs/xie.sig ../wms/xie.wm + +xieinstall: xie + $(CP) gen_xie_sig$(EXE) wm_xie_e$(EXE) wm_xie_d$(EXE) cmp_xie_sig$(EXE) $(INSTALLDIR) + +xieman: gen_xie_sig.ps wm_xie_e.ps wm_xie_d.ps + +wm_xie_e$(EXE): wm_xie_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_xie_e$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +wm_xie_d$(EXE): wm_xie_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_xie_d$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +gen_xie_sig$(EXE): gen_xie_sig$(O) wm$(O) + $(CC) $(LDFLAGS) -o $@ gen_xie_sig$(O) wm$(O) $(LIBS) + +cmp_xie_sig$(EXE): cmp_xie_sig$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ cmp_xie_sig$(O) $(WMLIB) $(LIBS) + +xieclean: + $(RM) gen_xie_sig$(EXE) wm_xie_e$(EXE) wm_xie_d$(EXE) cmp_xie_sig$(EXE) + +# Xie2's algorithm (DWT, blind, binary, quantization, approximation image) + +xie2: gen_xie2_sig$(EXE) wm_xie2_e$(EXE) wm_xie2_d$(EXE) cmp_xie2_sig$(EXE) + +xie2test: xie2 + gen_xie2_sig$(EXE) -n 800 gen_xie2_sig.c > ../sigs/xie2.sig + wm_xie2_e$(EXE) -s ../sigs/xie2.sig -o ../watermarked/xie2_lena.pgm ../images/lena.pgm + wm_xie2_d$(EXE) -s ../sigs/xie2.sig -o ../wms/xie2.wm ../watermarked/xie2_lena.pgm + cmp_xie2_sig$(EXE) -s ../sigs/xie2.sig ../wms/xie2.wm + +xie2install: xie2 + $(CP) gen_xie2_sig$(EXE) wm_xie2_e$(EXE) wm_xie2_d$(EXE) cmp_xie2_sig$(EXE) $(INSTALLDIR) + +xie2man: gen_xie2_sig.ps wm_xie2_e.ps wm_xie2_d.ps + +wm_xie2_e$(EXE): wm_xie2_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_xie2_e$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +wm_xie2_d$(EXE): wm_xie2_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_xie2_d$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +gen_xie2_sig$(EXE): gen_xie2_sig$(O) wm$(O) + $(CC) $(LDFLAGS) -o $@ gen_xie2_sig$(O) wm$(O) $(LIBS) + +cmp_xie2_sig$(EXE): cmp_xie2_sig$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ cmp_xie2_sig$(O) $(WMLIB) $(LIBS) + +xie2clean: + $(RM) gen_xie2_sig$(EXE) wm_xie2_e$(EXE) wm_xie2_d$(EXE) cmp_xie2_sig$(EXE) + +# Kundur's algorithm 2 (DWT, blind, binary, quantization, detail subbands, reference watermark) + +kund2: gen_kund2_sig$(EXE) wm_kund2_e$(EXE) wm_kund2_d$(EXE) cmp_kund2_sig$(EXE) + +kund2test: kund2 + gen_kund2_sig$(EXE) -n 1000 -l 3 -q 2 gen_kund2_sig.c > ../sigs/kund2.sig + wm_kund2_e$(EXE) -s ../sigs/kund2.sig -o ../watermarked/kund2_lena.pgm ../images/lena.pgm + cjpeg -quality 70 ../watermarked/kund2_lena.pgm | djpeg | wm_kund2_d$(EXE) -s ../sigs/kund2.sig -o ../wms/kund2.wm + cmp_kund2_sig$(EXE) -s ../sigs/kund2.sig ../wms/kund2.wm + +kund2install: kund2 + $(CP) gen_kund2_sig$(EXE) wm_kund2_e$(EXE) wm_kund2_d$(EXE) cmp_kund2_sig$(EXE) $(INSTALLDIR) + +kund2man: gen_kund2_sig.ps wm_kund2_e.ps wm_kund2_d.ps + +wm_kund2_e$(EXE): wm_kund2_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_kund2_e$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +wm_kund2_d$(EXE): wm_kund2_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_kund2_d$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +gen_kund2_sig$(EXE): gen_kund2_sig$(O) wm$(O) signature-utils$(O) + $(CC) $(LDFLAGS) -o $@ gen_kund2_sig$(O) wm$(O) signature-utils$(O) $(LIBS) + +cmp_kund2_sig$(EXE): cmp_kund2_sig$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ cmp_kund2_sig$(O) $(WMLIB) $(LIBS) + +kund2clean: + $(RM) gen_kund2_sig$(EXE) wm_kund2_e$(EXE) wm_kund2_d$(EXE) cmp_kund2_sig$(EXE) + +# Kundur's algorithm 3 (DWT, blind, binary, quantization, detail subbands) + +kund3: gen_kund3_sig$(EXE) wm_kund3_e$(EXE) wm_kund3_d$(EXE) cmp_kund3_sig$(EXE) + +kund3test: kund3 + gen_kund3_sig$(EXE) -n 1000 -l 2 -q 2 gen_kund3_sig.c > ../sigs/kund3.sig + wm_kund3_e$(EXE) -s ../sigs/kund3.sig -o ../watermarked/kund3_lena.pgm ../images/lena.pgm + wm_kund3_d$(EXE) -s ../sigs/kund3.sig -o ../wms/kund3.wm ../watermarked/kund3_lena.pgm + cmp_kund3_sig$(EXE) -s ../sigs/kund3.sig ../wms/kund3.wm + +kund3install: kund3 + $(CP) gen_kund3_sig$(EXE) wm_kund3_e$(EXE) wm_kund3_d$(EXE) cmp_kund3_sig$(EXE) $(INSTALLDIR) + +kund3man: gen_kund3_sig.ps wm_kund3_e.ps wm_kund3_d.ps + +wm_kund3_e$(EXE): wm_kund3_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_kund3_e$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +wm_kund3_d$(EXE): wm_kund3_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_kund3_d$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +gen_kund3_sig$(EXE): gen_kund3_sig$(O) wm$(O) signature-utils$(O) + $(CC) $(LDFLAGS) -o $@ gen_kund3_sig$(O) wm$(O) signature-utils$(O) $(LIBS) + +cmp_kund3_sig$(EXE): cmp_kund3_sig$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ cmp_kund3_sig$(O) $(WMLIB) $(LIBS) + +kund3clean: + $(RM) gen_kund3_sig$(EXE) wm_kund3_e$(EXE) wm_kund3_d$(EXE) cmp_kund3_sig$(EXE) + +# Dugad's algorithm (DWT, blind) + +dugad: gen_dugad_sig$(EXE) wm_dugad_e$(EXE) wm_dugad_d$(EXE) cmp_dugad_sig$(EXE) + +dugadtest: dugad + gen_dugad_sig$(EXE) -o ../sigs/dugad.sig + wm_dugad_e$(EXE) -s ../sigs/dugad.sig -o ../watermarked/dugad_lena.pgm ../images/lena.pgm + wm_dugad_d$(EXE) -s ../sigs/dugad.sig -o ../wms/dugad.wm ../watermarked/dugad_lena.pgm + cmp_dugad_sig$(EXE) -s ../sigs/dugad.sig ../wms/dugad.wm + +dugadinstall: dugad + $(CP) gen_dugad_sig$(EXE) wm_dugad_e$(EXE) wm_dugad_d$(EXE) cmp_dugad_sig$(EXE) $(INSTALLDIR) + +dugadman: gen_dugad_sig.ps wm_dugad_e.ps wm_dugad_d.ps + +wm_dugad_e$(EXE): wm_dugad_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_dugad_e$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +wm_dugad_d$(EXE): wm_dugad_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) + $(CC) $(LDFLAGS) -o $@ wm_dugad_d$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) + +gen_dugad_sig$(EXE): gen_dugad_sig$(O) + $(CC) $(LDFLAGS) -o $@ gen_dugad_sig$(O) $(LIBS) + +cmp_dugad_sig$(EXE): cmp_dugad_sig$(O) $(LIBPREFIX)wm$(LIB) + $(CC) $(LDFLAGS) -o $@ cmp_dugad_sig$(O) $(WMLIB) $(LIBS) + +dugadclean: + $(RM) gen_dugad_sig$(EXE) wm_dugad_e$(EXE) wm_dugad_d$(EXE) cmp_dugad_sig$(EXE) + + + +clean: coxclean bruynclean kochclean corviclean xiaclean zhuclean xieclean kund3clean kund2clean \ + dugadclean kimclean wangclean frid2clean toolsclean libraryclean waveletclean xie2clean + $(RM) *$(O) *.ps ../sigs/* ../wms/* ../watermarked/* + +man: coxman bruynman kochman corviman xiaman xieman toolsman + +test: coxtest bruyntest kochtest corvitest xiatest xietest dugadtest zhutest \ + wangtest frid2test kimtest toolstest kund3test kund2test + +install: coxinstall bruyninstall kochinstall corviinstall xiainstall xieinstall \ + dugadinstall zhuinstall wanginstall frid2install kiminstall toolsinstall kund3install kund2install + +depend: + $(MAKEDEP) *.h *.c + diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/README Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,157 @@ +This package provides source code for some watermarking algorithms in portable +C code. Currently it includes the following + + watermarking algorithms + + Bruyndonckx + refer to + O. Bruyndonckx, Jean-Jacques Quisquater, and Benoit M. Macq. + Spatial method for copyright labeling of digital images. + In IEEE Workshop on Nonlinear Signal and Image Processing '95, + Thessaloniki, Greece, pages 456 - 459, 1995. + + Corvi + refer to + Marco Corvi and Gianluca Nicchiotti. + Wavelet-based image watermarking for copyright protection. + In Scandinavian Conference on Image Analysis SCIA '97, Lappeenranta, + Finland, June 1997. + + Cox + refer to + Ingemar J. Cox, Joe Kilian, Tom Leighton, and Talal G. Shamoon. + Secure spread spectrum watermarking for multimedia. + In Proceedings of the IEEE ICIP '97, + volume 6, pages 1673 - 1687, Santa Barbara, California, USA, 1997. + + Dugad + refer to + Rakesh Dugad, Krishna Ratakonda, and Narendra Ahuja. + A new wavelet-based scheme for watermarking images. In Proceedings of + the IEEE International Conference on Image Processing, ICIP '98, + Chicago, IL, USA, October 1998. + + Fridrich (2. scheme) + refer to + Jiri Fridrich. + Combining low-frequency and spread spectrum watermarking. In + Proceedings of the SPIE Symposium on Optical Science, Engineering and + Instrumentation, San Diego, USA, July 1998. + + Koch + refer to + Eckhard Koch and Jian Zhao. + Towards robust and hidden image copyright labeling. + In Proceedings of the IEEE International Workshop on Nonlinear + Signal and Image Processing, pages 452 - 455, Halkidiki, Marmaras, + Greece, June 1995. + + Kim + refer to + Jong Ryul Kim and Young Shik Moon. + A robust wavelet-based digital watermark using level-adaptive + thresholding. In Proceedings of the 6th IEEE International + Conference on Image Processing ICIP '99, page 202, + Kobe, Japan, October 1999. + + Wang + refer to + Houng-Jyh Wang, Po-Chyi Su, and C.-C. Jay Kuo. + Wavelet-based digital image watermarking. Optics Express, 3 + pp. 497, December 1998. + + Xia + refer to + Xiang-Gen Xia, Charles G. Boncelet, and Gonzalo R. Arce. + Wavelet transform based watermark for digital images. Optics Express, 3 + pp. 497, December 1998. + + Xie + refer to + Liehua Xie and Gonzalo R. Arce. + Joint wavelet compression and authentication watermarking. In + Proceedings of the IEEE International Conference on Image Processing, + ICIP '98, Chicago, IL, USA, 1998. + + Zhu + refer to + Wenwu Zhu, Zixiang Xiong, and Ya-Qin Zhang. + Multiresolution watermarking for images and video: a unified approach. + In Proceedings of the IEEE International Conference o + + many more algorithms to come! + see what is in stock: http://www.cosy.sbg.ac.at/~pmeerw/Watermarking + + and utility programs + + cmp_pgm - compute difference image, PSNR, ... + cmp_dct - compute full-frame DCT domain difference image + cmp_dct8x8 - compute 8x8 block-based DCT difference image + cmp_dwt - compute DWT domain difference image + +What do I need? + +Unix (Linux), a reasonable C compiler (GCC), and the netpbm library which you +can get at http://wuarchive.wustl.edu/graphics/graphics/packages/NetPBM/ + + +Directions: How do I use the stuff? + +look at the MAKEFILE... +each algorithms has at least 4 files: gen_algo_sig.c, wm_algo_e.c, wm_algo_d.c, +cmp_algo_sig.c where 'algo' is the name of the actual watermarking algorithm +(usually the principal author's name), where might also be some common files +for each algorithm, algo_common.{c|h}, and some support files for sorting, +the DCT, ... + +just try + + make + make test + +next, try to run each program with the -h parameter to find out what options +are supported - the programs are pretty consistent and have reasonable +default settings + +e.g. + + wm_cox_e -h + +The programs all support standard input and standard output, the only +supported image file format is PGM for grayscale images and PPM for color +images; most programs have only been tested with 512x512 images. +You can find the Lena image in PGM format in the images/ sub-directory. + + +Disclaimer: #include + +Feel free to use the accompaigning code for your research! However, I do +not guarantee for anything, in particular parts of the provided code may +be covered by copyrights of a third party or by patent claims. I do not +guarantee for any functionality, bla-bla, ... + +If you use the accompanying code, please cite my thesis: + + Peter Meerwald, Digital Image Watermarking in the Wavelet Transform Domain, + Master's Thesis, Department of Scientific Computing, University of Salzburg, + Austria, January 2001. + + +Contact: Comments are welcome! + +More algorithms will be added over time, I have implemented about 13 +watermarking algorithms in the spatial-, DCT-, and wavelet domain so far. +Please report what problems you have, suggestions, ... + +Peter Meerwald + +Dept. of Scientific Computing +University of Salzburg +Jakob-Haringer-Str. 2 +A-5020 Salzburg +AUSTRIA + +pmeerw@cosy.sbg.ac.at +http://www.cosy.sbg.ac.at/~pmeerw/Watermarking + ++43-662-8044-6327 diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/bruyn_common.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/bruyn_common.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,44 @@ +#include "bruyn_common.h" + +gray lookup_pattern(int pattern, int c, int r) { +#define A CATEGORY_A +#define B CATEGORY_B + + gray pattern1[4][4] = + {{A, A, B, B}, + {A, A, B, B}, + {B, B, A, A}, + {B, B, A, A}}; + + gray pattern2[8][8] = + {{B, B, B, B, A, A, A, A}, + {B, B, B, B, A, A, A, A}, + {B, B, B, B, A, A, A, A}, + {B, B, B, B, A, A, A, A}, + {A, A, A, A, B, B, B, B}, + {A, A, A, A, B, B, B, B}, + {A, A, A, A, B, B, B, B}, + {A, A, A, A, B, B, B, B}}; + + gray pattern3[2][2] = + {{A, B}, {B, A}}; + +#undef A +#undef B + + switch (pattern) { + case 1: + return pattern1[r % 4][c % 4]; + break; + case 2: + return pattern2[r % 8][c % 8]; + break; + case 3: + return pattern3[r % 2][c % 2]; + break; + } + + return CATEGORY_VOID; +} + + diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/bruyn_common.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/bruyn_common.h Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,41 @@ +#ifndef BRUYN_COMMON_H +#define BRUYN_COMMON_H + +#include "netpbm/pgm.h" + +// for block type classification +#define BLOCKTYPE_UNKNOWN 0 +#define BLOCKTYPE_HARD 1 +#define BLOCKTYPE_PROGRESSIVE 2 +#define BLOCKTYPE_NOISE 3 + +// thresholds +#define THRESHOLD_NOISE 10.0 +#define THRESHOLD_SLOPE 5.0 +#define THRESHOLD_NOISE_USAGE "10.0" +#define THRESHOLD_SLOPE_USAGE "5.0" + +// zone classification +#define ZONE_VOID 0 +#define ZONE_1 1 +#define ZONE_2 2 + +// category classification +#define CATEGORY_VOID 0 +#define CATEGORY_A 4 +#define CATEGORY_B 8 + +// classifiction = zone | category +#define CLASSIFICATION_1A (ZONE_1 | CATEGORY_A) +#define CLASSIFICATION_1B (ZONE_1 | CATEGORY_B) +#define CLASSIFICATION_2A (ZONE_2 | CATEGORY_A) +#define CLASSIFICATION_2B (ZONE_2 | CATEGORY_B) +#define CLASSIFICATION_A CATEGORY_A +#define CLASSIFICATION_B CATEGORY_B + +#define NPATTERN 3 +#define NPATTERN_USAGE "3" + +gray lookup_pattern(int pattern, int c, int r); + +#endif /* BRUYN_COMMON_H */ diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_bruyn_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_bruyn_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,151 @@ +#include "wm.h" +#include "signature.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-C\t\toutput correlation only\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + + int c, i; + int pattern1, pattern2; + double quality; + double threshold1, threshold2; + int blocksize; + int corr = 0, match = 0; + int verbose = 0; + int skipping = 0; + + int correlation_only = 0; + + int seed; + char line[32]; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'C': + correlation_only = 1; + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "r")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + fgets(line, sizeof(line), sig); + if (strspn(line, "BRSG") >= 4) { + fscanf(sig, "%d\n", &nbit_signature1); + fscanf(sig, "%d\n", &skipping); + fscanf(sig, "%d\n", &pattern1); + fscanf(sig, "%d\n", &pattern2); + fscanf(sig, "%lf\n", &quality); + fscanf(sig, "%lf\n", &threshold1); + fscanf(sig, "%lf\n", &threshold2); + fscanf(sig, "%d\n", &blocksize); + fscanf(sig, "%d\n", &seed); + srandom(seed); + n_signature1 = NBITSTOBYTES(nbit_signature1); + fread(signature1, sizeof(char), n_signature1, sig); + fscanf(sig, "\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); + exit(1); + } + + fgets(line, sizeof(line), in); + if (strspn(line, "BRWM") >= 4) { + fscanf(in, "%d\n", &nbit_signature2); + n_signature2 = NBITSTOBYTES(nbit_signature2); + fread(signature2, sizeof(char), n_signature2, in); + fscanf(in, "\n"); + } + else { + fprintf(stderr, "%s: invalid watermark file %s\n", progname, input_name); + exit(1); + } + + if (verbose > 0) { + fprintf(stderr, "signature length: %d\n", nbit_signature1); + fprintf(stderr, "watermark length: %d\n", nbit_signature2); + } + + for (i = 0; i < nbit_signature2; i++) + if (get_signature1_bit(i % nbit_signature1) == get_signature2_bit(i)) + corr++, match++; + else + corr--; + + if (correlation_only) + fprintf(out, "%lf\n", (double) corr / nbit_signature2); + else { + fprintf(out, "bit matches: %d/%d\n", match, nbit_signature2); + fprintf(out, "correlation: %lf\n", (double) corr / nbit_signature2); + } + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_corvi_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_corvi_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,160 @@ +#include "wm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-C\t\toutput correlation only\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + + int c; + int sig_n, in_n; + double s1, s2, s3; + char line[32]; + int matches; + + int verbose = 0; + int correlation_only = 0; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "h?o:s:v:C")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + case 'C': + correlation_only = 1; + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "r")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (!sig) { + fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); + exit(1); + } + + fgets(line, sizeof(line), sig); + if (strspn(line, "CVSG") < 4) { + fprintf(stderr, "%s: original signature file %s invalid\n", progname, signature_name); + exit(1); + } + + fgets(line, sizeof(line), in); + if (strspn(line, "CVWM") < 4) { + fprintf(stderr, "%s: signature file %s invalid\n", progname, input_name); + exit(1); + } + + fscanf(sig, "%d\n", &sig_n); + fscanf(in, "%d\n", &in_n); + if (sig_n != in_n) { + fprintf(stderr, "%s: watermark length mismatch (original %d, input %d)\n", progname, sig_n, in_n); + exit(1); + } + if (sig_n <= 0 || sig_n > 1000) { + fprintf(stderr, "%s: invalid original watermark length %d\n", progname, sig_n); + exit(1); + } + if (in_n <= 0 || in_n > 1000) { + fprintf(stderr, "%s: invalid watermark length %d\n", progname, in_n); + exit(1); + } + + fscanf(sig, "%*f\n"); + fscanf(sig, "%*d\n"); + fscanf(sig, "%*d\n"); + fscanf(sig, "%*[^\n\r]\n"); + + /* + * normalized correlation + * Craver, S., "Can Invisible Watermarks Resolve Rightful Ownership?", IBM Research Report, 1996, p. 5 + */ + + s1 = s2 = s3 = 0.0; + matches = 0; + while (in_n > 0) { + double sig_x, in_x; + + fscanf(sig, "%lf\n", &sig_x); + fscanf(in, "%lf\n", &in_x); + + matches += SIGN(sig_x * in_x); + + if (verbose >= 1) { + fprintf(stderr, "orig %f input %f\n", sig_x, in_x); + } + + s1 += sig_x * in_x; + s2 += in_x * in_x; + s3 += sig_x * sig_x; + + in_n--; + } + + if (!correlation_only) { + fprintf(out, "%s: correlation %f, hamming distance %f\n", progname, s1 / sqrt(s2 * s3), (double) matches / sig_n); + } + else + fprintf(out, "%f\n", (double) matches / sig_n); + + fclose(sig); + fclose(out); + fclose(in); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_cox_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_cox_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,149 @@ +#include "wm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-h] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + + int c; + int sig_n, in_n; + double sig_a; + double sig_mean, sig_variance; + double s1, s2, s3; + char line[32]; + + int verbose = 0; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "h?o:s:v:")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "r")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (!sig) { + fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); + exit(1); + } + + fgets(line, sizeof(line), sig); + if (strspn(line, "CXSG") < 4) { + fprintf(stderr, "%s: original signature file %s invalid\n", progname, signature_name); + exit(1); + } + + fgets(line, sizeof(line), in); + if (strspn(line, "CXWM") < 4) { + fprintf(stderr, "%s: watermark file %s invalid\n", progname, input_name); + exit(1); + } + + fscanf(sig, "%d\n", &sig_n); + fscanf(in, "%d\n", &in_n); + if (sig_n != in_n) { + fprintf(stderr, "%s: watermark length mismatch (original %d, input %d)\n", progname, sig_n, in_n); + exit(1); + } + if (sig_n <= 0 || sig_n > 32000) { + fprintf(stderr, "%s: invalid original watermark length %d\n", progname, sig_n); + exit(1); + } + if (in_n <= 0 || in_n > 32000) { + fprintf(stderr, "%s: invalid watermark length %d\n", progname, in_n); + exit(1); + } + + fscanf(sig, "%lf\n", &sig_a); + + fscanf(sig, "%lf\n", &sig_mean); + fscanf(sig, "%lf\n", &sig_variance); + + /* + * normalized correlation + * Craver, S., "Can Invisible Watermarks Resolve Rightful Ownership?", IBM Research Report, 1996, p. 5 + */ + + s1 = s2 = s3 = 0.0; + while (in_n > 0) { + double sig_x, in_x; + + fscanf(sig, "%lf\n", &sig_x); + fscanf(in, "%lf\n", &in_x); + + if (verbose >= 1) { + fprintf(stderr, "orig %f input %f\n", sig_x, in_x); + } + + s1 += sig_x * in_x; + s2 += in_x * in_x; + s3 += sig_x * sig_x; + + in_n--; + } + + fprintf(out, "%f\n", s1 / sqrt(s2 * s3)); + + fclose(sig); + fclose(out); + fclose(in); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_dct.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_dct.1 Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,79 @@ +.\" +.\" cmp_dct.1 - the *roff document processor man page source +.\" +.TH cmp_dct 1 "98/07/08" "Watermarking, Version 1.0" +.SH NAME +cmp_dct \- a program to create the difference image of the +frequency domain of two PGM images +.SH SYNOPSIS +.B cmp_dct +[ +.B \-h +] +[ +.BI \-m \ number +] +[ +.BI \-o \ ofile +] +.BI \-i \ ifile +.I file +.SH DESCRIPTION +.B cmp_dct +is a program to create the difference image of the +frequency domain of two PGM (portable graymap) grayscale +images. To compare images in the spatial domain, either in +PPM (portable pixmap) format for RGB color images or in PGM (portable +graymap) format for grayscale images, use the +.B cmp_ppm +program or the +.B cmp_pgm +program, respectively. +.PP +If +.I file +or +.I ofile +is not specified, then standard input or standard output is +used. +.PP +.SH OPTIONS +.TP +.B \-h +Print a help message. +.TP +.BI \-i \ ifile +The original image. Mandatory. +.TP +.BI \-m \ number +Multiplication factor to magnify differences between the to +original and input image. +Default value: 16. +.TP +.BI \-o \ ofile +Output image file to contain the difference image in PGM format. +.TP +.I file +Input image that is compared against +.I ifile. +Default: standard input. +.SH OUTPUT +The difference image in PGM format is written to standard output or, +optionally, to +.I ofile. +.SH AUTHOR +Peter Meerwald. +Email bug reports to pmeerw@cosy.sbg.ac.at. +.SH AVAILABILITY +The most recent released version of +.B cmp_dct +is always available +at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the +directory /pub/people/pmeerw/Watermarking. +.SH "SEE ALSO" +.B cmp_pgm +(1), +.B cmp_ppm +(1), +.B cmp_dct8x8 +(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_dct.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_dct.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,198 @@ +#include "wm.h" +#include "dct.h" +#include "gray.h" +#include "netpbm/pgm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-h] [-m n] [-o file] [-pP] -i file file\n\n", progname); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-i file\t\toriginal image file\n"); + fprintf(stderr, "\t-m n\t\tmultiplication factor (default 16)\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-p\t\tprint PSNR, RMS and MSE\n"); + fprintf(stderr, "\t-P\t\tonly print PSNR, RMS and MSE, no difference image\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *orig = NULL; + + gray **input_image; + gray **orig_image; + double **input_dcts; + double **orig_dcts; + gray **output; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char orig_name[MAXPATHLEN]; + + int in_cols, in_rows, in_format; + gray in_maxval; + int orig_cols, orig_rows, orig_format; + gray orig_maxval; + int cols, rows, format; + gray maxval; + int col, row; + + int no_orig = 0; + int c; + + double error = 0.0; + int print_psnr = 0; + int print_psnr_only = 0; + int m = 16; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "h?i:m:o:pP")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'i': + if (!strcmp(optarg, "-")) { + no_orig = 1; + strcpy(orig_name, "(zero)"); + } + else { + if ((orig = fopen(optarg, "rb")) == NULL) { + fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); + exit(1); + } + strcpy(orig_name, optarg); + } + break; + case 'm': + m = atoi(optarg); + if (m <= 0) { + fprintf(stderr, "%s: multiplication factor %d out of range\n", progname, m); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'p': + print_psnr = 1; + break; + case 'P': + print_psnr_only = 1; + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (!orig && !no_orig) { + fprintf(stderr, "%s: original image file not specified, using zero image\n", progname); + strcpy(orig_name, "(zero)"); + no_orig = 1; + } + + pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); + + if (!no_orig) { + pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); + + if (in_cols != orig_cols || in_rows != orig_rows) { + fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); + exit(1); + } + } + + cols = in_cols; + rows = in_rows; + format = in_format; + maxval = in_maxval; + + input_image = pgm_allocarray(cols, rows); + orig_image = pgm_allocarray(cols, rows); + + init_dct_NxN(cols, rows); + input_dcts = alloc_coeffs(cols, rows); + orig_dcts = alloc_coeffs(cols, rows); + output = alloc_grays(cols, rows); + + if (no_orig) { + for (row = 0; row < rows; row++) { + pgm_readpgmrow(in, input_image[row], cols, maxval, format); + bzero(orig_image[row], sizeof(gray) * cols); + } + } + else { + for (row = 0; row < rows; row++) { + pgm_readpgmrow(in, input_image[row], cols, maxval, format); + pgm_readpgmrow(orig, orig_image[row], cols, maxval, format); + } + } + + fclose(in); + if (!no_orig) + fclose(orig); + + fdct_NxN(input_image, input_dcts); + fdct_NxN(orig_image, orig_dcts); + + for (row = 0; row < rows; row++) + for (col = 0; col < cols; col++) { + error += sqr(input_dcts[row][col] - orig_dcts[row][col]); + output[row][col] = PIXELRANGE(fabs(input_dcts[row][col] - orig_dcts[row][col]) * m); + } + + if (!print_psnr_only) { + pgm_writepgminit(out, cols, rows, maxval, 0); + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, output[row], cols, maxval, 0); + + fclose(out); + } + + pgm_freearray(input_image, rows); + pgm_freearray(orig_image, rows); + free_coeffs(input_dcts); + free_coeffs(orig_dcts); + free_grays(output); + + if (print_psnr || print_psnr_only) { + double mse = error / (double) (cols * rows); + double rmse = sqrt(mse); + double psnr = 20.0 * log(255.0 / rmse) / log(10.0); + FILE *print = print_psnr_only ? out : stderr; + if (mse > 0.0) + fprintf(print, "PSNR: %lf dB\n", psnr); + else + fprintf(print, "PSNR: inf\n"); + fprintf(print, "RMS: %lf\n", rmse); + fprintf(print, "MSE: %lf\n", mse); + } + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_dct8x8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_dct8x8.1 Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,79 @@ +.\" +.\" cmp_dct8x8.1 - the *roff document processor man page source +.\" +.TH cmp_dct8x8 1 "98/07/08" "Watermarking, Version 1.0" +.SH NAME +cmp_dct8x8 \- a program to create the difference image of the +8x8 DCT blocks of two PGM images +.SH SYNOPSIS +.B cmp_dct8x8 +[ +.B \-h +] +[ +.BI \-m \ number +] +[ +.BI \-o \ ofile +] +.BI \-i \ ifile +.I file +.SH DESCRIPTION +.B cmp_dct8x8 +is a program to create the difference image of the 8x8 DCT blocks +(frequency domain) of two PGM (portable graymap) grayscale +images. To compare images in the spatial domain, either in +PPM (portable pixmap) format for RGB color images or in PGM (portable +graymap) format for grayscale images, use the +.B cmp_ppm +program or the +.B cmp_pgm +program, respectively. +.PP +If +.I file +or +.I ofile +is not specified, then standard input or standard output is +used. +.PP +.SH OPTIONS +.TP +.B \-h +Print a help message. +.TP +.BI \-i \ ifile +The original image. Mandatory. +.TP +.BI \-m \ number +Multiplication factor to magnify differences between the to +original and input image. +Default value: 16. +.TP +.BI \-o \ ofile +Output image file to contain the difference image in PGM format. +.TP +.I file +Input image that is compared against +.I ifile. +Default: standard input. +.SH OUTPUT +The difference image in PGM format is written to standard output or, +optionally, to +.I ofile. +.SH AUTHOR +Peter Meerwald. +Email bug reports to pmeerw@cosy.sbg.ac.at. +.SH AVAILABILITY +The most recent released version of +.B cmp_dct8x8 +is always available +at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the +directory /pub/people/pmeerw/Watermarking. +.SH "SEE ALSO" +.B cmp_pgm +(1), +.B cmp_ppm +(1), +.B cmp_dct +(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_dct8x8.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_dct8x8.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,199 @@ +#include "wm.h" +#include "dct.h" +#include "gray.h" +#include "netpbm/pgm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-h] [-m n] [-o file] [-pP] -i file file\n\n", progname); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-i file\t\toriginal image file\n"); + fprintf(stderr, "\t-m n\t\tmultiplication factor (default 16)\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-p\t\tprint PSNR, RMS and MSE\n"); + fprintf(stderr, "\t-P\t\tonly print PSNR, RMS and MSE, no difference image\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *orig = NULL; + + gray **input_image; + gray **orig_image; + double **input_dcts; + double **orig_dcts; + gray **output; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char orig_name[MAXPATHLEN]; + + int in_cols, in_rows, in_format; + gray in_maxval; + int orig_cols, orig_rows, orig_format; + gray orig_maxval; + int cols, rows, format; + gray maxval; + int col, row; + + int i, j; + int c; + + int m = 16; + + int print_psnr = 0; + int print_psnr_only = 0; + double error = 0.0; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "h?i:m:o:pP")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'i': + if ((orig = fopen(optarg, "rb")) == NULL) { + fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); + exit(1); + } + strcpy(orig_name, optarg); + break; + case 'm': + m = atoi(optarg); + if (m <= 0) { + fprintf(stderr, "%s: multiplication factor %d out of range\n", progname, m); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'p': + print_psnr = 1; + break; + case 'P': + print_psnr_only = 1; + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (!orig) { + fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); + + pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); + + if (in_cols != orig_cols || in_rows != orig_rows) { + fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); + exit(1); + } + + cols = in_cols; + rows = in_rows; + format = in_format; + maxval = in_maxval; + + if (cols % NJPEG) { + fprintf(stderr, "%s: image width %d not a multiple of %d\n", progname, cols, NJPEG); + exit(1); + } + + if (rows % NJPEG) { + fprintf(stderr, "%s: image height %d not a multiple of %d\n", progname, rows, NJPEG); + exit(1); + } + + input_image = pgm_allocarray(cols, NJPEG); + orig_image = pgm_allocarray(cols, NJPEG); + + init_dct_8x8(); + input_dcts = alloc_coeffs_8x8(); + orig_dcts = alloc_coeffs_8x8(); + output = alloc_grays(cols, NJPEG); + + if (!print_psnr_only) + pgm_writepgminit(out, cols, rows, maxval, 0); + + for (row = 0; row < rows; row += NJPEG) { + + for (i = 0; i < NJPEG; i++) { + pgm_readpgmrow(in, input_image[row % NJPEG], cols, maxval, format); + pgm_readpgmrow(orig, orig_image[row % NJPEG], cols, maxval, format); + } + + for (col = 0; col < cols; col += NJPEG) { + fdct_block_8x8(input_image, col, 0, input_dcts); + fdct_block_8x8(orig_image, col, 0, orig_dcts); + + for (i = 0; i < NJPEG; i++) { + for (j = 0; j < NJPEG; j++) { + error += sqr(input_dcts[j][i + cols] - orig_dcts[j][i + cols]); + output[j][i + col] = PIXELRANGE(fabs(input_dcts[j][i + cols] - orig_dcts[j][i + cols]) * m); + } + } + } + + if (!print_psnr_only) { + for (i = 0; i < NJPEG; i++) + pgm_writepgmrow(out, output[i], cols, maxval, 0); + } + + } + fclose(in); + fclose(orig); + if (!print_psnr_only) + fclose(out); + + pgm_freearray(input_image, NJPEG); + pgm_freearray(orig_image, NJPEG); + free_coeffs(input_dcts); + free_coeffs(orig_dcts); + free_grays(output); + + if (print_psnr || print_psnr_only) { + double mse = error / (double) (cols * rows); + double rmse = sqrt(mse); + double psnr = 20.0 * log(255.0 / rmse) / log(10.0); + FILE *print = print_psnr_only ? out : stderr; + if (mse > 0.0) + fprintf(print, "PSNR: %lf dB\n", psnr); + else + fprintf(print, "PSNR: inf\n"); + fprintf(print, "RMS: %lf\n", rmse); + fprintf(print, "MSE: %lf\n", mse); + } + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_dugad_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_dugad_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,149 @@ +#include "wm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-h] [-s file] [-C] [-o file] [-v] file\n\n", progname); + fprintf(stderr, "\t-C\t\toutput correlation only\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-s file\t\tignored\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + + int c, i, n, ok; + int levels; + double alpha; + double diff; + char line[32]; + + int correlation_only = 0; + int verbose = 0; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "h?Co:v:s:")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'C': + correlation_only = 1; + break; + case 's': + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "r")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + fgets(line, sizeof(line), in); + if (strspn(line, "DGWM") < 4) { + fprintf(stderr, "%s: watermark file %s invalid\n", progname, input_name); + exit(1); + } + + fscanf(in, "%d\n", &levels); + fscanf(in, "%lf\n", &alpha); + + n = 3 * levels; + ok = 0; + diff = 0.0; + for (i = 0; i < levels; i++) { + int m; + double z, v; + + // HL subband + fscanf(in, "%d %lf %lf\n", &m, &z, &v); + if (verbose && !correlation_only) { + if (m) + fprintf(out, "%f %f\n", z / (double) m, (v * alpha) / (double) (1.0 * m)); + else + fprintf(out, "0.0 0.0\n"); + } + if (m) { + ok += (z > v * alpha / (double) 1.0) ? 1 : 0; + diff += ((z - v * alpha) / (double) (1.0 * m)); + } + else + n--; + + // LH subband + fscanf(in, "%d %lf %lf\n", &m, &z, &v); + if (verbose && !correlation_only) { + if (m) + fprintf(out, "%f %f\n", z / (double) m, (v * alpha) / (double) (1.0 * m)); + else + fprintf(out, "0.0 0.0\n"); + } + if (m) { + ok += (z > v * alpha / (double) 1.0) ? 1 : 0; + diff += ((z - v * alpha) / (double) (1.0 * m)); + } + else + n--; + + // HH subband + fscanf(in, "%d %lf %lf\n", &m, &z, &v); + if (verbose && !correlation_only) { + if (m) + fprintf(out, "%f %f\n", z / (double) m, (v * alpha) / (double) (1.0 * m)); + else + fprintf(out, "0.0 0.0\n"); + } + + if (m) { + ok += (z > v * alpha / (double) 1.0) ? 1 : 0; + diff += ((z - v * alpha) / (double) (1.0 * m)); + } + else + n--; + } + + if (!correlation_only) + fprintf(out, "%d/%d, diff %f\n", ok, n, diff); + fprintf(out, "%f\n", (double) ok / (double) n); + + fclose(out); + fclose(in); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_dwt.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_dwt.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,389 @@ +#include "wm.h" +#include "dwt.h" +#include "coeff.h" +#include "gray.h" +#include "netpbm/pgm.h" +#include "dwt_util.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-e n] [-f n] [-F file] [-h] [-l n] [-o file] [-pP] [-s name,..] -i file file\n\n", progname); + fprintf(stderr, "\t-e n\t\twavelet filtering method (default: 2)\n"); + fprintf(stderr, "\t-f n\t\tfilter number (default: 2)\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file (default: filter.dat\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-i file\t\toriginal image file\n"); + fprintf(stderr, "\t-l n\t\tmax. decomposition level (default: 0 = max)\n"); + fprintf(stderr, "\t-m n\t\tmultiplication factor (default: 0 = auto)\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-p\t\tprint PSNR, RMS and MSE\n"); + fprintf(stderr, "\t-P\t\tonly print PSNR, RMS and MSE, no difference image\n"); + fprintf(stderr, "\t-q\t\tprint PSNR, RMS and MSE per subband\n"); + fprintf(stderr, "\t-s name,...\tsubband/level (default: all subbands)\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +void process_subband_var(gray **output, int cols, int rows, Image_tree p, Image_tree q, int type, double min, double max, gray maxval) { + int col, row, startcol, startrow; + + if (!p || !q) return; + + calc_subband_location(cols, rows, type, p->level, &startcol, &startrow); + + for (row = 0; row < p->image->height; row++) + for (col = 0; col < p->image->width; col++) { + double diff = fabs(get_pixel(p->image, col, row) - get_pixel(q->image, col, row)); + output[startrow + row][startcol + col] = PIXELRANGE((double) (diff - min) / (double) (max - min) * maxval); + } +} + +void process_subband_fixed(gray **output, int cols, int rows, Image_tree p, Image_tree q, int type, double m) { + int col, row, startcol, startrow; + + if (!p || !q) return; + + calc_subband_location(cols, rows, type, p->level, &startcol, &startrow); + + for (row = 0; row < p->image->height; row++) + for (col = 0; col < p->image->width; col++) { + double diff = fabs(get_pixel(p->image, col, row) - get_pixel(q->image, col, row)); + output[startrow + row][startcol + col] = PIXELRANGE(diff * m); + } +} + +void print_subband_psnr(int type, int level, double error, int cols, int rows, double min, double max, FILE *print) { + double mse = error / (double) (cols * rows); + double rmse = sqrt(mse); + double psnr = 20.0 * log(255.0 / rmse) / log(10.0); + int startcol, startrow; + + calc_subband_location(cols << level, rows << level, type, level, &startcol, &startrow); + fprintf(print, "%s%d (%d x %d) at %d x %d\n", subband_name(type), level, cols, rows, startcol, startrow); + if (mse > 0.0) + fprintf(print, " PSNR: %lf dB\n", psnr); + else + fprintf(print, " PSNR: inf\n"); + fprintf(print, " RMS: %lf\n", rmse); + fprintf(print, " MSE: %lf\n", mse); + fprintf(print, " dmin, dmax: %lf, %lf\n", min, max); +} + +int main(int argc, char *argv[]) { + FILE *in = stdin; + FILE *out = stdout; + FILE *orig = NULL; + FILE *print; + + gray **input_image; + gray **orig_image; + Image_tree input_dwts, p; + Image_tree orig_dwts, q; + gray **output; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char orig_name[MAXPATHLEN]; + char *subband_list = NULL; + + int in_cols, in_rows, in_format; + gray in_maxval; + int orig_cols, orig_rows, orig_format; + gray orig_maxval; + int cols, rows, format; + gray maxval; + int row; + + int no_orig = 0; + int m = 0; + int c; + int maxlevel = 0; + + int filter = 1; + int method = 2; + int levels; + char filter_name[MAXPATHLEN] = "filter.dat"; + + double error = 0.0; + int print_psnr = 0; + int print_psnr_subband = 0; + int print_psnr_only = 0; + + double min, max; + + int verbose = 0; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "e:f:F:h?i:l:m:o:pPqs:v:")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'i': + if (!strcmp(optarg, "-")) { + no_orig = 1; + strcpy(orig_name, "(zero)"); + } + else { + if ((orig = fopen(optarg, "rb")) == NULL) { + fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); + exit(1); + } + strcpy(orig_name, optarg); + } + break; + case 'l': + maxlevel = atoi(optarg); + if (maxlevel < 0) { + fprintf(stderr, "%s: decomposition level %d out of range\n", progname, maxlevel); + exit(1); + } + break; + case 'm': + m = atoi(optarg); + if (m < -1) { + fprintf(stderr, "%s: multiplication factor %d out of range\n", progname, m); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'p': + print_psnr = 1; + break; + case 'P': + print_psnr_only = 1; + break; + case 'q': + print_psnr = 1; + print_psnr_subband = 1; + case 's': + subband_list = optarg; + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + print = print_psnr_only ? out : stderr; + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (!orig && !no_orig) { + fprintf(stderr, "%s: original image file not specified, using zero image\n", progname); + strcpy(orig_name, "(zero)"); + no_orig = 1; + } + + pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); + + if (!no_orig) { + pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); + if (in_cols != orig_cols || in_rows != orig_rows) { + fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); + exit(1); + } + } + + cols = in_cols; + rows = in_rows; + format = in_format; + maxval = in_maxval; + + input_image = pgm_allocarray(cols, rows); + orig_image = pgm_allocarray(cols, rows); + + output = alloc_grays(cols, rows); + + if (no_orig) { + for (row = 0; row < rows; row++) { + pgm_readpgmrow(in, input_image[row], cols, maxval, format); + bzero(orig_image[row], sizeof(gray) * cols); + } + } + else { + for (row = 0; row < rows; row++) { + pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); + pgm_readpgmrow(orig, orig_image[row], orig_cols, orig_maxval, orig_format); + } + } + + fclose(in); + if (!no_orig) + fclose(orig); + + // complete decomposition + levels = find_deepest_level(cols, rows) - 1; + if (!maxlevel) maxlevel = levels; + if (maxlevel > levels) { + fprintf(stderr, "%s: decomposition level %d not possible (max. %d), image size is %d x %d\n", progname, maxlevel, levels, cols, rows); + exit(1); + } + + init_dwt(cols, rows, filter_name, filter, maxlevel, method); + + input_dwts = fdwt(input_image); + orig_dwts = fdwt(orig_image); + + p = input_dwts; + q = orig_dwts; + min = 10000000.0; + max = 0.0; + error = 0.0; + while (p->coarse && q->coarse) { + double localmin, localmax, localerror; + + if (subband_in_list(subband_list, HORIZONTAL, p->horizontal->level)) { + calc_subband(p->horizontal, q->horizontal, HORIZONTAL, &localmin, &localmax, &localerror); + if (m == -1) process_subband_var(output, cols, rows, p->horizontal, q->horizontal, HORIZONTAL, localmin, localmax, maxval); + if (localmin < min) min = localmin; + if (localmax > max) max = localmax; + error += localerror; + if (print_psnr_subband) + print_subband_psnr(HORIZONTAL, p->horizontal->level, error, p->horizontal->image->width, p->horizontal->image->height, localmin, localmax, print); + } + else if (verbose > 5) + fprintf(stderr, "%s: subband %s%d skipped\n", progname, subband_name(HORIZONTAL), p->horizontal->level); + + if (subband_in_list(subband_list, VERTICAL, p->vertical->level)) { + calc_subband(p->vertical, q->vertical, VERTICAL, &localmin, &localmax, &localerror); + if (m == -1) process_subband_var(output, cols, rows, p->vertical, q->vertical, VERTICAL, localmin, localmax, maxval); + if (localmin < min) min = localmin; + if (localmax > max) max = localmax; + error += localerror; + if (print_psnr_subband) + print_subband_psnr(VERTICAL, p->vertical->level, error, p->vertical->image->width, p->vertical->image->height, localmin, localmax, print); + } + else if (verbose > 5) + fprintf(stderr, "%s: subband %s%d skipped\n", progname, subband_name(VERTICAL), p->vertical->level); + + if (subband_in_list(subband_list, DIAGONAL, p->diagonal->level)) { + calc_subband(p->diagonal, q->diagonal, DIAGONAL, &localmin, &localmax, &localerror); + if (m == -1) process_subband_var(output, cols, rows, p->diagonal, q->diagonal, DIAGONAL, localmin, localmax, maxval); + if (localmin < min) min = localmin; + if (localmax > max) max = localmax; + error += localerror; + if (print_psnr_subband) + print_subband_psnr(DIAGONAL, p->vertical->level, error, p->diagonal->image->width, p->diagonal->image->height, localmin, localmax, print); + } + else if (verbose > 5) + fprintf(stderr, "%s: subband %s%d skipped\n", progname, subband_name(DIAGONAL), p->diagonal->level); + + p = p->coarse; + q = q->coarse; + + if (!p->coarse) { + if (subband_in_list(subband_list, COARSE, p->level)) { + calc_subband(p, q, COARSE, &localmin, &localmax, &localerror); + if (m == -1) process_subband_var(output, cols, rows, p, q, COARSE, localmin, localmax, maxval); + if (localmin < min) min = localmin; + if (localmax > max) max = localmax; + error += localerror; + if (print_psnr_subband) + print_subband_psnr(COARSE, p->level, error, p->image->width, p->image->height, localmin, localmax, print); + } + else if (verbose > 5) + fprintf(stderr, "%s: subband %s%d skipped\n", progname, subband_name(COARSE), p->level); + } + } + + p = input_dwts; + q = orig_dwts; + while (p->coarse && q->coarse) { + if (m > 0) { + process_subband_fixed(output, cols, rows, p->horizontal, q->horizontal, HORIZONTAL, m); + process_subband_fixed(output, cols, rows, p->vertical, q->vertical, VERTICAL, m); + process_subband_fixed(output, cols, rows, p->diagonal, q->diagonal, DIAGONAL, m); + } + else if (m == 0) { + process_subband_var(output, cols, rows, p->horizontal, q->horizontal, HORIZONTAL, min, max, maxval); + process_subband_var(output, cols, rows, p->vertical, q->vertical, VERTICAL, min, max, maxval); + process_subband_var(output, cols, rows, p->diagonal, q->diagonal, DIAGONAL, min, max, maxval); + } + + p = p->coarse; + q = q->coarse; + + if (!p->coarse) { + if (m > 0) + process_subband_fixed(output, cols, rows, p, q, COARSE, m); + else if (m == 0) + process_subband_var(output, cols, rows, p, q, COARSE, min, max, maxval); + } + } + + if (!print_psnr_only) { + pgm_writepgminit(out, cols, rows, maxval, 0); + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, output[row], cols, maxval, 0); + + fclose(out); + } + + pgm_freearray(input_image, rows); + pgm_freearray(orig_image, rows); + free_grays(output); + + if (print_psnr || print_psnr_only) { + double mse = error / (double) (cols * rows); + double rmse = sqrt(mse); + double psnr = 20.0 * log(255.0 / rmse) / log(10.0); + if (mse > 0.0) + fprintf(print, "PSNR: %lf dB\n", psnr); + else + fprintf(print, "PSNR: inf\n"); + fprintf(print, "RMS: %lf\n", rmse); + fprintf(print, "MSE: %lf\n", mse); + fprintf(print, "dmin, dmax: %lf, %lf\n", min, max); + } + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_frid2_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_frid2_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,153 @@ +#include "wm.h" +#include "signature.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-C\t\toutput correlation only\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + + int correlation_only = 0; + + int c, i; + int corr1 = 0, match1 = 0; + int corr2 = 0, match2 = 0; + int verbose = 0; + + char line[1024]; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'C': + correlation_only = 1; + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "r")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + fgets(line, sizeof(line), sig); + if (strspn(line, "FR2SG") >= 5) { + fscanf(sig, "%d\n", &nbit_signature); + fscanf(sig, "%*f\n"); + fscanf(sig, "%*f\n"); + fscanf(sig, "%*d\n"); + n_signature = NBITSTOBYTES(nbit_signature); + fread(signature, sizeof(char), n_signature, sig); + fscanf(sig, "\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); + exit(1); + } + + fgets(line, sizeof(line), in); + if (strspn(line, "FR2WM") >= 5) { + fscanf(in, "%d\n", &nbit_signature1); + n_signature1 = NBITSTOBYTES(nbit_signature1); + fread(signature1, sizeof(char), n_signature1, in); +// fscanf(in, "\n"); + fscanf(in, "%d\n", &nbit_signature2); + n_signature2 = NBITSTOBYTES(nbit_signature2); + fread(signature2, sizeof(char), n_signature2, in); + fscanf(in, "\n"); + } + else { + fprintf(stderr, "%s: invalid watermark file %s\n", progname, input_name); + exit(1); + } + + if (verbose > 0) { + fprintf(stderr, "signature length: %d\n", nbit_signature); + fprintf(stderr, "watermark length (low. freq.): %d\n", nbit_signature1); + fprintf(stderr, "watermark length (med. freq.): %d\n", nbit_signature2); + } + + for (i = 0; i < nbit_signature; i++) { + if (get_signature_bit(i) == get_signature1_bit(i)) + corr1++, match1++; + else + corr1--; + if (get_signature_bit(i) == get_signature2_bit(i)) + corr2++, match2++; + else + corr2--; + } + + if (correlation_only) + fprintf(out, "%lf\n", (double) (corr1 + corr2) / (nbit_signature1 + nbit_signature2)); + else { + fprintf(out, "bit matches (low freq.): %d/%d\n", match1, nbit_signature1); + fprintf(out, "correlation (low. freq.): %lf\n", (double) corr1 / nbit_signature1); + fprintf(out, "bit matches (med. freq.): %d/%d\n", match2, nbit_signature2); + fprintf(out, "correlation (med. freq.): %lf\n", (double) corr2 / nbit_signature2); + fprintf(out, "total correlation: %lf\n", (double) (corr1 + corr2) / (nbit_signature1 + nbit_signature2)); + } + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_kim_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_kim_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,165 @@ +#include "wm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-C\t\toutput correlation only\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + + int c, i; + int in_level; + double *input_watermark, *orig_watermark; + int sig_n, in_n; + double sig_a; + double sig_A; + int sig_l; + int sig_e, sig_f; + double s1, s2, s3; + double correlation; + char line[32]; + + int verbose = 0; + int correlation_only = 0; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'C': + correlation_only = 1; + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "r")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (!sig) { + fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); + exit(1); + } + + fgets(line, sizeof(line), sig); + if (strspn(line, "KISG") < 4) { + fprintf(stderr, "%s: original signature file %s invalid\n", progname, signature_name); + exit(1); + } + + fgets(line, sizeof(line), in); + if (strspn(line, "KIWM") < 4) { + fprintf(stderr, "%s: watermark file %s invalid\n", progname, input_name); + exit(1); + } + + fscanf(sig, "%d\n", &sig_n); + fscanf(in, "%d\n", &in_n); + + if (sig_n <= 0 || sig_n > 32000) { + fprintf(stderr, "%s: invalid original watermark length %d\n", progname, sig_n); + exit(1); + } + + fscanf(sig, "%lf\n", &sig_a); + fscanf(sig, "%lf\n", &sig_A); + fscanf(sig, "%d\n", &sig_l); + fscanf(sig, "%d\n", &sig_e); + fscanf(sig, "%d\n", &sig_f); + fscanf(sig, "%*[^\n\r]\n"); + + orig_watermark = malloc(sig_n * sizeof(double)); + for (i = 0; i < sig_n; i++) + fscanf(sig, "%lf\n", &orig_watermark[i]); + fclose(sig); + + fscanf(in, "%d\n", &in_level); + input_watermark = malloc(in_n * sizeof(double)); + for (i = 0; i < in_n; i++) + fscanf(in, "%lf\n", &input_watermark[i]); + fclose(in); + + /* + * normalized correlation + * Craver, S., "Can Invisible Watermarks Resolve Rightful Ownership?", IBM Research Report, 1996, p. 5 + */ + + s1 = s2 = s3 = 0.0; + for (i = 0; i < in_n; i++) { + double in_x, sig_x; + + in_x = input_watermark[i]; + sig_x = orig_watermark[i % sig_n]; + + s1 += sig_x * in_x; + s2 += in_x * in_x; + s3 += sig_x * sig_x; + } + + correlation = s1 / sqrt(s2 * s3); + + if (!correlation_only) + fprintf(out, "%s: correlation: %f\n", progname, correlation); + else + fprintf(out, "%f\n", correlation); + + fclose(out); + + free(orig_watermark); + free(input_watermark); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_koch_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_koch_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,152 @@ +#include "wm.h" +#include "signature.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-C\t\toutput correlation only\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + + int c, i; + double quality = 0.0; + int quantization = 0; + int corr = 0, match = 0; + int verbose = 0; + + int correlation_only = 0; + + int seed; + char line[32]; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'C': + correlation_only = 1; + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "r")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + fgets(line, sizeof(line), sig); + if (strspn(line, "KCSG") >= 4) { + fscanf(sig, "%d\n", &nbit_signature1); + fscanf(sig, "%lf\n", &quality); + fscanf(sig, "%d\n", &quantization); + fscanf(sig, "%d\n", &seed); + srandom(seed); + n_signature1 = NBITSTOBYTES(nbit_signature1); + fread(signature1, sizeof(char), n_signature1, sig); + fscanf(sig, "\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); + exit(1); + } + + fgets(line, sizeof(line), in); + if (strspn(line, "KCWM") >= 4) { + fscanf(in, "%d\n", &nbit_signature2); + n_signature2 = NBITSTOBYTES(nbit_signature2); + fread(signature2, sizeof(char), n_signature2, in); + fscanf(in, "\n"); + } + else { + fprintf(stderr, "%s: invalid watermark file %s\n", progname, input_name); + exit(1); + } + + if (verbose > 0) { + fprintf(stderr, "signature length: %d\n", nbit_signature1); + fprintf(stderr, "watermark length: %d\n", nbit_signature2); + } + + for (i = 0; i < nbit_signature2; i++) + if (get_signature1_bit(i % nbit_signature1) == get_signature2_bit(i)) + corr++, match++; + else + corr--; + + if (verbose > 1) { + for (i = 0; i < nbit_signature2; i++) + fprintf(stderr, "%d", get_signature1_bit(i % nbit_signature1)); + fprintf(stderr, "\n"); + for (i = 0; i < nbit_signature2; i++) + fprintf(stderr, "%d", get_signature2_bit(i)); + fprintf(stderr, "\n"); + } + + if (correlation_only) + fprintf(out, "%lf\n", (double) corr / nbit_signature2); + else { + fprintf(out, "bit matches: %d/%d\n", match, nbit_signature2); + fprintf(out, "correlation: %lf\n", (double) corr / nbit_signature2); + } + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_kund2_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_kund2_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,214 @@ +#include "wm.h" +#include "signature.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-C\t\toutput correlation only\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + + char *binstr; + + int correlation_only = 0; + + int c, i; + int quality = 0; + int blocksize = 0; + int corr = 0, match = 0; + int verbose = 0; + int filter = 0; + int method = 0; + int level = 0; + char filter_name[MAXPATHLEN] = ""; + int k; + + int seed; + char line[32]; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'C': + correlation_only = 1; + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "r")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + fgets(line, sizeof(line), sig); + if (strspn(line, "KD2SG") >= 5) { + fscanf(sig, "%d\n", &nbit_signature1); + fscanf(sig, "%d\n", &quality); + fscanf(sig, "%d\n", &blocksize); + fscanf(sig, "%d\n", &method); + fscanf(sig, "%d\n", &filter); + fscanf(sig, "%[^\n\r]\n", filter_name); + fscanf(sig, "%d\n", &level); + fscanf(sig, "%d\n", &seed); + srandom(seed); + n_signature1 = NBITSTOBYTES(nbit_signature1); + + binstr = malloc((nbit_signature1 + 1) * sizeof(char)); + fscanf(sig, "%[01]\n", binstr); + binstr_to_sig1(binstr); + free(binstr); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); + exit(1); + } + + fgets(line, sizeof(line), in); + if (strspn(line, "KD2WM") >= 5) { + int max_nbit_signature; + int min_nbit_signature = -1; + double pe[100]; + double pe_sum; + double alpha[100]; + char *w[100]; + + fscanf(in, "%d\n", &max_nbit_signature); + + k = 0; + while (!feof(in) && k < 100) { + int e; + + fscanf(in, "%d\n", &nbit_signature2); + w[k] = binstr = malloc(sizeof(char) * (nbit_signature2 + 1)); + fscanf(in, "%[01]\n", binstr); + + binstr_to_sig2(binstr); + + if (nbit_signature2 < min_nbit_signature || min_nbit_signature == -1) + min_nbit_signature = nbit_signature2; + e = 0; + for (i = 0; i < nbit_signature2; i += 2) { + if (get_signature1_bit(i % nbit_signature1) != get_signature2_bit(i)) + e++; + } + if (e > 0) + pe[k++] = log( (1 - (e / (double) nbit_signature2)) / (e / (double) nbit_signature2)); + else + pe[k++] = 0; + } + + pe_sum = 0.0; + for (i = 0; i < k; i++) { +// fprintf(stderr, "XXX pe[%d] = %f\n", i, pe[i]); + pe_sum += pe[i]; + } + + for (i = 0; i < k; i++) { + if (pe_sum != 0) + alpha[i] = pe[i] / pe_sum; + else + alpha[i] = 1.0; + } + + nbit_signature = min_nbit_signature; + for (i = 0; i < min_nbit_signature; i++) { + double s = 0.0; + int j; + + for (j = 0; j < k; j++) { + int bit; +//fprintf(stderr, "XXX %d %d\n", i, j); + binstr_to_sig2(w[j]); + bit = get_signature2_bit(i) ? 1 : -1; + s += alpha[j] * bit; + } +// fprintf(stderr, "YYY %d %f\n", i, s); + set_signature_bit(i, s > 0 ? 1 : 0); + } + } + else { + fprintf(stderr, "%s: invalid watermark file %s\n", progname, input_name); + exit(1); + } + + if (verbose > 0) { + fprintf(stderr, "signature length: %d\n", nbit_signature1); + fprintf(stderr, "watermark length: %d\n", nbit_signature); + } + + for (i = 0; i < nbit_signature; i++) + if (get_signature1_bit(i % nbit_signature1) == get_signature2_bit(i)) + corr++, match++; + else + corr--; + + if (correlation_only) + fprintf(out, "%lf\n", (double) corr / nbit_signature2); + else { + fprintf(stderr, "redundant blocks: %d\n", k); + fprintf(out, "bit matches: %d/%d\n", match, nbit_signature2); + fprintf(out, "correlation: %lf\n", (double) corr / nbit_signature2); + } + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_kund3_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_kund3_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,157 @@ +#include "wm.h" +#include "signature.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-C\t\toutput correlation only\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + + char *binstr1; + char *binstr2; + + int correlation_only = 0; + + int c, i; + int quality = 0; + int corr = 0, match = 0; + int verbose = 0; + int filter = 0; + int method = 0; + int level = 0; + char filter_name[MAXPATHLEN] = ""; + + int seed; + char line[32]; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'C': + correlation_only = 1; + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "r")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + fgets(line, sizeof(line), sig); + if (strspn(line, "KD3SG") >= 5) { + fscanf(sig, "%d\n", &nbit_signature1); + fscanf(sig, "%d\n", &quality); + fscanf(sig, "%d\n", &method); + fscanf(sig, "%d\n", &filter); + fscanf(sig, "%[^\n\r]\n", filter_name); + fscanf(sig, "%d\n", &level); + fscanf(sig, "%d\n", &seed); + srandom(seed); + n_signature1 = NBITSTOBYTES(nbit_signature1); + + binstr1 = malloc((nbit_signature1 + 1) * sizeof(char)); + fscanf(sig, "%[01]\n", binstr1); + binstr_to_sig1(binstr1); + free(binstr1); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); + exit(1); + } + + fgets(line, sizeof(line), in); + if (strspn(line, "KD3WM") >= 5) { + fscanf(in, "%d\n", &nbit_signature2); + n_signature2 = NBITSTOBYTES(nbit_signature2); + binstr2 = malloc((nbit_signature2 + 1) * sizeof(char)); + fscanf(in, "%[01]\n", binstr2); + binstr_to_sig2(binstr2); + free(binstr2); + } + else { + fprintf(stderr, "%s: invalid watermark file %s\n", progname, input_name); + exit(1); + } + + if (verbose > 0) { + fprintf(stderr, "signature length: %d\n", nbit_signature1); + fprintf(stderr, "watermark length: %d\n", nbit_signature2); + } + + for (i = 0; i < nbit_signature2; i++) + if (get_signature1_bit(i % nbit_signature1) == get_signature2_bit(i)) + corr++, match++; + else + corr--; + + if (correlation_only) + fprintf(out, "%lf\n", (double) corr / nbit_signature2); + else { + fprintf(out, "bit matches: %d/%d\n", match, nbit_signature2); + fprintf(out, "correlation: %lf\n", (double) corr / nbit_signature2); + } + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_kund_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_kund_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,2 @@ +int main(int argc, char *argv[]) { +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_pgm.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_pgm.1 Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,69 @@ +.\" +.\" cmp_pgm.1 - the *roff document processor man page source +.\" +.TH cmp_pgm 1 "98/07/08" "Watermarking, Version 1.0" +.SH NAME +cmp_pgm \- a program to create the difference image of two PGM images +.SH SYNOPSIS +.B cmp_pgm +[ +.B \-h +] +[ +.BI \-m \ number +] +[ +.BI \-o \ ofile +] +.BI \-i \ ifile +.I file +.SH DESCRIPTION +.B cmp_pgm +is a program to create the difference image of two PGM (portable graymap) +grayscale images. To compare PPM (portable pixmap) RGB color images, use the +.B cmp_ppm +program. +.PP +If +.I file +or +.I ofile +is not specified, then standard input or standard output is +used. +.PP +.SH OPTIONS +.TP +.B \-h +Print a help message. +.TP +.BI \-i \ ifile +The original image. Mandatory. +.TP +.BI \-m \ number +Multiplication factor to magnify differences between the to +original and input image. +Default value: 16. +.TP +.BI \-o \ ofile +Output image file to contain the difference image in PGM format. +.TP +.I file +Input image that is compared against +.I ifile. +Default: standard input. +.SH OUTPUT +The difference image in PGM format is written to standard output or, +optionally, to +.I ofile. +.SH AUTHOR +Peter Meerwald. +Email bug reports to pmeerw@cosy.sbg.ac.at. +.SH AVAILABILITY +The most recent released version of +.B cmp_pgm +is always available +at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the +directory /pub/people/pmeerw/Watermarking. +.SH "SEE ALSO" +.B cmp_ppm +(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_pgm.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_pgm.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,202 @@ +#include "wm.h" +#include "netpbm/pgm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-C] [-h] [-m n] [-o file] [-pP] -i file file\n\n", progname); + fprintf(stderr, "\t-C\t\tprint PSNR value only\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-i file\t\toriginal image file\n"); + fprintf(stderr, "\t-m n\t\tmultiplication factor (default auto)\n"); + fprintf(stderr, "\t-o file\t\toutput file for difference image\n"); + fprintf(stderr, "\t-p\t\tprint PSNR, RMS and MSE\n"); + fprintf(stderr, "\t-P\t\tonly print PSNR, RMS and MSE, no difference image\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *orig = NULL; + + gray **input_image; + gray **orig_image; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char orig_name[MAXPATHLEN]; + + int in_cols, in_rows, in_format; + gray in_maxval; + int orig_cols, orig_rows, orig_format; + gray orig_maxval; + int cols, rows; + gray maxval; + int col, row; + + int c; + + int m = 0; + int min, max; + + int print_psnr = 0; + int print_psnr_only = 0; + int print_psnr_value_only = 0; + double error = 0.0; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "h?i:m:o:pPC")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'i': + if ((orig = fopen(optarg, "rb")) == NULL) { + fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); + exit(1); + } + strcpy(orig_name, optarg); + break; + case 'm': + m = atoi(optarg); + if (m <= 0) { + fprintf(stderr, "%s: multiplication factor %d out of range\n", progname, m); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'p': + print_psnr = 1; + break; + case 'P': + print_psnr_only = 1; + break; + case 'C': + print_psnr_value_only = 1; + print_psnr_only = 1; + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (!orig) { + fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); + + pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); + + if (in_cols != orig_cols || in_rows != orig_rows) { + fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); + exit(1); + } + + cols = in_cols; + rows = in_rows; + maxval = in_maxval; + + input_image = pgm_allocarray(cols, rows); + orig_image = pgm_allocarray(cols, rows); + + for (row = 0; row < rows; row++) { + pgm_readpgmrow(in, input_image[row], cols, in_maxval, in_format); + pgm_readpgmrow(orig, orig_image[row], cols, orig_maxval, orig_format); + } + + fclose(in); + fclose(orig); + + min = max = abs(input_image[0][0] - orig_image[0][0]); + + for (row = 0; row < rows; row++) { + gray *pi = input_image[row]; + gray *po = orig_image[row]; + + for (col = 0; col < cols; col++) { + int diff = abs(*pi - *po); + error += sqr(diff); + if (diff < min) min = diff; + if (diff > max) max = diff; + + pi++; + po++; + } + } + + for (row = 0; row < rows; row++) { + gray *pi = input_image[row]; + gray *po = orig_image[row]; + + for (col = 0; col < cols; col++) { + int diff = abs(*pi - *po); + if (m > 0) + *pi = PIXELRANGE(diff * m); + else + *pi = PIXELRANGE((double) (diff - min) / (double) (max - min) * maxval); + + pi++; + po++; + } + } + + if (!print_psnr_only) { + pgm_writepgminit(out, cols, rows, maxval, 0); + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, input_image[row], cols, maxval, 0); + + fclose(out); + } + + pgm_freearray(input_image, rows); + pgm_freearray(orig_image, rows); + + if (print_psnr || print_psnr_only) { + double mse = error / (double) (cols * rows); + double rmse = sqrt(mse); + double psnr = 20.0 * log(255.0 / rmse) / log(10.0); + FILE *print = print_psnr_only ? out : stderr; + if (!print_psnr_value_only) { + if (mse > 0.0) + fprintf(print, "PSNR: %lf dB\n", psnr); + else + fprintf(print, "PSNR: inf\n"); + fprintf(print, "RMSE: %lf\n", rmse); + fprintf(print, "MSE: %lf\n", mse); + fprintf(print, "dmin, dmax: %d, %d\n", min, max); + } + else + fprintf(print, "%lf\n", mse > 0.0 ? psnr : 100.0); + } + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_ppm.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_ppm.1 Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,100 @@ +.\" +.\" cmp_ppm.1 - the *roff document processor man page source +.\" +.TH cmp_ppm 1 "98/07/08" "Watermarking, Version 1.0" +.SH NAME +cmp_ppm \- a program to create the difference image of two PGM images +.SH SYNOPSIS +.B cmp_ppm +[ +.BI \-c \ name +] +[ +.B \-h +] +[ +.BI \-m \ number +] +[ +.BI \-o \ ofile +] +.BI \-i \ ifile +.I file +.SH DESCRIPTION +.B cmp_ppm +is a program to create the difference image of two PPM (portable pixmap) +RGB color images. To compare PGM (portable graymap) grayscale images, use +the +.B cmp_pgm +program. +.PP +The color components to compare are specified with the +.BI \-c \ name +option, where +.I name +is one of the following: +.TP +.B red +The red color component. +.TP +.B green +The green color component. +.TP +.B blue +The blue color component. +.PP +Multiple color components are allowed. Specifying only the inital letter +of a color component is sufficient. +Per default +.B cmp_ppm +compares the luminance value of the images. This operation may be +selected explicitly with the +.BI \-c \ luminance +option. +.PP +If +.I file +or +.I ofile +is not specified, then standard input or standard output is +used. +.PP +.SH OPTIONS +.TP +.BI \-c \ name +Specifies color component(s) or luminance to compare. Default: luminance. +.TP +.B \-h +Print a help message. +.TP +.BI \-i \ ifile +The original image. Mandatory. +.TP +.BI \-m \ number +Multiplication factor to magnify differences between the to +original and input image. +Default value: 16. +.TP +.BI \-o \ ofile +Output image file to contain the difference image in PPM format. +.TP +.I file +Input image that is compared against +.I ifile. +Default: standard input. +.SH OUTPUT +The difference image in PPM format is written to standard output or, +optionally, to +.I ofile. +.SH AUTHOR +Peter Meerwald. +Email bug reports to pmeerw@cosy.sbg.ac.at. +.SH AVAILABILITY +The most recent released version of +.B cmp_ppm +is always available +at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the +directory /pub/people/pmeerw/Watermarking. +.SH "SEE ALSO" +.B cmp_ppm +(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_ppm.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_ppm.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,270 @@ +#include "wm.h" +#include "netpbm/ppm.h" + +#define LUMINANCE 1 +#define RED 2 +#define GREEN 4 +#define BLUE 8 + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s -c name [-C] [-h] [-m n] [-o file] [-pP] -i file file\n\n", progname); + fprintf(stderr, "\t-c name\t\tcolor component (default luminance)\n"); + fprintf(stderr, "\t\t\teg. red, green, blue, luminance\n"); + fprintf(stderr, "\t-C\t\tprint PSNR value only\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-i file\t\toriginal image file\n"); + fprintf(stderr, "\t-m n\t\tmultiplication factor (default 16)\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-p\t\tprint PSNR, RMS and MSE\n"); + fprintf(stderr, "\t-P\t\tonly print PSNR, RMS and MSE, no difference image\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *orig = NULL; + + pixel **input_image; + pixel **orig_image; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char orig_name[MAXPATHLEN]; + + int in_cols, in_rows, in_format; + pixval in_maxval; + int orig_cols, orig_rows, orig_format; + pixval orig_maxval; + int cols, rows; + pixval maxval; + int col, row; + + int c; + + double error = 0.0; + int print_psnr = 0; + int print_psnr_only = 0; + int print_psnr_value_only = 0; + + int m = 16; + int component = 0; + int component_default = LUMINANCE; + int min, max; + + progname = argv[0]; + + ppm_init(&argc, argv); + +#ifdef __EMX__ + _fsetmode(in, "b"); + _fsetmode(out, "b"); +#endif + + while ((c = getopt(argc, argv, "Cc:h?i:m:o:pP")) != EOF) { + switch (c) { + case 'C': + print_psnr_value_only = 1; + print_psnr_only = 1; + break; + case 'c': + if (!strcasecmp(optarg, "RED") || toupper(*optarg) == 'R') + component |= RED; + else if (!strcasecmp(optarg, "GREEN") || toupper(*optarg) == 'G') + component |= GREEN; + else if (!strcasecmp(optarg, "BLUE") || toupper(*optarg) == 'B') + component |= BLUE; + else if (!strcasecmp(optarg, "LUMINANCE") || toupper(*optarg) == 'L') + component |= LUMINANCE; + else + fprintf(stderr, "%s: unknown color component %s\n", progname, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'i': + if ((orig = fopen(optarg, "rb")) == NULL) { + fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); + exit(1); + } + strcpy(orig_name, optarg); + break; + case 'm': + m = atoi(optarg); + if (m <= 0) { + fprintf(stderr, "%s: multiplication factor %d out of range\n", progname, m); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'p': + print_psnr = 1; + break; + case 'P': + print_psnr_only = 1; + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (!orig) { + fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); + exit(1); + } + + if (!component) { + if (component_default) + component = component_default; + else { + fprintf(stderr, "%s: color component(s) to compare not specified, use -c name option\n", progname); + exit(1); + } + } + + if (component & LUMINANCE && component & (RED | GREEN | BLUE)) { + fprintf(stderr, "%s: unable to compare luminance AND color component\n", progname); + exit(1); + } + + ppm_readppminit(in, &in_cols, &in_rows, &in_maxval, &in_format); + + ppm_readppminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); + + if (in_cols != orig_cols || in_rows != orig_rows) { + fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); + exit(1); + } + + cols = in_cols; + rows = in_rows; + maxval = in_maxval; + + input_image = ppm_allocarray(cols, rows); + + for (row = 0; row < rows; row++) + ppm_readppmrow(in, input_image[row], cols, in_maxval, in_format); + + fclose(in); + + orig_image = ppm_allocarray(cols, rows); + + for (row = 0; row < rows; row++) + ppm_readppmrow(orig, orig_image[row], cols, orig_maxval, orig_format); + + fclose(orig); + + if (component & LUMINANCE) + min = max = abs(PPM_LUMIN(input_image[0][0]) - PPM_LUMIN(orig_image[0][0])); + else { + if (component & RED) + min = max = abs(PPM_GETR(input_image[0][0]) - PPM_GETR(orig_image[0][0])); + else if (component & GREEN) + min = max = abs(PPM_GETG(input_image[0][0]) - PPM_GETG(orig_image[0][0])); + else if (component & BLUE) + min = max = abs(PPM_GETB(input_image[0][0]) - PPM_GETB(orig_image[0][0])); + else + min = max = 0; + } + + for (row = 0; row < rows; row++) { + pixel *pi = input_image[row]; + pixel *po = orig_image[row]; + + for (col = 0; col < cols; col++) { + int diff=0; + + if (component & LUMINANCE) { + pixval l; + diff = abs(PPM_LUMIN(*pi) - PPM_LUMIN(*po)); + error += sqr(PPM_LUMIN(*pi) - PPM_LUMIN(*po)); + l = PIXELRANGE(ROUND(abs(PPM_LUMIN(*pi) - PPM_LUMIN(*po)) * m)); + PPM_ASSIGN(*pi, l, l, l); + } + else { + if (component & RED) { + diff = abs(PPM_GETR(*pi) - PPM_GETR(*po)); + error += sqr(PPM_GETR(*pi) - PPM_GETR(*po)); + PPM_PUTR(*pi, PIXELRANGE(abs(PPM_GETR(*pi) - PPM_GETR(*po)) * m)); + } + else + PPM_PUTR(*pi, 0); + if (component & GREEN) { + diff = abs(PPM_GETG(*pi) - PPM_GETG(*po)); + error += sqr(PPM_GETG(*pi) - PPM_GETG(*po)); + PPM_PUTG(*pi, PIXELRANGE(abs(PPM_GETG(*pi) - PPM_GETG(*po)) * m)); + } + else + PPM_PUTG(*pi, 0); + if (component & BLUE) { + diff = abs(PPM_GETB(*pi) - PPM_GETB(*po)); + error += sqr(PPM_GETB(*pi) - PPM_GETB(*po)); + PPM_PUTB(*pi, PIXELRANGE(abs(PPM_GETB(*pi) - PPM_GETB(*po)) * m)); + } + else + PPM_PUTB(*pi, 0); + } + + if (diff < min) min = diff; + if (diff > max) max = diff; + pi++; + po++; + } + } + + if (!print_psnr_only) { + ppm_writeppminit(out, cols, rows, maxval, 0); + for (row = 0; row < rows; row++) + ppm_writeppmrow(out, input_image[row], cols, maxval, 0); + + fclose(out); + } + + ppm_freearray(input_image, rows); + ppm_freearray(orig_image, rows); + + if (print_psnr || print_psnr_only) { + double mse = error / (double) (cols * rows); + double rmse = sqrt(mse); + double psnr = 20.0 * log(255.0 / rmse) / log(10.0); + FILE *print = print_psnr_only ? out : stderr; + if (!print_psnr_value_only) { + if (mse > 0.0) + fprintf(print, "PSNR: %lf dB\n", psnr); + else + fprintf(print, "PSNR: inf\n"); + fprintf(print, "RMS: %lf\n", rmse); + fprintf(print, "MSE: %lf\n", mse); + fprintf(print, "dmin, dmax: %d, %d\n", min, max); + } + else + fprintf(print, "%lf\n", mse > 0.0 ? psnr : 100.0); + } + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_wang_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_wang_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,150 @@ +#include "wm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-h] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + + int c; + int sig_n, in_n; + double sig_a, sig_b; + int sig_e, sig_f; + double s1, s2, s3; + char line[32]; + + int verbose = 0; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "h?o:s:v:")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "r")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (!sig) { + fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); + exit(1); + } + + fgets(line, sizeof(line), sig); + if (strspn(line, "WGSG") < 4) { + fprintf(stderr, "%s: original signature file %s invalid\n", progname, signature_name); + exit(1); + } + + fgets(line, sizeof(line), in); + if (strspn(line, "WGWM") < 4) { + fprintf(stderr, "%s: watermark file %s invalid\n", progname, input_name); + exit(1); + } + + fscanf(sig, "%d\n", &sig_n); + fscanf(in, "%d\n", &in_n); + if (sig_n != in_n) { + fprintf(stderr, "%s: watermark length mismatch (original %d, input %d)\n", progname, sig_n, in_n); + exit(1); + } + if (sig_n <= 0 || sig_n > 32000) { + fprintf(stderr, "%s: invalid original watermark length %d\n", progname, sig_n); + exit(1); + } + if (in_n != sig_n) { + fprintf(stderr, "%s: invalid watermark length %d, does not match signature length\n", progname, in_n); + exit(1); + } + + fscanf(sig, "%lf\n", &sig_a); + fscanf(sig, "%lf\n", &sig_b); + fscanf(sig, "%d\n", &sig_e); + fscanf(sig, "%d\n", &sig_f); + fscanf(sig, "%*[^\n\r]\n"); + + /* + * normalized correlation + * Craver, S., "Can Invisible Watermarks Resolve Rightful Ownership?", IBM Research Report, 1996, p. 5 + */ + + s1 = s2 = s3 = 0.0; + while (in_n > 0) { + double sig_x, in_x; + + fscanf(sig, "%lf\n", &sig_x); + fscanf(in, "%lf\n", &in_x); + + if (verbose >= 1) { + fprintf(stderr, "orig %f input %f\n", sig_x, in_x); + } + + s1 += sig_x * in_x; + s2 += in_x * in_x; + s3 += sig_x * sig_x; + + in_n--; + } + + fprintf(out, "%f\n", s1 / sqrt(s2 * s3)); + + fclose(sig); + fclose(out); + fclose(in); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_xia_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_xia_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,213 @@ +#include "wm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-C\t\toutput correlation only\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + + int c, i, j, n; + int in_level; + double *cumul_watermark, *orig_watermark; + int *cumul_watermark_count; + int sig_n, in_n; + double sig_a; + int sig_l; + int sig_e, sig_f; + double s1, s2, s3; + double correlation, maxcorrelation; + char line[32]; + + int verbose = 0; + int correlation_only = 0; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'C': + correlation_only = 1; + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "r")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (!sig) { + fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); + exit(1); + } + + fgets(line, sizeof(line), sig); + if (strspn(line, "XASG") < 4) { + fprintf(stderr, "%s: original signature file %s invalid\n", progname, signature_name); + exit(1); + } + + fgets(line, sizeof(line), in); + if (strspn(line, "XAWM") < 4) { + fprintf(stderr, "%s: watermark file %s invalid\n", progname, input_name); + exit(1); + } + + fscanf(sig, "%d\n", &sig_n); + fscanf(in, "%d\n", &in_n); + if (sig_n != in_n) { + fprintf(stderr, "%s: watermark length mismatch (original %d, input %d)\n", progname, sig_n, in_n); + exit(1); + } + if (sig_n <= 0 || sig_n > 32000) { + fprintf(stderr, "%s: invalid original watermark length %d\n", progname, sig_n); + exit(1); + } + if (in_n != sig_n) { + fprintf(stderr, "%s: invalid watermark length %d, does not match signature length\n", progname, in_n); + exit(1); + } + + fscanf(sig, "%lf\n", &sig_a); + fscanf(sig, "%d\n", &sig_l); + fscanf(sig, "%d\n", &sig_e); + fscanf(sig, "%d\n", &sig_f); + fscanf(sig, "%*[^\n\r]\n"); + + orig_watermark = malloc(sig_n * sizeof(double)); + for (i = 0; i < sig_n; i++) + fscanf(sig, "%lf\n", &orig_watermark[i]); + fclose(sig); + + fscanf(in, "%d\n", &in_level); + + cumul_watermark = malloc(in_n * sizeof(double)); + cumul_watermark_count = malloc(in_n * sizeof(int)); + + for (i = 0; i < in_n; i++) { + cumul_watermark_count[i] = 0; + cumul_watermark[i] = 0.0; + } + + /* + * normalized correlation + * Craver, S., "Can Invisible Watermarks Resolve Rightful Ownership?", IBM Research Report, 1996, p. 5 + */ + + maxcorrelation = -10000.0; + for (i = 0; i < in_level; i++) { + fscanf(in, "%d\n", &n); + + s1 = s2 = s3 = 0.0; + for (j = 0; j < n; j++) { + double in_x, sig_x; + + sig_x = orig_watermark[j % sig_n]; + fscanf(in, "%lf\n", &in_x); + + s1 += sig_x * in_x; + s2 += in_x * in_x; + s3 += sig_x * sig_x; + + if (verbose > 2) + fprintf(stderr, "%s: level %d; orig %f input %f\n", progname, i, sig_x, in_x); + + cumul_watermark[j % in_n] += in_x; + cumul_watermark_count[j % in_n]++; + } + + correlation = s1 / sqrt(s2 * s3); + if (correlation > maxcorrelation) + maxcorrelation = correlation; + + if (!correlation_only) + fprintf(out, "%s: correlation subband %d: %f\n", progname, i, correlation); + } + + s1 = s2 = s3 = 0.0; + for (i = 0; i < in_n; i++) { + double in_x, sig_x; + + if (cumul_watermark_count[i] <= 0) continue; + in_x = cumul_watermark[i] / (double) cumul_watermark_count[i]; + sig_x = orig_watermark[i]; + + s1 += sig_x * in_x; + s2 += in_x * in_x; + s3 += sig_x * sig_x; + } + + correlation = s1 / sqrt(s2 * s3); + if (!correlation_only) + fprintf(out, "%s: cumultative correlation: %f\n", progname, correlation); + + if (correlation > maxcorrelation) + maxcorrelation = correlation; + + if (!correlation_only) + fprintf(out, "%s: max. correlation: %f\n", progname, maxcorrelation); + else + fprintf(out, "%f\n", maxcorrelation); + + fclose(out); + fclose(in); + + free(orig_watermark); + free(cumul_watermark); + free(cumul_watermark_count); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_xie2_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_xie2_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,151 @@ +#include "wm.h" +#include "signature.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-C\t\toutput correlation only\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + + int correlation_only = 0; + + int c, i; + int corr = 0, match = 0; + int verbose = 0; + int filter = 0; + int method = 0; + int level = 0; + int quant = 0; + double alpha = 0.0; + char filter_name[MAXPATHLEN] = ""; + + int seed; + char line[32]; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'C': + correlation_only = 1; + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "r")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + fgets(line, sizeof(line), sig); + if (strspn(line, "XE2SG") >= 5) { + fscanf(sig, "%d\n", &nbit_signature1); + fscanf(sig, "%lf\n", &alpha); + fscanf(sig, "%d\n", &method); + fscanf(sig, "%d\n", &filter); + fscanf(sig, "%[^\n\r]\n", filter_name); + fscanf(sig, "%d\n", &quant); + fscanf(sig, "%d\n", &level); + fscanf(sig, "%d\n", &seed); + srandom(seed); + n_signature1 = NBITSTOBYTES(nbit_signature1); + fread(signature1, sizeof(char), n_signature1, sig); + fscanf(sig, "\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); + exit(1); + } + + fgets(line, sizeof(line), in); + if (strspn(line, "XE2WM") >= 5) { + fscanf(in, "%d\n", &nbit_signature2); + n_signature2 = NBITSTOBYTES(nbit_signature2); + fread(signature2, sizeof(char), n_signature2, in); + fscanf(in, "\n"); + } + else { + fprintf(stderr, "%s: invalid watermark file %s\n", progname, input_name); + exit(1); + } + + if (verbose > 0) { + fprintf(stderr, "signature length: %d\n", nbit_signature1); + fprintf(stderr, "watermark length: %d\n", nbit_signature2); + } + + for (i = 0; i < nbit_signature2; i++) + if (get_signature1_bit(i % nbit_signature1) == get_signature2_bit(i)) + corr++, match++; + else + corr--; + + if (correlation_only) + fprintf(out, "%lf\n", (double) corr / nbit_signature2); + else { + fprintf(out, "bit matches: %d/%d\n", match, nbit_signature2); + fprintf(out, "correlation: %lf\n", (double) corr / nbit_signature2); + } + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_xie_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_xie_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,149 @@ +#include "wm.h" +#include "signature.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-C\t\toutput correlation only\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + + int correlation_only = 0; + + int c, i; + int corr = 0, match = 0; + int verbose = 0; + int filter = 0; + int method = 0; + int level = 0; + double alpha = 0.0; + char filter_name[MAXPATHLEN] = ""; + + int seed; + char line[32]; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'C': + correlation_only = 1; + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "r")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + fgets(line, sizeof(line), sig); + if (strspn(line, "XESG") >= 4) { + fscanf(sig, "%d\n", &nbit_signature1); + fscanf(sig, "%lf\n", &alpha); + fscanf(sig, "%d\n", &method); + fscanf(sig, "%d\n", &filter); + fscanf(sig, "%[^\n\r]\n", filter_name); + fscanf(sig, "%d\n", &level); + fscanf(sig, "%d\n", &seed); + srandom(seed); + n_signature1 = NBITSTOBYTES(nbit_signature1); + fread(signature1, sizeof(char), n_signature1, sig); + fscanf(sig, "\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); + exit(1); + } + + fgets(line, sizeof(line), in); + if (strspn(line, "XEWM") >= 4) { + fscanf(in, "%d\n", &nbit_signature2); + n_signature2 = NBITSTOBYTES(nbit_signature2); + fread(signature2, sizeof(char), n_signature2, in); + fscanf(in, "\n"); + } + else { + fprintf(stderr, "%s: invalid watermark file %s\n", progname, input_name); + exit(1); + } + + if (verbose > 0) { + fprintf(stderr, "signature length: %d\n", nbit_signature1); + fprintf(stderr, "watermark length: %d\n", nbit_signature2); + } + + for (i = 0; i < nbit_signature2; i++) + if (get_signature1_bit(i % nbit_signature1) == get_signature2_bit(i)) + corr++, match++; + else + corr--; + + if (correlation_only) + fprintf(out, "%lf\n", (double) corr / nbit_signature2); + else { + fprintf(out, "bit matches: %d/%d\n", match, nbit_signature2); + fprintf(out, "correlation: %lf\n", (double) corr / nbit_signature2); + } + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/cmp_zhu_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/cmp_zhu_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,211 @@ +#include "wm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-C\t\toutput correlation only\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + + int c, i, j, n; + int in_level; + double *cumul_watermark, *orig_watermark; + int *cumul_watermark_count; + int sig_n, in_n; + double sig_a; + int sig_l; + int sig_e, sig_f; + char line[32]; + double correlation, maxcorrelation; + double s1, s2, s3; + + int verbose = 0; + int correlation_only = 0; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'C': + correlation_only = 1; + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "r")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (!sig) { + fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); + exit(1); + } + + fgets(line, sizeof(line), sig); + if (strspn(line, "ZHSG") < 4) { + fprintf(stderr, "%s: original signature file %s invalid\n", progname, signature_name); + exit(1); + } + + fgets(line, sizeof(line), in); + if (strspn(line, "ZHWM") < 4) { + fprintf(stderr, "%s: watermark file %s invalid\n", progname, input_name); + exit(1); + } + + fscanf(sig, "%d\n", &sig_n); + fscanf(in, "%d\n", &in_n); + if (sig_n != in_n) { + fprintf(stderr, "%s: watermark length mismatch (original %d, input %d)\n", progname, sig_n, in_n); + exit(1); + } + if (sig_n <= 0 || sig_n > 32000) { + fprintf(stderr, "%s: invalid original watermark length %d\n", progname, sig_n); + exit(1); + } + if (in_n != sig_n) { + fprintf(stderr, "%s: invalid watermark length %d, does not match signature length\n", progname, in_n); + exit(1); + } + + fscanf(sig, "%lf\n", &sig_a); + fscanf(sig, "%d\n", &sig_l); + fscanf(sig, "%d\n", &sig_e); + fscanf(sig, "%d\n", &sig_f); + fscanf(sig, "%*[^\n\r]\n"); + + orig_watermark = malloc(sig_n * sizeof(double)); + for (i = 0; i < sig_n; i++) + fscanf(sig, "%lf\n", &orig_watermark[i]); + fclose(sig); + + fscanf(in, "%d\n", &in_level); + + cumul_watermark = malloc(in_n * sizeof(double)); + cumul_watermark_count = malloc(in_n * sizeof(int)); + + for (i = 0; i < in_n; i++) { + cumul_watermark_count[i] = 0; + cumul_watermark[i] = 0.0; + } + + /* + * normalized correlation + * Craver, S., "Can Invisible Watermarks Resolve Rightful Ownership?", IBM Research Report, 1996, p. 5 + */ + maxcorrelation = -10000.0; + for (i = 0; i < in_level; i++) { + fscanf(in, "%d\n", &n); + + s1 = s2 = s3 = 0.0; + for (j = 0; j < n; j++) { + double in_x, sig_x; + + sig_x = orig_watermark[j]; + fscanf(in, "%lf\n", &in_x); + + s1 += sig_x * in_x; + s2 += in_x * in_x; + s3 += sig_x * sig_x; + + if (verbose > 2) + fprintf(stderr, "%s: level %d; orig %f input %f\n", progname, i, sig_x, in_x); + + cumul_watermark[j % in_n] += in_x; + cumul_watermark_count[j % in_n]++; + } + + correlation = s1 / sqrt(s2 * s3); + if (correlation > maxcorrelation) + maxcorrelation = correlation; + + if (!correlation_only) + fprintf(out, "%s: correlation level %d: %f\n", progname, i, correlation); + } + + s1 = s2 = s3 = 0.0; + for (i = 0; i < in_n; i++) { + double in_x, sig_x; + + in_x = cumul_watermark[i] / (double) cumul_watermark_count[i]; + sig_x = orig_watermark[i]; + + s1 += sig_x * in_x; + s2 += in_x * in_x; + s3 += sig_x * sig_x; + } + + correlation = s1 / sqrt(s2 * s3); + if (!correlation_only) + fprintf(out, "%s: cumultative correlation: %f\n", progname, correlation); + + if (correlation > maxcorrelation) + maxcorrelation = correlation; + + if (!correlation_only) + fprintf(out, "%s: max. correlation: %f\n", progname, maxcorrelation); + else + fprintf(out, "%f\n", maxcorrelation); + + fclose(out); + fclose(in); + + free(orig_watermark); + free(cumul_watermark); + free(cumul_watermark_count); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/coeff.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/coeff.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,72 @@ +#include "wm.h" +#include "coeff.h" + +double **alloc_coeffs(int cols, int rows) { + double **p; + int i; + + p = (double **)malloc(rows * sizeof(double *)); + if (!p) { +#ifdef DEBUG + fprintf(stderr, "alloc_coeffs(): malloc() failed\n"); + exit(1); +#else + return NULL; +#endif + } + p[0] = malloc(rows * cols * sizeof(double)); + if (!p[0]) { +#ifdef DEBUG + fprintf(stderr, "alloc_coeffs(): malloc() failed\n"); + exit(1); +#else + free(p); + return NULL; +#endif + } + for (i = 1; i < rows; i++) { + p[i] = &(p[0][i * cols]); + } + + return p; +} + +void free_coeffs(double **coeffs) { + free(coeffs[0]); + free(coeffs); +} + +double **alloc_coeffs_8x8() { + return alloc_coeffs(8, 8); +} + +void print_coeffs_8x8(double **coeffs) { + int i, j; + + for (i = 0; i < 8; i++) { + for (j = 0; j < 8; j++) + fprintf(stderr, "%8.2f ", coeffs[i][j]); + fprintf(stderr, "\n"); + } +} + +void print_coeffs(double **coeffs, int c, int r, int w, int h) { + int i, j; + double *p; + +#ifdef DEBUG + if (!coeffs) { + fprintf(stderr, "print_coeffs(): NULL pixels\n"); + } + if (w <= 0 || h <= 0 || c < 0 || r < 0) { + fprintf(stderr, "print_coeffs(): block dimension out of range\n"); + } +#endif + + for (j = r; j < r + h; j++) { + p = &coeffs[j][c]; + for (i = 0; i < w; i++) + fprintf(stderr, "%8.2f ", *(p++)); + fprintf(stderr, "\n"); + } +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/coeff.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/coeff.h Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,12 @@ +#ifndef COEFF_H +#define COEFF_H + +#include "wm.h" + +double **alloc_coeffs(int cols, int rows); +double **alloc_coeffs_8x8(); +void free_coeffs(double **coeffs); +void print_coeffs_8x8(double **coeffs); +void print_coeffs(double **coeffs, int c, int r, int w, int h); + +#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/coord.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/coord.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,75 @@ +#include +#include +#include "coord.h" + +struct coords *alloc_coords(int n) { + struct coords *c; + + if ((c = malloc(sizeof(struct coords))) != NULL) + init_coords(c, n); +#ifdef DEBUG + else + fprintf(stderr, "alloc_coords(): malloc failed\n"); +#endif + + return c; +} + +void free_coords(struct coords *c) { + +#ifdef DEBUG + if (!c) + fprintf(stderr, "free_coords(): got NULL pointer\n"); +#endif + + free(c->values); + free(c); +} + +int init_coords(struct coords *c, int n) { + +#ifdef DEBUG + if (!c) + fprintf(stderr, "init_coords(): got NULL poiner\n"); + + if (n <= 0) + fprintf(stderr, "init_coords(): n out of range\n"); +#endif + + c->count = 0; + c->max = n; + + if ((c->values = malloc(n * sizeof(struct coord))) != NULL) + return 0; + else + return -1; +} + +int add_coord(struct coords *c, int x, int y) { + struct coord *v; + int n; + +#ifdef DEBUG + if (!c) + fprintf(stderr, "add_coord(): got NULL pointer\n"); + + if (c->count >= c->max) + fprintf(stderr, "add_coord(): maximum reached\n"); +#endif + + v = c->values; + + for (n = 0; n < c->count; v++, n++) + if (v->x == x && v->y == y) break; + + if (n == c->count) { + v->x = x; + v->y = y; + c->count++; + return 0; + } + else + return -1; +} + + diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/coord.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/coord.h Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,20 @@ +#ifndef COORD_H +#define COORD_H + +struct coord { + int x; + int y; +}; + +struct coords { + int count; + int max; + struct coord *values; +}; + +struct coords *alloc_coords(int n); +void free_coords(struct coords *c); +int init_coords(struct coords *c, int n); +int add_coord(struct coords *c, int x, int y); + +#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/dct.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/dct.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,651 @@ +#include "wm.h" +#include "dct.h" + +#define INVROOT2 0.7071067814 +#define SWAP(A, B) {double t = A; A = B; B = t;} + +int N; +int M; + +double *dct_NxN_tmp = NULL; +double *dct_NxN_costable = NULL; +int dct_NxN_log2N = 0; + +static const unsigned int JPEG_lumin_quant_table[NJPEG][NJPEG] = { + {16, 11, 10, 16, 24, 40, 51, 61}, + {12, 12, 14, 19, 26, 58, 60, 55}, + {14, 13, 16, 24, 40, 57, 69, 56}, + {14, 17, 22, 29, 51, 87, 80, 62}, + {18, 22, 37, 56, 68, 109, 103, 77}, + {24, 35, 55, 64, 81, 104, 113, 92}, + {49, 64, 78, 87, 103, 121, 120, 101}, + {72, 92, 95, 98, 112, 100, 103, 99}}; + +static void initcosarray() +{ + int i,group,base,item,nitems,halfN; + double factor; + + dct_NxN_log2N = -1; + do{ + dct_NxN_log2N++; + if ((1<N){ + fprintf(stderr, "dct_NxN: %d not a power of 2\n", N); + exit(1); + } + }while((1<>1; + while(j>m){ + j=j-m; + m=(m+1)>>1; + } + j=j+m; + } +} + +static void inv_sums(double *f) +{ + int stepsize,stage,curptr,nthreads,thread,step,nsteps; + + for(stage=1; stage <=dct_NxN_log2N-1; stage++){ + nthreads = 1<<(stage-1); + stepsize = nthreads<<1; + nsteps = (1<<(dct_NxN_log2N-stage)) - 1; + for(thread=1; thread<=nthreads; thread++){ + curptr=N-thread; + for(step=1; step<=nsteps; step++){ + f[curptr] += f[curptr-stepsize]; + curptr -= stepsize; + } + } + } +} + +static void fwd_sums(double *f) +{ + int stepsize,stage,curptr,nthreads,thread,step,nsteps; + + for(stage=dct_NxN_log2N-1; stage >=1; stage--){ + nthreads = 1<<(stage-1); + stepsize = nthreads<<1; + nsteps = (1<<(dct_NxN_log2N-stage)) - 1; + for(thread=1; thread<=nthreads; thread++){ + curptr=nthreads +thread-1; + for(step=1; step<=nsteps; step++){ + f[curptr] += f[curptr+stepsize]; + curptr += stepsize; + } + } + } +} + +static void scramble(double *f,int len){ + int i,ii1,ii2; + + bitrev(f,len); + bitrev(&f[0], len>>1); + bitrev(&f[len>>1], len>>1); + ii1=len-1; + ii2=len>>1; + for(i=0; i<(len>>2); i++){ + SWAP(f[ii1], f[ii2]); + ii1--; + ii2++; + } +} + +static void unscramble(double *f,int len) +{ + int i,ii1,ii2; + + ii1 = len-1; + ii2 = len>>1; + for(i=0; i<(len>>2); i++){ + SWAP(f[ii1], f[ii2]); + ii1--; + ii2++; + } + bitrev(&f[0], len>>1); + bitrev(&f[len>>1], len>>1); + bitrev(f,len); +} + +static void inv_butterflies(double *f) +{ + int stage,ii1,ii2,butterfly,ngroups,group,wingspan,increment,baseptr; + double Cfac,T; + + for(stage=1; stage<=dct_NxN_log2N;stage++){ + ngroups=1<<(dct_NxN_log2N-stage); + wingspan=1<<(stage-1); + increment=wingspan<<1; + for(butterfly=1; butterfly<=wingspan; butterfly++){ + Cfac = dct_NxN_costable[wingspan+butterfly-1]; + baseptr=0; + for(group=1; group<=ngroups; group++){ + ii1=baseptr+butterfly-1; + ii2=ii1+wingspan; + T=Cfac * f[ii2]; + f[ii2]=f[ii1]-T; + f[ii1]=f[ii1]+T; + baseptr += increment; + } + } + } +} + +static void fwd_butterflies(double *f) +{ + int stage,ii1,ii2,butterfly,ngroups,group,wingspan,increment,baseptr; + double Cfac,T; + + for(stage=dct_NxN_log2N; stage>=1;stage--){ + ngroups=1<<(dct_NxN_log2N-stage); + wingspan=1<<(stage-1); + increment=wingspan<<1; + for(butterfly=1; butterfly<=wingspan; butterfly++){ + Cfac = dct_NxN_costable[wingspan+butterfly-1]; + baseptr=0; + for(group=1; group<=ngroups; group++){ + ii1=baseptr+butterfly-1; + ii2=ii1+wingspan; + T= f[ii2]; + f[ii2]=Cfac *(f[ii1]-T); + f[ii1]=f[ii1]+T; + baseptr += increment; + } + } + } +} + +static void ifct_noscale(double *f) +{ + f[0] *= INVROOT2; + inv_sums(f); + bitrev(f,N); + inv_butterflies(f); + unscramble(f,N); +} + +static void fct_noscale(double *f) +{ + scramble(f,N); + fwd_butterflies(f); + bitrev(f,N); + fwd_sums(f); + f[0] *= INVROOT2; +} + +void fdct_NxN(gray **pixels, double **dcts) { + int u,v; + double two_over_sqrtncolsnrows = 2.0/sqrt((double) N*M); + + for (u=0; u < N; u++) + for (v=0; v < M; v++) + dcts[u][v] = ((int) pixels[u][v] - 128); + + for (u=0; u<=M-1; u++){ + fct_noscale(dcts[u]); + } + for (v=0; v<=N-1; v++){ + for (u=0; u<=M-1; u++){ + dct_NxN_tmp[u] = dcts[u][v]; + } + fct_noscale(dct_NxN_tmp); + for (u=0; u<=M-1; u++){ + dcts[u][v] = dct_NxN_tmp[u]*two_over_sqrtncolsnrows; + } + } +} + +void idct_NxN(double **dcts, gray **pixels) { + int u,v; + double two_over_sqrtncolsnrows = 2.0/sqrt((double) N*M); + + double **tmp; + + tmp = alloc_coeffs(N, N); + for (u=0;u rint(log(MIN(cols, rows))/log(2.0)) - 2) { + fprintf(stderr, "init_dwt(): level parameter does not match image width/height\n"); + return; + } +#endif + + if (dwt_filters && level != dwt_levels) { + free(dwt_filters); + dwt_filters = NULL; + } + + dwt_levels = level; + + if (!dwt_filters) + dwt_filters = calloc(level + 1, sizeof(FilterGH)); + + for (i = 0; i < level + 1; i++) + dwt_filters[i] = (dwt_allfilters->filter)[filter]; + + dwt_filter = filter; + dwt_method = method; + dwt_cols = cols; + dwt_rows = rows; +} + +Image_tree fdwt(gray **pixels) { + Image image; + Image_tree tree; + int i, j; + + image = new_image(dwt_cols, dwt_rows); + + for (i = 0; i < dwt_rows; i++) + for (j = 0; j < dwt_cols; j++) + set_pixel(image, j, i, pixels[i][j]); + + tree = wavelettransform(image, dwt_levels, dwt_filters, dwt_method); + free_image(image); + + return tree; +} + +Image_tree fdwt_wp(gray **pixels) { + Image image; + Image_tree tree; + int i, j; + + image = new_image(dwt_cols, dwt_rows); + + for (i = 0; i < dwt_rows; i++) + for (j = 0; j < dwt_cols; j++) + set_pixel(image, j, i, pixels[i][j]); + + tree = wavelettransform_wp(image, dwt_levels, dwt_filters, dwt_method); + free_image(image); + + return tree; +} + +void idwt(Image_tree dwts, gray **pixels) { + Image image; + int i, j; + + image = inv_transform(dwts, dwt_filters, dwt_method + 1); + + for (i = 0; i < dwt_rows; i++) + for (j = 0; j < dwt_cols; j++) + pixels[i][j] = PIXELRANGE((int) (get_pixel(image, j, i) + 0.5)); + + free_image(image); +} + +void idwt_wp(Image_tree dwts, gray **pixels) { + Image image; + int i, j; + + image = inv_transform(dwts, dwt_filters, dwt_method + 1); + + for (i = 0; i < dwt_rows; i++) + for (j = 0; j < dwt_cols; j++) + pixels[i][j] = PIXELRANGE((int) (get_pixel(image, j, i) + 0.5)); + + free_image(image); +} + +int gen_pollen_filter(double *filter, double alpha, double beta, int which) { + int i, j, k, filterlength; + double tf[6]; + + /* parameter alpha, beta have to be in range -Pi .. Pi */ + if (alpha < -M_PI || alpha >= M_PI) { + fprintf(stderr, "alpha %f out of range\n", alpha); + return -1; + } + + if (beta < -M_PI || beta >= M_PI) { + fprintf(stderr, "beta %f out of range\n", beta); + return -1; + } + + /* generate Pollen filter coefficients, see http://www.dfw.net/~cody for details */ + tf[0] = ((1.0 + cos(alpha) + sin(alpha)) * (1.0 - cos(beta) - sin(beta)) + 2.0 * sin(beta) * cos(alpha)) / 4.0; + tf[1] = ((1.0 - cos(alpha) + sin(alpha)) * (1.0 + cos(beta) - sin(beta)) - 2.0 * sin(beta) * cos(alpha)) / 4.0; + tf[2] = (1.0 + cos(alpha - beta) + sin(alpha - beta)) / 2.0; + tf[3] = (1.0 + cos(alpha - beta) - sin(alpha - beta)) / 2.0; + tf[4] = 1.0 - tf[0] - tf[2]; + tf[5] = 1.0 - tf[1] - tf[3]; + + /* set close-to-zero filter coefficients to zero */ + for (i = 0; i < 6; i++) + if (fabs(tf[i]) < 1.0e-15) tf[i] = 0.0; + + /* find the first non-zero wavelet coefficient */ + i = 0; + while (tf[i] == 0.0) i++; + + /* find the last non-zero wavelet coefficient */ + j = 5; + while (tf[j] == 0.0) j--; + + filterlength = j - i + 1; + for (k = 0; k < filterlength; k++) + switch (which) { + case FILTERH: + filter[k] = tf[j--] / 2.0; + break; + case FILTERG: + filter[k] = (double) (((i & 0x01) * 2) - 1) * tf[i] / 2.0; + i++; + break; + case FILTERHi: + filter[k] = tf[j--]; + break; + case FILTERGi: + filter[k] = (double) (((i & 0x01) * 2) - 1) * tf[i]; + i++; + break; + default: + return -1; + } + + while (k < 6) + filter[k++] = 0.0; + + return filterlength; +} + +void dwt_pollen_filter(double alpha, double beta) { + FilterGH filter; + int i; + + filter = malloc(sizeof(struct FilterGHStruct)); +#ifdef DEBUG + if (!filter) { + fprintf(stderr, "dwt_pollen_filter(): malloc failed()\n"); + return; + } +#endif + + filter->type = FTOther; + filter->name = "pollen"; + + filter->g = new_filter(6); + filter->g->type = FTSymm; + filter->g->hipass = 1; + filter->g->len = gen_pollen_filter(filter->g->data, alpha, beta, FILTERG); + filter->g->start = -filter->g->len / 2; + filter->g->end = filter->g->len / 2 - 1; + + filter->h = new_filter(6); + filter->h->type = FTSymm; + filter->h->hipass = 0; + filter->h->len = gen_pollen_filter(filter->h->data, alpha, beta, FILTERH); + filter->h->start = -filter->h->len / 2; + filter->h->end = filter->h->len / 2 - 1; + + filter->gi = new_filter(6); + filter->gi->type = FTSymm; + filter->gi->hipass = 1; + filter->gi->len = gen_pollen_filter(filter->gi->data, alpha, beta, FILTERGi); + filter->gi->start = -filter->gi->len / 2; + filter->gi->end = filter->gi->len / 2 - 1; + + filter->hi = new_filter(6); + filter->hi->type = FTSymm; + filter->hi->hipass = 0; + filter->hi->len = gen_pollen_filter(filter->hi->data, alpha, beta, FILTERHi); + filter->hi->start = -filter->hi->len / 2; + filter->hi->end = filter->hi->len / 2 - 1; + +#ifdef DEBUG + if (dwt_levels <= 0) { + fprintf(stderr, "dwt_pollen_filter(): level invalid - set to zero\n"); + return; + } +#endif + +#ifdef DEBUG + if (!dwt_filters) { + fprintf(stderr, "dwt_pollen_filter(): wm_dwt not initialized, call init_dwt() first\n"); + return; + } +#endif + + for (i = 0; i < dwt_levels + 1; i++) + dwt_filters[i] = filter; +} + +int gen_param_filter(double *filter, int n, double alpha[], int which) { + int i, j, k, filterlength; + double *tf, *t; + + tf = malloc(2 * (n + 1) * sizeof(double)); + t = malloc(2 * (n + 1) * sizeof(double)); + if (!tf) { + fprintf(stderr, "gen_param_filter(): malloc() failed\n"); + return -1; + } + + tf[0] = 1.0 / sqrt(2.0); + tf[1] = 1.0 / sqrt(2.0); + + for (k = 0; k < n; k++) { + for (i = 0; i < 2 * (k + 2); i++) { + +#define H(X) (((X) < 0 || (X) >= 2 * (k + 1)) ? 0.0 : tf[X]) + + t[i] = 0.5 * (H(i - 2) + H(i) + + cos(alpha[k]) * (H(i - 2) - H(i)) + + (i & 1 ? -1.0 : 1.0) * sin(alpha[k]) * (H(2 * (k + 2) - i - 1) - H(2 * (k + 2) - i - 3))); + } + for (i = 0; i < 2 * (k + 2); i++) tf[i] = t[i]; + } + + /* set close-to-zero filter coefficients to zero */ + for (i = 0; i < 2 * (n + 1) ; i++) + if (fabs(tf[i]) < 1.0e-15) tf[i] = 0.0; + + /* find the first non-zero wavelet coefficient */ + i = 0; + while (tf[i] == 0.0) i++; + + /* find the last non-zero wavelet coefficient */ + j = 2 * (n + 1) - 1; + while (tf[j] == 0.0) j--; + + filterlength = j - i + 1; + for (k = 0; k < filterlength; k++) + switch (which) { + case FILTERG: + case FILTERGi: + filter[k] = (double) ((((i+1) & 0x01) * 2) - 1) * tf[i]; + i++; + break; + case FILTERH: + case FILTERHi: + filter[k] = tf[j--]; + break; + default: + return -1; + } + + while (k < 2 * (n + 1)) + filter[k++] = 0.0; + + return filterlength; +} + +void dwt_param_filter(double alpha[], int param_len[]) { + FilterGH filter; + int i; + int param_len_sum = 0; + +#ifdef DEBUG + if (dwt_levels <= 0) { + fprintf(stderr, "dwt_param_filter(): level invalid - set to zero\n"); + return; + } +#endif + +#ifdef DEBUG + if (!dwt_filters) { + fprintf(stderr, "dwt_param_filter(): wm_dwt not initialized, call init_dwt() first\n"); + return; + } +#endif + + + for (i = 0; i < dwt_levels + 1; i++) { + + filter = malloc(sizeof(struct FilterGHStruct)); +#ifdef DEBUG + if (!filter) { + fprintf(stderr, "dwt_param_filter(): malloc failed()\n"); + return; + } +#endif + + filter->type = FTOrtho; + filter->name = "param"; + + filter->g = new_filter(2 * (param_len[i] + 1)); + filter->g->type = FTSymm; + filter->g->hipass = 1; + filter->g->len = gen_param_filter(filter->g->data, + param_len[i], &alpha[param_len_sum], + FILTERG); + filter->g->start = -filter->g->len / 2; + filter->g->end = filter->g->len / 2 - 1; + + filter->h = new_filter(2 * (param_len[i] + 1)); + filter->h->type = FTSymm; + filter->h->hipass = 0; + filter->h->len = gen_param_filter(filter->h->data, + param_len[i], &alpha[param_len_sum], + FILTERH); + filter->h->start = -filter->h->len / 2; + filter->h->end = filter->h->len / 2 - 1; + + filter->gi = 0; + filter->hi = 0; + + dwt_filters[i] = filter; + + param_len_sum += param_len[i]; + } +} + +void done_dwt() { +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/dwt.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/dwt.h Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,24 @@ +#ifndef DWT_H +#define DWT_H + +#include "wm.h" +#include "netpbm/pgm.h" +#include "wavelet.h" + +#define FILTERG 1 +#define FILTERH 2 +#define FILTERGi 3 +#define FILTERHi 4 + +void init_dwt(int cols, int rows, const char *filter_name, int filter, int level, int method); +Image_tree fdwt(gray **input); +Image_tree fdwt_wp(gray **input); +void idwt(Image_tree dwts, gray **output); +void idwt_wp(Image_tree dwts, gray **output); +int gen_pollen_filter(double *filter, double alpha, double beta, int which); +void dwt_pollen_filter(double alpha, double beta); +int gen_param_filter(double *filter, int n, double alpha[], int which); +void dwt_param_filter(double alpha[], int param_len[]); +void done_dwt(); + +#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/dwt_util.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/dwt_util.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,159 @@ +#include "wm.h" +#include "dwt_util.h" +#include + +void copy_coeffs_from_dwt(double ** block_coeffs, double ** dwt_coeffs, +int level, int band, int width, int height) { + int i, j; + int size = width >> level; + int h = (band > 2) ? size : 0; + int w = (band & 1) ? 0 : size; + + for (i = 0; i < size; i++) + for (j = 0; j < size; j++) + block_coeffs[i][j] = dwt_coeffs[h + i][w + j]; +} + +void copy_coeffs_to_dwt(double ** dwt_coeffs, double ** block_coeffs, +int level, int band, int width, int height) { + int i, j; + int size = width >> level; + int h = (band > 2) ? size : 0; + int w = (band & 1) ? 0 : size; + + for (i = 0; i < size; i++) + for (j = 0; j < size; j++) + dwt_coeffs[h + i][w + j] = block_coeffs[i][j]; +} + +char *subband_name(int type) { + switch (type) { + case LL: return "LL"; + case HL: return "HL"; + case LH: return "LH"; + case HH: return "HH"; + default: return "XX"; + } +} + +int subband_in_list(char *list, int type, int level) { + return 1; +} + +int subband_wp_in_list(char *list, char *name) { + return 1; +} + +int calc_subband_wp_level(char *name){ + return strlen(name); +} + +void calc_subband_location(int cols, int rows, int type, int level, int *col, int *row) { + *col = *row = 0; + + if (level <= 0 || level > find_deepest_level(cols, rows) - 1) return; + + switch (type) { + case LL: + break; + case HL: + *col = 0; + *row = rows >> level; + break; + case LH: + *col = cols >> level; + *row = 0; + break; + case HH: + *col = cols >> level; + *row = rows >> level; + break; + default: + break; + } +} + +void calc_subband_wp_location(int cols, int rows, char *name, int *col, int *row) { + char *p = name; + int level = 0; + *col = *row = 0; + + while (*p) { + level++; + switch (toupper(*p)) { + case 'A': + break; + case 'H': + *col += (cols >> level); + break; + case 'V': + *row += (rows >> level); + break; + case 'D': + *col += (cols >> level); + *row += (rows >> level); + break; + default: + break; + } + p++; + } +} + +Pixel *get_dwt_data(Image_tree dwt, int level, int type) { + return get_dwt_image(dwt, level, type)->data; +} + +Image get_dwt_image(Image_tree dwt, int level, int type) { + return get_dwt_subband(dwt, level, type)->image; +} + +Image_tree get_dwt_subband(Image_tree dwt, int level, int type) { + while (--level) + dwt = dwt->coarse; + + switch (type) { + case LL: + return dwt->coarse; + case HL: + return dwt->vertical; + case LH: + return dwt->horizontal; + case HH: + return dwt->diagonal; + } + + return NULL; +} + +Pixel get_dwt_coeff(Image_tree dwt, int level, int type, int coeff) { + return get_dwt_data(dwt, level, type)[coeff]; +} + +Pixel get_dwt_location(Image_tree dwt, int level, int type, int col, int row) { + return get_pixel(get_dwt_image(dwt, level, type), col, row); +} + +static void calc__subband(Image_tree p, Image_tree q, double *min, double *max, double *error) { + int i; + + if (!p || !q) return; + + *error = 0; + *min = *max = fabs(p->image->data[0] - q->image->data[0]); + for (i = 0; i < p->image->size; i++) { + double diff = fabs(p->image->data[i] - q->image->data[i]); + + *error += sqr(diff); + if (diff < *min) *min = diff; + if (diff > *max) *max = diff; + } +} + +void calc_subband(Image_tree p, Image_tree q, int type, double *min, double *max, double *error) { + calc__subband(p, q, min, max, error); +} + +void calc_subband_wp(Image_tree p, Image_tree q, char *name, double *min, double *max, double *error) { + calc__subband(p, q, min, max, error); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/dwt_util.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/dwt_util.h Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,41 @@ +#ifndef DWT_UTIL_H +#define DWT_UTIL_H + +#include "dwt.h" + +#define LL 1 +#define LH 2 +#define HL 3 +#define HH 4 + +#define COARSE LL +#define HORIZONTAL LH +#define VERTICAL HL +#define DIAGONAL HH + +void copy_coeffs_from_dwt(double ** block_coeffs, double ** dwt_coeffs, + int level, int band, int width, int height); + +void copy_coeffs_to_dwt(double ** dwt_coeffs, double ** block_coeffs, + int level, int band, int width, int height); + +char *subband_name(int type); + +int subband_in_list(char *list, int type, int level); +int subband_wp_in_list(char *list, char *name); + +void calc_subband_location(int cols, int rows, int type, int level, int *col, int *row); +void calc_subband_wp_location(int cols, int rows, char *name, int *col, int *row); +int calc_subband_wp_level(char *name); + +Pixel *get_dwt_data(Image_tree dwt, int level, int type); +Image get_dwt_image(Image_tree dwt, int level, int type); +Image_tree get_dwt_subband(Image_tree dwt, int level, int type); +Pixel get_dwt_coeff(Image_tree dwt, int level, int type, int coeff); +Pixel get_dwt_location(Image_tree dwt, int level, int type, int col, int row); + +void calc_subband(Image_tree p, Image_tree q, int type, double *min, double *max, double *error); +void calc_subband_wp(Image_tree p, Image_tree q, char *name, double *min, double *max, double *error); + + +#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/filter.dat --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/filter.dat Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,774 @@ +{ + Name biortho nr. 1 + Type biorthogonal + { + Type symm + Length 3 + Start 0 + End 2 + 0.353553 + -0.707107 + 0.353553 + } + { + Type symm + Length 5 + Start -2 + End 2 + -0.176777 + 0.353553 + 1.060660 + 0.353553 + -0.176777 + } + { + Type symm + Length 5 + Start -1 + End 3 + 0.176777 + 0.353553 + -1.060660 + 0.353553 + 0.176777 + } + { + Type symm + Length 3 + Start -1 + End 1 + 0.353553 + 0.707107 + 0.353553 + } +} + +{ + Name biortho nr. 2 + Type biorthogonal + { + Type symm + Length 7 + Start -4 + End 2 + -0.064539 + 0.040689 + 0.418092 + -0.788486 + 0.418092 + 0.040689 + -0.064539 + } + { + Type symm + Length 9 + Start -4 + End 4 + 0.037828 + -0.023849 + -0.110624 + 0.377402 + 0.852699 + 0.377402 + -0.110624 + -0.023849 + 0.037828 + } + { + Type symm + Length 9 + Start -5 + End 3 + -0.037828 + -0.023849 + 0.110624 + 0.377402 + -0.852699 + 0.377402 + 0.110624 + -0.023849 + -0.037828 + } + { + Type symm + Length 7 + Start -3 + End 3 + -0.064539 + -0.040689 + 0.418092 + 0.788486 + 0.418092 + -0.040689 + -0.064539 + } +} +{ + Name Daubechies 4 + Type orthogonal + { + Type symm + Length 4 + Start -1 + End 2 + + -0.129409522551 + -0.224143868042 + 0.836516303737 + -0.482962913144 + + } + { + Type symm + Length 4 + Start -1 + End 2 + + 0.482962913144 + 0.836516303737 + 0.224143868042 + -0.129409522551 + + } +} + +{ + Name Daubechies 6 + Type orthogonal + { + Type symm + Length 6 + Start -3 + End 2 + + 0.035226291882 + 0.085441273882 + -0.135011020010 + -0.459877502118 + 0.806891509311 + -0.332670552950 + + + } + { + Type symm + Length 6 + Start -1 + End 4 + + 0.332670552950 + 0.806891509311 + 0.459877502118 + -0.135011020010 + -0.085441273882 + 0.035226291882 + + } +} +{ + Name Daubechies 8 + Type orthogonal + { + Type symm + Length 8 + Start -1 + End 6 + + + -0.010597401785 + -0.032883011667 + 0.030841381836 + 0.187034811719 + -0.027983769417 + -0.630880766793 + 0.714846570553 + -0.230377813309 + + } + { + Type symm + Length 8 + Start -1 + End 6 + + 0.230377813309 + 0.714846570553 + 0.630880766793 + -0.027983769417 + -0.187034811719 + 0.030841381836 + 0.032883011667 + -0.010597401785 + + } +} +{ + Name Daubechies 10 + Type orthogonal + { + Type symm + Length 10 + Start -2 + End 7 + + 0.0033357252854738 + 0.0125807519990820 + -0.0062414902127983 + -0.0775714938400459 + -0.0322448695846381 + 0.2422948870663823 + 0.1384281459013203 + -0.7243085284377726 + 0.6038292697971895 + -0.1601023979741929 + + } + { + Type symm + Length 10 + Start -2 + End 7 + + 0.1601023979741929 + 0.6038292697971895 + 0.7243085284377726 + 0.1384281459013203 + -0.2422948870663823 + -0.0322448695846381 + 0.0775714938400459 + -0.0062414902127983 + -0.0125807519990820 + 0.0033357252854738 + + } +} + +{ + Name Daubechies 12 + Type orthogonal + { + Type symm + Length 12 + Start -1 + End 10 + + -0.0010773010853085 + -0.0047772575119455 + 0.0005538422011614 + 0.0315820393184862 + 0.0275228655303053 + -0.0975016055873225 + -0.1297668675672625 + 0.2262646939654400 + 0.3152503517091982 + -0.7511339080210959 + 0.4946238903984533 + -0.1115407433501095 + + } + { + Type symm + Length 12 + Start -1 + End 10 + + 0.1115407433501095 + 0.4946238903984533 + 0.7511339080210959 + 0.3152503517091982 + -0.2262646939654400 + -0.1297668675672625 + 0.0975016055873225 + 0.0275228655303053 + -0.0315820393184862 + 0.0005538422011614 + 0.0047772575119455 + -0.0010773010853085 + + } +} + +{ + Name Daubechies 14 + Type orthogonal + { + Type symm + Length 14 + Start -1 + End 12 + + 0.0003537138 + 0.001801640704 + 0.000429577973 + -0.012550998556 + -0.016574541631 + 0.038029936935 + 0.0806112609151 + -0.071309219267 + -0.224036184994 + 0.143906003929 + 0.469782287405 + -0.729132090846 + 0.396539319482 + -0.077852054085 + + } + { + Type symm + Length 14 + Start -1 + End 12 + + 0.077852054085 + 0.396539319482 + 0.729132090846 + 0.469782287405 + -0.143906003929 + -0.224036184994 + 0.071309219267 + 0.0806112609151 + -0.038029936935 + -0.016574541631 + 0.012550998556 + 0.000429577973 + -0.001801640704 + 0.0003537138 + + } +} + + +{ + Name Daubechies 20 + Type orthogonal + { + Type symm + Length 20 + Start -1 + End 18 + + -0.000013264203 + -0.000093588670 + -0.000116466855 + 0.000685856695 + 0.001992405295 + 0.001395351747 + -0.010733175483 + -0.003606553567 + 0.033212674059 + 0.029457536822 + -0.071394147166 + -0.093057364604 + 0.127369340336 + 0.195946274377 + -0.249846424327 + -0.281172343661 + 0.688459039454 + -0.527201188932 + 0.188176800078 + -0.026670057901 + + } + { + Type symm + Length 20 + Start -1 + End 18 + + 0.026670057901 + 0.188176800078 + 0.527201188932 + 0.688459039454 + 0.281172343661 + -0.249846424327 + -0.195946274377 + 0.127369340336 + 0.093057364604 + -0.071394147166 + -0.029457536822 + 0.033212674059 + 0.003606553567 + -0.010733175483 + 0.001395351747 + 0.001992405295 + -0.000685856695 + -0.000116466855 + 0.000093588670 + -0.000013264203 + } +} + + +{ + Name Beylkin 18 + Type orthogonal + { + Type symm + Length 18 + Start -1 + End 16 + + 0.00064048532852124535 + 0.0027360316262586061 + 0.0014842347824723461 + -0.01004041184463199 + -0.014365807968852611 + 0.017460408696028829 + 0.042916387274192273 + -0.01967986604432212 + -0.088543630622924835 + 0.017520746266529649 + 0.1555387318770938 + -0.02690030880369032 + -0.26449723144638482 + 0.1109275983482343 + 0.44971825114946867 + -0.69982521405660059 + 0.42421536081296141 + -0.099305765374353927 + + } + { + Type symm + Length 18 + Start -1 + End 16 + + 0.099305765374353927 + 0.42421536081296141 + 0.69982521405660059 + 0.44971825114946867 + -0.1109275983482343 + -0.26449723144638482 + 0.02690030880369032 + 0.1555387318770938 + -0.017520746266529649 + -0.088543630622924835 + 0.01967986604432212 + 0.042916387274192273 + -0.017460408696028829 + -0.014365807968852611 + 0.01004041184463199 + 0.0014842347824723461 + -0.0027360316262586061 + 0.00064048532852124535 + + } +} + + +{ + Name Vaidyanathan 24 + Type orthogonal + { + Type symm + Length 24 + Start -1 + End 22 + + 0.045799334110976718 + -0.25018412950466218 + 0.57279779321073432 + -0.63560105987221494 + 0.20161216177530866 + 0.26349480248845991 + -0.19445047176647817 + -0.13508422712948126 + 0.13197166141697772 + 0.08392888436611283 + -0.07770975090196941 + -0.055892523691373548 + 0.03874261929341144 + 0.035470398607283453 + -0.014853448005230099 + -0.019687215010072714 + 0.003153847055897004 + 0.008839103408613878 + 0.00070813750405244471 + -0.0028438345468355646 + -0.00094489713632194927 + 0.00045395661963721929 + 0.00034363190482102919 + 0.000062906118190737523 + + } + { + Type symm + Length 24 + Start -1 + End 22 + + -0.000062906118190737523 + 0.00034363190482102919 + -0.00045395661963721929 + -0.00094489713632194927 + 0.0028438345468355646 + 0.00070813750405244471 + -0.008839103408613878 + 0.003153847055897004 + 0.019687215010072714 + -0.014853448005230099 + -0.035470398607283453 + 0.03874261929341144 + 0.055892523691373548 + -0.07770975090196941 + -0.08392888436611283 + 0.13197166141697772 + 0.13508422712948126 + -0.19445047176647817 + -0.26349480248845991 + 0.20161216177530866 + 0.63560105987221494 + 0.57279779321073432 + 0.25018412950466218 + 0.045799334110976718 + } +} + + +{ + Name Coifman 6 + Type orthogonal + { + Type symm + Length 6 + Start -1 + End 4 + + 0.226584276197068560 + -0.745687558934434280 + 0.607391641385684120 + 0.077161555495773498 + -0.12696912539620520 + 0.038580777747886749 + + } + { + Type symm + Length 6 + Start -1 + End 4 + + 0.038580777747886749 + -0.12696912539620520 + -0.077161555495773498 + 0.607391641385684120 + 0.745687558934434280 + 0.226584276197068560 + } +} + + +{ + Name Coifman 12 + Type orthogonal + { + Type symm + Length 12 + Start -1 + End 10 + + -0.000720549445369115120 + 0.00182320887091009920 + 0.00561143481936598850 + -0.0236801719468767500 + -0.0594344186464712400 + 0.0764885990782645940 + 0.417005184423777600 + -0.812723635449606130 + 0.386110066823092900 + 0.0673725547222998740 + -0.0414649367819664850 + -0.0163873364631797850 + + } + { + Type symm + Length 12 + Start -1 + End 10 + + 0.0163873364631797850 + -0.0414649367819664850 + -0.0673725547222998740 + 0.386110066823092900 + 0.812723635449606130 + 0.417005184423777600 + -0.0764885990782645940 + -0.0594344186464712400 + 0.0236801719468767500 + 0.00561143481936598850 + -0.00182320887091009920 + -0.000720549445369115120 + + } +} + + +{ + Name Coifman 18 + Type orthogonal + { + Type symm + Length 18 + Start -1 + End 16 + + -0.000034599773197402695 + 0.000070983302505704928 + 0.00046621695982014403 + -0.00111751877082696180 + -0.0025745176881279692 + 0.0090079761367322896 + 0.0158805448636159010 + -0.0345550275733444640 + -0.082301927106320283 + 0.071799821619170590 + 0.428483476377618690 + -0.793777222625620340 + 0.405176902409616790 + 0.0611233900029556980 + -0.0657719112814312280 + -0.0234526961421191030 + 0.00778259642567178690 + 0.00379351286437787590 + + } + { + Type symm + Length 18 + Start -1 + End 16 + + -0.00379351286437787590 + 0.00778259642567178690 + 0.0234526961421191030 + -0.0657719112814312280 + -0.0611233900029556980 + 0.405176902409616790 + 0.793777222625620340 + 0.428483476377618690 + -0.071799821619170590 + -0.082301927106320283 + 0.0345550275733444640 + 0.0158805448636159010 + -0.0090079761367322896 + -0.0025745176881279692 + 0.00111751877082696180 + 0.00046621695982014403 + -0.000070983302505704928 + -0.000034599773197402695 + + } +} + +{ + Name Biorthogonal 1,3 + Type biorthogonal + { + Type symm + Length 6 + Start -1 + End 4 + + -0.08838834764832 + -0.08838834764832 + 0.707106781 + -0.707106781 + 0.08838834764832 + 0.08838834764832 + + } + { + Type symm + Length 2 + Start 1 + End 2 + 0.707106781 + 0.707106781 + + } + + { + Type symm + Length 2 + Start 1 + End 2 + 0.707106781 + -0.707106781 + } + { + Type symm + Length 6 + Start -1 + End 4 + + -0.08838834764832 + 0.08838834764832 + 0.707106781 + 0.707106781 + 0.08838834764832 + -0.08838834764832 + + } +} + +{ + Name Biorthogonal 1,5 + Type biorthogonal + { + Type symm + Length 10 + Start -1 + End 8 + + 0.01657281518406 + 0.01657281518406 + -0.1215339780164 + -0.1215339780164 + 0.707106781 + -0.707106781 + 0.1215339780164 + 0.1215339780164 + -0.01657281518406 + -0.01657281518406 + + } + { + Type symm + Length 2 + Start 3 + End 4 + + 0.707106781 + 0.707106781 + } + + { + Type symm + Length 2 + Start 3 + End 4 + + 0.707106781 + -0.707106781 + } + { + Type symm + Length 10 + Start -1 + End 8 + + 0.01657281518406 + -0.01657281518406 + -0.1215339780164 + 0.1215339780164 + 0.707106781 + 0.707106781 + 0.1215339780164 + -0.1215339780164 + -0.01657281518406 + 0.01657281518406 + + } +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/frid2_common.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/frid2_common.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,220 @@ +#include "frid2_common.h" +#include "signature-utils.h" +#include "wm.h" + +extern char *progname; + +void embed_low_freq(double **dcts, int cols, int rows, double alpha, int verbose) { + int n; + int row, col, dir; + + n = 0; + row = col = 0; + dir = 1; + while (n < nbit_signature) { + double d, x; + int embed; + int out; + + col -= dir; + row += dir; + if (col < 0) { dir = -1; col = 0; } + if (col >= cols) { dir = 1; col = cols - 1; row += 2; } + if (row < 0) { dir = 1; row = 0; } + if (row >= rows) { dir = -1; row = rows - 1; col += 2; } + + d = dcts[row][col]; + if (fabs(d) <= 1.0) { + if (verbose > 3) + fprintf(stderr, "%s: bit #%d - skipped (%d/%d)\n", progname, n, col, row); + continue; + } + + embed = 2 * get_signature_bit(n) - 1; + + x = (d > 0.0) ? 1.0 : -1.0; + out = 1; + while (fabs(x) < fabs(d)) { + x *= FORWARD_STEP(alpha); + out =- out; + } + + if (out != embed) { + if (fabs(d - x) < fabs(d - x * BACKWARD_STEP(alpha))) + x *= FORWARD_STEP(alpha); + else + x *= BACKWARD_STEP(alpha); + } + + d = (x + x * BACKWARD_STEP(alpha)) / 2.0; + + if (verbose > 3) + fprintf(stderr, "%s: embedding bit #%d (= %d) at (%d/%d): %f -> %f\n", progname, n, get_signature_bit(n), col, row, dcts[row][col], d); + + dcts[row][col] = d; + + n++; + } +} + +void embed_med_freq(double **dcts, int cols, int rows, double gamma, int seed, int verbose) { + // select mid-frequency (30%) coefficients + int start = (int) (0.35 * rows * cols + 0.5); + int end = (int) (0.65 * rows * cols + 0.5); + + double *vector; + int x = 0, y = 0, dir = 1; + int i, j; + + vector = malloc((end - start) * sizeof(double)); + for (i = 0; i < (end - start); i++) + vector[i] = 0.0; + + // create pseudo-random vector + srandom(seed); + for (i = 0; i < nbit_signature; i++) { + if (get_signature_bit(i)) + random(); + for (j = 0; j < (end - start); j++) + vector[j] += (double) (random() & RAND_MAX) / (double) RAND_MAX - 0.5; + if (!get_signature_bit(i)) + random(); + } + + for (i = 0; i < (end - start); i++) + vector[i] /= sqrt(nbit_signature); + + for (i = 0; i < end; i++) { + // zig-zag scan + x -= dir; + y += dir; + if (x < 0) { dir = -1; x = 0; } + if (x >= cols) { dir = 1; x = cols - 1; y += 2; } + if (y < 0) { dir = 1; y = 0; } + if (y >= rows) { dir = -1; y = rows - 1; x += 2; } + + // embed vector + if ((i - start) >= 0) { +// fprintf(stderr, "%d/%d: %f -> %f\n", x, y, dcts[y][x], dcts[y][x] + gamma * vector[i - start]); + dcts[y][x] += gamma * vector[i - start]; + } + } + + free(vector); +} + +double detect_low_freq(double **dcts, int cols, int rows, double alpha, double beta, int verbose) { + int n; + int row, col, dir; + double sum1, sum2; + + n = 0; + row = col = 0; + dir = 1; + sum1 = sum2 = 0.0; + while (n < nbit_signature1) { + double d, x; + int detect; + int out; + + col -= dir; + row += dir; + if (col < 0) { dir = -1; col = 0; } + if (col >= cols) { dir = 1; col = cols - 1; row += 2; } + if (row < 0) { dir = 1; row = 0; } + if (row >= rows) { dir = -1; row = rows - 1; col += 2; } + + d = dcts[row][col]; + if (fabs(d) <= 1.0) { + if (verbose > 3) + fprintf(stderr, "%s: bit #%d - skipped (%d/%d)\n", progname, n, col, row); + continue; + } + + detect = 2 * get_signature1_bit(n) - 1; + + x = (d > 0.0) ? 1.0 : -1.0; + out = 1; + while (fabs(x) < fabs(d)) { + x *= FORWARD_STEP(alpha); + out =- out; + } + + if (verbose > 3) + fprintf(stderr, "%s: detected bit #%d (= %d) at (%d/%d): %f\n", progname, n, out > 0 ? 1 : 0, col, row, d); + + set_signature2_bit(n, out > 0 ? 1 : 0); + sum1 += pow(fabs(d), beta) * out * detect; + sum2 += pow(fabs(d), beta); + + n++; + } + + return sum1 / sum2; +} + +double detect_med_freq(double **dcts, int cols, int rows, int seed, int verbose) { + int i, j, k; + int start= (int) (0.35 * rows * cols + 0.5); + int end = (int) (.65 * rows * cols + 0.5); + + int sum, sum1, sum2; + int x = 0, y = 0, dir = 1; + double *vector; + int startx, starty, startdir; + double corr[2]; + double correlation; + + // locate start positions + for (i = 0; i < start; i++) { + x -= dir; + y += dir; + if (x < 0) { dir = -1; x = 0; } + if (x >= cols) { dir = 1; x = cols - 1; y += 2; } + if (y < 0) { dir = 1; y = 0; } + if (y >= rows) { dir = -1; y = rows - 1; x += 2; } + } + + // save start positions + startx = x; + starty = y; + startdir = dir; + srandom(seed); + + vector = malloc((end - start) * sizeof(double)); + + for (i = 0; i < nbit_signature1; i++) { + + for (j = 0; j <= (end - start); j++) + vector[j] = (double) (random() & RAND_MAX) / (double) RAND_MAX - 0.5; + + for (j = 0; j <= 1; j++) { + x = startx; + y = starty; + dir = startdir; + corr[j] = 0; + + for (k = 0; start + k < end; k++) { + x -= dir; + y += dir; + if (x < 0) { dir = -1; x = 0; } + if (x >= cols) { dir = 1; x = cols - 1; y += 2; } + if (y < 0) { dir = 1; y = 0; } + if (y >= rows) { dir = -1; y = rows - 1; x += 2; } + corr[j] += dcts[y][x] * vector[k + j]; + } + } + + set_signature2_bit(i, (corr[0] >= corr[1]) ? 0 : 1); + } + + sum = 0; sum1 = 0; sum2 = 0; + for (i = 0; i < nbit_signature1; i++) { + sum += get_signature1_bit(i) * get_signature2_bit(i); + sum1 += get_signature1_bit(i) * get_signature1_bit(i); + sum2 += get_signature2_bit(i) * get_signature2_bit(i); + } + correlation = (double) sum / (sqrt(sum1) * sqrt(sum2)); + + return correlation; +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/frid2_common.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/frid2_common.h Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,12 @@ +#ifndef FRID2_COMMON_H +#define FRID2_COMMON_H + +#define FORWARD_STEP(A) ((1.0 + A) / (1.0 - A)) +#define BACKWARD_STEP(A) ((1.0 - A) / (1.0 + A)) + +void embed_low_freq(double **dcts, int cols, int rows, double alpha, int verbose); +void embed_med_freq(double **dcts, int cols, int rows, double gamma, int seed, int verbose); +double detect_low_freq(double **dcts, int cols, int rows, double alpha, double beta, int verbose); +double detect_med_freq(double **dcts, int cols, int rows, int seed, int verbose); + +#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_bruyn_sig.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_bruyn_sig.1 Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,89 @@ +.\" +.\" gen_bruyn_sig.1 - the *roff document processor man page source +.\" +.TH gen_bruyn_sig 1 "98/06/30" "Watermarking, Version 1.0" +.SH NAME +gen_bruyn_sig \- an man page source template +.SH SYNOPSIS +.B gen_bruyn_sig +[ +.B \-abcdef +] +[ +.BI \-d opt +] +[ +.BI \-o file +] +[ +.IR files \|.\|.\|.\| +] +.SH DESCRIPTION +.B gen_bruyn_sig +is a program. +.PP +the +.B \-d +option is one of the following: +.TP +.B opt1 for option 1 +.TP +.B opt2 for option 2 +.TP +.B opt3 for option 3 +.LP +I hope you can guess the purpose of the program. +.LP +Can you? +.P +.SH OPTIONS +.TP +.B \-a +option a +.TP +.B \-b +option b +.TP +.B \-c +option c +.TP +.B \-d +option d +.TP +.B \-e +option e +.TP +.B \-f +option f +.PP +These are all the options, now on with some environment variables: +.TP +.SM +.B ENV_VAR1 +environment variable 1 +.TP +.SM +.B ENV_VAR2 +environment variable 2 +.TP +.SM +.B ENV_VAR3 +environment variable 2 +.SH FILES +.SH AUTHOR +Peter Meerwald +.SH NOTES +.SH BUGS +Email bug reports to pmeerw@cosy.sbg.ac.at. +.SH COPYRIGHT +Copyright \(co 1998 Peter Meerwald +.SH AVAILABILITY +The most recent released version of +.B gen_bruyn_sig +is always available +at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the +directory /pub/people/pmeerw/Watermarking. +.SH "SEE ALSO" +.BR program1, +.BR program2, +.BR program3 diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_bruyn_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_bruyn_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,232 @@ +#include "wm.h" +#include "signature.h" +#include "bruyn_common.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-b n] [-k] [-n n] [-o file] [-pP n] [-q n] [-s file] [-S n] [-tT n] file\n\n", progname); + fprintf(stderr, "\t-b n\t\tblock size (default 8)\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-k\t\tdisable block skipping\n"); + fprintf(stderr, "\t-n n\t\twatermark bit length\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-p n\t\tpattern type for zone 1 (default 1, 1.." NPATTERN_USAGE ")\n"); + fprintf(stderr, "\t-P n\t\tpattern type for zone 2 (default 2, 1.." NPATTERN_USAGE ")\n"); + fprintf(stderr, "\t-q n\t\tsignature strength (default 7.0)\n"); + fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); + fprintf(stderr, "\t-S n\t\tseed\n"); + fprintf(stderr, "\t-t n\t\tthreshold for noise (default " THRESHOLD_NOISE_USAGE ")\n"); + fprintf(stderr, "\t-T n\t\tthreshold for slope (default " THRESHOLD_SLOPE_USAGE ")\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int c; + int i; + int b = 8; + int n = 0; + int nb; + int s = 0; + int p1 = 1; + int p2 = 2; + double t1 = THRESHOLD_NOISE; + double t2 = THRESHOLD_SLOPE; + double q = 7.0; + int skipping = 0; + + progname = argv[0]; + wm_init(); + + while ((c = getopt(argc, argv, "b:h?n:o:p:P:q:s:S:t:T:k")) != EOF) { + switch (c) { + case 'b': + b = atoi(optarg); + if (b <= 0) { + fprintf(stderr, "%s: block size %d out of range\n", progname, b); + exit(1); + } + break; + case 'k': + skipping = 1; + break; + case 'h': + case '?': + usage(); + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 1000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'p': + p1 = atoi(optarg); + if (p1 <= 0 || p1 > NPATTERN) { + fprintf(stderr, "%s: pattern type out of range\n", progname); + exit(1); + } + break; + case 'P': + p2 = atoi(optarg); + if (p2 <= 0 || p2 > NPATTERN) { + fprintf(stderr, "%s: pattern type out of range\n", progname); + exit(1); + } + break; + case 'q': + q = atof(optarg); + if (q <= 0.0) { + fprintf(stderr, "%s: signature strength factor %f out of range\n", progname, q); + exit(1); + } + break; + case 't': + t1 = atof(optarg); + if (t1 <= 0) { + fprintf(stderr, "%s: noise threshold %f out of range\n", progname, t1); + } + break; + case 'T': + t2 = atof(optarg); + if (t2 <= 0) { + fprintf(stderr, "%s: slope threshold %f out of range\n", progname, t2); + } + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'S': + s = atoi(optarg); + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (b % 2 > 0 || b <= 2) { + fprintf(stderr, "%s: block size has to be even and greater than 2\n", progname); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + // read signature file and set options + // command line options override signature file options + if (sig) { + char line[128]; + fgets(line, sizeof(line), sig); + if (strspn(line, "BRSG") >= 4) { + if (n == 0) + fscanf(sig, "%d\n", &n); + else + fscanf(sig, "%*d\n"); + if (skipping == 0) + fscanf(sig, "%d\n", &skipping); + else + fscanf(sig, "%*d\n"); + if (p1 == 0) + fscanf(sig, "%d\n", &p1); + else + fscanf(sig, "%*d\n"); + if (p2 == 0) + fscanf(sig, "%d\n", &p2); + else + fscanf(sig, "%*d\n"); + if (q == 0.0) + fscanf(sig, "%lf\n", &q); + else + fscanf(sig, "%*f\n"); + if (t1 == 0.0) + fscanf(sig, "%lf\n", &t1); + else + fscanf(sig, "%*f\n"); + if (t2 == 0.0) + fscanf(sig, "%lf\n", &t2); + else + fscanf(sig, "%*f\n"); + if (b == 0) + fscanf(sig, "%d\n", &b); + else + fscanf(sig, "%*d\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + + if (s) + srandom(s); + else + srandom(time(NULL) * getpid()); + + if (n > 0) { + nb = fread(signature, sizeof(char), i = NBITSTOBYTES(n), in); + if (nb < i) { + fprintf(stderr, "%s: failed to read all %d signature bits from %s\n", progname, n, input_name); + exit(1); + } + } + else { + if (fscanf(in, "%128[^\n\r]", signature) == EOF) { + fprintf(stderr, "%s: failed to read signature bits from %s\n", progname, input_name); + exit(1); + } + nb = strlen(signature); + n = NBYTESTOBITS(nb); + fprintf(stderr, "%s: got %d signature bits\n", progname, n); + } + + + fprintf(out, "BRSG\n"); + fprintf(out, "%d\n", n); + fprintf(out, "%d\n", skipping); + fprintf(out, "%d\n", p1); + fprintf(out, "%d\n", p2); + fprintf(out, "%f\n", q); + fprintf(out, "%f\n", t1); + fprintf(out, "%f\n", t2); + fprintf(out, "%d\n", b); + fprintf(out, "%ld\n", random()); + fwrite(signature, sizeof(char), nb, out); + fprintf(out, "\n"); + + fclose(out); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_corvi_sig.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_corvi_sig.1 Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,161 @@ +.\" +.\" gen_corvi_sig.1 - the *roff document processor man page source +.\" +.TH gen_corvi_sig 1 "98/07/17" "Watermarking, Version 1.0" +.SH NAME +.B gen_corvi_sig +\- a program to generate a signature for +the +.B wm_corvi_e +watermarking program +.SH SYNOPSIS +.B gen_corvi_sig +[ +.BI \-a \ number +] +[ +.BI \-d \ number +] +[ +.BI \-e \ number +] +[ +.BI \-f \ number +] +[ +.BI \-F \ ffile +] +[ +.BI \-g \ number +] +.br +[ +.B \-h +] +[ +.BI \-m \ number +] +[ +.BI \-n \ number +] +[ +.BI \-o \ file +] +[ +.BI \-q \ number +] +[ +.BI \-s \ number +] +.SH DESCRIPTION +.B gen_corvi_sig +is a program to generate a signature to be +embedded with the +.B wm_corvi_e +watermarking program and extracted with the +.B wm_corvi_d +program. The +.B cmp_corvi_sig +program is used to compare and test an +extracted signature with the original signature. +.PP +Please refer to Marco Corvi's paper "Wavlet-based image watermarking +for copyright protection", to get an idea of the algorithm. +.PP +.SH OPTIONS +.TP +.BI \-a \ number +Alpha factor that determines embedding strength of the signature. Default +value 0.3. +.TP +.BI \-d \ number +Deviation for the normal distributed signature values, default 1.0. +.TP +.BI \-e \ number +The filtering method for the forward wavelet transform. Default value +1. +.TP +.BI \-F \ ffile +The filter definition file. Default +.I filter.dat. +.TP +.BI \-f \ number +Use the +.I number +filter from the filter definition file, +.I ffile. Default: 1. +.TP +.BI \-g \ number +The filtering method for the inverse wavelet transform. Default value +2. +.TP +.B \-h +Print a help message. +.TP +.BI \-m \ number +Mean of the normal distributed signature values, default 0.0. +.TP +.BI \-n \ number +Length of the watermark. Default value 100. +.TP +.BI \-o \ file +Output signature to the specified +.I file +instead of standard output. +.TP +.BI \-q \ number +Quantization/quality factor. Default value 3. +.TP +.BI \-s \ number +Specify a seed value to initialize the pseudo-random number +generator; if not specified, time and pid (process id) are used +to initialize the pseudo-random number generator. +.PP +.SH OUTPUT +The output file has the following format: +.TP +.B CVSG +Magic to identify file type. +.TP +.I number +The length of the signature in bits. +.TP +.I number +The alpha factor (embedding strength). +.TP +.I number +The quantization/quality factor. +.TP +.I number +The wavelet forward transform filtering method. +.TP +.I number +The wavelet filter number. +.TP +.I file +The wavelet filter definition file name. +.TP +.I number +The wavelet inverse transform filtering method. +.TP +.I numbers +The actual normal distributed signature values, one per line. +.PP +.SH AUTHOR +Peter Meerwald. +Email bug reports to pmeerw@cosy.sbg.ac.at. +.SH AVAILABILITY +The most recent released version of +.B gen_corvi_sig +is always available +at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the +directory /pub/people/pmeerw/Watermarking. +.SH "SEE ALSO" +.BR wm_corvi_e +(1), +.BR wm_corvi_d +(1), +.BR wm_corvi_s +(1), +.BR cmp_corvi_sig +(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_corvi_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_corvi_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,142 @@ +#include "wm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-d n] [-e n] [-f n] [-F file] [-m n] [-n n] [-o file] [-s n]\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor (default 0.1)\n"); + fprintf(stderr, "\t-d n\t\tdeviation (default 1.0)\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); + fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-m n \t\tmean value (default 0.0)\n"); + fprintf(stderr, "\t-n n\t\twatermark length (default 1000)\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-s n\t\tseed\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + FILE *out = stdout; + + char output_name[MAXPATHLEN] = "(stdout)"; + + int c; + int n = 1000; + int s = 0; + int e = 2; + int f = 1; + char F[MAXPATHLEN] = "filter.dat"; + double a = 0.1; + double m = 0.0; + double d = 1.0; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "a:d:e:f:F:h?m:n:o:s:")) != EOF) { + switch (c) { + case 'a': + a = atof(optarg); + if (a <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); + exit(1); + } + break; + case 'd': + d = atof(optarg); + if (d <= 0.0) { + fprintf(stderr, "%s: deviation %f out of range\n", progname, d); + exit(1); + } + break; + case 'e': + e = atoi(optarg); + if (e < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); + } + break; + case 'f': + f = atoi(optarg); + if (f <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, f); + exit(1); + } + break; + case 'F': + strcpy(F, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'm': + m = atof(optarg); + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 32000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + s = atoi(optarg); + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 0) { + usage(); + exit(1); + } + + if (s) + srandom(s); + else + srandom(time(NULL) * getpid()); + + fprintf(out, "CVSG\n"); + fprintf(out, "%d\n", n); + fprintf(out, "%f\n", a); + fprintf(out, "%d\n", e); + fprintf(out, "%d\n", f); + fprintf(out, "%s\n", F); + + n >>= 1; + while (n > 0) { + double x; + double x1, x2; + + /* + * Algorithm P (Polar method for normal deviates), + * Knuth, D., "The Art of Computer Programming", Vol. 2, 3rd Edition, p. 122 + */ + do { + x1 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; + x2 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; + x = x1 * x1 + x2 * x2; + } while (x >= 1.0); + x1 *= sqrt((-2.0) * log(x) / x); + x2 *= sqrt((-2.0) * log(x) / x); + + fprintf(out, "%f\n", m + d * x1); + fprintf(out, "%f\n", m + d * x2); + + n--; + } + + fclose(out); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_cox_sig.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_cox_sig.1 Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,115 @@ +.\" +.\" gen_cox_sig.1 - the *roff document processor man page source +.\" +.TH gen_cox_sig 1 "98/06/30" "Watermarking, Version 1.0" +.SH NAME +.B gen_cox_sig +\- a program to generate a signature for +the +.B wm_cox_e +watermarking program +.SH SYNOPSIS +.B gen_cox_sig +[ +.BI \-a \ number +] +[ +.BI \-d \ number +] +[ +.B \-h +] +[ +.BI \-m \ number +] +[ +.BI \-n \ number +] +[ +.BI \-o \ file +] +[ +.BI \-q \ number +] +[ +.BI \-s \ number +] +.SH DESCRIPTION +.B gen_cox_sig +is a program to generate a signature to be +embedded with the +.B wm_cox_e +watermarking program and extracted with the +.B wm_cox_d +program. The +.B cmp_cox_sig +program is used to compare and test an +extracted signature with the original signature. +.PP +Please refer to Ingemar J. Cox's paper "Secure Spread Spectrum +Watermarking for Multimedia", 1995, to get an idea about the algorithm. +.PP +.SH OPTIONS +.TP +.BI \-a \ number +Alpha factor that determines embedding strength of the signature. Default +value 0.3. +.TP +.BI \-d \ number +Deviation for the normal distributed signature values, default 1.0. +.TP +.B \-h +Print a help message. +.TP +.BI \-m \ number +Mean of the normal distributed signature values, default 0.0. +.TP +.BI \-n \ number +Length of the watermark. Default value 100. +.TP +.BI \-o \ file +Output signature to the specified +.I file +instead of standard output. +.TP +.BI \-q \ number +Quantization/quality factor. Default value 3. +.TP +.BI \-s \ number +Specify a seed value to initialize the pseudo-random number +generator; if not specified, time and pid (process id) are used +to initialize the pseudo-random number generator. +.PP +.SH OUTPUT +The output file has the following format: +.TP +.B CXSG +Magic to identify file type. +.TP +.I number +The length of the signature in bits. +.TP +.I number +The alpha factor (embedding strength). +.TP +.I number +The quantization/quality factor. +.TP +.I numbers +The actual normal distributed signature values, one per line. +.PP +.SH AUTHOR +Peter Meerwald. Email bug reports to pmeerw@cosy.sbg.ac.at. +.SH AVAILABILITY +The most recent released version of +.B gen_cox_sig +is always available +at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the +directory /pub/people/pmeerw/Watermarking. +.SH "SEE ALSO" +.BR wm_cox_e +(1), +.BR wm_cox_d +(1), +.BR cmp_cox_sig +(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_cox_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_cox_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,157 @@ +#include "wm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-d n] [-m n] [-n n] [-o file] [-s file] [-S n]\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor (default 0.3)\n"); + fprintf(stderr, "\t-d n\t\tdeviation (default 1.0)\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-m n \t\tmean value (default 0.0)\n"); + fprintf(stderr, "\t-n n\t\twatermark length (default 100)\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); + fprintf(stderr, "\t-S n\t\tseed\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char signature_name[MAXPATHLEN]; + + int c; + int n = 100; + int s = 0; + double a = 0.3; + double m = 0.0; + double d = 1.0; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "a:d:h?m:n:o:s:S:")) != EOF) { + switch (c) { + case 'a': + a = atof(optarg); + if (a <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); + exit(1); + } + break; + case 'd': + d = atof(optarg); + if (d <= 0.0) { + fprintf(stderr, "%s: deviation %f out of range\n", progname, d); + exit(1); + } + break; + case 'h': + case '?': + usage(); + break; + case 'm': + m = atof(optarg); + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 32000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'S': + s = atoi(optarg); + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 0) { + usage(); + exit(1); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "CXSG") >= 4) { + if (n == 0) + fscanf(sig, "%d\n", &n); + else + fscanf(sig, "%*d\n"); + if (a == 0.0) + fscanf(sig, "%lf\n", &a); + else + fscanf(sig, "%*f\n"); + if (m == 0.0) + fscanf(sig, "%lf\n", &m); + else + fscanf(sig, "%*f\n"); + if (d == 0.0) + fscanf(sig, "%lf\n", &d); + else + fscanf(sig, "%*f\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + + if (s) + srandom(s); + else + srandom(time(NULL) * getpid()); + + fprintf(out, "CXSG\n"); + fprintf(out, "%d\n", n); + fprintf(out, "%f\n", a); + fprintf(out, "%f\n", m); + fprintf(out, "%f\n", d); + + n >>= 1; + while (n > 0) { + double x; + double x1, x2; + + /* + * Algorithm P (Polar method for normal deviates), + * Knuth, D., "The Art of Computer Programming", Vol. 2, 3rd Edition, p. 122 + */ + do { + x1 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; + x2 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; + x = x1 * x1 + x2 * x2; + } while (x >= 1.0); + x1 *= sqrt((-2.0) * log(x) / x); + x2 *= sqrt((-2.0) * log(x) / x); + + fprintf(out, "%f\n", m + d * x1); + fprintf(out, "%f\n", m + d * x2); + + n--; + } + + fclose(out); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_dugad_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_dugad_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,226 @@ +#include "wm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-e n] [-f n] [-F file] [-l n] [-n n] [-o file] [-s file] [-S n] [-t n] [-T n]\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor (default 0.2)\n"); + fprintf(stderr, "\t-d n\t\tdeviation (default 1.0)\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); + fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-l n\t\tdecomposition levels (default 3)\n"); + fprintf(stderr, "\t-m n \t\tmean value (default 0.0)\n"); + fprintf(stderr, "\t-n n\t\twatermark length (default 1000)\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + fprintf(stderr, "\t-S n\t\tseed\n"); + fprintf(stderr, "\t-t n\t\tcasting threshold (default 40.0)\n"); + fprintf(stderr, "\t-T n\t\tdetection threshold (default 50.0)\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char signature_name[MAXPATHLEN]; + + int c; + int n = 1000; + int s = 0; + int e = 2; + int f = 1; + int l = 3; + char F[MAXPATHLEN] = "filter.dat"; + double a = 0.2; + double t1 = 40.0; + double t2 = 50.0; + double m = 0.0; + double d = 1.0; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "a:b:d:e:f:F:h?l:m:n:o:s:S:t:T:")) != EOF) { + switch (c) { + case 'a': + a = atof(optarg); + if (a <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); + exit(1); + } + break; + case 'd': + d = atof(optarg); + if (d <= 0.0) { + fprintf(stderr, "%s: deviation %f out of range\n", progname, d); + exit(1); + } + break; + + case 'e': + e = atoi(optarg); + if (e < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); + } + break; + case 'f': + f = atoi(optarg); + if (f <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, f); + exit(1); + } + break; + case 'F': + strcpy(F, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'l': + l = atoi(optarg); + if (l <= 0) { + fprintf(stderr, "%s: decomposition level %d out of range\n", progname, l); + exit(1); + } + break; + case 'm': + m = atof(optarg); + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 32000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'S': + s = atoi(optarg); + break; + case 't': + t1 = atof(optarg); + if (t1 <= 0.0) { + fprintf(stderr, "%s: casting threshold %f out of range\n", progname, t1); + exit(1); + } + break; + case 'T': + t2 = atof(optarg); + if (t2 <= 0.0) { + fprintf(stderr, "%s: detection threshold %f out of range\n", progname, t2); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 0) { + usage(); + exit(1); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "DGSG") >= 4) { + if (n == 0) + fscanf(sig, "%d\n", &n); + else + fscanf(sig, "%*d\n"); + if (l == 0) + fscanf(sig, "%d\n", &l); + else + fscanf(sig, "%*d\n"); + if (a == 0.0) + fscanf(sig, "%lf\n", &a); + else + fscanf(sig, "%*f\n"); + if (t1 == 0.0) + fscanf(sig, "%lf\n", &t1); + else + fscanf(sig, "%*f\n"); + if (t2 == 0.0) + fscanf(sig, "%lf\n", &t2); + else + fscanf(sig, "%*f\n"); + if (e < 0) + fscanf(sig, "%d\n", &e); + else + fscanf(sig, "%*d\n"); + if (f == 0) + fscanf(sig, "%d\n", &f); + else + fscanf(sig, "%*d\n"); + if (!strcmp(F, "")) + fscanf(sig, "%[^\n\r]\n", F); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + } + + if (s) + srandom(s); + else + srandom(time(NULL) * getpid()); + + fprintf(out, "DGSG\n"); + fprintf(out, "%d\n", n); + fprintf(out, "%d\n", l); + fprintf(out, "%f\n", a); + fprintf(out, "%f\n", t1); + fprintf(out, "%f\n", t2); + fprintf(out, "%d\n", e); + fprintf(out, "%d\n", f); + fprintf(out, "%s\n", F); + + n >>= 1; + while (n > 0) { + double x; + double x1, x2; + + /* + * Algorithm P (Polar method for normal deviates), + * Knuth, D., "The Art of Computer Programming", Vol. 2, 3rd Edition, p. 122 + */ + do { + x1 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; + x2 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; + x = x1 * x1 + x2 * x2; + } while (x >= 1.0); + x1 *= sqrt((-2.0) * log(x) / x); + x2 *= sqrt((-2.0) * log(x) / x); + + fprintf(out, "%f\n", m + d * x1); + fprintf(out, "%f\n", m + d * x2); + + n--; + } + + fclose(out); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_frid2_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_frid2_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,150 @@ +#include "wm.h" +#include "signature.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-g n] [-o file] [-s n] file\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor (default 0.25)\n"); + fprintf(stderr, "\t-g n\t\tgamma factor (default 1.0)\n"); + fprintf(stderr, "\t-s n\t\tseed (default 0)\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-n n\t\twatermark length (default 100)\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); + fprintf(stderr, "\t-S n\t\tseed\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int c; + int i; + int n = 100, nb; + double a = 0.25; + double g = 1.0; + int s = 0; + + progname = argv[0]; + +#ifdef __EMX__ + _fsetmode(in, "b"); + _fsetmode(out, "b"); +#endif + + while ((c = getopt(argc, argv, "a:g:h?n:o:s:S:")) != EOF) { + switch (c) { + case 'a': + a = atof(optarg); + if (a <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); + exit(1); + } + break; + case 'g': + g = atof(optarg); + if (g <= 0.0) { + fprintf(stderr, "%s: gamma factor %f out of range\n", progname, a); + exit(1); + } + break; + case 'h': + case '?': + usage(); + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 1000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'S': + s = atoi(optarg); + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (!s) + s = time(NULL) * getpid(); + srandom(s); + + if (sig) { + char line[128]; + fgets(line, sizeof(line), sig); + if (strspn(line, "FR2SG") >= 5) { + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + + if (n > 0) { + nb = fread(signature, sizeof(char), i = NBITSTOBYTES(n), in); + if (nb < i) { + fprintf(stderr, "%s: failed to read all %d signature bits from %s\n", progname, n, input_name); + exit(1); + } + } + else { + if (fscanf(in, "%128[^\n\r]", signature) == EOF) { + fprintf(stderr, "%s: failed to read signature bits from %s\n", progname, input_name); + exit(1); + } + nb = strlen(signature); + n = NBYTESTOBITS(nb); + fprintf(stderr, "%s: got %d signature bits\n", progname, n); + } + + fprintf(out, "FR2SG\n"); + fprintf(out, "%d\n", n); + fprintf(out, "%f\n", a); + fprintf(out, "%f\n", g); + fprintf(out, "%d\n", s); + fwrite(signature, sizeof(char), nb, out); + fprintf(out, "\n"); + + fclose(out); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_kim_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_kim_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,211 @@ +#include "wm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-A n] [-d n] [-e n] [-f n] [-F file] [-l n] [-m n] [-n n] [-o file] [-s file] [-S n]\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor for detail subbands (default 0.1)\n"); + fprintf(stderr, "\t-A n\t\talpha factor for approximation subband (default 0.02)\n"); + fprintf(stderr, "\t-d n\t\tdeviation (default 1.0)\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); + fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-l n\t\tdecomposition level (default 4)\n"); + fprintf(stderr, "\t-m n \t\tmean value (default 0.0)\n"); + fprintf(stderr, "\t-n n\t\twatermark length (default 1000)\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); + fprintf(stderr, "\t-S n\t\tseed\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char signature_name[MAXPATHLEN]; + + int c; + int n = 1000; + int s = 0; + int e = 2; + int f = 1; + char F[MAXPATHLEN] = "filter.dat"; + double a = 0.1; + double A = 0.02; + int l = 4; + double m = 0.0; + double d = 1.0; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "a:A:l:d:e:f:F:h?m:n:o:s:S:")) != EOF) { + switch (c) { + case 'a': + a = atof(optarg); + if (a <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); + exit(1); + } + break; + case 'A': + A = atof(optarg); + if (A <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); + exit(1); + } + break; + case 'l': + l = atoi(optarg); + if (l <= 0) { + fprintf(stderr, "%s: decomposition level %d out of range\n", progname, l); + exit(1); + } + break; + case 'd': + d = atof(optarg); + if (d <= 0.0) { + fprintf(stderr, "%s: deviation %f out of range\n", progname, d); + exit(1); + } + break; + case 'e': + e = atoi(optarg); + if (e < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); + } + break; + case 'f': + f = atoi(optarg); + if (f <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, f); + exit(1); + } + break; + case 'F': + strcpy(F, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'm': + m = atof(optarg); + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 32000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'S': + s = atoi(optarg); + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 0) { + usage(); + exit(1); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "KISG") >= 4) { + if (n == 0) + fscanf(sig, "%d\n", &n); + else + fscanf(sig, "%*d\n"); + if (a == 0.0) + fscanf(sig, "%lf\n", &a); + else + fscanf(sig, "%*f\n"); + if (A == 0.0) + fscanf(sig, "%lf\n", &A); + else + fscanf(sig, "%*f\n"); + if (l == 0) + fscanf(sig, "%d\n", &l); + else + fscanf(sig, "%*d\n"); + if (e < 0) + fscanf(sig, "%d\n", &e); + else + fscanf(sig, "%*d\n"); + if (f == 0) + fscanf(sig, "%d\n", &f); + else + fscanf(sig, "%*d\n"); + if (!strcmp(F, "")) + fscanf(sig, "%[^\n\r]\n", F); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + } + + if (s) + srandom(s); + else + srandom(time(NULL) * getpid()); + + fprintf(out, "KISG\n"); + fprintf(out, "%d\n", n); + fprintf(out, "%f\n", a); + fprintf(out, "%f\n", A); + fprintf(out, "%d\n", l); + fprintf(out, "%d\n", e); + fprintf(out, "%d\n", f); + fprintf(out, "%s\n", F); + + n >>= 1; + while (n > 0) { + double x; + double x1, x2; + + /* + * Algorithm P (Polar method for normal deviates), + * Knuth, D., "The Art of Computer Programming", Vol. 2, 3rd Edition, p. 122 + */ + do { + x1 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; + x2 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; + x = x1 * x1 + x2 * x2; + } while (x >= 1.0); + x1 *= sqrt((-2.0) * log(x) / x); + x2 *= sqrt((-2.0) * log(x) / x); + + fprintf(out, "%f\n", m + d * x1); + fprintf(out, "%f\n", m + d * x2); + + n--; + } + + fclose(out); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_koch_sig.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_koch_sig.1 Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,110 @@ +.\" +.\" gen_koch_sig.1 - the *roff document processor man page source +.\" +.TH gen_koch_sig 1 "98/06/30" "Watermarking, Version 1.0" +.SH NAME +.B gen_koch_sig +\- a program to generate a signature for +the +.B wm_koch_e +watermarking program +.SH SYNOPSIS +.B gen_koch_sig +[ +.B \-h +] +[ +.BI \-n \ number +] +[ +.BI \-o \ file +] +[ +.BI \-q \ number +] +[ +.BI \-s \ number +] +[ +.IR file +] +.SH DESCRIPTION +.B gen_koch_sig +is a program to generate a signature to be +embedded with the +.B wm_koch_e +watermarking program and extracted with the +.B wm_koch_d +program. The +.B cmp_koch_sig +program is used to compare and test an +extracted signature with the original signature. +.PP +Please refer to E. Koch's paper "Towards Robust and Hidden +Image Copyright", 1995, to get an idea about the algorithm. +.PP +.SH OPTIONS +.TP +.B \-h +Print a help message. +.TP +.BI \-n \ number +Limit the signature length to +.I number +bits (0 < +.I number +<= 1024) unless reading from standard input. When reading from +standard input, the signature is terminated by the first +carriage return character. +.TP +.BI \-o \ file +Output signature to the specified +.I file +instead of standard output. +.TP +.BI \-q \ number +Quality/robustness factor used to embed signature into image. +Default value: 3.0. +.TP +.BI \-s \ number +Specify a seed value to initialize the pseudo-random number +generator; if not specified, time and pid (process id) are used +to initialize the pseudo-random number generator. +.TP +.IR file +Input file to read raw signature data from. Default: standard +input. +.PP +.SH OUTPUT +The output file has the following format: +.TP +.B KCSG +Magic to identify file type. +.TP +.I number +The length of the signature in bits. +.TP +.I number +The quality/robustness factor. +.TP +.I number +The seed value for the pseudo-random number generator. +.TP +.I string +The actual signature bytes. +.PP +.SH AUTHOR +Peter Meerwald. Email bug reports to pmeerw@cosy.sbg.ac.at. +.SH AVAILABILITY +The most recent released version of +.B gen_koch_sig +is always available +at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the +directory /pub/people/pmeerw/Watermarking. +.SH "SEE ALSO" +.BR wm_koch_e +(1), +.BR wm_koch_d +(1), +.BR cmp_koch_sig +(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_koch_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_koch_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,158 @@ +#include "wm.h" +#include "signature.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-l n] [-n n] [-o file] [-q n] [-s file] [-S n] file\n\n", progname); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-l n\t\tsignature strength factor (default 5.0)\n"); + fprintf(stderr, "\t-n n\t\twatermark bit length\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-q n\t\tquantization (JPEG quality) factor (default 90)\n"); + fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); + fprintf(stderr, "\t-S n\t\tseed\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int c; + int i; + int n = 0; + int nb; + int s = 0; + int q = 90; + double l = 5.0; + + progname = argv[0]; wm_init(); + + while ((c = getopt(argc, argv, "h?l:n:o:q:s:S:")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'l': + l = atof(optarg); + if (l <= 0.0) { + fprintf(stderr, "%s: signature strength factor %f out of range\n", progname, l); + exit(1); + } + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 1000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'q': + q = atoi(optarg); + if (q <= 0 || q > 100) { + fprintf(stderr, "%s: quantization factor %d out of range\n", progname, q); + exit(1); + } + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'S': + s = atoi(optarg); + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (s) + srandom(s); + else + srandom(time(NULL) * getpid()); + + if (sig) { + char line[128]; + fgets(line, sizeof(line), sig); + if (strspn(line, "KCSG") >= 4) { + if (n == 0) + fscanf(sig, "%d\n", &n); + else + fscanf(sig, "%*d\n"); + if (l == 0.0) + fscanf(sig, "%lf\n", &l); + else + fscanf(sig, "%*f\n"); + if (q == 0) + fscanf(sig, "%d\n", &q); + else + fscanf(sig, "%*d\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + + if (n > 0) { + nb = fread(signature, sizeof(char), i = NBITSTOBYTES(n), in); + if (nb < i) { + fprintf(stderr, "%s: failed to read all %d signature bits from %s\n", progname, n, input_name); + exit(1); + } + } + else { + if (fscanf(in, "%128[^\n\r]", signature) == EOF) { + fprintf(stderr, "%s: failed to read signature bits from %s\n", progname, input_name); + exit(1); + } + nb = strlen(signature); + n = NBYTESTOBITS(nb); + fprintf(stderr, "%s: got %d signature bits\n", progname, n); + } + + fprintf(out, "KCSG\n"); + fprintf(out, "%d\n", n); + fprintf(out, "%f\n", l); + fprintf(out, "%d\n", q); + fprintf(out, "%ld\n", random()); + fwrite(signature, sizeof(char), nb, out); + fprintf(out, "\n"); + + fclose(out); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_kund2_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_kund2_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,221 @@ +#include "wm.h" +#include "signature.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-b n] [-e n] [-f n] [-F file] [-l n] [-n n] [-o file] [-q n] [-s file] [-S n] [-v n] file\n\n", progname); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-b n\t\tblock size (default 64)\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); + fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); + fprintf(stderr, "\t-l n\t\tembedding level (default 1)\n"); + fprintf(stderr, "\t-n n\t\twatermark bit length\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-q n\t\tsignature strength (default 4)\n"); + fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); + fprintf(stderr, "\t-S n\t\tseed\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + char *binstr; + + int verbose = 0; + int c; + int i; + int l = 3; + int n = 0; + int s = 0; + int q = 4; + int e = 2; + int f = 1; + int blocksize = 64; + char F[MAXPATHLEN] = "filter.dat"; + + progname = argv[0]; + + wm_init(); + + while ((c = getopt(argc, argv, "b:e:f:F:h?l:n:o:q:s:S:v:")) != EOF) { + switch (c) { + case 'b': + blocksize = atoi(optarg); + if (blocksize < 0) + fprintf(stderr, "%s: block size %d out of range\n", progname, blocksize); + break; + case 'e': + e = atoi(optarg); + if (e < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); + } + break; + case 'f': + f = atoi(optarg); + if (f <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, f); + exit(1); + } + break; + case 'F': + strcpy(F, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'l': + l = atoi(optarg); + if (l < 1) { + fprintf(stderr, "%s: embedding level out of range\n", progname); + exit(1); + } + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 1000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'q': + q = atoi(optarg); + if (q < 1) { + fprintf(stderr, "%s: signature strength %d out of range\n", progname, q); + exit(1); + } + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'S': + s = atoi(optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "KD2SG") >= 5) { + if (n == 0) + fscanf(sig, "%d\n", &n); + else + fscanf(sig, "%*d\n"); + if (q == 0) + fscanf(sig, "%d\n", &q); + else + fscanf(sig, "%*d\n"); + if (blocksize == 0) + fscanf(sig, "%d\n", &blocksize); + else + fscanf(sig, "%*d\n"); + if (e < 0) + fscanf(sig, "%d\n", &e); + else + fscanf(sig, "%*d\n"); + if (f == 0) + fscanf(sig, "%d\n", &f); + else + fscanf(sig, "%*d\n"); + if (!strcmp(F, "")) + fscanf(sig, "%[^\n\r]\n", F); + else + fscanf(sig, "%*[^\n\r]\n"); + if (l == 0) + fscanf(sig, "%d\n", &l); + else + fscanf(sig, "%*d\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + + if (s) + srandom(s); + else + srandom(time(NULL) * getpid()); + + if (n > 0) { + n_signature = fread(signature, sizeof(char), i = NBITSTOBYTES(n), in); + nbit_signature = NBYTESTOBITS(n_signature); + if (n_signature < i) { + fprintf(stderr, "%s: failed to read all %d signature bits from %s\n", progname, n, input_name); + exit(1); + } + } + else { + if (fscanf(in, "%128[^\n\r]", signature) == EOF) { + fprintf(stderr, "%s: failed to read signature bits from %s\n", progname, input_name); + exit(1); + } + n_signature = strlen(signature); + nbit_signature = NBYTESTOBITS(n_signature); + fprintf(stderr, "%s: got %d signature bits\n", progname, nbit_signature); + } + + fprintf(out, "KD2SG\n"); + fprintf(out, "%d\n", nbit_signature); + fprintf(out, "%d\n", q); + fprintf(out, "%d\n", blocksize); + fprintf(out, "%d\n", e); + fprintf(out, "%d\n", f); + fprintf(out, "%s\n", F); + fprintf(out, "%d\n", l); + fprintf(out, "%ld\n", random()); + binstr = malloc((nbit_signature + 1) * sizeof(char)); + sig_to_binstr(binstr); + fprintf(out, "%s\n", binstr); + free(binstr); + + fclose(out); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_kund3_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_kund3_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,209 @@ +#include "wm.h" +#include "signature.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-e n] [-f n] [-F file] [-l n] [-n n] [-o file] [-q n] [-s file] [-S n] [-v n] file\n\n", progname); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); + fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); + fprintf(stderr, "\t-l n\t\tembedding level (default 1)\n"); + fprintf(stderr, "\t-n n\t\twatermark bit length\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-q n\t\tsignature strength (default 4)\n"); + fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); + fprintf(stderr, "\t-S n\t\tseed\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + char *binstr; + + int verbose = 0; + int c; + int i; + int l = 1; + int n = 0; + int s = 0; + int q = 4; + int e = 2; + int f = 1; + char F[MAXPATHLEN] = "filter.dat"; + + progname = argv[0]; + + wm_init(); + + while ((c = getopt(argc, argv, "e:f:F:h?l:n:o:q:s:S:v:")) != EOF) { + switch (c) { + case 'e': + e = atoi(optarg); + if (e < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); + } + break; + case 'f': + f = atoi(optarg); + if (f <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, f); + exit(1); + } + break; + case 'F': + strcpy(F, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'l': + l = atoi(optarg); + if (l < 1) { + fprintf(stderr, "%s: embedding level out of range\n", progname); + exit(1); + } + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 1000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'q': + q = atoi(optarg); + if (q < 1) { + fprintf(stderr, "%s: signature strength %d out of range\n", progname, q); + exit(1); + } + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'S': + s = atoi(optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "KD3SG") >= 5) { + if (n == 0) + fscanf(sig, "%d\n", &n); + else + fscanf(sig, "%*d\n"); + if (q == 0) + fscanf(sig, "%d\n", &q); + else + fscanf(sig, "%*d\n"); + if (e < 0) + fscanf(sig, "%d\n", &e); + else + fscanf(sig, "%*d\n"); + if (f == 0) + fscanf(sig, "%d\n", &f); + else + fscanf(sig, "%*d\n"); + if (!strcmp(F, "")) + fscanf(sig, "%[^\n\r]\n", F); + else + fscanf(sig, "%*[^\n\r]\n"); + if (l == 0) + fscanf(sig, "%d\n", &l); + else + fscanf(sig, "%*d\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + + if (s) + srandom(s); + else + srandom(time(NULL) * getpid()); + + if (n > 0) { + n_signature = fread(signature, sizeof(char), i = NBITSTOBYTES(n), in); + if (n_signature < i) { + fprintf(stderr, "%s: failed to read all %d signature bits from %s\n", progname, n, input_name); + exit(1); + } + } + else { + if (fscanf(in, "%128[^\n\r]", signature) == EOF) { + fprintf(stderr, "%s: failed to read signature bits from %s\n", progname, input_name); + exit(1); + } + n_signature = strlen(signature); + n = nbit_signature = NBYTESTOBITS(n_signature); + fprintf(stderr, "%s: got %d signature bits\n", progname, nbit_signature); + } + + fprintf(out, "KD3SG\n"); + fprintf(out, "%d\n", n); + fprintf(out, "%d\n", q); + fprintf(out, "%d\n", e); + fprintf(out, "%d\n", f); + fprintf(out, "%s\n", F); + fprintf(out, "%d\n", l); + fprintf(out, "%ld\n", random()); + nbit_signature = NBYTESTOBITS(n_signature); + binstr = malloc((nbit_signature + 1) * sizeof(char)); + sig_to_binstr(binstr); + fprintf(out, "%s\n", binstr); + free(binstr); + + fclose(out); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_kund_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_kund_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,164 @@ +#include "wm.h" +#include "signature.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-e n] [-f n] [-F file] [-l n] [-n n] [-o file] [-q n] [-s n] file\n\n", progname); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); + fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); + fprintf(stderr, "\t-l n\t\tembedding level (default 1)\n"); + fprintf(stderr, "\t-n n\t\twatermark bit length\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-q n\t\tsignature strength (default 1.0)\n"); + fprintf(stderr, "\t-s n\t\tseed\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + FILE *in = stdin; + FILE *out = stdout; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + + int c; + int i; + int l = 1; + int n = 0, nb; + int s = 0; + double q = 1.0; + int e = 2; + int f = 1; + char F[MAXPATHLEN] = "filter.dat"; + + progname = argv[0]; + +#ifdef __EMX__ + _fsetmode(in, "b"); + _fsetmode(out, "b"); +#endif + + while ((c = getopt(argc, argv, "e:f:F:h?l:n:o:q:s:")) != EOF) { + switch (c) { + case 'e': + e = atoi(optarg); + if (e < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); + } + break; + case 'f': + f = atoi(optarg); + if (f <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, f); + exit(1); + } + break; + case 'F': + strcpy(F, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'l': + l = atoi(optarg); + if (l < 1) { + fprintf(stderr, "%s: embedding level out of range\n", progname); + exit(1); + } + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 1000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + if (n % 4 != 0 || (int) sqrt(n / 4) * (int) sqrt(n / 4) != n) { + fprintf(stderr, "%s: watermark length not divisible by 4 or not a square number\n", progname); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'q': + q = atof(optarg); + if (q <= 0.0) { + fprintf(stderr, "%s: signature strength factor %f out of range\n", progname, q); + exit(1); + } + break; + case 's': + s = atoi(optarg); + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 0) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + + if (s) + srandom(s); + else + srandom(time(NULL) * getpid()); + + if (n > 0) { + nb = fread(signature, sizeof(char), i = NBITSTOBYTES(n), in); + if (nb < i) { + fprintf(stderr, "%s: failed to read all %d signature bits from %s\n", progname, n, input_name); + exit(1); + } + } + else { + int n_square; + if (fscanf(in, "%128[^\n\r]", signature) == EOF) { + fprintf(stderr, "%s: failed to read signature bits from %s\n", progname, input_name); + exit(1); + } + nb = strlen(signature); + n = NBYTESTOBITS(nb); + n_square = (int) sqrt(n) * (int) sqrt(n); + fprintf(stderr, "%s: got %d signature bits, truncated to %d\n", progname, n, n_square); + n = n_square; + nb = NBITSTOBYTES(n); + if (n < 1) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + } + + fprintf(out, "KDSG\n"); + fprintf(out, "%d\n", n); + fprintf(out, "%d\n", e); + fprintf(out, "%d\n", f); + fprintf(out, "%s\n", F); + fprintf(out, "%d\n", l); + fprintf(out, "%f\n", q); + fprintf(out, "%d\n", random()); + fwrite(signature, sizeof(char), nb, out); + fprintf(out, "\n"); + + fclose(out); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_kutter_sig.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_kutter_sig.1 Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,131 @@ +.\" +.\" gen_kutter_sig.1 - the *roff document processor man page source +.\" +.TH gen_kutter_sig 1 "98/06/30" "Watermarking, Version 1.0" +.SH NAME +.B gen_kutter_sig +\- a program to generate a signature for +the +.B wm_kutter_e +watermarking program +.SH SYNOPSIS +.B gen_kutter_sig +[ +.B \-h +] +[ +.BI \-n \ number +] +[ +.BI \-o \ file +] +[ +.BI \-p \ number +] +[ +.BI \-q \ number +] +[ +.BI \-r \ number +] +.br +[ +.BI \-s \ number +] +[ +.I file +] +.SH DESCRIPTION +.B gen_kutter_sig +is a program to generate a signature to be +embedded with the +.B wm_kutter_e +watermarking program and extracted with the +.B wm_kutter_d +program. The +.B cmp_kutter_sig +program is used to compare and test an +extracted signature with the original signature. +.PP +Please refer to M. Kutter's paper "Digital Signature of Color Images +using Amplitude Modulation", 1997, to get an idea about the algorithm. +.PP +.SH OPTIONS +.TP +.B \-h +Print a help message. +.TP +.BI \-n \ number +Limit the signature length to +.I number +bits (0 < +.I number +<= 1024) unless reading from standard input. When reading from +standard input, the signature is terminated by the first +carriage return character. +.TP +.BI \-o \ file +Output signature to the specified +.TP +.BI \-p \ number +Density parameter in the range 0.0 < +.I number +<= 1.0. Default value 0.01. +.TP +.BI \-q \ number +Signature strength. Default value 0.1. +.TP +.BI \-r \ number +Signature bit repetition factor. Specifies how often a single +signature bit is embedded. Default value 8. +.I file +instead of standard output. +.TP +.BI \-s \ number +Specify a seed value to initialize the pseudo-random number +generator; if not specified, time and pid (process id) are used +to initialize the pseudo-random number generator. +.TP +.I file +Input file to read raw signature data from. Default: standard +input. +.PP +.SH OUTPUT +The output file has the following format: +.TP +.B KTSG +Magic to identify file type. +.TP +.I number +The length of the signature in bits. +.TP +.I number +The density parameter. +.TP +.I number +The signature strength. +.TP +.I number +The bit repetition parameter. +.TP +.I number +The seed value for the pseudo-random number generator. +.TP +.I string +The actual signature bytes. +.PP +.SH AUTHOR +Peter Meerwald. Email bug reports to pmeerw@cosy.sbg.ac.at. +.SH AVAILABILITY +The most recent released version of +.B gen_kutter_sig +is always available +at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the +directory /pub/people/pmeerw/Watermarking. +.SH "SEE ALSO" +.BR wm_kutter_e +(1), +.BR wm_kutter_d +(1), +.BR cmp_kutter_sig +(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_wang_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_wang_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,197 @@ +#include "wm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-b n] [-d n] [-e n] [-f n] [-F file] [-m n] [-n n] [-o file] [-s file] [-S n]\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor (default 0.3)\n"); + fprintf(stderr, "\t-b n\t\tbeta factor (default 1.0)\n"); + fprintf(stderr, "\t-d n\t\tdeviation (default 1.0)\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); + fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-m n \t\tmean value (default 0.0)\n"); + fprintf(stderr, "\t-n n\t\twatermark length (default 1000)\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); + fprintf(stderr, "\t-S n\t\tseed\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char signature_name[MAXPATHLEN]; + + int c; + int n = 1000; + int s = 0; + int e = 2; + int f = 1; + char F[MAXPATHLEN] = "filter.dat"; + double a = 0.3; + double b = 1.0; + double m = 0.0; + double d = 1.0; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "a:b:d:e:f:F:h?m:n:o:s:S:")) != EOF) { + switch (c) { + case 'a': + a = atof(optarg); + if (a <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); + exit(1); + } + break; + case 'b': + b = atof(optarg); + if (b <= 0.0) { + fprintf(stderr, "%s: beta factor %f out of range\n", progname, b); + exit(1); + } + break; + case 'd': + d = atof(optarg); + if (d <= 0.0) { + fprintf(stderr, "%s: deviation %f out of range\n", progname, d); + exit(1); + } + break; + case 'e': + e = atoi(optarg); + if (e < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); + } + break; + case 'f': + f = atoi(optarg); + if (f <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, f); + exit(1); + } + break; + case 'F': + strcpy(F, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'm': + m = atof(optarg); + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 32000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'S': + s = atoi(optarg); + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 0) { + usage(); + exit(1); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "WGSG") >= 4) { + if (n == 0) + fscanf(sig, "%d\n", &n); + else + fscanf(sig, "%*d\n"); + if (a == 0.0) + fscanf(sig, "%lf\n", &a); + else + fscanf(sig, "%*f\n"); + if (b == 0.0) + fscanf(sig, "%lf\n", &b); + else + fscanf(sig, "%*f\n"); + if (e < 0) + fscanf(sig, "%d\n", &e); + else + fscanf(sig, "%*d\n"); + if (f == 0) + fscanf(sig, "%d\n", &f); + else + fscanf(sig, "%*d\n"); + if (!strcmp(F, "")) + fscanf(sig, "%[^\n\r]\n", F); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + } + + if (s) + srandom(s); + else + srandom(time(NULL) * getpid()); + + fprintf(out, "WGSG\n"); + fprintf(out, "%d\n", n); + fprintf(out, "%f\n", a); + fprintf(out, "%f\n", b); + fprintf(out, "%d\n", e); + fprintf(out, "%d\n", f); + fprintf(out, "%s\n", F); + + n >>= 1; + while (n > 0) { + double x; + double x1, x2; + + /* + * Algorithm P (Polar method for normal deviates), + * Knuth, D., "The Art of Computer Programming", Vol. 2, 3rd Edition, p. 122 + */ + do { + x1 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; + x2 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; + x = x1 * x1 + x2 * x2; + } while (x >= 1.0); + x1 *= sqrt((-2.0) * log(x) / x); + x2 *= sqrt((-2.0) * log(x) / x); + + fprintf(out, "%f\n", m + d * x1); + fprintf(out, "%f\n", m + d * x2); + + n--; + } + + fclose(out); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_xia_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_xia_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,197 @@ +#include "wm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-d n] [-e n] [-f n] [-F file] [-l n] [-m n] [-n n] [-o file] [-s file] [-S n]\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor (default 0.2)\n"); + fprintf(stderr, "\t-d n\t\tdeviation (default 1.0)\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); + fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-l n\t\tdecomposition level (default 2)\n"); + fprintf(stderr, "\t-m n \t\tmean value (default 0.0)\n"); + fprintf(stderr, "\t-n n\t\twatermark length (default 1000)\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); + fprintf(stderr, "\t-S n\t\tseed\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char signature_name[MAXPATHLEN]; + + int c; + int n = 1000; + int s = 0; + int e = 2; + int f = 1; + char F[MAXPATHLEN] = "filter.dat"; + double a = 0.2; + int l = 2; + double m = 0.0; + double d = 1.0; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "a:l:d:e:f:F:h?m:n:o:s:S:")) != EOF) { + switch (c) { + case 'a': + a = atof(optarg); + if (a <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); + exit(1); + } + break; + case 'l': + l = atoi(optarg); + if (l <= 0) { + fprintf(stderr, "%s: decomposition level %d out of range\n", progname, l); + exit(1); + } + break; + case 'd': + d = atof(optarg); + if (d <= 0.0) { + fprintf(stderr, "%s: deviation %f out of range\n", progname, d); + exit(1); + } + break; + case 'e': + e = atoi(optarg); + if (e < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); + } + break; + case 'f': + f = atoi(optarg); + if (f <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, f); + exit(1); + } + break; + case 'F': + strcpy(F, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'm': + m = atof(optarg); + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 32000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'S': + s = atoi(optarg); + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 0) { + usage(); + exit(1); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "XASG") >= 4) { + if (n == 0) + fscanf(sig, "%d\n", &n); + else + fscanf(sig, "%*d\n"); + if (a == 0.0) + fscanf(sig, "%lf\n", &a); + else + fscanf(sig, "%*f\n"); + if (l == 0) + fscanf(sig, "%d\n", &l); + else + fscanf(sig, "%*d\n"); + if (e < 0) + fscanf(sig, "%d\n", &e); + else + fscanf(sig, "%*d\n"); + if (f == 0) + fscanf(sig, "%d\n", &f); + else + fscanf(sig, "%*d\n"); + if (!strcmp(F, "")) + fscanf(sig, "%[^\n\r]\n", F); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + } + + if (s) + srandom(s); + else + srandom(time(NULL) * getpid()); + + fprintf(out, "XASG\n"); + fprintf(out, "%d\n", n); + fprintf(out, "%f\n", a); + fprintf(out, "%d\n", l); + fprintf(out, "%d\n", e); + fprintf(out, "%d\n", f); + fprintf(out, "%s\n", F); + + n >>= 1; + while (n > 0) { + double x; + double x1, x2; + + /* + * Algorithm P (Polar method for normal deviates), + * Knuth, D., "The Art of Computer Programming", Vol. 2, 3rd Edition, p. 122 + */ + do { + x1 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; + x2 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; + x = x1 * x1 + x2 * x2; + } while (x >= 1.0); + x1 *= sqrt((-2.0) * log(x) / x); + x2 *= sqrt((-2.0) * log(x) / x); + + fprintf(out, "%f\n", m + d * x1); + fprintf(out, "%f\n", m + d * x2); + + n--; + } + + fclose(out); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_xie2_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_xie2_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,214 @@ +#include "wm.h" +#include "signature.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-e n] [-f n] [-F file] [-l n] [-n n] [-o file] [-s file] [-S n] [-v n] file\n\n", progname); + fprintf(stderr, "\t-a n\t\tembedding strength (default 0.5)\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); + fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-l n\t\tembedding level (default 5)\n"); + fprintf(stderr, "\t-n n\t\twatermark bit length\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-q n\t\tquantization level\n"); + fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); + fprintf(stderr, "\t-S n\t\tseed\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int verbose = 0; + int c; + int i; + double a = 0.5; + int q = 4; + int l = 5; + int n = 0, nb; + int s = 0; + int e = 2; + int f = 1; + char F[MAXPATHLEN] = "filter.dat"; + + progname = argv[0]; + wm_init(); + + while ((c = getopt(argc, argv, "a:e:f:F:h?l:n:o:s:S:v:q:")) != EOF) { + switch (c) { + case 'a': + a = atof(optarg); + if (a <= 0.0) { + fprintf(stderr, "%s: embedding strength %f out of range\n", progname, a); + exit(1); + } + break; + case 'e': + e = atoi(optarg); + if (e < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); + } + break; + case 'q': + q = atoi(optarg); + break; + case 'f': + f = atoi(optarg); + if (f <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, f); + exit(1); + } + break; + case 'F': + strcpy(F, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'l': + l = atoi(optarg); + if (l < 1) { + fprintf(stderr, "%s: embedding level out of range\n", progname); + exit(1); + } + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 1000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'S': + s = atoi(optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "XE2SG") >= 5) { + if (n == 0) + fscanf(sig, "%d\n", &n); + else + fscanf(sig, "%*d\n"); + if (a == 0.0) + fscanf(sig, "%lf\n", &a); + else + fscanf(sig, "%*f\n"); + if (e < 0) + fscanf(sig, "%d\n", &e); + else + fscanf(sig, "%*d\n"); + if (f == 0) + fscanf(sig, "%d\n", &f); + else + fscanf(sig, "%*d\n"); + if (!strcmp(F, "")) + fscanf(sig, "%[^\n\r]\n", F); + else + fscanf(sig, "%*[^\n\r]\n"); + if (q == 0) + fscanf(sig, "%d\n", &q); + else + fscanf(sig, "%*d\n"); + if (l == 0) + fscanf(sig, "%d\n", &l); + else + fscanf(sig, "%*d\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + + if (s) + srandom(s); + else + srandom(time(NULL) * getpid()); + + if (n > 0) { + nb = fread(signature, sizeof(char), i = NBITSTOBYTES(n), in); + if (nb < i) { + fprintf(stderr, "%s: failed to read all %d signature bits from %s\n", progname, n, input_name); + exit(1); + } + } + else { + if (fscanf(in, "%128[^\n\r]", signature) == EOF) { + fprintf(stderr, "%s: failed to read signature bits from %s\n", progname, input_name); + exit(1); + } + nb = strlen(signature); + n = NBYTESTOBITS(nb); + fprintf(stderr, "%s: got %d signature bits\n", progname, n); + } + + fprintf(out, "XE2SG\n"); + fprintf(out, "%d\n", n); + fprintf(out, "%f\n", a); + fprintf(out, "%d\n", e); + fprintf(out, "%d\n", f); + fprintf(out, "%s\n", F); + fprintf(out, "%d\n", q); + fprintf(out, "%d\n", l); + fprintf(out, "%ld\n", random()); + fwrite(signature, sizeof(char), nb, out); + fprintf(out, "\n"); + + fclose(out); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_xie_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_xie_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,204 @@ +#include "wm.h" +#include "signature.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-e n] [-f n] [-F file] [-l n] [-n n] [-o file] [-s file] [-S n] [-v n] file\n\n", progname); + fprintf(stderr, "\t-a n\t\tembedding strength (default 0.5)\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); + fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-l n\t\tembedding level (default 5)\n"); + fprintf(stderr, "\t-n n\t\twatermark bit length\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); + fprintf(stderr, "\t-S n\t\tseed\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int verbose = 0; + int c; + int i; + double a = 0.5; + int l = 5; + int n = 0, nb; + int s = 0; + int e = 2; + int f = 1; + char F[MAXPATHLEN] = "filter.dat"; + + progname = argv[0]; + wm_init(); + + while ((c = getopt(argc, argv, "a:e:f:F:h?l:n:o:s:S:v:")) != EOF) { + switch (c) { + case 'a': + a = atof(optarg); + if (a <= 0.0) { + fprintf(stderr, "%s: embedding strength %f out of range\n", progname, a); + exit(1); + } + break; + case 'e': + e = atoi(optarg); + if (e < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); + } + break; + case 'f': + f = atoi(optarg); + if (f <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, f); + exit(1); + } + break; + case 'F': + strcpy(F, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'l': + l = atoi(optarg); + if (l < 1) { + fprintf(stderr, "%s: embedding level out of range\n", progname); + exit(1); + } + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 1000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'S': + s = atoi(optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "XESG") >= 4) { + if (n == 0) + fscanf(sig, "%d\n", &n); + else + fscanf(sig, "%*d\n"); + if (a == 0.0) + fscanf(sig, "%lf\n", &a); + else + fscanf(sig, "%*f\n"); + if (e < 0) + fscanf(sig, "%d\n", &e); + else + fscanf(sig, "%*d\n"); + if (f == 0) + fscanf(sig, "%d\n", &f); + else + fscanf(sig, "%*d\n"); + if (!strcmp(F, "")) + fscanf(sig, "%[^\n\r]\n", F); + else + fscanf(sig, "%*[^\n\r]\n"); + if (l == 0) + fscanf(sig, "%d\n", &l); + else + fscanf(sig, "%*d\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + + if (s) + srandom(s); + else + srandom(time(NULL) * getpid()); + + if (n > 0) { + nb = fread(signature, sizeof(char), i = NBITSTOBYTES(n), in); + if (nb < i) { + fprintf(stderr, "%s: failed to read all %d signature bits from %s\n", progname, n, input_name); + exit(1); + } + } + else { + if (fscanf(in, "%128[^\n\r]", signature) == EOF) { + fprintf(stderr, "%s: failed to read signature bits from %s\n", progname, input_name); + exit(1); + } + nb = strlen(signature); + n = NBYTESTOBITS(nb); + fprintf(stderr, "%s: got %d signature bits\n", progname, n); + } + + fprintf(out, "XESG\n"); + fprintf(out, "%d\n", n); + fprintf(out, "%f\n", a); + fprintf(out, "%d\n", e); + fprintf(out, "%d\n", f); + fprintf(out, "%s\n", F); + fprintf(out, "%d\n", l); + fprintf(out, "%ld\n", random()); + fwrite(signature, sizeof(char), nb, out); + fprintf(out, "\n"); + + fclose(out); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gen_zhu_sig.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gen_zhu_sig.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,197 @@ +#include "wm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-d n] [-e n] [-f n] [-F file] [-l n] [-m n] [-n n] [-o file] [-s file] [-S n]\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor (default 0.2)\n"); + fprintf(stderr, "\t-d n\t\tdeviation (default 1.0)\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); + fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-l n\t\tdecomposition level (default 7)\n"); + fprintf(stderr, "\t-m n\t\tmean value (default 0.0)\n"); + fprintf(stderr, "\t-n n\t\twatermark length (default 1000)\n"); + fprintf(stderr, "\t-o file\t\toutput file\n"); + fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); + fprintf(stderr, "\t-S n\t\tseed\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char signature_name[MAXPATHLEN]; + + int c; + int n = 1000; + int s = 0; + int e = 2; + int f = 1; + char F[MAXPATHLEN] = "filter.dat"; + double a = 0.2; + double m = 0.0; + double d = 1.0; + int l = 7; + + progname = argv[0]; + + while ((c = getopt(argc, argv, "a:d:e:f:F:h?l:m:n:o:s:S:")) != EOF) { + switch (c) { + case 'a': + a = atof(optarg); + if (a <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); + exit(1); + } + break; + case 'l': + l = atoi(optarg); + if (l <= 0) { + fprintf(stderr, "%s: decomposition level %d out of range\n", progname, l); + exit(1); + } + break; + case 'd': + d = atof(optarg); + if (d <= 0.0) { + fprintf(stderr, "%s: deviation %f out of range\n", progname, d); + exit(1); + } + break; + case 'e': + e = atoi(optarg); + if (e < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); + } + break; + case 'f': + f = atoi(optarg); + if (f <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, f); + exit(1); + } + break; + case 'F': + strcpy(F, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'm': + m = atof(optarg); + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 32000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'S': + s = atoi(optarg); + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 0) { + usage(); + exit(1); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "ZHSG") >= 4) { + if (n == 0) + fscanf(sig, "%d\n", &n); + else + fscanf(sig, "%*d\n"); + if (a == 0.0) + fscanf(sig, "%lf\n", &a); + else + fscanf(sig, "%*f\n"); + if (l == 0) + fscanf(sig, "%d\n", &l); + else + fscanf(sig, "%*d\n"); + if (e < 0) + fscanf(sig, "%d\n", &e); + else + fscanf(sig, "%*d\n"); + if (f == 0) + fscanf(sig, "%d\n", &f); + else + fscanf(sig, "%*d\n"); + if (!strcmp(F, "")) + fscanf(sig, "%[^\n\r]\n", F); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + } + + if (s) + srandom(s); + else + srandom(time(NULL) * getpid()); + + fprintf(out, "ZHSG\n"); + fprintf(out, "%d\n", n); + fprintf(out, "%f\n", a); + fprintf(out, "%d\n", l); + fprintf(out, "%d\n", e); + fprintf(out, "%d\n", f); + fprintf(out, "%s\n", F); + + n >>= 1; + while (n > 0) { + double x; + double x1, x2; + + /* + * Algorithm P (Polar method for normal deviates), + * Knuth, D., "The Art of Computer Programming", Vol. 2, 3rd Edition, p. 122 + */ + do { + x1 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; + x2 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; + x = x1 * x1 + x2 * x2; + } while (x >= 1.0); + x1 *= sqrt((-2.0) * log(x) / x); + x2 *= sqrt((-2.0) * log(x) / x); + + fprintf(out, "%f\n", m + d * x1); + fprintf(out, "%f\n", m + d * x2); + + n--; + } + + fclose(out); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gray.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gray.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,117 @@ +#include "wm.h" +#include "gray.h" + +gray **alloc_grays_8x8() { + return alloc_grays(8, 8); +} + +gray **alloc_grays(int cols, int rows) { + gray **p; + int i; + + p = (gray **)malloc(rows * sizeof(gray *)); + if (!p) { +#ifdef DEBUG + fprintf(stderr, "alloc_grays(): malloc() failed\n"); + exit(1); +#else + return NULL; +#endif + } + + p[0] = (gray *)malloc(rows * cols * sizeof(gray)); + if (!p[0]) { +#ifdef DEBUG + fprintf(stderr, "alloc_grays(): malloc() failed\n"); + exit(1); +#else + free(p); + return NULL; +#endif + } + + for (i = 1; i < rows; i++) { + p[i] = &(p[0][i * cols]); + } + + return p; +} + +void free_grays(gray **grays) { + free(grays[0]); + free(grays); +} + +void copy_grays_to_block(gray ** block_grays, gray ** image_grays, int c, int r, int w, int h) { + int i, j; + +#ifdef DEBUG + if (!image_grays) { + fprintf(stderr, "copy_grays_to_block(): NULL image pixels\n"); + } + if (!block_grays) { + fprintf(stderr, "copy_grays_to_block(): NULL block pixels\n"); + } + if (w <= 0 || h <= 0 || c < 0 || r < 0) { + fprintf(stderr, "copy_grays_to_block(): block dimension out of range\n"); + } +#endif + + for (i = 0; i < w; i++) { + for (j = 0; j < h; j++) + block_grays[j][i] = image_grays[r + j][c + i]; + } +} + +void copy_grays_from_block(gray ** image_grays, gray ** block_grays, int +c, int r, int w, int h) { + int i, j; + +#ifdef DEBUG + if (!image_grays) { + fprintf(stderr, "copy_grays_from_block(): NULL image pixels\n"); + } + if (!block_grays) { + fprintf(stderr, "copy_grays_from_block(): NULL block pixels\n"); + } + if (w <= 0 || h <= 0 || c < 0 || r < 0) { + fprintf(stderr, "copy_grays_from_block(): block dimension out of range\n"); + } +#endif + + for (i = 0; i < w; i++) { + for (j = 0; j < h; j++) + image_grays[r + j][c + i] = block_grays[j][i]; + } +} + +void print_grays(gray **grays, int c, int r, int w, int h) { + int i, j; + gray *p; + +#ifdef DEBUG + if (!grays) { + fprintf(stderr, "print_grays(): NULL pixels\n"); + } + if (w <= 0 || h <= 0 || c < 0 || r < 0) { + fprintf(stderr, "print_grays(): block dimension out of range\n"); + } +#endif + + for (j = r; j < r + h; j++) { + p = &grays[j][c]; + for (i = 0; i < w; i++) + fprintf(stderr, "%3d ", *(p++)); + fprintf(stderr, "\n"); + } +} + +void print_grays_8x8(gray **grays) { + int i, j; + + for (i = 0; i < 8; i++) { + for (j = 0; j < 8; j++) + fprintf(stderr, "%3d ", grays[i][j]); + fprintf(stderr, "\n"); + } +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/gray.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/gray.h Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,14 @@ +#ifndef GRAY_H +#define GRAY_H + +#include "wm.h" +#include "netpbm/pgm.h" + +gray **alloc_grays(int cols, int rows); +gray **alloc_grays_8x8(); +void free_grays(gray **grays); +void copy_grays_to_block(gray ** block_grays, gray ** image_grays, int col, int row, int width, int height); +void copy_grays_from_block(gray ** image_grays, gray ** block_grays, int col, int row, int width, int height); +void print_grays(gray **grays, int col, int row, int width, int height); +void print_grays_8x8(gray **grays); +#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/kim_common.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/kim_common.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,60 @@ +#include "wm.h" +#include "kim_common.h" + + +// find the largest absolute coefficient of a subband +double find_subband_largest_coeff(Image_tree s, int subband, int verbose) { + int i, j; + double max; + + max = 0.0; + for (i = 5; i < s->image->height-5; i++) + for (j = 5; j < s->image->width-5; j++) { + double coeff; + + coeff = fabs(get_pixel(s->image, i, j)); + if (coeff > max) + max = coeff; + } + + if (verbose > 8) + fprintf(stderr, " subband %f\n", max); + + return max; +} + +// find largest absolute coefficient of the detail subbands (LH, HL, HH) of +// a decomposition level +double find_level_largest_coeff(Image_tree p, int verbose) { + double h, v, d; + + h = find_subband_largest_coeff(p->horizontal, HORIZONTAL, verbose); + v = find_subband_largest_coeff(p->vertical, VERTICAL, verbose); + d = find_subband_largest_coeff(p->diagonal, DIAGONAL, verbose); + + return MAX(h, MAX(v, d)); +} + +// calculate the significance threshold given the maximum absolute +// coefficient at a decomposition level +double calc_level_threshold(double max_coeff, int verbose) { + double threshold; + + threshold = pow(2.0, floor(log(max_coeff) / log(2.0)) - 1.0); + + if (verbose > 7) + fprintf(stderr, " max %f, threshold %f\n", max_coeff, threshold); + + return threshold; +} + +// calculate an appropriate embedding strength for a given decomposition level +// and a base alpha strength +double calc_level_alpha_detail(double alpha, int maxlevels, int level, int verbose) { + double level_alpha; + + level_alpha = alpha / pow(2.0, level - 1); + + return level_alpha; +} + diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/kim_common.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/kim_common.h Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,13 @@ +#ifndef KIM_COMMON_H +#define KIM_COMMON_H + +#include "dwt.h" +#include "dwt_util.h" + +double find_subband_largest_coeff(Image_tree p, int subband, int verbose); +double find_level_largest_coeff(Image_tree p, int verbose); + +double calc_level_threshold(double max_coeff, int verbose); +double calc_level_alpha_detail(double alpha, int maxlevels, int level, int verbose); + +#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/param_stuff.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/param_stuff.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,133 @@ +#ifdef PARAM_STUFF + { +#define MAXNALPHA 32 + + double alpha[MAXNALPHA]; + char *alpha_str = getenv("PARAM_ALPHA"); + double alpha_value; + int alpha_len = 0; + + int param_len[MAXNALPHA]; + char *param_len_str = getenv("PARAM_LEN"); + int param_len_value; + int param_len_len = 0; + int param_len_sum = 0; + + char buf[1024] = ""; + char *v; + + + if (alpha_str && strlen(alpha_str) < sizeof(buf) + && strcmp(alpha_str, "") ) { + + strcpy(buf, alpha_str); + + v = strtok(buf, "\",; "); + do { + + alpha_value = atof(v); + + if (alpha_value < -M_PI || alpha_value >= M_PI) { + fprintf(stderr, "%s: parametric - alpha %f out of range\n", + progname, alpha_value); + exit(1); + } + + alpha[alpha_len] = alpha_value; + alpha_len++; + } while ((v = strtok(NULL, "\",; "))); + + + if( param_len_str && strlen(param_len_str) < sizeof(buf) + && strcmp(param_len_str, "") ) { + /* There was an parameter length environment variable. */ + + strcpy(buf, param_len_str); + + v = strtok(buf, "\",; "); + do { + + param_len_value = atoi(v); + + if (param_len_value <= 0) { + fprintf(stderr, "%s: parameter length %d out of range\n", + progname, param_len_value); + exit(1); + } + + param_len[param_len_len] = param_len_value; + param_len_len++; + param_len_sum += param_len_value; + + } while ((v = strtok(NULL, "\",; "))); + + } else { + /* No length variable given. + For backward compatability we use all parameters for + one filter and therefore for all levels. + */ + + param_len[0] = alpha_len; + param_len_len = 1; + param_len_sum = alpha_len; + } + + + /* If we do not get a parameter length value for every + decomposition level then we reuse the last supplied value + for the remaining levels. + */ + if (param_len_len < level+1) { + int last_param_len = param_len[ param_len_len - 1 ]; + + for(; param_len_len < level+1; param_len_len++ ) { + param_len[ param_len_len ] = last_param_len; + param_len_sum += last_param_len; + } + } + + + /* If the number of supplied alphas is lower than is required + for by param_len then copy the last filter + parameters to the remaining levels. + */ + if( alpha_len < param_len_sum ) { + int i; + int last_param_len = param_len[ param_len_len - 1 ]; + int last_start = alpha_len - last_param_len; + + for( i=0; alpha_len < param_len_sum; alpha_len++, i++ ) { + alpha[ alpha_len ] = alpha[ last_start + (i % last_param_len) ]; + } + } + + if (verbose > 1) { + int i, j; + int cur_sum = 0; + + fprintf(stderr, "%s: parametric, number of levels: %d\n", + progname, level); + + for (i = 0; i < level+1; i++) { + + fprintf(stderr, " %d filter parameters for level %d: ", + param_len[i], i); + + for (j = 0; j < param_len[i]; j++) { + fprintf(stderr, "%f ", alpha[cur_sum + j]); + } + + fprintf(stderr, "\n"); + + cur_sum += param_len[i]; + } + } + + + dwt_param_filter(alpha, param_len); + + + } /* if( alpha_str... */ + } +#endif + diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/pollen_stuff.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/pollen_stuff.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,27 @@ +#ifdef POLLEN_STUFF + { + double alpha, beta; + char *alpha_str = getenv("POLLEN_ALPHA"), *beta_str = getenv("POLLEN_BETA"); + + if (alpha_str && beta_str) { + alpha = atof(alpha_str); + beta = atof(beta_str); + + if (alpha < -M_PI || alpha >= M_PI) { + fprintf(stderr, "%s: pollen - alpha %f out of range\n", progname, alpha); + exit(1); + } + + if (beta < -M_PI || beta >= M_PI) { + fprintf(stderr, "%s: pollen - beta %f out of range\n", progname, beta); + exit(1); + } + + if (verbose > 7) + fprintf(stderr, "%s: pollen - alpha %f, beta %f\n", progname, alpha, beta); + + dwt_pollen_filter(alpha, beta); + } + } +#endif + diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/signature-utils.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/signature-utils.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,120 @@ +#include +#include +#include "signature-utils.h" + +void init_signature_bits() { + bzero(signature, sizeof(signature)); +} + +void init_signature1_bits() { + bzero(signature1, sizeof(signature1)); +} + +void init_signature2_bits() { + bzero(signature2, sizeof(signature2)); +} + +int _get_signature_bit(char *s, int lim, int n) { + int byte = n >> 3; + int bit = n & 7; + +#ifdef DEBUG + if (byte < 0 || byte >= lim) + fprintf(stderr, "get_signature_bit?(): index out of range\n"); +#endif + + return (s[byte] & (1 << bit)) >> bit; +} + +int get_signature_bit(int n) { + return _get_signature_bit(signature, NSIGNATURE, n); +} + +int get_signature1_bit(int n) { + return _get_signature_bit(signature1, NSIGNATURE, n); +} + +int get_signature2_bit(int n) { + return _get_signature_bit(signature2, NSIGNATURE, n); +} + +void _set_signature_bit(char *s, int limit, int n, int v) { + int byte = n >> 3; + int bit = n & 7; + +#ifdef DEBUG + if (byte < 0 || byte >= limit / 8) + fprintf(stderr, "get_signature_bit?(): index out of range\n"); +#endif + + if (v) + s[byte] |= (1 << bit); + else + s[byte] &= ~(1 << bit); +} + +void set_signature_bit(int n, int v) { + _set_signature_bit(signature, NSIGNATURE, n, v); +} + +void set_signature1_bit(int n, int v) { + _set_signature_bit(signature1, NSIGNATURE, n, v); +} + +void set_signature2_bit(int n, int v) { + _set_signature_bit(signature2, NSIGNATURE, n, v); +} + +int _binstr_to_sig(const char *binstr, char *sig, int *bytes, int *bits) { + int n = strlen(binstr); + int i; + + for (i = 0; i < n; i++) { + if (binstr[i] == '0') + _set_signature_bit(sig, NSIGNATURE, i, 0); + else if (binstr[i] == '1') + _set_signature_bit(sig, NSIGNATURE, i, 1); + else + return 0; + } + + *bytes = (n % 8 > 0) ? n / 8 + 1 : n / 8; + *bits = n; + + return 1; +} + +int binstr_to_sig(const char *binstr) { + return _binstr_to_sig(binstr, signature, &n_signature, &nbit_signature); +} + +int binstr_to_sig1(const char *binstr) { + return _binstr_to_sig(binstr, signature1, &n_signature1, &nbit_signature1); +} + +int binstr_to_sig2(const char *binstr) { + return _binstr_to_sig(binstr, signature2, &n_signature2, &nbit_signature2); +} + +int _sig_to_binstr(char *binstr, char *sig, int bits) { + int i; + + for (i = 0; i < bits; i++) + binstr[i] = _get_signature_bit(sig, NSIGNATURE, i) ? '1' : '0'; + + binstr[bits] = '\0'; + + return 1; +} + +int sig_to_binstr(char *binstr) { + return _sig_to_binstr(binstr, signature, nbit_signature); +} + +int sig1_to_binstr(char *binstr) { + return _sig_to_binstr(binstr, signature1, nbit_signature1); +} + +int sig2_to_binstr(char *binstr) { + return _sig_to_binstr(binstr, signature2, nbit_signature2); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/signature-utils.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/signature-utils.h Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,37 @@ +#ifndef SIGNATURE_UTILS_H +#define SIGNATURE_UTILS_H + +#define NSIGNATURE 4096 +#define NBITSIGNATURE (NSIGNATURE * 8) + +extern int n_signature; +extern int nbit_signature; +extern int n_signature1; +extern int nbit_signature1; +extern int n_signature2; +extern int nbit_signature2; + +extern char signature[NSIGNATURE]; +extern char signature1[NSIGNATURE]; +extern char signature2[NSIGNATURE]; + +void init_signature_bits(); +int get_signature_bit(int n); +void set_signature_bit(int n, int v); + +void init_signature1_bits(); +int get_signature1_bit(int n); +void set_signature1_bit(int n, int v); + +void init_signature2_bits(); +int get_signature2_bit(int n); +void set_signature2_bit(int n, int v); + +int binstr_to_sig(const char *binstr); +int binstr_to_sig1(const char *binstr); +int binstr_to_sig2(const char *binstr); +int sig_to_binstr(char *binstr); +int sig1_to_binstr(char *binstr); +int sig2_to_binstr(char *binstr); + +#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/signature.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/signature.h Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,18 @@ +#ifndef SIGNATURE_H +#define SIGNATURE_H + +#include "wm.h" +#include "signature-utils.h" + +int n_signature; +int nbit_signature; +int n_signature1; +int nbit_signature1; +int n_signature2; +int nbit_signature2; + +char signature[NSIGNATURE]; +char signature1[NSIGNATURE]; +char signature2[NSIGNATURE]; + +#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/sort.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/sort.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,184 @@ +#include "sort.h" + +#define SWAP_GRAY(A, B) {gray t = A; A = B; B = t;} + +/* + * quicksort-alike, from the EMX library (emx/src/lib/misc/qsort.c) + * by Eberhard Mattes + * + * sort() is not stable, the order of equal elements is not defined + */ + +void _sort_grays(gray *l, gray *r) { + gray *i; + gray *j; + gray *x; + +redo: + i = l; + j = r; + x = l + sizeof(gray) * (((r-l) / sizeof(gray)) / 2); + + do { + while (i != x && *i < *x) + i++; + while (j != x && *j > *x) + j--; + if (i < j) { + SWAP_GRAY(*i, *j); + if (x == i) + x = j; + else if (x == j) + x = i; + } + if (i <= j) { + i++; + if (j > l) + j--; + } + } while (i <= j); + + if (j-l < r-i) { + if (l < j) + _sort_grays(l, j); + if (i < r) { + l = i; + goto redo; + } + } + else { + if (i < r) + _sort_grays(i, r); + if (l < j) { + r = j; + goto redo; + } + } +} + +void sort_grays(gray a[], int n) { + if (n > 1) + _sort_grays(&a[0], &a[n-1]); +} + +/* + * select_largest(), from the Numeric Recipes in C, Chapter 8, p. 344, + * see http://www.nr.com + * + * returns in largest[0..m-1] the largest m elements of array[0..n-1] + * with largest[0] guaranteed to be the mth largest element; largest[] is + * not sorted; the array[] is not altered; this function should be used + * only when m << n + */ + +void select_largest_grays(gray array[], int n, int m, gray largest[]) { + int i, j, k; + + if (m <= 0 || m > n/2) + return; + + for (i = 0; i < m; i++) + largest[i] = array[i]; + sort_grays(largest, m); + + for (i = m; i < n; i++) { + if (array[i] > largest[0]) { + largest[0] = array[i]; + j = 0; + k = 1; + while (k < m) { + if (k < m-1 && largest[k] > largest[k+1]) + k++; + if (largest[j] <= largest[k]) + break; + SWAP_GRAY(largest[k], largest[j]); + j = k; + k = k << 1; + } + } + } +} + +#define SWAP_DOUBLE(A, B) {double t = A; A = B; B = t;} + +void _sort_coeffs(double *l, double *r) { + double *i; + double *j; + double *x; + +redo: + i = l; + j = r; + x = l + sizeof(double) * (((r-l) / sizeof(double)) / 2); + + do { + while (i != x && *i < *x) + i++; + while (j != x && *j > *x) + j--; + if (i < j) { + SWAP_DOUBLE(*i, *j); + if (x == i) + x = j; + else if (x == j) + x = i; + } + if (i <= j) { + i++; + if (j > l) + j--; + } + } while (i <= j); + + if (j-l < r-i) { + if (l < j) + _sort_coeffs(l, j); + if (i < r) { + l = i; + goto redo; + } + } + else { + if (i < r) + _sort_coeffs(i, r); + if (l < j) { + r = j; + goto redo; + } + } +} + +void sort_coeffs(double a[], int n) { + if (n > 1) + _sort_coeffs(&a[0], &a[n-1]); +} + +void select_largest_coeffs(double array[], int n, int m, double largest[]) { + int i, j, k; + + if (m <= 0 || m > n/2) + return; + + for (i = 0; i < m; i++) + largest[i] = array[i]; + sort_coeffs(largest, m); + + for (i = m; i < n; i++) { + if (array[i] > largest[0]) { + largest[0] = array[i]; + j = 0; + k = 1; + while (k < m) { + if (k < m-1 && largest[k] > largest[k+1]) + k++; + if (largest[j] <= largest[k]) + break; + SWAP_DOUBLE(largest[k], largest[j]); + j = k; + k = k << 1; + } + } + } +} + + diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/sort.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/sort.h Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,13 @@ +#ifndef SORT_H +#define SORT_H + +#include "wm.h" +#include "netpbm/pgm.h" + +void sort_grays(gray a[], int n); +void select_largest_grays(gray array[], int n, int m, gray largest[]); + +void sort_coeffs(double a[], int n); +void select_largest_coeffs(double array[], int n, int m, double largest[]); + +#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wang_common.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wang_common.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,179 @@ +#include "dwt_util.h" +#include "wang_common.h" + +Subband_data *subbands; +int n_subbands; + +void init_subbands(Image_tree tree) { + int levels = 0; + int i; + Image_tree p = tree; + + // determine # of detail subbands + while (p->coarse != NULL) { + levels++; + p = p->coarse; + } + + // there are 3 detail subbands per level + n_subbands = 3 * levels; + + // allocate memory for subband data + subbands = malloc(n_subbands * sizeof(Subband_data)); + + p = tree; + i = 0; + while (p->coarse != NULL) { + subbands[i++] = alloc_subband(HORIZONTAL, p->horizontal); + subbands[i++] = alloc_subband(VERTICAL, p->vertical); + subbands[i++] = alloc_subband(DIAGONAL, p->diagonal); + + p = p->coarse; + } + +} + +Subband_data alloc_subband(int type, Image_tree tree) { + int i; + Subband_data p = malloc(sizeof(struct Subband_data_struct)); + + p->T = 0.0; + p->beta = 0.0; + p->Cmax = 0.0; + p->tree = tree; + p->level = tree->level; + p->width = tree->image->width; + p->height = tree->image->height; + p->size = p->height * p->width; + p->image = tree->image; + p->type = type; + + p->selected = malloc(p->height * sizeof(char *)); + p->selected[0] = calloc(p->size, sizeof(char)); + for (i = 1; i < p->height; i++) + p->selected[i] = &(p->selected[0][i * p->width]); + + return p; +} + +void set_subband_beta(Subband_data subband, double beta) { + subband->beta = beta; +} + +void set_subbands_beta(double beta) { + int i; + + for (i = 0; i < n_subbands; i++) + set_subband_beta(subbands[i], beta); +} + +void set_subbands_type_beta(int type, double beta) { + int i; + + for (i = 0; i < n_subbands; i++) + if (subbands[i]->type == type) + set_subband_beta(subbands[i], beta); +} + +void calc_subband_threshold(Subband_data subband) { + double max; + int i, j; + + max = fabs(get_pixel(subband->image, 0, 0)); + for (i = 0; i < subband->height; i++) + for (j = 0; j < subband->width; j++) { + Pixel p = fabs(get_pixel(subband->image, i, j)); + if (p > max) + max = p; + } + + subband->Cmax = max; + subband->T = max / 2.0; +} + +void calc_subbands_threshold() { + int i; + + for (i = 0; i < n_subbands; i++) + calc_subband_threshold(subbands[i]); +} + +Subband_data select_subband() { + int max = 0; + int i; + + for (i = 0; i < n_subbands; i++) + if ((subbands[i]->beta * subbands[i]->T) > (subbands[max]->beta * subbands[max]->T)) + max = i; + + return subbands[max]; +} + +int subband_coeff_isselected(Subband_data subband, int coeff) { + return subband->selected[0][coeff]; +} + +Pixel get_subband_coeff(Subband_data subband, int coeff) { + return subband->image->data[coeff]; +} + +void set_subband_coeff(Subband_data subband, int coeff, Pixel data) { + subband->image->data[coeff] = data; +} + +int select_subband_coeff_from(Subband_data subband, int from) { + int i; + + for (i = from; i < subband->size; i++) + if (!subband_coeff_isselected(subband, i) && + get_subband_coeff(subband, i) > subband->T) + return i; + + return -1; +} + +int select_subband_coeff(Subband_data subband) { + return select_subband_coeff_from(subband, 0); +} + +void mark_subband_coeff(Subband_data subband, int coeff) { + subband->selected[0][coeff] = 1; +} + +void free_subband(Subband_data subband) { + free(subband->selected[0]); + free(subband->selected); + free(subband); +} + +void free_subbands() { + int i; + + for (i = 0; i < n_subbands; i++) + free_subband(subbands[i]); + + free(subbands); +} + +#define LARGE DBL_MAX + +Pixel figure_orig_coeff(double T, double alpha, double beta, Pixel coeff) { + int p, p_min = 0; + double dist_min = LARGE; + double sign = (coeff >= 0) ? 1.0 : -1.0; + + for (p = 1; p < 1.0 / (2.0 * alpha); p++) { + double dist, delta; + + delta = (1.0 + 2.0 * p * alpha) * T; + dist = fabs(delta - fabs(coeff)); + + if (dist < dist_min) { + dist_min = dist; + p_min = p; + } + } + + if (!p_min) p_min = 1; + return sign * (1.0 + 2.0 * p_min * alpha) * T; +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wang_common.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wang_common.h Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,43 @@ +#ifndef WANG_COMMON_H +#define WANG_COMMON_H + +#include "dwt.h" + +typedef struct Subband_data_struct { + double T; + double Cmax; + double beta; + Image_tree tree; + int level; + int type; + int width; + int height; + int size; + Image image; + char** selected; +} *Subband_data; + +void init_subbands(Image_tree tree); +Subband_data alloc_subband(int type, Image_tree tree); +void free_subband(Subband_data subband); +void free_subbands(); + +void set_subband_beta(Subband_data subband, double beta); +void set_subbands_beta(double beta); +void set_subbands_type_beta(int type, double beta); + +void calc_subband_threshold(Subband_data subband); +void calc_subbands_threshold(); + +int subband_coeff_isselected(Subband_data subband, int coeff); +Pixel get_subband_coeff(Subband_data subband, int coeff); +void set_subband_coeff(Subband_data subband, int coeff, Pixel data); + +Subband_data select_subband(); +int select_subband_coeff_from(Subband_data subband, int from); +int select_subband_coeff(Subband_data subband); +void mark_subband_coeff(Subband_data subband, int coeff); + +Pixel figure_orig_coeff(double T, double alpha, double beta, Pixel coeff); + +#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wavelet.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wavelet.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,2982 @@ +#include +#include +#include +#include +#include "wavelet.h" +#include +#include + +static int read_char(FILE *fp); +static int read_int(FILE *fp); + +IntImage new_intimage(int width, int height) +{ + IntImage image; + + image = (IntImage) calloc(1,sizeof(struct IntImage_struct)); + if (image==NULL) goto error; + image->data = (IntPixel*) calloc(width*height,sizeof(IntPixel)); + if (image->data==NULL) goto error; + image->width = width; + image->height = height; + image->size = width*height; + image->bpp = 0; + image->min_val = (IntPixel) 0; + image->max_val = (IntPixel) 0; + + return image; + + error: + err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); + return NULL; +} + +Image new_image(int width, int height) +{ + Image image; + + image = (Image) calloc(1,sizeof(struct Image_struct)); + if (image==NULL) goto error; + image->data = (Pixel*) calloc(width*height,sizeof(Pixel)); + if (image->data==NULL) goto error; + image->width = width; + image->height = height; + image->size = width*height; + image->bpp = 0; + image->min_val = (Pixel) 0; + image->max_val = (Pixel) 0; + + return image; + + error: + err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); + return NULL; +} + + +void free_intimage(IntImage img) +{ + if (img) { + if (img->data) free(img->data); + free(img); + } +} + +void free_image(Image img) +{ + if (img) { + if (img->data) free(img->data); + free(img); + } +} + +/************************************************************************ + * Functionname: load_intimage + * -------------------------------------------------------------------- + * PARAMETER: + * file: filename of image + * max_val: scaling of grey values to [0..max_val] + * + * RETURN: + * Image that shoud be loaded, if not possible return NULL + * -------------------------------------------------------------------- + * DESCRIPTION: + * This function loads an IntImage (PGM, ASCII or binary + * encoded (P5 or P3 format) ) from a file. + ************************************************************************/ + +IntImage load_intimage(char *file, int max_val) +{ + IntImage img; + FILE *fp; + IntPixel *data; + int width, height, i, ch1, ch2; + + fp=fopen(file,"rb"); + if (fp==NULL) goto error; + + ch1=getc(fp); + ch2=getc(fp); + if (ch1!='P' || (ch2!='5' && ch2!='2')) goto error1; + + width=read_int(fp); + height=read_int(fp); + if ((width==0) || (height==0) ) goto error1; + read_int(fp); + + img=new_intimage(width,height); + + img->bpp=8; + + data=img->data; + for (i=0; isize; i++) + { if (ch2=='5') + *data=getc(fp); + else + *data=read_int(fp); + data++; + } + fclose(fp); + return img; + + error1: + err_SimpleMessage(err_GetErrorMessage(Error_WrongFileFormat)); + return NULL; + error: + err_SimpleMessage(err_GetErrorMessage(Error_CantOpenFile)); + return NULL; +} + +/************************************************************************ + * Functionname: load_image + * -------------------------------------------------------------------- + * PARAMETER: + * file: filename of image + * max_val: scaling of grey values to [0..max_val] + * + * RETURN: + * Image that shoud be loaded, if not possible return NULL + * -------------------------------------------------------------------- + * DESCRIPTION: + * This function loads an IntImage with load_intimage + * and then converts to Image. + ************************************************************************/ +Image load_image(char *file, int max_val) +{ + Image img; + IntImage intimg; + + intimg = load_intimage(file, max_val); + if (!intimg) return NULL; + img = intimage_to_image(intimg); + if (!intimg) return NULL; + + return img; +} + +/************************************************************************/ +/* Functionname: save_image_P5 */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* img: Image that shoud be saved */ +/* file: filename of image */ +/* -------------------------------------------------------------------- */ +/* Description: save an image as PGM (P5 binary decoded) file */ +/* */ +/************************************************************************/ + +int save_image_P5(char *file, Image img) +{ FILE *fp; + Pixel *data; + long i; + int p; + + fp=fopen(file,"wb"); + if (fp==NULL) + goto error; + fprintf(fp,"P5\n"); + fprintf(fp,"%d %d\n%d ",img->width,img->height,255); + data=img->data; + for (i=0;isize;i++) { + p=floor(*data+0.5); + if (p<0) p=0; + if (p>255) p=255; +/* putc(*data,fp); */ + putc(p,fp); + data++; + } + fclose(fp); + return 1; + + error: + err_SimpleMessage(err_GetErrorMessage(Error_CantOpenFile)); + return 0; +} + +void clear_image(Image img) +{ + int i; + + PreCondition(img!=NULL,"image==NULL"); + + for (i=0;isize;i++) + (img->data)[i]=(Pixel) 0; +} + +void copy_into_image(Image img1,Image img2,int x,int y) +/* copy img2 into img1 at position (x,y)*/ +{ + int start,i,j,aim; + Pixel *temp; + + temp=img2->data; + start=img1->width*y+x; + for (i=0;iheight;i++) { + for (j=0;jwidth;j++) { + aim=start+j+img1->width*i; + img1->data[aim]=*temp; + temp++; + } + } +} + +void copy_into_intimage(IntImage img1,IntImage img2,int x,int y) +{/* copy img2 into img1 at position (x,y)*/ + + int start,i,j,aim; + IntPixel *temp; + + temp=img2->data; + start=img1->width*y+x; + for (i=0;iheight;i++) + { + for (j=0;jwidth;j++) + { + aim=start+j+img1->width*i; + img1->data[aim]=*temp; + temp++; + } + } +} + +void copy_part_of_image_into_image(Image dest_img, int dest_x, int dest_y, + Image src_img, int src_x, int src_y, + int width, int height) +{ + Pixel *sp,*dp; + int y,siz; + + sp=get_pixel_adr(src_img,src_x,src_y); + dp=get_pixel_adr(dest_img,dest_x,dest_y); + + siz=width*sizeof(Pixel); + + for (y=0;ywidth; + dp+=dest_img->width; + } +} + +void copy_part_of_image(Image img1,Image img2,int x,int y) +/* copy part of img2 begining at position (x,y) into img1 */ +{ int i,j,width,height,start,step; + Pixel *data; + + width=img1->width; + height=img1->height; + start=img2->width*y+x; + data=img1->data; + for (i=0;iwidth; + for (j=0;jdata[start+j+step]; + data++; + } + } +} + + +void scale_image(Image img, int maximum) +/* scale image to [0..maximum]*/ +{ int i; + Pixel max = MINDOUBLE, min = MAXDOUBLE, multi; + + for (i=0;isize;i++) { + if (img->data[i]data[i]; + else if (img->data[i]>max) max=img->data[i]; + } + + multi=(Pixel)maximum/(max-min); + for (i=0;isize;i++) img->data[i]=multi*(img->data[i]-min); + img->min_val=0; + img->max_val=maximum; +} + +int string_to_pixel(char *str, Pixel *p) +{ + float ppp; + if (sscanf(str,"%f",&ppp)==1) + { + *p=(Pixel) ppp; + return 1; + } + else + { + *p=0.0; + return 0; + } +} + +Image intimage_to_image(IntImage i) +{ Image img; + int j; + + img=new_image(i->width,i->height); + if (img==NULL) goto error; + for (j=0;jsize;j++) + img->data[j]=(Pixel)i->data[j]; + img->bpp=i->bpp; + return img; + + error: + err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); + return NULL; +} +IntImage image_to_intimage(Image i) +{ IntImage img; + int j,multi=1,max,min; + + img=(IntImage)calloc(1,sizeof(struct IntImage_struct)); + if (img==NULL) goto error; + img->data=(IntPixel *)calloc(i->size,sizeof(IntPixel)); + if (img->data==NULL) goto error; + img->width=i->width; + img->height=i->height; + img->size=i->size; + img->bpp=i->bpp; + + max=i->max_val; + min=i->min_val; + if ((max-min)!=0) + multi=255.0/(max-min); + + for (j=0;jsize;j++) + img->data[j]=(int)((i->data[j]-min)*multi+0.5); + return img; + + error: + err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); + return NULL; + +} + +static int read_char(FILE *fp) +/*read a character from file, but skip any comments*/ +{ int ch; + + ch=getc(fp); + if (ch=='#'){ + do { + ch=getc(fp); + } while (ch!='\n' && ch!=EOF); + } + return ch; +} + + +static int read_int(FILE *fp) +/*read an ascii integer from file, and skip leading tabstops,new lines ...*/ +{ int r,ch; + + do { + ch=read_char(fp); + } while (ch==' ' || ch=='\n' || ch=='\t'); + + if (ch<'0' || ch>'9') + goto error; + + r=ch-'0'; + while ( (ch=read_char(fp)) >='0' && (ch <= '9') ) { + r*=10; + r+=ch-'0'; + } + return r; + error: + return 0; +} + +Image_tree new_image_tree() +{ + Image_tree t; + t=(Image_tree) calloc(1,sizeof(struct Image_tree_struct)); + t->entropy=0.0; + t->image=NULL; + t->coarse=t->horizontal=t->vertical=t->diagonal=t->doubletree=NULL; + t->level=0; + t->codec_data=NULL; + t->significance_map=NULL; + return t; +} + +void free_image_tree(Image_tree t) +{ + if (t->coarse) free_image_tree(t->coarse); + if (t->horizontal) free_image_tree(t->horizontal); + if (t->vertical) free_image_tree(t->vertical); + if (t->diagonal) free_image_tree(t->diagonal); + if (t->doubletree) free_image_tree(t->doubletree); + if (t->image) free_image(t->image); + if (t->significance_map) free_intimage(t->significance_map); + if (t->codec_data) free(t->codec_data); + t->image=NULL; + free(t); +} + +/*********************************************************************** + * Functionname: get_image_infos + * -------------------------------------------------------------------- + * Parameter: + * Image image: input image + * Pixel *min,*max,*avg,*var: return minimum, maximum, + * average and variance of current image + * -------------------------------------------------------------------- + * Description: + * get statistical information of Image + ************************************************************************/ + +void get_image_infos(Image image, Image_info info) +{ + int x,y; + Pixel p,sp,sp2; + + sp=sp2=(Pixel)0.0; + + p=get_pixel(image,0,0); + + info->min=info->max=p; + + for (y=0;yheight;y++) + for (x=0;xwidth;x++) + { + p=get_pixel(image,x,y); + info->max=MAX(info->max,p); + info->min=MIN(info->min,p); + sp+=p; + sp2+=p*p; + } + sp=sp/image->width/image->height; + sp2=sp2/image->width/image->height; + + info->mean=sp; + info->var=sp2-sp*sp; + info->rms=sqrt(sp2); +} + +/*********************************************************************** + * Functionname: get_difference_image + * -------------------------------------------------------------------- + * Parameter: + * Image image1, image 2: input images + * + * Return: + * Image : difference of image1 and image 2, + * NULL if error occurs + ************************************************************************/ + +Image get_difference_image(Image image1, Image image2) +{ + Image diff; + int i,max,w,h; + Pixel *d,*i1,*i2; + + if ((!image1) || (!image2)) return NULL; + + w=image1->width; + h=image1->height; + + if (image2->width != w || image2->height != h) return NULL; + + diff=new_image(w,h); + max=w*h; + + d=diff->data; + i1=image1->data; + i2=image2->data; + + for (i=0;iheight;y++) + for (x=0;xwidth;x++) + { + p= (Pixel) get_intpixel(image,x,y); + *max=MAX(*max, (IntPixel) p); + *min=MIN(*min, (IntPixel) p); + sp+=p; + sp2+=p*p; + } + sp=sp/image->width/image->height; + sp2=sp2/image->width/image->height; + + *avg=sp; + *var=sp2-sp*sp; +} + +/************************************************************************/ +/* Functionname: init_zigzag */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* Zigzag_data_struct: */ +/* output: will be initialized, x/y hold coordinates of */ +/* the first pixel */ +/* int width,height: */ +/* input: width/height of image: */ +/* -------------------------------------------------------------------- */ +/* Description: */ +/* initializes Zigzag_data structure for use with next_zigzag */ +/************************************************************************/ + +void init_zigzag(Zigzag_data zz, int width, int height) +{ + zz->x=0; + zz->y=0; + zz->dir=zigzag_up; + zz->w=width; + zz->h=height; +} + +/************************************************************************/ +/* Functionname: next_zigzag */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* Zigzag_data_struct: */ +/* int x,y: */ +/* input: current position of zigzag-scan */ +/* output: next position of zigzag-scan */ +/* int w,h: width and height of image */ +/* enum zigzag_direction *dir: i/o: */ +/* direction moving thru the image */ +/* -------------------------------------------------------------------- */ +/* Description: */ +/* calculates the next point (x',y') of the zigzag-scan */ +/* through the image with size (w,h) */ +/************************************************************************/ + + +void next_zigzag(Zigzag_data zz) +{ + switch(zz->dir) + { + case zigzag_up: + if (zz->y==0) + { + if (zz->x==zz->w-1) + { + (zz->y)++; zz->dir=zigzag_down; + } + else + { + (zz->x)++; zz->dir=zigzag_down; + } + } + else + { + if (zz->x==zz->w-1) + { + (zz->y)++; zz->dir=zigzag_down; + } + else + { + (zz->x)++; (zz->y)--; + } + } + break; + + case zigzag_down: + + if (zz->x==0) + { + if (zz->y==zz->h-1) + { + (zz->x)++; zz->dir=zigzag_up; + } + else + { + (zz->y)++; zz->dir=zigzag_up; + } + } + else + { + if (zz->y==zz->h-1) + { + (zz->x)++; zz->dir=zigzag_up; + } + else + { + (zz->x)--;(zz->y)++; + } + } + break; + } +} + +Image get_absolute_image_scaled(Image img) +{ + Image out; + + int x,y; + + struct Image_info_struct info; + Pixel scale,p; + + out=new_image(img->width,img->height); + + get_image_infos(img, &info); + + scale=255/MAX(fabs(info.min),fabs(info.max)); + + for(y=0;yheight;y++) + for(x=0;xwidth;x++) + { + p=get_pixel(img,x,y)*scale; + set_pixel(out,x,y,p); + } + return out; +} + +#define FLOOR_HALF(x) ((x)&1 ? ((x)-1)/2 : (x)/2) +#define CEILING_HALF(x) ((x)&1 ? ((x)+1)/2 : (x)/2) + +#define MOD(a,b) ( (a)<0 ? ((b)-((-(a))%(b))) : (a)%(b) ) + +Filter new_filter(int size) +{ + Filter f; + + Entering; + f=(Filter) calloc(1,sizeof(struct FilterStruct)); + f->data=(Pixel *)calloc(size,sizeof(Pixel)); + f->len=size; + f->hipass=0; + + Leaving; + return f; +} + +Pixel get_filter_center(Filter f) +{ + int i; + Pixel p, sum, norm; + + if (f==NULL) return 0; + + sum=norm=0; + + for (i=0;ilen;i++) + { + p=f->data[i]; + p=p*p; + norm += p; + sum += (i+f->start)*p; + } + p=sum/norm; + + return p; +} +int filter_cutoff(Image in, int in_start, int in_len, int in_step, + Image out, int out_start, int out_len, int out_step, + Filter f) +{ + int i,i2,j; + Pixel *out_pix, *in_pix, *f_data; + int fstart,fend; /* Source interval */ + + Entering; + + PreCondition(out_len == in_len/2,"out_len != in_len/2 !!!"); + +/* convolution: out[i]=sum_{j=start}^{end} (in[2*i-j]*f[j]) + + boundaries: image in [in_start ... in_start + in_len-1] + image out [out_start ... out_start + out_len-1] + filter f [0..f->len-1] = [f->start .. f->end] + cutoff at: +*/ + + for (i=0;istart); + fend=MIN(i2,f->end); + +#ifdef TRACE + sprintf(dbgstr,"i=%d fstart=%d fend=%d\n",i,fstart,fend); + Trace(dbgstr); +#endif + + out_pix=out->data+out_start+i*out_step; + + in_pix=in->data+in_start+(i2-fstart)*in_step; + + f_data=f->data-f->start+fstart; + + for (j=fstart;j<=fend;j++,in_pix-=in_step,f_data++) + { + *out_pix += (*f_data) * (*in_pix); +#ifdef TRACE + + sprintf(dbgstr," j=%2d in: %4.2f filter: %4.2f [%4d] [%4d] opt : %4.2f %4.2f\n", + j, + in->data[in_start+in_step*(i2-j)], + f->data[j-f->start], + in_start+in_step*(i2-j), + j-f->start, + *in_pix, *f_data); + Trace(dbgstr); +#endif + } + } + + Leaving; + return 1; +} + + +int filter_inv_cutoff(Image in, int in_start, int in_len, int in_step, + Image out, int out_start, int out_len, int out_step, + Filter f) +{ + int i,j; + Pixel *out_pix, *in_pix, *f_data; + int fstart,fend; /* Source interval */ + Entering; + PreCondition(out_len == in_len*2,"out_len != in_len*2 !!!"); + +/* convolution: out[i]=sum_{j=start}^{end} (f[2*j-i]*in[j]) + + boundaries: image in [in_start ... in_start + in_len-1] + image out [out_start ... out_start + out_len-1] + filter f [0..f->len-1] = [f->start .. f->end] + cutoff at: +*/ + + for (i=0;istart+i); + fend=FLOOR_HALF(f->end+i); + fstart=MAX(fstart,0); + fend=MIN(fend,in_len-1); + +#ifdef TRACE + sprintf(dbgstr,"i=%d fstart=%d fend=%d\n",i,fstart,fend); + Trace(dbgstr); +#endif + out_pix=out->data+out_start+i*out_step; + + in_pix=in->data+in_start+fstart*in_step; + + f_data=f->data-f->start+2*fstart-i; + + for (j=fstart;j<=fend;j++,in_pix+=in_step,f_data+=2) + { + *out_pix += (*f_data) * (*in_pix); +#ifdef TRACE + sprintf(dbgstr," j=%2d in: %4.2f filter: %4.2f [%4d] [%4d] opt : %4.2f %4.2f\n", + j, + in->data[in_start+j*in_step], + f->data[2*j-i-f->start], + in_start+j*in_step, + 2*j-i-f->start, + *in_pix, *f_data); + Trace(dbgstr); +#endif + } + } + + Leaving; + return 1; +} + +int filter_periodical(Image in, int in_start, int in_len, int in_step, + Image out, int out_start, int out_len, int out_step, + Filter f) +{ + int i,i2,j; + Pixel *out_pix, *in_pix, *f_data; + int fstart,fend; + int istart; + int ipix_len; + + Entering; + PreCondition(out_len == in_len/2,"out_len != in_len/2 !!!"); + +/* convolution: out[i]=sum_{j=start}^{end} (in[2*i-j]*f[j]) + + boundaries: image in [in_start ... in_start + in_len-1] + image out [out_start ... out_start + out_len-1] + filter f [0..f->len-1] = [f->start .. f->end] +*/ + + ipix_len=in_len*in_step; + + for (i=0;istart; + fend=f->end; + + istart=(i2-fstart); + istart=MOD(istart,in_len); + +#ifdef TRACE + sprintf(dbgstr,"i=%d istart=%d\n",i,istart); + Trace(dbgstr); +#endif + + out_pix=out->data+out_start+i*out_step; + + in_pix=in->data+in_start+istart*in_step; + + f_data=f->data; + + for (j=fstart;j<=fend;j++,f_data++) + { + *out_pix += (*f_data) * (*in_pix); +#ifdef TRACE + + sprintf(dbgstr," j=%2d in: %4.2f filter: %4.2f [%4d] [%4d] opt : %4.2f %4.2f\n", + j, + in->data[in_start+in_step*((i2-j+in_len)%in_len)], + f->data[j-f->start], + in_start+in_step*((i2-j+in_len)%in_len), + j-f->start, + *in_pix, *f_data); + Trace(dbgstr); +#endif + in_pix-=in_step; + istart--; + if (istart<0) + { + istart+=in_len; + in_pix+=ipix_len; + } + } + } + + Leaving; + return 1; +} + +int filter_inv_periodical(Image in, int in_start, int in_len, int in_step, + Image out, int out_start, int out_len, int out_step, + Filter f) +{ + int i,j; + Pixel *out_pix, *in_pix, *f_data; + int fstart,fend; /* Source interval */ + int istart; + int ipix_len; + Entering; + PreCondition(out_len == in_len*2,"out_len != in_len*2 !!!"); + +/* convolution: out[i]=sum_{j=start}^{end} (f[2*j-i]*in[j]) + + boundaries: image in [in_start ... in_start + in_len-1] + image out [out_start ... out_start + out_len-1] + filter f [0..f->len-1] = [f->start .. f->end] +*/ + + ipix_len=in_len*in_step; + + for (i=0;istart+i); + fend=FLOOR_HALF(f->end+i); + + istart=MOD(fstart,in_len); +#ifdef TRACE + sprintf(dbgstr,"i=%d fstart=%d fend=%d istart=%d\n",i,fstart,fend,istart); + Trace(dbgstr); +#endif + out_pix=out->data+out_start+i*out_step; + + in_pix=in->data+in_start+istart*in_step; + + f_data=f->data-f->start+2*fstart-i; + + for (j=fstart;j<=fend;j++,f_data+=2) + { + *out_pix += (*f_data) * (*in_pix); +#ifdef TRACE + sprintf(dbgstr," j=%2d in: %4.2f filter: %4.2f [%4d] [%4d] opt : %4.2f %4.2f\n", + j, + in->data[in_start+(j % in_len)*in_step], + f->data[2*j-i-f->start], + in_start+(j%in_len)*in_step, + 2*j-i-f->start, + *in_pix, *f_data); + Trace(dbgstr); +#endif + in_pix+=in_step; + istart++; + if (istart>=in_len) + { + istart-=in_len; + in_pix-=ipix_len; + } + } + } + + Leaving; + return 1; +} + +int filter_mirror(Image in, int in_start, int in_len, int in_step, + Image out, int out_start, int out_len, int out_step, + Filter f) +{ + int i,i2,j; + Pixel *out_pix, *in_pix, *f_data; + int fstart,fend; + int in_pos; + + Entering; + PreCondition(out_len == in_len/2,"out_len != in_len/2 !!!"); + +/* convolution: out[i]=sum_{j=start}^{end} (in[2*i-j]*f[j]) + + boundaries: image in [in_start ... in_start + in_len-1] + image out [out_start ... out_start + out_len-1] + filter f [0..f->len-1] = [f->start .. f->end] +*/ + + in_pix=in->data+in_start; + + for (i=0;istart; + fend=f->end; + + out_pix=out->data+out_start+i*out_step; + + f_data=f->data; + + for (j=fstart;j<=fend;j++) + { + in_pos=(i2-j); + if (in_pos<0) + { + in_pos=-in_pos; + if (in_pos>=in_len) continue; + } + if (in_pos>=in_len) + { + in_pos=2*in_len-2-in_pos; + if (in_pos<0) continue; + } + *out_pix += (f_data[j-fstart]) * (in_pix[in_pos*in_step]); + } + } + + Leaving; + return 1; +} + +int filter_inv_mirror(Image in, int in_start, int in_len, int in_step, + Image out, int out_start, int out_len, int out_step, + Filter f) +{ + int i,j; + Pixel *out_pix, *in_pix; + int fstart,fend; /* Source interval */ + int in_pos; + + Entering; + PreCondition(out_len == in_len*2,"out_len != in_len*2 !!!"); + +/* convolution: out[i]=sum_{j=start}^{end} (f[2*j-i]*in[j]) + + boundaries: image in [in_start ... in_start + in_len-1] + image out [out_start ... out_start + out_len-1] + filter f [0..f->len-1] = [f->start .. f->end] +*/ + + /*fprintf(stderr,"inv started\n");*/ + for (i=0;istart+i); + fend=FLOOR_HALF(f->end+i); + + out_pix=out->data+out_start+i*out_step; + + in_pix=in->data+in_start; + +/* + printf("in: %4d - %4d flt: %4d - %4d [%s]\n",fstart,fend,2*fstart-i,2*fend-i, + (2*fstart-istart || 2*fend-i>f->end) ? "error":"ok"); +*/ + /*fprintf(stderr,"inv[%d]\n",i);*/ + for (j=fstart;j<=fend;j++) + { + in_pos=j; + if (in_pos<0) + { + if (f->hipass) + in_pos=-in_pos-1; + else + in_pos=-in_pos; + if (in_pos>=in_len) continue; + } + if (in_pos>=in_len) + { + if (f->hipass) + in_pos=2*in_len-2-in_pos; + else + in_pos=2*in_len-1-in_pos; + if (in_pos<0) continue; + } + /*fprintf(stderr,"out+= %7.2f * %7.2f = %7.2f\n",f->data[2*j-i-f->start],in_pix[in_pos*in_step],f->data[2*j-i-f->start]*in_pix[in_pos*in_step]);*/ + *out_pix += f->data[2*j-i-f->start] * (in_pix[in_pos*in_step]); + } + } + + Leaving; + return 1; +} + +#define MAX_LINE 256 + +#define skip_blank(str) { while(isspace(*(str))) (str)++; } + +static int get_next_line(FILE *f, char *c) +{ + char *str,string[200]; + int len; + do + { + str=string; + if (!fgets(str,200,f)) + { + Trace("get_next_line: eof\n"); + goto error; + } + len=strlen(str); + while (len>=1 && isspace(str[len-1])) str[--len]=0; + while (isspace(*str)) str++; + } + while (strlen(str)==0 || *str=='#'); + strcpy(c,str); + return 1; +error: + return 0; +} + +static int next_line_str(FILE *f, char *tag, char *out) +{ + char str[MAX_LINE],*t_str; + + if (!get_next_line(f,str)) goto error; + t_str=strtok(str," "); + if (!t_str || strcmp(t_str,tag)) goto error; + t_str=strtok(NULL,"\n"); + if (!t_str) goto error; + skip_blank(t_str); + + strcpy(out,t_str); + return 1; +error: + return 0; +} + +static int next_line_str_alloc(FILE *f, char *tag, char **out) +{ + char str[MAX_LINE]; + if (!next_line_str(f,tag,str)) goto error; + + *out=malloc(strlen(str)+1); + strcpy(*out,str); + + return 1; +error: + return 0; +} + +static int next_line_int(FILE *f, char *tag, int *out) +{ + char str[MAX_LINE]; + if (next_line_str(f,tag,str) && sscanf(str,"%d",out)==1) + return 1; + else + return 0; +} + + +static Filter read_filter(FILE *f) +{ + char str[MAX_LINE]; + Filter filter; + int i; + + Entering; + + filter=calloc(1,sizeof(struct FilterStruct)); + + if (!next_line_str(f,"Type",str)) goto error1; + + if (!strcmp(str,"nosymm")) + { + filter->type=FTNoSymm; + } + else if (!strcmp(str,"symm")) + { + filter->type=FTSymm; + } + else if (!strcmp(str,"antisymm")) + { + filter->type=FTAntiSymm; + } + else + goto error1; + + if (!next_line_int(f,"Length",&(filter->len))) goto error1; + if (!next_line_int(f,"Start",&(filter->start))) goto error1; + if (!next_line_int(f,"End",&(filter->end))) goto error1; + + if ((filter->end-filter->start+1!=filter->len)) + { + Trace("error: len != end-start+1\n"); + goto error1; + } + + filter->data=calloc(filter->len,sizeof(Pixel)); + + for (i=0;ilen;i++) + { + if (!get_next_line(f,str)) goto error2; + if (!string_to_pixel(str,filter->data+i)) + { + Trace("error: invalid filter-value\n"); + goto error2; + } + } + if (!get_next_line(f,str)) goto error2; + if (*str!='}') + { + Trace("error: '}' not found\n"); + goto error2; + } + + Leaving; + return filter; + +error2: + free(filter->data); + +error1: + free(filter); + + LeavingErr; + return NULL; + +} + +static FilterGH read_filter_gh(FILE *f) +{ + char str[MAX_LINE]; + FilterGH fgh; + Filter filter; + int i,max; + + Entering; + + fgh=calloc(1,sizeof(struct FilterGHStruct)); + + if (!next_line_str_alloc(f,"Name",&(fgh->name))) + { + Trace("error: 'Name' tag not found\n"); + goto error1; + } + + if (!next_line_str(f,"Type",str)) + { + Trace("error: 'Type' tag not found\n"); + goto error1; + } + + if (!strcmp(str,"orthogonal")) + { + fgh->type=FTOrtho; + max=2; + } + else if (!strcmp(str,"biorthogonal")) + { + fgh->type=FTBiOrtho; + max=4; + } + else if (!strcmp(str,"other")) + { + fgh->type=FTOther; + max=4; + } + else + { + Trace("error: expecting 'orthogonal', 'biorthogonal' or 'other' type-tag\n"); + goto error1; + } + + for (i=0;ihipass = !(i&1); + switch(i) + { + case 0: fgh->g=filter; break; + case 1: fgh->h=filter; break; + case 2: fgh->gi=filter; break; + case 3: fgh->hi=filter; break; + } + } + if (!get_next_line(f,str)) goto error2; + if (*str!='}') + { + Trace("error: '}' not found\n"); + goto error2; + } + + Leaving; + return fgh; + +error2: + if (fgh->g) free(fgh->g); + if (fgh->h) free(fgh->h); + if (fgh->gi) free(fgh->gi); + if (fgh->hi) free(fgh->hi); + +error1: + free(fgh); + + LeavingErr; + return NULL; +} + + +AllFilters load_filters(char *name) +{ + FILE *f; + char str[MAX_LINE]; + AllFilters a; + FilterGH fgh; + + Entering; + + PreCondition(name!=NULL,"name=NULL!"); + + f=fopen(name,"rt"); + if (!f) + { + Trace("error: fopen failed\n"); + goto error1; + } + + a=calloc(1,sizeof(struct AllFilterStruct)); + a->count=0; + + while (get_next_line(f,str)) + { + if (*str=='{') + { + fgh=read_filter_gh(f); + if (!fgh) + { + Trace("error: read_filter returned NULL\n"); + goto error2; + } + if (a->count) + a->filter=realloc(a->filter,(a->count+1)*sizeof(FilterGH)); + else + a->filter=malloc(sizeof(FilterGH)); + (a->filter)[a->count]=fgh; + a->count++; + } + else + { + Trace("error: '{' not found\n"); + goto error2; + } + } + + fclose(f); + + Leaving; + return a; + +error2: + fclose(f); +error1: + + LeavingErr; + return 0; +} + +#define doubletree_min 32 +#define best_basis_min 8 + +static int convolute_lines(Image output,Image input,Filter flt,enum FilterMethod method); +static int convolute_rows(Image output,Image input,Filter flt,enum FilterMethod method); +static int decomposition(Image t_img,Image coarse,Image horizontal,Image vertical, + Image diagonal,Filter g,Filter h,enum FilterMethod method); +static int compute_best(Image_tree tree,int level,int max_level,FilterGH *flt, + enum FilterMethod method,enum Information_Cost cost,double epsilon); +static double compute_entropy(Image img,enum Information_Cost cost,double epsilon); +static void compute_levels(Image_tree tree,double *entropies,enum Information_Cost cost,double epsilon); +static void free_levels(Image_tree tree,int best); + +static Pixel sumationq(Image img); +static Pixel normq(Image_tree tree); +static Pixel sumation_down(Image_tree tree, Pixel normq); +static Pixel compute_non_additive(Image_tree tree,int size,enum Information_Cost cost,double +epsilon,int down); + +/************************************************************************/ +/* Functionname: wavelettransform */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* original: Image that should be transformed */ +/* level: transform down to level */ +/* flt: transform with filters flt[0..level] */ +/* method: method of filtering */ +/* -------------------------------------------------------------------- */ +/* Description: Carries out the wavelettransform */ +/* */ +/************************************************************************/ +Image_tree wavelettransform(Image original,int level,FilterGH *flt,enum FilterMethod method) +{ int i,width,height,min,max_level,e; + Image coarsei,horizontali,verticali,diagonali,tempi; + Image_tree ret_tree,temp_tree; + + width=original->width; + height=original->height; + + tempi=new_image(width,height); + if(!tempi) goto error; + + copy_into_image(tempi,original,0,0); + + ret_tree=new_image_tree(); + if(!ret_tree) goto error; + + temp_tree=ret_tree; + ret_tree->level=0; + + min=original->width; + if (original->heightheight; + max_level=log(min)/log(2)-2; + if (max_levelimage=tempi; + return ret_tree; + } + + /* decomposition */ + + for (i=0;ig,flt[i]->h,method); + if (!e) return NULL; + + temp_tree->coarse=new_image_tree(); + temp_tree->horizontal=new_image_tree(); + temp_tree->vertical=new_image_tree(); + temp_tree->diagonal=new_image_tree(); + + temp_tree->coarse->level=i+1; + temp_tree->horizontal->level=i+1; + temp_tree->vertical->level=i+1; + temp_tree->diagonal->level=i+1; + + temp_tree->horizontal->image=horizontali; + temp_tree->vertical->image=verticali; + temp_tree->diagonal->image=diagonali; + free_image(tempi); + + if (i!=(level-1)) + { + tempi=new_image(width,height); + copy_into_image(tempi,coarsei,0,0); + free_image(coarsei); + /*if i=level coarsei is inserted into the image tree + so we should not free coarsei on level-1*/ + } + + temp_tree=temp_tree->coarse; + + } + + temp_tree->image=coarsei; + return ret_tree; + + error: + err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); + return NULL; +} + +static Image_tree wavelettransform__wp(Image original, int current_level, int level, FilterGH *flt, enum FilterMethod method) +{ + int i, width, height, min, max_level, e; + Image coarse_image,horizontal_image,vertical_image,diagonal_image,temp_image; + Image_tree return_tree, temp_tree; + + width = original->width; + height = original->height; + + temp_image = new_image(width, height); + if (!temp_image) goto error; + + copy_into_image(temp_image, original, 0, 0); + + temp_tree = return_tree = new_image_tree(); + if (!return_tree) goto error; + + temp_tree->level = current_level; + + min = original->width; + if (original->height < min) min = original->height; + max_level = log(min) / log(2) - 2; + if (max_level < level) level = max_level; + + if (current_level >= level) { + return_tree->image = temp_image; + return return_tree; + } + + for (i = current_level; i < level; i++) { + width = (width + 1) / 2; + height = (height + 1) / 2; + + coarse_image = new_image(width, height); + horizontal_image = new_image(width, height); + vertical_image = new_image(width, height); + diagonal_image = new_image(width, height); + + if (!coarse_image || !horizontal_image || + !vertical_image || !diagonal_image) goto error; + + e = decomposition(temp_image, coarse_image, horizontal_image, + vertical_image, diagonal_image, + flt[i]->g, flt[i]->h, method); + if (!e) return NULL; + + temp_tree->coarse = new_image_tree(); + temp_tree->coarse->level = i+1; + temp_tree->horizontal = wavelettransform__wp(horizontal_image, i+1, level, flt, method); + temp_tree->vertical = wavelettransform__wp(vertical_image, i+1, level, flt, method); + temp_tree->diagonal = wavelettransform__wp(diagonal_image, i+1, level, flt, method); + + free_image(horizontal_image); + free_image(vertical_image); + free_image(diagonal_image); + free_image(temp_image); + + if (i != (level - 1)) { + temp_image = new_image(width, height); + copy_into_image(temp_image, coarse_image, 0, 0); + free_image(coarse_image); + } + + temp_tree = temp_tree->coarse; + } + + temp_tree->image = coarse_image; + return return_tree; + + error: + err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); + return NULL; +} + +Image_tree wavelettransform_wp(Image original, int level, FilterGH *flt, enum FilterMethod method) { + return wavelettransform__wp(original, 0, level, flt, method); +} + + +/************************************************************************/ +/* Functionname: best_basis */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* original: Image to be transformed */ +/* level: best basis selection down to this level */ +/* flt: transform with filters flt[0..level] */ +/* method: transform with filter method */ +/* cost: carry best basis selection out with this costfunc */ +/* epsilon: limit for threshold method */ +/* -------------------------------------------------------------------- */ +/* Description: carries best basis and near best basis selection */ +/* out */ +/************************************************************************/ +Image_tree best_basis(Image original,int level,FilterGH *flt, + enum FilterMethod method,enum Information_Cost cost,double epsilon) + +{ Image_tree tree; + Image img; + int min,max_level; + + tree=new_image_tree(); + if(!tree) goto error; + + img=new_image(original->width,original->height); + if(!img) goto error; + + copy_into_image(img,original,0,0); + + tree->image=img; + + min=original->width; + if (original->heightheight; + max_level=log10((float) min/best_basis_min)/log10(2); + if (max_level>level) max_level=level; + + compute_best(tree,0,max_level,flt,method,cost,epsilon); + + if (!tree->image) free(img); + + return tree; + + error: + err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); + return NULL; + +} +/************************************************************************/ +/* Functionname: best_level_selection */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* original: Image that should be transformed */ +/* maxlevel: transform down to level */ +/* flt: transform with filters flt[0..level] */ +/* method: transform with filter method */ +/* cost: carry best basis selection out with this costfunc */ +/* epsilon: limit for threshold method */ +/* -------------------------------------------------------------------- */ +/* Description: Carries out the best level selection */ +/* */ +/************************************************************************/ +Image_tree best_level(Image original,int maxlevel,int *bestlevel,FilterGH *flt,enum FilterMethod method, + enum Information_Cost cost,double epsilon) +{ Image_tree tree; + Image img; + double *entropies,min; + int best=0,i,e; + + img=new_image(original->width,original->height); + copy_into_image(img,original,0,0); + + tree=new_image_tree(); + tree->image=img; + + entropies=(double *)calloc(maxlevel+1,sizeof(double)); + if(!entropies) goto error; + + /* decompose down to maxlevel */ + e=decompose_all(tree,maxlevel,flt,method,cost,epsilon); + if (!e) return NULL; + + /* compute costs of each level and store it in entropies array*/ + compute_levels(tree,entropies,cost,epsilon); + + min=entropies[0]; + for (i=1;i<=maxlevel;i++) + { + if (entropies[i]level=level; + + /* non additive cost function*/ + if (cost>=shanon) + { + tree->entropy=compute_non_additive(tree,tree->image->size,cost,epsilon,0); + } + /*additive cost function*/ + else tree->entropy=compute_entropy(tree->image,cost,epsilon); + + if (levelimage->width+1)/2; + height=(tree->image->height+1)/2; + + tree->coarse=new_image_tree(); + tree->horizontal=new_image_tree(); + tree->vertical=new_image_tree(); + tree->diagonal=new_image_tree(); + + coarse=new_image(width,height); + horizontal=new_image(width,height); + vertical=new_image(width,height); + diagonal=new_image(width,height); + if(!coarse||!vertical||!horizontal||!diagonal) goto error; + + e=decomposition(tree->image,coarse,horizontal,vertical,diagonal,flt[0]->g,flt[0]->h,method); + if (!e) return 0; + + tree->coarse->image=coarse; + tree->horizontal->image=horizontal; + tree->vertical->image=vertical; + tree->diagonal->image=diagonal; + + e=compute_best(tree->coarse,level+1,max_level,flt+1,method,cost,epsilon); + e=compute_best(tree->horizontal,level+1,max_level,flt+1,method,cost,epsilon); + e=compute_best(tree->vertical,level+1,max_level,flt+1,method,cost,epsilon); + e=compute_best(tree->diagonal,level+1,max_level,flt+1,method,cost,epsilon); + if (!e) return 0; + + /*going back in recursion*/ + + if (cost>=shanon) { + sum=compute_non_additive(tree,tree->image->size,cost,epsilon,1); + } + else sum=(tree->coarse->entropy)+(tree->horizontal->entropy) + +(tree->vertical->entropy)+(tree->diagonal->entropy); + + if (tree->entropy>sum) + { + tree->entropy=sum; + free_image(tree->image); /* take down tree */ + tree->image=NULL; + + } + else + { /* delete the tree downwards */ + free_image_tree(tree->coarse); + free_image_tree(tree->horizontal); + free_image_tree(tree->vertical); + free_image_tree(tree->diagonal); + + tree->coarse=tree->vertical=tree->horizontal=tree->diagonal=NULL; + } + } + + return 1; + + error: + err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); + return 0; + +} + +/************************************************************************/ +/* Functionname: decompose_all */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* tree: Image tree to be decomposed */ +/* maxlevel: decompose down to level */ +/* flt: transform with filters flt[0..maxlevel] */ +/* method: transform with filter method */ +/* cost: cost function for entropy computing */ +/* epsilon: limit for threshold method */ +/* -------------------------------------------------------------------- */ +/* Description: whole decompositing down to maxlevel */ +/* The original image must be in tree->image */ +/************************************************************************/ +int decompose_all(Image_tree tree,int maxlevel,FilterGH *flt,enum FilterMethod method, + enum Information_Cost cost,double epsilon) +{ + Image original,coarse,horizontal,vertical,diagonal; + int e,width,height,level; + + if (tree->levelcoarse=new_image_tree(); + tree->horizontal=new_image_tree(); + tree->vertical=new_image_tree(); + tree->diagonal=new_image_tree(); + + original=tree->image; + width=(original->width+1)/2; + height=(original->height+1)/2; + level=tree->level; + + coarse=new_image(width,height); + horizontal=new_image(width,height); + vertical=new_image(width,height); + diagonal=new_image(width,height); + if(!coarse||!vertical||!horizontal||!diagonal) goto error; + + + e=decomposition(tree->image,coarse,horizontal,vertical,diagonal,flt[0]->g,flt[0]->h,method); + if (!e) return 0; + + tree->coarse->image=coarse; + tree->horizontal->image=horizontal; + tree->vertical->image=vertical; + tree->diagonal->image=diagonal; + + tree->coarse->entropy=compute_entropy(coarse,cost,epsilon); + tree->horizontal->entropy=compute_entropy(horizontal,cost,epsilon); + tree->vertical->entropy=compute_entropy(vertical,cost,epsilon); + tree->diagonal->entropy=compute_entropy(diagonal,cost,epsilon); + + tree->coarse->level=tree->horizontal->level= + tree->vertical->level=tree->diagonal->level=level+1; + + e=decompose_all(tree->coarse,maxlevel,flt+1,method,cost,epsilon); + e=decompose_all(tree->horizontal,maxlevel,flt+1,method,cost,epsilon); + e=decompose_all(tree->vertical,maxlevel,flt+1,method,cost,epsilon); + e=decompose_all(tree->diagonal,maxlevel,flt+1,method,cost,epsilon); + if (!e) return 0; + + } + + return 1; + + error: + err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); + return 0; +} + +/************************************************************************/ +/* Functionname: compute_levels */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* tree: Image tree where the entropy should be computed */ +/* entropies : array for entropy */ +/* cost: carry best basis selection out with this costfunc */ +/* epsilon: limit for threshold method */ +/* -------------------------------------------------------------------- */ +/* Description: Compute the entropies of all decomposition levels */ +/************************************************************************/ +static void compute_levels(Image_tree tree,double *entropies,enum Information_Cost cost,double epsilon) +{ + if (tree->image){ + entropies[tree->level]+=compute_entropy(tree->image,cost,epsilon); + } + if (tree->coarse) compute_levels(tree->coarse,entropies,cost,epsilon); + if (tree->horizontal) compute_levels(tree->horizontal,entropies,cost,epsilon); + if (tree->vertical) compute_levels(tree->vertical,entropies,cost,epsilon); + if (tree->diagonal) compute_levels(tree->diagonal,entropies,cost,epsilon); + +} + +/************************************************************************/ +/* Functionname: free_levels */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* tree: Image tree which should be cleaned */ +/* best: best level */ +/* -------------------------------------------------------------------- */ +/* Description: clean the image tree except the best level */ +/************************************************************************/ +static void free_levels(Image_tree tree,int best) +{ + if (tree->levelimage); + tree->image=NULL; + free_levels(tree->coarse,best); + free_levels(tree->horizontal,best); + free_levels(tree->vertical,best); + free_levels(tree->diagonal,best); + } + else + { + if (tree->coarse) + { + free_image_tree(tree->coarse); + free_image_tree(tree->horizontal); + free_image_tree(tree->vertical); + free_image_tree(tree->diagonal); + tree->coarse=tree->horizontal=tree->vertical=tree->diagonal=NULL; + } + } +} + +/************************************************************************/ +/* Functionname: decompose_to_level */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* original: original image */ +/* level: decompose to level */ +/* flt: decompos with filters[0..level] */ +/* method: transform with filter method */ +/* -------------------------------------------------------------------- */ +/* Description: Decomposes an image to an certain level and stores */ +/* only this level in the returned quadtree */ +/************************************************************************/ +Image_tree decompose_to_level(Image original,int level,FilterGH *flt,enum FilterMethod method) +{ Image_tree tree; + int e; + + tree=new_image_tree(); + tree->image=original; + + e=decompose_all(tree,level,flt,method,entropy,1); + if (!e) return NULL; + + free_levels(tree,level); + + return tree; + +} + +/************************************************************************/ +/* Functionname: decomposition */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* t_img: Image which should be decomposed */ +/* coarse,horizontal,vertical,diagonal: */ +/* decomposed images */ +/* method: transform with filter method */ +/* g,h: the transformation is carried out with these filters*/ +/* -------------------------------------------------------------------- */ +/* Description: This carries out one wavelettransformation */ +/* using waveletfilters. */ +/************************************************************************/ + +static int decomposition(Image t_img,Image coarse,Image horizontal,Image vertical, + Image diagonal,Filter g,Filter h,enum FilterMethod method) +{ Image temp1; + + /*coarse*/ + temp1=new_image(coarse->width,t_img->height); + if(!temp1) goto error; + convolute_lines(temp1,t_img,h,method); + convolute_rows(coarse,temp1,h,method); + + /*horizontal*/ + convolute_rows(horizontal,temp1,g,method); + free_image(temp1); + + /*vertical*/ + temp1=new_image(vertical->width,t_img->height); + if(!temp1) goto error; + convolute_lines(temp1,t_img,g,method); + convolute_rows(vertical,temp1,h,method); + + /*diagonal*/ + convolute_rows(diagonal,temp1,g,method); + free_image(temp1); + + return 1; + + error: + err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); + return 0; + +} + +/************************************************************************/ +/* Functionname: inv_decomposition */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* sum: reconstructed image */ +/* coarse,horizontal,vertical,diagonal: images to carry out*/ +/* the inverse transformation */ +/* flt_gh: transform with filters g and h */ +/* method: transform with filter method */ +/* -------------------------------------------------------------------- */ +/* Description: Carries out the wavelettransform */ +/* */ +/************************************************************************/ +static int inv_decomposition(Image sum,Image coarse,Image horizontal,Image vertical, + Image diagonal,FilterGH flt_gh,enum FilterMethod method) +{ Image temp1; + Filter g,h; + + if (flt_gh->type==FTOrtho) { + g=flt_gh->g; + h=flt_gh->h; + } + else { + g=flt_gh->gi; + h=flt_gh->hi; + } + + /*coarse*/ + temp1=new_image(coarse->width,sum->height); + if(!temp1) goto error; + convolute_rows(temp1,coarse,h,method); + + /*horizontal*/ + convolute_rows(temp1,horizontal,g,method); + convolute_lines(sum,temp1,h,method); + free_image(temp1); + + /*vertical*/ + temp1=new_image(vertical->width,sum->height); + if(!temp1) goto error; + convolute_rows(temp1,vertical,h,method); + + /*diagonal*/ + convolute_rows(temp1,diagonal,g,method); + convolute_lines(sum,temp1,g,method); + + free_image(temp1); + + return 1; + + error: + err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); + return 0; +} + +/************************************************************************/ +/* Functionname: build_image */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* quadtree: quadtree with decomposition information */ +/* width,height: image width and height */ +/* RETURN: returns the build up image */ +/* -------------------------------------------------------------------- */ +/* Description: builds up an image out of an Image_tree */ +/* */ +/************************************************************************/ +Image build_image(Image_tree quadtree,int width,int height) +{ Image ret_img,coarse,horizontal,vertical,diagonal; + + + ret_img=new_image(width,height); + if(!ret_img) goto error; + + width=(width+1)/2; + height=(height+1)/2; + + if (!(quadtree->image)) { + coarse=build_image(quadtree->coarse,width,height); + horizontal=build_image(quadtree->horizontal,width,height); + vertical=build_image(quadtree->vertical,width,height); + diagonal=build_image(quadtree->diagonal,width,height); + if (!coarse||!horizontal||!vertical||!diagonal) return NULL; + + copy_into_image(ret_img,coarse,0,0); + copy_into_image(ret_img,horizontal,width,0); + copy_into_image(ret_img,vertical,0,height); + copy_into_image(ret_img,diagonal,width,height); + + if (!quadtree->coarse->image) free_image(coarse); + if (!quadtree->horizontal->image) free_image(horizontal); + if (!quadtree->vertical->image) free_image(vertical); + if (!quadtree->diagonal->image) free_image(diagonal); + + return ret_img; + } + else return quadtree->image; + + error: + err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); + return NULL; +} + +/************************************************************************/ +/* Functionname: inv_transform */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* tree: tree with decomposition information */ +/* flt_gh: transform with filters g and h */ +/* method: transform with filter method */ +/* -------------------------------------------------------------------- */ +/* Description: Inverts the wavelettransform,best_basis,best_level */ +/* */ +/************************************************************************/ +Image inv_transform(Image_tree tree,FilterGH *flt, + enum FilterMethod method) + +{ int er,width,height; + Image ret_img,coarse,vertical,horizontal,diagonal; + + if (!tree->image) { + + coarse=inv_transform(tree->coarse,flt,method); + horizontal=inv_transform(tree->horizontal,flt,method); + vertical=inv_transform(tree->vertical,flt,method); + diagonal=inv_transform(tree->diagonal,flt,method); + if (!coarse||!horizontal||!vertical||!diagonal) return NULL; + + width=coarse->width+horizontal->width; + height=coarse->height+vertical->height; + + ret_img=new_image(width,height); + if(!ret_img) goto error; + + + if (tree->flag==0) /*if flag is set it is a doubletree tiling*/ + { +// er=inv_decomposition(ret_img,coarse,horizontal,vertical,diagonal,flt[1],method); + er=inv_decomposition(ret_img,coarse,horizontal,vertical,diagonal,flt[tree->level],method); + if (!er) return NULL; + } + else + { + copy_into_image(ret_img,coarse,0,0); + copy_into_image(ret_img,horizontal,coarse->width,0); + copy_into_image(ret_img,vertical,0,coarse->height); + copy_into_image(ret_img,diagonal,coarse->width,coarse->height); + } + + if (!tree->coarse->image) free_image(coarse); + if (!tree->horizontal->image) free_image(horizontal); + if (!tree->vertical->image) free_image(vertical); + if (!tree->diagonal->image) free_image(diagonal); + + return ret_img; + } + + else return tree->image; + + error: + err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); + return NULL; +} + +/************************************************************************/ +/* Functionname: find_deepest_level */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* -------------------------------------------------------------------- */ +/* Description: Finds the deepest possible level where width and */ +/* height can divided by two exactly. */ +/************************************************************************/ +int find_deepest_level(int width,int height) +{ + int level=0,w=width,h=height; + + while ( !((w%2)||(h%2))) + { + w=w/2; + h=h/2; + level++; + } + + return level-1; + +} + +/************************************************************************/ +/* Functionname: convolute_lines */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* output: output image of wavelettransformation */ +/* input: input image for decomposition */ +/* flt: transform with filter flt */ +/* method: transform with filter method */ +/* -------------------------------------------------------------------- */ +/* Description: Carries out the wavelettransform for all lines of */ +/* the input image */ +/************************************************************************/ +static int convolute_lines(Image output,Image input,Filter flt,enum FilterMethod method) +/*Convolute the lines with filter*/ +{ int i; + + for (i=0;iheight;i++) { + switch(method) { + case cutoff: + filter_cutoff(input,input->width*i,input->width,1, + output,output->width*i,output->width,1,flt); + break; + case inv_cutoff: + filter_inv_cutoff(input,input->width*i,input->width,1, + output,output->width*i,output->width,1,flt); + break; + case periodical: + filter_periodical(input,input->width*i,input->width,1, + output,output->width*i,output->width,1,flt); + break; + case inv_periodical: + filter_inv_periodical(input,input->width*i,input->width,1, + output,output->width*i,output->width,1,flt); + break; + case mirror: + filter_mirror(input,input->width*i,input->width,1, + output,output->width*i,output->width,1,flt); + break; + case inv_mirror: + filter_inv_mirror(input,input->width*i,input->width,1, + output,output->width*i,output->width,1,flt); + break; + + + } + } + + return 1; +} + +/************************************************************************/ +/* Functionname: convolute_rows */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* output: output image of wavelettransformation */ +/* input: input image for decomposition */ +/* flt: transform with filter flt */ +/* method: transform with filter method */ +/* -------------------------------------------------------------------- */ +/* Description: Carries out the wavelettransform for all rows of */ +/* the input image */ +/************************************************************************/ +static int convolute_rows(Image output,Image input,Filter flt,enum FilterMethod method) +/*Convolute the rows with filter*/ +{ int i; + + for (i=0;iwidth;i++) + { + switch (method) + { + case cutoff: + filter_cutoff(input,i,input->height,input->width, + output,i,output->height,output->width,flt); + break; + case inv_cutoff: + filter_inv_cutoff(input,i,input->height,input->width, + output,i,output->height,output->width,flt); + break; + case periodical: + filter_periodical(input,i,input->height,input->width, + output,i,output->height,output->width,flt); + break; + case inv_periodical: + filter_inv_periodical(input,i,input->height,input->width, + output,i,output->height,output->width,flt); + break; + case mirror: + filter_mirror(input,i,input->height,input->width, + output,i,output->height,output->width,flt); + break; + case inv_mirror: + filter_inv_mirror(input,i,input->height,input->width, + output,i,output->height,output->width,flt); + break; + + } + } + return 1; +} + +/************************************************************************/ +/* Functionname: sumationq */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* img: image to compute */ +/* -------------------------------------------------------------------- */ +/* Description: compute the sum of quadrats of all elements of */ +/* the input image */ +/************************************************************************/ +static Pixel sumationq(Image img) +{ Pixel sum=0; + int i; + + for (i=0;isize;i++) { + sum+=(*img->data+i)*(*img->data+i); + } + return sum; +} + +/************************************************************************/ +/* Functionname: normq */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* tree: tree to compute */ +/* -------------------------------------------------------------------- */ +/* Description: computes the quadratic norm over all images in */ +/* the input tree */ +/************************************************************************/ +static Pixel normq(Image_tree tree) +{ Pixel sum=0; + + if (tree->image) + { + sum=sumationq(tree->image); + } + else + { + if (tree->coarse) sum+=normq(tree->coarse); + if (tree->horizontal) sum+=normq(tree->horizontal); + if (tree->vertical) sum+=normq(tree->vertical); + if (tree->diagonal) sum+=normq(tree->diagonal); + } + + return sum; +} + +/************************************************************************/ +/* Functionname: sumation_down */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* tree: tree to compute */ +/* normq: norm of the images in the tree */ +/* -------------------------------------------------------------------- */ +/* Description: computes the Entropy over all (string aded) images */ +/* in the input tree */ +/************************************************************************/ +static Pixel sumation_down(Image_tree tree, Pixel normq) +{ Pixel sum=0,p; + int i; + Image img; + Pixel *data; + + if (tree->image) + { + img=tree->image; + data=img->data; + for (i=0;isize;i++,data++) + { + if (*data!=0) + { + p=(*data)*(*data)/normq; + sum+=p*log(1/p); + } + } + } + else + { + if (tree->coarse) sum+=sumation_down(tree->coarse,normq); + if (tree->horizontal) sum+=sumation_down(tree->horizontal,normq); + if (tree->vertical) sum+=sumation_down(tree->vertical,normq); + if (tree->diagonal) sum+=sumation_down(tree->diagonal,normq); + } + + return sum; +} + +/************************************************************************/ +/* Functionname: comp */ +/* -------------------------------------------------------------------- */ +/* Description: used for quicksort for decreasing order */ +/************************************************************************/ +int comp(const Pixel *x,const Pixel *y) +{ + if (*x<*y) return 1; + else if (*x==*y) return 0; + else return -1; +} + +/************************************************************************/ +/* Functionname: recarea */ +/* tree: Image tree to compute */ +/* list: target list */ +/* list_size: actual size of the list */ +/* -------------------------------------------------------------------- */ +/* Description: copies all elements within the tree into an list */ +/************************************************************************/ +static void recarea(Image_tree tree,Pixel *list,int *list_size) +{ Image img; + + if (tree->image) + { + img=tree->image; + memcpy(list+(*list_size),img->data,img->size*sizeof(Pixel)); + *list_size+=img->size; + } + else + { + if (tree->coarse) recarea(tree->coarse,list,list_size); + if (tree->horizontal) recarea(tree->horizontal,list,list_size); + if (tree->vertical) recarea(tree->vertical,list,list_size); + if (tree->diagonal) recarea(tree->diagonal,list,list_size); + } + +} + +static void abs_list(Pixel *list,int list_size) +{ + int i; + + for (i=0;imax) max=wlp; + } + + free(list); + + return max; + + error: + err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); + return 0; +} + +static Pixel comp_number(Image_tree tree,int size,int p,double f) +{ Pixel sum=0,*list,min=MAXDOUBLE,norm,npf,normf; + int *list_size=0,k; + + list_size=(int *)malloc(sizeof(int)); + if (!list_size) goto error; + *list_size=0; + + list=(Pixel *)calloc(size,sizeof(Pixel)); + if (!list) goto error; + recarea(tree,list,list_size); + abs_list(list,*list_size); + + qsort(list,*list_size, sizeof(Pixel), (int (*)(const void*, const void*)) comp); + + norm=sum_list(list,p,size); + normf=norm*f; + + for (k=0;kmaximum) maximum=x; + } + + free(list); + + return (1/(2*size)+maximum); + + error: + err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); + return 0; +} + +static Pixel compute_discrepancy(Image_tree tree,int size) +{ Pixel *list,min,max,factor,maximum=0,minimum=0,x; + int *list_size=0,k; + + list_size=(int *)malloc(sizeof(int)); + if (!list_size) goto error; + *list_size=0; + + list=(Pixel *)calloc(size,sizeof(Pixel)); + if (!list) goto error; + + recarea(tree,list,list_size); + + qsort(list,*list_size, sizeof(Pixel), (int (*)(const void*, const void*)) comp); + + min=list[0]; + max=list[size-1]; + factor=1/(max-min); + + /*scaling to [0,1]*/ + for (k=0;kmaximum) maximum=x; + else if (xdata; + + switch(cost) { + + case threshold: + for(i=0;isize;i++) + if (fabs(img->data[i])>epsilon) sum++; + break; + + case log_energy: + for(i=0;isize;i++,data++) { + x=(*data) * (*data); + if (x!=0) sum+=(x*log(1/x)); + } + break; + + case norml: + for(i=0;isize;i++,data++) { + x=fabs(*data); + sum+=x; + } + break; + + case norml2: + for(i=0;isize;i++,data++) { + x=(*data) * (*data); + sum+=x; + } + sum=pow(sum,0.5); + break; + + case entropy: + for(i=0;isize;i++,data++) { + x=(*data)*(*data); + if (x!=0) sum-=(x*log(x)); + } + break; + + case gauss_markov: + for(i=0;isize;i++) { + x=(img->data[i])*(img->data[i]); + if (x!=0) sum+=log(x*x); + } + break; + + } + + return sum; +} + +/************************************************************************/ +/* Functionname: compute_non_additive */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* tree: Image tree from which the entropy should be */ +/* computed */ +/* size : size of the image */ +/* cost: choosen costfunction */ +/* epsilon: limit for threshold method */ +/* down: decides if only the first image should be computed*/ +/* -------------------------------------------------------------------- */ +/* Description: computes entropy of an image */ +/************************************************************************/ +static Pixel compute_non_additive(Image_tree tree,int size,enum Information_Cost cost,double epsilon,int down) +{ Pixel sum=0,normx; + Image img=NULL; + + if (down) + { + img=tree->image; + tree->image=NULL; + } + switch (cost) + { + case shanon: + normx=normq(tree); + sum=-sumation_down(tree,normx); + + break; + case weak_l: + sum=weak_lp(tree,size,1,epsilon); + break; + case weak_lq: + sum=weak_lp(tree,size,2,epsilon); + break; + case compression_number: + sum=comp_number(tree,size,1,epsilon); + break; + case compression_numberq: + sum=comp_number(tree,size,2,epsilon); + break; + case compression_area: + sum=comp_area(tree,size,1,epsilon); + break; + case compression_areaq: + sum=comp_area(tree,size,2,epsilon); + break; + case discrepancy: + sum=compute_discrepancy(tree,size); + break; + case sdiscrepancy: + sum=compute_sdiscrepancy(tree,size); + break; + case concentration: + sum=compute_concentration(tree,size); + break; + + + } + + if (down) tree->image=img; + + return sum; +} + +int rec_double(Image_tree dtree,int level,FilterGH *flt,enum FilterMethod method,enum Information_Cost cost,double epsilon) + +{ int min,width,height; + double sum=0; + Image c,h,v,d; + + dtree->level=0; + + if (cost>=shanon) + { + dtree->entropy=compute_non_additive(dtree,dtree->image->size,cost,epsilon,0); + } + else dtree->entropy=compute_entropy(dtree->image,cost,epsilon); + + dtree->doubletree=best_basis(dtree->image,level,flt,method,cost,epsilon); + + min=dtree->image->width; + if (dtree->image->heightimage->height; + + if (doubletree_minimage->width+1)/2; + height=(dtree->image->height+1)/2; + + dtree->coarse=new_image_tree(); + dtree->horizontal=new_image_tree(); + dtree->vertical=new_image_tree(); + dtree->diagonal=new_image_tree(); + + c=new_image(width,height); + h=new_image(width,height); + v=new_image(width,height); + d=new_image(width,height); + if(!c||!h||!v||!d) goto error; + + + copy_part_of_image(c,dtree->image,0,0); + copy_part_of_image(h,dtree->image,width,0); + copy_part_of_image(v,dtree->image,0,height); + copy_part_of_image(d,dtree->image,width,height); + + dtree->coarse->image=c; + dtree->horizontal->image=h; + dtree->vertical->image=v; + dtree->diagonal->image=d; + + rec_double(dtree->coarse,level,flt,method,cost,epsilon); + rec_double(dtree->horizontal,level,flt,method,cost,epsilon); + rec_double(dtree->vertical,level,flt,method,cost,epsilon); + rec_double(dtree->diagonal,level,flt,method,cost,epsilon); + + /* going back in recursion*/ + + sum=dtree->coarse->entropy+dtree->horizontal->entropy+ + dtree->vertical->entropy+dtree->diagonal->entropy; + + if (sum>dtree->entropy) + { + /*take image*/ + + free_image_tree(dtree->coarse); + free_image_tree(dtree->horizontal); + free_image_tree(dtree->vertical); + free_image_tree(dtree->diagonal); + dtree->coarse=dtree->horizontal=dtree->vertical=dtree->diagonal=NULL; + } + else + { /*take tiling*/ + dtree->entropy=sum; + free_image(dtree->image); + dtree->image=NULL; + } + + if (dtree->entropy>dtree->doubletree->entropy) + { + /*take best basis tree*/ + + dtree->entropy=dtree->doubletree->entropy; + + if(dtree->coarse) free_image_tree(dtree->coarse); + if(dtree->horizontal) free_image_tree(dtree->horizontal); + if(dtree->vertical) free_image_tree(dtree->vertical); + if(dtree->diagonal) free_image_tree(dtree->diagonal); + + dtree->coarse=dtree->doubletree->coarse; + dtree->horizontal=dtree->doubletree->horizontal; + dtree->vertical=dtree->doubletree->vertical; + dtree->diagonal=dtree->doubletree->diagonal; + + free_image(dtree->image); + dtree->image=NULL; + free(dtree->doubletree); + dtree->doubletree=NULL; + + } + else + { + dtree->flag=1; + if(dtree->doubletree) free_image_tree(dtree->doubletree); + dtree->doubletree=NULL; + } + } + + return 1; + + error: + err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); + return 0; +} + +static void save_structur(Image_tree tree,FILE *fp,int pos) +{ + int shift,next_pos,max; + + if (tree->flag) + { + fprintf(fp,"%d ",pos); + + shift=pos-(pow(4,tree->level-1)-1)*4/3-1; + max=(int) ((pow(4,tree->level)-1)*4/3); + next_pos=max+4*shift+1; + if (tree->coarse) save_structur(tree->coarse,fp,next_pos); + if (tree->horizontal) save_structur(tree->horizontal,fp,next_pos+1); + if (tree->vertical) save_structur(tree->vertical,fp,next_pos+2); + if (tree->diagonal) save_structur(tree->diagonal,fp,next_pos+3); + } +} + +static int is_in_list(int *list,int len, int x) +{ + int i,found=0; + + for (i=0;iflag=1; + + shift=pos-(pow(4,tree->level-1)-1)*4/3-1; + max=(int) ((pow(4,tree->level)-1)*4/3); + next_pos=max+4*shift+1; + + write_flags(tree->coarse,list,len,next_pos); + write_flags(tree->horizontal,list,len,next_pos+1); + write_flags(tree->vertical,list,len,next_pos+2); + write_flags(tree->diagonal,list,len,next_pos+3); + } +} + +/************************************************************************/ +/* Functionname: err_simple_message */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* char *: string that contains information about an */ +/* error the user should know. */ +/* -------------------------------------------------------------------- */ +/* Description: */ +/* Prints error messages for the user. */ +/************************************************************************/ + +void err_SimpleMessage(char *message) +{ + fprintf(stderr,"%s\n",message); +} + +/************************************************************************/ +/* Functionname: err_get_message */ +/* -------------------------------------------------------------------- */ +/* Return value: Errormessage for this specific error. */ +/* Parameter: */ +/* Error err: Error whose errormessage should be returned */ +/* -------------------------------------------------------------------- */ +/* Description: */ +/************************************************************************/ +char * err_GetErrorMessage(Error err) +{ + + switch (err) + { + case Error_NotImplemented: + return "Sorry, this is not implemented yet. "; + break; + + case Error_AssertionFailed: + return "Sorry, an internal assertion was violated.\n" + "This action can not be completed. :-("; + break; + + case Error_NotEnoughMemory: + return "Sorry, there is not enough memory"; + break; + + case Error_Limitation: + return "Some limitation of the program exceeded"; + break; + + /* - FILES - */ + + case Error_CantOpenFile: + return "Could not open file"; + break; + + case Error_CantCreateFile: + return "Could not create file"; + break; + + case Error_CantCloseFile: + return "Could not close file"; + break; + + case Error_InternalError: + return "Sorry, an internal error occured.\n" + "This action can not be completed. :-("; + break; + + default: + return "Sorry, but an unknown error ocurred.\n" + "This action can not be completed. :-("; + break; + + + } +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wavelet.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wavelet.h Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,307 @@ +#ifndef WAVELET_H + +#include + +extern char dbgstr[1000]; + +/* this are internal functions - don't use 'em! */ +void out_dbg_str(const char *str); +void start_trace(void); +void stop_trace(void); +void flush_trace_file(void); + +/* public functions / macros */ +#define StartTrace +#define StopTrace + +#define Trace(str) +#define TraceVar(str,var) + +#define Entering +#define Leaving +#define LeavingErr +#define FlushTrace + +#define Warning(str) + +#define PreCondition(exp,str) +#define PostCondition(exp,str) + +/* Note that if an error is added, an errormessage for this specific + error must also be added. Otherwise no appropriate message can + be displayed in an error window. ( Then "Unknown error ocurred" + will be displayed.) + The errormessage must be added to the case-construct in the + procedure err_GetErrorMessage +*/ + +typedef enum +{ + Error_NoError, /* No Error has happened. */ + Error_NotImplemented, /* A needed part has not (yet) been + implemented */ + Error_AssertionFailed, /* An assertion, pre- or postcondition failed. + Occurs only in buggy programs. */ + Error_NotEnoughMemory, /* We can't allocate the memory we need. */ + + Error_Limitation, /* Some limitation exceeded, e.g. a string + variable is too short */ + + + Error_CantOpenFile, /* The file cannot be opened */ + Error_CantCreateFile, + Error_CantWriteIntoFile, + Error_CantCloseFile, + Error_WrongFileFormat, + + Error_WidthOrHeightZero, + Error_CompressedZeroContent, + Error_OriginalZeroContent, + + Error_InternalError + +}Error; + + +/************************************************************************/ +/* Functionname: err_simple_message */ +/* -------------------------------------------------------------------- */ +/* Parameter: */ +/* char *: string that contains information about an */ +/* error the user should know. */ +/* -------------------------------------------------------------------- */ +/* Description: */ +/* Prints error messages for the user. */ +/************************************************************************/ +void err_SimpleMessage(char *message); + +/************************************************************************/ +/* Functionname: err_get_message */ +/* -------------------------------------------------------------------- */ +/* Return value: Errormessage for this specific error. */ +/* Parameter: */ +/* Error err: Error whose errormessage should be returned */ +/* -------------------------------------------------------------------- */ +/* Description: */ +/************************************************************************/ +char * err_GetErrorMessage(Error err); + +#include + +typedef double Pixel; + +typedef struct Image_struct { + Pixel *data; + int width,height; + + /* redundant, for our fun only :-) */ + Pixel min_val,max_val; /* range of pixel-values in data */ + /* [min_val..max_val] */ + int size; /* = width * height */ + int bpp; /* bits per pixel of original image */ + } *Image; + +typedef unsigned int IntPixel; + +typedef struct IntImage_struct { + IntPixel *data; + int width, height; + + /* redundant, for our fun only :-) */ + IntPixel min_val,max_val; /* range of values in data */ + /* [min_val..max_val] */ + int size; /* = width * height */ + int bpp; /* bits per pixel of original image */ + } *IntImage; + +typedef struct Image_tree_struct { + double entropy; + struct Image_tree_struct *coarse,*horizontal,*vertical,*diagonal,*doubletree; + Image image; + int level; + int flag; + + void *codec_data; + IntImage significance_map; + } *Image_tree; + +typedef struct Image_info_struct { + Pixel min,max,mean,var,rms; + } *Image_info; + +enum zigzag_direction {zigzag_up,zigzag_down,zigzag_right,zigzag_left}; + +typedef struct Zigzag_data_struct { + int x,y,w,h; + enum zigzag_direction dir; + } *Zigzag_data; + +#define get_intpixel(image,x,y) ( ((image)==NULL || \ + (x)<0 || (x)>=(image)->width || (y)<0 || (y)>=(image)->height) \ + ? (IntPixel) 0 : (image)->data[(x)+(y)*(image)->width]) + +#define set_intpixel(image,x,y,val) if (!((image)==NULL || \ + (x)<0 || (x)>=(image)->width || (y)<0 || (y)>=(image)->height)) \ + (image)->data[(x)+(y)*(image)->width]=(IntPixel) (val) + +#define get_pixel(image,x,y) ( ((image)==NULL || \ + (x)<0 || (x)>=(image)->width || (y)<0 || (y)>=(image)->height) \ + ? (Pixel) 0 : (image)->data[(x)+(y)*(image)->width]) + +#define set_pixel(image,x,y,val) if (!((image)==NULL || \ + (x)<0 || (x)>=(image)->width || (y)<0 || (y)>=(image)->height)) \ + (image)->data[(x)+(y)*(image)->width]=(Pixel) (val) + +#define get_pixel_adr(image,x,y) ( ((image)==NULL || \ + (x)<0 || (x)>=(image)->width || (y)<0 || (y)>=(image)->height) \ + ? (Pixel*) NULL : (image)->data+((x)+(y)*(image)->width)) + +/* functions: */ + +IntImage new_intimage(int width, int height); +IntImage load_intimage(char *file, int max_val); +void free_intimage(IntImage img); + +void clear_intimage(IntImage img); +void copy_into_intimage(IntImage img1,IntImage img2,int x,int y); +void copy_part_of_intimage(IntImage img1,IntImage img2,int x,int y); + +Image new_image(int width, int height); +void free_image(Image img); +void clear_image(Image img); +void copy_into_image(Image img1,Image img2,int x,int y); +void scale_image(Image img,int maximum); +void copy_part_of_image(Image img1,Image img2,int x,int y); + +void copy_part_of_image_into_image( + Image dest_img, int dest_x, int dest_y, + Image src_img, int src_x, int src_y, + int width, int height); + + +int string_to_pixel(char *str, Pixel *p); + +Image load_image(char *file, int max_val); +int save_image_P5(char *file, Image img); + +Image intimage_to_image(IntImage i); +IntImage image_to_intimage(Image i); + +Image_tree new_image_tree(); +void free_image_tree(Image_tree t); + +Image get_difference_image(Image image1, Image image2); + +void get_image_infos(Image image, Image_info info); + +void get_intimage_infos(IntImage image, IntPixel *min, IntPixel *max, Pixel *avg, Pixel *var); + +void init_zigzag(Zigzag_data zz, int width, int height); +void next_zigzag(Zigzag_data zz); +Image get_absolute_image_scaled(Image img); + +/* common macros */ + +#ifndef MIN +#define MIN(a,b) ((a)<(b)?(a):(b)) +#endif + +#ifndef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) +#endif + +enum FilterType { FTNoSymm, FTSymm, FTAntiSymm}; + +typedef struct FilterStruct { + enum FilterType type; + int hipass; + Pixel * data; + int start,end; + + int len; + } *Filter; + +Filter new_filter(int size); + +int filter_cutoff(Image in, int in_start, int in_len, int in_step, + Image out, int out_start, int out_len, int out_step, + Filter f); + +int filter_inv_cutoff(Image in, int in_start, int in_len, int in_step, + Image out, int out_start, int out_len, int out_step, + Filter f); + +int filter_periodical(Image in, int in_start, int in_len, int in_step, + Image out, int out_start, int out_len, int out_step, + Filter f); + +int filter_inv_periodical(Image in, int in_start, int in_len, int in_step, + Image out, int out_start, int out_len, int out_step, + Filter f); + +int filter_mirror(Image in, int in_start, int in_len, int in_step, + Image out, int out_start, int out_len, int out_step, + Filter f); + +int filter_inv_mirror(Image in, int in_start, int in_len, int in_step, + Image out, int out_start, int out_len, int out_step, + Filter f); + +Pixel get_filter_center(Filter f); + +enum FilterGHType { FTOrtho, FTBiOrtho, FTOther}; + +typedef struct FilterGHStruct { + enum FilterGHType type; + Filter g, h, gi, hi; + char *name; + } *FilterGH; + +typedef struct AllFilterStruct { + FilterGH *filter; + int count; + } *AllFilters; + + +AllFilters load_filters(char *name); + +typedef struct SegmentsStruct { + int width,height; /* segment width & height*/ + int *data; + } *Segments; + +enum FilterMethod{cutoff,inv_cutoff,periodical,inv_periodical,mirror,inv_mirror}; + +enum Information_Cost{threshold,log_energy,entropy,norml,norml2,gauss_markov, + shanon,weak_l,weak_lq,compression_number,compression_numberq, + compression_area,compression_areaq,sdiscrepancy,discrepancy,concentration}; + +Image_tree wavelettransform(Image original,int level,FilterGH *flt,enum FilterMethod method); +Image_tree wavelettransform_wp(Image original,int level,FilterGH *flt,enum FilterMethod method); + +Image_tree best_basis(Image original,int level,FilterGH *flt, + enum FilterMethod method,enum Information_Cost cost,double epsilon); + +Image_tree best_level(Image original,int maxlevel,int *bestlevel,FilterGH *flt,enum FilterMethod method, + enum Information_Cost cost,double epsilon); + +Image build_image(Image_tree quadtree,int width,int height); + +Image inv_transform(Image_tree quadtree,FilterGH *flt, + enum FilterMethod method); + +Image inv_transform_wp(Image_tree quadtree,FilterGH *flt, + enum FilterMethod method); + +int rec_double(Image_tree dtree,int level,FilterGH *flt,enum FilterMethod method,enum Information_Cost cost,double epsilon); + +Image_tree decompose_to_level(Image original,int level,FilterGH *flt,enum FilterMethod method); + +int decompose_all(Image_tree tree,int maxlevel,FilterGH *flt,enum FilterMethod method, + enum Information_Cost cost,double epsilon); + +int find_deepest_level(int width,int height); + + +#define WAVELET_H +#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,38 @@ +#include "wm.h" + +#ifdef __MINGW32_VERSION +void bzero(char *b, size_t length) { + int i; + for (i=0; i +#include +#include +#include +#include +#include +#include + +#if defined(MINGW) +#define M_PI 3.1415926536 +#define rint floor +#define MAXPATHLEN 255 +void bzero(char *b, size_t length); +#elif defined(LINUX) +#include +#include +#include +#include +#else +#error plattform not supported +#endif + +/* + * This macro is used to ensure correct rounding of integer values. + */ +#define ROUND(a) (((a) < 0) ? (int) ((a) - 0.5) : (int) ((a) + 0.5)) + +/* + * Macros to converts number of bytes to number of bits and vice verse + */ +#define NBITSTOBYTES(N) ((N & 7) ? (N >> 3) + 1 : N >> 3) +#define NBYTESTOBITS(N) (N << 3) + +#define GRAYRANGE(P) ((P > 255) ? 255 : (P < 0) ? 0 : P) +#define PIXELRANGE(P) ((P > 255) ? 255 : (P < 0) ? 0 : P) + +#ifndef sqr +#define sqr(X) ((X) * (X)) +#endif + +#ifndef MAX +#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) +#endif + +#ifndef MIN +#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) +#endif + +#ifdef NEED_STRCASECMP +#define strcasecmp stricmp +#endif + +#ifndef SIGN +#define SIGN(X) (((X) > 0) ? ((X) == 0 ? 0 : 1) : -1) +#endif + +void wm_init(); +void wm_init1(); +void wm_init2(); + +#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_bruyn_d.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_bruyn_d.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,502 @@ +#include "wm.h" +#include "signature.h" +#include "coord.h" +#include "gray.h" +#include "sort.h" +#include "bruyn_common.h" +#include "netpbm/pgm.h" + +char *progname; + +// prints out program's parameters +void usage(void) { + fprintf(stderr, "usage: %s [-b n] [-h] [-k] [-n n] [-o file] [-pP n] [-q n] [-tT n] [-v n] -s file file\n", progname); + fprintf(stderr, "\t-b n\t\tblock size\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-k\t\tdisable block skipping\n"); + fprintf(stderr, "\t-n n\t\tnumber of signature bits to detect\n"); + fprintf(stderr, "\t-o file\t\textracted signature file\n"); + fprintf(stderr, "\t-p n\t\tpattern type for zone 1\n"); + fprintf(stderr, "\t-P n\t\tpattern type for zone 2\n"); + fprintf(stderr, "\t-q n\t\tsignature strength\n"); + fprintf(stderr, "\t-s file\t\tembedded signature\n"); + fprintf(stderr, "\t-t n\t\tthreshold for noise\n"); + fprintf(stderr, "\t-T n\t\tthreshold for slope\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + gray** image; + gray **block; + gray **zone; + gray **category1, **category2; + gray maxval; + double *slope; + int rows, cols, format; + int c; + int i, j; + int n; + int row; + int n_block; + + char signature_name[MAXPATHLEN]; + char input_name[MAXPATHLEN] = "(stdin)"; + char output_name[MAXPATHLEN] = "(stdout)"; + + double quality = 0.0; + double threshold_noise = 0.0; + double threshold_slope = 0.0; + int pattern1 = 0; + int pattern2 = 0; + int blocksize = 0; + int seed; + + int verbose = 0; + int skipping = 0; + + struct coords *coords; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init2(); + + // parse command line and set options + while ((c = getopt(argc, argv, "b:h?n:o:p:P:q:s:t:T:v:k")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'k': + skipping = 1; + break; + case 'n': + nbit_signature = atoi(optarg); + if (nbit_signature <= 0 || nbit_signature > NBITSIGNATURE) { + fprintf(stderr, "%s: invalid signature length %d\n", progname, nbit_signature); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'p': + pattern1 = atoi(optarg); + if (pattern1 <= 0 || pattern1 > NPATTERN) { + fprintf(stderr, "%s: pattern type out of range\n", progname); + exit(1); + } + break; + case 'P': + pattern2 = atoi(optarg); + if (pattern2 <= 0 || pattern2 > 3) { + fprintf(stderr, "%s: pattern type out of range\n", progname); + exit(1); + } + break; + case 'q': + quality = atof(optarg); + if (quality <= 0) { + fprintf(stderr, "%s: quality factor %f out of range\n", progname, quality); + } + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 't': + threshold_noise = atof(optarg); + if (threshold_noise <= 0) { + fprintf(stderr, "%s: noise threshold %f out of range\n", progname, threshold_noise); + } + break; + case 'T': + threshold_slope = atof(optarg); + if (threshold_slope <= 0) { + fprintf(stderr, "%s: slope threshold %f out of range\n", progname, threshold_slope); + } + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n",progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + // open input image file or read from stdin + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + // read signature file and set options + // command line options override signature file options + if (sig) { + char line[1024]; + fgets(line, sizeof(line), sig); + if (strspn(line, "BRSG") >= 4) { + if (nbit_signature == 0) + fscanf(sig, "%d\n", &nbit_signature); + else + fscanf(sig, "%*d\n"); + if (skipping == 0) + fscanf(sig, "%d\n", &skipping); + else + fscanf(sig, "%*d\n"); + if (pattern1 == 0) + fscanf(sig, "%d\n", &pattern1); + else + fscanf(sig, "%*d\n"); + if (pattern2 == 0) + fscanf(sig, "%d\n", &pattern2); + else + fscanf(sig, "%*d\n"); + if (quality == 0.0) + fscanf(sig, "%lf\n", &quality); + else + fscanf(sig, "%*f\n"); + if (threshold_noise == 0.0) + fscanf(sig, "%lf\n", &threshold_noise); + else + fscanf(sig, "%*f\n"); + if (threshold_slope == 0.0) + fscanf(sig, "%lf\n", &threshold_slope); + else + fscanf(sig, "%*f\n"); + if (blocksize == 0) + fscanf(sig, "%d\n", &blocksize); + else + fscanf(sig, "%*d\n"); + fscanf(sig, "%d\n", &seed); + srandom(seed); + n_signature = NBITSTOBYTES(nbit_signature); + fread(signature, sizeof(char), n_signature, sig); + init_signature_bits(); + fscanf(sig, "\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + if (pattern1 <= 0 || pattern2 <= 0 || pattern1 > NPATTERN || pattern2 > NPATTERN) { + fprintf(stderr, "%s: invalid pattern type specified\n", progname); + exit(1); + } + + // read dimensions of input image file + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + + // see if we can extract all signature bits + // we want at least half of the blocks untouched + if (((rows / blocksize) * (cols / blocksize)) < nbit_signature / 2) { + fprintf(stderr, "%s: image not large enough to contain %d bits of signature\n", progname, nbit_signature); + exit(1); + } + n_block = blocksize * blocksize; + + // allocate structure to remember which blocks we already touched, + // allow plenty of room to skip over blocks + if ((coords = alloc_coords(nbit_signature * 16)) == NULL) { + fprintf(stderr, "%s: unable to allocate memory\n", progname); + exit(1); + } + + // read in input image file + image = pgm_allocarray(cols, rows); + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + + fclose(in); + + row = 0; + + // allocate memory for one block + block = alloc_grays(blocksize, blocksize); + + // allocate memory for zone classification + zone = alloc_grays(blocksize, blocksize); + + // allocate memory for category classification + category1 = alloc_grays(blocksize, blocksize); + category2 = alloc_grays(blocksize, blocksize); + + // set up category classification array according to + // pattern type parameter + for (i = 0; i < blocksize; i++) + for (j = 0; j < blocksize; j++) { + category1[j][i] = lookup_pattern(pattern1, i, j); + category2[j][i] = lookup_pattern(pattern2, i, j); + } + + // allocate memory for slope calculation + slope = malloc(sizeof(double) * n_block); + + fprintf(out, "BRWM\n"); + fprintf(out, "%d\n", nbit_signature); + + // extract all the signature bits, one by one + n = 0; + while (n < nbit_signature) { + int xb; + int yb; + int blocktype; + double smax; + int alpha, beta_minus, beta_plus; + double mean_1A, mean_1B, mean_2A, mean_2B, mean_1, mean_2; + int n_1A, n_1B, n_2A, n_2B, n_1, n_2; + double sigma, sigma_1, sigma_2; + int zone1_ok, zone2_ok; + + // find an unused block randomly, depending on seed + do { + xb = random() % (cols / blocksize); + yb = random() % (rows / blocksize); + } while (add_coord(coords, xb, yb) < 0); + + // copy image block + fprintf(stderr, "XXX1 %d %d %d\n", xb*blocksize, yb*blocksize, blocksize); + copy_grays_to_block(block, image, xb * blocksize, yb * blocksize, blocksize, blocksize); + fprintf(stderr, "XXX2\n"); + + if (verbose > 0) + fprintf(stderr, "detecting bit #%d in block at (%d/%d)\n", n, xb * blocksize, yb * blocksize); + + // sort luminance values in block to represent increasing function F + sort_grays(block[0], n_block); + + // calculate slopes of F and determine smax, the max. slope of F + // the index where smax occures is called alpha + alpha = 0; + smax = 0.0; + for (i = 0; i < n_block - 1; i++) { + slope[i] = block[0][i + 1] - block[0][i]; + if (slope[i] > smax) { + smax = slope[i]; + alpha = i; + } + } + slope[n_block - 1] = 0; + + // block type classification + blocktype = BLOCKTYPE_UNKNOWN; + + if (smax < threshold_noise) { + // block has noise contrast + beta_minus = beta_plus = alpha; + blocktype = BLOCKTYPE_NOISE; + } + else { + // block has progressive or hard contrast, let's find out... + + beta_minus = alpha - 1; + while (beta_minus >= 0 && smax - slope[beta_minus] <= threshold_slope) + beta_minus--; + + beta_plus = alpha + 1; + while (beta_plus < n_block && smax - slope[beta_plus] <= threshold_slope) + beta_plus++; + + if (beta_minus + 1 == alpha && beta_plus - 1 == alpha) + blocktype = BLOCKTYPE_HARD; + else + blocktype = BLOCKTYPE_PROGRESSIVE; + } + + if (verbose > 1) { + fprintf(stderr, "blocktype: %d\n", blocktype); + fprintf(stderr, "Smax = %lf, alpha = %d, beta- = %d, beta+ = %d\n", smax, alpha, beta_minus, beta_plus); + } + + // block pixel classification + for (i = 0; i < blocksize; i++) + for (j = 0; j < blocksize; j++) { + gray pixel = image[yb * blocksize + j][xb * blocksize + i]; + zone[j][i] = ZONE_VOID; + switch (blocktype) { + case BLOCKTYPE_PROGRESSIVE: + case BLOCKTYPE_HARD: + if (pixel < block[0][beta_minus]) + zone[j][i] = ZONE_1; + else if (pixel > block[0][beta_plus]) + zone[j][i] = ZONE_2; + break; + case BLOCKTYPE_NOISE: + if (pixel < block[0][n_block / 2]) + zone[j][i] = ZONE_1; + else if (pixel > block[0][n_block / 2]) + zone[j][i] = ZONE_2; + break; + default: + fprintf(stderr, "%s: invalid block type\n", progname); + break; + } + } + + // calculate mean values for zone/categories + mean_1A = mean_1B = mean_2A = mean_2B = mean_1 = mean_2 = 0.0; + n_1A = n_1B = n_2A = n_2B = n_1 = n_2 = 0; + for (i = 0; i < blocksize; i++) + for (j = 0; j < blocksize; j++) { + gray pixel = image[yb * blocksize + j][xb * blocksize + i]; + int pixel_zone = zone[j][i]; + int pixel_category = CATEGORY_VOID; + if (pixel_zone == ZONE_1) + pixel_category = category1[j][i]; + else if (pixel_zone == ZONE_2) + pixel_category = category2[j][i]; + + switch (pixel_zone | pixel_category) { + case CLASSIFICATION_1A: + n_1++; + n_1A++; + mean_1A += pixel; + mean_1 += pixel; + break; + case CLASSIFICATION_1B: + n_1++; + n_1B++; + mean_1B += pixel; + mean_1 += pixel; + break; + case CLASSIFICATION_2A: + n_2++; + n_2A++; + mean_2A += pixel; + mean_2 += pixel; + break; + case CLASSIFICATION_2B: + n_2++; + n_2B++; + mean_2B += pixel; + mean_2 += pixel; + break; + } + } + + if (n_1 && n_1A && n_1B) { + mean_1 /= (double) n_1; + mean_1A /= (double) n_1A; + mean_1B /= (double) n_1B; + zone1_ok = 1; + } + else { + mean_1 = mean_1A = mean_1B = 0.0; + zone1_ok = 0; + if (verbose > 0) + fprintf(stderr, "zone 1 unusable\n"); + } + + if (n_2 && n_2A && n_2B) { + mean_2 /= (double) n_2; + mean_2A /= (double) n_2A; + mean_2B /= (double) n_2B; + zone2_ok = 1; + } + else { + mean_2 = mean_2A = mean_2B = 0.0; + zone2_ok = 0; + if (verbose > 0) + fprintf(stderr, "zone 2 unusable\n"); + } + + // bit extraction + if (zone1_ok && zone2_ok) { + sigma_1 = mean_1A - mean_1B; + sigma_2 = mean_2A - mean_2B; + + if (verbose > 2) { + fprintf(stderr, "m_1A = %lf, m_1B = %lf\n", mean_1A, mean_1B); + fprintf(stderr, "m_2A = %lf, m_2B = %lf\n", mean_2A, mean_2B); + fprintf(stderr, "sigma1 = %lf, sigma2 = %lf\n", sigma_1, sigma_2); + } + +#define EPSILON 0.001 + if (fabs(sigma_1 * sigma_2) < EPSILON) { + // case 3 + sigma = MAX(fabs(sigma_1), fabs(sigma_2)); + set_signature_bit(n, sigma > 0.0); + if (verbose > 0) + fprintf(stderr, "case 3, bit #%d = %d\n", n, sigma > 0.0); + } + else if (sigma_1 * sigma_2 > 0.0) { + // case 1 + set_signature_bit(n, sigma_1 > 0.0); + if (verbose > 0) + fprintf(stderr, "case 1, bit #%d = %d\n", n, sigma_1 > 0.0); + } + else if (sigma_1 * sigma_2 < 0.0) { + // case 2 + sigma = (double) (n_1A + n_1B) * sigma_1 + (double) (n_2A + n_2B) * sigma_2; + set_signature_bit(n, sigma > 0.0); + if (verbose > 0) + fprintf(stderr, "case 2, bit #%d = %d\n", n, sigma > 0.0); + } + } + else if (zone1_ok) { + set_signature_bit(n, mean_1A > mean_1B); + if (verbose > 0) + fprintf(stderr, "case 4, bit #%d = %d\n", n, mean_1A > mean_1B); + } + else if (zone2_ok) { + set_signature_bit(n, mean_2A > mean_2B); + if (verbose > 0) + fprintf(stderr, "case 5, bit #%d = %d\n", n, mean_2A > mean_2B); + } + else { + // pathological case - can it ever happen? + if (verbose > 0) + fprintf(stderr, "block skipped\n"); + if (!skipping) continue; + } + + n++; + } + + free_grays(category2); + free_grays(category1); + free_grays(zone); + free_grays(block); + + // write extracted signature + + fwrite(signature, sizeof(char), n_signature, out); + fclose(out); + + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_bruyn_e.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_bruyn_e.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,549 @@ +#include "wm.h" +#include "signature.h" +#include "coord.h" +#include "gray.h" +#include "sort.h" +#include "bruyn_common.h" +#include "netpbm/pgm.h" + +char *progname; + +// prints out program's parameters +void usage(void) { + fprintf(stderr, "usage: %s [-b n] [-h] [-k] [-n n] [-o file] [-pP n] [-q n] [-tT n] [-v n] -s file file\n", progname); + fprintf(stderr, "\t-b n\t\tblock size\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-k\t\tdisable block skipping\n"); + fprintf(stderr, "\t-n n\t\tnumber of signature bits to embed\n"); + fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); + fprintf(stderr, "\t-p n\t\tpattern type for zone 1\n"); + fprintf(stderr, "\t-P n\t\tpattern type for zone 2\n"); + fprintf(stderr, "\t-q n\t\tsignature strength\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + fprintf(stderr, "\t-t n\t\tthreshold for noise\n"); + fprintf(stderr, "\t-T n\t\tthreshold for slope\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + gray** image; + gray **block; + gray **zone; + gray **category1, **category2; + gray maxval; + double *slope; + int rows, cols, format; + int c; + int i, j; + int n; + int row; + int n_block; + int skipping = 0; + + char signature_name[MAXPATHLEN]; + char input_name[MAXPATHLEN] = "(stdin)"; + char output_name[MAXPATHLEN] = "(stdout)"; + + double quality = 0.0; + double threshold_noise = 0.0; + double threshold_slope = 0.0; + int pattern1 = 0; + int pattern2 = 0; + int blocksize = 0; + int seed; + + int verbose = 0; + + struct coords *coords; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init(); + + // parse command line and set options + while ((c = getopt(argc, argv, "b:h?n:o:p:P:q:s:t:T:v:k")) != EOF) { + switch (c) { + case 'k': + skipping = 1; + break; + case 'h': + case '?': + usage(); + break; + case 'n': + nbit_signature = atoi(optarg); + if (nbit_signature <= 0 || nbit_signature > NBITSIGNATURE) { + fprintf(stderr, "%s: invalid signature length %d\n", progname, nbit_signature); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'p': + pattern1 = atoi(optarg); + if (pattern1 <= 0 || pattern1 > NPATTERN) { + fprintf(stderr, "%s: pattern type out of range\n", progname); + exit(1); + } + break; + case 'P': + pattern2 = atoi(optarg); + if (pattern2 <= 0 || pattern2 > 3) { + fprintf(stderr, "%s: pattern type out of range\n", progname); + exit(1); + } + break; + case 'q': + quality = atof(optarg); + if (quality <= 0) { + fprintf(stderr, "%s: quality factor %f out of range\n", progname, quality); + } + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 't': + threshold_noise = atof(optarg); + if (threshold_noise <= 0) { + fprintf(stderr, "%s: noise threshold %f out of range\n", progname, threshold_noise); + } + break; + case 'T': + threshold_slope = atof(optarg); + if (threshold_slope <= 0) { + fprintf(stderr, "%s: slope threshold %f out of range\n", progname, threshold_slope); + } + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n",progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + // open input image file or read from stdin + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + // read signature file and set options + // command line options override signature file options + if (sig) { + char line[128]; + fgets(line, sizeof(line), sig); + if (strspn(line, "BRSG") >= 4) { + if (nbit_signature == 0) + fscanf(sig, "%d\n", &nbit_signature); + else + fscanf(sig, "%*d\n"); + if (skipping == 0) + fscanf(sig, "%d\n", &skipping); + else + fscanf(sig, "%*d\n"); + if (pattern1 == 0) + fscanf(sig, "%d\n", &pattern1); + else + fscanf(sig, "%*d\n"); + if (pattern2 == 0) + fscanf(sig, "%d\n", &pattern2); + else + fscanf(sig, "%*d\n"); + if (quality == 0.0) + fscanf(sig, "%lf\n", &quality); + else + fscanf(sig, "%*f\n"); + if (threshold_noise == 0.0) + fscanf(sig, "%lf\n", &threshold_noise); + else + fscanf(sig, "%*f\n"); + if (threshold_slope == 0.0) + fscanf(sig, "%lf\n", &threshold_slope); + else + fscanf(sig, "%*f\n"); + if (blocksize == 0) + fscanf(sig, "%d\n", &blocksize); + else + fscanf(sig, "%*d\n"); + fscanf(sig, "%d\n", &seed); + srandom(seed); + fread(signature, sizeof(char), NBITSTOBYTES(nbit_signature), sig); + fscanf(sig, "\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + if (pattern1 <= 0 || pattern2 <= 0 || pattern1 > NPATTERN || pattern2 > NPATTERN) { + fprintf(stderr, "%s: invalid pattern type specified\n", progname); + exit(1); + } + + // read dimensions of input image file + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + + // see if we can embed all signature bits + // we want at least half of the blocks untouched + if (((rows / blocksize) * (cols / blocksize)) < nbit_signature / 2) { + fprintf(stderr, "%s: image not large enough to embed %d bits of signature\n", progname, nbit_signature); + exit(1); + } + n_block = blocksize * blocksize; + + // allocate structure to remember which blocks we already touched, + // allow plenty of room to skip over blocks + if ((coords = alloc_coords(nbit_signature * 16)) == NULL) { + fprintf(stderr, "%s: unable to allocate memory\n", progname); + exit(1); + } + + // read in input image file + image = pgm_allocarray(cols, rows); + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + + fclose(in); + + row = 0; + + // allocate memory for one block + block = alloc_grays(blocksize, blocksize); + + // allocate memory for zone classification + zone = alloc_grays(blocksize, blocksize); + + // allocate memory for category classification + category1 = alloc_grays(blocksize, blocksize); + category2 = alloc_grays(blocksize, blocksize); + + // set up category classification array according to + // pattern type parameter + for (i = 0; i < blocksize; i++) + for (j = 0; j < blocksize; j++) { + category1[j][i] = lookup_pattern(pattern1, i, j); + category2[j][i] = lookup_pattern(pattern2, i, j); + } + + // allocate memory for slope calculation + slope = malloc(sizeof(double) * n_block); + + // embed all the signature bits, one by one + n = 0; + while (n < nbit_signature) { + int xb; + int yb; + int blocktype; + double smax; + int alpha, beta_minus, beta_plus; + double mean_1A, mean_1B, mean_2A, mean_2B, mean_1, mean_2; + double mean__1A, mean__1B, mean__2A, mean__2B; + int n_1A, n_1B, n_2A, n_2B, n_1, n_2; + int var_1A, var_1B, var_2A, var_2B; + int zone1_ok, zone2_ok; + + // find an unused block randomly, depending on seed + do { + xb = random() % (cols / blocksize); + yb = random() % (rows / blocksize); + } while (add_coord(coords, xb, yb) < 0); + + // copy image block + copy_grays_to_block(block, image, xb * blocksize, yb * blocksize, blocksize, blocksize); + + if (verbose > 0) + fprintf(stderr, "embedding bit #%d (= %d) in block at (%d/%d)\n", n, get_signature_bit(n), xb * blocksize, yb * blocksize); + if (verbose > 8) { + print_grays(image, xb * blocksize, yb * blocksize, blocksize, blocksize); + fprintf(stderr, "\n"); + } + + // sort luminance values in block to represent increasing function F + sort_grays(block[0], n_block); + + if (verbose > 8) { + print_grays(block, 0, 0, blocksize, blocksize); + fprintf(stderr, "\n"); + } + + // calculate slopes of F and determine smax, the max. slope of F + // the index where smax occures is called alpha + alpha = 0; + smax = 0.0; + for (i = 0; i < n_block - 1; i++) { + slope[i] = block[0][i + 1] - block[0][i]; + if (slope[i] > smax) { + smax = slope[i]; + alpha = i; + } + } + slope[n_block - 1] = 0; + + // block type classification + blocktype = BLOCKTYPE_UNKNOWN; + + if (smax < threshold_noise) { + // block has noise contrast + + blocktype = BLOCKTYPE_NOISE; + beta_minus = beta_plus = alpha; + } + else { + // block has progressive or hard contrast, let's find out... + + beta_minus = alpha - 1; + while (beta_minus >= 0 && smax - slope[beta_minus] <= threshold_slope) + beta_minus--; + + beta_plus = alpha + 1; + while (beta_plus < n_block && smax - slope[beta_plus] <= threshold_slope) + beta_plus++; + + if (beta_minus + 1 == alpha && beta_plus - 1 == alpha) + blocktype = BLOCKTYPE_HARD; + else + blocktype = BLOCKTYPE_PROGRESSIVE; + } + + if (verbose > 1) { + fprintf(stderr, "blocktype: %d\n", blocktype); + fprintf(stderr, "Smax = %lf, alpha = %d, beta- = %d, beta+ = %d\n", smax, alpha, beta_minus, beta_plus); + } + + // block pixel classification + for (i = 0; i < blocksize; i++) + for (j = 0; j < blocksize; j++) { + gray pixel = image[yb * blocksize + j][xb * blocksize + i]; + zone[j][i] = ZONE_VOID; + switch (blocktype) { + case BLOCKTYPE_PROGRESSIVE: + case BLOCKTYPE_HARD: + if (pixel < block[0][beta_minus]) + zone[j][i] = ZONE_1; + else if (pixel > block[0][beta_plus]) + zone[j][i] = ZONE_2; + break; + case BLOCKTYPE_NOISE: + if (pixel < block[0][n_block / 2]) + zone[j][i] = ZONE_1; + else if (pixel > block[0][n_block / 2]) + zone[j][i] = ZONE_2; + break; + default: + fprintf(stderr, "%s: invalid block type\n", progname); + break; + } + } + + if (verbose > 8) { + print_grays(zone, 0, 0, blocksize, blocksize); + fprintf(stderr, "\n"); + } + + // calculate mean values for zone/categories + mean_1A = mean_1B = mean_2A = mean_2B = mean_1 = mean_2 = 0.0; + mean__1A = mean__1B = mean__2A = mean__2B = 0.0; + n_1A = n_1B = n_2A = n_2B = n_1 = n_2 = 0; + for (i = 0; i < blocksize; i++) + for (j = 0; j < blocksize; j++) { + gray pixel = image[yb * blocksize + j][xb * blocksize + i]; + int pixel_zone = zone[j][i]; + int pixel_category = CATEGORY_VOID; + if (pixel_zone == ZONE_1) + pixel_category = category1[j][i]; + else if (pixel_zone == ZONE_2) + pixel_category = category2[j][i]; + + switch (pixel_zone | pixel_category) { + case CLASSIFICATION_1A: + n_1++; + n_1A++; + mean_1A += pixel; + mean_1 += pixel; + break; + case CLASSIFICATION_1B: + n_1++; + n_1B++; + mean_1B += pixel; + mean_1 += pixel; + break; + case CLASSIFICATION_2A: + n_2++; + n_2A++; + mean_2A += pixel; + mean_2 += pixel; + break; + case CLASSIFICATION_2B: + n_2++; + n_2B++; + mean_2B += pixel; + mean_2 += pixel; + break; + } + } + + if (n_1 && n_1A && n_1B) { + mean_1 /= (double) n_1; + mean_1A /= (double) n_1A; + mean_1B /= (double) n_1B; + zone1_ok = 1; + } + else { + mean_1 = mean_1A = mean_1B = 0.0; + zone1_ok = 0; + if (verbose > 0) + fprintf(stderr, "zone 1 unusable\n"); + } + + if (n_2 && n_2A && n_2B) { + mean_2 /= (double) n_2; + mean_2A /= (double) n_2A; + mean_2B /= (double) n_2B; + zone2_ok = 1; + } + else { + mean_2 = mean_2A = mean_2B = 0.0; + zone2_ok = 0; + if (verbose > 0) + fprintf(stderr, "zone 2 unusable\n"); + } + + if (!skipping && !zone1_ok && !zone2_ok) { + // pathological case - can it ever happen? + if (verbose > 0) + fprintf(stderr, "block skipped\n"); + continue; + } + + if (verbose > 2) { + fprintf(stderr, "m_1 = %lf, m_1A = %lf, m_1B = %lf\n", mean_1, mean_1A, mean_1B); + fprintf(stderr, "m_2 = %lf, m_2A = %lf, m_2B = %lf\n", mean_2, mean_2A, mean_2B); + } + + // calculate new mean values required by embedding rule + if (get_signature_bit(n)) { + if (zone1_ok) { + mean__1A = (mean_1 * (double) (n_1A + n_1B) + (double) n_1B * quality) / (double) (n_1A + n_1B); + mean__1B = mean__1A - quality; + } + if (zone2_ok) { + mean__2A = (mean_2 * (double) (n_2A + n_2B) + (double) n_2B * quality) / (double) (n_2A + n_2B); + mean__2B = mean__2A - quality; + } + } + else { + if (zone1_ok) { + mean__1A = (mean_1 * (double) (n_1A + n_1B) - (double) n_1B * quality) / (double) (n_1A + n_1B); + mean__1B = mean__1A + quality; + } + if (zone2_ok) { + mean__2A = (mean_2 * (double) (n_2A + n_2B) - (double) n_2B * quality) / (double) (n_2A + n_2B); + mean__2B = mean__2A + quality; + } + } + + // calculate luminance variations + if (zone1_ok) { + var_1A = rint(mean__1A - mean_1A); + var_1B = rint(mean__1B - mean_1B); + } + else var_1A = var_1B = 0; + + if (zone2_ok) { + var_2A = rint(mean__2A - mean_2A); + var_2B = rint(mean__2B - mean_2B); + } + else var_2A = var_2B = 0; + + if (verbose > 2) { + if (zone1_ok) + fprintf(stderr, "m*_1A = %lf, m*_1B = %lf\n", mean__1A, mean__1B); + if (zone2_ok) + fprintf(stderr, "m*_2A = %lf, m*_2B = %lf\n", mean__2A, mean__2B); + fprintf(stderr, "var %d %d %d %d\n", var_1A, var_1B, var_2A, var_2B); + } + + // apply luminance variations to image pixels + for (i = 0; i < blocksize; i++) + for (j = 0; j < blocksize; j++) { + int pixel = image[yb * blocksize + j][xb * blocksize + i]; + int pixel_zone = zone[j][i]; + int pixel_category = CATEGORY_VOID; + if (pixel_zone == ZONE_1) + pixel_category = category1[j][i]; + else if (pixel_zone == ZONE_2) + pixel_category = category2[j][i]; + + switch (pixel_zone | pixel_category) { + case CLASSIFICATION_1A: + pixel = GRAYRANGE(pixel + var_1A); + break; + case CLASSIFICATION_1B: + pixel = GRAYRANGE(pixel + var_1B); + break; + case CLASSIFICATION_2A: + pixel = GRAYRANGE(pixel + var_2A); + break; + case CLASSIFICATION_2B: + pixel = GRAYRANGE(pixel + var_2B); + break; + } + image[yb * blocksize + j][xb * blocksize + i] = pixel; + } + + n++; + } + + free_grays(category2); + free_grays(category1); + free_grays(zone); + free_grays(block); + + // write output image dimensions to output file + pgm_writepgminit(out, cols, rows, maxval, 0); + + // write output image + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, image[row], cols, maxval, 0); + + fclose(out); + + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_corvi_d.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_corvi_d.1 Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,173 @@ +.\" +.\" wm_corvi_d.1 - the *roff document processor man page source +.\" +.TH wm_corvi_d 1 "98/07/29" "Watermarking, Version 1.0" +.SH NAME +.B wm_corvi_d +\- a program to extract a signature from the DWT residue of a watermarked +image +.SH SYNOPSIS +.B wm_corvi_d +[ +.BI \-a \ number +] +[ +.BI \-e \ number +] +[ +.BI \-f \ number +] +[ +.BI \-F \ ffile +] +[ +.BI \-g \ number +] +[ +.B \-h +] +[ +.BI \-i \ ifile +] +.br +[ +.BI \-n \ number +] +[ +.BI \-o \ ofile +] +[ +.BI \-q \ number +] +[ +.BI \-v \ number +] +.BI \-s \ sfile +.I file +.SH DESCRIPTION +.B wm_corvi_d +is a program to extract a signature from the DWT residue of +a watermarked image +.I file. +The +.B cmp_corvi_sig +program is used to test the extracted signature against the original signature. +The input image is in PGM (portable graymap) format. +.PP +If +.I file +or +.I ofile +is not specified, then standard input or standard output is +used. +.PP +.B gen_corvi_sig +is used to generate a signature file, +.B wm_corvi_e +embeds the signature into an image. +.PP +Please refer to Marco Corvi's paper "Wavelet-based image watermarking +for copyright protection", to get an idea about the algorithm. +.PP +.SH OPTIONS +.TP +.BI \-a \ number +Alpha factor that determines embedding strength of the signature. +Allows to override the setting in the signature file. +.TP +.BI \-e \ number +Wavelet filtering method for forward transformation. +Allows to override the setting in the signature file. +.TP +.BI \-f \ number +Wavelet filter number. +Allows to override the setting in the signature file. +.TP +.BI \-F \ ffile +Wavelet filter definition file. +Allows to override the setting in the signature file. +.TP +.BI \-g \ number +Wavelet filtering method for inverse transformation. +Allows to override the setting in the signature file. +.TP +.B \-h +Print a help message. +.TP +.BI \-i \ ifile +The original image. +.TP +.BI \-o \ ofile +Output watermarked image to the specified +.I file +instead of standard output. +.TP +.BI \-q \ number +Set quantization/quality factor. Overrides the setting in the signature +file. +.TP +.BI \-v \ number +Verbosity level. Default value: 0. +.TP +.BI \-s \ sfile +The signature file to embed into the input image. See +.B gen_corvi_sig +(1) for a description of the file format. Mandatory parameter. +.IR file +Input image in PGM format to sign (watermark). Default: standard input. +.TP +.I file +The watermarked image in PGM format. +.PP +.SH OUTPUT +The signed (watermarked) image in PGM format is written to standard output +or, optionally, to +.I ofile. +.PP +The output file has the following format: +.TP +.B CVSG +Magic to identify file type. +.TP +.I number +The length of the signature in bits. +.TP +.I number +The alpha factor (embedding strength). +.TP +.I number +The quantization/quality factor. +.TP +.I number +The wavelet forward transform filtering method. +.TP +.I number +The wavelet filter number. +.TP +.I file +The wavelet filter definition file name. +.TP +.I number +The wavelet inverse transform filtering method. +.TP +.I numbers +The actual normal distributed signature values, one per line. +.PP +.SH AUTHOR +Peter Meerwald +Email bug reports to pmeerw@cosy.sbg.ac.at. +.SH AVAILABILITY +The most recent released version of +.B wm_corvi_d +is always available +at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the +directory /pub/people/pmeerw/Watermarking. +.SH "SEE ALSO" +.BR gen_corvi_sig +(1), +.BR wm_corvi_e +(1), +.BR wm_corvi_s +(1), +.BR cmp_corvi_sig +(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_corvi_d.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_corvi_d.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,310 @@ +#include "dwt.h" +#include "netpbm/pgm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-h] [-n n] [-o file] [-s file] [-v n] -i file file\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-i file\t\toriginal image file\n"); + fprintf(stderr, "\t-n n\t\twatermark length\n"); + fprintf(stderr, "\t-o file\t\textracted signature file\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *orig = NULL; + FILE *sig = NULL; + + gray **input_image; + gray **orig_image; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char orig_name[MAXPATHLEN]; + + int c; + int n = 0; + int method = -1; + int filter = 0; + char filter_name[MAXPATHLEN] = ""; + + int level = 0; + double alpha = 0.0; + + int in_rows, in_cols, in_format; + gray in_maxval; + int orig_rows, orig_cols, orig_format; + gray orig_maxval; + int rows, cols; + int row, col; + + Image_tree input_dwts; + Image_tree orig_dwts; + + int verbose = 0; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init2(); + + while ((c = getopt(argc, argv, "a:e:f:F:h?i:n:o:s:v:")) != EOF) { + switch (c) { + case 'a': + alpha = atof(optarg); + if (alpha <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'i': + if ((orig = fopen(optarg, "rb")) == NULL) { + fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); + exit(1); + } + strcpy(orig_name, optarg); + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 1000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (!orig) { + fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); + exit(1); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "CVSG") >= 4) { + fscanf(sig, "%d\n", &n); + if (alpha == 0.0) + fscanf(sig, "%lf\n", &alpha); + else + fscanf(sig, "%*f\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); + pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); + + if (in_cols != orig_cols || in_rows != orig_rows) { + fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); + exit(1); + } + + cols = in_cols; + rows = in_rows; + + input_image = pgm_allocarray(in_cols, in_rows); + + orig_image = pgm_allocarray(orig_cols, orig_rows); + + for (row = 0; row < in_rows; row++) + pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); + + fclose(in); + + for (row = 0; row < orig_rows; row++) + pgm_readpgmrow(orig, orig_image[row], orig_cols, orig_maxval, orig_format); + + fclose(orig); + + level = 0; + row = rows; + col = cols; + while (n < row * col / 4.0 && row >= 2 && col >= 2) { + row /= 2; + col /= 2; + level++; + } + + if (verbose >= 2) { + fprintf(stderr, "%s: extracting from coarse image (x %d/y %d) at level %d\n", progname, col, row, level); + } + + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + input_dwts = fdwt(input_image); + orig_dwts = fdwt(orig_image); + + fprintf(out, "CVWM\n"); + fprintf(out, "%d\n", n); + + { + Image_tree p = input_dwts; + Image_tree q = orig_dwts; + Image input_img; + Image orig_img; + double input_med; + double orig_med; + double input_var; + double orig_var; + + while (!p->image) + p = p->coarse; + + while (!q->image) + q = q->coarse; + + input_img = p->image; + orig_img = q->image; + + input_med = 0.0; + for (row = 0; row < input_img->height; row++) + for (col = 0; col < input_img->width; col++) + input_med += get_pixel(input_img, col, row); + input_med /= (double) (input_img->height * input_img->width); + + orig_med = 0.0; + for (row = 0; row < orig_img->height; row++) + for (col = 0; col < orig_img->width; col++) + orig_med += get_pixel(orig_img, col, row); + orig_med /= (double) (orig_img->height * orig_img->width); + + orig_var = 0.0; + for (row = 0; row < orig_img->height; row++) + for (col = 0; col < orig_img->width; col++) + orig_var += sqr(get_pixel(orig_img, col, row) - orig_med); + orig_var /= (double) (orig_img->height * orig_img->width); + + input_var = 0.0; + for (row = 0; row < input_img->height; row++) + for (col = 0; col < input_img->width; col++) + input_var += sqr(get_pixel(input_img, col, row) - input_med); + input_var /= (double) (input_img->height * input_img->width); + + orig_var = sqrt(orig_var); + input_var = sqrt(input_var); + + if (verbose > 3) + fprintf(stderr, "%s: mean (input, orig): %f, %f,\n variance (input, orig): %f, %f\n", progname, input_med, orig_med, input_var, orig_var); + + row = 0; + col = 0; + while (n > 0) { + double input_pix; + double orig_pix; + double x; + + input_pix = get_pixel(input_img, col, row); + orig_pix = get_pixel(orig_img, col, row); + + x = (((input_pix - input_med) * (orig_var / input_var) - (orig_pix / orig_med)) / (orig_pix - orig_med) - 1.0) / alpha; + + fprintf(out, "%f\n", x); + + if (++col == orig_img->width) { col = 0; row++; } + n--; + } + } + + fclose(out); + + pgm_freearray(input_image, rows); + pgm_freearray(orig_image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_corvi_e.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_corvi_e.1 Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,142 @@ +.\" +.\" wm_corvi_e.1 - the *roff document processor man page source +.\" +.TH wm_corvi_e 1 "98/07/29" "Watermarking, Version 1.0" +.SH NAME +.B wm_corvi_e +\- a program to embed a signature in the DWT residue of an image +.SH SYNOPSIS +.B wm_corvi_e +[ +.BI \-a \ number +] +[ +.BI \-e \ number +] +[ +.BI \-f \ number +] +[ +.BI \-F \ ffile +] +[ +.BI \-g \ number +] +[ +.B \-h +] +[ +.BI \-o \ ofile +] +.br +[ +.BI \-q \ number +] +[ +.BI \-v \ number +] +.BI \-s \ sfile +.I file +.SH DESCRIPTION +.B wm_corvi_e +is a program to embed a signature (watermark) from +.I sfile +into the DWT residue of an image +.I file +and output a signed (watermarked) image +.I ofile. +Both, input and output image, +are in PGM (portable graymap) format. +.PP +If +.I file +or +.I ofile +is not specified, then standard input or standard output is +used. The signature +.I sfile +is a mandatory parameter however. +.PP +.B gen_corvi_sig +is used to generate a signature file, +.B wm_corvi_d +extracts a signature from a watermarked image and +.B cmp_corvi_sig +allows to compare and test an extracted watermark against the original +signature. +.PP +Please refer to Marco Corvi's paper "Wavelet-based image watermarking +for copyright protection", to get an idea about the algorithm. +.PP +.SH OPTIONS +.TP +.BI \-a \ number +Alpha factor that determines embedding strength of the signature. +Allows to override the setting in the signature file. +.TP +.BI \-e \ number +Wavelet filtering method for forward transformation. +Allows to override the setting in the signature file. +.TP +.BI \-f \ number +Wavelet filter number. +Allows to override the setting in the signature file. +.TP +.BI \-F \ ffile +Wavelet filter definition file. +Allows to override the setting in the signature file. +.TP +.BI \-g \ number +Wavelet filtering method for inverse transformation. +Allows to override the setting in the signature file. +.TP +.B \-h +Print a help message. +.TP +.BI \-o \ ofile +Output watermarked image to the specified +.I file +instead of standard output. +.TP +.BI \-q \ number +Set quantization/quality factor. Overrides the setting in the signature +file. +.TP +.BI \-s \ sfile +The signature file to embed into the input image. See +.B gen_corvi_sig +(1) for a description of the file format. Mandatory parameter. +.IR file +Input image in PGM format to sign (watermark). Default: standard input. +.TP +.BI \-v \ number +Verbosity level. Specify higher numbers for more informatative +output. Default value: 0. +.TP +.I file +The image in PGM format to be watermarked. +.PP +.SH OUTPUT +The signed (watermarked) image in PGM format is written to standard output +or, optionally, to +.I ofile. +The length of the signature (watermark) determines the level of the +image residue (coarse image) where the signature is embedded. +.PP +.SH AUTHOR +Peter Meerwald. Email bug reports to pmeerw@cosy.sbg.ac.at. +.SH AVAILABILITY +The most recent released version of +.B wm_corvi_e +is always available +at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the +directory /pub/people/pmeerw/Watermarking. +.SH "SEE ALSO" +.BR gen_corvi_sig +(1), +.BR wm_corvi_d +(1), +.BR wm_corvi_s +(1), +.BR cmp_corvi_sig +(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_corvi_e.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_corvi_e.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,237 @@ +#include "wm.h" +#include "dwt.h" +#include "netpbm/pgm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-e n] [-f n] [-F n] [-h] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor/embedding strength\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int c; + int row, col; + + int n; + + double alpha = 0.0; + + int filter = 0; + int method = -1; + int level = 0; + char filter_name[MAXPATHLEN] = ""; + + int verbose = 0; + + gray **image; + Image_tree dwts; + + gray maxval; + int rows, cols, format; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "a:e:f:F:h?o:s:v:")) != EOF) { + switch (c) { + case 'a': + alpha = atof(optarg); + if (alpha <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "CVSG") >= 4) { + fscanf(sig, "%d\n", &n); + if (alpha == 0.0) + fscanf(sig, "%lf\n", &alpha); + else + fscanf(sig, "%*f\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + + image = pgm_allocarray(cols, rows); + + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + + fclose(in); + + level = 0; + row = rows; + col = cols; + while (n < row * col / 4.0 && row >= 2 && col >= 2) { + row /= 2; + col /= 2; + level++; + } + + if (verbose >= 2) { + fprintf(stderr, "%s: embedding into coarse image (x %d/y %d) at level %d\n", progname, col, row, level); + } + + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + dwts = fdwt(image); + + { + Image_tree p = dwts; + Image img; + double med; + + while (!p->image) + p = p->coarse; + + img = p->image; + + med = 0.0; + for (row = 0; row < img->height; row++) + for (col = 0; col < img->width; col++) + med += get_pixel(img, col, row); + + med /= (double) (img->height * img->width); + + row = 0; + col = 0; + while (n > 0) { + double pix; + double g; + + fscanf(sig, "%lf\n", &g); + + pix = get_pixel(img, col, row); + pix = med + (pix - med) * (1.0 + alpha * g); + set_pixel(img, col, row, pix); + + if (++col == img->width) { col = 0; row++; } + n--; + } + } + + fclose(sig); + + idwt(dwts, image); + + pgm_writepgminit(out, cols, rows, maxval, 0); + + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, image[row], cols, maxval, 0); + + fclose(out); + + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_corvi_s.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_corvi_s.1 Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,171 @@ +.\" +.\" wm_corvi_s.1 - the *roff document processor man page source +.\" +.TH wm_corvi_s 1 "98/07/29" "Watermarking, Version 1.0" +.SH NAME +.B wm_corvi_s +\- a program to extract a signature from the DWT residue of a watermarked +image +.SH SYNOPSIS +.B wm_corvi_s +[ +.BI \-a \ number +] +[ +.BI \-e \ number +] +[ +.BI \-f \ number +] +[ +.BI \-F \ ffile +] +[ +.BI \-g \ number +] +[ +.B \-h +] +[ +.BI \-i \ ifile +] +.br +[ +.BI \-n \ number +] +[ +.BI \-o \ ofile +] +[ +.BI \-q \ number +] +[ +.BI \-v \ number +] +.BI \-s \ sfile +.I file +.SH DESCRIPTION +.B wm_corvi_s +is a program to extract a signature from the DWT residue of +a watermarked image +.I file. +The +.B cmp_corvi_sig +program is used to test the extracted signature against the original signature. +The input image is in PGM (portable graymap) format. +.PP +If +.I file +or +.I ofile +is not specified, then standard input or standard output is +used. +.PP +.B gen_corvi_sig +is used to generate a signature file, +.B wm_corvi_e +embeds the signature into an image. +.PP +Please refer to Marco Corvi's paper "Wavelet-based image watermarking +for copyright protection", to get an idea about the algorithm. +.PP +.SH OPTIONS +.TP +.BI \-a \ number +Alpha factor that determines embedding strength of the signature. +Allows to override the setting in the signature file. +.TP +.BI \-e \ number +Wavelet filtering method for forward transformation. +Allows to override the setting in the signature file. +.TP +.BI \-f \ number +Wavelet filter number. +Allows to override the setting in the signature file. +.TP +.BI \-F \ ffile +Wavelet filter definition file. +Allows to override the setting in the signature file. +.TP +.BI \-g \ number +Wavelet filtering method for inverse transformation. +Allows to override the setting in the signature file. +.TP +.B \-h +Print a help message. +.TP +.BI \-i \ ifile +The original image. +.TP +.BI \-o \ ofile +Output watermarked image to the specified +.I file +instead of standard output. +.TP +.BI \-q \ number +Set quantization/quality factor. Overrides the setting in the signature +file. +.TP +.BI \-v \ number +Verbosity level. Default value: 0. +.TP +.BI \-s \ sfile +The signature file to embed into the input image. See +.B gen_corvi_sig +(1) for a description of the file format. Mandatory parameter. +.IR file +Input image in PGM format to sign (watermark). Default: standard input. +.TP +.I file +The watermarked image in PGM format. +.PP +.SH OUTPUT +The signed (watermarked) image in PGM format is written to standard output +or ,optionally, to +.I ofile. +.PP +The output file has the following format: +.TP +.B CVSG +Magic to identify file type. +.TP +.I number +The length of the signature in bits. +.TP +.I number +The alpha factor (embedding strength). +.TP +.I number +The quantization/quality factor. +.TP +.I number +The wavelet forward transform filtering method. +.TP +.I number +The wavelet filter number. +.I file +The wavelet filter definition file name. +.TP +.I number +The wavelet inverse transform filtering method. +.TP +.I numbers +The actual normal distributed signature values, one per line. +.PP +.SH AUTHOR +Peter Meerwald. Email bug reports to pmeerw@cosy.sbg.ac.at. +.SH AVAILABILITY +The most recent released version of +.B wm_corvi_s +is always available +at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the +directory /pub/people/pmeerw/Watermarking. +.SH "SEE ALSO" +.BR gen_corvi_sig +(1), +.BR wm_corvi_e +(1), +.BR wm_corvi_d +(1), +.BR cmp_corvi_sig +(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_corvi_s.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_corvi_s.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,295 @@ +#include "wm.h" +#include "wm_dwt.h" +#include "pgm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-h] [-n n] [-o file] [-q n] [-s file] [-v n] -i file file\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-i file\t\toriginal image file\n"); + fprintf(stderr, "\t-n n\t\twatermark length\n"); + fprintf(stderr, "\t-o file\t\textracted signature file\n"); + fprintf(stderr, "\t-q n\t\tquantization/quality factor\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *orig = NULL; + FILE *sig = NULL; + + gray **input_image; + gray **orig_image; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char orig_name[MAXPATHLEN]; + + int c; + int i; + int quantization = 0; + int n = 0; + int method = -1; + int filter = 0; + char filter_name[MAXPATHLEN] = ""; + + int level; + double alpha = 0.0; + + int in_rows, in_cols, in_format; + gray in_maxval; + int orig_rows, orig_cols, orig_format; + gray orig_maxval; + int rows, cols; + int row, col; + + Image_tree input_dwts; + Image_tree orig_dwts; + + int verbose = 0; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init2(); + + while ((c = getopt(argc, argv, "a:e:f:F:h?i:n:o:s:v:")) != EOF) { + switch (c) { + case 'a': + alpha = atof(optarg); + if (alpha <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'i': + if ((orig = fopen(optarg, "rb")) == NULL) { + fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); + exit(1); + } + strcpy(orig_name, optarg); + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 1000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + + if (!orig) { + fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); + exit(1); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "CVSG") >= 4) { + fscanf(sig, "%d\n", &n); + if (alpha == 0.0) + fscanf(sig, "%lf\n", &alpha); + else + fscanf(sig, "%*f\n"); + if (quantization == 0) + fscanf(sig, "%d\n", &quantization); + else + fscanf(sig, "%*d\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); + pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); + + if (in_cols != orig_cols || in_rows != orig_rows) { + fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); + exit(1); + } + + cols = in_cols; + rows = in_rows; + + input_image = pgm_allocarray(in_cols, in_rows); + + orig_image = pgm_allocarray(orig_cols, orig_rows); + + for (row = 0; row < in_rows; row++) + pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); + + fclose(in); + + for (row = 0; row < orig_rows; row++) + pgm_readpgmrow(orig, orig_image[row], orig_cols, orig_maxval, orig_format); + + fclose(orig); + + level = 0; + row = rows; + col = cols; + while (n < row * col / 4.0 && row >= 2 && col >= 2) { + row /= 2; + col /= 2; + level++; + } + + if (verbose >= 2) { + fprintf(stderr, "%s: extracting from coarse image (x %d/y %d) at level %d\n", progname, col, row, level); + } + + init_dwt(cols, rows, filter_name, filter, level, method); + input_dwts = fdwt(input_image); + orig_dwts = fdwt(orig_image); + + fprintf(out, "CVSG\n"); + fprintf(out, "%d\n", n); + fprintf(out, "%f\n", alpha); + fprintf(out, "%d\n", quantization); + fprintf(out, "%d\n", method); + fprintf(out, "%d\n", filter); + fprintf(out, "%s\n", filter_name); + + { + Image_tree p = input_dwts; + Image_tree q = orig_dwts; + Image input_img; + Image orig_img; + double input_med; + double orig_med; + + while (!p->image) + p = p->coarse; + + while (!q->image) + q = q->coarse; + + input_img = p->image; + orig_img = q->image; + + input_med = 0.0; + for (row = 0; row < input_img->height; row++) + for (col = 0; col < input_img->width; col++) + input_med += get_pixel(input_img, col, row); + input_med /= input_img->height * input_img->width; + + orig_med = 0.0; + for (row = 0; row < orig_img->height; row++) + for (col = 0; col < orig_img->width; col++) + orig_med += get_pixel(orig_img, col, row); + orig_med /= orig_img->height * orig_img->width; + + row = 0; + col = 0; + while (n > 0) { + Pixel input_pix; + Pixel orig_pix; + double x; + + input_pix = get_pixel(input_img, col, row); + orig_pix = get_pixel(orig_img, col, row); + + x = ((input_pix - orig_pix) / (orig_pix - orig_med)) / alpha; + + fprintf(out, "%f\n", x); + + if (++col == orig_img->width) { col = 0; row++; } + n--; + } + } + + fclose(out); + + pgm_freearray(input_image, rows); + pgm_freearray(orig_image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_cox_d.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_cox_d.1 Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,132 @@ +.\" +.\" wm_cox_d.1 - the *roff document processor man page source +.\" +.TH wm_cox_d 1 "98/07/05" "Watermarking, Version 1.0" +.SH NAME +.B wm_cox_d +\- a program to extract a signature from the DCT coefficients of a watermarked image +.SH SYNOPSIS +.B wm_cox_d +[ +.BI \-a \ number +] +[ +.B \-h +] +[ +.BI \-i \ ifile +] +[ +.BI \-n \ number +] +[ +.BI \-o \ ofile +] +[ +.BI \-q \ number +] +[ +.BI \-v \ number +] +.br +.BI \-s \ sfile +.I file +.SH DESCRIPTION +.B wm_cox_d +is a program to extract a signature from the DCT coefficients of the watermarked image +.I file. +The +.B cmp_cox_sig +program is used to test the extracted signature against the original signature. +The input image is in PGM (portable graymap) format. +.PP +If +.I file +or +.I ofile +is not specified, then standard input or standard output is +used. +.PP +.B gen_cox_sig +is used to generate a signature file, +.B wm_cox_e +embeds the signature into an image. +.PP +Please refer to Ingemar J. Cox's paper "Secure Spread Spectrum +Watermarking for Multimedia", 1995, to get an idea about the algorithm. +.PP +.SH OPTIONS +.TP +.BI \-a \ number +Alpha factor that determines embedding strength of the signature. +Allows to override the setting in the signature file. +.TP +.B \-h +Print a help message. +.TP +.BI \-i \ ifile +The original image. +.TP +.BI \-o \ ofile +Output watermarked image to the specified +.I file +instead of standard output. +.TP +.BI \-q \ number +Set quantization/quality factor. Overrides the setting in the signature +file. +.TP +.BI \-v \ number +Verbosity level. Default value: 0. +.TP +.BI \-s \ sfile +The signature file to embed into the input image. See +.B gen_cox_sig +(1) for a description of the file format. Mandatory parameter. +.IR file +Input image in PGM format to sign (watermark). Default: standard input. +.TP +.I +The watermarked image file in PGM format. +.PP +.SH OUTPUT +The signed (watermarked) image in PGM format is written to standard output +or ,optionally, to +.I ofile. +The embedding process may take some time on large images since the DCT +is performed on the whole image in one step (not block-wise). +.PP +.PP +The output file has the following format: +.TP +.B CXSG +Magic to identify file type. +.TP +.I number +The length of the signature in bits. +.TP +.I number +The alpha factor (embedding strength). +.TP +.I number +The quantization/quality factor. +.TP +.I numbers +The actual normal distributed signature values, one per line. +.PP +.SH AUTHOR +Peter Meerwald. +Email bug reports to pmeerw@cosy.sbg.ac.at. +.SH AVAILABILITY +The most recent released version of +.B wm_cox_d +is always available +at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the +directory /pub/people/pmeerw/Watermarking. +.SH "SEE ALSO" +.BR gen_cox_sig +(1), +.BR wm_cox_e +(1), +.BR cmp_cox_sig +(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_cox_d.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_cox_d.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,228 @@ +#include "wm.h" +#include "dct.h" +#include "netpbm/pgm.h" +#include "sort.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-h] [-n n] [-o file] [-s file] [-v n] -i file file\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor (default 0.3)\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-i file\t\toriginal image file\n"); + fprintf(stderr, "\t-n n\t\twatermark length (default 100)\n"); + fprintf(stderr, "\t-o file\t\textracted signature file\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *orig = NULL; + FILE *sig = NULL; + + gray **input_image; + gray **orig_image; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char orig_name[MAXPATHLEN]; + + int c; + int i, j; + int n = 100; + + double a = 0.3; + + int warn_n = 1; + int warn_a = 1; + + int in_rows, in_cols, in_format; + gray in_maxval; + int orig_rows, orig_cols, orig_format; + gray orig_maxval; + int rows, cols; + int row; + + double threshold; + double *largest; + + double **input_dcts; + double **orig_dcts; + + int verbose = 0; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init2(); + + while ((c = getopt(argc, argv, "h?i:n:o:s:v:")) != EOF) { + switch (c) { + case 'a': + a = atof(optarg); + if (a <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); + exit(1); + } + warn_a = 0; + break; + case 'h': + case '?': + usage(); + break; + case 'i': + if ((orig = fopen(optarg, "rb")) == NULL) { + fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); + exit(1); + } + strcpy(orig_name, optarg); + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 1000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + warn_n = 0; + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (!orig) { + fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); + exit(1); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "CXSG") >= 4) { + fscanf(sig, "%d\n", &n); + if (warn_a) + fscanf(sig, "%lf\n", &a); + else + fscanf(sig, "%*f\n"); + fscanf(sig, "%*f\n"); + fscanf(sig, "%*f\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + if (warn_a) + fprintf(stderr, "%s: warning - alpha factor not specified, using default %f\n", progname, a); + if (warn_n) + fprintf(stderr, "%s: warning - watermark length not specified, using default %d\n", progname, n); + } + + pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); + pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); + + if (in_cols != orig_cols || in_rows != orig_rows) { + fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); + exit(1); + } + + cols = in_cols; + rows = in_rows; + + init_dct_NxN(cols, rows); + + input_image = pgm_allocarray(in_cols, in_rows); + + orig_image = pgm_allocarray(orig_cols, orig_rows); + + for (row = 0; row < in_rows; row++) + pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); + + fclose(in); + + for (row = 0; row < orig_rows; row++) + pgm_readpgmrow(orig, orig_image[row], orig_cols, orig_maxval, orig_format); + + fclose(orig); + + input_dcts = alloc_coeffs(cols, rows); + orig_dcts = alloc_coeffs(cols, rows); + + fdct_NxN(input_image, input_dcts); + fdct_NxN(orig_image, orig_dcts); + + largest = malloc((n + 1) * sizeof(double)); + select_largest_coeffs(orig_dcts[0], cols * rows, n+1, largest); + threshold = largest[0]; + free(largest); + + fprintf(out, "CXWM\n"); + fprintf(out, "%d\n", n); + + j = 0; + for (i = 0; i < n; i++) { + double d, o, p; + + while ((o = orig_dcts[j / cols][j % cols]) < threshold) j++; + + p = input_dcts[j / cols][j % cols]; + + d = (p / o - 1.0) / a; + if (verbose >= 1) + fprintf(stderr, "input %f orig %f alpha %f d %f\n", p, o, a, d); + fprintf(out, "%f\n", d); + j++; + } + + fclose(out); + + free_coeffs(input_dcts); + free_coeffs(orig_dcts); + + pgm_freearray(input_image, rows); + pgm_freearray(orig_image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_cox_e.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_cox_e.1 Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,110 @@ +.\" +.\" wm_cox_e.1 - the *roff document processor man page source +.\" +.TH wm_cox_e 1 "98/07/01" "Watermarking, Version 1.0" +.SH NAME +.B wm_cox_e +\- a program to embed a signature in the DCT coefficients of an image +.SH SYNOPSIS +.B wm_cox_e +[ +.BI \-a \ number +] +[ +.B \-h +] +[ +.BI \-o \ ofile +] +[ +.BI \-q \ number +] +.BI \-s \ sfile +.I file +.SH DESCRIPTION +.B wm_cox_e +is a program to embed a signature (watermark) from +.I sfile +into the DCT coefficients of an image +.I file +and output a signed (watermarked) image +.I ofile. +Both, input and output image, +are in PGM (portable graymap) format. +.PP +If +.I file +or +.I ofile +is not specified, then standard input or standard output is +used. The signature +.I sfile +is a mandatory parameter however. +.PP +.B gen_cox_sig +is used to generate a signature file, +.B wm_cox_d +extracts a signature from a watermarked image and +.B cmp_cox_sig +allows to compare and test an extracted watermark against the original +signature. +.PP +Please refer to Ingemar J. Cox's paper "Secure Spread Spectrum +Watermarking for Multimedia", 1995, to get an idea about the algorithm. +.PP +.SH OPTIONS +.TP +.BI \-a \ number +Alpha factor that determines embedding strength of the signature. +Allows to override the setting in the signature file. +.TP +.B \-h +Print a help message. +.TP +.BI \-o \ ofile +Output watermarked image to the specified +.I file +instead of standard output. +.TP +.BI \-q \ number +Set quantization/quality factor. Overrides the setting in the signature +file. +.TP +.BI \-s \ sfile +The signature file to embed into the input image. See +.B gen_cox_sig +(1) for a description of the file format. Mandatory parameter. +.IR file +Input image in PGM format to sign (watermark). Default: standard input. +.TP +.I file +The input image in PGM format. +.PP +.SH OUTPUT +The signed (watermarked) image in PGM format is written to standard output +or, optionally, to +.I ofile. +The embedding process may take some time on large images since the DCT +is performed on the whole image in one step (not block-wise). +.PP +The +.I n +largest coefficients are pulsed to embed the +.I n +bit watermark. +.PP +.SH AUTHOR +Peter Meerwald. Email bug reports to pmeerw@cosy.sbg.ac.at. +.SH AVAILABILITY +The most recent released version of +.B wm_cox_e +is always available +at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the +directory /pub/people/pmeerw/Watermarking. +.SH "SEE ALSO" +.BR gen_cox_sig +(1), +.BR wm_cox_d +(1), +.BR cmp_cox_sig +(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_cox_e.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_cox_e.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,165 @@ +#include "wm.h" +#include "dct.h" +#include "netpbm/pgm.h" +#include "sort.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-h] [-o file] -s file file\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor/embedding strength\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int c; + int row; + int i,j; + + int n; + + double alpha = 0.0; + double threshold; + + double *largest; + gray **input_image; + gray **output_image; + double **dcts; + + gray maxval; + int rows, cols, format; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "a:h?o:s:")) != EOF) { + switch (c) { + case 'a': + alpha = atof(optarg); + if (alpha <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 'h': + case '?': + usage(); + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "CXSG") >= 4) { + fscanf(sig, "%d\n", &n); + if (alpha == 0.0) + fscanf(sig, "%lf\n", &alpha); + else + fscanf(sig, "%*f\n"); + fscanf(sig, "%*f\n"); + fscanf(sig, "%*f\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + + init_dct_NxN(cols, rows); + + dcts = alloc_coeffs(cols, rows); + input_image = pgm_allocarray(cols, rows); + + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, input_image[row], cols, maxval, format); + + fclose(in); + + output_image = pgm_allocarray(cols, rows); + + fdct_NxN(input_image, dcts); + + largest = malloc((n + 1) * sizeof(double)); + select_largest_coeffs(dcts[0], cols * rows, n+1, largest); + threshold = largest[0]; + free(largest); + + j = 0; + for (i = 0; i < n; i++) { + double v; + + while (dcts[j / cols][j % cols] < threshold) j++; + + fscanf(sig, "%lf\n", &v); + dcts[j / cols][j % cols] *= (1.0 + alpha * v); + j++; + } + + idct_NxN(dcts, output_image); + free_coeffs(dcts); + + pgm_writepgminit(out, cols, rows, maxval, 0); + + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, output_image[row], cols, maxval, 0); + + fclose(out); + + fclose(sig); + + pgm_freearray(output_image, rows); + pgm_freearray(input_image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_dugad_d.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_dugad_d.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,261 @@ +#include "wm.h" +#include "dwt.h" +#include "dwt_util.h" +#include "netpbm/pgm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-e n] [-f n] [-F file] [-h] [-l n] [-n n] [-o file] [-v n] [-t n] -s file file\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-l n\t\tdecomposition levels\n"); + fprintf(stderr, "\t-n n\t\twatermark length\n"); + fprintf(stderr, "\t-o file\t\tfile for extracted watermark\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-t n\t\tdetection threshold\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +void wm_subband(Image s, double *w, int n, double t2, int *m, double *z, double *v) { + int i; + + *m = 0; + *z = 0.0; + *v = 0.0; + for (i = 0; i < s->width * s->height; i++) + if (s->data[i] > t2) { + (*z) += (s->data[i] * w[i % n]); + (*v) += fabs(s->data[i]); + (*m)++; + } +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + gray **input_image; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + + int c; + int i; + int n = 0; + int method = -1; + int level = 0; + int filter = 0; + char filter_name[MAXPATHLEN] = ""; + + double alpha = 0.0; + double t2 = 0.0; + + int in_rows, in_cols, in_format; + gray in_maxval; + int rows, cols; + int row; + + double *watermark; + + Image_tree dwts, s; + + int verbose = 0; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init2(); + + while ((c = getopt(argc, argv, "a:e:f:F:h?l:n:o:s:v:t")) != EOF) { + switch (c) { + case 'a': + alpha = atof(optarg); + if (alpha <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'l': + level = atoi(optarg); + if (level <= 0) { + fprintf(stderr, "%s: decomposition level %d out of range\n", progname, level); + exit(1); + } + break; + + case 'n': + n = atoi(optarg); + if (n < 1 || n > 32000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 't': + t2 = atof(optarg); + if (t2 <= 0.0) { + fprintf(stderr, "%s: detection threshold %f out of range\n", progname, t2); + exit(1); + } + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "DGSG") >= 4) { + fscanf(sig, "%d\n", &n); + if (level == 0) + fscanf(sig, "%d\n", &level); + else + fscanf(sig, "%*d\n"); + if (alpha == 0.0) + fscanf(sig, "%lf\n", &alpha); + else + fscanf(sig, "%*f\n"); + fscanf(sig, "%*f\n"); + if (t2 == 0.0) + fscanf(sig, "%lf\n", &t2); + else + fscanf(sig, "%*f\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + watermark = malloc(n * sizeof(double)); + for (i = 0; i < n; i++) + fscanf(sig, "%lf\n", &watermark[i]); + fclose(sig); + + pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); + + cols = in_cols; + rows = in_rows; + + input_image = pgm_allocarray(in_cols, in_rows); + + for (row = 0; row < in_rows; row++) { + pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); + } + + fclose(in); + + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + dwts = fdwt(input_image); + + fprintf(out, "DGWM\n"); + fprintf(out, "%d\n", level); + fprintf(out, "%f\n", alpha); + + for (i = 0, s = dwts; i < level; i++, s = s->coarse) { + int m; + double z, v; + + wm_subband(s->horizontal->image, watermark, n, t2, &m, &z, &v); + fprintf(out, "%d %f %f\n", m, z, v); + wm_subband(s->vertical->image, watermark, n, t2, &m, &z, &v); + fprintf(out, "%d %f %f\n", m, z, v); + wm_subband(s->diagonal->image, watermark, n, t2, &m, &z, &v); + fprintf(out, "%d %f %f\n", m, z, v); + } + + fclose(out); + + free(watermark); + + pgm_freearray(input_image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_dugad_e.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_dugad_e.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,241 @@ +#include "wm.h" +#include "dwt.h" +#include "netpbm/pgm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-e n] [-f n] [-F file] [-h] [-l n] [-o file] [-t n] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor/embedding strength\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-l n\t\tdecomposition levels\n"); + fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + fprintf(stderr, "\t-t n\t\tcasting threshold\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +// actual watermarking procedure: embeds a watermark of n normally +// distributed values into a coefficients > threshold t1 of a subband +void wm_subband(Image s, double *w, int n, double a, double t1) { + int i; + + for (i = 0; i < s->width * s->height; i++) + if (fabs(s->data[i]) > t1) + s->data[i] += (a * fabs(s->data[i]) * w[i % n]); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int i, c; + int row; + + int n; + + double alpha = 0.0; + double t1 = 0.0; + + int level = 0; + int filter = 0; + int method = -1; + char filter_name[MAXPATHLEN] = ""; + + int verbose = 0; + + gray **image; + Image_tree dwts, s; + + gray maxval; + int rows, cols, format; + + double *watermark; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "a:e:f:F:h?l:o:s:t:v:")) != EOF) { + switch (c) { + case 'a': + alpha = atof(optarg); + if (alpha <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'l': + level = atoi(optarg); + if (level <= 0) { + fprintf(stderr, "%s: decomposition level %d out of range\n", progname, level); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 't': + t1 = atof(optarg); + if (t1 <= 0.0) { + fprintf(stderr, "%s: casting threshold %f out of range\n", progname, t1); + exit(1); + } + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "DGSG") >= 4) { + fscanf(sig, "%d\n", &n); + if (level == 0) + fscanf(sig, "%d\n", &level); + else + fscanf(sig, "%*d\n"); + if (alpha == 0.0) + fscanf(sig, "%lf\n", &alpha); + else + fscanf(sig, "%*f\n"); + if (t1 == 0.0) + fscanf(sig, "%lf\n", &t1); + else + fscanf(sig, "%*f\n"); + fscanf(sig, "%*f\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + watermark = malloc(n * sizeof(double)); + for (i = 0; i < n; i++) + fscanf(sig, "%lf\n", &watermark[i]); + fclose(sig); + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + + image = pgm_allocarray(cols, rows); + + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + + fclose(in); + + // wavelet transform + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + dwts = fdwt(image); + + // embed watermark in all subbands of a decomposition level + for (i = 0, s = dwts; i < 3; i++, s = s->coarse) { + wm_subband(s->horizontal->image, watermark, n, alpha, t1); + wm_subband(s->vertical->image, watermark, n, alpha, t1); + wm_subband(s->diagonal->image, watermark, n, alpha, t1); + } + + free(watermark); + + idwt(dwts, image); + + pgm_writepgminit(out, cols, rows, maxval, 0); + + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, image[row], cols, maxval, 0); + + fclose(out); + + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_frid2_d.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_frid2_d.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,212 @@ +#include "wm.h" +#include "dct.h" +#include "netpbm/pgm.h" +#include "signature.h" +#include "frid2_common.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-h] [-b n] [-n n] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor low freq. embedding strength\n"); + fprintf(stderr, "\t-b n\t\tbeta factor for weighted correlation (default 0)\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-n n\t\tnormalisation factor (default 1024.0)\n"); + fprintf(stderr, "\t-o file\t\tfile for extracted watermark information\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int c; + int row, col; + double normalization = 1024.0; + int seed, format; + + double alpha = 0.0; + double beta = 0.0; + + double correlation; + + gray **image; + double **coeffs; + + double mean, derivation, mult_factor; + int rows, cols; + + gray maxval; + int verbose = 0; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init2(); + + while ((c = getopt(argc, argv, "a:b:n:h?s:o:v:")) != EOF) { + switch (c) { + case 'a': + alpha = atof(optarg); + if (alpha <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 'b': + beta = atof(optarg); + if (beta <= 0.0) { + fprintf(stderr, "%s: beta factor %f out of range\n", progname, beta); + exit(1); + } + break; + case 'n': + normalization = atof(optarg); + if (normalization < 0) { + fprintf(stderr, "%s: normalisation factor %f out of range\n", progname, normalization); + exit(1); + } + break; + case 'h': + case '?': + usage(); + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "FR2SG") >= 5) { + fscanf(sig, "%d\n", &nbit_signature1); + if (alpha == 0.0) + fscanf(sig, "%lf\n", &alpha); + else + fscanf(sig, "%*f\n"); + fscanf(sig, "%*f\n"); + fscanf(sig, "%d\n", &seed); + n_signature1 = NBITSTOBYTES(nbit_signature1); + fread(signature1, sizeof(char), n_signature1, sig); + fscanf(sig, "\n"); + srandom(seed); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + image = pgm_allocarray(cols, rows); + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + fclose(in); + + // calculate mean malue + mean = 0.0; + for (row = 0; row < rows; row++) + for (col = 0; col < cols; col++) + mean += image[row][col]; + + mean /= cols * rows; + + // calculate derivation + derivation = 0.0; + for (row = 0; row < rows; row++) + for (col = 0; col < cols; col++) + derivation += sqr(image[row][col] - mean); + + derivation = sqrt(derivation / (cols * rows - 1)); + mult_factor = normalization / (sqrt(cols * rows) * derivation); + + if (verbose > 5) + fprintf(stderr, "%s: mean %f, derivation %f, mult_factor %f\n", progname, mean, derivation, mult_factor); + + // normalize image + coeffs = alloc_coeffs(cols, rows); + for (row = 0; row < rows; row++) + for (col = 0; col < cols; col++) + coeffs[row][col] = (image[row][col] - mean) * mult_factor; + + if (rows == cols) { + init_dct_NxN(cols, rows); + fdct_inplace_NxN(coeffs); + } +// else { +// init_dct_NxM(cols, rows); +// fdct_NxM(coeffs); +// } + + + fprintf(out, "FR2WM\n"); + + fprintf(out, "%d\n", nbit_signature1); + correlation = detect_low_freq(coeffs, cols, rows, alpha, beta, verbose); + if (verbose > 2) + fprintf(stderr, "low_freq correlation: %f\n", correlation); + fwrite(signature2, sizeof(char), NBITSTOBYTES(nbit_signature1), out); + fprintf(out, "\n"); + + fprintf(out, "%d\n", nbit_signature1); + correlation = detect_med_freq(coeffs, cols, rows, seed, verbose); + if (verbose > 2) + fprintf(stderr, "med_freq correlation: %f\n", correlation); + fwrite(signature2, sizeof(char), NBITSTOBYTES(nbit_signature1), out); + fprintf(out, "\n"); + + fclose(out); + + free_coeffs(coeffs); + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_frid2_e.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_frid2_e.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,218 @@ +#include "wm.h" +#include "dct.h" +#include "netpbm/pgm.h" +#include "signature.h" +#include "frid2_common.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-g n] [-n n] [-h] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor low freq. embedding strength\n"); + fprintf(stderr, "\t-g n\t\tgamma factor med freq. embedding strength\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-n n\t\tnormalisation factor (default 1024.0)\n"); + fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int c; + int row, col; + double normalization = 1024.0; + int seed, format; + + double alpha = 0.0; + double gamma = 0.0; + + gray **image; + double **coeffs; + + double mean, derivation; + double mult_factor; + + int rows, cols; + int verbose = 0; + gray maxval; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "a:g:n:h?o:s:v:")) != EOF) { + switch (c) { + case 'a': + alpha = atof(optarg); + if (alpha <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 'g': + gamma = atof(optarg); + if (gamma <= 0.0) { + fprintf(stderr, "%s: gamma factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 'n': + normalization = atof(optarg); + if (normalization < 0) { + fprintf(stderr, "%s: normalisation factor %f out of range\n", progname, normalization); + exit(1); + } + break; + case 'h': + case '?': + usage(); + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "FR2SG") >= 5) { + fscanf(sig, "%d\n", &nbit_signature); + if (alpha == 0.0) + fscanf(sig, "%lf\n", &alpha); + else + fscanf(sig, "%*f\n"); + if (gamma == 0.0) + fscanf(sig, "%lf\n", &gamma); + else + fscanf(sig, "%*f\n"); + + fscanf(sig, "%d\n", &seed); + n_signature = NBITSTOBYTES(nbit_signature); + fread(signature, sizeof(char), n_signature, sig); + fscanf(sig, "\n"); + srandom(seed); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + + if (rows == cols) + init_dct_NxN(cols, rows); + else + init_dct_NxM(cols, rows); + + image = pgm_allocarray(cols, rows); + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + fclose(in); + + // calculate mean value + mean = 0.0; + for (row = 0; row < rows; row++) + for (col = 0; col < cols; col++) + mean += image[row][col]; + + mean /= cols * rows; + + // calculate derivation + derivation = 0.0; + for (row = 0; row < rows; row++) + for (col = 0; col < cols; col++) + derivation += sqr(image[row][col] - mean); + + derivation = sqrt(derivation / (cols * rows - 1)); + mult_factor = normalization / (sqrt(cols * rows) * derivation); + + if (verbose > 5) + fprintf(stderr, "%s: mean %f, derivation %f, mult_factor %f\n", progname, mean, derivation, mult_factor); + + // normalize image + coeffs = alloc_coeffs(cols, rows); + for (row = 0; row < rows; row++) + for (col = 0; col < cols; col++) + coeffs[row][col] = (image[row][col] - mean) * mult_factor; + + if (cols == rows) + fdct_inplace_NxN(coeffs); +// else +// fdct_NxM(image, dcts); + + embed_low_freq(coeffs, cols, rows, alpha, verbose); + embed_med_freq(coeffs, cols, rows, gamma, seed, verbose); + + if (cols == rows) + idct_inplace_NxN(coeffs); +// else +// idct_NxM(dcts, image); + + for (row = 0; row < rows; row++) + for (col = 0; col < cols; col++) + image[row][col] = PIXELRANGE(coeffs[row][col] / mult_factor + mean + 0.5); + + free_coeffs(coeffs); + + pgm_writepgminit(out, cols, rows, maxval, 0); + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, image[row], cols, maxval, 0); + + fclose(out); + + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_kim_a.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_kim_a.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,292 @@ +#include "wm.h" +#include "wm_dwt.h" +#include "pgm.h" +#include "dwt_util.h" +#include "kim_common.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-A n] [-e n] [-f n] [-F n] [-h] [-l n] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor/embedding strength for detail subbands\n"); + fprintf(stderr, "\t-a n\t\talpha factor/embedding strength for approximation subband\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-l n\t\tdecomposition level\n"); + fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int mark_subband(Image_tree s, int name, double alpha, double watermark[], double threshold, int w, int n, int verbose) { + int i, j; + double last = 0.0; + + for (i = 5; i < s->image->height-5; i++) + for (j = 5; j < s->image->width-5; j++) { + double coeff, newcoeff; + + coeff = get_pixel(s->image, i, j); + if (fabs(coeff) > threshold / 1.5 ) { + newcoeff = coeff - coeff * alpha * watermark[w++ % n]; + set_pixel(s->image, i, j, newcoeff); + + fprintf(stderr, "%s: (%d/%d) %f: %f -> %f; a=%f\n", progname, j, i, watermark[w % n], coeff, newcoeff, alpha); + w++; + } + } + + if (verbose > 5) + fprintf(stderr, "%s: watermarking %s%d, size %d x %d; embedded %d coeffs. total\n", + progname, subband_name(name), s->level, s->image->width, s->image->height, w); + + return w; +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int i, c, w; + int row, col; + + int n; + + double alpha_detail = 0.0; + double alpha_approx = 0.0; + int level = 0; + + int filter = 0; + int method = -1; + int levels; + char filter_name[MAXPATHLEN] = ""; + + int verbose = 0; + + gray **image; + Image_tree p, dwts; + + gray maxval; + int rows, cols, colors, format; + + double *watermark; + + progname = argv[0]; + + pgm_init(&argc, argv); + +#ifdef __EMX__ + _fsetmode(in, "b"); + _fsetmode(out, "b"); +#endif + + while ((c = getopt(argc, argv, "a:A:e:f:F:h?o:l:s:v:")) != EOF) { + switch (c) { + case 'a': + alpha_detail = atof(optarg); + if (alpha_detail <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha_detail); + exit(1); + } + break; + case 'A': + alpha_approx = atof(optarg); + if (alpha_approx <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha_approx); + exit(1); + } + break; + case 'l': + level = atoi(optarg); + if (level <= 0) { + fprintf(stderr, "%s: decomposition level %d out of range\n", progname, level); + exit(1); + } + break; + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "KISG") >= 4) { + fscanf(sig, "%d\n", &n); + if (alpha_detail == 0.0) + fscanf(sig, "%lf\n", &alpha_detail); + else + fscanf(sig, "%*f\n"); + if (alpha_approx == 0.0) + fscanf(sig, "%lf\n", &alpha_approx); + else + fscanf(sig, "%*f\n"); + if (level == 0) + fscanf(sig, "%d\n", &level); + else + fscanf(sig, "%*d\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + watermark = malloc(n * sizeof(double)); + for (i = 0; i < n; i++) + fscanf(sig, "%lf\n", &watermark[i]); + fclose(sig); + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + image = pgm_allocarray(cols, rows); + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + fclose(in); + + // complete decomposition + levels = find_deepest_level(cols, rows) - 1; + if (level > levels) { + fprintf(stderr, "%s: decomposition level %d not possible (max. %d), image size is %d x %d\n", progname, level, levels, cols, rows); + exit(1); + } + + // wavelet transform + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + dwts = fdwt(image); + + p = dwts; + w = 0; + + // process each decomposition level + while (p->coarse) { + int current_level; + double threshold; + double max_coeff; + double alpha; + + // get current decomposition level number + current_level = p->horizontal->level; + + // find largest absolute coefficient in detail subbands of current decomposition level + max_coeff = find_level_largest_coeff(p, verbose); + + // calculate significance threshold for current decomposition level + threshold = calc_level_threshold(max_coeff, verbose); + + // calculate embedding strength alpha for current decomposition level + alpha = calc_level_alpha_detail(alpha_detail, level, current_level, verbose); + + if (verbose > 1) + fprintf(stderr, "%s: level %d, threshold %f, alpha %f\n", progname, current_level, threshold, alpha); + + // embed watermark sequence into detail subbands of current decomposition level + w = mark_subband(p->horizontal, HORIZONTAL, alpha, watermark, threshold, w, n, verbose); + w = mark_subband(p->vertical, VERTICAL, alpha, watermark, threshold, w, n, verbose); + w = mark_subband(p->diagonal, DIAGONAL, alpha, watermark, threshold, w, n, verbose); + + p = p->coarse; + } + + // mark approximation image using calculated significance threshold and embedding strength + w = mark_subband(p, COARSE, alpha_approx, watermark, calc_level_threshold(find_subband_largest_coeff(p, COARSE, verbose), verbose), w, n, verbose); + + free(watermark); + idwt(dwts, image); + + pgm_writepgminit(out, cols, rows, maxval, 0); + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, image[row], cols, maxval, 0); + fclose(out); + + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_kim_d.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_kim_d.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,326 @@ +#include "wm.h" +#include "dwt.h" +#include "netpbm/pgm.h" +#include "dwt_util.h" +#include "kim_common.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-A n] [-e n] [-f n] [-F file] [-h] [-l n] [-o file] [-v n] -s file -i file file\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor for detail subband\n"); + fprintf(stderr, "\t-A n\t\talpha factor for approximation image\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-i file\t\toriginal image file\n"); + fprintf(stderr, "\t-l n\t\tdecomposition level\n"); + fprintf(stderr, "\t-o file\t\tfile for extracted watermark\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int extract_subband(Image_tree s, Image_tree t, int name, double alpha, double watermark[], double threshold, int w, int n, int verbose) { + int i, j; + + for (i = 5; i < s->image->height-5; i++) + for (j = 5; j < s->image->width-5; j++) { + double orig_coeff, input_coeff; + + orig_coeff = get_pixel(s->image, i, j); + input_coeff = get_pixel(t->image, i, j); + if (fabs(orig_coeff) > threshold) { + watermark[w++] = (input_coeff - orig_coeff) / (alpha * orig_coeff); + } + } + + if (verbose > 5) + fprintf(stderr, "%s: extracted %s%d, size %d x %d; %d coeffs. total\n", + progname, subband_name(name), s->level, s->image->width, s->image->height, w); + + return w; +} + +void write_mark(FILE *out, double watermark[], int n) { + int i; + + fprintf(out, "%d\n", n); + for (i = 0; i < n; i++) + fprintf(out, "%f\n", watermark[i]); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *orig = NULL; + FILE *sig = NULL; + + gray **input_image; + gray **orig_image; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char orig_name[MAXPATHLEN]; + + int c, w; + int n = 0; + int method = -1; + int filter = 0; + char filter_name[MAXPATHLEN] = ""; + + int level = 0, levels; + double alpha_detail = 0.0; + double alpha_approx = 0.0; + + int in_rows, in_cols, in_format; + gray in_maxval; + int orig_rows, orig_cols, orig_format; + gray orig_maxval; + int rows, cols; + int row; + + double *watermark; + + Image_tree input_dwts, orig_dwts, p, q; + + int verbose = 0; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init2(); + + while ((c = getopt(argc, argv, "a:A:e:f:F:h?i:l:o:s:v:")) != EOF) { + switch (c) { + case 'a': + alpha_detail = atof(optarg); + if (alpha_detail <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha_detail); + exit(1); + } + break; + case 'A': + alpha_approx = atof(optarg); + if (alpha_approx <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha_approx); + exit(1); + } + break; + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'i': + if ((orig = fopen(optarg, "rb")) == NULL) { + fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); + exit(1); + } + strcpy(orig_name, optarg); + break; + case 'l': + level = atoi(optarg); + if (level <= 0) { + fprintf(stderr, "%s: decomposition level %d out of range\n", progname, level); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (!orig) { + fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); + exit(1); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "KISG") >= 4) { + fscanf(sig, "%d\n", &n); + if (alpha_detail == 0.0) + fscanf(sig, "%lf\n", &alpha_detail); + else + fscanf(sig, "%*f\n"); + if (alpha_approx == 0.0) + fscanf(sig, "%lf\n", &alpha_approx); + else + fscanf(sig, "%*f\n"); + if (level == 0) + fscanf(sig, "%d\n", &level); + else + fscanf(sig, "%*d\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); + pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); + + if (in_cols != orig_cols || in_rows != orig_rows) { + fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); + exit(1); + } + + cols = in_cols; + rows = in_rows; + + input_image = pgm_allocarray(in_cols, in_rows); + orig_image = pgm_allocarray(orig_cols, orig_rows); + + for (row = 0; row < in_rows; row++) { + pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); + pgm_readpgmrow(orig, orig_image[row], orig_cols, orig_maxval, orig_format); + } + + fclose(in); + fclose(orig); + + // complete decomposition + levels = find_deepest_level(cols, rows) - 1; + if (level > levels) { + fprintf(stderr, "%s: decomposition level %d not possible (max. %d), image size is %d x %d\n", progname, level, levels, cols, rows); + exit(1); + } + + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + input_dwts = fdwt(input_image); + orig_dwts = fdwt(orig_image); + + watermark = malloc((rows * cols) * sizeof(double)); + if (!watermark) { + fprintf(stderr, "%s: malloc() failed\n\n", progname); + exit(1); + } + + p = input_dwts; + q = orig_dwts; + w = 0; + while (p->coarse && q->coarse) { + int current_level; + double threshold; + double max_coeff; + double alpha; + + // get current decomposition level number + current_level = q->horizontal->level; + + // find largest absolute coefficient in detail subbands of current decomposition level + max_coeff = find_level_largest_coeff(q, verbose); + + // calculate significance threshold for current decomposition level + threshold = calc_level_threshold(max_coeff, verbose); + + // calculate embedding strength alpha for current decomposition level + alpha = calc_level_alpha_detail(alpha_detail, level, current_level, verbose); + + if (verbose > 1) + fprintf(stderr, "%s: level %d, threshold %f, alpha %f\n", progname, current_level, threshold, alpha); + + w = extract_subband(q->horizontal, p->horizontal, HORIZONTAL, alpha, watermark, threshold, w, n, verbose); + w = extract_subband(q->vertical, p->vertical, VERTICAL, alpha, watermark, threshold, w, n, verbose); + w = extract_subband(q->diagonal, p->diagonal, DIAGONAL, alpha, watermark, threshold, w, n, verbose); + + p = p->coarse; + q = q->coarse; + } + + // extract watermark from approximation image using calculated significance threshold and embedding strength + w = extract_subband(q, p, COARSE, alpha_approx, watermark, calc_level_threshold(find_subband_largest_coeff(q, COARSE, verbose), verbose), w, n, verbose); + + fprintf(out, "KIWM\n"); + write_mark(out, watermark, w); + + fclose(out); + + free(watermark); + + pgm_freearray(input_image, rows); + pgm_freearray(orig_image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_kim_e.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_kim_e.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,289 @@ +#include "wm.h" +#include "dwt.h" +#include "netpbm/pgm.h" +#include "dwt_util.h" +#include "kim_common.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-A n] [-e n] [-f n] [-F n] [-h] [-l n] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor/embedding strength for detail subbands\n"); + fprintf(stderr, "\t-a n\t\talpha factor/embedding strength for approximation subband\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-l n\t\tdecomposition level\n"); + fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int mark_subband(Image_tree s, int name, double alpha, double watermark[], double threshold, int w, int n, int verbose) { + int i, j; + + for (i = 5; i < s->image->height-5; i++) + for (j = 5; j < s->image->width-5; j++) { + double coeff, newcoeff; + + coeff = get_pixel(s->image, i, j); + if (fabs(coeff) > threshold) { + newcoeff = coeff + alpha * coeff * watermark[w % n]; + set_pixel(s->image, i, j, newcoeff); + + if (verbose >= 9) + fprintf(stderr, "%s: (%d/%d) %f: %f -> %f\n", progname, j, i, watermark[w % n], coeff, newcoeff); + + w++; + } + } + + if (verbose > 5) + fprintf(stderr, "%s: watermarking %s%d, size %d x %d; embedded %d coeffs. total\n", + progname, subband_name(name), s->level, s->image->width, s->image->height, w); + + return w; +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int i, c, w; + int row; + + int n; + + double alpha_detail = 0.0; + double alpha_approx = 0.0; + int level = 0; + + int filter = 0; + int method = -1; + int levels; + char filter_name[MAXPATHLEN] = ""; + + int verbose = 0; + + gray **image; + Image_tree p, dwts; + + gray maxval; + int rows, cols, format; + + double *watermark; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "a:A:e:f:F:h?o:l:s:v:")) != EOF) { + switch (c) { + case 'a': + alpha_detail = atof(optarg); + if (alpha_detail <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha_detail); + exit(1); + } + break; + case 'A': + alpha_approx = atof(optarg); + if (alpha_approx <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha_approx); + exit(1); + } + break; + case 'l': + level = atoi(optarg); + if (level <= 0) { + fprintf(stderr, "%s: decomposition level %d out of range\n", progname, level); + exit(1); + } + break; + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "KISG") >= 4) { + fscanf(sig, "%d\n", &n); + if (alpha_detail == 0.0) + fscanf(sig, "%lf\n", &alpha_detail); + else + fscanf(sig, "%*f\n"); + if (alpha_approx == 0.0) + fscanf(sig, "%lf\n", &alpha_approx); + else + fscanf(sig, "%*f\n"); + if (level == 0) + fscanf(sig, "%d\n", &level); + else + fscanf(sig, "%*d\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + watermark = malloc(n * sizeof(double)); + for (i = 0; i < n; i++) + fscanf(sig, "%lf\n", &watermark[i]); + fclose(sig); + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + image = pgm_allocarray(cols, rows); + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + fclose(in); + + // complete decomposition + levels = find_deepest_level(cols, rows) - 1; + if (level > levels) { + fprintf(stderr, "%s: decomposition level %d not possible (max. %d), image size is %d x %d\n", progname, level, levels, cols, rows); + exit(1); + } + + // wavelet transform + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + dwts = fdwt(image); + + p = dwts; + w = 0; + + // process each decomposition level + while (p->coarse) { + int current_level; + double threshold; + double max_coeff; + double alpha; + + // get current decomposition level number + current_level = p->horizontal->level; + + // find largest absolute coefficient in detail subbands of current decomposition level + max_coeff = find_level_largest_coeff(p, verbose); + + // calculate significance threshold for current decomposition level + threshold = calc_level_threshold(max_coeff, verbose); + + // calculate embedding strength alpha for current decomposition level + alpha = calc_level_alpha_detail(alpha_detail, level, current_level, verbose); + + if (verbose > 1) + fprintf(stderr, "%s: level %d, threshold %f, alpha %f\n", progname, current_level, threshold, alpha); + + // embed watermark sequence into detail subbands of current decomposition level + w = mark_subband(p->horizontal, HORIZONTAL, alpha, watermark, threshold, w, n, verbose); + w = mark_subband(p->vertical, VERTICAL, alpha, watermark, threshold, w, n, verbose); + w = mark_subband(p->diagonal, DIAGONAL, alpha, watermark, threshold, w, n, verbose); + + p = p->coarse; + } + + // mark approximation image using calculated significance threshold and embedding strength + w = mark_subband(p, COARSE, alpha_approx, watermark, calc_level_threshold(find_subband_largest_coeff(p, COARSE, verbose), verbose), w, n, verbose); + + free(watermark); + idwt(dwts, image); + + pgm_writepgminit(out, cols, rows, maxval, 0); + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, image[row], cols, maxval, 0); + fclose(out); + + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_koch_d.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_koch_d.1 Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,114 @@ +.\" +.\" wm_koch_d.1 - the *roff document processor man page source +.\" +.TH wm_koch_d 1 "98/07/05" "Watermarking, Version 1.0" +.SH NAME +.B wm_koch_d +\- a program to extract signature bits that have been embedded into +the DCT coefficients of an image +.SH SYNOPSIS +.B wm_koch_d +[ +.B \-h +] +[ +.BI \-o \ ofile +] +[ +.BI \-q \ number +] +[ +.BI \-v \ number +] +.BI \-s \ sfile +.IR file +.SH DESCRIPTION +.B wm_koch_d +is a program to extract signature bits from the 8x8 DCT coefficients of +an image, embedded with the +.B wm_koch_e +watermarking program. +.B cmp_koch_sig +program compares and tests the extracted signature against the original signature. +.PP +The input image is in PGM (portable graymap) format. +.PP +If +.I file +or +.I ofile +is not specified, then standard input or standard output is +used. The signature +.I sfile +is a mandatory parameter however. +.PP +Please refer to E. Koch's paper "Towards Robust and Hidden +Image Copyright", 1995, to get an idea about the algorithm. +.PP +.SH OPTIONS +.TP +.B \-h +Print a help message. +.TP +.BI \-o \ ofile +Output the extracted signature to +.I ofile +instead of standard output. +.TP +.BI \-q \ number +Quality/robustness factor used to extract the signature. +Overrides setting from signature file. +.TP +.BI \-s \ sfile +The original signature file. See +.B gen_koch_sig +(1) for a description of the file format. Mandatory parameter. +.BI \-v \ number +Verbosity level. 0 for quiet operation, higher numbers for more +output. Default value: 0. +.TP +.IR file +Signed (watermarked) input image in PGM format. Default: standard input. +.PP +.SH OUTPUT +The extracted signature is written to standard output +or, optionally, to +.I ofile. +.PP +The extraction algorithm examines the relationship between two random +coefficients of randomly selected 8x8 DCT blocks to reconstruct the +signature bits. +.PP +The output file has the following format: +.TP +.B KCSG +Magic to identify file type. +.TP +.I number +The length of the signature in bits. +.TP +.I number +The quality/robustness factor. +.TP +.I number +The seed value for the pseudo-random number generator. +.TP +.I string +The actual signature bytes. +.PP +.SH AUTHOR +Peter Meerwald. +Email bug reports to pmeerw@cosy.sbg.ac.at. +.SH AVAILABILITY +The most recent released version of +.B wm_koch_d +is always available +at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the +directory /pub/people/pmeerw/Watermarking. +.SH "SEE ALSO" +.BR gen_koch_sig +(1), +.BR wm_koch_e +(1), +.BR cmp_koch_sig +(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_koch_d.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_koch_d.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,234 @@ +#include "wm.h" +#include "dct.h" +#include "signature.h" +#include "coord.h" +#include "netpbm/pgm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-h] [-l n] [-o file] [-q n] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-l n\t\tsignature robustness factor\n"); + fprintf(stderr, "\t-o file\t\textracted signature file\n"); + fprintf(stderr, "\t-q n\t\tquantization (JPEG quality) factor\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + gray **image; + struct coords *coords; + + char signature_name[MAXPATHLEN]; + char input_name[MAXPATHLEN] = "(stdin)"; + char output_name[MAXPATHLEN] = "(stdout)"; + + int c; + int n; + + int rows, cols, format; + gray maxval; + int row; + + int seed; + int verbose = 0; + + double quality = 0.0; + int quantization = 0; + + double **dcts; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "h?i:l:o:q:s:v:")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'l': + quality = atof(optarg); + if (quality <= 0.0) { + fprintf(stderr, "%s: signature strength factor %f out of range\n", progname, quality); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'q': + quantization = atoi(optarg); + if (quantization <= 0 || quantization > 100) { + fprintf(stderr, "%s: quantization factor %d out of range\n", progname, quantization); + exit(1); + } + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[128]; + fgets(line, sizeof(line), sig); + if (strspn(line, "KCSG") >= 4) { + fscanf(sig, "%d\n", &nbit_signature); + n_signature = NBITSTOBYTES(nbit_signature); + if (quality == 0.0) + fscanf(sig, "%lf\n", &quality); + else + fscanf(sig, "%*f\n"); + if (quantization == 0) + fscanf(sig, "%d\n", &quantization); + else + fscanf(sig, "%*d\n"); + fscanf(sig, "%d\n", &seed); + srandom(seed); + fread(signature, sizeof(char), n_signature, sig); + init_signature_bits(); + fscanf(sig, "\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + + if (cols % NJPEG) { + fprintf(stderr, "%s: image width %d not a multiple of %d\n", progname, cols, NJPEG); + exit(1); + } + + if (rows % NJPEG) { + fprintf(stderr, "%s: image height %d not a multiple of %d\n", progname, rows, NJPEG); + exit(1); + } + + if ((rows * cols) / (NJPEG * NJPEG) < nbit_signature) { + fprintf(stderr, "%s: image too small to extract %d bits of signature\n", progname, nbit_signature); + exit(1); + } + + init_dct_8x8(); + init_quantum_JPEG_lumin(quantization); + + dcts = alloc_coeffs_8x8(); + + if ((coords = alloc_coords(nbit_signature)) == NULL) { + fprintf(stderr, "%s: unable to allocate memory\n", progname); + exit(1); + } + + image = pgm_allocarray(cols, rows); + + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + + fclose(in); + + n = 0; + while (n < nbit_signature) { + int xb; + int yb; + int c1, c2; + double v1, v2; + + do { + xb = random() % (cols / NJPEG); + yb = random() % (rows / NJPEG); + } while (add_coord(coords, xb, yb) < 0); + + fdct_block_8x8(image, xb * NJPEG, yb * NJPEG, dcts); + + do { + c1 = (random() % (NJPEG * NJPEG - 2)) + 1; + c2 = (random() % (NJPEG * NJPEG - 2)) + 1; + } while (c1 == c2 || !is_middle_frequency_coeff_8x8(c1) || !is_middle_frequency_coeff_8x8(c2)); + + quantize_8x8(dcts); + + if (verbose >= 1) + fprintf(stderr, "%d: quantized DCT block (x %d/y %d), extracting (x %d/y %d), (x %d/y %d) ", n, xb * NJPEG, yb * NJPEG, c1 % NJPEG, c1 / NJPEG, c2 % NJPEG, c2 / NJPEG); + + v1 = dcts[c1 / NJPEG][c1 % NJPEG]; + v2 = dcts[c2 / NJPEG][c2 % NJPEG]; + + if (fabs(v1) > fabs(v2)) { + set_signature_bit(n, 1); + if (verbose >= 1) + fprintf(stderr, "HIGH\n"); + } + else { + set_signature_bit(n, 0); + if (verbose >= 1) + fprintf(stderr, "LOW\n"); + } + + if (verbose >= 2) + print_coeffs_8x8(dcts); + + n++; + } + + fprintf(out, "KCWM\n"); + fprintf(out, "%d\n", nbit_signature); + fwrite(signature, sizeof(char), n_signature, out); + fprintf(out, "\n"); + + fclose(out); + + free_coeffs(dcts); + + pbm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_koch_e.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_koch_e.1 Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,98 @@ +.\" +.\" wm_koch_e.1 - the *roff document processor man page source +.\" +.TH wm_koch_e 1 "98/07/05" "Watermarking, Version 1.0" +.SH NAME +.B wm_koch_e +\- a program to embed signature bits in the DCT coefficients of an image +.SH SYNOPSIS +.B wm_koch_e +[ +.B \-h +] +[ +.BI \-o \ ofile +] +[ +.BI \-q \ number +] +[ +.BI \-v \ number +] +.BI \-s \ sfile +.IR file +.SH DESCRIPTION +.B wm_koch_e +is a program to embed signature bits in 8x8 DCT coefficients of +an image. The signature has to be generated by the +.B gen_koch_sig +program. The +.B wm_koch_d +program is used to extract a signature from a signed (watermarked) image. The +.B cmp_koch_sig +program compares and tests the extracted signature against the original signature. +.PP +Both, input and output image, +are in PGM (portable graymap) format. +.PP +If +.I file +or +.I ofile +is not specified, then standard input or standard output is +used. The signature +.I sfile +is a mandatory parameter however. +.PP +Please refer to E. Koch's paper "Towards Robust and Hidden +Image Copyright", 1995, to get an idea about the algorithm. +.PP +.SH OPTIONS +.TP +.B \-h +Print a help message. +.TP +.BI \-o \ ofile +Output signed (watermarked) image to +.I ofile +instead of standard output. +.TP +.BI \-q \ number +Quality/robustness factor used to embed signature into image. +Overrides setting from signature file. +.TP +.BI \-s \ sfile +The signature file to embed into image. See +.B gen_koch_sig +(1) for a description of the file format. Mandatory parameter. +.TP +.BI \-v \ number +Verbosity level. 0 for quiet operation, higher numbers for more +output. Default value: 0. +.TP +.IR file +Input image in PGM format to sign (watermark). Default: standard input. +.PP +.SH OUTPUT +The signed (watermarked) image in PGM format is written to standard output +or, optionally, to +.I ofile. +.PP +Two coefficients of an 8x8 DCT block are selected at random to embed a +single signature bit. +.PP +.SH AUTHOR +Peter Meerwald. Email bug reports to pmeerw@cosy.sbg.ac.at. +.SH AVAILABILITY +The most recent released version of +.B wm_koch_e +is always available +at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the +directory /pub/people/pmeerw/Watermarking. +.SH "SEE ALSO" +.BR gen_koch_sig +(1), +.BR wm_koch_d +(1), +.BR cmp_koch_sig +(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_koch_e.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_koch_e.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,354 @@ +#include "wm.h" +#include "dct.h" +#include "signature.h" +#include "coord.h" +#include "gray.h" +#include "netpbm/pgm.h" + +char *progname; + +double sign(double x) { + if (x >= 0.0) return 1.0; + else return -1.0; +} + +double try_modif(gray **image_block, double **dcts, int c1, int c2, double w1, double w2) { + int i, j; + gray **altered_block; + double **altered_dcts; + double sum; + + altered_block = alloc_grays_8x8(); + altered_dcts = alloc_coeffs_8x8(); + + for (i = 0; i < 8; i++) { + memcpy(altered_dcts[i], dcts[i], sizeof(double) * 8); + } + + // put the changed coefficients back to black + altered_dcts[c1 / NJPEG][c1 % NJPEG] = w1; + altered_dcts[c2 / NJPEG][c2 % NJPEG] = w2; + + dequantize_8x8(altered_dcts); + + idct_block_8x8(altered_dcts, altered_block, 0, 0); + + // compute MSE + sum = 0.0; + for (i = 0; i < 8; i++) { + for (j = 0; j < 8; j++) { + double ib = image_block[i][j]; + double ab = altered_block[i][j]; + sum += (ib - ab) * (ib - ab); + } + } + sum /= 64.0; + + free(altered_block); + free(altered_dcts); + + return sum; +} + +void usage(void) { + fprintf(stderr, "usage: %s [-h] [-l n] [-o file] [-q n] [-v n] -s file file\n", progname); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-l n\t\tsignature robustness factor\n"); + fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); + fprintf(stderr, "\t-q n\t\tquantization (JPEG quality) factor\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char signature_name[MAXPATHLEN]; + char input_name[MAXPATHLEN] = "(stdin)"; + char output_name[MAXPATHLEN] = "(stdout)"; + + int c; + int n; + + int seed; + int verbose = 0; + + int rows, cols, format; + gray maxval; + int row; + + int quantization = 0; + double quality = 0.0; + + struct coords *coords; + + gray **image; + double **dcts; + gray **image_block; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "h?i:l:o:q:s:v:")) != EOF) { + switch (c) { + case 'h': + case '?': + usage(); + break; + case 'l': + quality = atof(optarg); + if (quality <= 0.0) { + fprintf(stderr, "%s: signature strength factor %f out of range\n", progname, quality); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'q': + quantization = atoi(optarg); + if (quantization <= 0 || quantization > 100) { + fprintf(stderr, "%s: quantization factor %d out of range\n", progname, quantization); + exit(1); + } + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[128]; + fgets(line, sizeof(line), sig); + if (strspn(line, "KCSG") >= 4) { + fscanf(sig, "%d\n", &nbit_signature); + if (quality == 0.0) + fscanf(sig, "%lf\n", &quality); + else + fscanf(sig, "%*f\n"); + if (quantization == 0) + fscanf(sig, "%d\n", &quantization); + else + fscanf(sig, "%*d\n"); + fscanf(sig, "%d\n", &seed); + n_signature = NBITSTOBYTES(nbit_signature); + fread(signature, sizeof(char), n_signature, sig); + fscanf(sig, "\n"); + srandom(seed); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + + if (cols % NJPEG) { + fprintf(stderr, "%s: image width %d not a multiple of %d\n", progname, cols, NJPEG); + exit(1); + } + + if (rows % NJPEG) { + fprintf(stderr, "%s: image height %d not a multiple of %d\n", progname, rows, NJPEG); + exit(1); + } + + if ((cols * rows) / (NJPEG * NJPEG) < nbit_signature) { + fprintf(stderr, "%s: image not large enough to embed %d bits of signature\n", progname, nbit_signature); + exit(1); + } + + init_dct_8x8(); + init_quantum_JPEG_lumin(quantization); + + dcts = alloc_coeffs_8x8(); + image_block = alloc_grays_8x8(); + + if ((coords = alloc_coords(nbit_signature)) == NULL) { + fprintf(stderr, "%s: unable to allocate memory\n", progname); + exit(1); + } + + image = pgm_allocarray(cols, rows); + + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + + fclose(in); + + // embedding signature bits by modifying two coefficient relationship, + // one bit for each block + n = 0; + while (n < nbit_signature) { + int xb; + int yb; + int c1, c2; + double v1, v2; + double w1, w2; + double best_w1, best_w2; + double diff; + double mod; + double try; + double best_mse; + int no_mse_opt = 0; + + // randomly select a block, check to get distinct blocks + // (don't watermark a block twice) + do { + xb = random() % (cols / NJPEG); + yb = random() % (rows / NJPEG); + } while (add_coord(coords, xb, yb) < 0); + + // do the forward 8x8 DCT of that block + fdct_block_8x8(image, xb * NJPEG, yb * NJPEG, dcts); + + copy_grays_to_block(image_block, image, xb*NJPEG, yb*NJPEG, NJPEG, NJPEG); + + // randomly select two distinct coefficients from block + // only accept coefficients in the middle frequency range + do { + c1 = (random() % (NJPEG * NJPEG - 2)) + 1; + c2 = (random() % (NJPEG * NJPEG - 2)) + 1; + } while (c1 == c2 || !is_middle_frequency_coeff_8x8(c1) || !is_middle_frequency_coeff_8x8(c2)); + + // quantize block according to quantization quality parameter + quantize_8x8(dcts); + + if (verbose > 0) + fprintf(stderr, "%d: quantized DCT block (x %d/y %d), modifying (x %d/y %d), (x %d/y %d) for %s\n", n, xb * NJPEG, yb * NJPEG, c1 % NJPEG, c1 / NJPEG, c2 % NJPEG, c2 / NJPEG, get_signature_bit(n) ? "HIGH" : "LOW"); + if (verbose > 5) + print_coeffs_8x8(dcts); + + v1 = dcts[c1 / NJPEG][c1 % NJPEG]; + v2 = dcts[c2 / NJPEG][c2 % NJPEG]; + + best_w1 = DBL_MAX, best_w2 = DBL_MAX; + try = 0.0; + best_mse = DBL_MAX; + + diff = fabs(v1) - fabs(v2); + + if (get_signature_bit(n)) + mod = fabs(quality - ( fabs(v1) - fabs(v2) )); + else + mod = fabs(quality - (fabs(v2) - fabs(v1))); + + if (verbose > 2) + fprintf(stderr, "%d / %d: %.2f %.2f %.2f | %d\n", xb, yb, diff, v1, v2, get_signature_bit(n)); + + while (try <= mod) { + w1 = v1; + w2 = v2; + + // modify coefficient's relationship to embed signature bit + // using mean square error to minimize error + if (get_signature_bit(n)) { + if (diff < quality) { + // we have to impose the relationship, does not occur naturally + w1 = sign(v1)*(fabs(v1) + mod - try); + w2 = sign(v2)*(fabs(v2) - try); + } + } + else { + if (diff > -quality) { + // force the relationship + w2 = sign(v2)*(fabs(v2) + mod - try); + w1 = sign(v1)*(fabs(v1) - try); + } + } + + double mse = try_modif(image_block, dcts, c1, c2, w1, w2); + if (mse < best_mse) { + best_w1 = w1; + best_w2 = w2; + best_mse = mse; + } + + if (verbose > 2) + fprintf(stderr, "%d / %d: MSE %.2f %.2f; %.2f: %.2f %.2f\n", xb, yb, mse, best_mse, try, w1, w2); + + if (fabs(mse) == 1e-3) + break; + + if (fabs(fabs(w1) - fabs(w2) + quality) > 1e-3) + break; + + if (no_mse_opt) + break; + + try += 0.05; + } + + if (verbose > 1) + fprintf(stderr, " %f -> %f, %f -> %f\n", v1, best_w1, v2, best_w2); + + // put the changed coefficients back to black + dcts[c1 / NJPEG][c1 % NJPEG] = best_w1; + dcts[c2 / NJPEG][c2 % NJPEG] = best_w2; + + // the obvious :-) + dequantize_8x8(dcts); + + // do the inverse DCT on the modified 8x8 block + idct_block_8x8(dcts, image, xb * NJPEG, yb * NJPEG); + + n++; + } + + free_grays(image_block); + free_coeffs(dcts); + + pgm_writepgminit(out, cols, rows, maxval, 0); + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, image[row], cols, maxval, 0); + + fclose(out); + + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_kund2_d.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_kund2_d.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,315 @@ +#include "wm.h" +#include "signature.h" +#include "dwt.h" +#include "netpbm/pgm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-e n] [-f n] [-F n] [-h] [-l n] [-o file] [-q n] [-s file] [-v n] file\n\n", progname); + fprintf(stderr, "\t-a n\t\toverall embedding strength\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-l n\t\tembedding level\n"); + fprintf(stderr, "\t-o file\t\textracted signature file\n"); + fprintf(stderr, "\t-q n\t\tsignature strength\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + gray **input_image; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + + int r, c; + int quality = 0; + int blocksize = 0; + int seed = 0; + int n = 0; + int method = -1; + int filter = 0; + char filter_name[MAXPATHLEN] = ""; + char *binstr; + + int level = 0; + double alpha = 0.0; + + int in_rows, in_cols, in_format; + gray in_maxval; + int rows, cols; + int row, col; + + Image_tree dwts, p; + + int verbose = 0; + + progname = argv[0]; + + pgm_init(&argc, argv); + wm_init(); + + while ((c = getopt(argc, argv, "a:e:f:F:h?l:o:q:s:v:")) != EOF) { + switch (c) { + case 'a': + alpha = atof(optarg); + break; + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'l': + level = atoi(optarg); + if (level < 1) { + fprintf(stderr, "%s: embedding level out of range\n", progname); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'q': + quality = atoi(optarg); + if (quality < 1) { + fprintf(stderr, "%s: quality level %d out of range\n", progname, quality); + exit(1); + } + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[1024]; + fgets(line, sizeof(line), sig); + if (strspn(line, "KD2SG") >= 5) { + fscanf(sig, "%d\n", &nbit_signature); + if (quality == 0) + fscanf(sig, "%d\n", &quality); + else + fscanf(sig, "%*d\n"); + if (blocksize == 0) + fscanf(sig, "%d\n", &blocksize); + else + fscanf(sig, "%*d\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + if (level == 0) + fscanf(sig, "%d\n", &level); + else + fscanf(sig, "%*d\n"); + fscanf(sig, "%d\n", &seed); + srandom(seed); + nbit_signature2 = nbit_signature; + n_signature = n_signature2 = NBITSTOBYTES(nbit_signature2); + binstr = malloc((nbit_signature2 + 1) * sizeof(char)); + fscanf(sig, "%[01]\n", binstr); + binstr_to_sig2(binstr); + free(binstr); + init_signature_bits(); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); + + cols = in_cols; + rows = in_rows; + + if (verbose > 0) + fprintf(stderr, "%s: extracting %d bits with quality %d from\n" + " %d x %d host image, decomposition level %d\n", + progname, nbit_signature, quality, cols, rows, level); + + input_image = pgm_allocarray(in_cols, in_rows); + + for (row = 0; row < in_rows; row++) + pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); + + fclose(in); + + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + fprintf(out, "KD2WM\n"); + fprintf(out, "%d\n", nbit_signature); + + dwts = fdwt(input_image); + + + p = dwts; + + // consider each resolution level + while (p->coarse->level < level) { + int lwidth = p->vertical->image->width; + int lheight = p->vertical->image->height; + int bx, by; + + for (bx = 0; bx < lwidth; bx += blocksize) { + for (by = 0; by < lheight; by += blocksize) { + int bw = MIN(bx + blocksize, lwidth); + int bh = MIN(by + blocksize, lheight); + int STEP; + + // start to extracting watermark from beginning at each level + // get width and height of detail images at current level + + if (verbose > 1) + fprintf(stderr, "%s: extracting at level %d now, size %d x %d\n", + progname, p->coarse->level, lwidth, lheight); + + STEP = ROUND(alpha * (-15.555) + 10.777); + n = 0; + // consider each coefficient at resolution level + for (row = by; row < bh - STEP; row += STEP) + for (col = bx; col < bw - STEP; col += STEP) { + double h, v, d; + double *f1 = &h, *f2 = &v, *f3 = &d; + double delta; + + // key-dependant coefficient selection + r = row + 1 + random() % (STEP-2); + c = col + 1 + random() % (STEP-2); + + // get coefficient values, one from each detail image + h = get_pixel(p->horizontal->image, c, r); + v = get_pixel(p->vertical->image, c, r); + d = get_pixel(p->diagonal->image, c, r); + + // order pointer to coefficient values such that f1 <= f2 <= f3 +#define SWAP(A, B) {double *t = A; A = B; B = t;} + if (*f1 > *f2) SWAP(f1, f2); + if (*f2 > *f3) SWAP(f2, f3); + if (*f1 > *f2) SWAP(f1, f2); + + // calculate delta, the width of the bins + delta = (*f3 - *f1) / (double) (2 * quality - 1); + + // set middle coefficient to closest appropriate bin, + // according to watermark bit + if (quality == 1) + set_signature_bit(n, (*f3 - *f2) < (*f2 - *f1)); + else { + double l = *f1; + int i = 0; + while ((l + delta) < *f2) { + l += delta; + i++; + } + if (i % 2) + set_signature_bit(n, (l + delta - *f2) > (*f2 - l)); + else + set_signature_bit(n, (l + delta - *f2) < (*f2 - l)); + } + + if (verbose > 2) + fprintf(stderr, "%s: extracted bit #%d (= %d =? %d) at (%d/%d),\n" + " f1=%lf, f2=%lf, f3=%lf\n", progname, n, + get_signature_bit(n), get_signature2_bit(n), + c, r, *f1, *f2, *f3); + n++; + } + + nbit_signature = n; + binstr = malloc(sizeof(char) * (nbit_signature + 1)); + sig_to_binstr(binstr); + fprintf(out, "%d\n", nbit_signature); + fprintf(out, "%s\n", binstr); + free(binstr); + + } + } + // descend one level + p = p->coarse; + } + + fclose(out); + + pgm_freearray(input_image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_kund2_e.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_kund2_e.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,331 @@ +#include "wm.h" +#include "signature.h" +#include "dwt.h" +#include "netpbm/pgm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-e n] [-f n] [-F n] [-h] [-l n] [-o file] [-q n] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-a n\t\toverall embedding strength\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-l n\t\tembedding level\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); + fprintf(stderr, "\t-q n\t\tsignature strength (default 4)\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + char *binstr; + + int r, c, n; + int row, col; + + int quality = 0; + int blocksize = 0; + int filter = 0; + int method = -1; + int level = 0; + char filter_name[MAXPATHLEN] = ""; + + double alpha = 0.0; + int seed; + int verbose = 0; + + gray **image; + Image_tree dwts, p; + + gray maxval; + int rows, cols, format; + + progname = argv[0]; + + pgm_init(&argc, argv); + wm_init(); + + while ((c = getopt(argc, argv, "a:e:f:F:h?l:o:q:s:v:")) != EOF) { + switch (c) { + case 'a': + alpha = atof(optarg); + break; + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'l': + level = atoi(optarg); + if (level < 1) { + fprintf(stderr, "%s: embedding level out of range\n", progname); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'q': + quality = atoi(optarg); + if (quality < 1) { + fprintf(stderr, "%s: quality factor %d out of range\n", progname, quality); + exit(1); + } + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[1024]; + fgets(line, sizeof(line), sig); + if (strspn(line, "KD2SG") >= 5) { + fscanf(sig, "%d\n", &nbit_signature); + if (quality == 0) + fscanf(sig, "%d\n", &quality); + else + fscanf(sig, "%*d\n"); + if (blocksize == 0) + fscanf(sig, "%d\n", &blocksize); + else + fscanf(sig, "%*d\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + if (level == 0) + fscanf(sig, "%d\n", &level); + else + fscanf(sig, "%*d\n"); + fscanf(sig, "%d\n", &seed); + srandom(seed); + n_signature = NBITSTOBYTES(nbit_signature); + binstr = malloc((nbit_signature + 1) * sizeof(char)); + fscanf(sig, "%[01]\n", binstr); + binstr_to_sig(binstr); + free(binstr); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + + if (verbose > 0) + fprintf(stderr, "%s: embedding %d bits with quality %d in\n" + " %d x %d host image, up to decomposition level %d\n", + progname, nbit_signature, quality, cols, rows, level); + + image = pgm_allocarray(cols, rows); + + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + + fclose(in); + + // decomposition of image + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + dwts = fdwt(image); + + p = dwts; + + // consider each resolution level + while (p->coarse->level < level) { + int lwidth = p->vertical->image->width; + int lheight = p->vertical->image->height; + int l = p->vertical->level; + int bx, by; + int nblock; + int bits_per_level; + + nblock = 0; + bits_per_level = 0; + for (bx = 0; bx < lwidth; bx += blocksize) { + for (by = 0; by < lheight; by += blocksize) { + int bw = MIN(bx + blocksize, lwidth); + int bh = MIN(by + blocksize, lheight); + int STEP; + float MIN_DIFF; + + // start to embed signature from beginning at each level + // get width and height of detail images at current level + + + if (verbose > 1) + fprintf(stderr, "%s: embedding at level %d now, block %d, size %d x %d at %d, %d\n", + progname, l, nblock, bw, bh, bx, by); + + MIN_DIFF = ROUND(120.0 * alpha); + STEP = ROUND(alpha * (-15.555) + 10.777); +// fprintf(stderr, "XXX %d %f\n", STEP, MIN_DIFF); + + n = 0; + // consider each coefficient at resolution level + for (row = by; row < bh - STEP; row += STEP) + for (col = bx; col < bw - STEP; col += STEP) { + double h, v, d; + double *f1 = &h, *f2 = &v, *f3 = &d; + double delta; + + // key-dependant coefficient selection + r = row + 1+random() % (STEP-2); + c = col + 1+random() % (STEP-2); + + // get coefficient values, one from each detail image + h = get_pixel(p->horizontal->image, c, r); + v = get_pixel(p->vertical->image, c, r); + d = get_pixel(p->diagonal->image, c, r); + + // order pointer to coefficient values such that f1 <= f2 <= f3 +#define SWAP(A, B) {double *t = A; A = B; B = t;} + if (*f1 > *f2) SWAP(f1, f2); + if (*f2 > *f3) SWAP(f2, f3); + if (*f1 > *f2) SWAP(f1, f2); + + if (verbose > 2) + fprintf(stderr, "%s: embedding bit #%d (= %d) at (%d/%d),\n", + progname, n, get_signature_bit(n % nbit_signature), c, r); + if (verbose > 5) + fprintf(stderr, " h=%lf, v=%lf, d=%lf\n", h, v, d); + if (verbose > 2) + fprintf(stderr, " f1=%lf, f2=%lf", *f1, *f2); + + if ((*f3 - *f1) < MIN_DIFF) { + double adj = (MIN_DIFF - (*f3 - *f1)) / 2.0; + *f1 -= adj; + *f3 += adj; + } + + // calculate delta, the width of the bins + delta = (*f3 - *f1) / (double) (2 * quality - 1); + + // set middle coefficient to closest appropriate bin, + // according to watermark bit + bits_per_level++; + if (quality == 1) + *f2 = get_signature_bit(n % nbit_signature) ? *f3 : *f1; + else { + double l = get_signature_bit(n % nbit_signature) ? *f1 + delta : *f1; + while ((l + 2 * delta) < *f2) l += 2 * delta; + *f2 = (*f2 - l) < (l + 2 * delta - *f2) ? l : l + 2 * delta; + } + + if (verbose > 2) + fprintf(stderr, " -> %lf, f3=%lf\n", *f2, *f3); + + // write pixels, one of them modified + set_pixel(p->horizontal->image, c, r, h); + set_pixel(p->vertical->image, c, r, v); + set_pixel(p->diagonal->image, c, r, d); + + n++; + + } + } + } + + if (verbose > 1) + fprintf(stderr, "%s: embedded %d bits at level %d\n", + progname, bits_per_level, l); + + // descend one level + p = p->coarse; + } + + idwt(dwts, image); + + pgm_writepgminit(out, cols, rows, maxval, 0); + + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, image[row], cols, maxval, 0); + + fclose(out); + + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_kund3_d.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_kund3_d.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,293 @@ +#include "wm.h" +#include "signature.h" +#include "dwt.h" +#include "netpbm/pgm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-e n] [-f n] [-F n] [-h] [-l n] [-o file] [-q n] [-s file] [-v n] file\n\n", progname); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-l n\t\tembedding level\n"); + fprintf(stderr, "\t-o file\t\textracted signature file\n"); + fprintf(stderr, "\t-q n\t\tsignature strength\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + gray **input_image; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + + int r, c; + int quality = 0; + int seed = 0; + int n = 0; + int method = -1; + int filter = 0; + char filter_name[MAXPATHLEN] = ""; + + char *binstr; + + int level = 0; + + int in_rows, in_cols, in_format; + gray in_maxval; + int rows, cols; + int row, col; + + Image_tree dwts, p; + + int verbose = 0; + + progname = argv[0]; + + pgm_init(&argc, argv); + wm_init(); + + while ((c = getopt(argc, argv, "e:f:F:h?l:o:q:s:v:")) != EOF) { + switch (c) { + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'l': + level = atoi(optarg); + if (level < 1) { + fprintf(stderr, "%s: embedding level out of range\n", progname); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'q': + quality = atoi(optarg); + if (quality < 1) { + fprintf(stderr, "%s: quality level %d out of range\n", progname, quality); + exit(1); + } + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "KD3SG") >= 5) { + fscanf(sig, "%d\n", &nbit_signature); + if (quality == 0) + fscanf(sig, "%d\n", &quality); + else + fscanf(sig, "%*d\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + if (level == 0) + fscanf(sig, "%d\n", &level); + else + fscanf(sig, "%*d\n"); + fscanf(sig, "%d\n", &seed); + srandom(seed); + nbit_signature2 = nbit_signature; + n_signature = n_signature2 = NBITSTOBYTES(nbit_signature2); + binstr = malloc((nbit_signature2 + 1) * sizeof(char)); + fscanf(sig, "%[01]\n", binstr); + binstr_to_sig2(binstr); + free(binstr); + init_signature_bits(); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); + + cols = in_cols; + rows = in_rows; + + if (verbose > 0) + fprintf(stderr, "%s: extracting %d bits with quality %d from\n" + " %d x %d host image, decomposition level %d\n", + progname, nbit_signature, quality, cols, rows, level); + + input_image = pgm_allocarray(in_cols, in_rows); + + for (row = 0; row < in_rows; row++) + pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); + + fclose(in); + + init_dwt(cols, rows, filter_name, filter, level, method); +/*#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif*/ + + dwts = fdwt(input_image); + + p = dwts; + +#define STEP 3 + + // consider each resolution level + while (p->coarse->level < level) + // descend one level + p = p->coarse; + + // start to extracting watermark from beginning at each level + { + // get width and height of detail images at current level + int lwidth = p->vertical->image->width; + int lheight = p->vertical->image->height; + + if (verbose > 1) + fprintf(stderr, "%s: extracting at level %d now, size %d x %d\n", + progname, p->coarse->level, lwidth, lheight); + + // consider each coefficient at resolution level + for (row = 0; row < lwidth - STEP; row += STEP) + for (col = 0; col < lheight - STEP; col += STEP) { + double h, v, d; + double *f1 = &h, *f2 = &v, *f3 = &d; + double delta; + + // key-dependant coefficient selection + r = row + 1 + random() % (STEP-2); + c = col + 1 + random() % (STEP-2); + + // get coefficient values, one from each detail image + h = get_pixel(p->horizontal->image, c, r); + v = get_pixel(p->vertical->image, c, r); + d = get_pixel(p->diagonal->image, c, r); + + // order pointer to coefficient values such that f1 <= f2 <= f3 +#define SWAP(A, B) {double *t = A; A = B; B = t;} + if (*f1 > *f2) SWAP(f1, f2); + if (*f2 > *f3) SWAP(f2, f3); + if (*f1 > *f2) SWAP(f1, f2); + + // calculate delta, the width of the bins + delta = (*f3 - *f1) / (double) (2 * quality - 1); + + // set middle coefficient to closest appropriate bin, + // according to watermark bit + if (quality == 1) + set_signature_bit(n, (*f3 - *f2) < (*f2 - *f1)); + else { + double l = *f1; + int i = 0; + while ((l + delta) < *f2) { + l += delta; + i++; + } + if (i % 2) + set_signature_bit(n, (l + delta - *f2) > (*f2 - l)); + else + set_signature_bit(n, (l + delta - *f2) < (*f2 - l)); + } + + if (verbose > 2) + fprintf(stderr, "%s: extracted bit #%d (= %d =? %d) at (%d/%d),\n" + " f1=%lf, f2=%lf, f3=%lf\n", progname, n, + get_signature_bit(n), get_signature2_bit(n), + c, r, *f1, *f2, *f3); + n++; + } + } + + fprintf(out, "KD3WM\n"); + fprintf(out, "%d\n", n); + nbit_signature = n; + binstr = malloc(sizeof(char) * (nbit_signature + 1)); + sig_to_binstr(binstr); + fprintf(out, "%s\n", binstr); + free(binstr); + fclose(out); + + pgm_freearray(input_image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_kund3_e.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_kund3_e.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,299 @@ +#include "wm.h" +#include "signature.h" +#include "dwt.h" +#include "netpbm/pgm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-e n] [-f n] [-F n] [-h] [-l n] [-o file] [-q n] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-l n\t\tembedding level\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); + fprintf(stderr, "\t-q n\t\tsignature strength (default 4)\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + char *binstr; + + int r, c, n; + int row, col; + + int quality = 0; + + int filter = 0; + int method = -1; + int level = 0; + char filter_name[MAXPATHLEN] = ""; + + int seed; + int verbose = 0; + + gray **image; + Image_tree dwts, p; + + gray maxval; + int rows, cols, format; + + progname = argv[0]; + + pgm_init(&argc, argv); + wm_init(); + + while ((c = getopt(argc, argv, "e:f:F:h?l:o:q:s:v:")) != EOF) { + switch (c) { + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'l': + level = atoi(optarg); + if (level < 1) { + fprintf(stderr, "%s: embedding level out of range\n", progname); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'q': + quality = atoi(optarg); + if (quality < 1) { + fprintf(stderr, "%s: quality factor %d out of range\n", progname, quality); + exit(1); + } + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "KD3SG") >= 5) { + fscanf(sig, "%d\n", &nbit_signature); + if (quality == 0) + fscanf(sig, "%d\n", &quality); + else + fscanf(sig, "%*d\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + if (level == 0) + fscanf(sig, "%d\n", &level); + else + fscanf(sig, "%*d\n"); + fscanf(sig, "%d\n", &seed); + srandom(seed); + n_signature = NBITSTOBYTES(nbit_signature); + binstr = malloc((nbit_signature + 1) * sizeof(char)); + fscanf(sig, "%[01]\n", binstr); + binstr_to_sig(binstr); + free(binstr); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + + if (verbose > 0) + fprintf(stderr, "%s: embedding %d bits with quality %d in\n" + " %d x %d host image, decomposition level %d\n", + progname, nbit_signature, quality, cols, rows, level); + + image = pgm_allocarray(cols, rows); + + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + + fclose(in); + + // decomposition of image + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + dwts = fdwt(image); + + p = dwts; + + // consider each resolution level + while (p->coarse->level < level) + // descend one level + p = p->coarse; + + // start to embed signature from beginning at each level + // get width and height of detail images at current level + { + int lwidth = p->vertical->image->width; + int lheight = p->vertical->image->height; + + if (verbose > 1) + fprintf(stderr, "%s: embedding at level %d now, size %d x %d\n", progname, + p->coarse->level, lwidth, lheight); + +#define STEP 3 + n = 0; + // consider each coefficient at resolution level + for (row = 0; row < lwidth - STEP; row += STEP) + for (col = 0; col < lheight - STEP; col += STEP) { + double h, v, d; + double *f1 = &h, *f2 = &v, *f3 = &d; + double delta; + + // key-dependant coefficient selection + r = row + 1+random() % (STEP-2); + c = col + 1+random() % (STEP-2); + + // get coefficient values, one from each detail image + h = get_pixel(p->horizontal->image, c, r); + v = get_pixel(p->vertical->image, c, r); + d = get_pixel(p->diagonal->image, c, r); + + // order pointer to coefficient values such that f1 <= f2 <= f3 +#define SWAP(A, B) {double *t = A; A = B; B = t;} + if (*f1 > *f2) SWAP(f1, f2); + if (*f2 > *f3) SWAP(f2, f3); + if (*f1 > *f2) SWAP(f1, f2); + + if (verbose > 2) + fprintf(stderr, "%s: embedding bit #%d (= %d) at (%d/%d),\n", + progname, n, get_signature_bit(n % nbit_signature), c, r); + if (verbose > 5) + fprintf(stderr, " h=%lf, v=%lf, d=%lf\n", h, v, d); + if (verbose > 2) + fprintf(stderr, " f1=%lf, f2=%lf", *f1, *f2); + +#define MIN_DIFF 20.0 + if (*f3 - *f1 < MIN_DIFF) { + double adj = (MIN_DIFF - (*f3 - *f1)) / 2.0; + *f1 -= adj; + *f3 += adj; + } + + // calculate delta, the width of the bins + delta = (*f3 - *f1) / (double) (2 * quality - 1); + + // set middle coefficient to closest appropriate bin, + // according to watermark bit + if (quality == 1) + *f2 = get_signature_bit(n % nbit_signature) ? *f3 : *f1; + else { + double l = get_signature_bit(n % nbit_signature) ? *f1 + delta : *f1; + while ((l + 2 * delta) < *f2) l += 2 * delta; + *f2 = (*f2 - l) < (l + 2 * delta - *f2) ? l : l + 2 * delta; + } + + if (verbose > 2) + fprintf(stderr, " -> %lf, f3=%lf\n", *f2, *f3); + + // write pixels, one of them modified + set_pixel(p->horizontal->image, c, r, h); + set_pixel(p->vertical->image, c, r, v); + set_pixel(p->diagonal->image, c, r, d); + + n++; + + } + } + + idwt(dwts, image); + + pgm_writepgminit(out, cols, rows, maxval, 0); + + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, image[row], cols, maxval, 0); + + fclose(out); + + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_kund_d.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_kund_d.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,2 @@ +int main(int argc, char *argv[]) { +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_kund_e.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_kund_e.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,257 @@ +#include "wm.h" +#include "signature.h" +#include "wm_dwt.h" +#include "pgm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-e n] [-f n] [-F n] [-h] [-o file] [-q n] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); + fprintf(stderr, "\t-q n\t\tquantization/quality factor\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int c; + int row, col; + + int n; + + double quality = 0.0; + + int filter = 0; + int method = -1; + int level = 0; + char filter_name[MAXPATHLEN] = ""; + + int seed; + int verbose = 0; + + gray **image; + Image_tree dwts; + + gray maxval; + int rows, cols, colors, format; + + progname = argv[0]; + + pgm_init(&argc, argv); + +#ifdef __EMX__ + _fsetmode(in, "b"); + _fsetmode(out, "b"); +#endif + + while ((c = getopt(argc, argv, "e:f:F:h?l:o:q:s:v:")) != EOF) { + switch (c) { + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'l': + level = atoi(optarg); + if (level < 1) { + fprintf(stderr, "%s: embedding level out of range\n", progname); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'q': + quality = atoi(optarg); + if (quality <= 0) { + fprintf(stderr, "%s: quality factor %d out of range\n", progname, quality); + exit(1); + } + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "KDSG") >= 4) { + fscanf(sig, "%d\n", &n); + if (quality == 0.0) + fscanf(sig, "%lf\n", &quality); + else + fscanf(sig, "%*f\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + if (level == 0) + fscanf(sig, "%d\n", &level); + else + fscanf(sig, "%*d\n"); + fscanf(sig, "%d\n", &seed); + srandom(seed); + n_signature = NBITSTOBYTES(nbit_signature); + fread(signature, sizeof(char), n_signature, sig); + fscanf(sig, "\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + + image = pgm_allocarray(cols, rows); + + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + + fclose(in); + + // check watermark dimensions and decomposition level + + + // decomposition of image + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF + { + double alpha, beta; + char *alpha_str = getenv("POLLEN_ALPHA"), *beta_str = getenv("POLLEN_BETA"); + + if (alpha_str && beta_str) { + alpha = atof(alpha_str); + beta = atof(beta_str); + + if (alpha < -M_PI || alpha >= M_PI) { + fprintf(stderr, "%s: pollen - alpha %f out of range\n", progname, alpha); + exit(1); + } + + if (beta < -M_PI || beta >= M_PI) { + fprintf(stderr, "%s: pollen - beta %f out of range\n", progname, beta); + exit(1); + } + + if (verbose > 7) + fprintf(stderr, "%s: pollen - alpha %f, beta %f\n", progname, alpha, beta); + + dwt_pollen_filter(alpha, beta); + } + } +#endif + + dwts = fdwt(image); + + // create 'image' from binary watermark + + // decomposition of watermark + init_dwt(cols, rows, filter_name, filter, 1, method); +// dwts = fdwt(watermark); + + // calculate mean value of image and set alpha + + // setup of contrast sensitivity matrix + + // segment detail images at each level + + // calculate DFT of each segment + + // compute salience for each segment + + // calculate gamma or each detail image + + // embed watermark + + // reconstruction of watermarked image + + idwt(dwts, image); + + pgm_writepgminit(out, cols, rows, maxval, 0); + + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, image[row], cols, maxval, 0); + + fclose(out); + + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_wang_d.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_wang_d.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,302 @@ +#include "wm.h" +#include "dwt.h" +#include "wang_common.h" +#include "dwt_util.h" +#include "netpbm/pgm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-b n] [-e n] [-f n] [-F file] [-h] [-n n] [-o file] [-v n] -s file -i file file\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor\n"); + fprintf(stderr, "\t-b n\t\tbeta factor\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-i file\t\toriginal image file\n"); + fprintf(stderr, "\t-n n\t\twatermark length\n"); + fprintf(stderr, "\t-o file\t\tfile for extracted watermark\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *orig = NULL; + FILE *sig = NULL; + + gray **input_image; + gray **orig_image; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char orig_name[MAXPATHLEN]; + + int c, w; + int n = 0; + int method = -1; + int filter = 0; + char filter_name[MAXPATHLEN] = ""; + + int level = 0; + double alpha = 0.0; + double beta = 0.0; + + int in_rows, in_cols, in_format; + gray in_maxval; + int orig_rows, orig_cols, orig_format; + gray orig_maxval; + int rows, cols; + int row; + + double *watermark; + + Image_tree input_dwts; + Image_tree orig_dwts; + + int verbose = 0; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init2(); + + while ((c = getopt(argc, argv, "a:b:e:f:F:h?i:n:o:s:v:")) != EOF) { + switch (c) { + case 'a': + alpha = atof(optarg); + if (alpha <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 'b': + beta = atof(optarg); + if (beta <= 0.0) { + fprintf(stderr, "%s: beta factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'i': + if ((orig = fopen(optarg, "rb")) == NULL) { + fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); + exit(1); + } + strcpy(orig_name, optarg); + break; + case 'n': + n = atoi(optarg); + if (n < 1 || n > 32000) { + fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (!orig) { + fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); + exit(1); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "WGSG") >= 4) { + fscanf(sig, "%d\n", &n); + if (alpha == 0.0) + fscanf(sig, "%lf\n", &alpha); + else + fscanf(sig, "%*f\n"); + if (beta == 0.0) + fscanf(sig, "%lf\n", &beta); + else + fscanf(sig, "%*f\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + watermark = malloc(n * sizeof(double)); + + pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); + pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); + + if (in_cols != orig_cols || in_rows != orig_rows) { + fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); + exit(1); + } + + cols = in_cols; + rows = in_rows; + + input_image = pgm_allocarray(in_cols, in_rows); + + orig_image = pgm_allocarray(orig_cols, orig_rows); + + for (row = 0; row < in_rows; row++) { + pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); + pgm_readpgmrow(orig, orig_image[row], orig_cols, orig_maxval, orig_format); + } + + fclose(in); + fclose(orig); + + // complete decomposition + level = find_deepest_level(cols, rows) - 1; + + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + input_dwts = fdwt(input_image); + orig_dwts = fdwt(orig_image); + + // build tree for subband selection, calculate subband thresholds + init_subbands(orig_dwts); + set_subbands_type_beta(HORIZONTAL, beta); + set_subbands_type_beta(VERTICAL, beta); + calc_subbands_threshold(); + + fprintf(out, "WGWM\n"); + fprintf(out, "%d\n", n); + + w = 0; + while (w < n) { + Subband_data s; + + // select subband with max. threshold + s = select_subband(); + if (verbose > 1) + fprintf(stderr, "%s: selected subband %s%d, T=%lf, beta=%lf\n", progname, subband_name(s->type), s->level, s->T, s->beta); + + // watermark significant coefficients and set them selected + // check is entire signature has been embedded + c = select_subband_coeff(s); + do { + Pixel p; + Pixel q; + if (c < 0) + // no more significant coefficients in subband + break; + + p = get_subband_coeff(s, c); + if (p < s->Cmax) { + q = get_dwt_coeff(input_dwts, s->level, s->type, c); + watermark[w] = (q - p) / (alpha * s->beta * s->T); + fprintf(out, "%lf\n", watermark[w]); + + if (verbose > 2) + fprintf(stderr, "%s: detected sig. coeff. #%d (= %lf)\n from %s%d coeff. #%d\n", + progname, w, watermark[w], subband_name(s->type), s->level, c); + + w++; + } + mark_subband_coeff(s, c); + + // select next significant coefficient + c = select_subband_coeff_from(s, c); + } while (w < n); + + // update subband threshold + s->T /= 2.0; + + } + + fclose(out); + + free_subbands(); + + free(watermark); + + pgm_freearray(input_image, rows); + pgm_freearray(orig_image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_wang_e.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_wang_e.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,263 @@ +#include "wm.h" +#include "dwt.h" +#include "wang_common.h" +#include "dwt_util.h" +#include "netpbm/pgm.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-b n] [-e n] [-f n] [-F n] [-h] [-o file] [-v n] -s file file\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor/embedding strength\n"); + fprintf(stderr, "\t-b n\t\tsubband weighting factor\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int i, c, w; + int row; + + int n; + + double alpha = 0.0; + double beta = 0.0; + + int filter = 0; + int method = -1; + int level = 0; + char filter_name[MAXPATHLEN] = ""; + + int verbose = 0; + + gray **image; + Image_tree dwts; + + gray maxval; + int rows, cols, format; + + double *watermark; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "a:b:e:f:F:h?o:s:v:")) != EOF) { + switch (c) { + case 'a': + alpha = atof(optarg); + if (alpha <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 'b': + beta = atof(optarg); + if (beta <= 0.0) { + fprintf(stderr, "%s: beta factor %f out of range\n", progname, beta); + exit(1); + } + break; + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "WGSG") >= 4) { + fscanf(sig, "%d\n", &n); + if (alpha == 0.0) + fscanf(sig, "%lf\n", &alpha); + else + fscanf(sig, "%*f\n"); + if (beta == 0.0) + fscanf(sig, "%lf\n", &beta); + else + fscanf(sig, "%*f\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + watermark = malloc(n * sizeof(double)); + for (i = 0; i < n; i++) + fscanf(sig, "%lf\n", &watermark[i]); + fclose(sig); + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + + image = pgm_allocarray(cols, rows); + + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + + fclose(in); + + // complete decomposition + level = find_deepest_level(cols, rows) - 1; + + // wavelet transform + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + dwts = fdwt(image); + + // build tree for subband selection, calculate subband thresholds + init_subbands(dwts); + set_subbands_type_beta(HORIZONTAL, beta); + set_subbands_type_beta(VERTICAL, beta); + calc_subbands_threshold(); + + w = 0; + while (w < n) { + Subband_data s; + + // select subband with max. threshold + s = select_subband(); + if (verbose > 1) + fprintf(stderr, "%s: selected subband %s%d, T=%lf, beta=%lf\n", progname, subband_name(s->type), s->level, s->T, s->beta); + + // watermark significant coefficients and set them selected + // check is entire signature has been embedded + c = select_subband_coeff(s); + do { + double p; + if (c < 0) + // no more significant coefficients in subband + break; + + p = get_subband_coeff(s, c); + if (p < s->Cmax) { + if (verbose > 2) + fprintf(stderr, "%s: embedding sig. coeff. #%d (= %lf)\n into %s%d coeff. #%d\n", + progname, w, watermark[w], subband_name(s->type), s->level, c); + + p = p + alpha * s->beta * s->T * watermark[w]; + set_subband_coeff(s, c, p); + w++; + } + mark_subband_coeff(s, c); + + // select next significant coefficient + c = select_subband_coeff_from(s, c); + } while (w < n); + + // update subband threshold + s->T /= 2.0; + + } + + free_subbands(); + + free(watermark); + + idwt(dwts, image); + + pgm_writepgminit(out, cols, rows, maxval, 0); + + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, image[row], cols, maxval, 0); + + fclose(out); + + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_xia_d.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_xia_d.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,295 @@ +#include "wm.h" +#include "dwt.h" +#include "netpbm/pgm.h" +#include "dwt_util.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-e n] [-f n] [-F file] [-h] [-l n] [-o file] [-v n] -s file -i file file\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-i file\t\toriginal image file\n"); + fprintf(stderr, "\t-l n\t\tdecomposition level\n"); + fprintf(stderr, "\t-o file\t\tfile for extracted watermark\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int extract_subband(Image_tree s, Image_tree t, int name, double alpha, double watermark[], int n, int verbose) { + int i, j; + int w; + + w = 0; + for (i = 5; i < s->image->height-5; i++) + for (j = 5; j < s->image->width-5; j++) { + double input_coeff, orig_coeff; + + input_coeff = get_pixel(s->image, i, j); + orig_coeff = get_pixel(t->image, i, j); + if (fabs(orig_coeff) > 20.0) + watermark[w++] = (input_coeff - orig_coeff) / (alpha * pow(fabs(orig_coeff), 1.0 / 1.2)); + } + + if (verbose > 3) + fprintf(stderr, "%s: extracting %s%d, size %d x %d; extracted %d coeffs.\n", + progname, subband_name(name), s->level, s->image->width, s->image->height, w); + + return w; +} + +void write_mark(FILE *out, double watermark[], int n) { + int i; + + fprintf(out, "%d\n", n); + for (i = 0; i < n; i++) + fprintf(out, "%f\n", watermark[i]); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *orig = NULL; + FILE *sig = NULL; + + gray **input_image; + gray **orig_image; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char orig_name[MAXPATHLEN]; + + int c; + int n = 0; + int method = -1; + int filter = 0; + char filter_name[MAXPATHLEN] = ""; + + int level = 0, levels; + double alpha = 0.0; + + int in_rows, in_cols, in_format; + gray in_maxval; + int orig_rows, orig_cols, orig_format; + gray orig_maxval; + int rows, cols; + int row; + + double *watermark; + + Image_tree input_dwts, orig_dwts, p, q; + + int verbose = 0; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init2(); + + while ((c = getopt(argc, argv, "a:e:f:F:h?i:l:o:s:v:")) != EOF) { + switch (c) { + case 'a': + alpha = atof(optarg); + if (alpha <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'i': + if ((orig = fopen(optarg, "rb")) == NULL) { + fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); + exit(1); + } + strcpy(orig_name, optarg); + break; + case 'l': + level = atoi(optarg); + if (level <= 0) { + fprintf(stderr, "%s: decomposition level %d out of range\n", progname, level); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (!orig) { + fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); + exit(1); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "XASG") >= 4) { + fscanf(sig, "%d\n", &n); + if (alpha == 0.0) + fscanf(sig, "%lf\n", &alpha); + else + fscanf(sig, "%*f\n"); + if (level == 0) + fscanf(sig, "%d\n", &level); + else + fscanf(sig, "%*d\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); + pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); + + if (in_cols != orig_cols || in_rows != orig_rows) { + fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); + exit(1); + } + + cols = in_cols; + rows = in_rows; + + input_image = pgm_allocarray(in_cols, in_rows); + orig_image = pgm_allocarray(orig_cols, orig_rows); + + for (row = 0; row < in_rows; row++) { + pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); + pgm_readpgmrow(orig, orig_image[row], orig_cols, orig_maxval, orig_format); + } + + fclose(in); + fclose(orig); + + // complete decomposition + levels = find_deepest_level(cols, rows) - 1; + if (level > levels) { + fprintf(stderr, "%s: decomposition level %d not possible (max. %d), image size is %d x %d\n", progname, level, levels, cols, rows); + exit(1); + } + + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + input_dwts = fdwt(input_image); + orig_dwts = fdwt(orig_image); + + watermark = malloc((rows * cols / 4.0) * sizeof(double)); + if (!watermark) { + fprintf(stderr, "%s: malloc() failed\n\n", progname); + exit(1); + } + + fprintf(out, "XAWM\n"); + fprintf(out, "%d\n", n); + fprintf(out, "%d\n", level * 3); + + p = input_dwts; + q = orig_dwts; + while (p->coarse && q->coarse) { + int size; + + size = extract_subband(p->horizontal, q->horizontal, HORIZONTAL, alpha, watermark, n, verbose); + write_mark(out, watermark, size); + size = extract_subband(p->vertical, q->vertical, VERTICAL, alpha, watermark, n, verbose); + write_mark(out, watermark, size); + size = extract_subband(p->diagonal, q->diagonal, DIAGONAL, alpha, watermark, n, verbose); + write_mark(out, watermark, size); + + p = p->coarse; + q = q->coarse; + } + + fclose(out); + + free(watermark); + + pgm_freearray(input_image, rows); + pgm_freearray(orig_image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_xia_e.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_xia_e.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,244 @@ +#include "wm.h" +#include "dwt.h" +#include "netpbm/pgm.h" +#include "dwt_util.h" + +char *progname; + +void usage(void) { + 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); + fprintf(stderr, "\t-a n\t\talpha factor/embedding strength\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-l n\t\tdecomposition level\n"); + fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +void mark_subband(Image_tree s, int name, double alpha, double watermark[], int n, int verbose) { + int i, j; + int w; + + w = 0; + for (i = 5; i < s->image->height-5; i++) + for (j = 5; j < s->image->width-5; j++) { + double coeff, newcoeff; + + coeff = get_pixel(s->image, i, j); + if (fabs(coeff) > 20.0) { + newcoeff = coeff + alpha * pow(fabs(coeff), 1.2) * watermark[w++ % n]; + set_pixel(s->image, i, j, newcoeff); + } + } + + if (verbose > 3) + fprintf(stderr, "%s: watermarking %s%d, size %d x %d; embedded %d coeffs.\n", + progname, subband_name(name), s->level, s->image->width, s->image->height, w); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int i, c; + int row; + + int n; + + double alpha = 0.0; + int level = 0; + + int filter = 0; + int method = -1; + int levels; + char filter_name[MAXPATHLEN] = ""; + + int verbose = 0; + + gray **image; + Image_tree p, dwts; + + gray maxval; + int rows, cols, format; + + double *watermark; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "a:e:f:F:h?o:l:s:v:")) != EOF) { + switch (c) { + case 'a': + alpha = atof(optarg); + if (alpha <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 'l': + level = atoi(optarg); + if (level <= 0) { + fprintf(stderr, "%s: decomposition level %d out of range\n", progname, level); + exit(1); + } + break; + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "XASG") >= 4) { + fscanf(sig, "%d\n", &n); + if (alpha == 0.0) + fscanf(sig, "%lf\n", &alpha); + else + fscanf(sig, "%*f\n"); + if (level == 0) + fscanf(sig, "%d\n", &level); + else + fscanf(sig, "%*d\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + watermark = malloc(n * sizeof(double)); + for (i = 0; i < n; i++) + fscanf(sig, "%lf\n", &watermark[i]); + fclose(sig); + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + image = pgm_allocarray(cols, rows); + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + fclose(in); + + // complete decomposition + levels = find_deepest_level(cols, rows) - 1; + if (level > levels) { + fprintf(stderr, "%s: decomposition level %d not possible (max. %d), image size is %d x %d\n", progname, level, levels, cols, rows); + exit(1); + } + + // wavelet transform + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + dwts = fdwt(image); + + p = dwts; + while (p->coarse) { + + mark_subband(p->horizontal, HORIZONTAL, alpha, watermark, n, verbose); + mark_subband(p->vertical, VERTICAL, alpha, watermark, n, verbose); + mark_subband(p->diagonal, DIAGONAL, alpha, watermark, n, verbose); + + p = p->coarse; + } + + free(watermark); + idwt(dwts, image); + + pgm_writepgminit(out, cols, rows, maxval, 0); + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, image[row], cols, maxval, 0); + fclose(out); + + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_xie2_d.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_xie2_d.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,270 @@ +#include "wm.h" +#include "signature.h" +#include "dwt.h" +#include "netpbm/pgm.h" + +char *progname; + +// inverse watermarking transformation, extract embedded bit, check quantization boundaries +double wm_transform(int quant, double f1, double f2, double f3) { + double s = (fabs(f3) - fabs(f1)) / (double) quant; + double l = f1; + int x; + + x = 0; + while (l < f2) { + l += s; + x++; + } + + if (fabs(l - s - f2) < fabs(l-f2)) + return (x+1) % 2; + else + return (x) % 2; +} + +void usage(void) { + 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); + fprintf(stderr, "\t-a n\t\tembedding strength (default 0.05)\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-l n\t\tembedding level\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\textracted signature file\n"); + fprintf(stderr, "\t-q n\t\tquantization level\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int c, n; + int row, col; + + double alpha = 0.0; + int quant = 0; + int filter = 0; + int method = -1; + int level = 0; + char filter_name[MAXPATHLEN] = ""; + + int seed; + int verbose = 0; + + gray **image; + Image_tree dwts, p; + + gray maxval; + int rows, cols, format; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init2(); + + while ((c = getopt(argc, argv, "a:e:f:F:h?l:o:s:v:q:")) != EOF) { + switch (c) { + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'l': + level = atoi(optarg); + if (level < 1) { + fprintf(stderr, "%s: embedding level out of range\n", progname); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'q': + quant = atoi(optarg); + break; + case 'a': + alpha = atof(optarg); + if (alpha <= 0.0) { + fprintf(stderr, "%s: embedding strength factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "XE2SG") >= 5) { + fscanf(sig, "%d\n", &nbit_signature); + if (alpha == 0.0) + fscanf(sig, "%lf\n", &alpha); + else + fscanf(sig, "%*f\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + if (quant == 0) + fscanf(sig, "%d\n", &quant); + else + fscanf(sig, "%*d\n"); + if (level == 0) + fscanf(sig, "%d\n", &level); + else + fscanf(sig, "%*d\n"); + fscanf(sig, "%d\n", &seed); + srandom(seed); + n_signature = NBITSTOBYTES(nbit_signature); + fread(signature, sizeof(char), n_signature, sig); + fscanf(sig, "\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + if (verbose > 0) + fprintf(stderr, "%s: embedding %d bits with strength %d in\n" + " %d x %d host image, decomposition level %d\n", + progname, nbit_signature, quant, cols, rows, level); + + image = pgm_allocarray(cols, rows); + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + fclose(in); + + // decomposition of image + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + dwts = fdwt(image); + + p = dwts; + + // consider each resolution level + while (p->level < level) + // descend one level + p = p->coarse; + + // repeat binary watermark by sliding a 3-pixel window of approximation image + n = 0; + for (row = 0; row < p->image->height; row++) { + col = 0; + while (col < p->image->width - 3) { + double b1, b2, b3; + double *f1 = &b1, *f2 = &b2, *f3 = &b3; + + // get all three approximation pixels in window + b1 = get_pixel(p->image, col + 0, row); + b2 = get_pixel(p->image, col + 1, row); + b3 = get_pixel(p->image, col + 2, row); + + // bring selected pixels in ascending order +#define SWAP(A, B) {double *t = A; A = B; B = t;} + if (*f1 > *f2) SWAP(f1, f2); + if (*f2 > *f3) SWAP(f2, f3); + if (*f1 > *f2) SWAP(f1, f2); + + set_signature_bit(n, wm_transform(quant, *f1, *f2, *f3)); + + if (verbose > 1) + fprintf(stderr, "%s: extracting #%d (= %d) at (%d/%d); %f < %f < %f\n", + progname, n, get_signature_bit(n % nbit_signature), col, row, *f1, *f2, *f3); + + n++; + col += 3; + col += (2.0 / alpha); + } + } + + fprintf(out, "XE2WM\n"); + fprintf(out, "%d\n", n); + fwrite(signature, sizeof(char), NBITSTOBYTES(n), out); + fprintf(out, "\n"); + fclose(out); + + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_xie2_e.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_xie2_e.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,288 @@ +#include "wm.h" +#include "signature.h" +#include "dwt.h" +#include "netpbm/pgm.h" + +char *progname; + +// watermarking transformation, set median pixel to quantization boundary +double wm_transform(int quant, double f1, double f2, double f3, int x) { + double s = (fabs(f3) - fabs(f1)) / (double) quant; + double l = x ? (f1 + s) : f1; + double f2new; + + while ((l + 2 * s) < f2) l += 2 * s; + f2new = ((f2 - l) < (l + 2 * s - f2)) ? l : (l + 2 * s); + + return f2new; +} + +void usage(void) { + 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); + fprintf(stderr, "\t-a n\t\tembedding strength (default 0.05)\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-l n\t\tembedding level\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); + fprintf(stderr, "\t-q n\t\tquantization level\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int c, n; + int row, col; + + double alpha = 0.0; + int filter = 0; + int method = -1; + int level = 0; + int quant = 0; + char filter_name[MAXPATHLEN] = ""; + + int seed; + int verbose = 0; + + gray **image; + Image_tree dwts, p; + + gray maxval; + int rows, cols, format; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "a:e:f:F:h?l:o:s:v:")) != EOF) { + switch (c) { + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'l': + level = atoi(optarg); + if (level < 1) { + fprintf(stderr, "%s: embedding level out of range\n", progname); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'q': + quant = atoi(optarg); + break; + case 'a': + alpha = atof(optarg); + if (alpha <= 0.0) { + fprintf(stderr, "%s: embedding strength factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "XE2SG") >= 5) { + fscanf(sig, "%d\n", &nbit_signature); + if (alpha == 0.0) + fscanf(sig, "%lf\n", &alpha); + else + fscanf(sig, "%*f\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + if (quant == 0) + fscanf(sig, "%d\n", &quant); + else + fscanf(sig, "%*d\n"); + if (level == 0) + fscanf(sig, "%d\n", &level); + else + fscanf(sig, "%*d\n"); + fscanf(sig, "%d\n", &seed); + srandom(seed); + n_signature = NBITSTOBYTES(nbit_signature); + fread(signature, sizeof(char), n_signature, sig); + fscanf(sig, "\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + + if (verbose > 0) + fprintf(stderr, "%s: embedding %d bits with strength %d in\n" + " %d x %d host image, decomposition level %d\n", + progname, nbit_signature, quant, cols, rows, level); + + image = pgm_allocarray(cols, rows); + + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + + fclose(in); + + // decomposition of image + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + dwts = fdwt(image); + + p = dwts; + + // consider each resolution level + while (p->level < level) + // descend one level + p = p->coarse; + + // repeat binary watermark by sliding a 3-pixel window of approximation image + n = 0; + for (row = 0; row < p->image->height; row++) { + col = 0; + while (col < p->image->width - 3) { + double MIN_DIFF = (20.0 * alpha); + double b1, b2, b3; + double *f1 = &b1, *f2 = &b2, *f3 = &b3; + double f2new; + + // get all three approximation pixels in window + b1 = get_pixel(p->image, col + 0, row); + b2 = get_pixel(p->image, col + 1, row); + b3 = get_pixel(p->image, col + 2, row); + + // bring selected pixels in ascending order +#define SWAP(A, B) {double *t = A; A = B; B = t;} + if (*f1 > *f2) SWAP(f1, f2); + if (*f2 > *f3) SWAP(f2, f3); + if (*f1 > *f2) SWAP(f1, f2); + + if ((*f3 - *f1) < MIN_DIFF) { + double adj = (MIN_DIFF - (*f3 - *f1)) / 2.0; + *f1 -= adj; + *f3 += adj; + } + + // apply watermarking transformation (modify median pixel) + f2new = wm_transform(quant, *f1, *f2, *f3, get_signature_bit(n % nbit_signature)); + + if (verbose > 1) + fprintf(stderr, "%s: embedding #%d (= %d) at (%d/%d); %f < %f -> %f < %f\n", + progname, n, get_signature_bit(n % nbit_signature), col, row, *f1, *f2, f2new, *f3); + + *f2 = f2new; + + // write modified pixel + set_pixel(p->image, col + 0, row, b1); + set_pixel(p->image, col + 1, row, b2); + set_pixel(p->image, col + 2, row, b3); + n++; + col += 3; + col+= (2.0 / alpha); + } + } + + + // skip over some pixels + + idwt(dwts, image); + + pgm_writepgminit(out, cols, rows, maxval, 0); + + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, image[row], cols, maxval, 0); + + fclose(out); + + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_xie_d.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_xie_d.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,258 @@ +#include "wm.h" +#include "signature.h" +#include "dwt.h" +#include "netpbm/pgm.h" + +char *progname; + +// inverse watermarking transformation, extract embedded bit, check quantization boundaries +double wm_transform(double alpha, double f1, double f2, double f3) { + double s = alpha * (fabs(f3) - fabs(f1)) / 2.0; + double l = f1; + int x; + + x = 0; + while (l < f2) { + l += s; + x++; + } + + if (fabs(l - s - f2) < fabs(l-f2)) + return (x+1) % 2; + else + return (x) % 2; +} + +void usage(void) { + 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); + fprintf(stderr, "\t-a n\t\tembedding strength (default 0.05)\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-l n\t\tembedding level\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\textracted signature file\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int c, n; + int row, col; + + double alpha = 0.0; + int filter = 0; + int method = -1; + int level = 0; + char filter_name[MAXPATHLEN] = ""; + + int seed; + int verbose = 0; + + gray **image; + Image_tree dwts, p; + + gray maxval; + int rows, cols, format; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init2(); + + while ((c = getopt(argc, argv, "a:e:f:F:h?l:o:s:v:")) != EOF) { + switch (c) { + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'l': + level = atoi(optarg); + if (level < 1) { + fprintf(stderr, "%s: embedding level out of range\n", progname); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'a': + alpha = atof(optarg); + if (alpha <= 0.0) { + fprintf(stderr, "%s: embedding strength factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "XESG") >= 4) { + fscanf(sig, "%d\n", &nbit_signature); + if (alpha == 0.0) + fscanf(sig, "%lf\n", &alpha); + else + fscanf(sig, "%*f\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + if (level == 0) + fscanf(sig, "%d\n", &level); + else + fscanf(sig, "%*d\n"); + fscanf(sig, "%d\n", &seed); + srandom(seed); + n_signature = NBITSTOBYTES(nbit_signature); + fread(signature, sizeof(char), n_signature, sig); + fscanf(sig, "\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + if (verbose > 0) + fprintf(stderr, "%s: embedding %d bits with strength %f in\n" + " %d x %d host image, decomposition level %d\n", + progname, nbit_signature, alpha, cols, rows, level); + + image = pgm_allocarray(cols, rows); + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + fclose(in); + + // decomposition of image + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + dwts = fdwt(image); + + p = dwts; + + // consider each resolution level + while (p->level < level) + // descend one level + p = p->coarse; + + // repeat binary watermark by sliding a 3-pixel window of approximation image + n = 0; + for (row = 0; row < p->image->height; row++) { + for (col = 0; col < p->image->width - 3; col += 3) { + double b1, b2, b3; + double *f1 = &b1, *f2 = &b2, *f3 = &b3; + + // get all three approximation pixels in window + b1 = get_pixel(p->image, col + 0, row); + b2 = get_pixel(p->image, col + 1, row); + b3 = get_pixel(p->image, col + 2, row); + + // bring selected pixels in ascending order +#define SWAP(A, B) {double *t = A; A = B; B = t;} + if (*f1 > *f2) SWAP(f1, f2); + if (*f2 > *f3) SWAP(f2, f3); + if (*f1 > *f2) SWAP(f1, f2); + + set_signature_bit(n, wm_transform(alpha, *f1, *f2, *f3)); + + if (verbose > 1) + fprintf(stderr, "%s: extracting #%d (= %d) at (%d/%d); %f < %f < %f\n", + progname, n, get_signature_bit(n % nbit_signature), col, row, *f1, *f2, *f3); + + n++; + } + } + + fprintf(out, "XEWM\n"); + fprintf(out, "%d\n", n); + fwrite(signature, sizeof(char), NBITSTOBYTES(n), out); + fprintf(out, "\n"); + fclose(out); + + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_xie_e.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_xie_e.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,270 @@ +#include "wm.h" +#include "signature.h" +#include "dwt.h" +#include "netpbm/pgm.h" + +char *progname; + +// watermarking transformation, set median pixel to quantization boundary +double wm_transform(double alpha, double f1, double f2, double f3, int x) { + double s = alpha * (fabs(f3) - fabs(f1)) / 2.0; + double l = x ? (f1 + s) : f1; + double f2new; + + while ((l + 2 * s) < f2) l += 2 * s; + f2new = ((f2 - l) < (l + 2 * s - f2)) ? l : (l + 2 * s); + + return f2new; +} + +void usage(void) { + 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); + fprintf(stderr, "\t-a n\t\tembedding strength (default 0.05)\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-l n\t\tembedding level\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int c, n; + int row, col; + + double alpha = 0.0; + int filter = 0; + int method = -1; + int level = 0; + char filter_name[MAXPATHLEN] = ""; + + int seed; + int verbose = 0; + + gray **image; + Image_tree dwts, p; + + gray maxval; + int rows, cols, format; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "a:e:f:F:h?l:o:s:v:")) != EOF) { + switch (c) { + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'l': + level = atoi(optarg); + if (level < 1) { + fprintf(stderr, "%s: embedding level out of range\n", progname); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 'a': + alpha = atof(optarg); + if (alpha <= 0.0) { + fprintf(stderr, "%s: embedding strength factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "XESG") >= 4) { + fscanf(sig, "%d\n", &nbit_signature); + if (alpha == 0.0) + fscanf(sig, "%lf\n", &alpha); + else + fscanf(sig, "%*f\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + if (level == 0) + fscanf(sig, "%d\n", &level); + else + fscanf(sig, "%*d\n"); + fscanf(sig, "%d\n", &seed); + srandom(seed); + n_signature = NBITSTOBYTES(nbit_signature); + fread(signature, sizeof(char), n_signature, sig); + fscanf(sig, "\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + + if (verbose > 0) + fprintf(stderr, "%s: embedding %d bits with strength %f in\n" + " %d x %d host image, decomposition level %d\n", + progname, nbit_signature, alpha, cols, rows, level); + + image = pgm_allocarray(cols, rows); + + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + + fclose(in); + + // decomposition of image + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + dwts = fdwt(image); + + p = dwts; + + // consider each resolution level + while (p->level < level) + // descend one level + p = p->coarse; + + // repeat binary watermark by sliding a 3-pixel window of approximation image + n = 0; + for (row = 0; row < p->image->height; row++) { + for (col = 0; col < p->image->width - 3; col += 3) { + double b1, b2, b3; + double *f1 = &b1, *f2 = &b2, *f3 = &b3; + double f2new; + + // get all three approximation pixels in window + b1 = get_pixel(p->image, col + 0, row); + b2 = get_pixel(p->image, col + 1, row); + b3 = get_pixel(p->image, col + 2, row); + + // bring selected pixels in ascending order +#define SWAP(A, B) {double *t = A; A = B; B = t;} + if (*f1 > *f2) SWAP(f1, f2); + if (*f2 > *f3) SWAP(f2, f3); + if (*f1 > *f2) SWAP(f1, f2); + + // apply watermarking transformation (modify median pixel) + f2new = wm_transform(alpha, *f1, *f2, *f3, get_signature_bit(n % nbit_signature)); + + if (verbose > 1) + fprintf(stderr, "%s: embedding #%d (= %d) at (%d/%d); %f < %f -> %f < %f\n", + progname, n, get_signature_bit(n % nbit_signature), col, row, *f1, *f2, f2new, *f3); + + *f2 = f2new; + + // write modified pixel + set_pixel(p->image, col + 0, row, b1); + set_pixel(p->image, col + 1, row, b2); + set_pixel(p->image, col + 2, row, b3); + + n++; + } + } + + + // skip over some pixels + + idwt(dwts, image); + + pgm_writepgminit(out, cols, rows, maxval, 0); + + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, image[row], cols, maxval, 0); + + fclose(out); + + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_zhu_d.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_zhu_d.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,306 @@ +#include "wm.h" +#include "dwt.h" +#include "netpbm/pgm.h" +#include "sort.h" + +char *progname; + +void usage(void) { + fprintf(stderr, "usage: %s [-a n] [-e n] [-f n] [-F file] [-h] [-l n] [-o file] [-v n] -s file -i file file\n\n", progname); + fprintf(stderr, "\t-a n\t\talpha factor\n"); + fprintf(stderr, "\t-b n\t\tbeta factor\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-i file\t\toriginal image file\n"); + fprintf(stderr, "\t-l n\t\tdecomposition level\n"); + fprintf(stderr, "\t-o file\t\tfile for extracted watermark\n"); + fprintf(stderr, "\t-s file\t\toriginal signature file\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +void write_mark(FILE *out, double watermark[], int n) { + int i; + + fprintf(out, "%d\n", n); + for (i = 0; i < n; i++) + fprintf(out, "%f\n", watermark[i]); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *orig = NULL; + FILE *sig = NULL; + + gray **input_image; + gray **orig_image; + + char signature_name[MAXPATHLEN]; + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char orig_name[MAXPATHLEN]; + + int c, w; + int i; + int n = 0; + int method = -1; + int filter = 0; + char filter_name[MAXPATHLEN] = ""; + + int level = 0, levels; + double alpha = 0.0; + + int in_rows, in_cols, in_format; + gray in_maxval; + int orig_rows, orig_cols, orig_format; + gray orig_maxval; + int rows, cols; + int row; + + double *watermark; + + Image_tree input_dwts, orig_dwts, p, q; + + int verbose = 0; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init2(); + + while ((c = getopt(argc, argv, "a:e:f:F:h?i:l:o:s:v:")) != EOF) { + switch (c) { + case 'a': + alpha = atof(optarg); + if (alpha <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'i': + if ((orig = fopen(optarg, "rb")) == NULL) { + fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); + exit(1); + } + strcpy(orig_name, optarg); + break; + case 'l': + level = atoi(optarg); + if (level <= 0) { + fprintf(stderr, "%s: decomposition level %d out of range\n", progname, level); + exit(1); + } + break; + case 'o': + if ((out = fopen(optarg, "w")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (!orig) { + fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); + exit(1); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "ZHSG") >= 4) { + fscanf(sig, "%d\n", &n); + if (alpha == 0.0) + fscanf(sig, "%lf\n", &alpha); + else + fscanf(sig, "%*f\n"); + if (level == 0) + fscanf(sig, "%d\n", &level); + else + fscanf(sig, "%*d\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + fclose(sig); + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); + pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); + + if (in_cols != orig_cols || in_rows != orig_rows) { + fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); + exit(1); + } + + cols = in_cols; + rows = in_rows; + + input_image = pgm_allocarray(in_cols, in_rows); + orig_image = pgm_allocarray(orig_cols, orig_rows); + + for (row = 0; row < in_rows; row++) { + pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); + pgm_readpgmrow(orig, orig_image[row], orig_cols, orig_maxval, orig_format); + } + + fclose(in); + fclose(orig); + + // complete decomposition + levels = find_deepest_level(cols, rows) - 1; + if (level > levels) { + fprintf(stderr, "%s: decomposition level %d not possible (max. %d), image size is %d x %d\n", progname, level, levels, cols, rows); + exit(1); + } + + init_dwt(cols, rows, filter_name, filter, levels, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + input_dwts = fdwt(input_image); + orig_dwts = fdwt(orig_image); + + watermark = malloc(n * sizeof(double)); + if (!watermark) { + fprintf(stderr, "%s: malloc() failed\n\n", progname); + exit(1); + } + + fprintf(out, "ZHWM\n"); + fprintf(out, "%d\n", n); + fprintf(out, "%d\n", level); + + p = input_dwts; + q = orig_dwts; + while (p->coarse && q->coarse) { + double *collected_coeffs, *largest; + int subband_size = q->horizontal->image->size; + int maxselect = MIN(3 * subband_size, n + 1); + double threshold; + + collected_coeffs = malloc(3 * subband_size * sizeof(double)); + if (!collected_coeffs) { + fprintf(stderr, "%s: malloc() failed\n", progname); + exit(1); + } + + for (i = 0; i < subband_size; i++) { + collected_coeffs[3 * i + 0] = q->horizontal->image->data[i]; + collected_coeffs[3 * i + 1] = q->vertical->image->data[i]; + collected_coeffs[3 * i + 2] = q->diagonal->image->data[i]; + } + + largest = malloc(maxselect * sizeof(double)); + if (!largest) { + fprintf(stderr, "%s: malloc() failed\n", progname); + exit(1); + } + + select_largest_coeffs(collected_coeffs, 3 * subband_size, maxselect, largest); + threshold = largest[0]; + free(largest); + free(collected_coeffs); + + w = 0; + for (i = 0; i < subband_size && w < n; i++) { + if (q->horizontal->image->data[i] > threshold) + watermark[w++] = (p->horizontal->image->data[i] / q->horizontal->image->data[i] - 1.0) / alpha; + if (q->vertical->image->data[i] > threshold) + watermark[w++] = (p->vertical->image->data[i] / q->vertical->image->data[i] - 1.0) / alpha; + if (q->diagonal->image->data[i] > threshold) + watermark[w++] = (p->diagonal->image->data[i] / q->diagonal->image->data[i] - 1.0) / alpha; + } + + write_mark(out, watermark, w); + + p = p->coarse; + q = q->coarse; + } + + fclose(out); + + free(watermark); + + pgm_freearray(input_image, rows); + pgm_freearray(orig_image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald-dir/wm_zhu_e.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Meerwald-dir/wm_zhu_e.c Fri Dec 20 13:08:59 2024 +0100 @@ -0,0 +1,261 @@ +#include "wm.h" +#include "dwt.h" +#include "netpbm/pgm.h" +#include "sort.h" + +char *progname; + +void usage(void) { + 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); + fprintf(stderr, "\t-a n\t\talpha factor/embedding strength\n"); + fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); + fprintf(stderr, "\t-f n\t\tfilter number\n"); + fprintf(stderr, "\t-F file\t\tfilter definition file\n"); + fprintf(stderr, "\t-h\t\tprint usage\n"); + fprintf(stderr, "\t-l n\t\tdecomposition level\n"); + fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); + fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); + fprintf(stderr, "\t-v n\t\tverbosity level\n"); + exit(0); +} + +int main(int argc, char *argv[]) { + + FILE *in = stdin; + FILE *out = stdout; + FILE *sig = NULL; + + char output_name[MAXPATHLEN] = "(stdout)"; + char input_name[MAXPATHLEN] = "(stdin)"; + char signature_name[MAXPATHLEN]; + + int i, c, w; + int row; + + int n; + + double alpha = 0.0; + int level = 0; + + int filter = 0; + int method = -1; + int levels; + char filter_name[MAXPATHLEN] = ""; + + int verbose = 0; + + gray **image; + Image_tree p, dwts; + + gray maxval; + int rows, cols, format; + + double *watermark; + + progname = argv[0]; + + pgm_init(&argc, argv); wm_init(); + + while ((c = getopt(argc, argv, "a:e:f:F:h?o:l:s:v:")) != EOF) { + switch (c) { + case 'a': + alpha = atof(optarg); + if (alpha <= 0.0) { + fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); + exit(1); + } + break; + case 'l': + level = atoi(optarg); + if (level <= 0) { + fprintf(stderr, "%s: decomposition level %d out of range\n", progname, level); + exit(1); + } + break; + case 'e': + method = atoi(optarg); + if (method < 0) { + fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); + exit(1); + } + break; + case 'f': + filter = atoi(optarg); + if (filter <= 0) { + fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); + exit(1); + } + break; + case 'F': + strcpy(filter_name, optarg); + break; + case 'h': + case '?': + usage(); + break; + case 'o': + if ((out = fopen(optarg, "wb")) == NULL) { + fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); + exit(1); + } + strcpy(output_name, optarg); + break; + case 's': + if ((sig = fopen(optarg, "r")) == NULL) { + fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); + exit(1); + } + strcpy(signature_name, optarg); + break; + case 'v': + verbose = atoi(optarg); + if (verbose < 0) { + fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); + exit(1); + } + break; + } + } + + argc -= optind; + argv += optind; + + if (argc > 1) { + usage(); + exit(1); + } + + if (argc == 1 && *argv[0] != '-') { + if ((in = fopen(argv[0], "rb")) == NULL) { + fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); + exit(1); + } + else + strcpy(input_name, argv[0]); + } + + if (sig) { + char line[32]; + fgets(line, sizeof(line), sig); + if (strspn(line, "ZHSG") >= 4) { + fscanf(sig, "%d\n", &n); + if (alpha == 0.0) + fscanf(sig, "%lf\n", &alpha); + else + fscanf(sig, "%*f\n"); + if (level == 0) + fscanf(sig, "%d\n", &level); + else + fscanf(sig, "%*d\n"); + if (method < 0) + fscanf(sig, "%d\n", &method); + else + fscanf(sig, "%*d\n"); + if (filter == 0) + fscanf(sig, "%d\n", &filter); + else + fscanf(sig, "%*d\n"); + if (!strcmp(filter_name, "")) + fscanf(sig, "%[^\n\r]\n", filter_name); + else + fscanf(sig, "%*[^\n\r]\n"); + } + else { + fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); + exit(1); + } + } + else { + fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); + exit(1); + } + + watermark = malloc(n * sizeof(double)); + for (i = 0; i < n; i++) + fscanf(sig, "%lf\n", &watermark[i]); + fclose(sig); + + pgm_readpgminit(in, &cols, &rows, &maxval, &format); + image = pgm_allocarray(cols, rows); + for (row = 0; row < rows; row++) + pgm_readpgmrow(in, image[row], cols, maxval, format); + fclose(in); + + // complete decomposition + levels = find_deepest_level(cols, rows) - 1; + if (level > levels) { + fprintf(stderr, "%s: decomposition level %d not possible (max. %d), image size is %d x %d\n", progname, level, levels, cols, rows); + exit(1); + } + + // wavelet transform + init_dwt(cols, rows, filter_name, filter, level, method); +#ifdef POLLEN_STUFF +#include "pollen_stuff.c" +#endif +#ifdef PARAM_STUFF +#include "param_stuff.c" +#endif + + dwts = fdwt(image); + + p = dwts; + while (p->coarse) { + double *collected_coeffs, *largest; + int subband_size = p->horizontal->image->size; + int maxselect = MIN(3 * subband_size, n + 1); + double threshold; + + // allocate memory for coefficient vector + collected_coeffs = malloc(3 * subband_size * sizeof(double)); + if (!collected_coeffs) { + fprintf(stderr, "%s: malloc() failed\n", progname); + exit(1); + } + + // collect coefficients from all subbands of one level into one vector + for (i = 0; i < subband_size; i++) { + collected_coeffs[3 * i + 0] = p->horizontal->image->data[i]; + collected_coeffs[3 * i + 1] = p->vertical->image->data[i]; + collected_coeffs[3 * i + 2] = p->diagonal->image->data[i]; + } + + // allocate memory for largest coefficients + largest = malloc(maxselect * sizeof(double)); + if (!largest) { + fprintf(stderr, "%s: malloc() failed\n", progname); + exit(1); + } + + // select largest coefficients (involves sorting) + select_largest_coeffs(collected_coeffs, 3 * subband_size, maxselect, largest); + // threshold is the smallest of the largest coefficients + threshold = largest[0]; + free(largest); + free(collected_coeffs); + + w = 0; + for (i = 0; i < subband_size && w < n; i++) { + if (p->horizontal->image->data[i] > threshold) + p->horizontal->image->data[i] *= (1.0 + alpha * watermark[w++]); + if (p->vertical->image->data[i] > threshold) + p->vertical->image->data[i] *= (1.0 + alpha * watermark[w++]); + if (p->diagonal->image->data[i] > threshold) + p->diagonal->image->data[i] *= (1.0 + alpha * watermark[w++]); + } + + p = p->coarse; + } + + free(watermark); + idwt(dwts, image); + + pgm_writepgminit(out, cols, rows, maxval, 0); + for (row = 0; row < rows; row++) + pgm_writepgmrow(out, image[row], cols, maxval, 0); + fclose(out); + + pgm_freearray(image, rows); + + exit(0); +} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/Makefile --- a/Meerwald/Makefile Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,520 +0,0 @@ -# Makefile - -# chose build plattform -include ../make/make.config - -OPTIONS=-DPARAM_STUFF -DPOLLEN_STUFF - -all: tools \ - bruyn \ - koch \ - corvi \ - xia \ - xie \ - xie2 \ - cox \ - zhu \ - dugad \ - wang \ - frid2 \ - kim \ - kund2 \ - kund3 - -.SUFFIXES: .c .o .1 .ps - -.c$(O): - $(CC) $(CFLAGS) $(INCLUDES) $(OPTIONS) -o $@ -c $< - -.1.ps: - $(GROFF) $< > $@ - -# library containing general stuff - -$(LIBPREFIX)wm$(LIB): dct$(O) coeff$(O) gray$(O) sort$(O) signature-utils$(O) coord$(O) wm$(O) - $(RM) $@ - ar -rc $@ dct$(O) coeff$(O) gray$(O) sort$(O) signature-utils$(O) coord$(O) wm$(O) - -libraryclean: - $(RM) $(LIBPREFIX)wm$(LIB) - -# library containing wavelet transform stuff - -$(LIBPREFIX)wavelet$(LIB): wavelet$(O) dwt$(O) dwt_util$(O) - $(RM) $@ - ar -rc $@ wavelet$(O) dwt$(O) dwt_util$(O) - -waveletclean: - $(RM) $(LIBPREFIX)wavelet$(LIB) - -# some general tools to compute difference image, PSNR, ... - -tools: cmp_pgm$(EXE) cmp_dct8x8$(EXE) cmp_dct$(EXE) cmp_dwt$(EXE) cmp_ppm$(EXE) - -toolstest: - -toolsinstall: tools - $(CP) cmp_ppm$(EXE) cmp_pgm$(EXE) cmp_dct8x8$(EXE) cmp_dct$(EXE) cmp_dwt$(EXE) $(INSTALLDIR) - -toolsman: cmp_ppm.ps cmp_pgm.ps cmp_dct8x8.ps cmp_dct.ps - -toolsclean: - $(RM) cmp_ppm$(EXE) cmp_pgm$(EXE) cmp_dct$(EXE) cmp_dct8x8$(EXE) cmp_dwt$(EXE) - -cmp_pgm$(EXE): cmp_pgm$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ cmp_pgm$(O) $(WMLIB) $(PGMLIBS) $(LIBS) - -cmp_ppm$(EXE): cmp_ppm$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ cmp_ppm$(O) $(WMLIB) $(PGMLIBS) $(LIBS) - -cmp_dct$(EXE): cmp_dct$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ cmp_dct$(O) $(WMLIB) $(PGMLIBS) - -cmp_dwt$(EXE): cmp_dwt$(O) $(LIBPREFIX)wavelet$(LIB) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ cmp_dwt$(O) $(WAVELIB) $(WMLIB) $(PGMLIBS) - -cmp_dct8x8$(EXE): cmp_dct8x8$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ cmp_dct8x8$(O) $(WMLIB) $(PGMLIBS) - - -# Koch's algorithm (8x8 block DCT, blind, binary) - -koch: gen_koch_sig$(EXE) wm_koch_e$(EXE) wm_koch_d$(EXE) cmp_koch_sig$(EXE) - -kochtest: koch - gen_koch_sig$(EXE) -n 150 < gen_koch_sig.c > ../sigs/koch.sig - wm_koch_e$(EXE) -s ../sigs/koch.sig -o ../watermarked/koch_lena.pgm ../images/lena.pgm - wm_koch_d$(EXE) -s ../sigs/koch.sig -o ../wms/koch.wm ../watermarked/koch_lena.pgm - cmp_koch_sig$(EXE) -s ../sigs/koch.sig ../wms/koch.wm - -kochinstall: koch - $(CP) gen_koch_sig$(EXE) wm_koch_e$(EXE) wm_koch_d$(EXE) cmp_koch_sig$(EXE) $(INSTALLDIR) - -kochclean: - $(RM) gen_koch_sig$(EXE) wm_koch_e$(EXE) wm_koch_d$(EXE) cmp_koch_sig$(EXE) - -kochman: - -wm_koch_e$(EXE): wm_koch_e$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_koch_e$(O) $(WMLIB) $(LIBS) $(PGMLIBS) - -wm_koch_d$(EXE): wm_koch_d$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_koch_d$(O) $(WMLIB) $(LIBS) $(PGMLIBS) - -gen_koch_sig$(EXE): gen_koch_sig$(O) wm$(O) - $(CC) $(LDFLAGS) -o $@ gen_koch_sig$(O) wm$(O) $(LIBS) - -cmp_koch_sig$(EXE): cmp_koch_sig$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ cmp_koch_sig$(O) $(WMLIB) $(LIBS) - -# Fridrich's 2. scheme (full-frame DCT, blind, binary) - -frid2: gen_frid2_sig$(EXE) wm_frid2_e$(EXE) wm_frid2_d$(EXE) cmp_frid2_sig$(EXE) - -frid2test: frid2 - gen_frid2_sig$(EXE) -n 250 < gen_frid2_sig.c > ../sigs/frid2.sig - wm_frid2_e$(EXE) -s ../sigs/frid2.sig -o ../watermarked/frid2_lena.pgm ../images/lena.pgm - wm_frid2_d$(EXE) -s ../sigs/frid2.sig -o ../wms/frid2.wm ../watermarked/frid2_lena.pgm - cmp_frid2_sig$(EXE) -s ../sigs/frid2.sig ../wms/frid2.wm - -frid2install: frid2 - $(CP) gen_frid2_sig$(EXE) wm_frid2_e$(EXE) wm_frid2_d$(EXE) cmp_frid2_sig$(EXE) $(INSTALLDIR) - -frid2clean: - $(RM) gen_frid2_sig$(EXE) wm_frid2_e$(EXE) wm_frid2_d$(EXE) cmp_frid2_sig$(EXE) - -frid2man: - -wm_frid2_e$(EXE): wm_frid2_e$(O) $(LIBPREFIX)wm$(LIB) frid2_common$(O) - $(CC) $(LDFLAGS) -o $@ wm_frid2_e$(O) frid2_common$(O) $(WMLIB) $(LIBS) $(PGMLIBS) - -wm_frid2_d$(EXE): wm_frid2_d$(O) $(LIBPREFIX)wm$(LIB) frid2_common$(O) - $(CC) $(LDFLAGS) -o $@ wm_frid2_d$(O) frid2_common$(O) $(WMLIB) $(LIBS) $(PGMLIBS) - -gen_frid2_sig$(EXE): gen_frid2_sig$(O) wm$(O) - $(CC) $(LDFLAGS) -o $@ gen_frid2_sig$(O) wm$(O) $(LIBS) - -cmp_frid2_sig$(EXE): cmp_frid2_sig$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ cmp_frid2_sig$(O) $(WMLIB) $(LIBS) - - -# Bruyndonckx's algorithm (spatial domain, block classification, blind) - -bruyn: gen_bruyn_sig$(EXE) wm_bruyn_e$(EXE) wm_bruyn_d$(EXE) cmp_bruyn_sig$(EXE) - -bruyntest: bruyn - gen_bruyn_sig$(EXE) -n 400 < gen_bruyn_sig.c > ../sigs/bruyn.sig - wm_bruyn_e$(EXE) -s ../sigs/bruyn.sig -o ../watermarked/bruyn_lena.pgm ../images/lena.pgm - wm_bruyn_d$(EXE) -s ../sigs/bruyn.sig -o ../wms/bruyn.wm ../watermarked/bruyn_lena.pgm - cmp_bruyn_sig$(EXE) -s ../sigs/bruyn.sig ../wms/bruyn.wm - -bruyninstall: bruyn - $(CP) gen_bruyn_sig$(EXE) wm_bruyn_e$(EXE) wm_bruyn_d$(EXE) cmp_bruyn_sig$(EXE) $(INSTALLDIR) - -bruynclean: - $(RM) gen_bruyn_sig$(EXE) wm_bruyn_e$(EXE) wm_bruyn_d$(EXE) cmp_bruyn_sig$(EXE) - -bruynman: - -wm_bruyn_e$(EXE): wm_bruyn_e$(O) bruyn_common$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_bruyn_e$(O) bruyn_common$(O) $(WMLIB) $(LIBS) $(PGMLIBS) - -wm_bruyn_d$(EXE): wm_bruyn_d$(O) bruyn_common$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_bruyn_d$(O) bruyn_common$(O) $(WMLIB) $(LIBS) $(PGMLIBS) - -gen_bruyn_sig$(EXE): gen_bruyn_sig$(O) wm$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ gen_bruyn_sig$(O) wm$(O) $(WMLIB) - -cmp_bruyn_sig$(EXE): cmp_bruyn_sig$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ cmp_bruyn_sig$(O) $(WMLIB) $(LIBS) - - -# Cox's algorithm (full-frame DCT, non-blind, spread-spectrum) - -cox: gen_cox_sig$(EXE) wm_cox_e$(EXE) wm_cox_d$(EXE) cmp_cox_sig$(EXE) - -coxtest: cox - gen_cox_sig$(EXE) > ../sigs/cox.sig - wm_cox_e$(EXE) -s ../sigs/cox.sig -o ../watermarked/cox_lena.pgm ../images/lena.pgm - wm_cox_d$(EXE) -s ../sigs/cox.sig -o ../wms/cox.wm -i ../images/lena.pgm ../watermarked/cox_lena.pgm - cmp_cox_sig$(EXE) -s ../sigs/cox.sig ../wms/cox.wm - -coxinstall: cox - $(CP) gen_cox_sig$(EXE) wm_cox_e$(EXE) wm_cox_d$(EXE) cmp_cox_sig$(EXE) $(INSTALLDIR) - -coxman: gen_cox_sig.ps wm_cox_e.ps wm_cox_d.ps - -wm_cox_e$(EXE): wm_cox_e$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_cox_e$(O) $(WMLIB) $(LIBS) $(PGMLIBS) - -wm_cox_d$(EXE): wm_cox_d$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_cox_d$(O) $(WMLIB) $(LIBS) $(PGMLIBS) - -gen_cox_sig$(EXE): gen_cox_sig$(O) - $(CC) $(LDFLAGS) -o $@ gen_cox_sig$(O) $(LIBS) - -cmp_cox_sig$(EXE): cmp_cox_sig$(O) - $(CC) $(LDFLAGS) -o $@ cmp_cox_sig$(O) $(LIBS) - -coxclean: - $(RM) gen_cox_sig$(EXE) wm_cox_e$(EXE) wm_cox_d$(EXE) cmp_cox_sig$(EXE) - - -# Corvi's algorithm (DWT, non-blind, spread-spectrum, approximation image) - -corvi: gen_corvi_sig$(EXE) wm_corvi_e$(EXE) wm_corvi_d$(EXE) cmp_corvi_sig$(EXE) - -corvitest: corvi - gen_corvi_sig$(EXE) > ../sigs/corvi.sig - wm_corvi_e$(EXE) -s ../sigs/corvi.sig -o ../watermarked/corvi_lena.pgm ../images/lena.pgm - wm_corvi_d$(EXE) -s ../sigs/corvi.sig -o ../wms/corvi.wm -i ../images/lena.pgm ../watermarked/corvi_lena.pgm - cmp_corvi_sig$(EXE) -s ../sigs/corvi.sig ../wms/corvi.wm - -corviinstall: corvi - $(CP) gen_corvi_sig$(EXE) wm_corvi_e$(EXE) wm_corvi_d$(EXE) cmp_corvi_sig$(EXE) $(INSTALLDIR) - -corviman: gen_corvi_sig.ps wm_corvi_e.ps wm_corvi_d.ps - -wm_corvi_e$(EXE): wm_corvi_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_corvi_e$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -wm_corvi_d$(EXE): wm_corvi_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_corvi_d$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -gen_corvi_sig$(EXE): gen_corvi_sig$(O) - $(CC) $(LDFLAGS) -o $@ gen_corvi_sig$(O) $(LIBS) - -cmp_corvi_sig$(EXE): cmp_corvi_sig$(O) - $(CC) $(LDFLAGS) -o $@ cmp_corvi_sig$(O) $(LIBS) - -corviclean: - $(RM) gen_corvi_sig$(EXE) wm_corvi_e$(EXE) wm_corvi_d$(EXE) cmp_corvi_sig$(EXE) - - -# Xia's algorithm (DWT, non-blind, spread-spectrum, detail subbands) - -xia: gen_xia_sig$(EXE) wm_xia_e$(EXE) wm_xia_d$(EXE) cmp_xia_sig$(EXE) - -xiatest: xia - gen_xia_sig$(EXE) > ../sigs/xia.sig - wm_xia_e$(EXE) -s ../sigs/xia.sig -o ../watermarked/xia_lena.pgm ../images/lena.pgm - wm_xia_d$(EXE) -s ../sigs/xia.sig -o ../wms/xia.wm -i ../images/lena.pgm ../watermarked/xia_lena.pgm - cmp_xia_sig$(EXE) -s ../sigs/xia.sig ../wms/xia.wm - -xiainstall: xia - $(CP) gen_xia_sig$(EXE) wm_xia_e$(EXE) wm_xia_d$(EXE) cmp_xia_sig$(EXE) $(INSTALLDIR) - -xiaman: gen_xia_sig.ps wm_xia_e.ps wm_xia_d.ps - -wm_xia_e$(EXE): wm_xia_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_xia_e$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -wm_xia_d$(EXE): wm_xia_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_xia_d$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -gen_xia_sig$(EXE): gen_xia_sig$(O) - $(CC) $(LDFLAGS) -o $@ gen_xia_sig$(O) $(LIBS) - -cmp_xia_sig$(EXE): cmp_xia_sig$(O) - $(CC) $(LDFLAGS) -o $@ cmp_xia_sig$(O) $(LIBS) - -xiaclean: - $(RM) gen_xia_sig$(EXE) wm_xia_e$(EXE) wm_xia_d$(EXE) cmp_xia_sig$(EXE) - -# Wang's algorithm (DWT, non-blind, spread-spectrum, detail subbands) - -wang: gen_wang_sig$(EXE) wm_wang_e$(EXE) wm_wang_d$(EXE) cmp_wang_sig$(EXE) - -wangtest: wang - gen_wang_sig$(EXE) -n 1000 > ../sigs/wang.sig - wm_wang_e$(EXE) -s ../sigs/wang.sig -o ../watermarked/wang_lena.pgm ../images/lena.pgm - wm_wang_d$(EXE) -s ../sigs/wang.sig -o ../wms/wang.wm -i ../images/lena.pgm ../watermarked/wang_lena.pgm - cmp_wang_sig$(EXE) -s ../sigs/wang.sig ../wms/wang.wm - -wanginstall: wang - $(CP) gen_wang_sig$(EXE) wm_wang_e$(EXE) wm_wang_d$(EXE) cmp_wang_sig$(EXE) $(INSTALLDIR) - -wangman: gen_wang_sig.ps wm_wang_e.ps wm_wang_d.ps - -wm_wang_e$(EXE): wm_wang_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) wang_common$(O) - $(CC) $(LDFLAGS) -o $@ wm_wang_e$(O) wang_common$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -wm_wang_d$(EXE): wm_wang_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) wang_common$(O) - $(CC) $(LDFLAGS) -o $@ wm_wang_d$(O) wang_common$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -gen_wang_sig$(EXE): gen_wang_sig$(O) - $(CC) $(LDFLAGS) -o $@ gen_wang_sig$(O) $(LIBS) - -cmp_wang_sig$(EXE): cmp_wang_sig$(O) - $(CC) $(LDFLAGS) -o $@ cmp_wang_sig$(O) $(LIBS) - -wangclean: - $(RM) gen_wang_sig$(EXE) wm_wang_e$(EXE) wm_wang_d$(EXE) cmp_wang_sig$(EXE) - -# Kim's algorithm (DWT, non-blind, spread-spectrum, approx. & detail subbands) - -kim: gen_kim_sig$(EXE) wm_kim_e$(EXE) wm_kim_d$(EXE) cmp_kim_sig$(EXE) - -kimtest: kim - gen_kim_sig$(EXE) -n 1000 > ../sigs/kim.sig - wm_kim_e$(EXE) -s ../sigs/kim.sig -o ../watermarked/kim_lena.pgm ../images/lena.pgm - wm_kim_d$(EXE) -s ../sigs/kim.sig -o ../wms/kim.wm -i ../images/lena.pgm ../watermarked/kim_lena.pgm - cmp_kim_sig$(EXE) -s ../sigs/kim.sig ../wms/kim.wm - -kiminstall: kim - $(CP) gen_kim_sig$(EXE) wm_kim_e$(EXE) wm_kim_d$(EXE) cmp_kim_sig$(EXE) $(INSTALLDIR) - -kimman: gen_kim_sig.ps wm_kim_e.ps wm_kim_d.ps - -wm_kim_e$(EXE): wm_kim_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) kim_common$(O) - $(CC) $(LDFLAGS) -o $@ wm_kim_e$(O) kim_common$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -wm_kim_d$(EXE): wm_kim_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) kim_common$(O) - $(CC) $(LDFLAGS) -o $@ wm_kim_d$(O) kim_common$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -gen_kim_sig$(EXE): gen_kim_sig$(O) - $(CC) $(LDFLAGS) -o $@ gen_kim_sig$(O) $(LIBS) - -cmp_kim_sig$(EXE): cmp_kim_sig$(O) - $(CC) $(LDFLAGS) -o $@ cmp_kim_sig$(O) $(LIBS) - -kimclean: - $(RM) gen_kim_sig$(EXE) wm_kim_e$(EXE) wm_kim_d$(EXE) cmp_kim_sig$(EXE) - -# Zhu's algorithm (DWT, non-blind, spread-spectrum, detail subbands) - -zhu: gen_zhu_sig$(EXE) wm_zhu_e$(EXE) wm_zhu_d$(EXE) cmp_zhu_sig$(EXE) - -zhutest: zhu - gen_zhu_sig$(EXE) > ../sigs/zhu.sig - wm_zhu_e$(EXE) -s ../sigs/zhu.sig -o ../watermarked/zhu_lena.pgm ../images/lena.pgm - wm_zhu_d$(EXE) -s ../sigs/zhu.sig -o ../wms/zhu.wm -i ../images/lena.pgm ../watermarked/zhu_lena.pgm - cmp_zhu_sig$(EXE) -s ../sigs/zhu.sig ../wms/zhu.wm - -zhuinstall: zhu - $(CP) gen_zhu_sig$(EXE) wm_zhu_e$(EXE) wm_zhu_d$(EXE) cmp_zhu_sig$(EXE) $(INSTALLDIR) - -zhuman: gen_zhu_sig.ps wm_zhu_e.ps wm_zhu_d.ps - -wm_zhu_e$(EXE): wm_zhu_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_zhu_e$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -wm_zhu_d$(EXE): wm_zhu_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_zhu_d$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -gen_zhu_sig$(EXE): gen_zhu_sig$(O) - $(CC) $(LDFLAGS) -o $@ gen_zhu_sig$(O) $(LIBS) - -cmp_zhu_sig$(EXE): cmp_zhu_sig$(O) - $(CC) $(LDFLAGS) -o $@ cmp_zhu_sig$(O) $(LIBS) - -zhuclean: - $(RM) gen_zhu_sig$(EXE) wm_zhu_e$(EXE) wm_zhu_d$(EXE) cmp_zhu_sig$(EXE) - -# Xie's algorithm (DWT, blind, binary, quantization, approximation image) - -xie: gen_xie_sig$(EXE) wm_xie_e$(EXE) wm_xie_d$(EXE) cmp_xie_sig$(EXE) - -xietest: xie - gen_xie_sig$(EXE) -n 800 gen_xie_sig.c > ../sigs/xie.sig - wm_xie_e$(EXE) -s ../sigs/xie.sig -o ../watermarked/xie_lena.pgm ../images/lena.pgm - wm_xie_d$(EXE) -s ../sigs/xie.sig -o ../wms/xie.wm ../watermarked/xie_lena.pgm - cmp_xie_sig$(EXE) -s ../sigs/xie.sig ../wms/xie.wm - -xieinstall: xie - $(CP) gen_xie_sig$(EXE) wm_xie_e$(EXE) wm_xie_d$(EXE) cmp_xie_sig$(EXE) $(INSTALLDIR) - -xieman: gen_xie_sig.ps wm_xie_e.ps wm_xie_d.ps - -wm_xie_e$(EXE): wm_xie_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_xie_e$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -wm_xie_d$(EXE): wm_xie_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_xie_d$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -gen_xie_sig$(EXE): gen_xie_sig$(O) wm$(O) - $(CC) $(LDFLAGS) -o $@ gen_xie_sig$(O) wm$(O) $(LIBS) - -cmp_xie_sig$(EXE): cmp_xie_sig$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ cmp_xie_sig$(O) $(WMLIB) $(LIBS) - -xieclean: - $(RM) gen_xie_sig$(EXE) wm_xie_e$(EXE) wm_xie_d$(EXE) cmp_xie_sig$(EXE) - -# Xie2's algorithm (DWT, blind, binary, quantization, approximation image) - -xie2: gen_xie2_sig$(EXE) wm_xie2_e$(EXE) wm_xie2_d$(EXE) cmp_xie2_sig$(EXE) - -xie2test: xie2 - gen_xie2_sig$(EXE) -n 800 gen_xie2_sig.c > ../sigs/xie2.sig - wm_xie2_e$(EXE) -s ../sigs/xie2.sig -o ../watermarked/xie2_lena.pgm ../images/lena.pgm - wm_xie2_d$(EXE) -s ../sigs/xie2.sig -o ../wms/xie2.wm ../watermarked/xie2_lena.pgm - cmp_xie2_sig$(EXE) -s ../sigs/xie2.sig ../wms/xie2.wm - -xie2install: xie2 - $(CP) gen_xie2_sig$(EXE) wm_xie2_e$(EXE) wm_xie2_d$(EXE) cmp_xie2_sig$(EXE) $(INSTALLDIR) - -xie2man: gen_xie2_sig.ps wm_xie2_e.ps wm_xie2_d.ps - -wm_xie2_e$(EXE): wm_xie2_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_xie2_e$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -wm_xie2_d$(EXE): wm_xie2_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_xie2_d$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -gen_xie2_sig$(EXE): gen_xie2_sig$(O) wm$(O) - $(CC) $(LDFLAGS) -o $@ gen_xie2_sig$(O) wm$(O) $(LIBS) - -cmp_xie2_sig$(EXE): cmp_xie2_sig$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ cmp_xie2_sig$(O) $(WMLIB) $(LIBS) - -xie2clean: - $(RM) gen_xie2_sig$(EXE) wm_xie2_e$(EXE) wm_xie2_d$(EXE) cmp_xie2_sig$(EXE) - -# Kundur's algorithm 2 (DWT, blind, binary, quantization, detail subbands, reference watermark) - -kund2: gen_kund2_sig$(EXE) wm_kund2_e$(EXE) wm_kund2_d$(EXE) cmp_kund2_sig$(EXE) - -kund2test: kund2 - gen_kund2_sig$(EXE) -n 1000 -l 3 -q 2 gen_kund2_sig.c > ../sigs/kund2.sig - wm_kund2_e$(EXE) -s ../sigs/kund2.sig -o ../watermarked/kund2_lena.pgm ../images/lena.pgm - cjpeg -quality 70 ../watermarked/kund2_lena.pgm | djpeg | wm_kund2_d$(EXE) -s ../sigs/kund2.sig -o ../wms/kund2.wm - cmp_kund2_sig$(EXE) -s ../sigs/kund2.sig ../wms/kund2.wm - -kund2install: kund2 - $(CP) gen_kund2_sig$(EXE) wm_kund2_e$(EXE) wm_kund2_d$(EXE) cmp_kund2_sig$(EXE) $(INSTALLDIR) - -kund2man: gen_kund2_sig.ps wm_kund2_e.ps wm_kund2_d.ps - -wm_kund2_e$(EXE): wm_kund2_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_kund2_e$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -wm_kund2_d$(EXE): wm_kund2_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_kund2_d$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -gen_kund2_sig$(EXE): gen_kund2_sig$(O) wm$(O) signature-utils$(O) - $(CC) $(LDFLAGS) -o $@ gen_kund2_sig$(O) wm$(O) signature-utils$(O) $(LIBS) - -cmp_kund2_sig$(EXE): cmp_kund2_sig$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ cmp_kund2_sig$(O) $(WMLIB) $(LIBS) - -kund2clean: - $(RM) gen_kund2_sig$(EXE) wm_kund2_e$(EXE) wm_kund2_d$(EXE) cmp_kund2_sig$(EXE) - -# Kundur's algorithm 3 (DWT, blind, binary, quantization, detail subbands) - -kund3: gen_kund3_sig$(EXE) wm_kund3_e$(EXE) wm_kund3_d$(EXE) cmp_kund3_sig$(EXE) - -kund3test: kund3 - gen_kund3_sig$(EXE) -n 1000 -l 2 -q 2 gen_kund3_sig.c > ../sigs/kund3.sig - wm_kund3_e$(EXE) -s ../sigs/kund3.sig -o ../watermarked/kund3_lena.pgm ../images/lena.pgm - wm_kund3_d$(EXE) -s ../sigs/kund3.sig -o ../wms/kund3.wm ../watermarked/kund3_lena.pgm - cmp_kund3_sig$(EXE) -s ../sigs/kund3.sig ../wms/kund3.wm - -kund3install: kund3 - $(CP) gen_kund3_sig$(EXE) wm_kund3_e$(EXE) wm_kund3_d$(EXE) cmp_kund3_sig$(EXE) $(INSTALLDIR) - -kund3man: gen_kund3_sig.ps wm_kund3_e.ps wm_kund3_d.ps - -wm_kund3_e$(EXE): wm_kund3_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_kund3_e$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -wm_kund3_d$(EXE): wm_kund3_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_kund3_d$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -gen_kund3_sig$(EXE): gen_kund3_sig$(O) wm$(O) signature-utils$(O) - $(CC) $(LDFLAGS) -o $@ gen_kund3_sig$(O) wm$(O) signature-utils$(O) $(LIBS) - -cmp_kund3_sig$(EXE): cmp_kund3_sig$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ cmp_kund3_sig$(O) $(WMLIB) $(LIBS) - -kund3clean: - $(RM) gen_kund3_sig$(EXE) wm_kund3_e$(EXE) wm_kund3_d$(EXE) cmp_kund3_sig$(EXE) - -# Dugad's algorithm (DWT, blind) - -dugad: gen_dugad_sig$(EXE) wm_dugad_e$(EXE) wm_dugad_d$(EXE) cmp_dugad_sig$(EXE) - -dugadtest: dugad - gen_dugad_sig$(EXE) -o ../sigs/dugad.sig - wm_dugad_e$(EXE) -s ../sigs/dugad.sig -o ../watermarked/dugad_lena.pgm ../images/lena.pgm - wm_dugad_d$(EXE) -s ../sigs/dugad.sig -o ../wms/dugad.wm ../watermarked/dugad_lena.pgm - cmp_dugad_sig$(EXE) -s ../sigs/dugad.sig ../wms/dugad.wm - -dugadinstall: dugad - $(CP) gen_dugad_sig$(EXE) wm_dugad_e$(EXE) wm_dugad_d$(EXE) cmp_dugad_sig$(EXE) $(INSTALLDIR) - -dugadman: gen_dugad_sig.ps wm_dugad_e.ps wm_dugad_d.ps - -wm_dugad_e$(EXE): wm_dugad_e$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_dugad_e$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -wm_dugad_d$(EXE): wm_dugad_d$(O) $(LIBPREFIX)wm$(LIB) $(LIBPREFIX)wavelet$(LIB) - $(CC) $(LDFLAGS) -o $@ wm_dugad_d$(O) $(WMLIB) $(WAVELIB) $(LIBS) $(PGMLIBS) - -gen_dugad_sig$(EXE): gen_dugad_sig$(O) - $(CC) $(LDFLAGS) -o $@ gen_dugad_sig$(O) $(LIBS) - -cmp_dugad_sig$(EXE): cmp_dugad_sig$(O) $(LIBPREFIX)wm$(LIB) - $(CC) $(LDFLAGS) -o $@ cmp_dugad_sig$(O) $(WMLIB) $(LIBS) - -dugadclean: - $(RM) gen_dugad_sig$(EXE) wm_dugad_e$(EXE) wm_dugad_d$(EXE) cmp_dugad_sig$(EXE) - - - -clean: coxclean bruynclean kochclean corviclean xiaclean zhuclean xieclean kund3clean kund2clean \ - dugadclean kimclean wangclean frid2clean toolsclean libraryclean waveletclean xie2clean - $(RM) *$(O) *.ps ../sigs/* ../wms/* ../watermarked/* - -man: coxman bruynman kochman corviman xiaman xieman toolsman - -test: coxtest bruyntest kochtest corvitest xiatest xietest dugadtest zhutest \ - wangtest frid2test kimtest toolstest kund3test kund2test - -install: coxinstall bruyninstall kochinstall corviinstall xiainstall xieinstall \ - dugadinstall zhuinstall wanginstall frid2install kiminstall toolsinstall kund3install kund2install - -depend: - $(MAKEDEP) *.h *.c - diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/README --- a/Meerwald/README Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ -This package provides source code for some watermarking algorithms in portable -C code. Currently it includes the following - - watermarking algorithms - - Bruyndonckx - refer to - O. Bruyndonckx, Jean-Jacques Quisquater, and Benoit M. Macq. - Spatial method for copyright labeling of digital images. - In IEEE Workshop on Nonlinear Signal and Image Processing '95, - Thessaloniki, Greece, pages 456 - 459, 1995. - - Corvi - refer to - Marco Corvi and Gianluca Nicchiotti. - Wavelet-based image watermarking for copyright protection. - In Scandinavian Conference on Image Analysis SCIA '97, Lappeenranta, - Finland, June 1997. - - Cox - refer to - Ingemar J. Cox, Joe Kilian, Tom Leighton, and Talal G. Shamoon. - Secure spread spectrum watermarking for multimedia. - In Proceedings of the IEEE ICIP '97, - volume 6, pages 1673 - 1687, Santa Barbara, California, USA, 1997. - - Dugad - refer to - Rakesh Dugad, Krishna Ratakonda, and Narendra Ahuja. - A new wavelet-based scheme for watermarking images. In Proceedings of - the IEEE International Conference on Image Processing, ICIP '98, - Chicago, IL, USA, October 1998. - - Fridrich (2. scheme) - refer to - Jiri Fridrich. - Combining low-frequency and spread spectrum watermarking. In - Proceedings of the SPIE Symposium on Optical Science, Engineering and - Instrumentation, San Diego, USA, July 1998. - - Koch - refer to - Eckhard Koch and Jian Zhao. - Towards robust and hidden image copyright labeling. - In Proceedings of the IEEE International Workshop on Nonlinear - Signal and Image Processing, pages 452 - 455, Halkidiki, Marmaras, - Greece, June 1995. - - Kim - refer to - Jong Ryul Kim and Young Shik Moon. - A robust wavelet-based digital watermark using level-adaptive - thresholding. In Proceedings of the 6th IEEE International - Conference on Image Processing ICIP '99, page 202, - Kobe, Japan, October 1999. - - Wang - refer to - Houng-Jyh Wang, Po-Chyi Su, and C.-C. Jay Kuo. - Wavelet-based digital image watermarking. Optics Express, 3 - pp. 497, December 1998. - - Xia - refer to - Xiang-Gen Xia, Charles G. Boncelet, and Gonzalo R. Arce. - Wavelet transform based watermark for digital images. Optics Express, 3 - pp. 497, December 1998. - - Xie - refer to - Liehua Xie and Gonzalo R. Arce. - Joint wavelet compression and authentication watermarking. In - Proceedings of the IEEE International Conference on Image Processing, - ICIP '98, Chicago, IL, USA, 1998. - - Zhu - refer to - Wenwu Zhu, Zixiang Xiong, and Ya-Qin Zhang. - Multiresolution watermarking for images and video: a unified approach. - In Proceedings of the IEEE International Conference o - - many more algorithms to come! - see what is in stock: http://www.cosy.sbg.ac.at/~pmeerw/Watermarking - - and utility programs - - cmp_pgm - compute difference image, PSNR, ... - cmp_dct - compute full-frame DCT domain difference image - cmp_dct8x8 - compute 8x8 block-based DCT difference image - cmp_dwt - compute DWT domain difference image - -What do I need? - -Unix (Linux), a reasonable C compiler (GCC), and the netpbm library which you -can get at http://wuarchive.wustl.edu/graphics/graphics/packages/NetPBM/ - - -Directions: How do I use the stuff? - -look at the MAKEFILE... -each algorithms has at least 4 files: gen_algo_sig.c, wm_algo_e.c, wm_algo_d.c, -cmp_algo_sig.c where 'algo' is the name of the actual watermarking algorithm -(usually the principal author's name), where might also be some common files -for each algorithm, algo_common.{c|h}, and some support files for sorting, -the DCT, ... - -just try - - make - make test - -next, try to run each program with the -h parameter to find out what options -are supported - the programs are pretty consistent and have reasonable -default settings - -e.g. - - wm_cox_e -h - -The programs all support standard input and standard output, the only -supported image file format is PGM for grayscale images and PPM for color -images; most programs have only been tested with 512x512 images. -You can find the Lena image in PGM format in the images/ sub-directory. - - -Disclaimer: #include - -Feel free to use the accompaigning code for your research! However, I do -not guarantee for anything, in particular parts of the provided code may -be covered by copyrights of a third party or by patent claims. I do not -guarantee for any functionality, bla-bla, ... - -If you use the accompanying code, please cite my thesis: - - Peter Meerwald, Digital Image Watermarking in the Wavelet Transform Domain, - Master's Thesis, Department of Scientific Computing, University of Salzburg, - Austria, January 2001. - - -Contact: Comments are welcome! - -More algorithms will be added over time, I have implemented about 13 -watermarking algorithms in the spatial-, DCT-, and wavelet domain so far. -Please report what problems you have, suggestions, ... - -Peter Meerwald - -Dept. of Scientific Computing -University of Salzburg -Jakob-Haringer-Str. 2 -A-5020 Salzburg -AUSTRIA - -pmeerw@cosy.sbg.ac.at -http://www.cosy.sbg.ac.at/~pmeerw/Watermarking - -+43-662-8044-6327 diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/bruyn_common.c --- a/Meerwald/bruyn_common.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -#include "bruyn_common.h" - -gray lookup_pattern(int pattern, int c, int r) { -#define A CATEGORY_A -#define B CATEGORY_B - - gray pattern1[4][4] = - {{A, A, B, B}, - {A, A, B, B}, - {B, B, A, A}, - {B, B, A, A}}; - - gray pattern2[8][8] = - {{B, B, B, B, A, A, A, A}, - {B, B, B, B, A, A, A, A}, - {B, B, B, B, A, A, A, A}, - {B, B, B, B, A, A, A, A}, - {A, A, A, A, B, B, B, B}, - {A, A, A, A, B, B, B, B}, - {A, A, A, A, B, B, B, B}, - {A, A, A, A, B, B, B, B}}; - - gray pattern3[2][2] = - {{A, B}, {B, A}}; - -#undef A -#undef B - - switch (pattern) { - case 1: - return pattern1[r % 4][c % 4]; - break; - case 2: - return pattern2[r % 8][c % 8]; - break; - case 3: - return pattern3[r % 2][c % 2]; - break; - } - - return CATEGORY_VOID; -} - - diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/bruyn_common.h --- a/Meerwald/bruyn_common.h Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -#ifndef BRUYN_COMMON_H -#define BRUYN_COMMON_H - -#include "pgm.h" - -// for block type classification -#define BLOCKTYPE_UNKNOWN 0 -#define BLOCKTYPE_HARD 1 -#define BLOCKTYPE_PROGRESSIVE 2 -#define BLOCKTYPE_NOISE 3 - -// thresholds -#define THRESHOLD_NOISE 10.0 -#define THRESHOLD_SLOPE 5.0 -#define THRESHOLD_NOISE_USAGE "10.0" -#define THRESHOLD_SLOPE_USAGE "5.0" - -// zone classification -#define ZONE_VOID 0 -#define ZONE_1 1 -#define ZONE_2 2 - -// category classification -#define CATEGORY_VOID 0 -#define CATEGORY_A 4 -#define CATEGORY_B 8 - -// classifiction = zone | category -#define CLASSIFICATION_1A (ZONE_1 | CATEGORY_A) -#define CLASSIFICATION_1B (ZONE_1 | CATEGORY_B) -#define CLASSIFICATION_2A (ZONE_2 | CATEGORY_A) -#define CLASSIFICATION_2B (ZONE_2 | CATEGORY_B) -#define CLASSIFICATION_A CATEGORY_A -#define CLASSIFICATION_B CATEGORY_B - -#define NPATTERN 3 -#define NPATTERN_USAGE "3" - -gray lookup_pattern(int pattern, int c, int r); - -#endif /* BRUYN_COMMON_H */ diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_bruyn_sig.c --- a/Meerwald/cmp_bruyn_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,151 +0,0 @@ -#include "wm.h" -#include "signature.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-C\t\toutput correlation only\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - - int c, i; - int pattern1, pattern2; - double quality; - double threshold1, threshold2; - int blocksize; - int corr = 0, match = 0; - int verbose = 0; - int skipping = 0; - - int correlation_only = 0; - - int seed; - char line[32]; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'C': - correlation_only = 1; - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "r")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - fgets(line, sizeof(line), sig); - if (strspn(line, "BRSG") >= 4) { - fscanf(sig, "%d\n", &nbit_signature1); - fscanf(sig, "%d\n", &skipping); - fscanf(sig, "%d\n", &pattern1); - fscanf(sig, "%d\n", &pattern2); - fscanf(sig, "%lf\n", &quality); - fscanf(sig, "%lf\n", &threshold1); - fscanf(sig, "%lf\n", &threshold2); - fscanf(sig, "%d\n", &blocksize); - fscanf(sig, "%d\n", &seed); - srandom(seed); - n_signature1 = NBITSTOBYTES(nbit_signature1); - fread(signature1, sizeof(char), n_signature1, sig); - fscanf(sig, "\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); - exit(1); - } - - fgets(line, sizeof(line), in); - if (strspn(line, "BRWM") >= 4) { - fscanf(in, "%d\n", &nbit_signature2); - n_signature2 = NBITSTOBYTES(nbit_signature2); - fread(signature2, sizeof(char), n_signature2, in); - fscanf(in, "\n"); - } - else { - fprintf(stderr, "%s: invalid watermark file %s\n", progname, input_name); - exit(1); - } - - if (verbose > 0) { - fprintf(stderr, "signature length: %d\n", nbit_signature1); - fprintf(stderr, "watermark length: %d\n", nbit_signature2); - } - - for (i = 0; i < nbit_signature2; i++) - if (get_signature1_bit(i % nbit_signature1) == get_signature2_bit(i)) - corr++, match++; - else - corr--; - - if (correlation_only) - fprintf(out, "%lf\n", (double) corr / nbit_signature2); - else { - fprintf(out, "bit matches: %d/%d\n", match, nbit_signature2); - fprintf(out, "correlation: %lf\n", (double) corr / nbit_signature2); - } - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_corvi_sig.c --- a/Meerwald/cmp_corvi_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,160 +0,0 @@ -#include "wm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-C\t\toutput correlation only\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - - int c; - int sig_n, in_n; - double s1, s2, s3; - char line[32]; - int matches; - - int verbose = 0; - int correlation_only = 0; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "h?o:s:v:C")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - case 'C': - correlation_only = 1; - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "r")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (!sig) { - fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); - exit(1); - } - - fgets(line, sizeof(line), sig); - if (strspn(line, "CVSG") < 4) { - fprintf(stderr, "%s: original signature file %s invalid\n", progname, signature_name); - exit(1); - } - - fgets(line, sizeof(line), in); - if (strspn(line, "CVWM") < 4) { - fprintf(stderr, "%s: signature file %s invalid\n", progname, input_name); - exit(1); - } - - fscanf(sig, "%d\n", &sig_n); - fscanf(in, "%d\n", &in_n); - if (sig_n != in_n) { - fprintf(stderr, "%s: watermark length mismatch (original %d, input %d)\n", progname, sig_n, in_n); - exit(1); - } - if (sig_n <= 0 || sig_n > 1000) { - fprintf(stderr, "%s: invalid original watermark length %d\n", progname, sig_n); - exit(1); - } - if (in_n <= 0 || in_n > 1000) { - fprintf(stderr, "%s: invalid watermark length %d\n", progname, in_n); - exit(1); - } - - fscanf(sig, "%*f\n"); - fscanf(sig, "%*d\n"); - fscanf(sig, "%*d\n"); - fscanf(sig, "%*[^\n\r]\n"); - - /* - * normalized correlation - * Craver, S., "Can Invisible Watermarks Resolve Rightful Ownership?", IBM Research Report, 1996, p. 5 - */ - - s1 = s2 = s3 = 0.0; - matches = 0; - while (in_n > 0) { - double sig_x, in_x; - - fscanf(sig, "%lf\n", &sig_x); - fscanf(in, "%lf\n", &in_x); - - matches += SIGN(sig_x * in_x); - - if (verbose >= 1) { - fprintf(stderr, "orig %f input %f\n", sig_x, in_x); - } - - s1 += sig_x * in_x; - s2 += in_x * in_x; - s3 += sig_x * sig_x; - - in_n--; - } - - if (!correlation_only) { - fprintf(out, "%s: correlation %f, hamming distance %f\n", progname, s1 / sqrt(s2 * s3), (double) matches / sig_n); - } - else - fprintf(out, "%f\n", (double) matches / sig_n); - - fclose(sig); - fclose(out); - fclose(in); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_cox_sig.c --- a/Meerwald/cmp_cox_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,149 +0,0 @@ -#include "wm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-h] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - - int c; - int sig_n, in_n; - double sig_a; - double sig_mean, sig_variance; - double s1, s2, s3; - char line[32]; - - int verbose = 0; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "h?o:s:v:")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "r")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (!sig) { - fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); - exit(1); - } - - fgets(line, sizeof(line), sig); - if (strspn(line, "CXSG") < 4) { - fprintf(stderr, "%s: original signature file %s invalid\n", progname, signature_name); - exit(1); - } - - fgets(line, sizeof(line), in); - if (strspn(line, "CXWM") < 4) { - fprintf(stderr, "%s: watermark file %s invalid\n", progname, input_name); - exit(1); - } - - fscanf(sig, "%d\n", &sig_n); - fscanf(in, "%d\n", &in_n); - if (sig_n != in_n) { - fprintf(stderr, "%s: watermark length mismatch (original %d, input %d)\n", progname, sig_n, in_n); - exit(1); - } - if (sig_n <= 0 || sig_n > 32000) { - fprintf(stderr, "%s: invalid original watermark length %d\n", progname, sig_n); - exit(1); - } - if (in_n <= 0 || in_n > 32000) { - fprintf(stderr, "%s: invalid watermark length %d\n", progname, in_n); - exit(1); - } - - fscanf(sig, "%lf\n", &sig_a); - - fscanf(sig, "%lf\n", &sig_mean); - fscanf(sig, "%lf\n", &sig_variance); - - /* - * normalized correlation - * Craver, S., "Can Invisible Watermarks Resolve Rightful Ownership?", IBM Research Report, 1996, p. 5 - */ - - s1 = s2 = s3 = 0.0; - while (in_n > 0) { - double sig_x, in_x; - - fscanf(sig, "%lf\n", &sig_x); - fscanf(in, "%lf\n", &in_x); - - if (verbose >= 1) { - fprintf(stderr, "orig %f input %f\n", sig_x, in_x); - } - - s1 += sig_x * in_x; - s2 += in_x * in_x; - s3 += sig_x * sig_x; - - in_n--; - } - - fprintf(out, "%f\n", s1 / sqrt(s2 * s3)); - - fclose(sig); - fclose(out); - fclose(in); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_dct.1 --- a/Meerwald/cmp_dct.1 Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -.\" -.\" cmp_dct.1 - the *roff document processor man page source -.\" -.TH cmp_dct 1 "98/07/08" "Watermarking, Version 1.0" -.SH NAME -cmp_dct \- a program to create the difference image of the -frequency domain of two PGM images -.SH SYNOPSIS -.B cmp_dct -[ -.B \-h -] -[ -.BI \-m \ number -] -[ -.BI \-o \ ofile -] -.BI \-i \ ifile -.I file -.SH DESCRIPTION -.B cmp_dct -is a program to create the difference image of the -frequency domain of two PGM (portable graymap) grayscale -images. To compare images in the spatial domain, either in -PPM (portable pixmap) format for RGB color images or in PGM (portable -graymap) format for grayscale images, use the -.B cmp_ppm -program or the -.B cmp_pgm -program, respectively. -.PP -If -.I file -or -.I ofile -is not specified, then standard input or standard output is -used. -.PP -.SH OPTIONS -.TP -.B \-h -Print a help message. -.TP -.BI \-i \ ifile -The original image. Mandatory. -.TP -.BI \-m \ number -Multiplication factor to magnify differences between the to -original and input image. -Default value: 16. -.TP -.BI \-o \ ofile -Output image file to contain the difference image in PGM format. -.TP -.I file -Input image that is compared against -.I ifile. -Default: standard input. -.SH OUTPUT -The difference image in PGM format is written to standard output or, -optionally, to -.I ofile. -.SH AUTHOR -Peter Meerwald. -Email bug reports to pmeerw@cosy.sbg.ac.at. -.SH AVAILABILITY -The most recent released version of -.B cmp_dct -is always available -at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the -directory /pub/people/pmeerw/Watermarking. -.SH "SEE ALSO" -.B cmp_pgm -(1), -.B cmp_ppm -(1), -.B cmp_dct8x8 -(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_dct.c --- a/Meerwald/cmp_dct.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,198 +0,0 @@ -#include "wm.h" -#include "dct.h" -#include "gray.h" -#include "pgm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-h] [-m n] [-o file] [-pP] -i file file\n\n", progname); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-i file\t\toriginal image file\n"); - fprintf(stderr, "\t-m n\t\tmultiplication factor (default 16)\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-p\t\tprint PSNR, RMS and MSE\n"); - fprintf(stderr, "\t-P\t\tonly print PSNR, RMS and MSE, no difference image\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *orig = NULL; - - gray **input_image; - gray **orig_image; - double **input_dcts; - double **orig_dcts; - gray **output; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char orig_name[MAXPATHLEN]; - - int in_cols, in_rows, in_format; - gray in_maxval; - int orig_cols, orig_rows, orig_format; - gray orig_maxval; - int cols, rows, format; - gray maxval; - int col, row; - - int no_orig = 0; - int c; - - double error = 0.0; - int print_psnr = 0; - int print_psnr_only = 0; - int m = 16; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "h?i:m:o:pP")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'i': - if (!strcmp(optarg, "-")) { - no_orig = 1; - strcpy(orig_name, "(zero)"); - } - else { - if ((orig = fopen(optarg, "rb")) == NULL) { - fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); - exit(1); - } - strcpy(orig_name, optarg); - } - break; - case 'm': - m = atoi(optarg); - if (m <= 0) { - fprintf(stderr, "%s: multiplication factor %d out of range\n", progname, m); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'p': - print_psnr = 1; - break; - case 'P': - print_psnr_only = 1; - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (!orig && !no_orig) { - fprintf(stderr, "%s: original image file not specified, using zero image\n", progname); - strcpy(orig_name, "(zero)"); - no_orig = 1; - } - - pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); - - if (!no_orig) { - pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); - - if (in_cols != orig_cols || in_rows != orig_rows) { - fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); - exit(1); - } - } - - cols = in_cols; - rows = in_rows; - format = in_format; - maxval = in_maxval; - - input_image = pgm_allocarray(cols, rows); - orig_image = pgm_allocarray(cols, rows); - - init_dct_NxN(cols, rows); - input_dcts = alloc_coeffs(cols, rows); - orig_dcts = alloc_coeffs(cols, rows); - output = alloc_grays(cols, rows); - - if (no_orig) { - for (row = 0; row < rows; row++) { - pgm_readpgmrow(in, input_image[row], cols, maxval, format); - bzero(orig_image[row], sizeof(gray) * cols); - } - } - else { - for (row = 0; row < rows; row++) { - pgm_readpgmrow(in, input_image[row], cols, maxval, format); - pgm_readpgmrow(orig, orig_image[row], cols, maxval, format); - } - } - - fclose(in); - if (!no_orig) - fclose(orig); - - fdct_NxN(input_image, input_dcts); - fdct_NxN(orig_image, orig_dcts); - - for (row = 0; row < rows; row++) - for (col = 0; col < cols; col++) { - error += sqr(input_dcts[row][col] - orig_dcts[row][col]); - output[row][col] = PIXELRANGE(fabs(input_dcts[row][col] - orig_dcts[row][col]) * m); - } - - if (!print_psnr_only) { - pgm_writepgminit(out, cols, rows, maxval, 0); - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, output[row], cols, maxval, 0); - - fclose(out); - } - - pgm_freearray(input_image, rows); - pgm_freearray(orig_image, rows); - free_coeffs(input_dcts); - free_coeffs(orig_dcts); - free_grays(output); - - if (print_psnr || print_psnr_only) { - double mse = error / (double) (cols * rows); - double rmse = sqrt(mse); - double psnr = 20.0 * log(255.0 / rmse) / log(10.0); - FILE *print = print_psnr_only ? out : stderr; - if (mse > 0.0) - fprintf(print, "PSNR: %lf dB\n", psnr); - else - fprintf(print, "PSNR: inf\n"); - fprintf(print, "RMS: %lf\n", rmse); - fprintf(print, "MSE: %lf\n", mse); - } - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_dct8x8.1 --- a/Meerwald/cmp_dct8x8.1 Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -.\" -.\" cmp_dct8x8.1 - the *roff document processor man page source -.\" -.TH cmp_dct8x8 1 "98/07/08" "Watermarking, Version 1.0" -.SH NAME -cmp_dct8x8 \- a program to create the difference image of the -8x8 DCT blocks of two PGM images -.SH SYNOPSIS -.B cmp_dct8x8 -[ -.B \-h -] -[ -.BI \-m \ number -] -[ -.BI \-o \ ofile -] -.BI \-i \ ifile -.I file -.SH DESCRIPTION -.B cmp_dct8x8 -is a program to create the difference image of the 8x8 DCT blocks -(frequency domain) of two PGM (portable graymap) grayscale -images. To compare images in the spatial domain, either in -PPM (portable pixmap) format for RGB color images or in PGM (portable -graymap) format for grayscale images, use the -.B cmp_ppm -program or the -.B cmp_pgm -program, respectively. -.PP -If -.I file -or -.I ofile -is not specified, then standard input or standard output is -used. -.PP -.SH OPTIONS -.TP -.B \-h -Print a help message. -.TP -.BI \-i \ ifile -The original image. Mandatory. -.TP -.BI \-m \ number -Multiplication factor to magnify differences between the to -original and input image. -Default value: 16. -.TP -.BI \-o \ ofile -Output image file to contain the difference image in PGM format. -.TP -.I file -Input image that is compared against -.I ifile. -Default: standard input. -.SH OUTPUT -The difference image in PGM format is written to standard output or, -optionally, to -.I ofile. -.SH AUTHOR -Peter Meerwald. -Email bug reports to pmeerw@cosy.sbg.ac.at. -.SH AVAILABILITY -The most recent released version of -.B cmp_dct8x8 -is always available -at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the -directory /pub/people/pmeerw/Watermarking. -.SH "SEE ALSO" -.B cmp_pgm -(1), -.B cmp_ppm -(1), -.B cmp_dct -(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_dct8x8.c --- a/Meerwald/cmp_dct8x8.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,199 +0,0 @@ -#include "wm.h" -#include "dct.h" -#include "gray.h" -#include "pgm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-h] [-m n] [-o file] [-pP] -i file file\n\n", progname); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-i file\t\toriginal image file\n"); - fprintf(stderr, "\t-m n\t\tmultiplication factor (default 16)\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-p\t\tprint PSNR, RMS and MSE\n"); - fprintf(stderr, "\t-P\t\tonly print PSNR, RMS and MSE, no difference image\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *orig = NULL; - - gray **input_image; - gray **orig_image; - double **input_dcts; - double **orig_dcts; - gray **output; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char orig_name[MAXPATHLEN]; - - int in_cols, in_rows, in_format; - gray in_maxval; - int orig_cols, orig_rows, orig_format; - gray orig_maxval; - int cols, rows, format; - gray maxval; - int col, row; - - int i, j; - int c; - - int m = 16; - - int print_psnr = 0; - int print_psnr_only = 0; - double error = 0.0; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "h?i:m:o:pP")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'i': - if ((orig = fopen(optarg, "rb")) == NULL) { - fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); - exit(1); - } - strcpy(orig_name, optarg); - break; - case 'm': - m = atoi(optarg); - if (m <= 0) { - fprintf(stderr, "%s: multiplication factor %d out of range\n", progname, m); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'p': - print_psnr = 1; - break; - case 'P': - print_psnr_only = 1; - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (!orig) { - fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); - - pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); - - if (in_cols != orig_cols || in_rows != orig_rows) { - fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); - exit(1); - } - - cols = in_cols; - rows = in_rows; - format = in_format; - maxval = in_maxval; - - if (cols % NJPEG) { - fprintf(stderr, "%s: image width %d not a multiple of %d\n", progname, cols, NJPEG); - exit(1); - } - - if (rows % NJPEG) { - fprintf(stderr, "%s: image height %d not a multiple of %d\n", progname, rows, NJPEG); - exit(1); - } - - input_image = pgm_allocarray(cols, NJPEG); - orig_image = pgm_allocarray(cols, NJPEG); - - init_dct_8x8(); - input_dcts = alloc_coeffs_8x8(); - orig_dcts = alloc_coeffs_8x8(); - output = alloc_grays(cols, NJPEG); - - if (!print_psnr_only) - pgm_writepgminit(out, cols, rows, maxval, 0); - - for (row = 0; row < rows; row += NJPEG) { - - for (i = 0; i < NJPEG; i++) { - pgm_readpgmrow(in, input_image[row % NJPEG], cols, maxval, format); - pgm_readpgmrow(orig, orig_image[row % NJPEG], cols, maxval, format); - } - - for (col = 0; col < cols; col += NJPEG) { - fdct_block_8x8(input_image, col, 0, input_dcts); - fdct_block_8x8(orig_image, col, 0, orig_dcts); - - for (i = 0; i < NJPEG; i++) { - for (j = 0; j < NJPEG; j++) { - error += sqr(input_dcts[j][i + cols] - orig_dcts[j][i + cols]); - output[j][i + col] = PIXELRANGE(fabs(input_dcts[j][i + cols] - orig_dcts[j][i + cols]) * m); - } - } - } - - if (!print_psnr_only) { - for (i = 0; i < NJPEG; i++) - pgm_writepgmrow(out, output[i], cols, maxval, 0); - } - - } - fclose(in); - fclose(orig); - if (!print_psnr_only) - fclose(out); - - pgm_freearray(input_image, NJPEG); - pgm_freearray(orig_image, NJPEG); - free_coeffs(input_dcts); - free_coeffs(orig_dcts); - free_grays(output); - - if (print_psnr || print_psnr_only) { - double mse = error / (double) (cols * rows); - double rmse = sqrt(mse); - double psnr = 20.0 * log(255.0 / rmse) / log(10.0); - FILE *print = print_psnr_only ? out : stderr; - if (mse > 0.0) - fprintf(print, "PSNR: %lf dB\n", psnr); - else - fprintf(print, "PSNR: inf\n"); - fprintf(print, "RMS: %lf\n", rmse); - fprintf(print, "MSE: %lf\n", mse); - } - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_dugad_sig.c --- a/Meerwald/cmp_dugad_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,149 +0,0 @@ -#include "wm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-h] [-s file] [-C] [-o file] [-v] file\n\n", progname); - fprintf(stderr, "\t-C\t\toutput correlation only\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-s file\t\tignored\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - - int c, i, n, ok; - int levels; - double alpha; - double diff; - char line[32]; - - int correlation_only = 0; - int verbose = 0; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "h?Co:v:s:")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'C': - correlation_only = 1; - break; - case 's': - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "r")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - fgets(line, sizeof(line), in); - if (strspn(line, "DGWM") < 4) { - fprintf(stderr, "%s: watermark file %s invalid\n", progname, input_name); - exit(1); - } - - fscanf(in, "%d\n", &levels); - fscanf(in, "%lf\n", &alpha); - - n = 3 * levels; - ok = 0; - diff = 0.0; - for (i = 0; i < levels; i++) { - int m; - double z, v; - - // HL subband - fscanf(in, "%d %lf %lf\n", &m, &z, &v); - if (verbose && !correlation_only) { - if (m) - fprintf(out, "%f %f\n", z / (double) m, (v * alpha) / (double) (1.0 * m)); - else - fprintf(out, "0.0 0.0\n"); - } - if (m) { - ok += (z > v * alpha / (double) 1.0) ? 1 : 0; - diff += ((z - v * alpha) / (double) (1.0 * m)); - } - else - n--; - - // LH subband - fscanf(in, "%d %lf %lf\n", &m, &z, &v); - if (verbose && !correlation_only) { - if (m) - fprintf(out, "%f %f\n", z / (double) m, (v * alpha) / (double) (1.0 * m)); - else - fprintf(out, "0.0 0.0\n"); - } - if (m) { - ok += (z > v * alpha / (double) 1.0) ? 1 : 0; - diff += ((z - v * alpha) / (double) (1.0 * m)); - } - else - n--; - - // HH subband - fscanf(in, "%d %lf %lf\n", &m, &z, &v); - if (verbose && !correlation_only) { - if (m) - fprintf(out, "%f %f\n", z / (double) m, (v * alpha) / (double) (1.0 * m)); - else - fprintf(out, "0.0 0.0\n"); - } - - if (m) { - ok += (z > v * alpha / (double) 1.0) ? 1 : 0; - diff += ((z - v * alpha) / (double) (1.0 * m)); - } - else - n--; - } - - if (!correlation_only) - fprintf(out, "%d/%d, diff %f\n", ok, n, diff); - fprintf(out, "%f\n", (double) ok / (double) n); - - fclose(out); - fclose(in); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_dwt.c --- a/Meerwald/cmp_dwt.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,389 +0,0 @@ -#include "wm.h" -#include "dwt.h" -#include "coeff.h" -#include "gray.h" -#include "pgm.h" -#include "dwt_util.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-e n] [-f n] [-F file] [-h] [-l n] [-o file] [-pP] [-s name,..] -i file file\n\n", progname); - fprintf(stderr, "\t-e n\t\twavelet filtering method (default: 2)\n"); - fprintf(stderr, "\t-f n\t\tfilter number (default: 2)\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file (default: filter.dat\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-i file\t\toriginal image file\n"); - fprintf(stderr, "\t-l n\t\tmax. decomposition level (default: 0 = max)\n"); - fprintf(stderr, "\t-m n\t\tmultiplication factor (default: 0 = auto)\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-p\t\tprint PSNR, RMS and MSE\n"); - fprintf(stderr, "\t-P\t\tonly print PSNR, RMS and MSE, no difference image\n"); - fprintf(stderr, "\t-q\t\tprint PSNR, RMS and MSE per subband\n"); - fprintf(stderr, "\t-s name,...\tsubband/level (default: all subbands)\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -void process_subband_var(gray **output, int cols, int rows, Image_tree p, Image_tree q, int type, double min, double max, gray maxval) { - int col, row, startcol, startrow; - - if (!p || !q) return; - - calc_subband_location(cols, rows, type, p->level, &startcol, &startrow); - - for (row = 0; row < p->image->height; row++) - for (col = 0; col < p->image->width; col++) { - double diff = fabs(get_pixel(p->image, col, row) - get_pixel(q->image, col, row)); - output[startrow + row][startcol + col] = PIXELRANGE((double) (diff - min) / (double) (max - min) * maxval); - } -} - -void process_subband_fixed(gray **output, int cols, int rows, Image_tree p, Image_tree q, int type, double m) { - int col, row, startcol, startrow; - - if (!p || !q) return; - - calc_subband_location(cols, rows, type, p->level, &startcol, &startrow); - - for (row = 0; row < p->image->height; row++) - for (col = 0; col < p->image->width; col++) { - double diff = fabs(get_pixel(p->image, col, row) - get_pixel(q->image, col, row)); - output[startrow + row][startcol + col] = PIXELRANGE(diff * m); - } -} - -void print_subband_psnr(int type, int level, double error, int cols, int rows, double min, double max, FILE *print) { - double mse = error / (double) (cols * rows); - double rmse = sqrt(mse); - double psnr = 20.0 * log(255.0 / rmse) / log(10.0); - int startcol, startrow; - - calc_subband_location(cols << level, rows << level, type, level, &startcol, &startrow); - fprintf(print, "%s%d (%d x %d) at %d x %d\n", subband_name(type), level, cols, rows, startcol, startrow); - if (mse > 0.0) - fprintf(print, " PSNR: %lf dB\n", psnr); - else - fprintf(print, " PSNR: inf\n"); - fprintf(print, " RMS: %lf\n", rmse); - fprintf(print, " MSE: %lf\n", mse); - fprintf(print, " dmin, dmax: %lf, %lf\n", min, max); -} - -int main(int argc, char *argv[]) { - FILE *in = stdin; - FILE *out = stdout; - FILE *orig = NULL; - FILE *print; - - gray **input_image; - gray **orig_image; - Image_tree input_dwts, p; - Image_tree orig_dwts, q; - gray **output; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char orig_name[MAXPATHLEN]; - char *subband_list = NULL; - - int in_cols, in_rows, in_format; - gray in_maxval; - int orig_cols, orig_rows, orig_format; - gray orig_maxval; - int cols, rows, format; - gray maxval; - int row; - - int no_orig = 0; - int m = 0; - int c; - int maxlevel = 0; - - int filter = 1; - int method = 2; - int levels; - char filter_name[MAXPATHLEN] = "filter.dat"; - - double error = 0.0; - int print_psnr = 0; - int print_psnr_subband = 0; - int print_psnr_only = 0; - - double min, max; - - int verbose = 0; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "e:f:F:h?i:l:m:o:pPqs:v:")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'i': - if (!strcmp(optarg, "-")) { - no_orig = 1; - strcpy(orig_name, "(zero)"); - } - else { - if ((orig = fopen(optarg, "rb")) == NULL) { - fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); - exit(1); - } - strcpy(orig_name, optarg); - } - break; - case 'l': - maxlevel = atoi(optarg); - if (maxlevel < 0) { - fprintf(stderr, "%s: decomposition level %d out of range\n", progname, maxlevel); - exit(1); - } - break; - case 'm': - m = atoi(optarg); - if (m < -1) { - fprintf(stderr, "%s: multiplication factor %d out of range\n", progname, m); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'p': - print_psnr = 1; - break; - case 'P': - print_psnr_only = 1; - break; - case 'q': - print_psnr = 1; - print_psnr_subband = 1; - case 's': - subband_list = optarg; - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - print = print_psnr_only ? out : stderr; - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (!orig && !no_orig) { - fprintf(stderr, "%s: original image file not specified, using zero image\n", progname); - strcpy(orig_name, "(zero)"); - no_orig = 1; - } - - pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); - - if (!no_orig) { - pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); - if (in_cols != orig_cols || in_rows != orig_rows) { - fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); - exit(1); - } - } - - cols = in_cols; - rows = in_rows; - format = in_format; - maxval = in_maxval; - - input_image = pgm_allocarray(cols, rows); - orig_image = pgm_allocarray(cols, rows); - - output = alloc_grays(cols, rows); - - if (no_orig) { - for (row = 0; row < rows; row++) { - pgm_readpgmrow(in, input_image[row], cols, maxval, format); - bzero(orig_image[row], sizeof(gray) * cols); - } - } - else { - for (row = 0; row < rows; row++) { - pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); - pgm_readpgmrow(orig, orig_image[row], orig_cols, orig_maxval, orig_format); - } - } - - fclose(in); - if (!no_orig) - fclose(orig); - - // complete decomposition - levels = find_deepest_level(cols, rows) - 1; - if (!maxlevel) maxlevel = levels; - if (maxlevel > levels) { - fprintf(stderr, "%s: decomposition level %d not possible (max. %d), image size is %d x %d\n", progname, maxlevel, levels, cols, rows); - exit(1); - } - - init_dwt(cols, rows, filter_name, filter, maxlevel, method); - - input_dwts = fdwt(input_image); - orig_dwts = fdwt(orig_image); - - p = input_dwts; - q = orig_dwts; - min = 10000000.0; - max = 0.0; - error = 0.0; - while (p->coarse && q->coarse) { - double localmin, localmax, localerror; - - if (subband_in_list(subband_list, HORIZONTAL, p->horizontal->level)) { - calc_subband(p->horizontal, q->horizontal, HORIZONTAL, &localmin, &localmax, &localerror); - if (m == -1) process_subband_var(output, cols, rows, p->horizontal, q->horizontal, HORIZONTAL, localmin, localmax, maxval); - if (localmin < min) min = localmin; - if (localmax > max) max = localmax; - error += localerror; - if (print_psnr_subband) - print_subband_psnr(HORIZONTAL, p->horizontal->level, error, p->horizontal->image->width, p->horizontal->image->height, localmin, localmax, print); - } - else if (verbose > 5) - fprintf(stderr, "%s: subband %s%d skipped\n", progname, subband_name(HORIZONTAL), p->horizontal->level); - - if (subband_in_list(subband_list, VERTICAL, p->vertical->level)) { - calc_subband(p->vertical, q->vertical, VERTICAL, &localmin, &localmax, &localerror); - if (m == -1) process_subband_var(output, cols, rows, p->vertical, q->vertical, VERTICAL, localmin, localmax, maxval); - if (localmin < min) min = localmin; - if (localmax > max) max = localmax; - error += localerror; - if (print_psnr_subband) - print_subband_psnr(VERTICAL, p->vertical->level, error, p->vertical->image->width, p->vertical->image->height, localmin, localmax, print); - } - else if (verbose > 5) - fprintf(stderr, "%s: subband %s%d skipped\n", progname, subband_name(VERTICAL), p->vertical->level); - - if (subband_in_list(subband_list, DIAGONAL, p->diagonal->level)) { - calc_subband(p->diagonal, q->diagonal, DIAGONAL, &localmin, &localmax, &localerror); - if (m == -1) process_subband_var(output, cols, rows, p->diagonal, q->diagonal, DIAGONAL, localmin, localmax, maxval); - if (localmin < min) min = localmin; - if (localmax > max) max = localmax; - error += localerror; - if (print_psnr_subband) - print_subband_psnr(DIAGONAL, p->vertical->level, error, p->diagonal->image->width, p->diagonal->image->height, localmin, localmax, print); - } - else if (verbose > 5) - fprintf(stderr, "%s: subband %s%d skipped\n", progname, subband_name(DIAGONAL), p->diagonal->level); - - p = p->coarse; - q = q->coarse; - - if (!p->coarse) { - if (subband_in_list(subband_list, COARSE, p->level)) { - calc_subband(p, q, COARSE, &localmin, &localmax, &localerror); - if (m == -1) process_subband_var(output, cols, rows, p, q, COARSE, localmin, localmax, maxval); - if (localmin < min) min = localmin; - if (localmax > max) max = localmax; - error += localerror; - if (print_psnr_subband) - print_subband_psnr(COARSE, p->level, error, p->image->width, p->image->height, localmin, localmax, print); - } - else if (verbose > 5) - fprintf(stderr, "%s: subband %s%d skipped\n", progname, subband_name(COARSE), p->level); - } - } - - p = input_dwts; - q = orig_dwts; - while (p->coarse && q->coarse) { - if (m > 0) { - process_subband_fixed(output, cols, rows, p->horizontal, q->horizontal, HORIZONTAL, m); - process_subband_fixed(output, cols, rows, p->vertical, q->vertical, VERTICAL, m); - process_subband_fixed(output, cols, rows, p->diagonal, q->diagonal, DIAGONAL, m); - } - else if (m == 0) { - process_subband_var(output, cols, rows, p->horizontal, q->horizontal, HORIZONTAL, min, max, maxval); - process_subband_var(output, cols, rows, p->vertical, q->vertical, VERTICAL, min, max, maxval); - process_subband_var(output, cols, rows, p->diagonal, q->diagonal, DIAGONAL, min, max, maxval); - } - - p = p->coarse; - q = q->coarse; - - if (!p->coarse) { - if (m > 0) - process_subband_fixed(output, cols, rows, p, q, COARSE, m); - else if (m == 0) - process_subband_var(output, cols, rows, p, q, COARSE, min, max, maxval); - } - } - - if (!print_psnr_only) { - pgm_writepgminit(out, cols, rows, maxval, 0); - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, output[row], cols, maxval, 0); - - fclose(out); - } - - pgm_freearray(input_image, rows); - pgm_freearray(orig_image, rows); - free_grays(output); - - if (print_psnr || print_psnr_only) { - double mse = error / (double) (cols * rows); - double rmse = sqrt(mse); - double psnr = 20.0 * log(255.0 / rmse) / log(10.0); - if (mse > 0.0) - fprintf(print, "PSNR: %lf dB\n", psnr); - else - fprintf(print, "PSNR: inf\n"); - fprintf(print, "RMS: %lf\n", rmse); - fprintf(print, "MSE: %lf\n", mse); - fprintf(print, "dmin, dmax: %lf, %lf\n", min, max); - } - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_frid2_sig.c --- a/Meerwald/cmp_frid2_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,153 +0,0 @@ -#include "wm.h" -#include "signature.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-C\t\toutput correlation only\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - - int correlation_only = 0; - - int c, i; - int corr1 = 0, match1 = 0; - int corr2 = 0, match2 = 0; - int verbose = 0; - - char line[1024]; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'C': - correlation_only = 1; - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "r")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - fgets(line, sizeof(line), sig); - if (strspn(line, "FR2SG") >= 5) { - fscanf(sig, "%d\n", &nbit_signature); - fscanf(sig, "%*f\n"); - fscanf(sig, "%*f\n"); - fscanf(sig, "%*d\n"); - n_signature = NBITSTOBYTES(nbit_signature); - fread(signature, sizeof(char), n_signature, sig); - fscanf(sig, "\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); - exit(1); - } - - fgets(line, sizeof(line), in); - if (strspn(line, "FR2WM") >= 5) { - fscanf(in, "%d\n", &nbit_signature1); - n_signature1 = NBITSTOBYTES(nbit_signature1); - fread(signature1, sizeof(char), n_signature1, in); -// fscanf(in, "\n"); - fscanf(in, "%d\n", &nbit_signature2); - n_signature2 = NBITSTOBYTES(nbit_signature2); - fread(signature2, sizeof(char), n_signature2, in); - fscanf(in, "\n"); - } - else { - fprintf(stderr, "%s: invalid watermark file %s\n", progname, input_name); - exit(1); - } - - if (verbose > 0) { - fprintf(stderr, "signature length: %d\n", nbit_signature); - fprintf(stderr, "watermark length (low. freq.): %d\n", nbit_signature1); - fprintf(stderr, "watermark length (med. freq.): %d\n", nbit_signature2); - } - - for (i = 0; i < nbit_signature; i++) { - if (get_signature_bit(i) == get_signature1_bit(i)) - corr1++, match1++; - else - corr1--; - if (get_signature_bit(i) == get_signature2_bit(i)) - corr2++, match2++; - else - corr2--; - } - - if (correlation_only) - fprintf(out, "%lf\n", (double) (corr1 + corr2) / (nbit_signature1 + nbit_signature2)); - else { - fprintf(out, "bit matches (low freq.): %d/%d\n", match1, nbit_signature1); - fprintf(out, "correlation (low. freq.): %lf\n", (double) corr1 / nbit_signature1); - fprintf(out, "bit matches (med. freq.): %d/%d\n", match2, nbit_signature2); - fprintf(out, "correlation (med. freq.): %lf\n", (double) corr2 / nbit_signature2); - fprintf(out, "total correlation: %lf\n", (double) (corr1 + corr2) / (nbit_signature1 + nbit_signature2)); - } - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_kim_sig.c --- a/Meerwald/cmp_kim_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,165 +0,0 @@ -#include "wm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-C\t\toutput correlation only\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - - int c, i; - int in_level; - double *input_watermark, *orig_watermark; - int sig_n, in_n; - double sig_a; - double sig_A; - int sig_l; - int sig_e, sig_f; - double s1, s2, s3; - double correlation; - char line[32]; - - int verbose = 0; - int correlation_only = 0; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'C': - correlation_only = 1; - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "r")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (!sig) { - fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); - exit(1); - } - - fgets(line, sizeof(line), sig); - if (strspn(line, "KISG") < 4) { - fprintf(stderr, "%s: original signature file %s invalid\n", progname, signature_name); - exit(1); - } - - fgets(line, sizeof(line), in); - if (strspn(line, "KIWM") < 4) { - fprintf(stderr, "%s: watermark file %s invalid\n", progname, input_name); - exit(1); - } - - fscanf(sig, "%d\n", &sig_n); - fscanf(in, "%d\n", &in_n); - - if (sig_n <= 0 || sig_n > 32000) { - fprintf(stderr, "%s: invalid original watermark length %d\n", progname, sig_n); - exit(1); - } - - fscanf(sig, "%lf\n", &sig_a); - fscanf(sig, "%lf\n", &sig_A); - fscanf(sig, "%d\n", &sig_l); - fscanf(sig, "%d\n", &sig_e); - fscanf(sig, "%d\n", &sig_f); - fscanf(sig, "%*[^\n\r]\n"); - - orig_watermark = malloc(sig_n * sizeof(double)); - for (i = 0; i < sig_n; i++) - fscanf(sig, "%lf\n", &orig_watermark[i]); - fclose(sig); - - fscanf(in, "%d\n", &in_level); - input_watermark = malloc(in_n * sizeof(double)); - for (i = 0; i < in_n; i++) - fscanf(in, "%lf\n", &input_watermark[i]); - fclose(in); - - /* - * normalized correlation - * Craver, S., "Can Invisible Watermarks Resolve Rightful Ownership?", IBM Research Report, 1996, p. 5 - */ - - s1 = s2 = s3 = 0.0; - for (i = 0; i < in_n; i++) { - double in_x, sig_x; - - in_x = input_watermark[i]; - sig_x = orig_watermark[i % sig_n]; - - s1 += sig_x * in_x; - s2 += in_x * in_x; - s3 += sig_x * sig_x; - } - - correlation = s1 / sqrt(s2 * s3); - - if (!correlation_only) - fprintf(out, "%s: correlation: %f\n", progname, correlation); - else - fprintf(out, "%f\n", correlation); - - fclose(out); - - free(orig_watermark); - free(input_watermark); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_koch_sig.c --- a/Meerwald/cmp_koch_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,152 +0,0 @@ -#include "wm.h" -#include "signature.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-C\t\toutput correlation only\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - - int c, i; - double quality = 0.0; - int quantization = 0; - int corr = 0, match = 0; - int verbose = 0; - - int correlation_only = 0; - - int seed; - char line[32]; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'C': - correlation_only = 1; - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "r")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - fgets(line, sizeof(line), sig); - if (strspn(line, "KCSG") >= 4) { - fscanf(sig, "%d\n", &nbit_signature1); - fscanf(sig, "%lf\n", &quality); - fscanf(sig, "%d\n", &quantization); - fscanf(sig, "%d\n", &seed); - srandom(seed); - n_signature1 = NBITSTOBYTES(nbit_signature1); - fread(signature1, sizeof(char), n_signature1, sig); - fscanf(sig, "\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); - exit(1); - } - - fgets(line, sizeof(line), in); - if (strspn(line, "KCWM") >= 4) { - fscanf(in, "%d\n", &nbit_signature2); - n_signature2 = NBITSTOBYTES(nbit_signature2); - fread(signature2, sizeof(char), n_signature2, in); - fscanf(in, "\n"); - } - else { - fprintf(stderr, "%s: invalid watermark file %s\n", progname, input_name); - exit(1); - } - - if (verbose > 0) { - fprintf(stderr, "signature length: %d\n", nbit_signature1); - fprintf(stderr, "watermark length: %d\n", nbit_signature2); - } - - for (i = 0; i < nbit_signature2; i++) - if (get_signature1_bit(i % nbit_signature1) == get_signature2_bit(i)) - corr++, match++; - else - corr--; - - if (verbose > 1) { - for (i = 0; i < nbit_signature2; i++) - fprintf(stderr, "%d", get_signature1_bit(i % nbit_signature1)); - fprintf(stderr, "\n"); - for (i = 0; i < nbit_signature2; i++) - fprintf(stderr, "%d", get_signature2_bit(i)); - fprintf(stderr, "\n"); - } - - if (correlation_only) - fprintf(out, "%lf\n", (double) corr / nbit_signature2); - else { - fprintf(out, "bit matches: %d/%d\n", match, nbit_signature2); - fprintf(out, "correlation: %lf\n", (double) corr / nbit_signature2); - } - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_kund2_sig.c --- a/Meerwald/cmp_kund2_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,214 +0,0 @@ -#include "wm.h" -#include "signature.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-C\t\toutput correlation only\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - - char *binstr; - - int correlation_only = 0; - - int c, i; - int quality = 0; - int blocksize = 0; - int corr = 0, match = 0; - int verbose = 0; - int filter = 0; - int method = 0; - int level = 0; - char filter_name[MAXPATHLEN] = ""; - int k; - - int seed; - char line[32]; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'C': - correlation_only = 1; - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "r")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - fgets(line, sizeof(line), sig); - if (strspn(line, "KD2SG") >= 5) { - fscanf(sig, "%d\n", &nbit_signature1); - fscanf(sig, "%d\n", &quality); - fscanf(sig, "%d\n", &blocksize); - fscanf(sig, "%d\n", &method); - fscanf(sig, "%d\n", &filter); - fscanf(sig, "%[^\n\r]\n", filter_name); - fscanf(sig, "%d\n", &level); - fscanf(sig, "%d\n", &seed); - srandom(seed); - n_signature1 = NBITSTOBYTES(nbit_signature1); - - binstr = malloc((nbit_signature1 + 1) * sizeof(char)); - fscanf(sig, "%[01]\n", binstr); - binstr_to_sig1(binstr); - free(binstr); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); - exit(1); - } - - fgets(line, sizeof(line), in); - if (strspn(line, "KD2WM") >= 5) { - int max_nbit_signature; - int min_nbit_signature = -1; - double pe[100]; - double pe_sum; - double alpha[100]; - char *w[100]; - - fscanf(in, "%d\n", &max_nbit_signature); - - k = 0; - while (!feof(in) && k < 100) { - int e; - - fscanf(in, "%d\n", &nbit_signature2); - w[k] = binstr = malloc(sizeof(char) * (nbit_signature2 + 1)); - fscanf(in, "%[01]\n", binstr); - - binstr_to_sig2(binstr); - - if (nbit_signature2 < min_nbit_signature || min_nbit_signature == -1) - min_nbit_signature = nbit_signature2; - e = 0; - for (i = 0; i < nbit_signature2; i += 2) { - if (get_signature1_bit(i % nbit_signature1) != get_signature2_bit(i)) - e++; - } - if (e > 0) - pe[k++] = log( (1 - (e / (double) nbit_signature2)) / (e / (double) nbit_signature2)); - else - pe[k++] = 0; - } - - pe_sum = 0.0; - for (i = 0; i < k; i++) { -// fprintf(stderr, "XXX pe[%d] = %f\n", i, pe[i]); - pe_sum += pe[i]; - } - - for (i = 0; i < k; i++) { - if (pe_sum != 0) - alpha[i] = pe[i] / pe_sum; - else - alpha[i] = 1.0; - } - - nbit_signature = min_nbit_signature; - for (i = 0; i < min_nbit_signature; i++) { - double s = 0.0; - int j; - - for (j = 0; j < k; j++) { - int bit; -//fprintf(stderr, "XXX %d %d\n", i, j); - binstr_to_sig2(w[j]); - bit = get_signature2_bit(i) ? 1 : -1; - s += alpha[j] * bit; - } -// fprintf(stderr, "YYY %d %f\n", i, s); - set_signature_bit(i, s > 0 ? 1 : 0); - } - } - else { - fprintf(stderr, "%s: invalid watermark file %s\n", progname, input_name); - exit(1); - } - - if (verbose > 0) { - fprintf(stderr, "signature length: %d\n", nbit_signature1); - fprintf(stderr, "watermark length: %d\n", nbit_signature); - } - - for (i = 0; i < nbit_signature; i++) - if (get_signature1_bit(i % nbit_signature1) == get_signature2_bit(i)) - corr++, match++; - else - corr--; - - if (correlation_only) - fprintf(out, "%lf\n", (double) corr / nbit_signature2); - else { - fprintf(stderr, "redundant blocks: %d\n", k); - fprintf(out, "bit matches: %d/%d\n", match, nbit_signature2); - fprintf(out, "correlation: %lf\n", (double) corr / nbit_signature2); - } - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_kund3_sig.c --- a/Meerwald/cmp_kund3_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ -#include "wm.h" -#include "signature.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-C\t\toutput correlation only\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - - char *binstr1; - char *binstr2; - - int correlation_only = 0; - - int c, i; - int quality = 0; - int corr = 0, match = 0; - int verbose = 0; - int filter = 0; - int method = 0; - int level = 0; - char filter_name[MAXPATHLEN] = ""; - - int seed; - char line[32]; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'C': - correlation_only = 1; - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "r")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - fgets(line, sizeof(line), sig); - if (strspn(line, "KD3SG") >= 5) { - fscanf(sig, "%d\n", &nbit_signature1); - fscanf(sig, "%d\n", &quality); - fscanf(sig, "%d\n", &method); - fscanf(sig, "%d\n", &filter); - fscanf(sig, "%[^\n\r]\n", filter_name); - fscanf(sig, "%d\n", &level); - fscanf(sig, "%d\n", &seed); - srandom(seed); - n_signature1 = NBITSTOBYTES(nbit_signature1); - - binstr1 = malloc((nbit_signature1 + 1) * sizeof(char)); - fscanf(sig, "%[01]\n", binstr1); - binstr_to_sig1(binstr1); - free(binstr1); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); - exit(1); - } - - fgets(line, sizeof(line), in); - if (strspn(line, "KD3WM") >= 5) { - fscanf(in, "%d\n", &nbit_signature2); - n_signature2 = NBITSTOBYTES(nbit_signature2); - binstr2 = malloc((nbit_signature2 + 1) * sizeof(char)); - fscanf(in, "%[01]\n", binstr2); - binstr_to_sig2(binstr2); - free(binstr2); - } - else { - fprintf(stderr, "%s: invalid watermark file %s\n", progname, input_name); - exit(1); - } - - if (verbose > 0) { - fprintf(stderr, "signature length: %d\n", nbit_signature1); - fprintf(stderr, "watermark length: %d\n", nbit_signature2); - } - - for (i = 0; i < nbit_signature2; i++) - if (get_signature1_bit(i % nbit_signature1) == get_signature2_bit(i)) - corr++, match++; - else - corr--; - - if (correlation_only) - fprintf(out, "%lf\n", (double) corr / nbit_signature2); - else { - fprintf(out, "bit matches: %d/%d\n", match, nbit_signature2); - fprintf(out, "correlation: %lf\n", (double) corr / nbit_signature2); - } - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_kund_sig.c --- a/Meerwald/cmp_kund_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -int main(int argc, char *argv[]) { -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_pgm.1 --- a/Meerwald/cmp_pgm.1 Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -.\" -.\" cmp_pgm.1 - the *roff document processor man page source -.\" -.TH cmp_pgm 1 "98/07/08" "Watermarking, Version 1.0" -.SH NAME -cmp_pgm \- a program to create the difference image of two PGM images -.SH SYNOPSIS -.B cmp_pgm -[ -.B \-h -] -[ -.BI \-m \ number -] -[ -.BI \-o \ ofile -] -.BI \-i \ ifile -.I file -.SH DESCRIPTION -.B cmp_pgm -is a program to create the difference image of two PGM (portable graymap) -grayscale images. To compare PPM (portable pixmap) RGB color images, use the -.B cmp_ppm -program. -.PP -If -.I file -or -.I ofile -is not specified, then standard input or standard output is -used. -.PP -.SH OPTIONS -.TP -.B \-h -Print a help message. -.TP -.BI \-i \ ifile -The original image. Mandatory. -.TP -.BI \-m \ number -Multiplication factor to magnify differences between the to -original and input image. -Default value: 16. -.TP -.BI \-o \ ofile -Output image file to contain the difference image in PGM format. -.TP -.I file -Input image that is compared against -.I ifile. -Default: standard input. -.SH OUTPUT -The difference image in PGM format is written to standard output or, -optionally, to -.I ofile. -.SH AUTHOR -Peter Meerwald. -Email bug reports to pmeerw@cosy.sbg.ac.at. -.SH AVAILABILITY -The most recent released version of -.B cmp_pgm -is always available -at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the -directory /pub/people/pmeerw/Watermarking. -.SH "SEE ALSO" -.B cmp_ppm -(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_pgm.c --- a/Meerwald/cmp_pgm.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,202 +0,0 @@ -#include "wm.h" -#include "pgm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-C] [-h] [-m n] [-o file] [-pP] -i file file\n\n", progname); - fprintf(stderr, "\t-C\t\tprint PSNR value only\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-i file\t\toriginal image file\n"); - fprintf(stderr, "\t-m n\t\tmultiplication factor (default auto)\n"); - fprintf(stderr, "\t-o file\t\toutput file for difference image\n"); - fprintf(stderr, "\t-p\t\tprint PSNR, RMS and MSE\n"); - fprintf(stderr, "\t-P\t\tonly print PSNR, RMS and MSE, no difference image\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *orig = NULL; - - gray **input_image; - gray **orig_image; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char orig_name[MAXPATHLEN]; - - int in_cols, in_rows, in_format; - gray in_maxval; - int orig_cols, orig_rows, orig_format; - gray orig_maxval; - int cols, rows; - gray maxval; - int col, row; - - int c; - - int m = 0; - int min, max; - - int print_psnr = 0; - int print_psnr_only = 0; - int print_psnr_value_only = 0; - double error = 0.0; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "h?i:m:o:pPC")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'i': - if ((orig = fopen(optarg, "rb")) == NULL) { - fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); - exit(1); - } - strcpy(orig_name, optarg); - break; - case 'm': - m = atoi(optarg); - if (m <= 0) { - fprintf(stderr, "%s: multiplication factor %d out of range\n", progname, m); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'p': - print_psnr = 1; - break; - case 'P': - print_psnr_only = 1; - break; - case 'C': - print_psnr_value_only = 1; - print_psnr_only = 1; - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (!orig) { - fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); - - pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); - - if (in_cols != orig_cols || in_rows != orig_rows) { - fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); - exit(1); - } - - cols = in_cols; - rows = in_rows; - maxval = in_maxval; - - input_image = pgm_allocarray(cols, rows); - orig_image = pgm_allocarray(cols, rows); - - for (row = 0; row < rows; row++) { - pgm_readpgmrow(in, input_image[row], cols, in_maxval, in_format); - pgm_readpgmrow(orig, orig_image[row], cols, orig_maxval, orig_format); - } - - fclose(in); - fclose(orig); - - min = max = abs(input_image[0][0] - orig_image[0][0]); - - for (row = 0; row < rows; row++) { - gray *pi = input_image[row]; - gray *po = orig_image[row]; - - for (col = 0; col < cols; col++) { - int diff = abs(*pi - *po); - error += sqr(diff); - if (diff < min) min = diff; - if (diff > max) max = diff; - - pi++; - po++; - } - } - - for (row = 0; row < rows; row++) { - gray *pi = input_image[row]; - gray *po = orig_image[row]; - - for (col = 0; col < cols; col++) { - int diff = abs(*pi - *po); - if (m > 0) - *pi = PIXELRANGE(diff * m); - else - *pi = PIXELRANGE((double) (diff - min) / (double) (max - min) * maxval); - - pi++; - po++; - } - } - - if (!print_psnr_only) { - pgm_writepgminit(out, cols, rows, maxval, 0); - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, input_image[row], cols, maxval, 0); - - fclose(out); - } - - pgm_freearray(input_image, rows); - pgm_freearray(orig_image, rows); - - if (print_psnr || print_psnr_only) { - double mse = error / (double) (cols * rows); - double rmse = sqrt(mse); - double psnr = 20.0 * log(255.0 / rmse) / log(10.0); - FILE *print = print_psnr_only ? out : stderr; - if (!print_psnr_value_only) { - if (mse > 0.0) - fprintf(print, "PSNR: %lf dB\n", psnr); - else - fprintf(print, "PSNR: inf\n"); - fprintf(print, "RMSE: %lf\n", rmse); - fprintf(print, "MSE: %lf\n", mse); - fprintf(print, "dmin, dmax: %d, %d\n", min, max); - } - else - fprintf(print, "%lf\n", mse > 0.0 ? psnr : 100.0); - } - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_ppm.1 --- a/Meerwald/cmp_ppm.1 Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,100 +0,0 @@ -.\" -.\" cmp_ppm.1 - the *roff document processor man page source -.\" -.TH cmp_ppm 1 "98/07/08" "Watermarking, Version 1.0" -.SH NAME -cmp_ppm \- a program to create the difference image of two PGM images -.SH SYNOPSIS -.B cmp_ppm -[ -.BI \-c \ name -] -[ -.B \-h -] -[ -.BI \-m \ number -] -[ -.BI \-o \ ofile -] -.BI \-i \ ifile -.I file -.SH DESCRIPTION -.B cmp_ppm -is a program to create the difference image of two PPM (portable pixmap) -RGB color images. To compare PGM (portable graymap) grayscale images, use -the -.B cmp_pgm -program. -.PP -The color components to compare are specified with the -.BI \-c \ name -option, where -.I name -is one of the following: -.TP -.B red -The red color component. -.TP -.B green -The green color component. -.TP -.B blue -The blue color component. -.PP -Multiple color components are allowed. Specifying only the inital letter -of a color component is sufficient. -Per default -.B cmp_ppm -compares the luminance value of the images. This operation may be -selected explicitly with the -.BI \-c \ luminance -option. -.PP -If -.I file -or -.I ofile -is not specified, then standard input or standard output is -used. -.PP -.SH OPTIONS -.TP -.BI \-c \ name -Specifies color component(s) or luminance to compare. Default: luminance. -.TP -.B \-h -Print a help message. -.TP -.BI \-i \ ifile -The original image. Mandatory. -.TP -.BI \-m \ number -Multiplication factor to magnify differences between the to -original and input image. -Default value: 16. -.TP -.BI \-o \ ofile -Output image file to contain the difference image in PPM format. -.TP -.I file -Input image that is compared against -.I ifile. -Default: standard input. -.SH OUTPUT -The difference image in PPM format is written to standard output or, -optionally, to -.I ofile. -.SH AUTHOR -Peter Meerwald. -Email bug reports to pmeerw@cosy.sbg.ac.at. -.SH AVAILABILITY -The most recent released version of -.B cmp_ppm -is always available -at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the -directory /pub/people/pmeerw/Watermarking. -.SH "SEE ALSO" -.B cmp_ppm -(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_ppm.c --- a/Meerwald/cmp_ppm.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,270 +0,0 @@ -#include "wm.h" -#include "ppm.h" - -#define LUMINANCE 1 -#define RED 2 -#define GREEN 4 -#define BLUE 8 - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s -c name [-C] [-h] [-m n] [-o file] [-pP] -i file file\n\n", progname); - fprintf(stderr, "\t-c name\t\tcolor component (default luminance)\n"); - fprintf(stderr, "\t\t\teg. red, green, blue, luminance\n"); - fprintf(stderr, "\t-C\t\tprint PSNR value only\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-i file\t\toriginal image file\n"); - fprintf(stderr, "\t-m n\t\tmultiplication factor (default 16)\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-p\t\tprint PSNR, RMS and MSE\n"); - fprintf(stderr, "\t-P\t\tonly print PSNR, RMS and MSE, no difference image\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *orig = NULL; - - pixel **input_image; - pixel **orig_image; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char orig_name[MAXPATHLEN]; - - int in_cols, in_rows, in_format; - pixval in_maxval; - int orig_cols, orig_rows, orig_format; - pixval orig_maxval; - int cols, rows; - pixval maxval; - int col, row; - - int c; - - double error = 0.0; - int print_psnr = 0; - int print_psnr_only = 0; - int print_psnr_value_only = 0; - - int m = 16; - int component = 0; - int component_default = LUMINANCE; - int min, max; - - progname = argv[0]; - - ppm_init(&argc, argv); - -#ifdef __EMX__ - _fsetmode(in, "b"); - _fsetmode(out, "b"); -#endif - - while ((c = getopt(argc, argv, "Cc:h?i:m:o:pP")) != EOF) { - switch (c) { - case 'C': - print_psnr_value_only = 1; - print_psnr_only = 1; - break; - case 'c': - if (!strcasecmp(optarg, "RED") || toupper(*optarg) == 'R') - component |= RED; - else if (!strcasecmp(optarg, "GREEN") || toupper(*optarg) == 'G') - component |= GREEN; - else if (!strcasecmp(optarg, "BLUE") || toupper(*optarg) == 'B') - component |= BLUE; - else if (!strcasecmp(optarg, "LUMINANCE") || toupper(*optarg) == 'L') - component |= LUMINANCE; - else - fprintf(stderr, "%s: unknown color component %s\n", progname, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'i': - if ((orig = fopen(optarg, "rb")) == NULL) { - fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); - exit(1); - } - strcpy(orig_name, optarg); - break; - case 'm': - m = atoi(optarg); - if (m <= 0) { - fprintf(stderr, "%s: multiplication factor %d out of range\n", progname, m); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'p': - print_psnr = 1; - break; - case 'P': - print_psnr_only = 1; - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (!orig) { - fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); - exit(1); - } - - if (!component) { - if (component_default) - component = component_default; - else { - fprintf(stderr, "%s: color component(s) to compare not specified, use -c name option\n", progname); - exit(1); - } - } - - if (component & LUMINANCE && component & (RED | GREEN | BLUE)) { - fprintf(stderr, "%s: unable to compare luminance AND color component\n", progname); - exit(1); - } - - ppm_readppminit(in, &in_cols, &in_rows, &in_maxval, &in_format); - - ppm_readppminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); - - if (in_cols != orig_cols || in_rows != orig_rows) { - fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); - exit(1); - } - - cols = in_cols; - rows = in_rows; - maxval = in_maxval; - - input_image = ppm_allocarray(cols, rows); - - for (row = 0; row < rows; row++) - ppm_readppmrow(in, input_image[row], cols, in_maxval, in_format); - - fclose(in); - - orig_image = ppm_allocarray(cols, rows); - - for (row = 0; row < rows; row++) - ppm_readppmrow(orig, orig_image[row], cols, orig_maxval, orig_format); - - fclose(orig); - - if (component & LUMINANCE) - min = max = abs(PPM_LUMIN(input_image[0][0]) - PPM_LUMIN(orig_image[0][0])); - else { - if (component & RED) - min = max = abs(PPM_GETR(input_image[0][0]) - PPM_GETR(orig_image[0][0])); - else if (component & GREEN) - min = max = abs(PPM_GETG(input_image[0][0]) - PPM_GETG(orig_image[0][0])); - else if (component & BLUE) - min = max = abs(PPM_GETB(input_image[0][0]) - PPM_GETB(orig_image[0][0])); - else - min = max = 0; - } - - for (row = 0; row < rows; row++) { - pixel *pi = input_image[row]; - pixel *po = orig_image[row]; - - for (col = 0; col < cols; col++) { - int diff=0; - - if (component & LUMINANCE) { - pixval l; - diff = abs(PPM_LUMIN(*pi) - PPM_LUMIN(*po)); - error += sqr(PPM_LUMIN(*pi) - PPM_LUMIN(*po)); - l = PIXELRANGE(ROUND(abs(PPM_LUMIN(*pi) - PPM_LUMIN(*po)) * m)); - PPM_ASSIGN(*pi, l, l, l); - } - else { - if (component & RED) { - diff = abs(PPM_GETR(*pi) - PPM_GETR(*po)); - error += sqr(PPM_GETR(*pi) - PPM_GETR(*po)); - PPM_PUTR(*pi, PIXELRANGE(abs(PPM_GETR(*pi) - PPM_GETR(*po)) * m)); - } - else - PPM_PUTR(*pi, 0); - if (component & GREEN) { - diff = abs(PPM_GETG(*pi) - PPM_GETG(*po)); - error += sqr(PPM_GETG(*pi) - PPM_GETG(*po)); - PPM_PUTG(*pi, PIXELRANGE(abs(PPM_GETG(*pi) - PPM_GETG(*po)) * m)); - } - else - PPM_PUTG(*pi, 0); - if (component & BLUE) { - diff = abs(PPM_GETB(*pi) - PPM_GETB(*po)); - error += sqr(PPM_GETB(*pi) - PPM_GETB(*po)); - PPM_PUTB(*pi, PIXELRANGE(abs(PPM_GETB(*pi) - PPM_GETB(*po)) * m)); - } - else - PPM_PUTB(*pi, 0); - } - - if (diff < min) min = diff; - if (diff > max) max = diff; - pi++; - po++; - } - } - - if (!print_psnr_only) { - ppm_writeppminit(out, cols, rows, maxval, 0); - for (row = 0; row < rows; row++) - ppm_writeppmrow(out, input_image[row], cols, maxval, 0); - - fclose(out); - } - - ppm_freearray(input_image, rows); - ppm_freearray(orig_image, rows); - - if (print_psnr || print_psnr_only) { - double mse = error / (double) (cols * rows); - double rmse = sqrt(mse); - double psnr = 20.0 * log(255.0 / rmse) / log(10.0); - FILE *print = print_psnr_only ? out : stderr; - if (!print_psnr_value_only) { - if (mse > 0.0) - fprintf(print, "PSNR: %lf dB\n", psnr); - else - fprintf(print, "PSNR: inf\n"); - fprintf(print, "RMS: %lf\n", rmse); - fprintf(print, "MSE: %lf\n", mse); - fprintf(print, "dmin, dmax: %d, %d\n", min, max); - } - else - fprintf(print, "%lf\n", mse > 0.0 ? psnr : 100.0); - } - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_wang_sig.c --- a/Meerwald/cmp_wang_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,150 +0,0 @@ -#include "wm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-h] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - - int c; - int sig_n, in_n; - double sig_a, sig_b; - int sig_e, sig_f; - double s1, s2, s3; - char line[32]; - - int verbose = 0; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "h?o:s:v:")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "r")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (!sig) { - fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); - exit(1); - } - - fgets(line, sizeof(line), sig); - if (strspn(line, "WGSG") < 4) { - fprintf(stderr, "%s: original signature file %s invalid\n", progname, signature_name); - exit(1); - } - - fgets(line, sizeof(line), in); - if (strspn(line, "WGWM") < 4) { - fprintf(stderr, "%s: watermark file %s invalid\n", progname, input_name); - exit(1); - } - - fscanf(sig, "%d\n", &sig_n); - fscanf(in, "%d\n", &in_n); - if (sig_n != in_n) { - fprintf(stderr, "%s: watermark length mismatch (original %d, input %d)\n", progname, sig_n, in_n); - exit(1); - } - if (sig_n <= 0 || sig_n > 32000) { - fprintf(stderr, "%s: invalid original watermark length %d\n", progname, sig_n); - exit(1); - } - if (in_n != sig_n) { - fprintf(stderr, "%s: invalid watermark length %d, does not match signature length\n", progname, in_n); - exit(1); - } - - fscanf(sig, "%lf\n", &sig_a); - fscanf(sig, "%lf\n", &sig_b); - fscanf(sig, "%d\n", &sig_e); - fscanf(sig, "%d\n", &sig_f); - fscanf(sig, "%*[^\n\r]\n"); - - /* - * normalized correlation - * Craver, S., "Can Invisible Watermarks Resolve Rightful Ownership?", IBM Research Report, 1996, p. 5 - */ - - s1 = s2 = s3 = 0.0; - while (in_n > 0) { - double sig_x, in_x; - - fscanf(sig, "%lf\n", &sig_x); - fscanf(in, "%lf\n", &in_x); - - if (verbose >= 1) { - fprintf(stderr, "orig %f input %f\n", sig_x, in_x); - } - - s1 += sig_x * in_x; - s2 += in_x * in_x; - s3 += sig_x * sig_x; - - in_n--; - } - - fprintf(out, "%f\n", s1 / sqrt(s2 * s3)); - - fclose(sig); - fclose(out); - fclose(in); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_xia_sig.c --- a/Meerwald/cmp_xia_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,213 +0,0 @@ -#include "wm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-C\t\toutput correlation only\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - - int c, i, j, n; - int in_level; - double *cumul_watermark, *orig_watermark; - int *cumul_watermark_count; - int sig_n, in_n; - double sig_a; - int sig_l; - int sig_e, sig_f; - double s1, s2, s3; - double correlation, maxcorrelation; - char line[32]; - - int verbose = 0; - int correlation_only = 0; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'C': - correlation_only = 1; - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "r")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (!sig) { - fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); - exit(1); - } - - fgets(line, sizeof(line), sig); - if (strspn(line, "XASG") < 4) { - fprintf(stderr, "%s: original signature file %s invalid\n", progname, signature_name); - exit(1); - } - - fgets(line, sizeof(line), in); - if (strspn(line, "XAWM") < 4) { - fprintf(stderr, "%s: watermark file %s invalid\n", progname, input_name); - exit(1); - } - - fscanf(sig, "%d\n", &sig_n); - fscanf(in, "%d\n", &in_n); - if (sig_n != in_n) { - fprintf(stderr, "%s: watermark length mismatch (original %d, input %d)\n", progname, sig_n, in_n); - exit(1); - } - if (sig_n <= 0 || sig_n > 32000) { - fprintf(stderr, "%s: invalid original watermark length %d\n", progname, sig_n); - exit(1); - } - if (in_n != sig_n) { - fprintf(stderr, "%s: invalid watermark length %d, does not match signature length\n", progname, in_n); - exit(1); - } - - fscanf(sig, "%lf\n", &sig_a); - fscanf(sig, "%d\n", &sig_l); - fscanf(sig, "%d\n", &sig_e); - fscanf(sig, "%d\n", &sig_f); - fscanf(sig, "%*[^\n\r]\n"); - - orig_watermark = malloc(sig_n * sizeof(double)); - for (i = 0; i < sig_n; i++) - fscanf(sig, "%lf\n", &orig_watermark[i]); - fclose(sig); - - fscanf(in, "%d\n", &in_level); - - cumul_watermark = malloc(in_n * sizeof(double)); - cumul_watermark_count = malloc(in_n * sizeof(int)); - - for (i = 0; i < in_n; i++) { - cumul_watermark_count[i] = 0; - cumul_watermark[i] = 0.0; - } - - /* - * normalized correlation - * Craver, S., "Can Invisible Watermarks Resolve Rightful Ownership?", IBM Research Report, 1996, p. 5 - */ - - maxcorrelation = -10000.0; - for (i = 0; i < in_level; i++) { - fscanf(in, "%d\n", &n); - - s1 = s2 = s3 = 0.0; - for (j = 0; j < n; j++) { - double in_x, sig_x; - - sig_x = orig_watermark[j % sig_n]; - fscanf(in, "%lf\n", &in_x); - - s1 += sig_x * in_x; - s2 += in_x * in_x; - s3 += sig_x * sig_x; - - if (verbose > 2) - fprintf(stderr, "%s: level %d; orig %f input %f\n", progname, i, sig_x, in_x); - - cumul_watermark[j % in_n] += in_x; - cumul_watermark_count[j % in_n]++; - } - - correlation = s1 / sqrt(s2 * s3); - if (correlation > maxcorrelation) - maxcorrelation = correlation; - - if (!correlation_only) - fprintf(out, "%s: correlation subband %d: %f\n", progname, i, correlation); - } - - s1 = s2 = s3 = 0.0; - for (i = 0; i < in_n; i++) { - double in_x, sig_x; - - if (cumul_watermark_count[i] <= 0) continue; - in_x = cumul_watermark[i] / (double) cumul_watermark_count[i]; - sig_x = orig_watermark[i]; - - s1 += sig_x * in_x; - s2 += in_x * in_x; - s3 += sig_x * sig_x; - } - - correlation = s1 / sqrt(s2 * s3); - if (!correlation_only) - fprintf(out, "%s: cumultative correlation: %f\n", progname, correlation); - - if (correlation > maxcorrelation) - maxcorrelation = correlation; - - if (!correlation_only) - fprintf(out, "%s: max. correlation: %f\n", progname, maxcorrelation); - else - fprintf(out, "%f\n", maxcorrelation); - - fclose(out); - fclose(in); - - free(orig_watermark); - free(cumul_watermark); - free(cumul_watermark_count); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_xie2_sig.c --- a/Meerwald/cmp_xie2_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,151 +0,0 @@ -#include "wm.h" -#include "signature.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-C\t\toutput correlation only\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - - int correlation_only = 0; - - int c, i; - int corr = 0, match = 0; - int verbose = 0; - int filter = 0; - int method = 0; - int level = 0; - int quant = 0; - double alpha = 0.0; - char filter_name[MAXPATHLEN] = ""; - - int seed; - char line[32]; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'C': - correlation_only = 1; - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "r")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - fgets(line, sizeof(line), sig); - if (strspn(line, "XE2SG") >= 5) { - fscanf(sig, "%d\n", &nbit_signature1); - fscanf(sig, "%lf\n", &alpha); - fscanf(sig, "%d\n", &method); - fscanf(sig, "%d\n", &filter); - fscanf(sig, "%[^\n\r]\n", filter_name); - fscanf(sig, "%d\n", &quant); - fscanf(sig, "%d\n", &level); - fscanf(sig, "%d\n", &seed); - srandom(seed); - n_signature1 = NBITSTOBYTES(nbit_signature1); - fread(signature1, sizeof(char), n_signature1, sig); - fscanf(sig, "\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); - exit(1); - } - - fgets(line, sizeof(line), in); - if (strspn(line, "XE2WM") >= 5) { - fscanf(in, "%d\n", &nbit_signature2); - n_signature2 = NBITSTOBYTES(nbit_signature2); - fread(signature2, sizeof(char), n_signature2, in); - fscanf(in, "\n"); - } - else { - fprintf(stderr, "%s: invalid watermark file %s\n", progname, input_name); - exit(1); - } - - if (verbose > 0) { - fprintf(stderr, "signature length: %d\n", nbit_signature1); - fprintf(stderr, "watermark length: %d\n", nbit_signature2); - } - - for (i = 0; i < nbit_signature2; i++) - if (get_signature1_bit(i % nbit_signature1) == get_signature2_bit(i)) - corr++, match++; - else - corr--; - - if (correlation_only) - fprintf(out, "%lf\n", (double) corr / nbit_signature2); - else { - fprintf(out, "bit matches: %d/%d\n", match, nbit_signature2); - fprintf(out, "correlation: %lf\n", (double) corr / nbit_signature2); - } - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_xie_sig.c --- a/Meerwald/cmp_xie_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,149 +0,0 @@ -#include "wm.h" -#include "signature.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-C\t\toutput correlation only\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - - int correlation_only = 0; - - int c, i; - int corr = 0, match = 0; - int verbose = 0; - int filter = 0; - int method = 0; - int level = 0; - double alpha = 0.0; - char filter_name[MAXPATHLEN] = ""; - - int seed; - char line[32]; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'C': - correlation_only = 1; - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "r")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - fgets(line, sizeof(line), sig); - if (strspn(line, "XESG") >= 4) { - fscanf(sig, "%d\n", &nbit_signature1); - fscanf(sig, "%lf\n", &alpha); - fscanf(sig, "%d\n", &method); - fscanf(sig, "%d\n", &filter); - fscanf(sig, "%[^\n\r]\n", filter_name); - fscanf(sig, "%d\n", &level); - fscanf(sig, "%d\n", &seed); - srandom(seed); - n_signature1 = NBITSTOBYTES(nbit_signature1); - fread(signature1, sizeof(char), n_signature1, sig); - fscanf(sig, "\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); - exit(1); - } - - fgets(line, sizeof(line), in); - if (strspn(line, "XEWM") >= 4) { - fscanf(in, "%d\n", &nbit_signature2); - n_signature2 = NBITSTOBYTES(nbit_signature2); - fread(signature2, sizeof(char), n_signature2, in); - fscanf(in, "\n"); - } - else { - fprintf(stderr, "%s: invalid watermark file %s\n", progname, input_name); - exit(1); - } - - if (verbose > 0) { - fprintf(stderr, "signature length: %d\n", nbit_signature1); - fprintf(stderr, "watermark length: %d\n", nbit_signature2); - } - - for (i = 0; i < nbit_signature2; i++) - if (get_signature1_bit(i % nbit_signature1) == get_signature2_bit(i)) - corr++, match++; - else - corr--; - - if (correlation_only) - fprintf(out, "%lf\n", (double) corr / nbit_signature2); - else { - fprintf(out, "bit matches: %d/%d\n", match, nbit_signature2); - fprintf(out, "correlation: %lf\n", (double) corr / nbit_signature2); - } - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/cmp_zhu_sig.c --- a/Meerwald/cmp_zhu_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,211 +0,0 @@ -#include "wm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-h] [-C] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-C\t\toutput correlation only\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - - int c, i, j, n; - int in_level; - double *cumul_watermark, *orig_watermark; - int *cumul_watermark_count; - int sig_n, in_n; - double sig_a; - int sig_l; - int sig_e, sig_f; - char line[32]; - double correlation, maxcorrelation; - double s1, s2, s3; - - int verbose = 0; - int correlation_only = 0; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "h?Co:s:v:")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'C': - correlation_only = 1; - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "r")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (!sig) { - fprintf(stderr, "%s: original signature file not specified, use -s file option\n", progname); - exit(1); - } - - fgets(line, sizeof(line), sig); - if (strspn(line, "ZHSG") < 4) { - fprintf(stderr, "%s: original signature file %s invalid\n", progname, signature_name); - exit(1); - } - - fgets(line, sizeof(line), in); - if (strspn(line, "ZHWM") < 4) { - fprintf(stderr, "%s: watermark file %s invalid\n", progname, input_name); - exit(1); - } - - fscanf(sig, "%d\n", &sig_n); - fscanf(in, "%d\n", &in_n); - if (sig_n != in_n) { - fprintf(stderr, "%s: watermark length mismatch (original %d, input %d)\n", progname, sig_n, in_n); - exit(1); - } - if (sig_n <= 0 || sig_n > 32000) { - fprintf(stderr, "%s: invalid original watermark length %d\n", progname, sig_n); - exit(1); - } - if (in_n != sig_n) { - fprintf(stderr, "%s: invalid watermark length %d, does not match signature length\n", progname, in_n); - exit(1); - } - - fscanf(sig, "%lf\n", &sig_a); - fscanf(sig, "%d\n", &sig_l); - fscanf(sig, "%d\n", &sig_e); - fscanf(sig, "%d\n", &sig_f); - fscanf(sig, "%*[^\n\r]\n"); - - orig_watermark = malloc(sig_n * sizeof(double)); - for (i = 0; i < sig_n; i++) - fscanf(sig, "%lf\n", &orig_watermark[i]); - fclose(sig); - - fscanf(in, "%d\n", &in_level); - - cumul_watermark = malloc(in_n * sizeof(double)); - cumul_watermark_count = malloc(in_n * sizeof(int)); - - for (i = 0; i < in_n; i++) { - cumul_watermark_count[i] = 0; - cumul_watermark[i] = 0.0; - } - - /* - * normalized correlation - * Craver, S., "Can Invisible Watermarks Resolve Rightful Ownership?", IBM Research Report, 1996, p. 5 - */ - maxcorrelation = -10000.0; - for (i = 0; i < in_level; i++) { - fscanf(in, "%d\n", &n); - - s1 = s2 = s3 = 0.0; - for (j = 0; j < n; j++) { - double in_x, sig_x; - - sig_x = orig_watermark[j]; - fscanf(in, "%lf\n", &in_x); - - s1 += sig_x * in_x; - s2 += in_x * in_x; - s3 += sig_x * sig_x; - - if (verbose > 2) - fprintf(stderr, "%s: level %d; orig %f input %f\n", progname, i, sig_x, in_x); - - cumul_watermark[j % in_n] += in_x; - cumul_watermark_count[j % in_n]++; - } - - correlation = s1 / sqrt(s2 * s3); - if (correlation > maxcorrelation) - maxcorrelation = correlation; - - if (!correlation_only) - fprintf(out, "%s: correlation level %d: %f\n", progname, i, correlation); - } - - s1 = s2 = s3 = 0.0; - for (i = 0; i < in_n; i++) { - double in_x, sig_x; - - in_x = cumul_watermark[i] / (double) cumul_watermark_count[i]; - sig_x = orig_watermark[i]; - - s1 += sig_x * in_x; - s2 += in_x * in_x; - s3 += sig_x * sig_x; - } - - correlation = s1 / sqrt(s2 * s3); - if (!correlation_only) - fprintf(out, "%s: cumultative correlation: %f\n", progname, correlation); - - if (correlation > maxcorrelation) - maxcorrelation = correlation; - - if (!correlation_only) - fprintf(out, "%s: max. correlation: %f\n", progname, maxcorrelation); - else - fprintf(out, "%f\n", maxcorrelation); - - fclose(out); - fclose(in); - - free(orig_watermark); - free(cumul_watermark); - free(cumul_watermark_count); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/coeff.c --- a/Meerwald/coeff.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,72 +0,0 @@ -#include "wm.h" -#include "coeff.h" - -double **alloc_coeffs(int cols, int rows) { - double **p; - int i; - - p = (double **)malloc(rows * sizeof(double *)); - if (!p) { -#ifdef DEBUG - fprintf(stderr, "alloc_coeffs(): malloc() failed\n"); - exit(1); -#else - return NULL; -#endif - } - p[0] = malloc(rows * cols * sizeof(double)); - if (!p[0]) { -#ifdef DEBUG - fprintf(stderr, "alloc_coeffs(): malloc() failed\n"); - exit(1); -#else - free(p); - return NULL; -#endif - } - for (i = 1; i < rows; i++) { - p[i] = &(p[0][i * cols]); - } - - return p; -} - -void free_coeffs(double **coeffs) { - free(coeffs[0]); - free(coeffs); -} - -double **alloc_coeffs_8x8() { - return alloc_coeffs(8, 8); -} - -void print_coeffs_8x8(double **coeffs) { - int i, j; - - for (i = 0; i < 8; i++) { - for (j = 0; j < 8; j++) - fprintf(stderr, "%8.2f ", coeffs[i][j]); - fprintf(stderr, "\n"); - } -} - -void print_coeffs(double **coeffs, int c, int r, int w, int h) { - int i, j; - double *p; - -#ifdef DEBUG - if (!coeffs) { - fprintf(stderr, "print_coeffs(): NULL pixels\n"); - } - if (w <= 0 || h <= 0 || c < 0 || r < 0) { - fprintf(stderr, "print_coeffs(): block dimension out of range\n"); - } -#endif - - for (j = r; j < r + h; j++) { - p = &coeffs[j][c]; - for (i = 0; i < w; i++) - fprintf(stderr, "%8.2f ", *(p++)); - fprintf(stderr, "\n"); - } -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/coeff.h --- a/Meerwald/coeff.h Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -#ifndef COEFF_H -#define COEFF_H - -#include "wm.h" - -double **alloc_coeffs(int cols, int rows); -double **alloc_coeffs_8x8(); -void free_coeffs(double **coeffs); -void print_coeffs_8x8(double **coeffs); -void print_coeffs(double **coeffs, int c, int r, int w, int h); - -#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/coord.c --- a/Meerwald/coord.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -#include -#include -#include "coord.h" - -struct coords *alloc_coords(int n) { - struct coords *c; - - if ((c = malloc(sizeof(struct coords))) != NULL) - init_coords(c, n); -#ifdef DEBUG - else - fprintf(stderr, "alloc_coords(): malloc failed\n"); -#endif - - return c; -} - -void free_coords(struct coords *c) { - -#ifdef DEBUG - if (!c) - fprintf(stderr, "free_coords(): got NULL pointer\n"); -#endif - - free(c->values); - free(c); -} - -int init_coords(struct coords *c, int n) { - -#ifdef DEBUG - if (!c) - fprintf(stderr, "init_coords(): got NULL poiner\n"); - - if (n <= 0) - fprintf(stderr, "init_coords(): n out of range\n"); -#endif - - c->count = 0; - c->max = n; - - if ((c->values = malloc(n * sizeof(struct coord))) != NULL) - return 0; - else - return -1; -} - -int add_coord(struct coords *c, int x, int y) { - struct coord *v; - int n; - -#ifdef DEBUG - if (!c) - fprintf(stderr, "add_coord(): got NULL pointer\n"); - - if (c->count >= c->max) - fprintf(stderr, "add_coord(): maximum reached\n"); -#endif - - v = c->values; - - for (n = 0; n < c->count; v++, n++) - if (v->x == x && v->y == y) break; - - if (n == c->count) { - v->x = x; - v->y = y; - c->count++; - return 0; - } - else - return -1; -} - - diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/coord.h --- a/Meerwald/coord.h Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -#ifndef COORD_H -#define COORD_H - -struct coord { - int x; - int y; -}; - -struct coords { - int count; - int max; - struct coord *values; -}; - -struct coords *alloc_coords(int n); -void free_coords(struct coords *c); -int init_coords(struct coords *c, int n); -int add_coord(struct coords *c, int x, int y); - -#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/dct.c --- a/Meerwald/dct.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,651 +0,0 @@ -#include "wm.h" -#include "dct.h" - -#define INVROOT2 0.7071067814 -#define SWAP(A, B) {double t = A; A = B; B = t;} - -int N; -int M; - -double *dct_NxN_tmp = NULL; -double *dct_NxN_costable = NULL; -int dct_NxN_log2N = 0; - -static const unsigned int JPEG_lumin_quant_table[NJPEG][NJPEG] = { - {16, 11, 10, 16, 24, 40, 51, 61}, - {12, 12, 14, 19, 26, 58, 60, 55}, - {14, 13, 16, 24, 40, 57, 69, 56}, - {14, 17, 22, 29, 51, 87, 80, 62}, - {18, 22, 37, 56, 68, 109, 103, 77}, - {24, 35, 55, 64, 81, 104, 113, 92}, - {49, 64, 78, 87, 103, 121, 120, 101}, - {72, 92, 95, 98, 112, 100, 103, 99}}; - -static void initcosarray() -{ - int i,group,base,item,nitems,halfN; - double factor; - - dct_NxN_log2N = -1; - do{ - dct_NxN_log2N++; - if ((1<N){ - fprintf(stderr, "dct_NxN: %d not a power of 2\n", N); - exit(1); - } - }while((1<>1; - while(j>m){ - j=j-m; - m=(m+1)>>1; - } - j=j+m; - } -} - -static void inv_sums(double *f) -{ - int stepsize,stage,curptr,nthreads,thread,step,nsteps; - - for(stage=1; stage <=dct_NxN_log2N-1; stage++){ - nthreads = 1<<(stage-1); - stepsize = nthreads<<1; - nsteps = (1<<(dct_NxN_log2N-stage)) - 1; - for(thread=1; thread<=nthreads; thread++){ - curptr=N-thread; - for(step=1; step<=nsteps; step++){ - f[curptr] += f[curptr-stepsize]; - curptr -= stepsize; - } - } - } -} - -static void fwd_sums(double *f) -{ - int stepsize,stage,curptr,nthreads,thread,step,nsteps; - - for(stage=dct_NxN_log2N-1; stage >=1; stage--){ - nthreads = 1<<(stage-1); - stepsize = nthreads<<1; - nsteps = (1<<(dct_NxN_log2N-stage)) - 1; - for(thread=1; thread<=nthreads; thread++){ - curptr=nthreads +thread-1; - for(step=1; step<=nsteps; step++){ - f[curptr] += f[curptr+stepsize]; - curptr += stepsize; - } - } - } -} - -static void scramble(double *f,int len){ - int i,ii1,ii2; - - bitrev(f,len); - bitrev(&f[0], len>>1); - bitrev(&f[len>>1], len>>1); - ii1=len-1; - ii2=len>>1; - for(i=0; i<(len>>2); i++){ - SWAP(f[ii1], f[ii2]); - ii1--; - ii2++; - } -} - -static void unscramble(double *f,int len) -{ - int i,ii1,ii2; - - ii1 = len-1; - ii2 = len>>1; - for(i=0; i<(len>>2); i++){ - SWAP(f[ii1], f[ii2]); - ii1--; - ii2++; - } - bitrev(&f[0], len>>1); - bitrev(&f[len>>1], len>>1); - bitrev(f,len); -} - -static void inv_butterflies(double *f) -{ - int stage,ii1,ii2,butterfly,ngroups,group,wingspan,increment,baseptr; - double Cfac,T; - - for(stage=1; stage<=dct_NxN_log2N;stage++){ - ngroups=1<<(dct_NxN_log2N-stage); - wingspan=1<<(stage-1); - increment=wingspan<<1; - for(butterfly=1; butterfly<=wingspan; butterfly++){ - Cfac = dct_NxN_costable[wingspan+butterfly-1]; - baseptr=0; - for(group=1; group<=ngroups; group++){ - ii1=baseptr+butterfly-1; - ii2=ii1+wingspan; - T=Cfac * f[ii2]; - f[ii2]=f[ii1]-T; - f[ii1]=f[ii1]+T; - baseptr += increment; - } - } - } -} - -static void fwd_butterflies(double *f) -{ - int stage,ii1,ii2,butterfly,ngroups,group,wingspan,increment,baseptr; - double Cfac,T; - - for(stage=dct_NxN_log2N; stage>=1;stage--){ - ngroups=1<<(dct_NxN_log2N-stage); - wingspan=1<<(stage-1); - increment=wingspan<<1; - for(butterfly=1; butterfly<=wingspan; butterfly++){ - Cfac = dct_NxN_costable[wingspan+butterfly-1]; - baseptr=0; - for(group=1; group<=ngroups; group++){ - ii1=baseptr+butterfly-1; - ii2=ii1+wingspan; - T= f[ii2]; - f[ii2]=Cfac *(f[ii1]-T); - f[ii1]=f[ii1]+T; - baseptr += increment; - } - } - } -} - -static void ifct_noscale(double *f) -{ - f[0] *= INVROOT2; - inv_sums(f); - bitrev(f,N); - inv_butterflies(f); - unscramble(f,N); -} - -static void fct_noscale(double *f) -{ - scramble(f,N); - fwd_butterflies(f); - bitrev(f,N); - fwd_sums(f); - f[0] *= INVROOT2; -} - -void fdct_NxN(gray **pixels, double **dcts) { - int u,v; - double two_over_sqrtncolsnrows = 2.0/sqrt((double) N*M); - - for (u=0; u < N; u++) - for (v=0; v < M; v++) - dcts[u][v] = ((int) pixels[u][v] - 128); - - for (u=0; u<=M-1; u++){ - fct_noscale(dcts[u]); - } - for (v=0; v<=N-1; v++){ - for (u=0; u<=M-1; u++){ - dct_NxN_tmp[u] = dcts[u][v]; - } - fct_noscale(dct_NxN_tmp); - for (u=0; u<=M-1; u++){ - dcts[u][v] = dct_NxN_tmp[u]*two_over_sqrtncolsnrows; - } - } -} - -void idct_NxN(double **dcts, gray **pixels) { - int u,v; - double two_over_sqrtncolsnrows = 2.0/sqrt((double) N*M); - - double **tmp; - - tmp = alloc_coeffs(N, N); - for (u=0;u rint(log(MIN(cols, rows))/log(2.0)) - 2) { - fprintf(stderr, "init_dwt(): level parameter does not match image width/height\n"); - return; - } -#endif - - if (dwt_filters && level != dwt_levels) { - free(dwt_filters); - dwt_filters = NULL; - } - - dwt_levels = level; - - if (!dwt_filters) - dwt_filters = calloc(level + 1, sizeof(FilterGH)); - - for (i = 0; i < level + 1; i++) - dwt_filters[i] = (dwt_allfilters->filter)[filter]; - - dwt_filter = filter; - dwt_method = method; - dwt_cols = cols; - dwt_rows = rows; -} - -Image_tree fdwt(gray **pixels) { - Image image; - Image_tree tree; - int i, j; - - image = new_image(dwt_cols, dwt_rows); - - for (i = 0; i < dwt_rows; i++) - for (j = 0; j < dwt_cols; j++) - set_pixel(image, j, i, pixels[i][j]); - - tree = wavelettransform(image, dwt_levels, dwt_filters, dwt_method); - free_image(image); - - return tree; -} - -Image_tree fdwt_wp(gray **pixels) { - Image image; - Image_tree tree; - int i, j; - - image = new_image(dwt_cols, dwt_rows); - - for (i = 0; i < dwt_rows; i++) - for (j = 0; j < dwt_cols; j++) - set_pixel(image, j, i, pixels[i][j]); - - tree = wavelettransform_wp(image, dwt_levels, dwt_filters, dwt_method); - free_image(image); - - return tree; -} - -void idwt(Image_tree dwts, gray **pixels) { - Image image; - int i, j; - - image = inv_transform(dwts, dwt_filters, dwt_method + 1); - - for (i = 0; i < dwt_rows; i++) - for (j = 0; j < dwt_cols; j++) - pixels[i][j] = PIXELRANGE((int) (get_pixel(image, j, i) + 0.5)); - - free_image(image); -} - -void idwt_wp(Image_tree dwts, gray **pixels) { - Image image; - int i, j; - - image = inv_transform(dwts, dwt_filters, dwt_method + 1); - - for (i = 0; i < dwt_rows; i++) - for (j = 0; j < dwt_cols; j++) - pixels[i][j] = PIXELRANGE((int) (get_pixel(image, j, i) + 0.5)); - - free_image(image); -} - -int gen_pollen_filter(double *filter, double alpha, double beta, int which) { - int i, j, k, filterlength; - double tf[6]; - - /* parameter alpha, beta have to be in range -Pi .. Pi */ - if (alpha < -M_PI || alpha >= M_PI) { - fprintf(stderr, "alpha %f out of range\n", alpha); - return -1; - } - - if (beta < -M_PI || beta >= M_PI) { - fprintf(stderr, "beta %f out of range\n", beta); - return -1; - } - - /* generate Pollen filter coefficients, see http://www.dfw.net/~cody for details */ - tf[0] = ((1.0 + cos(alpha) + sin(alpha)) * (1.0 - cos(beta) - sin(beta)) + 2.0 * sin(beta) * cos(alpha)) / 4.0; - tf[1] = ((1.0 - cos(alpha) + sin(alpha)) * (1.0 + cos(beta) - sin(beta)) - 2.0 * sin(beta) * cos(alpha)) / 4.0; - tf[2] = (1.0 + cos(alpha - beta) + sin(alpha - beta)) / 2.0; - tf[3] = (1.0 + cos(alpha - beta) - sin(alpha - beta)) / 2.0; - tf[4] = 1.0 - tf[0] - tf[2]; - tf[5] = 1.0 - tf[1] - tf[3]; - - /* set close-to-zero filter coefficients to zero */ - for (i = 0; i < 6; i++) - if (fabs(tf[i]) < 1.0e-15) tf[i] = 0.0; - - /* find the first non-zero wavelet coefficient */ - i = 0; - while (tf[i] == 0.0) i++; - - /* find the last non-zero wavelet coefficient */ - j = 5; - while (tf[j] == 0.0) j--; - - filterlength = j - i + 1; - for (k = 0; k < filterlength; k++) - switch (which) { - case FILTERH: - filter[k] = tf[j--] / 2.0; - break; - case FILTERG: - filter[k] = (double) (((i & 0x01) * 2) - 1) * tf[i] / 2.0; - i++; - break; - case FILTERHi: - filter[k] = tf[j--]; - break; - case FILTERGi: - filter[k] = (double) (((i & 0x01) * 2) - 1) * tf[i]; - i++; - break; - default: - return -1; - } - - while (k < 6) - filter[k++] = 0.0; - - return filterlength; -} - -void dwt_pollen_filter(double alpha, double beta) { - FilterGH filter; - int i; - - filter = malloc(sizeof(struct FilterGHStruct)); -#ifdef DEBUG - if (!filter) { - fprintf(stderr, "dwt_pollen_filter(): malloc failed()\n"); - return; - } -#endif - - filter->type = FTOther; - filter->name = "pollen"; - - filter->g = new_filter(6); - filter->g->type = FTSymm; - filter->g->hipass = 1; - filter->g->len = gen_pollen_filter(filter->g->data, alpha, beta, FILTERG); - filter->g->start = -filter->g->len / 2; - filter->g->end = filter->g->len / 2 - 1; - - filter->h = new_filter(6); - filter->h->type = FTSymm; - filter->h->hipass = 0; - filter->h->len = gen_pollen_filter(filter->h->data, alpha, beta, FILTERH); - filter->h->start = -filter->h->len / 2; - filter->h->end = filter->h->len / 2 - 1; - - filter->gi = new_filter(6); - filter->gi->type = FTSymm; - filter->gi->hipass = 1; - filter->gi->len = gen_pollen_filter(filter->gi->data, alpha, beta, FILTERGi); - filter->gi->start = -filter->gi->len / 2; - filter->gi->end = filter->gi->len / 2 - 1; - - filter->hi = new_filter(6); - filter->hi->type = FTSymm; - filter->hi->hipass = 0; - filter->hi->len = gen_pollen_filter(filter->hi->data, alpha, beta, FILTERHi); - filter->hi->start = -filter->hi->len / 2; - filter->hi->end = filter->hi->len / 2 - 1; - -#ifdef DEBUG - if (dwt_levels <= 0) { - fprintf(stderr, "dwt_pollen_filter(): level invalid - set to zero\n"); - return; - } -#endif - -#ifdef DEBUG - if (!dwt_filters) { - fprintf(stderr, "dwt_pollen_filter(): wm_dwt not initialized, call init_dwt() first\n"); - return; - } -#endif - - for (i = 0; i < dwt_levels + 1; i++) - dwt_filters[i] = filter; -} - -int gen_param_filter(double *filter, int n, double alpha[], int which) { - int i, j, k, filterlength; - double *tf, *t; - - tf = malloc(2 * (n + 1) * sizeof(double)); - t = malloc(2 * (n + 1) * sizeof(double)); - if (!tf) { - fprintf(stderr, "gen_param_filter(): malloc() failed\n"); - return -1; - } - - tf[0] = 1.0 / sqrt(2.0); - tf[1] = 1.0 / sqrt(2.0); - - for (k = 0; k < n; k++) { - for (i = 0; i < 2 * (k + 2); i++) { - -#define H(X) (((X) < 0 || (X) >= 2 * (k + 1)) ? 0.0 : tf[X]) - - t[i] = 0.5 * (H(i - 2) + H(i) + - cos(alpha[k]) * (H(i - 2) - H(i)) + - (i & 1 ? -1.0 : 1.0) * sin(alpha[k]) * (H(2 * (k + 2) - i - 1) - H(2 * (k + 2) - i - 3))); - } - for (i = 0; i < 2 * (k + 2); i++) tf[i] = t[i]; - } - - /* set close-to-zero filter coefficients to zero */ - for (i = 0; i < 2 * (n + 1) ; i++) - if (fabs(tf[i]) < 1.0e-15) tf[i] = 0.0; - - /* find the first non-zero wavelet coefficient */ - i = 0; - while (tf[i] == 0.0) i++; - - /* find the last non-zero wavelet coefficient */ - j = 2 * (n + 1) - 1; - while (tf[j] == 0.0) j--; - - filterlength = j - i + 1; - for (k = 0; k < filterlength; k++) - switch (which) { - case FILTERG: - case FILTERGi: - filter[k] = (double) ((((i+1) & 0x01) * 2) - 1) * tf[i]; - i++; - break; - case FILTERH: - case FILTERHi: - filter[k] = tf[j--]; - break; - default: - return -1; - } - - while (k < 2 * (n + 1)) - filter[k++] = 0.0; - - return filterlength; -} - -void dwt_param_filter(double alpha[], int param_len[]) { - FilterGH filter; - int i; - int param_len_sum = 0; - -#ifdef DEBUG - if (dwt_levels <= 0) { - fprintf(stderr, "dwt_param_filter(): level invalid - set to zero\n"); - return; - } -#endif - -#ifdef DEBUG - if (!dwt_filters) { - fprintf(stderr, "dwt_param_filter(): wm_dwt not initialized, call init_dwt() first\n"); - return; - } -#endif - - - for (i = 0; i < dwt_levels + 1; i++) { - - filter = malloc(sizeof(struct FilterGHStruct)); -#ifdef DEBUG - if (!filter) { - fprintf(stderr, "dwt_param_filter(): malloc failed()\n"); - return; - } -#endif - - filter->type = FTOrtho; - filter->name = "param"; - - filter->g = new_filter(2 * (param_len[i] + 1)); - filter->g->type = FTSymm; - filter->g->hipass = 1; - filter->g->len = gen_param_filter(filter->g->data, - param_len[i], &alpha[param_len_sum], - FILTERG); - filter->g->start = -filter->g->len / 2; - filter->g->end = filter->g->len / 2 - 1; - - filter->h = new_filter(2 * (param_len[i] + 1)); - filter->h->type = FTSymm; - filter->h->hipass = 0; - filter->h->len = gen_param_filter(filter->h->data, - param_len[i], &alpha[param_len_sum], - FILTERH); - filter->h->start = -filter->h->len / 2; - filter->h->end = filter->h->len / 2 - 1; - - filter->gi = 0; - filter->hi = 0; - - dwt_filters[i] = filter; - - param_len_sum += param_len[i]; - } -} - -void done_dwt() { -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/dwt.h --- a/Meerwald/dwt.h Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -#ifndef DWT_H -#define DWT_H - -#include "wm.h" -#include "pgm.h" -#include "wavelet.h" - -#define FILTERG 1 -#define FILTERH 2 -#define FILTERGi 3 -#define FILTERHi 4 - -void init_dwt(int cols, int rows, const char *filter_name, int filter, int level, int method); -Image_tree fdwt(gray **input); -Image_tree fdwt_wp(gray **input); -void idwt(Image_tree dwts, gray **output); -void idwt_wp(Image_tree dwts, gray **output); -int gen_pollen_filter(double *filter, double alpha, double beta, int which); -void dwt_pollen_filter(double alpha, double beta); -int gen_param_filter(double *filter, int n, double alpha[], int which); -void dwt_param_filter(double alpha[], int param_len[]); -void done_dwt(); - -#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/dwt_util.c --- a/Meerwald/dwt_util.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,159 +0,0 @@ -#include "wm.h" -#include "dwt_util.h" -#include - -void copy_coeffs_from_dwt(double ** block_coeffs, double ** dwt_coeffs, -int level, int band, int width, int height) { - int i, j; - int size = width >> level; - int h = (band > 2) ? size : 0; - int w = (band & 1) ? 0 : size; - - for (i = 0; i < size; i++) - for (j = 0; j < size; j++) - block_coeffs[i][j] = dwt_coeffs[h + i][w + j]; -} - -void copy_coeffs_to_dwt(double ** dwt_coeffs, double ** block_coeffs, -int level, int band, int width, int height) { - int i, j; - int size = width >> level; - int h = (band > 2) ? size : 0; - int w = (band & 1) ? 0 : size; - - for (i = 0; i < size; i++) - for (j = 0; j < size; j++) - dwt_coeffs[h + i][w + j] = block_coeffs[i][j]; -} - -char *subband_name(int type) { - switch (type) { - case LL: return "LL"; - case HL: return "HL"; - case LH: return "LH"; - case HH: return "HH"; - default: return "XX"; - } -} - -int subband_in_list(char *list, int type, int level) { - return 1; -} - -int subband_wp_in_list(char *list, char *name) { - return 1; -} - -int calc_subband_wp_level(char *name){ - return strlen(name); -} - -void calc_subband_location(int cols, int rows, int type, int level, int *col, int *row) { - *col = *row = 0; - - if (level <= 0 || level > find_deepest_level(cols, rows) - 1) return; - - switch (type) { - case LL: - break; - case HL: - *col = 0; - *row = rows >> level; - break; - case LH: - *col = cols >> level; - *row = 0; - break; - case HH: - *col = cols >> level; - *row = rows >> level; - break; - default: - break; - } -} - -void calc_subband_wp_location(int cols, int rows, char *name, int *col, int *row) { - char *p = name; - int level = 0; - *col = *row = 0; - - while (*p) { - level++; - switch (toupper(*p)) { - case 'A': - break; - case 'H': - *col += (cols >> level); - break; - case 'V': - *row += (rows >> level); - break; - case 'D': - *col += (cols >> level); - *row += (rows >> level); - break; - default: - break; - } - p++; - } -} - -Pixel *get_dwt_data(Image_tree dwt, int level, int type) { - return get_dwt_image(dwt, level, type)->data; -} - -Image get_dwt_image(Image_tree dwt, int level, int type) { - return get_dwt_subband(dwt, level, type)->image; -} - -Image_tree get_dwt_subband(Image_tree dwt, int level, int type) { - while (--level) - dwt = dwt->coarse; - - switch (type) { - case LL: - return dwt->coarse; - case HL: - return dwt->vertical; - case LH: - return dwt->horizontal; - case HH: - return dwt->diagonal; - } - - return NULL; -} - -Pixel get_dwt_coeff(Image_tree dwt, int level, int type, int coeff) { - return get_dwt_data(dwt, level, type)[coeff]; -} - -Pixel get_dwt_location(Image_tree dwt, int level, int type, int col, int row) { - return get_pixel(get_dwt_image(dwt, level, type), col, row); -} - -static void calc__subband(Image_tree p, Image_tree q, double *min, double *max, double *error) { - int i; - - if (!p || !q) return; - - *error = 0; - *min = *max = fabs(p->image->data[0] - q->image->data[0]); - for (i = 0; i < p->image->size; i++) { - double diff = fabs(p->image->data[i] - q->image->data[i]); - - *error += sqr(diff); - if (diff < *min) *min = diff; - if (diff > *max) *max = diff; - } -} - -void calc_subband(Image_tree p, Image_tree q, int type, double *min, double *max, double *error) { - calc__subband(p, q, min, max, error); -} - -void calc_subband_wp(Image_tree p, Image_tree q, char *name, double *min, double *max, double *error) { - calc__subband(p, q, min, max, error); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/dwt_util.h --- a/Meerwald/dwt_util.h Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -#ifndef DWT_UTIL_H -#define DWT_UTIL_H - -#include "dwt.h" - -#define LL 1 -#define LH 2 -#define HL 3 -#define HH 4 - -#define COARSE LL -#define HORIZONTAL LH -#define VERTICAL HL -#define DIAGONAL HH - -void copy_coeffs_from_dwt(double ** block_coeffs, double ** dwt_coeffs, - int level, int band, int width, int height); - -void copy_coeffs_to_dwt(double ** dwt_coeffs, double ** block_coeffs, - int level, int band, int width, int height); - -char *subband_name(int type); - -int subband_in_list(char *list, int type, int level); -int subband_wp_in_list(char *list, char *name); - -void calc_subband_location(int cols, int rows, int type, int level, int *col, int *row); -void calc_subband_wp_location(int cols, int rows, char *name, int *col, int *row); -int calc_subband_wp_level(char *name); - -Pixel *get_dwt_data(Image_tree dwt, int level, int type); -Image get_dwt_image(Image_tree dwt, int level, int type); -Image_tree get_dwt_subband(Image_tree dwt, int level, int type); -Pixel get_dwt_coeff(Image_tree dwt, int level, int type, int coeff); -Pixel get_dwt_location(Image_tree dwt, int level, int type, int col, int row); - -void calc_subband(Image_tree p, Image_tree q, int type, double *min, double *max, double *error); -void calc_subband_wp(Image_tree p, Image_tree q, char *name, double *min, double *max, double *error); - - -#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/filter.dat --- a/Meerwald/filter.dat Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,774 +0,0 @@ -{ - Name biortho nr. 1 - Type biorthogonal - { - Type symm - Length 3 - Start 0 - End 2 - 0.353553 - -0.707107 - 0.353553 - } - { - Type symm - Length 5 - Start -2 - End 2 - -0.176777 - 0.353553 - 1.060660 - 0.353553 - -0.176777 - } - { - Type symm - Length 5 - Start -1 - End 3 - 0.176777 - 0.353553 - -1.060660 - 0.353553 - 0.176777 - } - { - Type symm - Length 3 - Start -1 - End 1 - 0.353553 - 0.707107 - 0.353553 - } -} - -{ - Name biortho nr. 2 - Type biorthogonal - { - Type symm - Length 7 - Start -4 - End 2 - -0.064539 - 0.040689 - 0.418092 - -0.788486 - 0.418092 - 0.040689 - -0.064539 - } - { - Type symm - Length 9 - Start -4 - End 4 - 0.037828 - -0.023849 - -0.110624 - 0.377402 - 0.852699 - 0.377402 - -0.110624 - -0.023849 - 0.037828 - } - { - Type symm - Length 9 - Start -5 - End 3 - -0.037828 - -0.023849 - 0.110624 - 0.377402 - -0.852699 - 0.377402 - 0.110624 - -0.023849 - -0.037828 - } - { - Type symm - Length 7 - Start -3 - End 3 - -0.064539 - -0.040689 - 0.418092 - 0.788486 - 0.418092 - -0.040689 - -0.064539 - } -} -{ - Name Daubechies 4 - Type orthogonal - { - Type symm - Length 4 - Start -1 - End 2 - - -0.129409522551 - -0.224143868042 - 0.836516303737 - -0.482962913144 - - } - { - Type symm - Length 4 - Start -1 - End 2 - - 0.482962913144 - 0.836516303737 - 0.224143868042 - -0.129409522551 - - } -} - -{ - Name Daubechies 6 - Type orthogonal - { - Type symm - Length 6 - Start -3 - End 2 - - 0.035226291882 - 0.085441273882 - -0.135011020010 - -0.459877502118 - 0.806891509311 - -0.332670552950 - - - } - { - Type symm - Length 6 - Start -1 - End 4 - - 0.332670552950 - 0.806891509311 - 0.459877502118 - -0.135011020010 - -0.085441273882 - 0.035226291882 - - } -} -{ - Name Daubechies 8 - Type orthogonal - { - Type symm - Length 8 - Start -1 - End 6 - - - -0.010597401785 - -0.032883011667 - 0.030841381836 - 0.187034811719 - -0.027983769417 - -0.630880766793 - 0.714846570553 - -0.230377813309 - - } - { - Type symm - Length 8 - Start -1 - End 6 - - 0.230377813309 - 0.714846570553 - 0.630880766793 - -0.027983769417 - -0.187034811719 - 0.030841381836 - 0.032883011667 - -0.010597401785 - - } -} -{ - Name Daubechies 10 - Type orthogonal - { - Type symm - Length 10 - Start -2 - End 7 - - 0.0033357252854738 - 0.0125807519990820 - -0.0062414902127983 - -0.0775714938400459 - -0.0322448695846381 - 0.2422948870663823 - 0.1384281459013203 - -0.7243085284377726 - 0.6038292697971895 - -0.1601023979741929 - - } - { - Type symm - Length 10 - Start -2 - End 7 - - 0.1601023979741929 - 0.6038292697971895 - 0.7243085284377726 - 0.1384281459013203 - -0.2422948870663823 - -0.0322448695846381 - 0.0775714938400459 - -0.0062414902127983 - -0.0125807519990820 - 0.0033357252854738 - - } -} - -{ - Name Daubechies 12 - Type orthogonal - { - Type symm - Length 12 - Start -1 - End 10 - - -0.0010773010853085 - -0.0047772575119455 - 0.0005538422011614 - 0.0315820393184862 - 0.0275228655303053 - -0.0975016055873225 - -0.1297668675672625 - 0.2262646939654400 - 0.3152503517091982 - -0.7511339080210959 - 0.4946238903984533 - -0.1115407433501095 - - } - { - Type symm - Length 12 - Start -1 - End 10 - - 0.1115407433501095 - 0.4946238903984533 - 0.7511339080210959 - 0.3152503517091982 - -0.2262646939654400 - -0.1297668675672625 - 0.0975016055873225 - 0.0275228655303053 - -0.0315820393184862 - 0.0005538422011614 - 0.0047772575119455 - -0.0010773010853085 - - } -} - -{ - Name Daubechies 14 - Type orthogonal - { - Type symm - Length 14 - Start -1 - End 12 - - 0.0003537138 - 0.001801640704 - 0.000429577973 - -0.012550998556 - -0.016574541631 - 0.038029936935 - 0.0806112609151 - -0.071309219267 - -0.224036184994 - 0.143906003929 - 0.469782287405 - -0.729132090846 - 0.396539319482 - -0.077852054085 - - } - { - Type symm - Length 14 - Start -1 - End 12 - - 0.077852054085 - 0.396539319482 - 0.729132090846 - 0.469782287405 - -0.143906003929 - -0.224036184994 - 0.071309219267 - 0.0806112609151 - -0.038029936935 - -0.016574541631 - 0.012550998556 - 0.000429577973 - -0.001801640704 - 0.0003537138 - - } -} - - -{ - Name Daubechies 20 - Type orthogonal - { - Type symm - Length 20 - Start -1 - End 18 - - -0.000013264203 - -0.000093588670 - -0.000116466855 - 0.000685856695 - 0.001992405295 - 0.001395351747 - -0.010733175483 - -0.003606553567 - 0.033212674059 - 0.029457536822 - -0.071394147166 - -0.093057364604 - 0.127369340336 - 0.195946274377 - -0.249846424327 - -0.281172343661 - 0.688459039454 - -0.527201188932 - 0.188176800078 - -0.026670057901 - - } - { - Type symm - Length 20 - Start -1 - End 18 - - 0.026670057901 - 0.188176800078 - 0.527201188932 - 0.688459039454 - 0.281172343661 - -0.249846424327 - -0.195946274377 - 0.127369340336 - 0.093057364604 - -0.071394147166 - -0.029457536822 - 0.033212674059 - 0.003606553567 - -0.010733175483 - 0.001395351747 - 0.001992405295 - -0.000685856695 - -0.000116466855 - 0.000093588670 - -0.000013264203 - } -} - - -{ - Name Beylkin 18 - Type orthogonal - { - Type symm - Length 18 - Start -1 - End 16 - - 0.00064048532852124535 - 0.0027360316262586061 - 0.0014842347824723461 - -0.01004041184463199 - -0.014365807968852611 - 0.017460408696028829 - 0.042916387274192273 - -0.01967986604432212 - -0.088543630622924835 - 0.017520746266529649 - 0.1555387318770938 - -0.02690030880369032 - -0.26449723144638482 - 0.1109275983482343 - 0.44971825114946867 - -0.69982521405660059 - 0.42421536081296141 - -0.099305765374353927 - - } - { - Type symm - Length 18 - Start -1 - End 16 - - 0.099305765374353927 - 0.42421536081296141 - 0.69982521405660059 - 0.44971825114946867 - -0.1109275983482343 - -0.26449723144638482 - 0.02690030880369032 - 0.1555387318770938 - -0.017520746266529649 - -0.088543630622924835 - 0.01967986604432212 - 0.042916387274192273 - -0.017460408696028829 - -0.014365807968852611 - 0.01004041184463199 - 0.0014842347824723461 - -0.0027360316262586061 - 0.00064048532852124535 - - } -} - - -{ - Name Vaidyanathan 24 - Type orthogonal - { - Type symm - Length 24 - Start -1 - End 22 - - 0.045799334110976718 - -0.25018412950466218 - 0.57279779321073432 - -0.63560105987221494 - 0.20161216177530866 - 0.26349480248845991 - -0.19445047176647817 - -0.13508422712948126 - 0.13197166141697772 - 0.08392888436611283 - -0.07770975090196941 - -0.055892523691373548 - 0.03874261929341144 - 0.035470398607283453 - -0.014853448005230099 - -0.019687215010072714 - 0.003153847055897004 - 0.008839103408613878 - 0.00070813750405244471 - -0.0028438345468355646 - -0.00094489713632194927 - 0.00045395661963721929 - 0.00034363190482102919 - 0.000062906118190737523 - - } - { - Type symm - Length 24 - Start -1 - End 22 - - -0.000062906118190737523 - 0.00034363190482102919 - -0.00045395661963721929 - -0.00094489713632194927 - 0.0028438345468355646 - 0.00070813750405244471 - -0.008839103408613878 - 0.003153847055897004 - 0.019687215010072714 - -0.014853448005230099 - -0.035470398607283453 - 0.03874261929341144 - 0.055892523691373548 - -0.07770975090196941 - -0.08392888436611283 - 0.13197166141697772 - 0.13508422712948126 - -0.19445047176647817 - -0.26349480248845991 - 0.20161216177530866 - 0.63560105987221494 - 0.57279779321073432 - 0.25018412950466218 - 0.045799334110976718 - } -} - - -{ - Name Coifman 6 - Type orthogonal - { - Type symm - Length 6 - Start -1 - End 4 - - 0.226584276197068560 - -0.745687558934434280 - 0.607391641385684120 - 0.077161555495773498 - -0.12696912539620520 - 0.038580777747886749 - - } - { - Type symm - Length 6 - Start -1 - End 4 - - 0.038580777747886749 - -0.12696912539620520 - -0.077161555495773498 - 0.607391641385684120 - 0.745687558934434280 - 0.226584276197068560 - } -} - - -{ - Name Coifman 12 - Type orthogonal - { - Type symm - Length 12 - Start -1 - End 10 - - -0.000720549445369115120 - 0.00182320887091009920 - 0.00561143481936598850 - -0.0236801719468767500 - -0.0594344186464712400 - 0.0764885990782645940 - 0.417005184423777600 - -0.812723635449606130 - 0.386110066823092900 - 0.0673725547222998740 - -0.0414649367819664850 - -0.0163873364631797850 - - } - { - Type symm - Length 12 - Start -1 - End 10 - - 0.0163873364631797850 - -0.0414649367819664850 - -0.0673725547222998740 - 0.386110066823092900 - 0.812723635449606130 - 0.417005184423777600 - -0.0764885990782645940 - -0.0594344186464712400 - 0.0236801719468767500 - 0.00561143481936598850 - -0.00182320887091009920 - -0.000720549445369115120 - - } -} - - -{ - Name Coifman 18 - Type orthogonal - { - Type symm - Length 18 - Start -1 - End 16 - - -0.000034599773197402695 - 0.000070983302505704928 - 0.00046621695982014403 - -0.00111751877082696180 - -0.0025745176881279692 - 0.0090079761367322896 - 0.0158805448636159010 - -0.0345550275733444640 - -0.082301927106320283 - 0.071799821619170590 - 0.428483476377618690 - -0.793777222625620340 - 0.405176902409616790 - 0.0611233900029556980 - -0.0657719112814312280 - -0.0234526961421191030 - 0.00778259642567178690 - 0.00379351286437787590 - - } - { - Type symm - Length 18 - Start -1 - End 16 - - -0.00379351286437787590 - 0.00778259642567178690 - 0.0234526961421191030 - -0.0657719112814312280 - -0.0611233900029556980 - 0.405176902409616790 - 0.793777222625620340 - 0.428483476377618690 - -0.071799821619170590 - -0.082301927106320283 - 0.0345550275733444640 - 0.0158805448636159010 - -0.0090079761367322896 - -0.0025745176881279692 - 0.00111751877082696180 - 0.00046621695982014403 - -0.000070983302505704928 - -0.000034599773197402695 - - } -} - -{ - Name Biorthogonal 1,3 - Type biorthogonal - { - Type symm - Length 6 - Start -1 - End 4 - - -0.08838834764832 - -0.08838834764832 - 0.707106781 - -0.707106781 - 0.08838834764832 - 0.08838834764832 - - } - { - Type symm - Length 2 - Start 1 - End 2 - 0.707106781 - 0.707106781 - - } - - { - Type symm - Length 2 - Start 1 - End 2 - 0.707106781 - -0.707106781 - } - { - Type symm - Length 6 - Start -1 - End 4 - - -0.08838834764832 - 0.08838834764832 - 0.707106781 - 0.707106781 - 0.08838834764832 - -0.08838834764832 - - } -} - -{ - Name Biorthogonal 1,5 - Type biorthogonal - { - Type symm - Length 10 - Start -1 - End 8 - - 0.01657281518406 - 0.01657281518406 - -0.1215339780164 - -0.1215339780164 - 0.707106781 - -0.707106781 - 0.1215339780164 - 0.1215339780164 - -0.01657281518406 - -0.01657281518406 - - } - { - Type symm - Length 2 - Start 3 - End 4 - - 0.707106781 - 0.707106781 - } - - { - Type symm - Length 2 - Start 3 - End 4 - - 0.707106781 - -0.707106781 - } - { - Type symm - Length 10 - Start -1 - End 8 - - 0.01657281518406 - -0.01657281518406 - -0.1215339780164 - 0.1215339780164 - 0.707106781 - 0.707106781 - 0.1215339780164 - -0.1215339780164 - -0.01657281518406 - 0.01657281518406 - - } -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/frid2_common.c --- a/Meerwald/frid2_common.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,220 +0,0 @@ -#include "frid2_common.h" -#include "signature-utils.h" -#include "wm.h" - -extern char *progname; - -void embed_low_freq(double **dcts, int cols, int rows, double alpha, int verbose) { - int n; - int row, col, dir; - - n = 0; - row = col = 0; - dir = 1; - while (n < nbit_signature) { - double d, x; - int embed; - int out; - - col -= dir; - row += dir; - if (col < 0) { dir = -1; col = 0; } - if (col >= cols) { dir = 1; col = cols - 1; row += 2; } - if (row < 0) { dir = 1; row = 0; } - if (row >= rows) { dir = -1; row = rows - 1; col += 2; } - - d = dcts[row][col]; - if (fabs(d) <= 1.0) { - if (verbose > 3) - fprintf(stderr, "%s: bit #%d - skipped (%d/%d)\n", progname, n, col, row); - continue; - } - - embed = 2 * get_signature_bit(n) - 1; - - x = (d > 0.0) ? 1.0 : -1.0; - out = 1; - while (fabs(x) < fabs(d)) { - x *= FORWARD_STEP(alpha); - out =- out; - } - - if (out != embed) { - if (fabs(d - x) < fabs(d - x * BACKWARD_STEP(alpha))) - x *= FORWARD_STEP(alpha); - else - x *= BACKWARD_STEP(alpha); - } - - d = (x + x * BACKWARD_STEP(alpha)) / 2.0; - - if (verbose > 3) - fprintf(stderr, "%s: embedding bit #%d (= %d) at (%d/%d): %f -> %f\n", progname, n, get_signature_bit(n), col, row, dcts[row][col], d); - - dcts[row][col] = d; - - n++; - } -} - -void embed_med_freq(double **dcts, int cols, int rows, double gamma, int seed, int verbose) { - // select mid-frequency (30%) coefficients - int start = (int) (0.35 * rows * cols + 0.5); - int end = (int) (0.65 * rows * cols + 0.5); - - double *vector; - int x = 0, y = 0, dir = 1; - int i, j; - - vector = malloc((end - start) * sizeof(double)); - for (i = 0; i < (end - start); i++) - vector[i] = 0.0; - - // create pseudo-random vector - srandom(seed); - for (i = 0; i < nbit_signature; i++) { - if (get_signature_bit(i)) - random(); - for (j = 0; j < (end - start); j++) - vector[j] += (double) (random() & RAND_MAX) / (double) RAND_MAX - 0.5; - if (!get_signature_bit(i)) - random(); - } - - for (i = 0; i < (end - start); i++) - vector[i] /= sqrt(nbit_signature); - - for (i = 0; i < end; i++) { - // zig-zag scan - x -= dir; - y += dir; - if (x < 0) { dir = -1; x = 0; } - if (x >= cols) { dir = 1; x = cols - 1; y += 2; } - if (y < 0) { dir = 1; y = 0; } - if (y >= rows) { dir = -1; y = rows - 1; x += 2; } - - // embed vector - if ((i - start) >= 0) { -// fprintf(stderr, "%d/%d: %f -> %f\n", x, y, dcts[y][x], dcts[y][x] + gamma * vector[i - start]); - dcts[y][x] += gamma * vector[i - start]; - } - } - - free(vector); -} - -double detect_low_freq(double **dcts, int cols, int rows, double alpha, double beta, int verbose) { - int n; - int row, col, dir; - double sum1, sum2; - - n = 0; - row = col = 0; - dir = 1; - sum1 = sum2 = 0.0; - while (n < nbit_signature1) { - double d, x; - int detect; - int out; - - col -= dir; - row += dir; - if (col < 0) { dir = -1; col = 0; } - if (col >= cols) { dir = 1; col = cols - 1; row += 2; } - if (row < 0) { dir = 1; row = 0; } - if (row >= rows) { dir = -1; row = rows - 1; col += 2; } - - d = dcts[row][col]; - if (fabs(d) <= 1.0) { - if (verbose > 3) - fprintf(stderr, "%s: bit #%d - skipped (%d/%d)\n", progname, n, col, row); - continue; - } - - detect = 2 * get_signature1_bit(n) - 1; - - x = (d > 0.0) ? 1.0 : -1.0; - out = 1; - while (fabs(x) < fabs(d)) { - x *= FORWARD_STEP(alpha); - out =- out; - } - - if (verbose > 3) - fprintf(stderr, "%s: detected bit #%d (= %d) at (%d/%d): %f\n", progname, n, out > 0 ? 1 : 0, col, row, d); - - set_signature2_bit(n, out > 0 ? 1 : 0); - sum1 += pow(fabs(d), beta) * out * detect; - sum2 += pow(fabs(d), beta); - - n++; - } - - return sum1 / sum2; -} - -double detect_med_freq(double **dcts, int cols, int rows, int seed, int verbose) { - int i, j, k; - int start= (int) (0.35 * rows * cols + 0.5); - int end = (int) (.65 * rows * cols + 0.5); - - int sum, sum1, sum2; - int x = 0, y = 0, dir = 1; - double *vector; - int startx, starty, startdir; - double corr[2]; - double correlation; - - // locate start positions - for (i = 0; i < start; i++) { - x -= dir; - y += dir; - if (x < 0) { dir = -1; x = 0; } - if (x >= cols) { dir = 1; x = cols - 1; y += 2; } - if (y < 0) { dir = 1; y = 0; } - if (y >= rows) { dir = -1; y = rows - 1; x += 2; } - } - - // save start positions - startx = x; - starty = y; - startdir = dir; - srandom(seed); - - vector = malloc((end - start) * sizeof(double)); - - for (i = 0; i < nbit_signature1; i++) { - - for (j = 0; j <= (end - start); j++) - vector[j] = (double) (random() & RAND_MAX) / (double) RAND_MAX - 0.5; - - for (j = 0; j <= 1; j++) { - x = startx; - y = starty; - dir = startdir; - corr[j] = 0; - - for (k = 0; start + k < end; k++) { - x -= dir; - y += dir; - if (x < 0) { dir = -1; x = 0; } - if (x >= cols) { dir = 1; x = cols - 1; y += 2; } - if (y < 0) { dir = 1; y = 0; } - if (y >= rows) { dir = -1; y = rows - 1; x += 2; } - corr[j] += dcts[y][x] * vector[k + j]; - } - } - - set_signature2_bit(i, (corr[0] >= corr[1]) ? 0 : 1); - } - - sum = 0; sum1 = 0; sum2 = 0; - for (i = 0; i < nbit_signature1; i++) { - sum += get_signature1_bit(i) * get_signature2_bit(i); - sum1 += get_signature1_bit(i) * get_signature1_bit(i); - sum2 += get_signature2_bit(i) * get_signature2_bit(i); - } - correlation = (double) sum / (sqrt(sum1) * sqrt(sum2)); - - return correlation; -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/frid2_common.h --- a/Meerwald/frid2_common.h Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,12 +0,0 @@ -#ifndef FRID2_COMMON_H -#define FRID2_COMMON_H - -#define FORWARD_STEP(A) ((1.0 + A) / (1.0 - A)) -#define BACKWARD_STEP(A) ((1.0 - A) / (1.0 + A)) - -void embed_low_freq(double **dcts, int cols, int rows, double alpha, int verbose); -void embed_med_freq(double **dcts, int cols, int rows, double gamma, int seed, int verbose); -double detect_low_freq(double **dcts, int cols, int rows, double alpha, double beta, int verbose); -double detect_med_freq(double **dcts, int cols, int rows, int seed, int verbose); - -#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_bruyn_sig.1 --- a/Meerwald/gen_bruyn_sig.1 Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -.\" -.\" gen_bruyn_sig.1 - the *roff document processor man page source -.\" -.TH gen_bruyn_sig 1 "98/06/30" "Watermarking, Version 1.0" -.SH NAME -gen_bruyn_sig \- an man page source template -.SH SYNOPSIS -.B gen_bruyn_sig -[ -.B \-abcdef -] -[ -.BI \-d opt -] -[ -.BI \-o file -] -[ -.IR files \|.\|.\|.\| -] -.SH DESCRIPTION -.B gen_bruyn_sig -is a program. -.PP -the -.B \-d -option is one of the following: -.TP -.B opt1 for option 1 -.TP -.B opt2 for option 2 -.TP -.B opt3 for option 3 -.LP -I hope you can guess the purpose of the program. -.LP -Can you? -.P -.SH OPTIONS -.TP -.B \-a -option a -.TP -.B \-b -option b -.TP -.B \-c -option c -.TP -.B \-d -option d -.TP -.B \-e -option e -.TP -.B \-f -option f -.PP -These are all the options, now on with some environment variables: -.TP -.SM -.B ENV_VAR1 -environment variable 1 -.TP -.SM -.B ENV_VAR2 -environment variable 2 -.TP -.SM -.B ENV_VAR3 -environment variable 2 -.SH FILES -.SH AUTHOR -Peter Meerwald -.SH NOTES -.SH BUGS -Email bug reports to pmeerw@cosy.sbg.ac.at. -.SH COPYRIGHT -Copyright \(co 1998 Peter Meerwald -.SH AVAILABILITY -The most recent released version of -.B gen_bruyn_sig -is always available -at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the -directory /pub/people/pmeerw/Watermarking. -.SH "SEE ALSO" -.BR program1, -.BR program2, -.BR program3 diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_bruyn_sig.c --- a/Meerwald/gen_bruyn_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,232 +0,0 @@ -#include "wm.h" -#include "signature.h" -#include "bruyn_common.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-b n] [-k] [-n n] [-o file] [-pP n] [-q n] [-s file] [-S n] [-tT n] file\n\n", progname); - fprintf(stderr, "\t-b n\t\tblock size (default 8)\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-k\t\tdisable block skipping\n"); - fprintf(stderr, "\t-n n\t\twatermark bit length\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-p n\t\tpattern type for zone 1 (default 1, 1.." NPATTERN_USAGE ")\n"); - fprintf(stderr, "\t-P n\t\tpattern type for zone 2 (default 2, 1.." NPATTERN_USAGE ")\n"); - fprintf(stderr, "\t-q n\t\tsignature strength (default 7.0)\n"); - fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); - fprintf(stderr, "\t-S n\t\tseed\n"); - fprintf(stderr, "\t-t n\t\tthreshold for noise (default " THRESHOLD_NOISE_USAGE ")\n"); - fprintf(stderr, "\t-T n\t\tthreshold for slope (default " THRESHOLD_SLOPE_USAGE ")\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int c; - int i; - int b = 8; - int n = 0; - int nb; - int s = 0; - int p1 = 1; - int p2 = 2; - double t1 = THRESHOLD_NOISE; - double t2 = THRESHOLD_SLOPE; - double q = 7.0; - int skipping = 0; - - progname = argv[0]; - wm_init(); - - while ((c = getopt(argc, argv, "b:h?n:o:p:P:q:s:S:t:T:k")) != EOF) { - switch (c) { - case 'b': - b = atoi(optarg); - if (b <= 0) { - fprintf(stderr, "%s: block size %d out of range\n", progname, b); - exit(1); - } - break; - case 'k': - skipping = 1; - break; - case 'h': - case '?': - usage(); - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 1000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'p': - p1 = atoi(optarg); - if (p1 <= 0 || p1 > NPATTERN) { - fprintf(stderr, "%s: pattern type out of range\n", progname); - exit(1); - } - break; - case 'P': - p2 = atoi(optarg); - if (p2 <= 0 || p2 > NPATTERN) { - fprintf(stderr, "%s: pattern type out of range\n", progname); - exit(1); - } - break; - case 'q': - q = atof(optarg); - if (q <= 0.0) { - fprintf(stderr, "%s: signature strength factor %f out of range\n", progname, q); - exit(1); - } - break; - case 't': - t1 = atof(optarg); - if (t1 <= 0) { - fprintf(stderr, "%s: noise threshold %f out of range\n", progname, t1); - } - break; - case 'T': - t2 = atof(optarg); - if (t2 <= 0) { - fprintf(stderr, "%s: slope threshold %f out of range\n", progname, t2); - } - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'S': - s = atoi(optarg); - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (b % 2 > 0 || b <= 2) { - fprintf(stderr, "%s: block size has to be even and greater than 2\n", progname); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - // read signature file and set options - // command line options override signature file options - if (sig) { - char line[128]; - fgets(line, sizeof(line), sig); - if (strspn(line, "BRSG") >= 4) { - if (n == 0) - fscanf(sig, "%d\n", &n); - else - fscanf(sig, "%*d\n"); - if (skipping == 0) - fscanf(sig, "%d\n", &skipping); - else - fscanf(sig, "%*d\n"); - if (p1 == 0) - fscanf(sig, "%d\n", &p1); - else - fscanf(sig, "%*d\n"); - if (p2 == 0) - fscanf(sig, "%d\n", &p2); - else - fscanf(sig, "%*d\n"); - if (q == 0.0) - fscanf(sig, "%lf\n", &q); - else - fscanf(sig, "%*f\n"); - if (t1 == 0.0) - fscanf(sig, "%lf\n", &t1); - else - fscanf(sig, "%*f\n"); - if (t2 == 0.0) - fscanf(sig, "%lf\n", &t2); - else - fscanf(sig, "%*f\n"); - if (b == 0) - fscanf(sig, "%d\n", &b); - else - fscanf(sig, "%*d\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - - if (s) - srandom(s); - else - srandom(time(NULL) * getpid()); - - if (n > 0) { - nb = fread(signature, sizeof(char), i = NBITSTOBYTES(n), in); - if (nb < i) { - fprintf(stderr, "%s: failed to read all %d signature bits from %s\n", progname, n, input_name); - exit(1); - } - } - else { - if (fscanf(in, "%128[^\n\r]", signature) == EOF) { - fprintf(stderr, "%s: failed to read signature bits from %s\n", progname, input_name); - exit(1); - } - nb = strlen(signature); - n = NBYTESTOBITS(nb); - fprintf(stderr, "%s: got %d signature bits\n", progname, n); - } - - - fprintf(out, "BRSG\n"); - fprintf(out, "%d\n", n); - fprintf(out, "%d\n", skipping); - fprintf(out, "%d\n", p1); - fprintf(out, "%d\n", p2); - fprintf(out, "%f\n", q); - fprintf(out, "%f\n", t1); - fprintf(out, "%f\n", t2); - fprintf(out, "%d\n", b); - fprintf(out, "%ld\n", random()); - fwrite(signature, sizeof(char), nb, out); - fprintf(out, "\n"); - - fclose(out); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_corvi_sig.1 --- a/Meerwald/gen_corvi_sig.1 Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,161 +0,0 @@ -.\" -.\" gen_corvi_sig.1 - the *roff document processor man page source -.\" -.TH gen_corvi_sig 1 "98/07/17" "Watermarking, Version 1.0" -.SH NAME -.B gen_corvi_sig -\- a program to generate a signature for -the -.B wm_corvi_e -watermarking program -.SH SYNOPSIS -.B gen_corvi_sig -[ -.BI \-a \ number -] -[ -.BI \-d \ number -] -[ -.BI \-e \ number -] -[ -.BI \-f \ number -] -[ -.BI \-F \ ffile -] -[ -.BI \-g \ number -] -.br -[ -.B \-h -] -[ -.BI \-m \ number -] -[ -.BI \-n \ number -] -[ -.BI \-o \ file -] -[ -.BI \-q \ number -] -[ -.BI \-s \ number -] -.SH DESCRIPTION -.B gen_corvi_sig -is a program to generate a signature to be -embedded with the -.B wm_corvi_e -watermarking program and extracted with the -.B wm_corvi_d -program. The -.B cmp_corvi_sig -program is used to compare and test an -extracted signature with the original signature. -.PP -Please refer to Marco Corvi's paper "Wavlet-based image watermarking -for copyright protection", to get an idea of the algorithm. -.PP -.SH OPTIONS -.TP -.BI \-a \ number -Alpha factor that determines embedding strength of the signature. Default -value 0.3. -.TP -.BI \-d \ number -Deviation for the normal distributed signature values, default 1.0. -.TP -.BI \-e \ number -The filtering method for the forward wavelet transform. Default value -1. -.TP -.BI \-F \ ffile -The filter definition file. Default -.I filter.dat. -.TP -.BI \-f \ number -Use the -.I number -filter from the filter definition file, -.I ffile. Default: 1. -.TP -.BI \-g \ number -The filtering method for the inverse wavelet transform. Default value -2. -.TP -.B \-h -Print a help message. -.TP -.BI \-m \ number -Mean of the normal distributed signature values, default 0.0. -.TP -.BI \-n \ number -Length of the watermark. Default value 100. -.TP -.BI \-o \ file -Output signature to the specified -.I file -instead of standard output. -.TP -.BI \-q \ number -Quantization/quality factor. Default value 3. -.TP -.BI \-s \ number -Specify a seed value to initialize the pseudo-random number -generator; if not specified, time and pid (process id) are used -to initialize the pseudo-random number generator. -.PP -.SH OUTPUT -The output file has the following format: -.TP -.B CVSG -Magic to identify file type. -.TP -.I number -The length of the signature in bits. -.TP -.I number -The alpha factor (embedding strength). -.TP -.I number -The quantization/quality factor. -.TP -.I number -The wavelet forward transform filtering method. -.TP -.I number -The wavelet filter number. -.TP -.I file -The wavelet filter definition file name. -.TP -.I number -The wavelet inverse transform filtering method. -.TP -.I numbers -The actual normal distributed signature values, one per line. -.PP -.SH AUTHOR -Peter Meerwald. -Email bug reports to pmeerw@cosy.sbg.ac.at. -.SH AVAILABILITY -The most recent released version of -.B gen_corvi_sig -is always available -at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the -directory /pub/people/pmeerw/Watermarking. -.SH "SEE ALSO" -.BR wm_corvi_e -(1), -.BR wm_corvi_d -(1), -.BR wm_corvi_s -(1), -.BR cmp_corvi_sig -(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_corvi_sig.c --- a/Meerwald/gen_corvi_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +0,0 @@ -#include "wm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-d n] [-e n] [-f n] [-F file] [-m n] [-n n] [-o file] [-s n]\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor (default 0.1)\n"); - fprintf(stderr, "\t-d n\t\tdeviation (default 1.0)\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); - fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-m n \t\tmean value (default 0.0)\n"); - fprintf(stderr, "\t-n n\t\twatermark length (default 1000)\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-s n\t\tseed\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - FILE *out = stdout; - - char output_name[MAXPATHLEN] = "(stdout)"; - - int c; - int n = 1000; - int s = 0; - int e = 2; - int f = 1; - char F[MAXPATHLEN] = "filter.dat"; - double a = 0.1; - double m = 0.0; - double d = 1.0; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "a:d:e:f:F:h?m:n:o:s:")) != EOF) { - switch (c) { - case 'a': - a = atof(optarg); - if (a <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); - exit(1); - } - break; - case 'd': - d = atof(optarg); - if (d <= 0.0) { - fprintf(stderr, "%s: deviation %f out of range\n", progname, d); - exit(1); - } - break; - case 'e': - e = atoi(optarg); - if (e < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); - } - break; - case 'f': - f = atoi(optarg); - if (f <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, f); - exit(1); - } - break; - case 'F': - strcpy(F, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'm': - m = atof(optarg); - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 32000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - s = atoi(optarg); - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 0) { - usage(); - exit(1); - } - - if (s) - srandom(s); - else - srandom(time(NULL) * getpid()); - - fprintf(out, "CVSG\n"); - fprintf(out, "%d\n", n); - fprintf(out, "%f\n", a); - fprintf(out, "%d\n", e); - fprintf(out, "%d\n", f); - fprintf(out, "%s\n", F); - - n >>= 1; - while (n > 0) { - double x; - double x1, x2; - - /* - * Algorithm P (Polar method for normal deviates), - * Knuth, D., "The Art of Computer Programming", Vol. 2, 3rd Edition, p. 122 - */ - do { - x1 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; - x2 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; - x = x1 * x1 + x2 * x2; - } while (x >= 1.0); - x1 *= sqrt((-2.0) * log(x) / x); - x2 *= sqrt((-2.0) * log(x) / x); - - fprintf(out, "%f\n", m + d * x1); - fprintf(out, "%f\n", m + d * x2); - - n--; - } - - fclose(out); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_cox_sig.1 --- a/Meerwald/gen_cox_sig.1 Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,115 +0,0 @@ -.\" -.\" gen_cox_sig.1 - the *roff document processor man page source -.\" -.TH gen_cox_sig 1 "98/06/30" "Watermarking, Version 1.0" -.SH NAME -.B gen_cox_sig -\- a program to generate a signature for -the -.B wm_cox_e -watermarking program -.SH SYNOPSIS -.B gen_cox_sig -[ -.BI \-a \ number -] -[ -.BI \-d \ number -] -[ -.B \-h -] -[ -.BI \-m \ number -] -[ -.BI \-n \ number -] -[ -.BI \-o \ file -] -[ -.BI \-q \ number -] -[ -.BI \-s \ number -] -.SH DESCRIPTION -.B gen_cox_sig -is a program to generate a signature to be -embedded with the -.B wm_cox_e -watermarking program and extracted with the -.B wm_cox_d -program. The -.B cmp_cox_sig -program is used to compare and test an -extracted signature with the original signature. -.PP -Please refer to Ingemar J. Cox's paper "Secure Spread Spectrum -Watermarking for Multimedia", 1995, to get an idea about the algorithm. -.PP -.SH OPTIONS -.TP -.BI \-a \ number -Alpha factor that determines embedding strength of the signature. Default -value 0.3. -.TP -.BI \-d \ number -Deviation for the normal distributed signature values, default 1.0. -.TP -.B \-h -Print a help message. -.TP -.BI \-m \ number -Mean of the normal distributed signature values, default 0.0. -.TP -.BI \-n \ number -Length of the watermark. Default value 100. -.TP -.BI \-o \ file -Output signature to the specified -.I file -instead of standard output. -.TP -.BI \-q \ number -Quantization/quality factor. Default value 3. -.TP -.BI \-s \ number -Specify a seed value to initialize the pseudo-random number -generator; if not specified, time and pid (process id) are used -to initialize the pseudo-random number generator. -.PP -.SH OUTPUT -The output file has the following format: -.TP -.B CXSG -Magic to identify file type. -.TP -.I number -The length of the signature in bits. -.TP -.I number -The alpha factor (embedding strength). -.TP -.I number -The quantization/quality factor. -.TP -.I numbers -The actual normal distributed signature values, one per line. -.PP -.SH AUTHOR -Peter Meerwald. Email bug reports to pmeerw@cosy.sbg.ac.at. -.SH AVAILABILITY -The most recent released version of -.B gen_cox_sig -is always available -at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the -directory /pub/people/pmeerw/Watermarking. -.SH "SEE ALSO" -.BR wm_cox_e -(1), -.BR wm_cox_d -(1), -.BR cmp_cox_sig -(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_cox_sig.c --- a/Meerwald/gen_cox_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,157 +0,0 @@ -#include "wm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-d n] [-m n] [-n n] [-o file] [-s file] [-S n]\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor (default 0.3)\n"); - fprintf(stderr, "\t-d n\t\tdeviation (default 1.0)\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-m n \t\tmean value (default 0.0)\n"); - fprintf(stderr, "\t-n n\t\twatermark length (default 100)\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); - fprintf(stderr, "\t-S n\t\tseed\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char signature_name[MAXPATHLEN]; - - int c; - int n = 100; - int s = 0; - double a = 0.3; - double m = 0.0; - double d = 1.0; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "a:d:h?m:n:o:s:S:")) != EOF) { - switch (c) { - case 'a': - a = atof(optarg); - if (a <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); - exit(1); - } - break; - case 'd': - d = atof(optarg); - if (d <= 0.0) { - fprintf(stderr, "%s: deviation %f out of range\n", progname, d); - exit(1); - } - break; - case 'h': - case '?': - usage(); - break; - case 'm': - m = atof(optarg); - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 32000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'S': - s = atoi(optarg); - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 0) { - usage(); - exit(1); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "CXSG") >= 4) { - if (n == 0) - fscanf(sig, "%d\n", &n); - else - fscanf(sig, "%*d\n"); - if (a == 0.0) - fscanf(sig, "%lf\n", &a); - else - fscanf(sig, "%*f\n"); - if (m == 0.0) - fscanf(sig, "%lf\n", &m); - else - fscanf(sig, "%*f\n"); - if (d == 0.0) - fscanf(sig, "%lf\n", &d); - else - fscanf(sig, "%*f\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - - if (s) - srandom(s); - else - srandom(time(NULL) * getpid()); - - fprintf(out, "CXSG\n"); - fprintf(out, "%d\n", n); - fprintf(out, "%f\n", a); - fprintf(out, "%f\n", m); - fprintf(out, "%f\n", d); - - n >>= 1; - while (n > 0) { - double x; - double x1, x2; - - /* - * Algorithm P (Polar method for normal deviates), - * Knuth, D., "The Art of Computer Programming", Vol. 2, 3rd Edition, p. 122 - */ - do { - x1 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; - x2 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; - x = x1 * x1 + x2 * x2; - } while (x >= 1.0); - x1 *= sqrt((-2.0) * log(x) / x); - x2 *= sqrt((-2.0) * log(x) / x); - - fprintf(out, "%f\n", m + d * x1); - fprintf(out, "%f\n", m + d * x2); - - n--; - } - - fclose(out); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_dugad_sig.c --- a/Meerwald/gen_dugad_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,226 +0,0 @@ -#include "wm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-e n] [-f n] [-F file] [-l n] [-n n] [-o file] [-s file] [-S n] [-t n] [-T n]\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor (default 0.2)\n"); - fprintf(stderr, "\t-d n\t\tdeviation (default 1.0)\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); - fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-l n\t\tdecomposition levels (default 3)\n"); - fprintf(stderr, "\t-m n \t\tmean value (default 0.0)\n"); - fprintf(stderr, "\t-n n\t\twatermark length (default 1000)\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - fprintf(stderr, "\t-S n\t\tseed\n"); - fprintf(stderr, "\t-t n\t\tcasting threshold (default 40.0)\n"); - fprintf(stderr, "\t-T n\t\tdetection threshold (default 50.0)\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char signature_name[MAXPATHLEN]; - - int c; - int n = 1000; - int s = 0; - int e = 2; - int f = 1; - int l = 3; - char F[MAXPATHLEN] = "filter.dat"; - double a = 0.2; - double t1 = 40.0; - double t2 = 50.0; - double m = 0.0; - double d = 1.0; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "a:b:d:e:f:F:h?l:m:n:o:s:S:t:T:")) != EOF) { - switch (c) { - case 'a': - a = atof(optarg); - if (a <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); - exit(1); - } - break; - case 'd': - d = atof(optarg); - if (d <= 0.0) { - fprintf(stderr, "%s: deviation %f out of range\n", progname, d); - exit(1); - } - break; - - case 'e': - e = atoi(optarg); - if (e < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); - } - break; - case 'f': - f = atoi(optarg); - if (f <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, f); - exit(1); - } - break; - case 'F': - strcpy(F, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'l': - l = atoi(optarg); - if (l <= 0) { - fprintf(stderr, "%s: decomposition level %d out of range\n", progname, l); - exit(1); - } - break; - case 'm': - m = atof(optarg); - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 32000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'S': - s = atoi(optarg); - break; - case 't': - t1 = atof(optarg); - if (t1 <= 0.0) { - fprintf(stderr, "%s: casting threshold %f out of range\n", progname, t1); - exit(1); - } - break; - case 'T': - t2 = atof(optarg); - if (t2 <= 0.0) { - fprintf(stderr, "%s: detection threshold %f out of range\n", progname, t2); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 0) { - usage(); - exit(1); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "DGSG") >= 4) { - if (n == 0) - fscanf(sig, "%d\n", &n); - else - fscanf(sig, "%*d\n"); - if (l == 0) - fscanf(sig, "%d\n", &l); - else - fscanf(sig, "%*d\n"); - if (a == 0.0) - fscanf(sig, "%lf\n", &a); - else - fscanf(sig, "%*f\n"); - if (t1 == 0.0) - fscanf(sig, "%lf\n", &t1); - else - fscanf(sig, "%*f\n"); - if (t2 == 0.0) - fscanf(sig, "%lf\n", &t2); - else - fscanf(sig, "%*f\n"); - if (e < 0) - fscanf(sig, "%d\n", &e); - else - fscanf(sig, "%*d\n"); - if (f == 0) - fscanf(sig, "%d\n", &f); - else - fscanf(sig, "%*d\n"); - if (!strcmp(F, "")) - fscanf(sig, "%[^\n\r]\n", F); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - } - - if (s) - srandom(s); - else - srandom(time(NULL) * getpid()); - - fprintf(out, "DGSG\n"); - fprintf(out, "%d\n", n); - fprintf(out, "%d\n", l); - fprintf(out, "%f\n", a); - fprintf(out, "%f\n", t1); - fprintf(out, "%f\n", t2); - fprintf(out, "%d\n", e); - fprintf(out, "%d\n", f); - fprintf(out, "%s\n", F); - - n >>= 1; - while (n > 0) { - double x; - double x1, x2; - - /* - * Algorithm P (Polar method for normal deviates), - * Knuth, D., "The Art of Computer Programming", Vol. 2, 3rd Edition, p. 122 - */ - do { - x1 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; - x2 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; - x = x1 * x1 + x2 * x2; - } while (x >= 1.0); - x1 *= sqrt((-2.0) * log(x) / x); - x2 *= sqrt((-2.0) * log(x) / x); - - fprintf(out, "%f\n", m + d * x1); - fprintf(out, "%f\n", m + d * x2); - - n--; - } - - fclose(out); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_frid2_sig.c --- a/Meerwald/gen_frid2_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,150 +0,0 @@ -#include "wm.h" -#include "signature.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-g n] [-o file] [-s n] file\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor (default 0.25)\n"); - fprintf(stderr, "\t-g n\t\tgamma factor (default 1.0)\n"); - fprintf(stderr, "\t-s n\t\tseed (default 0)\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-n n\t\twatermark length (default 100)\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); - fprintf(stderr, "\t-S n\t\tseed\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int c; - int i; - int n = 100, nb; - double a = 0.25; - double g = 1.0; - int s = 0; - - progname = argv[0]; - -#ifdef __EMX__ - _fsetmode(in, "b"); - _fsetmode(out, "b"); -#endif - - while ((c = getopt(argc, argv, "a:g:h?n:o:s:S:")) != EOF) { - switch (c) { - case 'a': - a = atof(optarg); - if (a <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); - exit(1); - } - break; - case 'g': - g = atof(optarg); - if (g <= 0.0) { - fprintf(stderr, "%s: gamma factor %f out of range\n", progname, a); - exit(1); - } - break; - case 'h': - case '?': - usage(); - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 1000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'S': - s = atoi(optarg); - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (!s) - s = time(NULL) * getpid(); - srandom(s); - - if (sig) { - char line[128]; - fgets(line, sizeof(line), sig); - if (strspn(line, "FR2SG") >= 5) { - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - - if (n > 0) { - nb = fread(signature, sizeof(char), i = NBITSTOBYTES(n), in); - if (nb < i) { - fprintf(stderr, "%s: failed to read all %d signature bits from %s\n", progname, n, input_name); - exit(1); - } - } - else { - if (fscanf(in, "%128[^\n\r]", signature) == EOF) { - fprintf(stderr, "%s: failed to read signature bits from %s\n", progname, input_name); - exit(1); - } - nb = strlen(signature); - n = NBYTESTOBITS(nb); - fprintf(stderr, "%s: got %d signature bits\n", progname, n); - } - - fprintf(out, "FR2SG\n"); - fprintf(out, "%d\n", n); - fprintf(out, "%f\n", a); - fprintf(out, "%f\n", g); - fprintf(out, "%d\n", s); - fwrite(signature, sizeof(char), nb, out); - fprintf(out, "\n"); - - fclose(out); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_kim_sig.c --- a/Meerwald/gen_kim_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,211 +0,0 @@ -#include "wm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-A n] [-d n] [-e n] [-f n] [-F file] [-l n] [-m n] [-n n] [-o file] [-s file] [-S n]\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor for detail subbands (default 0.1)\n"); - fprintf(stderr, "\t-A n\t\talpha factor for approximation subband (default 0.02)\n"); - fprintf(stderr, "\t-d n\t\tdeviation (default 1.0)\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); - fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-l n\t\tdecomposition level (default 4)\n"); - fprintf(stderr, "\t-m n \t\tmean value (default 0.0)\n"); - fprintf(stderr, "\t-n n\t\twatermark length (default 1000)\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); - fprintf(stderr, "\t-S n\t\tseed\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char signature_name[MAXPATHLEN]; - - int c; - int n = 1000; - int s = 0; - int e = 2; - int f = 1; - char F[MAXPATHLEN] = "filter.dat"; - double a = 0.1; - double A = 0.02; - int l = 4; - double m = 0.0; - double d = 1.0; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "a:A:l:d:e:f:F:h?m:n:o:s:S:")) != EOF) { - switch (c) { - case 'a': - a = atof(optarg); - if (a <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); - exit(1); - } - break; - case 'A': - A = atof(optarg); - if (A <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); - exit(1); - } - break; - case 'l': - l = atoi(optarg); - if (l <= 0) { - fprintf(stderr, "%s: decomposition level %d out of range\n", progname, l); - exit(1); - } - break; - case 'd': - d = atof(optarg); - if (d <= 0.0) { - fprintf(stderr, "%s: deviation %f out of range\n", progname, d); - exit(1); - } - break; - case 'e': - e = atoi(optarg); - if (e < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); - } - break; - case 'f': - f = atoi(optarg); - if (f <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, f); - exit(1); - } - break; - case 'F': - strcpy(F, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'm': - m = atof(optarg); - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 32000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'S': - s = atoi(optarg); - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 0) { - usage(); - exit(1); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "KISG") >= 4) { - if (n == 0) - fscanf(sig, "%d\n", &n); - else - fscanf(sig, "%*d\n"); - if (a == 0.0) - fscanf(sig, "%lf\n", &a); - else - fscanf(sig, "%*f\n"); - if (A == 0.0) - fscanf(sig, "%lf\n", &A); - else - fscanf(sig, "%*f\n"); - if (l == 0) - fscanf(sig, "%d\n", &l); - else - fscanf(sig, "%*d\n"); - if (e < 0) - fscanf(sig, "%d\n", &e); - else - fscanf(sig, "%*d\n"); - if (f == 0) - fscanf(sig, "%d\n", &f); - else - fscanf(sig, "%*d\n"); - if (!strcmp(F, "")) - fscanf(sig, "%[^\n\r]\n", F); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - } - - if (s) - srandom(s); - else - srandom(time(NULL) * getpid()); - - fprintf(out, "KISG\n"); - fprintf(out, "%d\n", n); - fprintf(out, "%f\n", a); - fprintf(out, "%f\n", A); - fprintf(out, "%d\n", l); - fprintf(out, "%d\n", e); - fprintf(out, "%d\n", f); - fprintf(out, "%s\n", F); - - n >>= 1; - while (n > 0) { - double x; - double x1, x2; - - /* - * Algorithm P (Polar method for normal deviates), - * Knuth, D., "The Art of Computer Programming", Vol. 2, 3rd Edition, p. 122 - */ - do { - x1 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; - x2 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; - x = x1 * x1 + x2 * x2; - } while (x >= 1.0); - x1 *= sqrt((-2.0) * log(x) / x); - x2 *= sqrt((-2.0) * log(x) / x); - - fprintf(out, "%f\n", m + d * x1); - fprintf(out, "%f\n", m + d * x2); - - n--; - } - - fclose(out); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_koch_sig.1 --- a/Meerwald/gen_koch_sig.1 Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -.\" -.\" gen_koch_sig.1 - the *roff document processor man page source -.\" -.TH gen_koch_sig 1 "98/06/30" "Watermarking, Version 1.0" -.SH NAME -.B gen_koch_sig -\- a program to generate a signature for -the -.B wm_koch_e -watermarking program -.SH SYNOPSIS -.B gen_koch_sig -[ -.B \-h -] -[ -.BI \-n \ number -] -[ -.BI \-o \ file -] -[ -.BI \-q \ number -] -[ -.BI \-s \ number -] -[ -.IR file -] -.SH DESCRIPTION -.B gen_koch_sig -is a program to generate a signature to be -embedded with the -.B wm_koch_e -watermarking program and extracted with the -.B wm_koch_d -program. The -.B cmp_koch_sig -program is used to compare and test an -extracted signature with the original signature. -.PP -Please refer to E. Koch's paper "Towards Robust and Hidden -Image Copyright", 1995, to get an idea about the algorithm. -.PP -.SH OPTIONS -.TP -.B \-h -Print a help message. -.TP -.BI \-n \ number -Limit the signature length to -.I number -bits (0 < -.I number -<= 1024) unless reading from standard input. When reading from -standard input, the signature is terminated by the first -carriage return character. -.TP -.BI \-o \ file -Output signature to the specified -.I file -instead of standard output. -.TP -.BI \-q \ number -Quality/robustness factor used to embed signature into image. -Default value: 3.0. -.TP -.BI \-s \ number -Specify a seed value to initialize the pseudo-random number -generator; if not specified, time and pid (process id) are used -to initialize the pseudo-random number generator. -.TP -.IR file -Input file to read raw signature data from. Default: standard -input. -.PP -.SH OUTPUT -The output file has the following format: -.TP -.B KCSG -Magic to identify file type. -.TP -.I number -The length of the signature in bits. -.TP -.I number -The quality/robustness factor. -.TP -.I number -The seed value for the pseudo-random number generator. -.TP -.I string -The actual signature bytes. -.PP -.SH AUTHOR -Peter Meerwald. Email bug reports to pmeerw@cosy.sbg.ac.at. -.SH AVAILABILITY -The most recent released version of -.B gen_koch_sig -is always available -at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the -directory /pub/people/pmeerw/Watermarking. -.SH "SEE ALSO" -.BR wm_koch_e -(1), -.BR wm_koch_d -(1), -.BR cmp_koch_sig -(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_koch_sig.c --- a/Meerwald/gen_koch_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,158 +0,0 @@ -#include "wm.h" -#include "signature.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-l n] [-n n] [-o file] [-q n] [-s file] [-S n] file\n\n", progname); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-l n\t\tsignature strength factor (default 5.0)\n"); - fprintf(stderr, "\t-n n\t\twatermark bit length\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-q n\t\tquantization (JPEG quality) factor (default 90)\n"); - fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); - fprintf(stderr, "\t-S n\t\tseed\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int c; - int i; - int n = 0; - int nb; - int s = 0; - int q = 90; - double l = 5.0; - - progname = argv[0]; wm_init(); - - while ((c = getopt(argc, argv, "h?l:n:o:q:s:S:")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'l': - l = atof(optarg); - if (l <= 0.0) { - fprintf(stderr, "%s: signature strength factor %f out of range\n", progname, l); - exit(1); - } - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 1000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'q': - q = atoi(optarg); - if (q <= 0 || q > 100) { - fprintf(stderr, "%s: quantization factor %d out of range\n", progname, q); - exit(1); - } - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'S': - s = atoi(optarg); - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (s) - srandom(s); - else - srandom(time(NULL) * getpid()); - - if (sig) { - char line[128]; - fgets(line, sizeof(line), sig); - if (strspn(line, "KCSG") >= 4) { - if (n == 0) - fscanf(sig, "%d\n", &n); - else - fscanf(sig, "%*d\n"); - if (l == 0.0) - fscanf(sig, "%lf\n", &l); - else - fscanf(sig, "%*f\n"); - if (q == 0) - fscanf(sig, "%d\n", &q); - else - fscanf(sig, "%*d\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - - if (n > 0) { - nb = fread(signature, sizeof(char), i = NBITSTOBYTES(n), in); - if (nb < i) { - fprintf(stderr, "%s: failed to read all %d signature bits from %s\n", progname, n, input_name); - exit(1); - } - } - else { - if (fscanf(in, "%128[^\n\r]", signature) == EOF) { - fprintf(stderr, "%s: failed to read signature bits from %s\n", progname, input_name); - exit(1); - } - nb = strlen(signature); - n = NBYTESTOBITS(nb); - fprintf(stderr, "%s: got %d signature bits\n", progname, n); - } - - fprintf(out, "KCSG\n"); - fprintf(out, "%d\n", n); - fprintf(out, "%f\n", l); - fprintf(out, "%d\n", q); - fprintf(out, "%ld\n", random()); - fwrite(signature, sizeof(char), nb, out); - fprintf(out, "\n"); - - fclose(out); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_kund2_sig.c --- a/Meerwald/gen_kund2_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,221 +0,0 @@ -#include "wm.h" -#include "signature.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-b n] [-e n] [-f n] [-F file] [-l n] [-n n] [-o file] [-q n] [-s file] [-S n] [-v n] file\n\n", progname); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-b n\t\tblock size (default 64)\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); - fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); - fprintf(stderr, "\t-l n\t\tembedding level (default 1)\n"); - fprintf(stderr, "\t-n n\t\twatermark bit length\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-q n\t\tsignature strength (default 4)\n"); - fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); - fprintf(stderr, "\t-S n\t\tseed\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - char *binstr; - - int verbose = 0; - int c; - int i; - int l = 3; - int n = 0; - int s = 0; - int q = 4; - int e = 2; - int f = 1; - int blocksize = 64; - char F[MAXPATHLEN] = "filter.dat"; - - progname = argv[0]; - - wm_init(); - - while ((c = getopt(argc, argv, "b:e:f:F:h?l:n:o:q:s:S:v:")) != EOF) { - switch (c) { - case 'b': - blocksize = atoi(optarg); - if (blocksize < 0) - fprintf(stderr, "%s: block size %d out of range\n", progname, blocksize); - break; - case 'e': - e = atoi(optarg); - if (e < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); - } - break; - case 'f': - f = atoi(optarg); - if (f <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, f); - exit(1); - } - break; - case 'F': - strcpy(F, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'l': - l = atoi(optarg); - if (l < 1) { - fprintf(stderr, "%s: embedding level out of range\n", progname); - exit(1); - } - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 1000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'q': - q = atoi(optarg); - if (q < 1) { - fprintf(stderr, "%s: signature strength %d out of range\n", progname, q); - exit(1); - } - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'S': - s = atoi(optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "KD2SG") >= 5) { - if (n == 0) - fscanf(sig, "%d\n", &n); - else - fscanf(sig, "%*d\n"); - if (q == 0) - fscanf(sig, "%d\n", &q); - else - fscanf(sig, "%*d\n"); - if (blocksize == 0) - fscanf(sig, "%d\n", &blocksize); - else - fscanf(sig, "%*d\n"); - if (e < 0) - fscanf(sig, "%d\n", &e); - else - fscanf(sig, "%*d\n"); - if (f == 0) - fscanf(sig, "%d\n", &f); - else - fscanf(sig, "%*d\n"); - if (!strcmp(F, "")) - fscanf(sig, "%[^\n\r]\n", F); - else - fscanf(sig, "%*[^\n\r]\n"); - if (l == 0) - fscanf(sig, "%d\n", &l); - else - fscanf(sig, "%*d\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - - if (s) - srandom(s); - else - srandom(time(NULL) * getpid()); - - if (n > 0) { - n_signature = fread(signature, sizeof(char), i = NBITSTOBYTES(n), in); - nbit_signature = NBYTESTOBITS(n_signature); - if (n_signature < i) { - fprintf(stderr, "%s: failed to read all %d signature bits from %s\n", progname, n, input_name); - exit(1); - } - } - else { - if (fscanf(in, "%128[^\n\r]", signature) == EOF) { - fprintf(stderr, "%s: failed to read signature bits from %s\n", progname, input_name); - exit(1); - } - n_signature = strlen(signature); - nbit_signature = NBYTESTOBITS(n_signature); - fprintf(stderr, "%s: got %d signature bits\n", progname, nbit_signature); - } - - fprintf(out, "KD2SG\n"); - fprintf(out, "%d\n", nbit_signature); - fprintf(out, "%d\n", q); - fprintf(out, "%d\n", blocksize); - fprintf(out, "%d\n", e); - fprintf(out, "%d\n", f); - fprintf(out, "%s\n", F); - fprintf(out, "%d\n", l); - fprintf(out, "%ld\n", random()); - binstr = malloc((nbit_signature + 1) * sizeof(char)); - sig_to_binstr(binstr); - fprintf(out, "%s\n", binstr); - free(binstr); - - fclose(out); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_kund3_sig.c --- a/Meerwald/gen_kund3_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,209 +0,0 @@ -#include "wm.h" -#include "signature.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-e n] [-f n] [-F file] [-l n] [-n n] [-o file] [-q n] [-s file] [-S n] [-v n] file\n\n", progname); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); - fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); - fprintf(stderr, "\t-l n\t\tembedding level (default 1)\n"); - fprintf(stderr, "\t-n n\t\twatermark bit length\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-q n\t\tsignature strength (default 4)\n"); - fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); - fprintf(stderr, "\t-S n\t\tseed\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - char *binstr; - - int verbose = 0; - int c; - int i; - int l = 1; - int n = 0; - int s = 0; - int q = 4; - int e = 2; - int f = 1; - char F[MAXPATHLEN] = "filter.dat"; - - progname = argv[0]; - - wm_init(); - - while ((c = getopt(argc, argv, "e:f:F:h?l:n:o:q:s:S:v:")) != EOF) { - switch (c) { - case 'e': - e = atoi(optarg); - if (e < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); - } - break; - case 'f': - f = atoi(optarg); - if (f <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, f); - exit(1); - } - break; - case 'F': - strcpy(F, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'l': - l = atoi(optarg); - if (l < 1) { - fprintf(stderr, "%s: embedding level out of range\n", progname); - exit(1); - } - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 1000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'q': - q = atoi(optarg); - if (q < 1) { - fprintf(stderr, "%s: signature strength %d out of range\n", progname, q); - exit(1); - } - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'S': - s = atoi(optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "KD3SG") >= 5) { - if (n == 0) - fscanf(sig, "%d\n", &n); - else - fscanf(sig, "%*d\n"); - if (q == 0) - fscanf(sig, "%d\n", &q); - else - fscanf(sig, "%*d\n"); - if (e < 0) - fscanf(sig, "%d\n", &e); - else - fscanf(sig, "%*d\n"); - if (f == 0) - fscanf(sig, "%d\n", &f); - else - fscanf(sig, "%*d\n"); - if (!strcmp(F, "")) - fscanf(sig, "%[^\n\r]\n", F); - else - fscanf(sig, "%*[^\n\r]\n"); - if (l == 0) - fscanf(sig, "%d\n", &l); - else - fscanf(sig, "%*d\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - - if (s) - srandom(s); - else - srandom(time(NULL) * getpid()); - - if (n > 0) { - n_signature = fread(signature, sizeof(char), i = NBITSTOBYTES(n), in); - if (n_signature < i) { - fprintf(stderr, "%s: failed to read all %d signature bits from %s\n", progname, n, input_name); - exit(1); - } - } - else { - if (fscanf(in, "%128[^\n\r]", signature) == EOF) { - fprintf(stderr, "%s: failed to read signature bits from %s\n", progname, input_name); - exit(1); - } - n_signature = strlen(signature); - n = nbit_signature = NBYTESTOBITS(n_signature); - fprintf(stderr, "%s: got %d signature bits\n", progname, nbit_signature); - } - - fprintf(out, "KD3SG\n"); - fprintf(out, "%d\n", n); - fprintf(out, "%d\n", q); - fprintf(out, "%d\n", e); - fprintf(out, "%d\n", f); - fprintf(out, "%s\n", F); - fprintf(out, "%d\n", l); - fprintf(out, "%ld\n", random()); - nbit_signature = NBYTESTOBITS(n_signature); - binstr = malloc((nbit_signature + 1) * sizeof(char)); - sig_to_binstr(binstr); - fprintf(out, "%s\n", binstr); - free(binstr); - - fclose(out); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_kund_sig.c --- a/Meerwald/gen_kund_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,164 +0,0 @@ -#include "wm.h" -#include "signature.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-e n] [-f n] [-F file] [-l n] [-n n] [-o file] [-q n] [-s n] file\n\n", progname); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); - fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); - fprintf(stderr, "\t-l n\t\tembedding level (default 1)\n"); - fprintf(stderr, "\t-n n\t\twatermark bit length\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-q n\t\tsignature strength (default 1.0)\n"); - fprintf(stderr, "\t-s n\t\tseed\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - FILE *in = stdin; - FILE *out = stdout; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - - int c; - int i; - int l = 1; - int n = 0, nb; - int s = 0; - double q = 1.0; - int e = 2; - int f = 1; - char F[MAXPATHLEN] = "filter.dat"; - - progname = argv[0]; - -#ifdef __EMX__ - _fsetmode(in, "b"); - _fsetmode(out, "b"); -#endif - - while ((c = getopt(argc, argv, "e:f:F:h?l:n:o:q:s:")) != EOF) { - switch (c) { - case 'e': - e = atoi(optarg); - if (e < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); - } - break; - case 'f': - f = atoi(optarg); - if (f <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, f); - exit(1); - } - break; - case 'F': - strcpy(F, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'l': - l = atoi(optarg); - if (l < 1) { - fprintf(stderr, "%s: embedding level out of range\n", progname); - exit(1); - } - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 1000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - if (n % 4 != 0 || (int) sqrt(n / 4) * (int) sqrt(n / 4) != n) { - fprintf(stderr, "%s: watermark length not divisible by 4 or not a square number\n", progname); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'q': - q = atof(optarg); - if (q <= 0.0) { - fprintf(stderr, "%s: signature strength factor %f out of range\n", progname, q); - exit(1); - } - break; - case 's': - s = atoi(optarg); - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 0) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - - if (s) - srandom(s); - else - srandom(time(NULL) * getpid()); - - if (n > 0) { - nb = fread(signature, sizeof(char), i = NBITSTOBYTES(n), in); - if (nb < i) { - fprintf(stderr, "%s: failed to read all %d signature bits from %s\n", progname, n, input_name); - exit(1); - } - } - else { - int n_square; - if (fscanf(in, "%128[^\n\r]", signature) == EOF) { - fprintf(stderr, "%s: failed to read signature bits from %s\n", progname, input_name); - exit(1); - } - nb = strlen(signature); - n = NBYTESTOBITS(nb); - n_square = (int) sqrt(n) * (int) sqrt(n); - fprintf(stderr, "%s: got %d signature bits, truncated to %d\n", progname, n, n_square); - n = n_square; - nb = NBITSTOBYTES(n); - if (n < 1) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - } - - fprintf(out, "KDSG\n"); - fprintf(out, "%d\n", n); - fprintf(out, "%d\n", e); - fprintf(out, "%d\n", f); - fprintf(out, "%s\n", F); - fprintf(out, "%d\n", l); - fprintf(out, "%f\n", q); - fprintf(out, "%d\n", random()); - fwrite(signature, sizeof(char), nb, out); - fprintf(out, "\n"); - - fclose(out); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_kutter_sig.1 --- a/Meerwald/gen_kutter_sig.1 Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,131 +0,0 @@ -.\" -.\" gen_kutter_sig.1 - the *roff document processor man page source -.\" -.TH gen_kutter_sig 1 "98/06/30" "Watermarking, Version 1.0" -.SH NAME -.B gen_kutter_sig -\- a program to generate a signature for -the -.B wm_kutter_e -watermarking program -.SH SYNOPSIS -.B gen_kutter_sig -[ -.B \-h -] -[ -.BI \-n \ number -] -[ -.BI \-o \ file -] -[ -.BI \-p \ number -] -[ -.BI \-q \ number -] -[ -.BI \-r \ number -] -.br -[ -.BI \-s \ number -] -[ -.I file -] -.SH DESCRIPTION -.B gen_kutter_sig -is a program to generate a signature to be -embedded with the -.B wm_kutter_e -watermarking program and extracted with the -.B wm_kutter_d -program. The -.B cmp_kutter_sig -program is used to compare and test an -extracted signature with the original signature. -.PP -Please refer to M. Kutter's paper "Digital Signature of Color Images -using Amplitude Modulation", 1997, to get an idea about the algorithm. -.PP -.SH OPTIONS -.TP -.B \-h -Print a help message. -.TP -.BI \-n \ number -Limit the signature length to -.I number -bits (0 < -.I number -<= 1024) unless reading from standard input. When reading from -standard input, the signature is terminated by the first -carriage return character. -.TP -.BI \-o \ file -Output signature to the specified -.TP -.BI \-p \ number -Density parameter in the range 0.0 < -.I number -<= 1.0. Default value 0.01. -.TP -.BI \-q \ number -Signature strength. Default value 0.1. -.TP -.BI \-r \ number -Signature bit repetition factor. Specifies how often a single -signature bit is embedded. Default value 8. -.I file -instead of standard output. -.TP -.BI \-s \ number -Specify a seed value to initialize the pseudo-random number -generator; if not specified, time and pid (process id) are used -to initialize the pseudo-random number generator. -.TP -.I file -Input file to read raw signature data from. Default: standard -input. -.PP -.SH OUTPUT -The output file has the following format: -.TP -.B KTSG -Magic to identify file type. -.TP -.I number -The length of the signature in bits. -.TP -.I number -The density parameter. -.TP -.I number -The signature strength. -.TP -.I number -The bit repetition parameter. -.TP -.I number -The seed value for the pseudo-random number generator. -.TP -.I string -The actual signature bytes. -.PP -.SH AUTHOR -Peter Meerwald. Email bug reports to pmeerw@cosy.sbg.ac.at. -.SH AVAILABILITY -The most recent released version of -.B gen_kutter_sig -is always available -at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the -directory /pub/people/pmeerw/Watermarking. -.SH "SEE ALSO" -.BR wm_kutter_e -(1), -.BR wm_kutter_d -(1), -.BR cmp_kutter_sig -(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_wang_sig.c --- a/Meerwald/gen_wang_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,197 +0,0 @@ -#include "wm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-b n] [-d n] [-e n] [-f n] [-F file] [-m n] [-n n] [-o file] [-s file] [-S n]\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor (default 0.3)\n"); - fprintf(stderr, "\t-b n\t\tbeta factor (default 1.0)\n"); - fprintf(stderr, "\t-d n\t\tdeviation (default 1.0)\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); - fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-m n \t\tmean value (default 0.0)\n"); - fprintf(stderr, "\t-n n\t\twatermark length (default 1000)\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); - fprintf(stderr, "\t-S n\t\tseed\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char signature_name[MAXPATHLEN]; - - int c; - int n = 1000; - int s = 0; - int e = 2; - int f = 1; - char F[MAXPATHLEN] = "filter.dat"; - double a = 0.3; - double b = 1.0; - double m = 0.0; - double d = 1.0; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "a:b:d:e:f:F:h?m:n:o:s:S:")) != EOF) { - switch (c) { - case 'a': - a = atof(optarg); - if (a <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); - exit(1); - } - break; - case 'b': - b = atof(optarg); - if (b <= 0.0) { - fprintf(stderr, "%s: beta factor %f out of range\n", progname, b); - exit(1); - } - break; - case 'd': - d = atof(optarg); - if (d <= 0.0) { - fprintf(stderr, "%s: deviation %f out of range\n", progname, d); - exit(1); - } - break; - case 'e': - e = atoi(optarg); - if (e < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); - } - break; - case 'f': - f = atoi(optarg); - if (f <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, f); - exit(1); - } - break; - case 'F': - strcpy(F, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'm': - m = atof(optarg); - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 32000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'S': - s = atoi(optarg); - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 0) { - usage(); - exit(1); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "WGSG") >= 4) { - if (n == 0) - fscanf(sig, "%d\n", &n); - else - fscanf(sig, "%*d\n"); - if (a == 0.0) - fscanf(sig, "%lf\n", &a); - else - fscanf(sig, "%*f\n"); - if (b == 0.0) - fscanf(sig, "%lf\n", &b); - else - fscanf(sig, "%*f\n"); - if (e < 0) - fscanf(sig, "%d\n", &e); - else - fscanf(sig, "%*d\n"); - if (f == 0) - fscanf(sig, "%d\n", &f); - else - fscanf(sig, "%*d\n"); - if (!strcmp(F, "")) - fscanf(sig, "%[^\n\r]\n", F); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - } - - if (s) - srandom(s); - else - srandom(time(NULL) * getpid()); - - fprintf(out, "WGSG\n"); - fprintf(out, "%d\n", n); - fprintf(out, "%f\n", a); - fprintf(out, "%f\n", b); - fprintf(out, "%d\n", e); - fprintf(out, "%d\n", f); - fprintf(out, "%s\n", F); - - n >>= 1; - while (n > 0) { - double x; - double x1, x2; - - /* - * Algorithm P (Polar method for normal deviates), - * Knuth, D., "The Art of Computer Programming", Vol. 2, 3rd Edition, p. 122 - */ - do { - x1 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; - x2 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; - x = x1 * x1 + x2 * x2; - } while (x >= 1.0); - x1 *= sqrt((-2.0) * log(x) / x); - x2 *= sqrt((-2.0) * log(x) / x); - - fprintf(out, "%f\n", m + d * x1); - fprintf(out, "%f\n", m + d * x2); - - n--; - } - - fclose(out); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_xia_sig.c --- a/Meerwald/gen_xia_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,197 +0,0 @@ -#include "wm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-d n] [-e n] [-f n] [-F file] [-l n] [-m n] [-n n] [-o file] [-s file] [-S n]\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor (default 0.2)\n"); - fprintf(stderr, "\t-d n\t\tdeviation (default 1.0)\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); - fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-l n\t\tdecomposition level (default 2)\n"); - fprintf(stderr, "\t-m n \t\tmean value (default 0.0)\n"); - fprintf(stderr, "\t-n n\t\twatermark length (default 1000)\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); - fprintf(stderr, "\t-S n\t\tseed\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char signature_name[MAXPATHLEN]; - - int c; - int n = 1000; - int s = 0; - int e = 2; - int f = 1; - char F[MAXPATHLEN] = "filter.dat"; - double a = 0.2; - int l = 2; - double m = 0.0; - double d = 1.0; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "a:l:d:e:f:F:h?m:n:o:s:S:")) != EOF) { - switch (c) { - case 'a': - a = atof(optarg); - if (a <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); - exit(1); - } - break; - case 'l': - l = atoi(optarg); - if (l <= 0) { - fprintf(stderr, "%s: decomposition level %d out of range\n", progname, l); - exit(1); - } - break; - case 'd': - d = atof(optarg); - if (d <= 0.0) { - fprintf(stderr, "%s: deviation %f out of range\n", progname, d); - exit(1); - } - break; - case 'e': - e = atoi(optarg); - if (e < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); - } - break; - case 'f': - f = atoi(optarg); - if (f <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, f); - exit(1); - } - break; - case 'F': - strcpy(F, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'm': - m = atof(optarg); - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 32000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'S': - s = atoi(optarg); - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 0) { - usage(); - exit(1); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "XASG") >= 4) { - if (n == 0) - fscanf(sig, "%d\n", &n); - else - fscanf(sig, "%*d\n"); - if (a == 0.0) - fscanf(sig, "%lf\n", &a); - else - fscanf(sig, "%*f\n"); - if (l == 0) - fscanf(sig, "%d\n", &l); - else - fscanf(sig, "%*d\n"); - if (e < 0) - fscanf(sig, "%d\n", &e); - else - fscanf(sig, "%*d\n"); - if (f == 0) - fscanf(sig, "%d\n", &f); - else - fscanf(sig, "%*d\n"); - if (!strcmp(F, "")) - fscanf(sig, "%[^\n\r]\n", F); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - } - - if (s) - srandom(s); - else - srandom(time(NULL) * getpid()); - - fprintf(out, "XASG\n"); - fprintf(out, "%d\n", n); - fprintf(out, "%f\n", a); - fprintf(out, "%d\n", l); - fprintf(out, "%d\n", e); - fprintf(out, "%d\n", f); - fprintf(out, "%s\n", F); - - n >>= 1; - while (n > 0) { - double x; - double x1, x2; - - /* - * Algorithm P (Polar method for normal deviates), - * Knuth, D., "The Art of Computer Programming", Vol. 2, 3rd Edition, p. 122 - */ - do { - x1 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; - x2 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; - x = x1 * x1 + x2 * x2; - } while (x >= 1.0); - x1 *= sqrt((-2.0) * log(x) / x); - x2 *= sqrt((-2.0) * log(x) / x); - - fprintf(out, "%f\n", m + d * x1); - fprintf(out, "%f\n", m + d * x2); - - n--; - } - - fclose(out); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_xie2_sig.c --- a/Meerwald/gen_xie2_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,214 +0,0 @@ -#include "wm.h" -#include "signature.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-e n] [-f n] [-F file] [-l n] [-n n] [-o file] [-s file] [-S n] [-v n] file\n\n", progname); - fprintf(stderr, "\t-a n\t\tembedding strength (default 0.5)\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); - fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-l n\t\tembedding level (default 5)\n"); - fprintf(stderr, "\t-n n\t\twatermark bit length\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-q n\t\tquantization level\n"); - fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); - fprintf(stderr, "\t-S n\t\tseed\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int verbose = 0; - int c; - int i; - double a = 0.5; - int q = 4; - int l = 5; - int n = 0, nb; - int s = 0; - int e = 2; - int f = 1; - char F[MAXPATHLEN] = "filter.dat"; - - progname = argv[0]; - wm_init(); - - while ((c = getopt(argc, argv, "a:e:f:F:h?l:n:o:s:S:v:q:")) != EOF) { - switch (c) { - case 'a': - a = atof(optarg); - if (a <= 0.0) { - fprintf(stderr, "%s: embedding strength %f out of range\n", progname, a); - exit(1); - } - break; - case 'e': - e = atoi(optarg); - if (e < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); - } - break; - case 'q': - q = atoi(optarg); - break; - case 'f': - f = atoi(optarg); - if (f <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, f); - exit(1); - } - break; - case 'F': - strcpy(F, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'l': - l = atoi(optarg); - if (l < 1) { - fprintf(stderr, "%s: embedding level out of range\n", progname); - exit(1); - } - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 1000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'S': - s = atoi(optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "XE2SG") >= 5) { - if (n == 0) - fscanf(sig, "%d\n", &n); - else - fscanf(sig, "%*d\n"); - if (a == 0.0) - fscanf(sig, "%lf\n", &a); - else - fscanf(sig, "%*f\n"); - if (e < 0) - fscanf(sig, "%d\n", &e); - else - fscanf(sig, "%*d\n"); - if (f == 0) - fscanf(sig, "%d\n", &f); - else - fscanf(sig, "%*d\n"); - if (!strcmp(F, "")) - fscanf(sig, "%[^\n\r]\n", F); - else - fscanf(sig, "%*[^\n\r]\n"); - if (q == 0) - fscanf(sig, "%d\n", &q); - else - fscanf(sig, "%*d\n"); - if (l == 0) - fscanf(sig, "%d\n", &l); - else - fscanf(sig, "%*d\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - - if (s) - srandom(s); - else - srandom(time(NULL) * getpid()); - - if (n > 0) { - nb = fread(signature, sizeof(char), i = NBITSTOBYTES(n), in); - if (nb < i) { - fprintf(stderr, "%s: failed to read all %d signature bits from %s\n", progname, n, input_name); - exit(1); - } - } - else { - if (fscanf(in, "%128[^\n\r]", signature) == EOF) { - fprintf(stderr, "%s: failed to read signature bits from %s\n", progname, input_name); - exit(1); - } - nb = strlen(signature); - n = NBYTESTOBITS(nb); - fprintf(stderr, "%s: got %d signature bits\n", progname, n); - } - - fprintf(out, "XE2SG\n"); - fprintf(out, "%d\n", n); - fprintf(out, "%f\n", a); - fprintf(out, "%d\n", e); - fprintf(out, "%d\n", f); - fprintf(out, "%s\n", F); - fprintf(out, "%d\n", q); - fprintf(out, "%d\n", l); - fprintf(out, "%ld\n", random()); - fwrite(signature, sizeof(char), nb, out); - fprintf(out, "\n"); - - fclose(out); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_xie_sig.c --- a/Meerwald/gen_xie_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,204 +0,0 @@ -#include "wm.h" -#include "signature.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-e n] [-f n] [-F file] [-l n] [-n n] [-o file] [-s file] [-S n] [-v n] file\n\n", progname); - fprintf(stderr, "\t-a n\t\tembedding strength (default 0.5)\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); - fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-l n\t\tembedding level (default 5)\n"); - fprintf(stderr, "\t-n n\t\twatermark bit length\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); - fprintf(stderr, "\t-S n\t\tseed\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int verbose = 0; - int c; - int i; - double a = 0.5; - int l = 5; - int n = 0, nb; - int s = 0; - int e = 2; - int f = 1; - char F[MAXPATHLEN] = "filter.dat"; - - progname = argv[0]; - wm_init(); - - while ((c = getopt(argc, argv, "a:e:f:F:h?l:n:o:s:S:v:")) != EOF) { - switch (c) { - case 'a': - a = atof(optarg); - if (a <= 0.0) { - fprintf(stderr, "%s: embedding strength %f out of range\n", progname, a); - exit(1); - } - break; - case 'e': - e = atoi(optarg); - if (e < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); - } - break; - case 'f': - f = atoi(optarg); - if (f <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, f); - exit(1); - } - break; - case 'F': - strcpy(F, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'l': - l = atoi(optarg); - if (l < 1) { - fprintf(stderr, "%s: embedding level out of range\n", progname); - exit(1); - } - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 1000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'S': - s = atoi(optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "XESG") >= 4) { - if (n == 0) - fscanf(sig, "%d\n", &n); - else - fscanf(sig, "%*d\n"); - if (a == 0.0) - fscanf(sig, "%lf\n", &a); - else - fscanf(sig, "%*f\n"); - if (e < 0) - fscanf(sig, "%d\n", &e); - else - fscanf(sig, "%*d\n"); - if (f == 0) - fscanf(sig, "%d\n", &f); - else - fscanf(sig, "%*d\n"); - if (!strcmp(F, "")) - fscanf(sig, "%[^\n\r]\n", F); - else - fscanf(sig, "%*[^\n\r]\n"); - if (l == 0) - fscanf(sig, "%d\n", &l); - else - fscanf(sig, "%*d\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - - if (s) - srandom(s); - else - srandom(time(NULL) * getpid()); - - if (n > 0) { - nb = fread(signature, sizeof(char), i = NBITSTOBYTES(n), in); - if (nb < i) { - fprintf(stderr, "%s: failed to read all %d signature bits from %s\n", progname, n, input_name); - exit(1); - } - } - else { - if (fscanf(in, "%128[^\n\r]", signature) == EOF) { - fprintf(stderr, "%s: failed to read signature bits from %s\n", progname, input_name); - exit(1); - } - nb = strlen(signature); - n = NBYTESTOBITS(nb); - fprintf(stderr, "%s: got %d signature bits\n", progname, n); - } - - fprintf(out, "XESG\n"); - fprintf(out, "%d\n", n); - fprintf(out, "%f\n", a); - fprintf(out, "%d\n", e); - fprintf(out, "%d\n", f); - fprintf(out, "%s\n", F); - fprintf(out, "%d\n", l); - fprintf(out, "%ld\n", random()); - fwrite(signature, sizeof(char), nb, out); - fprintf(out, "\n"); - - fclose(out); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gen_zhu_sig.c --- a/Meerwald/gen_zhu_sig.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,197 +0,0 @@ -#include "wm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-d n] [-e n] [-f n] [-F file] [-l n] [-m n] [-n n] [-o file] [-s file] [-S n]\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor (default 0.2)\n"); - fprintf(stderr, "\t-d n\t\tdeviation (default 1.0)\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method (default 2)\n"); - fprintf(stderr, "\t-f n\t\tfilter number (default 1)\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file (default 'filter.dat')\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-l n\t\tdecomposition level (default 7)\n"); - fprintf(stderr, "\t-m n\t\tmean value (default 0.0)\n"); - fprintf(stderr, "\t-n n\t\twatermark length (default 1000)\n"); - fprintf(stderr, "\t-o file\t\toutput file\n"); - fprintf(stderr, "\t-s file\t\tuse signature file's embedding information\n"); - fprintf(stderr, "\t-S n\t\tseed\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char signature_name[MAXPATHLEN]; - - int c; - int n = 1000; - int s = 0; - int e = 2; - int f = 1; - char F[MAXPATHLEN] = "filter.dat"; - double a = 0.2; - double m = 0.0; - double d = 1.0; - int l = 7; - - progname = argv[0]; - - while ((c = getopt(argc, argv, "a:d:e:f:F:h?l:m:n:o:s:S:")) != EOF) { - switch (c) { - case 'a': - a = atof(optarg); - if (a <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); - exit(1); - } - break; - case 'l': - l = atoi(optarg); - if (l <= 0) { - fprintf(stderr, "%s: decomposition level %d out of range\n", progname, l); - exit(1); - } - break; - case 'd': - d = atof(optarg); - if (d <= 0.0) { - fprintf(stderr, "%s: deviation %f out of range\n", progname, d); - exit(1); - } - break; - case 'e': - e = atoi(optarg); - if (e < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, e); - } - break; - case 'f': - f = atoi(optarg); - if (f <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, f); - exit(1); - } - break; - case 'F': - strcpy(F, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'm': - m = atof(optarg); - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 32000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'S': - s = atoi(optarg); - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 0) { - usage(); - exit(1); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "ZHSG") >= 4) { - if (n == 0) - fscanf(sig, "%d\n", &n); - else - fscanf(sig, "%*d\n"); - if (a == 0.0) - fscanf(sig, "%lf\n", &a); - else - fscanf(sig, "%*f\n"); - if (l == 0) - fscanf(sig, "%d\n", &l); - else - fscanf(sig, "%*d\n"); - if (e < 0) - fscanf(sig, "%d\n", &e); - else - fscanf(sig, "%*d\n"); - if (f == 0) - fscanf(sig, "%d\n", &f); - else - fscanf(sig, "%*d\n"); - if (!strcmp(F, "")) - fscanf(sig, "%[^\n\r]\n", F); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - } - - if (s) - srandom(s); - else - srandom(time(NULL) * getpid()); - - fprintf(out, "ZHSG\n"); - fprintf(out, "%d\n", n); - fprintf(out, "%f\n", a); - fprintf(out, "%d\n", l); - fprintf(out, "%d\n", e); - fprintf(out, "%d\n", f); - fprintf(out, "%s\n", F); - - n >>= 1; - while (n > 0) { - double x; - double x1, x2; - - /* - * Algorithm P (Polar method for normal deviates), - * Knuth, D., "The Art of Computer Programming", Vol. 2, 3rd Edition, p. 122 - */ - do { - x1 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; - x2 = 2.0 * ((random() & RAND_MAX) / ((double) RAND_MAX + 1.0)) - 1.0; - x = x1 * x1 + x2 * x2; - } while (x >= 1.0); - x1 *= sqrt((-2.0) * log(x) / x); - x2 *= sqrt((-2.0) * log(x) / x); - - fprintf(out, "%f\n", m + d * x1); - fprintf(out, "%f\n", m + d * x2); - - n--; - } - - fclose(out); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gray.c --- a/Meerwald/gray.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,117 +0,0 @@ -#include "wm.h" -#include "gray.h" - -gray **alloc_grays_8x8() { - return alloc_grays(8, 8); -} - -gray **alloc_grays(int cols, int rows) { - gray **p; - int i; - - p = (gray **)malloc(rows * sizeof(gray *)); - if (!p) { -#ifdef DEBUG - fprintf(stderr, "alloc_grays(): malloc() failed\n"); - exit(1); -#else - return NULL; -#endif - } - - p[0] = (gray *)malloc(rows * cols * sizeof(gray)); - if (!p[0]) { -#ifdef DEBUG - fprintf(stderr, "alloc_grays(): malloc() failed\n"); - exit(1); -#else - free(p); - return NULL; -#endif - } - - for (i = 1; i < rows; i++) { - p[i] = &(p[0][i * cols]); - } - - return p; -} - -void free_grays(gray **grays) { - free(grays[0]); - free(grays); -} - -void copy_grays_to_block(gray ** block_grays, gray ** image_grays, int c, int r, int w, int h) { - int i, j; - -#ifdef DEBUG - if (!image_grays) { - fprintf(stderr, "copy_grays_to_block(): NULL image pixels\n"); - } - if (!block_grays) { - fprintf(stderr, "copy_grays_to_block(): NULL block pixels\n"); - } - if (w <= 0 || h <= 0 || c < 0 || r < 0) { - fprintf(stderr, "copy_grays_to_block(): block dimension out of range\n"); - } -#endif - - for (i = 0; i < w; i++) { - for (j = 0; j < h; j++) - block_grays[j][i] = image_grays[r + j][c + i]; - } -} - -void copy_grays_from_block(gray ** image_grays, gray ** block_grays, int -c, int r, int w, int h) { - int i, j; - -#ifdef DEBUG - if (!image_grays) { - fprintf(stderr, "copy_grays_from_block(): NULL image pixels\n"); - } - if (!block_grays) { - fprintf(stderr, "copy_grays_from_block(): NULL block pixels\n"); - } - if (w <= 0 || h <= 0 || c < 0 || r < 0) { - fprintf(stderr, "copy_grays_from_block(): block dimension out of range\n"); - } -#endif - - for (i = 0; i < w; i++) { - for (j = 0; j < h; j++) - image_grays[r + j][c + i] = block_grays[j][i]; - } -} - -void print_grays(gray **grays, int c, int r, int w, int h) { - int i, j; - gray *p; - -#ifdef DEBUG - if (!grays) { - fprintf(stderr, "print_grays(): NULL pixels\n"); - } - if (w <= 0 || h <= 0 || c < 0 || r < 0) { - fprintf(stderr, "print_grays(): block dimension out of range\n"); - } -#endif - - for (j = r; j < r + h; j++) { - p = &grays[j][c]; - for (i = 0; i < w; i++) - fprintf(stderr, "%3d ", *(p++)); - fprintf(stderr, "\n"); - } -} - -void print_grays_8x8(gray **grays) { - int i, j; - - for (i = 0; i < 8; i++) { - for (j = 0; j < 8; j++) - fprintf(stderr, "%3d ", grays[i][j]); - fprintf(stderr, "\n"); - } -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/gray.h --- a/Meerwald/gray.h Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -#ifndef GRAY_H -#define GRAY_H - -#include "wm.h" -#include "pgm.h" - -gray **alloc_grays(int cols, int rows); -gray **alloc_grays_8x8(); -void free_grays(gray **grays); -void copy_grays_to_block(gray ** block_grays, gray ** image_grays, int col, int row, int width, int height); -void copy_grays_from_block(gray ** image_grays, gray ** block_grays, int col, int row, int width, int height); -void print_grays(gray **grays, int col, int row, int width, int height); -void print_grays_8x8(gray **grays); -#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/kim_common.c --- a/Meerwald/kim_common.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -#include "wm.h" -#include "kim_common.h" - - -// find the largest absolute coefficient of a subband -double find_subband_largest_coeff(Image_tree s, int subband, int verbose) { - int i, j; - double max; - - max = 0.0; - for (i = 5; i < s->image->height-5; i++) - for (j = 5; j < s->image->width-5; j++) { - double coeff; - - coeff = fabs(get_pixel(s->image, i, j)); - if (coeff > max) - max = coeff; - } - - if (verbose > 8) - fprintf(stderr, " subband %f\n", max); - - return max; -} - -// find largest absolute coefficient of the detail subbands (LH, HL, HH) of -// a decomposition level -double find_level_largest_coeff(Image_tree p, int verbose) { - double h, v, d; - - h = find_subband_largest_coeff(p->horizontal, HORIZONTAL, verbose); - v = find_subband_largest_coeff(p->vertical, VERTICAL, verbose); - d = find_subband_largest_coeff(p->diagonal, DIAGONAL, verbose); - - return MAX(h, MAX(v, d)); -} - -// calculate the significance threshold given the maximum absolute -// coefficient at a decomposition level -double calc_level_threshold(double max_coeff, int verbose) { - double threshold; - - threshold = pow(2.0, floor(log(max_coeff) / log(2.0)) - 1.0); - - if (verbose > 7) - fprintf(stderr, " max %f, threshold %f\n", max_coeff, threshold); - - return threshold; -} - -// calculate an appropriate embedding strength for a given decomposition level -// and a base alpha strength -double calc_level_alpha_detail(double alpha, int maxlevels, int level, int verbose) { - double level_alpha; - - level_alpha = alpha / pow(2.0, level - 1); - - return level_alpha; -} - diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/kim_common.h --- a/Meerwald/kim_common.h Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -#ifndef KIM_COMMON_H -#define KIM_COMMON_H - -#include "dwt.h" -#include "dwt_util.h" - -double find_subband_largest_coeff(Image_tree p, int subband, int verbose); -double find_level_largest_coeff(Image_tree p, int verbose); - -double calc_level_threshold(double max_coeff, int verbose); -double calc_level_alpha_detail(double alpha, int maxlevels, int level, int verbose); - -#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/param_stuff.c --- a/Meerwald/param_stuff.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,133 +0,0 @@ -#ifdef PARAM_STUFF - { -#define MAXNALPHA 32 - - double alpha[MAXNALPHA]; - char *alpha_str = getenv("PARAM_ALPHA"); - double alpha_value; - int alpha_len = 0; - - int param_len[MAXNALPHA]; - char *param_len_str = getenv("PARAM_LEN"); - int param_len_value; - int param_len_len = 0; - int param_len_sum = 0; - - char buf[1024] = ""; - char *v; - - - if (alpha_str && strlen(alpha_str) < sizeof(buf) - && strcmp(alpha_str, "") ) { - - strcpy(buf, alpha_str); - - v = strtok(buf, "\",; "); - do { - - alpha_value = atof(v); - - if (alpha_value < -M_PI || alpha_value >= M_PI) { - fprintf(stderr, "%s: parametric - alpha %f out of range\n", - progname, alpha_value); - exit(1); - } - - alpha[alpha_len] = alpha_value; - alpha_len++; - } while ((v = strtok(NULL, "\",; "))); - - - if( param_len_str && strlen(param_len_str) < sizeof(buf) - && strcmp(param_len_str, "") ) { - /* There was an parameter length environment variable. */ - - strcpy(buf, param_len_str); - - v = strtok(buf, "\",; "); - do { - - param_len_value = atoi(v); - - if (param_len_value <= 0) { - fprintf(stderr, "%s: parameter length %d out of range\n", - progname, param_len_value); - exit(1); - } - - param_len[param_len_len] = param_len_value; - param_len_len++; - param_len_sum += param_len_value; - - } while ((v = strtok(NULL, "\",; "))); - - } else { - /* No length variable given. - For backward compatability we use all parameters for - one filter and therefore for all levels. - */ - - param_len[0] = alpha_len; - param_len_len = 1; - param_len_sum = alpha_len; - } - - - /* If we do not get a parameter length value for every - decomposition level then we reuse the last supplied value - for the remaining levels. - */ - if (param_len_len < level+1) { - int last_param_len = param_len[ param_len_len - 1 ]; - - for(; param_len_len < level+1; param_len_len++ ) { - param_len[ param_len_len ] = last_param_len; - param_len_sum += last_param_len; - } - } - - - /* If the number of supplied alphas is lower than is required - for by param_len then copy the last filter - parameters to the remaining levels. - */ - if( alpha_len < param_len_sum ) { - int i; - int last_param_len = param_len[ param_len_len - 1 ]; - int last_start = alpha_len - last_param_len; - - for( i=0; alpha_len < param_len_sum; alpha_len++, i++ ) { - alpha[ alpha_len ] = alpha[ last_start + (i % last_param_len) ]; - } - } - - if (verbose > 1) { - int i, j; - int cur_sum = 0; - - fprintf(stderr, "%s: parametric, number of levels: %d\n", - progname, level); - - for (i = 0; i < level+1; i++) { - - fprintf(stderr, " %d filter parameters for level %d: ", - param_len[i], i); - - for (j = 0; j < param_len[i]; j++) { - fprintf(stderr, "%f ", alpha[cur_sum + j]); - } - - fprintf(stderr, "\n"); - - cur_sum += param_len[i]; - } - } - - - dwt_param_filter(alpha, param_len); - - - } /* if( alpha_str... */ - } -#endif - diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/pollen_stuff.c --- a/Meerwald/pollen_stuff.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -#ifdef POLLEN_STUFF - { - double alpha, beta; - char *alpha_str = getenv("POLLEN_ALPHA"), *beta_str = getenv("POLLEN_BETA"); - - if (alpha_str && beta_str) { - alpha = atof(alpha_str); - beta = atof(beta_str); - - if (alpha < -M_PI || alpha >= M_PI) { - fprintf(stderr, "%s: pollen - alpha %f out of range\n", progname, alpha); - exit(1); - } - - if (beta < -M_PI || beta >= M_PI) { - fprintf(stderr, "%s: pollen - beta %f out of range\n", progname, beta); - exit(1); - } - - if (verbose > 7) - fprintf(stderr, "%s: pollen - alpha %f, beta %f\n", progname, alpha, beta); - - dwt_pollen_filter(alpha, beta); - } - } -#endif - diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/signature-utils.c --- a/Meerwald/signature-utils.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,120 +0,0 @@ -#include -#include -#include "signature-utils.h" - -void init_signature_bits() { - bzero(signature, sizeof(signature)); -} - -void init_signature1_bits() { - bzero(signature1, sizeof(signature1)); -} - -void init_signature2_bits() { - bzero(signature2, sizeof(signature2)); -} - -int _get_signature_bit(char *s, int lim, int n) { - int byte = n >> 3; - int bit = n & 7; - -#ifdef DEBUG - if (byte < 0 || byte >= lim) - fprintf(stderr, "get_signature_bit?(): index out of range\n"); -#endif - - return (s[byte] & (1 << bit)) >> bit; -} - -int get_signature_bit(int n) { - return _get_signature_bit(signature, NSIGNATURE, n); -} - -int get_signature1_bit(int n) { - return _get_signature_bit(signature1, NSIGNATURE, n); -} - -int get_signature2_bit(int n) { - return _get_signature_bit(signature2, NSIGNATURE, n); -} - -void _set_signature_bit(char *s, int limit, int n, int v) { - int byte = n >> 3; - int bit = n & 7; - -#ifdef DEBUG - if (byte < 0 || byte >= limit / 8) - fprintf(stderr, "get_signature_bit?(): index out of range\n"); -#endif - - if (v) - s[byte] |= (1 << bit); - else - s[byte] &= ~(1 << bit); -} - -void set_signature_bit(int n, int v) { - _set_signature_bit(signature, NSIGNATURE, n, v); -} - -void set_signature1_bit(int n, int v) { - _set_signature_bit(signature1, NSIGNATURE, n, v); -} - -void set_signature2_bit(int n, int v) { - _set_signature_bit(signature2, NSIGNATURE, n, v); -} - -int _binstr_to_sig(const char *binstr, char *sig, int *bytes, int *bits) { - int n = strlen(binstr); - int i; - - for (i = 0; i < n; i++) { - if (binstr[i] == '0') - _set_signature_bit(sig, NSIGNATURE, i, 0); - else if (binstr[i] == '1') - _set_signature_bit(sig, NSIGNATURE, i, 1); - else - return 0; - } - - *bytes = (n % 8 > 0) ? n / 8 + 1 : n / 8; - *bits = n; - - return 1; -} - -int binstr_to_sig(const char *binstr) { - return _binstr_to_sig(binstr, signature, &n_signature, &nbit_signature); -} - -int binstr_to_sig1(const char *binstr) { - return _binstr_to_sig(binstr, signature1, &n_signature1, &nbit_signature1); -} - -int binstr_to_sig2(const char *binstr) { - return _binstr_to_sig(binstr, signature2, &n_signature2, &nbit_signature2); -} - -int _sig_to_binstr(char *binstr, char *sig, int bits) { - int i; - - for (i = 0; i < bits; i++) - binstr[i] = _get_signature_bit(sig, NSIGNATURE, i) ? '1' : '0'; - - binstr[bits] = '\0'; - - return 1; -} - -int sig_to_binstr(char *binstr) { - return _sig_to_binstr(binstr, signature, nbit_signature); -} - -int sig1_to_binstr(char *binstr) { - return _sig_to_binstr(binstr, signature1, nbit_signature1); -} - -int sig2_to_binstr(char *binstr) { - return _sig_to_binstr(binstr, signature2, nbit_signature2); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/signature-utils.h --- a/Meerwald/signature-utils.h Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -#ifndef SIGNATURE_UTILS_H -#define SIGNATURE_UTILS_H - -#define NSIGNATURE 4096 -#define NBITSIGNATURE (NSIGNATURE * 8) - -extern int n_signature; -extern int nbit_signature; -extern int n_signature1; -extern int nbit_signature1; -extern int n_signature2; -extern int nbit_signature2; - -extern char signature[NSIGNATURE]; -extern char signature1[NSIGNATURE]; -extern char signature2[NSIGNATURE]; - -void init_signature_bits(); -int get_signature_bit(int n); -void set_signature_bit(int n, int v); - -void init_signature1_bits(); -int get_signature1_bit(int n); -void set_signature1_bit(int n, int v); - -void init_signature2_bits(); -int get_signature2_bit(int n); -void set_signature2_bit(int n, int v); - -int binstr_to_sig(const char *binstr); -int binstr_to_sig1(const char *binstr); -int binstr_to_sig2(const char *binstr); -int sig_to_binstr(char *binstr); -int sig1_to_binstr(char *binstr); -int sig2_to_binstr(char *binstr); - -#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/signature.h --- a/Meerwald/signature.h Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -#ifndef SIGNATURE_H -#define SIGNATURE_H - -#include "wm.h" -#include "signature-utils.h" - -int n_signature; -int nbit_signature; -int n_signature1; -int nbit_signature1; -int n_signature2; -int nbit_signature2; - -char signature[NSIGNATURE]; -char signature1[NSIGNATURE]; -char signature2[NSIGNATURE]; - -#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/sort.c --- a/Meerwald/sort.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,184 +0,0 @@ -#include "sort.h" - -#define SWAP_GRAY(A, B) {gray t = A; A = B; B = t;} - -/* - * quicksort-alike, from the EMX library (emx/src/lib/misc/qsort.c) - * by Eberhard Mattes - * - * sort() is not stable, the order of equal elements is not defined - */ - -void _sort_grays(gray *l, gray *r) { - gray *i; - gray *j; - gray *x; - -redo: - i = l; - j = r; - x = l + sizeof(gray) * (((r-l) / sizeof(gray)) / 2); - - do { - while (i != x && *i < *x) - i++; - while (j != x && *j > *x) - j--; - if (i < j) { - SWAP_GRAY(*i, *j); - if (x == i) - x = j; - else if (x == j) - x = i; - } - if (i <= j) { - i++; - if (j > l) - j--; - } - } while (i <= j); - - if (j-l < r-i) { - if (l < j) - _sort_grays(l, j); - if (i < r) { - l = i; - goto redo; - } - } - else { - if (i < r) - _sort_grays(i, r); - if (l < j) { - r = j; - goto redo; - } - } -} - -void sort_grays(gray a[], int n) { - if (n > 1) - _sort_grays(&a[0], &a[n-1]); -} - -/* - * select_largest(), from the Numeric Recipes in C, Chapter 8, p. 344, - * see http://www.nr.com - * - * returns in largest[0..m-1] the largest m elements of array[0..n-1] - * with largest[0] guaranteed to be the mth largest element; largest[] is - * not sorted; the array[] is not altered; this function should be used - * only when m << n - */ - -void select_largest_grays(gray array[], int n, int m, gray largest[]) { - int i, j, k; - - if (m <= 0 || m > n/2) - return; - - for (i = 0; i < m; i++) - largest[i] = array[i]; - sort_grays(largest, m); - - for (i = m; i < n; i++) { - if (array[i] > largest[0]) { - largest[0] = array[i]; - j = 0; - k = 1; - while (k < m) { - if (k < m-1 && largest[k] > largest[k+1]) - k++; - if (largest[j] <= largest[k]) - break; - SWAP_GRAY(largest[k], largest[j]); - j = k; - k = k << 1; - } - } - } -} - -#define SWAP_DOUBLE(A, B) {double t = A; A = B; B = t;} - -void _sort_coeffs(double *l, double *r) { - double *i; - double *j; - double *x; - -redo: - i = l; - j = r; - x = l + sizeof(double) * (((r-l) / sizeof(double)) / 2); - - do { - while (i != x && *i < *x) - i++; - while (j != x && *j > *x) - j--; - if (i < j) { - SWAP_DOUBLE(*i, *j); - if (x == i) - x = j; - else if (x == j) - x = i; - } - if (i <= j) { - i++; - if (j > l) - j--; - } - } while (i <= j); - - if (j-l < r-i) { - if (l < j) - _sort_coeffs(l, j); - if (i < r) { - l = i; - goto redo; - } - } - else { - if (i < r) - _sort_coeffs(i, r); - if (l < j) { - r = j; - goto redo; - } - } -} - -void sort_coeffs(double a[], int n) { - if (n > 1) - _sort_coeffs(&a[0], &a[n-1]); -} - -void select_largest_coeffs(double array[], int n, int m, double largest[]) { - int i, j, k; - - if (m <= 0 || m > n/2) - return; - - for (i = 0; i < m; i++) - largest[i] = array[i]; - sort_coeffs(largest, m); - - for (i = m; i < n; i++) { - if (array[i] > largest[0]) { - largest[0] = array[i]; - j = 0; - k = 1; - while (k < m) { - if (k < m-1 && largest[k] > largest[k+1]) - k++; - if (largest[j] <= largest[k]) - break; - SWAP_DOUBLE(largest[k], largest[j]); - j = k; - k = k << 1; - } - } - } -} - - diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/sort.h --- a/Meerwald/sort.h Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,13 +0,0 @@ -#ifndef SORT_H -#define SORT_H - -#include "wm.h" -#include "pgm.h" - -void sort_grays(gray a[], int n); -void select_largest_grays(gray array[], int n, int m, gray largest[]); - -void sort_coeffs(double a[], int n); -void select_largest_coeffs(double array[], int n, int m, double largest[]); - -#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wang_common.c --- a/Meerwald/wang_common.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,179 +0,0 @@ -#include "dwt_util.h" -#include "wang_common.h" - -Subband_data *subbands; -int n_subbands; - -void init_subbands(Image_tree tree) { - int levels = 0; - int i; - Image_tree p = tree; - - // determine # of detail subbands - while (p->coarse != NULL) { - levels++; - p = p->coarse; - } - - // there are 3 detail subbands per level - n_subbands = 3 * levels; - - // allocate memory for subband data - subbands = malloc(n_subbands * sizeof(Subband_data)); - - p = tree; - i = 0; - while (p->coarse != NULL) { - subbands[i++] = alloc_subband(HORIZONTAL, p->horizontal); - subbands[i++] = alloc_subband(VERTICAL, p->vertical); - subbands[i++] = alloc_subband(DIAGONAL, p->diagonal); - - p = p->coarse; - } - -} - -Subband_data alloc_subband(int type, Image_tree tree) { - int i; - Subband_data p = malloc(sizeof(struct Subband_data_struct)); - - p->T = 0.0; - p->beta = 0.0; - p->Cmax = 0.0; - p->tree = tree; - p->level = tree->level; - p->width = tree->image->width; - p->height = tree->image->height; - p->size = p->height * p->width; - p->image = tree->image; - p->type = type; - - p->selected = malloc(p->height * sizeof(char *)); - p->selected[0] = calloc(p->size, sizeof(char)); - for (i = 1; i < p->height; i++) - p->selected[i] = &(p->selected[0][i * p->width]); - - return p; -} - -void set_subband_beta(Subband_data subband, double beta) { - subband->beta = beta; -} - -void set_subbands_beta(double beta) { - int i; - - for (i = 0; i < n_subbands; i++) - set_subband_beta(subbands[i], beta); -} - -void set_subbands_type_beta(int type, double beta) { - int i; - - for (i = 0; i < n_subbands; i++) - if (subbands[i]->type == type) - set_subband_beta(subbands[i], beta); -} - -void calc_subband_threshold(Subband_data subband) { - double max; - int i, j; - - max = fabs(get_pixel(subband->image, 0, 0)); - for (i = 0; i < subband->height; i++) - for (j = 0; j < subband->width; j++) { - Pixel p = fabs(get_pixel(subband->image, i, j)); - if (p > max) - max = p; - } - - subband->Cmax = max; - subband->T = max / 2.0; -} - -void calc_subbands_threshold() { - int i; - - for (i = 0; i < n_subbands; i++) - calc_subband_threshold(subbands[i]); -} - -Subband_data select_subband() { - int max = 0; - int i; - - for (i = 0; i < n_subbands; i++) - if ((subbands[i]->beta * subbands[i]->T) > (subbands[max]->beta * subbands[max]->T)) - max = i; - - return subbands[max]; -} - -int subband_coeff_isselected(Subband_data subband, int coeff) { - return subband->selected[0][coeff]; -} - -Pixel get_subband_coeff(Subband_data subband, int coeff) { - return subband->image->data[coeff]; -} - -void set_subband_coeff(Subband_data subband, int coeff, Pixel data) { - subband->image->data[coeff] = data; -} - -int select_subband_coeff_from(Subband_data subband, int from) { - int i; - - for (i = from; i < subband->size; i++) - if (!subband_coeff_isselected(subband, i) && - get_subband_coeff(subband, i) > subband->T) - return i; - - return -1; -} - -int select_subband_coeff(Subband_data subband) { - return select_subband_coeff_from(subband, 0); -} - -void mark_subband_coeff(Subband_data subband, int coeff) { - subband->selected[0][coeff] = 1; -} - -void free_subband(Subband_data subband) { - free(subband->selected[0]); - free(subband->selected); - free(subband); -} - -void free_subbands() { - int i; - - for (i = 0; i < n_subbands; i++) - free_subband(subbands[i]); - - free(subbands); -} - -#define LARGE DBL_MAX - -Pixel figure_orig_coeff(double T, double alpha, double beta, Pixel coeff) { - int p, p_min = 0; - double dist_min = LARGE; - double sign = (coeff >= 0) ? 1.0 : -1.0; - - for (p = 1; p < 1.0 / (2.0 * alpha); p++) { - double dist, delta; - - delta = (1.0 + 2.0 * p * alpha) * T; - dist = fabs(delta - fabs(coeff)); - - if (dist < dist_min) { - dist_min = dist; - p_min = p; - } - } - - if (!p_min) p_min = 1; - return sign * (1.0 + 2.0 * p_min * alpha) * T; -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wang_common.h --- a/Meerwald/wang_common.h Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -#ifndef WANG_COMMON_H -#define WANG_COMMON_H - -#include "dwt.h" - -typedef struct Subband_data_struct { - double T; - double Cmax; - double beta; - Image_tree tree; - int level; - int type; - int width; - int height; - int size; - Image image; - char** selected; -} *Subband_data; - -void init_subbands(Image_tree tree); -Subband_data alloc_subband(int type, Image_tree tree); -void free_subband(Subband_data subband); -void free_subbands(); - -void set_subband_beta(Subband_data subband, double beta); -void set_subbands_beta(double beta); -void set_subbands_type_beta(int type, double beta); - -void calc_subband_threshold(Subband_data subband); -void calc_subbands_threshold(); - -int subband_coeff_isselected(Subband_data subband, int coeff); -Pixel get_subband_coeff(Subband_data subband, int coeff); -void set_subband_coeff(Subband_data subband, int coeff, Pixel data); - -Subband_data select_subband(); -int select_subband_coeff_from(Subband_data subband, int from); -int select_subband_coeff(Subband_data subband); -void mark_subband_coeff(Subband_data subband, int coeff); - -Pixel figure_orig_coeff(double T, double alpha, double beta, Pixel coeff); - -#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wavelet.c --- a/Meerwald/wavelet.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2982 +0,0 @@ -#include -#include -#include -#include -#include "wavelet.h" -#include -#include - -static int read_char(FILE *fp); -static int read_int(FILE *fp); - -IntImage new_intimage(int width, int height) -{ - IntImage image; - - image = (IntImage) calloc(1,sizeof(struct IntImage_struct)); - if (image==NULL) goto error; - image->data = (IntPixel*) calloc(width*height,sizeof(IntPixel)); - if (image->data==NULL) goto error; - image->width = width; - image->height = height; - image->size = width*height; - image->bpp = 0; - image->min_val = (IntPixel) 0; - image->max_val = (IntPixel) 0; - - return image; - - error: - err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); - return NULL; -} - -Image new_image(int width, int height) -{ - Image image; - - image = (Image) calloc(1,sizeof(struct Image_struct)); - if (image==NULL) goto error; - image->data = (Pixel*) calloc(width*height,sizeof(Pixel)); - if (image->data==NULL) goto error; - image->width = width; - image->height = height; - image->size = width*height; - image->bpp = 0; - image->min_val = (Pixel) 0; - image->max_val = (Pixel) 0; - - return image; - - error: - err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); - return NULL; -} - - -void free_intimage(IntImage img) -{ - if (img) { - if (img->data) free(img->data); - free(img); - } -} - -void free_image(Image img) -{ - if (img) { - if (img->data) free(img->data); - free(img); - } -} - -/************************************************************************ - * Functionname: load_intimage - * -------------------------------------------------------------------- - * PARAMETER: - * file: filename of image - * max_val: scaling of grey values to [0..max_val] - * - * RETURN: - * Image that shoud be loaded, if not possible return NULL - * -------------------------------------------------------------------- - * DESCRIPTION: - * This function loads an IntImage (PGM, ASCII or binary - * encoded (P5 or P3 format) ) from a file. - ************************************************************************/ - -IntImage load_intimage(char *file, int max_val) -{ - IntImage img; - FILE *fp; - IntPixel *data; - int width, height, i, ch1, ch2; - - fp=fopen(file,"rb"); - if (fp==NULL) goto error; - - ch1=getc(fp); - ch2=getc(fp); - if (ch1!='P' || (ch2!='5' && ch2!='2')) goto error1; - - width=read_int(fp); - height=read_int(fp); - if ((width==0) || (height==0) ) goto error1; - read_int(fp); - - img=new_intimage(width,height); - - img->bpp=8; - - data=img->data; - for (i=0; isize; i++) - { if (ch2=='5') - *data=getc(fp); - else - *data=read_int(fp); - data++; - } - fclose(fp); - return img; - - error1: - err_SimpleMessage(err_GetErrorMessage(Error_WrongFileFormat)); - return NULL; - error: - err_SimpleMessage(err_GetErrorMessage(Error_CantOpenFile)); - return NULL; -} - -/************************************************************************ - * Functionname: load_image - * -------------------------------------------------------------------- - * PARAMETER: - * file: filename of image - * max_val: scaling of grey values to [0..max_val] - * - * RETURN: - * Image that shoud be loaded, if not possible return NULL - * -------------------------------------------------------------------- - * DESCRIPTION: - * This function loads an IntImage with load_intimage - * and then converts to Image. - ************************************************************************/ -Image load_image(char *file, int max_val) -{ - Image img; - IntImage intimg; - - intimg = load_intimage(file, max_val); - if (!intimg) return NULL; - img = intimage_to_image(intimg); - if (!intimg) return NULL; - - return img; -} - -/************************************************************************/ -/* Functionname: save_image_P5 */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* img: Image that shoud be saved */ -/* file: filename of image */ -/* -------------------------------------------------------------------- */ -/* Description: save an image as PGM (P5 binary decoded) file */ -/* */ -/************************************************************************/ - -int save_image_P5(char *file, Image img) -{ FILE *fp; - Pixel *data; - long i; - int p; - - fp=fopen(file,"wb"); - if (fp==NULL) - goto error; - fprintf(fp,"P5\n"); - fprintf(fp,"%d %d\n%d ",img->width,img->height,255); - data=img->data; - for (i=0;isize;i++) { - p=floor(*data+0.5); - if (p<0) p=0; - if (p>255) p=255; -/* putc(*data,fp); */ - putc(p,fp); - data++; - } - fclose(fp); - return 1; - - error: - err_SimpleMessage(err_GetErrorMessage(Error_CantOpenFile)); - return 0; -} - -void clear_image(Image img) -{ - int i; - - PreCondition(img!=NULL,"image==NULL"); - - for (i=0;isize;i++) - (img->data)[i]=(Pixel) 0; -} - -void copy_into_image(Image img1,Image img2,int x,int y) -/* copy img2 into img1 at position (x,y)*/ -{ - int start,i,j,aim; - Pixel *temp; - - temp=img2->data; - start=img1->width*y+x; - for (i=0;iheight;i++) { - for (j=0;jwidth;j++) { - aim=start+j+img1->width*i; - img1->data[aim]=*temp; - temp++; - } - } -} - -void copy_into_intimage(IntImage img1,IntImage img2,int x,int y) -{/* copy img2 into img1 at position (x,y)*/ - - int start,i,j,aim; - IntPixel *temp; - - temp=img2->data; - start=img1->width*y+x; - for (i=0;iheight;i++) - { - for (j=0;jwidth;j++) - { - aim=start+j+img1->width*i; - img1->data[aim]=*temp; - temp++; - } - } -} - -void copy_part_of_image_into_image(Image dest_img, int dest_x, int dest_y, - Image src_img, int src_x, int src_y, - int width, int height) -{ - Pixel *sp,*dp; - int y,siz; - - sp=get_pixel_adr(src_img,src_x,src_y); - dp=get_pixel_adr(dest_img,dest_x,dest_y); - - siz=width*sizeof(Pixel); - - for (y=0;ywidth; - dp+=dest_img->width; - } -} - -void copy_part_of_image(Image img1,Image img2,int x,int y) -/* copy part of img2 begining at position (x,y) into img1 */ -{ int i,j,width,height,start,step; - Pixel *data; - - width=img1->width; - height=img1->height; - start=img2->width*y+x; - data=img1->data; - for (i=0;iwidth; - for (j=0;jdata[start+j+step]; - data++; - } - } -} - - -void scale_image(Image img, int maximum) -/* scale image to [0..maximum]*/ -{ int i; - Pixel max = MINDOUBLE, min = MAXDOUBLE, multi; - - for (i=0;isize;i++) { - if (img->data[i]data[i]; - else if (img->data[i]>max) max=img->data[i]; - } - - multi=(Pixel)maximum/(max-min); - for (i=0;isize;i++) img->data[i]=multi*(img->data[i]-min); - img->min_val=0; - img->max_val=maximum; -} - -int string_to_pixel(char *str, Pixel *p) -{ - float ppp; - if (sscanf(str,"%f",&ppp)==1) - { - *p=(Pixel) ppp; - return 1; - } - else - { - *p=0.0; - return 0; - } -} - -Image intimage_to_image(IntImage i) -{ Image img; - int j; - - img=new_image(i->width,i->height); - if (img==NULL) goto error; - for (j=0;jsize;j++) - img->data[j]=(Pixel)i->data[j]; - img->bpp=i->bpp; - return img; - - error: - err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); - return NULL; -} -IntImage image_to_intimage(Image i) -{ IntImage img; - int j,multi=1,max,min; - - img=(IntImage)calloc(1,sizeof(struct IntImage_struct)); - if (img==NULL) goto error; - img->data=(IntPixel *)calloc(i->size,sizeof(IntPixel)); - if (img->data==NULL) goto error; - img->width=i->width; - img->height=i->height; - img->size=i->size; - img->bpp=i->bpp; - - max=i->max_val; - min=i->min_val; - if ((max-min)!=0) - multi=255.0/(max-min); - - for (j=0;jsize;j++) - img->data[j]=(int)((i->data[j]-min)*multi+0.5); - return img; - - error: - err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); - return NULL; - -} - -static int read_char(FILE *fp) -/*read a character from file, but skip any comments*/ -{ int ch; - - ch=getc(fp); - if (ch=='#'){ - do { - ch=getc(fp); - } while (ch!='\n' && ch!=EOF); - } - return ch; -} - - -static int read_int(FILE *fp) -/*read an ascii integer from file, and skip leading tabstops,new lines ...*/ -{ int r,ch; - - do { - ch=read_char(fp); - } while (ch==' ' || ch=='\n' || ch=='\t'); - - if (ch<'0' || ch>'9') - goto error; - - r=ch-'0'; - while ( (ch=read_char(fp)) >='0' && (ch <= '9') ) { - r*=10; - r+=ch-'0'; - } - return r; - error: - return 0; -} - -Image_tree new_image_tree() -{ - Image_tree t; - t=(Image_tree) calloc(1,sizeof(struct Image_tree_struct)); - t->entropy=0.0; - t->image=NULL; - t->coarse=t->horizontal=t->vertical=t->diagonal=t->doubletree=NULL; - t->level=0; - t->codec_data=NULL; - t->significance_map=NULL; - return t; -} - -void free_image_tree(Image_tree t) -{ - if (t->coarse) free_image_tree(t->coarse); - if (t->horizontal) free_image_tree(t->horizontal); - if (t->vertical) free_image_tree(t->vertical); - if (t->diagonal) free_image_tree(t->diagonal); - if (t->doubletree) free_image_tree(t->doubletree); - if (t->image) free_image(t->image); - if (t->significance_map) free_intimage(t->significance_map); - if (t->codec_data) free(t->codec_data); - t->image=NULL; - free(t); -} - -/*********************************************************************** - * Functionname: get_image_infos - * -------------------------------------------------------------------- - * Parameter: - * Image image: input image - * Pixel *min,*max,*avg,*var: return minimum, maximum, - * average and variance of current image - * -------------------------------------------------------------------- - * Description: - * get statistical information of Image - ************************************************************************/ - -void get_image_infos(Image image, Image_info info) -{ - int x,y; - Pixel p,sp,sp2; - - sp=sp2=(Pixel)0.0; - - p=get_pixel(image,0,0); - - info->min=info->max=p; - - for (y=0;yheight;y++) - for (x=0;xwidth;x++) - { - p=get_pixel(image,x,y); - info->max=MAX(info->max,p); - info->min=MIN(info->min,p); - sp+=p; - sp2+=p*p; - } - sp=sp/image->width/image->height; - sp2=sp2/image->width/image->height; - - info->mean=sp; - info->var=sp2-sp*sp; - info->rms=sqrt(sp2); -} - -/*********************************************************************** - * Functionname: get_difference_image - * -------------------------------------------------------------------- - * Parameter: - * Image image1, image 2: input images - * - * Return: - * Image : difference of image1 and image 2, - * NULL if error occurs - ************************************************************************/ - -Image get_difference_image(Image image1, Image image2) -{ - Image diff; - int i,max,w,h; - Pixel *d,*i1,*i2; - - if ((!image1) || (!image2)) return NULL; - - w=image1->width; - h=image1->height; - - if (image2->width != w || image2->height != h) return NULL; - - diff=new_image(w,h); - max=w*h; - - d=diff->data; - i1=image1->data; - i2=image2->data; - - for (i=0;iheight;y++) - for (x=0;xwidth;x++) - { - p= (Pixel) get_intpixel(image,x,y); - *max=MAX(*max, (IntPixel) p); - *min=MIN(*min, (IntPixel) p); - sp+=p; - sp2+=p*p; - } - sp=sp/image->width/image->height; - sp2=sp2/image->width/image->height; - - *avg=sp; - *var=sp2-sp*sp; -} - -/************************************************************************/ -/* Functionname: init_zigzag */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* Zigzag_data_struct: */ -/* output: will be initialized, x/y hold coordinates of */ -/* the first pixel */ -/* int width,height: */ -/* input: width/height of image: */ -/* -------------------------------------------------------------------- */ -/* Description: */ -/* initializes Zigzag_data structure for use with next_zigzag */ -/************************************************************************/ - -void init_zigzag(Zigzag_data zz, int width, int height) -{ - zz->x=0; - zz->y=0; - zz->dir=zigzag_up; - zz->w=width; - zz->h=height; -} - -/************************************************************************/ -/* Functionname: next_zigzag */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* Zigzag_data_struct: */ -/* int x,y: */ -/* input: current position of zigzag-scan */ -/* output: next position of zigzag-scan */ -/* int w,h: width and height of image */ -/* enum zigzag_direction *dir: i/o: */ -/* direction moving thru the image */ -/* -------------------------------------------------------------------- */ -/* Description: */ -/* calculates the next point (x',y') of the zigzag-scan */ -/* through the image with size (w,h) */ -/************************************************************************/ - - -void next_zigzag(Zigzag_data zz) -{ - switch(zz->dir) - { - case zigzag_up: - if (zz->y==0) - { - if (zz->x==zz->w-1) - { - (zz->y)++; zz->dir=zigzag_down; - } - else - { - (zz->x)++; zz->dir=zigzag_down; - } - } - else - { - if (zz->x==zz->w-1) - { - (zz->y)++; zz->dir=zigzag_down; - } - else - { - (zz->x)++; (zz->y)--; - } - } - break; - - case zigzag_down: - - if (zz->x==0) - { - if (zz->y==zz->h-1) - { - (zz->x)++; zz->dir=zigzag_up; - } - else - { - (zz->y)++; zz->dir=zigzag_up; - } - } - else - { - if (zz->y==zz->h-1) - { - (zz->x)++; zz->dir=zigzag_up; - } - else - { - (zz->x)--;(zz->y)++; - } - } - break; - } -} - -Image get_absolute_image_scaled(Image img) -{ - Image out; - - int x,y; - - struct Image_info_struct info; - Pixel scale,p; - - out=new_image(img->width,img->height); - - get_image_infos(img, &info); - - scale=255/MAX(fabs(info.min),fabs(info.max)); - - for(y=0;yheight;y++) - for(x=0;xwidth;x++) - { - p=get_pixel(img,x,y)*scale; - set_pixel(out,x,y,p); - } - return out; -} - -#define FLOOR_HALF(x) ((x)&1 ? ((x)-1)/2 : (x)/2) -#define CEILING_HALF(x) ((x)&1 ? ((x)+1)/2 : (x)/2) - -#define MOD(a,b) ( (a)<0 ? ((b)-((-(a))%(b))) : (a)%(b) ) - -Filter new_filter(int size) -{ - Filter f; - - Entering; - f=(Filter) calloc(1,sizeof(struct FilterStruct)); - f->data=(Pixel *)calloc(size,sizeof(Pixel)); - f->len=size; - f->hipass=0; - - Leaving; - return f; -} - -Pixel get_filter_center(Filter f) -{ - int i; - Pixel p, sum, norm; - - if (f==NULL) return 0; - - sum=norm=0; - - for (i=0;ilen;i++) - { - p=f->data[i]; - p=p*p; - norm += p; - sum += (i+f->start)*p; - } - p=sum/norm; - - return p; -} -int filter_cutoff(Image in, int in_start, int in_len, int in_step, - Image out, int out_start, int out_len, int out_step, - Filter f) -{ - int i,i2,j; - Pixel *out_pix, *in_pix, *f_data; - int fstart,fend; /* Source interval */ - - Entering; - - PreCondition(out_len == in_len/2,"out_len != in_len/2 !!!"); - -/* convolution: out[i]=sum_{j=start}^{end} (in[2*i-j]*f[j]) - - boundaries: image in [in_start ... in_start + in_len-1] - image out [out_start ... out_start + out_len-1] - filter f [0..f->len-1] = [f->start .. f->end] - cutoff at: -*/ - - for (i=0;istart); - fend=MIN(i2,f->end); - -#ifdef TRACE - sprintf(dbgstr,"i=%d fstart=%d fend=%d\n",i,fstart,fend); - Trace(dbgstr); -#endif - - out_pix=out->data+out_start+i*out_step; - - in_pix=in->data+in_start+(i2-fstart)*in_step; - - f_data=f->data-f->start+fstart; - - for (j=fstart;j<=fend;j++,in_pix-=in_step,f_data++) - { - *out_pix += (*f_data) * (*in_pix); -#ifdef TRACE - - sprintf(dbgstr," j=%2d in: %4.2f filter: %4.2f [%4d] [%4d] opt : %4.2f %4.2f\n", - j, - in->data[in_start+in_step*(i2-j)], - f->data[j-f->start], - in_start+in_step*(i2-j), - j-f->start, - *in_pix, *f_data); - Trace(dbgstr); -#endif - } - } - - Leaving; - return 1; -} - - -int filter_inv_cutoff(Image in, int in_start, int in_len, int in_step, - Image out, int out_start, int out_len, int out_step, - Filter f) -{ - int i,j; - Pixel *out_pix, *in_pix, *f_data; - int fstart,fend; /* Source interval */ - Entering; - PreCondition(out_len == in_len*2,"out_len != in_len*2 !!!"); - -/* convolution: out[i]=sum_{j=start}^{end} (f[2*j-i]*in[j]) - - boundaries: image in [in_start ... in_start + in_len-1] - image out [out_start ... out_start + out_len-1] - filter f [0..f->len-1] = [f->start .. f->end] - cutoff at: -*/ - - for (i=0;istart+i); - fend=FLOOR_HALF(f->end+i); - fstart=MAX(fstart,0); - fend=MIN(fend,in_len-1); - -#ifdef TRACE - sprintf(dbgstr,"i=%d fstart=%d fend=%d\n",i,fstart,fend); - Trace(dbgstr); -#endif - out_pix=out->data+out_start+i*out_step; - - in_pix=in->data+in_start+fstart*in_step; - - f_data=f->data-f->start+2*fstart-i; - - for (j=fstart;j<=fend;j++,in_pix+=in_step,f_data+=2) - { - *out_pix += (*f_data) * (*in_pix); -#ifdef TRACE - sprintf(dbgstr," j=%2d in: %4.2f filter: %4.2f [%4d] [%4d] opt : %4.2f %4.2f\n", - j, - in->data[in_start+j*in_step], - f->data[2*j-i-f->start], - in_start+j*in_step, - 2*j-i-f->start, - *in_pix, *f_data); - Trace(dbgstr); -#endif - } - } - - Leaving; - return 1; -} - -int filter_periodical(Image in, int in_start, int in_len, int in_step, - Image out, int out_start, int out_len, int out_step, - Filter f) -{ - int i,i2,j; - Pixel *out_pix, *in_pix, *f_data; - int fstart,fend; - int istart; - int ipix_len; - - Entering; - PreCondition(out_len == in_len/2,"out_len != in_len/2 !!!"); - -/* convolution: out[i]=sum_{j=start}^{end} (in[2*i-j]*f[j]) - - boundaries: image in [in_start ... in_start + in_len-1] - image out [out_start ... out_start + out_len-1] - filter f [0..f->len-1] = [f->start .. f->end] -*/ - - ipix_len=in_len*in_step; - - for (i=0;istart; - fend=f->end; - - istart=(i2-fstart); - istart=MOD(istart,in_len); - -#ifdef TRACE - sprintf(dbgstr,"i=%d istart=%d\n",i,istart); - Trace(dbgstr); -#endif - - out_pix=out->data+out_start+i*out_step; - - in_pix=in->data+in_start+istart*in_step; - - f_data=f->data; - - for (j=fstart;j<=fend;j++,f_data++) - { - *out_pix += (*f_data) * (*in_pix); -#ifdef TRACE - - sprintf(dbgstr," j=%2d in: %4.2f filter: %4.2f [%4d] [%4d] opt : %4.2f %4.2f\n", - j, - in->data[in_start+in_step*((i2-j+in_len)%in_len)], - f->data[j-f->start], - in_start+in_step*((i2-j+in_len)%in_len), - j-f->start, - *in_pix, *f_data); - Trace(dbgstr); -#endif - in_pix-=in_step; - istart--; - if (istart<0) - { - istart+=in_len; - in_pix+=ipix_len; - } - } - } - - Leaving; - return 1; -} - -int filter_inv_periodical(Image in, int in_start, int in_len, int in_step, - Image out, int out_start, int out_len, int out_step, - Filter f) -{ - int i,j; - Pixel *out_pix, *in_pix, *f_data; - int fstart,fend; /* Source interval */ - int istart; - int ipix_len; - Entering; - PreCondition(out_len == in_len*2,"out_len != in_len*2 !!!"); - -/* convolution: out[i]=sum_{j=start}^{end} (f[2*j-i]*in[j]) - - boundaries: image in [in_start ... in_start + in_len-1] - image out [out_start ... out_start + out_len-1] - filter f [0..f->len-1] = [f->start .. f->end] -*/ - - ipix_len=in_len*in_step; - - for (i=0;istart+i); - fend=FLOOR_HALF(f->end+i); - - istart=MOD(fstart,in_len); -#ifdef TRACE - sprintf(dbgstr,"i=%d fstart=%d fend=%d istart=%d\n",i,fstart,fend,istart); - Trace(dbgstr); -#endif - out_pix=out->data+out_start+i*out_step; - - in_pix=in->data+in_start+istart*in_step; - - f_data=f->data-f->start+2*fstart-i; - - for (j=fstart;j<=fend;j++,f_data+=2) - { - *out_pix += (*f_data) * (*in_pix); -#ifdef TRACE - sprintf(dbgstr," j=%2d in: %4.2f filter: %4.2f [%4d] [%4d] opt : %4.2f %4.2f\n", - j, - in->data[in_start+(j % in_len)*in_step], - f->data[2*j-i-f->start], - in_start+(j%in_len)*in_step, - 2*j-i-f->start, - *in_pix, *f_data); - Trace(dbgstr); -#endif - in_pix+=in_step; - istart++; - if (istart>=in_len) - { - istart-=in_len; - in_pix-=ipix_len; - } - } - } - - Leaving; - return 1; -} - -int filter_mirror(Image in, int in_start, int in_len, int in_step, - Image out, int out_start, int out_len, int out_step, - Filter f) -{ - int i,i2,j; - Pixel *out_pix, *in_pix, *f_data; - int fstart,fend; - int in_pos; - - Entering; - PreCondition(out_len == in_len/2,"out_len != in_len/2 !!!"); - -/* convolution: out[i]=sum_{j=start}^{end} (in[2*i-j]*f[j]) - - boundaries: image in [in_start ... in_start + in_len-1] - image out [out_start ... out_start + out_len-1] - filter f [0..f->len-1] = [f->start .. f->end] -*/ - - in_pix=in->data+in_start; - - for (i=0;istart; - fend=f->end; - - out_pix=out->data+out_start+i*out_step; - - f_data=f->data; - - for (j=fstart;j<=fend;j++) - { - in_pos=(i2-j); - if (in_pos<0) - { - in_pos=-in_pos; - if (in_pos>=in_len) continue; - } - if (in_pos>=in_len) - { - in_pos=2*in_len-2-in_pos; - if (in_pos<0) continue; - } - *out_pix += (f_data[j-fstart]) * (in_pix[in_pos*in_step]); - } - } - - Leaving; - return 1; -} - -int filter_inv_mirror(Image in, int in_start, int in_len, int in_step, - Image out, int out_start, int out_len, int out_step, - Filter f) -{ - int i,j; - Pixel *out_pix, *in_pix; - int fstart,fend; /* Source interval */ - int in_pos; - - Entering; - PreCondition(out_len == in_len*2,"out_len != in_len*2 !!!"); - -/* convolution: out[i]=sum_{j=start}^{end} (f[2*j-i]*in[j]) - - boundaries: image in [in_start ... in_start + in_len-1] - image out [out_start ... out_start + out_len-1] - filter f [0..f->len-1] = [f->start .. f->end] -*/ - - /*fprintf(stderr,"inv started\n");*/ - for (i=0;istart+i); - fend=FLOOR_HALF(f->end+i); - - out_pix=out->data+out_start+i*out_step; - - in_pix=in->data+in_start; - -/* - printf("in: %4d - %4d flt: %4d - %4d [%s]\n",fstart,fend,2*fstart-i,2*fend-i, - (2*fstart-istart || 2*fend-i>f->end) ? "error":"ok"); -*/ - /*fprintf(stderr,"inv[%d]\n",i);*/ - for (j=fstart;j<=fend;j++) - { - in_pos=j; - if (in_pos<0) - { - if (f->hipass) - in_pos=-in_pos-1; - else - in_pos=-in_pos; - if (in_pos>=in_len) continue; - } - if (in_pos>=in_len) - { - if (f->hipass) - in_pos=2*in_len-2-in_pos; - else - in_pos=2*in_len-1-in_pos; - if (in_pos<0) continue; - } - /*fprintf(stderr,"out+= %7.2f * %7.2f = %7.2f\n",f->data[2*j-i-f->start],in_pix[in_pos*in_step],f->data[2*j-i-f->start]*in_pix[in_pos*in_step]);*/ - *out_pix += f->data[2*j-i-f->start] * (in_pix[in_pos*in_step]); - } - } - - Leaving; - return 1; -} - -#define MAX_LINE 256 - -#define skip_blank(str) { while(isspace(*(str))) (str)++; } - -static int get_next_line(FILE *f, char *c) -{ - char *str,string[200]; - int len; - do - { - str=string; - if (!fgets(str,200,f)) - { - Trace("get_next_line: eof\n"); - goto error; - } - len=strlen(str); - while (len>=1 && isspace(str[len-1])) str[--len]=0; - while (isspace(*str)) str++; - } - while (strlen(str)==0 || *str=='#'); - strcpy(c,str); - return 1; -error: - return 0; -} - -static int next_line_str(FILE *f, char *tag, char *out) -{ - char str[MAX_LINE],*t_str; - - if (!get_next_line(f,str)) goto error; - t_str=strtok(str," "); - if (!t_str || strcmp(t_str,tag)) goto error; - t_str=strtok(NULL,"\n"); - if (!t_str) goto error; - skip_blank(t_str); - - strcpy(out,t_str); - return 1; -error: - return 0; -} - -static int next_line_str_alloc(FILE *f, char *tag, char **out) -{ - char str[MAX_LINE]; - if (!next_line_str(f,tag,str)) goto error; - - *out=malloc(strlen(str)+1); - strcpy(*out,str); - - return 1; -error: - return 0; -} - -static int next_line_int(FILE *f, char *tag, int *out) -{ - char str[MAX_LINE]; - if (next_line_str(f,tag,str) && sscanf(str,"%d",out)==1) - return 1; - else - return 0; -} - - -static Filter read_filter(FILE *f) -{ - char str[MAX_LINE]; - Filter filter; - int i; - - Entering; - - filter=calloc(1,sizeof(struct FilterStruct)); - - if (!next_line_str(f,"Type",str)) goto error1; - - if (!strcmp(str,"nosymm")) - { - filter->type=FTNoSymm; - } - else if (!strcmp(str,"symm")) - { - filter->type=FTSymm; - } - else if (!strcmp(str,"antisymm")) - { - filter->type=FTAntiSymm; - } - else - goto error1; - - if (!next_line_int(f,"Length",&(filter->len))) goto error1; - if (!next_line_int(f,"Start",&(filter->start))) goto error1; - if (!next_line_int(f,"End",&(filter->end))) goto error1; - - if ((filter->end-filter->start+1!=filter->len)) - { - Trace("error: len != end-start+1\n"); - goto error1; - } - - filter->data=calloc(filter->len,sizeof(Pixel)); - - for (i=0;ilen;i++) - { - if (!get_next_line(f,str)) goto error2; - if (!string_to_pixel(str,filter->data+i)) - { - Trace("error: invalid filter-value\n"); - goto error2; - } - } - if (!get_next_line(f,str)) goto error2; - if (*str!='}') - { - Trace("error: '}' not found\n"); - goto error2; - } - - Leaving; - return filter; - -error2: - free(filter->data); - -error1: - free(filter); - - LeavingErr; - return NULL; - -} - -static FilterGH read_filter_gh(FILE *f) -{ - char str[MAX_LINE]; - FilterGH fgh; - Filter filter; - int i,max; - - Entering; - - fgh=calloc(1,sizeof(struct FilterGHStruct)); - - if (!next_line_str_alloc(f,"Name",&(fgh->name))) - { - Trace("error: 'Name' tag not found\n"); - goto error1; - } - - if (!next_line_str(f,"Type",str)) - { - Trace("error: 'Type' tag not found\n"); - goto error1; - } - - if (!strcmp(str,"orthogonal")) - { - fgh->type=FTOrtho; - max=2; - } - else if (!strcmp(str,"biorthogonal")) - { - fgh->type=FTBiOrtho; - max=4; - } - else if (!strcmp(str,"other")) - { - fgh->type=FTOther; - max=4; - } - else - { - Trace("error: expecting 'orthogonal', 'biorthogonal' or 'other' type-tag\n"); - goto error1; - } - - for (i=0;ihipass = !(i&1); - switch(i) - { - case 0: fgh->g=filter; break; - case 1: fgh->h=filter; break; - case 2: fgh->gi=filter; break; - case 3: fgh->hi=filter; break; - } - } - if (!get_next_line(f,str)) goto error2; - if (*str!='}') - { - Trace("error: '}' not found\n"); - goto error2; - } - - Leaving; - return fgh; - -error2: - if (fgh->g) free(fgh->g); - if (fgh->h) free(fgh->h); - if (fgh->gi) free(fgh->gi); - if (fgh->hi) free(fgh->hi); - -error1: - free(fgh); - - LeavingErr; - return NULL; -} - - -AllFilters load_filters(char *name) -{ - FILE *f; - char str[MAX_LINE]; - AllFilters a; - FilterGH fgh; - - Entering; - - PreCondition(name!=NULL,"name=NULL!"); - - f=fopen(name,"rt"); - if (!f) - { - Trace("error: fopen failed\n"); - goto error1; - } - - a=calloc(1,sizeof(struct AllFilterStruct)); - a->count=0; - - while (get_next_line(f,str)) - { - if (*str=='{') - { - fgh=read_filter_gh(f); - if (!fgh) - { - Trace("error: read_filter returned NULL\n"); - goto error2; - } - if (a->count) - a->filter=realloc(a->filter,(a->count+1)*sizeof(FilterGH)); - else - a->filter=malloc(sizeof(FilterGH)); - (a->filter)[a->count]=fgh; - a->count++; - } - else - { - Trace("error: '{' not found\n"); - goto error2; - } - } - - fclose(f); - - Leaving; - return a; - -error2: - fclose(f); -error1: - - LeavingErr; - return 0; -} - -#define doubletree_min 32 -#define best_basis_min 8 - -static int convolute_lines(Image output,Image input,Filter flt,enum FilterMethod method); -static int convolute_rows(Image output,Image input,Filter flt,enum FilterMethod method); -static int decomposition(Image t_img,Image coarse,Image horizontal,Image vertical, - Image diagonal,Filter g,Filter h,enum FilterMethod method); -static int compute_best(Image_tree tree,int level,int max_level,FilterGH *flt, - enum FilterMethod method,enum Information_Cost cost,double epsilon); -static double compute_entropy(Image img,enum Information_Cost cost,double epsilon); -static void compute_levels(Image_tree tree,double *entropies,enum Information_Cost cost,double epsilon); -static void free_levels(Image_tree tree,int best); - -static Pixel sumationq(Image img); -static Pixel normq(Image_tree tree); -static Pixel sumation_down(Image_tree tree, Pixel normq); -static Pixel compute_non_additive(Image_tree tree,int size,enum Information_Cost cost,double -epsilon,int down); - -/************************************************************************/ -/* Functionname: wavelettransform */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* original: Image that should be transformed */ -/* level: transform down to level */ -/* flt: transform with filters flt[0..level] */ -/* method: method of filtering */ -/* -------------------------------------------------------------------- */ -/* Description: Carries out the wavelettransform */ -/* */ -/************************************************************************/ -Image_tree wavelettransform(Image original,int level,FilterGH *flt,enum FilterMethod method) -{ int i,width,height,min,max_level,e; - Image coarsei,horizontali,verticali,diagonali,tempi; - Image_tree ret_tree,temp_tree; - - width=original->width; - height=original->height; - - tempi=new_image(width,height); - if(!tempi) goto error; - - copy_into_image(tempi,original,0,0); - - ret_tree=new_image_tree(); - if(!ret_tree) goto error; - - temp_tree=ret_tree; - ret_tree->level=0; - - min=original->width; - if (original->heightheight; - max_level=log(min)/log(2)-2; - if (max_levelimage=tempi; - return ret_tree; - } - - /* decomposition */ - - for (i=0;ig,flt[i]->h,method); - if (!e) return NULL; - - temp_tree->coarse=new_image_tree(); - temp_tree->horizontal=new_image_tree(); - temp_tree->vertical=new_image_tree(); - temp_tree->diagonal=new_image_tree(); - - temp_tree->coarse->level=i+1; - temp_tree->horizontal->level=i+1; - temp_tree->vertical->level=i+1; - temp_tree->diagonal->level=i+1; - - temp_tree->horizontal->image=horizontali; - temp_tree->vertical->image=verticali; - temp_tree->diagonal->image=diagonali; - free_image(tempi); - - if (i!=(level-1)) - { - tempi=new_image(width,height); - copy_into_image(tempi,coarsei,0,0); - free_image(coarsei); - /*if i=level coarsei is inserted into the image tree - so we should not free coarsei on level-1*/ - } - - temp_tree=temp_tree->coarse; - - } - - temp_tree->image=coarsei; - return ret_tree; - - error: - err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); - return NULL; -} - -static Image_tree wavelettransform__wp(Image original, int current_level, int level, FilterGH *flt, enum FilterMethod method) -{ - int i, width, height, min, max_level, e; - Image coarse_image,horizontal_image,vertical_image,diagonal_image,temp_image; - Image_tree return_tree, temp_tree; - - width = original->width; - height = original->height; - - temp_image = new_image(width, height); - if (!temp_image) goto error; - - copy_into_image(temp_image, original, 0, 0); - - temp_tree = return_tree = new_image_tree(); - if (!return_tree) goto error; - - temp_tree->level = current_level; - - min = original->width; - if (original->height < min) min = original->height; - max_level = log(min) / log(2) - 2; - if (max_level < level) level = max_level; - - if (current_level >= level) { - return_tree->image = temp_image; - return return_tree; - } - - for (i = current_level; i < level; i++) { - width = (width + 1) / 2; - height = (height + 1) / 2; - - coarse_image = new_image(width, height); - horizontal_image = new_image(width, height); - vertical_image = new_image(width, height); - diagonal_image = new_image(width, height); - - if (!coarse_image || !horizontal_image || - !vertical_image || !diagonal_image) goto error; - - e = decomposition(temp_image, coarse_image, horizontal_image, - vertical_image, diagonal_image, - flt[i]->g, flt[i]->h, method); - if (!e) return NULL; - - temp_tree->coarse = new_image_tree(); - temp_tree->coarse->level = i+1; - temp_tree->horizontal = wavelettransform__wp(horizontal_image, i+1, level, flt, method); - temp_tree->vertical = wavelettransform__wp(vertical_image, i+1, level, flt, method); - temp_tree->diagonal = wavelettransform__wp(diagonal_image, i+1, level, flt, method); - - free_image(horizontal_image); - free_image(vertical_image); - free_image(diagonal_image); - free_image(temp_image); - - if (i != (level - 1)) { - temp_image = new_image(width, height); - copy_into_image(temp_image, coarse_image, 0, 0); - free_image(coarse_image); - } - - temp_tree = temp_tree->coarse; - } - - temp_tree->image = coarse_image; - return return_tree; - - error: - err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); - return NULL; -} - -Image_tree wavelettransform_wp(Image original, int level, FilterGH *flt, enum FilterMethod method) { - return wavelettransform__wp(original, 0, level, flt, method); -} - - -/************************************************************************/ -/* Functionname: best_basis */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* original: Image to be transformed */ -/* level: best basis selection down to this level */ -/* flt: transform with filters flt[0..level] */ -/* method: transform with filter method */ -/* cost: carry best basis selection out with this costfunc */ -/* epsilon: limit for threshold method */ -/* -------------------------------------------------------------------- */ -/* Description: carries best basis and near best basis selection */ -/* out */ -/************************************************************************/ -Image_tree best_basis(Image original,int level,FilterGH *flt, - enum FilterMethod method,enum Information_Cost cost,double epsilon) - -{ Image_tree tree; - Image img; - int min,max_level; - - tree=new_image_tree(); - if(!tree) goto error; - - img=new_image(original->width,original->height); - if(!img) goto error; - - copy_into_image(img,original,0,0); - - tree->image=img; - - min=original->width; - if (original->heightheight; - max_level=log10((float) min/best_basis_min)/log10(2); - if (max_level>level) max_level=level; - - compute_best(tree,0,max_level,flt,method,cost,epsilon); - - if (!tree->image) free(img); - - return tree; - - error: - err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); - return NULL; - -} -/************************************************************************/ -/* Functionname: best_level_selection */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* original: Image that should be transformed */ -/* maxlevel: transform down to level */ -/* flt: transform with filters flt[0..level] */ -/* method: transform with filter method */ -/* cost: carry best basis selection out with this costfunc */ -/* epsilon: limit for threshold method */ -/* -------------------------------------------------------------------- */ -/* Description: Carries out the best level selection */ -/* */ -/************************************************************************/ -Image_tree best_level(Image original,int maxlevel,int *bestlevel,FilterGH *flt,enum FilterMethod method, - enum Information_Cost cost,double epsilon) -{ Image_tree tree; - Image img; - double *entropies,min; - int best=0,i,e; - - img=new_image(original->width,original->height); - copy_into_image(img,original,0,0); - - tree=new_image_tree(); - tree->image=img; - - entropies=(double *)calloc(maxlevel+1,sizeof(double)); - if(!entropies) goto error; - - /* decompose down to maxlevel */ - e=decompose_all(tree,maxlevel,flt,method,cost,epsilon); - if (!e) return NULL; - - /* compute costs of each level and store it in entropies array*/ - compute_levels(tree,entropies,cost,epsilon); - - min=entropies[0]; - for (i=1;i<=maxlevel;i++) - { - if (entropies[i]level=level; - - /* non additive cost function*/ - if (cost>=shanon) - { - tree->entropy=compute_non_additive(tree,tree->image->size,cost,epsilon,0); - } - /*additive cost function*/ - else tree->entropy=compute_entropy(tree->image,cost,epsilon); - - if (levelimage->width+1)/2; - height=(tree->image->height+1)/2; - - tree->coarse=new_image_tree(); - tree->horizontal=new_image_tree(); - tree->vertical=new_image_tree(); - tree->diagonal=new_image_tree(); - - coarse=new_image(width,height); - horizontal=new_image(width,height); - vertical=new_image(width,height); - diagonal=new_image(width,height); - if(!coarse||!vertical||!horizontal||!diagonal) goto error; - - e=decomposition(tree->image,coarse,horizontal,vertical,diagonal,flt[0]->g,flt[0]->h,method); - if (!e) return 0; - - tree->coarse->image=coarse; - tree->horizontal->image=horizontal; - tree->vertical->image=vertical; - tree->diagonal->image=diagonal; - - e=compute_best(tree->coarse,level+1,max_level,flt+1,method,cost,epsilon); - e=compute_best(tree->horizontal,level+1,max_level,flt+1,method,cost,epsilon); - e=compute_best(tree->vertical,level+1,max_level,flt+1,method,cost,epsilon); - e=compute_best(tree->diagonal,level+1,max_level,flt+1,method,cost,epsilon); - if (!e) return 0; - - /*going back in recursion*/ - - if (cost>=shanon) { - sum=compute_non_additive(tree,tree->image->size,cost,epsilon,1); - } - else sum=(tree->coarse->entropy)+(tree->horizontal->entropy) - +(tree->vertical->entropy)+(tree->diagonal->entropy); - - if (tree->entropy>sum) - { - tree->entropy=sum; - free_image(tree->image); /* take down tree */ - tree->image=NULL; - - } - else - { /* delete the tree downwards */ - free_image_tree(tree->coarse); - free_image_tree(tree->horizontal); - free_image_tree(tree->vertical); - free_image_tree(tree->diagonal); - - tree->coarse=tree->vertical=tree->horizontal=tree->diagonal=NULL; - } - } - - return 1; - - error: - err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); - return 0; - -} - -/************************************************************************/ -/* Functionname: decompose_all */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* tree: Image tree to be decomposed */ -/* maxlevel: decompose down to level */ -/* flt: transform with filters flt[0..maxlevel] */ -/* method: transform with filter method */ -/* cost: cost function for entropy computing */ -/* epsilon: limit for threshold method */ -/* -------------------------------------------------------------------- */ -/* Description: whole decompositing down to maxlevel */ -/* The original image must be in tree->image */ -/************************************************************************/ -int decompose_all(Image_tree tree,int maxlevel,FilterGH *flt,enum FilterMethod method, - enum Information_Cost cost,double epsilon) -{ - Image original,coarse,horizontal,vertical,diagonal; - int e,width,height,level; - - if (tree->levelcoarse=new_image_tree(); - tree->horizontal=new_image_tree(); - tree->vertical=new_image_tree(); - tree->diagonal=new_image_tree(); - - original=tree->image; - width=(original->width+1)/2; - height=(original->height+1)/2; - level=tree->level; - - coarse=new_image(width,height); - horizontal=new_image(width,height); - vertical=new_image(width,height); - diagonal=new_image(width,height); - if(!coarse||!vertical||!horizontal||!diagonal) goto error; - - - e=decomposition(tree->image,coarse,horizontal,vertical,diagonal,flt[0]->g,flt[0]->h,method); - if (!e) return 0; - - tree->coarse->image=coarse; - tree->horizontal->image=horizontal; - tree->vertical->image=vertical; - tree->diagonal->image=diagonal; - - tree->coarse->entropy=compute_entropy(coarse,cost,epsilon); - tree->horizontal->entropy=compute_entropy(horizontal,cost,epsilon); - tree->vertical->entropy=compute_entropy(vertical,cost,epsilon); - tree->diagonal->entropy=compute_entropy(diagonal,cost,epsilon); - - tree->coarse->level=tree->horizontal->level= - tree->vertical->level=tree->diagonal->level=level+1; - - e=decompose_all(tree->coarse,maxlevel,flt+1,method,cost,epsilon); - e=decompose_all(tree->horizontal,maxlevel,flt+1,method,cost,epsilon); - e=decompose_all(tree->vertical,maxlevel,flt+1,method,cost,epsilon); - e=decompose_all(tree->diagonal,maxlevel,flt+1,method,cost,epsilon); - if (!e) return 0; - - } - - return 1; - - error: - err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); - return 0; -} - -/************************************************************************/ -/* Functionname: compute_levels */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* tree: Image tree where the entropy should be computed */ -/* entropies : array for entropy */ -/* cost: carry best basis selection out with this costfunc */ -/* epsilon: limit for threshold method */ -/* -------------------------------------------------------------------- */ -/* Description: Compute the entropies of all decomposition levels */ -/************************************************************************/ -static void compute_levels(Image_tree tree,double *entropies,enum Information_Cost cost,double epsilon) -{ - if (tree->image){ - entropies[tree->level]+=compute_entropy(tree->image,cost,epsilon); - } - if (tree->coarse) compute_levels(tree->coarse,entropies,cost,epsilon); - if (tree->horizontal) compute_levels(tree->horizontal,entropies,cost,epsilon); - if (tree->vertical) compute_levels(tree->vertical,entropies,cost,epsilon); - if (tree->diagonal) compute_levels(tree->diagonal,entropies,cost,epsilon); - -} - -/************************************************************************/ -/* Functionname: free_levels */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* tree: Image tree which should be cleaned */ -/* best: best level */ -/* -------------------------------------------------------------------- */ -/* Description: clean the image tree except the best level */ -/************************************************************************/ -static void free_levels(Image_tree tree,int best) -{ - if (tree->levelimage); - tree->image=NULL; - free_levels(tree->coarse,best); - free_levels(tree->horizontal,best); - free_levels(tree->vertical,best); - free_levels(tree->diagonal,best); - } - else - { - if (tree->coarse) - { - free_image_tree(tree->coarse); - free_image_tree(tree->horizontal); - free_image_tree(tree->vertical); - free_image_tree(tree->diagonal); - tree->coarse=tree->horizontal=tree->vertical=tree->diagonal=NULL; - } - } -} - -/************************************************************************/ -/* Functionname: decompose_to_level */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* original: original image */ -/* level: decompose to level */ -/* flt: decompos with filters[0..level] */ -/* method: transform with filter method */ -/* -------------------------------------------------------------------- */ -/* Description: Decomposes an image to an certain level and stores */ -/* only this level in the returned quadtree */ -/************************************************************************/ -Image_tree decompose_to_level(Image original,int level,FilterGH *flt,enum FilterMethod method) -{ Image_tree tree; - int e; - - tree=new_image_tree(); - tree->image=original; - - e=decompose_all(tree,level,flt,method,entropy,1); - if (!e) return NULL; - - free_levels(tree,level); - - return tree; - -} - -/************************************************************************/ -/* Functionname: decomposition */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* t_img: Image which should be decomposed */ -/* coarse,horizontal,vertical,diagonal: */ -/* decomposed images */ -/* method: transform with filter method */ -/* g,h: the transformation is carried out with these filters*/ -/* -------------------------------------------------------------------- */ -/* Description: This carries out one wavelettransformation */ -/* using waveletfilters. */ -/************************************************************************/ - -static int decomposition(Image t_img,Image coarse,Image horizontal,Image vertical, - Image diagonal,Filter g,Filter h,enum FilterMethod method) -{ Image temp1; - - /*coarse*/ - temp1=new_image(coarse->width,t_img->height); - if(!temp1) goto error; - convolute_lines(temp1,t_img,h,method); - convolute_rows(coarse,temp1,h,method); - - /*horizontal*/ - convolute_rows(horizontal,temp1,g,method); - free_image(temp1); - - /*vertical*/ - temp1=new_image(vertical->width,t_img->height); - if(!temp1) goto error; - convolute_lines(temp1,t_img,g,method); - convolute_rows(vertical,temp1,h,method); - - /*diagonal*/ - convolute_rows(diagonal,temp1,g,method); - free_image(temp1); - - return 1; - - error: - err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); - return 0; - -} - -/************************************************************************/ -/* Functionname: inv_decomposition */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* sum: reconstructed image */ -/* coarse,horizontal,vertical,diagonal: images to carry out*/ -/* the inverse transformation */ -/* flt_gh: transform with filters g and h */ -/* method: transform with filter method */ -/* -------------------------------------------------------------------- */ -/* Description: Carries out the wavelettransform */ -/* */ -/************************************************************************/ -static int inv_decomposition(Image sum,Image coarse,Image horizontal,Image vertical, - Image diagonal,FilterGH flt_gh,enum FilterMethod method) -{ Image temp1; - Filter g,h; - - if (flt_gh->type==FTOrtho) { - g=flt_gh->g; - h=flt_gh->h; - } - else { - g=flt_gh->gi; - h=flt_gh->hi; - } - - /*coarse*/ - temp1=new_image(coarse->width,sum->height); - if(!temp1) goto error; - convolute_rows(temp1,coarse,h,method); - - /*horizontal*/ - convolute_rows(temp1,horizontal,g,method); - convolute_lines(sum,temp1,h,method); - free_image(temp1); - - /*vertical*/ - temp1=new_image(vertical->width,sum->height); - if(!temp1) goto error; - convolute_rows(temp1,vertical,h,method); - - /*diagonal*/ - convolute_rows(temp1,diagonal,g,method); - convolute_lines(sum,temp1,g,method); - - free_image(temp1); - - return 1; - - error: - err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); - return 0; -} - -/************************************************************************/ -/* Functionname: build_image */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* quadtree: quadtree with decomposition information */ -/* width,height: image width and height */ -/* RETURN: returns the build up image */ -/* -------------------------------------------------------------------- */ -/* Description: builds up an image out of an Image_tree */ -/* */ -/************************************************************************/ -Image build_image(Image_tree quadtree,int width,int height) -{ Image ret_img,coarse,horizontal,vertical,diagonal; - - - ret_img=new_image(width,height); - if(!ret_img) goto error; - - width=(width+1)/2; - height=(height+1)/2; - - if (!(quadtree->image)) { - coarse=build_image(quadtree->coarse,width,height); - horizontal=build_image(quadtree->horizontal,width,height); - vertical=build_image(quadtree->vertical,width,height); - diagonal=build_image(quadtree->diagonal,width,height); - if (!coarse||!horizontal||!vertical||!diagonal) return NULL; - - copy_into_image(ret_img,coarse,0,0); - copy_into_image(ret_img,horizontal,width,0); - copy_into_image(ret_img,vertical,0,height); - copy_into_image(ret_img,diagonal,width,height); - - if (!quadtree->coarse->image) free_image(coarse); - if (!quadtree->horizontal->image) free_image(horizontal); - if (!quadtree->vertical->image) free_image(vertical); - if (!quadtree->diagonal->image) free_image(diagonal); - - return ret_img; - } - else return quadtree->image; - - error: - err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); - return NULL; -} - -/************************************************************************/ -/* Functionname: inv_transform */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* tree: tree with decomposition information */ -/* flt_gh: transform with filters g and h */ -/* method: transform with filter method */ -/* -------------------------------------------------------------------- */ -/* Description: Inverts the wavelettransform,best_basis,best_level */ -/* */ -/************************************************************************/ -Image inv_transform(Image_tree tree,FilterGH *flt, - enum FilterMethod method) - -{ int er,width,height; - Image ret_img,coarse,vertical,horizontal,diagonal; - - if (!tree->image) { - - coarse=inv_transform(tree->coarse,flt,method); - horizontal=inv_transform(tree->horizontal,flt,method); - vertical=inv_transform(tree->vertical,flt,method); - diagonal=inv_transform(tree->diagonal,flt,method); - if (!coarse||!horizontal||!vertical||!diagonal) return NULL; - - width=coarse->width+horizontal->width; - height=coarse->height+vertical->height; - - ret_img=new_image(width,height); - if(!ret_img) goto error; - - - if (tree->flag==0) /*if flag is set it is a doubletree tiling*/ - { -// er=inv_decomposition(ret_img,coarse,horizontal,vertical,diagonal,flt[1],method); - er=inv_decomposition(ret_img,coarse,horizontal,vertical,diagonal,flt[tree->level],method); - if (!er) return NULL; - } - else - { - copy_into_image(ret_img,coarse,0,0); - copy_into_image(ret_img,horizontal,coarse->width,0); - copy_into_image(ret_img,vertical,0,coarse->height); - copy_into_image(ret_img,diagonal,coarse->width,coarse->height); - } - - if (!tree->coarse->image) free_image(coarse); - if (!tree->horizontal->image) free_image(horizontal); - if (!tree->vertical->image) free_image(vertical); - if (!tree->diagonal->image) free_image(diagonal); - - return ret_img; - } - - else return tree->image; - - error: - err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); - return NULL; -} - -/************************************************************************/ -/* Functionname: find_deepest_level */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* -------------------------------------------------------------------- */ -/* Description: Finds the deepest possible level where width and */ -/* height can divided by two exactly. */ -/************************************************************************/ -int find_deepest_level(int width,int height) -{ - int level=0,w=width,h=height; - - while ( !((w%2)||(h%2))) - { - w=w/2; - h=h/2; - level++; - } - - return level-1; - -} - -/************************************************************************/ -/* Functionname: convolute_lines */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* output: output image of wavelettransformation */ -/* input: input image for decomposition */ -/* flt: transform with filter flt */ -/* method: transform with filter method */ -/* -------------------------------------------------------------------- */ -/* Description: Carries out the wavelettransform for all lines of */ -/* the input image */ -/************************************************************************/ -static int convolute_lines(Image output,Image input,Filter flt,enum FilterMethod method) -/*Convolute the lines with filter*/ -{ int i; - - for (i=0;iheight;i++) { - switch(method) { - case cutoff: - filter_cutoff(input,input->width*i,input->width,1, - output,output->width*i,output->width,1,flt); - break; - case inv_cutoff: - filter_inv_cutoff(input,input->width*i,input->width,1, - output,output->width*i,output->width,1,flt); - break; - case periodical: - filter_periodical(input,input->width*i,input->width,1, - output,output->width*i,output->width,1,flt); - break; - case inv_periodical: - filter_inv_periodical(input,input->width*i,input->width,1, - output,output->width*i,output->width,1,flt); - break; - case mirror: - filter_mirror(input,input->width*i,input->width,1, - output,output->width*i,output->width,1,flt); - break; - case inv_mirror: - filter_inv_mirror(input,input->width*i,input->width,1, - output,output->width*i,output->width,1,flt); - break; - - - } - } - - return 1; -} - -/************************************************************************/ -/* Functionname: convolute_rows */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* output: output image of wavelettransformation */ -/* input: input image for decomposition */ -/* flt: transform with filter flt */ -/* method: transform with filter method */ -/* -------------------------------------------------------------------- */ -/* Description: Carries out the wavelettransform for all rows of */ -/* the input image */ -/************************************************************************/ -static int convolute_rows(Image output,Image input,Filter flt,enum FilterMethod method) -/*Convolute the rows with filter*/ -{ int i; - - for (i=0;iwidth;i++) - { - switch (method) - { - case cutoff: - filter_cutoff(input,i,input->height,input->width, - output,i,output->height,output->width,flt); - break; - case inv_cutoff: - filter_inv_cutoff(input,i,input->height,input->width, - output,i,output->height,output->width,flt); - break; - case periodical: - filter_periodical(input,i,input->height,input->width, - output,i,output->height,output->width,flt); - break; - case inv_periodical: - filter_inv_periodical(input,i,input->height,input->width, - output,i,output->height,output->width,flt); - break; - case mirror: - filter_mirror(input,i,input->height,input->width, - output,i,output->height,output->width,flt); - break; - case inv_mirror: - filter_inv_mirror(input,i,input->height,input->width, - output,i,output->height,output->width,flt); - break; - - } - } - return 1; -} - -/************************************************************************/ -/* Functionname: sumationq */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* img: image to compute */ -/* -------------------------------------------------------------------- */ -/* Description: compute the sum of quadrats of all elements of */ -/* the input image */ -/************************************************************************/ -static Pixel sumationq(Image img) -{ Pixel sum=0; - int i; - - for (i=0;isize;i++) { - sum+=(*img->data+i)*(*img->data+i); - } - return sum; -} - -/************************************************************************/ -/* Functionname: normq */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* tree: tree to compute */ -/* -------------------------------------------------------------------- */ -/* Description: computes the quadratic norm over all images in */ -/* the input tree */ -/************************************************************************/ -static Pixel normq(Image_tree tree) -{ Pixel sum=0; - - if (tree->image) - { - sum=sumationq(tree->image); - } - else - { - if (tree->coarse) sum+=normq(tree->coarse); - if (tree->horizontal) sum+=normq(tree->horizontal); - if (tree->vertical) sum+=normq(tree->vertical); - if (tree->diagonal) sum+=normq(tree->diagonal); - } - - return sum; -} - -/************************************************************************/ -/* Functionname: sumation_down */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* tree: tree to compute */ -/* normq: norm of the images in the tree */ -/* -------------------------------------------------------------------- */ -/* Description: computes the Entropy over all (string aded) images */ -/* in the input tree */ -/************************************************************************/ -static Pixel sumation_down(Image_tree tree, Pixel normq) -{ Pixel sum=0,p; - int i; - Image img; - Pixel *data; - - if (tree->image) - { - img=tree->image; - data=img->data; - for (i=0;isize;i++,data++) - { - if (*data!=0) - { - p=(*data)*(*data)/normq; - sum+=p*log(1/p); - } - } - } - else - { - if (tree->coarse) sum+=sumation_down(tree->coarse,normq); - if (tree->horizontal) sum+=sumation_down(tree->horizontal,normq); - if (tree->vertical) sum+=sumation_down(tree->vertical,normq); - if (tree->diagonal) sum+=sumation_down(tree->diagonal,normq); - } - - return sum; -} - -/************************************************************************/ -/* Functionname: comp */ -/* -------------------------------------------------------------------- */ -/* Description: used for quicksort for decreasing order */ -/************************************************************************/ -int comp(const Pixel *x,const Pixel *y) -{ - if (*x<*y) return 1; - else if (*x==*y) return 0; - else return -1; -} - -/************************************************************************/ -/* Functionname: recarea */ -/* tree: Image tree to compute */ -/* list: target list */ -/* list_size: actual size of the list */ -/* -------------------------------------------------------------------- */ -/* Description: copies all elements within the tree into an list */ -/************************************************************************/ -static void recarea(Image_tree tree,Pixel *list,int *list_size) -{ Image img; - - if (tree->image) - { - img=tree->image; - memcpy(list+(*list_size),img->data,img->size*sizeof(Pixel)); - *list_size+=img->size; - } - else - { - if (tree->coarse) recarea(tree->coarse,list,list_size); - if (tree->horizontal) recarea(tree->horizontal,list,list_size); - if (tree->vertical) recarea(tree->vertical,list,list_size); - if (tree->diagonal) recarea(tree->diagonal,list,list_size); - } - -} - -static void abs_list(Pixel *list,int list_size) -{ - int i; - - for (i=0;imax) max=wlp; - } - - free(list); - - return max; - - error: - err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); - return 0; -} - -static Pixel comp_number(Image_tree tree,int size,int p,double f) -{ Pixel sum=0,*list,min=MAXDOUBLE,norm,npf,normf; - int *list_size=0,k; - - list_size=(int *)malloc(sizeof(int)); - if (!list_size) goto error; - *list_size=0; - - list=(Pixel *)calloc(size,sizeof(Pixel)); - if (!list) goto error; - recarea(tree,list,list_size); - abs_list(list,*list_size); - - qsort(list,*list_size, sizeof(Pixel), (int (*)(const void*, const void*)) comp); - - norm=sum_list(list,p,size); - normf=norm*f; - - for (k=0;kmaximum) maximum=x; - } - - free(list); - - return (1/(2*size)+maximum); - - error: - err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); - return 0; -} - -static Pixel compute_discrepancy(Image_tree tree,int size) -{ Pixel *list,min,max,factor,maximum=0,minimum=0,x; - int *list_size=0,k; - - list_size=(int *)malloc(sizeof(int)); - if (!list_size) goto error; - *list_size=0; - - list=(Pixel *)calloc(size,sizeof(Pixel)); - if (!list) goto error; - - recarea(tree,list,list_size); - - qsort(list,*list_size, sizeof(Pixel), (int (*)(const void*, const void*)) comp); - - min=list[0]; - max=list[size-1]; - factor=1/(max-min); - - /*scaling to [0,1]*/ - for (k=0;kmaximum) maximum=x; - else if (xdata; - - switch(cost) { - - case threshold: - for(i=0;isize;i++) - if (fabs(img->data[i])>epsilon) sum++; - break; - - case log_energy: - for(i=0;isize;i++,data++) { - x=(*data) * (*data); - if (x!=0) sum+=(x*log(1/x)); - } - break; - - case norml: - for(i=0;isize;i++,data++) { - x=fabs(*data); - sum+=x; - } - break; - - case norml2: - for(i=0;isize;i++,data++) { - x=(*data) * (*data); - sum+=x; - } - sum=pow(sum,0.5); - break; - - case entropy: - for(i=0;isize;i++,data++) { - x=(*data)*(*data); - if (x!=0) sum-=(x*log(x)); - } - break; - - case gauss_markov: - for(i=0;isize;i++) { - x=(img->data[i])*(img->data[i]); - if (x!=0) sum+=log(x*x); - } - break; - - } - - return sum; -} - -/************************************************************************/ -/* Functionname: compute_non_additive */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* tree: Image tree from which the entropy should be */ -/* computed */ -/* size : size of the image */ -/* cost: choosen costfunction */ -/* epsilon: limit for threshold method */ -/* down: decides if only the first image should be computed*/ -/* -------------------------------------------------------------------- */ -/* Description: computes entropy of an image */ -/************************************************************************/ -static Pixel compute_non_additive(Image_tree tree,int size,enum Information_Cost cost,double epsilon,int down) -{ Pixel sum=0,normx; - Image img=NULL; - - if (down) - { - img=tree->image; - tree->image=NULL; - } - switch (cost) - { - case shanon: - normx=normq(tree); - sum=-sumation_down(tree,normx); - - break; - case weak_l: - sum=weak_lp(tree,size,1,epsilon); - break; - case weak_lq: - sum=weak_lp(tree,size,2,epsilon); - break; - case compression_number: - sum=comp_number(tree,size,1,epsilon); - break; - case compression_numberq: - sum=comp_number(tree,size,2,epsilon); - break; - case compression_area: - sum=comp_area(tree,size,1,epsilon); - break; - case compression_areaq: - sum=comp_area(tree,size,2,epsilon); - break; - case discrepancy: - sum=compute_discrepancy(tree,size); - break; - case sdiscrepancy: - sum=compute_sdiscrepancy(tree,size); - break; - case concentration: - sum=compute_concentration(tree,size); - break; - - - } - - if (down) tree->image=img; - - return sum; -} - -int rec_double(Image_tree dtree,int level,FilterGH *flt,enum FilterMethod method,enum Information_Cost cost,double epsilon) - -{ int min,width,height; - double sum=0; - Image c,h,v,d; - - dtree->level=0; - - if (cost>=shanon) - { - dtree->entropy=compute_non_additive(dtree,dtree->image->size,cost,epsilon,0); - } - else dtree->entropy=compute_entropy(dtree->image,cost,epsilon); - - dtree->doubletree=best_basis(dtree->image,level,flt,method,cost,epsilon); - - min=dtree->image->width; - if (dtree->image->heightimage->height; - - if (doubletree_minimage->width+1)/2; - height=(dtree->image->height+1)/2; - - dtree->coarse=new_image_tree(); - dtree->horizontal=new_image_tree(); - dtree->vertical=new_image_tree(); - dtree->diagonal=new_image_tree(); - - c=new_image(width,height); - h=new_image(width,height); - v=new_image(width,height); - d=new_image(width,height); - if(!c||!h||!v||!d) goto error; - - - copy_part_of_image(c,dtree->image,0,0); - copy_part_of_image(h,dtree->image,width,0); - copy_part_of_image(v,dtree->image,0,height); - copy_part_of_image(d,dtree->image,width,height); - - dtree->coarse->image=c; - dtree->horizontal->image=h; - dtree->vertical->image=v; - dtree->diagonal->image=d; - - rec_double(dtree->coarse,level,flt,method,cost,epsilon); - rec_double(dtree->horizontal,level,flt,method,cost,epsilon); - rec_double(dtree->vertical,level,flt,method,cost,epsilon); - rec_double(dtree->diagonal,level,flt,method,cost,epsilon); - - /* going back in recursion*/ - - sum=dtree->coarse->entropy+dtree->horizontal->entropy+ - dtree->vertical->entropy+dtree->diagonal->entropy; - - if (sum>dtree->entropy) - { - /*take image*/ - - free_image_tree(dtree->coarse); - free_image_tree(dtree->horizontal); - free_image_tree(dtree->vertical); - free_image_tree(dtree->diagonal); - dtree->coarse=dtree->horizontal=dtree->vertical=dtree->diagonal=NULL; - } - else - { /*take tiling*/ - dtree->entropy=sum; - free_image(dtree->image); - dtree->image=NULL; - } - - if (dtree->entropy>dtree->doubletree->entropy) - { - /*take best basis tree*/ - - dtree->entropy=dtree->doubletree->entropy; - - if(dtree->coarse) free_image_tree(dtree->coarse); - if(dtree->horizontal) free_image_tree(dtree->horizontal); - if(dtree->vertical) free_image_tree(dtree->vertical); - if(dtree->diagonal) free_image_tree(dtree->diagonal); - - dtree->coarse=dtree->doubletree->coarse; - dtree->horizontal=dtree->doubletree->horizontal; - dtree->vertical=dtree->doubletree->vertical; - dtree->diagonal=dtree->doubletree->diagonal; - - free_image(dtree->image); - dtree->image=NULL; - free(dtree->doubletree); - dtree->doubletree=NULL; - - } - else - { - dtree->flag=1; - if(dtree->doubletree) free_image_tree(dtree->doubletree); - dtree->doubletree=NULL; - } - } - - return 1; - - error: - err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory)); - return 0; -} - -static void save_structur(Image_tree tree,FILE *fp,int pos) -{ - int shift,next_pos,max; - - if (tree->flag) - { - fprintf(fp,"%d ",pos); - - shift=pos-(pow(4,tree->level-1)-1)*4/3-1; - max=(int) ((pow(4,tree->level)-1)*4/3); - next_pos=max+4*shift+1; - if (tree->coarse) save_structur(tree->coarse,fp,next_pos); - if (tree->horizontal) save_structur(tree->horizontal,fp,next_pos+1); - if (tree->vertical) save_structur(tree->vertical,fp,next_pos+2); - if (tree->diagonal) save_structur(tree->diagonal,fp,next_pos+3); - } -} - -static int is_in_list(int *list,int len, int x) -{ - int i,found=0; - - for (i=0;iflag=1; - - shift=pos-(pow(4,tree->level-1)-1)*4/3-1; - max=(int) ((pow(4,tree->level)-1)*4/3); - next_pos=max+4*shift+1; - - write_flags(tree->coarse,list,len,next_pos); - write_flags(tree->horizontal,list,len,next_pos+1); - write_flags(tree->vertical,list,len,next_pos+2); - write_flags(tree->diagonal,list,len,next_pos+3); - } -} - -/************************************************************************/ -/* Functionname: err_simple_message */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* char *: string that contains information about an */ -/* error the user should know. */ -/* -------------------------------------------------------------------- */ -/* Description: */ -/* Prints error messages for the user. */ -/************************************************************************/ - -void err_SimpleMessage(char *message) -{ - fprintf(stderr,"%s\n",message); -} - -/************************************************************************/ -/* Functionname: err_get_message */ -/* -------------------------------------------------------------------- */ -/* Return value: Errormessage for this specific error. */ -/* Parameter: */ -/* Error err: Error whose errormessage should be returned */ -/* -------------------------------------------------------------------- */ -/* Description: */ -/************************************************************************/ -char * err_GetErrorMessage(Error err) -{ - - switch (err) - { - case Error_NotImplemented: - return "Sorry, this is not implemented yet. "; - break; - - case Error_AssertionFailed: - return "Sorry, an internal assertion was violated.\n" - "This action can not be completed. :-("; - break; - - case Error_NotEnoughMemory: - return "Sorry, there is not enough memory"; - break; - - case Error_Limitation: - return "Some limitation of the program exceeded"; - break; - - /* - FILES - */ - - case Error_CantOpenFile: - return "Could not open file"; - break; - - case Error_CantCreateFile: - return "Could not create file"; - break; - - case Error_CantCloseFile: - return "Could not close file"; - break; - - case Error_InternalError: - return "Sorry, an internal error occured.\n" - "This action can not be completed. :-("; - break; - - default: - return "Sorry, but an unknown error ocurred.\n" - "This action can not be completed. :-("; - break; - - - } -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wavelet.h --- a/Meerwald/wavelet.h Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,307 +0,0 @@ -#ifndef WAVELET_H - -#include - -extern char dbgstr[1000]; - -/* this are internal functions - don't use 'em! */ -void out_dbg_str(const char *str); -void start_trace(void); -void stop_trace(void); -void flush_trace_file(void); - -/* public functions / macros */ -#define StartTrace -#define StopTrace - -#define Trace(str) -#define TraceVar(str,var) - -#define Entering -#define Leaving -#define LeavingErr -#define FlushTrace - -#define Warning(str) - -#define PreCondition(exp,str) -#define PostCondition(exp,str) - -/* Note that if an error is added, an errormessage for this specific - error must also be added. Otherwise no appropriate message can - be displayed in an error window. ( Then "Unknown error ocurred" - will be displayed.) - The errormessage must be added to the case-construct in the - procedure err_GetErrorMessage -*/ - -typedef enum -{ - Error_NoError, /* No Error has happened. */ - Error_NotImplemented, /* A needed part has not (yet) been - implemented */ - Error_AssertionFailed, /* An assertion, pre- or postcondition failed. - Occurs only in buggy programs. */ - Error_NotEnoughMemory, /* We can't allocate the memory we need. */ - - Error_Limitation, /* Some limitation exceeded, e.g. a string - variable is too short */ - - - Error_CantOpenFile, /* The file cannot be opened */ - Error_CantCreateFile, - Error_CantWriteIntoFile, - Error_CantCloseFile, - Error_WrongFileFormat, - - Error_WidthOrHeightZero, - Error_CompressedZeroContent, - Error_OriginalZeroContent, - - Error_InternalError - -}Error; - - -/************************************************************************/ -/* Functionname: err_simple_message */ -/* -------------------------------------------------------------------- */ -/* Parameter: */ -/* char *: string that contains information about an */ -/* error the user should know. */ -/* -------------------------------------------------------------------- */ -/* Description: */ -/* Prints error messages for the user. */ -/************************************************************************/ -void err_SimpleMessage(char *message); - -/************************************************************************/ -/* Functionname: err_get_message */ -/* -------------------------------------------------------------------- */ -/* Return value: Errormessage for this specific error. */ -/* Parameter: */ -/* Error err: Error whose errormessage should be returned */ -/* -------------------------------------------------------------------- */ -/* Description: */ -/************************************************************************/ -char * err_GetErrorMessage(Error err); - -#include - -typedef double Pixel; - -typedef struct Image_struct { - Pixel *data; - int width,height; - - /* redundant, for our fun only :-) */ - Pixel min_val,max_val; /* range of pixel-values in data */ - /* [min_val..max_val] */ - int size; /* = width * height */ - int bpp; /* bits per pixel of original image */ - } *Image; - -typedef unsigned int IntPixel; - -typedef struct IntImage_struct { - IntPixel *data; - int width, height; - - /* redundant, for our fun only :-) */ - IntPixel min_val,max_val; /* range of values in data */ - /* [min_val..max_val] */ - int size; /* = width * height */ - int bpp; /* bits per pixel of original image */ - } *IntImage; - -typedef struct Image_tree_struct { - double entropy; - struct Image_tree_struct *coarse,*horizontal,*vertical,*diagonal,*doubletree; - Image image; - int level; - int flag; - - void *codec_data; - IntImage significance_map; - } *Image_tree; - -typedef struct Image_info_struct { - Pixel min,max,mean,var,rms; - } *Image_info; - -enum zigzag_direction {zigzag_up,zigzag_down,zigzag_right,zigzag_left}; - -typedef struct Zigzag_data_struct { - int x,y,w,h; - enum zigzag_direction dir; - } *Zigzag_data; - -#define get_intpixel(image,x,y) ( ((image)==NULL || \ - (x)<0 || (x)>=(image)->width || (y)<0 || (y)>=(image)->height) \ - ? (IntPixel) 0 : (image)->data[(x)+(y)*(image)->width]) - -#define set_intpixel(image,x,y,val) if (!((image)==NULL || \ - (x)<0 || (x)>=(image)->width || (y)<0 || (y)>=(image)->height)) \ - (image)->data[(x)+(y)*(image)->width]=(IntPixel) (val) - -#define get_pixel(image,x,y) ( ((image)==NULL || \ - (x)<0 || (x)>=(image)->width || (y)<0 || (y)>=(image)->height) \ - ? (Pixel) 0 : (image)->data[(x)+(y)*(image)->width]) - -#define set_pixel(image,x,y,val) if (!((image)==NULL || \ - (x)<0 || (x)>=(image)->width || (y)<0 || (y)>=(image)->height)) \ - (image)->data[(x)+(y)*(image)->width]=(Pixel) (val) - -#define get_pixel_adr(image,x,y) ( ((image)==NULL || \ - (x)<0 || (x)>=(image)->width || (y)<0 || (y)>=(image)->height) \ - ? (Pixel*) NULL : (image)->data+((x)+(y)*(image)->width)) - -/* functions: */ - -IntImage new_intimage(int width, int height); -IntImage load_intimage(char *file, int max_val); -void free_intimage(IntImage img); - -void clear_intimage(IntImage img); -void copy_into_intimage(IntImage img1,IntImage img2,int x,int y); -void copy_part_of_intimage(IntImage img1,IntImage img2,int x,int y); - -Image new_image(int width, int height); -void free_image(Image img); -void clear_image(Image img); -void copy_into_image(Image img1,Image img2,int x,int y); -void scale_image(Image img,int maximum); -void copy_part_of_image(Image img1,Image img2,int x,int y); - -void copy_part_of_image_into_image( - Image dest_img, int dest_x, int dest_y, - Image src_img, int src_x, int src_y, - int width, int height); - - -int string_to_pixel(char *str, Pixel *p); - -Image load_image(char *file, int max_val); -int save_image_P5(char *file, Image img); - -Image intimage_to_image(IntImage i); -IntImage image_to_intimage(Image i); - -Image_tree new_image_tree(); -void free_image_tree(Image_tree t); - -Image get_difference_image(Image image1, Image image2); - -void get_image_infos(Image image, Image_info info); - -void get_intimage_infos(IntImage image, IntPixel *min, IntPixel *max, Pixel *avg, Pixel *var); - -void init_zigzag(Zigzag_data zz, int width, int height); -void next_zigzag(Zigzag_data zz); -Image get_absolute_image_scaled(Image img); - -/* common macros */ - -#ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) -#endif - -#ifndef MAX -#define MAX(a,b) ((a)>(b)?(a):(b)) -#endif - -enum FilterType { FTNoSymm, FTSymm, FTAntiSymm}; - -typedef struct FilterStruct { - enum FilterType type; - int hipass; - Pixel * data; - int start,end; - - int len; - } *Filter; - -Filter new_filter(int size); - -int filter_cutoff(Image in, int in_start, int in_len, int in_step, - Image out, int out_start, int out_len, int out_step, - Filter f); - -int filter_inv_cutoff(Image in, int in_start, int in_len, int in_step, - Image out, int out_start, int out_len, int out_step, - Filter f); - -int filter_periodical(Image in, int in_start, int in_len, int in_step, - Image out, int out_start, int out_len, int out_step, - Filter f); - -int filter_inv_periodical(Image in, int in_start, int in_len, int in_step, - Image out, int out_start, int out_len, int out_step, - Filter f); - -int filter_mirror(Image in, int in_start, int in_len, int in_step, - Image out, int out_start, int out_len, int out_step, - Filter f); - -int filter_inv_mirror(Image in, int in_start, int in_len, int in_step, - Image out, int out_start, int out_len, int out_step, - Filter f); - -Pixel get_filter_center(Filter f); - -enum FilterGHType { FTOrtho, FTBiOrtho, FTOther}; - -typedef struct FilterGHStruct { - enum FilterGHType type; - Filter g, h, gi, hi; - char *name; - } *FilterGH; - -typedef struct AllFilterStruct { - FilterGH *filter; - int count; - } *AllFilters; - - -AllFilters load_filters(char *name); - -typedef struct SegmentsStruct { - int width,height; /* segment width & height*/ - int *data; - } *Segments; - -enum FilterMethod{cutoff,inv_cutoff,periodical,inv_periodical,mirror,inv_mirror}; - -enum Information_Cost{threshold,log_energy,entropy,norml,norml2,gauss_markov, - shanon,weak_l,weak_lq,compression_number,compression_numberq, - compression_area,compression_areaq,sdiscrepancy,discrepancy,concentration}; - -Image_tree wavelettransform(Image original,int level,FilterGH *flt,enum FilterMethod method); -Image_tree wavelettransform_wp(Image original,int level,FilterGH *flt,enum FilterMethod method); - -Image_tree best_basis(Image original,int level,FilterGH *flt, - enum FilterMethod method,enum Information_Cost cost,double epsilon); - -Image_tree best_level(Image original,int maxlevel,int *bestlevel,FilterGH *flt,enum FilterMethod method, - enum Information_Cost cost,double epsilon); - -Image build_image(Image_tree quadtree,int width,int height); - -Image inv_transform(Image_tree quadtree,FilterGH *flt, - enum FilterMethod method); - -Image inv_transform_wp(Image_tree quadtree,FilterGH *flt, - enum FilterMethod method); - -int rec_double(Image_tree dtree,int level,FilterGH *flt,enum FilterMethod method,enum Information_Cost cost,double epsilon); - -Image_tree decompose_to_level(Image original,int level,FilterGH *flt,enum FilterMethod method); - -int decompose_all(Image_tree tree,int maxlevel,FilterGH *flt,enum FilterMethod method, - enum Information_Cost cost,double epsilon); - -int find_deepest_level(int width,int height); - - -#define WAVELET_H -#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm.c --- a/Meerwald/wm.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -#include "wm.h" - -#ifdef __MINGW32_VERSION -void bzero(char *b, size_t length) { - int i; - for (i=0; i -#include -#include -#include -#include -#include -#include - -#if defined(MINGW) -#define M_PI 3.1415926536 -#define rint floor -#define MAXPATHLEN 255 -void bzero(char *b, size_t length); -#elif defined(LINUX) -#include -#include -#include -#include -#else -#error plattform not supported -#endif - -/* - * This macro is used to ensure correct rounding of integer values. - */ -#define ROUND(a) (((a) < 0) ? (int) ((a) - 0.5) : (int) ((a) + 0.5)) - -/* - * Macros to converts number of bytes to number of bits and vice verse - */ -#define NBITSTOBYTES(N) ((N & 7) ? (N >> 3) + 1 : N >> 3) -#define NBYTESTOBITS(N) (N << 3) - -#define GRAYRANGE(P) ((P > 255) ? 255 : (P < 0) ? 0 : P) -#define PIXELRANGE(P) ((P > 255) ? 255 : (P < 0) ? 0 : P) - -#ifndef sqr -#define sqr(X) ((X) * (X)) -#endif - -#ifndef MAX -#define MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) -#endif - -#ifndef MIN -#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) -#endif - -#ifdef NEED_STRCASECMP -#define strcasecmp stricmp -#endif - -#ifndef SIGN -#define SIGN(X) (((X) > 0) ? ((X) == 0 ? 0 : 1) : -1) -#endif - -void wm_init(); -void wm_init1(); -void wm_init2(); - -#endif diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_bruyn_d.c --- a/Meerwald/wm_bruyn_d.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,502 +0,0 @@ -#include "wm.h" -#include "signature.h" -#include "coord.h" -#include "gray.h" -#include "sort.h" -#include "bruyn_common.h" -#include "pgm.h" - -char *progname; - -// prints out program's parameters -void usage(void) { - fprintf(stderr, "usage: %s [-b n] [-h] [-k] [-n n] [-o file] [-pP n] [-q n] [-tT n] [-v n] -s file file\n", progname); - fprintf(stderr, "\t-b n\t\tblock size\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-k\t\tdisable block skipping\n"); - fprintf(stderr, "\t-n n\t\tnumber of signature bits to detect\n"); - fprintf(stderr, "\t-o file\t\textracted signature file\n"); - fprintf(stderr, "\t-p n\t\tpattern type for zone 1\n"); - fprintf(stderr, "\t-P n\t\tpattern type for zone 2\n"); - fprintf(stderr, "\t-q n\t\tsignature strength\n"); - fprintf(stderr, "\t-s file\t\tembedded signature\n"); - fprintf(stderr, "\t-t n\t\tthreshold for noise\n"); - fprintf(stderr, "\t-T n\t\tthreshold for slope\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - gray** image; - gray **block; - gray **zone; - gray **category1, **category2; - gray maxval; - double *slope; - int rows, cols, format; - int c; - int i, j; - int n; - int row; - int n_block; - - char signature_name[MAXPATHLEN]; - char input_name[MAXPATHLEN] = "(stdin)"; - char output_name[MAXPATHLEN] = "(stdout)"; - - double quality = 0.0; - double threshold_noise = 0.0; - double threshold_slope = 0.0; - int pattern1 = 0; - int pattern2 = 0; - int blocksize = 0; - int seed; - - int verbose = 0; - int skipping = 0; - - struct coords *coords; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init2(); - - // parse command line and set options - while ((c = getopt(argc, argv, "b:h?n:o:p:P:q:s:t:T:v:k")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'k': - skipping = 1; - break; - case 'n': - nbit_signature = atoi(optarg); - if (nbit_signature <= 0 || nbit_signature > NBITSIGNATURE) { - fprintf(stderr, "%s: invalid signature length %d\n", progname, nbit_signature); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'p': - pattern1 = atoi(optarg); - if (pattern1 <= 0 || pattern1 > NPATTERN) { - fprintf(stderr, "%s: pattern type out of range\n", progname); - exit(1); - } - break; - case 'P': - pattern2 = atoi(optarg); - if (pattern2 <= 0 || pattern2 > 3) { - fprintf(stderr, "%s: pattern type out of range\n", progname); - exit(1); - } - break; - case 'q': - quality = atof(optarg); - if (quality <= 0) { - fprintf(stderr, "%s: quality factor %f out of range\n", progname, quality); - } - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 't': - threshold_noise = atof(optarg); - if (threshold_noise <= 0) { - fprintf(stderr, "%s: noise threshold %f out of range\n", progname, threshold_noise); - } - break; - case 'T': - threshold_slope = atof(optarg); - if (threshold_slope <= 0) { - fprintf(stderr, "%s: slope threshold %f out of range\n", progname, threshold_slope); - } - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n",progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - // open input image file or read from stdin - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - // read signature file and set options - // command line options override signature file options - if (sig) { - char line[1024]; - fgets(line, sizeof(line), sig); - if (strspn(line, "BRSG") >= 4) { - if (nbit_signature == 0) - fscanf(sig, "%d\n", &nbit_signature); - else - fscanf(sig, "%*d\n"); - if (skipping == 0) - fscanf(sig, "%d\n", &skipping); - else - fscanf(sig, "%*d\n"); - if (pattern1 == 0) - fscanf(sig, "%d\n", &pattern1); - else - fscanf(sig, "%*d\n"); - if (pattern2 == 0) - fscanf(sig, "%d\n", &pattern2); - else - fscanf(sig, "%*d\n"); - if (quality == 0.0) - fscanf(sig, "%lf\n", &quality); - else - fscanf(sig, "%*f\n"); - if (threshold_noise == 0.0) - fscanf(sig, "%lf\n", &threshold_noise); - else - fscanf(sig, "%*f\n"); - if (threshold_slope == 0.0) - fscanf(sig, "%lf\n", &threshold_slope); - else - fscanf(sig, "%*f\n"); - if (blocksize == 0) - fscanf(sig, "%d\n", &blocksize); - else - fscanf(sig, "%*d\n"); - fscanf(sig, "%d\n", &seed); - srandom(seed); - n_signature = NBITSTOBYTES(nbit_signature); - fread(signature, sizeof(char), n_signature, sig); - init_signature_bits(); - fscanf(sig, "\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - if (pattern1 <= 0 || pattern2 <= 0 || pattern1 > NPATTERN || pattern2 > NPATTERN) { - fprintf(stderr, "%s: invalid pattern type specified\n", progname); - exit(1); - } - - // read dimensions of input image file - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - - // see if we can extract all signature bits - // we want at least half of the blocks untouched - if (((rows / blocksize) * (cols / blocksize)) < nbit_signature / 2) { - fprintf(stderr, "%s: image not large enough to contain %d bits of signature\n", progname, nbit_signature); - exit(1); - } - n_block = blocksize * blocksize; - - // allocate structure to remember which blocks we already touched, - // allow plenty of room to skip over blocks - if ((coords = alloc_coords(nbit_signature * 16)) == NULL) { - fprintf(stderr, "%s: unable to allocate memory\n", progname); - exit(1); - } - - // read in input image file - image = pgm_allocarray(cols, rows); - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - - fclose(in); - - row = 0; - - // allocate memory for one block - block = alloc_grays(blocksize, blocksize); - - // allocate memory for zone classification - zone = alloc_grays(blocksize, blocksize); - - // allocate memory for category classification - category1 = alloc_grays(blocksize, blocksize); - category2 = alloc_grays(blocksize, blocksize); - - // set up category classification array according to - // pattern type parameter - for (i = 0; i < blocksize; i++) - for (j = 0; j < blocksize; j++) { - category1[j][i] = lookup_pattern(pattern1, i, j); - category2[j][i] = lookup_pattern(pattern2, i, j); - } - - // allocate memory for slope calculation - slope = malloc(sizeof(double) * n_block); - - fprintf(out, "BRWM\n"); - fprintf(out, "%d\n", nbit_signature); - - // extract all the signature bits, one by one - n = 0; - while (n < nbit_signature) { - int xb; - int yb; - int blocktype; - double smax; - int alpha, beta_minus, beta_plus; - double mean_1A, mean_1B, mean_2A, mean_2B, mean_1, mean_2; - int n_1A, n_1B, n_2A, n_2B, n_1, n_2; - double sigma, sigma_1, sigma_2; - int zone1_ok, zone2_ok; - - // find an unused block randomly, depending on seed - do { - xb = random() % (cols / blocksize); - yb = random() % (rows / blocksize); - } while (add_coord(coords, xb, yb) < 0); - - // copy image block - fprintf(stderr, "XXX1 %d %d %d\n", xb*blocksize, yb*blocksize, blocksize); - copy_grays_to_block(block, image, xb * blocksize, yb * blocksize, blocksize, blocksize); - fprintf(stderr, "XXX2\n"); - - if (verbose > 0) - fprintf(stderr, "detecting bit #%d in block at (%d/%d)\n", n, xb * blocksize, yb * blocksize); - - // sort luminance values in block to represent increasing function F - sort_grays(block[0], n_block); - - // calculate slopes of F and determine smax, the max. slope of F - // the index where smax occures is called alpha - alpha = 0; - smax = 0.0; - for (i = 0; i < n_block - 1; i++) { - slope[i] = block[0][i + 1] - block[0][i]; - if (slope[i] > smax) { - smax = slope[i]; - alpha = i; - } - } - slope[n_block - 1] = 0; - - // block type classification - blocktype = BLOCKTYPE_UNKNOWN; - - if (smax < threshold_noise) { - // block has noise contrast - beta_minus = beta_plus = alpha; - blocktype = BLOCKTYPE_NOISE; - } - else { - // block has progressive or hard contrast, let's find out... - - beta_minus = alpha - 1; - while (beta_minus >= 0 && smax - slope[beta_minus] <= threshold_slope) - beta_minus--; - - beta_plus = alpha + 1; - while (beta_plus < n_block && smax - slope[beta_plus] <= threshold_slope) - beta_plus++; - - if (beta_minus + 1 == alpha && beta_plus - 1 == alpha) - blocktype = BLOCKTYPE_HARD; - else - blocktype = BLOCKTYPE_PROGRESSIVE; - } - - if (verbose > 1) { - fprintf(stderr, "blocktype: %d\n", blocktype); - fprintf(stderr, "Smax = %lf, alpha = %d, beta- = %d, beta+ = %d\n", smax, alpha, beta_minus, beta_plus); - } - - // block pixel classification - for (i = 0; i < blocksize; i++) - for (j = 0; j < blocksize; j++) { - gray pixel = image[yb * blocksize + j][xb * blocksize + i]; - zone[j][i] = ZONE_VOID; - switch (blocktype) { - case BLOCKTYPE_PROGRESSIVE: - case BLOCKTYPE_HARD: - if (pixel < block[0][beta_minus]) - zone[j][i] = ZONE_1; - else if (pixel > block[0][beta_plus]) - zone[j][i] = ZONE_2; - break; - case BLOCKTYPE_NOISE: - if (pixel < block[0][n_block / 2]) - zone[j][i] = ZONE_1; - else if (pixel > block[0][n_block / 2]) - zone[j][i] = ZONE_2; - break; - default: - fprintf(stderr, "%s: invalid block type\n", progname); - break; - } - } - - // calculate mean values for zone/categories - mean_1A = mean_1B = mean_2A = mean_2B = mean_1 = mean_2 = 0.0; - n_1A = n_1B = n_2A = n_2B = n_1 = n_2 = 0; - for (i = 0; i < blocksize; i++) - for (j = 0; j < blocksize; j++) { - gray pixel = image[yb * blocksize + j][xb * blocksize + i]; - int pixel_zone = zone[j][i]; - int pixel_category = CATEGORY_VOID; - if (pixel_zone == ZONE_1) - pixel_category = category1[j][i]; - else if (pixel_zone == ZONE_2) - pixel_category = category2[j][i]; - - switch (pixel_zone | pixel_category) { - case CLASSIFICATION_1A: - n_1++; - n_1A++; - mean_1A += pixel; - mean_1 += pixel; - break; - case CLASSIFICATION_1B: - n_1++; - n_1B++; - mean_1B += pixel; - mean_1 += pixel; - break; - case CLASSIFICATION_2A: - n_2++; - n_2A++; - mean_2A += pixel; - mean_2 += pixel; - break; - case CLASSIFICATION_2B: - n_2++; - n_2B++; - mean_2B += pixel; - mean_2 += pixel; - break; - } - } - - if (n_1 && n_1A && n_1B) { - mean_1 /= (double) n_1; - mean_1A /= (double) n_1A; - mean_1B /= (double) n_1B; - zone1_ok = 1; - } - else { - mean_1 = mean_1A = mean_1B = 0.0; - zone1_ok = 0; - if (verbose > 0) - fprintf(stderr, "zone 1 unusable\n"); - } - - if (n_2 && n_2A && n_2B) { - mean_2 /= (double) n_2; - mean_2A /= (double) n_2A; - mean_2B /= (double) n_2B; - zone2_ok = 1; - } - else { - mean_2 = mean_2A = mean_2B = 0.0; - zone2_ok = 0; - if (verbose > 0) - fprintf(stderr, "zone 2 unusable\n"); - } - - // bit extraction - if (zone1_ok && zone2_ok) { - sigma_1 = mean_1A - mean_1B; - sigma_2 = mean_2A - mean_2B; - - if (verbose > 2) { - fprintf(stderr, "m_1A = %lf, m_1B = %lf\n", mean_1A, mean_1B); - fprintf(stderr, "m_2A = %lf, m_2B = %lf\n", mean_2A, mean_2B); - fprintf(stderr, "sigma1 = %lf, sigma2 = %lf\n", sigma_1, sigma_2); - } - -#define EPSILON 0.001 - if (fabs(sigma_1 * sigma_2) < EPSILON) { - // case 3 - sigma = MAX(fabs(sigma_1), fabs(sigma_2)); - set_signature_bit(n, sigma > 0.0); - if (verbose > 0) - fprintf(stderr, "case 3, bit #%d = %d\n", n, sigma > 0.0); - } - else if (sigma_1 * sigma_2 > 0.0) { - // case 1 - set_signature_bit(n, sigma_1 > 0.0); - if (verbose > 0) - fprintf(stderr, "case 1, bit #%d = %d\n", n, sigma_1 > 0.0); - } - else if (sigma_1 * sigma_2 < 0.0) { - // case 2 - sigma = (double) (n_1A + n_1B) * sigma_1 + (double) (n_2A + n_2B) * sigma_2; - set_signature_bit(n, sigma > 0.0); - if (verbose > 0) - fprintf(stderr, "case 2, bit #%d = %d\n", n, sigma > 0.0); - } - } - else if (zone1_ok) { - set_signature_bit(n, mean_1A > mean_1B); - if (verbose > 0) - fprintf(stderr, "case 4, bit #%d = %d\n", n, mean_1A > mean_1B); - } - else if (zone2_ok) { - set_signature_bit(n, mean_2A > mean_2B); - if (verbose > 0) - fprintf(stderr, "case 5, bit #%d = %d\n", n, mean_2A > mean_2B); - } - else { - // pathological case - can it ever happen? - if (verbose > 0) - fprintf(stderr, "block skipped\n"); - if (!skipping) continue; - } - - n++; - } - - free_grays(category2); - free_grays(category1); - free_grays(zone); - free_grays(block); - - // write extracted signature - - fwrite(signature, sizeof(char), n_signature, out); - fclose(out); - - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_bruyn_e.c --- a/Meerwald/wm_bruyn_e.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,549 +0,0 @@ -#include "wm.h" -#include "signature.h" -#include "coord.h" -#include "gray.h" -#include "sort.h" -#include "bruyn_common.h" -#include "pgm.h" - -char *progname; - -// prints out program's parameters -void usage(void) { - fprintf(stderr, "usage: %s [-b n] [-h] [-k] [-n n] [-o file] [-pP n] [-q n] [-tT n] [-v n] -s file file\n", progname); - fprintf(stderr, "\t-b n\t\tblock size\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-k\t\tdisable block skipping\n"); - fprintf(stderr, "\t-n n\t\tnumber of signature bits to embed\n"); - fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); - fprintf(stderr, "\t-p n\t\tpattern type for zone 1\n"); - fprintf(stderr, "\t-P n\t\tpattern type for zone 2\n"); - fprintf(stderr, "\t-q n\t\tsignature strength\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - fprintf(stderr, "\t-t n\t\tthreshold for noise\n"); - fprintf(stderr, "\t-T n\t\tthreshold for slope\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - gray** image; - gray **block; - gray **zone; - gray **category1, **category2; - gray maxval; - double *slope; - int rows, cols, format; - int c; - int i, j; - int n; - int row; - int n_block; - int skipping = 0; - - char signature_name[MAXPATHLEN]; - char input_name[MAXPATHLEN] = "(stdin)"; - char output_name[MAXPATHLEN] = "(stdout)"; - - double quality = 0.0; - double threshold_noise = 0.0; - double threshold_slope = 0.0; - int pattern1 = 0; - int pattern2 = 0; - int blocksize = 0; - int seed; - - int verbose = 0; - - struct coords *coords; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init(); - - // parse command line and set options - while ((c = getopt(argc, argv, "b:h?n:o:p:P:q:s:t:T:v:k")) != EOF) { - switch (c) { - case 'k': - skipping = 1; - break; - case 'h': - case '?': - usage(); - break; - case 'n': - nbit_signature = atoi(optarg); - if (nbit_signature <= 0 || nbit_signature > NBITSIGNATURE) { - fprintf(stderr, "%s: invalid signature length %d\n", progname, nbit_signature); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'p': - pattern1 = atoi(optarg); - if (pattern1 <= 0 || pattern1 > NPATTERN) { - fprintf(stderr, "%s: pattern type out of range\n", progname); - exit(1); - } - break; - case 'P': - pattern2 = atoi(optarg); - if (pattern2 <= 0 || pattern2 > 3) { - fprintf(stderr, "%s: pattern type out of range\n", progname); - exit(1); - } - break; - case 'q': - quality = atof(optarg); - if (quality <= 0) { - fprintf(stderr, "%s: quality factor %f out of range\n", progname, quality); - } - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 't': - threshold_noise = atof(optarg); - if (threshold_noise <= 0) { - fprintf(stderr, "%s: noise threshold %f out of range\n", progname, threshold_noise); - } - break; - case 'T': - threshold_slope = atof(optarg); - if (threshold_slope <= 0) { - fprintf(stderr, "%s: slope threshold %f out of range\n", progname, threshold_slope); - } - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n",progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - // open input image file or read from stdin - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - // read signature file and set options - // command line options override signature file options - if (sig) { - char line[128]; - fgets(line, sizeof(line), sig); - if (strspn(line, "BRSG") >= 4) { - if (nbit_signature == 0) - fscanf(sig, "%d\n", &nbit_signature); - else - fscanf(sig, "%*d\n"); - if (skipping == 0) - fscanf(sig, "%d\n", &skipping); - else - fscanf(sig, "%*d\n"); - if (pattern1 == 0) - fscanf(sig, "%d\n", &pattern1); - else - fscanf(sig, "%*d\n"); - if (pattern2 == 0) - fscanf(sig, "%d\n", &pattern2); - else - fscanf(sig, "%*d\n"); - if (quality == 0.0) - fscanf(sig, "%lf\n", &quality); - else - fscanf(sig, "%*f\n"); - if (threshold_noise == 0.0) - fscanf(sig, "%lf\n", &threshold_noise); - else - fscanf(sig, "%*f\n"); - if (threshold_slope == 0.0) - fscanf(sig, "%lf\n", &threshold_slope); - else - fscanf(sig, "%*f\n"); - if (blocksize == 0) - fscanf(sig, "%d\n", &blocksize); - else - fscanf(sig, "%*d\n"); - fscanf(sig, "%d\n", &seed); - srandom(seed); - fread(signature, sizeof(char), NBITSTOBYTES(nbit_signature), sig); - fscanf(sig, "\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - if (pattern1 <= 0 || pattern2 <= 0 || pattern1 > NPATTERN || pattern2 > NPATTERN) { - fprintf(stderr, "%s: invalid pattern type specified\n", progname); - exit(1); - } - - // read dimensions of input image file - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - - // see if we can embed all signature bits - // we want at least half of the blocks untouched - if (((rows / blocksize) * (cols / blocksize)) < nbit_signature / 2) { - fprintf(stderr, "%s: image not large enough to embed %d bits of signature\n", progname, nbit_signature); - exit(1); - } - n_block = blocksize * blocksize; - - // allocate structure to remember which blocks we already touched, - // allow plenty of room to skip over blocks - if ((coords = alloc_coords(nbit_signature * 16)) == NULL) { - fprintf(stderr, "%s: unable to allocate memory\n", progname); - exit(1); - } - - // read in input image file - image = pgm_allocarray(cols, rows); - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - - fclose(in); - - row = 0; - - // allocate memory for one block - block = alloc_grays(blocksize, blocksize); - - // allocate memory for zone classification - zone = alloc_grays(blocksize, blocksize); - - // allocate memory for category classification - category1 = alloc_grays(blocksize, blocksize); - category2 = alloc_grays(blocksize, blocksize); - - // set up category classification array according to - // pattern type parameter - for (i = 0; i < blocksize; i++) - for (j = 0; j < blocksize; j++) { - category1[j][i] = lookup_pattern(pattern1, i, j); - category2[j][i] = lookup_pattern(pattern2, i, j); - } - - // allocate memory for slope calculation - slope = malloc(sizeof(double) * n_block); - - // embed all the signature bits, one by one - n = 0; - while (n < nbit_signature) { - int xb; - int yb; - int blocktype; - double smax; - int alpha, beta_minus, beta_plus; - double mean_1A, mean_1B, mean_2A, mean_2B, mean_1, mean_2; - double mean__1A, mean__1B, mean__2A, mean__2B; - int n_1A, n_1B, n_2A, n_2B, n_1, n_2; - int var_1A, var_1B, var_2A, var_2B; - int zone1_ok, zone2_ok; - - // find an unused block randomly, depending on seed - do { - xb = random() % (cols / blocksize); - yb = random() % (rows / blocksize); - } while (add_coord(coords, xb, yb) < 0); - - // copy image block - copy_grays_to_block(block, image, xb * blocksize, yb * blocksize, blocksize, blocksize); - - if (verbose > 0) - fprintf(stderr, "embedding bit #%d (= %d) in block at (%d/%d)\n", n, get_signature_bit(n), xb * blocksize, yb * blocksize); - if (verbose > 8) { - print_grays(image, xb * blocksize, yb * blocksize, blocksize, blocksize); - fprintf(stderr, "\n"); - } - - // sort luminance values in block to represent increasing function F - sort_grays(block[0], n_block); - - if (verbose > 8) { - print_grays(block, 0, 0, blocksize, blocksize); - fprintf(stderr, "\n"); - } - - // calculate slopes of F and determine smax, the max. slope of F - // the index where smax occures is called alpha - alpha = 0; - smax = 0.0; - for (i = 0; i < n_block - 1; i++) { - slope[i] = block[0][i + 1] - block[0][i]; - if (slope[i] > smax) { - smax = slope[i]; - alpha = i; - } - } - slope[n_block - 1] = 0; - - // block type classification - blocktype = BLOCKTYPE_UNKNOWN; - - if (smax < threshold_noise) { - // block has noise contrast - - blocktype = BLOCKTYPE_NOISE; - beta_minus = beta_plus = alpha; - } - else { - // block has progressive or hard contrast, let's find out... - - beta_minus = alpha - 1; - while (beta_minus >= 0 && smax - slope[beta_minus] <= threshold_slope) - beta_minus--; - - beta_plus = alpha + 1; - while (beta_plus < n_block && smax - slope[beta_plus] <= threshold_slope) - beta_plus++; - - if (beta_minus + 1 == alpha && beta_plus - 1 == alpha) - blocktype = BLOCKTYPE_HARD; - else - blocktype = BLOCKTYPE_PROGRESSIVE; - } - - if (verbose > 1) { - fprintf(stderr, "blocktype: %d\n", blocktype); - fprintf(stderr, "Smax = %lf, alpha = %d, beta- = %d, beta+ = %d\n", smax, alpha, beta_minus, beta_plus); - } - - // block pixel classification - for (i = 0; i < blocksize; i++) - for (j = 0; j < blocksize; j++) { - gray pixel = image[yb * blocksize + j][xb * blocksize + i]; - zone[j][i] = ZONE_VOID; - switch (blocktype) { - case BLOCKTYPE_PROGRESSIVE: - case BLOCKTYPE_HARD: - if (pixel < block[0][beta_minus]) - zone[j][i] = ZONE_1; - else if (pixel > block[0][beta_plus]) - zone[j][i] = ZONE_2; - break; - case BLOCKTYPE_NOISE: - if (pixel < block[0][n_block / 2]) - zone[j][i] = ZONE_1; - else if (pixel > block[0][n_block / 2]) - zone[j][i] = ZONE_2; - break; - default: - fprintf(stderr, "%s: invalid block type\n", progname); - break; - } - } - - if (verbose > 8) { - print_grays(zone, 0, 0, blocksize, blocksize); - fprintf(stderr, "\n"); - } - - // calculate mean values for zone/categories - mean_1A = mean_1B = mean_2A = mean_2B = mean_1 = mean_2 = 0.0; - mean__1A = mean__1B = mean__2A = mean__2B = 0.0; - n_1A = n_1B = n_2A = n_2B = n_1 = n_2 = 0; - for (i = 0; i < blocksize; i++) - for (j = 0; j < blocksize; j++) { - gray pixel = image[yb * blocksize + j][xb * blocksize + i]; - int pixel_zone = zone[j][i]; - int pixel_category = CATEGORY_VOID; - if (pixel_zone == ZONE_1) - pixel_category = category1[j][i]; - else if (pixel_zone == ZONE_2) - pixel_category = category2[j][i]; - - switch (pixel_zone | pixel_category) { - case CLASSIFICATION_1A: - n_1++; - n_1A++; - mean_1A += pixel; - mean_1 += pixel; - break; - case CLASSIFICATION_1B: - n_1++; - n_1B++; - mean_1B += pixel; - mean_1 += pixel; - break; - case CLASSIFICATION_2A: - n_2++; - n_2A++; - mean_2A += pixel; - mean_2 += pixel; - break; - case CLASSIFICATION_2B: - n_2++; - n_2B++; - mean_2B += pixel; - mean_2 += pixel; - break; - } - } - - if (n_1 && n_1A && n_1B) { - mean_1 /= (double) n_1; - mean_1A /= (double) n_1A; - mean_1B /= (double) n_1B; - zone1_ok = 1; - } - else { - mean_1 = mean_1A = mean_1B = 0.0; - zone1_ok = 0; - if (verbose > 0) - fprintf(stderr, "zone 1 unusable\n"); - } - - if (n_2 && n_2A && n_2B) { - mean_2 /= (double) n_2; - mean_2A /= (double) n_2A; - mean_2B /= (double) n_2B; - zone2_ok = 1; - } - else { - mean_2 = mean_2A = mean_2B = 0.0; - zone2_ok = 0; - if (verbose > 0) - fprintf(stderr, "zone 2 unusable\n"); - } - - if (!skipping && !zone1_ok && !zone2_ok) { - // pathological case - can it ever happen? - if (verbose > 0) - fprintf(stderr, "block skipped\n"); - continue; - } - - if (verbose > 2) { - fprintf(stderr, "m_1 = %lf, m_1A = %lf, m_1B = %lf\n", mean_1, mean_1A, mean_1B); - fprintf(stderr, "m_2 = %lf, m_2A = %lf, m_2B = %lf\n", mean_2, mean_2A, mean_2B); - } - - // calculate new mean values required by embedding rule - if (get_signature_bit(n)) { - if (zone1_ok) { - mean__1A = (mean_1 * (double) (n_1A + n_1B) + (double) n_1B * quality) / (double) (n_1A + n_1B); - mean__1B = mean__1A - quality; - } - if (zone2_ok) { - mean__2A = (mean_2 * (double) (n_2A + n_2B) + (double) n_2B * quality) / (double) (n_2A + n_2B); - mean__2B = mean__2A - quality; - } - } - else { - if (zone1_ok) { - mean__1A = (mean_1 * (double) (n_1A + n_1B) - (double) n_1B * quality) / (double) (n_1A + n_1B); - mean__1B = mean__1A + quality; - } - if (zone2_ok) { - mean__2A = (mean_2 * (double) (n_2A + n_2B) - (double) n_2B * quality) / (double) (n_2A + n_2B); - mean__2B = mean__2A + quality; - } - } - - // calculate luminance variations - if (zone1_ok) { - var_1A = rint(mean__1A - mean_1A); - var_1B = rint(mean__1B - mean_1B); - } - else var_1A = var_1B = 0; - - if (zone2_ok) { - var_2A = rint(mean__2A - mean_2A); - var_2B = rint(mean__2B - mean_2B); - } - else var_2A = var_2B = 0; - - if (verbose > 2) { - if (zone1_ok) - fprintf(stderr, "m*_1A = %lf, m*_1B = %lf\n", mean__1A, mean__1B); - if (zone2_ok) - fprintf(stderr, "m*_2A = %lf, m*_2B = %lf\n", mean__2A, mean__2B); - fprintf(stderr, "var %d %d %d %d\n", var_1A, var_1B, var_2A, var_2B); - } - - // apply luminance variations to image pixels - for (i = 0; i < blocksize; i++) - for (j = 0; j < blocksize; j++) { - int pixel = image[yb * blocksize + j][xb * blocksize + i]; - int pixel_zone = zone[j][i]; - int pixel_category = CATEGORY_VOID; - if (pixel_zone == ZONE_1) - pixel_category = category1[j][i]; - else if (pixel_zone == ZONE_2) - pixel_category = category2[j][i]; - - switch (pixel_zone | pixel_category) { - case CLASSIFICATION_1A: - pixel = GRAYRANGE(pixel + var_1A); - break; - case CLASSIFICATION_1B: - pixel = GRAYRANGE(pixel + var_1B); - break; - case CLASSIFICATION_2A: - pixel = GRAYRANGE(pixel + var_2A); - break; - case CLASSIFICATION_2B: - pixel = GRAYRANGE(pixel + var_2B); - break; - } - image[yb * blocksize + j][xb * blocksize + i] = pixel; - } - - n++; - } - - free_grays(category2); - free_grays(category1); - free_grays(zone); - free_grays(block); - - // write output image dimensions to output file - pgm_writepgminit(out, cols, rows, maxval, 0); - - // write output image - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, image[row], cols, maxval, 0); - - fclose(out); - - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_corvi_d.1 --- a/Meerwald/wm_corvi_d.1 Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,173 +0,0 @@ -.\" -.\" wm_corvi_d.1 - the *roff document processor man page source -.\" -.TH wm_corvi_d 1 "98/07/29" "Watermarking, Version 1.0" -.SH NAME -.B wm_corvi_d -\- a program to extract a signature from the DWT residue of a watermarked -image -.SH SYNOPSIS -.B wm_corvi_d -[ -.BI \-a \ number -] -[ -.BI \-e \ number -] -[ -.BI \-f \ number -] -[ -.BI \-F \ ffile -] -[ -.BI \-g \ number -] -[ -.B \-h -] -[ -.BI \-i \ ifile -] -.br -[ -.BI \-n \ number -] -[ -.BI \-o \ ofile -] -[ -.BI \-q \ number -] -[ -.BI \-v \ number -] -.BI \-s \ sfile -.I file -.SH DESCRIPTION -.B wm_corvi_d -is a program to extract a signature from the DWT residue of -a watermarked image -.I file. -The -.B cmp_corvi_sig -program is used to test the extracted signature against the original signature. -The input image is in PGM (portable graymap) format. -.PP -If -.I file -or -.I ofile -is not specified, then standard input or standard output is -used. -.PP -.B gen_corvi_sig -is used to generate a signature file, -.B wm_corvi_e -embeds the signature into an image. -.PP -Please refer to Marco Corvi's paper "Wavelet-based image watermarking -for copyright protection", to get an idea about the algorithm. -.PP -.SH OPTIONS -.TP -.BI \-a \ number -Alpha factor that determines embedding strength of the signature. -Allows to override the setting in the signature file. -.TP -.BI \-e \ number -Wavelet filtering method for forward transformation. -Allows to override the setting in the signature file. -.TP -.BI \-f \ number -Wavelet filter number. -Allows to override the setting in the signature file. -.TP -.BI \-F \ ffile -Wavelet filter definition file. -Allows to override the setting in the signature file. -.TP -.BI \-g \ number -Wavelet filtering method for inverse transformation. -Allows to override the setting in the signature file. -.TP -.B \-h -Print a help message. -.TP -.BI \-i \ ifile -The original image. -.TP -.BI \-o \ ofile -Output watermarked image to the specified -.I file -instead of standard output. -.TP -.BI \-q \ number -Set quantization/quality factor. Overrides the setting in the signature -file. -.TP -.BI \-v \ number -Verbosity level. Default value: 0. -.TP -.BI \-s \ sfile -The signature file to embed into the input image. See -.B gen_corvi_sig -(1) for a description of the file format. Mandatory parameter. -.IR file -Input image in PGM format to sign (watermark). Default: standard input. -.TP -.I file -The watermarked image in PGM format. -.PP -.SH OUTPUT -The signed (watermarked) image in PGM format is written to standard output -or, optionally, to -.I ofile. -.PP -The output file has the following format: -.TP -.B CVSG -Magic to identify file type. -.TP -.I number -The length of the signature in bits. -.TP -.I number -The alpha factor (embedding strength). -.TP -.I number -The quantization/quality factor. -.TP -.I number -The wavelet forward transform filtering method. -.TP -.I number -The wavelet filter number. -.TP -.I file -The wavelet filter definition file name. -.TP -.I number -The wavelet inverse transform filtering method. -.TP -.I numbers -The actual normal distributed signature values, one per line. -.PP -.SH AUTHOR -Peter Meerwald -Email bug reports to pmeerw@cosy.sbg.ac.at. -.SH AVAILABILITY -The most recent released version of -.B wm_corvi_d -is always available -at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the -directory /pub/people/pmeerw/Watermarking. -.SH "SEE ALSO" -.BR gen_corvi_sig -(1), -.BR wm_corvi_e -(1), -.BR wm_corvi_s -(1), -.BR cmp_corvi_sig -(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_corvi_d.c --- a/Meerwald/wm_corvi_d.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,310 +0,0 @@ -#include "dwt.h" -#include "pgm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-h] [-n n] [-o file] [-s file] [-v n] -i file file\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-i file\t\toriginal image file\n"); - fprintf(stderr, "\t-n n\t\twatermark length\n"); - fprintf(stderr, "\t-o file\t\textracted signature file\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *orig = NULL; - FILE *sig = NULL; - - gray **input_image; - gray **orig_image; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char orig_name[MAXPATHLEN]; - - int c; - int n = 0; - int method = -1; - int filter = 0; - char filter_name[MAXPATHLEN] = ""; - - int level = 0; - double alpha = 0.0; - - int in_rows, in_cols, in_format; - gray in_maxval; - int orig_rows, orig_cols, orig_format; - gray orig_maxval; - int rows, cols; - int row, col; - - Image_tree input_dwts; - Image_tree orig_dwts; - - int verbose = 0; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init2(); - - while ((c = getopt(argc, argv, "a:e:f:F:h?i:n:o:s:v:")) != EOF) { - switch (c) { - case 'a': - alpha = atof(optarg); - if (alpha <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'i': - if ((orig = fopen(optarg, "rb")) == NULL) { - fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); - exit(1); - } - strcpy(orig_name, optarg); - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 1000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (!orig) { - fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); - exit(1); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "CVSG") >= 4) { - fscanf(sig, "%d\n", &n); - if (alpha == 0.0) - fscanf(sig, "%lf\n", &alpha); - else - fscanf(sig, "%*f\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); - pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); - - if (in_cols != orig_cols || in_rows != orig_rows) { - fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); - exit(1); - } - - cols = in_cols; - rows = in_rows; - - input_image = pgm_allocarray(in_cols, in_rows); - - orig_image = pgm_allocarray(orig_cols, orig_rows); - - for (row = 0; row < in_rows; row++) - pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); - - fclose(in); - - for (row = 0; row < orig_rows; row++) - pgm_readpgmrow(orig, orig_image[row], orig_cols, orig_maxval, orig_format); - - fclose(orig); - - level = 0; - row = rows; - col = cols; - while (n < row * col / 4.0 && row >= 2 && col >= 2) { - row /= 2; - col /= 2; - level++; - } - - if (verbose >= 2) { - fprintf(stderr, "%s: extracting from coarse image (x %d/y %d) at level %d\n", progname, col, row, level); - } - - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - input_dwts = fdwt(input_image); - orig_dwts = fdwt(orig_image); - - fprintf(out, "CVWM\n"); - fprintf(out, "%d\n", n); - - { - Image_tree p = input_dwts; - Image_tree q = orig_dwts; - Image input_img; - Image orig_img; - double input_med; - double orig_med; - double input_var; - double orig_var; - - while (!p->image) - p = p->coarse; - - while (!q->image) - q = q->coarse; - - input_img = p->image; - orig_img = q->image; - - input_med = 0.0; - for (row = 0; row < input_img->height; row++) - for (col = 0; col < input_img->width; col++) - input_med += get_pixel(input_img, col, row); - input_med /= (double) (input_img->height * input_img->width); - - orig_med = 0.0; - for (row = 0; row < orig_img->height; row++) - for (col = 0; col < orig_img->width; col++) - orig_med += get_pixel(orig_img, col, row); - orig_med /= (double) (orig_img->height * orig_img->width); - - orig_var = 0.0; - for (row = 0; row < orig_img->height; row++) - for (col = 0; col < orig_img->width; col++) - orig_var += sqr(get_pixel(orig_img, col, row) - orig_med); - orig_var /= (double) (orig_img->height * orig_img->width); - - input_var = 0.0; - for (row = 0; row < input_img->height; row++) - for (col = 0; col < input_img->width; col++) - input_var += sqr(get_pixel(input_img, col, row) - input_med); - input_var /= (double) (input_img->height * input_img->width); - - orig_var = sqrt(orig_var); - input_var = sqrt(input_var); - - if (verbose > 3) - fprintf(stderr, "%s: mean (input, orig): %f, %f,\n variance (input, orig): %f, %f\n", progname, input_med, orig_med, input_var, orig_var); - - row = 0; - col = 0; - while (n > 0) { - double input_pix; - double orig_pix; - double x; - - input_pix = get_pixel(input_img, col, row); - orig_pix = get_pixel(orig_img, col, row); - - x = (((input_pix - input_med) * (orig_var / input_var) - (orig_pix / orig_med)) / (orig_pix - orig_med) - 1.0) / alpha; - - fprintf(out, "%f\n", x); - - if (++col == orig_img->width) { col = 0; row++; } - n--; - } - } - - fclose(out); - - pgm_freearray(input_image, rows); - pgm_freearray(orig_image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_corvi_e.1 --- a/Meerwald/wm_corvi_e.1 Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +0,0 @@ -.\" -.\" wm_corvi_e.1 - the *roff document processor man page source -.\" -.TH wm_corvi_e 1 "98/07/29" "Watermarking, Version 1.0" -.SH NAME -.B wm_corvi_e -\- a program to embed a signature in the DWT residue of an image -.SH SYNOPSIS -.B wm_corvi_e -[ -.BI \-a \ number -] -[ -.BI \-e \ number -] -[ -.BI \-f \ number -] -[ -.BI \-F \ ffile -] -[ -.BI \-g \ number -] -[ -.B \-h -] -[ -.BI \-o \ ofile -] -.br -[ -.BI \-q \ number -] -[ -.BI \-v \ number -] -.BI \-s \ sfile -.I file -.SH DESCRIPTION -.B wm_corvi_e -is a program to embed a signature (watermark) from -.I sfile -into the DWT residue of an image -.I file -and output a signed (watermarked) image -.I ofile. -Both, input and output image, -are in PGM (portable graymap) format. -.PP -If -.I file -or -.I ofile -is not specified, then standard input or standard output is -used. The signature -.I sfile -is a mandatory parameter however. -.PP -.B gen_corvi_sig -is used to generate a signature file, -.B wm_corvi_d -extracts a signature from a watermarked image and -.B cmp_corvi_sig -allows to compare and test an extracted watermark against the original -signature. -.PP -Please refer to Marco Corvi's paper "Wavelet-based image watermarking -for copyright protection", to get an idea about the algorithm. -.PP -.SH OPTIONS -.TP -.BI \-a \ number -Alpha factor that determines embedding strength of the signature. -Allows to override the setting in the signature file. -.TP -.BI \-e \ number -Wavelet filtering method for forward transformation. -Allows to override the setting in the signature file. -.TP -.BI \-f \ number -Wavelet filter number. -Allows to override the setting in the signature file. -.TP -.BI \-F \ ffile -Wavelet filter definition file. -Allows to override the setting in the signature file. -.TP -.BI \-g \ number -Wavelet filtering method for inverse transformation. -Allows to override the setting in the signature file. -.TP -.B \-h -Print a help message. -.TP -.BI \-o \ ofile -Output watermarked image to the specified -.I file -instead of standard output. -.TP -.BI \-q \ number -Set quantization/quality factor. Overrides the setting in the signature -file. -.TP -.BI \-s \ sfile -The signature file to embed into the input image. See -.B gen_corvi_sig -(1) for a description of the file format. Mandatory parameter. -.IR file -Input image in PGM format to sign (watermark). Default: standard input. -.TP -.BI \-v \ number -Verbosity level. Specify higher numbers for more informatative -output. Default value: 0. -.TP -.I file -The image in PGM format to be watermarked. -.PP -.SH OUTPUT -The signed (watermarked) image in PGM format is written to standard output -or, optionally, to -.I ofile. -The length of the signature (watermark) determines the level of the -image residue (coarse image) where the signature is embedded. -.PP -.SH AUTHOR -Peter Meerwald. Email bug reports to pmeerw@cosy.sbg.ac.at. -.SH AVAILABILITY -The most recent released version of -.B wm_corvi_e -is always available -at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the -directory /pub/people/pmeerw/Watermarking. -.SH "SEE ALSO" -.BR gen_corvi_sig -(1), -.BR wm_corvi_d -(1), -.BR wm_corvi_s -(1), -.BR cmp_corvi_sig -(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_corvi_e.c --- a/Meerwald/wm_corvi_e.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,237 +0,0 @@ -#include "wm.h" -#include "dwt.h" -#include "pgm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-e n] [-f n] [-F n] [-h] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor/embedding strength\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int c; - int row, col; - - int n; - - double alpha = 0.0; - - int filter = 0; - int method = -1; - int level = 0; - char filter_name[MAXPATHLEN] = ""; - - int verbose = 0; - - gray **image; - Image_tree dwts; - - gray maxval; - int rows, cols, format; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "a:e:f:F:h?o:s:v:")) != EOF) { - switch (c) { - case 'a': - alpha = atof(optarg); - if (alpha <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "CVSG") >= 4) { - fscanf(sig, "%d\n", &n); - if (alpha == 0.0) - fscanf(sig, "%lf\n", &alpha); - else - fscanf(sig, "%*f\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - - image = pgm_allocarray(cols, rows); - - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - - fclose(in); - - level = 0; - row = rows; - col = cols; - while (n < row * col / 4.0 && row >= 2 && col >= 2) { - row /= 2; - col /= 2; - level++; - } - - if (verbose >= 2) { - fprintf(stderr, "%s: embedding into coarse image (x %d/y %d) at level %d\n", progname, col, row, level); - } - - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - dwts = fdwt(image); - - { - Image_tree p = dwts; - Image img; - double med; - - while (!p->image) - p = p->coarse; - - img = p->image; - - med = 0.0; - for (row = 0; row < img->height; row++) - for (col = 0; col < img->width; col++) - med += get_pixel(img, col, row); - - med /= (double) (img->height * img->width); - - row = 0; - col = 0; - while (n > 0) { - double pix; - double g; - - fscanf(sig, "%lf\n", &g); - - pix = get_pixel(img, col, row); - pix = med + (pix - med) * (1.0 + alpha * g); - set_pixel(img, col, row, pix); - - if (++col == img->width) { col = 0; row++; } - n--; - } - } - - fclose(sig); - - idwt(dwts, image); - - pgm_writepgminit(out, cols, rows, maxval, 0); - - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, image[row], cols, maxval, 0); - - fclose(out); - - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_corvi_s.1 --- a/Meerwald/wm_corvi_s.1 Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,171 +0,0 @@ -.\" -.\" wm_corvi_s.1 - the *roff document processor man page source -.\" -.TH wm_corvi_s 1 "98/07/29" "Watermarking, Version 1.0" -.SH NAME -.B wm_corvi_s -\- a program to extract a signature from the DWT residue of a watermarked -image -.SH SYNOPSIS -.B wm_corvi_s -[ -.BI \-a \ number -] -[ -.BI \-e \ number -] -[ -.BI \-f \ number -] -[ -.BI \-F \ ffile -] -[ -.BI \-g \ number -] -[ -.B \-h -] -[ -.BI \-i \ ifile -] -.br -[ -.BI \-n \ number -] -[ -.BI \-o \ ofile -] -[ -.BI \-q \ number -] -[ -.BI \-v \ number -] -.BI \-s \ sfile -.I file -.SH DESCRIPTION -.B wm_corvi_s -is a program to extract a signature from the DWT residue of -a watermarked image -.I file. -The -.B cmp_corvi_sig -program is used to test the extracted signature against the original signature. -The input image is in PGM (portable graymap) format. -.PP -If -.I file -or -.I ofile -is not specified, then standard input or standard output is -used. -.PP -.B gen_corvi_sig -is used to generate a signature file, -.B wm_corvi_e -embeds the signature into an image. -.PP -Please refer to Marco Corvi's paper "Wavelet-based image watermarking -for copyright protection", to get an idea about the algorithm. -.PP -.SH OPTIONS -.TP -.BI \-a \ number -Alpha factor that determines embedding strength of the signature. -Allows to override the setting in the signature file. -.TP -.BI \-e \ number -Wavelet filtering method for forward transformation. -Allows to override the setting in the signature file. -.TP -.BI \-f \ number -Wavelet filter number. -Allows to override the setting in the signature file. -.TP -.BI \-F \ ffile -Wavelet filter definition file. -Allows to override the setting in the signature file. -.TP -.BI \-g \ number -Wavelet filtering method for inverse transformation. -Allows to override the setting in the signature file. -.TP -.B \-h -Print a help message. -.TP -.BI \-i \ ifile -The original image. -.TP -.BI \-o \ ofile -Output watermarked image to the specified -.I file -instead of standard output. -.TP -.BI \-q \ number -Set quantization/quality factor. Overrides the setting in the signature -file. -.TP -.BI \-v \ number -Verbosity level. Default value: 0. -.TP -.BI \-s \ sfile -The signature file to embed into the input image. See -.B gen_corvi_sig -(1) for a description of the file format. Mandatory parameter. -.IR file -Input image in PGM format to sign (watermark). Default: standard input. -.TP -.I file -The watermarked image in PGM format. -.PP -.SH OUTPUT -The signed (watermarked) image in PGM format is written to standard output -or ,optionally, to -.I ofile. -.PP -The output file has the following format: -.TP -.B CVSG -Magic to identify file type. -.TP -.I number -The length of the signature in bits. -.TP -.I number -The alpha factor (embedding strength). -.TP -.I number -The quantization/quality factor. -.TP -.I number -The wavelet forward transform filtering method. -.TP -.I number -The wavelet filter number. -.I file -The wavelet filter definition file name. -.TP -.I number -The wavelet inverse transform filtering method. -.TP -.I numbers -The actual normal distributed signature values, one per line. -.PP -.SH AUTHOR -Peter Meerwald. Email bug reports to pmeerw@cosy.sbg.ac.at. -.SH AVAILABILITY -The most recent released version of -.B wm_corvi_s -is always available -at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the -directory /pub/people/pmeerw/Watermarking. -.SH "SEE ALSO" -.BR gen_corvi_sig -(1), -.BR wm_corvi_e -(1), -.BR wm_corvi_d -(1), -.BR cmp_corvi_sig -(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_corvi_s.c --- a/Meerwald/wm_corvi_s.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,295 +0,0 @@ -#include "wm.h" -#include "wm_dwt.h" -#include "pgm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-h] [-n n] [-o file] [-q n] [-s file] [-v n] -i file file\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-i file\t\toriginal image file\n"); - fprintf(stderr, "\t-n n\t\twatermark length\n"); - fprintf(stderr, "\t-o file\t\textracted signature file\n"); - fprintf(stderr, "\t-q n\t\tquantization/quality factor\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *orig = NULL; - FILE *sig = NULL; - - gray **input_image; - gray **orig_image; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char orig_name[MAXPATHLEN]; - - int c; - int i; - int quantization = 0; - int n = 0; - int method = -1; - int filter = 0; - char filter_name[MAXPATHLEN] = ""; - - int level; - double alpha = 0.0; - - int in_rows, in_cols, in_format; - gray in_maxval; - int orig_rows, orig_cols, orig_format; - gray orig_maxval; - int rows, cols; - int row, col; - - Image_tree input_dwts; - Image_tree orig_dwts; - - int verbose = 0; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init2(); - - while ((c = getopt(argc, argv, "a:e:f:F:h?i:n:o:s:v:")) != EOF) { - switch (c) { - case 'a': - alpha = atof(optarg); - if (alpha <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'i': - if ((orig = fopen(optarg, "rb")) == NULL) { - fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); - exit(1); - } - strcpy(orig_name, optarg); - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 1000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - - if (!orig) { - fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); - exit(1); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "CVSG") >= 4) { - fscanf(sig, "%d\n", &n); - if (alpha == 0.0) - fscanf(sig, "%lf\n", &alpha); - else - fscanf(sig, "%*f\n"); - if (quantization == 0) - fscanf(sig, "%d\n", &quantization); - else - fscanf(sig, "%*d\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); - pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); - - if (in_cols != orig_cols || in_rows != orig_rows) { - fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); - exit(1); - } - - cols = in_cols; - rows = in_rows; - - input_image = pgm_allocarray(in_cols, in_rows); - - orig_image = pgm_allocarray(orig_cols, orig_rows); - - for (row = 0; row < in_rows; row++) - pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); - - fclose(in); - - for (row = 0; row < orig_rows; row++) - pgm_readpgmrow(orig, orig_image[row], orig_cols, orig_maxval, orig_format); - - fclose(orig); - - level = 0; - row = rows; - col = cols; - while (n < row * col / 4.0 && row >= 2 && col >= 2) { - row /= 2; - col /= 2; - level++; - } - - if (verbose >= 2) { - fprintf(stderr, "%s: extracting from coarse image (x %d/y %d) at level %d\n", progname, col, row, level); - } - - init_dwt(cols, rows, filter_name, filter, level, method); - input_dwts = fdwt(input_image); - orig_dwts = fdwt(orig_image); - - fprintf(out, "CVSG\n"); - fprintf(out, "%d\n", n); - fprintf(out, "%f\n", alpha); - fprintf(out, "%d\n", quantization); - fprintf(out, "%d\n", method); - fprintf(out, "%d\n", filter); - fprintf(out, "%s\n", filter_name); - - { - Image_tree p = input_dwts; - Image_tree q = orig_dwts; - Image input_img; - Image orig_img; - double input_med; - double orig_med; - - while (!p->image) - p = p->coarse; - - while (!q->image) - q = q->coarse; - - input_img = p->image; - orig_img = q->image; - - input_med = 0.0; - for (row = 0; row < input_img->height; row++) - for (col = 0; col < input_img->width; col++) - input_med += get_pixel(input_img, col, row); - input_med /= input_img->height * input_img->width; - - orig_med = 0.0; - for (row = 0; row < orig_img->height; row++) - for (col = 0; col < orig_img->width; col++) - orig_med += get_pixel(orig_img, col, row); - orig_med /= orig_img->height * orig_img->width; - - row = 0; - col = 0; - while (n > 0) { - Pixel input_pix; - Pixel orig_pix; - double x; - - input_pix = get_pixel(input_img, col, row); - orig_pix = get_pixel(orig_img, col, row); - - x = ((input_pix - orig_pix) / (orig_pix - orig_med)) / alpha; - - fprintf(out, "%f\n", x); - - if (++col == orig_img->width) { col = 0; row++; } - n--; - } - } - - fclose(out); - - pgm_freearray(input_image, rows); - pgm_freearray(orig_image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_cox_d.1 --- a/Meerwald/wm_cox_d.1 Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -.\" -.\" wm_cox_d.1 - the *roff document processor man page source -.\" -.TH wm_cox_d 1 "98/07/05" "Watermarking, Version 1.0" -.SH NAME -.B wm_cox_d -\- a program to extract a signature from the DCT coefficients of a watermarked image -.SH SYNOPSIS -.B wm_cox_d -[ -.BI \-a \ number -] -[ -.B \-h -] -[ -.BI \-i \ ifile -] -[ -.BI \-n \ number -] -[ -.BI \-o \ ofile -] -[ -.BI \-q \ number -] -[ -.BI \-v \ number -] -.br -.BI \-s \ sfile -.I file -.SH DESCRIPTION -.B wm_cox_d -is a program to extract a signature from the DCT coefficients of the watermarked image -.I file. -The -.B cmp_cox_sig -program is used to test the extracted signature against the original signature. -The input image is in PGM (portable graymap) format. -.PP -If -.I file -or -.I ofile -is not specified, then standard input or standard output is -used. -.PP -.B gen_cox_sig -is used to generate a signature file, -.B wm_cox_e -embeds the signature into an image. -.PP -Please refer to Ingemar J. Cox's paper "Secure Spread Spectrum -Watermarking for Multimedia", 1995, to get an idea about the algorithm. -.PP -.SH OPTIONS -.TP -.BI \-a \ number -Alpha factor that determines embedding strength of the signature. -Allows to override the setting in the signature file. -.TP -.B \-h -Print a help message. -.TP -.BI \-i \ ifile -The original image. -.TP -.BI \-o \ ofile -Output watermarked image to the specified -.I file -instead of standard output. -.TP -.BI \-q \ number -Set quantization/quality factor. Overrides the setting in the signature -file. -.TP -.BI \-v \ number -Verbosity level. Default value: 0. -.TP -.BI \-s \ sfile -The signature file to embed into the input image. See -.B gen_cox_sig -(1) for a description of the file format. Mandatory parameter. -.IR file -Input image in PGM format to sign (watermark). Default: standard input. -.TP -.I -The watermarked image file in PGM format. -.PP -.SH OUTPUT -The signed (watermarked) image in PGM format is written to standard output -or ,optionally, to -.I ofile. -The embedding process may take some time on large images since the DCT -is performed on the whole image in one step (not block-wise). -.PP -.PP -The output file has the following format: -.TP -.B CXSG -Magic to identify file type. -.TP -.I number -The length of the signature in bits. -.TP -.I number -The alpha factor (embedding strength). -.TP -.I number -The quantization/quality factor. -.TP -.I numbers -The actual normal distributed signature values, one per line. -.PP -.SH AUTHOR -Peter Meerwald. -Email bug reports to pmeerw@cosy.sbg.ac.at. -.SH AVAILABILITY -The most recent released version of -.B wm_cox_d -is always available -at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the -directory /pub/people/pmeerw/Watermarking. -.SH "SEE ALSO" -.BR gen_cox_sig -(1), -.BR wm_cox_e -(1), -.BR cmp_cox_sig -(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_cox_d.c --- a/Meerwald/wm_cox_d.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,228 +0,0 @@ -#include "wm.h" -#include "dct.h" -#include "pgm.h" -#include "sort.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-h] [-n n] [-o file] [-s file] [-v n] -i file file\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor (default 0.3)\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-i file\t\toriginal image file\n"); - fprintf(stderr, "\t-n n\t\twatermark length (default 100)\n"); - fprintf(stderr, "\t-o file\t\textracted signature file\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *orig = NULL; - FILE *sig = NULL; - - gray **input_image; - gray **orig_image; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char orig_name[MAXPATHLEN]; - - int c; - int i, j; - int n = 100; - - double a = 0.3; - - int warn_n = 1; - int warn_a = 1; - - int in_rows, in_cols, in_format; - gray in_maxval; - int orig_rows, orig_cols, orig_format; - gray orig_maxval; - int rows, cols; - int row; - - double threshold; - double *largest; - - double **input_dcts; - double **orig_dcts; - - int verbose = 0; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init2(); - - while ((c = getopt(argc, argv, "h?i:n:o:s:v:")) != EOF) { - switch (c) { - case 'a': - a = atof(optarg); - if (a <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, a); - exit(1); - } - warn_a = 0; - break; - case 'h': - case '?': - usage(); - break; - case 'i': - if ((orig = fopen(optarg, "rb")) == NULL) { - fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); - exit(1); - } - strcpy(orig_name, optarg); - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 1000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - warn_n = 0; - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (!orig) { - fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); - exit(1); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "CXSG") >= 4) { - fscanf(sig, "%d\n", &n); - if (warn_a) - fscanf(sig, "%lf\n", &a); - else - fscanf(sig, "%*f\n"); - fscanf(sig, "%*f\n"); - fscanf(sig, "%*f\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - if (warn_a) - fprintf(stderr, "%s: warning - alpha factor not specified, using default %f\n", progname, a); - if (warn_n) - fprintf(stderr, "%s: warning - watermark length not specified, using default %d\n", progname, n); - } - - pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); - pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); - - if (in_cols != orig_cols || in_rows != orig_rows) { - fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); - exit(1); - } - - cols = in_cols; - rows = in_rows; - - init_dct_NxN(cols, rows); - - input_image = pgm_allocarray(in_cols, in_rows); - - orig_image = pgm_allocarray(orig_cols, orig_rows); - - for (row = 0; row < in_rows; row++) - pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); - - fclose(in); - - for (row = 0; row < orig_rows; row++) - pgm_readpgmrow(orig, orig_image[row], orig_cols, orig_maxval, orig_format); - - fclose(orig); - - input_dcts = alloc_coeffs(cols, rows); - orig_dcts = alloc_coeffs(cols, rows); - - fdct_NxN(input_image, input_dcts); - fdct_NxN(orig_image, orig_dcts); - - largest = malloc((n + 1) * sizeof(double)); - select_largest_coeffs(orig_dcts[0], cols * rows, n+1, largest); - threshold = largest[0]; - free(largest); - - fprintf(out, "CXWM\n"); - fprintf(out, "%d\n", n); - - j = 0; - for (i = 0; i < n; i++) { - double d, o, p; - - while ((o = orig_dcts[j / cols][j % cols]) < threshold) j++; - - p = input_dcts[j / cols][j % cols]; - - d = (p / o - 1.0) / a; - if (verbose >= 1) - fprintf(stderr, "input %f orig %f alpha %f d %f\n", p, o, a, d); - fprintf(out, "%f\n", d); - j++; - } - - fclose(out); - - free_coeffs(input_dcts); - free_coeffs(orig_dcts); - - pgm_freearray(input_image, rows); - pgm_freearray(orig_image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_cox_e.1 --- a/Meerwald/wm_cox_e.1 Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,110 +0,0 @@ -.\" -.\" wm_cox_e.1 - the *roff document processor man page source -.\" -.TH wm_cox_e 1 "98/07/01" "Watermarking, Version 1.0" -.SH NAME -.B wm_cox_e -\- a program to embed a signature in the DCT coefficients of an image -.SH SYNOPSIS -.B wm_cox_e -[ -.BI \-a \ number -] -[ -.B \-h -] -[ -.BI \-o \ ofile -] -[ -.BI \-q \ number -] -.BI \-s \ sfile -.I file -.SH DESCRIPTION -.B wm_cox_e -is a program to embed a signature (watermark) from -.I sfile -into the DCT coefficients of an image -.I file -and output a signed (watermarked) image -.I ofile. -Both, input and output image, -are in PGM (portable graymap) format. -.PP -If -.I file -or -.I ofile -is not specified, then standard input or standard output is -used. The signature -.I sfile -is a mandatory parameter however. -.PP -.B gen_cox_sig -is used to generate a signature file, -.B wm_cox_d -extracts a signature from a watermarked image and -.B cmp_cox_sig -allows to compare and test an extracted watermark against the original -signature. -.PP -Please refer to Ingemar J. Cox's paper "Secure Spread Spectrum -Watermarking for Multimedia", 1995, to get an idea about the algorithm. -.PP -.SH OPTIONS -.TP -.BI \-a \ number -Alpha factor that determines embedding strength of the signature. -Allows to override the setting in the signature file. -.TP -.B \-h -Print a help message. -.TP -.BI \-o \ ofile -Output watermarked image to the specified -.I file -instead of standard output. -.TP -.BI \-q \ number -Set quantization/quality factor. Overrides the setting in the signature -file. -.TP -.BI \-s \ sfile -The signature file to embed into the input image. See -.B gen_cox_sig -(1) for a description of the file format. Mandatory parameter. -.IR file -Input image in PGM format to sign (watermark). Default: standard input. -.TP -.I file -The input image in PGM format. -.PP -.SH OUTPUT -The signed (watermarked) image in PGM format is written to standard output -or, optionally, to -.I ofile. -The embedding process may take some time on large images since the DCT -is performed on the whole image in one step (not block-wise). -.PP -The -.I n -largest coefficients are pulsed to embed the -.I n -bit watermark. -.PP -.SH AUTHOR -Peter Meerwald. Email bug reports to pmeerw@cosy.sbg.ac.at. -.SH AVAILABILITY -The most recent released version of -.B wm_cox_e -is always available -at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the -directory /pub/people/pmeerw/Watermarking. -.SH "SEE ALSO" -.BR gen_cox_sig -(1), -.BR wm_cox_d -(1), -.BR cmp_cox_sig -(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_cox_e.c --- a/Meerwald/wm_cox_e.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,165 +0,0 @@ -#include "wm.h" -#include "dct.h" -#include "pgm.h" -#include "sort.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-h] [-o file] -s file file\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor/embedding strength\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int c; - int row; - int i,j; - - int n; - - double alpha = 0.0; - double threshold; - - double *largest; - gray **input_image; - gray **output_image; - double **dcts; - - gray maxval; - int rows, cols, format; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "a:h?o:s:")) != EOF) { - switch (c) { - case 'a': - alpha = atof(optarg); - if (alpha <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 'h': - case '?': - usage(); - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "CXSG") >= 4) { - fscanf(sig, "%d\n", &n); - if (alpha == 0.0) - fscanf(sig, "%lf\n", &alpha); - else - fscanf(sig, "%*f\n"); - fscanf(sig, "%*f\n"); - fscanf(sig, "%*f\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - - init_dct_NxN(cols, rows); - - dcts = alloc_coeffs(cols, rows); - input_image = pgm_allocarray(cols, rows); - - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, input_image[row], cols, maxval, format); - - fclose(in); - - output_image = pgm_allocarray(cols, rows); - - fdct_NxN(input_image, dcts); - - largest = malloc((n + 1) * sizeof(double)); - select_largest_coeffs(dcts[0], cols * rows, n+1, largest); - threshold = largest[0]; - free(largest); - - j = 0; - for (i = 0; i < n; i++) { - double v; - - while (dcts[j / cols][j % cols] < threshold) j++; - - fscanf(sig, "%lf\n", &v); - dcts[j / cols][j % cols] *= (1.0 + alpha * v); - j++; - } - - idct_NxN(dcts, output_image); - free_coeffs(dcts); - - pgm_writepgminit(out, cols, rows, maxval, 0); - - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, output_image[row], cols, maxval, 0); - - fclose(out); - - fclose(sig); - - pgm_freearray(output_image, rows); - pgm_freearray(input_image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_dugad_d.c --- a/Meerwald/wm_dugad_d.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,261 +0,0 @@ -#include "wm.h" -#include "dwt.h" -#include "dwt_util.h" -#include "pgm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-e n] [-f n] [-F file] [-h] [-l n] [-n n] [-o file] [-v n] [-t n] -s file file\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-l n\t\tdecomposition levels\n"); - fprintf(stderr, "\t-n n\t\twatermark length\n"); - fprintf(stderr, "\t-o file\t\tfile for extracted watermark\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-t n\t\tdetection threshold\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -void wm_subband(Image s, double *w, int n, double t2, int *m, double *z, double *v) { - int i; - - *m = 0; - *z = 0.0; - *v = 0.0; - for (i = 0; i < s->width * s->height; i++) - if (s->data[i] > t2) { - (*z) += (s->data[i] * w[i % n]); - (*v) += fabs(s->data[i]); - (*m)++; - } -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - gray **input_image; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - - int c; - int i; - int n = 0; - int method = -1; - int level = 0; - int filter = 0; - char filter_name[MAXPATHLEN] = ""; - - double alpha = 0.0; - double t2 = 0.0; - - int in_rows, in_cols, in_format; - gray in_maxval; - int rows, cols; - int row; - - double *watermark; - - Image_tree dwts, s; - - int verbose = 0; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init2(); - - while ((c = getopt(argc, argv, "a:e:f:F:h?l:n:o:s:v:t")) != EOF) { - switch (c) { - case 'a': - alpha = atof(optarg); - if (alpha <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'l': - level = atoi(optarg); - if (level <= 0) { - fprintf(stderr, "%s: decomposition level %d out of range\n", progname, level); - exit(1); - } - break; - - case 'n': - n = atoi(optarg); - if (n < 1 || n > 32000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 't': - t2 = atof(optarg); - if (t2 <= 0.0) { - fprintf(stderr, "%s: detection threshold %f out of range\n", progname, t2); - exit(1); - } - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "DGSG") >= 4) { - fscanf(sig, "%d\n", &n); - if (level == 0) - fscanf(sig, "%d\n", &level); - else - fscanf(sig, "%*d\n"); - if (alpha == 0.0) - fscanf(sig, "%lf\n", &alpha); - else - fscanf(sig, "%*f\n"); - fscanf(sig, "%*f\n"); - if (t2 == 0.0) - fscanf(sig, "%lf\n", &t2); - else - fscanf(sig, "%*f\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - watermark = malloc(n * sizeof(double)); - for (i = 0; i < n; i++) - fscanf(sig, "%lf\n", &watermark[i]); - fclose(sig); - - pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); - - cols = in_cols; - rows = in_rows; - - input_image = pgm_allocarray(in_cols, in_rows); - - for (row = 0; row < in_rows; row++) { - pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); - } - - fclose(in); - - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - dwts = fdwt(input_image); - - fprintf(out, "DGWM\n"); - fprintf(out, "%d\n", level); - fprintf(out, "%f\n", alpha); - - for (i = 0, s = dwts; i < level; i++, s = s->coarse) { - int m; - double z, v; - - wm_subband(s->horizontal->image, watermark, n, t2, &m, &z, &v); - fprintf(out, "%d %f %f\n", m, z, v); - wm_subband(s->vertical->image, watermark, n, t2, &m, &z, &v); - fprintf(out, "%d %f %f\n", m, z, v); - wm_subband(s->diagonal->image, watermark, n, t2, &m, &z, &v); - fprintf(out, "%d %f %f\n", m, z, v); - } - - fclose(out); - - free(watermark); - - pgm_freearray(input_image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_dugad_e.c --- a/Meerwald/wm_dugad_e.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,241 +0,0 @@ -#include "wm.h" -#include "dwt.h" -#include "pgm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-e n] [-f n] [-F file] [-h] [-l n] [-o file] [-t n] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor/embedding strength\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-l n\t\tdecomposition levels\n"); - fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - fprintf(stderr, "\t-t n\t\tcasting threshold\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -// actual watermarking procedure: embeds a watermark of n normally -// distributed values into a coefficients > threshold t1 of a subband -void wm_subband(Image s, double *w, int n, double a, double t1) { - int i; - - for (i = 0; i < s->width * s->height; i++) - if (fabs(s->data[i]) > t1) - s->data[i] += (a * fabs(s->data[i]) * w[i % n]); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int i, c; - int row; - - int n; - - double alpha = 0.0; - double t1 = 0.0; - - int level = 0; - int filter = 0; - int method = -1; - char filter_name[MAXPATHLEN] = ""; - - int verbose = 0; - - gray **image; - Image_tree dwts, s; - - gray maxval; - int rows, cols, format; - - double *watermark; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "a:e:f:F:h?l:o:s:t:v:")) != EOF) { - switch (c) { - case 'a': - alpha = atof(optarg); - if (alpha <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'l': - level = atoi(optarg); - if (level <= 0) { - fprintf(stderr, "%s: decomposition level %d out of range\n", progname, level); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 't': - t1 = atof(optarg); - if (t1 <= 0.0) { - fprintf(stderr, "%s: casting threshold %f out of range\n", progname, t1); - exit(1); - } - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "DGSG") >= 4) { - fscanf(sig, "%d\n", &n); - if (level == 0) - fscanf(sig, "%d\n", &level); - else - fscanf(sig, "%*d\n"); - if (alpha == 0.0) - fscanf(sig, "%lf\n", &alpha); - else - fscanf(sig, "%*f\n"); - if (t1 == 0.0) - fscanf(sig, "%lf\n", &t1); - else - fscanf(sig, "%*f\n"); - fscanf(sig, "%*f\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - watermark = malloc(n * sizeof(double)); - for (i = 0; i < n; i++) - fscanf(sig, "%lf\n", &watermark[i]); - fclose(sig); - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - - image = pgm_allocarray(cols, rows); - - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - - fclose(in); - - // wavelet transform - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - dwts = fdwt(image); - - // embed watermark in all subbands of a decomposition level - for (i = 0, s = dwts; i < 3; i++, s = s->coarse) { - wm_subband(s->horizontal->image, watermark, n, alpha, t1); - wm_subband(s->vertical->image, watermark, n, alpha, t1); - wm_subband(s->diagonal->image, watermark, n, alpha, t1); - } - - free(watermark); - - idwt(dwts, image); - - pgm_writepgminit(out, cols, rows, maxval, 0); - - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, image[row], cols, maxval, 0); - - fclose(out); - - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_frid2_d.c --- a/Meerwald/wm_frid2_d.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,212 +0,0 @@ -#include "wm.h" -#include "dct.h" -#include "pgm.h" -#include "signature.h" -#include "frid2_common.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-h] [-b n] [-n n] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor low freq. embedding strength\n"); - fprintf(stderr, "\t-b n\t\tbeta factor for weighted correlation (default 0)\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-n n\t\tnormalisation factor (default 1024.0)\n"); - fprintf(stderr, "\t-o file\t\tfile for extracted watermark information\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int c; - int row, col; - double normalization = 1024.0; - int seed, format; - - double alpha = 0.0; - double beta = 0.0; - - double correlation; - - gray **image; - double **coeffs; - - double mean, derivation, mult_factor; - int rows, cols; - - gray maxval; - int verbose = 0; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init2(); - - while ((c = getopt(argc, argv, "a:b:n:h?s:o:v:")) != EOF) { - switch (c) { - case 'a': - alpha = atof(optarg); - if (alpha <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 'b': - beta = atof(optarg); - if (beta <= 0.0) { - fprintf(stderr, "%s: beta factor %f out of range\n", progname, beta); - exit(1); - } - break; - case 'n': - normalization = atof(optarg); - if (normalization < 0) { - fprintf(stderr, "%s: normalisation factor %f out of range\n", progname, normalization); - exit(1); - } - break; - case 'h': - case '?': - usage(); - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "FR2SG") >= 5) { - fscanf(sig, "%d\n", &nbit_signature1); - if (alpha == 0.0) - fscanf(sig, "%lf\n", &alpha); - else - fscanf(sig, "%*f\n"); - fscanf(sig, "%*f\n"); - fscanf(sig, "%d\n", &seed); - n_signature1 = NBITSTOBYTES(nbit_signature1); - fread(signature1, sizeof(char), n_signature1, sig); - fscanf(sig, "\n"); - srandom(seed); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - image = pgm_allocarray(cols, rows); - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - fclose(in); - - // calculate mean malue - mean = 0.0; - for (row = 0; row < rows; row++) - for (col = 0; col < cols; col++) - mean += image[row][col]; - - mean /= cols * rows; - - // calculate derivation - derivation = 0.0; - for (row = 0; row < rows; row++) - for (col = 0; col < cols; col++) - derivation += sqr(image[row][col] - mean); - - derivation = sqrt(derivation / (cols * rows - 1)); - mult_factor = normalization / (sqrt(cols * rows) * derivation); - - if (verbose > 5) - fprintf(stderr, "%s: mean %f, derivation %f, mult_factor %f\n", progname, mean, derivation, mult_factor); - - // normalize image - coeffs = alloc_coeffs(cols, rows); - for (row = 0; row < rows; row++) - for (col = 0; col < cols; col++) - coeffs[row][col] = (image[row][col] - mean) * mult_factor; - - if (rows == cols) { - init_dct_NxN(cols, rows); - fdct_inplace_NxN(coeffs); - } -// else { -// init_dct_NxM(cols, rows); -// fdct_NxM(coeffs); -// } - - - fprintf(out, "FR2WM\n"); - - fprintf(out, "%d\n", nbit_signature1); - correlation = detect_low_freq(coeffs, cols, rows, alpha, beta, verbose); - if (verbose > 2) - fprintf(stderr, "low_freq correlation: %f\n", correlation); - fwrite(signature2, sizeof(char), NBITSTOBYTES(nbit_signature1), out); - fprintf(out, "\n"); - - fprintf(out, "%d\n", nbit_signature1); - correlation = detect_med_freq(coeffs, cols, rows, seed, verbose); - if (verbose > 2) - fprintf(stderr, "med_freq correlation: %f\n", correlation); - fwrite(signature2, sizeof(char), NBITSTOBYTES(nbit_signature1), out); - fprintf(out, "\n"); - - fclose(out); - - free_coeffs(coeffs); - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_frid2_e.c --- a/Meerwald/wm_frid2_e.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,218 +0,0 @@ -#include "wm.h" -#include "dct.h" -#include "pgm.h" -#include "signature.h" -#include "frid2_common.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-g n] [-n n] [-h] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor low freq. embedding strength\n"); - fprintf(stderr, "\t-g n\t\tgamma factor med freq. embedding strength\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-n n\t\tnormalisation factor (default 1024.0)\n"); - fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int c; - int row, col; - double normalization = 1024.0; - int seed, format; - - double alpha = 0.0; - double gamma = 0.0; - - gray **image; - double **coeffs; - - double mean, derivation; - double mult_factor; - - int rows, cols; - int verbose = 0; - gray maxval; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "a:g:n:h?o:s:v:")) != EOF) { - switch (c) { - case 'a': - alpha = atof(optarg); - if (alpha <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 'g': - gamma = atof(optarg); - if (gamma <= 0.0) { - fprintf(stderr, "%s: gamma factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 'n': - normalization = atof(optarg); - if (normalization < 0) { - fprintf(stderr, "%s: normalisation factor %f out of range\n", progname, normalization); - exit(1); - } - break; - case 'h': - case '?': - usage(); - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "FR2SG") >= 5) { - fscanf(sig, "%d\n", &nbit_signature); - if (alpha == 0.0) - fscanf(sig, "%lf\n", &alpha); - else - fscanf(sig, "%*f\n"); - if (gamma == 0.0) - fscanf(sig, "%lf\n", &gamma); - else - fscanf(sig, "%*f\n"); - - fscanf(sig, "%d\n", &seed); - n_signature = NBITSTOBYTES(nbit_signature); - fread(signature, sizeof(char), n_signature, sig); - fscanf(sig, "\n"); - srandom(seed); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - - if (rows == cols) - init_dct_NxN(cols, rows); - else - init_dct_NxM(cols, rows); - - image = pgm_allocarray(cols, rows); - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - fclose(in); - - // calculate mean value - mean = 0.0; - for (row = 0; row < rows; row++) - for (col = 0; col < cols; col++) - mean += image[row][col]; - - mean /= cols * rows; - - // calculate derivation - derivation = 0.0; - for (row = 0; row < rows; row++) - for (col = 0; col < cols; col++) - derivation += sqr(image[row][col] - mean); - - derivation = sqrt(derivation / (cols * rows - 1)); - mult_factor = normalization / (sqrt(cols * rows) * derivation); - - if (verbose > 5) - fprintf(stderr, "%s: mean %f, derivation %f, mult_factor %f\n", progname, mean, derivation, mult_factor); - - // normalize image - coeffs = alloc_coeffs(cols, rows); - for (row = 0; row < rows; row++) - for (col = 0; col < cols; col++) - coeffs[row][col] = (image[row][col] - mean) * mult_factor; - - if (cols == rows) - fdct_inplace_NxN(coeffs); -// else -// fdct_NxM(image, dcts); - - embed_low_freq(coeffs, cols, rows, alpha, verbose); - embed_med_freq(coeffs, cols, rows, gamma, seed, verbose); - - if (cols == rows) - idct_inplace_NxN(coeffs); -// else -// idct_NxM(dcts, image); - - for (row = 0; row < rows; row++) - for (col = 0; col < cols; col++) - image[row][col] = PIXELRANGE(coeffs[row][col] / mult_factor + mean + 0.5); - - free_coeffs(coeffs); - - pgm_writepgminit(out, cols, rows, maxval, 0); - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, image[row], cols, maxval, 0); - - fclose(out); - - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_kim_a.c --- a/Meerwald/wm_kim_a.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,292 +0,0 @@ -#include "wm.h" -#include "wm_dwt.h" -#include "pgm.h" -#include "dwt_util.h" -#include "kim_common.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-A n] [-e n] [-f n] [-F n] [-h] [-l n] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor/embedding strength for detail subbands\n"); - fprintf(stderr, "\t-a n\t\talpha factor/embedding strength for approximation subband\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-l n\t\tdecomposition level\n"); - fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int mark_subband(Image_tree s, int name, double alpha, double watermark[], double threshold, int w, int n, int verbose) { - int i, j; - double last = 0.0; - - for (i = 5; i < s->image->height-5; i++) - for (j = 5; j < s->image->width-5; j++) { - double coeff, newcoeff; - - coeff = get_pixel(s->image, i, j); - if (fabs(coeff) > threshold / 1.5 ) { - newcoeff = coeff - coeff * alpha * watermark[w++ % n]; - set_pixel(s->image, i, j, newcoeff); - - fprintf(stderr, "%s: (%d/%d) %f: %f -> %f; a=%f\n", progname, j, i, watermark[w % n], coeff, newcoeff, alpha); - w++; - } - } - - if (verbose > 5) - fprintf(stderr, "%s: watermarking %s%d, size %d x %d; embedded %d coeffs. total\n", - progname, subband_name(name), s->level, s->image->width, s->image->height, w); - - return w; -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int i, c, w; - int row, col; - - int n; - - double alpha_detail = 0.0; - double alpha_approx = 0.0; - int level = 0; - - int filter = 0; - int method = -1; - int levels; - char filter_name[MAXPATHLEN] = ""; - - int verbose = 0; - - gray **image; - Image_tree p, dwts; - - gray maxval; - int rows, cols, colors, format; - - double *watermark; - - progname = argv[0]; - - pgm_init(&argc, argv); - -#ifdef __EMX__ - _fsetmode(in, "b"); - _fsetmode(out, "b"); -#endif - - while ((c = getopt(argc, argv, "a:A:e:f:F:h?o:l:s:v:")) != EOF) { - switch (c) { - case 'a': - alpha_detail = atof(optarg); - if (alpha_detail <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha_detail); - exit(1); - } - break; - case 'A': - alpha_approx = atof(optarg); - if (alpha_approx <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha_approx); - exit(1); - } - break; - case 'l': - level = atoi(optarg); - if (level <= 0) { - fprintf(stderr, "%s: decomposition level %d out of range\n", progname, level); - exit(1); - } - break; - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "KISG") >= 4) { - fscanf(sig, "%d\n", &n); - if (alpha_detail == 0.0) - fscanf(sig, "%lf\n", &alpha_detail); - else - fscanf(sig, "%*f\n"); - if (alpha_approx == 0.0) - fscanf(sig, "%lf\n", &alpha_approx); - else - fscanf(sig, "%*f\n"); - if (level == 0) - fscanf(sig, "%d\n", &level); - else - fscanf(sig, "%*d\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - watermark = malloc(n * sizeof(double)); - for (i = 0; i < n; i++) - fscanf(sig, "%lf\n", &watermark[i]); - fclose(sig); - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - image = pgm_allocarray(cols, rows); - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - fclose(in); - - // complete decomposition - levels = find_deepest_level(cols, rows) - 1; - if (level > levels) { - fprintf(stderr, "%s: decomposition level %d not possible (max. %d), image size is %d x %d\n", progname, level, levels, cols, rows); - exit(1); - } - - // wavelet transform - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - dwts = fdwt(image); - - p = dwts; - w = 0; - - // process each decomposition level - while (p->coarse) { - int current_level; - double threshold; - double max_coeff; - double alpha; - - // get current decomposition level number - current_level = p->horizontal->level; - - // find largest absolute coefficient in detail subbands of current decomposition level - max_coeff = find_level_largest_coeff(p, verbose); - - // calculate significance threshold for current decomposition level - threshold = calc_level_threshold(max_coeff, verbose); - - // calculate embedding strength alpha for current decomposition level - alpha = calc_level_alpha_detail(alpha_detail, level, current_level, verbose); - - if (verbose > 1) - fprintf(stderr, "%s: level %d, threshold %f, alpha %f\n", progname, current_level, threshold, alpha); - - // embed watermark sequence into detail subbands of current decomposition level - w = mark_subband(p->horizontal, HORIZONTAL, alpha, watermark, threshold, w, n, verbose); - w = mark_subband(p->vertical, VERTICAL, alpha, watermark, threshold, w, n, verbose); - w = mark_subband(p->diagonal, DIAGONAL, alpha, watermark, threshold, w, n, verbose); - - p = p->coarse; - } - - // mark approximation image using calculated significance threshold and embedding strength - w = mark_subband(p, COARSE, alpha_approx, watermark, calc_level_threshold(find_subband_largest_coeff(p, COARSE, verbose), verbose), w, n, verbose); - - free(watermark); - idwt(dwts, image); - - pgm_writepgminit(out, cols, rows, maxval, 0); - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, image[row], cols, maxval, 0); - fclose(out); - - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_kim_d.c --- a/Meerwald/wm_kim_d.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,326 +0,0 @@ -#include "wm.h" -#include "dwt.h" -#include "pgm.h" -#include "dwt_util.h" -#include "kim_common.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-A n] [-e n] [-f n] [-F file] [-h] [-l n] [-o file] [-v n] -s file -i file file\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor for detail subband\n"); - fprintf(stderr, "\t-A n\t\talpha factor for approximation image\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-i file\t\toriginal image file\n"); - fprintf(stderr, "\t-l n\t\tdecomposition level\n"); - fprintf(stderr, "\t-o file\t\tfile for extracted watermark\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int extract_subband(Image_tree s, Image_tree t, int name, double alpha, double watermark[], double threshold, int w, int n, int verbose) { - int i, j; - - for (i = 5; i < s->image->height-5; i++) - for (j = 5; j < s->image->width-5; j++) { - double orig_coeff, input_coeff; - - orig_coeff = get_pixel(s->image, i, j); - input_coeff = get_pixel(t->image, i, j); - if (fabs(orig_coeff) > threshold) { - watermark[w++] = (input_coeff - orig_coeff) / (alpha * orig_coeff); - } - } - - if (verbose > 5) - fprintf(stderr, "%s: extracted %s%d, size %d x %d; %d coeffs. total\n", - progname, subband_name(name), s->level, s->image->width, s->image->height, w); - - return w; -} - -void write_mark(FILE *out, double watermark[], int n) { - int i; - - fprintf(out, "%d\n", n); - for (i = 0; i < n; i++) - fprintf(out, "%f\n", watermark[i]); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *orig = NULL; - FILE *sig = NULL; - - gray **input_image; - gray **orig_image; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char orig_name[MAXPATHLEN]; - - int c, w; - int n = 0; - int method = -1; - int filter = 0; - char filter_name[MAXPATHLEN] = ""; - - int level = 0, levels; - double alpha_detail = 0.0; - double alpha_approx = 0.0; - - int in_rows, in_cols, in_format; - gray in_maxval; - int orig_rows, orig_cols, orig_format; - gray orig_maxval; - int rows, cols; - int row; - - double *watermark; - - Image_tree input_dwts, orig_dwts, p, q; - - int verbose = 0; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init2(); - - while ((c = getopt(argc, argv, "a:A:e:f:F:h?i:l:o:s:v:")) != EOF) { - switch (c) { - case 'a': - alpha_detail = atof(optarg); - if (alpha_detail <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha_detail); - exit(1); - } - break; - case 'A': - alpha_approx = atof(optarg); - if (alpha_approx <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha_approx); - exit(1); - } - break; - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'i': - if ((orig = fopen(optarg, "rb")) == NULL) { - fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); - exit(1); - } - strcpy(orig_name, optarg); - break; - case 'l': - level = atoi(optarg); - if (level <= 0) { - fprintf(stderr, "%s: decomposition level %d out of range\n", progname, level); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (!orig) { - fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); - exit(1); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "KISG") >= 4) { - fscanf(sig, "%d\n", &n); - if (alpha_detail == 0.0) - fscanf(sig, "%lf\n", &alpha_detail); - else - fscanf(sig, "%*f\n"); - if (alpha_approx == 0.0) - fscanf(sig, "%lf\n", &alpha_approx); - else - fscanf(sig, "%*f\n"); - if (level == 0) - fscanf(sig, "%d\n", &level); - else - fscanf(sig, "%*d\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); - pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); - - if (in_cols != orig_cols || in_rows != orig_rows) { - fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); - exit(1); - } - - cols = in_cols; - rows = in_rows; - - input_image = pgm_allocarray(in_cols, in_rows); - orig_image = pgm_allocarray(orig_cols, orig_rows); - - for (row = 0; row < in_rows; row++) { - pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); - pgm_readpgmrow(orig, orig_image[row], orig_cols, orig_maxval, orig_format); - } - - fclose(in); - fclose(orig); - - // complete decomposition - levels = find_deepest_level(cols, rows) - 1; - if (level > levels) { - fprintf(stderr, "%s: decomposition level %d not possible (max. %d), image size is %d x %d\n", progname, level, levels, cols, rows); - exit(1); - } - - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - input_dwts = fdwt(input_image); - orig_dwts = fdwt(orig_image); - - watermark = malloc((rows * cols) * sizeof(double)); - if (!watermark) { - fprintf(stderr, "%s: malloc() failed\n\n", progname); - exit(1); - } - - p = input_dwts; - q = orig_dwts; - w = 0; - while (p->coarse && q->coarse) { - int current_level; - double threshold; - double max_coeff; - double alpha; - - // get current decomposition level number - current_level = q->horizontal->level; - - // find largest absolute coefficient in detail subbands of current decomposition level - max_coeff = find_level_largest_coeff(q, verbose); - - // calculate significance threshold for current decomposition level - threshold = calc_level_threshold(max_coeff, verbose); - - // calculate embedding strength alpha for current decomposition level - alpha = calc_level_alpha_detail(alpha_detail, level, current_level, verbose); - - if (verbose > 1) - fprintf(stderr, "%s: level %d, threshold %f, alpha %f\n", progname, current_level, threshold, alpha); - - w = extract_subband(q->horizontal, p->horizontal, HORIZONTAL, alpha, watermark, threshold, w, n, verbose); - w = extract_subband(q->vertical, p->vertical, VERTICAL, alpha, watermark, threshold, w, n, verbose); - w = extract_subband(q->diagonal, p->diagonal, DIAGONAL, alpha, watermark, threshold, w, n, verbose); - - p = p->coarse; - q = q->coarse; - } - - // extract watermark from approximation image using calculated significance threshold and embedding strength - w = extract_subband(q, p, COARSE, alpha_approx, watermark, calc_level_threshold(find_subband_largest_coeff(q, COARSE, verbose), verbose), w, n, verbose); - - fprintf(out, "KIWM\n"); - write_mark(out, watermark, w); - - fclose(out); - - free(watermark); - - pgm_freearray(input_image, rows); - pgm_freearray(orig_image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_kim_e.c --- a/Meerwald/wm_kim_e.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,289 +0,0 @@ -#include "wm.h" -#include "dwt.h" -#include "pgm.h" -#include "dwt_util.h" -#include "kim_common.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-A n] [-e n] [-f n] [-F n] [-h] [-l n] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor/embedding strength for detail subbands\n"); - fprintf(stderr, "\t-a n\t\talpha factor/embedding strength for approximation subband\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-l n\t\tdecomposition level\n"); - fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int mark_subband(Image_tree s, int name, double alpha, double watermark[], double threshold, int w, int n, int verbose) { - int i, j; - - for (i = 5; i < s->image->height-5; i++) - for (j = 5; j < s->image->width-5; j++) { - double coeff, newcoeff; - - coeff = get_pixel(s->image, i, j); - if (fabs(coeff) > threshold) { - newcoeff = coeff + alpha * coeff * watermark[w % n]; - set_pixel(s->image, i, j, newcoeff); - - if (verbose >= 9) - fprintf(stderr, "%s: (%d/%d) %f: %f -> %f\n", progname, j, i, watermark[w % n], coeff, newcoeff); - - w++; - } - } - - if (verbose > 5) - fprintf(stderr, "%s: watermarking %s%d, size %d x %d; embedded %d coeffs. total\n", - progname, subband_name(name), s->level, s->image->width, s->image->height, w); - - return w; -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int i, c, w; - int row; - - int n; - - double alpha_detail = 0.0; - double alpha_approx = 0.0; - int level = 0; - - int filter = 0; - int method = -1; - int levels; - char filter_name[MAXPATHLEN] = ""; - - int verbose = 0; - - gray **image; - Image_tree p, dwts; - - gray maxval; - int rows, cols, format; - - double *watermark; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "a:A:e:f:F:h?o:l:s:v:")) != EOF) { - switch (c) { - case 'a': - alpha_detail = atof(optarg); - if (alpha_detail <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha_detail); - exit(1); - } - break; - case 'A': - alpha_approx = atof(optarg); - if (alpha_approx <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha_approx); - exit(1); - } - break; - case 'l': - level = atoi(optarg); - if (level <= 0) { - fprintf(stderr, "%s: decomposition level %d out of range\n", progname, level); - exit(1); - } - break; - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "KISG") >= 4) { - fscanf(sig, "%d\n", &n); - if (alpha_detail == 0.0) - fscanf(sig, "%lf\n", &alpha_detail); - else - fscanf(sig, "%*f\n"); - if (alpha_approx == 0.0) - fscanf(sig, "%lf\n", &alpha_approx); - else - fscanf(sig, "%*f\n"); - if (level == 0) - fscanf(sig, "%d\n", &level); - else - fscanf(sig, "%*d\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - watermark = malloc(n * sizeof(double)); - for (i = 0; i < n; i++) - fscanf(sig, "%lf\n", &watermark[i]); - fclose(sig); - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - image = pgm_allocarray(cols, rows); - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - fclose(in); - - // complete decomposition - levels = find_deepest_level(cols, rows) - 1; - if (level > levels) { - fprintf(stderr, "%s: decomposition level %d not possible (max. %d), image size is %d x %d\n", progname, level, levels, cols, rows); - exit(1); - } - - // wavelet transform - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - dwts = fdwt(image); - - p = dwts; - w = 0; - - // process each decomposition level - while (p->coarse) { - int current_level; - double threshold; - double max_coeff; - double alpha; - - // get current decomposition level number - current_level = p->horizontal->level; - - // find largest absolute coefficient in detail subbands of current decomposition level - max_coeff = find_level_largest_coeff(p, verbose); - - // calculate significance threshold for current decomposition level - threshold = calc_level_threshold(max_coeff, verbose); - - // calculate embedding strength alpha for current decomposition level - alpha = calc_level_alpha_detail(alpha_detail, level, current_level, verbose); - - if (verbose > 1) - fprintf(stderr, "%s: level %d, threshold %f, alpha %f\n", progname, current_level, threshold, alpha); - - // embed watermark sequence into detail subbands of current decomposition level - w = mark_subband(p->horizontal, HORIZONTAL, alpha, watermark, threshold, w, n, verbose); - w = mark_subband(p->vertical, VERTICAL, alpha, watermark, threshold, w, n, verbose); - w = mark_subband(p->diagonal, DIAGONAL, alpha, watermark, threshold, w, n, verbose); - - p = p->coarse; - } - - // mark approximation image using calculated significance threshold and embedding strength - w = mark_subband(p, COARSE, alpha_approx, watermark, calc_level_threshold(find_subband_largest_coeff(p, COARSE, verbose), verbose), w, n, verbose); - - free(watermark); - idwt(dwts, image); - - pgm_writepgminit(out, cols, rows, maxval, 0); - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, image[row], cols, maxval, 0); - fclose(out); - - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_koch_d.1 --- a/Meerwald/wm_koch_d.1 Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,114 +0,0 @@ -.\" -.\" wm_koch_d.1 - the *roff document processor man page source -.\" -.TH wm_koch_d 1 "98/07/05" "Watermarking, Version 1.0" -.SH NAME -.B wm_koch_d -\- a program to extract signature bits that have been embedded into -the DCT coefficients of an image -.SH SYNOPSIS -.B wm_koch_d -[ -.B \-h -] -[ -.BI \-o \ ofile -] -[ -.BI \-q \ number -] -[ -.BI \-v \ number -] -.BI \-s \ sfile -.IR file -.SH DESCRIPTION -.B wm_koch_d -is a program to extract signature bits from the 8x8 DCT coefficients of -an image, embedded with the -.B wm_koch_e -watermarking program. -.B cmp_koch_sig -program compares and tests the extracted signature against the original signature. -.PP -The input image is in PGM (portable graymap) format. -.PP -If -.I file -or -.I ofile -is not specified, then standard input or standard output is -used. The signature -.I sfile -is a mandatory parameter however. -.PP -Please refer to E. Koch's paper "Towards Robust and Hidden -Image Copyright", 1995, to get an idea about the algorithm. -.PP -.SH OPTIONS -.TP -.B \-h -Print a help message. -.TP -.BI \-o \ ofile -Output the extracted signature to -.I ofile -instead of standard output. -.TP -.BI \-q \ number -Quality/robustness factor used to extract the signature. -Overrides setting from signature file. -.TP -.BI \-s \ sfile -The original signature file. See -.B gen_koch_sig -(1) for a description of the file format. Mandatory parameter. -.BI \-v \ number -Verbosity level. 0 for quiet operation, higher numbers for more -output. Default value: 0. -.TP -.IR file -Signed (watermarked) input image in PGM format. Default: standard input. -.PP -.SH OUTPUT -The extracted signature is written to standard output -or, optionally, to -.I ofile. -.PP -The extraction algorithm examines the relationship between two random -coefficients of randomly selected 8x8 DCT blocks to reconstruct the -signature bits. -.PP -The output file has the following format: -.TP -.B KCSG -Magic to identify file type. -.TP -.I number -The length of the signature in bits. -.TP -.I number -The quality/robustness factor. -.TP -.I number -The seed value for the pseudo-random number generator. -.TP -.I string -The actual signature bytes. -.PP -.SH AUTHOR -Peter Meerwald. -Email bug reports to pmeerw@cosy.sbg.ac.at. -.SH AVAILABILITY -The most recent released version of -.B wm_koch_d -is always available -at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the -directory /pub/people/pmeerw/Watermarking. -.SH "SEE ALSO" -.BR gen_koch_sig -(1), -.BR wm_koch_e -(1), -.BR cmp_koch_sig -(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_koch_d.c --- a/Meerwald/wm_koch_d.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,234 +0,0 @@ -#include "wm.h" -#include "dct.h" -#include "signature.h" -#include "coord.h" -#include "pgm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-h] [-l n] [-o file] [-q n] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-l n\t\tsignature robustness factor\n"); - fprintf(stderr, "\t-o file\t\textracted signature file\n"); - fprintf(stderr, "\t-q n\t\tquantization (JPEG quality) factor\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - gray **image; - struct coords *coords; - - char signature_name[MAXPATHLEN]; - char input_name[MAXPATHLEN] = "(stdin)"; - char output_name[MAXPATHLEN] = "(stdout)"; - - int c; - int n; - - int rows, cols, format; - gray maxval; - int row; - - int seed; - int verbose = 0; - - double quality = 0.0; - int quantization = 0; - - double **dcts; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "h?i:l:o:q:s:v:")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'l': - quality = atof(optarg); - if (quality <= 0.0) { - fprintf(stderr, "%s: signature strength factor %f out of range\n", progname, quality); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'q': - quantization = atoi(optarg); - if (quantization <= 0 || quantization > 100) { - fprintf(stderr, "%s: quantization factor %d out of range\n", progname, quantization); - exit(1); - } - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[128]; - fgets(line, sizeof(line), sig); - if (strspn(line, "KCSG") >= 4) { - fscanf(sig, "%d\n", &nbit_signature); - n_signature = NBITSTOBYTES(nbit_signature); - if (quality == 0.0) - fscanf(sig, "%lf\n", &quality); - else - fscanf(sig, "%*f\n"); - if (quantization == 0) - fscanf(sig, "%d\n", &quantization); - else - fscanf(sig, "%*d\n"); - fscanf(sig, "%d\n", &seed); - srandom(seed); - fread(signature, sizeof(char), n_signature, sig); - init_signature_bits(); - fscanf(sig, "\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - - if (cols % NJPEG) { - fprintf(stderr, "%s: image width %d not a multiple of %d\n", progname, cols, NJPEG); - exit(1); - } - - if (rows % NJPEG) { - fprintf(stderr, "%s: image height %d not a multiple of %d\n", progname, rows, NJPEG); - exit(1); - } - - if ((rows * cols) / (NJPEG * NJPEG) < nbit_signature) { - fprintf(stderr, "%s: image too small to extract %d bits of signature\n", progname, nbit_signature); - exit(1); - } - - init_dct_8x8(); - init_quantum_JPEG_lumin(quantization); - - dcts = alloc_coeffs_8x8(); - - if ((coords = alloc_coords(nbit_signature)) == NULL) { - fprintf(stderr, "%s: unable to allocate memory\n", progname); - exit(1); - } - - image = pgm_allocarray(cols, rows); - - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - - fclose(in); - - n = 0; - while (n < nbit_signature) { - int xb; - int yb; - int c1, c2; - double v1, v2; - - do { - xb = random() % (cols / NJPEG); - yb = random() % (rows / NJPEG); - } while (add_coord(coords, xb, yb) < 0); - - fdct_block_8x8(image, xb * NJPEG, yb * NJPEG, dcts); - - do { - c1 = (random() % (NJPEG * NJPEG - 2)) + 1; - c2 = (random() % (NJPEG * NJPEG - 2)) + 1; - } while (c1 == c2 || !is_middle_frequency_coeff_8x8(c1) || !is_middle_frequency_coeff_8x8(c2)); - - quantize_8x8(dcts); - - if (verbose >= 1) - fprintf(stderr, "%d: quantized DCT block (x %d/y %d), extracting (x %d/y %d), (x %d/y %d) ", n, xb * NJPEG, yb * NJPEG, c1 % NJPEG, c1 / NJPEG, c2 % NJPEG, c2 / NJPEG); - - v1 = dcts[c1 / NJPEG][c1 % NJPEG]; - v2 = dcts[c2 / NJPEG][c2 % NJPEG]; - - if (fabs(v1) > fabs(v2)) { - set_signature_bit(n, 1); - if (verbose >= 1) - fprintf(stderr, "HIGH\n"); - } - else { - set_signature_bit(n, 0); - if (verbose >= 1) - fprintf(stderr, "LOW\n"); - } - - if (verbose >= 2) - print_coeffs_8x8(dcts); - - n++; - } - - fprintf(out, "KCWM\n"); - fprintf(out, "%d\n", nbit_signature); - fwrite(signature, sizeof(char), n_signature, out); - fprintf(out, "\n"); - - fclose(out); - - free_coeffs(dcts); - - pbm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_koch_e.1 --- a/Meerwald/wm_koch_e.1 Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -.\" -.\" wm_koch_e.1 - the *roff document processor man page source -.\" -.TH wm_koch_e 1 "98/07/05" "Watermarking, Version 1.0" -.SH NAME -.B wm_koch_e -\- a program to embed signature bits in the DCT coefficients of an image -.SH SYNOPSIS -.B wm_koch_e -[ -.B \-h -] -[ -.BI \-o \ ofile -] -[ -.BI \-q \ number -] -[ -.BI \-v \ number -] -.BI \-s \ sfile -.IR file -.SH DESCRIPTION -.B wm_koch_e -is a program to embed signature bits in 8x8 DCT coefficients of -an image. The signature has to be generated by the -.B gen_koch_sig -program. The -.B wm_koch_d -program is used to extract a signature from a signed (watermarked) image. The -.B cmp_koch_sig -program compares and tests the extracted signature against the original signature. -.PP -Both, input and output image, -are in PGM (portable graymap) format. -.PP -If -.I file -or -.I ofile -is not specified, then standard input or standard output is -used. The signature -.I sfile -is a mandatory parameter however. -.PP -Please refer to E. Koch's paper "Towards Robust and Hidden -Image Copyright", 1995, to get an idea about the algorithm. -.PP -.SH OPTIONS -.TP -.B \-h -Print a help message. -.TP -.BI \-o \ ofile -Output signed (watermarked) image to -.I ofile -instead of standard output. -.TP -.BI \-q \ number -Quality/robustness factor used to embed signature into image. -Overrides setting from signature file. -.TP -.BI \-s \ sfile -The signature file to embed into image. See -.B gen_koch_sig -(1) for a description of the file format. Mandatory parameter. -.TP -.BI \-v \ number -Verbosity level. 0 for quiet operation, higher numbers for more -output. Default value: 0. -.TP -.IR file -Input image in PGM format to sign (watermark). Default: standard input. -.PP -.SH OUTPUT -The signed (watermarked) image in PGM format is written to standard output -or, optionally, to -.I ofile. -.PP -Two coefficients of an 8x8 DCT block are selected at random to embed a -single signature bit. -.PP -.SH AUTHOR -Peter Meerwald. Email bug reports to pmeerw@cosy.sbg.ac.at. -.SH AVAILABILITY -The most recent released version of -.B wm_koch_e -is always available -at http://www.cosy.sbg.ac.at/~pmeerw/Watermarking or via anonymous ftp from ftp.cosy.sbg.ac.at in the -directory /pub/people/pmeerw/Watermarking. -.SH "SEE ALSO" -.BR gen_koch_sig -(1), -.BR wm_koch_d -(1), -.BR cmp_koch_sig -(1) diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_koch_e.c --- a/Meerwald/wm_koch_e.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,354 +0,0 @@ -#include "wm.h" -#include "dct.h" -#include "signature.h" -#include "coord.h" -#include "gray.h" -#include "pgm.h" - -char *progname; - -double sign(double x) { - if (x >= 0.0) return 1.0; - else return -1.0; -} - -double try_modif(gray **image_block, double **dcts, int c1, int c2, double w1, double w2) { - int i, j; - gray **altered_block; - double **altered_dcts; - double sum; - - altered_block = alloc_grays_8x8(); - altered_dcts = alloc_coeffs_8x8(); - - for (i = 0; i < 8; i++) { - memcpy(altered_dcts[i], dcts[i], sizeof(double) * 8); - } - - // put the changed coefficients back to black - altered_dcts[c1 / NJPEG][c1 % NJPEG] = w1; - altered_dcts[c2 / NJPEG][c2 % NJPEG] = w2; - - dequantize_8x8(altered_dcts); - - idct_block_8x8(altered_dcts, altered_block, 0, 0); - - // compute MSE - sum = 0.0; - for (i = 0; i < 8; i++) { - for (j = 0; j < 8; j++) { - double ib = image_block[i][j]; - double ab = altered_block[i][j]; - sum += (ib - ab) * (ib - ab); - } - } - sum /= 64.0; - - free(altered_block); - free(altered_dcts); - - return sum; -} - -void usage(void) { - fprintf(stderr, "usage: %s [-h] [-l n] [-o file] [-q n] [-v n] -s file file\n", progname); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-l n\t\tsignature robustness factor\n"); - fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); - fprintf(stderr, "\t-q n\t\tquantization (JPEG quality) factor\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char signature_name[MAXPATHLEN]; - char input_name[MAXPATHLEN] = "(stdin)"; - char output_name[MAXPATHLEN] = "(stdout)"; - - int c; - int n; - - int seed; - int verbose = 0; - - int rows, cols, format; - gray maxval; - int row; - - int quantization = 0; - double quality = 0.0; - - struct coords *coords; - - gray **image; - double **dcts; - gray **image_block; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "h?i:l:o:q:s:v:")) != EOF) { - switch (c) { - case 'h': - case '?': - usage(); - break; - case 'l': - quality = atof(optarg); - if (quality <= 0.0) { - fprintf(stderr, "%s: signature strength factor %f out of range\n", progname, quality); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'q': - quantization = atoi(optarg); - if (quantization <= 0 || quantization > 100) { - fprintf(stderr, "%s: quantization factor %d out of range\n", progname, quantization); - exit(1); - } - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[128]; - fgets(line, sizeof(line), sig); - if (strspn(line, "KCSG") >= 4) { - fscanf(sig, "%d\n", &nbit_signature); - if (quality == 0.0) - fscanf(sig, "%lf\n", &quality); - else - fscanf(sig, "%*f\n"); - if (quantization == 0) - fscanf(sig, "%d\n", &quantization); - else - fscanf(sig, "%*d\n"); - fscanf(sig, "%d\n", &seed); - n_signature = NBITSTOBYTES(nbit_signature); - fread(signature, sizeof(char), n_signature, sig); - fscanf(sig, "\n"); - srandom(seed); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - - if (cols % NJPEG) { - fprintf(stderr, "%s: image width %d not a multiple of %d\n", progname, cols, NJPEG); - exit(1); - } - - if (rows % NJPEG) { - fprintf(stderr, "%s: image height %d not a multiple of %d\n", progname, rows, NJPEG); - exit(1); - } - - if ((cols * rows) / (NJPEG * NJPEG) < nbit_signature) { - fprintf(stderr, "%s: image not large enough to embed %d bits of signature\n", progname, nbit_signature); - exit(1); - } - - init_dct_8x8(); - init_quantum_JPEG_lumin(quantization); - - dcts = alloc_coeffs_8x8(); - image_block = alloc_grays_8x8(); - - if ((coords = alloc_coords(nbit_signature)) == NULL) { - fprintf(stderr, "%s: unable to allocate memory\n", progname); - exit(1); - } - - image = pgm_allocarray(cols, rows); - - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - - fclose(in); - - // embedding signature bits by modifying two coefficient relationship, - // one bit for each block - n = 0; - while (n < nbit_signature) { - int xb; - int yb; - int c1, c2; - double v1, v2; - double w1, w2; - double best_w1, best_w2; - double diff; - double mod; - double try; - double best_mse; - int no_mse_opt = 0; - - // randomly select a block, check to get distinct blocks - // (don't watermark a block twice) - do { - xb = random() % (cols / NJPEG); - yb = random() % (rows / NJPEG); - } while (add_coord(coords, xb, yb) < 0); - - // do the forward 8x8 DCT of that block - fdct_block_8x8(image, xb * NJPEG, yb * NJPEG, dcts); - - copy_grays_to_block(image_block, image, xb*NJPEG, yb*NJPEG, NJPEG, NJPEG); - - // randomly select two distinct coefficients from block - // only accept coefficients in the middle frequency range - do { - c1 = (random() % (NJPEG * NJPEG - 2)) + 1; - c2 = (random() % (NJPEG * NJPEG - 2)) + 1; - } while (c1 == c2 || !is_middle_frequency_coeff_8x8(c1) || !is_middle_frequency_coeff_8x8(c2)); - - // quantize block according to quantization quality parameter - quantize_8x8(dcts); - - if (verbose > 0) - fprintf(stderr, "%d: quantized DCT block (x %d/y %d), modifying (x %d/y %d), (x %d/y %d) for %s\n", n, xb * NJPEG, yb * NJPEG, c1 % NJPEG, c1 / NJPEG, c2 % NJPEG, c2 / NJPEG, get_signature_bit(n) ? "HIGH" : "LOW"); - if (verbose > 5) - print_coeffs_8x8(dcts); - - v1 = dcts[c1 / NJPEG][c1 % NJPEG]; - v2 = dcts[c2 / NJPEG][c2 % NJPEG]; - - best_w1 = DBL_MAX, best_w2 = DBL_MAX; - try = 0.0; - best_mse = DBL_MAX; - - diff = fabs(v1) - fabs(v2); - - if (get_signature_bit(n)) - mod = fabs(quality - ( fabs(v1) - fabs(v2) )); - else - mod = fabs(quality - (fabs(v2) - fabs(v1))); - - if (verbose > 2) - fprintf(stderr, "%d / %d: %.2f %.2f %.2f | %d\n", xb, yb, diff, v1, v2, get_signature_bit(n)); - - while (try <= mod) { - w1 = v1; - w2 = v2; - - // modify coefficient's relationship to embed signature bit - // using mean square error to minimize error - if (get_signature_bit(n)) { - if (diff < quality) { - // we have to impose the relationship, does not occur naturally - w1 = sign(v1)*(fabs(v1) + mod - try); - w2 = sign(v2)*(fabs(v2) - try); - } - } - else { - if (diff > -quality) { - // force the relationship - w2 = sign(v2)*(fabs(v2) + mod - try); - w1 = sign(v1)*(fabs(v1) - try); - } - } - - double mse = try_modif(image_block, dcts, c1, c2, w1, w2); - if (mse < best_mse) { - best_w1 = w1; - best_w2 = w2; - best_mse = mse; - } - - if (verbose > 2) - fprintf(stderr, "%d / %d: MSE %.2f %.2f; %.2f: %.2f %.2f\n", xb, yb, mse, best_mse, try, w1, w2); - - if (fabs(mse) == 1e-3) - break; - - if (fabs(fabs(w1) - fabs(w2) + quality) > 1e-3) - break; - - if (no_mse_opt) - break; - - try += 0.05; - } - - if (verbose > 1) - fprintf(stderr, " %f -> %f, %f -> %f\n", v1, best_w1, v2, best_w2); - - // put the changed coefficients back to black - dcts[c1 / NJPEG][c1 % NJPEG] = best_w1; - dcts[c2 / NJPEG][c2 % NJPEG] = best_w2; - - // the obvious :-) - dequantize_8x8(dcts); - - // do the inverse DCT on the modified 8x8 block - idct_block_8x8(dcts, image, xb * NJPEG, yb * NJPEG); - - n++; - } - - free_grays(image_block); - free_coeffs(dcts); - - pgm_writepgminit(out, cols, rows, maxval, 0); - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, image[row], cols, maxval, 0); - - fclose(out); - - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_kund2_d.c --- a/Meerwald/wm_kund2_d.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,315 +0,0 @@ -#include "wm.h" -#include "signature.h" -#include "dwt.h" -#include "pgm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-e n] [-f n] [-F n] [-h] [-l n] [-o file] [-q n] [-s file] [-v n] file\n\n", progname); - fprintf(stderr, "\t-a n\t\toverall embedding strength\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-l n\t\tembedding level\n"); - fprintf(stderr, "\t-o file\t\textracted signature file\n"); - fprintf(stderr, "\t-q n\t\tsignature strength\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - gray **input_image; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - - int r, c; - int quality = 0; - int blocksize = 0; - int seed = 0; - int n = 0; - int method = -1; - int filter = 0; - char filter_name[MAXPATHLEN] = ""; - char *binstr; - - int level = 0; - double alpha = 0.0; - - int in_rows, in_cols, in_format; - gray in_maxval; - int rows, cols; - int row, col; - - Image_tree dwts, p; - - int verbose = 0; - - progname = argv[0]; - - pgm_init(&argc, argv); - wm_init(); - - while ((c = getopt(argc, argv, "a:e:f:F:h?l:o:q:s:v:")) != EOF) { - switch (c) { - case 'a': - alpha = atof(optarg); - break; - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'l': - level = atoi(optarg); - if (level < 1) { - fprintf(stderr, "%s: embedding level out of range\n", progname); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'q': - quality = atoi(optarg); - if (quality < 1) { - fprintf(stderr, "%s: quality level %d out of range\n", progname, quality); - exit(1); - } - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[1024]; - fgets(line, sizeof(line), sig); - if (strspn(line, "KD2SG") >= 5) { - fscanf(sig, "%d\n", &nbit_signature); - if (quality == 0) - fscanf(sig, "%d\n", &quality); - else - fscanf(sig, "%*d\n"); - if (blocksize == 0) - fscanf(sig, "%d\n", &blocksize); - else - fscanf(sig, "%*d\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - if (level == 0) - fscanf(sig, "%d\n", &level); - else - fscanf(sig, "%*d\n"); - fscanf(sig, "%d\n", &seed); - srandom(seed); - nbit_signature2 = nbit_signature; - n_signature = n_signature2 = NBITSTOBYTES(nbit_signature2); - binstr = malloc((nbit_signature2 + 1) * sizeof(char)); - fscanf(sig, "%[01]\n", binstr); - binstr_to_sig2(binstr); - free(binstr); - init_signature_bits(); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); - - cols = in_cols; - rows = in_rows; - - if (verbose > 0) - fprintf(stderr, "%s: extracting %d bits with quality %d from\n" - " %d x %d host image, decomposition level %d\n", - progname, nbit_signature, quality, cols, rows, level); - - input_image = pgm_allocarray(in_cols, in_rows); - - for (row = 0; row < in_rows; row++) - pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); - - fclose(in); - - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - fprintf(out, "KD2WM\n"); - fprintf(out, "%d\n", nbit_signature); - - dwts = fdwt(input_image); - - - p = dwts; - - // consider each resolution level - while (p->coarse->level < level) { - int lwidth = p->vertical->image->width; - int lheight = p->vertical->image->height; - int bx, by; - - for (bx = 0; bx < lwidth; bx += blocksize) { - for (by = 0; by < lheight; by += blocksize) { - int bw = MIN(bx + blocksize, lwidth); - int bh = MIN(by + blocksize, lheight); - int STEP; - - // start to extracting watermark from beginning at each level - // get width and height of detail images at current level - - if (verbose > 1) - fprintf(stderr, "%s: extracting at level %d now, size %d x %d\n", - progname, p->coarse->level, lwidth, lheight); - - STEP = ROUND(alpha * (-15.555) + 10.777); - n = 0; - // consider each coefficient at resolution level - for (row = by; row < bh - STEP; row += STEP) - for (col = bx; col < bw - STEP; col += STEP) { - double h, v, d; - double *f1 = &h, *f2 = &v, *f3 = &d; - double delta; - - // key-dependant coefficient selection - r = row + 1 + random() % (STEP-2); - c = col + 1 + random() % (STEP-2); - - // get coefficient values, one from each detail image - h = get_pixel(p->horizontal->image, c, r); - v = get_pixel(p->vertical->image, c, r); - d = get_pixel(p->diagonal->image, c, r); - - // order pointer to coefficient values such that f1 <= f2 <= f3 -#define SWAP(A, B) {double *t = A; A = B; B = t;} - if (*f1 > *f2) SWAP(f1, f2); - if (*f2 > *f3) SWAP(f2, f3); - if (*f1 > *f2) SWAP(f1, f2); - - // calculate delta, the width of the bins - delta = (*f3 - *f1) / (double) (2 * quality - 1); - - // set middle coefficient to closest appropriate bin, - // according to watermark bit - if (quality == 1) - set_signature_bit(n, (*f3 - *f2) < (*f2 - *f1)); - else { - double l = *f1; - int i = 0; - while ((l + delta) < *f2) { - l += delta; - i++; - } - if (i % 2) - set_signature_bit(n, (l + delta - *f2) > (*f2 - l)); - else - set_signature_bit(n, (l + delta - *f2) < (*f2 - l)); - } - - if (verbose > 2) - fprintf(stderr, "%s: extracted bit #%d (= %d =? %d) at (%d/%d),\n" - " f1=%lf, f2=%lf, f3=%lf\n", progname, n, - get_signature_bit(n), get_signature2_bit(n), - c, r, *f1, *f2, *f3); - n++; - } - - nbit_signature = n; - binstr = malloc(sizeof(char) * (nbit_signature + 1)); - sig_to_binstr(binstr); - fprintf(out, "%d\n", nbit_signature); - fprintf(out, "%s\n", binstr); - free(binstr); - - } - } - // descend one level - p = p->coarse; - } - - fclose(out); - - pgm_freearray(input_image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_kund2_e.c --- a/Meerwald/wm_kund2_e.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,331 +0,0 @@ -#include "wm.h" -#include "signature.h" -#include "dwt.h" -#include "pgm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-e n] [-f n] [-F n] [-h] [-l n] [-o file] [-q n] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-a n\t\toverall embedding strength\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-l n\t\tembedding level\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); - fprintf(stderr, "\t-q n\t\tsignature strength (default 4)\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - char *binstr; - - int r, c, n; - int row, col; - - int quality = 0; - int blocksize = 0; - int filter = 0; - int method = -1; - int level = 0; - char filter_name[MAXPATHLEN] = ""; - - double alpha = 0.0; - int seed; - int verbose = 0; - - gray **image; - Image_tree dwts, p; - - gray maxval; - int rows, cols, format; - - progname = argv[0]; - - pgm_init(&argc, argv); - wm_init(); - - while ((c = getopt(argc, argv, "a:e:f:F:h?l:o:q:s:v:")) != EOF) { - switch (c) { - case 'a': - alpha = atof(optarg); - break; - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'l': - level = atoi(optarg); - if (level < 1) { - fprintf(stderr, "%s: embedding level out of range\n", progname); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'q': - quality = atoi(optarg); - if (quality < 1) { - fprintf(stderr, "%s: quality factor %d out of range\n", progname, quality); - exit(1); - } - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[1024]; - fgets(line, sizeof(line), sig); - if (strspn(line, "KD2SG") >= 5) { - fscanf(sig, "%d\n", &nbit_signature); - if (quality == 0) - fscanf(sig, "%d\n", &quality); - else - fscanf(sig, "%*d\n"); - if (blocksize == 0) - fscanf(sig, "%d\n", &blocksize); - else - fscanf(sig, "%*d\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - if (level == 0) - fscanf(sig, "%d\n", &level); - else - fscanf(sig, "%*d\n"); - fscanf(sig, "%d\n", &seed); - srandom(seed); - n_signature = NBITSTOBYTES(nbit_signature); - binstr = malloc((nbit_signature + 1) * sizeof(char)); - fscanf(sig, "%[01]\n", binstr); - binstr_to_sig(binstr); - free(binstr); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - - if (verbose > 0) - fprintf(stderr, "%s: embedding %d bits with quality %d in\n" - " %d x %d host image, up to decomposition level %d\n", - progname, nbit_signature, quality, cols, rows, level); - - image = pgm_allocarray(cols, rows); - - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - - fclose(in); - - // decomposition of image - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - dwts = fdwt(image); - - p = dwts; - - // consider each resolution level - while (p->coarse->level < level) { - int lwidth = p->vertical->image->width; - int lheight = p->vertical->image->height; - int l = p->vertical->level; - int bx, by; - int nblock; - int bits_per_level; - - nblock = 0; - bits_per_level = 0; - for (bx = 0; bx < lwidth; bx += blocksize) { - for (by = 0; by < lheight; by += blocksize) { - int bw = MIN(bx + blocksize, lwidth); - int bh = MIN(by + blocksize, lheight); - int STEP; - float MIN_DIFF; - - // start to embed signature from beginning at each level - // get width and height of detail images at current level - - - if (verbose > 1) - fprintf(stderr, "%s: embedding at level %d now, block %d, size %d x %d at %d, %d\n", - progname, l, nblock, bw, bh, bx, by); - - MIN_DIFF = ROUND(120.0 * alpha); - STEP = ROUND(alpha * (-15.555) + 10.777); -// fprintf(stderr, "XXX %d %f\n", STEP, MIN_DIFF); - - n = 0; - // consider each coefficient at resolution level - for (row = by; row < bh - STEP; row += STEP) - for (col = bx; col < bw - STEP; col += STEP) { - double h, v, d; - double *f1 = &h, *f2 = &v, *f3 = &d; - double delta; - - // key-dependant coefficient selection - r = row + 1+random() % (STEP-2); - c = col + 1+random() % (STEP-2); - - // get coefficient values, one from each detail image - h = get_pixel(p->horizontal->image, c, r); - v = get_pixel(p->vertical->image, c, r); - d = get_pixel(p->diagonal->image, c, r); - - // order pointer to coefficient values such that f1 <= f2 <= f3 -#define SWAP(A, B) {double *t = A; A = B; B = t;} - if (*f1 > *f2) SWAP(f1, f2); - if (*f2 > *f3) SWAP(f2, f3); - if (*f1 > *f2) SWAP(f1, f2); - - if (verbose > 2) - fprintf(stderr, "%s: embedding bit #%d (= %d) at (%d/%d),\n", - progname, n, get_signature_bit(n % nbit_signature), c, r); - if (verbose > 5) - fprintf(stderr, " h=%lf, v=%lf, d=%lf\n", h, v, d); - if (verbose > 2) - fprintf(stderr, " f1=%lf, f2=%lf", *f1, *f2); - - if ((*f3 - *f1) < MIN_DIFF) { - double adj = (MIN_DIFF - (*f3 - *f1)) / 2.0; - *f1 -= adj; - *f3 += adj; - } - - // calculate delta, the width of the bins - delta = (*f3 - *f1) / (double) (2 * quality - 1); - - // set middle coefficient to closest appropriate bin, - // according to watermark bit - bits_per_level++; - if (quality == 1) - *f2 = get_signature_bit(n % nbit_signature) ? *f3 : *f1; - else { - double l = get_signature_bit(n % nbit_signature) ? *f1 + delta : *f1; - while ((l + 2 * delta) < *f2) l += 2 * delta; - *f2 = (*f2 - l) < (l + 2 * delta - *f2) ? l : l + 2 * delta; - } - - if (verbose > 2) - fprintf(stderr, " -> %lf, f3=%lf\n", *f2, *f3); - - // write pixels, one of them modified - set_pixel(p->horizontal->image, c, r, h); - set_pixel(p->vertical->image, c, r, v); - set_pixel(p->diagonal->image, c, r, d); - - n++; - - } - } - } - - if (verbose > 1) - fprintf(stderr, "%s: embedded %d bits at level %d\n", - progname, bits_per_level, l); - - // descend one level - p = p->coarse; - } - - idwt(dwts, image); - - pgm_writepgminit(out, cols, rows, maxval, 0); - - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, image[row], cols, maxval, 0); - - fclose(out); - - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_kund3_d.c --- a/Meerwald/wm_kund3_d.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,293 +0,0 @@ -#include "wm.h" -#include "signature.h" -#include "dwt.h" -#include "pgm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-e n] [-f n] [-F n] [-h] [-l n] [-o file] [-q n] [-s file] [-v n] file\n\n", progname); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-l n\t\tembedding level\n"); - fprintf(stderr, "\t-o file\t\textracted signature file\n"); - fprintf(stderr, "\t-q n\t\tsignature strength\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - gray **input_image; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - - int r, c; - int quality = 0; - int seed = 0; - int n = 0; - int method = -1; - int filter = 0; - char filter_name[MAXPATHLEN] = ""; - - char *binstr; - - int level = 0; - - int in_rows, in_cols, in_format; - gray in_maxval; - int rows, cols; - int row, col; - - Image_tree dwts, p; - - int verbose = 0; - - progname = argv[0]; - - pgm_init(&argc, argv); - wm_init(); - - while ((c = getopt(argc, argv, "e:f:F:h?l:o:q:s:v:")) != EOF) { - switch (c) { - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'l': - level = atoi(optarg); - if (level < 1) { - fprintf(stderr, "%s: embedding level out of range\n", progname); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'q': - quality = atoi(optarg); - if (quality < 1) { - fprintf(stderr, "%s: quality level %d out of range\n", progname, quality); - exit(1); - } - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "KD3SG") >= 5) { - fscanf(sig, "%d\n", &nbit_signature); - if (quality == 0) - fscanf(sig, "%d\n", &quality); - else - fscanf(sig, "%*d\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - if (level == 0) - fscanf(sig, "%d\n", &level); - else - fscanf(sig, "%*d\n"); - fscanf(sig, "%d\n", &seed); - srandom(seed); - nbit_signature2 = nbit_signature; - n_signature = n_signature2 = NBITSTOBYTES(nbit_signature2); - binstr = malloc((nbit_signature2 + 1) * sizeof(char)); - fscanf(sig, "%[01]\n", binstr); - binstr_to_sig2(binstr); - free(binstr); - init_signature_bits(); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); - - cols = in_cols; - rows = in_rows; - - if (verbose > 0) - fprintf(stderr, "%s: extracting %d bits with quality %d from\n" - " %d x %d host image, decomposition level %d\n", - progname, nbit_signature, quality, cols, rows, level); - - input_image = pgm_allocarray(in_cols, in_rows); - - for (row = 0; row < in_rows; row++) - pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); - - fclose(in); - - init_dwt(cols, rows, filter_name, filter, level, method); -/*#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif*/ - - dwts = fdwt(input_image); - - p = dwts; - -#define STEP 3 - - // consider each resolution level - while (p->coarse->level < level) - // descend one level - p = p->coarse; - - // start to extracting watermark from beginning at each level - { - // get width and height of detail images at current level - int lwidth = p->vertical->image->width; - int lheight = p->vertical->image->height; - - if (verbose > 1) - fprintf(stderr, "%s: extracting at level %d now, size %d x %d\n", - progname, p->coarse->level, lwidth, lheight); - - // consider each coefficient at resolution level - for (row = 0; row < lwidth - STEP; row += STEP) - for (col = 0; col < lheight - STEP; col += STEP) { - double h, v, d; - double *f1 = &h, *f2 = &v, *f3 = &d; - double delta; - - // key-dependant coefficient selection - r = row + 1 + random() % (STEP-2); - c = col + 1 + random() % (STEP-2); - - // get coefficient values, one from each detail image - h = get_pixel(p->horizontal->image, c, r); - v = get_pixel(p->vertical->image, c, r); - d = get_pixel(p->diagonal->image, c, r); - - // order pointer to coefficient values such that f1 <= f2 <= f3 -#define SWAP(A, B) {double *t = A; A = B; B = t;} - if (*f1 > *f2) SWAP(f1, f2); - if (*f2 > *f3) SWAP(f2, f3); - if (*f1 > *f2) SWAP(f1, f2); - - // calculate delta, the width of the bins - delta = (*f3 - *f1) / (double) (2 * quality - 1); - - // set middle coefficient to closest appropriate bin, - // according to watermark bit - if (quality == 1) - set_signature_bit(n, (*f3 - *f2) < (*f2 - *f1)); - else { - double l = *f1; - int i = 0; - while ((l + delta) < *f2) { - l += delta; - i++; - } - if (i % 2) - set_signature_bit(n, (l + delta - *f2) > (*f2 - l)); - else - set_signature_bit(n, (l + delta - *f2) < (*f2 - l)); - } - - if (verbose > 2) - fprintf(stderr, "%s: extracted bit #%d (= %d =? %d) at (%d/%d),\n" - " f1=%lf, f2=%lf, f3=%lf\n", progname, n, - get_signature_bit(n), get_signature2_bit(n), - c, r, *f1, *f2, *f3); - n++; - } - } - - fprintf(out, "KD3WM\n"); - fprintf(out, "%d\n", n); - nbit_signature = n; - binstr = malloc(sizeof(char) * (nbit_signature + 1)); - sig_to_binstr(binstr); - fprintf(out, "%s\n", binstr); - free(binstr); - fclose(out); - - pgm_freearray(input_image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_kund3_e.c --- a/Meerwald/wm_kund3_e.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,299 +0,0 @@ -#include "wm.h" -#include "signature.h" -#include "dwt.h" -#include "pgm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-e n] [-f n] [-F n] [-h] [-l n] [-o file] [-q n] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-l n\t\tembedding level\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); - fprintf(stderr, "\t-q n\t\tsignature strength (default 4)\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - char *binstr; - - int r, c, n; - int row, col; - - int quality = 0; - - int filter = 0; - int method = -1; - int level = 0; - char filter_name[MAXPATHLEN] = ""; - - int seed; - int verbose = 0; - - gray **image; - Image_tree dwts, p; - - gray maxval; - int rows, cols, format; - - progname = argv[0]; - - pgm_init(&argc, argv); - wm_init(); - - while ((c = getopt(argc, argv, "e:f:F:h?l:o:q:s:v:")) != EOF) { - switch (c) { - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'l': - level = atoi(optarg); - if (level < 1) { - fprintf(stderr, "%s: embedding level out of range\n", progname); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'q': - quality = atoi(optarg); - if (quality < 1) { - fprintf(stderr, "%s: quality factor %d out of range\n", progname, quality); - exit(1); - } - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "KD3SG") >= 5) { - fscanf(sig, "%d\n", &nbit_signature); - if (quality == 0) - fscanf(sig, "%d\n", &quality); - else - fscanf(sig, "%*d\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - if (level == 0) - fscanf(sig, "%d\n", &level); - else - fscanf(sig, "%*d\n"); - fscanf(sig, "%d\n", &seed); - srandom(seed); - n_signature = NBITSTOBYTES(nbit_signature); - binstr = malloc((nbit_signature + 1) * sizeof(char)); - fscanf(sig, "%[01]\n", binstr); - binstr_to_sig(binstr); - free(binstr); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - - if (verbose > 0) - fprintf(stderr, "%s: embedding %d bits with quality %d in\n" - " %d x %d host image, decomposition level %d\n", - progname, nbit_signature, quality, cols, rows, level); - - image = pgm_allocarray(cols, rows); - - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - - fclose(in); - - // decomposition of image - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - dwts = fdwt(image); - - p = dwts; - - // consider each resolution level - while (p->coarse->level < level) - // descend one level - p = p->coarse; - - // start to embed signature from beginning at each level - // get width and height of detail images at current level - { - int lwidth = p->vertical->image->width; - int lheight = p->vertical->image->height; - - if (verbose > 1) - fprintf(stderr, "%s: embedding at level %d now, size %d x %d\n", progname, - p->coarse->level, lwidth, lheight); - -#define STEP 3 - n = 0; - // consider each coefficient at resolution level - for (row = 0; row < lwidth - STEP; row += STEP) - for (col = 0; col < lheight - STEP; col += STEP) { - double h, v, d; - double *f1 = &h, *f2 = &v, *f3 = &d; - double delta; - - // key-dependant coefficient selection - r = row + 1+random() % (STEP-2); - c = col + 1+random() % (STEP-2); - - // get coefficient values, one from each detail image - h = get_pixel(p->horizontal->image, c, r); - v = get_pixel(p->vertical->image, c, r); - d = get_pixel(p->diagonal->image, c, r); - - // order pointer to coefficient values such that f1 <= f2 <= f3 -#define SWAP(A, B) {double *t = A; A = B; B = t;} - if (*f1 > *f2) SWAP(f1, f2); - if (*f2 > *f3) SWAP(f2, f3); - if (*f1 > *f2) SWAP(f1, f2); - - if (verbose > 2) - fprintf(stderr, "%s: embedding bit #%d (= %d) at (%d/%d),\n", - progname, n, get_signature_bit(n % nbit_signature), c, r); - if (verbose > 5) - fprintf(stderr, " h=%lf, v=%lf, d=%lf\n", h, v, d); - if (verbose > 2) - fprintf(stderr, " f1=%lf, f2=%lf", *f1, *f2); - -#define MIN_DIFF 20.0 - if (*f3 - *f1 < MIN_DIFF) { - double adj = (MIN_DIFF - (*f3 - *f1)) / 2.0; - *f1 -= adj; - *f3 += adj; - } - - // calculate delta, the width of the bins - delta = (*f3 - *f1) / (double) (2 * quality - 1); - - // set middle coefficient to closest appropriate bin, - // according to watermark bit - if (quality == 1) - *f2 = get_signature_bit(n % nbit_signature) ? *f3 : *f1; - else { - double l = get_signature_bit(n % nbit_signature) ? *f1 + delta : *f1; - while ((l + 2 * delta) < *f2) l += 2 * delta; - *f2 = (*f2 - l) < (l + 2 * delta - *f2) ? l : l + 2 * delta; - } - - if (verbose > 2) - fprintf(stderr, " -> %lf, f3=%lf\n", *f2, *f3); - - // write pixels, one of them modified - set_pixel(p->horizontal->image, c, r, h); - set_pixel(p->vertical->image, c, r, v); - set_pixel(p->diagonal->image, c, r, d); - - n++; - - } - } - - idwt(dwts, image); - - pgm_writepgminit(out, cols, rows, maxval, 0); - - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, image[row], cols, maxval, 0); - - fclose(out); - - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_kund_d.c --- a/Meerwald/wm_kund_d.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2 +0,0 @@ -int main(int argc, char *argv[]) { -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_kund_e.c --- a/Meerwald/wm_kund_e.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,257 +0,0 @@ -#include "wm.h" -#include "signature.h" -#include "wm_dwt.h" -#include "pgm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-e n] [-f n] [-F n] [-h] [-o file] [-q n] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); - fprintf(stderr, "\t-q n\t\tquantization/quality factor\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int c; - int row, col; - - int n; - - double quality = 0.0; - - int filter = 0; - int method = -1; - int level = 0; - char filter_name[MAXPATHLEN] = ""; - - int seed; - int verbose = 0; - - gray **image; - Image_tree dwts; - - gray maxval; - int rows, cols, colors, format; - - progname = argv[0]; - - pgm_init(&argc, argv); - -#ifdef __EMX__ - _fsetmode(in, "b"); - _fsetmode(out, "b"); -#endif - - while ((c = getopt(argc, argv, "e:f:F:h?l:o:q:s:v:")) != EOF) { - switch (c) { - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'l': - level = atoi(optarg); - if (level < 1) { - fprintf(stderr, "%s: embedding level out of range\n", progname); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'q': - quality = atoi(optarg); - if (quality <= 0) { - fprintf(stderr, "%s: quality factor %d out of range\n", progname, quality); - exit(1); - } - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "KDSG") >= 4) { - fscanf(sig, "%d\n", &n); - if (quality == 0.0) - fscanf(sig, "%lf\n", &quality); - else - fscanf(sig, "%*f\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - if (level == 0) - fscanf(sig, "%d\n", &level); - else - fscanf(sig, "%*d\n"); - fscanf(sig, "%d\n", &seed); - srandom(seed); - n_signature = NBITSTOBYTES(nbit_signature); - fread(signature, sizeof(char), n_signature, sig); - fscanf(sig, "\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - - image = pgm_allocarray(cols, rows); - - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - - fclose(in); - - // check watermark dimensions and decomposition level - - - // decomposition of image - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF - { - double alpha, beta; - char *alpha_str = getenv("POLLEN_ALPHA"), *beta_str = getenv("POLLEN_BETA"); - - if (alpha_str && beta_str) { - alpha = atof(alpha_str); - beta = atof(beta_str); - - if (alpha < -M_PI || alpha >= M_PI) { - fprintf(stderr, "%s: pollen - alpha %f out of range\n", progname, alpha); - exit(1); - } - - if (beta < -M_PI || beta >= M_PI) { - fprintf(stderr, "%s: pollen - beta %f out of range\n", progname, beta); - exit(1); - } - - if (verbose > 7) - fprintf(stderr, "%s: pollen - alpha %f, beta %f\n", progname, alpha, beta); - - dwt_pollen_filter(alpha, beta); - } - } -#endif - - dwts = fdwt(image); - - // create 'image' from binary watermark - - // decomposition of watermark - init_dwt(cols, rows, filter_name, filter, 1, method); -// dwts = fdwt(watermark); - - // calculate mean value of image and set alpha - - // setup of contrast sensitivity matrix - - // segment detail images at each level - - // calculate DFT of each segment - - // compute salience for each segment - - // calculate gamma or each detail image - - // embed watermark - - // reconstruction of watermarked image - - idwt(dwts, image); - - pgm_writepgminit(out, cols, rows, maxval, 0); - - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, image[row], cols, maxval, 0); - - fclose(out); - - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_wang_d.c --- a/Meerwald/wm_wang_d.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,302 +0,0 @@ -#include "wm.h" -#include "dwt.h" -#include "wang_common.h" -#include "dwt_util.h" -#include "pgm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-b n] [-e n] [-f n] [-F file] [-h] [-n n] [-o file] [-v n] -s file -i file file\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor\n"); - fprintf(stderr, "\t-b n\t\tbeta factor\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-i file\t\toriginal image file\n"); - fprintf(stderr, "\t-n n\t\twatermark length\n"); - fprintf(stderr, "\t-o file\t\tfile for extracted watermark\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *orig = NULL; - FILE *sig = NULL; - - gray **input_image; - gray **orig_image; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char orig_name[MAXPATHLEN]; - - int c, w; - int n = 0; - int method = -1; - int filter = 0; - char filter_name[MAXPATHLEN] = ""; - - int level = 0; - double alpha = 0.0; - double beta = 0.0; - - int in_rows, in_cols, in_format; - gray in_maxval; - int orig_rows, orig_cols, orig_format; - gray orig_maxval; - int rows, cols; - int row; - - double *watermark; - - Image_tree input_dwts; - Image_tree orig_dwts; - - int verbose = 0; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init2(); - - while ((c = getopt(argc, argv, "a:b:e:f:F:h?i:n:o:s:v:")) != EOF) { - switch (c) { - case 'a': - alpha = atof(optarg); - if (alpha <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 'b': - beta = atof(optarg); - if (beta <= 0.0) { - fprintf(stderr, "%s: beta factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'i': - if ((orig = fopen(optarg, "rb")) == NULL) { - fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); - exit(1); - } - strcpy(orig_name, optarg); - break; - case 'n': - n = atoi(optarg); - if (n < 1 || n > 32000) { - fprintf(stderr, "%s: watermark length %d out of range\n", progname, n); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (!orig) { - fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); - exit(1); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "WGSG") >= 4) { - fscanf(sig, "%d\n", &n); - if (alpha == 0.0) - fscanf(sig, "%lf\n", &alpha); - else - fscanf(sig, "%*f\n"); - if (beta == 0.0) - fscanf(sig, "%lf\n", &beta); - else - fscanf(sig, "%*f\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - watermark = malloc(n * sizeof(double)); - - pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); - pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); - - if (in_cols != orig_cols || in_rows != orig_rows) { - fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); - exit(1); - } - - cols = in_cols; - rows = in_rows; - - input_image = pgm_allocarray(in_cols, in_rows); - - orig_image = pgm_allocarray(orig_cols, orig_rows); - - for (row = 0; row < in_rows; row++) { - pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); - pgm_readpgmrow(orig, orig_image[row], orig_cols, orig_maxval, orig_format); - } - - fclose(in); - fclose(orig); - - // complete decomposition - level = find_deepest_level(cols, rows) - 1; - - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - input_dwts = fdwt(input_image); - orig_dwts = fdwt(orig_image); - - // build tree for subband selection, calculate subband thresholds - init_subbands(orig_dwts); - set_subbands_type_beta(HORIZONTAL, beta); - set_subbands_type_beta(VERTICAL, beta); - calc_subbands_threshold(); - - fprintf(out, "WGWM\n"); - fprintf(out, "%d\n", n); - - w = 0; - while (w < n) { - Subband_data s; - - // select subband with max. threshold - s = select_subband(); - if (verbose > 1) - fprintf(stderr, "%s: selected subband %s%d, T=%lf, beta=%lf\n", progname, subband_name(s->type), s->level, s->T, s->beta); - - // watermark significant coefficients and set them selected - // check is entire signature has been embedded - c = select_subband_coeff(s); - do { - Pixel p; - Pixel q; - if (c < 0) - // no more significant coefficients in subband - break; - - p = get_subband_coeff(s, c); - if (p < s->Cmax) { - q = get_dwt_coeff(input_dwts, s->level, s->type, c); - watermark[w] = (q - p) / (alpha * s->beta * s->T); - fprintf(out, "%lf\n", watermark[w]); - - if (verbose > 2) - fprintf(stderr, "%s: detected sig. coeff. #%d (= %lf)\n from %s%d coeff. #%d\n", - progname, w, watermark[w], subband_name(s->type), s->level, c); - - w++; - } - mark_subband_coeff(s, c); - - // select next significant coefficient - c = select_subband_coeff_from(s, c); - } while (w < n); - - // update subband threshold - s->T /= 2.0; - - } - - fclose(out); - - free_subbands(); - - free(watermark); - - pgm_freearray(input_image, rows); - pgm_freearray(orig_image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_wang_e.c --- a/Meerwald/wm_wang_e.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,263 +0,0 @@ -#include "wm.h" -#include "dwt.h" -#include "wang_common.h" -#include "dwt_util.h" -#include "pgm.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-b n] [-e n] [-f n] [-F n] [-h] [-o file] [-v n] -s file file\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor/embedding strength\n"); - fprintf(stderr, "\t-b n\t\tsubband weighting factor\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int i, c, w; - int row; - - int n; - - double alpha = 0.0; - double beta = 0.0; - - int filter = 0; - int method = -1; - int level = 0; - char filter_name[MAXPATHLEN] = ""; - - int verbose = 0; - - gray **image; - Image_tree dwts; - - gray maxval; - int rows, cols, format; - - double *watermark; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "a:b:e:f:F:h?o:s:v:")) != EOF) { - switch (c) { - case 'a': - alpha = atof(optarg); - if (alpha <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 'b': - beta = atof(optarg); - if (beta <= 0.0) { - fprintf(stderr, "%s: beta factor %f out of range\n", progname, beta); - exit(1); - } - break; - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "WGSG") >= 4) { - fscanf(sig, "%d\n", &n); - if (alpha == 0.0) - fscanf(sig, "%lf\n", &alpha); - else - fscanf(sig, "%*f\n"); - if (beta == 0.0) - fscanf(sig, "%lf\n", &beta); - else - fscanf(sig, "%*f\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - watermark = malloc(n * sizeof(double)); - for (i = 0; i < n; i++) - fscanf(sig, "%lf\n", &watermark[i]); - fclose(sig); - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - - image = pgm_allocarray(cols, rows); - - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - - fclose(in); - - // complete decomposition - level = find_deepest_level(cols, rows) - 1; - - // wavelet transform - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - dwts = fdwt(image); - - // build tree for subband selection, calculate subband thresholds - init_subbands(dwts); - set_subbands_type_beta(HORIZONTAL, beta); - set_subbands_type_beta(VERTICAL, beta); - calc_subbands_threshold(); - - w = 0; - while (w < n) { - Subband_data s; - - // select subband with max. threshold - s = select_subband(); - if (verbose > 1) - fprintf(stderr, "%s: selected subband %s%d, T=%lf, beta=%lf\n", progname, subband_name(s->type), s->level, s->T, s->beta); - - // watermark significant coefficients and set them selected - // check is entire signature has been embedded - c = select_subband_coeff(s); - do { - double p; - if (c < 0) - // no more significant coefficients in subband - break; - - p = get_subband_coeff(s, c); - if (p < s->Cmax) { - if (verbose > 2) - fprintf(stderr, "%s: embedding sig. coeff. #%d (= %lf)\n into %s%d coeff. #%d\n", - progname, w, watermark[w], subband_name(s->type), s->level, c); - - p = p + alpha * s->beta * s->T * watermark[w]; - set_subband_coeff(s, c, p); - w++; - } - mark_subband_coeff(s, c); - - // select next significant coefficient - c = select_subband_coeff_from(s, c); - } while (w < n); - - // update subband threshold - s->T /= 2.0; - - } - - free_subbands(); - - free(watermark); - - idwt(dwts, image); - - pgm_writepgminit(out, cols, rows, maxval, 0); - - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, image[row], cols, maxval, 0); - - fclose(out); - - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_xia_d.c --- a/Meerwald/wm_xia_d.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,295 +0,0 @@ -#include "wm.h" -#include "dwt.h" -#include "pgm.h" -#include "dwt_util.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-e n] [-f n] [-F file] [-h] [-l n] [-o file] [-v n] -s file -i file file\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-i file\t\toriginal image file\n"); - fprintf(stderr, "\t-l n\t\tdecomposition level\n"); - fprintf(stderr, "\t-o file\t\tfile for extracted watermark\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int extract_subband(Image_tree s, Image_tree t, int name, double alpha, double watermark[], int n, int verbose) { - int i, j; - int w; - - w = 0; - for (i = 5; i < s->image->height-5; i++) - for (j = 5; j < s->image->width-5; j++) { - double input_coeff, orig_coeff; - - input_coeff = get_pixel(s->image, i, j); - orig_coeff = get_pixel(t->image, i, j); - if (fabs(orig_coeff) > 20.0) - watermark[w++] = (input_coeff - orig_coeff) / (alpha * pow(fabs(orig_coeff), 1.0 / 1.2)); - } - - if (verbose > 3) - fprintf(stderr, "%s: extracting %s%d, size %d x %d; extracted %d coeffs.\n", - progname, subband_name(name), s->level, s->image->width, s->image->height, w); - - return w; -} - -void write_mark(FILE *out, double watermark[], int n) { - int i; - - fprintf(out, "%d\n", n); - for (i = 0; i < n; i++) - fprintf(out, "%f\n", watermark[i]); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *orig = NULL; - FILE *sig = NULL; - - gray **input_image; - gray **orig_image; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char orig_name[MAXPATHLEN]; - - int c; - int n = 0; - int method = -1; - int filter = 0; - char filter_name[MAXPATHLEN] = ""; - - int level = 0, levels; - double alpha = 0.0; - - int in_rows, in_cols, in_format; - gray in_maxval; - int orig_rows, orig_cols, orig_format; - gray orig_maxval; - int rows, cols; - int row; - - double *watermark; - - Image_tree input_dwts, orig_dwts, p, q; - - int verbose = 0; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init2(); - - while ((c = getopt(argc, argv, "a:e:f:F:h?i:l:o:s:v:")) != EOF) { - switch (c) { - case 'a': - alpha = atof(optarg); - if (alpha <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'i': - if ((orig = fopen(optarg, "rb")) == NULL) { - fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); - exit(1); - } - strcpy(orig_name, optarg); - break; - case 'l': - level = atoi(optarg); - if (level <= 0) { - fprintf(stderr, "%s: decomposition level %d out of range\n", progname, level); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (!orig) { - fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); - exit(1); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "XASG") >= 4) { - fscanf(sig, "%d\n", &n); - if (alpha == 0.0) - fscanf(sig, "%lf\n", &alpha); - else - fscanf(sig, "%*f\n"); - if (level == 0) - fscanf(sig, "%d\n", &level); - else - fscanf(sig, "%*d\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); - pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); - - if (in_cols != orig_cols || in_rows != orig_rows) { - fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); - exit(1); - } - - cols = in_cols; - rows = in_rows; - - input_image = pgm_allocarray(in_cols, in_rows); - orig_image = pgm_allocarray(orig_cols, orig_rows); - - for (row = 0; row < in_rows; row++) { - pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); - pgm_readpgmrow(orig, orig_image[row], orig_cols, orig_maxval, orig_format); - } - - fclose(in); - fclose(orig); - - // complete decomposition - levels = find_deepest_level(cols, rows) - 1; - if (level > levels) { - fprintf(stderr, "%s: decomposition level %d not possible (max. %d), image size is %d x %d\n", progname, level, levels, cols, rows); - exit(1); - } - - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - input_dwts = fdwt(input_image); - orig_dwts = fdwt(orig_image); - - watermark = malloc((rows * cols / 4.0) * sizeof(double)); - if (!watermark) { - fprintf(stderr, "%s: malloc() failed\n\n", progname); - exit(1); - } - - fprintf(out, "XAWM\n"); - fprintf(out, "%d\n", n); - fprintf(out, "%d\n", level * 3); - - p = input_dwts; - q = orig_dwts; - while (p->coarse && q->coarse) { - int size; - - size = extract_subband(p->horizontal, q->horizontal, HORIZONTAL, alpha, watermark, n, verbose); - write_mark(out, watermark, size); - size = extract_subband(p->vertical, q->vertical, VERTICAL, alpha, watermark, n, verbose); - write_mark(out, watermark, size); - size = extract_subband(p->diagonal, q->diagonal, DIAGONAL, alpha, watermark, n, verbose); - write_mark(out, watermark, size); - - p = p->coarse; - q = q->coarse; - } - - fclose(out); - - free(watermark); - - pgm_freearray(input_image, rows); - pgm_freearray(orig_image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_xia_e.c --- a/Meerwald/wm_xia_e.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,244 +0,0 @@ -#include "wm.h" -#include "dwt.h" -#include "pgm.h" -#include "dwt_util.h" - -char *progname; - -void usage(void) { - 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); - fprintf(stderr, "\t-a n\t\talpha factor/embedding strength\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-l n\t\tdecomposition level\n"); - fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -void mark_subband(Image_tree s, int name, double alpha, double watermark[], int n, int verbose) { - int i, j; - int w; - - w = 0; - for (i = 5; i < s->image->height-5; i++) - for (j = 5; j < s->image->width-5; j++) { - double coeff, newcoeff; - - coeff = get_pixel(s->image, i, j); - if (fabs(coeff) > 20.0) { - newcoeff = coeff + alpha * pow(fabs(coeff), 1.2) * watermark[w++ % n]; - set_pixel(s->image, i, j, newcoeff); - } - } - - if (verbose > 3) - fprintf(stderr, "%s: watermarking %s%d, size %d x %d; embedded %d coeffs.\n", - progname, subband_name(name), s->level, s->image->width, s->image->height, w); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int i, c; - int row; - - int n; - - double alpha = 0.0; - int level = 0; - - int filter = 0; - int method = -1; - int levels; - char filter_name[MAXPATHLEN] = ""; - - int verbose = 0; - - gray **image; - Image_tree p, dwts; - - gray maxval; - int rows, cols, format; - - double *watermark; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "a:e:f:F:h?o:l:s:v:")) != EOF) { - switch (c) { - case 'a': - alpha = atof(optarg); - if (alpha <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 'l': - level = atoi(optarg); - if (level <= 0) { - fprintf(stderr, "%s: decomposition level %d out of range\n", progname, level); - exit(1); - } - break; - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "XASG") >= 4) { - fscanf(sig, "%d\n", &n); - if (alpha == 0.0) - fscanf(sig, "%lf\n", &alpha); - else - fscanf(sig, "%*f\n"); - if (level == 0) - fscanf(sig, "%d\n", &level); - else - fscanf(sig, "%*d\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - watermark = malloc(n * sizeof(double)); - for (i = 0; i < n; i++) - fscanf(sig, "%lf\n", &watermark[i]); - fclose(sig); - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - image = pgm_allocarray(cols, rows); - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - fclose(in); - - // complete decomposition - levels = find_deepest_level(cols, rows) - 1; - if (level > levels) { - fprintf(stderr, "%s: decomposition level %d not possible (max. %d), image size is %d x %d\n", progname, level, levels, cols, rows); - exit(1); - } - - // wavelet transform - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - dwts = fdwt(image); - - p = dwts; - while (p->coarse) { - - mark_subband(p->horizontal, HORIZONTAL, alpha, watermark, n, verbose); - mark_subband(p->vertical, VERTICAL, alpha, watermark, n, verbose); - mark_subband(p->diagonal, DIAGONAL, alpha, watermark, n, verbose); - - p = p->coarse; - } - - free(watermark); - idwt(dwts, image); - - pgm_writepgminit(out, cols, rows, maxval, 0); - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, image[row], cols, maxval, 0); - fclose(out); - - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_xie2_d.c --- a/Meerwald/wm_xie2_d.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,270 +0,0 @@ -#include "wm.h" -#include "signature.h" -#include "dwt.h" -#include "pgm.h" - -char *progname; - -// inverse watermarking transformation, extract embedded bit, check quantization boundaries -double wm_transform(int quant, double f1, double f2, double f3) { - double s = (fabs(f3) - fabs(f1)) / (double) quant; - double l = f1; - int x; - - x = 0; - while (l < f2) { - l += s; - x++; - } - - if (fabs(l - s - f2) < fabs(l-f2)) - return (x+1) % 2; - else - return (x) % 2; -} - -void usage(void) { - 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); - fprintf(stderr, "\t-a n\t\tembedding strength (default 0.05)\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-l n\t\tembedding level\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\textracted signature file\n"); - fprintf(stderr, "\t-q n\t\tquantization level\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int c, n; - int row, col; - - double alpha = 0.0; - int quant = 0; - int filter = 0; - int method = -1; - int level = 0; - char filter_name[MAXPATHLEN] = ""; - - int seed; - int verbose = 0; - - gray **image; - Image_tree dwts, p; - - gray maxval; - int rows, cols, format; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init2(); - - while ((c = getopt(argc, argv, "a:e:f:F:h?l:o:s:v:q:")) != EOF) { - switch (c) { - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'l': - level = atoi(optarg); - if (level < 1) { - fprintf(stderr, "%s: embedding level out of range\n", progname); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'q': - quant = atoi(optarg); - break; - case 'a': - alpha = atof(optarg); - if (alpha <= 0.0) { - fprintf(stderr, "%s: embedding strength factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "XE2SG") >= 5) { - fscanf(sig, "%d\n", &nbit_signature); - if (alpha == 0.0) - fscanf(sig, "%lf\n", &alpha); - else - fscanf(sig, "%*f\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - if (quant == 0) - fscanf(sig, "%d\n", &quant); - else - fscanf(sig, "%*d\n"); - if (level == 0) - fscanf(sig, "%d\n", &level); - else - fscanf(sig, "%*d\n"); - fscanf(sig, "%d\n", &seed); - srandom(seed); - n_signature = NBITSTOBYTES(nbit_signature); - fread(signature, sizeof(char), n_signature, sig); - fscanf(sig, "\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - if (verbose > 0) - fprintf(stderr, "%s: embedding %d bits with strength %d in\n" - " %d x %d host image, decomposition level %d\n", - progname, nbit_signature, quant, cols, rows, level); - - image = pgm_allocarray(cols, rows); - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - fclose(in); - - // decomposition of image - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - dwts = fdwt(image); - - p = dwts; - - // consider each resolution level - while (p->level < level) - // descend one level - p = p->coarse; - - // repeat binary watermark by sliding a 3-pixel window of approximation image - n = 0; - for (row = 0; row < p->image->height; row++) { - col = 0; - while (col < p->image->width - 3) { - double b1, b2, b3; - double *f1 = &b1, *f2 = &b2, *f3 = &b3; - - // get all three approximation pixels in window - b1 = get_pixel(p->image, col + 0, row); - b2 = get_pixel(p->image, col + 1, row); - b3 = get_pixel(p->image, col + 2, row); - - // bring selected pixels in ascending order -#define SWAP(A, B) {double *t = A; A = B; B = t;} - if (*f1 > *f2) SWAP(f1, f2); - if (*f2 > *f3) SWAP(f2, f3); - if (*f1 > *f2) SWAP(f1, f2); - - set_signature_bit(n, wm_transform(quant, *f1, *f2, *f3)); - - if (verbose > 1) - fprintf(stderr, "%s: extracting #%d (= %d) at (%d/%d); %f < %f < %f\n", - progname, n, get_signature_bit(n % nbit_signature), col, row, *f1, *f2, *f3); - - n++; - col += 3; - col += (2.0 / alpha); - } - } - - fprintf(out, "XE2WM\n"); - fprintf(out, "%d\n", n); - fwrite(signature, sizeof(char), NBITSTOBYTES(n), out); - fprintf(out, "\n"); - fclose(out); - - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_xie2_e.c --- a/Meerwald/wm_xie2_e.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,288 +0,0 @@ -#include "wm.h" -#include "signature.h" -#include "dwt.h" -#include "pgm.h" - -char *progname; - -// watermarking transformation, set median pixel to quantization boundary -double wm_transform(int quant, double f1, double f2, double f3, int x) { - double s = (fabs(f3) - fabs(f1)) / (double) quant; - double l = x ? (f1 + s) : f1; - double f2new; - - while ((l + 2 * s) < f2) l += 2 * s; - f2new = ((f2 - l) < (l + 2 * s - f2)) ? l : (l + 2 * s); - - return f2new; -} - -void usage(void) { - 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); - fprintf(stderr, "\t-a n\t\tembedding strength (default 0.05)\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-l n\t\tembedding level\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); - fprintf(stderr, "\t-q n\t\tquantization level\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int c, n; - int row, col; - - double alpha = 0.0; - int filter = 0; - int method = -1; - int level = 0; - int quant = 0; - char filter_name[MAXPATHLEN] = ""; - - int seed; - int verbose = 0; - - gray **image; - Image_tree dwts, p; - - gray maxval; - int rows, cols, format; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "a:e:f:F:h?l:o:s:v:")) != EOF) { - switch (c) { - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'l': - level = atoi(optarg); - if (level < 1) { - fprintf(stderr, "%s: embedding level out of range\n", progname); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'q': - quant = atoi(optarg); - break; - case 'a': - alpha = atof(optarg); - if (alpha <= 0.0) { - fprintf(stderr, "%s: embedding strength factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "XE2SG") >= 5) { - fscanf(sig, "%d\n", &nbit_signature); - if (alpha == 0.0) - fscanf(sig, "%lf\n", &alpha); - else - fscanf(sig, "%*f\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - if (quant == 0) - fscanf(sig, "%d\n", &quant); - else - fscanf(sig, "%*d\n"); - if (level == 0) - fscanf(sig, "%d\n", &level); - else - fscanf(sig, "%*d\n"); - fscanf(sig, "%d\n", &seed); - srandom(seed); - n_signature = NBITSTOBYTES(nbit_signature); - fread(signature, sizeof(char), n_signature, sig); - fscanf(sig, "\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - - if (verbose > 0) - fprintf(stderr, "%s: embedding %d bits with strength %d in\n" - " %d x %d host image, decomposition level %d\n", - progname, nbit_signature, quant, cols, rows, level); - - image = pgm_allocarray(cols, rows); - - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - - fclose(in); - - // decomposition of image - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - dwts = fdwt(image); - - p = dwts; - - // consider each resolution level - while (p->level < level) - // descend one level - p = p->coarse; - - // repeat binary watermark by sliding a 3-pixel window of approximation image - n = 0; - for (row = 0; row < p->image->height; row++) { - col = 0; - while (col < p->image->width - 3) { - double MIN_DIFF = (20.0 * alpha); - double b1, b2, b3; - double *f1 = &b1, *f2 = &b2, *f3 = &b3; - double f2new; - - // get all three approximation pixels in window - b1 = get_pixel(p->image, col + 0, row); - b2 = get_pixel(p->image, col + 1, row); - b3 = get_pixel(p->image, col + 2, row); - - // bring selected pixels in ascending order -#define SWAP(A, B) {double *t = A; A = B; B = t;} - if (*f1 > *f2) SWAP(f1, f2); - if (*f2 > *f3) SWAP(f2, f3); - if (*f1 > *f2) SWAP(f1, f2); - - if ((*f3 - *f1) < MIN_DIFF) { - double adj = (MIN_DIFF - (*f3 - *f1)) / 2.0; - *f1 -= adj; - *f3 += adj; - } - - // apply watermarking transformation (modify median pixel) - f2new = wm_transform(quant, *f1, *f2, *f3, get_signature_bit(n % nbit_signature)); - - if (verbose > 1) - fprintf(stderr, "%s: embedding #%d (= %d) at (%d/%d); %f < %f -> %f < %f\n", - progname, n, get_signature_bit(n % nbit_signature), col, row, *f1, *f2, f2new, *f3); - - *f2 = f2new; - - // write modified pixel - set_pixel(p->image, col + 0, row, b1); - set_pixel(p->image, col + 1, row, b2); - set_pixel(p->image, col + 2, row, b3); - n++; - col += 3; - col+= (2.0 / alpha); - } - } - - - // skip over some pixels - - idwt(dwts, image); - - pgm_writepgminit(out, cols, rows, maxval, 0); - - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, image[row], cols, maxval, 0); - - fclose(out); - - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_xie_d.c --- a/Meerwald/wm_xie_d.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,258 +0,0 @@ -#include "wm.h" -#include "signature.h" -#include "dwt.h" -#include "pgm.h" - -char *progname; - -// inverse watermarking transformation, extract embedded bit, check quantization boundaries -double wm_transform(double alpha, double f1, double f2, double f3) { - double s = alpha * (fabs(f3) - fabs(f1)) / 2.0; - double l = f1; - int x; - - x = 0; - while (l < f2) { - l += s; - x++; - } - - if (fabs(l - s - f2) < fabs(l-f2)) - return (x+1) % 2; - else - return (x) % 2; -} - -void usage(void) { - 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); - fprintf(stderr, "\t-a n\t\tembedding strength (default 0.05)\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-l n\t\tembedding level\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\textracted signature file\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int c, n; - int row, col; - - double alpha = 0.0; - int filter = 0; - int method = -1; - int level = 0; - char filter_name[MAXPATHLEN] = ""; - - int seed; - int verbose = 0; - - gray **image; - Image_tree dwts, p; - - gray maxval; - int rows, cols, format; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init2(); - - while ((c = getopt(argc, argv, "a:e:f:F:h?l:o:s:v:")) != EOF) { - switch (c) { - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'l': - level = atoi(optarg); - if (level < 1) { - fprintf(stderr, "%s: embedding level out of range\n", progname); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'a': - alpha = atof(optarg); - if (alpha <= 0.0) { - fprintf(stderr, "%s: embedding strength factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "XESG") >= 4) { - fscanf(sig, "%d\n", &nbit_signature); - if (alpha == 0.0) - fscanf(sig, "%lf\n", &alpha); - else - fscanf(sig, "%*f\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - if (level == 0) - fscanf(sig, "%d\n", &level); - else - fscanf(sig, "%*d\n"); - fscanf(sig, "%d\n", &seed); - srandom(seed); - n_signature = NBITSTOBYTES(nbit_signature); - fread(signature, sizeof(char), n_signature, sig); - fscanf(sig, "\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - if (verbose > 0) - fprintf(stderr, "%s: embedding %d bits with strength %f in\n" - " %d x %d host image, decomposition level %d\n", - progname, nbit_signature, alpha, cols, rows, level); - - image = pgm_allocarray(cols, rows); - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - fclose(in); - - // decomposition of image - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - dwts = fdwt(image); - - p = dwts; - - // consider each resolution level - while (p->level < level) - // descend one level - p = p->coarse; - - // repeat binary watermark by sliding a 3-pixel window of approximation image - n = 0; - for (row = 0; row < p->image->height; row++) { - for (col = 0; col < p->image->width - 3; col += 3) { - double b1, b2, b3; - double *f1 = &b1, *f2 = &b2, *f3 = &b3; - - // get all three approximation pixels in window - b1 = get_pixel(p->image, col + 0, row); - b2 = get_pixel(p->image, col + 1, row); - b3 = get_pixel(p->image, col + 2, row); - - // bring selected pixels in ascending order -#define SWAP(A, B) {double *t = A; A = B; B = t;} - if (*f1 > *f2) SWAP(f1, f2); - if (*f2 > *f3) SWAP(f2, f3); - if (*f1 > *f2) SWAP(f1, f2); - - set_signature_bit(n, wm_transform(alpha, *f1, *f2, *f3)); - - if (verbose > 1) - fprintf(stderr, "%s: extracting #%d (= %d) at (%d/%d); %f < %f < %f\n", - progname, n, get_signature_bit(n % nbit_signature), col, row, *f1, *f2, *f3); - - n++; - } - } - - fprintf(out, "XEWM\n"); - fprintf(out, "%d\n", n); - fwrite(signature, sizeof(char), NBITSTOBYTES(n), out); - fprintf(out, "\n"); - fclose(out); - - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_xie_e.c --- a/Meerwald/wm_xie_e.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,270 +0,0 @@ -#include "wm.h" -#include "signature.h" -#include "dwt.h" -#include "pgm.h" - -char *progname; - -// watermarking transformation, set median pixel to quantization boundary -double wm_transform(double alpha, double f1, double f2, double f3, int x) { - double s = alpha * (fabs(f3) - fabs(f1)) / 2.0; - double l = x ? (f1 + s) : f1; - double f2new; - - while ((l + 2 * s) < f2) l += 2 * s; - f2new = ((f2 - l) < (l + 2 * s - f2)) ? l : (l + 2 * s); - - return f2new; -} - -void usage(void) { - 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); - fprintf(stderr, "\t-a n\t\tembedding strength (default 0.05)\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-l n\t\tembedding level\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int c, n; - int row, col; - - double alpha = 0.0; - int filter = 0; - int method = -1; - int level = 0; - char filter_name[MAXPATHLEN] = ""; - - int seed; - int verbose = 0; - - gray **image; - Image_tree dwts, p; - - gray maxval; - int rows, cols, format; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "a:e:f:F:h?l:o:s:v:")) != EOF) { - switch (c) { - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'l': - level = atoi(optarg); - if (level < 1) { - fprintf(stderr, "%s: embedding level out of range\n", progname); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 'a': - alpha = atof(optarg); - if (alpha <= 0.0) { - fprintf(stderr, "%s: embedding strength factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "XESG") >= 4) { - fscanf(sig, "%d\n", &nbit_signature); - if (alpha == 0.0) - fscanf(sig, "%lf\n", &alpha); - else - fscanf(sig, "%*f\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - if (level == 0) - fscanf(sig, "%d\n", &level); - else - fscanf(sig, "%*d\n"); - fscanf(sig, "%d\n", &seed); - srandom(seed); - n_signature = NBITSTOBYTES(nbit_signature); - fread(signature, sizeof(char), n_signature, sig); - fscanf(sig, "\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - - if (verbose > 0) - fprintf(stderr, "%s: embedding %d bits with strength %f in\n" - " %d x %d host image, decomposition level %d\n", - progname, nbit_signature, alpha, cols, rows, level); - - image = pgm_allocarray(cols, rows); - - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - - fclose(in); - - // decomposition of image - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - dwts = fdwt(image); - - p = dwts; - - // consider each resolution level - while (p->level < level) - // descend one level - p = p->coarse; - - // repeat binary watermark by sliding a 3-pixel window of approximation image - n = 0; - for (row = 0; row < p->image->height; row++) { - for (col = 0; col < p->image->width - 3; col += 3) { - double b1, b2, b3; - double *f1 = &b1, *f2 = &b2, *f3 = &b3; - double f2new; - - // get all three approximation pixels in window - b1 = get_pixel(p->image, col + 0, row); - b2 = get_pixel(p->image, col + 1, row); - b3 = get_pixel(p->image, col + 2, row); - - // bring selected pixels in ascending order -#define SWAP(A, B) {double *t = A; A = B; B = t;} - if (*f1 > *f2) SWAP(f1, f2); - if (*f2 > *f3) SWAP(f2, f3); - if (*f1 > *f2) SWAP(f1, f2); - - // apply watermarking transformation (modify median pixel) - f2new = wm_transform(alpha, *f1, *f2, *f3, get_signature_bit(n % nbit_signature)); - - if (verbose > 1) - fprintf(stderr, "%s: embedding #%d (= %d) at (%d/%d); %f < %f -> %f < %f\n", - progname, n, get_signature_bit(n % nbit_signature), col, row, *f1, *f2, f2new, *f3); - - *f2 = f2new; - - // write modified pixel - set_pixel(p->image, col + 0, row, b1); - set_pixel(p->image, col + 1, row, b2); - set_pixel(p->image, col + 2, row, b3); - - n++; - } - } - - - // skip over some pixels - - idwt(dwts, image); - - pgm_writepgminit(out, cols, rows, maxval, 0); - - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, image[row], cols, maxval, 0); - - fclose(out); - - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_zhu_d.c --- a/Meerwald/wm_zhu_d.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,306 +0,0 @@ -#include "wm.h" -#include "dwt.h" -#include "pgm.h" -#include "sort.h" - -char *progname; - -void usage(void) { - fprintf(stderr, "usage: %s [-a n] [-e n] [-f n] [-F file] [-h] [-l n] [-o file] [-v n] -s file -i file file\n\n", progname); - fprintf(stderr, "\t-a n\t\talpha factor\n"); - fprintf(stderr, "\t-b n\t\tbeta factor\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-i file\t\toriginal image file\n"); - fprintf(stderr, "\t-l n\t\tdecomposition level\n"); - fprintf(stderr, "\t-o file\t\tfile for extracted watermark\n"); - fprintf(stderr, "\t-s file\t\toriginal signature file\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -void write_mark(FILE *out, double watermark[], int n) { - int i; - - fprintf(out, "%d\n", n); - for (i = 0; i < n; i++) - fprintf(out, "%f\n", watermark[i]); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *orig = NULL; - FILE *sig = NULL; - - gray **input_image; - gray **orig_image; - - char signature_name[MAXPATHLEN]; - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char orig_name[MAXPATHLEN]; - - int c, w; - int i; - int n = 0; - int method = -1; - int filter = 0; - char filter_name[MAXPATHLEN] = ""; - - int level = 0, levels; - double alpha = 0.0; - - int in_rows, in_cols, in_format; - gray in_maxval; - int orig_rows, orig_cols, orig_format; - gray orig_maxval; - int rows, cols; - int row; - - double *watermark; - - Image_tree input_dwts, orig_dwts, p, q; - - int verbose = 0; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init2(); - - while ((c = getopt(argc, argv, "a:e:f:F:h?i:l:o:s:v:")) != EOF) { - switch (c) { - case 'a': - alpha = atof(optarg); - if (alpha <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'i': - if ((orig = fopen(optarg, "rb")) == NULL) { - fprintf(stderr, "%s: unable to open original image file %s\n", progname, optarg); - exit(1); - } - strcpy(orig_name, optarg); - break; - case 'l': - level = atoi(optarg); - if (level <= 0) { - fprintf(stderr, "%s: decomposition level %d out of range\n", progname, level); - exit(1); - } - break; - case 'o': - if ((out = fopen(optarg, "w")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (!orig) { - fprintf(stderr, "%s: original image file not specified, use -i file option\n", progname); - exit(1); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "ZHSG") >= 4) { - fscanf(sig, "%d\n", &n); - if (alpha == 0.0) - fscanf(sig, "%lf\n", &alpha); - else - fscanf(sig, "%*f\n"); - if (level == 0) - fscanf(sig, "%d\n", &level); - else - fscanf(sig, "%*d\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - fclose(sig); - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - pgm_readpgminit(in, &in_cols, &in_rows, &in_maxval, &in_format); - pgm_readpgminit(orig, &orig_cols, &orig_rows, &orig_maxval, &orig_format); - - if (in_cols != orig_cols || in_rows != orig_rows) { - fprintf(stderr, "%s: input image %s does not match dimensions of original image %s\n", progname, input_name, orig_name); - exit(1); - } - - cols = in_cols; - rows = in_rows; - - input_image = pgm_allocarray(in_cols, in_rows); - orig_image = pgm_allocarray(orig_cols, orig_rows); - - for (row = 0; row < in_rows; row++) { - pgm_readpgmrow(in, input_image[row], in_cols, in_maxval, in_format); - pgm_readpgmrow(orig, orig_image[row], orig_cols, orig_maxval, orig_format); - } - - fclose(in); - fclose(orig); - - // complete decomposition - levels = find_deepest_level(cols, rows) - 1; - if (level > levels) { - fprintf(stderr, "%s: decomposition level %d not possible (max. %d), image size is %d x %d\n", progname, level, levels, cols, rows); - exit(1); - } - - init_dwt(cols, rows, filter_name, filter, levels, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - input_dwts = fdwt(input_image); - orig_dwts = fdwt(orig_image); - - watermark = malloc(n * sizeof(double)); - if (!watermark) { - fprintf(stderr, "%s: malloc() failed\n\n", progname); - exit(1); - } - - fprintf(out, "ZHWM\n"); - fprintf(out, "%d\n", n); - fprintf(out, "%d\n", level); - - p = input_dwts; - q = orig_dwts; - while (p->coarse && q->coarse) { - double *collected_coeffs, *largest; - int subband_size = q->horizontal->image->size; - int maxselect = MIN(3 * subband_size, n + 1); - double threshold; - - collected_coeffs = malloc(3 * subband_size * sizeof(double)); - if (!collected_coeffs) { - fprintf(stderr, "%s: malloc() failed\n", progname); - exit(1); - } - - for (i = 0; i < subband_size; i++) { - collected_coeffs[3 * i + 0] = q->horizontal->image->data[i]; - collected_coeffs[3 * i + 1] = q->vertical->image->data[i]; - collected_coeffs[3 * i + 2] = q->diagonal->image->data[i]; - } - - largest = malloc(maxselect * sizeof(double)); - if (!largest) { - fprintf(stderr, "%s: malloc() failed\n", progname); - exit(1); - } - - select_largest_coeffs(collected_coeffs, 3 * subband_size, maxselect, largest); - threshold = largest[0]; - free(largest); - free(collected_coeffs); - - w = 0; - for (i = 0; i < subband_size && w < n; i++) { - if (q->horizontal->image->data[i] > threshold) - watermark[w++] = (p->horizontal->image->data[i] / q->horizontal->image->data[i] - 1.0) / alpha; - if (q->vertical->image->data[i] > threshold) - watermark[w++] = (p->vertical->image->data[i] / q->vertical->image->data[i] - 1.0) / alpha; - if (q->diagonal->image->data[i] > threshold) - watermark[w++] = (p->diagonal->image->data[i] / q->diagonal->image->data[i] - 1.0) / alpha; - } - - write_mark(out, watermark, w); - - p = p->coarse; - q = q->coarse; - } - - fclose(out); - - free(watermark); - - pgm_freearray(input_image, rows); - pgm_freearray(orig_image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e Meerwald/wm_zhu_e.c --- a/Meerwald/wm_zhu_e.c Fri Dec 20 12:53:41 2024 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,261 +0,0 @@ -#include "wm.h" -#include "dwt.h" -#include "pgm.h" -#include "sort.h" - -char *progname; - -void usage(void) { - 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); - fprintf(stderr, "\t-a n\t\talpha factor/embedding strength\n"); - fprintf(stderr, "\t-e n\t\twavelet filtering method\n"); - fprintf(stderr, "\t-f n\t\tfilter number\n"); - fprintf(stderr, "\t-F file\t\tfilter definition file\n"); - fprintf(stderr, "\t-h\t\tprint usage\n"); - fprintf(stderr, "\t-l n\t\tdecomposition level\n"); - fprintf(stderr, "\t-o file\t\toutput (watermarked) file\n"); - fprintf(stderr, "\t-s file\t\tsignature to embed in input image\n"); - fprintf(stderr, "\t-v n\t\tverbosity level\n"); - exit(0); -} - -int main(int argc, char *argv[]) { - - FILE *in = stdin; - FILE *out = stdout; - FILE *sig = NULL; - - char output_name[MAXPATHLEN] = "(stdout)"; - char input_name[MAXPATHLEN] = "(stdin)"; - char signature_name[MAXPATHLEN]; - - int i, c, w; - int row; - - int n; - - double alpha = 0.0; - int level = 0; - - int filter = 0; - int method = -1; - int levels; - char filter_name[MAXPATHLEN] = ""; - - int verbose = 0; - - gray **image; - Image_tree p, dwts; - - gray maxval; - int rows, cols, format; - - double *watermark; - - progname = argv[0]; - - pgm_init(&argc, argv); wm_init(); - - while ((c = getopt(argc, argv, "a:e:f:F:h?o:l:s:v:")) != EOF) { - switch (c) { - case 'a': - alpha = atof(optarg); - if (alpha <= 0.0) { - fprintf(stderr, "%s: alpha factor %f out of range\n", progname, alpha); - exit(1); - } - break; - case 'l': - level = atoi(optarg); - if (level <= 0) { - fprintf(stderr, "%s: decomposition level %d out of range\n", progname, level); - exit(1); - } - break; - case 'e': - method = atoi(optarg); - if (method < 0) { - fprintf(stderr, "%s: wavelet filtering method %d out of range\n", progname, method); - exit(1); - } - break; - case 'f': - filter = atoi(optarg); - if (filter <= 0) { - fprintf(stderr, "%s: filter number %d out of range\n", progname, filter); - exit(1); - } - break; - case 'F': - strcpy(filter_name, optarg); - break; - case 'h': - case '?': - usage(); - break; - case 'o': - if ((out = fopen(optarg, "wb")) == NULL) { - fprintf(stderr, "%s: unable to open output file %s\n", progname, optarg); - exit(1); - } - strcpy(output_name, optarg); - break; - case 's': - if ((sig = fopen(optarg, "r")) == NULL) { - fprintf(stderr, "%s: unable to open signature file %s\n", progname, optarg); - exit(1); - } - strcpy(signature_name, optarg); - break; - case 'v': - verbose = atoi(optarg); - if (verbose < 0) { - fprintf(stderr, "%s: verbosity level %d out of range\n", progname, verbose); - exit(1); - } - break; - } - } - - argc -= optind; - argv += optind; - - if (argc > 1) { - usage(); - exit(1); - } - - if (argc == 1 && *argv[0] != '-') { - if ((in = fopen(argv[0], "rb")) == NULL) { - fprintf(stderr, "%s: unable to open input file %s\n", progname, argv[0]); - exit(1); - } - else - strcpy(input_name, argv[0]); - } - - if (sig) { - char line[32]; - fgets(line, sizeof(line), sig); - if (strspn(line, "ZHSG") >= 4) { - fscanf(sig, "%d\n", &n); - if (alpha == 0.0) - fscanf(sig, "%lf\n", &alpha); - else - fscanf(sig, "%*f\n"); - if (level == 0) - fscanf(sig, "%d\n", &level); - else - fscanf(sig, "%*d\n"); - if (method < 0) - fscanf(sig, "%d\n", &method); - else - fscanf(sig, "%*d\n"); - if (filter == 0) - fscanf(sig, "%d\n", &filter); - else - fscanf(sig, "%*d\n"); - if (!strcmp(filter_name, "")) - fscanf(sig, "%[^\n\r]\n", filter_name); - else - fscanf(sig, "%*[^\n\r]\n"); - } - else { - fprintf(stderr, "%s: invalid signature file %s\n", progname, signature_name); - exit(1); - } - } - else { - fprintf(stderr, "%s: signature file not specified, use -s file option\n", progname); - exit(1); - } - - watermark = malloc(n * sizeof(double)); - for (i = 0; i < n; i++) - fscanf(sig, "%lf\n", &watermark[i]); - fclose(sig); - - pgm_readpgminit(in, &cols, &rows, &maxval, &format); - image = pgm_allocarray(cols, rows); - for (row = 0; row < rows; row++) - pgm_readpgmrow(in, image[row], cols, maxval, format); - fclose(in); - - // complete decomposition - levels = find_deepest_level(cols, rows) - 1; - if (level > levels) { - fprintf(stderr, "%s: decomposition level %d not possible (max. %d), image size is %d x %d\n", progname, level, levels, cols, rows); - exit(1); - } - - // wavelet transform - init_dwt(cols, rows, filter_name, filter, level, method); -#ifdef POLLEN_STUFF -#include "pollen_stuff.c" -#endif -#ifdef PARAM_STUFF -#include "param_stuff.c" -#endif - - dwts = fdwt(image); - - p = dwts; - while (p->coarse) { - double *collected_coeffs, *largest; - int subband_size = p->horizontal->image->size; - int maxselect = MIN(3 * subband_size, n + 1); - double threshold; - - // allocate memory for coefficient vector - collected_coeffs = malloc(3 * subband_size * sizeof(double)); - if (!collected_coeffs) { - fprintf(stderr, "%s: malloc() failed\n", progname); - exit(1); - } - - // collect coefficients from all subbands of one level into one vector - for (i = 0; i < subband_size; i++) { - collected_coeffs[3 * i + 0] = p->horizontal->image->data[i]; - collected_coeffs[3 * i + 1] = p->vertical->image->data[i]; - collected_coeffs[3 * i + 2] = p->diagonal->image->data[i]; - } - - // allocate memory for largest coefficients - largest = malloc(maxselect * sizeof(double)); - if (!largest) { - fprintf(stderr, "%s: malloc() failed\n", progname); - exit(1); - } - - // select largest coefficients (involves sorting) - select_largest_coeffs(collected_coeffs, 3 * subband_size, maxselect, largest); - // threshold is the smallest of the largest coefficients - threshold = largest[0]; - free(largest); - free(collected_coeffs); - - w = 0; - for (i = 0; i < subband_size && w < n; i++) { - if (p->horizontal->image->data[i] > threshold) - p->horizontal->image->data[i] *= (1.0 + alpha * watermark[w++]); - if (p->vertical->image->data[i] > threshold) - p->vertical->image->data[i] *= (1.0 + alpha * watermark[w++]); - if (p->diagonal->image->data[i] > threshold) - p->diagonal->image->data[i] *= (1.0 + alpha * watermark[w++]); - } - - p = p->coarse; - } - - free(watermark); - idwt(dwts, image); - - pgm_writepgminit(out, cols, rows, maxval, 0); - for (row = 0; row < rows; row++) - pgm_writepgmrow(out, image[row], cols, maxval, 0); - fclose(out); - - pgm_freearray(image, rows); - - exit(0); -} diff -r 71dd4b96221b -r 9f20bce6184e README --- a/README Fri Dec 20 12:53:41 2024 +0100 +++ b/README Fri Dec 20 13:08:59 2024 +0100 @@ -1,5 +1,13 @@ Watermarking source +version 0.7 + * fixed some compiler warnings + * move Meerwald and Fotopoulos to Meerwald-dir and Fotopoulos-dir + * support netpbm 11 (is not in /usr/include/netpbm, instead of /usr/include) + +version 0.6 + * various fixes + version 0.5 * added algorithm kund2 and kund3 * added xie2