Changeset 1313 in SHVCSoftware


Ignore:
Timestamp:
21 Jul 2015, 01:34:51 (9 years ago)
Author:
seregin
Message:

port rev 4387

Location:
branches/SHM-dev/source/Lib
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/SHM-dev/source/Lib/TLibCommon/TComYuv.cpp

    r1287 r1313  
    6868  m_chromaFormatIDC = chromaFormatIDC;
    6969
    70   for(Int ch=0; ch<MAX_NUM_COMPONENT; ch++)
     70  for(Int comp=0; comp<MAX_NUM_COMPONENT; comp++)
    7171  {
    7272    // memory allocation
    73     m_apiBuf[ch]  = (Pel*)xMalloc( Pel, getWidth(ComponentID(ch))*getHeight(ComponentID(ch)) );
     73    m_apiBuf[comp]  = (Pel*)xMalloc( Pel, getWidth(ComponentID(comp))*getHeight(ComponentID(comp)) );
    7474  }
    7575}
     
    7878{
    7979  // memory free
    80   for(Int ch=0; ch<MAX_NUM_COMPONENT; ch++)
    81   {
    82     if (m_apiBuf[ch]!=NULL)
    83     {
    84       xFree( m_apiBuf[ch] );
    85       m_apiBuf[ch] = NULL;
     80  for(Int comp=0; comp<MAX_NUM_COMPONENT; comp++)
     81  {
     82    if (m_apiBuf[comp]!=NULL)
     83    {
     84      xFree( m_apiBuf[comp] );
     85      m_apiBuf[comp] = NULL;
    8686    }
    8787  }
     
    9090Void TComYuv::clear()
    9191{
    92   for(Int ch=0; ch<MAX_NUM_COMPONENT; ch++)
    93   {
    94     if (m_apiBuf[ch]!=NULL)
    95     {
    96       ::memset( m_apiBuf[ch], 0, ( getWidth(ComponentID(ch)) * getHeight(ComponentID(ch))  )*sizeof(Pel) );
     92  for(Int comp=0; comp<MAX_NUM_COMPONENT; comp++)
     93  {
     94    if (m_apiBuf[comp]!=NULL)
     95    {
     96      ::memset( m_apiBuf[comp], 0, ( getWidth(ComponentID(comp)) * getHeight(ComponentID(comp))  )*sizeof(Pel) );
    9797    }
    9898  }
     
    104104Void TComYuv::copyToPicYuv   ( TComPicYuv* pcPicYuvDst, const UInt ctuRsAddr, const UInt uiAbsZorderIdx, const UInt uiPartDepth, const UInt uiPartIdx ) const
    105105{
    106   for(Int ch=0; ch<getNumberValidComponents(); ch++)
    107   {
    108     copyToPicComponent  ( ComponentID(ch), pcPicYuvDst, ctuRsAddr, uiAbsZorderIdx, uiPartDepth, uiPartIdx );
    109   }
    110 }
    111 
    112 Void TComYuv::copyToPicComponent  ( const ComponentID ch, TComPicYuv* pcPicYuvDst, const UInt ctuRsAddr, const UInt uiAbsZorderIdx, const UInt uiPartDepth, const UInt uiPartIdx ) const
    113 {
    114   const Int iWidth  = getWidth(ch) >>uiPartDepth;
    115   const Int iHeight = getHeight(ch)>>uiPartDepth;
    116 
    117   const Pel* pSrc     = getAddr(ch, uiPartIdx, iWidth);
    118         Pel* pDst     = pcPicYuvDst->getAddr ( ch, ctuRsAddr, uiAbsZorderIdx );
    119 
    120   const UInt  iSrcStride  = getStride(ch);
    121   const UInt  iDstStride  = pcPicYuvDst->getStride(ch);
     106  for(Int comp=0; comp<getNumberValidComponents(); comp++)
     107  {
     108    copyToPicComponent  ( ComponentID(comp), pcPicYuvDst, ctuRsAddr, uiAbsZorderIdx, uiPartDepth, uiPartIdx );
     109  }
     110}
     111
     112Void TComYuv::copyToPicComponent  ( const ComponentID compID, TComPicYuv* pcPicYuvDst, const UInt ctuRsAddr, const UInt uiAbsZorderIdx, const UInt uiPartDepth, const UInt uiPartIdx ) const
     113{
     114  const Int iWidth  = getWidth(compID) >>uiPartDepth;
     115  const Int iHeight = getHeight(compID)>>uiPartDepth;
     116
     117  const Pel* pSrc     = getAddr(compID, uiPartIdx, iWidth);
     118        Pel* pDst     = pcPicYuvDst->getAddr ( compID, ctuRsAddr, uiAbsZorderIdx );
     119
     120  const UInt  iSrcStride  = getStride(compID);
     121  const UInt  iDstStride  = pcPicYuvDst->getStride(compID);
    122122
    123123  for ( Int y = iHeight; y != 0; y-- )
     
    134134Void TComYuv::copyFromPicYuv   ( const TComPicYuv* pcPicYuvSrc, const UInt ctuRsAddr, const UInt uiAbsZorderIdx )
    135135{
    136   for(Int ch=0; ch<getNumberValidComponents(); ch++)
    137   {
    138     copyFromPicComponent  ( ComponentID(ch), pcPicYuvSrc, ctuRsAddr, uiAbsZorderIdx );
    139   }
    140 }
    141 
    142 Void TComYuv::copyFromPicComponent  ( const ComponentID ch, const TComPicYuv* pcPicYuvSrc, const UInt ctuRsAddr, const UInt uiAbsZorderIdx )
    143 {
    144         Pel* pDst     = getAddr(ch);
    145   const Pel* pSrc     = pcPicYuvSrc->getAddr ( ch, ctuRsAddr, uiAbsZorderIdx );
    146 
    147   const UInt iDstStride  = getStride(ch);
    148   const UInt iSrcStride  = pcPicYuvSrc->getStride(ch);
    149   const Int  iWidth=getWidth(ch);
    150   const Int  iHeight=getHeight(ch);
     136  for(Int comp=0; comp<getNumberValidComponents(); comp++)
     137  {
     138    copyFromPicComponent  ( ComponentID(comp), pcPicYuvSrc, ctuRsAddr, uiAbsZorderIdx );
     139  }
     140}
     141
     142Void TComYuv::copyFromPicComponent  ( const ComponentID compID, const TComPicYuv* pcPicYuvSrc, const UInt ctuRsAddr, const UInt uiAbsZorderIdx )
     143{
     144        Pel* pDst     = getAddr(compID);
     145  const Pel* pSrc     = pcPicYuvSrc->getAddr ( compID, ctuRsAddr, uiAbsZorderIdx );
     146
     147  const UInt iDstStride  = getStride(compID);
     148  const UInt iSrcStride  = pcPicYuvSrc->getStride(compID);
     149  const Int  iWidth=getWidth(compID);
     150  const Int  iHeight=getHeight(compID);
    151151
    152152  for (Int y = iHeight; y != 0; y-- )
     
    163163Void TComYuv::copyToPartYuv( TComYuv* pcYuvDst, const UInt uiDstPartIdx ) const
    164164{
    165   for(Int ch=0; ch<getNumberValidComponents(); ch++)
    166   {
    167     copyToPartComponent  ( ComponentID(ch), pcYuvDst, uiDstPartIdx );
    168   }
    169 }
    170 
    171 Void TComYuv::copyToPartComponent( const ComponentID ch, TComYuv* pcYuvDst, const UInt uiDstPartIdx ) const
    172 {
    173   const Pel* pSrc     = getAddr(ch);
    174         Pel* pDst     = pcYuvDst->getAddr( ch, uiDstPartIdx );
    175 
    176   const UInt iSrcStride  = getStride(ch);
    177   const UInt iDstStride  = pcYuvDst->getStride(ch);
    178   const Int  iWidth=getWidth(ch);
    179   const Int  iHeight=getHeight(ch);
     165  for(Int comp=0; comp<getNumberValidComponents(); comp++)
     166  {
     167    copyToPartComponent  ( ComponentID(comp), pcYuvDst, uiDstPartIdx );
     168  }
     169}
     170
     171Void TComYuv::copyToPartComponent( const ComponentID compID, TComYuv* pcYuvDst, const UInt uiDstPartIdx ) const
     172{
     173  const Pel* pSrc     = getAddr(compID);
     174        Pel* pDst     = pcYuvDst->getAddr( compID, uiDstPartIdx );
     175
     176  const UInt iSrcStride  = getStride(compID);
     177  const UInt iDstStride  = pcYuvDst->getStride(compID);
     178  const Int  iWidth=getWidth(compID);
     179  const Int  iHeight=getHeight(compID);
    180180
    181181  for (Int y = iHeight; y != 0; y-- )
     
    192192Void TComYuv::copyPartToYuv( TComYuv* pcYuvDst, const UInt uiSrcPartIdx ) const
    193193{
    194   for(Int ch=0; ch<getNumberValidComponents(); ch++)
    195   {
    196     copyPartToComponent  ( ComponentID(ch), pcYuvDst, uiSrcPartIdx );
    197   }
    198 }
    199 
    200 Void TComYuv::copyPartToComponent( const ComponentID ch, TComYuv* pcYuvDst, const UInt uiSrcPartIdx ) const
    201 {
    202   const Pel* pSrc     = getAddr(ch, uiSrcPartIdx);
    203         Pel* pDst     = pcYuvDst->getAddr(ch, 0 );
    204 
    205   const UInt  iSrcStride  = getStride(ch);
    206   const UInt  iDstStride  = pcYuvDst->getStride(ch);
    207 
    208   const UInt uiHeight = pcYuvDst->getHeight(ch);
    209   const UInt uiWidth = pcYuvDst->getWidth(ch);
     194  for(Int comp=0; comp<getNumberValidComponents(); comp++)
     195  {
     196    copyPartToComponent  ( ComponentID(comp), pcYuvDst, uiSrcPartIdx );
     197  }
     198}
     199
     200Void TComYuv::copyPartToComponent( const ComponentID compID, TComYuv* pcYuvDst, const UInt uiSrcPartIdx ) const
     201{
     202  const Pel* pSrc     = getAddr(compID, uiSrcPartIdx);
     203        Pel* pDst     = pcYuvDst->getAddr(compID, 0 );
     204
     205  const UInt  iSrcStride  = getStride(compID);
     206  const UInt  iDstStride  = pcYuvDst->getStride(compID);
     207
     208  const UInt uiHeight = pcYuvDst->getHeight(compID);
     209  const UInt uiWidth = pcYuvDst->getWidth(compID);
    210210
    211211  for ( UInt y = uiHeight; y != 0; y-- )
     
    222222Void TComYuv::copyPartToPartYuv   ( TComYuv* pcYuvDst, const UInt uiPartIdx, const UInt iWidth, const UInt iHeight ) const
    223223{
    224   for(Int ch=0; ch<getNumberValidComponents(); ch++)
    225   {
    226     copyPartToPartComponent   (ComponentID(ch), pcYuvDst, uiPartIdx, iWidth>>getComponentScaleX(ComponentID(ch)), iHeight>>getComponentScaleY(ComponentID(ch)) );
    227   }
    228 }
    229 
    230 Void TComYuv::copyPartToPartComponent  ( const ComponentID ch, TComYuv* pcYuvDst, const UInt uiPartIdx, const UInt iWidthComponent, const UInt iHeightComponent ) const
    231 {
    232   const Pel* pSrc =           getAddr(ch, uiPartIdx);
    233         Pel* pDst = pcYuvDst->getAddr(ch, uiPartIdx);
     224  for(Int comp=0; comp<getNumberValidComponents(); comp++)
     225  {
     226    copyPartToPartComponent   (ComponentID(comp), pcYuvDst, uiPartIdx, iWidth>>getComponentScaleX(ComponentID(comp)), iHeight>>getComponentScaleY(ComponentID(comp)) );
     227  }
     228}
     229
     230Void TComYuv::copyPartToPartComponent  ( const ComponentID compID, TComYuv* pcYuvDst, const UInt uiPartIdx, const UInt iWidthComponent, const UInt iHeightComponent ) const
     231{
     232  const Pel* pSrc =           getAddr(compID);
     233        Pel* pDst = pcYuvDst->getAddr(compID, uiPartIdx);
    234234  if( pSrc == pDst )
    235235  {
     
    239239  }
    240240
    241   const UInt  iSrcStride = getStride(ch);
    242   const UInt  iDstStride = pcYuvDst->getStride(ch);
     241  const UInt  iSrcStride = getStride(compID);
     242  const UInt  iDstStride = pcYuvDst->getStride(compID);
    243243  for ( UInt y = iHeightComponent; y != 0; y-- )
    244244  {
     
    252252
    253253
    254 Void TComYuv::copyPartToPartComponentMxN  ( const ComponentID ch, TComYuv* pcYuvDst, const TComRectangle &rect) const
    255 {
    256   const Pel* pSrc =           getAddrPix( ch, rect.x0, rect.y0 );
    257         Pel* pDst = pcYuvDst->getAddrPix( ch, rect.x0, rect.y0 );
     254Void TComYuv::copyPartToPartComponentMxN  ( const ComponentID compID, TComYuv* pcYuvDst, const TComRectangle &rect) const
     255{
     256  const Pel* pSrc =           getAddrPix( compID, rect.x0, rect.y0 );
     257        Pel* pDst = pcYuvDst->getAddrPix( compID, rect.x0, rect.y0 );
    258258  if( pSrc == pDst )
    259259  {
     
    263263  }
    264264
    265   const UInt  iSrcStride = getStride(ch);
    266   const UInt  iDstStride = pcYuvDst->getStride(ch);
     265  const UInt  iSrcStride = getStride(compID);
     266  const UInt  iDstStride = pcYuvDst->getStride(compID);
    267267  const UInt uiHeightComponent=rect.height;
    268268  const UInt uiWidthComponent=rect.width;
     
    280280Void TComYuv::addClip( const TComYuv* pcYuvSrc0, const TComYuv* pcYuvSrc1, const UInt uiTrUnitIdx, const UInt uiPartSize, const BitDepths &clipBitDepths )
    281281{
    282   for(Int chan=0; chan<getNumberValidComponents(); chan++)
    283   {
    284     const ComponentID ch=ComponentID(chan);
    285     const Int uiPartWidth =uiPartSize>>getComponentScaleX(ch);
    286     const Int uiPartHeight=uiPartSize>>getComponentScaleY(ch);
    287 
    288     const Pel* pSrc0 = pcYuvSrc0->getAddr(ch, uiTrUnitIdx, uiPartWidth );
    289     const Pel* pSrc1 = pcYuvSrc1->getAddr(ch, uiTrUnitIdx, uiPartWidth );
    290           Pel* pDst  = getAddr(ch, uiTrUnitIdx, uiPartWidth );
    291 
    292     const UInt iSrc0Stride = pcYuvSrc0->getStride(ch);
    293     const UInt iSrc1Stride = pcYuvSrc1->getStride(ch);
    294     const UInt iDstStride  = getStride(ch);
    295     const Int clipbd = clipBitDepths.recon[toChannelType(ch)];
     282  for(Int comp=0; comp<getNumberValidComponents(); comp++)
     283  {
     284    const ComponentID compID=ComponentID(comp);
     285    const Int uiPartWidth =uiPartSize>>getComponentScaleX(compID);
     286    const Int uiPartHeight=uiPartSize>>getComponentScaleY(compID);
     287
     288    const Pel* pSrc0 = pcYuvSrc0->getAddr(compID, uiTrUnitIdx, uiPartWidth );
     289    const Pel* pSrc1 = pcYuvSrc1->getAddr(compID, uiTrUnitIdx, uiPartWidth );
     290          Pel* pDst  = getAddr(compID, uiTrUnitIdx, uiPartWidth );
     291
     292    const UInt iSrc0Stride = pcYuvSrc0->getStride(compID);
     293    const UInt iSrc1Stride = pcYuvSrc1->getStride(compID);
     294    const UInt iDstStride  = getStride(compID);
     295    const Int clipbd = clipBitDepths.recon[toChannelType(compID)];
    296296#if O0043_BEST_EFFORT_DECODING
    297     const Int bitDepthDelta = clipBitDepths.stream[toChannelType(ch)] - clipbd;
     297    const Int bitDepthDelta = clipBitDepths.stream[toChannelType(compID)] - clipbd;
    298298#endif
    299299
     
    320320Void TComYuv::subtract( const TComYuv* pcYuvSrc0, const TComYuv* pcYuvSrc1, const UInt uiTrUnitIdx, const UInt uiPartSize )
    321321{
    322   for(Int chan=0; chan<getNumberValidComponents(); chan++)
    323   {
    324     const ComponentID ch=ComponentID(chan);
    325     const Int uiPartWidth =uiPartSize>>getComponentScaleX(ch);
    326     const Int uiPartHeight=uiPartSize>>getComponentScaleY(ch);
    327 
    328     const Pel* pSrc0 = pcYuvSrc0->getAddr( ch, uiTrUnitIdx, uiPartWidth );
    329     const Pel* pSrc1 = pcYuvSrc1->getAddr( ch, uiTrUnitIdx, uiPartWidth );
    330           Pel* pDst  = getAddr( ch, uiTrUnitIdx, uiPartWidth );
    331 
    332     const Int  iSrc0Stride = pcYuvSrc0->getStride(ch);
    333     const Int  iSrc1Stride = pcYuvSrc1->getStride(ch);
    334     const Int  iDstStride  = getStride(ch);
     322  for(Int comp=0; comp<getNumberValidComponents(); comp++)
     323  {
     324    const ComponentID compID=ComponentID(comp);
     325    const Int uiPartWidth =uiPartSize>>getComponentScaleX(compID);
     326    const Int uiPartHeight=uiPartSize>>getComponentScaleY(compID);
     327
     328    const Pel* pSrc0 = pcYuvSrc0->getAddr( compID, uiTrUnitIdx, uiPartWidth );
     329    const Pel* pSrc1 = pcYuvSrc1->getAddr( compID, uiTrUnitIdx, uiPartWidth );
     330          Pel* pDst  = getAddr( compID, uiTrUnitIdx, uiPartWidth );
     331
     332    const Int  iSrc0Stride = pcYuvSrc0->getStride(compID);
     333    const Int  iSrc1Stride = pcYuvSrc1->getStride(compID);
     334    const Int  iDstStride  = getStride(compID);
    335335
    336336    for (Int y = uiPartHeight-1; y >= 0; y-- )
     
    352352Void TComYuv::addAvg( const TComYuv* pcYuvSrc0, const TComYuv* pcYuvSrc1, const UInt iPartUnitIdx, const UInt uiWidth, const UInt uiHeight, const BitDepths &clipBitDepths )
    353353{
    354   for(Int chan=0; chan<getNumberValidComponents(); chan++)
    355   {
    356     const ComponentID ch=ComponentID(chan);
    357     const Pel* pSrc0  = pcYuvSrc0->getAddr( ch, iPartUnitIdx );
    358     const Pel* pSrc1  = pcYuvSrc1->getAddr( ch, iPartUnitIdx );
    359     Pel* pDst   = getAddr( ch, iPartUnitIdx );
    360 
    361     const UInt  iSrc0Stride = pcYuvSrc0->getStride(ch);
    362     const UInt  iSrc1Stride = pcYuvSrc1->getStride(ch);
    363     const UInt  iDstStride  = getStride(ch);
    364     const Int   clipbd      = clipBitDepths.recon[toChannelType(ch)];
     354  for(Int comp=0; comp<getNumberValidComponents(); comp++)
     355  {
     356    const ComponentID compID=ComponentID(comp);
     357    const Pel* pSrc0  = pcYuvSrc0->getAddr( compID, iPartUnitIdx );
     358    const Pel* pSrc1  = pcYuvSrc1->getAddr( compID, iPartUnitIdx );
     359    Pel* pDst   = getAddr( compID, iPartUnitIdx );
     360
     361    const UInt  iSrc0Stride = pcYuvSrc0->getStride(compID);
     362    const UInt  iSrc1Stride = pcYuvSrc1->getStride(compID);
     363    const UInt  iDstStride  = getStride(compID);
     364    const Int   clipbd      = clipBitDepths.recon[toChannelType(compID)];
    365365    const Int   shiftNum    = std::max<Int>(2, (IF_INTERNAL_PREC - clipbd)) + 1;
    366366    const Int   offset      = ( 1 << ( shiftNum - 1 ) ) + 2 * IF_INTERNAL_OFFS;
    367367
    368     const Int   iWidth      = uiWidth  >> getComponentScaleX(ch);
    369     const Int   iHeight     = uiHeight >> getComponentScaleY(ch);
     368    const Int   iWidth      = uiWidth  >> getComponentScaleX(compID);
     369    const Int   iHeight     = uiHeight >> getComponentScaleY(compID);
    370370
    371371    if (iWidth&1)
     
    407407}
    408408
    409 Void TComYuv::removeHighFreq( const TComYuv* pcYuvSrc, const UInt uiPartIdx, const UInt uiWidth, UInt const uiHeight )
    410 {
    411   for(Int chan=0; chan<getNumberValidComponents(); chan++)
    412   {
    413     const ComponentID ch=ComponentID(chan);
     409Void TComYuv::removeHighFreq( const TComYuv* pcYuvSrc,
     410                              const UInt uiPartIdx,
     411                              const UInt uiWidth,
     412                              const UInt uiHeight
    414413#if !DISABLING_CLIP_FOR_BIPREDME
    415     const ChannelType chType=toChannelType(ch);
     414                              ,const Int bitDepths[MAX_NUM_CHANNEL_TYPE]
    416415#endif
    417 
    418     const Pel* pSrc  = pcYuvSrc->getAddr(ch, uiPartIdx);
    419     Pel* pDst  = getAddr(ch, uiPartIdx);
    420 
    421     const Int iSrcStride = pcYuvSrc->getStride(ch);
    422     const Int iDstStride = getStride(ch);
    423     const Int iWidth  = uiWidth >>getComponentScaleX(ch);
    424     const Int iHeight = uiHeight>>getComponentScaleY(ch);
     416                              )
     417{
     418  for(Int comp=0; comp<getNumberValidComponents(); comp++)
     419  {
     420    const ComponentID compID=ComponentID(comp);
     421#if !DISABLING_CLIP_FOR_BIPREDME
     422    const Int clipBd=bitDepths[toChannelType(compID)];
     423#endif
     424
     425    const Pel* pSrc  = pcYuvSrc->getAddr(compID, uiPartIdx);
     426    Pel* pDst  = getAddr(compID, uiPartIdx);
     427
     428    const Int iSrcStride = pcYuvSrc->getStride(compID);
     429    const Int iDstStride = getStride(compID);
     430    const Int iWidth  = uiWidth >>getComponentScaleX(compID);
     431    const Int iHeight = uiHeight>>getComponentScaleY(compID);
    425432
    426433    for ( Int y = iHeight-1; y >= 0; y-- )
     
    431438        pDst[x ] = (2 * pDst[x]) - pSrc[x];
    432439#else
    433         pDst[x ] = Clip((2 * pDst[x]) - pSrc[x], chType);
     440        pDst[x ] = ClipBD((2 * pDst[x]) - pSrc[x], clipBd);
    434441#endif
    435442      }
  • branches/SHM-dev/source/Lib/TLibCommon/TComYuv.h

    r1287 r1313  
    139139  Void         addAvg                     ( const TComYuv* pcYuvSrc0, const TComYuv* pcYuvSrc1, const UInt iPartUnitIdx, const UInt iWidth, const UInt iHeight, const BitDepths &clipBitDepths );
    140140
    141   Void         removeHighFreq             ( const TComYuv* pcYuvSrc, const UInt uiPartIdx, const UInt uiWidth, const UInt uiHeight );
     141  Void         removeHighFreq             ( const TComYuv* pcYuvSrc, const UInt uiPartIdx, const UInt uiWidth, const UInt uiHeight
     142#if !DISABLING_CLIP_FOR_BIPREDME
     143                                          , const Int bitDepths[MAX_NUM_CHANNEL_TYPE]
     144#endif
     145                                          );
    142146
    143147  // ------------------------------------------------------------------------------------------------------------------
  • branches/SHM-dev/source/Lib/TLibEncoder/TEncSearch.cpp

    r1307 r1313  
    38923892    pcYuvOrg->copyPartToPartYuv( pcYuv, uiPartAddr, iRoiWidth, iRoiHeight );
    38933893
    3894     pcYuv->removeHighFreq( pcYuvOther, uiPartAddr, iRoiWidth, iRoiHeight );
     3894    pcYuv->removeHighFreq( pcYuvOther, uiPartAddr, iRoiWidth, iRoiHeight
     3895#if !DISABLING_CLIP_FOR_BIPREDME
     3896                          , pcCU->getSlice()->getSPS()->getBitDepths().recon
     3897#endif
     3898                          );
    38953899
    38963900    fWeight = 0.5;
Note: See TracChangeset for help on using the changeset viewer.