1 #ifndef DYSCO_BYTE_PACKER_H
2 #define DYSCO_BYTE_PACKER_H
35 static void pack(
unsigned bitCount,
unsigned char *dest,
36 const unsigned *symbolBuffer,
size_t symbolCount);
47 static void unpack(
unsigned bitCount,
unsigned *symbolBuffer,
48 unsigned char *packedBuffer,
size_t symbolCount);
54 static void pack2(
unsigned char *dest,
const unsigned *symbolBuffer,
59 static void unpack2(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
66 static void pack3(
unsigned char *dest,
const unsigned *symbolBuffer,
71 static void unpack3(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
78 static void pack4(
unsigned char *dest,
const unsigned *symbolBuffer,
83 static void unpack4(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
90 static void pack6(
unsigned char *dest,
const unsigned *symbolBuffer,
96 static void unpack6(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
103 static void pack8(
unsigned char *dest,
const unsigned *symbolBuffer,
108 static void unpack8(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
115 static void pack10(
unsigned char *dest,
const unsigned *symbolBuffer,
120 static void unpack10(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
127 static void pack12(
unsigned char *dest,
const unsigned *symbolBuffer,
132 static void unpack12(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
139 static void pack16(
unsigned char *dest,
const unsigned *symbolBuffer,
144 static void unpack16(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
148 return (nSymbols * nBits + 7) / 8;
153 const unsigned int *symbolBuffer,
154 size_t symbolCount) {
157 pack2(dest, symbolBuffer, symbolCount);
160 pack3(dest, symbolBuffer, symbolCount);
163 pack4(dest, symbolBuffer, symbolCount);
166 pack6(dest, symbolBuffer, symbolCount);
169 pack8(dest, symbolBuffer, symbolCount);
172 pack10(dest, symbolBuffer, symbolCount);
175 pack12(dest, symbolBuffer, symbolCount);
178 pack16(dest, symbolBuffer, symbolCount);
181 throw std::runtime_error(
"Unsupported packing size");
186 unsigned int *symbolBuffer,
187 unsigned char *packedBuffer,
188 size_t symbolCount) {
191 unpack2(symbolBuffer, packedBuffer, symbolCount);
194 unpack3(symbolBuffer, packedBuffer, symbolCount);
197 unpack4(symbolBuffer, packedBuffer, symbolCount);
200 unpack6(symbolBuffer, packedBuffer, symbolCount);
203 unpack8(symbolBuffer, packedBuffer, symbolCount);
206 unpack10(symbolBuffer, packedBuffer, symbolCount);
209 unpack12(symbolBuffer, packedBuffer, symbolCount);
212 unpack16(symbolBuffer, packedBuffer, symbolCount);
215 throw std::runtime_error(
"Unsupported unpacking size");
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);
226 *dest |= (*symbolBuffer) << 2;
228 *dest |= (*symbolBuffer) << 4;
230 *dest |= (*symbolBuffer) << 6;
234 size_t pos = limit * 4;
235 if (pos != symbolCount) {
236 *dest = (*symbolBuffer);
239 if (pos != symbolCount) {
241 *dest |= (*symbolBuffer) << 2;
244 if (pos != symbolCount) {
246 *dest |= (*symbolBuffer) << 4;
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;
259 *symbolBuffer = ((*packedBuffer) & 0x0C) >> 2;
261 *symbolBuffer = ((*packedBuffer) & 0x30) >> 4;
263 *symbolBuffer = ((*packedBuffer) & 0xC0) >> 6;
267 size_t pos = limit * 4;
268 if (pos != symbolCount) {
269 *symbolBuffer = *packedBuffer & 0x03;
272 if (pos != symbolCount) {
274 *symbolBuffer = ((*packedBuffer) & 0x0C) >> 2;
277 if (pos != symbolCount) {
279 *symbolBuffer = ((*packedBuffer) & 0x30) >> 4;
286 size_t symbolCount) {
287 const size_t limit = symbolCount / 8;
288 for (
size_t i = 0; i != limit; i++) {
289 *dest = *symbolBuffer;
291 *dest |= (*symbolBuffer) << 3;
293 *dest |= ((*symbolBuffer) & 0x3) << 6;
296 *dest = ((*symbolBuffer) & 0x4) >> 2;
298 *dest |= (*symbolBuffer) << 1;
300 *dest |= (*symbolBuffer) << 4;
302 *dest |= ((*symbolBuffer) & 0x1) << 7;
305 *dest = ((*symbolBuffer) & 0x6) >> 1;
307 *dest |= (*symbolBuffer) << 2;
309 *dest |= (*symbolBuffer) << 5;
314 size_t pos = limit * 8;
315 if (pos != symbolCount) {
316 *dest = *symbolBuffer;
318 if (pos != symbolCount) {
320 *dest |= (*symbolBuffer) << 3;
322 if (pos != symbolCount) {
324 *dest |= ((*symbolBuffer) & 0x3) << 6;
326 *dest = ((*symbolBuffer) & 0x4) >> 2;
328 if (pos != symbolCount) {
330 *dest |= (*symbolBuffer) << 1;
332 if (pos != symbolCount) {
334 *dest |= (*symbolBuffer) << 4;
336 if (pos != symbolCount) {
338 *dest |= ((*symbolBuffer) & 0x1) << 7;
340 *dest = ((*symbolBuffer) & 0x6) >> 1;
342 if (pos != symbolCount) {
344 *dest |= (*symbolBuffer) << 2;
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;
361 *symbolBuffer = ((*packedBuffer) & 0x38) >> 3;
363 *symbolBuffer = ((*packedBuffer) & 0xC0) >> 6;
366 *symbolBuffer |= ((*packedBuffer) & 0x01) << 2;
368 *symbolBuffer = ((*packedBuffer) & 0x0e) >> 1;
370 *symbolBuffer = ((*packedBuffer) & 0x70) >> 4;
372 *symbolBuffer = ((*packedBuffer) & 0x80) >> 7;
375 *symbolBuffer |= ((*packedBuffer) & 0x03) << 1;
377 *symbolBuffer = ((*packedBuffer) & 0x1c) >> 2;
379 *symbolBuffer = ((*packedBuffer) & 0xe0) >> 5;
383 size_t pos = limit * 8;
384 if (pos != symbolCount) {
385 *symbolBuffer = (*packedBuffer) & 0x07;
388 if (pos != symbolCount) {
390 *symbolBuffer = ((*packedBuffer) & 0x38) >> 3;
393 if (pos != symbolCount) {
395 *symbolBuffer = ((*packedBuffer) & 0xC0) >> 6;
397 *symbolBuffer |= ((*packedBuffer) & 0x01) << 2;
400 if (pos != symbolCount) {
402 *symbolBuffer = ((*packedBuffer) & 0x0e) >> 1;
405 if (pos != symbolCount) {
408 ((*packedBuffer) & 0x70) >> 4;
411 if (pos != symbolCount) {
413 *symbolBuffer = ((*packedBuffer) & 0x80) >> 7;
415 *symbolBuffer |= ((*packedBuffer) & 0x03)
419 if (pos != symbolCount) {
422 ((*packedBuffer) & 0x1c) >> 2;
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);
439 *dest |= (*symbolBuffer) << 4;
443 if (limit * 2 != symbolCount) *dest = (*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;
453 *symbolBuffer = ((*packedBuffer) & 0xF0) >> 4;
457 if (limit * 2 != symbolCount)
458 *symbolBuffer = *packedBuffer & 0x0F;
462 size_t symbolCount) {
463 const size_t limit = symbolCount / 4;
464 for (
size_t i = 0; i != limit; i++) {
465 *dest = *symbolBuffer;
467 *dest |= (*symbolBuffer & 3) << 6;
470 *dest = (*symbolBuffer & 60) >> 2;
472 *dest |= (*symbolBuffer & 15) << 4;
475 *dest = (*symbolBuffer & 48) >> 4;
477 *dest |= *symbolBuffer << 2;
482 size_t pos = limit * 4;
483 if (pos != symbolCount) {
484 *dest = *symbolBuffer;
487 if (pos != symbolCount) {
490 *dest |= (*symbolBuffer & 3) << 6;
493 *dest = (*symbolBuffer & 60) >> 2;
496 if (pos != symbolCount) {
499 *dest |= (*symbolBuffer & 15) << 4;
502 *dest = (*symbolBuffer & 48) >> 4;
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;
516 *symbolBuffer = ((*packedBuffer) & 192) >> 6;
519 *symbolBuffer |= ((*packedBuffer) & 15) << 2;
521 *symbolBuffer = ((*packedBuffer) & 240) >> 4;
524 *symbolBuffer |= ((*packedBuffer) & 3) << 4;
526 *symbolBuffer = ((*packedBuffer) & 252) >> 2;
530 size_t pos = limit * 4;
531 if (pos != symbolCount) {
532 *symbolBuffer = (*packedBuffer) & 63;
535 if (pos != symbolCount) {
538 *symbolBuffer = ((*packedBuffer) & 192) >> 6;
541 *symbolBuffer |= ((*packedBuffer) & 15) << 2;
544 if (pos != symbolCount) {
546 *symbolBuffer = ((*packedBuffer) & 240) >> 4;
549 *symbolBuffer |= ((*packedBuffer) & 3) << 4;
556 size_t symbolCount) {
557 for (
size_t i = 0; i != symbolCount; ++i) dest[i] = symbolBuffer[i];
561 unsigned char *packedBuffer,
562 size_t symbolCount) {
563 for (
size_t i = 0; i != symbolCount; ++i) symbolBuffer[i] = packedBuffer[i];
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);
573 *dest = (*symbolBuffer & 0x300) >> 8;
575 *dest |= (*symbolBuffer & 0x03F) << 2;
577 *dest = (*symbolBuffer & 0x3C0) >> 6;
580 *dest |= (*symbolBuffer & 0x00F) << 4;
582 *dest = (*symbolBuffer & 0x3F0) >> 4;
584 *dest |= (*symbolBuffer & 0x003) << 6;
586 *dest = (*symbolBuffer & 0x3FC) >> 2;
591 size_t pos = limit * 4;
592 if (pos != symbolCount) {
593 *dest = (*symbolBuffer & 0x0FF);
595 *dest = (*symbolBuffer & 0x300) >> 8;
598 if (pos != symbolCount) {
601 *dest |= (*symbolBuffer & 0x03F) << 2;
603 *dest = (*symbolBuffer & 0x3C0) >> 6;
606 if (pos != symbolCount) {
609 *dest |= (*symbolBuffer & 0x00F) << 4;
611 *dest = (*symbolBuffer & 0x3F0) >> 4;
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;
625 *symbolBuffer |= ((*packedBuffer) & 0x03) << 8;
628 *symbolBuffer = ((*packedBuffer) & 0xFC) >> 2;
630 *symbolBuffer |= ((*packedBuffer) & 0x0F) << 6;
633 *symbolBuffer = ((*packedBuffer) & 0xF0) >> 4;
635 *symbolBuffer |= ((*packedBuffer) & 0x3F) << 4;
638 *symbolBuffer = ((*packedBuffer) & 0xC0) >> 6;
640 *symbolBuffer |= (*packedBuffer) << 2;
644 size_t pos = limit * 4;
645 if (pos != symbolCount) {
646 *symbolBuffer = *packedBuffer;
648 *symbolBuffer |= ((*packedBuffer) & 0x03) << 8;
651 if (pos != symbolCount) {
654 *symbolBuffer = ((*packedBuffer) & 0xFC) >> 2;
656 *symbolBuffer |= ((*packedBuffer) & 0x0F) << 6;
659 if (pos != symbolCount) {
661 *symbolBuffer = ((*packedBuffer) & 0xF0) >> 4;
663 *symbolBuffer |= ((*packedBuffer) & 0x3F) << 4;
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;
677 *dest = ((*symbolBuffer) & 0xF00) >> 8;
679 *dest |= ((*symbolBuffer) & 0x00F) << 4;
682 *dest = ((*symbolBuffer) & 0xFF0) >> 4;
686 if (limit * 2 != symbolCount) {
687 *dest = (*symbolBuffer) & 0x0FF;
690 *dest = ((*symbolBuffer) & 0xF00) >> 8;
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;
701 *symbolBuffer |= ((*packedBuffer) & 0x0F) << 8;
704 *symbolBuffer = ((*packedBuffer) & 0xF0) >> 4;
706 *symbolBuffer |= ((*packedBuffer) & 0xFF) << 4;
710 if (limit * 2 != symbolCount) {
711 *symbolBuffer = *packedBuffer;
713 *symbolBuffer |= ((*packedBuffer) & 0x0F) << 8;
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];
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];
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 unpack3(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack3().
static void unpack4(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack4().
static void unpack10(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack10().
static void unpack2(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack2().
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 pack3(unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Pack the symbols from symbolBuffer into the destination array using bitCount=3.
static void unpack8(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack8().
static void unpack12(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack12().
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 size_t bufferSize(size_t nSymbols, size_t nBits)
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 unpack(unsigned bitCount, unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Call an unpack..() function for a given bit count.
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 unpack6(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack6().
Class for bit packing of values into bytes.
static void unpack16(unsigned *symbolBuffer, unsigned char *packedBuffer, size_t symbolCount)
Reverse of pack16().
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 pack2(unsigned char *dest, const unsigned *symbolBuffer, size_t symbolCount)
Pack the symbols from symbolBuffer into the destination array using bitCount=2.