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