1cabdff1aSopenharmony_ci/*
2cabdff1aSopenharmony_ci * exp golomb vlc writing stuff
3cabdff1aSopenharmony_ci * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
4cabdff1aSopenharmony_ci * Copyright (c) 2004 Alex Beregszaszi
5cabdff1aSopenharmony_ci *
6cabdff1aSopenharmony_ci * This file is part of FFmpeg.
7cabdff1aSopenharmony_ci *
8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or
9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public
10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either
11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version.
12cabdff1aSopenharmony_ci *
13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful,
14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of
15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16cabdff1aSopenharmony_ci * Lesser General Public License for more details.
17cabdff1aSopenharmony_ci *
18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public
19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software
20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21cabdff1aSopenharmony_ci */
22cabdff1aSopenharmony_ci
23cabdff1aSopenharmony_ci/**
24cabdff1aSopenharmony_ci * @file
25cabdff1aSopenharmony_ci * @brief
26cabdff1aSopenharmony_ci *     exp golomb vlc writing stuff
27cabdff1aSopenharmony_ci * @author Michael Niedermayer <michaelni@gmx.at> and Alex Beregszaszi
28cabdff1aSopenharmony_ci */
29cabdff1aSopenharmony_ci
30cabdff1aSopenharmony_ci#ifndef AVCODEC_PUT_GOLOMB_H
31cabdff1aSopenharmony_ci#define AVCODEC_PUT_GOLOMB_H
32cabdff1aSopenharmony_ci
33cabdff1aSopenharmony_ci#include <stdint.h>
34cabdff1aSopenharmony_ci#include "put_bits.h"
35cabdff1aSopenharmony_ci
36cabdff1aSopenharmony_ciextern const uint8_t ff_ue_golomb_len[256];
37cabdff1aSopenharmony_ci
38cabdff1aSopenharmony_ci/**
39cabdff1aSopenharmony_ci * write unsigned exp golomb code. 2^16 - 2 at most
40cabdff1aSopenharmony_ci */
41cabdff1aSopenharmony_cistatic inline void set_ue_golomb(PutBitContext *pb, int i)
42cabdff1aSopenharmony_ci{
43cabdff1aSopenharmony_ci    av_assert2(i >= 0);
44cabdff1aSopenharmony_ci    av_assert2(i <= 0xFFFE);
45cabdff1aSopenharmony_ci
46cabdff1aSopenharmony_ci    if (i < 256)
47cabdff1aSopenharmony_ci        put_bits(pb, ff_ue_golomb_len[i], i + 1);
48cabdff1aSopenharmony_ci    else {
49cabdff1aSopenharmony_ci        int e = av_log2(i + 1);
50cabdff1aSopenharmony_ci        put_bits(pb, 2 * e + 1, i + 1);
51cabdff1aSopenharmony_ci    }
52cabdff1aSopenharmony_ci}
53cabdff1aSopenharmony_ci
54cabdff1aSopenharmony_ci/**
55cabdff1aSopenharmony_ci * write unsigned exp golomb code. 2^32-2 at most.
56cabdff1aSopenharmony_ci */
57cabdff1aSopenharmony_cistatic inline void set_ue_golomb_long(PutBitContext *pb, uint32_t i)
58cabdff1aSopenharmony_ci{
59cabdff1aSopenharmony_ci    av_assert2(i <= (UINT32_MAX - 1));
60cabdff1aSopenharmony_ci
61cabdff1aSopenharmony_ci    if (i < 256)
62cabdff1aSopenharmony_ci        put_bits(pb, ff_ue_golomb_len[i], i + 1);
63cabdff1aSopenharmony_ci    else {
64cabdff1aSopenharmony_ci        int e = av_log2(i + 1);
65cabdff1aSopenharmony_ci        put_bits64(pb, 2 * e + 1, i + 1);
66cabdff1aSopenharmony_ci    }
67cabdff1aSopenharmony_ci}
68cabdff1aSopenharmony_ci
69cabdff1aSopenharmony_ci/**
70cabdff1aSopenharmony_ci * write truncated unsigned exp golomb code.
71cabdff1aSopenharmony_ci */
72cabdff1aSopenharmony_cistatic inline void set_te_golomb(PutBitContext *pb, int i, int range)
73cabdff1aSopenharmony_ci{
74cabdff1aSopenharmony_ci    av_assert2(range >= 1);
75cabdff1aSopenharmony_ci    av_assert2(i <= range);
76cabdff1aSopenharmony_ci
77cabdff1aSopenharmony_ci    if (range == 2)
78cabdff1aSopenharmony_ci        put_bits(pb, 1, i ^ 1);
79cabdff1aSopenharmony_ci    else
80cabdff1aSopenharmony_ci        set_ue_golomb(pb, i);
81cabdff1aSopenharmony_ci}
82cabdff1aSopenharmony_ci
83cabdff1aSopenharmony_ci/**
84cabdff1aSopenharmony_ci * write signed exp golomb code. 16 bits at most.
85cabdff1aSopenharmony_ci */
86cabdff1aSopenharmony_cistatic inline void set_se_golomb(PutBitContext *pb, int i)
87cabdff1aSopenharmony_ci{
88cabdff1aSopenharmony_ci    i = 2 * i - 1;
89cabdff1aSopenharmony_ci    if (i < 0)
90cabdff1aSopenharmony_ci        i ^= -1;    //FIXME check if gcc does the right thing
91cabdff1aSopenharmony_ci    set_ue_golomb(pb, i);
92cabdff1aSopenharmony_ci}
93cabdff1aSopenharmony_ci
94cabdff1aSopenharmony_ci/**
95cabdff1aSopenharmony_ci * write unsigned golomb rice code (ffv1).
96cabdff1aSopenharmony_ci */
97cabdff1aSopenharmony_cistatic inline void set_ur_golomb(PutBitContext *pb, int i, int k, int limit,
98cabdff1aSopenharmony_ci                                 int esc_len)
99cabdff1aSopenharmony_ci{
100cabdff1aSopenharmony_ci    int e;
101cabdff1aSopenharmony_ci
102cabdff1aSopenharmony_ci    av_assert2(i >= 0);
103cabdff1aSopenharmony_ci
104cabdff1aSopenharmony_ci    e = i >> k;
105cabdff1aSopenharmony_ci    if (e < limit)
106cabdff1aSopenharmony_ci        put_bits(pb, e + k + 1, (1 << k) + av_mod_uintp2(i, k));
107cabdff1aSopenharmony_ci    else
108cabdff1aSopenharmony_ci        put_bits(pb, limit + esc_len, i - limit + 1);
109cabdff1aSopenharmony_ci}
110cabdff1aSopenharmony_ci
111cabdff1aSopenharmony_ci/**
112cabdff1aSopenharmony_ci * write unsigned golomb rice code (jpegls).
113cabdff1aSopenharmony_ci */
114cabdff1aSopenharmony_cistatic inline void set_ur_golomb_jpegls(PutBitContext *pb, int i, int k,
115cabdff1aSopenharmony_ci                                        int limit, int esc_len)
116cabdff1aSopenharmony_ci{
117cabdff1aSopenharmony_ci    int e;
118cabdff1aSopenharmony_ci
119cabdff1aSopenharmony_ci    av_assert2(i >= 0);
120cabdff1aSopenharmony_ci
121cabdff1aSopenharmony_ci    e = (i >> k) + 1;
122cabdff1aSopenharmony_ci    if (e < limit) {
123cabdff1aSopenharmony_ci        while (e > 31) {
124cabdff1aSopenharmony_ci            put_bits(pb, 31, 0);
125cabdff1aSopenharmony_ci            e -= 31;
126cabdff1aSopenharmony_ci        }
127cabdff1aSopenharmony_ci        put_bits(pb, e, 1);
128cabdff1aSopenharmony_ci        if (k)
129cabdff1aSopenharmony_ci            put_sbits(pb, k, i);
130cabdff1aSopenharmony_ci    } else {
131cabdff1aSopenharmony_ci        while (limit > 31) {
132cabdff1aSopenharmony_ci            put_bits(pb, 31, 0);
133cabdff1aSopenharmony_ci            limit -= 31;
134cabdff1aSopenharmony_ci        }
135cabdff1aSopenharmony_ci        put_bits(pb, limit, 1);
136cabdff1aSopenharmony_ci        put_bits(pb, esc_len, i - 1);
137cabdff1aSopenharmony_ci    }
138cabdff1aSopenharmony_ci}
139cabdff1aSopenharmony_ci
140cabdff1aSopenharmony_ci/**
141cabdff1aSopenharmony_ci * write signed golomb rice code (ffv1).
142cabdff1aSopenharmony_ci */
143cabdff1aSopenharmony_cistatic inline void set_sr_golomb(PutBitContext *pb, int i, int k, int limit,
144cabdff1aSopenharmony_ci                                 int esc_len)
145cabdff1aSopenharmony_ci{
146cabdff1aSopenharmony_ci    int v;
147cabdff1aSopenharmony_ci
148cabdff1aSopenharmony_ci    v  = -2 * i - 1;
149cabdff1aSopenharmony_ci    v ^= (v >> 31);
150cabdff1aSopenharmony_ci
151cabdff1aSopenharmony_ci    set_ur_golomb(pb, v, k, limit, esc_len);
152cabdff1aSopenharmony_ci}
153cabdff1aSopenharmony_ci
154cabdff1aSopenharmony_ci/**
155cabdff1aSopenharmony_ci * write signed golomb rice code (flac).
156cabdff1aSopenharmony_ci */
157cabdff1aSopenharmony_cistatic inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k,
158cabdff1aSopenharmony_ci                                      int limit, int esc_len)
159cabdff1aSopenharmony_ci{
160cabdff1aSopenharmony_ci    int v;
161cabdff1aSopenharmony_ci
162cabdff1aSopenharmony_ci    v  = -2 * i - 1;
163cabdff1aSopenharmony_ci    v ^= (v >> 31);
164cabdff1aSopenharmony_ci
165cabdff1aSopenharmony_ci    set_ur_golomb_jpegls(pb, v, k, limit, esc_len);
166cabdff1aSopenharmony_ci}
167cabdff1aSopenharmony_ci
168cabdff1aSopenharmony_ci#endif /* AVCODEC_PUT_GOLOMB_H */
169