Defines | Functions

cbf_uncompressed.c File Reference

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include "cbf.h"
#include "cbf_alloc.h"
#include "cbf_compress.h"
#include "cbf_file.h"
#include "cbf_uncompressed.h"
Include dependency graph for cbf_uncompressed.c:

Go to the source code of this file.

Defines

#define CBF_SHIFT63   (sizeof (int) * CHAR_BIT > 64 ? 63 : 0)

Functions

int cbf_compress_none (void *source, size_t elsize, int elsign, size_t nelem, unsigned int compression, cbf_file *file, size_t *compressedsize, int *storedbits)
int cbf_decompress_none (void *destination, size_t elsize, int elsign, size_t nelem, size_t *nelem_read, unsigned int compression, int data_bits, int data_sign, cbf_file *file)

Define Documentation

#define CBF_SHIFT63   (sizeof (int) * CHAR_BIT > 64 ? 63 : 0)

Definition at line 135 of file cbf_uncompressed.c.

Referenced by cbf_compress_none().


Function Documentation

int cbf_compress_none ( void *  source,
size_t  elsize,
int  elsign,
size_t  nelem,
unsigned int  compression,
cbf_file file,
size_t *  compressedsize,
int *  storedbits 
)

Definition at line 140 of file cbf_uncompressed.c.

References bits(), CBF_ARGUMENT, cbf_failnez, cbf_put_integer(), and CBF_SHIFT63.

Referenced by cbf_compress().

{
  unsigned int count, element, unsign, sign, limit, bits;

  unsigned char *unsigned_char_data;
  

    /* Is the element size valid? */
    
  if (elsize != sizeof (int) &&
      elsize != sizeof (short) &&
      elsize != sizeof (char))

    return CBF_ARGUMENT;


    /* Initialise the pointer */

  unsigned_char_data = (unsigned char *) source;


    /* Maximum limit (unsigned) is 64 bits */

  if (elsize * CHAR_BIT > 64)
  {
    sign = 1 << CBF_SHIFT63;

    limit = ~-(sign << 1);
    
    bits = 64;
  }
  else
  {
    sign = 1 << (elsize * CHAR_BIT - 1);

    limit = ~0;

    bits = elsize * CHAR_BIT;
  }

  if (storedbits)
    
    *storedbits = bits;


    /* Offset to make the value unsigned */

  if (elsign)

    unsign = sign;

  else

    unsign = 0;


    /* Initialise the pointer */
    
  unsigned_char_data = (unsigned char *) source;


    /* Write the elements */
    
  for (count = 0; count < nelem; count++)
  {
      /* Get the next element */
      
    if (elsize == sizeof (int))
    
      element = *((unsigned int *) unsigned_char_data);
      
    else
    
      if (elsize == sizeof (short))
      
        element = *((unsigned short *) unsigned_char_data);
        
      else
      
        element = *unsigned_char_data;
        
    unsigned_char_data += elsize;


      /* Make the element unsigned */

    element += unsign;


      /* Limit the value to 64 bits */

    if (element > limit)

      if (elsign && (int) (element - unsign) < 0)

        element = 0;

      else

        element = limit;
        

      /* Write the element to the file */

    cbf_failnez (cbf_put_integer (file, element - unsign, 0, bits))
  }


    /* Return the number of characters written */
    
  if (compressedsize)
  
    *compressedsize = (nelem * bits + 7) / 8;


    /* Success */

  return 0;
}
int cbf_decompress_none ( void *  destination,
size_t  elsize,
int  elsign,
size_t  nelem,
size_t *  nelem_read,
unsigned int  compression,
int  data_bits,
int  data_sign,
cbf_file file 
)

Definition at line 270 of file cbf_uncompressed.c.

References bit, CBF_ARGUMENT, CBF_FORMAT, cbf_get_integer(), and CBF_OVERFLOW.

Referenced by cbf_decompress().

{
  unsigned int element, sign, unsign, limit, count, bit;

  unsigned int data_unsign;

  unsigned char *unsigned_char_data;

  int errorcode, overflow;


    /* Is the element size valid? */
    
  if (elsize != sizeof (int) &&
      elsize != sizeof (short) &&
      elsize != sizeof (char))

    return CBF_ARGUMENT;
    
    
    /* Check the stored element size */
    
  if (data_bits < 1 || data_bits > 64)
  
    return CBF_ARGUMENT;


    /* Initialise the pointer */

  unsigned_char_data = (unsigned char *) destination;


    /* Maximum limits */
    
  sign = 1 << (elsize * CHAR_BIT - 1);
    
  if (elsize == sizeof (int))
    
    limit = ~0;
      
  else
    
    limit = ~-(1 << (elsize * CHAR_BIT));


    /* Check the element size */
    
  if (data_bits < 1 || data_bits > 64)
  
    return CBF_FORMAT;
  

    /* Offsets to make the value unsigned */

  if (data_sign)

    data_unsign = sign;

  else

    data_unsign = 0;

  if (elsign)

    unsign = sign;

  else

    unsign = 0;


    /* Read the elements */

  count = 0;

  overflow = 0;

  while (count < nelem)
  {
      /* Get the next element */

    errorcode = cbf_get_integer (file, (int *) &element, 
                                                data_sign, data_bits);

    if (errorcode)

      if (errorcode == CBF_OVERFLOW)

        overflow = errorcode;

      else
      {
        if (nelem_read)
      
          *nelem_read = count;
        
        return errorcode | overflow;
      }


      /* Make the element unsigned */

    element += data_unsign;


      /* Limit the value to fit the element size */

    if (element > limit)
    {
      if (elsign && (int) (element - unsign) < 0)
      
        element = 0;
        
      else
      
        element = limit;

      overflow = CBF_OVERFLOW;
    }
        
        
      /* Make the element signed? */
        
    element -= unsign;


      /* Save the element */
        
    if (elsize == sizeof (int))
      
      *((unsigned int *) unsigned_char_data) = element;
        
    else
      
      if (elsize == sizeof (short))
        
        *((unsigned short *) unsigned_char_data) = element;
          
      else
        
        *unsigned_char_data = element;
          
    unsigned_char_data += elsize;
    
    count++;
  }


    /* Number read */
    
  if (nelem_read)
  
    *nelem_read = count;


    /* Success */

  return overflow;
}