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