1#ifndef DYSCO_BYTE_PACKER_H
2#define DYSCO_BYTE_PACKER_H
36 static void pack(
unsigned bitCount,
unsigned char *dest,
37 const unsigned *symbolBuffer,
size_t symbolCount);
48 static void unpack(
unsigned bitCount,
unsigned *symbolBuffer,
49 unsigned char *packedBuffer,
size_t symbolCount);
55 static void pack2(
unsigned char *dest,
const unsigned *symbolBuffer,
60 static void unpack2(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
67 static void pack3(
unsigned char *dest,
const unsigned *symbolBuffer,
72 static void unpack3(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
79 static void pack4(
unsigned char *dest,
const unsigned *symbolBuffer,
84 static void unpack4(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
91 static void pack6(
unsigned char *dest,
const unsigned *symbolBuffer,
97 static void unpack6(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
104 static void pack8(
unsigned char *dest,
const unsigned *symbolBuffer,
109 static void unpack8(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
116 static void pack10(
unsigned char *dest,
const unsigned *symbolBuffer,
121 static void unpack10(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
128 static void pack12(
unsigned char *dest,
const unsigned *symbolBuffer,
133 static void unpack12(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
140 static void pack16(
unsigned char *dest,
const unsigned *symbolBuffer,
145 static void unpack16(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
149 return (nSymbols * nBits + 7) / 8;
154 const unsigned int *symbolBuffer,
155 size_t symbolCount) {
158 pack2(dest, symbolBuffer, symbolCount);
161 pack3(dest, symbolBuffer, symbolCount);
164 pack4(dest, symbolBuffer, symbolCount);
167 pack6(dest, symbolBuffer, symbolCount);
170 pack8(dest, symbolBuffer, symbolCount);
173 pack10(dest, symbolBuffer, symbolCount);
176 pack12(dest, symbolBuffer, symbolCount);
179 pack16(dest, symbolBuffer, symbolCount);
182 throw std::runtime_error(
"Unsupported packing size");
187 unsigned int *symbolBuffer,
188 unsigned char *packedBuffer,
189 size_t symbolCount) {
192 unpack2(symbolBuffer, packedBuffer, symbolCount);
195 unpack3(symbolBuffer, packedBuffer, symbolCount);
198 unpack4(symbolBuffer, packedBuffer, symbolCount);
201 unpack6(symbolBuffer, packedBuffer, symbolCount);
204 unpack8(symbolBuffer, packedBuffer, symbolCount);
207 unpack10(symbolBuffer, packedBuffer, symbolCount);
210 unpack12(symbolBuffer, packedBuffer, symbolCount);
213 unpack16(symbolBuffer, packedBuffer, symbolCount);
216 throw std::runtime_error(
"Unsupported unpacking size");
221 const unsigned int *symbolBuffer,
222 size_t symbolCount) {
223 const size_t limit = symbolCount / 4;
224 for (
size_t i = 0; i != limit; i++) {
225 *dest = (*symbolBuffer);
227 *dest |= (*symbolBuffer) << 2;
229 *dest |= (*symbolBuffer) << 4;
231 *dest |= (*symbolBuffer) << 6;
235 size_t pos = limit * 4;
236 if (pos != symbolCount) {
237 *dest = (*symbolBuffer);
240 if (pos != symbolCount) {
242 *dest |= (*symbolBuffer) << 2;
245 if (pos != symbolCount) {
247 *dest |= (*symbolBuffer) << 4;
254 unsigned char *packedBuffer,
255 size_t symbolCount) {
256 const size_t limit = symbolCount / 4;
257 for (
size_t i = 0; i != limit; i++) {
258 *symbolBuffer = *packedBuffer & 0x03;
260 *symbolBuffer = ((*packedBuffer) & 0x0C) >> 2;
262 *symbolBuffer = ((*packedBuffer) & 0x30) >> 4;
264 *symbolBuffer = ((*packedBuffer) & 0xC0) >> 6;
268 size_t pos = limit * 4;
269 if (pos != symbolCount) {
270 *symbolBuffer = *packedBuffer & 0x03;
273 if (pos != symbolCount) {
275 *symbolBuffer = ((*packedBuffer) & 0x0C) >> 2;
278 if (pos != symbolCount) {
280 *symbolBuffer = ((*packedBuffer) & 0x30) >> 4;
287 size_t symbolCount) {
288 const size_t limit = symbolCount / 8;
289 for (
size_t i = 0; i != limit; i++) {
290 *dest = *symbolBuffer;
292 *dest |= (*symbolBuffer) << 3;
294 *dest |= ((*symbolBuffer) & 0x3) << 6;
297 *dest = ((*symbolBuffer) & 0x4) >> 2;
299 *dest |= (*symbolBuffer) << 1;
301 *dest |= (*symbolBuffer) << 4;
303 *dest |= ((*symbolBuffer) & 0x1) << 7;
306 *dest = ((*symbolBuffer) & 0x6) >> 1;
308 *dest |= (*symbolBuffer) << 2;
310 *dest |= (*symbolBuffer) << 5;
315 size_t pos = limit * 8;
316 if (pos != symbolCount) {
317 *dest = *symbolBuffer;
319 if (pos != symbolCount) {
321 *dest |= (*symbolBuffer) << 3;
323 if (pos != symbolCount) {
325 *dest |= ((*symbolBuffer) & 0x3) << 6;
327 *dest = ((*symbolBuffer) & 0x4) >> 2;
329 if (pos != symbolCount) {
331 *dest |= (*symbolBuffer) << 1;
333 if (pos != symbolCount) {
335 *dest |= (*symbolBuffer) << 4;
337 if (pos != symbolCount) {
339 *dest |= ((*symbolBuffer) & 0x1) << 7;
341 *dest = ((*symbolBuffer) & 0x6) >> 1;
343 if (pos != symbolCount) {
345 *dest |= (*symbolBuffer) << 2;
356 unsigned char *packedBuffer,
357 size_t symbolCount) {
358 const size_t limit = symbolCount / 8;
359 for (
size_t i = 0; i != limit; i++) {
360 *symbolBuffer = (*packedBuffer) & 0x07;
362 *symbolBuffer = ((*packedBuffer) & 0x38) >> 3;
364 *symbolBuffer = ((*packedBuffer) & 0xC0) >> 6;
367 *symbolBuffer |= ((*packedBuffer) & 0x01) << 2;
369 *symbolBuffer = ((*packedBuffer) & 0x0e) >> 1;
371 *symbolBuffer = ((*packedBuffer) & 0x70) >> 4;
373 *symbolBuffer = ((*packedBuffer) & 0x80) >> 7;
376 *symbolBuffer |= ((*packedBuffer) & 0x03) << 1;
378 *symbolBuffer = ((*packedBuffer) & 0x1c) >> 2;
380 *symbolBuffer = ((*packedBuffer) & 0xe0) >> 5;
384 size_t pos = limit * 8;
385 if (pos != symbolCount) {
386 *symbolBuffer = (*packedBuffer) & 0x07;
389 if (pos != symbolCount) {
391 *symbolBuffer = ((*packedBuffer) & 0x38) >> 3;
394 if (pos != symbolCount) {
396 *symbolBuffer = ((*packedBuffer) & 0xC0) >> 6;
398 *symbolBuffer |= ((*packedBuffer) & 0x01) << 2;
401 if (pos != symbolCount) {
403 *symbolBuffer = ((*packedBuffer) & 0x0e) >> 1;
406 if (pos != symbolCount) {
409 ((*packedBuffer) & 0x70) >> 4;
412 if (pos != symbolCount) {
414 *symbolBuffer = ((*packedBuffer) & 0x80) >> 7;
416 *symbolBuffer |= ((*packedBuffer) & 0x03)
420 if (pos != symbolCount) {
423 ((*packedBuffer) & 0x1c) >> 2;
434 const unsigned int *symbolBuffer,
435 size_t symbolCount) {
436 const size_t limit = symbolCount / 2;
437 for (
size_t i = 0; i != limit; i++) {
438 *dest = (*symbolBuffer);
440 *dest |= (*symbolBuffer) << 4;
444 if (limit * 2 != symbolCount) *dest = (*symbolBuffer);
448 unsigned char *packedBuffer,
449 size_t symbolCount) {
450 const size_t limit = symbolCount / 2;
451 for (
size_t i = 0; i != limit; i++) {
452 *symbolBuffer = *packedBuffer & 0x0F;
454 *symbolBuffer = ((*packedBuffer) & 0xF0) >> 4;
458 if (limit * 2 != symbolCount)
459 *symbolBuffer = *packedBuffer & 0x0F;
463 size_t symbolCount) {
464 const size_t limit = symbolCount / 4;
465 for (
size_t i = 0; i != limit; i++) {
466 *dest = *symbolBuffer;
468 *dest |= (*symbolBuffer & 3) << 6;
471 *dest = (*symbolBuffer & 60) >> 2;
473 *dest |= (*symbolBuffer & 15) << 4;
476 *dest = (*symbolBuffer & 48) >> 4;
478 *dest |= *symbolBuffer << 2;
483 size_t pos = limit * 4;
484 if (pos != symbolCount) {
485 *dest = *symbolBuffer;
488 if (pos != symbolCount) {
491 *dest |= (*symbolBuffer & 3) << 6;
494 *dest = (*symbolBuffer & 60) >> 2;
497 if (pos != symbolCount) {
500 *dest |= (*symbolBuffer & 15) << 4;
503 *dest = (*symbolBuffer & 48) >> 4;
511 unsigned char *packedBuffer,
512 size_t symbolCount) {
513 const size_t limit = symbolCount / 4;
514 for (
size_t i = 0; i != limit; i++) {
515 *symbolBuffer = (*packedBuffer) & 63;
517 *symbolBuffer = ((*packedBuffer) & 192) >> 6;
520 *symbolBuffer |= ((*packedBuffer) & 15) << 2;
522 *symbolBuffer = ((*packedBuffer) & 240) >> 4;
525 *symbolBuffer |= ((*packedBuffer) & 3) << 4;
527 *symbolBuffer = ((*packedBuffer) & 252) >> 2;
531 size_t pos = limit * 4;
532 if (pos != symbolCount) {
533 *symbolBuffer = (*packedBuffer) & 63;
536 if (pos != symbolCount) {
539 *symbolBuffer = ((*packedBuffer) & 192) >> 6;
542 *symbolBuffer |= ((*packedBuffer) & 15) << 2;
545 if (pos != symbolCount) {
547 *symbolBuffer = ((*packedBuffer) & 240) >> 4;
550 *symbolBuffer |= ((*packedBuffer) & 3) << 4;
557 size_t symbolCount) {
558 for (
size_t i = 0; i != symbolCount; ++i) dest[i] = symbolBuffer[i];
562 unsigned char *packedBuffer,
563 size_t symbolCount) {
564 for (
size_t i = 0; i != symbolCount; ++i) symbolBuffer[i] = packedBuffer[i];
568 const unsigned int *symbolBuffer,
569 size_t symbolCount) {
570 const size_t limit = symbolCount / 4;
571 for (
size_t i = 0; i != limit; i++) {
572 *dest = (*symbolBuffer & 0x0FF);
574 *dest = (*symbolBuffer & 0x300) >> 8;
576 *dest |= (*symbolBuffer & 0x03F) << 2;
578 *dest = (*symbolBuffer & 0x3C0) >> 6;
581 *dest |= (*symbolBuffer & 0x00F) << 4;
583 *dest = (*symbolBuffer & 0x3F0) >> 4;
585 *dest |= (*symbolBuffer & 0x003) << 6;
587 *dest = (*symbolBuffer & 0x3FC) >> 2;
592 size_t pos = limit * 4;
593 if (pos != symbolCount) {
594 *dest = (*symbolBuffer & 0x0FF);
596 *dest = (*symbolBuffer & 0x300) >> 8;
599 if (pos != symbolCount) {
602 *dest |= (*symbolBuffer & 0x03F) << 2;
604 *dest = (*symbolBuffer & 0x3C0) >> 6;
607 if (pos != symbolCount) {
610 *dest |= (*symbolBuffer & 0x00F) << 4;
612 *dest = (*symbolBuffer & 0x3F0) >> 4;
620 unsigned char *packedBuffer,
621 size_t symbolCount) {
622 const size_t limit = symbolCount / 4;
623 for (
size_t i = 0; i != limit; i++) {
624 *symbolBuffer = *packedBuffer;
626 *symbolBuffer |= ((*packedBuffer) & 0x03) << 8;
629 *symbolBuffer = ((*packedBuffer) & 0xFC) >> 2;
631 *symbolBuffer |= ((*packedBuffer) & 0x0F) << 6;
634 *symbolBuffer = ((*packedBuffer) & 0xF0) >> 4;
636 *symbolBuffer |= ((*packedBuffer) & 0x3F) << 4;
639 *symbolBuffer = ((*packedBuffer) & 0xC0) >> 6;
641 *symbolBuffer |= (*packedBuffer) << 2;
645 size_t pos = limit * 4;
646 if (pos != symbolCount) {
647 *symbolBuffer = *packedBuffer;
649 *symbolBuffer |= ((*packedBuffer) & 0x03) << 8;
652 if (pos != symbolCount) {
655 *symbolBuffer = ((*packedBuffer) & 0xFC) >> 2;
657 *symbolBuffer |= ((*packedBuffer) & 0x0F) << 6;
660 if (pos != symbolCount) {
662 *symbolBuffer = ((*packedBuffer) & 0xF0) >> 4;
664 *symbolBuffer |= ((*packedBuffer) & 0x3F) << 4;
671 const unsigned int *symbolBuffer,
672 size_t symbolCount) {
673 const size_t limit = symbolCount / 2;
674 for (
size_t i = 0; i != limit; i++) {
675 *dest = (*symbolBuffer) & 0x0FF;
678 *dest = ((*symbolBuffer) & 0xF00) >> 8;
680 *dest |= ((*symbolBuffer) & 0x00F) << 4;
683 *dest = ((*symbolBuffer) & 0xFF0) >> 4;
687 if (limit * 2 != symbolCount) {
688 *dest = (*symbolBuffer) & 0x0FF;
691 *dest = ((*symbolBuffer) & 0xF00) >> 8;
696 unsigned char *packedBuffer,
697 size_t symbolCount) {
698 const size_t limit = symbolCount / 2;
699 for (
size_t i = 0; i != limit; i++) {
700 *symbolBuffer = *packedBuffer;
702 *symbolBuffer |= ((*packedBuffer) & 0x0F) << 8;
705 *symbolBuffer = ((*packedBuffer) & 0xF0) >> 4;
707 *symbolBuffer |= ((*packedBuffer) & 0xFF) << 4;
711 if (limit * 2 != symbolCount) {
712 *symbolBuffer = *packedBuffer;
714 *symbolBuffer |= ((*packedBuffer) & 0x0F) << 8;
719 const unsigned *symbolBuffer,
720 size_t symbolCount) {
721 for (
size_t i = 0; i != symbolCount; ++i)
722 reinterpret_cast<uint16_t *
>(dest)[i] = symbolBuffer[i];
726 unsigned char *packedBuffer,
727 size_t symbolCount) {
728 for (
size_t i = 0; i != symbolCount; ++i)
729 symbolBuffer[i] =
reinterpret_cast<uint16_t *
>(packedBuffer)[i];
Class for bit packing of values into bytes.
static void unpack4(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack4().
static void unpack12(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack12().
static void pack2(unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Pack the symbols from symbolBuffer into the destination array using bitCount=2.
static size_t bufferSize(size_t nSymbols, size_t nBits)
static void pack8(unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Pack the symbols from symbolBuffer into the destination array using bitCount=8.
static void pack4(unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Pack the symbols from symbolBuffer into the destination array using bitCount=4.
static void pack3(unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Pack the symbols from symbolBuffer into the destination array using bitCount=3.
static void pack16(unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Pack the symbols from symbolBuffer into the destination array using bitCount=16.
static void pack10(unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Pack the symbols from symbolBuffer into the destination array using bitCount=10.
static void unpack6(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack6().
static void unpack3(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack3().
static void unpack(unsigned bitCount, unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Call an unpack..() function for a given bit count.
static void pack6(unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Pack the symbols from symbolBuffer into the destination array using bitCount=6.
static void unpack2(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack2().
static void pack12(unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Pack the symbols from symbolBuffer into the destination array using bitCount=12.
static void unpack16(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack16().
static void unpack10(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack10().
static void pack(unsigned bitCount, unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Call a pack..() function for a given bit count.
static void unpack8(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack8().