src/arithmetic_codec.c

Go to the documentation of this file.
00001 /*
00002    libit - Library for basic source and channel coding functions
00003    Copyright (C) 2005-2005 Vivien Chappelier, Herve Jegou
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public
00016    License along with this library; if not, write to the Free
00017    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 */
00019 
00020 /*
00021   Arithmetic coder/decoder
00022   Copyright (C) 2005 Vivien Chappelier
00023 */
00024 
00025 #include <it/types.h>
00026 #include <it/vec.h>
00027 #include <it/arithmetic_codec.h>
00028 
00029 /* output bits from the register to the bitstream */
00030 static void write_bit (arithmetic_coder_t * arithmetic_coder,
00031            unsigned char bit)
00032 {
00033   *arithmetic_coder->sequence++ = bit;
00034 
00035   while (arithmetic_coder->pending > 0) {
00036     *arithmetic_coder->sequence++ = !bit;
00037     arithmetic_coder->pending--;
00038   }
00039 }
00040 
00041 /* input bits from the bitstream to the register */
00042 static void read_bit (arithmetic_decoder_t * arithmetic_decoder)
00043 {
00044   int  i;
00045 
00046   arithmetic_decoder->sequence++;
00047 
00048   i = arithmetic_decoder->sequence[arithmetic_decoder->precision - 1] & 1;
00049   arithmetic_decoder->value += arithmetic_decoder->value + i;
00050 }
00051 
00052 /* renormalize the encoder */
00053 static void renormalize_enc (arithmetic_coder_t * arithmetic_coder)
00054 {
00055   arithmetic_codec_register_t half = 1UL << (arithmetic_coder->precision - 1);
00056   arithmetic_codec_register_t quarter =
00057     1UL << (arithmetic_coder->precision - 2);
00058 
00059   while (arithmetic_coder->range < quarter) {
00060     if (arithmetic_coder->lower >= half) {
00061       /* range entirely contained in upper half */
00062       write_bit (arithmetic_coder, 1);
00063       arithmetic_coder->lower -= half;
00064     }
00065     else if (arithmetic_coder->lower + arithmetic_coder->range <= half) {
00066       /* range entirely contained in lower half */
00067       write_bit (arithmetic_coder, 0);
00068     }
00069     else {
00070       /* bit cannot be determined yet */
00071       arithmetic_coder->pending++;
00072       arithmetic_coder->lower -= quarter;
00073     }
00074 
00075     arithmetic_coder->lower <<= 1;
00076     arithmetic_coder->range <<= 1;
00077   }
00078 }
00079 
00080 /* renormalize the decoder */
00081 static void renormalize_dec (arithmetic_decoder_t * arithmetic_decoder)
00082 {
00083   arithmetic_codec_register_t half =
00084     1UL << (arithmetic_decoder->precision - 1);
00085   arithmetic_codec_register_t quarter =
00086     1UL << (arithmetic_decoder->precision - 2);
00087 
00088   while (arithmetic_decoder->range < quarter) {
00089     if (arithmetic_decoder->lower >= half) {
00090       /* range entirely contained in upper half */
00091       arithmetic_decoder->value -= half;
00092       arithmetic_decoder->lower -= half;
00093     }
00094     else if (arithmetic_decoder->lower + arithmetic_decoder->range <= half) {
00095       /* range entirely contained in lower half */
00096       /* nothing to do */
00097     }
00098     else {
00099       arithmetic_decoder->value -= quarter;
00100       arithmetic_decoder->lower -= quarter;
00101     }
00102 
00103     arithmetic_decoder->lower <<= 1;
00104     arithmetic_decoder->range <<= 1;
00105 
00106     read_bit (arithmetic_decoder);
00107   }
00108 }
00109 
00110 void arithmetic_coder_start (arithmetic_coder_t * arithmetic_coder,
00111            bvec buffer)
00112 {
00113   arithmetic_coder->buffer = buffer;
00114   arithmetic_coder->lower = 0;
00115   arithmetic_coder->range = (1UL << arithmetic_coder->precision) - 1;
00116   arithmetic_coder->pending = 0;
00117   arithmetic_coder->sequence = arithmetic_coder->buffer;
00118 }
00119 
00120 int arithmetic_coder_stop (arithmetic_coder_t * arithmetic_coder)
00121 {
00122   int  i;
00123   arithmetic_codec_register_t bits;
00124 
00125   /* flush the register */
00126   bits = arithmetic_coder->lower + 1;
00127   for (i = 0; i < arithmetic_coder->precision; i++)
00128     write_bit (arithmetic_coder,
00129          (unsigned
00130     char) ((bits >> (arithmetic_coder->precision - 1 - i))
00131            & 1));
00132 
00133   return (arithmetic_coder->sequence - arithmetic_coder->buffer);
00134 }
00135 
00136 arithmetic_coder_t *arithmetic_coder_new (int precision)
00137 {
00138   arithmetic_coder_t *arithmetic_coder;
00139 
00140   assert (precision <= 8 * sizeof (arithmetic_codec_register_t));
00141   arithmetic_coder =
00142     (arithmetic_coder_t *) malloc (sizeof (arithmetic_coder_t));
00143   memset (arithmetic_coder, 0, sizeof (arithmetic_coder_t));
00144   arithmetic_coder->precision = precision;
00145   arithmetic_coder->buffer = 0;
00146 
00147   return (arithmetic_coder);
00148 }
00149 
00150 void arithmetic_coder_delete (arithmetic_coder_t * arithmetic_coder)
00151 {
00152   free (arithmetic_coder);
00153 }
00154 
00155 void arithmetic_coder_encode_bit (arithmetic_coder_t * arithmetic_coder,
00156           double prob_0, arithmetic_codec_bit_t bit)
00157 {
00158   double prob_1 = 1.0 - prob_0;
00159   int  LPS = prob_0 > prob_1;
00160   double prob_LPS = LPS ? prob_1 : prob_0;
00161   arithmetic_codec_register_t range_LPS;
00162 
00163   range_LPS =
00164     (arithmetic_codec_register_t) (arithmetic_coder->range * prob_LPS);
00165   if (!range_LPS)
00166     range_LPS = 1;    /* avoid ranges below the coder precision */
00167 
00168   if (bit == LPS) {
00169     arithmetic_coder->lower += arithmetic_coder->range - range_LPS;
00170     arithmetic_coder->range = range_LPS;
00171   }
00172   else
00173     arithmetic_coder->range -= range_LPS;
00174 
00175   renormalize_enc (arithmetic_coder);
00176 }
00177 
00178 
00179 void arithmetic_decoder_start (arithmetic_decoder_t * arithmetic_decoder,
00180              bvec buffer)
00181 {
00182   int  i, j;
00183 
00184   arithmetic_decoder->buffer = buffer;
00185   arithmetic_decoder->sequence = buffer;
00186   arithmetic_decoder->value = 0;
00187 
00188   for (i = 0; i < arithmetic_decoder->precision; i++) {
00189     j = arithmetic_decoder->sequence[i] & 1;
00190     arithmetic_decoder->value += arithmetic_decoder->value + j;
00191   }
00192 
00193   arithmetic_decoder->lower = 0;
00194   arithmetic_decoder->range = (1UL << arithmetic_decoder->precision) - 1;
00195 }
00196 
00197 int arithmetic_decoder_stop (arithmetic_decoder_t * arithmetic_decoder)
00198 {
00199   int  i;
00200 
00201   /* flush the register */
00202   for (i = 0; i < arithmetic_decoder->precision; i++)
00203     read_bit (arithmetic_decoder);
00204 
00205   return (arithmetic_decoder->sequence - arithmetic_decoder->buffer);
00206 }
00207 
00208 arithmetic_decoder_t *arithmetic_decoder_new (int precision)
00209 {
00210   arithmetic_decoder_t *arithmetic_decoder;
00211 
00212   assert (precision <= 8 * sizeof (arithmetic_codec_register_t));
00213   arithmetic_decoder =
00214     (arithmetic_decoder_t *) malloc (sizeof (arithmetic_decoder_t));
00215   memset (arithmetic_decoder, 0, sizeof (arithmetic_decoder_t));
00216   arithmetic_decoder->precision = precision;
00217   return (arithmetic_decoder);
00218 }
00219 
00220 void arithmetic_decoder_delete (arithmetic_decoder_t * arithmetic_decoder)
00221 {
00222   free (arithmetic_decoder);
00223 }
00224 
00225 arithmetic_codec_bit_t arithmetic_decoder_decode_bit (arithmetic_decoder_t *
00226                   arithmetic_decoder,
00227                   double prob_0)
00228 {
00229   int  bit;
00230   double prob_1 = 1.0 - prob_0;
00231   int  LPS = prob_0 > prob_1;
00232   double prob_LPS = LPS ? prob_1 : prob_0;
00233   arithmetic_codec_register_t range_LPS;
00234 
00235   range_LPS =
00236     (arithmetic_codec_register_t) (arithmetic_decoder->range * prob_LPS);
00237   if (!range_LPS)
00238     range_LPS = 1;    /* avoid ranges below the coder precision */
00239 
00240   if (arithmetic_decoder->value - arithmetic_decoder->lower >=
00241       arithmetic_decoder->range - range_LPS) {
00242     bit = LPS;
00243     arithmetic_decoder->lower += arithmetic_decoder->range - range_LPS;
00244     arithmetic_decoder->range = range_LPS;
00245   }
00246   else {
00247     bit = !LPS;
00248     arithmetic_decoder->range -= range_LPS;
00249   }
00250 
00251   renormalize_dec (arithmetic_decoder);
00252   return (bit);
00253 }
00254 
00255 /* encode a symbol with the binary arithmetic coder using unary binarization */
00256 /* BUG: this may fail if the probabilities are too close to zero */
00257 /* FIXME: force the probabilities to be > 1 / (2^precision) */
00258 void arithmetic_coder_encode_symbol (arithmetic_coder_t * arithmetic_coder,
00259              vec pdf, int symbol)
00260 {
00261   int  i, l;
00262   double p0, p1;
00263 
00264   l = vec_length (pdf);
00265   assert (l > 1);
00266   assert (symbol < l);
00267 
00268   p0 = 0;
00269   p1 = 1;
00270 
00271   for (i = 0; i < l; i++) {
00272 
00273     p0 = pdf[i];
00274     p1 -= pdf[i];
00275 
00276     if (symbol == i) {
00277       arithmetic_coder_encode_bit (arithmetic_coder, p0 / (p1 + p0), 0);
00278       break;
00279     }
00280     else {
00281       arithmetic_coder_encode_bit (arithmetic_coder, p0 / (p1 + p0), 1);
00282     }
00283   }
00284 }
00285 
00286 /* decode a symbol with the binary arithmetic coder using unary binarization */
00287 int arithmetic_decoder_decode_symbol (arithmetic_decoder_t *
00288               arithmetic_decoder, vec pdf)
00289 {
00290   int  i, l;
00291   double p0, p1;
00292 
00293   l = vec_length (pdf);
00294   assert (l > 1);
00295 
00296   p0 = 0;
00297   p1 = 1;
00298 
00299   for (i = 0; i < l; i++) {
00300 
00301     p0 = pdf[i];
00302     p1 -= pdf[i];
00303 
00304     if (arithmetic_decoder_decode_bit (arithmetic_decoder, p0 / (p1 + p0))
00305   == 0)
00306       return (i);
00307   }
00308   return (-1);
00309 }

Hosted by
Copyright (C) 2005-2006 Hervé Jégou
Vivien Chappelier
Francois Cayre
libit logo courtesy of Jonathan Delhumeau