⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bit-io.c

📁 linux下将各类格式图片转换工具
💻 C
字号:
/* *  bit-io.c:       Buffered and bit oriented file I/O  * *  Written by:     Ullrich Hafner *   *  This file is part of FIASCO (獸籸actal 獻籱age 獳籲d 玈籩quence 獵O籨ec) *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> */ /* *  $Date: 2000/06/14 20:49:37 $ *  $Author: hafner $ *  $Revision: 5.1 $ *  $State: Exp $ */#define _BSD_SOURCE 1   /* Make sure strdup() is in string.h */#define _XOPEN_SOURCE 500  /* Make sure strdup() is in string.h */#include "config.h"#include <string.h>#if STDC_HEADERS#   include <stdlib.h>#endif /* not STDC_HEADERS */#include "macros.h"#include "types.h"#include "error.h"#include "misc.h"#include "bit-io.h"/*****************************************************************************                 local constants  *****************************************************************************/static const unsigned BUFFER_SIZE = 16350;static const unsigned mask[] = {0x0001, 0x0002, 0x0004, 0x0008,                                0x0010, 0x0020, 0x0040, 0x0080,                                0x0100, 0x0200, 0x0400, 0x0800,                                0x1000, 0x2000, 0x4000, 0x8000};/*****************************************************************************                public code  *****************************************************************************/FILE *open_file (const char *filename, const char *env_var, openmode_e mode)/* *  Try to open file 'filename' with mode 'mode' (READ_ACCESS, WRITE_ACCESS). *  Scan the current directory first and then cycle through the *  path given in the environment variable 'env_var', if set. *  *  Return value: *  Pointer to open file on success, else NULL. */{    char       *path;        /* current path */    FILE       *fp;      /* file pointer of I/O stream */    char       *ext_filename = NULL; /* full path of file */    char       *env_path     = NULL; /* path given by 'env_var' */    char const * const PATH_SEP     = " ;:,"; /* path separation characters */    char const * const DEFAULT_PATH = "."; /* default for output files */    const char * const read_mode  = "rb";    const char * const write_mode = "wb";    assert (mode == READ_ACCESS || mode == WRITE_ACCESS);    /*     *  First check for stdin or stdout     */    if (filename == NULL || streq (filename, "-"))    {        if (mode == READ_ACCESS)            return stdin;        else             return stdout;    }       /*     *  Try to open 'readonly' file in the current directory     */    if (mode == READ_ACCESS && (fp = fopen (filename, read_mode)))        return fp;     if (mode == WRITE_ACCESS && strchr (filename, '/')) /* contains path */        return fopen (filename, write_mode);       /*     *  Get value of environment variable 'env_var', if set     *  else use DEFAULT_PATH ("./")     */    if (env_var != NULL)        env_path = getenv (env_var);    if (env_path == NULL)         env_path = strdup (DEFAULT_PATH);    else        env_path = strdup (env_path);       /*     *  Try to open file in the directory given by the environment     *  variable env_var - individual path components are separated by PATH_SEP      */    path = strtok (env_path, PATH_SEP);    do     {        if (ext_filename)             Free (ext_filename);        ext_filename =  Calloc (strlen (path) + strlen (filename) + 2,                                sizeof (char));        strcpy (ext_filename, path);         if (*(ext_filename + strlen (ext_filename) - 1) != '/')            strcat (ext_filename, "/");        strcat (ext_filename, filename);        fp = fopen (ext_filename, mode == READ_ACCESS ? read_mode : write_mode);    }    while (fp == NULL && (path = strtok (NULL, PATH_SEP)) != NULL);    Free (env_path);       return fp;}bitfile_t *open_bitfile (const char *filename, const char *env_var, openmode_e mode)/* *  Bitfile constructor: *  Try to open file 'filename' for buffered bit oriented access with mode *  'mode'. Scan the current directory first and then cycle through the path *  given in the environment variable 'env_var', if set. * *  Return value: *  Pointer to open bitfile on success, *      otherwise the program is terminated. */{    bitfile_t *bitfile = Calloc (1, sizeof (bitfile_t));       bitfile->file = open_file (filename, env_var, mode);    if (bitfile->file == NULL)        file_error (filename);    if (mode == READ_ACCESS)    {        bitfile->bytepos  = 0;        bitfile->bitpos   = 0;        bitfile->mode     = mode;        bitfile->filename = filename ? strdup (filename) : strdup ("(stdin)");    }    else if (mode == WRITE_ACCESS)    {        bitfile->bytepos  = BUFFER_SIZE - 1;        bitfile->bitpos   = 8;        bitfile->mode     = mode;        bitfile->filename = filename ? strdup (filename) : strdup ("(stdout)");    }    else        error ("Unknow file access mode '%d'.", mode);       bitfile->bits_processed = 0;    bitfile->buffer         = Calloc (BUFFER_SIZE, sizeof (byte_t));    bitfile->ptr            = bitfile->buffer;    return bitfile;}bool_tget_bit (bitfile_t *bitfile)/* *  Get one bit from the given stream 'bitfile'. * *  Return value: *   1  H bit *   0  L bit * *  Side effects: *  Buffer of 'bitfile' is modified accordingly. */{    assert (bitfile);       if (!bitfile->bitpos--)      /* use next byte ? */    {        bitfile->ptr++;        if (!bitfile->bytepos--)      /* no more bytes left in the buffer? */        {            /*             *  Fill buffer with new data             */            int bytes = fread (bitfile->buffer, sizeof (byte_t),                               BUFFER_SIZE, bitfile->file) - 1;            if (bytes < 0)         /* Error or EOF */                error ("Can't read next bit from bitfile %s.", bitfile->filename);            else                bitfile->bytepos = bytes;            bitfile->ptr = bitfile->buffer;        }        bitfile->bitpos = 7;    }    bitfile->bits_processed++;    return *bitfile->ptr & mask [bitfile->bitpos] ? 1 : 0;}unsigned intget_bits (bitfile_t *bitfile, unsigned bits)/* *  Get #'bits' bits from the given stream 'bitfile'. * *  Return value: *  composed integer value * *  Side effects: *  Buffer of 'bitfile' is modified. */{    unsigned value = 0;          /* input value */       while (bits--)        value = (unsigned) (value << 1) | get_bit (bitfile);    return value;}voidput_bit (bitfile_t *bitfile, unsigned value)/*      *  Put the bit 'value' to the bitfile buffer. *  The buffer is written to the file 'bitfile->file' if the number of *  buffer bytes exceeds 'BUFFER_SIZE'. * *  No return value. * *  Side effects: *  Buffer of 'bitfile' is modified. */{    assert (bitfile);       if (!bitfile->bitpos--)      /* use next byte ? */    {        bitfile->ptr++;        if (!bitfile->bytepos--)      /* no more bytes left ? */        {            /*             *  Write buffer to disk and fill buffer with zeros             */            if (fwrite (bitfile->buffer, sizeof (byte_t),                        BUFFER_SIZE, bitfile->file) != BUFFER_SIZE)                error ("Can't write next bit of bitfile %s!", bitfile->filename);            memset (bitfile->buffer, 0, BUFFER_SIZE);            bitfile->bytepos = BUFFER_SIZE - 1;            bitfile->ptr     = bitfile->buffer;        }        bitfile->bitpos = 7;    }       if (value)        *bitfile->ptr |= mask [bitfile->bitpos];    bitfile->bits_processed++;}voidput_bits (bitfile_t *bitfile, unsigned value, unsigned bits)/*      *  Put #'bits' bits of integer 'value' to the bitfile buffer 'bitfile'. * *  No return value. * *  Side effects: *  Buffer of 'bitfile' is modified. */{    while (bits--)        put_bit (bitfile, value & mask [bits]);}voidclose_bitfile (bitfile_t *bitfile)/* *  Bitfile destructor: *  Close 'bitfile', if 'bitfile->mode' == WRITE_ACCESS write bit buffer *  to disk.  * *  No return value. * *  Side effects: *  Structure 'bitfile' is discarded. */{    assert (bitfile);       if (bitfile->mode == WRITE_ACCESS)    {        unsigned bytes = fwrite (bitfile->buffer, sizeof (byte_t),                                 BUFFER_SIZE - bitfile->bytepos, bitfile->file);        if (bytes != BUFFER_SIZE - bitfile->bytepos)            error ("Can't write remaining %d bytes of bitfile "                   "(only %d bytes written)!",                   BUFFER_SIZE - bitfile->bytepos, bytes);    }    fclose (bitfile->file);    Free (bitfile->buffer);    Free (bitfile->filename);    Free (bitfile);}unsignedbits_processed (const bitfile_t *bitfile)/* *  Return value: *  Number of bits processed up to now */{    return bitfile->bits_processed;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -