LCOV - code coverage report
Current view: top level - libavcodec - rangecoder.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 54 54 100.0 %
Date: 2017-12-15 18:13:28 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Range coder
       3             :  * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg is free software; you can redistribute it and/or
       8             :  * modify it under the terms of the GNU Lesser General Public
       9             :  * License as published by the Free Software Foundation; either
      10             :  * version 2.1 of the License, or (at your option) any later version.
      11             :  *
      12             :  * FFmpeg is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with FFmpeg; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : /**
      23             :  * @file
      24             :  * Range coder.
      25             :  */
      26             : 
      27             : #ifndef AVCODEC_RANGECODER_H
      28             : #define AVCODEC_RANGECODER_H
      29             : 
      30             : #include <stdint.h>
      31             : 
      32             : #include "libavutil/common.h"
      33             : #include "libavutil/avassert.h"
      34             : 
      35             : typedef struct RangeCoder {
      36             :     int low;
      37             :     int range;
      38             :     int outstanding_count;
      39             :     int outstanding_byte;
      40             :     uint8_t zero_state[256];
      41             :     uint8_t one_state[256];
      42             :     uint8_t *bytestream_start;
      43             :     uint8_t *bytestream;
      44             :     uint8_t *bytestream_end;
      45             :     int overread;
      46             : #define MAX_OVERREAD 2
      47             : } RangeCoder;
      48             : 
      49             : void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size);
      50             : void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, int buf_size);
      51             : int ff_rac_terminate(RangeCoder *c);
      52             : void ff_build_rac_states(RangeCoder *c, int factor, int max_p);
      53             : 
      54  1359541333 : static inline void renorm_encoder(RangeCoder *c)
      55             : {
      56             :     // FIXME: optimize
      57  2803038532 :     while (c->range < 0x100) {
      58    83955866 :         if (c->outstanding_byte < 0) {
      59        6348 :             c->outstanding_byte = c->low >> 8;
      60    83949518 :         } else if (c->low <= 0xFF00) {
      61    54948290 :             *c->bytestream++ = c->outstanding_byte;
      62    55469676 :             for (; c->outstanding_count; c->outstanding_count--)
      63      521386 :                 *c->bytestream++ = 0xFF;
      64    54948290 :             c->outstanding_byte = c->low >> 8;
      65    29001228 :         } else if (c->low >= 0x10000) {
      66    28369390 :             *c->bytestream++ = c->outstanding_byte + 1;
      67    28479752 :             for (; c->outstanding_count; c->outstanding_count--)
      68      110362 :                 *c->bytestream++ = 0x00;
      69    28369390 :             c->outstanding_byte = (c->low >> 8) & 0xFF;
      70             :         } else {
      71      631838 :             c->outstanding_count++;
      72             :         }
      73             : 
      74    83955866 :         c->low     = (c->low & 0xFF) << 8;
      75    83955866 :         c->range <<= 8;
      76             :     }
      77  1359541333 : }
      78             : 
      79     1673460 : static inline int get_rac_count(RangeCoder *c)
      80             : {
      81     1673460 :     int x = c->bytestream - c->bytestream_start + c->outstanding_count;
      82     1673460 :     if (c->outstanding_byte >= 0)
      83     1672998 :         x++;
      84     1673460 :     return 8 * x - av_log2(c->range);
      85             : }
      86             : 
      87  1359530263 : static inline void put_rac(RangeCoder *c, uint8_t *const state, int bit)
      88             : {
      89  1359530263 :     int range1 = (c->range * (*state)) >> 8;
      90             : 
      91             :     av_assert2(*state);
      92             :     av_assert2(range1 < c->range);
      93             :     av_assert2(range1 > 0);
      94  1359530263 :     if (!bit) {
      95   580319379 :         c->range -= range1;
      96   580319379 :         *state    = c->zero_state[*state];
      97             :     } else {
      98   779210884 :         c->low  += c->range - range1;
      99   779210884 :         c->range = range1;
     100   779210884 :         *state   = c->one_state[*state];
     101             :     }
     102             : 
     103  1359530263 :     renorm_encoder(c);
     104  1359530263 : }
     105             : 
     106  1369158503 : static inline void refill(RangeCoder *c)
     107             : {
     108  1369158503 :     if (c->range < 0x100) {
     109    83414183 :         c->range <<= 8;
     110    83414183 :         c->low   <<= 8;
     111    83414183 :         if (c->bytestream < c->bytestream_end) {
     112    83413673 :             c->low += c->bytestream[0];
     113    83413673 :             c->bytestream++;
     114             :         } else
     115         510 :             c->overread ++;
     116             :     }
     117  1369158503 : }
     118             : 
     119  1369158503 : static inline int get_rac(RangeCoder *c, uint8_t *const state)
     120             : {
     121  1369158503 :     int range1 = (c->range * (*state)) >> 8;
     122             : 
     123  1369158503 :     c->range -= range1;
     124  1369158503 :     if (c->low < c->range) {
     125   583789115 :         *state = c->zero_state[*state];
     126   583789115 :         refill(c);
     127   583789115 :         return 0;
     128             :     } else {
     129   785369388 :         c->low  -= c->range;
     130   785369388 :         *state   = c->one_state[*state];
     131   785369388 :         c->range = range1;
     132   785369388 :         refill(c);
     133   785369388 :         return 1;
     134             :     }
     135             : }
     136             : 
     137             : #endif /* AVCODEC_RANGECODER_H */

Generated by: LCOV version 1.13