summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--src/GipfelWidget.H5
-rw-r--r--src/GipfelWidget.cxx129
-rw-r--r--src/Makefile.am4
-rw-r--r--src/gipfel.cxx12
-rw-r--r--src/util.c76
-rw-r--r--src/util.h39
7 files changed, 251 insertions, 15 deletions
diff --git a/configure.ac b/configure.ac
index 121e507..08330d7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -13,6 +13,7 @@ LDFLAGS="-g $LDFLAGS"
# Checks for programs.
AC_PROG_CXX
+AC_PROG_CC
AC_LANG_CPLUSPLUS
diff --git a/src/GipfelWidget.H b/src/GipfelWidget.H
index c16c4a9..54252b6 100644
--- a/src/GipfelWidget.H
+++ b/src/GipfelWidget.H
@@ -35,6 +35,7 @@ class GipfelWidget : public Fl_Widget {
Hill *m1, *m2;
Panorama *pan;
Fl_Menu_Button *mb;
+ char *img_file;
int handle(int event);
@@ -52,7 +53,9 @@ class GipfelWidget : public Fl_Widget {
void menu_cb(Hill *hill);
- int load_image(const char *file);
+ int load_image(char *file);
+
+ int save_image(char *file);
int load_data(const char *file);
diff --git a/src/GipfelWidget.cxx b/src/GipfelWidget.cxx
index 802db90..8af751b 100644
--- a/src/GipfelWidget.cxx
+++ b/src/GipfelWidget.cxx
@@ -39,6 +39,7 @@
#include <FL/fl_draw.H>
#include <FL/x.H>
+#include "util.h"
#include "GipfelWidget.H"
static Fl_Menu_Item *menuitems;
@@ -56,6 +57,8 @@ GipfelWidget::GipfelWidget(int X,int Y,int W, int H): Fl_Widget(X, Y, W, H) {
marker = new Hills();
m1 = NULL;
m2 = NULL;
+ img_file = NULL;
+
for (i=0; i<=3; i++) {
marker->add(new Hill(i * 10, 0));
}
@@ -63,30 +66,141 @@ GipfelWidget::GipfelWidget(int X,int Y,int W, int H): Fl_Widget(X, Y, W, H) {
fl_register_images();
}
+#define GIPFEL_FORMAT "gipfel: longitude %lf, latitude %lf, height %lf, direction %lf, nick %lf, tilt %lf, scale %lf"
+
int
-GipfelWidget::load_image(const char *file) {
- img = new Fl_JPEG_Image(file);
+GipfelWidget::load_image(char *file) {
+ char * args[32];
+ FILE *p;
+ pid_t pid;
+ char buf[1024];
+ double lo, la, he, dir, ni, ti, sc;
+ int status;
+ Fl_Image *new_img;
+
+ new_img = new Fl_JPEG_Image(file);
- if (img == NULL) {
+ if (new_img == NULL) {
return 1;
}
+
+ if (img) {
+ delete img;
+ }
+
+ img = new_img;
- w(img->w());
- h(img->h());
+ if (img_file) {
+ free(img_file);
+ }
+
+ img_file = strdup(file);
+
+ h(img->h());
+ w(img->w());
mb = new Fl_Menu_Button(x(),y(),w()+x(),h()+y(),"&popup");
mb->type(Fl_Menu_Button::POPUP3);
mb->box(FL_NO_BOX);
mb->menu(menuitems);
+// try to retrieve gipfel data from JPEG comment section
+ args[0] = "rdjpgcom";
+ args[1] = file;
+ args[2] = NULL;
+
+ p = pexecvp(args[0], args, &pid, "r");
+
+ if (p) {
+ while (fgets(buf, sizeof(buf), p) != NULL) {
+ if (sscanf(buf, GIPFEL_FORMAT, &lo, &la, &he, &dir, &ni, &ti, &sc) == 7) {
+ set_view_long(lo);
+ set_view_lat(la);
+ set_view_height(he);
+ set_center_angle(dir);
+ set_nick_angle(ni);
+ set_tilt_angle(ti);
+ set_scale(sc);
+
+ break;
+ }
+ }
+ fclose(p);
+ waitpid(pid, &status, 0);
+ if (WEXITSTATUS(status) == 127 || WEXITSTATUS(status) == 126) {
+ fprintf(stderr, "%s not found\n", args[0]);
+ }
+ }
+
+ return 0;
+}
+
+int
+GipfelWidget::save_image(char *file) {
+ char * args[32];
+ FILE *p, *out;
+ pid_t pid;
+ char buf[1024];
+ int status;
+ size_t n;
+
+ if (img_file == NULL) {
+ fprintf(stderr, "Nothing to save\n");
+ return 1;
+ }
+
+ out = fopen(file, "w");
+ if (out == NULL) {
+ perror("fopen");
+ return 1;
+ }
+
+ snprintf(buf, sizeof(buf), GIPFEL_FORMAT,
+ get_view_long(),
+ get_view_lat(),
+ get_view_height(),
+ get_center_angle(),
+ get_nick_angle(),
+ get_tilt_angle(),
+ get_scale());
+
+// try to save gipfel data in JPEG comment section
+ args[0] = "wrjpgcom";
+ args[1] = "-replace";
+ args[2] = "-comment";
+ args[3] = buf;
+ args[4] = img_file;
+ args[5] = NULL;
+
+ p = pexecvp(args[0], args, &pid, "r");
+
+ if (p) {
+ while ((n = fread(buf, 1, sizeof(buf), p)) != 0) {
+ if (fwrite(buf, 1, n, out) != n) {
+ perror("fwrite");
+ fclose(out);
+ fclose(p);
+ waitpid(pid, &status, 0);
+ }
+ }
+ fclose(p);
+ waitpid(pid, &status, 0);
+ if (WEXITSTATUS(status) == 127 || WEXITSTATUS(status) == 126) {
+ fprintf(stderr, "%s not found\n", args[0]);
+ }
+ }
+
+ fclose(out);
return 0;
}
+
int
GipfelWidget::load_data(const char *file) {
int r;
r = pan->load_data(file);
+ set_labels(pan->get_visible_mountains());
update_menuitems(pan->get_close_mountains());
return r;
@@ -452,11 +566,8 @@ GipfelWidget::update_menuitems(Hills *h) {
void
GipfelWidget::set_height_dist_ratio(double r) {
- Hills *h;
-
pan->set_height_dist_ratio(r);
- h = pan->get_visible_mountains();
- set_labels(h);
+ set_labels(pan->get_visible_mountains());
update_menuitems(pan->get_close_mountains());
redraw();
diff --git a/src/Makefile.am b/src/Makefile.am
index 8c078fc..dc96e49 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2,6 +2,7 @@ bin_PROGRAMS = gipfel
gipfel_SOURCES = \
gipfel.cxx \
+ util.c \
GipfelWidget.cxx \
Panorama.cxx \
Hill.cxx \
@@ -11,4 +12,5 @@ noinst_HEADERS = \
GipfelWidget.H \
Panorama.H \
Hill.H \
- Fl_Value_Dial.H
+ Fl_Value_Dial.H \
+ util.h
diff --git a/src/gipfel.cxx b/src/gipfel.cxx
index 79199ec..19fcdeb 100644
--- a/src/gipfel.cxx
+++ b/src/gipfel.cxx
@@ -85,6 +85,11 @@ void track_cb() {
gipf->load_track(file);
}
+void save_cb() {
+ char *file = fl_file_chooser("Save Image As?", NULL, NULL);
+ gipf->save_image(file);
+}
+
void scale_cb(Fl_Slider* o, void*) {
if (gipf) {
gipf->set_scale(o->value());
@@ -156,6 +161,7 @@ void about_cb() {
Fl_Menu_Item menuitems[] = {
{ "&File", 0, 0, 0, FL_SUBMENU },
+ { "&Save Image", FL_CTRL + 's', (Fl_Callback *)save_cb, 0 },
{ "Load &Track", FL_CTRL + 't', (Fl_Callback *)track_cb, 0 },
{ "&Quit", FL_CTRL + 'q', (Fl_Callback *)quit_cb, 0 },
{0},
@@ -305,7 +311,7 @@ int main(int argc, char** argv) {
img_file = my_argv[0];
}
- if (data_file == NULL || view_point == NULL || img_file == NULL || err) {
+ if (data_file == NULL || img_file == NULL || err) {
usage();
exit(1);
}
@@ -316,15 +322,13 @@ int main(int argc, char** argv) {
view_win = new Fl_Window(800, 600);
scroll = new Fl_Scroll(0, 0, view_win->w(), view_win->h());
- gipf = new GipfelWidget(0,0,800,600);
-
+ gipf = new GipfelWidget(0,0,50,50);
gipf->load_image(img_file);
if (gipf->w() < 1024 && gipf->h() < 768) {
view_win->size(gipf->w(), gipf->h());
scroll->size(gipf->w(), gipf->h());
}
-
gipf->load_data(data_file);
if (view_point) {
gipf->set_viewpoint(view_point);
diff --git a/src/util.c b/src/util.c
new file mode 100644
index 0000000..f33c1b4
--- /dev/null
+++ b/src/util.c
@@ -0,0 +1,76 @@
+/*
+ * "$Id: util.c,v 1.1 2005/02/28 17:56:51 hofmann Exp $"
+ *
+ * flpsed program.
+ *
+ * Copyright 2005 by Johannes Hofmann
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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 <unistd.h>
+
+#include "util.h"
+
+FILE *
+pexecvp(const char *file, char *const argv[], pid_t *pid, char *type) {
+ FILE *iop;
+ int pdes[2];
+
+ if (pipe(pdes) < 0) {
+ return NULL;
+ }
+
+ *pid = vfork();
+
+ if (*pid == -1) {
+ perror("vfork");
+ close(pdes[0]);
+ close(pdes[1]);
+ return NULL;
+ } else if (*pid == 0) {
+ /* child */
+
+ if (*type == 'r') {
+ close(pdes[0]);
+ if (pdes[1] != STDOUT_FILENO) {
+ dup2(pdes[1], STDOUT_FILENO);
+ close(pdes[1]);
+ }
+ } else {
+ close(pdes[1]);
+ if (pdes[0] != STDIN_FILENO) {
+ dup2(pdes[0], STDIN_FILENO);
+ close(pdes[0]);
+ }
+ }
+
+ execvp(file, argv);
+ exit(127);
+ } else {
+ /* parent */
+ if (*type == 'r') {
+ iop = fdopen(pdes[0], "r");
+ close(pdes[1]);
+ } else {
+ iop = fdopen(pdes[1], "w");
+ close(pdes[0]);
+ }
+ return iop;
+ }
+}
diff --git a/src/util.h b/src/util.h
new file mode 100644
index 0000000..d5a71e1
--- /dev/null
+++ b/src/util.h
@@ -0,0 +1,39 @@
+/*
+ * "$Id: util.h,v 1.2 2005/03/17 18:46:20 hofmann Exp $"
+ *
+ * flpsed program.
+ *
+ * Copyright 2005 by Johannes Hofmann
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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 _UTIL_H_
+#define _UTIL_H_
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+FILE *
+pexecvp(const char *file, char *const argv[], pid_t *pid, char *type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif