Fawkes API Fawkes Development Version
lossy.cpp
1
2/***************************************************************************
3 * lossy.cpp - lossy scaler
4 *
5 * Generated: Tue May 16 14:59:30 2006 (Automatica 2006)
6 * Copyright 2005-2007 Tim Niemueller [www.niemueller.de]
7 *
8 ****************************************************************************/
9
10/* This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version. A runtime exception applies to
14 * this software (see LICENSE.GPL_WRE file mentioned below for details).
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Library General Public License for more details.
20 *
21 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22 */
23
24#include <fvutils/color/yuv.h>
25#include <fvutils/scalers/lossy.h>
26
27#include <cmath>
28#include <cstring>
29
30namespace firevision {
31
32/** @class LossyScaler <fvutils/scalers/lossy.h>
33 * Lossy image scaler.
34 * This scaler just takes the required pixels from the image and throws away
35 * the rest. No enhancement of the image is done.
36 * This is only suitable for downscaling. The scale factor must be between
37 * 0 and 1.
38 */
39
40/** Constructor. */
42{
43 orig_width = orig_height = 0;
44 scal_width = scal_height = 0;
45 orig_buffer = NULL;
46 scal_buffer = NULL;
47
48 scale_factor = 1.f;
49}
50
51/** Destructor. */
53{
54}
55
56void
58{
59 if ((factor <= 0) || (factor > 1)) {
60 scale_factor = 1.f;
61 } else {
62 scale_factor = factor;
63 }
64
65 if (orig_width != 0) {
66 scal_width = (unsigned int)ceilf(orig_width * scale_factor);
67 scal_width += (scal_width % 2);
68 }
69 if (orig_height != 0) {
70 scal_height = (unsigned int)ceilf(orig_height * scale_factor);
71 scal_height += (scal_width % 2);
72 }
73}
74
75void
76LossyScaler::set_original_dimensions(unsigned int width, unsigned int height)
77{
78 orig_width = width;
79 orig_height = height;
80}
81
82void
83LossyScaler::set_scaled_dimensions(unsigned int width, unsigned int height)
84{
85 scal_width = width;
86 scal_height = height;
87
88 float scale_factor_width = 1.0;
89 float scale_factor_height = 1.0;
90
91 if (orig_width != 0) {
92 scale_factor_width = scal_width / float(orig_width);
93 }
94 if (orig_height != 0) {
95 scale_factor_height = scal_height / float(orig_height);
96 }
97
98 scale_factor =
99 (scale_factor_width < scale_factor_height) ? scale_factor_width : scale_factor_height;
100
101 scal_width = (unsigned int)floorf(orig_width * scale_factor);
102 scal_height = (unsigned int)floorf(orig_height * scale_factor);
103
104 scal_width += (scal_width % 2);
105 scal_height += (scal_height % 2);
106}
107
108void
110{
111 orig_buffer = buffer;
112}
113
114void
115LossyScaler::set_scaled_buffer(unsigned char *buffer)
116{
117 scal_buffer = buffer;
118}
119
120unsigned int
122{
123 return scal_width;
124}
125
126unsigned int
128{
129 return scal_height;
130}
131
132float
134{
135 return scale_factor;
136}
137
138void
140{
141 if (orig_width == 0)
142 return;
143 if (orig_height == 0)
144 return;
145 if (scal_width == 0)
146 return;
147 if (scal_height == 0)
148 return;
149 if (orig_buffer == NULL)
150 return;
151 if (scal_buffer == NULL)
152 return;
153 if (scal_width < needed_scaled_width())
154 return;
155 if (scal_height < needed_scaled_height())
156 return;
157
158 float skip = 1 / scale_factor;
159 unsigned char *oyp = orig_buffer;
160 unsigned char *oup = YUV422_PLANAR_U_PLANE(orig_buffer, orig_width, orig_height);
161 unsigned char *ovp = YUV422_PLANAR_V_PLANE(orig_buffer, orig_width, orig_height);
162
163 unsigned char *syp = scal_buffer;
164 unsigned char *sup = YUV422_PLANAR_U_PLANE(scal_buffer, scal_width, scal_height);
165 unsigned char *svp = YUV422_PLANAR_V_PLANE(scal_buffer, scal_width, scal_height);
166
167 memset(syp, 0, (size_t)scal_width * scal_height);
168 memset(sup, 128, (size_t)scal_width * scal_height);
169
170 float oh_float = 0.0;
171 float ow_float = 0.0;
172
173 unsigned int oh_pixel;
174 unsigned int ow_pixel;
175 unsigned int ow_pixel_next;
176
177 for (unsigned int h = 0; h < scal_height; ++h) {
178 oh_pixel = (unsigned int)rint(oh_float);
179 ow_float = 0.0;
180
181 if (oh_pixel >= orig_height) {
182 oh_pixel = orig_height - 1;
183 }
184 for (unsigned int w = 0; w < scal_width; w += 2) {
185 ow_pixel = (unsigned int)rint(ow_float);
186 ow_pixel_next = (unsigned int)rint(ow_float + skip);
187
188 if (ow_pixel >= orig_width) {
189 ow_pixel = orig_width - 1;
190 }
191
192 if (ow_pixel_next >= orig_width) {
193 ow_pixel_next = orig_width - 1;
194 }
195
196 syp[h * scal_width + w] = oyp[oh_pixel * orig_width + ow_pixel];
197 syp[h * scal_width + w + 1] = oyp[oh_pixel * orig_width + ow_pixel_next];
198 sup[(h * scal_width + w) / 2] = (oup[(oh_pixel * orig_width + ow_pixel) / 2]
199 + oup[(oh_pixel * orig_width + ow_pixel_next) / 2])
200 / 2;
201 svp[(h * scal_width + w) / 2] = (ovp[(oh_pixel * orig_width + ow_pixel) / 2]
202 + ovp[(oh_pixel * orig_width + ow_pixel_next) / 2])
203 / 2;
204
205 ow_float += 2 * skip;
206 }
207 oh_float += skip;
208 }
209}
210
211} // end namespace firevision
virtual ~LossyScaler()
Destructor.
Definition: lossy.cpp:52
virtual void set_scale_factor(float factor)
Set scale factor.
Definition: lossy.cpp:57
virtual void scale()
Scale image.
Definition: lossy.cpp:139
virtual unsigned int needed_scaled_height()
Minimum needed height of scaled image depending on factor and original image height.
Definition: lossy.cpp:127
virtual void set_scaled_dimensions(unsigned int width, unsigned int height)
Set dimenins of scaled image buffer.
Definition: lossy.cpp:83
virtual void set_original_dimensions(unsigned int width, unsigned int height)
Set original image dimensions.
Definition: lossy.cpp:76
LossyScaler()
Constructor.
Definition: lossy.cpp:41
virtual float get_scale_factor()
Returns the scale factor.
Definition: lossy.cpp:133
virtual unsigned int needed_scaled_width()
Minimum needed width of scaled image depending on factor and original image width.
Definition: lossy.cpp:121
virtual void set_original_buffer(unsigned char *buffer)
Set original image buffer.
Definition: lossy.cpp:109
virtual void set_scaled_buffer(unsigned char *buffer)
Set scaled image buffer.
Definition: lossy.cpp:115