diff options
| -rw-r--r-- | NEWS | 3 | ||||
| -rw-r--r-- | README | 40 | ||||
| -rw-r--r-- | configure.ac | 6 | ||||
| -rw-r--r-- | src/Fl_Search_Chooser.H | 4 | ||||
| -rw-r--r-- | src/Fl_Value_Dial.H | 8 | ||||
| -rw-r--r-- | src/Fl_Value_Dial.cxx | 4 | ||||
| -rw-r--r-- | src/GipfelWidget.H | 15 | ||||
| -rw-r--r-- | src/GipfelWidget.cxx | 75 | ||||
| -rw-r--r-- | src/Hill.H | 2 | ||||
| -rw-r--r-- | src/Hill.cxx | 2 | ||||
| -rw-r--r-- | src/JPEGOutputImage.H | 55 | ||||
| -rw-r--r-- | src/JPEGOutputImage.cxx | 121 | ||||
| -rw-r--r-- | src/Makefile.am | 12 | ||||
| -rw-r--r-- | src/OutputImage.H | 53 | ||||
| -rw-r--r-- | src/OutputImage.cxx | 92 | ||||
| -rw-r--r-- | src/Panorama.H | 4 | ||||
| -rw-r--r-- | src/Panorama.cxx | 24 | ||||
| -rw-r--r-- | src/PreviewOutputImage.H | 52 | ||||
| -rw-r--r-- | src/PreviewOutputImage.cxx | 91 | ||||
| -rw-r--r-- | src/Projection.H | 7 | ||||
| -rw-r--r-- | src/Projection.cxx | 3 | ||||
| -rw-r--r-- | src/ProjectionSphaeric.H | 5 | ||||
| -rw-r--r-- | src/ProjectionSphaeric.cxx | 22 | ||||
| -rw-r--r-- | src/ProjectionTangential.H | 5 | ||||
| -rw-r--r-- | src/ProjectionTangential.cxx | 11 | ||||
| -rw-r--r-- | src/Stitch.H | 51 | ||||
| -rw-r--r-- | src/Stitch.cxx | 151 | ||||
| -rw-r--r-- | src/TIFFOutputImage.H | 49 | ||||
| -rw-r--r-- | src/TIFFOutputImage.cxx | 110 | ||||
| -rw-r--r-- | src/choose_hill.H | 6 | ||||
| -rw-r--r-- | src/gipfel.cxx | 99 | 
31 files changed, 1109 insertions, 73 deletions
@@ -1,6 +1,9 @@  gipfel ChangeLog  ================= +gipfel-0.1.3 + - Add stitching mode (gipfel -s). See README  for details. +  gipfel-0.1.2   - Fix bugs for "Normal Projection" and "Panoramic Projection" mode.     Panorama mode now works with the great view from Mount Everest by @@ -18,9 +18,11 @@ picture manually.  Requirements  ============ -- gipfel works on UNIX-like system (e.g. Linux, *BSD and probably others). -- You need fltk-1.1.x from www.fltk.org. -- You need the ccmath library (http://freshmeat.net/projects/ccmath/). +- fltk-1.1.x (http://www.fltk.org) +- libtiff (http://www.remotesensing.org/libtiff/) +- libjpeg (http://www.ijg.org/) +- ccmath library (http://freshmeat.net/projects/ccmath/) +- gipfel works on UNIX-like system (e.g. Linux, *BSD and probably others)  Installation @@ -133,6 +135,37 @@ the Option->Show Hidden menu entry. Hidden objects and hidden GPS way points  are displayed in blue. +Stitching +========= + +If you have multiple images from the same viewpoint referenced with gipfel +you can stitch them together to form a panorama image. +For stitching the input images must all have been correctly referenced +with gipfel and saved (see "Loading and Saving Images"). +You can then call gipfel -s <img1> <img2> ... +to see the result in a window. Alternatively you can call +gipfel -s -j <outimg> <img1> <img2> ... +to save the result as a JPEG image to <outimg> or  +gipfel -s -t <outdir> <img1> <img2> ... +to save the result as multiple TIFF images to <outdir>. +Use the multiple TIFF option for blending the result with enblend +(http://enblend.sourceforge.net/). +The width and height of the result images can be adjusted with the +-w and -h options. + +The nice thing about stitching is that gipfel uses the same code that +it already had for positioning mountains on the pictures. +gipfel simply scans all directions needed for the panorama and determines +where these directions would end up on the various pictures. It can then +record the corresponding color values from the input images. + +In contrast to other stitching programs, the input images don't need to  +overlap. + +If you want to open a stitched image in gipfel to locate the mountains +on it, don't forget to choose Panoramic Projection! + +  Troubleshooting  =============== @@ -180,4 +213,3 @@ results of gipfel.  Johannes Hofmann  (Johannes.Hofmann@gmx.de) -Nov 14, 2005 diff --git a/configure.ac b/configure.ac index 6d4f557..1b5d0ac 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@  # Process this file with autoconf to produce a configure script.  AC_PREREQ(2.59) -AC_INIT(gipfel, 0.1.2, Johannes.Hofmann@gmx.de) +AC_INIT(gipfel, 0.1.3, Johannes.Hofmann@gmx.de)  AM_INIT_AUTOMAKE  AC_CONFIG_SRCDIR([src/Panorama.H])  AC_CONFIG_HEADER(config.h) @@ -52,5 +52,9 @@ LIBS="`$FLTKCONFIG --use-images --ldflags` $LIBS"  AC_CHECK_HEADERS([ccmath.h], [], [echo "Error: ccmath.h not found."; exit 1;])  AC_CHECK_LIB([ccm], [open], [], [echo "Error: ccmath.so not found."; exit 1;]) +# Check for libtiff +AC_CHECK_HEADERS([tiffio.h], [], [echo "Error: tiffio.h not found."; exit 1;]) +AC_CHECK_LIB([tiff], [TIFFOpen], [], [echo "Error: libtiff.so not found."; exit 1;]) +  AC_CONFIG_FILES([Makefile src/Makefile])  AC_OUTPUT diff --git a/src/Fl_Search_Chooser.H b/src/Fl_Search_Chooser.H index 6bb71fe..c87f0de 100644 --- a/src/Fl_Search_Chooser.H +++ b/src/Fl_Search_Chooser.H @@ -1,6 +1,4 @@  // -// "$Id: Fl_Value_Dial.H,v 1.2 2005/05/18 11:34:30 hofmann Exp $" -//  // Value dial header file for the Fast Light Tool Kit (FLTK).  //  // Copyright 1998-2004 by Bill Spitzak and others. @@ -20,8 +18,6 @@  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  // USA.  // -// Please report all bugs and problems to "fltk-bugs@fltk.org". -//  #ifndef FL_SEARCH_CHOOSER_H  #define FL_SEARCH_CHOOSER_H diff --git a/src/Fl_Value_Dial.H b/src/Fl_Value_Dial.H index 7d41aa5..f9ac18c 100644 --- a/src/Fl_Value_Dial.H +++ b/src/Fl_Value_Dial.H @@ -1,6 +1,4 @@  // -// "$Id: Fl_Value_Dial.H,v 1.2 2005/05/18 11:34:30 hofmann Exp $" -//  // Value dial header file for the Fast Light Tool Kit (FLTK).  //  // Copyright 1998-2004 by Bill Spitzak and others. @@ -20,8 +18,6 @@  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  // USA.  // -// Please report all bugs and problems to "fltk-bugs@fltk.org". -//  #ifndef Fl_Value_Dial_H  #define Fl_Value_Dial_H @@ -45,7 +41,3 @@ class Fl_Value_Dial : public Fl_Dial {  };  #endif - -// -// End of "$Id: Fl_Value_Dial.H,v 1.2 2005/05/18 11:34:30 hofmann Exp $". -// diff --git a/src/Fl_Value_Dial.cxx b/src/Fl_Value_Dial.cxx index 6e5c35c..c837930 100644 --- a/src/Fl_Value_Dial.cxx +++ b/src/Fl_Value_Dial.cxx @@ -1,6 +1,4 @@  // -// "$Id: Fl_Value_Dial.cxx,v 1.2 2005/05/18 11:34:30 hofmann Exp $" -//  // Value dial widget for the Fast Light Tool Kit (FLTK).  //  // Copyright 1998-2004 by Bill Spitzak and others. @@ -20,8 +18,6 @@  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  // USA.  // -// Please report all bugs and problems to "fltk-bugs@fltk.org". -//  #include <FL/Fl.H>  #include <FL/fl_draw.H> diff --git a/src/GipfelWidget.H b/src/GipfelWidget.H index 1aebbea..7bcd3c0 100644 --- a/src/GipfelWidget.H +++ b/src/GipfelWidget.H @@ -1,7 +1,5 @@  //  -// "$Id: GipfelWidget.H,v 1.22 2005/06/22 19:47:19 hofmann Exp $" -// -// Copyright 2005 by Johannes Hofmann +// Copyright 2006 by Johannes Hofmann  //  // This library is free software; you can redistribute it and/or  // modify it under the terms of the GNU Library General Public @@ -49,6 +47,12 @@ class GipfelWidget : public Fl_Widget {    int get_rel_track_width(Hill *m); +  static int get_pixel_nearest(Fl_Image *img, double x, double y, +                     char *r, char *g, char *b); + +  static int get_pixel(Fl_Image *img, int x, int y, +                     char *r, char *g, char *b); +   public:    GipfelWidget(int X,int Y,int W, int H); @@ -57,6 +61,8 @@ class GipfelWidget : public Fl_Widget {    int load_image(char *file);    int save_image(char *file); +	 +  const char * get_image_filename();    int load_data(const char *file); @@ -118,6 +124,9 @@ class GipfelWidget : public Fl_Widget {    int update(); +  int get_pixel(double a_view, double a_nick, +                    char *r, char *g, char *b); +    void draw();  };  #endif diff --git a/src/GipfelWidget.cxx b/src/GipfelWidget.cxx index 0c4ef08..c4fe032 100644 --- a/src/GipfelWidget.cxx +++ b/src/GipfelWidget.cxx @@ -147,6 +147,11 @@ GipfelWidget::load_image(char *file) {    return 0;  } +const char * +GipfelWidget::get_image_filename() { +	return img_file; +} +  int  GipfelWidget::save_image(char *file) {    char * args[32]; @@ -714,6 +719,7 @@ GipfelWidget::set_track_width(double w) {    redraw();  } +  int  GipfelWidget::handle(int event) {    int mark_x, mark_y; @@ -743,3 +749,72 @@ GipfelWidget::handle(int event) {    }    return 0;  } + +int +GipfelWidget::get_pixel(double a_view, double a_nick, +                        char *r, char *g, char *b) { +	double px, py; + + +	if (img == NULL) { +		return 1; +	} + +	if (pan->get_coordinates(a_view, a_nick, &px, &py) != 0) { +		return 1; +	} + +	return get_pixel_nearest(img, px + ((double) img->w()) / 2.0, +				py + ((double) img->h()) / 2.0, r, g, b); +} + +int +GipfelWidget::get_pixel_nearest(Fl_Image *img, double x, double y, +	char *r, char *g, char *b) { +	if (isnan(x) || isnan(y)) { +		return 1; +	} else { +		return get_pixel(img, (int) rint(x), (int) rint(y), r, g, b); +	} +} + + +int +GipfelWidget::get_pixel(Fl_Image *img, int x, int y, +                     char *r, char *g, char *b) { +    if ( img->d() == 0 ) { +        return 1; +    } + +    if (x < 0 || x >=img->w() || y < 0 || y >= img->h()) { +        return 1; +    } +    long index = (y * img->w() * img->d()) + (x * img->d()); // X/Y -> buf index   +    switch ( img->count() ) { +        case 1: {                                            // bitmap +                const char *buf = img->data()[0]; +                switch ( img->d() ) { +                    case 1: {                                    // 8bit +                            *r = *g = *b = *(buf+index); +                            break; +                        } +                    case 3:                                      // 24bit +                        *r = *(buf+index+0); +                        *g = *(buf+index+1); +                        *b = *(buf+index+2); +                        break; +                    default:                                     // ?? +                        printf("Not supported: chans=%d\n", img->d()); +                        return 1; +                    } +                break; +            } +        default:                                             // ?? pixmap, bit vals +            printf("Not supported: count=%d\n", img->count()); +            return 1; +    } + +    return 0; + +} + @@ -1,6 +1,4 @@  //  -// "$Id: Hill.H,v 1.16 2005/06/22 20:40:35 hofmann Exp $" -//  // Copyright 2005 by Johannes Hofmann  //  // This library is free software; you can redistribute it and/or diff --git a/src/Hill.cxx b/src/Hill.cxx index 626e470..67e1d8e 100644 --- a/src/Hill.cxx +++ b/src/Hill.cxx @@ -58,7 +58,7 @@ Hill::Hill(const Hill& h) {  }  Hill::Hill(int x_tmp, int y_tmp) { -  name = ""; +  name = NULL;    phi = 0.0;    lam = 0.0;    height = 0.0; diff --git a/src/JPEGOutputImage.H b/src/JPEGOutputImage.H new file mode 100644 index 0000000..50570e5 --- /dev/null +++ b/src/JPEGOutputImage.H @@ -0,0 +1,55 @@ +//  +// Copyright 2006 by Johannes Hofmann +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +#ifndef JPEGOUTPUTIMAGE_H +#define JPEGOUTPUTIMAGE_H + +#include <stdio.h> +extern "C" { +#include <jpeglib.h> +#undef HAVE_STDLIB_H +} + +#include "OutputImage.H" + +class JPEGOutputImage : OutputImage { +	private: +		unsigned char *row; +		char *file; +		struct jpeg_compress_struct cinfo; +		struct jpeg_error_mgr jerr; +		FILE *fp; +		int quality; + +	public: +		JPEGOutputImage(const char *file, int quality = 90); + +		~JPEGOutputImage(); + +	protected: +		int init_internal(int w, int h); + +		int set_pixel_internal(int x, char r, char g, char b);	 + +		int next_line_internal(); + +		int done_internal(); +}; + +#endif diff --git a/src/JPEGOutputImage.cxx b/src/JPEGOutputImage.cxx new file mode 100644 index 0000000..3f7fd11 --- /dev/null +++ b/src/JPEGOutputImage.cxx @@ -0,0 +1,121 @@ +//  +// Copyright 2006 by Johannes Hofmann +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +extern "C" { +#include <jpeglib.h> +} + +#include "JPEGOutputImage.H" + +JPEGOutputImage::JPEGOutputImage(const char *f, int q) { +	file = strdup(f); +	fp = NULL; +	row = NULL; +	quality = q; +} + +JPEGOutputImage::~JPEGOutputImage() { +	if (row) { +		free(row); +	} +	if (file) { +		free(file); +	} +} + +int +JPEGOutputImage::init_internal(int w1, int h1) { +	if (row) { +		free(row); +		row = NULL; +	} + +	row = (unsigned char*) malloc(sizeof(char) * 3 * W); +	if (!row) { +		perror("malloc"); +		return 1; +	} +	memset(row, 0, sizeof(char) * 3 * W); + +	if (fp) { +		fclose(fp); +	} + +	if ((fp = fopen(file, "wb")) == NULL) { +		fprintf(stderr, "can't open %s\n", file); +		return 1; +	} + +	cinfo.err = jpeg_std_error(&jerr); +	jpeg_create_compress(&cinfo); +	jpeg_stdio_dest(&cinfo, fp); +	cinfo.image_width = W; +	cinfo.image_height = H; +	cinfo.input_components = 3;          /* # of color components per pixel */ +	cinfo.in_color_space = JCS_RGB; + +	jpeg_set_defaults(&cinfo); +	jpeg_set_quality(&cinfo, quality, TRUE); + +	jpeg_start_compress(&cinfo, TRUE); + +} + +int +JPEGOutputImage::set_pixel_internal(int x, char r, char g, char b) { +	row[x*3+0] = r; +	row[x*3+1] = g; +	row[x*3+2] = b; + +	return 0; +} + +int +JPEGOutputImage::next_line_internal() { +	JSAMPROW row_pointer[1]; + +	row_pointer[0] = row; +	jpeg_write_scanlines(&cinfo, row_pointer, 1); +	memset(row, 0, sizeof(char) * 3 * W); +	return 0; +} + +int +JPEGOutputImage::done_internal() { +	jpeg_finish_compress(&cinfo); +	jpeg_destroy_compress(&cinfo); + +	if (fp) { +		fclose(fp); +		fp = NULL; +	} +	if (row) { +		free(row); +	} + +	if (fp) { +		fclose(fp); +		fp = NULL; +	} +	return 0; +}	 + diff --git a/src/Makefile.am b/src/Makefile.am index e9e32f7..5577090 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,7 +11,12 @@ gipfel_SOURCES = \  	Hill.cxx \  	Fl_Value_Dial.cxx \  	Fl_Search_Chooser.cxx \ -	choose_hill.cxx +	choose_hill.cxx \ +	Stitch.cxx \ +	OutputImage.cxx \ +	JPEGOutputImage.cxx \ +	TIFFOutputImage.cxx \ +	PreviewOutputImage.cxx   noinst_HEADERS = \  	GipfelWidget.H \ @@ -24,4 +29,9 @@ noinst_HEADERS = \  	Fl_Value_Dial.H \  	Fl_Search_Chooser.H \  	choose_hill.H \ +	Stitch.H \ +	OutputImage.H \ +	JPEGOutputImage.H \ +	TIFFOutputImage.H \ +	PreviewOutputImage.H \  	util.h diff --git a/src/OutputImage.H b/src/OutputImage.H new file mode 100644 index 0000000..8792eb6 --- /dev/null +++ b/src/OutputImage.H @@ -0,0 +1,53 @@ +//  +// Copyright 2006 by Johannes Hofmann +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +#ifndef OUTPUTIMAGE_H +#define OUTPUTIMAGE_H + + +class OutputImage { +	private: +		int initialized; + +	public: +		OutputImage(); + +		~OutputImage(); +		 +		virtual int init(int w1, int h1); + +		int set_pixel(int x, char r, char g, char b); + +		int next_line(); + +		int done(); + +	protected: +		int W, H, line; + +		virtual int init_internal(int w1, int h1); + +		virtual int set_pixel_internal(int x, char r, char g, char b);	 +	 +		virtual int next_line_internal(); + +		virtual int done_internal(); +}; + +#endif diff --git a/src/OutputImage.cxx b/src/OutputImage.cxx new file mode 100644 index 0000000..f2e7296 --- /dev/null +++ b/src/OutputImage.cxx @@ -0,0 +1,92 @@ +//  +// Copyright 2006 by Johannes Hofmann +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +#include <stdlib.h> +#include <stdio.h> + +#include "OutputImage.H" + +OutputImage::OutputImage() { +	W = 0; +	H = 0; +	initialized = 0; +} + +OutputImage::~OutputImage() { +} + +int +OutputImage::init(int w1, int h1) { +	W = w1; +	H = h1; +	line = 0; +	initialized = 1; + +	return init_internal(w1, h1); +} + + +int +OutputImage::init_internal(int w1, int h1) { +	return 0; +} + +int +OutputImage::set_pixel(int x, char r, char g, char b) { +	if (!initialized || x < 0 || x >= W) { +		return 1; +	} else { +		return set_pixel_internal(x, r, g, b); +	} +} + +int +OutputImage::set_pixel_internal(int x, char r, char g, char b) { +	return 0; +} + +int +OutputImage::next_line() { +	if (!initialized || line++ >= H) { +		return 1; +	} else { +		return next_line_internal(); +	} +} + +int +OutputImage::next_line_internal() { +	return 0; +} + +int +OutputImage::done() { +	if (!initialized) { +		return 1; +	} else { +		next_line(); +		return done_internal(); +	} +} + +int +OutputImage::done_internal() { +	return 0; +} + diff --git a/src/Panorama.H b/src/Panorama.H index 32cefa6..a538809 100644 --- a/src/Panorama.H +++ b/src/Panorama.H @@ -1,6 +1,4 @@  //  -// "$Id: Panorama.H,v 1.20 2005/06/22 19:47:20 hofmann Exp $" -//  // Copyright 2005 by Johannes Hofmann  //  // This library is free software; you can redistribute it and/or @@ -144,5 +142,7 @@ class Panorama {    Projection::Projection_t get_projection();    void set_projection(Projection::Projection_t p); + +  int get_coordinates(double a_view, double a_nick, double *x, double *y);  };  #endif diff --git a/src/Panorama.cxx b/src/Panorama.cxx index c8cb1dc..73bc003 100644 --- a/src/Panorama.cxx +++ b/src/Panorama.cxx @@ -508,8 +508,11 @@ Panorama::update_coordinates() {    for (int i=0; i<visible_mountains->get_num(); i++) {      m = visible_mountains->get(i); +	double tmp_x, tmp_y; -    proj->set_coordinates(m, &parms); +    proj->get_coordinates(m->a_view, m->a_nick, &parms, &tmp_x, &tmp_y); +	m->x = (int) rint(tmp_x); +	m->y = (int) rint(tmp_y);    }  } @@ -586,3 +589,22 @@ Panorama::get_real_distance(Hill *m) {    return c;  } +int +Panorama::get_coordinates(double a_view, double a_nick, double *x, double *y) { +	a_view = a_view - parms.a_center; + +    if (a_view > pi_d) { +      a_view -= 2.0*pi_d; +    } else if (a_view < -pi_d) { +      a_view += 2.0*pi_d; +    } +   +    if (a_view > view_angle || a_view < - view_angle) { +		return 1; +	} + +    proj->get_coordinates(a_view, a_nick, &parms, x, y); + +	return 0; +} + diff --git a/src/PreviewOutputImage.H b/src/PreviewOutputImage.H new file mode 100644 index 0000000..7095999 --- /dev/null +++ b/src/PreviewOutputImage.H @@ -0,0 +1,52 @@ +//  +// Copyright 2006 by Johannes Hofmann +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +#ifndef PREVIEWOUTPUTIMAGE_H +#define PREVIEWOUTPUTIMAGE_H + +#include <stdio.h> + +#include <FL/Fl_Widget.H> +#include <FL/Fl_Image.H> + +#include "OutputImage.H" + +class PreviewOutputImage : OutputImage , public Fl_Widget { +	private: +		uchar *data; +		int d; + +	public: +		PreviewOutputImage(int X, int Y, int W, int H); + +		~PreviewOutputImage(); + +		void draw(); + +	protected: +		int init_internal(int w, int h); + +		int set_pixel_internal(int x, char r, char g, char b);	 + +		int next_line_internal(); + +		int done_internal(); +}; + +#endif diff --git a/src/PreviewOutputImage.cxx b/src/PreviewOutputImage.cxx new file mode 100644 index 0000000..078ba26 --- /dev/null +++ b/src/PreviewOutputImage.cxx @@ -0,0 +1,91 @@ +//  +// DataImage routines. +// +// Copyright 2006 by Johannes Hofmann +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <Fl/Fl.H> +#include <Fl/fl_draw.h> + +#include "PreviewOutputImage.H" + +PreviewOutputImage::PreviewOutputImage(int X, int Y, int W, int H): Fl_Widget(X, Y, W, H) { +	d = 3; +	data = NULL; +} + +PreviewOutputImage::~PreviewOutputImage() { +	if (data) { +		free(data); +	} +} + +int +PreviewOutputImage::init_internal(int w, int h) { +	data = (uchar*) malloc(w * h * d); +	memset(data, 0, w * h * d); +	size(w, h); +	return 0; +} +	 + + +int +PreviewOutputImage::set_pixel_internal(int x, char r, char g, char b) { +	if (!data) { +		return 1; +	} + +	long index = (line * w() * d + (x * d)); +	*(data+index+0) = r; +	*(data+index+1) = g; +	*(data+index+2) = b; + +	return 0; +} + +int +PreviewOutputImage::next_line_internal() { +	if (line % 10 == 0) { +		redraw(); +		Fl::check(); +	} +	return 0; +} + +int +PreviewOutputImage::done_internal() { +	return 0; +} + +void +PreviewOutputImage::draw() { +	if (!data) { +		return; +	} +	fl_push_clip(x(), y(), w(), h()); + +	fl_draw_image(data, x(), y(), w(), h(), d); + +	fl_pop_clip(); +} + diff --git a/src/Projection.H b/src/Projection.H index b81e531..0a6ec81 100644 --- a/src/Projection.H +++ b/src/Projection.H @@ -1,7 +1,5 @@  //  -// "$Id: Panorama.H,v 1.20 2005/06/22 19:47:20 hofmann Exp $" -// -// Copyright 2005 by Johannes Hofmann +// Copyright 2006 by Johannes Hofmann  //  // This library is free software; you can redistribute it and/or  // modify it under the terms of the GNU Library General Public @@ -37,7 +35,8 @@ class Projection {    Projection(); -  virtual void set_coordinates(Hill *m, const ViewParams *parms); +  virtual void get_coordinates(double a_view, double a_nick, +	const ViewParams *parms, double *x, double *y);    virtual int comp_params(const Hill *m1, const Hill *m2, ViewParams *parms);  }; diff --git a/src/Projection.cxx b/src/Projection.cxx index 57a210a..1f224e8 100644 --- a/src/Projection.cxx +++ b/src/Projection.cxx @@ -31,7 +31,8 @@ Projection::Projection() {  };  void -Projection::set_coordinates(Hill *m, const ViewParams *parms) { +Projection::get_coordinates(double a_view, double a_nick, +		const ViewParams *parms, double *x, double *y) {    fprintf(stderr, "Error: Projection::set_coordinates()\n");  } diff --git a/src/ProjectionSphaeric.H b/src/ProjectionSphaeric.H index fcaffa8..06396f1 100644 --- a/src/ProjectionSphaeric.H +++ b/src/ProjectionSphaeric.H @@ -30,11 +30,10 @@ class ProjectionSphaeric : public Projection {    double comp_dir_view(const Hill *m1, const Hill *m2, double d_m1_2, double d_m2_2, double scale, double sign3);    double comp_nick_view(const Hill *m1, const Hill *m2, double d_m1_2, double scale, double dir_view, double sign1);    double comp_tilt_view(const Hill *m, double scale, double dir_view, double nick_view); -  void set_coordinates(const Hill *m, const ViewParams *parms, -                       double *x, double *y);   public: -  void set_coordinates(Hill *m, const ViewParams *parms); +  void get_coordinates(double a_view, double a_nick, const ViewParams *parms, +		double *x, double *y);    int comp_params(const Hill *m1, const Hill *m2, ViewParams *parms);  }; diff --git a/src/ProjectionSphaeric.cxx b/src/ProjectionSphaeric.cxx index 74c9de6..e69882b 100644 --- a/src/ProjectionSphaeric.cxx +++ b/src/ProjectionSphaeric.cxx @@ -66,9 +66,9 @@ ProjectionSphaeric::comp_params(const Hill *m1, const Hill *m2, ViewParams *parm            isnan(tmp.a_nick) || isnan(tmp.a_tilt)) {          ;        } else { -        set_coordinates(m1, &tmp, &tmp_x, &tmp_y); +        get_coordinates(m1->a_view, m1->a_nick, &tmp, &tmp_x, &tmp_y);          val = sqrt(pow(tmp_x - m1->x, 2.0) + pow(tmp_y - m1->y, 2.0));  -        set_coordinates(m2, &tmp, &tmp_x, &tmp_y); +        get_coordinates(m2->a_view, m2->a_nick, &tmp, &tmp_x, &tmp_y);          val += sqrt(pow(tmp_x - m2->x, 2.0) + pow(tmp_y - m2->y, 2.0));           if (val < best_val) {	 @@ -88,22 +88,12 @@ ProjectionSphaeric::comp_params(const Hill *m1, const Hill *m2, ViewParams *parm  }  void  -ProjectionSphaeric::set_coordinates(Hill *m, const ViewParams *parms) { +ProjectionSphaeric::get_coordinates(double a_view, double a_nick, +	const ViewParams *parms, double *x, double *y) {    double x_tmp, y_tmp; -  set_coordinates(m, parms, &x_tmp, &y_tmp); - -  m->x = (int) rint(x_tmp); -  m->y = (int) rint(y_tmp); -} - -void  -ProjectionSphaeric::set_coordinates(const Hill *m, const ViewParams *parms, -                                    double *x, double *y) { -  double x_tmp, y_tmp; - -  x_tmp = m->a_view * parms->scale; -  y_tmp = - (m->a_nick - parms->a_nick) * parms->scale; +  x_tmp = a_view * parms->scale; +  y_tmp = - (a_nick - parms->a_nick) * parms->scale;    // rotate by a_tilt;    *x = x_tmp * cos(parms->a_tilt) - y_tmp * sin(parms->a_tilt); diff --git a/src/ProjectionTangential.H b/src/ProjectionTangential.H index 8e7673e..e74511f 100644 --- a/src/ProjectionTangential.H +++ b/src/ProjectionTangential.H @@ -1,6 +1,4 @@  //  -// "$Id: Panorama.H,v 1.20 2005/06/22 19:47:20 hofmann Exp $" -//  // Copyright 2005 by Johannes Hofmann  //  // This library is free software; you can redistribute it and/or @@ -36,7 +34,8 @@ class ProjectionTangential : public Projection {    int optimize(const Hill *m1, const Hill *m2, ViewParams *parms);   public: -  void set_coordinates(Hill *m, const ViewParams *parms); +  void get_coordinates(double a_view, double a_nick, const ViewParams *parms, +		double *x, double *y);    int comp_params(const Hill *m1, const Hill *m2, ViewParams *parms);  }; diff --git a/src/ProjectionTangential.cxx b/src/ProjectionTangential.cxx index 032005d..416d27d 100644 --- a/src/ProjectionTangential.cxx +++ b/src/ProjectionTangential.cxx @@ -160,15 +160,16 @@ ProjectionTangential::optimize(const Hill *m1, const Hill *m2, ViewParams *parms  }  void  -ProjectionTangential::set_coordinates(Hill *m, const ViewParams *parms) { +ProjectionTangential::get_coordinates(double a_view, double a_nick, +	const ViewParams *parms, double *x, double *y) {    double x_tmp, y_tmp; -  x_tmp = tan(m->a_view) * parms->scale; -  y_tmp = - (tan(m->a_nick - parms->a_nick) * parms->scale); +  x_tmp = tan(a_view) * parms->scale; +  y_tmp = - (tan(a_nick - parms->a_nick) * parms->scale);    // rotate by a_tilt; -  m->x = (int) rint(x_tmp * cos(parms->a_tilt) - y_tmp * sin(parms->a_tilt)); -  m->y = (int) rint(x_tmp * sin(parms->a_tilt) + y_tmp * cos(parms->a_tilt)); +  *x = x_tmp * cos(parms->a_tilt) - y_tmp * sin(parms->a_tilt); +  *y = x_tmp * sin(parms->a_tilt) + y_tmp * cos(parms->a_tilt);  }  double diff --git a/src/Stitch.H b/src/Stitch.H new file mode 100644 index 0000000..0bb6d48 --- /dev/null +++ b/src/Stitch.H @@ -0,0 +1,51 @@ +//  +// Copyright 2005 by Johannes Hofmann +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +#ifndef STITCH_H +#define STITCH_H + +#include "GipfelWidget.H" +#include "OutputImage.H" + +#define MAX_PICS 256 + +		 +class Stitch { +	private: +		GipfelWidget *gipf[MAX_PICS]; +		OutputImage *single_images[MAX_PICS]; +		OutputImage *merged_image; +		 + +	public: +		Stitch(); + +		~Stitch(); +		 +		int load_image(char *file); + +		OutputImage * set_output(OutputImage *img); + +		OutputImage * set_output(const char *file, OutputImage *img); + +		int resample(int w, int h, +			double view_start, double view_end); +}; + +#endif diff --git a/src/Stitch.cxx b/src/Stitch.cxx new file mode 100644 index 0000000..1fe3d88 --- /dev/null +++ b/src/Stitch.cxx @@ -0,0 +1,151 @@ +//  +// Stitch routines. +// +// Copyright 2006 by Johannes Hofmann +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <math.h> + +#include <Fl/Fl.H> + +#include "OutputImage.H" +#include "Stitch.H" + +static double pi_d = asin(1.0) * 2.0; + +Stitch::Stitch() { +	for (int i=0; i<MAX_PICS; i++) { +		gipf[i] = NULL; +		single_images[i] = NULL; +	} +	merged_image = NULL; +} + +Stitch::~Stitch() { +	for (int i=0; i<MAX_PICS; i++) { +		if (gipf[i]) { +			delete(gipf[i]); +		} else { +			break; +		} +	} +} + + +int +Stitch::load_image(char *file) { +	for (int i=0; i<MAX_PICS; i++) { +		if (gipf[i] == NULL) { +			gipf[i] = new GipfelWidget(0, 0, 800, 600); +			if (gipf[i]->load_image(file) != 0) { +				delete gipf[i]; +				gipf[i] = NULL; +			} +			break; +		} +	} + + +} + +OutputImage* +Stitch::set_output(OutputImage *img) { +	OutputImage *ret = merged_image; +	merged_image = img; +	return ret; +} + +OutputImage* +Stitch::set_output(const char *file, OutputImage *img) { +	OutputImage *ret = NULL; + +	for (int i=0; i<MAX_PICS; i++) { +		if (gipf[i] != NULL) { +			const char *img_file = gipf[i]->get_image_filename(); +			if (img_file && strcmp(file, img_file) == 0) { +				ret = single_images[i]; +				single_images[i] = img; +				break; +			} +		} +	} + +	return ret; +} + +int +Stitch::resample(int w, int h, +            double view_start, double view_end) { +	double step_view = (view_end - view_start) / w; +	char r, g, b; +	int y_off = h / 2; +	int merged_pixel_set; + 	double radius = (double) w / (view_end -view_start); + +	if (merged_image) { +		merged_image->init(w, h); +	} +	for (int i=0; i<MAX_PICS; i++) { +		if (single_images[i]) { +			single_images[i]->init(w, h); +		} +	} + +	for (int y=0; y<h; y++) { +		double a_nick = atan((double)(y_off - y)/radius); + +		for (int x=0; x<w; x++) { +			double a_view; +			a_view = view_start + x * step_view; +			merged_pixel_set = 0; +			for (int i=0; i<MAX_PICS; i++) { +				if (gipf[i] == NULL) { +					break; +				} else if (gipf[i]->get_pixel(a_view, a_nick, &r, &g, &b)==0) { +					if (single_images[i]) { +						single_images[i]->set_pixel(x, r, g, b); +					} +					if (!merged_pixel_set && merged_image) { +						merged_image->set_pixel(x, r, g, b); +						merged_pixel_set++; +					} +				} +			} +		} +		if (merged_image) { +			merged_image->next_line(); +		} +		for (int i=0; i<MAX_PICS; i++) { +			if (single_images[i]) { +				single_images[i]->next_line(); +			} +		} +	} + +	if (merged_image) { +		merged_image->done(); +	} +	for (int i=0; i<MAX_PICS; i++) { +		if (single_images[i]) { +			single_images[i]->done(); +		} +	} +} diff --git a/src/TIFFOutputImage.H b/src/TIFFOutputImage.H new file mode 100644 index 0000000..3a14279 --- /dev/null +++ b/src/TIFFOutputImage.H @@ -0,0 +1,49 @@ +//  +// Copyright 2006 by Johannes Hofmann +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +#ifndef TIFFOUTPUTIMAGE_H +#define TIFFOUTPUTIMAGE_H + +#include <stdio.h> +#include <tiffio.h> + +#include "OutputImage.H" + +class TIFFOutputImage : OutputImage { +	private: +		unsigned char *row; +		char *file; +		TIFF *tiff; + +	public: +		TIFFOutputImage(const char *file); + +		~TIFFOutputImage(); + +	protected: +		int init_internal(int w, int h); + +		int set_pixel_internal(int x, char r, char g, char b);	 + +		int next_line_internal(); + +		int done_internal(); +}; + +#endif diff --git a/src/TIFFOutputImage.cxx b/src/TIFFOutputImage.cxx new file mode 100644 index 0000000..b8433ca --- /dev/null +++ b/src/TIFFOutputImage.cxx @@ -0,0 +1,110 @@ +//  +// Copyright 2006 by Johannes Hofmann +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA. +// + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "TIFFOutputImage.H" + +TIFFOutputImage::TIFFOutputImage(const char *f) { +	file = strdup(f); +	tiff = NULL; +	row = NULL; +} + +TIFFOutputImage::~TIFFOutputImage() { +	if (row) { +		free(row); +	} +	if (file) { +		free(file); +	} +} + +int +TIFFOutputImage::init_internal(int w1, int h1) { +	if (row) { +		free(row); +		row = NULL; +	} + +	row = (unsigned char*) malloc(sizeof(char) * 4 * w1); +	if (!row) { +		perror("malloc"); +		return 1; +	} +	memset(row, 0, sizeof(char) * 4 * w1); + +	if (tiff) { +		TIFFClose(tiff); +	} + +	if((tiff = TIFFOpen(file, "w")) == NULL){ +		fprintf(stderr, "can't open %s\n", file); +		return 1; +	} + +	TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, w1); +	TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, h1); +	TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE); +	TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); +	TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); +	TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, 1); +	TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8); +	TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 4); + +	return 0; +} + +int +TIFFOutputImage::set_pixel_internal(int x, char r, char g, char b) { +	row[x*4+0] = r; +	row[x*4+1] = g; +	row[x*4+2] = b; +	row[x*4+3] = 255; + +	return 0; +} + +int +TIFFOutputImage::next_line_internal() { +	int ret; + +	TIFFWriteEncodedStrip(tiff, line -1 , row, W * 4); + +	memset(row, 0, sizeof(char) * 4 * W); +	return 0; +} + +int +TIFFOutputImage::done_internal() { +	if (tiff) { +		TIFFClose(tiff); +		tiff = NULL; +	} + +	if (row) { +		free(row); +		row = NULL; +	} + +	return 0; +}	 + diff --git a/src/choose_hill.H b/src/choose_hill.H index 1387868..e424d70 100644 --- a/src/choose_hill.H +++ b/src/choose_hill.H @@ -1,8 +1,4 @@  // -// "$Id: Fl_Value_Dial.H,v 1.2 2005/05/18 11:34:30 hofmann Exp $" -// -// Value dial header file for the Fast Light Tool Kit (FLTK). -//  // Copyright 1998-2004 by Bill Spitzak and others.  //  // This library is free software; you can redistribute it and/or @@ -20,8 +16,6 @@  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  // USA.  // -// Please report all bugs and problems to "fltk-bugs@fltk.org". -//  #ifndef CHOOSE_HILL_H  #define CHOOSE_HILL_H diff --git a/src/gipfel.cxx b/src/gipfel.cxx index 4a284aa..9755f2e 100644 --- a/src/gipfel.cxx +++ b/src/gipfel.cxx @@ -41,6 +41,10 @@  #include "Fl_Value_Dial.H"  #include "Fl_Search_Chooser.H"  #include "GipfelWidget.H" +#include "JPEGOutputImage.H" +#include "TIFFOutputImage.H" +#include "PreviewOutputImage.H" +#include "Stitch.H"  #include "choose_hill.H"  #include "../config.h" @@ -60,6 +64,12 @@ Fl_Value_Input *i_view_lat, *i_view_long, *i_view_height;  Fl_Box *b_viewpoint;  Fl_Menu_Bar *mb; +#define STITCH_PREVIEW 1 +#define STITCH_JPEG    2 +#define STITCH_TIFF    4 +static int stitch(int stitch_w, int stitch_h, int type, const char *path, +  int argc, char **argv); +  void set_values() {    s_center->value(gipf->get_center_angle());    s_nick->value(gipf->get_nick_angle()); @@ -201,12 +211,17 @@ void fill_menubar(Fl_Menu_Bar* mb) {  void usage() {    fprintf(stderr, -	  "usage: gipfel [-v <viewpoint>] [-d <datafile>] [<image>]\n" +	  "usage: gipfel [-v <viewpoint>] [-d <datafile>]\n" +      "          [-s] [-j <outfile>] [-t <outdir] [-w <width>] [-h <height>]\n" +      "          [<image(s)>]\n"  	  "   -v <viewpoint>  Set point from which the picture was taken.\n"  	  "                   This must be a string that unambiguously \n"  	  "                   matches the name of an entry in the data file.\n"  	  "   -d <datafile>   Use <datafile> for GPS data.\n" -	  "      <image>      JPEG file to use.\n"); +      "   -s              Stitch mode.\n" +      "   -j <outfile>    JPEG output file for Stitch mode.\n" +      "   -t <outdir>     Output directory for TIFF images in Stitch mode.\n" +	  "      <image(s)>   JPEG file(s) to use.\n");  }  Fl_Window *  @@ -319,14 +334,17 @@ int main(int argc, char** argv) {    char c, *sep, *tmp, **my_argv;    char *view_point = NULL;    int err, bflag = 0, dflag = 0, my_argc; +  int stitch_flag = 0, stitch_w = 2000, stitch_h = 500; +  int jpeg_flag = 0, tiff_flag = 0; +  char *outpath;    Fl_Window *control_win, *view_win;    Fl_Scroll *scroll;    err = 0; -  while ((c = getopt(argc, argv, "d:v:")) != EOF) { +  while ((c = getopt(argc, argv, "?d:v:sw:h:j:t:")) != EOF) {      switch (c) {   -    case 'h': +    case '?':        usage();        exit(0);        break; @@ -336,6 +354,23 @@ int main(int argc, char** argv) {      case 'v':        view_point = optarg;        break; +    case 's': +      stitch_flag++; +      break; +    case 'j': +      jpeg_flag++; +      outpath = optarg; +      break; +    case 't': +      tiff_flag++; +      outpath = optarg; +      break; +    case 'w': +      stitch_w = atoi(optarg); +      break; +    case 'h': +      stitch_h = atoi(optarg); +      break;      default:        err++;      } @@ -354,6 +389,17 @@ int main(int argc, char** argv) {      exit(1);    } +  if (stitch_flag) { +    int type = STITCH_PREVIEW; +    if (jpeg_flag) { +      type = STITCH_JPEG; +    } else if (tiff_flag) { +      type = STITCH_TIFF; +    } +    stitch(stitch_w, stitch_h, type, outpath, my_argc, my_argv); +    exit(0); +  } +    Fl::get_system_colors();    if (getenv("FLTK_SCHEME")) {      Fl::scheme(NULL); @@ -398,3 +444,48 @@ int main(int argc, char** argv) {    return Fl::run();  } + +static int stitch(int stitch_w, int stitch_h, int type, const char *path, int argc, char **argv) { +  Fl_Window *win; +  Fl_Scroll *scroll; +  Stitch *st = new Stitch(); + +  for (int i=0; i<argc; i++) { +    st->load_image(argv[i]); +  } +   +  if (type == STITCH_JPEG) { + +    st->set_output((OutputImage*) new JPEGOutputImage(path, 90)); +    st->resample(stitch_w, stitch_h, 0.0, 7.0); + +  } else if (type == STITCH_TIFF) { + +    for (int i=0; i<argc; i++) { +      char buf[1024]; +      char *dot; + +      snprintf(buf, sizeof(buf), "%s/%s", path, argv[i]); +      dot = strrchr(buf, '.'); +      *dot = '\0'; +      strncat(buf, ".tiff", sizeof(buf)); + +      st->set_output(argv[i], (OutputImage*) new TIFFOutputImage(buf)); +    } + +    st->resample(stitch_w, stitch_h, 0.0, 7.0); + +  } else { +    win = new Fl_Window(0,0, stitch_w, stitch_h); +    scroll = new Fl_Scroll(0, 0, win->w(), win->h()); +    PreviewOutputImage *img = new PreviewOutputImage(0, 0, stitch_w, stitch_h); +    win->resizable(scroll); +    win->show(0, argv);  +    st->set_output((OutputImage*) img); +    st->resample(stitch_w, stitch_h, 0.0, 7.0); +    img->redraw(); +    Fl::run(); +  } + +  return 0; +}  | 
