comparison tools/libgfx.c @ 2207:1ea48084055e

Add functionality for separate palette file handling, reading, writing and probing similarly to image formats. For now, we only support ".ACT" palettes.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 14 Jun 2019 03:28:46 +0300
parents 455a3849b8ac
children 90ec1ec89c56
comparison
equal deleted inserted replaced
2206:7694b5c8edc1 2207:1ea48084055e
322 if (!dmf_write_byte(fp, 0) || 322 if (!dmf_write_byte(fp, 0) ||
323 !dmf_write_byte(fp, 0) || 323 !dmf_write_byte(fp, 0) ||
324 !dmf_write_byte(fp, 0)) 324 !dmf_write_byte(fp, 0))
325 return DMERR_FWRITE; 325 return DMERR_FWRITE;
326 } 326 }
327
328 return DMERR_OK;
329 }
330
331
332 #define ACT_MAGIC_ID 0x0010ffff
333
334
335 static int fmtProbeACT(const Uint8 *buf, const size_t len)
336 {
337 if (len == 0x304 &&
338 DM_BE32_TO_NATIVE(*(Uint32 *) (buf + 0x300)) == ACT_MAGIC_ID)
339 return DM_PROBE_SCORE_MAX;
340
341 return DM_PROBE_SCORE_FALSE;
342 }
343
344
345 int dmReadACTPalette(DMResource *fp, DMPalette **pdst)
346 {
347 int res;
348 Uint32 magicID;
349
350 if ((res = dmPaletteAlloc(pdst, 256, -1)) != DMERR_OK)
351 return res;
352
353 if ((res = dmPaletteReadData(fp, *pdst, 256)) != DMERR_OK)
354 goto error;
355
356 if (!dmf_read_be32(fp, &magicID))
357 {
358 res = DMERR_FREAD;
359 goto error;
360 }
361
362 if (magicID != ACT_MAGIC_ID)
363 {
364 res = DMERR_INVALID_DATA;
365 goto error;
366 }
367
368 return res;
369
370 error:
371 dmPaletteFree(*pdst);
372 *pdst = NULL;
373 return res;
374 }
375
376
377 int dmWriteACTPalette(DMResource *fp, const DMPalette *ppal)
378 {
379 int res;
380
381 if ((res = dmPaletteWriteData(fp, ppal, ppal->ncolors, 256)) != DMERR_OK)
382 return res;
383
384 if (!dmf_write_be32(fp, ACT_MAGIC_ID))
385 return DMERR_FWRITE;
327 386
328 return DMERR_OK; 387 return DMERR_OK;
329 } 388 }
330 389
331 390
1271 1330
1272 1331
1273 // 1332 //
1274 // Z-Soft PCX format 1333 // Z-Soft PCX format
1275 // 1334 //
1276 #define DMPCX_PAL_COLORS 16 // Number of internal palette colors 1335 #define PCX_PAL_COLORS 16 // Number of internal palette colors
1277 1336
1278 typedef struct 1337 typedef struct
1279 { 1338 {
1280 Uint8 r,g,b; 1339 Uint8 r,g,b;
1281 } DMPCXColor; 1340 } DMPCXColor;
1294 encoding, // usually 0x01 = RLE, 0x00 = uncompressed 1353 encoding, // usually 0x01 = RLE, 0x00 = uncompressed
1295 bitsPerPlane; // bits per pixel per plane 1354 bitsPerPlane; // bits per pixel per plane
1296 1355
1297 Uint16 xmin, ymin, xmax, ymax; 1356 Uint16 xmin, ymin, xmax, ymax;
1298 Uint16 hres, vres; // resolution in DPI, can be image dimensions as well. 1357 Uint16 hres, vres; // resolution in DPI, can be image dimensions as well.
1299 DMPCXColor colorMap[DMPCX_PAL_COLORS]; 1358 DMPCXColor colorMap[PCX_PAL_COLORS];
1300 Uint8 reserved; // should be set to 0 1359 Uint8 reserved; // should be set to 0
1301 Uint8 nplanes; // number of planes 1360 Uint8 nplanes; // number of planes
1302 Uint16 bpl; // bytes per plane LINE 1361 Uint16 bpl; // bytes per plane LINE
1303 Uint16 palInfo; // 1 = color/BW, 2 = grayscale 1362 Uint16 palInfo; // 1 = color/BW, 2 = grayscale
1304 Uint16 hScreenSize, vScreenSize; 1363 Uint16 hScreenSize, vScreenSize;
1449 // Create PCX header 1508 // Create PCX header
1450 dmMemset(&hdr, 0, sizeof(hdr)); 1509 dmMemset(&hdr, 0, sizeof(hdr));
1451 if (spec.pixfmt == DM_PIXFMT_PALETTE || 1510 if (spec.pixfmt == DM_PIXFMT_PALETTE ||
1452 spec.pixfmt == DM_PIXFMT_GRAYSCALE) 1511 spec.pixfmt == DM_PIXFMT_GRAYSCALE)
1453 { 1512 {
1454 const int ncolors = img->pal->ncolors > DMPCX_PAL_COLORS ? DMPCX_PAL_COLORS : img->pal->ncolors; 1513 const int ncolors = img->pal->ncolors > PCX_PAL_COLORS ? PCX_PAL_COLORS : img->pal->ncolors;
1455 for (int i = 0; i < ncolors; i++) 1514 for (int i = 0; i < ncolors; i++)
1456 { 1515 {
1457 hdr.colorMap[i].r = img->pal->colors[i].r; 1516 hdr.colorMap[i].r = img->pal->colors[i].r;
1458 hdr.colorMap[i].g = img->pal->colors[i].g; 1517 hdr.colorMap[i].g = img->pal->colors[i].g;
1459 hdr.colorMap[i].b = img->pal->colors[i].b; 1518 hdr.colorMap[i].b = img->pal->colors[i].b;
1808 BOOL read; 1867 BOOL read;
1809 1868
1810 if (!dmf_read_byte(fp, &tmpb) || tmpb != 0x0C) 1869 if (!dmf_read_byte(fp, &tmpb) || tmpb != 0x0C)
1811 { 1870 {
1812 read = FALSE; 1871 read = FALSE;
1813 ncolors = DMPCX_PAL_COLORS; 1872 ncolors = PCX_PAL_COLORS;
1814 } 1873 }
1815 else 1874 else
1816 { 1875 {
1817 read = TRUE; 1876 read = TRUE;
1818 ncolors = 256; 1877 ncolors = 256;
1835 goto error; 1894 goto error;
1836 } 1895 }
1837 } 1896 }
1838 else 1897 else
1839 { 1898 {
1840 const int nmax = img->pal->ncolors > DMPCX_PAL_COLORS ? DMPCX_PAL_COLORS : img->pal->ncolors; 1899 const int nmax = img->pal->ncolors > PCX_PAL_COLORS ? PCX_PAL_COLORS : img->pal->ncolors;
1841 1900
1842 // If the extra palette is not available, copy the colors from 1901 // If the extra palette is not available, copy the colors from
1843 // the header palette to our internal palette structure. 1902 // the header palette to our internal palette structure.
1844 dmMsg(2, "PCX: Initializing palette from header of %d colors (%d)\n", ncolors, nmax); 1903 dmMsg(2, "PCX: Initializing palette from header of %d colors (%d)\n", ncolors, nmax);
1845 1904
2956 return scoreMax; 3015 return scoreMax;
2957 } 3016 }
2958 else 3017 else
2959 return DM_PROBE_SCORE_FALSE; 3018 return DM_PROBE_SCORE_FALSE;
2960 } 3019 }
3020
3021
3022 //
3023 // List of formats
3024 //
3025 const DMPaletteFormat dmPaletteFormatList[] =
3026 {
3027 {
3028 "act", "ACT Palette",
3029 DM_PALFMT_ACT, DM_FMT_RDWR,
3030 fmtProbeACT, dmReadACTPalette, dmWriteACTPalette,
3031 },
3032 };
3033
3034 const int ndmPaletteFormatList = sizeof(dmPaletteFormatList) / sizeof(dmPaletteFormatList[0]);
3035
3036
3037 int dmPaletteProbeGeneric(const Uint8 *buf, const size_t len, const DMPaletteFormat **pfmt, int *index)
3038 {
3039 int scoreMax = DM_PROBE_SCORE_FALSE, scoreIndex = -1;
3040
3041 for (int i = 0; i < ndmPaletteFormatList; i++)
3042 {
3043 const DMPaletteFormat *fmt = &dmPaletteFormatList[i];
3044 if (fmt->probe != NULL)
3045 {
3046 int score = fmt->probe(buf, len);
3047 if (score > scoreMax)
3048 {
3049 scoreMax = score;
3050 scoreIndex = i;
3051 }
3052 }
3053 }
3054
3055 if (scoreIndex >= 0)
3056 {
3057 *pfmt = &dmPaletteFormatList[scoreIndex];
3058 *index = scoreIndex;
3059 return scoreMax;
3060 }
3061 else
3062 return DM_PROBE_SCORE_FALSE;
3063 }