From b915f19001afa440234f270a9518cb62295b32b4 Mon Sep 17 00:00:00 2001 From: Johannes Hofmann Date: Wed, 3 Aug 2005 20:44:17 +0100 Subject: initial load/save support --- configure.ac | 1 + src/GipfelWidget.H | 5 +- src/GipfelWidget.cxx | 129 +++++++++++++++++++++++++++++++++++++++++++++++---- src/Makefile.am | 4 +- src/gipfel.cxx | 12 +++-- src/util.c | 76 ++++++++++++++++++++++++++++++ src/util.h | 39 ++++++++++++++++ 7 files changed, 251 insertions(+), 15 deletions(-) create mode 100644 src/util.c create mode 100644 src/util.h 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 #include +#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 +#include +#include + +#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 + +#ifdef __cplusplus +extern "C" { +#endif + +FILE * +pexecvp(const char *file, char *const argv[], pid_t *pid, char *type); + +#ifdef __cplusplus +} +#endif + +#endif -- cgit v1.2.3