Skip to content

Instantly share code, notes, and snippets.

@quirinpa
Last active April 9, 2016 22:07

Revisions

  1. quirinpa revised this gist Apr 9, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion fileb.h
    Original file line number Diff line number Diff line change
    @@ -65,7 +65,7 @@ void fwriteb(void *restrict ptr, size_t sizeb, size_t rSizeb, FILE *fp, bitCurso
    firstRelevantByte = firstRelevantBit / 8,
    distanceToStartOfByte = firstRelevantBit - firstRelevantByte * 8;

    unsigned char *pchar = (unsigned char*)ptr + firstRelevantByte;
    unsigned char *pchar = (unsigned char*)ptr + firstRelevantByte; // Assuming little Endian

    size_t bitsToWrite = sizeb,
    bitsToAdd;
  2. quirinpa revised this gist Mar 30, 2016. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions fileb.h
    Original file line number Diff line number Diff line change
    @@ -106,7 +106,7 @@ void fcloseb(FILE *fp, bitCursor *c) {
    fwrite(&curData, 1, 1, fp);
    }

    /* Reads a number of bits from a file
    /* Reads a number of bits from a file (it is your responsibility to init the var as 0)
    *
    * @param ptr a pointer to the variable in which to write data that is read
    * @param sizeb the number of bits to be read
    @@ -121,7 +121,6 @@ void freadb(void *restrict ptr, size_t sizeb, size_t rSizeb, FILE *fp, bitCursor
    distanceToStartOfByte = firstRelevantBit - firstRelevantByte*8;

    unsigned char *pchar = (unsigned char*)ptr + firstRelevantByte;
    *pchar = 0;

    size_t bitsToRead = sizeb,
    bitsToAdd,
  3. quirinpa created this gist Mar 27, 2016.
    154 changes: 154 additions & 0 deletions fileb.h
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,154 @@
    /* fileb.h - write/read files bit by bit
    *
    * MIT License
    *
    * Copyright (c) 2016 Paulo André Azevedo Quirino
    *
    * Permission is hereby granted, free of charge, to any person obtaining a copy
    * of this software and associated documentation files (the "Software"), to deal
    * in the Software without restriction, including without limitation the rights
    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    * copies of the Software, and to permit persons to whom the Software is
    * furnished to do so, subject to the following conditions:
    *
    * The above copyright notice and this permission notice shall be included in all
    * copies or substantial portions of the Software.
    *
    * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    * SOFTWARE.
    *
    * quirinpa@gmail.com
    */

    #ifndef FILEB_H
    #define FILEB_H

    #include <stdio.h>

    typedef struct bCursor {
    unsigned char d;
    size_t s;
    } bitCursor;

    /* creates a new bitCursor object with default values
    * (needed for starting bit-wise read/write operations,
    * a pointer to that same cursor must then be provided
    * to subsequent read/write operations until all data is
    * read/written)
    *
    * @returns cursor with default values
    */
    bitCursor newBitCursor() {
    bitCursor c = {0, 0};
    return c;
    }

    #define curBusySpace c->s
    #define curData c->d

    /* Writes a number of bits into a file
    *
    * @param ptr a pointer to the variable containing the data to be written
    * @param sizeb the number of bits to be written
    * @param rSizeb the real size of the variable in bits
    * @param fp a pointer to the file
    * @param c a pointer to a bitCursor (possibly containing bits from the last variable written)
    */
    void fwriteb(void *restrict ptr, size_t sizeb, size_t rSizeb, FILE *fp, bitCursor *c) {

    size_t firstRelevantBit = rSizeb - sizeb,
    firstRelevantByte = firstRelevantBit / 8,
    distanceToStartOfByte = firstRelevantBit - firstRelevantByte * 8;

    unsigned char *pchar = (unsigned char*)ptr + firstRelevantByte;

    size_t bitsToWrite = sizeb,
    bitsToAdd;

    readywrite:
    bitsToAdd = 8 - (curBusySpace > distanceToStartOfByte ? curBusySpace : distanceToStartOfByte);

    curData |= (*pchar << distanceToStartOfByte) >> curBusySpace;

    curBusySpace += bitsToAdd;
    if (curBusySpace >= 8) {
    fwrite(&curData, 1, 1, fp);
    curBusySpace = curData = 0;
    }

    bitsToWrite -= bitsToAdd;
    if (bitsToWrite <= 0) return;

    distanceToStartOfByte += bitsToAdd;

    if (distanceToStartOfByte >= 8) {
    distanceToStartOfByte = 0;
    pchar++;
    }

    goto readywrite;
    }


    /* Writes the remaining bits after a sequence of fwriteb operations
    * (required for correct behaviour)
    *
    * @param fp a pointer to the file
    * @param c a pointer to a bitCursor (possibly containing bits from the last variable written)
    */
    void fcloseb(FILE *fp, bitCursor *c) {
    if (curBusySpace <= 0) return;
    fwrite(&curData, 1, 1, fp);
    }

    /* Reads a number of bits from a file
    *
    * @param ptr a pointer to the variable in which to write data that is read
    * @param sizeb the number of bits to be read
    * @param rSizeb the real size of the variable in bits
    * @param fp a pointer to the file
    * @param c a pointer to a bitCursor (possibly containing bits from the last read Byte)
    */
    void freadb(void *restrict ptr, size_t sizeb, size_t rSizeb, FILE *fp, bitCursor *c) {

    size_t firstRelevantBit = rSizeb - sizeb,
    firstRelevantByte = firstRelevantBit / 8,
    distanceToStartOfByte = firstRelevantBit - firstRelevantByte*8;

    unsigned char *pchar = (unsigned char*)ptr + firstRelevantByte;
    *pchar = 0;

    size_t bitsToRead = sizeb,
    bitsToAdd,
    availableBits = 8 - distanceToStartOfByte;

    readyread:
    if (curBusySpace <= 0) {
    fread(&curData, 1, 1, fp);
    curBusySpace = 8;
    }

    bitsToAdd = curBusySpace > availableBits ? availableBits : curBusySpace;
    (*pchar) |= curData >> distanceToStartOfByte;

    curData <<= bitsToAdd;
    curBusySpace -= bitsToAdd;
    bitsToRead -= bitsToAdd;
    if (bitsToRead <= 0) return;

    distanceToStartOfByte += bitsToAdd;
    if (distanceToStartOfByte >= 8) {
    distanceToStartOfByte = 0;
    pchar++;
    }
    availableBits = 8 - distanceToStartOfByte;

    goto readyread;
    }

    #endif