view tools/lib64util.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 cbac4912992c
children fa5e74384d87
line wrap: on
line source

/*
 * Common utility functions for gfxconv and 64vw
 * Programmed and designed by Matti 'ccr' Hamalainen
 * (C) Copyright 2019 Tecnic Software productions (TNSP)
 *
 * Please read file 'COPYING' for information on license and distribution.
 */
#include "lib64util.h"
#include "dmfile.h"


char * dmC64GetImageTypeString(char *buf, const size_t len, const int type, const BOOL lng)
{
    static const char *fmtModesShort[] = { "*", "HiR", "MC", "ECM" };
    static const char *fmtModesLong[] = { "*", "HiRes", "MultiColor", "Extended Color Mode" };
    const char *fmtStr;
    size_t nfmt = type & D64_FMT_MODE_MASK;

    if (nfmt < sizeof(fmtModesShort) / sizeof(fmtModesShort[0]))
        fmtStr = lng ? fmtModesLong[nfmt] : fmtModesShort[nfmt];
    else
        fmtStr = lng ? "ERROR" : "ERR";

    snprintf(buf, len,
        "%s %s%s%s",
        fmtStr,
        (type & D64_FMT_ILACE) ? (lng ? "Interlaced " : "ILace ") : "",
        (type & D64_FMT_FLI)   ? "FLI " : "",
        (type & D64_FMT_CHAR)  ? "CHAR" : ""
        );

    return buf;
}


void dmC64ImageDump(FILE *fh, const DMC64Image *img, const DMC64ImageFormat *fmt, const char *indent)
{
    char typeStr[64];

    if (fmt != NULL)
    {
        fprintf(fh,
            "%sFormat              : %s [%s]\n",
            indent, fmt->name, fmt->fext);
    }

    if (img != NULL)
    {
        dmC64GetImageTypeString(typeStr, sizeof(typeStr), img->fmt->type, TRUE);

        fprintf(fh,
            "%sType                : %s\n"
            "%sInternal blocks     : %d\n",
            indent, typeStr,
            indent, img->nblocks);

        if (img->fmt->type & D64_FMT_ILACE)
        {
            char *tmps;
            switch (img->laceType)
            {
                case D64_ILACE_COLOR: tmps = "color"; break;
                case D64_ILACE_RES: tmps = "resolution"; break;
                default: tmps = "ERROR"; break;
            }
            fprintf(fh,
                "%sInterlace type      : %s\n",
                indent, tmps);
        }

        fprintf(fh,
            "%sWidth x Height      : %d x %d\n"
            "%sCHwidth x CHheight  : %d x %d\n"
            "%sd020 / border       : %d ($%02x)\n"
            "%sd021 / background   : %d ($%02x)\n",
            indent, img->fmt->width, img->fmt->height,
            indent, img->fmt->chWidth, img->fmt->chHeight,
            indent, img->d020, img->d020,
            indent, img->bgcolor, img->bgcolor);
    }
    else
    if (fmt != NULL)
    {
        dmC64GetImageTypeString(typeStr, sizeof(typeStr), fmt->format->type, TRUE);
        fprintf(fh,
            "%sType                : %s\n"
            "%sWidth x Height      : %d x %d\n"
            "%sCHwidth x CHheight  : %d x %d\n",
            indent, typeStr,
            indent, fmt->format->width, fmt->format->height,
            indent, fmt->format->chWidth, fmt->format->chHeight);
    }
}


void argShowC64PaletteHelp()
{
    fprintf(stdout, "\nAvailable C64 palettes:\n");
    for (int n = 0; n < ndmC64DefaultPalettes; n++)
    {
        DMC64Palette *pal = &dmC64DefaultPalettes[n];
        fprintf(stdout,
            "%-10s | %s\n",
            pal->name, pal->desc);
    }
    fprintf(stdout, "\n");
}


BOOL argHandleC64PaletteOption(char *optArg, DMC64Palette **ppal, char **palFile)
{
    if (strcasecmp(optArg, "help") == 0 ||
        strcasecmp(optArg, "list") == 0)
    {
        argShowC64PaletteHelp();
        return FALSE;
    }

    for (int n = 0; n < ndmC64DefaultPalettes; n++)
    {
        DMC64Palette *pal = &dmC64DefaultPalettes[n];
        if (strcasecmp(pal->name, optArg) == 0)
        {
            *ppal = pal;
            return TRUE;
        }
    }

    *palFile = optArg;
    return TRUE;
}


int dmHandleExternalPalette(const char *filename, DMPalette **ppal)
{
    DMResource *fp = NULL;
    const DMImageFormat *ifmt = NULL;
    const DMPaletteFormat *pfmt = NULL;
    DMImage *inImage = NULL;
    Uint8 *dataBuf = NULL;
    size_t dataSize;
    int index, res;

    dmMsg(1, "Probing file '%s' for palette data.\n", filename);

    if ((res = dmReadDataFile(NULL, filename, &dataBuf, &dataSize)) != DMERR_OK)
    {
        dmErrorMsg("No such palette '%s', and no such file found (%s).\n",
            filename, dmErrorStr(res));
        goto done;
    }

    if ((res = dmf_open_memio(NULL, filename, dataBuf, dataSize, &fp)) != DMERR_OK)
    {
        dmErrorMsg("Could not create MemIO handle for input.\n");
        goto done;
    }

    if (dmImageProbeGeneric(dataBuf, dataSize, &ifmt, &index) > 0 &&
        ifmt->read != NULL)
    {
        dmMsg(1, "Probed image format %s (%s)\n",
            ifmt->name, ifmt->fext);

        res = ifmt->read(fp, &inImage);
        if (res != DMERR_OK)
        {
            dmErrorMsg("Could not read image file: %s\n",
                dmErrorStr(res));
            goto done;
        }

        res = dmPaletteCopy(ppal, inImage->pal);
    }
    else
    if (dmPaletteProbeGeneric(dataBuf, dataSize, &pfmt, &index) > 0 &&
        pfmt->read != NULL)
    {
        dmMsg(1, "Probed palette format %s (%s)\n",
            pfmt->name, pfmt->fext);

        res = pfmt->read(fp, ppal);
    }
    else
    {
        res = DMERR_NOT_SUPPORTED;
        dmErrorMsg("Not an internal palette or recognized palette file '%s'.\n",
            filename);
    }

done:
    dmf_close(fp);
    dmImageFree(inImage);
    dmFree(dataBuf);

    return res;
}