Added option -U
[gpivtools.git] / src / misc / combing.c
blobd323306d773cf9323cb414972e5248aca3905600
1 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 c-style: "K&R" -*- */
4 /*-----------------------------------------------------------------------------
6 combing - combines two images for cross-correlation
8 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
9 Gerber van der Graaf <gerber_graaf@users.sourceforge.net
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software Foundation,
23 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 -----------------------------------------------------------------------------*/
27 #include <gpiv.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <assert.h>
31 #include <unistd.h> /* get_login() */
32 #include <time.h>
35 #define GPIV_EXT_PNG_IMAGE ".png"
36 #define GPIV_URL "gpiv.sourceforge.net"
38 /* #define VERSION "0.1" */
39 #define DEFAULT_INNAME "../test/pngtest.png"
41 #define PARFILE "gpivrc" /* Parameter file name */
42 #define USAGE "\
43 Usage: gpiv_combing [-h | --help] [-p | --print] [-v | --version] \n\
44 [-a | --suf_a] [-b | --suf_b] [-d | --dt] [-u | --suf_num] [-U | --Suf_num] \n\
45 [-s | --suf_skip] [-t | type] [-w | --warning] file_basename \n\
46 \n\
47 keys: \n\
48 -h | --help: this on-line help \n\
49 -p | --print: print parameters to stdout \n\
50 -v | --version: version number \n\
51 -V | --verbose: program behaves verbose during operation \n\
52 -a | --suf_a S: use a suffix of the first image (default: _a) \n\
53 -b | --suf_b S: use a suffix of the second image (default: _b) \n\
54 -d | --dt S: separation time delta t between subsequent \n\
55 recordings [in milliseconds] \n\
56 -u | --suf_num M: use numbered images, instead of suf_a/suf_b, of which \n\
57 the first one with number M and the second N (default: M+1). \n \
58 The converted image will be named to file_base_nameM \n\
59 -U | --Suf_num M: use numbered images, instead of suf_a/suf_b, of which \n\
60 the first one with number M and the second N (default: M+1). \n \
61 The converted image will be named to file_base_nameM-N. \n\
62 -s | --skip S: skip S numbers; the first image with number M will \n\
63 combine with the second image M+S+1 (default: S = 0) \n\
64 -t | type: input image type (tif, gif, bmp, pgm, r, gpi). Default: png. \n \
65 Output image will be in png format. \n\
66 -w | --warning: Warns if an input image already contains two frames. \n\
67 file_basename: filename without extension or suffix \n\
70 #define HELP "\
71 gpiv_combing - combines two images for cross-correlation"
73 #define RCSID "$Id: combing.c,v 1.5 2008-09-25 13:08:34 gerber Exp $"
76 /* static const char *fname = "/home/gerber/src/GBTOOLS/gbtools-0.1.0/test/png/img1"; */
77 /* static const gchar *program_name = "gpiv_combing"; */
78 static gboolean verbose = FALSE;
79 static gboolean print_par = FALSE;
81 static gint num = 0;
82 static gint numboth = 0;
83 static gint skip = 0;
84 static gchar *suf_a = "_a";
85 static gchar *suf_b = "_b";
86 static gchar *itype = "png";
87 static gboolean warning = FALSE;
90 static gboolean num__set = FALSE;
91 static gboolean numboth__set = FALSE;
92 static gboolean skip__set = FALSE;
93 static gboolean suf_a__set = FALSE;
94 static gboolean suf_b__set = FALSE;
95 static gboolean itype__set = FALSE;
96 static gboolean warning__set = FALSE;
100 static void
101 command_args (int argc,
102 char *argv[],
103 char fname[GPIV_MAX_CHARS],
104 GpivImagePar *image_par
106 /* ----------------------------------------------------------------------------
107 * Command line argument handling
110 char c = '\0';
111 gint argc_next;
113 while (--argc > 0 && (*++argv)[0] == '-') {
116 * argc_next is set to 1 if the next cmd line argument has to be searched for;
117 * in case that the command line argument concerns more than one char or cmd
118 * line argument needs a parameter
121 argc_next = 0;
122 while (argc_next == 0 && (c = *++argv[0]))
124 switch (c) {
125 case 'v':
126 printf("%s\n", RCSID);
127 exit(0);
128 break;
130 case 'V':
131 verbose = TRUE;
132 break;
134 case 'h':
135 printf("%s\n", argv[0]);
136 printf("%s\n",HELP);
137 printf("%s\n",USAGE);
138 exit(0);
139 break;
141 case 'p':
142 print_par = TRUE;
143 break;
145 case 'a':
146 suf_a = g_strdup(*++argv);
147 argc_next = 1;
148 --argc;
149 suf_a__set = TRUE;
150 break;
152 case 'b':
153 suf_b = g_strdup(*++argv);
154 argc_next = 1;
155 --argc;
156 suf_b__set = TRUE;
157 break;
160 * Time scaling parameter
162 case 'd':
163 image_par->t_scale = atof(*++argv);
164 image_par->t_scale__set = TRUE;
165 argc_next = 1;
166 --argc;
167 break;
169 case 's':
170 skip = atoi(*++argv);
171 argc_next = 1;
172 --argc;
173 skip__set = TRUE;
174 break;
176 case 'u':
177 num = atoi(*++argv);
178 argc_next = 1;
179 --argc;
180 num__set = TRUE;
181 break;
183 case 'U':
184 numboth = atoi(*++argv);
185 argc_next = 1;
186 --argc;
187 numboth__set = TRUE;
188 break;
190 case 't':
191 itype = g_strdup(*++argv);
192 argc_next = 1;
193 --argc;
194 itype__set = TRUE;
195 break;
197 case 'w':
198 warning = TRUE;
199 warning__set = TRUE;
200 break;
203 * long option keys
205 case '-':
206 if (strcmp("-help", *argv) == 0) {
207 printf("\n%s", argv[0]);
208 printf("\n%s", HELP);
209 printf("\n%s", USAGE);
210 exit(0);
211 } else if (strcmp("-print", *argv) == 0) {
212 print_par = TRUE;
213 } else if (strcmp("-version", *argv) == 0) {
214 printf("%s\n", RCSID);
215 exit(0);
216 } else if (strcmp("-verbose", *argv) == 0) {
217 verbose = TRUE;
218 } else if (strcmp("-dt", *argv) == 0) {
219 image_par->t_scale = atof(*++argv);
220 image_par->t_scale__set = TRUE;
221 argc_next = 1;
222 --argc;
223 } else if (strcmp("-suf_a", *argv) == 0) {
224 suf_a = g_strdup(*++argv);
225 argc_next = 1;
226 --argc;
227 suf_a__set = TRUE;
228 } else if (strcmp("-suf_b", *argv) == 0) {
229 suf_b = g_strdup(*++argv);
230 argc_next = 1;
231 --argc;
232 suf_b__set = TRUE;
233 } else if (strcmp("-skip", *argv) == 0) {
234 skip = atoi(*++argv);
235 argc_next = 1;
236 --argc;
237 skip__set = TRUE;
238 } else if (strcmp("-suf_num", *argv) == 0) {
239 num = atoi(*++argv);
240 argc_next = 1;
241 --argc;
242 num__set = TRUE;
243 } else if (strcmp("-Suf_num", *argv) == 0) {
244 numboth = atoi(*++argv);
245 argc_next = 1;
246 --argc;
247 numboth__set = TRUE;
248 } else if (strcmp("-type", *argv) == 0) {
249 itype = g_strdup(*++argv);
250 argc_next = 1;
251 --argc;
252 itype__set = TRUE;
253 } else if (strcmp("-warning", *argv) == 0) {
254 warning = TRUE;
255 warning__set = TRUE;
257 } else {
258 gpiv_error ("%s: unknown option: %s", argv[0], *argv);
260 argc_next = 1;
261 break;
263 default:
264 gpiv_error (USAGE);
265 break;
270 if (argc == 1) {
271 strcpy(fname, argv[argc - 1]);
272 } else {
273 gpiv_error ("\n%s", USAGE);
276 if ((num__set || numboth__set) && (suf_a__set || suf_b__set)) {
277 gpiv_error ("\nA suffix has been defined as well as numbered filenames.");
280 if (num__set && numboth__set) {
281 gpiv_error ("\nOnly choose one of the options '-u' or '-U' to use numbered filenames.");
285 if (skip__set == TRUE
286 && image_par->t_scale__set == TRUE) {
287 image_par->t_scale *= (skip + 1);
290 if (verbose) {
291 if (suf_a__set) g_message("comand_args: suf_a = %s", suf_a);
292 if (suf_b__set) g_message("comand_args: suf_b = %s", suf_b);
293 if (num__set) g_message("comand_args: num = %d", num);
294 if (numboth__set) g_message("comand_args: numboth = %d", numboth);
295 if (skip__set) g_message("comand_args: skip = %d", skip);
296 if (image_par->t_scale__set) g_message("comand_args: t_scale = %f",
297 image_par->t_scale);
298 g_message("comand_args: fname = %s", fname);
305 static int
306 make_fname (char *fname,
307 char *fname_in1,
308 char *fname_in2,
309 char *fname_out
311 /*-----------------------------------------------------------------------------
312 * generates filenames
315 gchar *dirname = g_strdup (g_path_get_dirname(fname));
316 gchar *fname_base = g_strdup (g_path_get_basename(fname));
317 strtok (fname_base, ".");
320 * Input image #1, #2 filename
322 if (fname != NULL ) {
323 if (num__set) {
324 if (fname_in1 != NULL ) {
325 g_snprintf(fname_in1, GPIV_MAX_CHARS, "%s%d.%s",
326 fname_base, num, itype);
327 if (verbose) printf("\n#input image #1 is: %s", fname_in1);
330 if (fname_in2 != NULL ) {
331 g_snprintf(fname_in2, GPIV_MAX_CHARS, "%s%d.%s",
332 fname_base, num + 1 + skip, itype);
333 if (verbose) printf("\n#input image #2 is: %s", fname_in2);
335 } else if (numboth__set) {
336 if (fname_in1 != NULL ) {
337 g_snprintf(fname_in1, GPIV_MAX_CHARS, "%s%d.%s",
338 fname_base, numboth, itype);
339 if (verbose) printf("\n#input image #1 is: %s", fname_in1);
342 if (fname_in2 != NULL ) {
343 g_snprintf(fname_in2, GPIV_MAX_CHARS, "%s%d.%s",
344 fname_base, numboth + 1 + skip, itype);
345 if (verbose) printf("\n#input image #2 is: %s", fname_in2);
347 } else {
348 if (fname_in1 != NULL ) {
349 g_snprintf(fname_in1, GPIV_MAX_CHARS, "%s%s.%s",
350 fname_base, suf_a, itype);
351 if (verbose) printf("\n#input image #1 is: %s", fname_in1);
354 if (fname_in2 != NULL ) {
355 g_snprintf(fname_in2, GPIV_MAX_CHARS, "%s%s.%s",
356 fname_base, suf_b, itype);
357 if (verbose) printf("\n#input image #2 is: %s", fname_in2);
361 * Output image filename
363 if (fname_out != NULL ) {
364 /* BUGFIX: removed "comb_" in output filename */
365 if (num__set) {
366 g_snprintf(fname_out, GPIV_MAX_CHARS, "%s%s%s%d%s",
367 dirname, G_DIR_SEPARATOR_S, fname_base, num,
368 GPIV_EXT_PNG_IMAGE);
369 if (verbose) printf("\n#output image file is: %s", fname_out);
370 } else if (numboth__set) {
371 g_snprintf(fname_out, GPIV_MAX_CHARS, "%s%s%s%d-%d%s",
372 dirname, G_DIR_SEPARATOR_S, fname_base,
373 numboth, numboth + skip + 1,
374 GPIV_EXT_PNG_IMAGE);
375 if (verbose) printf("\n#output image file is: %s", fname_out);
376 } else {
377 g_snprintf(fname_out, GPIV_MAX_CHARS, "%s%s%s%s",
378 dirname, G_DIR_SEPARATOR_S, fname_base,
379 GPIV_EXT_PNG_IMAGE);
380 if (verbose) printf("\n#output image file is: %s",
381 fname_out);
385 if (verbose) printf("\n");
387 return 0;
393 main (int argc, char *argv[])
394 /*-----------------------------------------------------------------------------*/
396 gchar *err_msg = NULL;
397 FILE *fp;
398 gchar fname_base[GPIV_MAX_CHARS],
399 fname_in_a[GPIV_MAX_CHARS],
400 fname_in_b[GPIV_MAX_CHARS],
401 fname_out[GPIV_MAX_CHARS];
403 GpivImage *image_a = NULL; /* Image containing first frame */
404 GpivImage *image_b = NULL; /* Image containing second frame */
405 GpivImage *image_c = g_new0 (GpivImage, 1); /* Combination of image_a and image_b */
407 GpivImagePar *image_par = g_new0 (GpivImagePar, 1);
408 GpivImagePar *image_par_c = NULL;
409 gint return_val = 0;
412 * Construct file names from output PNG files for writing or
413 * read / write to stdin and stdout
415 command_args (argc, argv, fname_base, image_par);
417 if ((return_val =
418 make_fname (fname_base, fname_in_a, fname_in_b, fname_out))
419 != 0) {
420 gpiv_error ("%s: Failure make_fname", argv[0]);
424 * reads input images and checks if they are of equal dimensions
426 if ((image_a = gpiv_fread_image (fname_in_a)) == NULL) {
427 gpiv_error ("%s: %s\n", argv[0], err_msg);
430 if ((image_b = gpiv_fread_image (fname_in_b)) == NULL) {
431 gpiv_error ("%s: %s\n", argv[0], err_msg);
434 if (warning
435 && image_a->header->x_corr == TRUE) {
436 gpiv_error ("%s: the first input image contains two frames", argv[0]);
439 if (warning
440 && image_b->header->x_corr == TRUE) {
441 gpiv_error ("%s: the second input image contains two frames", argv[0]);
444 if (image_a->header->nrows != image_b->header->nrows) {
445 gpiv_error ("%s: input images differ in nrows; %d <=> %d", argv[0],
446 image_a->header->nrows, image_b->header->nrows);
449 if (image_a->header->ncolumns != image_b->header->ncolumns) {
450 gpiv_error ("%s: input images differ in ncolumns; %d <=> %d", argv[0],
451 image_a->header->ncolumns, image_b->header->ncolumns);
454 if (image_a->header->depth != image_b->header->depth) {
455 gpiv_error ("%s: input images differ in depth; %d <=> %d", argv[0],
456 image_b->header->depth);
460 * Header info from image_par and image_a->header will be used for the new image
461 * Adding some extra info to image_c header
463 image_par_c = gpiv_img_cp_parameters (image_a->header);
464 image_par_c->t_scale = image_par->t_scale;
465 image_par_c->t_scale__set = TRUE;
466 image_par_c->x_corr = TRUE;
467 image_par_c->x_corr__set = TRUE;
469 if (image_par_c->software__set == FALSE) {
470 g_snprintf (image_par_c->software, GPIV_MAX_CHARS, "%s", argv[0]);
471 image_par_c->software__set = TRUE;
474 if (image_par_c->author__set == FALSE) {
475 g_snprintf (image_par_c->author, GPIV_MAX_CHARS,"%s", g_get_real_name());
476 image_par_c->author__set = TRUE;
479 if (image_par_c->creation_date__set == FALSE) {
480 char time_string[GPIV_MAX_CHARS];
481 struct tm time_struct;
482 time_t itime;
483 time (&itime);
484 time_struct = *gmtime (&itime);
485 strftime (time_string, GPIV_MAX_CHARS, "%a %b %d %Y %T", &time_struct);
486 if (verbose)
487 g_message ("Setting new time = %s", time_string);
488 snprintf (image_par_c->creation_date, GPIV_MAX_CHARS, "%s", time_string);
489 image_par_c->creation_date__set = TRUE;
493 * Reading the rest of (optional) image parameters.
495 gpiv_scan_parameter (GPIV_IMGPAR_KEY, PARFILE, image_par_c, print_par);
496 gpiv_scan_resourcefiles (GPIV_IMGPAR_KEY, image_par_c, print_par);
499 * Creating image_c from image_a, image_b and image_par_c
501 image_c->header = image_par_c;
502 image_c->frame1 = image_a->frame1;
503 image_c->frame2 = image_b->frame1;
504 if (print_par) gpiv_img_print_header (stdout, image_c->header);
507 * Writing image
509 if ((fp = fopen(fname_out, "wb")) == NULL) {
510 return (1);
512 if ((err_msg = gpiv_write_png_image (fp, image_c, FALSE)) != NULL) {
513 gpiv_error ("%s: %s\n", argv[0], err_msg);
515 fclose (fp);
519 if (image_a != NULL) gpiv_free_img(image_a);
520 if (image_b != NULL) gpiv_free_img(image_b);
521 if (suf_a__set) g_free (suf_a);
522 if (suf_b__set) g_free (suf_b);
523 if (itype__set) g_free (itype);
524 exit (0);