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 
30 namespace 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 
56 void
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 
75 void
76 LossyScaler::set_original_dimensions(unsigned int width, unsigned int height)
77 {
78  orig_width = width;
79  orig_height = height;
80 }
81 
82 void
83 LossyScaler::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 
108 void
109 LossyScaler::set_original_buffer(unsigned char *buffer)
110 {
111  orig_buffer = buffer;
112 }
113 
114 void
115 LossyScaler::set_scaled_buffer(unsigned char *buffer)
116 {
117  scal_buffer = buffer;
118 }
119 
120 unsigned int
122 {
123  return scal_width;
124 }
125 
126 unsigned int
128 {
129  return scal_height;
130 }
131 
132 float
134 {
135  return scale_factor;
136 }
137 
138 void
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
firevision::LossyScaler::scale
virtual void scale()
Scale image.
Definition: lossy.cpp:139
firevision::LossyScaler::set_original_buffer
virtual void set_original_buffer(unsigned char *buffer)
Set original image buffer.
Definition: lossy.cpp:109
firevision::LossyScaler::set_scaled_dimensions
virtual void set_scaled_dimensions(unsigned int width, unsigned int height)
Set dimenins of scaled image buffer.
Definition: lossy.cpp:83
firevision::LossyScaler::get_scale_factor
virtual float get_scale_factor()
Returns the scale factor.
Definition: lossy.cpp:133
firevision::LossyScaler::needed_scaled_width
virtual unsigned int needed_scaled_width()
Minimum needed width of scaled image depending on factor and original image width.
Definition: lossy.cpp:121
firevision::LossyScaler::~LossyScaler
virtual ~LossyScaler()
Destructor.
Definition: lossy.cpp:52
firevision::LossyScaler::LossyScaler
LossyScaler()
Constructor.
Definition: lossy.cpp:41
firevision::LossyScaler::set_original_dimensions
virtual void set_original_dimensions(unsigned int width, unsigned int height)
Set original image dimensions.
Definition: lossy.cpp:76
firevision::LossyScaler::set_scaled_buffer
virtual void set_scaled_buffer(unsigned char *buffer)
Set scaled image buffer.
Definition: lossy.cpp:115
firevision::LossyScaler::set_scale_factor
virtual void set_scale_factor(float factor)
Set scale factor.
Definition: lossy.cpp:57
firevision::LossyScaler::needed_scaled_height
virtual unsigned int needed_scaled_height()
Minimum needed height of scaled image depending on factor and original image height.
Definition: lossy.cpp:127