Fixed #2984304. Fix compilation errors reported by gcc 4.5.0.
[dirac-research.git] / libdirac_encoder / enc_picture.cpp
blob88678a219e8342e4fa60c0dc859af11f6601b3de
1 /* ***** BEGIN LICENSE BLOCK *****
3 * $Id: enc_picture.cpp,v 1.1 2008/06/19 10:02:02 tjdwave Exp $ $Name: $
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
7 * The contents of this file are subject to the Mozilla Public License
8 * Version 1.1 (the "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
14 * the specific language governing rights and limitations under the License.
16 * The Original Code is BBC Research and Development code.
18 * The Initial Developer of the Original Code is the British Broadcasting
19 * Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 2008.
21 * All Rights Reserved.
23 * Contributor(s): Thomas Davies (Original Author),
25 * Alternatively, the contents of this file may be used under the terms of
26 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
27 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
28 * the GPL or the LGPL are applicable instead of those above. If you wish to
29 * allow use of your version of this file only under the terms of the either
30 * the GPL or LGPL and not to allow others to use your version of this file
31 * under the MPL, indicate your decision by deleting the provisions above
32 * and replace them with the notice and other provisions required by the GPL
33 * or LGPL. If you do not delete the provisions above, a recipient may use
34 * your version of this file under the terms of any one of the MPL, the GPL
35 * or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include <libdirac_encoder/enc_picture.h>
39 #include <libdirac_common/upconvert.h>
41 using namespace dirac;
43 EncPicture::EncPicture( const PictureParams& pp):
44 Picture( pp ),
45 m_me_data( NULL ),
46 m_status( NO_ENC ),
47 m_complexity( 0.0 ),
48 m_norm_complexity( 1.0 ),
49 m_pred_bias(0.5)
51 for (int c=0; c<3; ++c ){
52 m_orig_data[c] = new PicArray( m_pic_data[c]->LengthY(), m_pic_data[c]->LengthX() );
53 m_orig_up_data[c] = NULL;
54 m_filt_data[c] = NULL;
55 m_filt_up_data[c] = NULL;
59 void EncPicture::ClearData(){
61 Picture::ClearData();
63 for (int c=0;c<3;++c){
64 if (m_orig_data[c] != NULL){
65 delete m_orig_data[c];
66 m_orig_data[c] = NULL;
69 if (m_orig_up_data[c] != NULL){
70 delete m_orig_up_data[c];
71 m_orig_up_data[c] = NULL;
74 if (m_filt_data[c] != NULL){
75 delete m_filt_data[c];
76 m_filt_data[c] = NULL;
79 if (m_filt_up_data[c] != NULL){
80 delete m_filt_up_data[c];
81 m_filt_up_data[c] = NULL;
85 if ( m_me_data != NULL )
86 delete m_me_data;
89 EncPicture::~EncPicture()
91 ClearData();
94 void EncPicture::SetOrigData()
96 for ( int c=0; c<3 ; ++c )
97 SetOrigData(c);
100 void EncPicture::SetOrigData( const int c )
102 if ( m_pic_data[c] != NULL )
103 *(m_orig_data[c]) = *(m_pic_data[c]);
106 void EncPicture::InitMEData( const PicturePredParams& predparams , const int num_refs)
108 if (m_me_data != NULL)
109 delete m_me_data;
111 m_me_data=new MEData( predparams, num_refs );
114 const PicArray& EncPicture::DataForME( bool combined_me ) const{
116 if (combined_me)
117 return CombinedData();
118 else
119 return OrigData( Y_COMP );
122 const PicArray& EncPicture::UpDataForME( bool combined_me ) const{
124 if (combined_me)
125 return UpCombinedData();
126 else
127 return UpOrigData( Y_COMP );
131 const PicArray& EncPicture::UpOrigData(CompSort cs) const
133 const int c = (int) cs;
135 if (m_orig_up_data[c] != NULL)
136 return *m_orig_up_data[c];
137 else
138 {//we have to do the upconversion
140 m_orig_up_data[c] = new PicArray( 2*m_orig_data[c]->LengthY(),
141 2*m_orig_data[c]->LengthX() );
142 UpConverter* myupconv;
143 if (c>0)
144 myupconv = new UpConverter(-(1 << (m_pparams.ChromaDepth()-1)),
145 (1 << (m_pparams.ChromaDepth()-1))-1,
146 m_pparams.ChromaXl(), m_pparams.ChromaYl());
147 else
148 myupconv = new UpConverter(-(1 << (m_pparams.LumaDepth()-1)),
149 (1 << (m_pparams.LumaDepth()-1))-1,
150 m_pparams.Xl(), m_pparams.Yl());
152 myupconv->DoUpConverter( *(m_orig_data[c]) , *(m_orig_up_data[c]) );
154 delete myupconv;
156 return *(m_orig_up_data[c]);
161 const PicArray& EncPicture::FiltData(CompSort cs) const
163 const int c = (int) cs;
165 if (m_filt_data[c] != NULL)
166 return *m_filt_data[c];
167 else
168 {//we have to do the filtering
170 if (m_orig_data[c] != NULL )
171 m_filt_data[c] = new PicArray( m_orig_data[c]->LengthY(),
172 m_orig_data[c]->LengthX() );
174 AntiAliasFilter( *(m_filt_data[c]), *(m_orig_data[c]));
176 return *(m_filt_data[c]);
181 const PicArray& EncPicture::UpFiltData(CompSort cs) const
183 const int c = (int) cs;
185 if (m_filt_up_data[c] != NULL)
186 return *m_filt_up_data[c];
187 else
188 {//we have to do the upconversion
190 const PicArray& filt_data = FiltData( cs );
192 m_filt_up_data[c] = new PicArray( 2*filt_data.LengthY(),
193 2*filt_data.LengthX() );
194 UpConverter* myupconv;
195 if (c>0)
196 myupconv = new UpConverter(-(1 << (m_pparams.ChromaDepth()-1)),
197 (1 << (m_pparams.ChromaDepth()-1))-1,
198 m_pparams.ChromaXl(), m_pparams.ChromaYl());
199 else
200 myupconv = new UpConverter(-(1 << (m_pparams.LumaDepth()-1)),
201 (1 << (m_pparams.LumaDepth()-1))-1,
202 m_pparams.Xl(), m_pparams.Yl());
204 myupconv->DoUpConverter( filt_data , *(m_filt_up_data[c]) );
206 delete myupconv;
208 return *(m_filt_up_data[c]);
213 void EncPicture::AntiAliasFilter( PicArray& out_data, const PicArray& in_data ) const{
215 //Special case for first row
216 for (int i = in_data.FirstX(); i <= in_data.LastX(); ++i)
218 out_data[in_data.FirstY()][i] = (3*in_data[in_data.FirstY()][i] +
219 in_data[in_data.FirstY()+1][i] +2 )>>2;
221 //Middle section
222 for (int j = in_data.FirstY()+1; j < in_data.LastY(); ++j)
224 for (int i = in_data.FirstX(); i <= in_data.LastX(); ++i)
226 out_data[j][i] = (in_data[j-1][i] + 2*in_data[j][i] + in_data[j+1][i] + 2)>>2;
229 //Special case for last row
230 for (int i = in_data.FirstX(); i <= in_data.LastX(); ++i)
232 out_data[in_data.LastY()][i] = (in_data[in_data.LastY()-1][i] +
233 3*in_data[in_data.LastY()][i] + 2)>>2;
237 const PicArray& EncPicture::CombinedData() const
240 if (m_filt_data[Y_COMP] != NULL)
241 return *m_filt_data[Y_COMP];
242 else
243 {//we have to do the combining
245 if (m_orig_data[Y_COMP] != NULL )
246 m_filt_data[Y_COMP] = new PicArray( m_orig_data[Y_COMP]->LengthY(),
247 m_orig_data[Y_COMP]->LengthX() );
249 Combine( *(m_filt_data[Y_COMP]), *(m_orig_data[Y_COMP]),
250 *(m_orig_data[U_COMP]), *(m_orig_data[V_COMP])
253 return *(m_filt_data[Y_COMP]);
258 const PicArray& EncPicture::UpCombinedData() const
260 if (m_filt_up_data[Y_COMP] != NULL)
261 return *m_filt_up_data[Y_COMP];
262 else
263 {//we have to do the upconversion
265 const PicArray& filt_data = CombinedData();
267 m_filt_up_data[Y_COMP] = new PicArray( 2*filt_data.LengthY(),
268 2*filt_data.LengthX() );
269 UpConverter* myupconv;
270 myupconv = new UpConverter(-(1 << (m_pparams.LumaDepth()-1)),
271 (1 << (m_pparams.LumaDepth()-1))-1,
272 m_pparams.Xl(), m_pparams.Yl());
274 myupconv->DoUpConverter( filt_data , *(m_filt_up_data[Y_COMP]) );
276 delete myupconv;
278 return *(m_filt_up_data[Y_COMP]);
285 void EncPicture::Combine( PicArray& comb_data, const PicArray& y_data,
286 const PicArray& u_data, const PicArray& v_data ) const
288 int hcr = y_data.LengthX()/u_data.LengthX();
289 int vcr = y_data.LengthY()/u_data.LengthY();
291 float val, valc, valy;
293 if (vcr==1){
294 for (int j=0; j<comb_data.LengthY(); ++j) {
295 if (hcr==1){// 444 format
296 for (int i=0; i<comb_data.LengthX(); ++i ){
297 val = float(u_data[j][i]);
298 val *= val;
299 valc = val;
301 val = float(v_data[j][i]);
302 val *= val;
303 valc += val;
305 valy = float(y_data[j][i]) + 128.0;
306 valy *= valy;
307 comb_data[j][i] = ValueType( std::sqrt(valc+valy)-128.0 );
308 }// i
310 else{ // 422 format
311 for (int i=0; i<comb_data.LengthX(); i+=2 ){
313 val = float(u_data[j][i>>1]);
314 val *= val;
315 valc = val;
317 val = float(v_data[j][i>>1]);
318 val *= val;
319 valc += val;
321 valy = float(y_data[j][i]) + 128.0;
322 valy *= valy;
323 comb_data[j][i] = ValueType( std::sqrt(valc+valy)-128.0 );
325 valy = float(y_data[j][i+1]) + 128.0;
326 valy *= valy;
328 comb_data[j][i+1] = ValueType( std::sqrt(valc+valy)-128.0 );
330 }// i
332 }// j
334 else{ // 420 format
335 for (int j=0; j<comb_data.LengthY(); j+=2 ) {
337 for (int i=0; i<comb_data.LengthX(); i+=2 ){
339 val = float(u_data[j>>1][i>>1]);
340 val *= val;
341 valc = val;
343 val = float(v_data[j>>1][i>>1]);
344 val *= val;
345 valc += val;
347 valy = float(y_data[j][i]) + 128.0;
348 valy *= valy;
349 comb_data[j][i] = ValueType( std::sqrt(valc+valy)-128.0 );
351 valy = float(y_data[j][i+1]) + 128.0;
352 valy *= valy;
353 comb_data[j][i+1] = ValueType( std::sqrt(valc+valy)-128.0 );
355 valy = float(y_data[j+1][i]) + 128.0;
356 valy *= valy;
357 comb_data[j+1][i] = ValueType( std::sqrt(valc+valy)-128.0 );
359 valy = float(y_data[j+1][i+1]) + 128.0;
360 valy *= valy;
361 comb_data[j+1][i+1] = ValueType( std::sqrt(valc+valy)-128.0 );
363 }// i
364 }// j
372 void EncPicture::DropRef( int rindex ){
374 std::vector<int>& refs = m_pparams.Refs();
376 if (rindex==1 || rindex==2 )
377 refs.erase( refs.begin()+rindex-1 );
379 // Now reconfigure the motion data
380 if ( m_me_data!=NULL )
381 m_me_data->DropRef( rindex );