show git hash (if available) when invoking -v key
[gpivtools.git] / src / misc / combing.c
blobcb5cb33a01c6e2b06baacfdfd547890a792da07f
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>
33 #include "config.h"
34 #include "git-rev.h"
37 #define GPIV_EXT_PNG_IMAGE ".png"
38 #define GPIV_URL "gpiv.sourceforge.net"
40 /* #define VERSION "0.1" */
41 #define DEFAULT_INNAME "../test/pngtest.png"
43 #define PARFILE "gpivrc" /* Parameter file name */
44 #define USAGE "\
45 Usage: gpiv_combing [-h | --help] [-p | --print] [-v | --version] \n\
46 [-a | --suf_a] [-b | --suf_b] [-d | --dt] [-u | --suf_num] [-U | --Suf_num] \n\
47 [-s | --suf_skip] [-t | type] [-w | --warning] file_basename \n\
48 \n\
49 keys: \n\
50 -h | --help: this on-line help \n\
51 -p | --print: print parameters to stdout \n\
52 -v | --version: version number \n\
53 -V | --verbose: program behaves verbose during operation \n\
54 -a | --suf_a S: use a suffix of the first image (default: _a) \n\
55 -b | --suf_b S: use a suffix of the second image (default: _b) \n\
56 -d | --dt S: separation time delta t between subsequent \n\
57 recordings [in milliseconds] \n\
58 -u | --suf_num M: use numbered images, instead of suf_a/suf_b, of which \n\
59 the first one with number M and the second N (default: M+1). \n \
60 The converted image will be named to file_base_nameM \n\
61 -U | --Suf_num M: use numbered images, instead of suf_a/suf_b, of which \n\
62 the first one with number M and the second N (default: M+1). \n \
63 The converted image will be named to file_base_nameM-N. \n\
64 -s | --skip S: skip S numbers; the first image with number M will \n\
65 combine with the second image M+S+1 (default: S = 0) \n\
66 -t | type: input image type (tif, gif, bmp, pgm, r, gpi). Default: png. \n \
67 Output image will be in png format. \n\
68 -w | --warning: Warns if an input image already contains two frames. \n\
69 file_basename: filename without extension or suffix \n\
72 #define HELP "\
73 gpiv_combing - combines two images for cross-correlation"
75 /* static const char *fname = "/home/gerber/src/GBTOOLS/gbtools-0.1.0/test/png/img1"; */
76 /* static const gchar *program_name = "gpiv_combing"; */
77 static gboolean verbose = FALSE;
78 static gboolean print_par = FALSE;
80 static gint num = 0;
81 static gint numboth = 0;
82 static gint skip = 0;
83 static gchar *suf_a = "_a";
84 static gchar *suf_b = "_b";
85 static gchar *itype = "png";
86 static gboolean warning = FALSE;
89 static gboolean num__set = FALSE;
90 static gboolean numboth__set = FALSE;
91 static gboolean skip__set = FALSE;
92 static gboolean suf_a__set = FALSE;
93 static gboolean suf_b__set = FALSE;
94 static gboolean itype__set = FALSE;
95 static gboolean warning__set = FALSE;
99 static void
100 command_args (int argc,
101 char *argv[],
102 char fname[GPIV_MAX_CHARS],
103 GpivImagePar *image_par
105 /* ----------------------------------------------------------------------------
106 * Command line argument handling
109 char c = '\0';
110 gint argc_next;
112 while (--argc > 0 && (*++argv)[0] == '-') {
115 * argc_next is set to 1 if the next cmd line argument has to be searched for;
116 * in case that the command line argument concerns more than one char or cmd
117 * line argument needs a parameter
120 argc_next = 0;
121 while (argc_next == 0 && (c = *++argv[0]))
123 switch (c) {
124 case 'v':
125 #ifdef GIT_HASH
126 printf ("git hash: %s\n", GIT_REV);
127 #else
128 printf ("version: %s\n", GPIVTOOLS_VERSION);
129 #endif
130 exit(0);
131 break;
133 case 'V':
134 verbose = TRUE;
135 break;
137 case 'h':
138 printf("%s\n", argv[0]);
139 printf("%s\n",HELP);
140 printf("%s\n",USAGE);
141 exit(0);
142 break;
144 case 'p':
145 print_par = TRUE;
146 break;
148 case 'a':
149 suf_a = g_strdup(*++argv);
150 argc_next = 1;
151 --argc;
152 suf_a__set = TRUE;
153 break;
155 case 'b':
156 suf_b = g_strdup(*++argv);
157 argc_next = 1;
158 --argc;
159 suf_b__set = TRUE;
160 break;
163 * Time scaling parameter
165 case 'd':
166 image_par->t_scale = atof(*++argv);
167 image_par->t_scale__set = TRUE;
168 argc_next = 1;
169 --argc;
170 break;
172 case 's':
173 skip = atoi(*++argv);
174 argc_next = 1;
175 --argc;
176 skip__set = TRUE;
177 break;
179 case 'u':
180 num = atoi(*++argv);
181 argc_next = 1;
182 --argc;
183 num__set = TRUE;
184 break;
186 case 'U':
187 numboth = atoi(*++argv);
188 argc_next = 1;
189 --argc;
190 numboth__set = TRUE;
191 break;
193 case 't':
194 itype = g_strdup(*++argv);
195 argc_next = 1;
196 --argc;
197 itype__set = TRUE;
198 break;
200 case 'w':
201 warning = TRUE;
202 warning__set = TRUE;
203 break;
206 * long option keys
208 case '-':
209 if (strcmp("-help", *argv) == 0) {
210 printf("\n%s", argv[0]);
211 printf("\n%s", HELP);
212 printf("\n%s", USAGE);
213 exit(0);
214 } else if (strcmp("-print", *argv) == 0) {
215 print_par = TRUE;
216 } else if (strcmp("-version", *argv) == 0) {
217 #ifdef GIT_HASH
218 printf ("git hash: %s\n", GIT_REV);
219 #else
220 printf ("version: %s\n", GPIVTOOLS_VERSION);
221 #endif
222 exit(0);
223 } else if (strcmp("-verbose", *argv) == 0) {
224 verbose = TRUE;
225 } else if (strcmp("-dt", *argv) == 0) {
226 image_par->t_scale = atof(*++argv);
227 image_par->t_scale__set = TRUE;
228 argc_next = 1;
229 --argc;
230 } else if (strcmp("-suf_a", *argv) == 0) {
231 suf_a = g_strdup(*++argv);
232 argc_next = 1;
233 --argc;
234 suf_a__set = TRUE;
235 } else if (strcmp("-suf_b", *argv) == 0) {
236 suf_b = g_strdup(*++argv);
237 argc_next = 1;
238 --argc;
239 suf_b__set = TRUE;
240 } else if (strcmp("-skip", *argv) == 0) {
241 skip = atoi(*++argv);
242 argc_next = 1;
243 --argc;
244 skip__set = TRUE;
245 } else if (strcmp("-suf_num", *argv) == 0) {
246 num = atoi(*++argv);
247 argc_next = 1;
248 --argc;
249 num__set = TRUE;
250 } else if (strcmp("-Suf_num", *argv) == 0) {
251 numboth = atoi(*++argv);
252 argc_next = 1;
253 --argc;
254 numboth__set = TRUE;
255 } else if (strcmp("-type", *argv) == 0) {
256 itype = g_strdup(*++argv);
257 argc_next = 1;
258 --argc;
259 itype__set = TRUE;
260 } else if (strcmp("-warning", *argv) == 0) {
261 warning = TRUE;
262 warning__set = TRUE;
264 } else {
265 gpiv_error ("%s: unknown option: %s", argv[0], *argv);
267 argc_next = 1;
268 break;
270 default:
271 gpiv_error (USAGE);
272 break;
277 if (argc == 1) {
278 strcpy(fname, argv[argc - 1]);
279 } else {
280 gpiv_error ("\n%s", USAGE);
283 if ((num__set || numboth__set) && (suf_a__set || suf_b__set)) {
284 gpiv_error ("\nA suffix has been defined as well as numbered filenames.");
287 if (num__set && numboth__set) {
288 gpiv_error ("\nOnly choose one of the options '-u' or '-U' to use numbered filenames.");
292 if (skip__set == TRUE
293 && image_par->t_scale__set == TRUE) {
294 image_par->t_scale *= (skip + 1);
297 if (verbose) {
298 if (suf_a__set) g_message("comand_args: suf_a = %s", suf_a);
299 if (suf_b__set) g_message("comand_args: suf_b = %s", suf_b);
300 if (num__set) g_message("comand_args: num = %d", num);
301 if (numboth__set) g_message("comand_args: numboth = %d", numboth);
302 if (skip__set) g_message("comand_args: skip = %d", skip);
303 if (image_par->t_scale__set) g_message("comand_args: t_scale = %f",
304 image_par->t_scale);
305 g_message("comand_args: fname = %s", fname);
312 static int
313 make_fname (char *fname,
314 char *fname_in1,
315 char *fname_in2,
316 char *fname_out
318 /*-----------------------------------------------------------------------------
319 * generates filenames
322 gchar *dirname = g_strdup (g_path_get_dirname(fname));
323 gchar *fname_base = g_strdup (g_path_get_basename(fname));
324 strtok (fname_base, ".");
327 * Input image #1, #2 filename
329 if (fname != NULL ) {
330 if (num__set) {
331 if (fname_in1 != NULL ) {
332 g_snprintf(fname_in1, GPIV_MAX_CHARS, "%s%d.%s",
333 fname_base, num, itype);
334 if (verbose) printf("\n#input image #1 is: %s", fname_in1);
337 if (fname_in2 != NULL ) {
338 g_snprintf(fname_in2, GPIV_MAX_CHARS, "%s%d.%s",
339 fname_base, num + 1 + skip, itype);
340 if (verbose) printf("\n#input image #2 is: %s", fname_in2);
342 } else if (numboth__set) {
343 if (fname_in1 != NULL ) {
344 g_snprintf(fname_in1, GPIV_MAX_CHARS, "%s%d.%s",
345 fname_base, numboth, itype);
346 if (verbose) printf("\n#input image #1 is: %s", fname_in1);
349 if (fname_in2 != NULL ) {
350 g_snprintf(fname_in2, GPIV_MAX_CHARS, "%s%d.%s",
351 fname_base, numboth + 1 + skip, itype);
352 if (verbose) printf("\n#input image #2 is: %s", fname_in2);
354 } else {
355 if (fname_in1 != NULL ) {
356 g_snprintf(fname_in1, GPIV_MAX_CHARS, "%s%s.%s",
357 fname_base, suf_a, itype);
358 if (verbose) printf("\n#input image #1 is: %s", fname_in1);
361 if (fname_in2 != NULL ) {
362 g_snprintf(fname_in2, GPIV_MAX_CHARS, "%s%s.%s",
363 fname_base, suf_b, itype);
364 if (verbose) printf("\n#input image #2 is: %s", fname_in2);
368 * Output image filename
370 if (fname_out != NULL ) {
371 /* BUGFIX: removed "comb_" in output filename */
372 if (num__set) {
373 g_snprintf(fname_out, GPIV_MAX_CHARS, "%s%s%s%d%s",
374 dirname, G_DIR_SEPARATOR_S, fname_base, num,
375 GPIV_EXT_PNG_IMAGE);
376 if (verbose) printf("\n#output image file is: %s", fname_out);
377 } else if (numboth__set) {
378 g_snprintf(fname_out, GPIV_MAX_CHARS, "%s%s%s%d-%d%s",
379 dirname, G_DIR_SEPARATOR_S, fname_base,
380 numboth, numboth + skip + 1,
381 GPIV_EXT_PNG_IMAGE);
382 if (verbose) printf("\n#output image file is: %s", fname_out);
383 } else {
384 g_snprintf(fname_out, GPIV_MAX_CHARS, "%s%s%s%s",
385 dirname, G_DIR_SEPARATOR_S, fname_base,
386 GPIV_EXT_PNG_IMAGE);
387 if (verbose) printf("\n#output image file is: %s",
388 fname_out);
392 if (verbose) printf("\n");
394 return 0;
400 main (int argc, char *argv[])
401 /*-----------------------------------------------------------------------------*/
403 gchar *err_msg = NULL;
404 FILE *fp;
405 gchar fname_base[GPIV_MAX_CHARS],
406 fname_in_a[GPIV_MAX_CHARS],
407 fname_in_b[GPIV_MAX_CHARS],
408 fname_out[GPIV_MAX_CHARS];
410 GpivImage *image_a = NULL; /* Image containing first frame */
411 GpivImage *image_b = NULL; /* Image containing second frame */
412 GpivImage *image_c = g_new0 (GpivImage, 1); /* Combination of image_a and image_b */
414 GpivImagePar *image_par = g_new0 (GpivImagePar, 1);
415 GpivImagePar *image_par_c = NULL;
416 gint return_val = 0;
419 * Construct file names from output PNG files for writing or
420 * read / write to stdin and stdout
422 command_args (argc, argv, fname_base, image_par);
424 if ((return_val =
425 make_fname (fname_base, fname_in_a, fname_in_b, fname_out))
426 != 0) {
427 gpiv_error ("%s: Failure make_fname", argv[0]);
431 * reads input images and checks if they are of equal dimensions
433 if ((image_a = gpiv_fread_image (fname_in_a)) == NULL) {
434 gpiv_error ("%s: %s\n", argv[0], err_msg);
437 if ((image_b = gpiv_fread_image (fname_in_b)) == NULL) {
438 gpiv_error ("%s: %s\n", argv[0], err_msg);
441 if (warning
442 && image_a->header->x_corr == TRUE) {
443 gpiv_error ("%s: the first input image contains two frames", argv[0]);
446 if (warning
447 && image_b->header->x_corr == TRUE) {
448 gpiv_error ("%s: the second input image contains two frames", argv[0]);
451 if (image_a->header->nrows != image_b->header->nrows) {
452 gpiv_error ("%s: input images differ in nrows; %d <=> %d", argv[0],
453 image_a->header->nrows, image_b->header->nrows);
456 if (image_a->header->ncolumns != image_b->header->ncolumns) {
457 gpiv_error ("%s: input images differ in ncolumns; %d <=> %d", argv[0],
458 image_a->header->ncolumns, image_b->header->ncolumns);
461 if (image_a->header->depth != image_b->header->depth) {
462 gpiv_error ("%s: input images differ in depth; %d <=> %d", argv[0],
463 image_b->header->depth);
467 * Header info from image_par and image_a->header will be used for the new image
468 * Adding some extra info to image_c header
470 image_par_c = gpiv_img_cp_parameters (image_a->header);
471 image_par_c->t_scale = image_par->t_scale;
472 image_par_c->t_scale__set = TRUE;
473 image_par_c->x_corr = TRUE;
474 image_par_c->x_corr__set = TRUE;
476 if (image_par_c->software__set == FALSE) {
477 g_snprintf (image_par_c->software, GPIV_MAX_CHARS, "%s", argv[0]);
478 image_par_c->software__set = TRUE;
481 if (image_par_c->author__set == FALSE) {
482 g_snprintf (image_par_c->author, GPIV_MAX_CHARS,"%s", g_get_real_name());
483 image_par_c->author__set = TRUE;
486 if (image_par_c->creation_date__set == FALSE) {
487 char time_string[GPIV_MAX_CHARS];
488 struct tm time_struct;
489 time_t itime;
490 time (&itime);
491 time_struct = *gmtime (&itime);
492 strftime (time_string, GPIV_MAX_CHARS, "%a %b %d %Y %T", &time_struct);
493 if (verbose)
494 g_message ("Setting new time = %s", time_string);
495 snprintf (image_par_c->creation_date, GPIV_MAX_CHARS, "%s", time_string);
496 image_par_c->creation_date__set = TRUE;
500 * Reading the rest of (optional) image parameters.
502 gpiv_scan_parameter (GPIV_IMGPAR_KEY, PARFILE, image_par_c, print_par);
503 gpiv_scan_resourcefiles (GPIV_IMGPAR_KEY, image_par_c, print_par);
506 * Creating image_c from image_a, image_b and image_par_c
508 image_c->header = image_par_c;
509 image_c->frame1 = image_a->frame1;
510 image_c->frame2 = image_b->frame1;
511 if (print_par) gpiv_img_print_header (stdout, image_c->header);
514 * Writing image
516 if ((fp = fopen(fname_out, "wb")) == NULL) {
517 return (1);
519 if ((err_msg = gpiv_write_png_image (fp, image_c, FALSE)) != NULL) {
520 gpiv_error ("%s: %s\n", argv[0], err_msg);
522 fclose (fp);
526 if (image_a != NULL) gpiv_free_img(image_a);
527 if (image_b != NULL) gpiv_free_img(image_b);
528 if (suf_a__set) g_free (suf_a);
529 if (suf_b__set) g_free (suf_b);
530 if (itype__set) g_free (itype);
531 exit (0);