Logo Search packages:      
Sourcecode: yiff version File versions  Download package

raw.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "raw.h"


static void RawReportError(
      const char *filename, const char *reason, int how_bad
);
static FILE *RawOpenFile(
      const char *filename, const char *mode, off_t *size_rtn
);

int RawIsFileRaw(const char *filename);

int RawReadHeader(const char *filename, FILE *fp, raw_data_struct *rd);
int RawReadPartialData(
      raw_data_struct *rd,
      long offset,
      long max_chunk_size,
      int read_opt
);


#define MIN(a,b)        ((a) < (b) ? (a) : (b))
#define MAX(a,b)        ((a) > (b) ? (a) : (b))
#define CLIP(a,l,h)     (MIN(MAX((a),(l)),(h)))
#define ABSOLUTE(x)     (((x) < 0) ? ((x) * -1) : (x))


static void RawReportError(
      const char *filename, const char *reason, int how_bad
)
{
      if(filename != NULL)
          fprintf(stderr, "%s: ", filename);
      if(reason != NULL)
          fprintf(stderr, "%s (Error level %i)", reason, how_bad);

      fprintf(stderr, "\n");

      return;
}


void RawDestroyData(raw_data_struct *rd)
{
      if(rd == NULL)
          return;

      free(rd->filename);
      rd->filename = NULL;

      if(rd->fp != NULL)
      {
          fclose(rd->fp);
          rd->fp = NULL;
      }

      rd->data_offset = 0;
      rd->data_length = 0;

      rd->block_align = 0;
      rd->sample_size = 0;
      rd->channels = 0;
      rd->sample_rate = 0;

      free(rd->data);
      rd->data = NULL;

      rd->data_len = 0;

      return;
}


static FILE *RawOpenFile(
      const char *filename, const char *mode, off_t *size_rtn
)
{
      FILE *fp;
      struct stat stat_buf;


      if(filename == NULL)
      {
          fprintf(stderr, "Cannot open file with no name.\n");
          *size_rtn = 0;
          return(NULL);
      }
      if(mode == NULL)
      {
          fprintf(stderr, "%s: Open mode not givin.\n", filename);
          *size_rtn = 0;
          return(NULL);
      }

      if(stat(filename, &stat_buf))
      {
          fprintf(stderr, "%s: No such file.\n", filename);
          *size_rtn = 0;
          return(NULL);
      }
      *size_rtn = stat_buf.st_size;

      fp = fopen(filename, mode);
      if(fp == NULL)
      {
          fprintf(stderr, "%s: Cannot open.\n", filename);
          *size_rtn = 0;
          return(NULL);
      }

      return(fp);
}


int RawIsFileRaw(const char *filename)
{
      FILE *fp;
      off_t filesize;


      /* Open file. */
      fp = RawOpenFile(filename, "rb", &filesize);
      if(fp == NULL)
          return(RawErrorNoAccess);
      if(filesize == 0)
          return(RawErrorNoAccess);

/* What do we check? */

      /* Close file. */
      fclose(fp);

      return(RawSuccess); 
}

/*
 *      Reads the header from the stream fp and initializes the given
 *      rd structure if fp is valid and a raw file.
 *
 *      The given filename is used only for referance purposes, it can be
 *      NULL.
 *
 *      If RawSuccess is returned then the given fp will be transfered
 *      to the rd structure and should not be referanced again. For all
 *      other return values, the calling function is responsible for
 *      closing the given fp.
 */
int RawReadHeader(const char *filename, FILE *fp, raw_data_struct *rd)
{
      off_t filesize;
      struct stat stat_buf;


      /* Error checks. */
      if(rd == NULL)
          return(RawErrorNoBuffers);
      if(fp == NULL)
          return(RawErrorBadValue);

      /* Rewind to beginning of raw file. */
      rewind(fp);


      /* Reset values. */
      memset(rd, 0x00, sizeof(raw_data_struct));

      /* Get size of file. */
      if(fstat(fileno(fp), &stat_buf))
          return(RawErrorNoAccess);

      filesize = stat_buf.st_size;
      if(filesize == 0)
          return(RawErrorNoAccess);


      /* Here we should be checking if this is a raw file, but there
       * really is no way to tell so just assume that it is a raw
       * file.
       */

      /* Begin reading raw file header. */

      /* Record file name. */
      if(filename != NULL)
          rd->filename = strdup(filename);

/* Check for offset? */
      /* Get offset. */
      rd->data_offset = 0;

      /* Get length of data. */
      rd->data_length = (long)filesize - (long)rd->data_offset;
      if(rd->data_length < 0)
          rd->data_length = 0;

      /* Standard values. */
      rd->block_align = 0;
      rd->sample_size = 8;
      rd->channels = 1;
      rd->sample_rate = 8000;

      /* Transfer given fp to the rd structure, the calling
       * function should not referance it again since we are returning
       * RawSuccess.
       */
      rd->fp = fp;

      return(RawSuccess);
}

/*
 *      Reads a segment of data from the raw file reffered to
 *      by the filename member on the given wd structure (which
 *      should have been initialized wuth a prior call to
 *      RawReadHeader().
 *
 *      File will be opened as needed if the fp member is NULL.
 *
 *      The member data and data_len will be reallocated as needed
 *      if the requested max_chunk_size is different than data_len.
 */
int RawReadPartialData(
      raw_data_struct *rd,
      long offset,            /* In bytes. */
      long max_chunk_size,    /* In bytes. */
      int read_opt
)
{
      int i;
      char *buf_ptr;


      if(rd == NULL)
          return(RawErrorNoBuffers);
      if(offset < 0)
          return(RawErrorBadValue);

      /* Read nothing? */
      if(max_chunk_size <= 0)
      {
          free(rd->data);
          rd->data = NULL;
          rd->data_len = 0;

          return(RawSuccess);
      }

      /* Sanitize values. */
      if(offset >= rd->data_length)
      {
          return(RawErrorEndOfData);
      }
      if((offset + max_chunk_size) > rd->data_length)
      {
          max_chunk_size = rd->data_length - offset;
      }
      if(max_chunk_size <= 0)
      {
          return(RawErrorEndOfData);
      }


      /* Open file as needed. */
      if(rd->fp == NULL)
      {   
          off_t filesize;

          if(rd->filename == NULL)
            return(RawErrorBadValue);
       
          rd->fp = RawOpenFile(rd->filename, "rb", &filesize);
          if(rd->fp == NULL)
            return(RawErrorNoAccess);
          if(filesize == 0)
            return(RawErrorNoAccess);
      }


      /* Reallocate buffer for data (as needed). */
      if(rd->data_len != max_chunk_size)
      {
          rd->data_len = max_chunk_size;

          rd->data = (char *)realloc(
            rd->data,
            rd->data_len * sizeof(char)
          );
      }
      if(rd->data == NULL)
      {
          rd->data_len = 0;

          fclose(rd->fp);
          rd->fp = NULL;

          return(RawErrorNoBuffers);
      }

      /* Position file pointer. */
      fseek(rd->fp, rd->data_offset + offset, SEEK_SET);

      /* Read the data, raw file format stores DSP as signed 8. */
      buf_ptr = rd->data;
      switch(read_opt)
      {
        /* Shift byte value by + 128. */
        case RawReadUnsigned8:
          for(i = 0; i < max_chunk_size; i++)
            *buf_ptr++ = (char)(fgetc(rd->fp) + 128);
          break;

        /* Get data as is (signed 8). */
        default:
          for(i = 0; i < max_chunk_size; i++)
            *buf_ptr++ = (char)fgetc(rd->fp);
          break;
      }

      return(RawSuccess);
}

Generated by  Doxygen 1.6.0   Back to index