diff options
-rw-r--r-- | NEWS | 8 | ||||
-rw-r--r-- | README | 9 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | gipfel.dat | 4 | ||||
-rw-r--r-- | gipfel.spec | 12 | ||||
-rw-r--r-- | src/GipfelWidget.H | 9 | ||||
-rw-r--r-- | src/GipfelWidget.cxx | 126 | ||||
-rw-r--r-- | src/Hill.cxx | 8 | ||||
-rw-r--r-- | src/ImageMetaData.cxx | 6 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/ScanImage.H | 31 | ||||
-rw-r--r-- | src/ScanImage.cxx | 118 | ||||
-rw-r--r-- | src/Stitch.H | 3 | ||||
-rw-r--r-- | src/Stitch.cxx | 2 | ||||
-rw-r--r-- | src/gipfel.cxx | 18 |
15 files changed, 222 insertions, 138 deletions
@@ -1,6 +1,14 @@ gipfel ChangeLog ================= +gipfel-0.3.2 +* Fix 16bit tiff output in stitching mode. +* Don't draw labels of mountains that are slightly off the image. +* Factored out ScanImage class. + +gipfel-0.3.1 +* Fix compile error and warnings on Linux. + gipfel-0.3.0 * Use exiv2 library for image metadata reading and writing. (initial patch by Konrad Golling). @@ -1,6 +1,8 @@ gipfel ====== +[homepage](http://www.ecademix.com/JohannesHofmann) + Description ----------- __gipfel__ helps to find the names of mountains or points of interest @@ -35,6 +37,11 @@ Installation ------------ Unpack the tar file and run `./configure; make; make install` +Donations +--------- +If you like gipfel please consider to make a donation at my +[homepage](http://www.ecademix.com/JohannesHofmann). + Running ------- To start gipfel, enter @@ -48,7 +55,7 @@ Additionally a "Choose Viewpoint" window should pop up, where you can search for the viewpoint from which the picture was taken. Select a viewpoint and click "Ok". Alternatively, you can enter the GPS coordinate of the viewpoint directly in -the control window. +the control window (hit <Enter> for every data field). You can now use the controls in the control window to modify the view parameters. These are: * View direction diff --git a/configure.ac b/configure.ac index 62a4c65..beedc4b 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.3.0, Johannes.Hofmann@gmx.de) +AC_INIT(gipfel, 0.3.1, Johannes.Hofmann@gmx.de) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([src/Panorama.H]) AC_CONFIG_HEADER(config.h) @@ -34,7 +34,7 @@ AC_FUNC_FORK AC_FUNC_MALLOC AC_FUNC_REALLOC AC_TYPE_SIGNAL -AC_CHECK_FUNCS([strchr strdup strrchr strstr mkstemp fsync]) +AC_CHECK_FUNCS([strchr strdup strrchr strstr mkstemp fsync strsep]) # Check for fltk AC_PATH_PROG(FLTKCONFIG,fltk-config) @@ -2,6 +2,10 @@ # http://www.viewfinderpanoramas.org/ (Alps) and # http://www.alpin-koordinaten.de/ (Nepal) # +# local additions +# +loc_1,PARSEIERSPITZE,,47.174257,10.478691,3036 +# # Thu Feb 26 12:00:46 CET 2009 # and is included in the gipfel tarball with the kind permission of # Jonathan de Ferranti and www.alpin-koordinaten.de diff --git a/gipfel.spec b/gipfel.spec index 2dead57..493cab3 100644 --- a/gipfel.spec +++ b/gipfel.spec @@ -1,6 +1,6 @@ Name: gipfel Summary: gipfel - Photogrammetry For Mountain Images -Version: 0.3.0 +Version: 0.3.1 Release: 3.1 URL: http://www.ecademix.com/JohannesHofmann/gipfel.html BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -8,7 +8,13 @@ Source0: %{name}-%{version}.tar.gz License: GPL Group: Productivity/Scientific/Other -BuildRequires: binutils gcc gcc-c++ libstdc++-devel gsl-devel fltk-devel libjpeg-devel libtiff-devel libpng-devel exiv2-devel +BuildRequires: binutils gcc gcc-c++ libstdc++-devel gsl-devel fltk-devel libjpeg-devel libtiff-devel libpng-devel + +%if 0%{?fedora_version} +BuildRequires: exiv2-devel +%else +BuildRequires: libexiv2-devel +%endif %if 0%{?suse_version} BuildRequires: xorg-x11-libXext-devel @@ -39,7 +45,7 @@ rm -rf $RPM_BUILD_ROOT/%{_defaultdocdir}/%{name} %changelog * Tue Apr 7 2009 Johannes Hofmann <Johannes.Hofmann@gmx.de> -- update to gipfel-0.3.0 +- update to gipfel-0.3.1 * Thu Mar 26 2009 Johannes Hofmann <Johannes.Hofmann@gmx.de> - update to gipfel-0.2.9 * Sun Mar 22 2009 Johannes Hofmann <Johannes.Hofmann@gmx.de> diff --git a/src/GipfelWidget.H b/src/GipfelWidget.H index 24d0bb6..2e440c5 100644 --- a/src/GipfelWidget.H +++ b/src/GipfelWidget.H @@ -14,6 +14,7 @@ #include "Panorama.H" #include "ImageMetaData.H" +#include "ScanImage.H" class GipfelWidget : public Fl_Group { private: @@ -37,12 +38,6 @@ class GipfelWidget : public Fl_Group { void set_labels(Hills *v); int get_rel_track_width(Hill *m); - static int get_pixel_nearest(Fl_Image *img, double x, double y, - int *r, int *g, int *b); - static int get_pixel_bicubic(Fl_Image *img, double x, double y, - int *r, int *g, int *b); - static int get_pixel(Fl_Image *img, int x, int y, - int *r, int *g, int *b); static void find_peak_cb(Fl_Widget *o, void *f); public: @@ -91,7 +86,7 @@ class GipfelWidget : public Fl_Group { void set_distortion_params(double k0, double k1, double x0); Hills *get_mountains() { return pan->get_mountains(); }; int comp_params(); - int get_pixel(GipfelWidget::sample_mode_t, + int get_pixel(ScanImage::mode_t m, double a_alph, double a_nick, int *r, int *g, int *b); int get_distortion_profile_name(char *buf, int buflen); int save_distortion_params(const char *prof_name, int force); diff --git a/src/GipfelWidget.cxx b/src/GipfelWidget.cxx index 91a9dc5..7e9f6fc 100644 --- a/src/GipfelWidget.cxx +++ b/src/GipfelWidget.cxx @@ -22,6 +22,7 @@ #include "Fl_Search_Chooser.H" #include "choose_hill.H" +#include "ScanImage.H" #include "GipfelWidget.H" #define CROSS_SIZE 2 @@ -245,6 +246,9 @@ GipfelWidget::draw() { known_hills->contains(m) || m == focused_mountain) continue; + if (fabs(m->x) > img->w() / 2 || fabs(m->y) > img->h() / 2) + continue; + fl_xyline(m_x - CROSS_SIZE, m_y, m_x + CROSS_SIZE); fl_yxline(m_x, m_y + m->label_y - height, m_y + CROSS_SIZE); fl_xyline(m_x, m_y + m->label_y - height, m_x + m->label_x); @@ -259,6 +263,9 @@ GipfelWidget::draw() { (!show_hidden && (m->flags & Hill::HIDDEN)) || m == focused_mountain) continue; + if (fabs(m->x) > img->w() / 2 || fabs(m->y) > img->h() / 2) + continue; + if (known_hills->contains(m)) { if (known_hills->get_num() > 3) fl_color(FL_GREEN); @@ -298,16 +305,16 @@ GipfelWidget::draw() { m = track_points->get(i); int m_x = w() / 2 + x() + (int) rint(m->x); int m_y = h() / 2 + y() + (int) rint(m->y); - if (!(track_points->get(i)->flags & Hill::VISIBLE)) { + + if (!(track_points->get(i)->flags & Hill::VISIBLE)) continue; - } if (track_points->get(i)->flags & Hill::HIDDEN) fl_color(FL_BLUE); else fl_color(FL_RED); - fl_line_style(FL_SOLID|FL_CAP_ROUND|FL_JOIN_ROUND, + fl_line_style(FL_SOLID | FL_CAP_ROUND | FL_JOIN_ROUND, get_rel_track_width(track_points->get(i))); if (last_initialized) { fl_begin_line(); @@ -348,6 +355,9 @@ GipfelWidget::set_labels(Hills *v) { if (!show_hidden && (m->flags & Hill::HIDDEN)) continue; + if (fabs(m->x) > img->w() / 2 || fabs(m->y) > img->h() / 2) + continue; + m->label_x = (int) fl_width(m->name) + 1; m->label_y = 0; @@ -360,6 +370,9 @@ GipfelWidget::set_labels(Hills *v) { if (!show_hidden && (n->flags & Hill::HIDDEN)) continue; + if (fabs(m->x) > img->w() / 2 || fabs(m->y) > img->h() / 2) + continue; + if (overlap(m->x, m->label_x, n->x - CROSS_SIZE, n->label_x)) colliding.add(n); else @@ -707,7 +720,7 @@ GipfelWidget::export_hills(const char *file, FILE *fp) { } int -GipfelWidget::get_pixel(GipfelWidget::sample_mode_t m, +GipfelWidget::get_pixel(ScanImage::mode_t m, double a_alph, double a_nick, int *r, int *g, int *b) { double px, py; int ret; @@ -718,114 +731,13 @@ GipfelWidget::get_pixel(GipfelWidget::sample_mode_t m, if (pan->get_coordinates(a_alph, a_nick, &px, &py) != 0) return 1; - if (m == GipfelWidget::BICUBIC) - ret = get_pixel_bicubic(img, px + ((double) img->w()) / 2.0, - py + ((double) img->h()) / 2.0, r, g, b); - else - ret = get_pixel_nearest(img, px + ((double) img->w()) / 2.0, - py + ((double) img->h()) / 2.0, r, g, b); + ret = ScanImage::get_pixel(img, m, px + ((double) img->w()) / 2.0, + py + ((double) img->h()) / 2.0, r, g, b); return ret; } int -GipfelWidget::get_pixel_nearest(Fl_Image *img, double x, double y, - int *r, int *g, int *b) { - - if (isnan(x) || isnan(y)) - return 1; - else - return get_pixel(img, (int) rint(x), (int) rint(y), r, g, b); -} - -static inline double -interp_cubic(double x, double x2, double x3, double *v) { - double a0, a1, a2, a3; - - a0 = v[3] - v[2] - v[0] + v[1]; - a1 = v[0] - v[1] - a0; - a2 = v[2] - v[0]; - a3 = v[1]; - - return a0 * x3 + a1 * x2 + a2 * x + a3; -} - -int -GipfelWidget::get_pixel_bicubic(Fl_Image *img, double x, double y, - int *r, int *g, int *b) { - - double fl_x = floor(x); - double fl_y = floor(y); - double dx = x - fl_x, dx2 = dx * dx, dx3 = dx2 * dx; - double dy = y - fl_y, dy2 = dy * dy, dy3 = dy2 * dy; - int ic[3]; - double c[3][4]; - double c1[3][4]; - - for (int iy = 0; iy < 4; iy++) { - for (int ix = 0; ix < 4; ix++) { - - if (get_pixel(img, (int) fl_x + ix - 1, (int) fl_y + iy - 1, - &ic[0], &ic[1], &ic[2]) != 0) - return 1; - - for (int l = 0; l < 3; l++) - c[l][ix] = (double) ic[l]; - } - - for (int l = 0; l < 3; l++) - c1[l][iy] = interp_cubic(dx, dx2, dx3, c[l]); - } - - *r = (int) rint(interp_cubic(dy, dy2, dy3, c1[0])); - *g = (int) rint(interp_cubic(dy, dy2, dy3, c1[1])); - *b = (int) rint(interp_cubic(dy, dy2, dy3, c1[2])); - return 0; -} - -int -GipfelWidget::get_pixel(Fl_Image *img, int x, int y, - int *r, int *g, int *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 unsigned char *buf = (const unsigned char*) img->data()[0]; - switch (img->d()) - { - case 1: - *r = *g = *b = *(buf+index); - break; - case 3: // 24bit - *r = (int) *(buf+index+0); - *g = (int) *(buf+index+1); - *b = (int) *(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; - } - - *r = *r * 255; - *g = *g * 255; - *b = *b * 255; - - return 0; -} - -int GipfelWidget::get_distortion_profile_name(char *buf, int buflen) { int n; diff --git a/src/Hill.cxx b/src/Hill.cxx index 3b1c6bd..b059897 100644 --- a/src/Hill.cxx +++ b/src/Hill.cxx @@ -132,13 +132,13 @@ void Hills::mark_duplicates(double dist) { sort(SORT_PHI); - for(i=0; i<get_num();i++) { + for(i = 0; i < get_num(); i++) { m = get(i); - if (m->flags & Hill::TRACK_POINT) - continue; - if (m) { + if (m->flags & Hill::TRACK_POINT) + continue; + j = i + 1; n = get(j); while (n && fabs(n->phi - m->phi) <= dist) { diff --git a/src/ImageMetaData.cxx b/src/ImageMetaData.cxx index b738b4d..03886b3 100644 --- a/src/ImageMetaData.cxx +++ b/src/ImageMetaData.cxx @@ -108,7 +108,7 @@ ImageMetaData::load_image_exif(char *name) { image = Exiv2::ImageFactory::open(name); image->readMetadata(); } catch (Exiv2::Error error) { - fprintf(stderr, "Error reading metadata (%s)\n", error.what()); + fprintf(stderr, "Error reading metadata\n"); return 1; } @@ -166,7 +166,7 @@ ImageMetaData::load_image_jpgcom(char *name) { image = Exiv2::ImageFactory::open(name); image->readMetadata(); } catch (Exiv2::Error error) { - fprintf(stderr, "Error reading metadata (%s)\n", error.what()); + fprintf(stderr, "Error reading metadata\n"); return 1; } @@ -258,7 +258,7 @@ ImageMetaData::save_image_jpgcom(char *in_img, char *out_img) { try { image->writeMetadata(); } catch (Exiv2::Error error) { - fprintf(stderr, "Error writing metadata (%s)\n", error.what()); + fprintf(stderr, "Error writing metadata\n"); err++; } diff --git a/src/Makefile.am b/src/Makefile.am index a9fe688..3d4a174 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,6 +18,7 @@ gipfel_SOURCES = \ PreviewOutputImage.cxx \ ImageMetaData.cxx \ ScreenDump.cxx \ + ScanImage.cxx \ strsep.c noinst_HEADERS = \ @@ -40,4 +41,5 @@ noinst_HEADERS = \ PreviewOutputImage.H \ ImageMetaData.H \ ScreenDump.H \ + ScanImage.H \ strsep.h diff --git a/src/ScanImage.H b/src/ScanImage.H new file mode 100644 index 0000000..e318273 --- /dev/null +++ b/src/ScanImage.H @@ -0,0 +1,31 @@ +// +// Copyright 2006 Johannes Hofmann <Johannes.Hofmann@gmx.de> +// +// This software may be used and distributed according to the terms +// of the GNU General Public License, incorporated herein by reference. + +#ifndef ScanImage_H +#define ScanImage_H + +#include <FL/Fl_Image.H> + +class ScanImage { + private: + static int get_pixel_nearest(Fl_Image *img, double x, double y, + int *r, int *g, int *b); + static int get_pixel_bicubic(Fl_Image *img, double x, double y, + int *r, int *g, int *b); + static int get_pixel(Fl_Image *img, int x, int y, + int *r, int *g, int *b); + + public: + typedef enum { + NEAREST = 0, + BICUBIC = 1 + } mode_t; + + static int get_pixel(Fl_Image *img, mode_t mode, + double x, double y, int *r, int *g, int *b); +}; + +#endif diff --git a/src/ScanImage.cxx b/src/ScanImage.cxx new file mode 100644 index 0000000..747da36 --- /dev/null +++ b/src/ScanImage.cxx @@ -0,0 +1,118 @@ +// +// Copyright 2007-2009 Johannes Hofmann <Johannes.Hofmann@gmx.de> +// +// This software may be used and distributed according to the terms +// of the GNU General Public License, incorporated herein by reference. + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> + +#include <Fl/Fl_Image.H> +#include "ScanImage.H" + +int +ScanImage::get_pixel(Fl_Image *img, mode_t mode, + double x, double y, int *r, int *g, int *b) { + if (mode == BICUBIC) + return get_pixel_bicubic(img, x, y, r, g, b); + else + return get_pixel_nearest(img, x, y, r, g, b); +} + +int +ScanImage::get_pixel_nearest(Fl_Image *img, double x, double y, + int *r, int *g, int *b) { + + if (isnan(x) || isnan(y)) + return 1; + else + return get_pixel(img, (int) rint(x), (int) rint(y), r, g, b); +} + +static inline double +interp_cubic(double x, double x2, double x3, double *v) { + double a0, a1, a2, a3; + + a0 = v[3] - v[2] - v[0] + v[1]; + a1 = v[0] - v[1] - a0; + a2 = v[2] - v[0]; + a3 = v[1]; + + return a0 * x3 + a1 * x2 + a2 * x + a3; +} + +int +ScanImage::get_pixel_bicubic(Fl_Image *img, double x, double y, + int *r, int *g, int *b) { + + double fl_x = floor(x); + double fl_y = floor(y); + double dx = x - fl_x, dx2 = dx * dx, dx3 = dx2 * dx; + double dy = y - fl_y, dy2 = dy * dy, dy3 = dy2 * dy; + int ic[3]; + double c[3][4]; + double c1[3][4]; + + for (int iy = 0; iy < 4; iy++) { + for (int ix = 0; ix < 4; ix++) { + + if (get_pixel(img, (int) fl_x + ix - 1, (int) fl_y + iy - 1, + &ic[0], &ic[1], &ic[2]) != 0) + return 1; + + for (int l = 0; l < 3; l++) + c[l][ix] = (double) ic[l]; + } + + for (int l = 0; l < 3; l++) + c1[l][iy] = interp_cubic(dx, dx2, dx3, c[l]); + } + + *r = (int) rint(interp_cubic(dy, dy2, dy3, c1[0])); + *g = (int) rint(interp_cubic(dy, dy2, dy3, c1[1])); + *b = (int) rint(interp_cubic(dy, dy2, dy3, c1[2])); + return 0; +} + +int +ScanImage::get_pixel(Fl_Image *img, int x, int y, + int *r, int *g, int *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 unsigned char *buf = (const unsigned char*) img->data()[0]; + switch (img->d()) + { + case 1: + *r = *g = *b = *(buf+index); + break; + case 3: // 24bit + *r = (int) *(buf+index+0); + *g = (int) *(buf+index+1); + *b = (int) *(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; + } + + *r = *r * 255; + *g = *g * 255; + *b = *b * 255; + + return 0; +} diff --git a/src/Stitch.H b/src/Stitch.H index 20087ab..7c9a60e 100644 --- a/src/Stitch.H +++ b/src/Stitch.H @@ -9,6 +9,7 @@ #include "GipfelWidget.H" #include "OutputImage.H" +#include "ScanImage.H" #define MAX_PICS 256 @@ -24,7 +25,7 @@ class Stitch { int load_image(char *file); OutputImage * set_output(OutputImage *img); - int resample(GipfelWidget::sample_mode_t m, + int resample(ScanImage::mode_t m, int w, int h, double view_start, double view_end); }; diff --git a/src/Stitch.cxx b/src/Stitch.cxx index 8a1b429..eeb4562 100644 --- a/src/Stitch.cxx +++ b/src/Stitch.cxx @@ -64,7 +64,7 @@ Stitch::set_output(OutputImage *img) { } int -Stitch::resample(GipfelWidget::sample_mode_t m, +Stitch::resample(ScanImage::mode_t m, int w, int h, double view_start, double view_end) { view_start = view_start * deg2rad; diff --git a/src/gipfel.cxx b/src/gipfel.cxx index 1e038d2..8add46a 100644 --- a/src/gipfel.cxx +++ b/src/gipfel.cxx @@ -65,7 +65,7 @@ static Fl_Menu_Bar *mb; #define STITCH_JPEG 2 #define STITCH_TIFF 4 -static int stitch(GipfelWidget::sample_mode_t m , int b_16, +static int stitch(ScanImage::mode_t m , int b_16, int stitch_w, int stitch_h, double from, double to, int type, const char *path, int argc, char **argv); @@ -129,12 +129,11 @@ void set_values() { } void quit_cb() { + if (Fl::event() == FL_SHORTCUT && Fl::event_key() == FL_Escape) + return; // ignore Escape exit(0); } -void dummy_cb() { -} - void open_cb() { char *file = fl_file_chooser("Open File?", "*.jpg", img_file); if (file) { @@ -286,6 +285,7 @@ void about_cb() { fl_message("gipfel -- Photogrammetry for Mountain Images.\n" "Version %s\n\n" "(c) Johannes Hofmann 2006-2009\n\n" + "Homepage: http://www.ecademix.com/JohannesHofmann\n\n" "Default datafile from http://www.viewfinderpanoramas.org/ and\n" "http://www.alpin-koordinaten.de\n", VERSION); @@ -602,7 +602,7 @@ int main(int argc, char** argv) { type = STITCH_PREVIEW; } - return stitch(bicubic_flag?GipfelWidget::BICUBIC:GipfelWidget::NEAREST, + return stitch(bicubic_flag ? ScanImage::BICUBIC : ScanImage::NEAREST, b_16_flag, stitch_w, stitch_h, stitch_from, stitch_to, type, outpath, my_argc, my_argv); @@ -620,10 +620,10 @@ int main(int argc, char** argv) { Fl::scheme("plastic"); control_win = create_control_window(); - control_win->callback((Fl_Callback*) dummy_cb); + control_win->callback((Fl_Callback*) quit_cb); view_win = new Fl_Window(800, 600); - view_win->callback((Fl_Callback*) dummy_cb); + view_win->callback((Fl_Callback*) quit_cb); // The Fl_Group is used to avoid FL_DAMAGE_ALL in Fl_Scroll::position Fl_Group *g = new Fl_Group(0, 0, view_win->w(), view_win->h()); @@ -667,7 +667,7 @@ int main(int argc, char** argv) { } static int -stitch(GipfelWidget::sample_mode_t m, int b_16, +stitch(ScanImage::mode_t m, int b_16, int stitch_w, int stitch_h, double from, double to, int type, const char *path, int argc, char **argv) { @@ -685,7 +685,7 @@ stitch(GipfelWidget::sample_mode_t m, int b_16, } else if (type & STITCH_TIFF) { - st->set_output(new TIFFOutputImage(path, 90)); + st->set_output(new TIFFOutputImage(path, b_16 ? 16 : 8)); st->resample(m, stitch_w, stitch_h, from, to); } else { |