/*! @file vlc.h * * @brief Declaration of the data structures for variable-length encoding * * @version 1.0.0 * * (C) Copyright 2018 GoPro Inc (http://gopro.com/). * * Licensed under either: * - Apache License, Version 2.0, http://www.apache.org/licenses/LICENSE-2.0 * - MIT license, http://opensource.org/licenses/MIT * at your option. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef VLC_H #define VLC_H /*! @brief Codebook entries for arbitrary runs and values The codebook data structure allows runs of an arbitrary value, but all codec implementations only use runs of zeros. The codeword for a non-zero value is followed by the sign bit. @todo Could add the sign bit to the magnitude entries in this table if it improves performance or makes the code more clear. */ typedef struct _rlv { uint_fast8_t size; //!< Size of code word in bits uint32_t bits; //!< Code word bits right justified uint32_t count; //!< Run length int32_t value; //!< Run value (unsigned) } RLV; /*! @brief Declaration of a codebook This data structure is often called the master codebook to distinguish it from the encoding tables that are derived from the codebook. The codebook has a header that is immediately followed by the codebook entries. Each entry is an @ref RLV data structure that contains the codeword and the size of the codeword in bits. Each codeword represent a run length and value. The current codec implementation only supports runs of zeros, so the run length is one for non-zero values. A non-zero value is an unsigned coefficient magnitude. Special codewords that mark significant locations in the bitstream are indicated by a run length of zero and the value indicates the type of marker. The codebook is generated by a separate program that takes as input a table of the frequencies of coefficient magnitudes and runs of zeros. */ typedef struct _codebook { uint32_t length; //!< Number of entries in the code book // The length is followed by the RLV entries } CODEBOOK; //! Macro used to define the codebook generated by the Huffman program #define RLVTABLE(n) \ static struct \ { \ uint32_t length; \ RLV entries[n]; \ } /*! @brief Table of codewords for coefficient magnitudes The entries in this table are indexed by the coefficient magnitude. This table is derived from the master codebook by sorting the entries for coefficient magnitudes into increasing order. Each entry in the table is a codeword and its size in bits. */ typedef struct _magnitude_table { uint32_t length; //!< Number of entries in the encoding table // The length is followed by the VLE entries } MAGS_TABLE; /*! @brief Entry in the table for encoding coefficients magnitudes Each entry is the codeword and its size in bits. The typename VLE stands for variable length encoding to distinguish this entry from the data structures for variable length coding in general. */ typedef struct _vle { uint_fast8_t size; //!< Size of code word in bits uint32_t bits; //!< Code words bits (right justified) } VLE; /*! @brief Table of codewords for runs of zeros The entries in this table are indexed by length of the run of zeros. This table is derived from the master codebook by concatenating codewords for runs of zeros to form a codeword a run with the specified length. Each entry in the table is a codeword and its size in bits and the number of zeros that are that are not included in the run represented by the codeword. */ typedef struct _runs_table { uint32_t length; //!< Number of entries in the encoding table // The length is followed by the RLC entries } RUNS_TABLE; /*! @brief Entry in the table for encoding runs of zeros */ typedef struct _rlc { // Codebook entries for runs of zeros uint_fast8_t size; //!< Size of code word in bits uint32_t count; //!< Remaining length of the run uint32_t bits; //!< Code word bits (right justified) } RLC; #ifdef __cplusplus extern "C" { #endif CODEC_ERROR PutZeros(BITSTREAM *stream, const RUNS_TABLE *codebook, uint32_t count); CODEC_ERROR PutSpecial(BITSTREAM *stream, const CODEBOOK *codebook, SPECIAL_MARKER marker); #ifdef __cplusplus } #endif #endif // VLC_H