Commit f55b32e2 by Rudolf
parents
Showing with 128 additions and 0 deletions
/*
Copyright (C) 2015 Thiago Bellini <hackedbellini@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <stdio.h>
#include "bit-buffer.h"
/*
* Initialize the bit buffer.
*/
void
bb_init (struct BIT_BUFFER *buffer, FILE *fp)
{
buffer->pos = 0;
buffer->bits = 0;
buffer->first_read = 0;
buffer->fp = fp;
}
/*
* Flush bit buffer to file.
*/
void
bb_flush (struct BIT_BUFFER *buffer)
{
if (buffer->pos == 0)
return;
/* Fill the rest of the byte with 0s */
while (buffer->pos < BYTE_BIT)
{
buffer->bits &= ~(1 << (BYTE_BIT - buffer->pos - 1));
(buffer->pos)++;
}
fwrite (&(buffer->bits), sizeof (byte), 1, buffer->fp);
buffer->pos = 0;
buffer->bits = 0;
}
/*
* Write bits to file.
*/
void
bb_write (struct BIT_BUFFER *buffer, int *bits, int size)
{
int i, shift_pos;
for (i = 0; i < size; i++)
{
if (buffer->pos == BYTE_BIT)
bb_flush (buffer);
shift_pos = BYTE_BIT - buffer->pos - 1;
if (bits[i])
buffer->bits |= (1 << shift_pos);
else
buffer->bits &= ~(1 << shift_pos);
(buffer->pos)++;
}
}
/*
* Read bits from file.
*
* The return value must be freed after being used.
*/
int *
bb_read (struct BIT_BUFFER *buffer, int size)
{
int i, shift_pos;
int *bin;
bin = malloc (size * sizeof (int));
for (i = 0; i < size; i++)
{
if (!buffer->first_read || buffer->pos == BYTE_BIT)
{
/* When we reach EOF, that mens any read bit was just fillers from
the bb_flush function. We actually don't have any more data */
if (!(fread (&(buffer->bits), sizeof (byte), 1, buffer->fp)))
return NULL;
buffer->first_read = 1;
buffer->pos = 0;
}
shift_pos = BYTE_BIT - buffer->pos - 1;
bin[i] = (buffer->bits >> shift_pos) & 1;
(buffer->pos)++;
}
return bin;
}
#include <limits.h>
#define BYTE_BIT CHAR_BIT
typedef char byte;
typedef struct BIT_BUFFER
{
FILE *fp;
int pos;
byte bits;
int first_read;
} BIT_BUFFER;
void bb_init (struct BIT_BUFFER *buffer, FILE *fp);
void bb_flush (struct BIT_BUFFER *buffer);
void bb_write (struct BIT_BUFFER *buffer, int *bits, int size);
int *bb_read (struct BIT_BUFFER *buffer, int size);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment