⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aiccabac.pas

📁 很好的源代码
💻 PAS
字号:
unit AICCabac;
{ Advanced Image Coding (AIC)
  ===========================
  Base class for Context Adaptive Binary Arithmetic Coding. 
  Parts of the code in this unit are based on the H.264 reference software.
  See JM.txt for license details. }

interface

uses
  AICCommon, Classes;

type
  PCabacContext = ^TCabacContext;
  TCabacContext = record
  { Represents a context by a state (0..63) and Most Probable Symbol (0/1) }
    State: Cardinal;
    MPS  : Cardinal;
  end;

const
  CabacCodeStreamSize = 8192;
  { The Cabac codec reads or writes 8192 bytes at a time }

  CabacBits           = 10;
  { Precision of Cabac values in bits }

  CabacOne            = 1 shl  CabacBits;
  { The value 1 expressed as an integer with a precision of CabacBits bits }

  CabacHalf           = 1 shl (CabacBits - 1);
  { The value 0.5 expressed as an integer with a precision of CabacBits bits }

  CabacQuarter        = 1 shl (CabacBits - 2);
  { The value 0.25 expressed as an integer with a precision of CabacBits bits }

  CabacExpStart       = 13;
  { A threshold used to encode or decode exponential Golomb codes }

type
  TAICCabac = class
  { Base class for Context Adaptive Binary Arithmetic Coding (as used by the
    H.264 video coding standard) }
  private
    FQuality: TAICQuality;
    { The quality level of the image. Used to initialize the contexts with
      appropriate values for this setting }
    FStream: TStream;
    { The stream used for reading and writing Cabac codes }
    procedure InitializeContexts;
    { Initializes all contexts with appropriate values for Quality }
    procedure InitializeContext(out Context: TCabacContext; const M, N: Integer);
    { Used by InitializeContexts }
    procedure InitializeContext1D(const InitData; out Contexts;
      const Count: Integer);
    { Used by InitializeContexts }
    procedure InitializeContext2D(const InitData; out Contexts;
      const Count: Integer);
    { Used by InitializeContexts }
  protected
    BitsToGo: Integer;
    { The number of bits left in the current byte (Buffer) }
    Buffer: Cardinal;
    { The current byte containing encoded/decoded bits }
    Range: Cardinal;
    { The current range representing the probabilities of recent symbols }
    Low: Cardinal;
    { The current lower value representing the probabilities of recent symbols }
    CodeStream: array [0..CabacCodeStreamSize - 1] of Byte;
    { A buffer used for speeding up reading to and writing from files }
    CodeStreamLen: Integer;
    { The length of the CodeStream }
    CtxPredictionMode: array [0..1] of TCabacContext;
    { The contexts used to encode/decode the prediction mode.
      Context 0 is used to code a boolean specifying if the predicted prediction
      mode is used.
      Context 1 is used when the actual prediction mode differs from the
      predicted one. This context is used to encode the actual prediction mode }
    CtxCoefficientMap: array [TAICChannelType,0..62] of TCabacContext;
    { The contexts used to encode/decode boolean values indicating if the
      coefficients at position 0..62 in the zig zag array are
      significant (<> 0). }
    CtxLastCoefficient: array [TAICChannelType,0..62] of TCabacContext;
    { The contexts used to encode/decode boolean values indicating if the
      coefficient at position 0..62 in the zig zag array is the last
      significant coefficient. }
    CtxCoefGreaterOne: array [TAICChannelType,0..4] of TCabacContext;
    { The contexts used to encode/decode if a the absolute value of a
      coefficient is greater than 1 }
    CtxCoefAbsolute: array [TAICChannelType,0..4] of TCabacContext;
    { The contexts used to encode/decode the absolute value of a coefficient
      when it is greater than 1 }
    CtxCodedBlock: TCabacContext;
    { The context used to encode/decode if a block of coefficients contains
      non-zero values }

    property Stream: TStream read FStream;
    { The stream used for reading and writing Cabac codes }
  public
    constructor Create(const AQuality: TAICQuality; const AStream: TStream);
  end;

const
  CabacRLPSTable: array [0..63,0..3] of Byte = (
    ( 128, 176, 208, 240),
    ( 128, 167, 197, 227),
    ( 128, 158, 187, 216),
    ( 123, 150, 178, 205),
    ( 116, 142, 169, 195),
    ( 111, 135, 160, 185),
    ( 105, 128, 152, 175),
    ( 100, 122, 144, 166),
    (  95, 116, 137, 158),
    (  90, 110, 130, 150),
    (  85, 104, 123, 142),
    (  81,  99, 117, 135),
    (  77,  94, 111, 128),
    (  73,  89, 105, 122),
    (  69,  85, 100, 116),
    (  66,  80,  95, 110),
    (  62,  76,  90, 104),
    (  59,  72,  86,  99),
    (  56,  69,  81,  94),
    (  53,  65,  77,  89),
    (  51,  62,  73,  85),
    (  48,  59,  69,  80),
    (  46,  56,  66,  76),
    (  43,  53,  63,  72),
    (  41,  50,  59,  69),
    (  39,  48,  56,  65),
    (  37,  45,  54,  62),
    (  35,  43,  51,  59),
    (  33,  41,  48,  56),
    (  32,  39,  46,  53),
    (  30,  37,  43,  50),
    (  29,  35,  41,  48),
    (  27,  33,  39,  45),
    (  26,  31,  37,  43),
    (  24,  30,  35,  41),
    (  23,  28,  33,  39),
    (  22,  27,  32,  37),
    (  21,  26,  30,  35),
    (  20,  24,  29,  33),
    (  19,  23,  27,  31),
    (  18,  22,  26,  30),
    (  17,  21,  25,  28),
    (  16,  20,  23,  27),
    (  15,  19,  22,  25),
    (  14,  18,  21,  24),
    (  14,  17,  20,  23),
    (  13,  16,  19,  22),
    (  12,  15,  18,  21),
    (  12,  14,  17,  20),
    (  11,  14,  16,  19),
    (  11,  13,  15,  18),
    (  10,  12,  15,  17),
    (  10,  12,  14,  16),
    (   9,  11,  13,  15),
    (   9,  11,  12,  14),
    (   8,  10,  12,  14),
    (   8,   9,  11,  13),
    (   7,   9,  11,  12),
    (   7,   9,  10,  12),
    (   7,   8,  10,  11),
    (   6,   8,   9,  11),
    (   6,   7,   9,  10),
    (   6,   7,   8,   9),
    (   2,   2,   2,   2));

const
  CabacACNextStateMPS: array [0..63] of Byte = (
    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,30,
    31,32,33,34,35,36,37,38,39,40,
    41,42,43,44,45,46,47,48,49,50,
    51,52,53,54,55,56,57,58,59,60,
    61,62,62,63);

const
  CabacACNextStateLPS: array [0..63] of Byte = (
    0, 0, 1, 2, 2, 4, 4, 5, 6, 7,
    8, 9, 9,11,11,12,13,13,15,15,
    16,16,18,18,19,19,21,21,22,22,
    23,24,24,25,26,26,27,27,28,29,
    29,30,30,30,31,32,32,33,33,33,
    34,34,35,35,35,36,36,36,37,37,
    37,38,38,63);

implementation

uses
  Math;

type
  TInitData = array [0..62,0..1] of Integer;
  TContexts = array [0..999] of TCabacContext;

const
  InitPredictionMode: array [0..1,0..1] of Integer = (
    (  2, 48),(  4, 67));
  InitCoefficientMap: array [0..62,0..1] of Integer = (
    (  7, 67),(  8, 61),(  8, 60),( 10, 40),(  8, 59),(  2, 64),(  4, 54),
    (  3, 61),(  9, 50),( 11, 35),( 31,-22),( 10, 34),(  5, 52),(  0, 62),
    (  0, 59),(  3, 54),(  2, 58),(  1, 59),(  7, 45),( 14, 27),( 28,-15),
    ( 41,-56),( 31,-27),( 29,-15),(  3, 51),(  2, 58),(  0, 59),(  1, 56),
    ( 10, 28),(  4, 51),( -1, 61),( -2, 61),(  0, 52),(  7, 24),( 26,-24),
    ( 24,-13),( 53,-88),( 44,-61),(  5, 36),(  1, 50),( -3, 58),( -2, 61),
    (  6, 46),(  1, 52),( -5, 64),( -6, 60),(  1, 48),(  4, 38),( 35,-41),
    ( 34,-39),(  6, 46),( -3, 56),( -1, 55),( -2, 63),( -7, 62),( -2, 62),
    ( -3, 61),( -1, 59),( -3, 60),( -2, 61),( -1, 70),( -4, 71),(  2, 69));
  InitLastCoefficient: array [0..62,0..1] of Integer = (
    (-29, 66),(-25, 65),(-28, 70),(-22, 39),(-28, 72),(-23, 61),(-22, 54),
    (-21, 60),(-22, 64),(-25, 60),(-20, 37),(-15, 39),(-20, 56),(-19, 54),
    (-25, 67),(-22, 59),(-20, 57),(-25, 65),(-26, 70),(-19, 52),(-22, 56),
    (-23, 60),(-17, 41),(-19, 51),(-24, 61),(-20, 54),(-27, 62),(-25, 77),
    (-21, 78),(-26, 71),(-18, 68),(-22, 63),(-27, 72),(-24, 71),(-22, 65),
    (-22, 70),(-23, 72),(-21, 64),(-24, 64),(-24, 74),(-24, 75),(-24, 80),
    (-22, 81),(-20, 74),(-20, 71),(-25, 78),(-20, 78),(-20, 78),( -5, 55),
    (-14, 63),(-21, 74),(-16, 77),(-16, 70),( -7, 63),(-12, 70),(-12, 71),
    ( -4, 60),(  5, 49),(  1, 50),(  7, 46),(  5, 55),( 15, 41),( 25, 30));
  InitCoefGreaterOne: array [0..4,0..1] of Integer = (
    (  5, 57),(181,-493),(129,-330),(-7,32),( -2, 45));
  InitCoefAbsolute: array [0..4,0..1] of Integer = (
    (  7, 28),(  2, 48),(  0, 57),(  1, 59),( 11, 55));
  InitCodedBlock: array [0..0,0..1] of Integer = (
    ( 31, 40));

{ TAICCabac }

constructor TAICCabac.Create(const AQuality: TAICQuality;
  const AStream: TStream);
begin
  inherited Create;
  FQuality := AQuality;
  FStream := AStream;
  InitializeContexts;
end;

procedure TAICCabac.InitializeContext(out Context: TCabacContext; const M,
  N: Integer);
var
  State: Integer;
begin
  State := ((M * FQuality) div 32) + N;
  State := EnsureRange(State,1,126);
  if State >= 64 then begin
    Context.State := State - 64;
    Context.MPS   := 1;
  end else begin
    Context.State := 63 - State;
    Context.MPS   := 0;
  end;
end;

procedure TAICCabac.InitializeContext1D(const InitData; out Contexts;
  const Count: Integer);
var
  D: TInitData absolute InitData;
  C: TContexts absolute Contexts;
  J: Integer;
begin
  for J := 0 to Count - 1 do
    InitializeContext(C[J],D[J,0],D[J,1]);
end;

procedure TAICCabac.InitializeContext2D(const InitData; out Contexts;
  const Count: Integer);
var
  D: TInitData absolute InitData;
  C: TContexts absolute Contexts;
  CT: TAICChannelType;
  J: Integer;
begin
  for CT := System.Low(TAICChannelType) to High(TAICChannelType) do
    for J := 0 to Count - 1 do
      InitializeContext(C[Ord(CT) * Count + J],D[J,0],D[J,1]);
end;

procedure TAICCabac.InitializeContexts;
begin
  InitializeContext1D(InitPredictionMode,CtxPredictionMode,2);
  InitializeContext2D(InitPredictionMode,CtxPredictionMode,63);
  InitializeContext2D(InitLastCoefficient,CtxLastCoefficient,63);
  InitializeContext2D(InitCoefGreaterOne,CtxCoefGreaterOne,5);
  InitializeContext2D(InitCoefAbsolute,CtxCoefAbsolute,5);
  InitializeContext1D(InitCodedBlock,CtxCodedBlock,1);
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -