AV1 specification を読む 2018-03-26 (7.10.1.x. Hoge Intra Prediction Process) 

#AV1 specification 日本語訳 (2018-03-26)

#### 7.10.1.1. Basic Intra Prediction Process

> The inputs to this process are:
>
> * a variable mode specifying the type of intra prediction to apply,
> * a variable w specifying the width of the region to be predicted,
> * a variable h specifying the height of the region to be predicted.

この処理の入力は以下のとおりです。

 * イントラ予測処理モード mode
 * 予測領域の幅 w
 * 予測領域の高さ h

> The output of this process is a 2D array named pred containing the intra predicted samples.

この処理の出力は、イントラ予測画素を含む2次元配列 pred　です。

> The process uses simple filters to generate filtered samples from the samples in LeftCol and AboveRow as follows:

この処理では、LeftCol, AboveCol 内の画素からフィルタされた画素を生成するために、以下のような単純なフィルタを使います。

> * If mode is equal to V_PRED, pred[ i ][ j ] is set equal to AboveRow[ j ] with j = 0..w-1 and i = 0..h-1 (each row of the block is filled with a copy of AboveRow).
> * Otherwise if mode is equal to H_PRED, pred[ i ][ j ] is set equal to LeftCol[ i ] with j = 0..w-1 and i = 0..h-1 (each column of the block is filled with a copy of LeftCol).
> * Otherwise if mode is equal to D203_PRED, the following applies for i = 0..h-1:
>  1. pred[ i ][ j ] = Round2( LeftCol[ i + j/2 ] + LeftCol[ i + 1 + j/2 ], 1 ) for even values of j in the range 0..w-2
>  2. pred[ i ][ j ] = Round2( LeftCol[ i + j/2 ] + 2 * LeftCol[ i + 1 + j/2 ] + LeftCol[ i + 2 + j/2 ], 2 ) for odd values of j in the range 0..w-1
> * Otherwise if mode is equal to D45_PRED, the following applies for i = 0..h-1, for j = 0..w-1:
>  1. pred[ i ][ j ] = Round2( AboveRow[ i + j ] + 2 * AboveRow[ i + j + 1 ] + AboveRow[ i + j + 1 ], 2 ) if (i + j + 2 >= w + h)
>  2. pred[ i ][ j ] = Round2( AboveRow[ i + j ] + 2 * AboveRow[ i + j + 1 ] + AboveRow[ i + j + 2 ], 2 ) if (i + j + 2 < w + h)
> * Otherwise if mode is equal to D67_PRED, the following applies for i = 0..h-1, for j = 0..w-1:
>  1. pred[ i ][ j ] = Round2( AboveRow[ i/2 + j ] + AboveRow[ i/2 + j + 1 ], 1 ) for even values of i in the range 0..h-2
>  2. pred[ i ][ j ] = Round2( AboveRow[ i/2 + j ] + 2 * AboveRow[ i/2 + j + 1 ] + AboveRow[ i/2 + j + 2 ], 2 ) for odd values of i in the range 0..h-1.
> * Otherwise if mode is equal to D113_PRED, the following applies:
>  1. pred[ 0 ][ j ] = Round2( AboveRow[ j - 1 ] + AboveRow[ j ], 1 ) for j = 0..w-1
>  2. pred[ 1 ][ 0 ] = Round2( LeftCol[ 0 ] + 2 * AboveRow[ -1 ] + AboveRow[ 0 ], 2 )
>  3. pred[ 1 ][ j ] = Round2( AboveRow[ j - 2 ] + 2 * AboveRow[ j - 1 ] + AboveRow[ j ], 2 ) for j = 1..w-1
>  4. pred[ 2 ][ 0 ] = Round2( AboveRow[ -1 ] + 2 * LeftCol[ 0 ] + LeftCol[ 1 ], 2 )
>  5. pred[ i ][ 0 ] = Round2( LeftCol[ i - 3 ] + 2 * LeftCol[ i - 2 ] + LeftCol[ i - 1 ], 2 ) for i = 3..h-1
>  6. pred[ i ][ j ] = pred[ i - 2 ][ j - 1 ] for i = 2..h-1, for j = 1..w-1
> * Otherwise if mode is equal to D135_PRED, the following applies:
>  1. pred[ 0 ][ 0 ] = Round2( LeftCol[ 0 ] + 2 * AboveRow[ -1 ] + AboveRow[ 0 ], 2 )
>  2. pred[ 0 ][ j ] = Round2( AboveRow[ j - 2 ] + 2 * AboveRow[ j - 1 ] + AboveRow[ j ], 2 ) for j = 1..w-1
>  3. pred[ 1 ][ 0 ] = Round2( AboveRow[ -1 ] + 2 * LeftCol[ 0 ] + LeftCol[ 1 ], 2 )
>  4. pred[ i ][ 0 ] = Round2( LeftCol[ i - 2 ] + 2 * LeftCol[ i - 1 ] + LeftCol[ i ], 2 ) for i = 2..h-1
>  5. pred[ i ][ j ] = pred[ i - 1 ][ j - 1 ] for i = 1..h-1, for j = 1..w-1
> * Otherwise if mode is equal to D157_PRED, the following applies:
>  1. pred[ 0 ][ 0 ] = Round2( LeftCol[ 0 ] + AboveRow[ -1 ], 1 )
>  2. pred[ i ][ 0 ] = Round2( LeftCol[ i - 1 ] + LeftCol[ i ], 1 ) for i = 1..h-1
>  3. pred[ 0 ][ 1 ] = Round2( LeftCol[ 0 ] + 2 * AboveRow[ -1 ] + AboveRow[ 0 ], 2 )
>  4. pred[ 1 ][ 1 ] = Round2( AboveRow[ -1 ] + 2 * LeftCol[ 0 ] + LeftCol[ 1 ], 2 )
>  5. pred[ i ][ 1 ] = Round2( LeftCol[ i - 2 ] + 2 * LeftCol[ i - 1 ] + LeftCol[ i ], 2 ) for i = 2..h-1
>  6. pred[ 0 ][ j ] = Round2( AboveRow[ j - 3 ] + 2 * AboveRow[ j - 2 ] + AboveRow[ j - 1 ], 2 ) for j = 2..w-1
>  7. pred[ i ][ j ] = pred[ i - 1 ][ j - 2 ] for i = 1..h-1, for j = 2..w-1
> * Otherwise (mode is equal to TM_PRED), the following ordered steps apply for i = 0..h-1, for j = 0..w-1:
>  1. The variable base is set equal to AboveRow[ j ] + LeftCol[ i ] - AboveRow[ -1 ].
>  2. The variable pLeft is set equal to Abs( base - LeftCol[ i ]).
>  3. The variable pTop is set equal to Abs( base - AboveRow[ j ]).
>  4. The variable pTopLeft is set equal to Abs( base - AboveRow[ -1 ] ).
>  5. If pLeft <= pTop and pLeft <= pTopLeft, pred[ i ][ j ] is set equal to LeftCol[ i ].
>  6. Otherwise, if pTop <= pTopLeft, pred[ i ][ j ] is set equal to AboveRow[ j ].
>  7. Otherwise, pred[ i ][ j ] is set equal to AboveRow[ -1 ].

>The output of the process is the array pred.

この処理の出力は、配列 pred です。

#### 7.10.1.2. Recursive Intra Prediction Process

>The inputs to this process are:
>
> * a variable w specifying the width of the region to be predicted,
> * a variable h specifying the height of the region to be predicted.

この処理の入力は以下のとおりです。

 * 予測領域の幅 w
 * 予測領域の高さ h

> The output of this process is a 2D array named pred containing the intra predicted samples.

この処理の出力は、イントラ予測画素を含む2次元配列 pred　です。

> For each block of 4x2 samples, this process first prepares an array p of 7 neighboring samples, and then produces the output block by filtering this array.

4x2画素のブロックごとに、この処理ではまず7近傍画素のは入れ宇t p を準備し、この配列をフィルタすることで出力ブロックを生成します。

> The variable w4 is set equal to w >> 2.
> The variable h2 is set equal to h >> 1.

w4 = w >> 2
h2 = h >> 1

>The following steps apply for i2 = 0..h2-1, for j4 = 0..w4-1:
>
> * The array p is derived as follows for i = 0..6:
>  * If i is less than 5, p[ i ] is derived as follows:
>   * If i2 is equal to 0, p[ i ] is set equal to AboveRow[ ( j4 << 2 ) + i - 1 ].
>   * Otherwise (i2 is not equal to 0), p[ i ] is set equal to pred[ ( i2 << 1 ) - 1 ][ ( j4 << 2 ) + i - 1 ].
>  * Otherwise (i is greater than or equal to 5), p[ i ] is derived as follows:
>   * If j4 is equal to 0, p[ i ] is set equal to LeftCol[ ( i2 << 1 ) + i - 5 ].
>   * Otherwise (j4 is not equal to 0), p[ i ] is set equal to pred[ ( i2 << 1 ) + i - 5 ][ ( j4 << 2 ) - 1 ].
> * The following steps apply for i1 = 0..1, j1 = 0..3:
>  * The variable pr is set equal to 0.
>  * The variable pr is incremented by Intra_Filter_Taps[ filter_intra_mode ][ ( i1 << 2 ) + j1 ][ i ] * p[ i ] for i = 0..6.
>  * pred[ ( i2 << 1 ) + i1 ][ ( j4 << 2 ) + j1 ] is set equal to Clip1( Round2Signed( pr, INTRA_FILTER_SCALE_BITS ) ).

i2=0..h2-1. j4=0..w4-1 について、以下の手順を適用します。

 * 配列 p を i=0..6 について求めます
  * i<5 ならば、p[i] を以下のように求めます
   * i2==0 ならば、p[i] = AboveRow[ ( j4 << 2 ) + i - 1 ]
   * i2!=0 ならば、p[i] = pred[ ( i2 << 1 ) - 1 ][ ( j4 << 2 ) + i - 1 ]
  * i>=5 ならば、p[i] を以下のように求めます
   * j4==0 ならば、p[i] = LeftCol[ ( i2 << 1 ) + i - 5 ]
   * j4!=0 ならば、p[i] = pred[ ( i2 << 1 ) + i - 5 ][ ( j4 << 2 ) - 1 ]
 * i1=0..1, j1=0..3 について、以下の手順を適用します。
  * pr =0
  * pr += Intra_Filter_Taps[ filter_intra_mode ][ ( i1 << 2 ) + j1 ][ i ] * p[ i ], i=0.6
  * pred[ ( i2 << 1 ) + i1 ][ ( j4 << 2 ) + j1 ] = Clip1( Round2Signed( pr, INTRA_FILTER_SCALE_BITS ) )

> The output of the process is the array pred.

この処理の出力は、配列 pred です。

#### 7.10.1.3. Directional Intra Prediction Process

> The inputs to this process are:
>
> * a variable plane specifying which plane is being predicted,
> * variables x and y specifying the location of the top left sample in the CurrFrame[ plane ] array of the current transform block,
> * a variable haveLeft that is equal to 1 if there are valid samples to the left of this transform block,
> * a variable haveAbove that is equal to 1 if there are valid samples above this transform block,
> * a variable mode specifying the type of intra prediction to apply,
> * a variable w specifying the width of the region to be predicted,
> * a variable h specifying the height of the region to be predicted,
> * a variable maxX specifying the largest valid x coordinate for the current plane,
> * a variable maxY specifying the largest valid y coordinate for the current plane.

この処理の入力は以下のとおりです。

 * 予測するプレーン plane
 * カレント変換ブロック左上角の CurrFrame[planee] 内の座標 (x, y)
 * 変換ブロックの左に有効な画素があるかどうかの変数 haveLeft
 * 変換ブロックの上に有効な画素があるかどうかの変数 haveAbove
 * イントラ予想モード mode
 * 予測領域の幅　w
 * 予測領域の高さ　h
 * カレントプレーン内のx軸の最大の有効な値 maxX
 * カレントプレーン内のy軸の最大の有効な値 maxY

> The output of this process is a 2D array named pred containing the intra predicted samples.

この処理の出力は、イントラ予測された画素を含む2次元配列 pred です。

> The process uses a directional filter to generate filtered samples from the samples in LeftCol and AboveRow.

この処理では、LeftCol, AboveCol 内の画素からフィルタされた画素を生成するために、以下のようなフィルタを使います。

> The following ordered steps apply:
>
> 1. The variable angleDelta is derived as follows:
>  * If plane is equal to 0, angleDelta is set equal to AngleDeltaY.
>  * Otherwise (plane is not equal to 0), angleDelta is set equal to AngleDeltaUV.
> 2. The variable pAngle is set equal to ( Mode_To_Angle[ mode ] + angleDelta * ANGLE_STEP ).
> 3. The variables upsampleAbove and upsampleLeft are set equal to 0.
> 4. If enable_intra_edge_filter is equal to 1, the following applies:
>  * If pAngle is not equal to 90 and pAngle is not equal to 180, the following applies:
>   * If (pAngle > 90) and (pAngle < 180) and (w + h) >= 24), the filter corner process specified in section 7.10.1.6 is invoked and the output assigned to both LeftCol[ -1 ] and AboveRow[ -1 ].
>   * The intra filter type process specified in section 7.10.1.7 is invoked with the input variable plane and the output assigned to filterType.
>   * haveAbove is equal to 1, the following steps apply:
>      * The intra edge filter strength selection process specified in section 7.10.1.8 is invoked with w, h, filterType, and pAngle - 90 as inputs, and the output assigned to the variable strength.
>      * The variable numPx is set equal to Min( w, ( maxX - x + 1 ) ) + ( pAngle < 90 ? h : 0 )+ 1.
>      * The intra edge filter process specified in section 7.10.1.11 is invoked with the parameters numPx, strength, and 0 as inputs.
>   * If haveLeft is equal to 1, the following steps apply:
>      * The intra edge filter strength selection process specified in section 7.10.1.8 is invoked with w, h, filterType, and pAngle - 180 as inputs, and the output assigned to the variable strength.
>      * The variable numPx is set equal to Min( h, ( maxY - y + 1 ) ) + ( pAngle > 180 ? w : 0 ) + 1.
>      * The intra edge filter process specified in section 7.10.1.11 is invoked with the parameters numPx, strength, and 1 as inputs.
>  * The intra edge upsample selection process specified in section 7.10.1.9 is invoked with w, h, filterType, and pAngle - 90 as inputs, and the output assigned to the variable upsampleAbove.
>  * The variable numPx is set equal to ( w + (pAngle < 90 ? h : 0) ).
>  * If upsampleAbove is equal to 1, the intra edge upsample process specified in section 7.10.1.10 is invoked with the parameters numPx and 0 as inputs.
>  * The intra edge upsample selection process specified in section 7.10.1.9 is invoked with w, h, filterType, and pAngle - 180 as inputs, and the output assigned to the variable upsampleLeft.
>  * The variable numPx is set equal to ( h + (pAngle < 180 ? w : 0) ).
>  * If upsampleLeft is equal to 1, the intra edge upsample process specified in section 7.10.1.10 is invoked with the parameters numPx and 1 as inputs.
> 5. The variable dx is derived as follows:
>  * If pAngle is greater than 0 and less than 90, dx is set equal to Dr_Intra_Derivative[ pAngle ].
>  * Otherwise, if pAngle is greater than 90 and less than 180, dx is set equal to Dr_Intra_Derivative[ 180 - pAngle ].
>  * Otherwise, dx is undefined.
> 6. The variable dy is derived as follows:
>  * If pAngle is greater than 90 and less than 180, dy is set equal to Dr_Intra_Derivative[ pAngle - 90 ].
>  * Otherwise, if pAngle is greater than 180 and less than 270, dy is set equal to Dr_Intra_Derivative[ 270 - pAngle ].
>  * Otherwise, dy is undefined.
> 7. If pAngle is greater than 0 and less than 90, the following steps apply for i = 0..h-1, for j = 0..w-1:
>  * The variable idx is set equal to ( i + 1 ) * dx.
>  * The variable base is set equal to (idx >> ( 6 - upsampleAbove ) ) + (j << upsampleAbove).
>  * The variable shift is set equal to ( (idx << upsampleAbove) >> 1 ) & 0x1F.
>  * The variable maxBaseX is set equal to (w + h - 1) << upsampleAbove.
>  * If base is less than maxBaseX, pred[ i ][ j ] is set equal to Clip1( Round2( AboveRow[ base ] * ( 32 - shift ) + AboveRow[ base + 1 ] * shift, 5 ) ).
>  * Otherwise (base is greater than or equal to maxBaseX), pred[ i ][ j ] is set equal to AboveRow[maxBaseX ].
> 8. Otherwise, if pAngle is greater than 90 and pAngle is less than 180, the following steps apply for i = 0..h-1, for j =0..w-1:
>  * The variable idx is set equal to ( j << 6 ) - ( i + 1 ) * dx.
>  * The variable base is set equal to idx >> ( 6 - upsampleAbove ).
>  * If base is greater than or equal to -(1 << upsampleAbove), the following steps apply:
>      * The variable shift is set equal to ( ( idx << upsampleAbove ) >> 1 ) & 0x1F.
>      * pred[ i ][ j ] is set equal to Clip1( Round2( AboveRow[ base ] * ( 32 - shift ) + AboveRow[ base+ 1 ] * shift, 5 ) ).
>  * Otherwise (base is less than -(1 << upsampleAbove), the following steps apply:
>      * The variable idx is set equal to ( i << 6 ) - ( j + 1 ) * dy.
>      * The variable base is set equal to idx >> ( 6 - upsampleLeft ).
>      * The variable shift is set equal to ( ( idx << upsampleLeft ) >> 1 ) & 0x1F.
>      * pred[ i ][ j ] is set equal to Clip1( Round2( LeftCol[ base ] * ( 32 - shift ) + LeftCol[ base + 1 ] *shift, 5 ) ).
> 9. Otherwise, if pAngle is greater than 180 and pAngle is less than 270, the following steps apply for i = 0..h-1, for j = 0..w-1:
>  * The variable idx is set equal to ( j + 1 ) * dy.
>  * The variable base is set equal to ( idx >> ( 6 - upsampleLeft ) ) + ( i << upsampleLeft ).
>  * The variable shift is set equal to ( ( idx << upsampleLeft ) >> 1 ) & 0x1F.
>  * The variable maxBaseY is set equal to ( w + h - 1 ) << upsampleLeft.
>  * If base is less than maxBaseY, pred[ i ][ j ] is set equal to Clip1( Round2( LeftCol[ base ] * ( 32 - shift ) + LeftCol[ base + 1 ] * shift, 5 ) ).
>  * Otherwise (base is greater than or equal to maxBaseY), pred[ i ][ j ] is set equal to LeftCol[ maxBaseY ].
> 10. Otherwise, if pAngle is equal to 90, pred[ i ][ j ] is set equal to AboveRow[ j ] with j = 0..w-1 and i = 0..h-1 (each row of the block is filled with a copy of AboveRow).
> 11. Otherwise, if pAngle is equal to 180, pred[ i ][ j ] is set equal to LeftCol[ i ] with j = 0..w-1 and i = 0..h-1 (each column of the block is filled with a copy of LeftCol).

以下の手順を適用します。

 1. angleDelta を以下のように求めます。
  * plane==0 ならば、angleDelta = AngleDeltaY
  * plane!=0 ならば、angleDelta = AngleDeltaUV
 2. pAngle = ( Mode_To_Angle[ mode ] + angleDelta * ANGLE_STEP )
 3. upsampleAbove = upsampleLeft = 0
 4. enable_intra_edge_filter==1 ならば、以下を適用します。
  * pAngle!=90 && pAngle!=180 ならば、以下を適用します。
   * (pAngle > 90) && (pAngle < 180) && (w + h) >= 24) ならば、角フィルタ処理（7.10.1.6節）を呼び出し、出力を LeftCol[-1], AbovRow[-1] の両方に割り当てます。
   * haveAbove==1 ならば、以下の手順を適用します。
      * イントラエッジフィルタ強度選択処理（7.10.1.8節）を、w, h, filterType, pAngle - 90 を入力として呼び出し、出力を　strength に割り当てます。
      * numPx = Min( w, ( maxX - x + 1 ) ) + ( pAngle < 90 ? h : 0 ) + 1
      * イントラエッジフィルタ処理（7.10.1.11節）を、numPx, strength, 0 を入力として呼び出します。
   * haveLeft==1 ならば、以下の手順を適用します。
      * イントラエッジフィルタ強度選択処理（7.10.1.8節）を、w, h, filterType, pAngle - 180 を入力として呼び出し、出力を　strength に割り当てます。
      * numPx = Min( w, ( maxY - y + 1 ) ) + ( pAngle > 180 ? w : 0 ) + 1
      * イントラエッジフィルタ処理（7.10.1.11節）を、numPx, strength, 1 を入力として呼び出します。
  * イントラエッジアップサンプル選択処理（7.10.1.9節）を、w, h, filterType, pAngle - 90 を入力よして呼び出し、出力を upsampleAbove に割り当てます。
  * numPx = ( w + (pAngle < 90 ? h : 0) )
  * upsampleAbove==1 ならば、イントラエッジアップサンプル処理（7.10.1.10節）を、numPx, 0 を入力として呼び出します。
  * イントラエッジアップサンプル選択処理（7.10.1.9節）を、w, h, filterType, pAngle - 180 を入力よして呼び出し、出力を upsampleLeft に割り当てます。
  * numPx = ( h + (pAngle < 180 ? w : 0) )
  * upsampleLeft==1 ならば、イントラエッジアップサンプル処理（7.10.1.10節）を、numPx, 1 を入力として呼び出します。
 5. dx を以下のように求めます。
  * pAngle>0 && pAngle<90 ならば、dx = Dr_IntraDerivative[pAngle]
  * そうではなく、pAngle>90 && pAngke<180 ならば、dx = Dr_IntraDerivative[180-pAngle]
  * そうではなければ、dx は未定義とします。
 6. dy を以下のように求めます。
  * pAngle>90 && pAngle<180 ならば、dy = Dr_IntraDerivative[pAngle-90]
  * そうではなく、pAngle>180 && pAngke<270 ならば、dy = Dr_IntraDerivative[270-pAngle]
  * そうではなければ、dy は未定義とします。
 7. pAngle>0 && pAngle<90 ならば、i=0..h-1, j=0..w-1 について以下の手順を適用します。
  * idx = ( i + 1 ) * dx
  * base = (idx >> ( 6 - upsampleAbove ) ) + (j << upsampleAbove)
  * shift = ( (idx << upsampleAbove) >> 1 ) & 0x1F
  * maxBaseX = (w + h - 1) << upsampleAbove
  * base<maxBaseX ならば、pred[ i ][ j ] = Clip1( Round2( AboveRow[ base ] * ( 32 - shift ) + AboveRow[ base + 1 ] * shift, 5 ) )
  * そうではなければ（base>=maxBaseX ならば）、pred[ i ][ j ] = AboveRow[maxBaseX ]
 8. そうではなく、pAngle>90 && pAngle<180 ならば、i=0..h-1, j=0..w-1 について以下の手順を適用します。
  * idx = ( j << 6 ) - ( i + 1 ) * dx
  * base = idx >> ( 6 - upsampleAbove )
  * base>=-(1 << upsampleAbove) ならば、以下の手順を適用します。
      * shift = ( ( idx << upsampleAbove ) >> 1 ) & 0x1F
      * pred[ i ][ j ] =o Clip1( Round2( AboveRow[ base ] * ( 32 - shift ) + AboveRow[ base+ 1 ] * shift, 5 ) )
  * そうではなければ（base<-(1 << upsampleAblve) ならば）、以下の手順を適用します。
        * idx = ( i << 6 ) - ( j + 1 ) * dy
        * base = idx >> ( 6 - upsampleLeft )
        * shift = ( ( idx << upsampleLeft ) >> 1 ) & 0x1F
        * pred[ i ][ j ] = Clip1( Round2( LeftCol[ base ] * ( 32 - shift ) + LeftCol[ base + 1 ] *shift, 5 ) )
 9. そうではなく、pAngle>180 && pAngle<270 ならば、i=0..h-1, j=0..w-1 について以下の手順を適用します。
  * idx = ( j + 1 ) * dy
  * base = ( idx >> ( 6 - upsampleLeft ) ) + ( i << upsampleLeft )
  * shift = ( ( idx << upsampleLeft ) >> 1 ) & 0x1F
  * maxBaseY = ( w + h - 1 ) << upsampleLeft
  * base<maxBaseY ならば、pred[ i ][ j ] = Clip1( Round2( LeftCol[ base ] * ( 32 - shift ) + LeftCol[ base + 1 ] * shift, 5 ) )
  * そうではなければ（base>=maxBaseY ならば）、pred[ i ][ j ] = LeftCol[ maxBaseY ]
 10. そうではなく、pAngle==90 ならば、pred[ i ][ j ] = AboveRow[ j ], j = 0..w-1, i = 0..h-1 （ブロックの各列を AboveRow のコピーで埋める）
 11. そうではなく、pAngle==180ならば、pred[ i ][ j ] = LeftCol[ i ], j = 0..w-1, i = 0..h-1 （ブロックの各行を LeftCol のコピーで埋める） 

> The output of the process is the array pred.

この処理の出力は、配列 pred です。


#### 7.10.1.4. DC Intra Prediction Process

The inputs to this process are:

> * a variable haveLeft that is equal to 1 if there are valid samples to the left of this transform block,
> * a variable haveAbove that is equal to 1 if there are valid samples above this transform block,
> * a variable log2W specifying the base 2 logarithm of the width of the region to be predicted,
> * a variable log2H specifying the base 2 logarithm of the height of the region to be predicted,
> * a variable w specifying the width of the region to be predicted,
> * a variable h specifying the height of the region to be predicted.

この処理の入力は以下のとおりです。

 * haveLeft==1 ならば、この変換ブロックの左に有効な画素が存在する
 * haveAbove==1 ならば、この変換ブロックの上に有効な画素が存在する
 * 予測領域のlog2幅 log2W
 * 予測領域のlog2高さ log2H
 * 予測領域の幅 w
 * 予測領域の高さ h

> The output of this process is a 2D array named pred containing the intra predicted samples.

この処理の出力は、イントラ予測画素を含む2次元配列 pred です。

> The process averages the available edge samples in LeftCol and AboveRow to generate the prediction as follows:
>
> * If haveLeft is equal to 1 and haveAbove is equal to 1, pred[ i ][ j ] is set equal to avg with i = 0..h-1 and j = 0..w-1.

この処理は、LeftCol, AboveRow の有効なエッジ画素を平均して、以下のように予測値を生成します。

 * haveLeft==1 && haveAbove==1 ならば、pred[i][j] = avg, i=0..h-1, j=0..w-1

> The variable avg (the average of the samples in union of AboveRow and LeftCol) is specified as follows:

avg（AboveRow, LeftCol の結合の平均）を以下のように規定します。

```C++
sum = 0
for ( k = 0; k < h; k++ )
  sum += LeftCol[ k ]
for ( k = 0; k < w; k++ )
  sum += AboveRow[ k ]
sum += ( w + h ) >> 1
avg = sum / ( w + h )
```

> Note: The reference code shows how the division by (w+h) can be implemented with multiplication and shift operations.

注意：
リファレンスコードでは、どのように (w+h) を乗算とシフト演算で実装しているかを示しています。

> * Otherwise if haveLeft is equal to 1 and haveAbove is equal to 0, pred[ i ][ j ] is set equal to leftAvg with i = 0..h-1 and j = 0..w-1.
>
> The variable leftAvg is specified as follows:

 * そうではなく、haveLeft==1 && haveAbove==0 ならば、pred[i][j] = leftAvg, i=0..h-1, j=0..w-1 

leftAvg を以下のように規定します。

```C++
sum = 0
for ( k = 0; k < h; k++ ) {
  sum += LeftCol[ k ]
}
leftAvg = Clip1( ( sum + ( h >> 1 ) ) >> log2H )
```

> * Otherwise if haveLeft is equal to 0 and haveAbove is equal to 1, pred[ i ][ j ] is set equal to aboveAvg with i = 0..h-1 and j = 0..w-1. 
>
> The variable aboveAvg is specified as follows:

 * そうではなく、haveLeft==0 && haveAbove==1 ならば、pred[i][j] = aboveAvg, i=0..h-1, j=0..w-1

aboveAvg を以下のように規定します。

```C++
sum = 0
for ( k = 0; k < w; k++ ) {
  sum += AboveRow[ k ]
}
aboveAvg = Clip1( ( sum + ( w >> 1 ) ) >> log2W )
```

> * Otherwise (haveLeft is equal to 0 and haveAbove is equal to 0), pred[ i ][ j ] is set equal to 1 << ( BitDepth - 1 ) with i = 0..h-1 and j = 0..w-1.

そうではなければ（haveLeft==0 &6 haveAbove==0） ならば、pred[i][j] = 1 << (BitDepth - 1), i=0..h-1. j=0..h-1

> The output of the process is the array pred.

この処理の出力は、配列 pred です。

#### 7.10.1.5. Smooth Intra Prediction Process

>The inputs to this process are:
>
> * a variable mode specifying the type of intra prediction to apply,
> * a variable log2W specifying the base 2 logarithm of the width of the region to be predicted,
> * a variable log2H specifying the base 2 logarithm of the height of the region to be predicted,
> * a variable w specifying the width of the region to be predicted,
> * a variable h specifying the height of the region to be predicted.

この処理の入力は以下のとおりです。

 * イントラ予測のタイプ mode
 * 予測領域のlog2幅 log2W
 * 予測領域のlog2高さ log2H
 * 予測領域の幅 w
 * 予測領域の高さ h

>The output of this process is a 2D array named pred containing the intra predicted samples.

この処理の出力は、予測された画素を含む2次元配列 pred です。

>The process uses linear interpolation to generate filtered samples from the samples in LeftCol and AboveRow as follows:

この処理では、LeftCol, AboveRow の画素を線形補間でフィルタした画素を使います。

> * If mode is equal to SMOOTH_PRED, the following ordered steps apply for i = 0..h-1, for j = 0..w-1:
>  1. The array smWeightsX is set dependent on the value of log2W according to the following table:
>  2. The array smWeightsY is set dependent on the value of log2H according to the following table:
>  3. The variable smoothPred is set as follows:
>  4. pred[ i ][ j ] is set equal to Round2( smoothPred, 9 ).

 * mode==SMOOTH_PRED ならば、以下の手順を i=0..h-1, j=0..w-1 について適用します。
  1. 配列 smWeightsX を、log2W 値に依存して以下のテーブルの通り設定します。
  2. 配列 smWeightsY を、log2H 値に依存して以下のテーブルの通り設定します。
  3. smoothPred を以下のように設定します。
  4. pred[ i ][ j ] = Round2( smoothPred, 9 )

```C++
smoothPred = smWeightsY[ i ] * AboveRow[ j ] + ( 256 - smWeightsY[ i ] ) * LeftCol[ h - 1 ] +
             smWeightsX[ j ] * LeftCol[ i ]  + ( 256 - smWeightsX[ j ] ) * AboveRow[ w - 1 ]
```

|log2W|smWeightsX|
|:---:|:---:|
|2|Sm_Weights_Tx_4x4|
|3|Sm_Weights_Tx_8x8|
|4|Sm_Weights_Tx_16x16|
|5|Sm_Weights_Tx_32x32|
|6|Sm_Weights_Tx_64x64|

|log2H| smWeightsY|
|:---:|:---:|
|2| Sm_Weights_Tx_4x4|
|3| Sm_Weights_Tx_8x8|
|4| Sm_Weights_Tx_16x16|
|5| Sm_Weights_Tx_32x32|
|6| Sm_Weights_Tx_64x64|

 * Otherwise if mode is equal to SMOOTH_V_PRED, the following ordered steps apply for i = 0..h-1, for j = 0..w-1:
  1. The array smWeights is set dependent on the value of log2H according to the following table:
  2. The variable smoothPred is set as follows:
  3. pred[ i ][ j ] is set equal to Round2( smoothPred, 8 ).

 * そうではなく、mode==SMOOTH_V_PRED ならば、以下の手順を i=0..h-1, h=0..w-1 について適用します
  1. 配列 smWeights を、log2H 値に依存して以下のテーブルのとおり設定します。
  2. smoothPred を以下のように設定します。
  3. pred[ i ][ j ] = Round2( smoothPred, 8 )

```C++
smoothPred = smWeights[ i ] * AboveRow[ j ] + ( 256 - smWeights[ i ] ) * LeftCol[ h - 1 ]
```

|log2H| smWeights|
|:---:|:---:|
|2| Sm_Weights_Tx_4x4|
|3| Sm_Weights_Tx_8x8|
|4| Sm_Weights_Tx_16x16|
|5| Sm_Weights_Tx_32x32|
|6| Sm_Weights_Tx_64x64|

> * Otherwise if mode is equal to SMOOTH_H_PRED, the following ordered steps apply for i = 0..h-1, for j = 0..w-1:
>  1. The array smWeights is set dependent on the value of log2W according to the following table:
>  2. The variable smoothPred is set as follows:
>  3. pred[ i ][ j ] is set equal to Round2( smoothPred, 8 ).

 * そうではなく、mode==SMOOTH_H_PRED ならば、以下の手順を i=0..h-1, j=0..w-1 について適用します。
  1. 配列 smWeights を、log2W 値に依存して以下のテーブルのとおり設定します。
  2. smoothPred を以下のように設定します。
  3. pred[ i ][ j ] = Round2( smoothPred, 8 )

```C+
smoothPred = smWeights[ j ] * LeftCol[ i ] + ( 256 - smWeights[ j ] ) * AboveRow[ w - 1 ]
```

|log2W| smWeights|
|:---:|:---:|
|2| Sm_Weights_Tx_4x4|
|3| Sm_Weights_Tx_8x8|
|4| Sm_Weights_Tx_16x16|
|5| Sm_Weights_Tx_32x32|
|6| Sm_Weights_Tx_64x64|

>The output of the process is the array pred.

この処理の出力は、配列 pred です。


#### 7.10.1.6. Filter Corner Process

>This process uses a three tap filter to compute the value to be used for the top-left corner.
>The variable s is set equal to LeftCol[ 0 ] * 5 + AboveRow[ -1 ] * 6 + AboveRow[ 0 ] * 5.
>The output of this process is Round2(s, 4).

この処理では、左上角に使うための値を3タップフィルタで生成します。
s = LeftCol[ 0 ] * 5 + AboveRow[ -1 ] * 6 + AboveRow[ 0 ] * 5
この処理の出力は、Round2(s, 4) です


#### 7.10.1.7. Intra Filter Type Process

> The input to this process is a variable plane specifying the color plane being processed.

この処理の入力は、どの色プレーンを処理するかを指定する plane です。

> The output of this process is a variable filterType that is set to 1 if either the block above or to the left uses a smooth prediction mode.

この処理の出力は filterType で、1 ならばブロックの上と左の両方をスムース予測モードで使います。

>The process is specified as follows:

この処理は以下のように規定します。

```C++
get_filter_type( plane ) {
  aboveSmooth = 0
  leftSmooth = 0
  if ( ( plane == 0 ) ? AvailU : AvailUChroma ) {
    r = MiRow - 1
    c = MiCol
    if ( plane > 0 ) {
      if ( subsampling_x && !( MiCol & 1 ) )
        c++
      if ( subsampling_y && ( MiRow & 1 ) )
        r--
    }
    aboveSmooth = is_smooth( r, c, plane )
  }
  if ( ( plane == 0 ) ? AvailL : AvailLChroma ) {
    r = MiRow
    c = MiCol - 1
    if ( plane > 0 ) {
      if ( subsampling_x && ( MiCol & 1 ) )
        c--
      if ( subsampling_y && !( MiRow & 1 ) )
        r++
    }
  leftSmooth = is_smooth( r, c, plane )
  }
  return aboveSmooth || leftSmooth
}
```

> where the function is_smooth indicates if a prediction mode is one of the smooth intra modes and is specified as:

ここで、関数 is_smooth は、予測モードがスムースイントラモードの1つかどうかを示し、以下のように規定されます。

```C++
is_smooth( row, col, plane ) {
  if ( plane == 0 ) {
    mode = YModes[ row ][ col ]
  } else {
    if ( RefFrames[ row ][ col ][ 0 ] > INTRA_FRAME )
      return 0
  mode = UVModes[ row ][ col ]
  }
  return (mode == SMOOTH_PRED || mode == SMOOTH_V_PRED || mode == SMOOTH_H_PRED)
}
```

#### 7.10.1.8. Intra Edge Filter Strength Selection Process

>The inputs to this process are:
>
> * a variable w containing the width of the transform in samples,
> * a variable h containing the height of the transform in samples,
> * a variable filterType that is 0 or 1 that controls the strength of filtering,
> * a variable delta containing an angle difference in degrees.

この処理の入力は以下のとおりです。

 * 画素単位の変換の幅 w
 * 画素単位の変換の高さ h
 * フィルタ強度 1 or 2 を示す filterype
 * 度単位での角度差分 delta

> The output is an intra edge filter strength from 0 to 3 inclusive.

この処理の出力は、0..3 までのイントラエッジフィルタ強度です。

> The variable d is set equal to Abs( delta ).
> The variable blkWh (containing the sum of the dimensions) is set equal to w + h.

d = Abs(delta)
blkWh = w + h, （縦横の合計）

> The output variable strength is specified as follows:

出力 strength を以下のように規定します。

```C++
strength = 0
if (filterType == 0) {
  if (blkWh <= 8) {
    if (d >= 56) strength = 1
  } else if (blkWh <= 12) {
    if (d >= 40) strength = 1
  } else if (blkWh <= 16) {
    if (d >= 40) strength = 1
  } else if (blkWh <= 24) {
    if (d >= 8) strength = 1
    if (d >= 16) strength = 2
    if (d >= 32) strength = 3
  } else if (blkWh <= 32) {
    if (d >= 1) strength = 1
    if (d >= 4) strength = 2
    if (d >= 32) strength = 3
  } else {
    if (d >= 1) strength = 3
  }
} else {
  if (blkWh <= 8) {
    if (d >= 40) strength = 1
    if (d >= 64) strength = 2
  } else if (blkWh <= 16) {
    if (d >= 20) strength = 1
    if (d >= 48) strength = 2
  } else if (blkWh <= 24) {
    if (d >= 4) strength = 3
  } else {
    if (d >= 1) strength = 3
  }
}
```

#### 7.10.1.9. Intra Edge Upsample Selection Process

>The inputs to this process are:
>
> * a variable w containing the width of the transform in samples,
> * a variable h containing the height of the transform in samples,
> * a variable filterType that is 0 or 1 that controls the strength of filtering,
> * a variable delta containing an angle difference in degrees.

この処理の入力は以下のとおりです。

 * 画素単位の変換の幅 w
 * 画素単位の変換の高さ h
 * フィルタ強度 1 or 2 を示す filterype
 * 度単位での角度差分 delta

> The output is a flag useUpsample that is true if upsampling should be applied to the edge.

この処理の出力は、エッジにアップサンプリングをするかどうかのフラグです。

>The variable d is set equal to Abs( delta ).
>The variable blkWh (containing the sum of the dimensions) is set equal to w + h.

d = Abs(delta)
blkWh = w + h, （縦横の合計）

>The output variable useUpsample is specified as follows:

出力 useUpsample を以下のように規定します。

```C++
if (d <= 0 || d >= 40) {
  useUpsample = 0
} else if ( filterType == 0 ) {
  useUpsample = (blkWh <= 16)
} else {
  useUpsample = (blkWh <= 8)
}
```

#### 7.10.1.10. Intra Edge Upsample Process

>The inputs to this process are:
>
> * a variable numPx specifying the number of samples to filter,
> * a variable dir containing 0 when filtering the above samples, and 1 when filtering the left samples.

この処理の入力は以下のとおりです。

 * フィルタすべき画素数 numPx
 * 上の画素をフィルタするならば 0、左の画素をフィルタするならば 1 である dir

>The output of this process are upsampled samples in the AboveRow and LeftCol arrays.

この処理の出力は、AboveRow と LeftCol をアップサンプルした画素です。

>The variable buf is set depending on dir:
>
> * If dir is equal to 0, buf is set equal to a reference to AboveRow.
> * Otherwise (dir is equal to 1), buf is set equal to a reference to LeftCol.

buf を dir に依存して設定します。

 * dir==0 ならば、buf = AboveRow への参照
 * dir==1 ならば、buf = LeftCol への参照

>Note: buf is a reference to either AboveRow or LeftCol. “reference” indicates that modifying values in buf modifies values in the original array.

注意：
buf は AboveRow, LeftCol どちらかへの参照です。
「参照」とは、buf の値の変更によって、オリジナル配列の値が変更されることを示します。

>When the process starts, entries -1 to numPx-1 are valid in buf and contain the original values. >When the process completes, entries -2 to 2*numPx-2 are valid in buf and contain the upsampled values.
>An array dup of length numPx+3 is generated by extending buf by one sample at the start and end as follows:

この処理を開始するとき、buf 内の -1 .. numPx-1 までのエントリには、オリジナルの値が入っています。
この処理が完了したとき、buf 内の -3 .. 2*numP-2 までのエントリに、っプサンプルされた値が入ります。
長さ numPx + 3 の配列 dup を、buf の最初と最後の1画素を拡張することによって、生成します。

```C++
dup[ 0 ] = buf[ -1 ]
for (i = -1; i < numPx; i++) {
  dup[ i + 2 ] = buf[ i ]
}
dup[ numPx + 2 ] = buf[ numPx - 1 ]
```

>The upsampling process (modifying values in buf) is specified as follows:

（buf 内の値変更する）アップサンプリング処理を以下のように規定します。

```C++
buf[-2] = dup[0]
for (i = 0; i < numPx; i++) {
  s = -dup[i] + (9 * dup[i + 1]) + (9 * dup[i + 2]) - dup[i + 3]
  s = Clip1( Round2(s, 4) )
  buf[ 2 * i - 1 ] = s
  buf[ 2 * i ] = dup[i + 2]
}
```

#### 7.10.1.11. Intra Edge Filter Process

>The inputs to this process are:
>
> * a size sz,
> * a filter strength strength between 0 and 3 inclusive,
> * an edge direction left (when equal to 1, it specifies a vertical edge; when equal to 0, it specifies a horizontal edge.

この処理の入力は以下のとおりです。

 * サイズ sz
 * 0..3 までのフィルタ強度 strength
 * エッジ方向 left（1ならば垂直エッジで、0ならば水平エッジ）

> The process filters the LeftCol (if left is equal to 1) or AboveRow (if left is equal to 0) arrays.

この処理では、LeftCol (left==1) あるいは AboveRow (left==0) をフィルタします。

>If strength is equal to 0, the process returns without doing anything.

strength==0 ならば、何もせずに処理を終了します。

>Otherwise (strength is not equal to 0), the following ordered steps apply for i = 1..sz-1:
>
> 1. The variable s is set equal to 0.
> 2. The following steps now apply for j = 0..INTRA_EDGE_TAPS-1.
>    * The variable k is set equal to Clip3( 0, sz - 1, i - 2 + j ).
>    * The variable s is incremented by Intra_Edge_Kernel[ strength - 1 ][ j ] * ( left ? LeftCol[ k - 1 ] : AboveRow[ k - 1 ] ).
> 3. If left is equal to 1, LeftCol[ i - 1 ] is set equal to ( s + 8 ) >> 4.
> 4. If left is equal to 0, AboveRow[ i - 1 ] is set equal to ( s + 8 ) >> 4.

そうではない（strength!=0）ならば、i=0..sz-1 について以下の手順を適用します。

 1. s = 0
 2. j = 0..INTRA_EDGE_TAPS-1 について、以下の手順を適用します。
   * k = Clip3(0, sz-1, i-2+j)
   * s += Intra_Edge_Kernel[ strength - 1 ][ j ] * ( left ? LeftCol[ k - 1 ] : AboveRow[ k - 1 ] )
 3. left==1 ならば、LeftCol[i-1] = (s+8) >> 4
 4. left==0 ならば、AboveRow[i-1] = (s+8) >> 4

>The array Intra_Edge_Kernel is specified as follows:

配列 Intra_Edge_Kernel を以下のように規定します。

```C++
Intra_Edge_Kernel[INTRA_EDGE_KERNELS][INTRA_EDGE_TAPS] = {
  { 0, 4, 8, 4, 0 },
  { 0, 5, 6, 5, 0 },
  { 2, 4, 4, 4, 2 }
}
```