Mercurial > hg > dmlib
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 |