1 // Copyright 2002, 2003, 2004 David Hilvert <dhilvert@auricle.dyndns.org>,
2 // <dhilvert@ugcs.caltech.edu>
4 /* This file is part of the Anti-Lamenessing Engine.
6 The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 The Anti-Lamenessing Engine is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with the Anti-Lamenessing Engine; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * zero_image.h: Image that is zero everywhere.
25 #ifndef __image_zero_h__
26 #define __image_zero_h__
30 #include "exposure/exposure.h"
32 class image_zero
: public image_weighted_avg
{
35 spixel
get_pixel(unsigned int y
, unsigned int x
) const {
39 void set_pixel(unsigned int y
, unsigned int x
, spixel p
) {
43 void set_chan(unsigned int y
, unsigned int x
, unsigned int k
, ale_sreal c
) {
47 ale_sreal
get_chan(unsigned int y
, unsigned int x
, unsigned int k
) const {
51 ale_real
maxval() const {
55 ale_real
minval() const {
60 * Get a color value at a given position using bilinear interpolation between the
61 * four nearest pixels. Result values:
63 * result[0] == pixel value
64 * result[1] == pixel confidence
66 void get_bl(point x
, pixel result
[2]) const {
67 result
[0] = pixel::zero();
68 result
[1] = pixel::zero();
71 pixel
get_bl(point x
) const {
79 pixel
get_scaled_bl(point x
, ale_pos f
) const {
85 * Make a new image suitable for receiving scaled values.
87 virtual image
*scale_generator(int height
, int width
, int depth
, const char *name
) const {
89 image
*is
= new image_zero(height
, width
, depth
, name
);
97 * Return an image scaled by some factor >= 1.0
99 image
*scale(ale_pos f
, const char *name
) const {
101 image
*is
= new image_zero(
102 (int) floor(height() * f
),
103 (int) floor(width() * f
), depth());
111 * Scale by half. We use the following filter:
117 * At the edges, these values are normalized so that the sum of
118 * contributing pixels is 1.
120 image
*scale_by_half(const char *name
) const {
123 image
*result
= new image_zero(
124 (int) floor(height() * f
),
125 (int) floor(width() * f
), depth());
133 * Scale an image definition array by 1/2.
135 * ALE considers an image definition array as a special kind of image
136 * weight array (typedefs of which should appear below the definition
137 * of this class). ALE uses nonzero pixel values to mean 'defined' and
138 * zero values to mean 'undefined'. Through this interpretation, the
139 * image weight array implementation that ALE uses allows image weight
140 * arrays to also serve as image definition arrays.
142 * Whereas scaling of image weight arrays is not generally obvious in
143 * either purpose or method, ALE requires that image definition arrays
144 * be scalable, and the method we implement here is a fairly obvious
145 * one. In particular, if any source pixel contributing to the value of
146 * a scaled target pixel has an undefined value, then the scaled target
147 * pixel is undefined (zero). Otherwise, it is defined (non-zero).
149 * Since there are many possible ways of implementing this function, we
150 * choose an easy way and simply multiply the numerical values of the
151 * source pixels to obtain the value of the scaled target pixel.
153 * XXX: we consider all pixels within a 9-pixel square to contribute.
154 * There are other approaches. For example, edge pixels could be
155 * considered to have six contributing pixels and corner pixels four
156 * contributing pixels. To use this convention, change the ': 0' text
157 * in the code below to ': 1'.
160 image
*defined_scale_by_half(const char *name
) const {
163 image
*result
= new image_zero(
164 (int) floor(height() * f
),
165 (int) floor(width() * f
), depth());
173 * Extend the image area to the top, bottom, left, and right,
174 * initializing the new image areas with black pixels.
176 virtual image
*_extend(int top
, int bottom
, int left
, int right
) {
177 _dimy
+= top
+ bottom
;
178 _dimx
+= left
+ right
;
188 image
*clone(const char *name
) const {
189 return new image_zero(_dimy
, _dimx
, _depth
, name
);
192 image_zero(unsigned int dimy
, unsigned int dimx
, unsigned int depth
,
193 const char *name
= "anonymous") : image_weighted_avg(dimy
, dimx
, depth
, name
) {
196 int accumulate_norender(int i
, int j
) {
200 void accumulate(int i
, int j
, int f
, pixel new_value
, pixel new_weight
) {
204 image
*get_colors() {
208 image
*get_weights() {