1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * Copyright (c) 2000-2002 Fabrice Bellard
3cabdff1aSopenharmony_ci * Copyright (c) 2002-2004 Michael Niedermayer
4cabdff1aSopenharmony_ci *
5cabdff1aSopenharmony_ci * This file is part of FFmpeg.
6cabdff1aSopenharmony_ci *
7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
11cabdff1aSopenharmony_ci *
12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15cabdff1aSopenharmony_ci * Lesser General Public License for more details.
16cabdff1aSopenharmony_ci *
17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20cabdff1aSopenharmony_ci */
21cabdff1aSopenharmony_ci
22cabdff1aSopenharmony_ci/**
23cabdff1aSopenharmony_ci * @file
24cabdff1aSopenharmony_ci * rl header.
25cabdff1aSopenharmony_ci */
26cabdff1aSopenharmony_ci
27cabdff1aSopenharmony_ci#ifndef AVCODEC_RL_H
28cabdff1aSopenharmony_ci#define AVCODEC_RL_H
29cabdff1aSopenharmony_ci
30cabdff1aSopenharmony_ci#include <stdint.h>
31cabdff1aSopenharmony_ci
32cabdff1aSopenharmony_ci#include "vlc.h"
33cabdff1aSopenharmony_ci
34cabdff1aSopenharmony_ci/* run length table */
35cabdff1aSopenharmony_ci#define MAX_RUN    64
36cabdff1aSopenharmony_ci#define MAX_LEVEL  64
37cabdff1aSopenharmony_ci
38cabdff1aSopenharmony_ci/** RLTable. */
39cabdff1aSopenharmony_citypedef struct RLTable {
40cabdff1aSopenharmony_ci    int n;                         ///< number of entries of table_vlc minus 1
41cabdff1aSopenharmony_ci    int last;                      ///< number of values for last = 0
42cabdff1aSopenharmony_ci    const uint16_t (*table_vlc)[2];
43cabdff1aSopenharmony_ci    const int8_t *table_run;
44cabdff1aSopenharmony_ci    const int8_t *table_level;
45cabdff1aSopenharmony_ci    uint8_t *index_run[2];         ///< encoding only
46cabdff1aSopenharmony_ci    int8_t *max_level[2];          ///< encoding & decoding
47cabdff1aSopenharmony_ci    int8_t *max_run[2];            ///< encoding & decoding
48cabdff1aSopenharmony_ci    RL_VLC_ELEM *rl_vlc[32];       ///< decoding only
49cabdff1aSopenharmony_ci} RLTable;
50cabdff1aSopenharmony_ci
51cabdff1aSopenharmony_ci/**
52cabdff1aSopenharmony_ci * Initialize index_run, max_level and max_run from n, last, table_vlc,
53cabdff1aSopenharmony_ci * table_run and table_level.
54cabdff1aSopenharmony_ci * @param static_store static uint8_t array[2][2*MAX_RUN + MAX_LEVEL + 3]
55cabdff1aSopenharmony_ci *                     to hold the level and run tables.
56cabdff1aSopenharmony_ci * @note  This function does not touch rl_vlc at all, hence there is no need
57cabdff1aSopenharmony_ci *        to synchronize calls to ff_rl_init() and ff_rl_init_vlc() using the
58cabdff1aSopenharmony_ci *        same RLTable.
59cabdff1aSopenharmony_ci */
60cabdff1aSopenharmony_civoid ff_rl_init(RLTable *rl, uint8_t static_store[2][2*MAX_RUN + MAX_LEVEL + 3]);
61cabdff1aSopenharmony_ci
62cabdff1aSopenharmony_ci/**
63cabdff1aSopenharmony_ci * Initialize rl_vlc from n, last, table_vlc, table_run and table_level.
64cabdff1aSopenharmony_ci * All rl_vlc pointers to be initialized must already point to a static
65cabdff1aSopenharmony_ci * buffer of `static_size` RL_VLC_ELEM elements; if a pointer is NULL,
66cabdff1aSopenharmony_ci * initializing further VLCs stops.
67cabdff1aSopenharmony_ci * @note  This function does not touch what ff_rl_init() initializes at all,
68cabdff1aSopenharmony_ci *        hence there is no need to synchronize calls to ff_rl_init() and
69cabdff1aSopenharmony_ci *        ff_rl_init_vlc() using the same RLTable.
70cabdff1aSopenharmony_ci */
71cabdff1aSopenharmony_civoid ff_rl_init_vlc(RLTable *rl, unsigned static_size);
72cabdff1aSopenharmony_ci
73cabdff1aSopenharmony_ci#define INIT_VLC_RL(rl, static_size)\
74cabdff1aSopenharmony_ci{\
75cabdff1aSopenharmony_ci    static RL_VLC_ELEM rl_vlc_table[32][static_size];\
76cabdff1aSopenharmony_ci\
77cabdff1aSopenharmony_ci    for (int q = 0; q < 32; q++) \
78cabdff1aSopenharmony_ci        rl.rl_vlc[q] = rl_vlc_table[q]; \
79cabdff1aSopenharmony_ci\
80cabdff1aSopenharmony_ci    ff_rl_init_vlc(&rl, static_size); \
81cabdff1aSopenharmony_ci}
82cabdff1aSopenharmony_ci
83cabdff1aSopenharmony_ci#define INIT_FIRST_VLC_RL(rl, static_size)              \
84cabdff1aSopenharmony_cido {                                                    \
85cabdff1aSopenharmony_ci    static RL_VLC_ELEM rl_vlc_table[static_size];       \
86cabdff1aSopenharmony_ci                                                        \
87cabdff1aSopenharmony_ci    rl.rl_vlc[0] = rl_vlc_table;                        \
88cabdff1aSopenharmony_ci    ff_rl_init_vlc(&rl, static_size);                   \
89cabdff1aSopenharmony_ci} while (0)
90cabdff1aSopenharmony_ci
91cabdff1aSopenharmony_cistatic inline int get_rl_index(const RLTable *rl, int last, int run, int level)
92cabdff1aSopenharmony_ci{
93cabdff1aSopenharmony_ci    int index;
94cabdff1aSopenharmony_ci    index = rl->index_run[last][run];
95cabdff1aSopenharmony_ci    if (index >= rl->n)
96cabdff1aSopenharmony_ci        return rl->n;
97cabdff1aSopenharmony_ci    if (level > rl->max_level[last][run])
98cabdff1aSopenharmony_ci        return rl->n;
99cabdff1aSopenharmony_ci    return index + level - 1;
100cabdff1aSopenharmony_ci}
101cabdff1aSopenharmony_ci
102cabdff1aSopenharmony_ci#endif /* AVCODEC_RL_H */
103