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
6namespace dyscostman {
7
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
152inline 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
185inline 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
219inline 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
252inline 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
285inline 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
354inline 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
432inline 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
446inline 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
461inline 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
509inline 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
555inline 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
560inline 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
566inline 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
618inline 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
669inline 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
694inline 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
717inline 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
724inline 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