comparison jctvc/TLibCommon/TComPattern.cpp @ 0:772086c29cc7

Initial import.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 16 Nov 2016 11:16:33 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:772086c29cc7
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-2014, 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
34 /** \file TComPattern.cpp
35 \brief neighbouring pixel access classes
36 */
37
38 #include "TComPic.h"
39 #include "TComPattern.h"
40 #include "TComDataCU.h"
41 #include "TComTU.h"
42 #include "Debug.h"
43 #include "TComPrediction.h"
44
45 //! \ingroup TLibCommon
46 //! \{
47
48 // Forward declarations
49
50 /// padding of unavailable reference samples for intra prediction
51 #if O0043_BEST_EFFORT_DECODING
52 Void fillReferenceSamples( const Int bitDepth, const Int bitDepthDelta, TComDataCU* pcCU, const Pel* piRoiOrigin, Pel* piAdiTemp, const Bool* bNeighborFlags,
53 #else
54 Void fillReferenceSamples( const Int bitDepth, TComDataCU* pcCU, const Pel* piRoiOrigin, Pel* piAdiTemp, const Bool* bNeighborFlags,
55 #endif
56 const Int iNumIntraNeighbor, const Int unitWidth, const Int unitHeight, const Int iAboveUnits, const Int iLeftUnits,
57 const UInt uiCuWidth, const UInt uiCuHeight, const UInt uiWidth, const UInt uiHeight, const Int iPicStride,
58 const ChannelType chType, const ChromaFormat chFmt );
59
60 /// constrained intra prediction
61 Bool isAboveLeftAvailable ( TComDataCU* pcCU, UInt uiPartIdxLT );
62 Int isAboveAvailable ( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool* bValidFlags );
63 Int isLeftAvailable ( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool* bValidFlags );
64 Int isAboveRightAvailable ( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool* bValidFlags );
65 Int isBelowLeftAvailable ( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool* bValidFlags );
66
67
68 // ====================================================================================================================
69 // Public member functions (TComPatternParam)
70 // ====================================================================================================================
71
72 /** \param piTexture pixel data
73 \param iRoiWidth pattern width
74 \param iRoiHeight pattern height
75 \param iStride buffer stride
76 \param iOffsetLeft neighbour offset (left)
77 \param iOffsetRight neighbour offset (right)
78 \param iOffsetAbove neighbour offset (above)
79 \param iOffsetBottom neighbour offset (bottom)
80 */
81 Void TComPatternParam::setPatternParamPel ( Pel* piTexture,
82 Int iRoiWidth,
83 Int iRoiHeight,
84 Int iStride
85 )
86 {
87 m_piROIOrigin = piTexture;
88 m_iROIWidth = iRoiWidth;
89 m_iROIHeight = iRoiHeight;
90 m_iPatternStride = iStride;
91 }
92
93 // ====================================================================================================================
94 // Public member functions (TComPattern)
95 // ====================================================================================================================
96
97 Void TComPattern::initPattern (Pel* piY,
98 Int iRoiWidth,
99 Int iRoiHeight,
100 Int iStride)
101 {
102 m_cPatternY. setPatternParamPel( piY, iRoiWidth, iRoiHeight, iStride);
103 }
104
105
106 // TODO: move this function to TComPrediction.cpp.
107 Void TComPrediction::initAdiPatternChType( TComTU &rTu, Bool& bAbove, Bool& bLeft, const ComponentID compID, const Bool bFilterRefSamples DEBUG_STRING_FN_DECLARE(sDebug))
108 {
109 const ChannelType chType = toChannelType(compID);
110
111 TComDataCU *pcCU=rTu.getCU();
112 const UInt uiZorderIdxInPart=rTu.GetAbsPartIdxTU();
113 const UInt uiTuWidth = rTu.getRect(compID).width;
114 const UInt uiTuHeight = rTu.getRect(compID).height;
115 const UInt uiTuWidth2 = uiTuWidth << 1;
116 const UInt uiTuHeight2 = uiTuHeight << 1;
117
118 const Int iBaseUnitSize = g_uiMaxCUWidth >> g_uiMaxCUDepth;
119 const Int iUnitWidth = iBaseUnitSize >> pcCU->getPic()->getPicYuvRec()->getComponentScaleX(compID);
120 const Int iUnitHeight = iBaseUnitSize >> pcCU->getPic()->getPicYuvRec()->getComponentScaleY(compID);
121 const Int iTUWidthInUnits = uiTuWidth / iUnitWidth;
122 const Int iTUHeightInUnits = uiTuHeight / iUnitHeight;
123 const Int iAboveUnits = iTUWidthInUnits << 1;
124 const Int iLeftUnits = iTUHeightInUnits << 1;
125
126 assert(iTUHeightInUnits > 0 && iTUWidthInUnits > 0);
127
128 const Int iPartIdxStride = pcCU->getPic()->getNumPartInCtuWidth();
129 const UInt uiPartIdxLT = pcCU->getZorderIdxInCtu() + uiZorderIdxInPart;
130 const UInt uiPartIdxRT = g_auiRasterToZscan[ g_auiZscanToRaster[ uiPartIdxLT ] + iTUWidthInUnits - 1 ];
131 const UInt uiPartIdxLB = g_auiRasterToZscan[ g_auiZscanToRaster[ uiPartIdxLT ] + ((iTUHeightInUnits - 1) * iPartIdxStride)];
132
133 Int iPicStride = pcCU->getPic()->getStride(compID);
134 Bool bNeighborFlags[4 * MAX_NUM_SPU_W + 1];
135 Int iNumIntraNeighbor = 0;
136
137 bNeighborFlags[iLeftUnits] = isAboveLeftAvailable( pcCU, uiPartIdxLT );
138 iNumIntraNeighbor += bNeighborFlags[iLeftUnits] ? 1 : 0;
139 iNumIntraNeighbor += isAboveAvailable ( pcCU, uiPartIdxLT, uiPartIdxRT, (bNeighborFlags + iLeftUnits + 1) );
140 iNumIntraNeighbor += isAboveRightAvailable( pcCU, uiPartIdxLT, uiPartIdxRT, (bNeighborFlags + iLeftUnits + 1 + iTUWidthInUnits ) );
141 iNumIntraNeighbor += isLeftAvailable ( pcCU, uiPartIdxLT, uiPartIdxLB, (bNeighborFlags + iLeftUnits - 1) );
142 iNumIntraNeighbor += isBelowLeftAvailable ( pcCU, uiPartIdxLT, uiPartIdxLB, (bNeighborFlags + iLeftUnits - 1 - iTUHeightInUnits) );
143
144 bAbove = true;
145 bLeft = true;
146
147 const ChromaFormat chFmt = rTu.GetChromaFormat();
148 const UInt uiROIWidth = uiTuWidth2+1;
149 const UInt uiROIHeight = uiTuHeight2+1;
150
151 assert(uiROIWidth*uiROIHeight <= m_iYuvExtSize);
152
153 #ifdef DEBUG_STRING
154 std::stringstream ss(stringstream::out);
155 #endif
156
157 {
158 Pel *piAdiTemp = m_piYuvExt[compID][PRED_BUF_UNFILTERED];
159 Pel *piRoiOrigin = pcCU->getPic()->getPicYuvRec()->getAddr(compID, pcCU->getCtuRsAddr(), pcCU->getZorderIdxInCtu()+uiZorderIdxInPart);
160 #if O0043_BEST_EFFORT_DECODING
161 fillReferenceSamples (g_bitDepthInStream[chType], g_bitDepthInStream[chType] - g_bitDepth[chType], pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitWidth, iUnitHeight, iAboveUnits, iLeftUnits,
162 #else
163 fillReferenceSamples (g_bitDepth[chType], pcCU, piRoiOrigin, piAdiTemp, bNeighborFlags, iNumIntraNeighbor, iUnitWidth, iUnitHeight, iAboveUnits, iLeftUnits,
164 #endif
165 uiTuWidth, uiTuHeight, uiROIWidth, uiROIHeight, iPicStride, toChannelType(compID), chFmt);
166
167
168 #ifdef DEBUG_STRING
169 if (DebugOptionList::DebugString_Pred.getInt()&DebugStringGetPredModeMask(MODE_INTRA))
170 {
171 ss << "###: generating Ref Samples for channel " << compID << " and " << rTu.getRect(compID).width << " x " << rTu.getRect(compID).height << "\n";
172 for (UInt y=0; y<uiROIHeight; y++)
173 {
174 ss << "###: - ";
175 for (UInt x=0; x<uiROIWidth; x++)
176 {
177 if (x==0 || y==0)
178 ss << piAdiTemp[y*uiROIWidth + x] << ", ";
179 // if (x%16==15) ss << "\nPart size: ~ ";
180 }
181 ss << "\n";
182 }
183 }
184 #endif
185
186 if (bFilterRefSamples)
187 {
188 // generate filtered intra prediction samples
189
190 Int stride = uiROIWidth;
191 const Pel *piSrcPtr = piAdiTemp + (stride * uiTuHeight2); // bottom left
192 Pel *piDestPtr = m_piYuvExt[compID][PRED_BUF_FILTERED] + (stride * uiTuHeight2); // bottom left
193
194 //------------------------------------------------
195
196 Bool useStrongIntraSmoothing = isLuma(chType) && pcCU->getSlice()->getSPS()->getUseStrongIntraSmoothing();
197
198 const Pel bottomLeft = piAdiTemp[stride * uiTuHeight2];
199 const Pel topLeft = piAdiTemp[0];
200 const Pel topRight = piAdiTemp[uiTuWidth2];
201
202 if (useStrongIntraSmoothing)
203 {
204 #if O0043_BEST_EFFORT_DECODING
205 const Int threshold = 1 << (g_bitDepthInStream[chType] - 5);
206 #else
207 const Int threshold = 1 << (g_bitDepth[chType] - 5);
208 #endif
209 const Bool bilinearLeft = abs((bottomLeft + topLeft ) - (2 * piAdiTemp[stride * uiTuHeight])) < threshold; //difference between the
210 const Bool bilinearAbove = abs((topLeft + topRight) - (2 * piAdiTemp[ uiTuWidth ])) < threshold; //ends and the middle
211 if ((uiTuWidth < 32) || (!bilinearLeft) || (!bilinearAbove))
212 useStrongIntraSmoothing = false;
213 }
214
215 *piDestPtr = *piSrcPtr; // bottom left is not filtered
216 piDestPtr -= stride;
217 piSrcPtr -= stride;
218
219 //------------------------------------------------
220
221 //left column (bottom to top)
222
223 if (useStrongIntraSmoothing)
224 {
225 const Int shift = g_aucConvertToBit[uiTuHeight] + 3; //log2(uiTuHeight2)
226
227 for(UInt i=1; i<uiTuHeight2; i++, piDestPtr-=stride)
228 {
229 *piDestPtr = (((uiTuHeight2 - i) * bottomLeft) + (i * topLeft) + uiTuHeight) >> shift;
230 }
231
232 piSrcPtr -= stride * (uiTuHeight2 - 1);
233 }
234 else
235 {
236 for(UInt i=1; i<uiTuHeight2; i++, piDestPtr-=stride, piSrcPtr-=stride)
237 {
238 *piDestPtr = ( piSrcPtr[stride] + 2*piSrcPtr[0] + piSrcPtr[-stride] + 2 ) >> 2;
239 }
240 }
241
242 //------------------------------------------------
243
244 //top-left
245
246 if (useStrongIntraSmoothing)
247 {
248 *piDestPtr = piSrcPtr[0];
249 }
250 else
251 {
252 *piDestPtr = ( piSrcPtr[stride] + 2*piSrcPtr[0] + piSrcPtr[1] + 2 ) >> 2;
253 }
254 piDestPtr += 1;
255 piSrcPtr += 1;
256
257 //------------------------------------------------
258
259 //top row (left-to-right)
260
261 if (useStrongIntraSmoothing)
262 {
263 const Int shift = g_aucConvertToBit[uiTuWidth] + 3; //log2(uiTuWidth2)
264
265 for(UInt i=1; i<uiTuWidth2; i++, piDestPtr++)
266 {
267 *piDestPtr = (((uiTuWidth2 - i) * topLeft) + (i * topRight) + uiTuWidth) >> shift;
268 }
269
270 piSrcPtr += uiTuWidth2 - 1;
271 }
272 else
273 {
274 for(UInt i=1; i<uiTuWidth2; i++, piDestPtr++, piSrcPtr++)
275 {
276 *piDestPtr = ( piSrcPtr[1] + 2*piSrcPtr[0] + piSrcPtr[-1] + 2 ) >> 2;
277 }
278 }
279
280 //------------------------------------------------
281
282 *piDestPtr=*piSrcPtr; // far right is not filtered
283
284 #ifdef DEBUG_STRING
285 if (DebugOptionList::DebugString_Pred.getInt()&DebugStringGetPredModeMask(MODE_INTRA))
286 {
287 ss << "###: filtered result for channel " << compID <<"\n";
288 for (UInt y=0; y<uiROIHeight; y++)
289 {
290 ss << "###: - ";
291 for (UInt x=0; x<uiROIWidth; x++)
292 {
293 if (x==0 || y==0)
294 ss << m_piYuvExt[compID][PRED_BUF_FILTERED][y*uiROIWidth + x] << ", ";
295 // if (x%16==15) ss << "\nPart size: ~ ";
296 }
297 ss << "\n";
298 }
299 }
300 #endif
301
302
303 }
304 }
305 DEBUG_STRING_APPEND(sDebug, ss.str())
306 }
307
308 #if O0043_BEST_EFFORT_DECODING
309 Void fillReferenceSamples( const Int bitDepth, const Int bitDepthDelta, TComDataCU* pcCU, const Pel* piRoiOrigin, Pel* piAdiTemp, const Bool* bNeighborFlags,
310 #else
311 Void fillReferenceSamples( const Int bitDepth, TComDataCU* pcCU, const Pel* piRoiOrigin, Pel* piAdiTemp, const Bool* bNeighborFlags,
312 #endif
313 const Int iNumIntraNeighbor, const Int unitWidth, const Int unitHeight, const Int iAboveUnits, const Int iLeftUnits,
314 const UInt uiCuWidth, const UInt uiCuHeight, const UInt uiWidth, const UInt uiHeight, const Int iPicStride,
315 const ChannelType chType, const ChromaFormat chFmt )
316 {
317 const Pel* piRoiTemp;
318 Int i, j;
319 Int iDCValue = 1 << (bitDepth - 1);
320 const Int iTotalUnits = iAboveUnits + iLeftUnits + 1; //+1 for top-left
321
322 if (iNumIntraNeighbor == 0)
323 {
324 // Fill border with DC value
325 for (i=0; i<uiWidth; i++)
326 {
327 piAdiTemp[i] = iDCValue;
328 }
329 for (i=1; i<uiHeight; i++)
330 {
331 piAdiTemp[i*uiWidth] = iDCValue;
332 }
333 }
334 else if (iNumIntraNeighbor == iTotalUnits)
335 {
336 // Fill top-left border and top and top right with rec. samples
337 piRoiTemp = piRoiOrigin - iPicStride - 1;
338
339 for (i=0; i<uiWidth; i++)
340 {
341 #if O0043_BEST_EFFORT_DECODING
342 piAdiTemp[i] = piRoiTemp[i] << bitDepthDelta;
343 #else
344 piAdiTemp[i] = piRoiTemp[i];
345 #endif
346 }
347
348 // Fill left and below left border with rec. samples
349 piRoiTemp = piRoiOrigin - 1;
350
351 for (i=1; i<uiHeight; i++)
352 {
353 #if O0043_BEST_EFFORT_DECODING
354 piAdiTemp[i*uiWidth] = (*(piRoiTemp)) << bitDepthDelta;
355 #else
356 piAdiTemp[i*uiWidth] = *(piRoiTemp);
357 #endif
358 piRoiTemp += iPicStride;
359 }
360 }
361 else // reference samples are partially available
362 {
363 // all above units have "unitWidth" samples each, all left/below-left units have "unitHeight" samples each
364 const Int iTotalSamples = (iLeftUnits * unitHeight) + ((iAboveUnits + 1) * unitWidth);
365 Pel piAdiLine[5 * MAX_CU_SIZE];
366 Pel *piAdiLineTemp;
367 const Bool *pbNeighborFlags;
368
369
370 // Initialize
371 for (i=0; i<iTotalSamples; i++)
372 {
373 piAdiLine[i] = iDCValue;
374 }
375
376 // Fill top-left sample
377 piRoiTemp = piRoiOrigin - iPicStride - 1;
378 piAdiLineTemp = piAdiLine + (iLeftUnits * unitHeight);
379 pbNeighborFlags = bNeighborFlags + iLeftUnits;
380 if (*pbNeighborFlags)
381 {
382 #if O0043_BEST_EFFORT_DECODING
383 Pel topLeftVal=piRoiTemp[0] << bitDepthDelta;
384 #else
385 Pel topLeftVal=piRoiTemp[0];
386 #endif
387 for (i=0; i<unitWidth; i++)
388 {
389 piAdiLineTemp[i] = topLeftVal;
390 }
391 }
392
393 // Fill left & below-left samples (downwards)
394 piRoiTemp += iPicStride;
395 piAdiLineTemp--;
396 pbNeighborFlags--;
397
398 for (j=0; j<iLeftUnits; j++)
399 {
400 if (*pbNeighborFlags)
401 {
402 for (i=0; i<unitHeight; i++)
403 {
404 #if O0043_BEST_EFFORT_DECODING
405 piAdiLineTemp[-i] = piRoiTemp[i*iPicStride] << bitDepthDelta;
406 #else
407 piAdiLineTemp[-i] = piRoiTemp[i*iPicStride];
408 #endif
409 }
410 }
411 piRoiTemp += unitHeight*iPicStride;
412 piAdiLineTemp -= unitHeight;
413 pbNeighborFlags--;
414 }
415
416 // Fill above & above-right samples (left-to-right) (each unit has "unitWidth" samples)
417 piRoiTemp = piRoiOrigin - iPicStride;
418 // offset line buffer by iNumUints2*unitHeight (for left/below-left) + unitWidth (for above-left)
419 piAdiLineTemp = piAdiLine + (iLeftUnits * unitHeight) + unitWidth;
420 pbNeighborFlags = bNeighborFlags + iLeftUnits + 1;
421 for (j=0; j<iAboveUnits; j++)
422 {
423 if (*pbNeighborFlags)
424 {
425 for (i=0; i<unitWidth; i++)
426 {
427 #if O0043_BEST_EFFORT_DECODING
428 piAdiLineTemp[i] = piRoiTemp[i] << bitDepthDelta;
429 #else
430 piAdiLineTemp[i] = piRoiTemp[i];
431 #endif
432 }
433 }
434 piRoiTemp += unitWidth;
435 piAdiLineTemp += unitWidth;
436 pbNeighborFlags++;
437 }
438
439 // Pad reference samples when necessary
440 Int iCurrJnit = 0;
441 Pel *piAdiLineCur = piAdiLine;
442 const UInt piAdiLineTopRowOffset = iLeftUnits * (unitHeight - unitWidth);
443
444 if (!bNeighborFlags[0])
445 {
446 // very bottom unit of bottom-left; at least one unit will be valid.
447 {
448 Int iNext = 1;
449 while (iNext < iTotalUnits && !bNeighborFlags[iNext])
450 {
451 iNext++;
452 }
453 Pel *piAdiLineNext = piAdiLine + ((iNext < iLeftUnits) ? (iNext * unitHeight) : (piAdiLineTopRowOffset + (iNext * unitWidth)));
454 const Pel refSample = *piAdiLineNext;
455 // Pad unavailable samples with new value
456 Int iNextOrTop = std::min<Int>(iNext, iLeftUnits);
457 // fill left column
458 while (iCurrJnit < iNextOrTop)
459 {
460 for (i=0; i<unitHeight; i++)
461 {
462 piAdiLineCur[i] = refSample;
463 }
464 piAdiLineCur += unitHeight;
465 iCurrJnit++;
466 }
467 // fill top row
468 while (iCurrJnit < iNext)
469 {
470 for (i=0; i<unitWidth; i++)
471 {
472 piAdiLineCur[i] = refSample;
473 }
474 piAdiLineCur += unitWidth;
475 iCurrJnit++;
476 }
477 }
478 }
479
480 // pad all other reference samples.
481 while (iCurrJnit < iTotalUnits)
482 {
483 if (!bNeighborFlags[iCurrJnit]) // samples not available
484 {
485 {
486 const Int numSamplesInCurrUnit = (iCurrJnit >= iLeftUnits) ? unitWidth : unitHeight;
487 const Pel refSample = *(piAdiLineCur-1);
488 for (i=0; i<numSamplesInCurrUnit; i++)
489 {
490 piAdiLineCur[i] = refSample;
491 }
492 piAdiLineCur += numSamplesInCurrUnit;
493 iCurrJnit++;
494 }
495 }
496 else
497 {
498 piAdiLineCur += (iCurrJnit >= iLeftUnits) ? unitWidth : unitHeight;
499 iCurrJnit++;
500 }
501 }
502
503 // Copy processed samples
504
505 piAdiLineTemp = piAdiLine + uiHeight + unitWidth - 2;
506 // top left, top and top right samples
507 for (i=0; i<uiWidth; i++)
508 {
509 piAdiTemp[i] = piAdiLineTemp[i];
510 }
511
512 piAdiLineTemp = piAdiLine + uiHeight - 1;
513 for (i=1; i<uiHeight; i++)
514 {
515 piAdiTemp[i*uiWidth] = piAdiLineTemp[-i];
516 }
517 }
518 }
519
520 /** Get pointer to reference samples for intra prediction
521 * \param uiDirMode prediction mode index
522 * \param log2BlkSize size of block (2 = 4x4, 3 = 8x8, 4 = 16x16, 5 = 32x32, 6 = 64x64)
523 * \param piAdiBuf pointer to unfiltered reference samples
524 * \return pointer to (possibly filtered) reference samples
525 *
526 * The prediction mode index is used to determine whether a smoothed reference sample buffer is returned.
527 */
528
529 Bool TComPrediction::filteringIntraReferenceSamples(const ComponentID compID, UInt uiDirMode, UInt uiTuChWidth, UInt uiTuChHeight, const ChromaFormat chFmt, const Bool intraReferenceSmoothingDisabled)
530 {
531 Bool bFilter;
532
533 if (!filterIntraReferenceSamples(toChannelType(compID), chFmt, intraReferenceSmoothingDisabled))
534 {
535 bFilter=false;
536 }
537 else
538 {
539 assert(uiTuChWidth>=4 && uiTuChHeight>=4 && uiTuChWidth<128 && uiTuChHeight<128);
540
541 if (uiDirMode == DC_IDX)
542 {
543 bFilter=false; //no smoothing for DC or LM chroma
544 }
545 else
546 {
547 Int diff = min<Int>(abs((Int) uiDirMode - HOR_IDX), abs((Int)uiDirMode - VER_IDX));
548 UInt sizeIndex=g_aucConvertToBit[uiTuChWidth];
549 assert(sizeIndex < MAX_INTRA_FILTER_DEPTHS);
550 bFilter = diff > m_aucIntraFilter[toChannelType(compID)][sizeIndex];
551 }
552 }
553 return bFilter;
554 }
555
556 Bool isAboveLeftAvailable( TComDataCU* pcCU, UInt uiPartIdxLT )
557 {
558 Bool bAboveLeftFlag;
559 UInt uiPartAboveLeft;
560 TComDataCU* pcCUAboveLeft = pcCU->getPUAboveLeft( uiPartAboveLeft, uiPartIdxLT );
561 if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred())
562 {
563 bAboveLeftFlag = ( pcCUAboveLeft && pcCUAboveLeft->isIntra( uiPartAboveLeft ) );
564 }
565 else
566 {
567 bAboveLeftFlag = (pcCUAboveLeft ? true : false);
568 }
569 return bAboveLeftFlag;
570 }
571
572 Int isAboveAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool *bValidFlags )
573 {
574 const UInt uiRasterPartBegin = g_auiZscanToRaster[uiPartIdxLT];
575 const UInt uiRasterPartEnd = g_auiZscanToRaster[uiPartIdxRT]+1;
576 const UInt uiIdxStep = 1;
577 Bool *pbValidFlags = bValidFlags;
578 Int iNumIntra = 0;
579
580 for ( UInt uiRasterPart = uiRasterPartBegin; uiRasterPart < uiRasterPartEnd; uiRasterPart += uiIdxStep )
581 {
582 UInt uiPartAbove;
583 TComDataCU* pcCUAbove = pcCU->getPUAbove( uiPartAbove, g_auiRasterToZscan[uiRasterPart] );
584 if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred())
585 {
586 if ( pcCUAbove && pcCUAbove->isIntra( uiPartAbove ) )
587 {
588 iNumIntra++;
589 *pbValidFlags = true;
590 }
591 else
592 {
593 *pbValidFlags = false;
594 }
595 }
596 else
597 {
598 if (pcCUAbove)
599 {
600 iNumIntra++;
601 *pbValidFlags = true;
602 }
603 else
604 {
605 *pbValidFlags = false;
606 }
607 }
608 pbValidFlags++;
609 }
610 return iNumIntra;
611 }
612
613 Int isLeftAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool *bValidFlags )
614 {
615 const UInt uiRasterPartBegin = g_auiZscanToRaster[uiPartIdxLT];
616 const UInt uiRasterPartEnd = g_auiZscanToRaster[uiPartIdxLB]+1;
617 const UInt uiIdxStep = pcCU->getPic()->getNumPartInCtuWidth();
618 Bool *pbValidFlags = bValidFlags;
619 Int iNumIntra = 0;
620
621 for ( UInt uiRasterPart = uiRasterPartBegin; uiRasterPart < uiRasterPartEnd; uiRasterPart += uiIdxStep )
622 {
623 UInt uiPartLeft;
624 TComDataCU* pcCULeft = pcCU->getPULeft( uiPartLeft, g_auiRasterToZscan[uiRasterPart] );
625 if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred())
626 {
627 if ( pcCULeft && pcCULeft->isIntra( uiPartLeft ) )
628 {
629 iNumIntra++;
630 *pbValidFlags = true;
631 }
632 else
633 {
634 *pbValidFlags = false;
635 }
636 }
637 else
638 {
639 if ( pcCULeft )
640 {
641 iNumIntra++;
642 *pbValidFlags = true;
643 }
644 else
645 {
646 *pbValidFlags = false;
647 }
648 }
649 pbValidFlags--; // opposite direction
650 }
651
652 return iNumIntra;
653 }
654
655 Int isAboveRightAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxRT, Bool *bValidFlags )
656 {
657 const UInt uiNumUnitsInPU = g_auiZscanToRaster[uiPartIdxRT] - g_auiZscanToRaster[uiPartIdxLT] + 1;
658 Bool *pbValidFlags = bValidFlags;
659 Int iNumIntra = 0;
660
661 for ( UInt uiOffset = 1; uiOffset <= uiNumUnitsInPU; uiOffset++ )
662 {
663 UInt uiPartAboveRight;
664 TComDataCU* pcCUAboveRight = pcCU->getPUAboveRightAdi( uiPartAboveRight, uiPartIdxRT, uiOffset );
665 if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred())
666 {
667 if ( pcCUAboveRight && pcCUAboveRight->isIntra( uiPartAboveRight ) )
668 {
669 iNumIntra++;
670 *pbValidFlags = true;
671 }
672 else
673 {
674 *pbValidFlags = false;
675 }
676 }
677 else
678 {
679 if ( pcCUAboveRight )
680 {
681 iNumIntra++;
682 *pbValidFlags = true;
683 }
684 else
685 {
686 *pbValidFlags = false;
687 }
688 }
689 pbValidFlags++;
690 }
691
692 return iNumIntra;
693 }
694
695 Int isBelowLeftAvailable( TComDataCU* pcCU, UInt uiPartIdxLT, UInt uiPartIdxLB, Bool *bValidFlags )
696 {
697 const UInt uiNumUnitsInPU = (g_auiZscanToRaster[uiPartIdxLB] - g_auiZscanToRaster[uiPartIdxLT]) / pcCU->getPic()->getNumPartInCtuWidth() + 1;
698 Bool *pbValidFlags = bValidFlags;
699 Int iNumIntra = 0;
700
701 for ( UInt uiOffset = 1; uiOffset <= uiNumUnitsInPU; uiOffset++ )
702 {
703 UInt uiPartBelowLeft;
704 TComDataCU* pcCUBelowLeft = pcCU->getPUBelowLeftAdi( uiPartBelowLeft, uiPartIdxLB, uiOffset );
705 if(pcCU->getSlice()->getPPS()->getConstrainedIntraPred())
706 {
707 if ( pcCUBelowLeft && pcCUBelowLeft->isIntra( uiPartBelowLeft ) )
708 {
709 iNumIntra++;
710 *pbValidFlags = true;
711 }
712 else
713 {
714 *pbValidFlags = false;
715 }
716 }
717 else
718 {
719 if ( pcCUBelowLeft )
720 {
721 iNumIntra++;
722 *pbValidFlags = true;
723 }
724 else
725 {
726 *pbValidFlags = false;
727 }
728 }
729 pbValidFlags--; // opposite direction
730 }
731
732 return iNumIntra;
733 }
734 //! \}