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() */
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 */
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\
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\
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
;
82 static gint numboth
= 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
;
101 command_args (int argc
,
103 char fname
[GPIV_MAX_CHARS
],
104 GpivImagePar
*image_par
106 /* ----------------------------------------------------------------------------
107 * Command line argument handling
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
122 while (argc_next
== 0 && (c
= *++argv
[0]))
126 printf("%s\n", RCSID
);
135 printf("%s\n", argv
[0]);
137 printf("%s\n",USAGE
);
146 suf_a
= g_strdup(*++argv
);
153 suf_b
= g_strdup(*++argv
);
160 * Time scaling parameter
163 image_par
->t_scale
= atof(*++argv
);
164 image_par
->t_scale__set
= TRUE
;
170 skip
= atoi(*++argv
);
184 numboth
= atoi(*++argv
);
191 itype
= g_strdup(*++argv
);
206 if (strcmp("-help", *argv
) == 0) {
207 printf("\n%s", argv
[0]);
208 printf("\n%s", HELP
);
209 printf("\n%s", USAGE
);
211 } else if (strcmp("-print", *argv
) == 0) {
213 } else if (strcmp("-version", *argv
) == 0) {
214 printf("%s\n", RCSID
);
216 } else if (strcmp("-verbose", *argv
) == 0) {
218 } else if (strcmp("-dt", *argv
) == 0) {
219 image_par
->t_scale
= atof(*++argv
);
220 image_par
->t_scale__set
= TRUE
;
223 } else if (strcmp("-suf_a", *argv
) == 0) {
224 suf_a
= g_strdup(*++argv
);
228 } else if (strcmp("-suf_b", *argv
) == 0) {
229 suf_b
= g_strdup(*++argv
);
233 } else if (strcmp("-skip", *argv
) == 0) {
234 skip
= atoi(*++argv
);
238 } else if (strcmp("-suf_num", *argv
) == 0) {
243 } else if (strcmp("-Suf_num", *argv
) == 0) {
244 numboth
= atoi(*++argv
);
248 } else if (strcmp("-type", *argv
) == 0) {
249 itype
= g_strdup(*++argv
);
253 } else if (strcmp("-warning", *argv
) == 0) {
258 gpiv_error ("%s: unknown option: %s", argv
[0], *argv
);
271 strcpy(fname
, argv
[argc
- 1]);
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);
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",
298 g_message("comand_args: fname = %s", fname
);
306 make_fname (char *fname
,
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
) {
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
);
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 */
366 g_snprintf(fname_out
, GPIV_MAX_CHARS
, "%s%s%s%d%s",
367 dirname
, G_DIR_SEPARATOR_S
, fname_base
, num
,
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,
375 if (verbose
) printf("\n#output image file is: %s", fname_out
);
377 g_snprintf(fname_out
, GPIV_MAX_CHARS
, "%s%s%s%s",
378 dirname
, G_DIR_SEPARATOR_S
, fname_base
,
380 if (verbose
) printf("\n#output image file is: %s",
385 if (verbose
) printf("\n");
393 main (int argc
, char *argv
[])
394 /*-----------------------------------------------------------------------------*/
396 gchar
*err_msg
= NULL
;
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
;
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
);
418 make_fname (fname_base
, fname_in_a
, fname_in_b
, fname_out
))
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
);
435 && image_a
->header
->x_corr
== TRUE
) {
436 gpiv_error ("%s: the first input image contains two frames", argv
[0]);
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
;
484 time_struct
= *gmtime (&itime
);
485 strftime (time_string
, GPIV_MAX_CHARS
, "%a %b %d %Y %T", &time_struct
);
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
);
509 if ((fp
= fopen(fname_out
, "wb")) == NULL
) {
512 if ((err_msg
= gpiv_write_png_image (fp
, image_c
, FALSE
)) != NULL
) {
513 gpiv_error ("%s: %s\n", argv
[0], err_msg
);
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
);