<?php
/**
* SeekQuarry/Yioop --
* Open Source Pure PHP Search Engine, Crawler, and Indexer
*
* Copyright (C) 2009 - 2026 Chris Pollett chris@pollett.org
*
* LICENSE:
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* END LICENSE
*
* @author Chris Pollett chris@pollett.org
* @license https://www.gnu.org/licenses/ GPL3
* @link https://www.seekquarry.com/
* @copyright 2009 - 2026
* @filesource
*
* This class holds the orders H.264 visits the values of a block in.
* Theora and VP8 use the same orders.
*/
namespace seekquarry\yioop\library\av_processing;
/**
* H264Scan holds the orders H.264 visits the values of a block in. Theora
* and VP8 use the same orders.
*/
final class H264Scan
{
/**
* ZZ4 says where each of the sixteen places of a four by four block
* sits in the picture. The format visits a block's places
* corner to corner rather than row by row, so a decoder needs
* this to put the values back where they belong.
*/
public const ZZ4 = [0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15];
/**
* ZZ8 says where each of the sixty-four places of an eight by eight
* block sits in the picture, for the same corner to corner
* order.
*/
public const ZZ8 = [
0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26, 33,
40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57, 50,
43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31, 39, 46,
53, 60, 61, 54, 47, 55, 62, 63,
];
/**
* DEFAULT_4X4_INTRA is the default four by four intra the format fixes.
* @var mixed
*/
public const DEFAULT_4X4_INTRA
= [6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42];
/**
* DEFAULT_4X4_INTER is the default four by four inter the format fixes.
* @var mixed
*/
public const DEFAULT_4X4_INTER
= [10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34];
/**
* DEFAULT_8X8_INTRA is the default eight by eight intra the format fixes.
* @var mixed
*/
public const DEFAULT_8X8_INTRA = [
6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23, 23, 23,
23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27,
29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31, 31, 33, 33, 33, 33, 33,
36, 36, 36, 36, 38, 38, 38, 40, 40, 42,
];
/**
* DEFAULT_8X8_INTER is the default eight by eight inter the format fixes.
* @var mixed
*/
public const DEFAULT_8X8_INTER = [
9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21, 21, 21,
21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24, 24, 24, 24, 24,
25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28,
30, 30, 30, 30, 32, 32, 32, 33, 33, 35,
];
/**
* CHROMA_QP is table 8-15, 8-bit: the quantizer index -> the color
* quantizer.
*/
public const CHROMA_QP = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 34,
35, 35, 36, 36, 37, 37, 37, 38, 38, 38, 39, 39, 39, 39,
];
/**
* V4 is the adjustments a four by four block's values are scaled by, chosen
* by whether the row and column are odd or even.
*/
public const V4 = [
[10, 16, 13], [11, 18, 14], [13, 20, 16],
[14, 23, 18], [16, 25, 20], [18, 29, 23],
];
/**
* V8 is the fixed adjustments for an eight by eight block, Table 8-15.
*/
public const V8 = [
[20, 18, 32, 19, 25, 24], [22, 19, 35, 21, 28, 26], [26, 23, 42, 24, 33,
31],
[28, 25, 45, 26, 35, 33], [32, 28, 51, 30, 40, 38], [36, 32, 58, 34, 46,
43],
];
/**
* eightColumnTransform works out which V8 column applies at raster position
* (x,y) of an eight by eight block
*
* @param int $across how far across the block
* @param int $down how far down the block
* @return int what was read
*/
public static function eightColumnTransform(int $across, int $down): int
{
$i = $down % 4;
$j = $across % 4;
if ($i === 0 && $j === 0) return 0;
if (($down & 1) === 1 && ($across & 1) === 1) return 1;
if ($i === 2 && $j === 2) return 2;
if (($i === 0 && ($across & 1) === 1)
|| (($down & 1) === 1 && $j === 0)) return 3;
if (($i === 0 && $j === 2) || ($i === 2 && $j === 0)) return 4;
return 5;
}
}