BitMagicC++Library
encoding.h
Go to the documentation of this file.
1 #ifndef BMENCODING_H__INCLUDED__
2 #define BMENCODING_H__INCLUDED__
3 /*
4 Copyright(c) 2002-2017 Anatoliy Kuznetsov(anatoliy_kuznetsov at yahoo.com)
5 
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9 
10  http://www.apache.org/licenses/LICENSE-2.0
11 
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 
18 For more information please visit: http://bitmagic.io
19 */
20 
21 #include <memory.h>
22 #include "bmutil.h"
23 
24 namespace bm
25 {
26 
27 
28 // ----------------------------------------------------------------
29 /*!
30  \brief Memory encoding.
31 
32  Class for encoding data into memory.
33  Properly handles aligment issues with integer data types.
34 
35  \ingroup gammacode
36 */
37 class encoder
38 {
39 public:
40  typedef unsigned char* position_type;
41 public:
42  encoder(unsigned char* buf, size_t size);
43  void put_8(unsigned char c);
44  void put_16(bm::short_t s);
45  void put_16(const bm::short_t* s, unsigned count);
46  void put_32(bm::word_t w);
47  void put_32(const bm::word_t* w, unsigned count);
48  void put_64(bm::id64_t w);
49  void put_prefixed_array_32(unsigned char c,
50  const bm::word_t* w, unsigned count);
51  void put_prefixed_array_16(unsigned char c,
52  const bm::short_t* s, unsigned count,
53  bool encode_count);
54  void memcpy(const unsigned char* src, size_t count);
55  unsigned size() const;
56  unsigned char* get_pos() const;
57  void set_pos(unsigned char* buf_pos);
58 private:
59  unsigned char* buf_;
60  unsigned char* start_;
61  size_t size_;
62 };
63 
64 // ----------------------------------------------------------------
65 /**
66  Base class for all decoding functionality
67  \ingroup gammacode
68 */
70 {
71 public:
72  decoder_base(const unsigned char* buf) { buf_ = start_ = buf; }
73 
74  /// Reads character from the decoding buffer.
75  unsigned char get_8() { return *buf_++; }
76 
77  /// Returns size of the current decoding stream.
78  unsigned size() const { return (unsigned)(buf_ - start_); }
79 
80  /// change current position
81  void seek(int delta) { buf_ += delta; }
82 
83  /// read bytes from the decode buffer
84  void memcpy(unsigned char* dst, size_t count);
85 
86  /// Return current buffer pointer
87  const unsigned char* get_pos() const { return buf_; }
88 protected:
89  const unsigned char* buf_;
90  const unsigned char* start_;
91 };
92 
93 
94 // ----------------------------------------------------------------
95 /**
96  Class for decoding data from memory buffer.
97  Properly handles aligment issues with integer data types.
98  \ingroup gammacode
99 */
100 class decoder : public decoder_base
101 {
102 public:
103  decoder(const unsigned char* buf);
104  bm::short_t get_16();
105  bm::word_t get_32();
106  bm::id64_t get_64();
107  void get_32(bm::word_t* w, unsigned count);
108  void get_16(bm::short_t* s, unsigned count);
109 };
110 
111 // ----------------------------------------------------------------
112 /**
113  Class for decoding data from memory buffer.
114  Properly handles aligment issues with integer data types.
115  Converts data to big endian architecture
116  (presumed it was encoded as little endian)
117  \ingroup gammacode
118 */
120 
121 
122 // ----------------------------------------------------------------
123 /**
124  Class for decoding data from memory buffer.
125  Properly handles aligment issues with integer data types.
126  Converts data to little endian architecture
127  (presumed it was encoded as big endian)
128  \ingroup gammacode
129 */
131 {
132 public:
133  decoder_little_endian(const unsigned char* buf);
134  bm::short_t get_16();
135  bm::word_t get_32();
136  void get_32(bm::word_t* w, unsigned count);
137  void get_16(bm::short_t* s, unsigned count);
138 };
139 
140 
141 /**
142  Byte based writer for un-aligned bit streaming
143 
144  @ingroup gammacode
145  @sa encoder
146 */
147 template<class TEncoder>
148 class bit_out
149 {
150 public:
151  bit_out(TEncoder& dest)
152  : dest_(dest), used_bits_(0), accum_(0)
153  {}
154 
156  {
157  if (used_bits_)
158  dest_.put_32(accum_);
159  }
160 
161  void put_bit(unsigned value)
162  {
163  BM_ASSERT(value <= 1);
164  accum_ |= (value << used_bits_);
165  if (++used_bits_ == (sizeof(accum_) * 8))
166  flush_accum();
167  }
168 
169  void put_bits(unsigned value, unsigned count)
170  {
171  unsigned used = used_bits_;
172  unsigned acc = accum_;
173 
174  {
175  unsigned mask = ~0;
176  mask >>= (sizeof(accum_) * 8) - count;
177  value &= mask;
178  }
179  for (;count;)
180  {
181  acc |= value << used;
182 
183  unsigned free_bits = (sizeof(accum_) * 8) - used;
184  if (count <= free_bits)
185  {
186  used += count;
187  break;
188  }
189  else
190  {
191  value >>= free_bits;
192  count -= free_bits;
193  dest_.put_32(acc);
194  acc = used = 0;
195  continue;
196  }
197  }
198  used_bits_ = used;
199  accum_ = acc;
200  }
201 
203  {
204  if (++used_bits_ == (sizeof(accum_) * 8))
205  flush_accum();
206  }
207 
208  void put_zero_bits(unsigned count)
209  {
210  unsigned used = used_bits_;
211  unsigned free_bits = (sizeof(accum_) * 8) - used;
212  if (count >= free_bits)
213  {
214  flush_accum();
215  count -= free_bits;
216  used = 0;
217 
218  for ( ;count >= sizeof(accum_) * 8; count -= sizeof(accum_) * 8)
219  {
220  dest_.put_32(0);
221  }
222  used += count;
223  }
224  else
225  {
226  used += count;
227  }
228  accum_ |= (1 << used);
229  if (++used == (sizeof(accum_) * 8))
230  flush_accum();
231  else
232  used_bits_ = used;
233  }
234 
235 
236  void gamma(unsigned value)
237  {
238  BM_ASSERT(value);
239 
240  unsigned logv =
241  #if defined(BM_x86) && (defined(__GNUG__) || defined(_MSC_VER))
242  bm::bsr_asm32(value);
243  #else
244  bm::ilog2_LUT(value);
245  #endif
246 
247  // Put zeroes + 1 bit
248 
249  unsigned used = used_bits_;
250  unsigned acc = accum_;
251  const unsigned acc_bits = (sizeof(acc) * 8);
252  unsigned free_bits = acc_bits - used;
253 
254  {
255  unsigned count = logv;
256  if (count >= free_bits)
257  {
258  dest_.put_32(acc);
259  acc = used ^= used;
260  count -= free_bits;
261 
262  for ( ;count >= acc_bits; count -= acc_bits)
263  {
264  dest_.put_32(0);
265  }
266  used += count;
267  }
268  else
269  {
270  used += count;
271  }
272  acc |= (1 << used);
273  if (++used == acc_bits)
274  {
275  dest_.put_32(acc);
276  acc = used ^= used;
277  }
278  }
279 
280  // Put the value bits
281  //
282  {
283  unsigned mask = (~0u);
284  mask >>= acc_bits - logv;
285  value &= mask;
286  }
287  for (;logv;)
288  {
289  acc |= value << used;
290  free_bits = acc_bits - used;
291  if (logv <= free_bits)
292  {
293  used += logv;
294  break;
295  }
296  else
297  {
298  value >>= free_bits;
299  logv -= free_bits;
300  dest_.put_32(acc);
301  acc = used ^= used;
302  continue;
303  }
304  } // for
305 
306  used_bits_ = used;
307  accum_ = acc;
308  }
309 
310 
311  void flush()
312  {
313  if (used_bits_)
314  flush_accum();
315  }
316 
317 private:
318  void flush_accum()
319  {
320  dest_.put_32(accum_);
321  used_bits_ = accum_ = 0;
322  }
323 private:
324  bit_out(const bit_out&);
325  bit_out& operator=(const bit_out&);
326 
327 private:
328  TEncoder& dest_; ///< Bit stream target
329  unsigned used_bits_; ///< Bits used in the accumulator
330  unsigned accum_; ///< write bit accumulator
331 };
332 
333 
334 /**
335  Byte based reader for un-aligned bit streaming
336 
337  @ingroup gammacode
338  @sa encoder
339 */
340 template<class TDecoder>
341 class bit_in
342 {
343 public:
344  bit_in(TDecoder& decoder)
345  : src_(decoder),
346  used_bits_(unsigned(sizeof(accum_) * 8)),
347  accum_(0)
348  {
349  }
350 
351  unsigned gamma()
352  {
353  unsigned acc = accum_;
354  unsigned used = used_bits_;
355 
356  if (used == (sizeof(acc) * 8))
357  {
358  acc = src_.get_32();
359  used ^= used;
360  }
361  unsigned zero_bits = 0;
362  while (true)
363  {
364  if (acc == 0)
365  {
366  zero_bits = unsigned(zero_bits +(sizeof(acc) * 8) - used);
367  used = 0;
368  acc = src_.get_32();
369  continue;
370  }
371  unsigned first_bit_idx =
372  #if defined(BM_x86) && (defined(__GNUG__) || defined(_MSC_VER))
373  bm::bsf_asm32(acc);
374  #else
375  bm::bit_scan_fwd(acc);
376  #endif
377  acc >>= first_bit_idx;
378  zero_bits += first_bit_idx;
379  used += first_bit_idx;
380  break;
381  } // while
382 
383  // eat the border bit
384  //
385  if (used == (sizeof(acc) * 8))
386  {
387  acc = src_.get_32();
388  used = 1;
389  }
390  else
391  {
392  ++used;
393  }
394  acc >>= 1;
395 
396  // get the value
397  unsigned current;
398 
399  unsigned free_bits = unsigned((sizeof(acc) * 8) - used);
400  if (zero_bits <= free_bits)
401  {
402  take_accum:
403  current =
404  (acc & block_set_table<true>::_left[zero_bits]) | (1 << zero_bits);
405  acc >>= zero_bits;
406  used += zero_bits;
407  goto ret;
408  }
409 
410  if (used == (sizeof(acc) * 8))
411  {
412  acc = src_.get_32();
413  used ^= used;
414  goto take_accum;
415  }
416 
417  // take the part
418  current = acc;
419  // read the next word
420  acc = src_.get_32();
421  used = zero_bits - free_bits;
422  current |=
423  ((acc & block_set_table<true>::_left[used]) << free_bits) |
424  (1 << zero_bits);
425 
426  acc >>= used;
427  ret:
428  accum_ = acc;
429  used_bits_ = used;
430  return current;
431  }
432 
433 
434 private:
435  bit_in(const bit_in&);
436  bit_in& operator=(const bit_in&);
437 private:
438  TDecoder& src_; ///< Source of bytes
439  unsigned used_bits_; ///< Bits used in the accumulator
440  unsigned accum_; ///< read bit accumulator
441 };
442 
443 
444 /**
445  Functor for Elias Gamma encoding
446  @ingroup gammacode
447 */
448 template<typename T, typename TBitIO>
450 {
451 public:
452  gamma_encoder(TBitIO& bout) : bout_(bout)
453  {}
454 
455  /**
456  Encode word
457  */
459  void operator()(T value)
460  {
461  bout_.gamma(value);
462  }
463 private:
465  gamma_encoder& operator=(const gamma_encoder&);
466 private:
467  TBitIO& bout_;
468 };
469 
470 
471 /**
472  Elias Gamma decoder
473  @ingroup gammacode
474 */
475 template<typename T, typename TBitIO>
477 {
478 public:
479  gamma_decoder(TBitIO& bin) : bin_(bin)
480  {}
481 
482  /**
483  Start encoding sequence
484  */
485  void start()
486  {}
487 
488  /**
489  Stop decoding sequence
490  */
491  void stop()
492  {}
493 
494  /**
495  Decode word
496  */
497  T operator()(void)
498  {
499  return (T)bin_.gamma();
500  }
501 private:
503  gamma_decoder& operator=(const gamma_decoder&);
504 private:
505  TBitIO& bin_;
506 };
507 
508 
509 // ----------------------------------------------------------------
510 // Implementation details.
511 // ----------------------------------------------------------------
512 
513 /*!
514  \fn encoder::encoder(unsigned char* buf, unsigned size)
515  \brief Construction.
516  \param buf - memory buffer pointer.
517  \param size - size of the buffer
518 */
519 inline encoder::encoder(unsigned char* buf, size_t a_size)
520 : buf_(buf), start_(buf)
521 {
522  size_ = a_size;
523 }
524 /*!
525  \brief Encode 8-bit prefix + an array
526 */
527 inline void encoder::put_prefixed_array_32(unsigned char c,
528  const bm::word_t* w,
529  unsigned count)
530 {
531  put_8(c);
532  put_32(w, count);
533 }
534 
535 /*!
536  \brief Encode 8-bit prefix + an array
537 */
538 inline void encoder::put_prefixed_array_16(unsigned char c,
539  const bm::short_t* s,
540  unsigned count,
541  bool encode_count)
542 {
543  put_8(c);
544  if (encode_count)
545  put_16((bm::short_t) count);
546  put_16(s, count);
547 }
548 
549 
550 /*!
551  \fn void encoder::put_8(unsigned char c)
552  \brief Puts one character into the encoding buffer.
553  \param c - character to encode
554 */
555 BMFORCEINLINE void encoder::put_8(unsigned char c)
556 {
557  *buf_++ = c;
558 }
559 
560 /*!
561  \fn encoder::put_16(bm::short_t s)
562  \brief Puts short word (16 bits) into the encoding buffer.
563  \param s - short word to encode
564 */
566 {
567 #if (BM_UNALIGNED_ACCESS_OK == 1)
568  *((bm::short_t*)buf_) = s;
569  buf_ += sizeof(s);
570 #else
571  *buf_++ = (unsigned char) s;
572  s >>= 8;
573  *buf_++ = (unsigned char) s;
574 #endif
575 }
576 
577 /*!
578  \brief Method puts array of short words (16 bits) into the encoding buffer.
579 */
580 inline void encoder::put_16(const bm::short_t* s, unsigned count)
581 {
582 #if (BM_UNALIGNED_ACCESS_OK == 1)
583  unsigned short* buf = (unsigned short*)buf_;
584  const bm::short_t* s_end = s + count;
585  do
586  {
587  *buf++ = *s++;
588  } while (s < s_end);
589 
590  buf_ = (unsigned char*)buf;
591 #else
592  unsigned char* buf = buf_;
593  const bm::short_t* s_end = s + count;
594  do
595  {
596  bm::short_t w16 = *s++;
597  unsigned char a = (unsigned char) w16;
598  unsigned char b = (unsigned char) (w16 >> 8);
599 
600  *buf++ = a;
601  *buf++ = b;
602 
603  } while (s < s_end);
604 
605  buf_ = (unsigned char*)buf;
606 #endif
607 }
608 
609 /*!
610  \brief copy bytes into target buffer or just rewind if src is NULL
611 */
612 inline
613 void encoder::memcpy(const unsigned char* src, size_t count)
614 {
615  BM_ASSERT((buf_ + count) < (start_ + size_));
616  if (src)
617  ::memcpy(buf_, src, count);
618  buf_ += count;
619 }
620 
621 
622 /*!
623  \fn unsigned encoder::size() const
624  \brief Returns size of the current encoding stream.
625 */
626 inline unsigned encoder::size() const
627 {
628  return (unsigned)(buf_ - start_);
629 }
630 
631 /**
632  \brief Get current memory stream position
633 */
635 {
636  return buf_;
637 }
638 
639 /**
640  \brief Set current memory stream position
641 */
643 {
644  buf_ = buf_pos;
645 }
646 
647 
648 /*!
649  \fn void encoder::put_32(bm::word_t w)
650  \brief Puts 32 bits word into encoding buffer.
651  \param w - word to encode.
652 */
654 {
655 #if (BM_UNALIGNED_ACCESS_OK == 1)
656  *((bm::word_t*) buf_) = w;
657  buf_ += sizeof(w);
658 #else
659  *buf_++ = (unsigned char) w;
660  *buf_++ = (unsigned char) (w >> 8);
661  *buf_++ = (unsigned char) (w >> 16);
662  *buf_++ = (unsigned char) (w >> 24);
663 #endif
664 }
665 
666 /*!
667  \fn void encoder::put_64(bm::id64_t w)
668  \brief Puts 64 bits word into encoding buffer.
669  \param w - word to encode.
670 */
672 {
673 #if (BM_UNALIGNED_ACCESS_OK == 1)
674  *((bm::id64_t*) buf_) = w;
675  buf_ += sizeof(w);
676 #else
677  *buf_++ = (unsigned char) w;
678  *buf_++ = (unsigned char) (w >> 8);
679  *buf_++ = (unsigned char) (w >> 16);
680  *buf_++ = (unsigned char) (w >> 24);
681  *buf_++ = (unsigned char) (w >> 32);
682  *buf_++ = (unsigned char) (w >> 40);
683  *buf_++ = (unsigned char) (w >> 48);
684  *buf_++ = (unsigned char) (w >> 56);
685 #endif
686 }
687 
688 
689 /*!
690  \brief Encodes array of 32-bit words
691 */
692 inline
693 void encoder::put_32(const bm::word_t* w, unsigned count)
694 {
695 #if (BM_UNALIGNED_ACCESS_OK == 1)
696  bm::word_t* buf = (bm::word_t*)buf_;
697  const bm::word_t* w_end = w + count;
698  do
699  {
700  *buf++ = *w++;
701  } while (w < w_end);
702 
703  buf_ = (unsigned char*)buf;
704 #else
705  unsigned char* buf = buf_;
706  const bm::word_t* w_end = w + count;
707  do
708  {
709  bm::word_t w32 = *w++;
710  unsigned char a = (unsigned char) w32;
711  unsigned char b = (unsigned char) (w32 >> 8);
712  unsigned char c = (unsigned char) (w32 >> 16);
713  unsigned char d = (unsigned char) (w32 >> 24);
714 
715  *buf++ = a;
716  *buf++ = b;
717  *buf++ = c;
718  *buf++ = d;
719  } while (w < w_end);
720 
721  buf_ = (unsigned char*)buf;
722 #endif
723 }
724 
725 
726 // ---------------------------------------------------------------------
727 
728 
729 /*!
730  Load bytes from the decode buffer
731 */
732 inline
733 void decoder_base::memcpy(unsigned char* dst, size_t count)
734 {
735  if (dst)
736  ::memcpy(dst, buf_, count);
737  buf_ += count;
738 }
739 
740 /*!
741  \fn decoder::decoder(const unsigned char* buf)
742  \brief Construction
743  \param buf - pointer to the decoding memory.
744 */
745 inline decoder::decoder(const unsigned char* buf)
746 : decoder_base(buf)
747 {
748 }
749 
750 /*!
751  \fn bm::short_t decoder::get_16()
752  \brief Reads 16-bit word from the decoding buffer.
753 */
755 {
756 #if (BM_UNALIGNED_ACCESS_OK == 1)
757  bm::short_t a = *((bm::short_t*)buf_);
758 #else
759  bm::short_t a = (bm::short_t)(buf_[0] + ((bm::short_t)buf_[1] << 8));
760 #endif
761  buf_ += sizeof(a);
762  return a;
763 }
764 
765 /*!
766  \fn bm::word_t decoder::get_32()
767  \brief Reads 32-bit word from the decoding buffer.
768 */
770 {
771 #if (BM_UNALIGNED_ACCESS_OK == 1)
772  bm::word_t a = *((bm::word_t*)buf_);
773 #else
774  bm::word_t a = buf_[0]+ ((unsigned)buf_[1] << 8) +
775  ((unsigned)buf_[2] << 16) + ((unsigned)buf_[3] << 24);
776 #endif
777  buf_+=sizeof(a);
778  return a;
779 }
780 
781 /*!
782  \fn bm::word_t decoder::get_64()
783  \brief Reads 64-bit word from the decoding buffer.
784 */
786 {
787 #if (BM_UNALIGNED_ACCESS_OK == 1)
788  bm::id64_t a = *((bm::id64_t*)buf_);
789 #else
790  bm::word_t a = buf_[0]+
791  ((bm::id64_t)buf_[1] << 8) +
792  ((bm::id64_t)buf_[2] << 16) +
793  ((bm::id64_t)buf_[3] << 24) +
794  ((bm::id64_t)buf_[4] << 32) +
795  ((bm::id64_t)buf_[5] << 40) +
796  ((bm::id64_t)buf_[6] << 48) +
797  ((bm::id64_t)buf_[7] << 56);
798 #endif
799  buf_+=sizeof(a);
800  return a;
801 }
802 
803 
804 /*!
805  \fn void decoder::get_32(bm::word_t* w, unsigned count)
806  \brief Reads block of 32-bit words from the decoding buffer.
807  \param w - pointer on memory block to read into.
808  \param count - size of memory block in words.
809 */
810 inline void decoder::get_32(bm::word_t* w, unsigned count)
811 {
812  if (!w)
813  {
814  seek(count * 4);
815  return;
816  }
817 #if (BM_UNALIGNED_ACCESS_OK == 1)
818  ::memcpy(w, buf_, count * sizeof(bm::word_t));
819  seek(count * 4);
820  return;
821 #else
822  const unsigned char* buf = buf_;
823  const bm::word_t* w_end = w + count;
824  do
825  {
826  bm::word_t a = buf[0]+ ((unsigned)buf[1] << 8) +
827  ((unsigned)buf[2] << 16) + ((unsigned)buf[3] << 24);
828  *w++ = a;
829  buf += sizeof(a);
830  } while (w < w_end);
831  buf_ = (unsigned char*)buf;
832 #endif
833 }
834 
835 /*!
836  \fn void decoder::get_16(bm::short_t* s, unsigned count)
837  \brief Reads block of 32-bit words from the decoding buffer.
838  \param s - pointer on memory block to read into.
839  \param count - size of memory block in words.
840 */
841 inline void decoder::get_16(bm::short_t* s, unsigned count)
842 {
843  if (!s)
844  {
845  seek(count * 2);
846  return;
847  }
848 #if (BM_UNALIGNED_ACCESS_OK == 1)
849  const bm::short_t* buf = (bm::short_t*)buf_;
850  const bm::short_t* s_end = s + count;
851  do
852  {
853  *s++ = *buf++;
854  } while (s < s_end);
855 #else
856  const unsigned char* buf = buf_;
857  const bm::short_t* s_end = s + count;
858  do
859  {
860  bm::short_t a = (bm::short_t)(buf[0] + ((bm::short_t)buf[1] << 8));
861  *s++ = a;
862  buf += sizeof(a);
863  } while (s < s_end);
864 #endif
865  buf_ = (unsigned char*)buf;
866 }
867 
868 
869 
870 // ---------------------------------------------------------------------
871 
872 inline decoder_little_endian::decoder_little_endian(const unsigned char* buf)
873 : decoder_base(buf)
874 {
875 }
876 
878 {
879  bm::short_t a = bm::short_t((bm::short_t)buf_[0] << 8) + ((bm::short_t)buf_[1]);
880  buf_ += sizeof(a);
881  return a;
882 }
883 
885 {
886  bm::word_t a = ((unsigned)buf_[0] << 24)+ ((unsigned)buf_[1] << 16) +
887  ((unsigned)buf_[2] << 8) + ((unsigned)buf_[3]);
888  buf_+=sizeof(a);
889  return a;
890 }
891 
892 inline void decoder_little_endian::get_32(bm::word_t* w, unsigned count)
893 {
894  if (!w)
895  {
896  seek(count * 4);
897  return;
898  }
899 
900  const unsigned char* buf = buf_;
901  const bm::word_t* w_end = w + count;
902  do
903  {
904  bm::word_t a = ((unsigned)buf[0] << 24)+ ((unsigned)buf[1] << 16) +
905  ((unsigned)buf[2] << 8) + ((unsigned)buf[3]);
906  *w++ = a;
907  buf += sizeof(a);
908  } while (w < w_end);
909  buf_ = (unsigned char*)buf;
910 }
911 
912 inline void decoder_little_endian::get_16(bm::short_t* s, unsigned count)
913 {
914  if (!s)
915  {
916  seek(count * 2);
917  return;
918  }
919 
920  const unsigned char* buf = buf_;
921  const bm::short_t* s_end = s + count;
922  do
923  {
924  bm::short_t a = bm::short_t((bm::short_t)buf[0] << 8) + ((bm::short_t)buf[1]);
925  *s++ = a;
926  buf += sizeof(a);
927  } while (s < s_end);
928  buf_ = (unsigned char*)buf;
929 }
930 
931 
932 } // namespace bm
933 
934 #endif
Structure keeps all-left/right ON bits masks.
Definition: bmconst.h:203
void put_64(bm::id64_t w)
Puts 64 bits word into encoding buffer.
Definition: encoding.h:671
void put_8(unsigned char c)
Puts one character into the encoding buffer.
Definition: encoding.h:555
unsigned size() const
Returns size of the current encoding stream.
Definition: encoding.h:626
unsigned char * position_type
Definition: encoding.h:40
T ilog2_LUT(T x)
Lookup table based integer LOG2.
Definition: bmutil.h:101
unsigned long long int id64_t
Definition: bmconst.h:30
gamma_decoder(TBitIO &bin)
Definition: encoding.h:479
void memcpy(unsigned char *dst, size_t count)
read bytes from the decode buffer
Definition: encoding.h:733
decoder_base(const unsigned char *buf)
Definition: encoding.h:72
Base class for all decoding functionality.
Definition: encoding.h:69
Definition: bm.h:59
bm::short_t get_16()
Definition: encoding.h:877
T bit_scan_fwd(T v)
Definition: bmutil.h:37
void set_pos(unsigned char *buf_pos)
Set current memory stream position.
Definition: encoding.h:642
void seek(int delta)
change current position
Definition: encoding.h:81
Byte based reader for un-aligned bit streaming.
Definition: encoding.h:341
void flush()
Definition: encoding.h:311
Class for decoding data from memory buffer.
Definition: encoding.h:100
gamma_encoder(TBitIO &bout)
Definition: encoding.h:452
Class for decoding data from memory buffer.
Definition: encoding.h:130
void stop()
Stop decoding sequence.
Definition: encoding.h:491
decoder decoder_big_endian
Class for decoding data from memory buffer.
Definition: encoding.h:119
unsigned int word_t
Definition: bmconst.h:35
bit_in(TDecoder &decoder)
Definition: encoding.h:344
const unsigned char * start_
Definition: encoding.h:90
bm::short_t get_16()
Reads 16-bit word from the decoding buffer.
Definition: encoding.h:754
unsigned size() const
Returns size of the current decoding stream.
Definition: encoding.h:78
BMFORCEINLINE void operator()(T value)
Encode word.
Definition: encoding.h:459
void put_32(bm::word_t w)
Puts 32 bits word into encoding buffer.
Definition: encoding.h:653
unsigned short short_t
Definition: bmconst.h:36
void put_bits(unsigned value, unsigned count)
Definition: encoding.h:169
Elias Gamma decoder.
Definition: encoding.h:476
Byte based writer for un-aligned bit streaming.
Definition: encoding.h:148
bm::id64_t get_64()
Reads 64-bit word from the decoding buffer.
Definition: encoding.h:785
void put_zero_bits(unsigned count)
Definition: encoding.h:208
void put_16(bm::short_t s)
Puts short word (16 bits) into the encoding buffer.
Definition: encoding.h:565
decoder(const unsigned char *buf)
Construction.
Definition: encoding.h:745
void put_prefixed_array_16(unsigned char c, const bm::short_t *s, unsigned count, bool encode_count)
Encode 8-bit prefix + an array.
Definition: encoding.h:538
unsigned char get_8()
Reads character from the decoding buffer.
Definition: encoding.h:75
void put_prefixed_array_32(unsigned char c, const bm::word_t *w, unsigned count)
Encode 8-bit prefix + an array.
Definition: encoding.h:527
unsigned char * get_pos() const
Get current memory stream position.
Definition: encoding.h:634
void memcpy(const unsigned char *src, size_t count)
copy bytes into target buffer or just rewind if src is NULL
Definition: encoding.h:613
const unsigned char * buf_
Definition: encoding.h:89
T operator()(void)
Decode word.
Definition: encoding.h:497
bit_out(TEncoder &dest)
Definition: encoding.h:151
decoder_little_endian(const unsigned char *buf)
Definition: encoding.h:872
void put_bit(unsigned value)
Definition: encoding.h:161
#define BMFORCEINLINE
Definition: bmdef.h:183
encoder(unsigned char *buf, size_t size)
Construction.
Definition: encoding.h:519
Functor for Elias Gamma encoding.
Definition: encoding.h:449
#define BM_ASSERT
Definition: bmdef.h:112
unsigned gamma()
Definition: encoding.h:351
void gamma(unsigned value)
Definition: encoding.h:236
const unsigned char * get_pos() const
Return current buffer pointer.
Definition: encoding.h:87
void put_zero_bit()
Definition: encoding.h:202
Memory encoding.
Definition: encoding.h:37
void start()
Start encoding sequence.
Definition: encoding.h:485
bm::word_t get_32()
Reads 32-bit word from the decoding buffer.
Definition: encoding.h:769