HEVC Test Model (HM)  HM-16.3
TComSampleAdaptiveOffset.cpp
Go to the documentation of this file.
1 /* The copyright in this software is being made available under the BSD
2  * License, included below. This software may be subject to other third party
3  * and contributor rights, including patent rights, and no such rights are
4  * granted under this license.
5  *
6  * Copyright (c) 2010-2015, ITU/ISO/IEC
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above copyright notice,
15  * this list of conditions and the following disclaimer in the documentation
16  * and/or other materials provided with the distribution.
17  * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18  * be used to endorse or promote products derived from this software without
19  * specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31  * THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
39 #include <string.h>
40 #include <stdlib.h>
41 #include <stdio.h>
42 #include <math.h>
43 
46 
48 
50 {
51  reset();
52 }
53 
55 {
56 
57 }
58 
60 {
62  typeIdc = -1;
63  typeAuxInfo = -1;
64  ::memset(offset, 0, sizeof(Int)* MAX_NUM_SAO_CLASSES);
65 }
66 
68 {
69  modeIdc = src.modeIdc;
70  typeIdc = src.typeIdc;
72  ::memcpy(offset, src.offset, sizeof(Int)* MAX_NUM_SAO_CLASSES);
73 
74  return *this;
75 }
76 
77 
79 {
80  reset();
81 }
82 
84 {
85 
86 }
87 
89 {
90  for(Int compIdx = 0; compIdx < MAX_NUM_COMPONENT; compIdx++)
91  {
92  offsetParam[compIdx].reset();
93  }
94 }
95 
97 {
98  for(Int compIdx = 0; compIdx < MAX_NUM_COMPONENT; compIdx++)
99  {
100  offsetParam[compIdx] = src.offsetParam[compIdx];
101  }
102  return *this;
103 
104 }
105 
107 {
108  m_tempPicYuv = NULL;
109  m_lineBufWidth = 0;
112 }
113 
114 
116 {
117  destroy();
118 
119  if (m_signLineBuf1)
120  {
121  delete[] m_signLineBuf1;
123  }
124  if (m_signLineBuf2)
125  {
126  delete[] m_signLineBuf2;
128  }
129 }
130 
131 Void TComSampleAdaptiveOffset::create( Int picWidth, Int picHeight, ChromaFormat format, UInt maxCUWidth, UInt maxCUHeight, UInt maxCUDepth, UInt lumaBitShift, UInt chromaBitShift )
132 {
133  destroy();
134 
135  m_picWidth = picWidth;
136  m_picHeight = picHeight;
137  m_chromaFormatIDC = format;
138  m_maxCUWidth = maxCUWidth;
139  m_maxCUHeight = maxCUHeight;
140 
144 
145  //temporary picture buffer
146  if ( !m_tempPicYuv )
147  {
148  m_tempPicYuv = new TComPicYuv;
149  m_tempPicYuv->create( m_picWidth, m_picHeight, m_chromaFormatIDC, m_maxCUWidth, m_maxCUHeight, maxCUDepth );
150  }
151 
152  //bit-depth related
153  for(Int compIdx = 0; compIdx < MAX_NUM_COMPONENT; compIdx++)
154  {
155  Int bitDepthSample = g_bitDepth[toChannelType(ComponentID(compIdx))];
156  m_offsetStepLog2 [compIdx] = isLuma(ComponentID(compIdx))? lumaBitShift : chromaBitShift;
157  g_saoMaxOffsetQVal[compIdx] = (1<<(min(bitDepthSample,MAX_SAO_TRUNCATED_BITDEPTH)-5))-1; //Table 9-32, inclusive
158  }
159 }
160 
162 {
163  if ( m_tempPicYuv )
164  {
166  delete m_tempPicYuv;
167  m_tempPicYuv = NULL;
168  }
169 }
170 
171 Void TComSampleAdaptiveOffset::invertQuantOffsets(ComponentID compIdx, Int typeIdc, Int typeAuxInfo, Int* dstOffsets, Int* srcOffsets)
172 {
173  Int codedOffset[MAX_NUM_SAO_CLASSES];
174 
175  ::memcpy(codedOffset, srcOffsets, sizeof(Int)*MAX_NUM_SAO_CLASSES);
176  ::memset(dstOffsets, 0, sizeof(Int)*MAX_NUM_SAO_CLASSES);
177 
178  if(typeIdc == SAO_TYPE_START_BO)
179  {
180  for(Int i=0; i< 4; i++)
181  {
182  dstOffsets[(typeAuxInfo+ i)%NUM_SAO_BO_CLASSES] = codedOffset[(typeAuxInfo+ i)%NUM_SAO_BO_CLASSES]*(1<<m_offsetStepLog2[compIdx]);
183  }
184  }
185  else //EO
186  {
187  for(Int i=0; i< NUM_SAO_EO_CLASSES; i++)
188  {
189  dstOffsets[i] = codedOffset[i] *(1<<m_offsetStepLog2[compIdx]);
190  }
191  assert(dstOffsets[SAO_CLASS_EO_PLAIN] == 0); //keep EO plain offset as zero
192  }
193 
194 }
195 
197 {
198  Int ctuX = ctuRsAddr % m_numCTUInWidth;
199  Int ctuY = ctuRsAddr / m_numCTUInWidth;
200  Int mergedCTUPos;
201  Int numValidMergeCandidates = 0;
202 
203  for(Int mergeType=0; mergeType< NUM_SAO_MERGE_TYPES; mergeType++)
204  {
205  SAOBlkParam* mergeCandidate = NULL;
206 
207  switch(mergeType)
208  {
209  case SAO_MERGE_ABOVE:
210  {
211  if(ctuY > 0)
212  {
213  mergedCTUPos = ctuRsAddr- m_numCTUInWidth;
214  if( pic->getSAOMergeAvailability(ctuRsAddr, mergedCTUPos) )
215  {
216  mergeCandidate = &(blkParams[mergedCTUPos]);
217  }
218  }
219  }
220  break;
221  case SAO_MERGE_LEFT:
222  {
223  if(ctuX > 0)
224  {
225  mergedCTUPos = ctuRsAddr- 1;
226  if( pic->getSAOMergeAvailability(ctuRsAddr, mergedCTUPos) )
227  {
228  mergeCandidate = &(blkParams[mergedCTUPos]);
229  }
230  }
231  }
232  break;
233  default:
234  {
235  printf("not a supported merge type");
236  assert(0);
237  exit(-1);
238  }
239  }
240 
241  mergeList[mergeType]=mergeCandidate;
242  if (mergeCandidate != NULL)
243  {
244  numValidMergeCandidates++;
245  }
246  }
247 
248  return numValidMergeCandidates;
249 }
250 
251 
253 {
254  const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
255  for(Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
256  {
257  const ComponentID component = ComponentID(compIdx);
258  SAOOffset& offsetParam = recParam[component];
259 
260  if(offsetParam.modeIdc == SAO_MODE_OFF)
261  {
262  continue;
263  }
264 
265  switch(offsetParam.modeIdc)
266  {
267  case SAO_MODE_NEW:
268  {
269  invertQuantOffsets(component, offsetParam.typeIdc, offsetParam.typeAuxInfo, offsetParam.offset, offsetParam.offset);
270  }
271  break;
272  case SAO_MODE_MERGE:
273  {
274  SAOBlkParam* mergeTarget = mergeList[offsetParam.typeIdc];
275  assert(mergeTarget != NULL);
276 
277  offsetParam = (*mergeTarget)[component];
278  }
279  break;
280  default:
281  {
282  printf("Not a supported mode");
283  assert(0);
284  exit(-1);
285  }
286  }
287  }
288 }
289 
291 {
292  for(Int compIdx = 0; compIdx < MAX_NUM_COMPONENT; compIdx++)
293  {
294  m_picSAOEnabled[compIdx] = false;
295  }
296 
297  const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
298 
299  for(Int ctuRsAddr=0; ctuRsAddr< m_numCTUsPic; ctuRsAddr++)
300  {
301  SAOBlkParam* mergeList[NUM_SAO_MERGE_TYPES] = { NULL };
302  getMergeList(pic, ctuRsAddr, saoBlkParams, mergeList);
303 
304  reconstructBlkSAOParam(saoBlkParams[ctuRsAddr], mergeList);
305 
306  for(Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
307  {
308  if(saoBlkParams[ctuRsAddr][compIdx].modeIdc != SAO_MODE_OFF)
309  {
310  m_picSAOEnabled[compIdx] = true;
311  }
312  }
313  }
314 }
315 
316 
318  , Pel* srcBlk, Pel* resBlk, Int srcStride, Int resStride, Int width, Int height
319  , Bool isLeftAvail, Bool isRightAvail, Bool isAboveAvail, Bool isBelowAvail, Bool isAboveLeftAvail, Bool isAboveRightAvail, Bool isBelowLeftAvail, Bool isBelowRightAvail)
320 {
322  {
324 
325  if (m_signLineBuf1)
326  {
327  delete[] m_signLineBuf1;
329  }
331 
332  if (m_signLineBuf2)
333  {
334  delete[] m_signLineBuf2;
336  }
338  }
339 
340  const Int maxSampleValueIncl = (1<< g_bitDepth[toChannelType(compIdx)] )-1;
341 
342  Int x,y, startX, startY, endX, endY, edgeType;
343  Int firstLineStartX, firstLineEndX, lastLineStartX, lastLineEndX;
344  Char signLeft, signRight, signDown;
345 
346  Pel* srcLine = srcBlk;
347  Pel* resLine = resBlk;
348 
349  switch(typeIdx)
350  {
351  case SAO_TYPE_EO_0:
352  {
353  offset += 2;
354  startX = isLeftAvail ? 0 : 1;
355  endX = isRightAvail ? width : (width -1);
356  for (y=0; y< height; y++)
357  {
358  signLeft = (Char)sgn(srcLine[startX] - srcLine[startX-1]);
359  for (x=startX; x< endX; x++)
360  {
361  signRight = (Char)sgn(srcLine[x] - srcLine[x+1]);
362  edgeType = signRight + signLeft;
363  signLeft = -signRight;
364 
365  resLine[x] = Clip3<Int>(0, maxSampleValueIncl, srcLine[x] + offset[edgeType]);
366  }
367  srcLine += srcStride;
368  resLine += resStride;
369  }
370 
371  }
372  break;
373  case SAO_TYPE_EO_90:
374  {
375  offset += 2;
376  Char *signUpLine = m_signLineBuf1;
377 
378  startY = isAboveAvail ? 0 : 1;
379  endY = isBelowAvail ? height : height-1;
380  if (!isAboveAvail)
381  {
382  srcLine += srcStride;
383  resLine += resStride;
384  }
385 
386  Pel* srcLineAbove= srcLine- srcStride;
387  for (x=0; x< width; x++)
388  {
389  signUpLine[x] = (Char)sgn(srcLine[x] - srcLineAbove[x]);
390  }
391 
392  Pel* srcLineBelow;
393  for (y=startY; y<endY; y++)
394  {
395  srcLineBelow= srcLine+ srcStride;
396 
397  for (x=0; x< width; x++)
398  {
399  signDown = (Char)sgn(srcLine[x] - srcLineBelow[x]);
400  edgeType = signDown + signUpLine[x];
401  signUpLine[x]= -signDown;
402 
403  resLine[x] = Clip3<Int>(0, maxSampleValueIncl, srcLine[x] + offset[edgeType]);
404  }
405  srcLine += srcStride;
406  resLine += resStride;
407  }
408 
409  }
410  break;
411  case SAO_TYPE_EO_135:
412  {
413  offset += 2;
414  Char *signUpLine, *signDownLine, *signTmpLine;
415 
416  signUpLine = m_signLineBuf1;
417  signDownLine= m_signLineBuf2;
418 
419  startX = isLeftAvail ? 0 : 1 ;
420  endX = isRightAvail ? width : (width-1);
421 
422  //prepare 2nd line's upper sign
423  Pel* srcLineBelow= srcLine+ srcStride;
424  for (x=startX; x< endX+1; x++)
425  {
426  signUpLine[x] = (Char)sgn(srcLineBelow[x] - srcLine[x- 1]);
427  }
428 
429  //1st line
430  Pel* srcLineAbove= srcLine- srcStride;
431  firstLineStartX = isAboveLeftAvail ? 0 : 1;
432  firstLineEndX = isAboveAvail? endX: 1;
433  for(x= firstLineStartX; x< firstLineEndX; x++)
434  {
435  edgeType = sgn(srcLine[x] - srcLineAbove[x- 1]) - signUpLine[x+1];
436 
437  resLine[x] = Clip3<Int>(0, maxSampleValueIncl, srcLine[x] + offset[edgeType]);
438  }
439  srcLine += srcStride;
440  resLine += resStride;
441 
442 
443  //middle lines
444  for (y= 1; y< height-1; y++)
445  {
446  srcLineBelow= srcLine+ srcStride;
447 
448  for (x=startX; x<endX; x++)
449  {
450  signDown = (Char)sgn(srcLine[x] - srcLineBelow[x+ 1]);
451  edgeType = signDown + signUpLine[x];
452  resLine[x] = Clip3<Int>(0, maxSampleValueIncl, srcLine[x] + offset[edgeType]);
453 
454  signDownLine[x+1] = -signDown;
455  }
456  signDownLine[startX] = (Char)sgn(srcLineBelow[startX] - srcLine[startX-1]);
457 
458  signTmpLine = signUpLine;
459  signUpLine = signDownLine;
460  signDownLine = signTmpLine;
461 
462  srcLine += srcStride;
463  resLine += resStride;
464  }
465 
466  //last line
467  srcLineBelow= srcLine+ srcStride;
468  lastLineStartX = isBelowAvail ? startX : (width -1);
469  lastLineEndX = isBelowRightAvail ? width : (width -1);
470  for(x= lastLineStartX; x< lastLineEndX; x++)
471  {
472  edgeType = sgn(srcLine[x] - srcLineBelow[x+ 1]) + signUpLine[x];
473  resLine[x] = Clip3<Int>(0, maxSampleValueIncl, srcLine[x] + offset[edgeType]);
474 
475  }
476  }
477  break;
478  case SAO_TYPE_EO_45:
479  {
480  offset += 2;
481  Char *signUpLine = m_signLineBuf1+1;
482 
483  startX = isLeftAvail ? 0 : 1;
484  endX = isRightAvail ? width : (width -1);
485 
486  //prepare 2nd line upper sign
487  Pel* srcLineBelow= srcLine+ srcStride;
488  for (x=startX-1; x< endX; x++)
489  {
490  signUpLine[x] = (Char)sgn(srcLineBelow[x] - srcLine[x+1]);
491  }
492 
493 
494  //first line
495  Pel* srcLineAbove= srcLine- srcStride;
496  firstLineStartX = isAboveAvail ? startX : (width -1 );
497  firstLineEndX = isAboveRightAvail ? width : (width-1);
498  for(x= firstLineStartX; x< firstLineEndX; x++)
499  {
500  edgeType = sgn(srcLine[x] - srcLineAbove[x+1]) -signUpLine[x-1];
501  resLine[x] = Clip3<Int>(0, maxSampleValueIncl, srcLine[x] + offset[edgeType]);
502  }
503  srcLine += srcStride;
504  resLine += resStride;
505 
506  //middle lines
507  for (y= 1; y< height-1; y++)
508  {
509  srcLineBelow= srcLine+ srcStride;
510 
511  for(x= startX; x< endX; x++)
512  {
513  signDown = (Char)sgn(srcLine[x] - srcLineBelow[x-1]);
514  edgeType = signDown + signUpLine[x];
515  resLine[x] = Clip3<Int>(0, maxSampleValueIncl, srcLine[x] + offset[edgeType]);
516  signUpLine[x-1] = -signDown;
517  }
518  signUpLine[endX-1] = (Char)sgn(srcLineBelow[endX-1] - srcLine[endX]);
519  srcLine += srcStride;
520  resLine += resStride;
521  }
522 
523  //last line
524  srcLineBelow= srcLine+ srcStride;
525  lastLineStartX = isBelowLeftAvail ? 0 : 1;
526  lastLineEndX = isBelowAvail ? endX : 1;
527  for(x= lastLineStartX; x< lastLineEndX; x++)
528  {
529  edgeType = sgn(srcLine[x] - srcLineBelow[x-1]) + signUpLine[x];
530  resLine[x] = Clip3<Int>(0, maxSampleValueIncl, srcLine[x] + offset[edgeType]);
531 
532  }
533  }
534  break;
535  case SAO_TYPE_BO:
536  {
537  const Int shiftBits = g_bitDepth[toChannelType(compIdx)] - NUM_SAO_BO_CLASSES_LOG2;
538  for (y=0; y< height; y++)
539  {
540  for (x=0; x< width; x++)
541  {
542  resLine[x] = Clip3<Int>(0, maxSampleValueIncl, srcLine[x] + offset[srcLine[x] >> shiftBits] );
543  }
544  srcLine += srcStride;
545  resLine += resStride;
546  }
547  }
548  break;
549  default:
550  {
551  printf("Not a supported SAO types\n");
552  assert(0);
553  exit(-1);
554  }
555  }
556 }
557 
558 Void TComSampleAdaptiveOffset::offsetCTU(Int ctuRsAddr, TComPicYuv* srcYuv, TComPicYuv* resYuv, SAOBlkParam& saoblkParam, TComPic* pPic)
559 {
560  Bool isLeftAvail,isRightAvail,isAboveAvail,isBelowAvail,isAboveLeftAvail,isAboveRightAvail,isBelowLeftAvail,isBelowRightAvail;
561 
562  const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
563  Bool bAllOff=true;
564  for(Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
565  {
566  if (saoblkParam[compIdx].modeIdc != SAO_MODE_OFF)
567  {
568  bAllOff=false;
569  }
570  }
571  if (bAllOff)
572  {
573  return;
574  }
575 
576  //block boundary availability
577  pPic->getPicSym()->deriveLoopFilterBoundaryAvailibility(ctuRsAddr, isLeftAvail,isRightAvail,isAboveAvail,isBelowAvail,isAboveLeftAvail,isAboveRightAvail,isBelowLeftAvail,isBelowRightAvail);
578 
579  Int yPos = (ctuRsAddr / m_numCTUInWidth)*m_maxCUHeight;
580  Int xPos = (ctuRsAddr % m_numCTUInWidth)*m_maxCUWidth;
581  Int height = (yPos + m_maxCUHeight > m_picHeight)?(m_picHeight- yPos):m_maxCUHeight;
582  Int width = (xPos + m_maxCUWidth > m_picWidth )?(m_picWidth - xPos):m_maxCUWidth;
583 
584  for(Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
585  {
586  const ComponentID component = ComponentID(compIdx);
587  SAOOffset& ctbOffset = saoblkParam[compIdx];
588 
589  if(ctbOffset.modeIdc != SAO_MODE_OFF)
590  {
591  const UInt componentScaleX = getComponentScaleX(component, pPic->getChromaFormat());
592  const UInt componentScaleY = getComponentScaleY(component, pPic->getChromaFormat());
593 
594  Int blkWidth = (width >> componentScaleX);
595  Int blkHeight = (height >> componentScaleY);
596  Int blkXPos = (xPos >> componentScaleX);
597  Int blkYPos = (yPos >> componentScaleY);
598 
599  Int srcStride = srcYuv->getStride(component);
600  Pel* srcBlk = srcYuv->getAddr(component) + blkYPos*srcStride + blkXPos;
601 
602  Int resStride = resYuv->getStride(component);
603  Pel* resBlk = resYuv->getAddr(component) + blkYPos*resStride + blkXPos;
604 
605  offsetBlock( component, ctbOffset.typeIdc, ctbOffset.offset
606  , srcBlk, resBlk, srcStride, resStride, blkWidth, blkHeight
607  , isLeftAvail, isRightAvail
608  , isAboveAvail, isBelowAvail
609  , isAboveLeftAvail, isAboveRightAvail
610  , isBelowLeftAvail, isBelowRightAvail
611  );
612  }
613  } //compIdx
614 
615 }
616 
617 
619 {
620  const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
621  Bool bAllDisabled=true;
622  for(Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
623  {
624  if (m_picSAOEnabled[compIdx])
625  {
626  bAllDisabled=false;
627  }
628  }
629  if (bAllDisabled)
630  {
631  return;
632  }
633 
634  TComPicYuv* resYuv = pDecPic->getPicYuvRec();
635  TComPicYuv* srcYuv = m_tempPicYuv;
636  resYuv->copyToPic(srcYuv);
637  for(Int ctuRsAddr= 0; ctuRsAddr < m_numCTUsPic; ctuRsAddr++)
638  {
639  offsetCTU(ctuRsAddr, srcYuv, resYuv, (pDecPic->getPicSym()->getSAOBlkParam())[ctuRsAddr], pDecPic);
640  } //ctu
641 }
642 
643 
650 {
651  xPCMRestoration(pcPic);
652 }
653 
658 {
659  Bool bPCMFilter = (pcPic->getSlice(0)->getSPS()->getUsePCM() && pcPic->getSlice(0)->getSPS()->getPCMFilterDisableFlag())? true : false;
660 
661  if(bPCMFilter || pcPic->getSlice(0)->getPPS()->getTransquantBypassEnableFlag())
662  {
663  for( UInt ctuRsAddr = 0; ctuRsAddr < pcPic->getNumberOfCtusInFrame() ; ctuRsAddr++ )
664  {
665  TComDataCU* pcCU = pcPic->getCtu(ctuRsAddr);
666 
667  xPCMCURestoration(pcCU, 0, 0);
668  }
669  }
670 }
671 
678 {
679  TComPic* pcPic = pcCU->getPic();
680  UInt uiCurNumParts = pcPic->getNumPartitionsInCtu() >> (uiDepth<<1);
681  UInt uiQNumParts = uiCurNumParts>>2;
682 
683  // go to sub-CU
684  if( pcCU->getDepth(uiAbsZorderIdx) > uiDepth )
685  {
686  for ( UInt uiPartIdx = 0; uiPartIdx < 4; uiPartIdx++, uiAbsZorderIdx+=uiQNumParts )
687  {
688  UInt uiLPelX = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsZorderIdx] ];
689  UInt uiTPelY = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsZorderIdx] ];
690  if( ( uiLPelX < pcCU->getSlice()->getSPS()->getPicWidthInLumaSamples() ) && ( uiTPelY < pcCU->getSlice()->getSPS()->getPicHeightInLumaSamples() ) )
691  {
692  xPCMCURestoration( pcCU, uiAbsZorderIdx, uiDepth+1 );
693  }
694  }
695  return;
696  }
697 
698  // restore PCM samples
699  if ((pcCU->getIPCMFlag(uiAbsZorderIdx)&& pcPic->getSlice(0)->getSPS()->getPCMFilterDisableFlag()) || pcCU->isLosslessCoded( uiAbsZorderIdx))
700  {
701  const UInt numComponents=pcPic->getNumberValidComponents();
702  for(UInt comp=0; comp<numComponents; comp++)
703  {
704  xPCMSampleRestoration (pcCU, uiAbsZorderIdx, uiDepth, ComponentID(comp));
705  }
706  }
707 }
708 
716 {
717  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec();
718  UInt uiPcmLeftShiftBit;
719  const UInt uiMinCoeffSize = pcCU->getPic()->getMinCUWidth()*pcCU->getPic()->getMinCUHeight();
720  const UInt csx=pcPicYuvRec->getComponentScaleX(compID);
721  const UInt csy=pcPicYuvRec->getComponentScaleY(compID);
722  const UInt uiOffset = (uiMinCoeffSize*uiAbsZorderIdx)>>(csx+csy);
723 
724  Pel *piSrc = pcPicYuvRec->getAddr(compID, pcCU->getCtuRsAddr(), uiAbsZorderIdx);
725  const Pel *piPcm = pcCU->getPCMSample(compID) + uiOffset;
726  const UInt uiStride = pcPicYuvRec->getStride(compID);
727  const UInt uiWidth = ((g_uiMaxCUWidth >> uiDepth) >> csx);
728  const UInt uiHeight = ((g_uiMaxCUWidth >> uiDepth) >> csy);
729 
730  if ( pcCU->isLosslessCoded(uiAbsZorderIdx) && !pcCU->getIPCMFlag(uiAbsZorderIdx) )
731  {
732  uiPcmLeftShiftBit = 0;
733  }
734  else
735  {
736  uiPcmLeftShiftBit = g_bitDepth[toChannelType(compID)] - pcCU->getSlice()->getSPS()->getPCMBitDepth(toChannelType(compID));
737  }
738 
739  for(UInt uiY = 0; uiY < uiHeight; uiY++ )
740  {
741  for(UInt uiX = 0; uiX < uiWidth; uiX++ )
742  {
743  piSrc[uiX] = (piPcm[uiX] << uiPcmLeftShiftBit);
744  }
745  piPcm += uiWidth;
746  piSrc += uiStride;
747  }
748 }
749 
Bool getPCMFilterDisableFlag() const
Definition: TComSlice.h:918
Void xPCMCURestoration(TComDataCU *pcCU, UInt uiAbsZorderIdx, UInt uiDepth)
sample adaptive offset class (header)
#define NUM_SAO_BO_CLASSES_LOG2
Definition: TypeDef.h:611
#define MAX_NUM_SAO_CLASSES
Definition: TypeDef.h:709
Void create(const Int iPicWidth, const Int iPicHeight, const ChromaFormat chromaFormatIDC, const UInt uiMaxCUWidth, const UInt uiMaxCUHeight, const UInt uiMaxCUDepth)
Definition: TComPicYuv.cpp:81
picture YUV buffer class
Definition: TComPicYuv.h:55
CU data structure class.
Definition: TComDataCU.h:64
Int typeAuxInfo
Definition: TypeDef.h:715
UInt getNumberOfCtusInFrame() const
Definition: TComPic.h:116
picture class (symbol + YUV buffers)
Definition: TComPic.h:56
void Void
Definition: TypeDef.h:285
Void offsetBlock(ComponentID compIdx, Int typeIdx, Int *offset, Pel *srcBlk, Pel *resBlk, Int srcStride, Int resStride, Int width, Int height, Bool isLeftAvail, Bool isRightAvail, Bool isAboveAvail, Bool isBelowAvail, Bool isAboveLeftAvail, Bool isAboveRightAvail, Bool isBelowLeftAvail, Bool isBelowRightAvail)
Int getStride(const ComponentID id) const
Definition: TComPicYuv.h:113
UInt g_auiRasterToPelX[((1<<(6))/4)*((1<<(6))/4)]
Definition: TComRom.cpp:257
#define NULL
Definition: CommonDef.h:100
Int typeIdc
Definition: TypeDef.h:714
TComSlice * getSlice(Int i)
Definition: TComPic.h:103
static UInt getComponentScaleY(const ComponentID id, const ChromaFormat fmt)
Int offset[32]
Definition: TypeDef.h:716
char Char
Definition: TypeDef.h:291
unsigned int UInt
Definition: TypeDef.h:297
UInt getNumPartitionsInCtu() const
Definition: TComPic.h:119
static UInt getComponentScaleX(const ComponentID id, const ChromaFormat fmt)
Short Pel
pixel type
Definition: TypeDef.h:692
Bool m_picSAOEnabled[MAX_NUM_COMPONENT]
Int sgn(T val)
Int getNumberValidComponents() const
Definition: TComPic.h:129
Int getMergeList(TComPic *pic, Int ctuRsAddr, SAOBlkParam *blkParams, SAOBlkParam *mergeList[NUM_SAO_MERGE_TYPES])
Void invertQuantOffsets(ComponentID compIdx, Int typeIdc, Int typeAuxInfo, Int *dstOffsets, Int *srcOffsets)
Void reconstructBlkSAOParam(SAOBlkParam &recParam, SAOBlkParam *mergeList[NUM_SAO_MERGE_TYPES])
UInt getMinCUWidth() const
Definition: TComPic.h:122
Bool getTransquantBypassEnableFlag() const
Definition: TComSlice.h:1116
TComPicYuv * getPicYuvRec()
Definition: TComPic.h:109
Void xPCMSampleRestoration(TComDataCU *pcCU, UInt uiAbsZorderIdx, UInt uiDepth, const ComponentID compID)
Bool * getIPCMFlag()
Definition: TComDataCU.h:350
Void offsetCTU(Int ctuRsAddr, TComPicYuv *srcYuv, TComPicYuv *resYuv, SAOBlkParam &saoblkParam, TComPic *pPic)
Void create(Int picWidth, Int picHeight, ChromaFormat format, UInt maxCUWidth, UInt maxCUHeight, UInt maxCUDepth, UInt lumaBitShift, UInt chromaBitShift)
UInt m_offsetStepLog2[MAX_NUM_COMPONENT]
#define MAX_SAO_TRUNCATED_BITDEPTH
SAOOffset offsetParam[MAX_NUM_COMPONENT]
Definition: TypeDef.h:734
#define NUM_SAO_BO_CLASSES
Definition: TypeDef.h:612
UInt getComponentScaleY(const ComponentID id) const
Definition: TComPicYuv.h:139
UInt getComponentScaleX(const ComponentID id) const
Definition: TComPicYuv.h:138
Bool getSAOMergeAvailability(Int currAddr, Int mergeAddr)
Definition: TComPic.cpp:118
bool Bool
Definition: TypeDef.h:286
UInt g_uiMaxCUWidth
Definition: TComRom.cpp:251
UInt getMinCUHeight() const
Definition: TComPic.h:123
Void copyToPic(TComPicYuv *pcPicYuvDst) const
Definition: TComPicYuv.cpp:176
UInt & getCtuRsAddr()
Definition: TComDataCU.h:207
UInt getCUPelY() const
Definition: TComDataCU.h:211
static ChannelType toChannelType(const ComponentID id)
UInt g_auiZscanToRaster[((1<<(6))/4)*((1<<(6))/4)]
Definition: TComRom.cpp:255
SAOMode modeIdc
Definition: TypeDef.h:713
TComPicSym * getPicSym()
Definition: TComPic.h:102
ChromaFormat
chroma formats (according to semantics of chroma_format_idc)
Definition: TypeDef.h:352
UInt g_auiRasterToPelY[((1<<(6))/4)*((1<<(6))/4)]
Definition: TComRom.cpp:258
UChar * getDepth()
Definition: TComDataCU.h:213
Void PCMLFDisableProcess(TComPic *pcPic)
const TComPPS * getPPS() const
Definition: TComSlice.h:1309
UInt getCUPelX() const
Definition: TComDataCU.h:210
ChromaFormat getChromaFormat() const
Definition: TComPic.h:128
const SAOBlkParam & operator=(const SAOBlkParam &src)
Bool getUsePCM() const
Definition: TComSlice.h:851
TComPic * getPic()
Definition: TComDataCU.h:203
Int g_bitDepth[MAX_NUM_CHANNEL_TYPE]
Definition: TComRom.cpp:548
TComDataCU * getCtu(UInt ctuRsAddr)
Definition: TComPic.h:105
Pel * getAddr(const ComponentID ch)
Definition: TComPicYuv.h:127
Void deriveLoopFilterBoundaryAvailibility(Int ctuRsAddr, Bool &isLeftAvail, Bool &isRightAvail, Bool &isAboveAvail, Bool &isBelowAvail, Bool &isAboveLeftAvail, Bool &isAboveRightAvail, Bool &isBelowLeftAvail, Bool &isBelowRightAvail)
Definition: TComPicSym.cpp:357
const SAOOffset & operator=(const SAOOffset &src)
int Int
Definition: TypeDef.h:296
UInt getPCMBitDepth(ChannelType type) const
Definition: TComSlice.h:915
ComponentID
Definition: TypeDef.h:368
Void reconstructBlkSAOParams(TComPic *pic, SAOBlkParam *saoBlkParams)
Pel * getPCMSample(ComponentID component)
Definition: TComDataCU.h:301
static UInt getNumberValidComponents(const ChromaFormat fmt)
Bool isLosslessCoded(UInt absPartIdx)
UInt g_saoMaxOffsetQVal[MAX_NUM_COMPONENT]
Void destroy()
Definition: TComPicYuv.cpp:146
static Bool isLuma(const ComponentID id)
TComSlice * getSlice()
Definition: TComDataCU.h:205
const TComSPS * getSPS() const
Definition: TComSlice.h:1306
SAOBlkParam * getSAOBlkParam()
Definition: TComPicSym.h:153