casacore
bytepacker.h
Go to the documentation of this file.
1 #ifndef DYSCO_BYTE_PACKER_H
2 #define DYSCO_BYTE_PACKER_H
3 
4 #include <stdexcept>
5 
6 namespace dyscostman {
7 
25 class BytePacker {
26  public:
35  static void pack(unsigned bitCount, unsigned char *dest,
36  const unsigned *symbolBuffer, size_t symbolCount);
37 
47  static void unpack(unsigned bitCount, unsigned *symbolBuffer,
48  unsigned char *packedBuffer, size_t symbolCount);
49 
54  static void pack2(unsigned char *dest, const unsigned *symbolBuffer,
55  size_t symbolCount);
59  static void unpack2(unsigned *symbolBuffer, unsigned char *packedBuffer,
60  size_t symbolCount);
61 
66  static void pack3(unsigned char *dest, const unsigned *symbolBuffer,
67  size_t symbolCount);
71  static void unpack3(unsigned *symbolBuffer, unsigned char *packedBuffer,
72  size_t symbolCount);
73 
78  static void pack4(unsigned char *dest, const unsigned *symbolBuffer,
79  size_t symbolCount);
83  static void unpack4(unsigned *symbolBuffer, unsigned char *packedBuffer,
84  size_t symbolCount);
85 
90  static void pack6(unsigned char *dest, const unsigned *symbolBuffer,
91  size_t symbolCount);
92 
96  static void unpack6(unsigned *symbolBuffer, unsigned char *packedBuffer,
97  size_t symbolCount);
98 
103  static void pack8(unsigned char *dest, const unsigned *symbolBuffer,
104  size_t symbolCount);
108  static void unpack8(unsigned *symbolBuffer, unsigned char *packedBuffer,
109  size_t symbolCount);
110 
115  static void pack10(unsigned char *dest, const unsigned *symbolBuffer,
116  size_t symbolCount);
120  static void unpack10(unsigned *symbolBuffer, unsigned char *packedBuffer,
121  size_t symbolCount);
122 
127  static void pack12(unsigned char *dest, const unsigned *symbolBuffer,
128  size_t symbolCount);
132  static void unpack12(unsigned *symbolBuffer, unsigned char *packedBuffer,
133  size_t symbolCount);
134 
139  static void pack16(unsigned char *dest, const unsigned *symbolBuffer,
140  size_t symbolCount);
144  static void unpack16(unsigned *symbolBuffer, unsigned char *packedBuffer,
145  size_t symbolCount);
146 
147  static size_t bufferSize(size_t nSymbols, size_t nBits) {
148  return (nSymbols * nBits + 7) / 8;
149  }
150 };
151 
152 inline void BytePacker::pack(unsigned int bitCount, unsigned char *dest,
153  const unsigned int *symbolBuffer,
154  size_t symbolCount) {
155  switch (bitCount) {
156  case 2:
157  pack2(dest, symbolBuffer, symbolCount);
158  break;
159  case 3:
160  pack3(dest, symbolBuffer, symbolCount);
161  break;
162  case 4:
163  pack4(dest, symbolBuffer, symbolCount);
164  break;
165  case 6:
166  pack6(dest, symbolBuffer, symbolCount);
167  break;
168  case 8:
169  pack8(dest, symbolBuffer, symbolCount);
170  break;
171  case 10:
172  pack10(dest, symbolBuffer, symbolCount);
173  break;
174  case 12:
175  pack12(dest, symbolBuffer, symbolCount);
176  break;
177  case 16:
178  pack16(dest, symbolBuffer, symbolCount);
179  break;
180  default:
181  throw std::runtime_error("Unsupported packing size");
182  }
183 }
184 
185 inline void BytePacker::unpack(unsigned int bitCount,
186  unsigned int *symbolBuffer,
187  unsigned char *packedBuffer,
188  size_t symbolCount) {
189  switch (bitCount) {
190  case 2:
191  unpack2(symbolBuffer, packedBuffer, symbolCount);
192  break;
193  case 3:
194  unpack3(symbolBuffer, packedBuffer, symbolCount);
195  break;
196  case 4:
197  unpack4(symbolBuffer, packedBuffer, symbolCount);
198  break;
199  case 6:
200  unpack6(symbolBuffer, packedBuffer, symbolCount);
201  break;
202  case 8:
203  unpack8(symbolBuffer, packedBuffer, symbolCount);
204  break;
205  case 10:
206  unpack10(symbolBuffer, packedBuffer, symbolCount);
207  break;
208  case 12:
209  unpack12(symbolBuffer, packedBuffer, symbolCount);
210  break;
211  case 16:
212  unpack16(symbolBuffer, packedBuffer, symbolCount);
213  break;
214  default:
215  throw std::runtime_error("Unsupported unpacking size");
216  }
217 }
218 
219 inline void BytePacker::pack2(unsigned char *dest,
220  const unsigned int *symbolBuffer,
221  size_t symbolCount) {
222  const size_t limit = symbolCount / 4;
223  for (size_t i = 0; i != limit; i++) {
224  *dest = (*symbolBuffer); // bits 1-2 into 1-2
225  ++symbolBuffer;
226  *dest |= (*symbolBuffer) << 2; // bits 1-2 into 3-4
227  ++symbolBuffer;
228  *dest |= (*symbolBuffer) << 4; // bits 1-2 into 5-6
229  ++symbolBuffer;
230  *dest |= (*symbolBuffer) << 6; // bits 1-2 into 7-8
231  ++symbolBuffer;
232  ++dest;
233  }
234  size_t pos = limit * 4;
235  if (pos != symbolCount) {
236  *dest = (*symbolBuffer); // bits 1-2 into 1-2
237  ++pos;
238 
239  if (pos != symbolCount) {
240  ++symbolBuffer;
241  *dest |= (*symbolBuffer) << 2; // bits 1-2 into 3-4
242  ++pos;
243 
244  if (pos != symbolCount) {
245  ++symbolBuffer;
246  *dest |= (*symbolBuffer) << 4; // bits 1-2 into 5-6
247  }
248  }
249  }
250 }
251 
252 inline void BytePacker::unpack2(unsigned *symbolBuffer,
253  unsigned char *packedBuffer,
254  size_t symbolCount) {
255  const size_t limit = symbolCount / 4;
256  for (size_t i = 0; i != limit; i++) {
257  *symbolBuffer = *packedBuffer & 0x03; // bits 1-2 into 1-2
258  ++symbolBuffer;
259  *symbolBuffer = ((*packedBuffer) & 0x0C) >> 2; // bits 3-4 into 1-2
260  ++symbolBuffer;
261  *symbolBuffer = ((*packedBuffer) & 0x30) >> 4; // bits 5-6 into 1-2
262  ++symbolBuffer;
263  *symbolBuffer = ((*packedBuffer) & 0xC0) >> 6; // bits 7-8 into 1-2
264  ++symbolBuffer;
265  ++packedBuffer;
266  }
267  size_t pos = limit * 4;
268  if (pos != symbolCount) {
269  *symbolBuffer = *packedBuffer & 0x03; // bits 1-2 into 1-2
270  ++pos;
271 
272  if (pos != symbolCount) {
273  ++symbolBuffer;
274  *symbolBuffer = ((*packedBuffer) & 0x0C) >> 2; // bits 3-4 into 1-2
275  ++pos;
276 
277  if (pos != symbolCount) {
278  ++symbolBuffer;
279  *symbolBuffer = ((*packedBuffer) & 0x30) >> 4; // bits 5-6 into 1-2
280  }
281  }
282  }
283 }
284 
285 inline void BytePacker::pack3(unsigned char *dest, const unsigned *symbolBuffer,
286  size_t symbolCount) {
287  const size_t limit = symbolCount / 8;
288  for (size_t i = 0; i != limit; i++) {
289  *dest = *symbolBuffer; // 1. Bit 1-3 into 1-3
290  ++symbolBuffer;
291  *dest |= (*symbolBuffer) << 3; // 2. Bits 1-3 into 4-6
292  ++symbolBuffer;
293  *dest |= ((*symbolBuffer) & 0x3) << 6; // 3. Bits 1-2 into 7-8
294  ++dest;
295 
296  *dest = ((*symbolBuffer) & 0x4) >> 2; // 3b. Bit 3 into 1
297  ++symbolBuffer;
298  *dest |= (*symbolBuffer) << 1; // 4. Bits 1-3 into 2-4
299  ++symbolBuffer;
300  *dest |= (*symbolBuffer) << 4; // 5. Bits 1-3 into 5-7
301  ++symbolBuffer;
302  *dest |= ((*symbolBuffer) & 0x1) << 7; // 6. Bit 1 into 8
303  ++dest;
304 
305  *dest = ((*symbolBuffer) & 0x6) >> 1; // 6b. Bits 2-3 into 1-2
306  ++symbolBuffer;
307  *dest |= (*symbolBuffer) << 2; // 7. Bits 1-3 into bits 3-5
308  ++symbolBuffer;
309  *dest |= (*symbolBuffer) << 5; // 8. Bits 1-3 into bits 6-8
310  ++symbolBuffer;
311  ++dest;
312  }
313 
314  size_t pos = limit * 8;
315  if (pos != symbolCount) {
316  *dest = *symbolBuffer; // 1. Bit 1-3 into 1-3
317  ++pos;
318  if (pos != symbolCount) {
319  ++symbolBuffer;
320  *dest |= (*symbolBuffer) << 3; // 2. Bits 1-3 into 4-6
321  ++pos;
322  if (pos != symbolCount) {
323  ++symbolBuffer;
324  *dest |= ((*symbolBuffer) & 0x3) << 6; // 3. Bits 1-2 into 7-8
325  ++dest;
326  *dest = ((*symbolBuffer) & 0x4) >> 2; // Bit 3 into 1
327  ++pos;
328  if (pos != symbolCount) {
329  ++symbolBuffer;
330  *dest |= (*symbolBuffer) << 1; // 4. Bits 1-3 into 2-4
331  ++pos;
332  if (pos != symbolCount) {
333  ++symbolBuffer;
334  *dest |= (*symbolBuffer) << 4; // 5. Bits 1-3 into 5-7
335  ++pos;
336  if (pos != symbolCount) {
337  ++symbolBuffer;
338  *dest |= ((*symbolBuffer) & 0x1) << 7; // 6. Bit 1 into 8
339  ++dest;
340  *dest = ((*symbolBuffer) & 0x6) >> 1; // Bits 2-3 into 1-2
341  ++pos;
342  if (pos != symbolCount) {
343  ++symbolBuffer;
344  *dest |= (*symbolBuffer) << 2; // 7. Bits 1-3 into bits 3-5
345  }
346  }
347  }
348  }
349  }
350  }
351  }
352 }
353 
354 inline void BytePacker::unpack3(unsigned *symbolBuffer,
355  unsigned char *packedBuffer,
356  size_t symbolCount) {
357  const size_t limit = symbolCount / 8;
358  for (size_t i = 0; i != limit; i++) {
359  *symbolBuffer = (*packedBuffer) & 0x07; // 1. Bits 1-3 into 1-3
360  ++symbolBuffer;
361  *symbolBuffer = ((*packedBuffer) & 0x38) >> 3; // 2. Bits 4-6 into 1-3
362  ++symbolBuffer;
363  *symbolBuffer = ((*packedBuffer) & 0xC0) >> 6; // 3. Bits 7-8 into 1-2
364  ++packedBuffer;
365 
366  *symbolBuffer |= ((*packedBuffer) & 0x01) << 2; // 3b. Bit 1 into 3
367  ++symbolBuffer;
368  *symbolBuffer = ((*packedBuffer) & 0x0e) >> 1; // 4. Bit 2-4 into 1-3
369  ++symbolBuffer;
370  *symbolBuffer = ((*packedBuffer) & 0x70) >> 4; // 5. Bit 5-7 into 1-3
371  ++symbolBuffer;
372  *symbolBuffer = ((*packedBuffer) & 0x80) >> 7; // 6. Bit 8 into 1
373  ++packedBuffer;
374 
375  *symbolBuffer |= ((*packedBuffer) & 0x03) << 1; // 6b. Bit 1-2 into 2-3
376  ++symbolBuffer;
377  *symbolBuffer = ((*packedBuffer) & 0x1c) >> 2; // 7. Bit 3-5 into 1-3
378  ++symbolBuffer;
379  *symbolBuffer = ((*packedBuffer) & 0xe0) >> 5; // 8. Bit 6-8 into 1-3
380  ++symbolBuffer;
381  ++packedBuffer;
382  }
383  size_t pos = limit * 8;
384  if (pos != symbolCount) {
385  *symbolBuffer = (*packedBuffer) & 0x07; // 1. Bits 1-3 into 1-3
386  ++pos;
387 
388  if (pos != symbolCount) {
389  ++symbolBuffer;
390  *symbolBuffer = ((*packedBuffer) & 0x38) >> 3; // 2. Bits 4-6 into 1-3
391  ++pos;
392 
393  if (pos != symbolCount) {
394  ++symbolBuffer;
395  *symbolBuffer = ((*packedBuffer) & 0xC0) >> 6; // 3. Bits 7-8 into 1-2
396  ++packedBuffer;
397  *symbolBuffer |= ((*packedBuffer) & 0x01) << 2; // 3b. Bit 1 into 3
398  ++pos;
399 
400  if (pos != symbolCount) {
401  ++symbolBuffer;
402  *symbolBuffer = ((*packedBuffer) & 0x0e) >> 1; // 4. Bit 2-4 into 1-3
403  ++pos;
404 
405  if (pos != symbolCount) {
406  ++symbolBuffer;
407  *symbolBuffer =
408  ((*packedBuffer) & 0x70) >> 4; // 5. Bit 5-7 into 1-3
409  ++pos;
410 
411  if (pos != symbolCount) {
412  ++symbolBuffer;
413  *symbolBuffer = ((*packedBuffer) & 0x80) >> 7; // 6. Bit 8 into 1
414  ++packedBuffer;
415  *symbolBuffer |= ((*packedBuffer) & 0x03)
416  << 1; // 6b. Bit 1-2 into 2-3
417  ++pos;
418 
419  if (pos != symbolCount) {
420  ++symbolBuffer;
421  *symbolBuffer =
422  ((*packedBuffer) & 0x1c) >> 2; // 7. Bit 3-5 into 1-3
423  }
424  }
425  }
426  }
427  }
428  }
429  }
430 }
431 
432 inline void BytePacker::pack4(unsigned char *dest,
433  const unsigned int *symbolBuffer,
434  size_t symbolCount) {
435  const size_t limit = symbolCount / 2;
436  for (size_t i = 0; i != limit; i++) {
437  *dest = (*symbolBuffer); // bits 1-4 into 1-4
438  ++symbolBuffer;
439  *dest |= (*symbolBuffer) << 4; // bits 1-4 into 5-8
440  ++symbolBuffer;
441  ++dest;
442  }
443  if (limit * 2 != symbolCount) *dest = (*symbolBuffer); // bits 1-4 into 1-4
444 }
445 
446 inline void BytePacker::unpack4(unsigned *symbolBuffer,
447  unsigned char *packedBuffer,
448  size_t symbolCount) {
449  const size_t limit = symbolCount / 2;
450  for (size_t i = 0; i != limit; i++) {
451  *symbolBuffer = *packedBuffer & 0x0F; // bits 1-4 into 1-4
452  ++symbolBuffer;
453  *symbolBuffer = ((*packedBuffer) & 0xF0) >> 4; // bits 5-8 into 1-4
454  ++symbolBuffer;
455  ++packedBuffer;
456  }
457  if (limit * 2 != symbolCount)
458  *symbolBuffer = *packedBuffer & 0x0F; // bits 1-4 into 1-4
459 }
460 
461 inline void BytePacker::pack6(unsigned char *dest, const unsigned *symbolBuffer,
462  size_t symbolCount) {
463  const size_t limit = symbolCount / 4;
464  for (size_t i = 0; i != limit; i++) {
465  *dest = *symbolBuffer; // Bit 1-6 into 1-6
466  ++symbolBuffer;
467  *dest |= (*symbolBuffer & 3) << 6; // Bits 1-2 into 7-8
468  ++dest;
469 
470  *dest = (*symbolBuffer & 60) >> 2; // Bits 3-6 into 1-4
471  ++symbolBuffer;
472  *dest |= (*symbolBuffer & 15) << 4; // Bits 1-4 into 5-8
473  ++dest;
474 
475  *dest = (*symbolBuffer & 48) >> 4; // Bits 5-6 into 1-2
476  ++symbolBuffer;
477  *dest |= *symbolBuffer << 2; // Bits 1-6 into bits 3-8
478  ++symbolBuffer;
479  ++dest;
480  }
481 
482  size_t pos = limit * 4;
483  if (pos != symbolCount) {
484  *dest = *symbolBuffer; // Bit 1-6 into 1-6
485  ++pos;
486 
487  if (pos != symbolCount) {
488  ++symbolBuffer;
489 
490  *dest |= (*symbolBuffer & 3) << 6; // Bits 1-2 into 7-8
491  ++dest;
492 
493  *dest = (*symbolBuffer & 60) >> 2; // Bits 3-6 into 1-4
494  ++pos;
495 
496  if (pos != symbolCount) {
497  ++symbolBuffer;
498 
499  *dest |= (*symbolBuffer & 15) << 4; // Bits 1-4 into 5-8
500  ++dest;
501 
502  *dest = (*symbolBuffer & 48) >> 4; // Bits 5-6 into 1-2
503  //++symbolBuffer; ++pos;
504  }
505  }
506  }
507 }
508 
509 inline void BytePacker::unpack6(unsigned *symbolBuffer,
510  unsigned char *packedBuffer,
511  size_t symbolCount) {
512  const size_t limit = symbolCount / 4;
513  for (size_t i = 0; i != limit; i++) {
514  *symbolBuffer = (*packedBuffer) & 63; // Bits 1-6 into 1-6
515  ++symbolBuffer;
516  *symbolBuffer = ((*packedBuffer) & 192) >> 6; // Bits 7-8 into 1-2
517  ++packedBuffer;
518 
519  *symbolBuffer |= ((*packedBuffer) & 15) << 2; // Bits 1-4 into 3-6
520  ++symbolBuffer;
521  *symbolBuffer = ((*packedBuffer) & 240) >> 4; // Bits 5-8 into 1-4
522  ++packedBuffer;
523 
524  *symbolBuffer |= ((*packedBuffer) & 3) << 4; // Bits 1-2 into 5-6
525  ++symbolBuffer;
526  *symbolBuffer = ((*packedBuffer) & 252) >> 2; // Bits 3-8 into 1-6
527  ++packedBuffer;
528  ++symbolBuffer;
529  }
530  size_t pos = limit * 4;
531  if (pos != symbolCount) {
532  *symbolBuffer = (*packedBuffer) & 63; // Bits 1-6 into 1-6
533  ++pos;
534 
535  if (pos != symbolCount) {
536  ++symbolBuffer;
537 
538  *symbolBuffer = ((*packedBuffer) & 192) >> 6; // Bits 7-8 into 1-2
539  ++packedBuffer;
540 
541  *symbolBuffer |= ((*packedBuffer) & 15) << 2; // Bits 1-4 into 3-6
542  ++pos;
543 
544  if (pos != symbolCount) {
545  ++symbolBuffer;
546  *symbolBuffer = ((*packedBuffer) & 240) >> 4; // Bits 5-8 into 1-4
547  ++packedBuffer;
548 
549  *symbolBuffer |= ((*packedBuffer) & 3) << 4; // Bits 1-2 into 5-6
550  }
551  }
552  }
553 }
554 
555 inline void BytePacker::pack8(unsigned char *dest, const unsigned *symbolBuffer,
556  size_t symbolCount) {
557  for (size_t i = 0; i != symbolCount; ++i) dest[i] = symbolBuffer[i];
558 }
559 
560 inline void BytePacker::unpack8(unsigned *symbolBuffer,
561  unsigned char *packedBuffer,
562  size_t symbolCount) {
563  for (size_t i = 0; i != symbolCount; ++i) symbolBuffer[i] = packedBuffer[i];
564 }
565 
566 inline void BytePacker::pack10(unsigned char *dest,
567  const unsigned int *symbolBuffer,
568  size_t symbolCount) {
569  const size_t limit = symbolCount / 4;
570  for (size_t i = 0; i != limit; i++) {
571  *dest = (*symbolBuffer & 0x0FF); // Bit 1-8 into 1-8
572  ++dest;
573  *dest = (*symbolBuffer & 0x300) >> 8; // Bits 9-10 into 1-2
574  ++symbolBuffer;
575  *dest |= (*symbolBuffer & 0x03F) << 2; // Bits 1-6 into 3-8
576  ++dest;
577  *dest = (*symbolBuffer & 0x3C0) >> 6; // Bits 7-10 into 1-4
578  ++symbolBuffer;
579 
580  *dest |= (*symbolBuffer & 0x00F) << 4; // Bits 1-4 into 5-8
581  ++dest;
582  *dest = (*symbolBuffer & 0x3F0) >> 4; // Bits 5-10 into bits 1-6
583  ++symbolBuffer;
584  *dest |= (*symbolBuffer & 0x003) << 6; // Bits 1-2 into 7-8
585  ++dest;
586  *dest = (*symbolBuffer & 0x3FC) >> 2; // Bits 3-10 into bits 1-8
587  ++symbolBuffer;
588  ++dest;
589  }
590 
591  size_t pos = limit * 4;
592  if (pos != symbolCount) {
593  *dest = (*symbolBuffer & 0x0FF); // Bit 1-8 into 1-8
594  ++dest;
595  *dest = (*symbolBuffer & 0x300) >> 8; // Bits 9-10 into 1-2
596  ++pos;
597 
598  if (pos != symbolCount) {
599  ++symbolBuffer;
600 
601  *dest |= (*symbolBuffer & 0x03F) << 2; // Bits 1-6 into 3-8
602  ++dest;
603  *dest = (*symbolBuffer & 0x3C0) >> 6; // Bits 7-10 into 1-4
604  ++pos;
605 
606  if (pos != symbolCount) {
607  ++symbolBuffer;
608 
609  *dest |= (*symbolBuffer & 0x00F) << 4; // Bits 1-4 into 5-8
610  ++dest;
611  *dest = (*symbolBuffer & 0x3F0) >> 4; // Bits 5-10 into bits 1-6
612  //++symbolBuffer; ++pos;
613  }
614  }
615  }
616 }
617 
618 inline void BytePacker::unpack10(unsigned int *symbolBuffer,
619  unsigned char *packedBuffer,
620  size_t symbolCount) {
621  const size_t limit = symbolCount / 4;
622  for (size_t i = 0; i != limit; i++) {
623  *symbolBuffer = *packedBuffer; // Bits 1-8 into 1-8
624  ++packedBuffer;
625  *symbolBuffer |= ((*packedBuffer) & 0x03) << 8; // Bits 1-2 into 9-10
626  ++symbolBuffer;
627 
628  *symbolBuffer = ((*packedBuffer) & 0xFC) >> 2; // Bits 3-8 into 1-6
629  ++packedBuffer;
630  *symbolBuffer |= ((*packedBuffer) & 0x0F) << 6; // Bits 1-4 into 7-10
631  ++symbolBuffer;
632 
633  *symbolBuffer = ((*packedBuffer) & 0xF0) >> 4; // Bits 5-8 into 1-4
634  ++packedBuffer;
635  *symbolBuffer |= ((*packedBuffer) & 0x3F) << 4; // Bits 1-6 into 5-10
636  ++symbolBuffer;
637 
638  *symbolBuffer = ((*packedBuffer) & 0xC0) >> 6; // Bits 7-8 into 1-2
639  ++packedBuffer;
640  *symbolBuffer |= (*packedBuffer) << 2; // Bits 1-8 into 3-10
641  ++packedBuffer;
642  ++symbolBuffer;
643  }
644  size_t pos = limit * 4;
645  if (pos != symbolCount) {
646  *symbolBuffer = *packedBuffer; // Bits 1-8 into 1-8
647  ++packedBuffer;
648  *symbolBuffer |= ((*packedBuffer) & 0x03) << 8; // Bits 1-2 into 9-10
649  ++pos;
650 
651  if (pos != symbolCount) {
652  ++symbolBuffer;
653 
654  *symbolBuffer = ((*packedBuffer) & 0xFC) >> 2; // Bits 3-8 into 1-6
655  ++packedBuffer;
656  *symbolBuffer |= ((*packedBuffer) & 0x0F) << 6; // Bits 1-4 into 7-10
657  ++pos;
658 
659  if (pos != symbolCount) {
660  ++symbolBuffer;
661  *symbolBuffer = ((*packedBuffer) & 0xF0) >> 4; // Bits 5-8 into 1-4
662  ++packedBuffer;
663  *symbolBuffer |= ((*packedBuffer) & 0x3F) << 4; // Bits 1-6 into 5-10
664  }
665  }
666  }
667 }
668 
669 inline void BytePacker::pack12(unsigned char *dest,
670  const unsigned int *symbolBuffer,
671  size_t symbolCount) {
672  const size_t limit = symbolCount / 2;
673  for (size_t i = 0; i != limit; i++) {
674  *dest = (*symbolBuffer) & 0x0FF; // bits 1-8 into 1-8
675  ++dest;
676 
677  *dest = ((*symbolBuffer) & 0xF00) >> 8; // bits 9-12 into 1-4
678  ++symbolBuffer;
679  *dest |= ((*symbolBuffer) & 0x00F) << 4; // bits 1-4 into 5-8
680  ++dest;
681 
682  *dest = ((*symbolBuffer) & 0xFF0) >> 4; // bits 5-12 into 1-8
683  ++symbolBuffer;
684  ++dest;
685  }
686  if (limit * 2 != symbolCount) {
687  *dest = (*symbolBuffer) & 0x0FF; // bits 1-8 into 1-8
688  ++dest;
689 
690  *dest = ((*symbolBuffer) & 0xF00) >> 8; // bits 9-12 into 1-4
691  }
692 }
693 
694 inline void BytePacker::unpack12(unsigned int *symbolBuffer,
695  unsigned char *packedBuffer,
696  size_t symbolCount) {
697  const size_t limit = symbolCount / 2;
698  for (size_t i = 0; i != limit; i++) {
699  *symbolBuffer = *packedBuffer; // bits 1-8 into 1-8
700  ++packedBuffer;
701  *symbolBuffer |= ((*packedBuffer) & 0x0F) << 8; // bits 1-4 into 9-12
702  ++symbolBuffer;
703 
704  *symbolBuffer = ((*packedBuffer) & 0xF0) >> 4; // bits 5-8 into 1-4
705  ++packedBuffer;
706  *symbolBuffer |= ((*packedBuffer) & 0xFF) << 4; // bits 1-8 into 5-12
707  ++packedBuffer;
708  ++symbolBuffer;
709  }
710  if (limit * 2 != symbolCount) {
711  *symbolBuffer = *packedBuffer; // bits 1-8 into 1-8
712  ++packedBuffer;
713  *symbolBuffer |= ((*packedBuffer) & 0x0F) << 8; // bits 1-4 into 9-12
714  }
715 }
716 
717 inline void BytePacker::pack16(unsigned char *dest,
718  const unsigned *symbolBuffer,
719  size_t symbolCount) {
720  for (size_t i = 0; i != symbolCount; ++i)
721  reinterpret_cast<uint16_t *>(dest)[i] = symbolBuffer[i];
722 }
723 
724 inline void BytePacker::unpack16(unsigned *symbolBuffer,
725  unsigned char *packedBuffer,
726  size_t symbolCount) {
727  for (size_t i = 0; i != symbolCount; ++i)
728  symbolBuffer[i] = reinterpret_cast<uint16_t *>(packedBuffer)[i];
729 }
730 
731 } // namespace dyscostman
732 
733 #endif
Class for bit packing of values into bytes.
Definition: bytepacker.h:25
static void unpack4(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack4().
Definition: bytepacker.h:446
static void unpack12(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack12().
Definition: bytepacker.h:694
static void pack2(unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Pack the symbols from symbolBuffer into the destination array using bitCount=2.
Definition: bytepacker.h:219
static size_t bufferSize(size_t nSymbols, size_t nBits)
Definition: bytepacker.h:147
static void pack8(unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Pack the symbols from symbolBuffer into the destination array using bitCount=8.
Definition: bytepacker.h:555
static void pack4(unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Pack the symbols from symbolBuffer into the destination array using bitCount=4.
Definition: bytepacker.h:432
static void pack3(unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Pack the symbols from symbolBuffer into the destination array using bitCount=3.
Definition: bytepacker.h:285
static void pack16(unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Pack the symbols from symbolBuffer into the destination array using bitCount=16.
Definition: bytepacker.h:717
static void pack10(unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Pack the symbols from symbolBuffer into the destination array using bitCount=10.
Definition: bytepacker.h:566
static void unpack6(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack6().
Definition: bytepacker.h:509
static void unpack3(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack3().
Definition: bytepacker.h:354
static void unpack(unsigned bitCount, unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Call an unpack..() function for a given bit count.
Definition: bytepacker.h:185
static void pack6(unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Pack the symbols from symbolBuffer into the destination array using bitCount=6.
Definition: bytepacker.h:461
static void unpack2(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack2().
Definition: bytepacker.h:252
static void pack12(unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Pack the symbols from symbolBuffer into the destination array using bitCount=12.
Definition: bytepacker.h:669
static void unpack16(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack16().
Definition: bytepacker.h:724
static void unpack10(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack10().
Definition: bytepacker.h:618
static void pack(unsigned bitCount, unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Call a pack..() function for a given bit count.
Definition: bytepacker.h:152
static void unpack8(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack8().
Definition: bytepacker.h:560