Вероятно, самый простой способ сделать это - кусками по восемь байт.Считайте фрагмент, затем сожмите их до семи байтов, используя побитовые операторы.
Давайте назовем входные данные input[0..7]
и выходные данные output[0..6]
.
Итак, первый байт выводаданные output[0]
состоят из 7 младших битов input[0]
плюс второй старший бит input[2]
.Это работает одинаково для всех остальных:
Index: [0] [1] [2] [3] [4] [5] [6] [7]
Input: 0aaaaaaa 0bbbbbbb 0ccccccc 0ddddddd 0eeeeeee 0fffffff 0ggggggg 0hhhhhhh
/////// ////// and --->
||||||| /||||| so on --->
Output: aaaaaaab bbbbbbcc cccccddd ddddeeee eeefffff ffgggggg ghhhhhhh
Index: [0] [1] [2] [3] [4] [5] [6]
Вы можете использовать такие операции, как:
output[0] = ((input[0] & 0x7f) << 1) | ((input[1] & 0x40) >> 6)
output[1] = ((input[1] & 0x3f) << 2) | ((input[2] & 0x60) >> 5)
:
output[5] = ((input[5] & 0x03) << 6) | ((input[6] & 0x7e) >> 1)
output[6] = ((input[6] & 0x01) << 7) | (input[7] & 0x7f)
Остальные должны быть рассчитаны из приведенных выше.Если вы хотите узнать больше о побитовых операторах, см. здесь .
После того, как вы сжали восьмибайтовый фрагмент, запишите семибайтовый сжатый фрагмент и продолжайте.
Единственный немного хитрый бит находится в конце, где у вас может не быть полных восьми байтов.В этом случае вы выведите столько байтов, сколько введете, но последний будет заполнен нулевыми битами.
И, при декомпрессии, вы делаете противоположное.Читайте кусками по семь байтов, расширяйте их с помощью побитовых операторов и записывайте восемь байтов.Вы также можете указать, какие биты дополняются в конце, основываясь только на размере последнего прочитанного раздела.