view src/dmfile.c @ 2208:90ec1ec89c56

Revamp the palette handling in lib64gfx somewhat, add helper functions to lib64util for handling external palette file options and add support for specifying one of the "internal" palettes or external (.act) palette file to gfxconv and 64vw.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 14 Jun 2019 05:01:12 +0300
parents ce3e56cfa9b9
children 5046458d6c34
line wrap: on
line source

/*
 * DMLib
 * -- Standard I/O (stdio) file write/read endianess helpers
 * Programmed and designed by Matti 'ccr' Hamalainen
 * (C) Copyright 2011 Tecnic Software productions (TNSP)
 */
#include "dmfile.h"


BOOL dm_fread_str(FILE *f, void *buf, const size_t len)
{
    return fread(buf, len, 1, f) == 1;
}


BOOL dm_fread_byte(FILE *f, Uint8 *val)
{
    int tmp = fgetc(f);
    *val = tmp;
    return tmp != EOF;
}


#define DM_DEFINE_FFUNC(xname, xtype, xmacro)         \
BOOL dm_fread_ ## xname (FILE *f, xtype *v) {         \
    xtype result;                                     \
    if (fread(&result, sizeof( xtype ), 1, f) != 1)   \
        return FALSE;                                 \
    *v = DM_ ## xmacro ## _TO_NATIVE (result);        \
    return TRUE;                                      \
}

#include "dmfiletmpl.h"

#undef DM_DEFINE_FFUNC


BOOL dm_fwrite_str(FILE *f, const void *buf, const size_t len)
{
    return fwrite(buf, len, 1, f) == 1;
}


BOOL dm_fwrite_byte(FILE *f, const Uint8 val)
{
    return fputc(val, f) == val;
}


#define DM_DEFINE_FFUNC(xname, xtype, xmacro)         \
BOOL dm_fwrite_ ## xname (FILE *f, const xtype v) {   \
    xtype result = DM_NATIVE_TO_ ## xmacro (v);       \
    return fwrite(&result, sizeof( xtype ), 1, f) == 1;  \
}

#include "dmfiletmpl.h"

#undef DM_DEFINE_FFUNC


int dmWriteDataFile(FILE *fh, const char *filename, const Uint8 *buf, const size_t bufSize)
{
    int res = DMERR_OK;

    if (fh == NULL && filename != NULL &&
        (fh = fopen(filename, "wb")) == NULL)
    {
        res = dmGetErrno();
        return dmError(res,
            "Could not open '%s' for writing: %s.\n",
            filename, dmErrorStr(res));
    }

    if (fh == NULL)
    {
        res = dmError(DMERR_NULLPTR,
            "NULL filename and stream pointers.\n");
        goto error;
    }

    if (fwrite(buf, 1, bufSize, fh) != bufSize)
    {
        res = dmGetErrno();
        dmError(res,
            "Error writing data to '%s': %s\n",
            filename, dmErrorStr(res));
    }

error:
    if (fh != NULL)
        fclose(fh);

    return res;
}


#define BUF_SIZE_INITIAL   (16*1024)
#define BUF_SIZE_GROW      (4*1024)

int dmReadDataFile(FILE *ffh, const char *filename, Uint8 **pbuf, size_t *pbufSize)
{
    FILE *fh = NULL;
    int res = DMERR_OK;
    Uint8 *dataBuf = NULL;
    size_t readSize, dataSize, dataRead, dataPos;

    if (ffh != NULL)
        fh = ffh;
    else
    if (filename != NULL)
    {
        if ((fh = fopen(filename, "rb")) == NULL)
        {
            return dmError(DMERR_FOPEN,
                "Could not open '%s' for reading.\n", filename);
        }
    }

    if (fh == NULL)
    {
        return dmError(DMERR_NULLPTR,
            "NULL filename and stream pointers.\n");
    }

    // Allocate initial data buffer
    readSize = dataSize = BUF_SIZE_INITIAL;
    if ((dataBuf = dmMalloc(dataSize)) == NULL)
    {
        res = dmError(DMERR_MALLOC,
            "Error allocating memory for data, %d bytes.\n", dataSize);
        goto error;
    }

    // Read the data
    dataPos = dataRead = 0;
    while (!feof(fh) && !ferror(fh))
    {
        size_t read = fread(dataBuf + dataPos, 1, readSize, fh);
        dataPos += read;
        dataRead += read;

        if (dataRead >= dataSize)
        {
            readSize = BUF_SIZE_GROW;
            dataSize += BUF_SIZE_GROW;
            if ((dataBuf = dmRealloc(dataBuf, dataSize)) == NULL)
            {
                res = dmError(DMERR_MALLOC,
                    "Error reallocating memory for data, %d bytes.\n",
                    dataSize);
                goto error;
            }
        }
        else
            break;
    }

    *pbufSize = dataRead;
    *pbuf = dataBuf;

error:
    if (ffh != fh)
        fclose(fh);

    return res;
}