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 
25 #include <fvutils/scalers/lossy.h>
26 #include <fvutils/color/yuv.h>
27 
28 #include <cmath>
29 #include <cstring>
30 
31 namespace firevision {
32 #if 0 /* just to make Emacs auto-indent happy */
33 }
34 #endif
35 
36 /** @class LossyScaler <fvutils/scalers/lossy.h>
37  * Lossy image scaler.
38  * This scaler just takes the required pixels from the image and throws away
39  * the rest. No enhancement of the image is done.
40  * This is only suitable for downscaling. The scale factor must be between
41  * 0 and 1.
42  */
43 
44 /** Constructor. */
46 {
47  orig_width = orig_height = 0;
48  scal_width = scal_height = 0;
49  orig_buffer = NULL;
50  scal_buffer = NULL;
51 
52  scale_factor = 1.f;
53 }
54 
55 
56 /** Destructor. */
58 {
59 }
60 
61 
62 void
64 {
65  if ( (factor <= 0) || (factor > 1) ) {
66  scale_factor = 1.f;
67  } else {
68  scale_factor = factor;
69  }
70 
71  if (orig_width != 0) {
72  scal_width = (unsigned int) ceil(orig_width * scale_factor);
73  scal_width += (scal_width % 2);
74  }
75  if (orig_height != 0) {
76  scal_height = (unsigned int) ceil(orig_height * scale_factor);
77  scal_height += (scal_width % 2);
78  }
79 }
80 
81 
82 void
84  unsigned int height)
85 {
86  orig_width = width;
87  orig_height = height;
88 }
89 
90 
91 void
93  unsigned int height)
94 {
95  scal_width = width;
96  scal_height = height;
97 
98  float scale_factor_width = 1.0;
99  float scale_factor_height = 1.0;
100 
101  if (orig_width != 0) {
102  scale_factor_width = scal_width / float(orig_width);
103  }
104  if (orig_height != 0) {
105  scale_factor_height = scal_height / float(orig_height);
106  }
107 
108  scale_factor = (scale_factor_width < scale_factor_height) ? scale_factor_width : scale_factor_height;
109 
110  scal_width = (unsigned int) floor(orig_width * scale_factor);
111  scal_height = (unsigned int) floor(orig_height * scale_factor);
112 
113  scal_width += (scal_width % 2);
114  scal_height += (scal_height % 2);
115 }
116 
117 
118 void
119 LossyScaler::set_original_buffer(unsigned char *buffer)
120 {
121  orig_buffer = buffer;
122 }
123 
124 
125 void
126 LossyScaler::set_scaled_buffer(unsigned char *buffer)
127 {
128  scal_buffer = buffer;
129 }
130 
131 
132 unsigned int
134 {
135  return scal_width;
136 }
137 
138 
139 unsigned int
141 {
142  return scal_height;
143 }
144 
145 
146 float
148 {
149  return scale_factor;
150 }
151 
152 void
154 {
155  if ( orig_width == 0 ) return;
156  if ( orig_height == 0 ) return;
157  if ( scal_width == 0 ) return;
158  if ( scal_height == 0 ) return;
159  if ( orig_buffer == NULL ) return;
160  if ( scal_buffer == NULL ) return;
161  if ( scal_width < needed_scaled_width() ) return;
162  if ( scal_height < needed_scaled_height() ) return;
163 
164  float skip = 1 / scale_factor;
165  unsigned char *oyp = orig_buffer;
166  unsigned char *oup = YUV422_PLANAR_U_PLANE( orig_buffer, orig_width, orig_height );
167  unsigned char *ovp = YUV422_PLANAR_V_PLANE( orig_buffer, orig_width, orig_height );
168 
169  unsigned char *syp = scal_buffer;
170  unsigned char *sup = YUV422_PLANAR_U_PLANE( scal_buffer, scal_width, scal_height );
171  unsigned char *svp = YUV422_PLANAR_V_PLANE( scal_buffer, scal_width, scal_height );
172 
173  memset( syp, 0, scal_width * scal_height );
174  memset( sup, 128, scal_width * scal_height );
175 
176  float oh_float = 0.0;
177  float ow_float = 0.0;
178 
179  unsigned int oh_pixel;
180  unsigned int ow_pixel;
181  unsigned int ow_pixel_next;
182 
183  for (unsigned int h = 0; h < scal_height; ++h) {
184  oh_pixel = (unsigned int) rint(oh_float);
185  ow_float = 0.0;
186 
187  if (oh_pixel >= orig_height) {
188  oh_pixel = orig_height - 1;
189  }
190  for (unsigned int w = 0; w < scal_width; w += 2) {
191  ow_pixel = (unsigned int) rint(ow_float);
192  ow_pixel_next = (unsigned int) rint( ow_float + skip);
193 
194  if (ow_pixel >= orig_width) {
195  ow_pixel = orig_width - 1;
196  }
197 
198  if (ow_pixel_next >= orig_width) {
199  ow_pixel_next = orig_width - 1;
200  }
201 
202  syp[ h * scal_width + w ] = oyp[ oh_pixel * orig_width + ow_pixel ];
203  syp[ h * scal_width + w + 1 ] = oyp[ oh_pixel * orig_width + ow_pixel_next ];
204  sup[ (h * scal_width + w) / 2 ] = (oup[ (oh_pixel * orig_width + ow_pixel) / 2 ] + oup[ (oh_pixel * orig_width + ow_pixel_next) / 2 ]) / 2;
205  svp[ (h * scal_width + w) / 2 ] = (ovp[ (oh_pixel * orig_width + ow_pixel) / 2 ] + ovp[ (oh_pixel * orig_width + ow_pixel_next) / 2 ]) / 2;
206 
207  ow_float += 2 * skip;
208  }
209  oh_float += skip;
210  }
211 }
212 
213 } // end namespace firevision
virtual float get_scale_factor()
Returns the scale factor.
Definition: lossy.cpp:147
virtual unsigned int needed_scaled_height()
Minimum needed height of scaled image depending on factor and original image height.
Definition: lossy.cpp:140
virtual void set_scaled_buffer(unsigned char *buffer)
Set scaled image buffer.
Definition: lossy.cpp:126
virtual void set_original_buffer(unsigned char *buffer)
Set original image buffer.
Definition: lossy.cpp:119
virtual ~LossyScaler()
Destructor.
Definition: lossy.cpp:57
virtual void set_original_dimensions(unsigned int width, unsigned int height)
Set original image dimensions.
Definition: lossy.cpp:83
virtual void set_scaled_dimensions(unsigned int width, unsigned int height)
Set dimenins of scaled image buffer.
Definition: lossy.cpp:92
LossyScaler()
Constructor.
Definition: lossy.cpp:45
virtual void set_scale_factor(float factor)
Set scale factor.
Definition: lossy.cpp:63
virtual unsigned int needed_scaled_width()
Minimum needed width of scaled image depending on factor and original image width.
Definition: lossy.cpp:133
virtual void scale()
Scale image.
Definition: lossy.cpp:153