Mercurial > hg > dmlib
comparison tools/lib64fmts.c @ 2141:009ee261704c
Add somewhat broken support for decoding packed Cosmos Designs Hires Manager files.
This format has a particularly buggy RLE+literal encoder.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 01 Jun 2019 03:56:05 +0300 |
parents | 84780a9d8d17 |
children | 810fc98d9003 |
comparison
equal
deleted
inserted
replaced
2140:b8491ee3cf24 | 2141:009ee261704c |
---|---|
973 if (fmt->size != 0 && fmt->size == buf->len) | 973 if (fmt->size != 0 && fmt->size == buf->len) |
974 return DM_PROBE_SCORE_GOOD; | 974 return DM_PROBE_SCORE_GOOD; |
975 } | 975 } |
976 | 976 |
977 return DM_PROBE_SCORE_FALSE; | 977 return DM_PROBE_SCORE_FALSE; |
978 } | |
979 | |
980 | |
981 static int fmtDecodeCosmosDesignsHiresManagerPacked(DMC64Image *img, const DMGrowBuf *psrc, const DMC64ImageFormat *fmt) | |
982 { | |
983 int res; | |
984 DMGrowBuf src, tmp; | |
985 DMCompParams cfg; | |
986 Uint8 data, count; | |
987 const size_t dstSize = 0x7ff2 - 0x4000; | |
988 size_t dstOffs; | |
989 Uint8 *dstBuf; | |
990 BOOL getByte = TRUE; | |
991 | |
992 if ((dstBuf = dmMalloc0(dstSize)) == NULL) | |
993 { | |
994 return dmError(DMERR_MALLOC, | |
995 "Could not allocate memory for RLE decoding buffer.\n"); | |
996 } | |
997 | |
998 cfg.func = fmt->name; | |
999 cfg.type = DM_COMP_RLE_MARKER; | |
1000 cfg.flags = DM_RLE_BACKWARDS_INPUT; | |
1001 | |
1002 dmGrowBufConstCopy(&src, psrc); | |
1003 dmSetupRLEBuffers(NULL, &src, &cfg); | |
1004 dstOffs = dstSize; | |
1005 | |
1006 while (dstOffs > 0 && src.offs > 0) | |
1007 { | |
1008 if (getByte && !dmGrowBufGetU8(&src, &data)) | |
1009 { | |
1010 res = dmError(DMERR_INVALID_DATA, | |
1011 "%s: RLE: Invalid data/out of data for literal sequence.\n", | |
1012 cfg.func); | |
1013 goto out; | |
1014 } | |
1015 | |
1016 // A simple marker byte RLE variant: [Marker] [count] [data] | |
1017 if (data == 0) | |
1018 { | |
1019 if (!dmGrowBufGetU8(&src, &count) || | |
1020 !dmGrowBufGetU8(&src, &data)) | |
1021 { | |
1022 res = dmError(DMERR_INVALID_DATA, | |
1023 "%s: RLE: Invalid data/out of data for run sequence.\n", | |
1024 cfg.func); | |
1025 goto out; | |
1026 } | |
1027 | |
1028 int ncount = (int) count; | |
1029 for (int n = 1; n < ncount && dstOffs > 0; n++) | |
1030 dstBuf[--dstOffs] = data; | |
1031 | |
1032 getByte = TRUE; | |
1033 } | |
1034 else | |
1035 // Literal run of data bytes | |
1036 { | |
1037 int ncount = (int) data; | |
1038 for (int n = 0; n < ncount; n++) | |
1039 { | |
1040 if (!dmGrowBufGetU8(&src, &data)) | |
1041 break; | |
1042 | |
1043 if (dstOffs > 0) | |
1044 dstBuf[--dstOffs] = data; | |
1045 else | |
1046 break; | |
1047 } | |
1048 getByte = FALSE; | |
1049 } | |
1050 } | |
1051 | |
1052 dmGrowBufConstCreateFrom(&tmp, dstBuf, 0x3fff); | |
1053 res = dmC64DecodeGenericBMP(img, &tmp, fmt); | |
1054 | |
1055 out: | |
1056 dmGrowBufFree(&src); | |
1057 dmFree(dstBuf); | |
1058 return res; | |
978 } | 1059 } |
979 | 1060 |
980 | 1061 |
981 #define FUNPAINT2_HEADER_SIZE (0x10) | 1062 #define FUNPAINT2_HEADER_SIZE (0x10) |
982 static const char *fmtFunPaint2MagicID = "FUNPAINT (MT) "; | 1063 static const char *fmtFunPaint2MagicID = "FUNPAINT (MT) "; |
2182 NULL, NULL, | 2263 NULL, NULL, |
2183 { }, &dmC64CommonFormats[8] | 2264 { }, &dmC64CommonFormats[8] |
2184 }, | 2265 }, |
2185 | 2266 |
2186 { | 2267 { |
2268 "cdhp", "Cosmos Designs Hires Manager (packed)", 0x4000, 0, DM_FMT_RD | DM_FMT_BROKEN, | |
2269 fmtProbeCosmosDesignsHiresManager, | |
2270 fmtDecodeCosmosDesignsHiresManagerPacked, NULL, | |
2271 { }, &dmC64CommonFormats[8] | |
2272 }, | |
2273 | |
2274 { | |
2187 "mrqp", "Marq's PETSCII editor (unpacked)", 0x0801, 0, DM_FMT_RD, | 2275 "mrqp", "Marq's PETSCII editor (unpacked)", 0x0801, 0, DM_FMT_RD, |
2188 fmtProbeMarqPETSCII, | 2276 fmtProbeMarqPETSCII, |
2189 NULL, NULL, | 2277 NULL, NULL, |
2190 { | 2278 { |
2191 D64_FMT_HIRES | D64_FMT_CHAR, | 2279 D64_FMT_HIRES | D64_FMT_CHAR, |