changeset 24:9f20bce6184e v0.7

move directories, support netpbm 11
author Peter Meerwald-Stadler <pmeerw@pmeerw.net>
date Fri, 20 Dec 2024 13:08:59 +0100
parents 71dd4b96221b
children 5a57a145bccb
files Fotopoulos-dir/CHANGES Fotopoulos-dir/Makefile Fotopoulos-dir/README Fotopoulos-dir/README_VASSILIS Fotopoulos-dir/cast-hart.c Fotopoulos-dir/cast-pv.c Fotopoulos-dir/cast-sub.c Fotopoulos-dir/common.c Fotopoulos-dir/common.h Fotopoulos-dir/test-hart.c Fotopoulos-dir/test-pv.c Fotopoulos-dir/test-sub.c Fotopoulos/CHANGES Fotopoulos/Makefile Fotopoulos/README Fotopoulos/README_VASSILIS Fotopoulos/cast-hart.c Fotopoulos/cast-pv.c Fotopoulos/cast-sub.c Fotopoulos/common.c Fotopoulos/common.h Fotopoulos/test-hart.c Fotopoulos/test-pv.c Fotopoulos/test-sub.c Makefile Meerwald-dir/Makefile Meerwald-dir/README Meerwald-dir/bruyn_common.c Meerwald-dir/bruyn_common.h Meerwald-dir/cmp_bruyn_sig.c Meerwald-dir/cmp_corvi_sig.c Meerwald-dir/cmp_cox_sig.c Meerwald-dir/cmp_dct.1 Meerwald-dir/cmp_dct.c Meerwald-dir/cmp_dct8x8.1 Meerwald-dir/cmp_dct8x8.c Meerwald-dir/cmp_dugad_sig.c Meerwald-dir/cmp_dwt.c Meerwald-dir/cmp_frid2_sig.c Meerwald-dir/cmp_kim_sig.c Meerwald-dir/cmp_koch_sig.c Meerwald-dir/cmp_kund2_sig.c Meerwald-dir/cmp_kund3_sig.c Meerwald-dir/cmp_kund_sig.c Meerwald-dir/cmp_pgm.1 Meerwald-dir/cmp_pgm.c Meerwald-dir/cmp_ppm.1 Meerwald-dir/cmp_ppm.c Meerwald-dir/cmp_wang_sig.c Meerwald-dir/cmp_xia_sig.c Meerwald-dir/cmp_xie2_sig.c Meerwald-dir/cmp_xie_sig.c Meerwald-dir/cmp_zhu_sig.c Meerwald-dir/coeff.c Meerwald-dir/coeff.h Meerwald-dir/coord.c Meerwald-dir/coord.h Meerwald-dir/dct.c Meerwald-dir/dct.h Meerwald-dir/dwt.c Meerwald-dir/dwt.h Meerwald-dir/dwt_util.c Meerwald-dir/dwt_util.h Meerwald-dir/filter.dat Meerwald-dir/frid2_common.c Meerwald-dir/frid2_common.h Meerwald-dir/gen_bruyn_sig.1 Meerwald-dir/gen_bruyn_sig.c Meerwald-dir/gen_corvi_sig.1 Meerwald-dir/gen_corvi_sig.c Meerwald-dir/gen_cox_sig.1 Meerwald-dir/gen_cox_sig.c Meerwald-dir/gen_dugad_sig.c Meerwald-dir/gen_frid2_sig.c Meerwald-dir/gen_kim_sig.c Meerwald-dir/gen_koch_sig.1 Meerwald-dir/gen_koch_sig.c Meerwald-dir/gen_kund2_sig.c Meerwald-dir/gen_kund3_sig.c Meerwald-dir/gen_kund_sig.c Meerwald-dir/gen_kutter_sig.1 Meerwald-dir/gen_wang_sig.c Meerwald-dir/gen_xia_sig.c Meerwald-dir/gen_xie2_sig.c Meerwald-dir/gen_xie_sig.c Meerwald-dir/gen_zhu_sig.c Meerwald-dir/gray.c Meerwald-dir/gray.h Meerwald-dir/kim_common.c Meerwald-dir/kim_common.h Meerwald-dir/param_stuff.c Meerwald-dir/pollen_stuff.c Meerwald-dir/signature-utils.c Meerwald-dir/signature-utils.h Meerwald-dir/signature.h Meerwald-dir/sort.c Meerwald-dir/sort.h Meerwald-dir/wang_common.c Meerwald-dir/wang_common.h Meerwald-dir/wavelet.c Meerwald-dir/wavelet.h Meerwald-dir/wm.c Meerwald-dir/wm.h Meerwald-dir/wm_bruyn_d.c Meerwald-dir/wm_bruyn_e.c Meerwald-dir/wm_corvi_d.1 Meerwald-dir/wm_corvi_d.c Meerwald-dir/wm_corvi_e.1 Meerwald-dir/wm_corvi_e.c Meerwald-dir/wm_corvi_s.1 Meerwald-dir/wm_corvi_s.c Meerwald-dir/wm_cox_d.1 Meerwald-dir/wm_cox_d.c Meerwald-dir/wm_cox_e.1 Meerwald-dir/wm_cox_e.c Meerwald-dir/wm_dugad_d.c Meerwald-dir/wm_dugad_e.c Meerwald-dir/wm_frid2_d.c Meerwald-dir/wm_frid2_e.c Meerwald-dir/wm_kim_a.c Meerwald-dir/wm_kim_d.c Meerwald-dir/wm_kim_e.c Meerwald-dir/wm_koch_d.1 Meerwald-dir/wm_koch_d.c Meerwald-dir/wm_koch_e.1 Meerwald-dir/wm_koch_e.c Meerwald-dir/wm_kund2_d.c Meerwald-dir/wm_kund2_e.c Meerwald-dir/wm_kund3_d.c Meerwald-dir/wm_kund3_e.c Meerwald-dir/wm_kund_d.c Meerwald-dir/wm_kund_e.c Meerwald-dir/wm_wang_d.c Meerwald-dir/wm_wang_e.c Meerwald-dir/wm_xia_d.c Meerwald-dir/wm_xia_e.c Meerwald-dir/wm_xie2_d.c Meerwald-dir/wm_xie2_e.c Meerwald-dir/wm_xie_d.c Meerwald-dir/wm_xie_e.c Meerwald-dir/wm_zhu_d.c Meerwald-dir/wm_zhu_e.c Meerwald/Makefile Meerwald/README Meerwald/bruyn_common.c Meerwald/bruyn_common.h Meerwald/cmp_bruyn_sig.c Meerwald/cmp_corvi_sig.c Meerwald/cmp_cox_sig.c Meerwald/cmp_dct.1 Meerwald/cmp_dct.c Meerwald/cmp_dct8x8.1 Meerwald/cmp_dct8x8.c Meerwald/cmp_dugad_sig.c Meerwald/cmp_dwt.c Meerwald/cmp_frid2_sig.c Meerwald/cmp_kim_sig.c Meerwald/cmp_koch_sig.c Meerwald/cmp_kund2_sig.c Meerwald/cmp_kund3_sig.c Meerwald/cmp_kund_sig.c Meerwald/cmp_pgm.1 Meerwald/cmp_pgm.c Meerwald/cmp_ppm.1 Meerwald/cmp_ppm.c Meerwald/cmp_wang_sig.c Meerwald/cmp_xia_sig.c Meerwald/cmp_xie2_sig.c Meerwald/cmp_xie_sig.c Meerwald/cmp_zhu_sig.c Meerwald/coeff.c Meerwald/coeff.h Meerwald/coord.c Meerwald/coord.h Meerwald/dct.c Meerwald/dct.h Meerwald/dwt.c Meerwald/dwt.h Meerwald/dwt_util.c Meerwald/dwt_util.h Meerwald/filter.dat Meerwald/frid2_common.c Meerwald/frid2_common.h Meerwald/gen_bruyn_sig.1 Meerwald/gen_bruyn_sig.c Meerwald/gen_corvi_sig.1 Meerwald/gen_corvi_sig.c Meerwald/gen_cox_sig.1 Meerwald/gen_cox_sig.c Meerwald/gen_dugad_sig.c Meerwald/gen_frid2_sig.c Meerwald/gen_kim_sig.c Meerwald/gen_koch_sig.1 Meerwald/gen_koch_sig.c Meerwald/gen_kund2_sig.c Meerwald/gen_kund3_sig.c Meerwald/gen_kund_sig.c Meerwald/gen_kutter_sig.1 Meerwald/gen_wang_sig.c Meerwald/gen_xia_sig.c Meerwald/gen_xie2_sig.c Meerwald/gen_xie_sig.c Meerwald/gen_zhu_sig.c Meerwald/gray.c Meerwald/gray.h Meerwald/kim_common.c Meerwald/kim_common.h Meerwald/param_stuff.c Meerwald/pollen_stuff.c Meerwald/signature-utils.c Meerwald/signature-utils.h Meerwald/signature.h Meerwald/sort.c Meerwald/sort.h Meerwald/wang_common.c Meerwald/wang_common.h Meerwald/wavelet.c Meerwald/wavelet.h Meerwald/wm.c Meerwald/wm.h Meerwald/wm_bruyn_d.c Meerwald/wm_bruyn_e.c Meerwald/wm_corvi_d.1 Meerwald/wm_corvi_d.c Meerwald/wm_corvi_e.1 Meerwald/wm_corvi_e.c Meerwald/wm_corvi_s.1 Meerwald/wm_corvi_s.c Meerwald/wm_cox_d.1 Meerwald/wm_cox_d.c Meerwald/wm_cox_e.1 Meerwald/wm_cox_e.c Meerwald/wm_dugad_d.c Meerwald/wm_dugad_e.c Meerwald/wm_frid2_d.c Meerwald/wm_frid2_e.c Meerwald/wm_kim_a.c Meerwald/wm_kim_d.c Meerwald/wm_kim_e.c Meerwald/wm_koch_d.1 Meerwald/wm_koch_d.c Meerwald/wm_koch_e.1 Meerwald/wm_koch_e.c Meerwald/wm_kund2_d.c Meerwald/wm_kund2_e.c Meerwald/wm_kund3_d.c Meerwald/wm_kund3_e.c Meerwald/wm_kund_d.c Meerwald/wm_kund_e.c Meerwald/wm_wang_d.c Meerwald/wm_wang_e.c Meerwald/wm_xia_d.c Meerwald/wm_xia_e.c Meerwald/wm_xie2_d.c Meerwald/wm_xie2_e.c Meerwald/wm_xie_d.c Meerwald/wm_xie_e.c Meerwald/wm_zhu_d.c Meerwald/wm_zhu_e.c README
diffstat 260 files changed, 26598 insertions(+), 26590 deletions(-) [+]
line wrap: on
line diff
--- /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 <values.h> - it is not needed and MS VC++ does not have 
+it (Sarat Atluri)
--- /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/*
--- /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
+
+
--- /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
--- /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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+#include <getopt.h>
+#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);
+}
--- /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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+#include <getopt.h>
+#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);
+}
--- /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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+#include <getopt.h>
+#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);
+}
+
+
+
+
--- /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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+#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();
+}
+
--- /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(); 
--- /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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+#include <getopt.h>
+#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);
+}
--- /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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+#include <getopt.h>
+#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);
+}
--- /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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+#include <getopt.h>
+#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);
+}
+
+
+
+
--- 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 <values.h> - it is not needed and MS VC++ does not have 
-it (Sarat Atluri)
--- 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/*
--- 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
-
-
--- 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
--- 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <float.h>
-#include <getopt.h>
-#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);
-}
--- 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <float.h>
-#include <getopt.h>
-#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);
-}
--- 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <float.h>
-#include <getopt.h>
-#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);
-}
-
-
-
-
--- 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <float.h>
-#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();
-}
-
--- 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(); 
--- 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <float.h>
-#include <getopt.h>
-#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);
-}
--- 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <float.h>
-#include <getopt.h>
-#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);
-}
--- 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <float.h>
-#include <getopt.h>
-#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);
-}
-
-
-
-
--- 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)/*
--- /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
+
--- /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 <disclaimer.h>
+
+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
--- /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;
+}
+
+
--- /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 */
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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)
--- /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);
+}
--- /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)
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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[]) {
+}
--- /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)
--- /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);
+}
--- /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)
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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");
+  }
+}
--- /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
--- /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 <stdlib.h>
+#include <stdio.h>
+#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;
+}
+
+
--- /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
--- /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<<dct_NxN_log2N)>N){
+      fprintf(stderr, "dct_NxN: %d not a power of 2\n", N);
+      exit(1);
+    }
+  }while((1<<dct_NxN_log2N)<N);
+  if (dct_NxN_costable) free(dct_NxN_costable);
+  dct_NxN_costable = malloc(N * sizeof(double));
+#ifdef DEBUG
+  if(!dct_NxN_costable){
+    fprintf(stderr, "Unable to allocate C array\n");
+    exit(1);
+  }
+#endif
+  halfN=N/2;
+  for(i=0;i<=halfN-1;i++) dct_NxN_costable[halfN+i]=4*i+1;
+  for(group=1;group<=dct_NxN_log2N-1;group++){
+    base= 1<<(group-1);
+    nitems=base;
+    factor = 1.0*(1<<(dct_NxN_log2N-group));
+    for(item=1; item<=nitems;item++) dct_NxN_costable[base+item-1]=factor*dct_NxN_costable[halfN+item-1];
+  }
+
+  for(i=1;i<=N-1;i++) dct_NxN_costable[i] = 1.0/(2.0*cos(dct_NxN_costable[i]*M_PI/(2.0*N)));
+}
+
+void init_dct_NxN(int width, int height) {
+#ifdef DEBUG
+  if (width != height || width <= 0) {
+    fprintf(stderr, "init_dct_NxN(): dimensions out of range\n");
+    exit(1);
+  }
+#endif
+
+  if (dct_NxN_tmp && M != height)
+    free(dct_NxN_tmp);
+
+  N = width;
+  M = height;
+
+  dct_NxN_tmp = malloc(height * sizeof(double));
+#ifdef DEBUG
+  if (!dct_NxN_tmp) {
+    fprintf(stderr, "init_dct_NxN(): failed to allocate memory\n");
+    exit(1);
+  }
+#endif
+
+  initcosarray();
+}
+
+static void bitrev(double *f, int len)
+{
+  int i,j,m;
+
+  if (len<=2) return; /* No action necessary if n=1 or n=2 */
+  j=1;
+  for(i=1; i<=len; i++){
+    if(i<j)
+      SWAP(f[j-1], f[i-1]);
+    m = len>>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<N;u++)
+    for (v=0;v<M;v++)
+      tmp[u][v] = dcts[u][v];
+
+  for (u=0; u<=M-1; u++){
+    ifct_noscale(tmp[u]);
+  }
+  for (v=0; v<=N-1; v++){
+    for (u=0; u<=M-1; u++){
+       dct_NxN_tmp[u] = tmp[u][v];
+    }
+    ifct_noscale(dct_NxN_tmp);
+    for (u=0; u<=M-1; u++){
+       tmp[u][v] = dct_NxN_tmp[u]*two_over_sqrtncolsnrows;
+    }
+  }
+
+ for (u=0;u<N;u++)
+    for (v=0;v<M;v++)
+      pixels[u][v] = PIXELRANGE(tmp[u][v] + 128.5);
+ free(tmp);
+}
+
+void fdct_inplace_NxN(double **coeffs) {
+  int u,v;
+  double two_over_sqrtncolsnrows = 2.0/sqrt((double) N*M);
+
+  for (u=0; u<=M-1; u++)
+    fct_noscale(coeffs[u]);
+
+  for (v=0; v<=N-1; v++){
+    for (u=0; u<=M-1; u++)
+       dct_NxN_tmp[u] = coeffs[u][v];
+
+    fct_noscale(dct_NxN_tmp);
+    for (u=0; u<=M-1; u++)
+      coeffs[u][v] = dct_NxN_tmp[u]*two_over_sqrtncolsnrows;
+  }
+}
+
+void idct_inplace_NxN(double **coeffs) {
+ int u,v;
+ double two_over_sqrtncolsnrows = 2.0/sqrt((double) N*M);
+
+  for (u=0; u<=M-1; u++)
+    ifct_noscale(coeffs[u]);
+
+  for (v=0; v<=N-1; v++) {
+    for (u=0; u<=M-1; u++)
+       dct_NxN_tmp[u] = coeffs[u][v];
+
+    ifct_noscale(dct_NxN_tmp);
+    for (u=0; u<=M-1; u++)
+       coeffs[u][v] = dct_NxN_tmp[u]*two_over_sqrtncolsnrows;
+  }
+
+}
+
+double **dct_NxM_costable_x = NULL;
+double **dct_NxM_costable_y = NULL;
+
+void init_dct_NxM(int cols, int rows) {
+  int i, j;
+  double cx = sqrt(2.0 / cols);
+  double cy = sqrt(2.0 / rows);
+
+#ifdef DEBUG
+  if (cols <= 0 || rows <= 0) {
+    fprintf(stderr, "init_dct_NxM(): dimensions out of range\n");
+    exit(1);
+  }
+#endif
+
+  if (dct_NxM_costable_x && N != cols) {
+    free_coeffs(dct_NxM_costable_x);
+    dct_NxM_costable_x = NULL;
+  }
+
+  if (dct_NxM_costable_y && M != rows) {
+    free_coeffs(dct_NxM_costable_y);
+    dct_NxM_costable_y = NULL;
+  }
+
+  if (!dct_NxM_costable_x)
+    dct_NxM_costable_x = alloc_coeffs(cols, cols);
+  if (!dct_NxM_costable_y)
+    dct_NxM_costable_y = alloc_coeffs(rows, rows);
+
+  N = cols;
+  M = rows;
+
+  for (i = 0; i < cols; i++) {
+    for (j = 0; j < cols; j++) {
+      dct_NxM_costable_x[i][j] = cx * cos((M_PI * ((2*i + 1) * j)) / (double) (2 * N));
+    }
+  }
+
+  for (i = 0; i < rows; i++) {
+    for (j = 0; j < rows; j++) {
+      dct_NxM_costable_y[i][j] = cy * cos((M_PI * ((2*i + 1) * j)) / (double) (2 * M));
+    }
+  }
+}
+
+void fdct_NxM(gray **pixels, double **dcts) {
+  int x, y;
+  int i, j;
+  double t;
+  double cx0 = sqrt(1.0 / N);
+  double cy0 = sqrt(1.0 / M);
+
+  t = 0.0;
+  for (x = 0; x < N; x++)
+    for (y = 0; y < M; y++)
+      t += ((int) pixels[y][x] - 128);
+  dcts[0][0] = cx0 * cy0 * t;
+
+  for (i = 1; i < N; i++) {
+    t = 0.0;
+    for (x = 0; x < N; x++) {
+      double s = 0.0;
+      for (y = 0; y < M; y++) {
+        s += ((int) pixels[y][x] - 128);
+      }
+      t += s * dct_NxM_costable_x[x][i];
+    }
+    dcts[0][i] = cy0 * t;
+  }
+
+  for (j = 1; j < M; j++) {
+    t = 0.0;
+    for (y = 0; y < M; y++) {
+      double s = 0.0;
+      for (x = 0; x < N; x++) {
+        s += ((int) pixels[y][x] - 128);
+      }
+      t += s * dct_NxM_costable_y[y][j];
+    }
+    dcts[j][0] = cx0 * t;
+  }
+
+  for (i = 1; i < N; i++) {
+     for (j = 1; j < M; j++) {
+      t = 0.0;
+      for (x = 0; x < N; x++) {
+        double s = 0;
+        for (y = 0; y < M; y++) {
+          s += ((int) pixels[y][x] - 128) * dct_NxM_costable_y[y][j];
+        }
+        t += s * dct_NxM_costable_x[x][i];
+      }
+      dcts[j][i] = t;
+    }
+  }
+}
+
+void idct_NxM(double **dcts, gray **pixels) {
+  int x, y;
+  int i, j;
+  double cx0 = sqrt(1.0 / N);
+  double cy0 = sqrt(1.0 / M);
+  double t;
+
+  for (x = 0; x < N; x++) {
+    for (y = 0; y < M; y++) {
+
+      t = cx0 * cy0 * dcts[0][0];
+
+      for (i = 1; i < N; i++)
+        t += cy0 * dcts[0][i] * dct_NxM_costable_x[x][i];
+
+      for (j = 1; j < M; j++)
+        t += cx0 * dcts[j][0] * dct_NxM_costable_y[y][j];
+
+      for (i = 1; i < N; i++) {
+        double s = 0.0;
+        for (j = 1; j < M; j++) {
+          s += dcts[j][i] * dct_NxM_costable_y[y][j];
+        }
+        t += s * dct_NxM_costable_x[x][i];
+      }
+
+      pixels[y][x] = PIXELRANGE((int) (t + 128.5));
+    }
+  }
+}
+
+double C[NJPEG][NJPEG];
+double Ct[NJPEG][NJPEG];
+int Quantum[NJPEG][NJPEG];
+
+void init_quantum_8x8(int quality) {
+  int i;
+  int j;
+
+  for (i = 0; i < NJPEG; i++)
+    for ( j = 0 ; j < NJPEG ; j++ )
+      Quantum[ i ][ j ] = 1 + ( ( 1 + i + j )  * quality );
+}
+
+void init_quantum_JPEG_lumin(int quality) {
+  int i;
+  int j;
+
+  if (quality < 50)
+    quality = 5000 / quality;
+  else
+    quality = 200 - quality * 2;
+
+  for (i = 0; i < NJPEG; i++)
+    for (j = 0 ; j < NJPEG ; j++)
+      if (quality)
+        Quantum[i][j] = (JPEG_lumin_quant_table[i][j] * quality + 50) / 100;
+      else
+        Quantum[i][j] = JPEG_lumin_quant_table[i][j];
+}
+
+void init_quantum_JPEG_chromin(int quality) {
+  int i;
+  int j;
+
+  if (quality < 50)
+    quality = 5000 / quality;
+  else
+    quality = 200 - quality * 2;
+
+  for (i = 0; i < NJPEG; i++)
+    for (j = 0 ; j < NJPEG ; j++)
+      if (quality)
+        Quantum[i][j] = (JPEG_lumin_quant_table[i][j] * quality + 50) / 100;
+      else
+        Quantum[i][j] = JPEG_lumin_quant_table[i][j];
+}
+
+void quantize_8x8(double **transform) {
+  int i;
+  int j;
+
+  for (i = 0; i < NJPEG; i++)
+    for (j = 0; j < NJPEG; j++)
+      transform[i][j] = ROUND(transform[i][j] / Quantum[i][j]);
+}
+
+void dequantize_8x8(double **transform) {
+  int i;
+  int j;
+
+  for (i = 0; i < NJPEG; i++)
+    for (j = 0; j < NJPEG; j++)
+      transform[i][j] = ROUND(transform[i][j] * Quantum[i][j]);
+}
+
+void init_dct_8x8() {
+  int i;
+  int j;
+  double pi = atan( 1.0 ) * 4.0;
+
+  for ( j = 0 ; j < NJPEG ; j++ ) {
+    C[ 0 ][ j ] = 1.0 / sqrt( (double) NJPEG );
+    Ct[ j ][ 0 ] = C[ 0 ][ j ];
+  }
+
+  for ( i = 1 ; i < NJPEG ; i++ )
+    for ( j = 0 ; j < NJPEG ; j++ ) {
+      C[ i ][ j ] = sqrt( 2.0 / NJPEG ) * cos( pi * ( 2 * j + 1 ) * i / ( 2.0 * NJPEG ) );
+      Ct[ j ][ i ] = C[ i ][ j ];
+    }
+}
+
+/*
+ * The Forward DCT routine implements the matrix function:
+ *
+ *                     DCT = C * pixels * Ct
+ */
+
+void fdct_8x8(gray **input, double **output) {
+    double temp[NJPEG][NJPEG];
+    double temp1;
+    int i;
+    int j;
+    int k;
+
+/*  MatrixMultiply( temp, input, Ct ); */
+    for ( i = 0 ; i < NJPEG ; i++ ) {
+        for ( j = 0 ; j < NJPEG ; j++ ) {
+            temp[ i ][ j ] = 0.0;
+            for ( k = 0 ; k < NJPEG ; k++ )
+                 temp[ i ][ j ] += ( (int) input[ i ][ k ] - 128 ) *
+                                   Ct[ k ][ j ];
+        }
+    }
+
+/*  MatrixMultiply( output, C, temp ); */
+    for ( i = 0 ; i < NJPEG ; i++ ) {
+        for ( j = 0 ; j < NJPEG ; j++ ) {
+            temp1 = 0.0;
+            for ( k = 0 ; k < NJPEG ; k++ )
+                temp1 += C[ i ][ k ] * temp[ k ][ j ];
+            output[ i ][ j ] = temp1;
+        }
+    }
+}
+
+void fdct_block_8x8(gray **input, int col, int row, double **output) {
+  int i;
+  gray *input_array[NJPEG];
+
+  for (i = 0; i < NJPEG; i++)
+    input_array[i] = &input[row + i][col];
+
+  fdct_8x8(input_array, output);
+}
+
+/*
+ * The Inverse DCT routine implements the matrix function:
+ *
+ *                     pixels = C * DCT * Ct
+ */
+
+void idct_8x8(double **input, gray **output) {
+    double temp[ NJPEG ][ NJPEG ];
+    double temp1;
+    int i;
+    int j;
+    int k;
+
+/*  MatrixMultiply( temp, input, C ); */
+    for ( i = 0 ; i < NJPEG ; i++ ) {
+        for ( j = 0 ; j < NJPEG ; j++ ) {
+            temp[ i ][ j ] = 0.0;
+            for ( k = 0 ; k < NJPEG ; k++ )
+                temp[ i ][ j ] += input[ i ][ k ] * C[ k ][ j ];
+        }
+    }
+
+/*  MatrixMultiply( output, Ct, temp ); */
+    for ( i = 0 ; i < NJPEG ; i++ ) {
+        for ( j = 0 ; j < NJPEG ; j++ ) {
+            temp1 = 0.0;
+            for ( k = 0 ; k < NJPEG ; k++ )
+                temp1 += Ct[ i ][ k ] * temp[ k ][ j ];
+            temp1 += 128.0;
+            output[i][j] = PIXELRANGE(ROUND(temp1));
+        }
+    }
+}
+
+void idct_block_8x8(double **input, gray **output, int col, int row) {
+  int i;
+  gray *output_array[NJPEG];
+
+  for (i = 0; i < NJPEG; i++)
+    output_array[i] = &output[row + i][col];
+
+  idct_8x8(input, output_array);
+}
+
+int is_middle_frequency_coeff_8x8(int coeff) {
+  switch (coeff) {
+    case 3:
+    case 10:
+    case 17:
+    case 24:
+      return 1;
+    case 4:
+    case 11:
+    case 18:
+    case 25:
+    case 32:
+      return 2;
+    case 5:
+    case 12:
+    case 19:
+    case 26:
+    case 33:
+    case 40:
+      return 3;
+    case 13:
+    case 20:
+    case 27:
+    case 34:
+    case 41:
+      return 4;
+    case 28:
+    case 35:
+      return 5;
+    default:
+      return 0;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Meerwald-dir/dct.h	Fri Dec 20 13:08:59 2024 +0100
@@ -0,0 +1,38 @@
+#ifndef DCT_H
+#define DCT_H
+
+#include "wm.h"
+#include "coeff.h"
+#include "netpbm/pgm.h"
+
+extern int N;
+extern int M;
+
+void init_dct_NxM(int width, int height);
+void fdct_NxM(gray **pixels, double **dcts);
+void idct_NxM(double **dcts, gray **pixels);
+
+void init_dct_NxN(int width, int height);
+void fdct_NxN(gray **pixels, double **dcts);
+void idct_NxN(double **dcts, gray **pixels);
+void fdct_inplace_NxN(double **coeffs);
+void idct_inplace_NxN(double **coeffs);
+
+/*
+ * 'NJPEG' defines the JPEG's DCT block size (8x8)
+ */
+#define NJPEG 8
+
+void init_quantum_8x8(int quality);
+void init_quantum_JPEG_lumin(int quality);
+void init_quantum_JPEG_chromin(int quality);
+void quantize_8x8(double **transform);
+void dequantize_8x8(double **transform);
+void init_dct_8x8();
+void fdct_8x8(gray **input, double **output);
+void fdct_block_8x8(gray **input, int col, int row, double **output);
+void idct_8x8(double **input, gray **output);
+void idct_block_8x8(double **input, gray **output, int col, int row);
+int is_middle_frequency_coeff_8x8(int coeff);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Meerwald-dir/dwt.c	Fri Dec 20 13:08:59 2024 +0100
@@ -0,0 +1,361 @@
+#include "wm.h"
+#include "dwt.h"
+
+char filter_file[MAXPATHLEN] = "";
+AllFilters dwt_allfilters;
+FilterGH *dwt_filters = NULL;
+int dwt_method;
+int dwt_cols;
+int dwt_rows;
+int dwt_levels;
+int dwt_filter;
+
+void init_dwt(int cols, int rows, const char *filter_name, int filter, int level, int method) {
+  int i;
+
+  if (strcmp(filter_file, filter_name)) {
+    if (filter_name)
+      strcpy(filter_file, filter_name);
+    else
+      strcpy(filter_file, "filter.dat");
+
+    /* memory leak here - there is no function unload_filters() */
+    dwt_allfilters = load_filters(filter_file);
+
+    if (!dwt_allfilters) {
+      fprintf(stderr, "init_dwt(): unable to open filter definition file %s\n", filter_file);
+      return;
+    }
+  }
+
+#ifdef DEBUG
+  if (level <= 0 || level > 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() {
+}
--- /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
--- /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 <ctype.h>
+
+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);
+}
--- /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
--- /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
+		
+	}
+}
--- /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;
+}
--- /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
--- /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 <pmeerw@cosy.sbg.ac.at>
+.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
--- /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);
+}
--- /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)
--- /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);
+}
--- /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)
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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)
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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)
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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");
+  }
+}
--- /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
--- /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;
+}
+
--- /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
--- /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
+
--- /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
+
--- /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 <string.h>
+#include <strings.h>
+#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);
+}
--- /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
--- /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
--- /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;
+      }
+    }
+  }
+}
+
+
--- /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
--- /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;
+}
--- /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
--- /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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "wavelet.h"
+#include <ctype.h>
+#include <values.h>
+
+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; i<img->size; 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;i<img->size;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;i<img->size;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;i<img2->height;i++) {
+          for (j=0;j<img2->width;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;i<img2->height;i++)
+        {
+          for (j=0;j<img2->width;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;y<height;y++)
+	{
+		memcpy(dp,sp,siz);
+		sp+=src_img->width;
+		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;i<height;i++) {
+	  step=i*img2->width;
+	  for (j=0;j<width;j++){
+	    *data=img2->data[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;i<img->size;i++) {
+  	  if (img->data[i]<min) min=img->data[i];
+  	  else if (img->data[i]>max) max=img->data[i];
+	}
+
+	multi=(Pixel)maximum/(max-min);
+	for (i=0;i<img->size;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;j<i->size;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;j<img->size;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;y<image->height;y++)
+		for (x=0;x<image->width;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;i<max;i++)
+		d[i]=i2[i]-i1[i];
+
+	return diff;
+}
+
+
+/************************************************************************/
+/*      Functionname: get_intimage_infos                                */
+/* -------------------------------------------------------------------- */
+/*      Parameter:                                                      */
+/*          IntImage image: input image                                 */
+/*          IntPixel *min,*max, return minimum, maximum			*/
+/*	       Pixel *avg,*var: average and variance of current image   */
+/*                average and variance of current image                 */
+/* -------------------------------------------------------------------- */
+/*      Description:                                                    */
+/*          get statistical information of Image                        */
+/************************************************************************/
+
+void get_intimage_infos(IntImage image, IntPixel *min, IntPixel *max, Pixel *avg, Pixel *var)
+{
+	int x,y;
+	Pixel p,sp,sp2;
+
+	sp=sp2=(Pixel)0.0;
+
+	p= (Pixel) get_intpixel(image,0,0);
+	*min=*max=p;
+
+	for (y=0;y<image->height;y++)
+		for (x=0;x<image->width;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;y<img->height;y++)
+	for(x=0;x<img->width;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;i<f->len;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;i<out_len;i++)
+	{
+		i2=2*i;
+
+		fstart=i2-(in_len-1);
+		fstart=MAX(fstart,f->start);
+		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;i<out_len;i++)
+	{
+		fstart=CEILING_HALF(f->start+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;i<out_len;i++)
+	{
+		i2=2*i;
+
+		fstart=f->start;
+		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;i<out_len;i++)
+	{
+		fstart=CEILING_HALF(f->start+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;i<out_len;i++)
+	{
+		i2=2*i;
+
+		fstart=f->start;
+		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;i<out_len;i++)
+	{
+		fstart=CEILING_HALF(f->start+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-i<f->start || 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;i<filter->len;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;i<max;i++)
+	{
+		if (!get_next_line(f,str)) goto error2;
+		if (*str!='{')
+		{
+			Trace("error: '{' not found\n");
+			goto error2;
+		}
+		if (!(filter=read_filter(f)))
+		{
+			Trace("error: read_filter failed\n");
+			goto error2;
+		}
+		filter->hipass = !(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->height<min) min=original->height;
+	max_level=log(min)/log(2)-2;
+	if (max_level<level) level=max_level;
+
+	if (level<1)  /* do not transform */
+	{
+		ret_tree->image=tempi;
+		return ret_tree;
+	}
+
+	/* decomposition */
+	
+	for (i=0;i<level;i++)
+	{
+
+	        width=(width+1)/2;
+		height=(height+1)/2;
+	
+		coarsei=new_image(width,height);
+		horizontali=new_image(width,height);
+		verticali=new_image(width,height);
+		diagonali=new_image(width,height);
+		if(!coarsei||!horizontali||!verticali||!diagonali) goto error;		
+
+		e=decomposition(tempi,coarsei,horizontali,verticali,diagonali,
+	                       flt[i]->g,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->height<min) min=original->height;
+	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]<min)
+		{
+			min=entropies[i];
+			best=i;
+		}
+	}
+
+	/* free all other levels */
+	free_levels(tree,best);
+
+	*bestlevel=best;
+	
+	return tree;
+
+	error:
+        	err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory));	
+	  	return NULL;	
+}
+
+/************************************************************************/
+/*	Functionname: compute_best					*/
+/* -------------------------------------------------------------------- */
+/*	Parameter: 							*/
+/*		img: Image that should be transformed	 		*/
+/*	        level: transform level	                		*/
+/*		max_level: transform to maximum 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 basis selection (recursivly)  */
+/*	             (is needed by the waveletpacket procedure)		*/
+/************************************************************************/
+static int compute_best(Image_tree tree,int level,int max_level,FilterGH *flt,
+                        enum FilterMethod method,enum Information_Cost cost,double epsilon)
+
+{ 	Image coarse,horizontal,vertical,diagonal;
+        int e,width,height;
+	double sum;
+	
+	tree->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 (level<max_level) {
+        	width=(tree->image->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->level<maxlevel)
+	{
+		tree->coarse=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->level<best)
+	{
+		free_image(tree->image);
+		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;i<input->height;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;i<input->width;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;i<img->size;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;i<img->size;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;i<list_size;i++) list[i]=fabs(list[i]);
+}
+
+/************************************************************************/
+/*	Functionname: sum_list						*/
+/* -------------------------------------------------------------------- */
+/* 	Description: computes the sum of all poweres list elements	*/
+/************************************************************************/
+static Pixel sum_list(Pixel *list,int p,int size)
+{	Pixel sum=0;
+	int i;
+	
+	for (i=0;i<size;i++)
+	{
+		if (p!=1) sum+=pow(list[i],p);
+		else sum+=list[i];
+	}
+	return sum;
+}
+
+static Pixel weak_lp(Image_tree tree,int size,int p,double epsilon)
+{	Pixel wlp,*list,max=0;
+	int *list_size,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);
+
+	for (k=0;k<size;k++)
+	{
+		if (k!=0) wlp=pow(k,1/p)*list[k];
+		else wlp=0;
+		if (wlp>max) 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;k<size;k++)
+	{
+		if (list[k]!=0)
+		{
+			sum+=pow(list[k],p);
+			npf=fabs(sum-normf);
+			if (npf<min) min=npf;
+		}
+	}
+	min=min/norm;
+
+	free(list);
+	
+	return min;
+
+	error:
+        	err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory));	
+	  	return 0;	
+}
+
+static Pixel comp_area(Image_tree tree,int size,int p,double f)
+{	Pixel sum=0,*list,norm,vk=0;
+	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);
+
+	for (k=0;k<size;k++)
+	{
+		if (list[k]!=0)
+		{
+			vk+=pow(list[k],p);
+			sum+=vk;
+			
+		}
+	}
+
+	free(list);
+	
+	return (size-sum/norm);
+
+	error:
+        	err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory));	
+	  	return 0;	
+}
+
+static Pixel compute_sdiscrepancy(Image_tree tree,int size)
+{	Pixel *list,min,max,factor,maximum=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;k<size;k++)
+	{
+		list[k]=factor*(list[k]-min);
+	}
+
+	for (k=0;k<size;k++)
+	{
+		x=fabs(list[k]-(2*k-1)/(2*size));
+		if (x>maximum) 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;k<size;k++)
+	{
+		list[k]=factor*(list[k]-min);
+	}
+
+	for (k=0;k<size;k++)
+	{
+		x=((Pixel)k/size-list[k]);
+		if (x>maximum) maximum=x;
+		else if (x<minimum) minimum=x;
+		
+	}
+	
+	free(list);
+	
+	return (1/size+maximum-minimum);
+
+	error:
+        	err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory));	
+	  	return 0;	
+}
+
+static Pixel compute_concentration(Image_tree tree,int size)
+{	Pixel *list,min,max,factor,lkm=0,length,sum=0,value,norm;
+	int *list_size=0,k,next=0,last=0,i=0;
+
+	list_size=(int *)malloc(sizeof(int));
+	if (!list_size) goto error;
+	*list_size=0;
+
+	list=(Pixel *)calloc(size+1,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];
+	length=(max-min)/100;
+	
+	factor=1/(max-min);
+	for (k=0;k<size;k++)
+	{
+		list[k]=factor*(list[k]-min);
+	}
+	
+	norm=size*sum_list(list,1,size);
+	length=0.01;
+	value=length;
+	
+	list[size]=max+value;
+	
+	for (k=0;k<100;k++)
+	{
+		while ((list[i]<value)&(i<size))
+		{
+			sum+=list[i];
+			next++;
+			i++;
+		}
+		lkm+=(next-last)*sum/norm;
+		value+=length;
+		last=next;
+		sum=0;
+	}
+	
+	return -lkm;
+	
+	error:
+        	err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory));	
+	  	return 0;	
+}
+/************************************************************************/
+/*	Functionname: compute_entropy					*/
+/* -------------------------------------------------------------------- */
+/*	Parameter: 							*/
+/*		img: Image from which the entropy should be computed	*/
+/*		cost: choosen costfunction				*/
+/*		epsilon: limit for threshold method			*/
+/* -------------------------------------------------------------------- */
+/* 	Description: computes entropy of an image			*/
+/************************************************************************/
+static double compute_entropy(Image img,enum Information_Cost cost,double epsilon)
+{       double sum=0,x=0;
+	int i;
+	Pixel *data;
+	
+	data=img->data;
+	
+	switch(cost) {
+
+	case threshold:
+  		for(i=0;i<img->size;i++) 
+	    		if (fabs(img->data[i])>epsilon) sum++;  
+  	break;
+
+	case log_energy:  
+        	for(i=0;i<img->size;i++,data++) {
+        		x=(*data) * (*data);
+	  		if (x!=0) sum+=(x*log(1/x));
+	  	}
+	break;
+
+	case norml:
+        	for(i=0;i<img->size;i++,data++) {
+        		x=fabs(*data);
+	  		sum+=x;
+	  	}
+	break;	
+
+	case norml2:
+        	for(i=0;i<img->size;i++,data++) {
+        		x=(*data) * (*data);
+	  		sum+=x;
+	  	}
+	  	sum=pow(sum,0.5);
+	break;	
+
+	case entropy:
+		for(i=0;i<img->size;i++,data++) {
+	    		x=(*data)*(*data);
+	    		if (x!=0) sum-=(x*log(x));
+	  	}
+	break;
+	 
+	case gauss_markov:
+		for(i=0;i<img->size;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->height<min) min=dtree->image->height;
+
+	if (doubletree_min<min)
+	{
+		width=(dtree->image->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;i<len;i++)
+	{
+		if (list[i]==x)
+		{
+			found=1;
+			i=len;
+		}
+	}
+
+	return found;
+}
+
+static void write_flags(Image_tree tree,int *list,int len,int pos)
+{
+	int shift,next_pos,max;
+
+	if (is_in_list(list,len,pos))
+	{
+		tree->flag=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;
+
+
+	}
+}
--- /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 <stdio.h>
+
+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 <stddef.h>
+
+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
--- /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<length; i++) { *b=0; b++; }
+}
+#endif
+
+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_in_binary();
+}
+
+void wm_init1() {
+  set_out_binary();
+}
+
+void wm_init() {
+  set_in_binary();
+  set_out_binary();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Meerwald-dir/wm.h	Fri Dec 20 13:08:59 2024 +0100
@@ -0,0 +1,64 @@
+#ifndef WM_H
+#define WM_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <getopt.h>
+#include <math.h>
+#include <float.h>
+#include <fcntl.h>
+
+#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 <values.h>
+#include <sys/param.h>
+#include <unistd.h>
+#include <time.h>
+#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
--- /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);
+}
--- /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);
+}
--- /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 <pmeerw@cosy.sbg.ac.at>
+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)
--- /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);
+}
--- /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)
--- /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);
+}
--- /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)
--- /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);
+}
--- /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)
--- /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);
+}
--- /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)
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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)
--- /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);
+}
--- /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)
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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[]) {
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- /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);
+}
--- 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
-
--- 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 <disclaimer.h>
-
-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
--- 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;
-}
-
-
--- 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 */
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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)
--- 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);
-}
--- 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)
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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[]) {
-}
--- 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)
--- 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);
-}
--- 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)
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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");
-  }
-}
--- 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
--- 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 <stdlib.h>
-#include <stdio.h>
-#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;
-}
-
-
--- 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
--- 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<<dct_NxN_log2N)>N){
-      fprintf(stderr, "dct_NxN: %d not a power of 2\n", N);
-      exit(1);
-    }
-  }while((1<<dct_NxN_log2N)<N);
-  if (dct_NxN_costable) free(dct_NxN_costable);
-  dct_NxN_costable = malloc(N * sizeof(double));
-#ifdef DEBUG
-  if(!dct_NxN_costable){
-    fprintf(stderr, "Unable to allocate C array\n");
-    exit(1);
-  }
-#endif
-  halfN=N/2;
-  for(i=0;i<=halfN-1;i++) dct_NxN_costable[halfN+i]=4*i+1;
-  for(group=1;group<=dct_NxN_log2N-1;group++){
-    base= 1<<(group-1);
-    nitems=base;
-    factor = 1.0*(1<<(dct_NxN_log2N-group));
-    for(item=1; item<=nitems;item++) dct_NxN_costable[base+item-1]=factor*dct_NxN_costable[halfN+item-1];
-  }
-
-  for(i=1;i<=N-1;i++) dct_NxN_costable[i] = 1.0/(2.0*cos(dct_NxN_costable[i]*M_PI/(2.0*N)));
-}
-
-void init_dct_NxN(int width, int height) {
-#ifdef DEBUG
-  if (width != height || width <= 0) {
-    fprintf(stderr, "init_dct_NxN(): dimensions out of range\n");
-    exit(1);
-  }
-#endif
-
-  if (dct_NxN_tmp && M != height)
-    free(dct_NxN_tmp);
-
-  N = width;
-  M = height;
-
-  dct_NxN_tmp = malloc(height * sizeof(double));
-#ifdef DEBUG
-  if (!dct_NxN_tmp) {
-    fprintf(stderr, "init_dct_NxN(): failed to allocate memory\n");
-    exit(1);
-  }
-#endif
-
-  initcosarray();
-}
-
-static void bitrev(double *f, int len)
-{
-  int i,j,m;
-
-  if (len<=2) return; /* No action necessary if n=1 or n=2 */
-  j=1;
-  for(i=1; i<=len; i++){
-    if(i<j)
-      SWAP(f[j-1], f[i-1]);
-    m = len>>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<N;u++)
-    for (v=0;v<M;v++)
-      tmp[u][v] = dcts[u][v];
-
-  for (u=0; u<=M-1; u++){
-    ifct_noscale(tmp[u]);
-  }
-  for (v=0; v<=N-1; v++){
-    for (u=0; u<=M-1; u++){
-       dct_NxN_tmp[u] = tmp[u][v];
-    }
-    ifct_noscale(dct_NxN_tmp);
-    for (u=0; u<=M-1; u++){
-       tmp[u][v] = dct_NxN_tmp[u]*two_over_sqrtncolsnrows;
-    }
-  }
-
- for (u=0;u<N;u++)
-    for (v=0;v<M;v++)
-      pixels[u][v] = PIXELRANGE(tmp[u][v] + 128.5);
- free(tmp);
-}
-
-void fdct_inplace_NxN(double **coeffs) {
-  int u,v;
-  double two_over_sqrtncolsnrows = 2.0/sqrt((double) N*M);
-
-  for (u=0; u<=M-1; u++)
-    fct_noscale(coeffs[u]);
-
-  for (v=0; v<=N-1; v++){
-    for (u=0; u<=M-1; u++)
-       dct_NxN_tmp[u] = coeffs[u][v];
-
-    fct_noscale(dct_NxN_tmp);
-    for (u=0; u<=M-1; u++)
-      coeffs[u][v] = dct_NxN_tmp[u]*two_over_sqrtncolsnrows;
-  }
-}
-
-void idct_inplace_NxN(double **coeffs) {
- int u,v;
- double two_over_sqrtncolsnrows = 2.0/sqrt((double) N*M);
-
-  for (u=0; u<=M-1; u++)
-    ifct_noscale(coeffs[u]);
-
-  for (v=0; v<=N-1; v++) {
-    for (u=0; u<=M-1; u++)
-       dct_NxN_tmp[u] = coeffs[u][v];
-
-    ifct_noscale(dct_NxN_tmp);
-    for (u=0; u<=M-1; u++)
-       coeffs[u][v] = dct_NxN_tmp[u]*two_over_sqrtncolsnrows;
-  }
-
-}
-
-double **dct_NxM_costable_x = NULL;
-double **dct_NxM_costable_y = NULL;
-
-void init_dct_NxM(int cols, int rows) {
-  int i, j;
-  double cx = sqrt(2.0 / cols);
-  double cy = sqrt(2.0 / rows);
-
-#ifdef DEBUG
-  if (cols <= 0 || rows <= 0) {
-    fprintf(stderr, "init_dct_NxM(): dimensions out of range\n");
-    exit(1);
-  }
-#endif
-
-  if (dct_NxM_costable_x && N != cols) {
-    free_coeffs(dct_NxM_costable_x);
-    dct_NxM_costable_x = NULL;
-  }
-
-  if (dct_NxM_costable_y && M != rows) {
-    free_coeffs(dct_NxM_costable_y);
-    dct_NxM_costable_y = NULL;
-  }
-
-  if (!dct_NxM_costable_x)
-    dct_NxM_costable_x = alloc_coeffs(cols, cols);
-  if (!dct_NxM_costable_y)
-    dct_NxM_costable_y = alloc_coeffs(rows, rows);
-
-  N = cols;
-  M = rows;
-
-  for (i = 0; i < cols; i++) {
-    for (j = 0; j < cols; j++) {
-      dct_NxM_costable_x[i][j] = cx * cos((M_PI * ((2*i + 1) * j)) / (double) (2 * N));
-    }
-  }
-
-  for (i = 0; i < rows; i++) {
-    for (j = 0; j < rows; j++) {
-      dct_NxM_costable_y[i][j] = cy * cos((M_PI * ((2*i + 1) * j)) / (double) (2 * M));
-    }
-  }
-}
-
-void fdct_NxM(gray **pixels, double **dcts) {
-  int x, y;
-  int i, j;
-  double t;
-  double cx0 = sqrt(1.0 / N);
-  double cy0 = sqrt(1.0 / M);
-
-  t = 0.0;
-  for (x = 0; x < N; x++)
-    for (y = 0; y < M; y++)
-      t += ((int) pixels[y][x] - 128);
-  dcts[0][0] = cx0 * cy0 * t;
-
-  for (i = 1; i < N; i++) {
-    t = 0.0;
-    for (x = 0; x < N; x++) {
-      double s = 0.0;
-      for (y = 0; y < M; y++) {
-        s += ((int) pixels[y][x] - 128);
-      }
-      t += s * dct_NxM_costable_x[x][i];
-    }
-    dcts[0][i] = cy0 * t;
-  }
-
-  for (j = 1; j < M; j++) {
-    t = 0.0;
-    for (y = 0; y < M; y++) {
-      double s = 0.0;
-      for (x = 0; x < N; x++) {
-        s += ((int) pixels[y][x] - 128);
-      }
-      t += s * dct_NxM_costable_y[y][j];
-    }
-    dcts[j][0] = cx0 * t;
-  }
-
-  for (i = 1; i < N; i++) {
-     for (j = 1; j < M; j++) {
-      t = 0.0;
-      for (x = 0; x < N; x++) {
-        double s = 0;
-        for (y = 0; y < M; y++) {
-          s += ((int) pixels[y][x] - 128) * dct_NxM_costable_y[y][j];
-        }
-        t += s * dct_NxM_costable_x[x][i];
-      }
-      dcts[j][i] = t;
-    }
-  }
-}
-
-void idct_NxM(double **dcts, gray **pixels) {
-  int x, y;
-  int i, j;
-  double cx0 = sqrt(1.0 / N);
-  double cy0 = sqrt(1.0 / M);
-  double t;
-
-  for (x = 0; x < N; x++) {
-    for (y = 0; y < M; y++) {
-
-      t = cx0 * cy0 * dcts[0][0];
-
-      for (i = 1; i < N; i++)
-        t += cy0 * dcts[0][i] * dct_NxM_costable_x[x][i];
-
-      for (j = 1; j < M; j++)
-        t += cx0 * dcts[j][0] * dct_NxM_costable_y[y][j];
-
-      for (i = 1; i < N; i++) {
-        double s = 0.0;
-        for (j = 1; j < M; j++) {
-          s += dcts[j][i] * dct_NxM_costable_y[y][j];
-        }
-        t += s * dct_NxM_costable_x[x][i];
-      }
-
-      pixels[y][x] = PIXELRANGE((int) (t + 128.5));
-    }
-  }
-}
-
-double C[NJPEG][NJPEG];
-double Ct[NJPEG][NJPEG];
-int Quantum[NJPEG][NJPEG];
-
-void init_quantum_8x8(int quality) {
-  int i;
-  int j;
-
-  for (i = 0; i < NJPEG; i++)
-    for ( j = 0 ; j < NJPEG ; j++ )
-      Quantum[ i ][ j ] = 1 + ( ( 1 + i + j )  * quality );
-}
-
-void init_quantum_JPEG_lumin(int quality) {
-  int i;
-  int j;
-
-  if (quality < 50)
-    quality = 5000 / quality;
-  else
-    quality = 200 - quality * 2;
-
-  for (i = 0; i < NJPEG; i++)
-    for (j = 0 ; j < NJPEG ; j++)
-      if (quality)
-        Quantum[i][j] = (JPEG_lumin_quant_table[i][j] * quality + 50) / 100;
-      else
-        Quantum[i][j] = JPEG_lumin_quant_table[i][j];
-}
-
-void init_quantum_JPEG_chromin(int quality) {
-  int i;
-  int j;
-
-  if (quality < 50)
-    quality = 5000 / quality;
-  else
-    quality = 200 - quality * 2;
-
-  for (i = 0; i < NJPEG; i++)
-    for (j = 0 ; j < NJPEG ; j++)
-      if (quality)
-        Quantum[i][j] = (JPEG_lumin_quant_table[i][j] * quality + 50) / 100;
-      else
-        Quantum[i][j] = JPEG_lumin_quant_table[i][j];
-}
-
-void quantize_8x8(double **transform) {
-  int i;
-  int j;
-
-  for (i = 0; i < NJPEG; i++)
-    for (j = 0; j < NJPEG; j++)
-      transform[i][j] = ROUND(transform[i][j] / Quantum[i][j]);
-}
-
-void dequantize_8x8(double **transform) {
-  int i;
-  int j;
-
-  for (i = 0; i < NJPEG; i++)
-    for (j = 0; j < NJPEG; j++)
-      transform[i][j] = ROUND(transform[i][j] * Quantum[i][j]);
-}
-
-void init_dct_8x8() {
-  int i;
-  int j;
-  double pi = atan( 1.0 ) * 4.0;
-
-  for ( j = 0 ; j < NJPEG ; j++ ) {
-    C[ 0 ][ j ] = 1.0 / sqrt( (double) NJPEG );
-    Ct[ j ][ 0 ] = C[ 0 ][ j ];
-  }
-
-  for ( i = 1 ; i < NJPEG ; i++ )
-    for ( j = 0 ; j < NJPEG ; j++ ) {
-      C[ i ][ j ] = sqrt( 2.0 / NJPEG ) * cos( pi * ( 2 * j + 1 ) * i / ( 2.0 * NJPEG ) );
-      Ct[ j ][ i ] = C[ i ][ j ];
-    }
-}
-
-/*
- * The Forward DCT routine implements the matrix function:
- *
- *                     DCT = C * pixels * Ct
- */
-
-void fdct_8x8(gray **input, double **output) {
-    double temp[NJPEG][NJPEG];
-    double temp1;
-    int i;
-    int j;
-    int k;
-
-/*  MatrixMultiply( temp, input, Ct ); */
-    for ( i = 0 ; i < NJPEG ; i++ ) {
-        for ( j = 0 ; j < NJPEG ; j++ ) {
-            temp[ i ][ j ] = 0.0;
-            for ( k = 0 ; k < NJPEG ; k++ )
-                 temp[ i ][ j ] += ( (int) input[ i ][ k ] - 128 ) *
-                                   Ct[ k ][ j ];
-        }
-    }
-
-/*  MatrixMultiply( output, C, temp ); */
-    for ( i = 0 ; i < NJPEG ; i++ ) {
-        for ( j = 0 ; j < NJPEG ; j++ ) {
-            temp1 = 0.0;
-            for ( k = 0 ; k < NJPEG ; k++ )
-                temp1 += C[ i ][ k ] * temp[ k ][ j ];
-            output[ i ][ j ] = temp1;
-        }
-    }
-}
-
-void fdct_block_8x8(gray **input, int col, int row, double **output) {
-  int i;
-  gray *input_array[NJPEG];
-
-  for (i = 0; i < NJPEG; i++)
-    input_array[i] = &input[row + i][col];
-
-  fdct_8x8(input_array, output);
-}
-
-/*
- * The Inverse DCT routine implements the matrix function:
- *
- *                     pixels = C * DCT * Ct
- */
-
-void idct_8x8(double **input, gray **output) {
-    double temp[ NJPEG ][ NJPEG ];
-    double temp1;
-    int i;
-    int j;
-    int k;
-
-/*  MatrixMultiply( temp, input, C ); */
-    for ( i = 0 ; i < NJPEG ; i++ ) {
-        for ( j = 0 ; j < NJPEG ; j++ ) {
-            temp[ i ][ j ] = 0.0;
-            for ( k = 0 ; k < NJPEG ; k++ )
-                temp[ i ][ j ] += input[ i ][ k ] * C[ k ][ j ];
-        }
-    }
-
-/*  MatrixMultiply( output, Ct, temp ); */
-    for ( i = 0 ; i < NJPEG ; i++ ) {
-        for ( j = 0 ; j < NJPEG ; j++ ) {
-            temp1 = 0.0;
-            for ( k = 0 ; k < NJPEG ; k++ )
-                temp1 += Ct[ i ][ k ] * temp[ k ][ j ];
-            temp1 += 128.0;
-            output[i][j] = PIXELRANGE(ROUND(temp1));
-        }
-    }
-}
-
-void idct_block_8x8(double **input, gray **output, int col, int row) {
-  int i;
-  gray *output_array[NJPEG];
-
-  for (i = 0; i < NJPEG; i++)
-    output_array[i] = &output[row + i][col];
-
-  idct_8x8(input, output_array);
-}
-
-int is_middle_frequency_coeff_8x8(int coeff) {
-  switch (coeff) {
-    case 3:
-    case 10:
-    case 17:
-    case 24:
-      return 1;
-    case 4:
-    case 11:
-    case 18:
-    case 25:
-    case 32:
-      return 2;
-    case 5:
-    case 12:
-    case 19:
-    case 26:
-    case 33:
-    case 40:
-      return 3;
-    case 13:
-    case 20:
-    case 27:
-    case 34:
-    case 41:
-      return 4;
-    case 28:
-    case 35:
-      return 5;
-    default:
-      return 0;
-  }
-}
--- a/Meerwald/dct.h	Fri Dec 20 12:53:41 2024 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-#ifndef DCT_H
-#define DCT_H
-
-#include "wm.h"
-#include "coeff.h"
-#include "pgm.h"
-
-extern int N;
-extern int M;
-
-void init_dct_NxM(int width, int height);
-void fdct_NxM(gray **pixels, double **dcts);
-void idct_NxM(double **dcts, gray **pixels);
-
-void init_dct_NxN(int width, int height);
-void fdct_NxN(gray **pixels, double **dcts);
-void idct_NxN(double **dcts, gray **pixels);
-void fdct_inplace_NxN(double **coeffs);
-void idct_inplace_NxN(double **coeffs);
-
-/*
- * 'NJPEG' defines the JPEG's DCT block size (8x8)
- */
-#define NJPEG 8
-
-void init_quantum_8x8(int quality);
-void init_quantum_JPEG_lumin(int quality);
-void init_quantum_JPEG_chromin(int quality);
-void quantize_8x8(double **transform);
-void dequantize_8x8(double **transform);
-void init_dct_8x8();
-void fdct_8x8(gray **input, double **output);
-void fdct_block_8x8(gray **input, int col, int row, double **output);
-void idct_8x8(double **input, gray **output);
-void idct_block_8x8(double **input, gray **output, int col, int row);
-int is_middle_frequency_coeff_8x8(int coeff);
-
-#endif
--- a/Meerwald/dwt.c	Fri Dec 20 12:53:41 2024 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,361 +0,0 @@
-#include "wm.h"
-#include "dwt.h"
-
-char filter_file[MAXPATHLEN] = "";
-AllFilters dwt_allfilters;
-FilterGH *dwt_filters = NULL;
-int dwt_method;
-int dwt_cols;
-int dwt_rows;
-int dwt_levels;
-int dwt_filter;
-
-void init_dwt(int cols, int rows, const char *filter_name, int filter, int level, int method) {
-  int i;
-
-  if (strcmp(filter_file, filter_name)) {
-    if (filter_name)
-      strcpy(filter_file, filter_name);
-    else
-      strcpy(filter_file, "filter.dat");
-
-    /* memory leak here - there is no function unload_filters() */
-    dwt_allfilters = load_filters(filter_file);
-
-    if (!dwt_allfilters) {
-      fprintf(stderr, "init_dwt(): unable to open filter definition file %s\n", filter_file);
-      return;
-    }
-  }
-
-#ifdef DEBUG
-  if (level <= 0 || level > 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() {
-}
--- 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
--- 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 <ctype.h>
-
-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);
-}
--- 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
--- 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
-		
-	}
-}
--- 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;
-}
--- 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
--- 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 <pmeerw@cosy.sbg.ac.at>
-.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
--- 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);
-}
--- 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)
--- 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);
-}
--- 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)
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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)
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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)
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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");
-  }
-}
--- 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
--- 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;
-}
-
--- 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
--- 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
-
--- 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
-
--- 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 <string.h>
-#include <strings.h>
-#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);
-}
--- 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
--- 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
--- 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;
-      }
-    }
-  }
-}
-
-
--- 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
--- 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;
-}
--- 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
--- 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include "wavelet.h"
-#include <ctype.h>
-#include <values.h>
-
-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; i<img->size; 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;i<img->size;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;i<img->size;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;i<img2->height;i++) {
-          for (j=0;j<img2->width;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;i<img2->height;i++)
-        {
-          for (j=0;j<img2->width;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;y<height;y++)
-	{
-		memcpy(dp,sp,siz);
-		sp+=src_img->width;
-		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;i<height;i++) {
-	  step=i*img2->width;
-	  for (j=0;j<width;j++){
-	    *data=img2->data[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;i<img->size;i++) {
-  	  if (img->data[i]<min) min=img->data[i];
-  	  else if (img->data[i]>max) max=img->data[i];
-	}
-
-	multi=(Pixel)maximum/(max-min);
-	for (i=0;i<img->size;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;j<i->size;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;j<img->size;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;y<image->height;y++)
-		for (x=0;x<image->width;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;i<max;i++)
-		d[i]=i2[i]-i1[i];
-
-	return diff;
-}
-
-
-/************************************************************************/
-/*      Functionname: get_intimage_infos                                */
-/* -------------------------------------------------------------------- */
-/*      Parameter:                                                      */
-/*          IntImage image: input image                                 */
-/*          IntPixel *min,*max, return minimum, maximum			*/
-/*	       Pixel *avg,*var: average and variance of current image   */
-/*                average and variance of current image                 */
-/* -------------------------------------------------------------------- */
-/*      Description:                                                    */
-/*          get statistical information of Image                        */
-/************************************************************************/
-
-void get_intimage_infos(IntImage image, IntPixel *min, IntPixel *max, Pixel *avg, Pixel *var)
-{
-	int x,y;
-	Pixel p,sp,sp2;
-
-	sp=sp2=(Pixel)0.0;
-
-	p= (Pixel) get_intpixel(image,0,0);
-	*min=*max=p;
-
-	for (y=0;y<image->height;y++)
-		for (x=0;x<image->width;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;y<img->height;y++)
-	for(x=0;x<img->width;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;i<f->len;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;i<out_len;i++)
-	{
-		i2=2*i;
-
-		fstart=i2-(in_len-1);
-		fstart=MAX(fstart,f->start);
-		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;i<out_len;i++)
-	{
-		fstart=CEILING_HALF(f->start+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;i<out_len;i++)
-	{
-		i2=2*i;
-
-		fstart=f->start;
-		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;i<out_len;i++)
-	{
-		fstart=CEILING_HALF(f->start+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;i<out_len;i++)
-	{
-		i2=2*i;
-
-		fstart=f->start;
-		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;i<out_len;i++)
-	{
-		fstart=CEILING_HALF(f->start+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-i<f->start || 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;i<filter->len;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;i<max;i++)
-	{
-		if (!get_next_line(f,str)) goto error2;
-		if (*str!='{')
-		{
-			Trace("error: '{' not found\n");
-			goto error2;
-		}
-		if (!(filter=read_filter(f)))
-		{
-			Trace("error: read_filter failed\n");
-			goto error2;
-		}
-		filter->hipass = !(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->height<min) min=original->height;
-	max_level=log(min)/log(2)-2;
-	if (max_level<level) level=max_level;
-
-	if (level<1)  /* do not transform */
-	{
-		ret_tree->image=tempi;
-		return ret_tree;
-	}
-
-	/* decomposition */
-	
-	for (i=0;i<level;i++)
-	{
-
-	        width=(width+1)/2;
-		height=(height+1)/2;
-	
-		coarsei=new_image(width,height);
-		horizontali=new_image(width,height);
-		verticali=new_image(width,height);
-		diagonali=new_image(width,height);
-		if(!coarsei||!horizontali||!verticali||!diagonali) goto error;		
-
-		e=decomposition(tempi,coarsei,horizontali,verticali,diagonali,
-	                       flt[i]->g,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->height<min) min=original->height;
-	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]<min)
-		{
-			min=entropies[i];
-			best=i;
-		}
-	}
-
-	/* free all other levels */
-	free_levels(tree,best);
-
-	*bestlevel=best;
-	
-	return tree;
-
-	error:
-        	err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory));	
-	  	return NULL;	
-}
-
-/************************************************************************/
-/*	Functionname: compute_best					*/
-/* -------------------------------------------------------------------- */
-/*	Parameter: 							*/
-/*		img: Image that should be transformed	 		*/
-/*	        level: transform level	                		*/
-/*		max_level: transform to maximum 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 basis selection (recursivly)  */
-/*	             (is needed by the waveletpacket procedure)		*/
-/************************************************************************/
-static int compute_best(Image_tree tree,int level,int max_level,FilterGH *flt,
-                        enum FilterMethod method,enum Information_Cost cost,double epsilon)
-
-{ 	Image coarse,horizontal,vertical,diagonal;
-        int e,width,height;
-	double sum;
-	
-	tree->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 (level<max_level) {
-        	width=(tree->image->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->level<maxlevel)
-	{
-		tree->coarse=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->level<best)
-	{
-		free_image(tree->image);
-		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;i<input->height;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;i<input->width;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;i<img->size;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;i<img->size;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;i<list_size;i++) list[i]=fabs(list[i]);
-}
-
-/************************************************************************/
-/*	Functionname: sum_list						*/
-/* -------------------------------------------------------------------- */
-/* 	Description: computes the sum of all poweres list elements	*/
-/************************************************************************/
-static Pixel sum_list(Pixel *list,int p,int size)
-{	Pixel sum=0;
-	int i;
-	
-	for (i=0;i<size;i++)
-	{
-		if (p!=1) sum+=pow(list[i],p);
-		else sum+=list[i];
-	}
-	return sum;
-}
-
-static Pixel weak_lp(Image_tree tree,int size,int p,double epsilon)
-{	Pixel wlp,*list,max=0;
-	int *list_size,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);
-
-	for (k=0;k<size;k++)
-	{
-		if (k!=0) wlp=pow(k,1/p)*list[k];
-		else wlp=0;
-		if (wlp>max) 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;k<size;k++)
-	{
-		if (list[k]!=0)
-		{
-			sum+=pow(list[k],p);
-			npf=fabs(sum-normf);
-			if (npf<min) min=npf;
-		}
-	}
-	min=min/norm;
-
-	free(list);
-	
-	return min;
-
-	error:
-        	err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory));	
-	  	return 0;	
-}
-
-static Pixel comp_area(Image_tree tree,int size,int p,double f)
-{	Pixel sum=0,*list,norm,vk=0;
-	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);
-
-	for (k=0;k<size;k++)
-	{
-		if (list[k]!=0)
-		{
-			vk+=pow(list[k],p);
-			sum+=vk;
-			
-		}
-	}
-
-	free(list);
-	
-	return (size-sum/norm);
-
-	error:
-        	err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory));	
-	  	return 0;	
-}
-
-static Pixel compute_sdiscrepancy(Image_tree tree,int size)
-{	Pixel *list,min,max,factor,maximum=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;k<size;k++)
-	{
-		list[k]=factor*(list[k]-min);
-	}
-
-	for (k=0;k<size;k++)
-	{
-		x=fabs(list[k]-(2*k-1)/(2*size));
-		if (x>maximum) 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;k<size;k++)
-	{
-		list[k]=factor*(list[k]-min);
-	}
-
-	for (k=0;k<size;k++)
-	{
-		x=((Pixel)k/size-list[k]);
-		if (x>maximum) maximum=x;
-		else if (x<minimum) minimum=x;
-		
-	}
-	
-	free(list);
-	
-	return (1/size+maximum-minimum);
-
-	error:
-        	err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory));	
-	  	return 0;	
-}
-
-static Pixel compute_concentration(Image_tree tree,int size)
-{	Pixel *list,min,max,factor,lkm=0,length,sum=0,value,norm;
-	int *list_size=0,k,next=0,last=0,i=0;
-
-	list_size=(int *)malloc(sizeof(int));
-	if (!list_size) goto error;
-	*list_size=0;
-
-	list=(Pixel *)calloc(size+1,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];
-	length=(max-min)/100;
-	
-	factor=1/(max-min);
-	for (k=0;k<size;k++)
-	{
-		list[k]=factor*(list[k]-min);
-	}
-	
-	norm=size*sum_list(list,1,size);
-	length=0.01;
-	value=length;
-	
-	list[size]=max+value;
-	
-	for (k=0;k<100;k++)
-	{
-		while ((list[i]<value)&(i<size))
-		{
-			sum+=list[i];
-			next++;
-			i++;
-		}
-		lkm+=(next-last)*sum/norm;
-		value+=length;
-		last=next;
-		sum=0;
-	}
-	
-	return -lkm;
-	
-	error:
-        	err_SimpleMessage(err_GetErrorMessage(Error_NotEnoughMemory));	
-	  	return 0;	
-}
-/************************************************************************/
-/*	Functionname: compute_entropy					*/
-/* -------------------------------------------------------------------- */
-/*	Parameter: 							*/
-/*		img: Image from which the entropy should be computed	*/
-/*		cost: choosen costfunction				*/
-/*		epsilon: limit for threshold method			*/
-/* -------------------------------------------------------------------- */
-/* 	Description: computes entropy of an image			*/
-/************************************************************************/
-static double compute_entropy(Image img,enum Information_Cost cost,double epsilon)
-{       double sum=0,x=0;
-	int i;
-	Pixel *data;
-	
-	data=img->data;
-	
-	switch(cost) {
-
-	case threshold:
-  		for(i=0;i<img->size;i++) 
-	    		if (fabs(img->data[i])>epsilon) sum++;  
-  	break;
-
-	case log_energy:  
-        	for(i=0;i<img->size;i++,data++) {
-        		x=(*data) * (*data);
-	  		if (x!=0) sum+=(x*log(1/x));
-	  	}
-	break;
-
-	case norml:
-        	for(i=0;i<img->size;i++,data++) {
-        		x=fabs(*data);
-	  		sum+=x;
-	  	}
-	break;	
-
-	case norml2:
-        	for(i=0;i<img->size;i++,data++) {
-        		x=(*data) * (*data);
-	  		sum+=x;
-	  	}
-	  	sum=pow(sum,0.5);
-	break;	
-
-	case entropy:
-		for(i=0;i<img->size;i++,data++) {
-	    		x=(*data)*(*data);
-	    		if (x!=0) sum-=(x*log(x));
-	  	}
-	break;
-	 
-	case gauss_markov:
-		for(i=0;i<img->size;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->height<min) min=dtree->image->height;
-
-	if (doubletree_min<min)
-	{
-		width=(dtree->image->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;i<len;i++)
-	{
-		if (list[i]==x)
-		{
-			found=1;
-			i=len;
-		}
-	}
-
-	return found;
-}
-
-static void write_flags(Image_tree tree,int *list,int len,int pos)
-{
-	int shift,next_pos,max;
-
-	if (is_in_list(list,len,pos))
-	{
-		tree->flag=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;
-
-
-	}
-}
--- 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 <stdio.h>
-
-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 <stddef.h>
-
-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
--- 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<length; i++) { *b=0; b++; }
-}
-#endif
-
-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_in_binary();
-}
-
-void wm_init1() {
-  set_out_binary();
-}
-
-void wm_init() {
-  set_in_binary();
-  set_out_binary();
-}
-
--- a/Meerwald/wm.h	Fri Dec 20 12:53:41 2024 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-#ifndef WM_H
-#define WM_H
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <getopt.h>
-#include <math.h>
-#include <float.h>
-#include <fcntl.h>
-
-#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 <values.h>
-#include <sys/param.h>
-#include <unistd.h>
-#include <time.h>
-#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
--- 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);
-}
--- 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);
-}
--- 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 <pmeerw@cosy.sbg.ac.at>
-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)
--- 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);
-}
--- 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)
--- 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);
-}
--- 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)
--- 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);
-}
--- 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)
--- 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);
-}
--- 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)
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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)
--- 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);
-}
--- 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)
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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[]) {
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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);
-}
--- 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

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.