1
#ifndef __PIXIE_INTERPOLATE_H
2
#define __PIXIE_INTERPOLATE_H
5
Copyright (C) 2005, 2007 Daniel M. Duley <daniel.duley@verizon.net>
7
Redistribution and use in source and binary forms, with or without
8
modification, are permitted provided that the following conditions
11
1. Redistributions of source code must retain the above copyright
12
notice, this list of conditions and the following disclaimer.
13
2. Redistributions in binary form must reproduce the above copyright
14
notice, this list of conditions and the following disclaimer in the
15
documentation and/or other materials provided with the distribution.
17
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
* Performs interpolation between a pixel's colors and it's neighbors.
36
* Handles 32bpp and 8bpp source images transparently.
38
* @short Inline interpolation
39
* @author Daniel M. Duley
41
class InlineInterpolate
45
* Constructs an interpolation object. Do this outside your main loop then
46
* call the inline interpolate methods when you need them.
48
* @param image The image whose pixels you will be interpolating. Once
49
* you have created an interpolation object you can change the image's
50
* pixel data, but do not resize or reset it.
51
* @param background The background color to use if a pixel's neighbor
52
* is off the edge of the image.
54
InlineInterpolate(QImage *image, unsigned int background){
55
img = image; ptr = img->bits();
56
colorTable = img->colorTable();
57
w=img->width(); h=img->height();
58
bg=background; truecolor = img->depth() > 8;
61
* Interpolates the pixel at the given x,y position. If the pixel's
62
* neighbor is off the edge of the image the last pixel is extended.
64
inline unsigned int interpolate(float x_offset, float y_offset);
66
* Interpolates the pixel at the given x,y position. If the pixel's
67
* neighbor is off the edge of the image the background color is used.
69
inline unsigned int interpolateBackground(float x_offset, float y_offset);
72
unsigned int p, q, r, s, bg;
74
QVector<QRgb> colorTable;
79
inline unsigned int InlineInterpolate::interpolate(float x_offset,
82
int x = qBound(0, (int)x_offset, w-2);
83
int y = qBound(0, (int)y_offset, h-2);
86
p = *(((QRgb *)ptr)+(y*w)+x);
87
q = *(((QRgb *)ptr)+(y*w)+x+1);
88
r = *(((QRgb *)ptr)+((y+1)*w)+x);
89
s = *(((QRgb *)ptr)+((y+1)*w)+x+1);
92
p = colorTable[*(ptr+(y*w)+x)];
93
q = colorTable[*(ptr+(y*w)+x+1)];
94
r = colorTable[*(ptr+((y+1)*w)+x)];
95
s = colorTable[*(ptr+((y+1)*w)+x+1)];
97
x_offset -= std::floor(x_offset); y_offset -= std::floor(y_offset);
98
unsigned int alpha = (unsigned int)(255*x_offset);
99
unsigned int beta = (unsigned int)(255*y_offset);
101
p = BlitzPrivate::interpolate255(p, 255-alpha, q, alpha);
102
r = BlitzPrivate::interpolate255(r, 255-alpha, s, alpha);
103
return(BlitzPrivate::interpolate255(p, 255-beta, r, beta));
106
inline unsigned int InlineInterpolate::interpolateBackground(float x_offset,
109
int x = (int)x_offset;
110
int y = (int)y_offset;
114
if(y >= 0 && y < h && x >= 0 && x < w){
115
p = *(((QRgb *)ptr)+(y*w)+x);
116
if(y+1 < h) r = *(((QRgb *)ptr)+((y+1)*w)+x);
118
q = *(((QRgb *)ptr)+(y*w)+x+1);
119
if(y+1 < h) q = *(((QRgb *)ptr)+((y+1)*w)+x+1);
124
if(y >= 0 && y < h && x >= 0 && x < w){
125
p = colorTable[*(ptr+(y*w)+x)];
126
if(y+1 < h) r = colorTable[*(ptr+((y+1)*w)+x)];
128
q = colorTable[*(ptr+(y*w)+x+1)];
129
if(y+1 < h) s = colorTable[*(ptr+((y+1)*w)+x+1)];
133
x_offset -= std::floor(x_offset); y_offset -= std::floor(y_offset);
134
unsigned int alpha = (unsigned int)(255*x_offset);
135
unsigned int beta = (unsigned int)(255*y_offset);
137
p = BlitzPrivate::interpolate255(p, 255-alpha, q, alpha);
138
r = BlitzPrivate::interpolate255(r, 255-alpha, s, alpha);
139
return(BlitzPrivate::interpolate255(p, 255-beta, r, beta));