comparison tools/lib64fmts.c @ 2605:f5f03c5d9fd5

Implement EXON VHI Editor 0.1 packed format support.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 25 Nov 2023 06:06:18 +0200
parents 1c80099fe47e
children 92909caccc9e
comparison
equal deleted inserted replaced
2604:1c80099fe47e 2605:f5f03c5d9fd5
2196 // And now RLE compress the data to the existing buffer 2196 // And now RLE compress the data to the existing buffer
2197 res = dmEncodeGenericRLE(buf, &tmp, &cfg); 2197 res = dmEncodeGenericRLE(buf, &tmp, &cfg);
2198 2198
2199 out: 2199 out:
2200 dmGrowBufFree(&tmp); 2200 dmGrowBufFree(&tmp);
2201 return res;
2202 }
2203
2204
2205 static const Uint8 fmtEXON_VHI_Packed_MagicID[] =
2206 {
2207 0x00, 0x00, 0x20, 0x16, 0x08, 0x09, 0x20, 0x05,
2208 0x04, 0x09, 0x14, 0x0f, 0x12, 0x20, 0x16, 0x30,
2209 0x2e, 0x31, 0x20, 0x20, 0x02, 0x19, 0x20, 0x16,
2210 0x0f, 0x0c, 0x03, 0x01, 0x0e, 0x0f, 0x2f, 0x05,
2211 0x18, 0x0f, 0x0e, 0x01,
2212 };
2213
2214
2215 static int fmtProbeEXON_VHI_Packed(const DMGrowBuf *buf, const DMC64ImageFormat *fmt)
2216 {
2217 if (buf->len > 200 &&
2218 dmCompareAddr16(buf, 0, fmt->addr))
2219 {
2220 // This is a bit heavy-handed, but what can one do
2221 for (size_t offs = 2; offs < buf->len - sizeof(fmtEXON_VHI_Packed_MagicID); offs++)
2222 {
2223 if (DM_MEMCMP_SIZE(buf->data + offs, fmtEXON_VHI_Packed_MagicID) == 0)
2224 return DM_PROBE_SCORE_MAX;
2225 }
2226 }
2227
2228 return DM_PROBE_SCORE_FALSE;
2229 }
2230
2231
2232 static int fmtDecodeEXON_VHI_Packed(DMC64Image *img, const DMGrowBuf *psrc, const DMC64ImageFormat *fmt)
2233 {
2234 DMGrowBuf tmp;
2235 Uint8 *dstBuf;
2236 const size_t dstSize = fmt->size - 2;
2237 size_t dstOffs = 0, srcOffs = 0;
2238 int res;
2239
2240 // Allocate output buffer
2241 if ((dstBuf = dmMalloc0(dstSize)) == NULL)
2242 {
2243 return dmError(DMERR_MALLOC,
2244 "EXON_VHI: Could not allocate memory for decoding buffer.\n");
2245 }
2246
2247 while (srcOffs < psrc->len && dstOffs < dstSize)
2248 {
2249 // Get one byte of data
2250 Uint8 data = psrc->data[srcOffs++];
2251 size_t ncount;
2252
2253 if (data & 0x80)
2254 {
2255 // High bit means end of stream
2256 break;
2257 }
2258 else
2259 if (data == 0)
2260 {
2261 // Zero means literal run
2262 if (srcOffs > psrc->len)
2263 {
2264 res = dmError(DMERR_INVALID_DATA,
2265 "EXON_VHI: Literal sequence out of data.\n");
2266 goto out;
2267 }
2268
2269 ncount = psrc->data[srcOffs++];
2270 if (ncount == 0)
2271 ncount = 256;
2272
2273 if (srcOffs + ncount > psrc->len)
2274 {
2275 res = dmError(DMERR_INVALID_DATA,
2276 "EXON_VHI: Literal sequence too long for source data.\n");
2277 goto out;
2278 }
2279
2280 if (dstOffs + ncount > dstSize)
2281 {
2282 res = dmError(DMERR_INVALID_DATA,
2283 "EXON_VHI: Literal sequence too long for destination data.\n");
2284 goto out;
2285 }
2286
2287 for (size_t n = 0; n < ncount; n++)
2288 dstBuf[dstOffs++] = psrc->data[srcOffs++];
2289 }
2290 else
2291 {
2292 // RLE run
2293 if (srcOffs + 2 > psrc->len)
2294 {
2295 res = dmError(DMERR_INVALID_DATA,
2296 "EXON_VHI: Invalid data/out of data for RLE sequence.\n");
2297 goto out;
2298 }
2299
2300 ncount = psrc->data[srcOffs++];
2301 data = psrc->data[srcOffs++];
2302 if (ncount == 0)
2303 ncount = 256;
2304
2305 if (dstOffs + ncount > dstSize)
2306 {
2307 res = dmError(DMERR_INVALID_DATA,
2308 "EXON_VHI: Invalid data/out of data for RLE sequence.\n");
2309 goto out;
2310 }
2311
2312 for (size_t n = 0; n < ncount; n++)
2313 dstBuf[dstOffs++] = data;
2314 }
2315 }
2316
2317 res = dmC64DecodeGenericBMP(img, dmGrowBufConstCreateFrom(&tmp, dstBuf, dstSize), fmt);
2318
2319 out:
2320 dmFree(dstBuf);
2201 return res; 2321 return res;
2202 } 2322 }
2203 2323
2204 2324
2205 static int fmtGetPixelEXON_VHI(DMC64ScanLine *scan, 2325 static int fmtGetPixelEXON_VHI(DMC64ScanLine *scan,
3510 }, 3630 },
3511 NULL 3631 NULL
3512 }, 3632 },
3513 3633
3514 { 3634 {
3515 "vhi", "EXON VHI Editor 0.1 (unpacked)", 0x2000, 17389, 0, DM_FMT_RD, 3635 "vhi", "EXON VHI Editor 0.1 (unpacked)", 0x2000, 17389, 0, DM_FMT_RDWR,
3516 NULL, 3636 NULL,
3517 NULL, NULL, 3637 NULL, NULL,
3518 { 0 }, &dmC64CommonFormats[12] 3638 { 0 }, &dmC64CommonFormats[12]
3519 }, 3639 },
3520 3640
3641 {
3642 "vhip", "EXON VHI Editor 0.1 (packed)", 0x2000, 17389, 0, DM_FMT_RD,
3643 fmtProbeEXON_VHI_Packed,
3644 fmtDecodeEXON_VHI_Packed, NULL,
3645 { 0 }, &dmC64CommonFormats[12]
3646 },
3647
3521 }; 3648 };
3522 3649
3523 const int ndmC64ImageFormats = sizeof(dmC64ImageFormats) / sizeof(dmC64ImageFormats[0]); 3650 const int ndmC64ImageFormats = sizeof(dmC64ImageFormats) / sizeof(dmC64ImageFormats[0]);
3524 3651