# HG changeset patch # User Matti Hamalainen # Date 1560472126 -10800 # Node ID 1ea48084055eeb33eae4cd5b3eb4c269a4eb9785 # Parent 7694b5c8edc145d348d8f4662a1aa780f749ff94 Add functionality for separate palette file handling, reading, writing and probing similarly to image formats. For now, we only support ".ACT" palettes. diff -r 7694b5c8edc1 -r 1ea48084055e tools/libgfx.c --- a/tools/libgfx.c Fri Jun 14 03:27:50 2019 +0300 +++ b/tools/libgfx.c Fri Jun 14 03:28:46 2019 +0300 @@ -329,6 +329,65 @@ } +#define ACT_MAGIC_ID 0x0010ffff + + +static int fmtProbeACT(const Uint8 *buf, const size_t len) +{ + if (len == 0x304 && + DM_BE32_TO_NATIVE(*(Uint32 *) (buf + 0x300)) == ACT_MAGIC_ID) + return DM_PROBE_SCORE_MAX; + + return DM_PROBE_SCORE_FALSE; +} + + +int dmReadACTPalette(DMResource *fp, DMPalette **pdst) +{ + int res; + Uint32 magicID; + + if ((res = dmPaletteAlloc(pdst, 256, -1)) != DMERR_OK) + return res; + + if ((res = dmPaletteReadData(fp, *pdst, 256)) != DMERR_OK) + goto error; + + if (!dmf_read_be32(fp, &magicID)) + { + res = DMERR_FREAD; + goto error; + } + + if (magicID != ACT_MAGIC_ID) + { + res = DMERR_INVALID_DATA; + goto error; + } + + return res; + +error: + dmPaletteFree(*pdst); + *pdst = NULL; + return res; +} + + +int dmWriteACTPalette(DMResource *fp, const DMPalette *ppal) +{ + int res; + + if ((res = dmPaletteWriteData(fp, ppal, ppal->ncolors, 256)) != DMERR_OK) + return res; + + if (!dmf_write_be32(fp, ACT_MAGIC_ID)) + return DMERR_FWRITE; + + return DMERR_OK; +} + + int dmWriteImageData(const DMImage *img, void *cbdata, int (*writeRowCB)(void *, const Uint8 *, const size_t), const DMImageWriteSpec *spec) @@ -1273,7 +1332,7 @@ // // Z-Soft PCX format // -#define DMPCX_PAL_COLORS 16 // Number of internal palette colors +#define PCX_PAL_COLORS 16 // Number of internal palette colors typedef struct { @@ -1296,7 +1355,7 @@ Uint16 xmin, ymin, xmax, ymax; Uint16 hres, vres; // resolution in DPI, can be image dimensions as well. - DMPCXColor colorMap[DMPCX_PAL_COLORS]; + DMPCXColor colorMap[PCX_PAL_COLORS]; Uint8 reserved; // should be set to 0 Uint8 nplanes; // number of planes Uint16 bpl; // bytes per plane LINE @@ -1451,7 +1510,7 @@ if (spec.pixfmt == DM_PIXFMT_PALETTE || spec.pixfmt == DM_PIXFMT_GRAYSCALE) { - const int ncolors = img->pal->ncolors > DMPCX_PAL_COLORS ? DMPCX_PAL_COLORS : img->pal->ncolors; + const int ncolors = img->pal->ncolors > PCX_PAL_COLORS ? PCX_PAL_COLORS : img->pal->ncolors; for (int i = 0; i < ncolors; i++) { hdr.colorMap[i].r = img->pal->colors[i].r; @@ -1810,7 +1869,7 @@ if (!dmf_read_byte(fp, &tmpb) || tmpb != 0x0C) { read = FALSE; - ncolors = DMPCX_PAL_COLORS; + ncolors = PCX_PAL_COLORS; } else { @@ -1837,7 +1896,7 @@ } else { - const int nmax = img->pal->ncolors > DMPCX_PAL_COLORS ? DMPCX_PAL_COLORS : img->pal->ncolors; + const int nmax = img->pal->ncolors > PCX_PAL_COLORS ? PCX_PAL_COLORS : img->pal->ncolors; // If the extra palette is not available, copy the colors from // the header palette to our internal palette structure. @@ -2958,3 +3017,47 @@ else return DM_PROBE_SCORE_FALSE; } + + +// +// List of formats +// +const DMPaletteFormat dmPaletteFormatList[] = +{ + { + "act", "ACT Palette", + DM_PALFMT_ACT, DM_FMT_RDWR, + fmtProbeACT, dmReadACTPalette, dmWriteACTPalette, + }, +}; + +const int ndmPaletteFormatList = sizeof(dmPaletteFormatList) / sizeof(dmPaletteFormatList[0]); + + +int dmPaletteProbeGeneric(const Uint8 *buf, const size_t len, const DMPaletteFormat **pfmt, int *index) +{ + int scoreMax = DM_PROBE_SCORE_FALSE, scoreIndex = -1; + + for (int i = 0; i < ndmPaletteFormatList; i++) + { + const DMPaletteFormat *fmt = &dmPaletteFormatList[i]; + if (fmt->probe != NULL) + { + int score = fmt->probe(buf, len); + if (score > scoreMax) + { + scoreMax = score; + scoreIndex = i; + } + } + } + + if (scoreIndex >= 0) + { + *pfmt = &dmPaletteFormatList[scoreIndex]; + *index = scoreIndex; + return scoreMax; + } + else + return DM_PROBE_SCORE_FALSE; +} diff -r 7694b5c8edc1 -r 1ea48084055e tools/libgfx.h --- a/tools/libgfx.h Fri Jun 14 03:27:50 2019 +0300 +++ b/tools/libgfx.h Fri Jun 14 03:28:46 2019 +0300 @@ -17,6 +17,7 @@ #endif +// Image formats enum { DM_IMGFMT_PNG, @@ -31,6 +32,13 @@ }; +// Palette formats +enum +{ + DM_PALFMT_ACT, +}; + + // Color formats (these can be used along with DM_FMT_*) enum { @@ -124,8 +132,23 @@ } DMImageFormat; +typedef struct +{ + char *fext; // Typical filename extension + char *name; // Format name / description + int fmtid; // DM_PALFMT_* + int flags; // DM_FMT_* + + int (*probe)(const Uint8 *buf, const size_t len); + int (*read)(DMResource *fp, DMPalette **ppal); + int (*write)(DMResource *fp, const DMPalette *ppal); +} DMPaletteFormat; + + extern const DMImageFormat dmImageFormatList[]; extern const int ndmImageFormatList; +extern const DMPaletteFormat dmPaletteFormatList[]; +extern const int ndmPaletteFormatList; extern int dmGFXErrorMode; @@ -136,11 +159,16 @@ int dmImageProbeGeneric(const Uint8 *buf, const size_t len, const DMImageFormat **fmt, int *index); int dmGetNPlanesFromNColors(const int ncolors); -BOOL dmCompareColor(const DMColor *c1, const DMColor *c2, const BOOL alpha); -int dmPaletteAlloc(DMPalette **ppal, const int ncolors, const int ctransp); -int dmPaletteResize(DMPalette **ppal, const int ncolors); -void dmPaletteFree(DMPalette *pal); -int dmPaletteCopy(DMPalette **pdst, const DMPalette *src); +BOOL dmCompareColor(const DMColor *c1, const DMColor *c2, const BOOL alpha); +int dmPaletteAlloc(DMPalette **ppal, const int ncolors, const int ctransp); +int dmPaletteResize(DMPalette **ppal, const int ncolors); +void dmPaletteFree(DMPalette *pal); +int dmPaletteCopy(DMPalette **pdst, const DMPalette *src); +int dmPaletteProbeGeneric(const Uint8 *buf, const size_t len, const DMPaletteFormat **fmt, int *index); + + +int dmReadACTPalette(DMResource *fp, DMPalette **pdst); +int dmWriteACTPalette(DMResource *fp, const DMPalette *pdst); int dmWriteImageData(const DMImage *img, void *cbdata,