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/ScanImage.cxx | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 src/ScanImage.cxx (limited to 'src/ScanImage.cxx') 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; +} -- cgit v1.2.3