diff options
| -rw-r--r-- | src/GipfelWidget.H | 9 | ||||
| -rw-r--r-- | src/GipfelWidget.cxx | 108 | ||||
| -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 | 6 | 
8 files changed, 163 insertions, 116 deletions
| 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,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/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 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) { | 
