~ubuntu-branches/ubuntu/feisty/qimageblitz/feisty-backports

« back to all changes in this revision

Viewing changes to blitz/private/interpolate.h

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2007-08-31 09:50:41 UTC
  • Revision ID: james.westby@ubuntu.com-20070831095041-rlguoifpqerdrs2o
Tags: upstream-0.0.706674
ImportĀ upstreamĀ versionĀ 0.0.706674

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef __PIXIE_INTERPOLATE_H
 
2
#define __PIXIE_INTERPOLATE_H
 
3
 
 
4
/*
 
5
 Copyright (C) 2005, 2007 Daniel M. Duley <daniel.duley@verizon.net>
 
6
 
 
7
Redistribution and use in source and binary forms, with or without
 
8
modification, are permitted provided that the following conditions
 
9
are met:
 
10
 
 
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.
 
16
 
 
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.
 
27
 
 
28
*/
 
29
 
 
30
#include <QImage>
 
31
#include <QVector>
 
32
#include <cmath>
 
33
 
 
34
/**
 
35
 * Performs interpolation between a pixel's colors and it's neighbors.
 
36
 * Handles 32bpp and 8bpp source images transparently.
 
37
 *
 
38
 * @short Inline interpolation
 
39
 * @author Daniel M. Duley
 
40
 */ 
 
41
class InlineInterpolate
 
42
{
 
43
public:
 
44
    /**
 
45
     * Constructs an interpolation object. Do this outside your main loop then
 
46
     * call the inline interpolate methods when you need them.
 
47
     *
 
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.
 
53
     */
 
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;
 
59
    }
 
60
    /**
 
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.
 
63
     */
 
64
    inline unsigned int interpolate(float x_offset, float y_offset);
 
65
    /**
 
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.
 
68
     */
 
69
    inline unsigned int interpolateBackground(float x_offset, float y_offset);
 
70
private:
 
71
    int w, h;
 
72
    unsigned int p, q, r, s, bg;
 
73
    unsigned char *ptr;
 
74
    QVector<QRgb> colorTable;
 
75
    bool truecolor;
 
76
    QImage *img;
 
77
};
 
78
 
 
79
inline unsigned int InlineInterpolate::interpolate(float x_offset,
 
80
                                                   float y_offset)
 
81
{
 
82
    int x = qBound(0, (int)x_offset, w-2);
 
83
    int y = qBound(0, (int)y_offset, h-2);
 
84
 
 
85
    if(truecolor){
 
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);
 
90
    }
 
91
    else{
 
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)];
 
96
    }
 
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);
 
100
 
 
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));
 
104
}
 
105
 
 
106
inline unsigned int InlineInterpolate::interpolateBackground(float x_offset,
 
107
                                                             float y_offset)
 
108
{
 
109
    int x = (int)x_offset;
 
110
    int y = (int)y_offset;
 
111
    p = q = r = s = bg;
 
112
 
 
113
    if(truecolor){
 
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);
 
117
            if(x+1 < w){
 
118
                q = *(((QRgb *)ptr)+(y*w)+x+1);
 
119
                if(y+1 < h) q = *(((QRgb *)ptr)+((y+1)*w)+x+1);
 
120
            }
 
121
        }
 
122
    }
 
123
    else{
 
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)];
 
127
            if(x+1 < w){
 
128
                q = colorTable[*(ptr+(y*w)+x+1)];
 
129
                if(y+1 < h) s = colorTable[*(ptr+((y+1)*w)+x+1)];
 
130
            }
 
131
        }
 
132
    }
 
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);
 
136
 
 
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));
 
140
}
 
141
 
 
142
#endif
 
143