From df5384ff38ee2c62cf9f038a7d4b8c5b6e7e62b2 Mon Sep 17 00:00:00 2001 From: Johannes Hofmann Date: Wed, 20 May 2009 09:49:16 +0200 Subject: factor out ScanImage class --- src/GipfelWidget.H | 9 +--- src/GipfelWidget.cxx | 108 ++-------------------------------------------- src/Makefile.am | 2 + src/ScanImage.H | 31 ++++++++++++++ src/ScanImage.cxx | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/Stitch.H | 3 +- src/Stitch.cxx | 2 +- src/gipfel.cxx | 6 +-- 8 files changed, 163 insertions(+), 116 deletions(-) create mode 100644 src/ScanImage.H create mode 100644 src/ScanImage.cxx (limited to 'src') 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 19be5ae..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 @@ -719,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; @@ -730,113 +731,12 @@ 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/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 +// +// 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 + +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 +// +// This software may be used and distributed according to the terms +// of the GNU General Public License, incorporated herein by reference. + +#include +#include +#include + +#include +#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 4fbf26f..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); @@ -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); @@ -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) { -- cgit v1.2.3