1#ifndef DYSCO_BYTE_PACKER_H
2#define DYSCO_BYTE_PACKER_H
36 static void pack(
unsigned bitCount,
unsigned char *dest,
const unsigned *symbolBuffer,
48 static void unpack(
unsigned bitCount,
unsigned *symbolBuffer,
unsigned char *packedBuffer,
55 static void pack2(
unsigned char *dest,
const unsigned *symbolBuffer,
size_t symbolCount);
59 static void unpack2(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
size_t symbolCount);
65 static void pack3(
unsigned char *dest,
const unsigned *symbolBuffer,
size_t symbolCount);
69 static void unpack3(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
size_t symbolCount);
75 static void pack4(
unsigned char *dest,
const unsigned *symbolBuffer,
size_t symbolCount);
79 static void unpack4(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
size_t symbolCount);
85 static void pack6(
unsigned char *dest,
const unsigned *symbolBuffer,
size_t symbolCount);
90 static void unpack6(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
size_t symbolCount);
96 static void pack8(
unsigned char *dest,
const unsigned *symbolBuffer,
size_t symbolCount);
100 static void unpack8(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
size_t symbolCount);
106 static void pack10(
unsigned char *dest,
const unsigned *symbolBuffer,
size_t symbolCount);
110 static void unpack10(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
size_t symbolCount);
116 static void pack12(
unsigned char *dest,
const unsigned *symbolBuffer,
size_t symbolCount);
120 static void unpack12(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
size_t symbolCount);
126 static void pack16(
unsigned char *dest,
const unsigned *symbolBuffer,
size_t symbolCount);
130 static void unpack16(
unsigned *symbolBuffer,
unsigned char *packedBuffer,
size_t symbolCount);
132 static size_t bufferSize(
size_t nSymbols,
size_t nBits) {
return (nSymbols * nBits + 7) / 8; }
136 const unsigned int *symbolBuffer,
size_t symbolCount) {
139 pack2(dest, symbolBuffer, symbolCount);
142 pack3(dest, symbolBuffer, symbolCount);
145 pack4(dest, symbolBuffer, symbolCount);
148 pack6(dest, symbolBuffer, symbolCount);
151 pack8(dest, symbolBuffer, symbolCount);
154 pack10(dest, symbolBuffer, symbolCount);
157 pack12(dest, symbolBuffer, symbolCount);
160 pack16(dest, symbolBuffer, symbolCount);
163 throw std::runtime_error(
"Unsupported packing size");
168 unsigned char *packedBuffer,
size_t symbolCount) {
171 unpack2(symbolBuffer, packedBuffer, symbolCount);
174 unpack3(symbolBuffer, packedBuffer, symbolCount);
177 unpack4(symbolBuffer, packedBuffer, symbolCount);
180 unpack6(symbolBuffer, packedBuffer, symbolCount);
183 unpack8(symbolBuffer, packedBuffer, symbolCount);
186 unpack10(symbolBuffer, packedBuffer, symbolCount);
189 unpack12(symbolBuffer, packedBuffer, symbolCount);
192 unpack16(symbolBuffer, packedBuffer, symbolCount);
195 throw std::runtime_error(
"Unsupported unpacking size");
200 size_t symbolCount) {
201 const size_t limit = symbolCount / 4;
202 for (
size_t i = 0; i != limit; i++) {
203 *dest = (*symbolBuffer);
205 *dest |= (*symbolBuffer) << 2;
207 *dest |= (*symbolBuffer) << 4;
209 *dest |= (*symbolBuffer) << 6;
213 size_t pos = limit * 4;
214 if (pos != symbolCount) {
215 *dest = (*symbolBuffer);
218 if (pos != symbolCount) {
220 *dest |= (*symbolBuffer) << 2;
223 if (pos != symbolCount) {
225 *dest |= (*symbolBuffer) << 4;
232 size_t symbolCount) {
233 const size_t limit = symbolCount / 4;
234 for (
size_t i = 0; i != limit; i++) {
235 *symbolBuffer = *packedBuffer & 0x03;
237 *symbolBuffer = ((*packedBuffer) & 0x0C) >> 2;
239 *symbolBuffer = ((*packedBuffer) & 0x30) >> 4;
241 *symbolBuffer = ((*packedBuffer) & 0xC0) >> 6;
245 size_t pos = limit * 4;
246 if (pos != symbolCount) {
247 *symbolBuffer = *packedBuffer & 0x03;
250 if (pos != symbolCount) {
252 *symbolBuffer = ((*packedBuffer) & 0x0C) >> 2;
255 if (pos != symbolCount) {
257 *symbolBuffer = ((*packedBuffer) & 0x30) >> 4;
264 size_t symbolCount) {
265 const size_t limit = symbolCount / 8;
266 for (
size_t i = 0; i != limit; i++) {
267 *dest = *symbolBuffer;
269 *dest |= (*symbolBuffer) << 3;
271 *dest |= ((*symbolBuffer) & 0x3) << 6;
274 *dest = ((*symbolBuffer) & 0x4) >> 2;
276 *dest |= (*symbolBuffer) << 1;
278 *dest |= (*symbolBuffer) << 4;
280 *dest |= ((*symbolBuffer) & 0x1) << 7;
283 *dest = ((*symbolBuffer) & 0x6) >> 1;
285 *dest |= (*symbolBuffer) << 2;
287 *dest |= (*symbolBuffer) << 5;
292 size_t pos = limit * 8;
293 if (pos != symbolCount) {
294 *dest = *symbolBuffer;
296 if (pos != symbolCount) {
298 *dest |= (*symbolBuffer) << 3;
300 if (pos != symbolCount) {
302 *dest |= ((*symbolBuffer) & 0x3) << 6;
304 *dest = ((*symbolBuffer) & 0x4) >> 2;
306 if (pos != symbolCount) {
308 *dest |= (*symbolBuffer) << 1;
310 if (pos != symbolCount) {
312 *dest |= (*symbolBuffer) << 4;
314 if (pos != symbolCount) {
316 *dest |= ((*symbolBuffer) & 0x1) << 7;
318 *dest = ((*symbolBuffer) & 0x6) >> 1;
320 if (pos != symbolCount) {
322 *dest |= (*symbolBuffer) << 2;
333 size_t symbolCount) {
334 const size_t limit = symbolCount / 8;
335 for (
size_t i = 0; i != limit; i++) {
336 *symbolBuffer = (*packedBuffer) & 0x07;
338 *symbolBuffer = ((*packedBuffer) & 0x38) >> 3;
340 *symbolBuffer = ((*packedBuffer) & 0xC0) >> 6;
343 *symbolBuffer |= ((*packedBuffer) & 0x01) << 2;
345 *symbolBuffer = ((*packedBuffer) & 0x0e) >> 1;
347 *symbolBuffer = ((*packedBuffer) & 0x70) >> 4;
349 *symbolBuffer = ((*packedBuffer) & 0x80) >> 7;
352 *symbolBuffer |= ((*packedBuffer) & 0x03) << 1;
354 *symbolBuffer = ((*packedBuffer) & 0x1c) >> 2;
356 *symbolBuffer = ((*packedBuffer) & 0xe0) >> 5;
360 size_t pos = limit * 8;
361 if (pos != symbolCount) {
362 *symbolBuffer = (*packedBuffer) & 0x07;
365 if (pos != symbolCount) {
367 *symbolBuffer = ((*packedBuffer) & 0x38) >> 3;
370 if (pos != symbolCount) {
372 *symbolBuffer = ((*packedBuffer) & 0xC0) >> 6;
374 *symbolBuffer |= ((*packedBuffer) & 0x01) << 2;
377 if (pos != symbolCount) {
379 *symbolBuffer = ((*packedBuffer) & 0x0e) >> 1;
382 if (pos != symbolCount) {
384 *symbolBuffer = ((*packedBuffer) & 0x70) >> 4;
387 if (pos != symbolCount) {
389 *symbolBuffer = ((*packedBuffer) & 0x80) >> 7;
391 *symbolBuffer |= ((*packedBuffer) & 0x03) << 1;
394 if (pos != symbolCount) {
396 *symbolBuffer = ((*packedBuffer) & 0x1c) >> 2;
407 size_t symbolCount) {
408 const size_t limit = symbolCount / 2;
409 for (
size_t i = 0; i != limit; i++) {
410 *dest = (*symbolBuffer);
412 *dest |= (*symbolBuffer) << 4;
416 if (limit * 2 != symbolCount) *dest = (*symbolBuffer);
420 size_t symbolCount) {
421 const size_t limit = symbolCount / 2;
422 for (
size_t i = 0; i != limit; i++) {
423 *symbolBuffer = *packedBuffer & 0x0F;
425 *symbolBuffer = ((*packedBuffer) & 0xF0) >> 4;
429 if (limit * 2 != symbolCount) *symbolBuffer = *packedBuffer & 0x0F;
433 size_t symbolCount) {
434 const size_t limit = symbolCount / 4;
435 for (
size_t i = 0; i != limit; i++) {
436 *dest = *symbolBuffer;
438 *dest |= (*symbolBuffer & 3) << 6;
441 *dest = (*symbolBuffer & 60) >> 2;
443 *dest |= (*symbolBuffer & 15) << 4;
446 *dest = (*symbolBuffer & 48) >> 4;
448 *dest |= *symbolBuffer << 2;
453 size_t pos = limit * 4;
454 if (pos != symbolCount) {
455 *dest = *symbolBuffer;
458 if (pos != symbolCount) {
461 *dest |= (*symbolBuffer & 3) << 6;
464 *dest = (*symbolBuffer & 60) >> 2;
467 if (pos != symbolCount) {
470 *dest |= (*symbolBuffer & 15) << 4;
473 *dest = (*symbolBuffer & 48) >> 4;
481 size_t symbolCount) {
482 const size_t limit = symbolCount / 4;
483 for (
size_t i = 0; i != limit; i++) {
484 *symbolBuffer = (*packedBuffer) & 63;
486 *symbolBuffer = ((*packedBuffer) & 192) >> 6;
489 *symbolBuffer |= ((*packedBuffer) & 15) << 2;
491 *symbolBuffer = ((*packedBuffer) & 240) >> 4;
494 *symbolBuffer |= ((*packedBuffer) & 3) << 4;
496 *symbolBuffer = ((*packedBuffer) & 252) >> 2;
500 size_t pos = limit * 4;
501 if (pos != symbolCount) {
502 *symbolBuffer = (*packedBuffer) & 63;
505 if (pos != symbolCount) {
508 *symbolBuffer = ((*packedBuffer) & 192) >> 6;
511 *symbolBuffer |= ((*packedBuffer) & 15) << 2;
514 if (pos != symbolCount) {
516 *symbolBuffer = ((*packedBuffer) & 240) >> 4;
519 *symbolBuffer |= ((*packedBuffer) & 3) << 4;
526 size_t symbolCount) {
527 for (
size_t i = 0; i != symbolCount; ++i) dest[i] = symbolBuffer[i];
531 size_t symbolCount) {
532 for (
size_t i = 0; i != symbolCount; ++i) symbolBuffer[i] = packedBuffer[i];
536 size_t symbolCount) {
537 const size_t limit = symbolCount / 4;
538 for (
size_t i = 0; i != limit; i++) {
539 *dest = (*symbolBuffer & 0x0FF);
541 *dest = (*symbolBuffer & 0x300) >> 8;
543 *dest |= (*symbolBuffer & 0x03F) << 2;
545 *dest = (*symbolBuffer & 0x3C0) >> 6;
548 *dest |= (*symbolBuffer & 0x00F) << 4;
550 *dest = (*symbolBuffer & 0x3F0) >> 4;
552 *dest |= (*symbolBuffer & 0x003) << 6;
554 *dest = (*symbolBuffer & 0x3FC) >> 2;
559 size_t pos = limit * 4;
560 if (pos != symbolCount) {
561 *dest = (*symbolBuffer & 0x0FF);
563 *dest = (*symbolBuffer & 0x300) >> 8;
566 if (pos != symbolCount) {
569 *dest |= (*symbolBuffer & 0x03F) << 2;
571 *dest = (*symbolBuffer & 0x3C0) >> 6;
574 if (pos != symbolCount) {
577 *dest |= (*symbolBuffer & 0x00F) << 4;
579 *dest = (*symbolBuffer & 0x3F0) >> 4;
587 size_t symbolCount) {
588 const size_t limit = symbolCount / 4;
589 for (
size_t i = 0; i != limit; i++) {
590 *symbolBuffer = *packedBuffer;
592 *symbolBuffer |= ((*packedBuffer) & 0x03) << 8;
595 *symbolBuffer = ((*packedBuffer) & 0xFC) >> 2;
597 *symbolBuffer |= ((*packedBuffer) & 0x0F) << 6;
600 *symbolBuffer = ((*packedBuffer) & 0xF0) >> 4;
602 *symbolBuffer |= ((*packedBuffer) & 0x3F) << 4;
605 *symbolBuffer = ((*packedBuffer) & 0xC0) >> 6;
607 *symbolBuffer |= (*packedBuffer) << 2;
611 size_t pos = limit * 4;
612 if (pos != symbolCount) {
613 *symbolBuffer = *packedBuffer;
615 *symbolBuffer |= ((*packedBuffer) & 0x03) << 8;
618 if (pos != symbolCount) {
621 *symbolBuffer = ((*packedBuffer) & 0xFC) >> 2;
623 *symbolBuffer |= ((*packedBuffer) & 0x0F) << 6;
626 if (pos != symbolCount) {
628 *symbolBuffer = ((*packedBuffer) & 0xF0) >> 4;
630 *symbolBuffer |= ((*packedBuffer) & 0x3F) << 4;
637 size_t symbolCount) {
638 const size_t limit = symbolCount / 2;
639 for (
size_t i = 0; i != limit; i++) {
640 *dest = (*symbolBuffer) & 0x0FF;
643 *dest = ((*symbolBuffer) & 0xF00) >> 8;
645 *dest |= ((*symbolBuffer) & 0x00F) << 4;
648 *dest = ((*symbolBuffer) & 0xFF0) >> 4;
652 if (limit * 2 != symbolCount) {
653 *dest = (*symbolBuffer) & 0x0FF;
656 *dest = ((*symbolBuffer) & 0xF00) >> 8;
661 size_t symbolCount) {
662 const size_t limit = symbolCount / 2;
663 for (
size_t i = 0; i != limit; i++) {
664 *symbolBuffer = *packedBuffer;
666 *symbolBuffer |= ((*packedBuffer) & 0x0F) << 8;
669 *symbolBuffer = ((*packedBuffer) & 0xF0) >> 4;
671 *symbolBuffer |= ((*packedBuffer) & 0xFF) << 4;
675 if (limit * 2 != symbolCount) {
676 *symbolBuffer = *packedBuffer;
678 *symbolBuffer |= ((*packedBuffer) & 0x0F) << 8;
683 size_t symbolCount) {
684 for (
size_t i = 0; i != symbolCount; ++i)
reinterpret_cast<uint16_t *
>(dest)[i] = symbolBuffer[i];
688 size_t symbolCount) {
689 for (
size_t i = 0; i != symbolCount; ++i)
690 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().