00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <libdirac_common/band_codec.h>
00039 using namespace dirac;
00040
00042 BandCodec::BandCodec(BasicOutputManager* bits_out,
00043 size_t number_of_contexts,
00044 const SubbandList & band_list,
00045 int band_num):
00046 ArithCodec<PicArray>(bits_out,number_of_contexts),
00047 m_bnum(band_num),
00048 m_node(band_list(band_num)),
00049 m_xp(m_node.Xp()),
00050 m_yp(m_node.Yp()),
00051 m_xl(m_node.Xl()),
00052 m_yl(m_node.Yl()),
00053 m_vol(m_node.Xl()*m_node.Yl()),
00054 m_reset_coeff_num( std::max( 25 , std::min(m_vol/32,800) ) ),
00055 m_cut_off_point(m_node.Scale()>>1)
00056 {
00057 if (m_node.Parent()!=0)
00058 m_pnode=band_list(m_node.Parent());
00059 }
00060
00062 BandCodec::BandCodec(BitInputManager* bits_in,
00063 size_t number_of_contexts,
00064 const SubbandList& band_list,
00065 int band_num):
00066 ArithCodec<PicArray>(bits_in,number_of_contexts),
00067 m_bnum(band_num),
00068 m_node(band_list(band_num)),
00069 m_xp(m_node.Xp()),
00070 m_yp(m_node.Yp()),
00071 m_xl(m_node.Xl()),
00072 m_yl(m_node.Yl()),
00073 m_vol(m_node.Xl()*m_node.Yl()),
00074 m_reset_coeff_num( std::max( 25 , std::min(m_vol/32,800) ) ),
00075 m_cut_off_point(m_node.Scale()>>1)
00076 {
00077 if (m_node.Parent()!=0) m_pnode=band_list(m_node.Parent());
00078 }
00079
00080 void BandCodec::InitContexts()
00081 {
00082
00083
00084
00085 Context tmp_ctx;
00086
00087 for (size_t i=0; i<m_context_list.size(); ++i)
00088 {
00089 if (i>=m_context_list.size())
00090 m_context_list.push_back(tmp_ctx);
00091 else
00092 {
00093 if (m_context_list[i].Weight()==0)
00094 m_context_list[i].SetCounts(1,1);
00095 }
00096 }
00097 }
00098
00099 void BandCodec::ResetAll()
00100 {
00101 for (unsigned int c = 0; c < m_context_list.size(); ++c)
00102 if (m_context_list[c].Weight()>16)
00103 m_context_list[c].HalveCounts();
00104 }
00105
00106 void BandCodec::Resize(const int context_num)
00107 {
00108 m_context_list[context_num].HalveCounts();
00109 }
00110
00111 void BandCodec::Update( const bool symbol , const int context_num )
00112 {
00113 m_context_list[context_num].IncrCount(symbol,1);
00114
00115 if ( m_context_list[context_num].Weight() >= 1024 )
00116 Resize( context_num );
00117 }
00118
00119 int BandCodec::ChooseContext(const PicArray& data) const{ return NZ_BIN5plus_CTX; }
00120
00121
00122 void BandCodec::DoWorkCode(PicArray& in_data)
00123 {
00124
00125
00126 if (m_node.Parent()!=0)
00127 {
00128 m_pxp=m_pnode.Xp(); m_pyp=m_pnode.Yp();
00129 m_pxl=m_pnode.Xl(); m_pyl=m_pnode.Yl();
00130 }
00131 else
00132 {
00133 m_pxp=0; m_pyp=0;
00134 m_pxl=0; m_pyl=0;
00135 }
00136
00137 ValueType val;
00138 m_qf=m_node.Qf(0);
00139 m_qfinv=(1<<17)/m_qf;
00140 m_offset=(3*m_qf+4)>>3;
00141 m_cut_off_point*=m_qf;
00142
00143 m_coeff_count=0;
00144
00145 for (m_ypos=m_yp,m_pypos=m_pyp;m_ypos<m_yp+m_yl;++m_ypos,m_pypos=((m_ypos-m_yp)>>1)+m_pyp)
00146 {
00147 for (m_xpos=m_xp,m_pxpos=m_pxp;m_xpos<m_xp+m_xl;++m_xpos,m_pxpos=((m_xpos-m_xp)>>1)+m_pxp)
00148 {
00149 if (m_xpos==m_xp)
00150 m_nhood_sum = (m_ypos!=m_yp) ? std::abs(in_data[m_ypos-1][m_xpos]) : 0;
00151 else
00152 m_nhood_sum = (m_ypos!=m_yp) ?
00153 (std::abs(in_data[m_ypos-1][m_xpos]) + std::abs(in_data[m_ypos][m_xpos-1]))
00154 : std::abs(in_data[m_ypos][m_xpos-1]);
00155
00156 m_parent_notzero = static_cast<bool> ( in_data[m_pypos][m_pxpos] );
00157 val = in_data[m_ypos][m_xpos];
00158 in_data[m_ypos][m_xpos]=0;
00159 CodeVal( in_data , val );
00160
00161 }
00162 }
00163
00164 #if defined(VERBOSE_DEBUG)
00165
00166 cerr<<endl<<"Context counts";
00167
00168 for (int c = 0; c < 16; ++c)
00169 cerr << endl
00170 << c
00171 << ": Zero-"
00172 << ContextList()[c].get_count0()
00173 << ", One-"
00174 << ContextList()[c].get_count1();
00175 #endif
00176 }
00177
00178 void BandCodec::CodeVal( PicArray& in_data , const ValueType val )
00179 {
00180 int abs_val( std::abs(val) );
00181 abs_val *= m_qfinv;
00182 abs_val >>= 17;
00183
00184 for ( int bin=1 ; bin<=abs_val ; ++bin )
00185 EncodeSymbol( 0 , ChooseContext( in_data , bin ) );
00186
00187 EncodeSymbol( 1 , ChooseContext( in_data , abs_val+1 ) );
00188
00189 if ( abs_val )
00190 {
00191 abs_val *= m_qf;
00192 in_data[m_ypos][m_xpos] = static_cast<ValueType>( abs_val );
00193
00194 if ( val>0 )
00195 {
00196 EncodeSymbol( 1 , ChooseSignContext( in_data ) );
00197 in_data[m_ypos][m_xpos] += m_offset;
00198 }
00199 else
00200 {
00201 EncodeSymbol( 0 , ChooseSignContext(in_data) );
00202 in_data[m_ypos][m_xpos] = -in_data[m_ypos][m_xpos];
00203 in_data[m_ypos][m_xpos] -= m_offset;
00204 }
00205 }
00206
00207 m_coeff_count++;
00208
00209 if (m_coeff_count > m_reset_coeff_num)
00210 {
00211 m_coeff_count=0;
00212 ResetAll();
00213 }
00214 }
00215
00216 void BandCodec::DoWorkDecode(PicArray& out_data, int num_bits)
00217 {
00218
00219 if (m_node.Parent()!=0)
00220 {
00221 m_pxp = m_pnode.Xp();
00222 m_pyp = m_pnode.Yp();
00223 m_pxl = m_pnode.Xl();
00224 m_pyl = m_pnode.Yl();
00225 }
00226 else
00227 {
00228 m_pxp = 0;
00229 m_pyp = 0;
00230 m_pxl = 0;
00231 m_pyl = 0;
00232 }
00233
00234 m_qf = m_node.Qf(0);
00235 m_offset = (3 * m_qf + 4) >> 3;
00236 m_cut_off_point *= m_qf;
00237
00238
00239 m_coeff_count=0;
00240
00241 for (m_ypos=m_yp,m_pypos=m_pyp;m_ypos<m_yp+m_yl;++m_ypos,m_pypos=((m_ypos-m_yp)>>1)+m_pyp)
00242 {
00243 for (m_xpos = m_xp, m_pxpos = m_pxp; m_xpos < m_xp+m_xl; ++m_xpos, m_pxpos=((m_xpos-m_xp)>>1)+m_pxp)
00244 {
00245 if (m_xpos == m_xp)
00246 m_nhood_sum=(m_ypos!=m_yp) ? std::abs(out_data[m_ypos-1][m_xpos]): 0;
00247 else
00248 m_nhood_sum=(m_ypos!=m_yp) ?
00249 (std::abs(out_data[m_ypos-1][m_xpos]) + std::abs(out_data[m_ypos][m_xpos-1]))
00250 : std::abs(out_data[m_ypos][m_xpos-1]);
00251
00252 m_parent_notzero = static_cast<bool>( out_data[m_pypos][m_pxpos] );
00253 DecodeVal(out_data);
00254 }
00255 }
00256 }
00257
00258 void BandCodec::DecodeVal(PicArray& out_data)
00259 {
00260 ValueType val = 0;
00261 bool bit;
00262 int bin = 1;
00263
00264 do
00265 {
00266 DecodeSymbol(bit,ChooseContext(out_data,bin));
00267
00268 if (!bit)
00269 val++;
00270
00271 bin++;
00272 }
00273 while (!bit);
00274
00275 out_data[m_ypos][m_xpos] = val;
00276
00277 if (out_data[m_ypos][m_xpos])
00278 {
00279 out_data[m_ypos][m_xpos] *= m_qf;
00280 out_data[m_ypos][m_xpos] += m_offset;
00281 DecodeSymbol( bit , ChooseSignContext(out_data) );
00282 }
00283
00284 if (!bit)
00285 out_data[m_ypos][m_xpos]=-out_data[m_ypos][m_xpos];
00286
00287 m_coeff_count++;
00288
00289 if (m_coeff_count>m_reset_coeff_num)
00290 {
00291 ResetAll();
00292 m_coeff_count=0;
00293 }
00294 }
00295
00296 int BandCodec::ChooseContext(const PicArray& data, const int BinNumber) const
00297 {
00298
00299 if (!m_parent_notzero && (m_pxp != 0 || m_pyp != 0))
00300 {
00301 if (BinNumber == 1)
00302 {
00303 if(m_nhood_sum == 0)
00304 return Z_BIN1z_CTX;
00305 else
00306 return Z_BIN1nz_CTX;
00307 }
00308 else if(BinNumber == 2)
00309 return Z_BIN2_CTX;
00310 else if(BinNumber == 3)
00311 return Z_BIN3_CTX;
00312 else if(BinNumber == 4)
00313 return Z_BIN4_CTX;
00314 else
00315 return Z_BIN5plus_CTX;
00316 }
00317 else
00318 {
00319 if (BinNumber == 1)
00320 {
00321 if(m_nhood_sum == 0)
00322 return NZ_BIN1z_CTX;
00323 else if (m_nhood_sum>m_cut_off_point)
00324 return NZ_BIN1b_CTX;
00325 else
00326 return NZ_BIN1a_CTX;
00327 }
00328 else if(BinNumber == 2)
00329 return NZ_BIN2_CTX;
00330 else if(BinNumber == 3)
00331 return NZ_BIN3_CTX;
00332 else if(BinNumber == 4)
00333 return NZ_BIN4_CTX;
00334 else
00335 return NZ_BIN5plus_CTX;
00336 }
00337 }
00338
00339 int BandCodec::ChooseSignContext(const PicArray& data) const
00340 {
00341 if (m_yp == 0 && m_xp != 0)
00342 {
00343
00344 if (m_ypos == 0)
00345 return SIGN0_CTX;
00346 else
00347 {
00348 if (data[m_ypos-1][m_xpos]>0)
00349 return SIGN_POS_CTX;
00350 else if (data[m_ypos-1][m_xpos]<0)
00351 return SIGN_NEG_CTX;
00352 else
00353 return SIGN0_CTX;
00354 }
00355 }
00356 else if (m_xp == 0 && m_yp != 0)
00357 {
00358
00359 if (m_xpos == 0)
00360 return SIGN0_CTX;
00361 else
00362 {
00363 if ( data[m_ypos][m_xpos-1] > 0 )
00364 return SIGN_POS_CTX;
00365 else if ( data[m_ypos][m_xpos-1] < 0 )
00366 return SIGN_NEG_CTX;
00367 else
00368 return SIGN0_CTX;
00369 }
00370 }
00371 else
00372 return SIGN0_CTX;
00373 }
00374
00376
00378
00379 void LFBandCodec::DoWorkCode(PicArray& in_data)
00380 {
00381
00382 m_pxp = 0;
00383 m_pyp = 0;
00384 m_parent_notzero = false;
00385 ValueType val;
00386
00387 m_qf = m_node.Qf(0);
00388 m_qfinv = (1<<17)/m_qf;
00389 m_offset = (3*m_qf+4)>>3;
00390 m_cut_off_point*=m_qf;
00391
00392 m_coeff_count = 0;
00393
00394 for ( m_ypos=m_yp ; m_ypos<m_yp+m_yl ; ++m_ypos )
00395 {
00396 for ( m_xpos=m_xp ; m_xpos<m_xp+m_xl ; ++m_xpos )
00397 {
00398 if ( m_xpos == m_xp )
00399 m_nhood_sum = (m_ypos!=m_yp) ? std::abs(in_data[m_ypos-1][m_xpos]) : 0;
00400 else
00401 m_nhood_sum = (m_ypos!=m_yp) ?
00402 (std::abs(in_data[m_ypos-1][m_xpos]) + std::abs(in_data[m_ypos][m_xpos-1]))
00403 : std::abs(in_data[m_ypos][m_xpos-1]);
00404
00405 val = in_data[m_ypos][m_xpos];
00406 in_data[m_ypos][m_xpos] = 0;
00407 CodeVal(in_data,val);
00408 }
00409 }
00410 }
00411
00412 void LFBandCodec::DoWorkDecode(PicArray& out_data, int num_bits)
00413 {
00414 m_pxp = 0;
00415 m_pyp = 0;
00416 m_parent_notzero = false;
00417 m_qf = m_node.Qf(0);
00418 m_offset = (3*m_qf+4)>>3;
00419 m_cut_off_point *= m_qf;
00420
00421
00422 m_coeff_count = 0;
00423
00424 for ( m_ypos=m_yp ; m_ypos<m_yp+m_yl ; ++m_ypos )
00425 {
00426 for ( m_xpos=0 ; m_xpos<m_xp+m_xl; ++m_xpos )
00427 {
00428 if ( m_xpos == m_xp )
00429 m_nhood_sum=(m_ypos!=m_yp) ? std::abs(out_data[m_ypos-1][m_xpos]) : 0;
00430 else
00431 m_nhood_sum=(m_ypos!=m_yp) ?
00432 (std::abs(out_data[m_ypos-1][m_xpos]) + std::abs(out_data[m_ypos][m_xpos-1]))
00433 : std::abs(out_data[m_ypos][m_xpos-1]);
00434
00435 DecodeVal(out_data);
00436 }
00437 }
00438 }
00439
00441
00443
00444 void IntraDCBandCodec::DoWorkCode(PicArray& in_data)
00445 {
00446
00447 m_pxp = 0;
00448 m_pyp = 0;
00449
00450
00451 m_parent_notzero = false;
00452 ValueType val;
00453
00454
00455 PicArray pred_res(m_yl , m_xl);
00456 ValueType prediction;
00457
00458 m_qf = m_node.Qf(0);
00459 m_qfinv = (1<<17) / m_qf;
00460 m_offset = (3*m_qf+4) >> 3;
00461 m_cut_off_point *= m_qf;
00462
00463 m_coeff_count=0;
00464
00465 for (m_ypos=m_yp; m_ypos < m_yp + m_yl; ++m_ypos)
00466 {
00467 for (m_xpos = m_xp; m_xpos < m_xp + m_xl; ++m_xpos)
00468 {
00469 if (m_xpos == m_xp)
00470 m_nhood_sum = (m_ypos!=m_yp) ? std::abs(pred_res[m_ypos-1][m_xpos]) : 0;
00471 else
00472 m_nhood_sum = (m_ypos!=m_yp) ?
00473 (std::abs(pred_res[m_ypos-1][m_xpos]) + std::abs(pred_res[m_ypos][m_xpos-1]))
00474 : std::abs(pred_res[m_ypos][m_xpos-1]);
00475
00476 prediction = GetPrediction(in_data);
00477 val = in_data[m_ypos][m_xpos]-prediction;
00478 in_data[m_ypos][m_xpos] = 0;
00479 CodeVal(in_data,val);
00480 pred_res[m_ypos][m_xpos] = in_data[m_ypos][m_xpos];
00481 in_data[m_ypos][m_xpos] += prediction;
00482 }
00483
00484 #if defined(VERBOSE_DEBUG)
00485 cerr << endl
00486 << "Val at "
00487 << m_ypos
00488 << " "
00489 << m_xl-1
00490 << " : "
00491 << in_data[m_ypos][m_xl-1]
00492 << endl
00493 << "Contexts at "
00494 << m_ypos
00495 << " "
00496 << m_xl-1
00497 << " : ";
00498
00499 for (int c=0;c<18;++c)
00500 cerr << endl
00501 << c
00502 << ": Zero "
00503 << ContextList()[c].get_count0()
00504 << ", One "
00505 << ContextList()[c].get_count1();
00506 #endif
00507
00508 }
00509 }
00510
00511 void IntraDCBandCodec::DoWorkDecode(PicArray& out_data, int num_bits)
00512 {
00513 m_pxp = 0;
00514 m_pyp = 0;
00515 m_parent_notzero = false;
00516
00517
00518 PicArray pred_res(m_yl , m_xl);
00519
00520 m_qf = m_node.Qf(0);
00521 m_offset = (3*m_qf+4)>>3;
00522 m_cut_off_point *= m_qf;
00523
00524
00525 m_coeff_count=0;
00526
00527 for (m_ypos=m_yp;m_ypos<m_yp+m_yl;++m_ypos)
00528 {
00529 for (m_xpos=0;m_xpos<m_xp+m_xl;++m_xpos)
00530 {
00531 if (m_xpos==m_xp)
00532 m_nhood_sum=(m_ypos!=m_yp) ? std::abs(pred_res[m_ypos - 1][m_xpos]) : 0;
00533 else
00534 m_nhood_sum=(m_ypos!=m_yp) ?
00535 (std::abs(pred_res[m_ypos - 1][m_xpos]) + std::abs(pred_res[m_ypos][m_xpos - 1]))
00536 : std::abs(pred_res[m_ypos][m_xpos-1]);
00537
00538 DecodeVal(out_data);
00539 pred_res[m_ypos][m_xpos]=out_data[m_ypos][m_xpos];
00540 out_data[m_ypos][m_xpos]+=GetPrediction(out_data);
00541 }
00542 }
00543 }
00544
00545 ValueType IntraDCBandCodec::GetPrediction(const PicArray& data) const
00546 {
00547 if (m_ypos!=0)
00548 {
00549 if (m_xpos!=0)
00550 return (data[m_ypos][m_xpos - 1] + data[m_ypos - 1][m_xpos - 1] + data[m_ypos - 1][m_xpos]) / 3;
00551 else
00552 return data[m_ypos - 1][0];
00553 }
00554 else
00555 {
00556 if(m_xpos!=0)
00557 return data[0][m_xpos - 1];
00558 else
00559 return 2692;
00560 }
00561 }