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)
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 -----------------------------------------------------------------------------*/
31 #include <unistd.h> /* get_login() */
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 */
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\
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\
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
;
81 static gint numboth
= 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
;
100 command_args (int argc
,
102 char fname
[GPIV_MAX_CHARS
],
103 GpivImagePar
*image_par
105 /* ----------------------------------------------------------------------------
106 * Command line argument handling
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
121 while (argc_next
== 0 && (c
= *++argv
[0]))
126 printf ("git hash: %s\n", GIT_REV
);
128 printf ("version: %s\n", GPIVTOOLS_VERSION
);
138 printf("%s\n", argv
[0]);
140 printf("%s\n",USAGE
);
149 suf_a
= g_strdup(*++argv
);
156 suf_b
= g_strdup(*++argv
);
163 * Time scaling parameter
166 image_par
->t_scale
= atof(*++argv
);
167 image_par
->t_scale__set
= TRUE
;
173 skip
= atoi(*++argv
);
187 numboth
= atoi(*++argv
);
194 itype
= g_strdup(*++argv
);
209 if (strcmp("-help", *argv
) == 0) {
210 printf("\n%s", argv
[0]);
211 printf("\n%s", HELP
);
212 printf("\n%s", USAGE
);
214 } else if (strcmp("-print", *argv
) == 0) {
216 } else if (strcmp("-version", *argv
) == 0) {
218 printf ("git hash: %s\n", GIT_REV
);
220 printf ("version: %s\n", GPIVTOOLS_VERSION
);
223 } else if (strcmp("-verbose", *argv
) == 0) {
225 } else if (strcmp("-dt", *argv
) == 0) {
226 image_par
->t_scale
= atof(*++argv
);
227 image_par
->t_scale__set
= TRUE
;
230 } else if (strcmp("-suf_a", *argv
) == 0) {
231 suf_a
= g_strdup(*++argv
);
235 } else if (strcmp("-suf_b", *argv
) == 0) {
236 suf_b
= g_strdup(*++argv
);
240 } else if (strcmp("-skip", *argv
) == 0) {
241 skip
= atoi(*++argv
);
245 } else if (strcmp("-suf_num", *argv
) == 0) {
250 } else if (strcmp("-Suf_num", *argv
) == 0) {
251 numboth
= atoi(*++argv
);
255 } else if (strcmp("-type", *argv
) == 0) {
256 itype
= g_strdup(*++argv
);
260 } else if (strcmp("-warning", *argv
) == 0) {
265 gpiv_error ("%s: unknown option: %s", argv
[0], *argv
);
278 strcpy(fname
, argv
[argc
- 1]);
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);
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",
305 g_message("comand_args: fname = %s", fname
);
313 make_fname (char *fname
,
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
) {
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
);
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 */
373 g_snprintf(fname_out
, GPIV_MAX_CHARS
, "%s%s%s%d%s",
374 dirname
, G_DIR_SEPARATOR_S
, fname_base
, num
,
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,
382 if (verbose
) printf("\n#output image file is: %s", fname_out
);
384 g_snprintf(fname_out
, GPIV_MAX_CHARS
, "%s%s%s%s",
385 dirname
, G_DIR_SEPARATOR_S
, fname_base
,
387 if (verbose
) printf("\n#output image file is: %s",
392 if (verbose
) printf("\n");
400 main (int argc
, char *argv
[])
401 /*-----------------------------------------------------------------------------*/
403 gchar
*err_msg
= NULL
;
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
;
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
);
425 make_fname (fname_base
, fname_in_a
, fname_in_b
, fname_out
))
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
);
442 && image_a
->header
->x_corr
== TRUE
) {
443 gpiv_error ("%s: the first input image contains two frames", argv
[0]);
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
;
491 time_struct
= *gmtime (&itime
);
492 strftime (time_string
, GPIV_MAX_CHARS
, "%a %b %d %Y %T", &time_struct
);
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
);
516 if ((fp
= fopen(fname_out
, "wb")) == NULL
) {
519 if ((err_msg
= gpiv_write_png_image (fp
, image_c
, FALSE
)) != NULL
) {
520 gpiv_error ("%s: %s\n", argv
[0], err_msg
);
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
);