HEVC Test Model (HM)  HM-16.18
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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-2017, 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 {
49  reset();
50 }
51 
53 {
54 
55 }
56 
58 {
60  typeIdc = -1;
61  typeAuxInfo = -1;
62  ::memset(offset, 0, sizeof(Int)* MAX_NUM_SAO_CLASSES);
63 }
64 
66 {
67  modeIdc = src.modeIdc;
68  typeIdc = src.typeIdc;
70  ::memcpy(offset, src.offset, sizeof(Int)* MAX_NUM_SAO_CLASSES);
71 
72  return *this;
73 }
74 
75 
77 {
78  reset();
79 }
80 
82 {
83 
84 }
85 
87 {
88  for(Int compIdx = 0; compIdx < MAX_NUM_COMPONENT; compIdx++)
89  {
90  offsetParam[compIdx].reset();
91  }
92 }
93 
95 {
96  for(Int compIdx = 0; compIdx < MAX_NUM_COMPONENT; compIdx++)
97  {
98  offsetParam[compIdx] = src.offsetParam[compIdx];
99  }
100  return *this;
101 
102 }
103 
105 {
106  m_tempPicYuv = NULL;
107  m_lineBufWidth = 0;
110 }
111 
112 
114 {
115  destroy();
116 
117  if (m_signLineBuf1)
118  {
119  delete[] m_signLineBuf1;
121  }
122  if (m_signLineBuf2)
123  {
124  delete[] m_signLineBuf2;
126  }
127 }
128 
129 Void TComSampleAdaptiveOffset::create( Int picWidth, Int picHeight, ChromaFormat format, UInt maxCUWidth, UInt maxCUHeight, UInt maxCUDepth, UInt lumaBitShift, UInt chromaBitShift )
130 {
131  destroy();
132 
133  m_picWidth = picWidth;
134  m_picHeight = picHeight;
135  m_chromaFormatIDC = format;
136  m_maxCUWidth = maxCUWidth;
137  m_maxCUHeight = maxCUHeight;
138 
142 
143  //temporary picture buffer
144  if ( !m_tempPicYuv )
145  {
146  m_tempPicYuv = new TComPicYuv;
147  m_tempPicYuv->create( m_picWidth, m_picHeight, m_chromaFormatIDC, m_maxCUWidth, m_maxCUHeight, maxCUDepth, true );
148  }
149 
150  //bit-depth related
151  for(Int compIdx = 0; compIdx < MAX_NUM_COMPONENT; compIdx++)
152  {
153  m_offsetStepLog2 [compIdx] = isLuma(ComponentID(compIdx))? lumaBitShift : chromaBitShift;
154  }
155 }
156 
158 {
159  if ( m_tempPicYuv )
160  {
162  delete m_tempPicYuv;
163  m_tempPicYuv = NULL;
164  }
165 }
166 
167 Void TComSampleAdaptiveOffset::invertQuantOffsets(ComponentID compIdx, Int typeIdc, Int typeAuxInfo, Int* dstOffsets, Int* srcOffsets)
168 {
169  Int codedOffset[MAX_NUM_SAO_CLASSES];
170 
171  ::memcpy(codedOffset, srcOffsets, sizeof(Int)*MAX_NUM_SAO_CLASSES);
172  ::memset(dstOffsets, 0, sizeof(Int)*MAX_NUM_SAO_CLASSES);
173 
174  if(typeIdc == SAO_TYPE_START_BO)
175  {
176  for(Int i=0; i< 4; i++)
177  {
178  dstOffsets[(typeAuxInfo+ i)%NUM_SAO_BO_CLASSES] = codedOffset[(typeAuxInfo+ i)%NUM_SAO_BO_CLASSES]*(1<<m_offsetStepLog2[compIdx]);
179  }
180  }
181  else //EO
182  {
183  for(Int i=0; i< NUM_SAO_EO_CLASSES; i++)
184  {
185  dstOffsets[i] = codedOffset[i] *(1<<m_offsetStepLog2[compIdx]);
186  }
187  assert(dstOffsets[SAO_CLASS_EO_PLAIN] == 0); //keep EO plain offset as zero
188  }
189 
190 }
191 
193 {
194  Int ctuX = ctuRsAddr % m_numCTUInWidth;
195  Int ctuY = ctuRsAddr / m_numCTUInWidth;
196  Int mergedCTUPos;
197  Int numValidMergeCandidates = 0;
198 
199  for(Int mergeType=0; mergeType< NUM_SAO_MERGE_TYPES; mergeType++)
200  {
201  SAOBlkParam* mergeCandidate = NULL;
202 
203  switch(mergeType)
204  {
205  case SAO_MERGE_ABOVE:
206  {
207  if(ctuY > 0)
208  {
209  mergedCTUPos = ctuRsAddr- m_numCTUInWidth;
210  if( pic->getSAOMergeAvailability(ctuRsAddr, mergedCTUPos) )
211  {
212  mergeCandidate = &(blkParams[mergedCTUPos]);
213  }
214  }
215  }
216  break;
217  case SAO_MERGE_LEFT:
218  {
219  if(ctuX > 0)
220  {
221  mergedCTUPos = ctuRsAddr- 1;
222  if( pic->getSAOMergeAvailability(ctuRsAddr, mergedCTUPos) )
223  {
224  mergeCandidate = &(blkParams[mergedCTUPos]);
225  }
226  }
227  }
228  break;
229  default:
230  {
231  printf("not a supported merge type");
232  assert(0);
233  exit(-1);
234  }
235  }
236 
237  mergeList[mergeType]=mergeCandidate;
238  if (mergeCandidate != NULL)
239  {
240  numValidMergeCandidates++;
241  }
242  }
243 
244  return numValidMergeCandidates;
245 }
246 
247 
249 {
250  const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
251  for(Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
252  {
253  const ComponentID component = ComponentID(compIdx);
254  SAOOffset& offsetParam = recParam[component];
255 
256  if(offsetParam.modeIdc == SAO_MODE_OFF)
257  {
258  continue;
259  }
260 
261  switch(offsetParam.modeIdc)
262  {
263  case SAO_MODE_NEW:
264  {
265  invertQuantOffsets(component, offsetParam.typeIdc, offsetParam.typeAuxInfo, offsetParam.offset, offsetParam.offset);
266  }
267  break;
268  case SAO_MODE_MERGE:
269  {
270  SAOBlkParam* mergeTarget = mergeList[offsetParam.typeIdc];
271  assert(mergeTarget != NULL);
272 
273  offsetParam = (*mergeTarget)[component];
274  }
275  break;
276  default:
277  {
278  printf("Not a supported mode");
279  assert(0);
280  exit(-1);
281  }
282  }
283  }
284 }
285 
287 {
288  for(Int compIdx = 0; compIdx < MAX_NUM_COMPONENT; compIdx++)
289  {
290  m_picSAOEnabled[compIdx] = false;
291  }
292 
293  const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
294 
295  for(Int ctuRsAddr=0; ctuRsAddr< m_numCTUsPic; ctuRsAddr++)
296  {
297  SAOBlkParam* mergeList[NUM_SAO_MERGE_TYPES] = { NULL };
298  getMergeList(pic, ctuRsAddr, saoBlkParams, mergeList);
299 
300  reconstructBlkSAOParam(saoBlkParams[ctuRsAddr], mergeList);
301 
302  for(Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
303  {
304  if(saoBlkParams[ctuRsAddr][compIdx].modeIdc != SAO_MODE_OFF)
305  {
306  m_picSAOEnabled[compIdx] = true;
307  }
308  }
309  }
310 }
311 
312 
313 Void TComSampleAdaptiveOffset::offsetBlock(const Int channelBitDepth, Int typeIdx, Int* offset
314  , Pel* srcBlk, Pel* resBlk, Int srcStride, Int resStride, Int width, Int height
315  , Bool isLeftAvail, Bool isRightAvail, Bool isAboveAvail, Bool isBelowAvail, Bool isAboveLeftAvail, Bool isAboveRightAvail, Bool isBelowLeftAvail, Bool isBelowRightAvail)
316 {
318  {
320 
321  if (m_signLineBuf1)
322  {
323  delete[] m_signLineBuf1;
325  }
327 
328  if (m_signLineBuf2)
329  {
330  delete[] m_signLineBuf2;
332  }
334  }
335 
336  const Int maxSampleValueIncl = (1<< channelBitDepth )-1;
337 
338  Int x,y, startX, startY, endX, endY, edgeType;
339  Int firstLineStartX, firstLineEndX, lastLineStartX, lastLineEndX;
340  SChar signLeft, signRight, signDown;
341 
342  Pel* srcLine = srcBlk;
343  Pel* resLine = resBlk;
344 
345  switch(typeIdx)
346  {
347  case SAO_TYPE_EO_0:
348  {
349  offset += 2;
350  startX = isLeftAvail ? 0 : 1;
351  endX = isRightAvail ? width : (width -1);
352  for (y=0; y< height; y++)
353  {
354  signLeft = (SChar)sgn(srcLine[startX] - srcLine[startX-1]);
355  for (x=startX; x< endX; x++)
356  {
357  signRight = (SChar)sgn(srcLine[x] - srcLine[x+1]);
358  edgeType = signRight + signLeft;
359  signLeft = -signRight;
360 
361  resLine[x] = Clip3<Int>(0, maxSampleValueIncl, srcLine[x] + offset[edgeType]);
362  }
363  srcLine += srcStride;
364  resLine += resStride;
365  }
366 
367  }
368  break;
369  case SAO_TYPE_EO_90:
370  {
371  offset += 2;
372  SChar *signUpLine = m_signLineBuf1;
373 
374  startY = isAboveAvail ? 0 : 1;
375  endY = isBelowAvail ? height : height-1;
376  if (!isAboveAvail)
377  {
378  srcLine += srcStride;
379  resLine += resStride;
380  }
381 
382  Pel* srcLineAbove= srcLine- srcStride;
383  for (x=0; x< width; x++)
384  {
385  signUpLine[x] = (SChar)sgn(srcLine[x] - srcLineAbove[x]);
386  }
387 
388  Pel* srcLineBelow;
389  for (y=startY; y<endY; y++)
390  {
391  srcLineBelow= srcLine+ srcStride;
392 
393  for (x=0; x< width; x++)
394  {
395  signDown = (SChar)sgn(srcLine[x] - srcLineBelow[x]);
396  edgeType = signDown + signUpLine[x];
397  signUpLine[x]= -signDown;
398 
399  resLine[x] = Clip3<Int>(0, maxSampleValueIncl, srcLine[x] + offset[edgeType]);
400  }
401  srcLine += srcStride;
402  resLine += resStride;
403  }
404 
405  }
406  break;
407  case SAO_TYPE_EO_135:
408  {
409  offset += 2;
410  SChar *signUpLine, *signDownLine, *signTmpLine;
411 
412  signUpLine = m_signLineBuf1;
413  signDownLine= m_signLineBuf2;
414 
415  startX = isLeftAvail ? 0 : 1 ;
416  endX = isRightAvail ? width : (width-1);
417 
418  //prepare 2nd line's upper sign
419  Pel* srcLineBelow= srcLine+ srcStride;
420  for (x=startX; x< endX+1; x++)
421  {
422  signUpLine[x] = (SChar)sgn(srcLineBelow[x] - srcLine[x- 1]);
423  }
424 
425  //1st line
426  Pel* srcLineAbove= srcLine- srcStride;
427  firstLineStartX = isAboveLeftAvail ? 0 : 1;
428  firstLineEndX = isAboveAvail? endX: 1;
429  for(x= firstLineStartX; x< firstLineEndX; x++)
430  {
431  edgeType = sgn(srcLine[x] - srcLineAbove[x- 1]) - signUpLine[x+1];
432 
433  resLine[x] = Clip3<Int>(0, maxSampleValueIncl, srcLine[x] + offset[edgeType]);
434  }
435  srcLine += srcStride;
436  resLine += resStride;
437 
438 
439  //middle lines
440  for (y= 1; y< height-1; y++)
441  {
442  srcLineBelow= srcLine+ srcStride;
443 
444  for (x=startX; x<endX; x++)
445  {
446  signDown = (SChar)sgn(srcLine[x] - srcLineBelow[x+ 1]);
447  edgeType = signDown + signUpLine[x];
448  resLine[x] = Clip3<Int>(0, maxSampleValueIncl, srcLine[x] + offset[edgeType]);
449 
450  signDownLine[x+1] = -signDown;
451  }
452  signDownLine[startX] = (SChar)sgn(srcLineBelow[startX] - srcLine[startX-1]);
453 
454  signTmpLine = signUpLine;
455  signUpLine = signDownLine;
456  signDownLine = signTmpLine;
457 
458  srcLine += srcStride;
459  resLine += resStride;
460  }
461 
462  //last line
463  srcLineBelow= srcLine+ srcStride;
464  lastLineStartX = isBelowAvail ? startX : (width -1);
465  lastLineEndX = isBelowRightAvail ? width : (width -1);
466  for(x= lastLineStartX; x< lastLineEndX; x++)
467  {
468  edgeType = sgn(srcLine[x] - srcLineBelow[x+ 1]) + signUpLine[x];
469  resLine[x] = Clip3<Int>(0, maxSampleValueIncl, srcLine[x] + offset[edgeType]);
470 
471  }
472  }
473  break;
474  case SAO_TYPE_EO_45:
475  {
476  offset += 2;
477  SChar *signUpLine = m_signLineBuf1+1;
478 
479  startX = isLeftAvail ? 0 : 1;
480  endX = isRightAvail ? width : (width -1);
481 
482  //prepare 2nd line upper sign
483  Pel* srcLineBelow= srcLine+ srcStride;
484  for (x=startX-1; x< endX; x++)
485  {
486  signUpLine[x] = (SChar)sgn(srcLineBelow[x] - srcLine[x+1]);
487  }
488 
489 
490  //first line
491  Pel* srcLineAbove= srcLine- srcStride;
492  firstLineStartX = isAboveAvail ? startX : (width -1 );
493  firstLineEndX = isAboveRightAvail ? width : (width-1);
494  for(x= firstLineStartX; x< firstLineEndX; x++)
495  {
496  edgeType = sgn(srcLine[x] - srcLineAbove[x+1]) -signUpLine[x-1];
497  resLine[x] = Clip3<Int>(0, maxSampleValueIncl, srcLine[x] + offset[edgeType]);
498  }
499  srcLine += srcStride;
500  resLine += resStride;
501 
502  //middle lines
503  for (y= 1; y< height-1; y++)
504  {
505  srcLineBelow= srcLine+ srcStride;
506 
507  for(x= startX; x< endX; x++)
508  {
509  signDown = (SChar)sgn(srcLine[x] - srcLineBelow[x-1]);
510  edgeType = signDown + signUpLine[x];
511  resLine[x] = Clip3<Int>(0, maxSampleValueIncl, srcLine[x] + offset[edgeType]);
512  signUpLine[x-1] = -signDown;
513  }
514  signUpLine[endX-1] = (SChar)sgn(srcLineBelow[endX-1] - srcLine[endX]);
515  srcLine += srcStride;
516  resLine += resStride;
517  }
518 
519  //last line
520  srcLineBelow= srcLine+ srcStride;
521  lastLineStartX = isBelowLeftAvail ? 0 : 1;
522  lastLineEndX = isBelowAvail ? endX : 1;
523  for(x= lastLineStartX; x< lastLineEndX; x++)
524  {
525  edgeType = sgn(srcLine[x] - srcLineBelow[x-1]) + signUpLine[x];
526  resLine[x] = Clip3<Int>(0, maxSampleValueIncl, srcLine[x] + offset[edgeType]);
527 
528  }
529  }
530  break;
531  case SAO_TYPE_BO:
532  {
533  const Int shiftBits = channelBitDepth - NUM_SAO_BO_CLASSES_LOG2;
534  for (y=0; y< height; y++)
535  {
536  for (x=0; x< width; x++)
537  {
538  resLine[x] = Clip3<Int>(0, maxSampleValueIncl, srcLine[x] + offset[srcLine[x] >> shiftBits] );
539  }
540  srcLine += srcStride;
541  resLine += resStride;
542  }
543  }
544  break;
545  default:
546  {
547  printf("Not a supported SAO types\n");
548  assert(0);
549  exit(-1);
550  }
551  }
552 }
553 
554 Void TComSampleAdaptiveOffset::offsetCTU(Int ctuRsAddr, TComPicYuv* srcYuv, TComPicYuv* resYuv, SAOBlkParam& saoblkParam, TComPic* pPic)
555 {
556  Bool isLeftAvail,isRightAvail,isAboveAvail,isBelowAvail,isAboveLeftAvail,isAboveRightAvail,isBelowLeftAvail,isBelowRightAvail;
557 
558  const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
559  Bool bAllOff=true;
560  for(Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
561  {
562  if (saoblkParam[compIdx].modeIdc != SAO_MODE_OFF)
563  {
564  bAllOff=false;
565  }
566  }
567  if (bAllOff)
568  {
569  return;
570  }
571 
572  //block boundary availability
573  pPic->getPicSym()->deriveLoopFilterBoundaryAvailibility(ctuRsAddr, isLeftAvail,isRightAvail,isAboveAvail,isBelowAvail,isAboveLeftAvail,isAboveRightAvail,isBelowLeftAvail,isBelowRightAvail);
574 
575  Int yPos = (ctuRsAddr / m_numCTUInWidth)*m_maxCUHeight;
576  Int xPos = (ctuRsAddr % m_numCTUInWidth)*m_maxCUWidth;
577  Int height = (yPos + m_maxCUHeight > m_picHeight)?(m_picHeight- yPos):m_maxCUHeight;
578  Int width = (xPos + m_maxCUWidth > m_picWidth )?(m_picWidth - xPos):m_maxCUWidth;
579 
580  for(Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
581  {
582  const ComponentID component = ComponentID(compIdx);
583  SAOOffset& ctbOffset = saoblkParam[compIdx];
584 
585  if(ctbOffset.modeIdc != SAO_MODE_OFF)
586  {
587  const UInt componentScaleX = getComponentScaleX(component, pPic->getChromaFormat());
588  const UInt componentScaleY = getComponentScaleY(component, pPic->getChromaFormat());
589 
590  Int blkWidth = (width >> componentScaleX);
591  Int blkHeight = (height >> componentScaleY);
592  Int blkXPos = (xPos >> componentScaleX);
593  Int blkYPos = (yPos >> componentScaleY);
594 
595  Int srcStride = srcYuv->getStride(component);
596  Pel* srcBlk = srcYuv->getAddr(component) + blkYPos*srcStride + blkXPos;
597 
598  Int resStride = resYuv->getStride(component);
599  Pel* resBlk = resYuv->getAddr(component) + blkYPos*resStride + blkXPos;
600 
601  offsetBlock( pPic->getPicSym()->getSPS().getBitDepth(toChannelType(component)), ctbOffset.typeIdc, ctbOffset.offset
602  , srcBlk, resBlk, srcStride, resStride, blkWidth, blkHeight
603  , isLeftAvail, isRightAvail
604  , isAboveAvail, isBelowAvail
605  , isAboveLeftAvail, isAboveRightAvail
606  , isBelowLeftAvail, isBelowRightAvail
607  );
608  }
609  } //compIdx
610 
611 }
612 
613 
615 {
616  const Int numberOfComponents = getNumberValidComponents(m_chromaFormatIDC);
617  Bool bAllDisabled=true;
618  for(Int compIdx = 0; compIdx < numberOfComponents; compIdx++)
619  {
620  if (m_picSAOEnabled[compIdx])
621  {
622  bAllDisabled=false;
623  }
624  }
625  if (bAllDisabled)
626  {
627  return;
628  }
629 
630  TComPicYuv* resYuv = pDecPic->getPicYuvRec();
631  TComPicYuv* srcYuv = m_tempPicYuv;
632  resYuv->copyToPic(srcYuv);
633  for(Int ctuRsAddr= 0; ctuRsAddr < m_numCTUsPic; ctuRsAddr++)
634  {
635  offsetCTU(ctuRsAddr, srcYuv, resYuv, (pDecPic->getPicSym()->getSAOBlkParam())[ctuRsAddr], pDecPic);
636  } //ctu
637 }
638 
639 
646 {
647  xPCMRestoration(pcPic);
648 }
649 
654 {
655  Bool bPCMFilter = (pcPic->getSlice(0)->getSPS()->getUsePCM() && pcPic->getSlice(0)->getSPS()->getPCMFilterDisableFlag())? true : false;
656 
657  if(bPCMFilter || pcPic->getSlice(0)->getPPS()->getTransquantBypassEnabledFlag())
658  {
659  for( UInt ctuRsAddr = 0; ctuRsAddr < pcPic->getNumberOfCtusInFrame() ; ctuRsAddr++ )
660  {
661  TComDataCU* pcCU = pcPic->getCtu(ctuRsAddr);
662 
663  xPCMCURestoration(pcCU, 0, 0);
664  }
665  }
666 }
667 
674 {
675  TComPic* pcPic = pcCU->getPic();
676  UInt uiCurNumParts = pcPic->getNumPartitionsInCtu() >> (uiDepth<<1);
677  UInt uiQNumParts = uiCurNumParts>>2;
678 
679  // go to sub-CU
680  if( pcCU->getDepth(uiAbsZorderIdx) > uiDepth )
681  {
682  for ( UInt uiPartIdx = 0; uiPartIdx < 4; uiPartIdx++, uiAbsZorderIdx+=uiQNumParts )
683  {
684  UInt uiLPelX = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsZorderIdx] ];
685  UInt uiTPelY = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsZorderIdx] ];
686  if( ( uiLPelX < pcCU->getSlice()->getSPS()->getPicWidthInLumaSamples() ) && ( uiTPelY < pcCU->getSlice()->getSPS()->getPicHeightInLumaSamples() ) )
687  {
688  xPCMCURestoration( pcCU, uiAbsZorderIdx, uiDepth+1 );
689  }
690  }
691  return;
692  }
693 
694  // restore PCM samples
695  if ((pcCU->getIPCMFlag(uiAbsZorderIdx)&& pcPic->getSlice(0)->getSPS()->getPCMFilterDisableFlag()) || pcCU->isLosslessCoded( uiAbsZorderIdx))
696  {
697  const UInt numComponents=pcPic->getNumberValidComponents();
698  for(UInt comp=0; comp<numComponents; comp++)
699  {
700  xPCMSampleRestoration (pcCU, uiAbsZorderIdx, uiDepth, ComponentID(comp));
701  }
702  }
703 }
704 
712 {
713  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec();
714  UInt uiPcmLeftShiftBit;
715  const UInt uiMinCoeffSize = pcCU->getPic()->getMinCUWidth()*pcCU->getPic()->getMinCUHeight();
716  const UInt csx=pcPicYuvRec->getComponentScaleX(compID);
717  const UInt csy=pcPicYuvRec->getComponentScaleY(compID);
718  const UInt uiOffset = (uiMinCoeffSize*uiAbsZorderIdx)>>(csx+csy);
719 
720  Pel *piSrc = pcPicYuvRec->getAddr(compID, pcCU->getCtuRsAddr(), uiAbsZorderIdx);
721  const Pel *piPcm = pcCU->getPCMSample(compID) + uiOffset;
722  const UInt uiStride = pcPicYuvRec->getStride(compID);
723  const TComSPS &sps = *(pcCU->getSlice()->getSPS());
724  const UInt uiWidth = ((sps.getMaxCUWidth() >> uiDepth) >> csx);
725  const UInt uiHeight = ((sps.getMaxCUHeight() >> uiDepth) >> csy);
726 
727  if ( pcCU->isLosslessCoded(uiAbsZorderIdx) && !pcCU->getIPCMFlag(uiAbsZorderIdx) )
728  {
729  uiPcmLeftShiftBit = 0;
730  }
731  else
732  {
733  uiPcmLeftShiftBit = sps.getBitDepth(toChannelType(compID)) - sps.getPCMBitDepth(toChannelType(compID));
734  }
735 
736  for(UInt uiY = 0; uiY < uiHeight; uiY++ )
737  {
738  for(UInt uiX = 0; uiX < uiWidth; uiX++ )
739  {
740  piSrc[uiX] = (piPcm[uiX] << uiPcmLeftShiftBit);
741  }
742  piPcm += uiWidth;
743  piSrc += uiStride;
744  }
745 }
746 
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:574
#define MAX_NUM_SAO_CLASSES
Definition: TypeDef.h:757
picture YUV buffer class
Definition: TComPicYuv.h:55
CU data structure class.
Definition: TComDataCU.h:64
Int typeAuxInfo
Definition: TypeDef.h:763
UInt getNumberOfCtusInFrame() const
Definition: TComPic.h:127
picture class (symbol + YUV buffers)
Definition: TComPic.h:56
void Void
Definition: TypeDef.h:203
Int getStride(const ComponentID id) const
Definition: TComPicYuv.h:121
#define NULL
Definition: CommonDef.h:107
Int typeIdc
Definition: TypeDef.h:762
TComSlice * getSlice(Int i)
Definition: TComPic.h:113
static UInt getComponentScaleY(const ComponentID id, const ChromaFormat fmt)
Int offset[32]
Definition: TypeDef.h:764
unsigned int UInt
Definition: TypeDef.h:212
UInt getNumPartitionsInCtu() const
Definition: TComPic.h:130
static UInt getComponentScaleX(const ComponentID id, const ChromaFormat fmt)
Short Pel
pixel type
Definition: TypeDef.h:249
Bool m_picSAOEnabled[MAX_NUM_COMPONENT]
UInt getMaxCUHeight() const
Definition: TComSlice.h:859
Int sgn(T val)
Int getNumberValidComponents() const
Definition: TComPic.h:140
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])
Bool getTransquantBypassEnabledFlag() const
Definition: TComSlice.h:1142
UInt getMinCUWidth() const
Definition: TComPic.h:133
TComPicYuv * getPicYuvRec()
Definition: TComPic.h:120
Void xPCMSampleRestoration(TComDataCU *pcCU, UInt uiAbsZorderIdx, UInt uiDepth, const ComponentID compID)
Bool * getIPCMFlag()
Definition: TComDataCU.h:354
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]
SAOOffset offsetParam[MAX_NUM_COMPONENT]
Definition: TypeDef.h:782
#define NUM_SAO_BO_CLASSES
Definition: TypeDef.h:575
signed char SChar
Definition: TypeDef.h:207
UInt getComponentScaleY(const ComponentID id) const
Definition: TComPicYuv.h:151
UInt getComponentScaleX(const ComponentID id) const
Definition: TComPicYuv.h:150
Bool getSAOMergeAvailability(Int currAddr, Int mergeAddr)
Definition: TComPic.cpp:216
bool Bool
Definition: TypeDef.h:204
const SAOOffset & operator=(const SAOOffset &src)
Bool isLosslessCoded(UInt absPartIdx) const
UInt getMinCUHeight() const
Definition: TComPic.h:134
Void copyToPic(TComPicYuv *pcPicYuvDst) const
Definition: TComPicYuv.cpp:198
UInt & getCtuRsAddr()
Definition: TComDataCU.h:204
UInt getCUPelY() const
Definition: TComDataCU.h:208
static ChannelType toChannelType(const ComponentID id)
Int getBitDepth(ChannelType type) const
Definition: TComSlice.h:894
SAOMode modeIdc
Definition: TypeDef.h:761
TComPicSym * getPicSym()
Definition: TComPic.h:111
ChromaFormat
chroma formats (according to semantics of chroma_format_idc)
Definition: TypeDef.h:292
UChar * getDepth()
Definition: TComDataCU.h:210
Void PCMLFDisableProcess(TComPic *pcPic)
UInt g_auiZscanToRaster[MAX_NUM_PART_IDXS_IN_CTU_WIDTH *MAX_NUM_PART_IDXS_IN_CTU_WIDTH]
Definition: TComRom.cpp:284
const TComPPS * getPPS() const
Definition: TComSlice.h:1332
UInt getCUPelX() const
Definition: TComDataCU.h:207
ChromaFormat getChromaFormat() const
Definition: TComPic.h:139
const TComSPS & getSPS() const
Definition: TComPicSym.h:163
const SAOBlkParam & operator=(const SAOBlkParam &src)
Bool getUsePCM() const
Definition: TComSlice.h:863
TComPic * getPic()
Definition: TComDataCU.h:200
TComDataCU * getCtu(UInt ctuRsAddr)
Definition: TComPic.h:116
Pel * getAddr(const ComponentID ch)
Definition: TComPicYuv.h:139
Void deriveLoopFilterBoundaryAvailibility(Int ctuRsAddr, Bool &isLeftAvail, Bool &isRightAvail, Bool &isAboveAvail, Bool &isBelowAvail, Bool &isAboveLeftAvail, Bool &isAboveRightAvail, Bool &isBelowLeftAvail, Bool &isBelowRightAvail)
Definition: TComPicSym.cpp:482
Void create(const Int picWidth, const Int picHeight, const ChromaFormat chromaFormatIDC, const UInt maxCUWidth, const UInt maxCUHeight, const UInt maxCUDepth, const Bool bUseMargin)
if true, then a margin of uiMaxCUWidth+16 and uiMaxCUHeight+16 is created around the image...
Definition: TComPicYuv.cpp:121
int Int
Definition: TypeDef.h:211
UInt getPCMBitDepth(ChannelType type) const
Definition: TComSlice.h:915
ComponentID
Definition: TypeDef.h:308
Void offsetBlock(const Int channelBitDepth, 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)
Void reconstructBlkSAOParams(TComPic *pic, SAOBlkParam *saoBlkParams)
Pel * getPCMSample(ComponentID component)
Definition: TComDataCU.h:305
UInt g_auiRasterToPelX[MAX_NUM_PART_IDXS_IN_CTU_WIDTH *MAX_NUM_PART_IDXS_IN_CTU_WIDTH]
Definition: TComRom.cpp:286
static UInt getNumberValidComponents(const ChromaFormat fmt)
Void destroy()
Definition: TComPicYuv.cpp:168
UInt g_auiRasterToPelY[MAX_NUM_PART_IDXS_IN_CTU_WIDTH *MAX_NUM_PART_IDXS_IN_CTU_WIDTH]
Definition: TComRom.cpp:287
static Bool isLuma(const ComponentID id)
UInt getMaxCUWidth() const
Definition: TComSlice.h:857
TComSlice * getSlice()
Definition: TComDataCU.h:202
const TComSPS * getSPS() const
Definition: TComSlice.h:1329
SPS class.
Definition: TComSlice.h:740
SAOBlkParam * getSAOBlkParam()
Definition: TComPicSym.h:186