Mercurial > hg > dmlib
comparison tools/lib64gfx.c @ 1463:bde6a66bc2f6
Change dmDecodeGenericRLE() to use DMGrowBuf as output. Also add support
for two different common types of RLE encoding. Add stub function of
dmEncodeGenericRLE(), not implemented yet. Change functions using
dmDecodeGenericRLE to use the new API. Also fix a problem in Amica Paint
RLE decoding as the format seems to save one byte less than is necessary.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Thu, 10 May 2018 21:27:24 +0300 |
parents | 9cb6dd1046bf |
children | 88845f95e791 |
comparison
equal
deleted
inserted
replaced
1462:9cb6dd1046bf | 1463:bde6a66bc2f6 |
---|---|
31 { 0x9A, 0xD2, 0x84, 0xff }, | 31 { 0x9A, 0xD2, 0x84, 0xff }, |
32 { 0x6C, 0x5E, 0xB5, 0xff }, | 32 { 0x6C, 0x5E, 0xB5, 0xff }, |
33 { 0x95, 0x95, 0x95, 0xff }, | 33 { 0x95, 0x95, 0x95, 0xff }, |
34 }; | 34 }; |
35 | 35 |
36 #define DM_RLE_MARKER 1 | |
37 #define DM_RLE_MASK 2 | |
38 | |
36 | 39 |
37 #define DM_GET_ADDR_LO(addr) ((addr) & 0xff) | 40 #define DM_GET_ADDR_LO(addr) ((addr) & 0xff) |
38 #define DM_GET_ADDR_HI(addr) (((addr) >> 8) & 0xff) | 41 #define DM_GET_ADDR_HI(addr) (((addr) >> 8) & 0xff) |
39 | 42 |
40 | 43 |
220 | 223 |
221 return DMERR_OK; | 224 return DMERR_OK; |
222 } | 225 } |
223 | 226 |
224 | 227 |
225 static int dmDecodeGenericRLE(Uint8 **mem, Uint8 **pdstEnd, const Uint8 *src, const Uint8 *srcEnd, const Uint8 rleMarker) | 228 static int dmDecodeGenericRLE(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, const Uint8 rleMarker, const Uint8 rleMask, const int rleType) |
226 { | 229 { |
227 Uint8 *dst, *dstEnd; | 230 int res; |
228 | 231 |
229 if ((*mem = dmMalloc(C64_RAM_SIZE)) == NULL) | 232 if ((res = dmGrowBufAlloc(dst, BUF_SIZE_INITIAL, BUF_SIZE_GROW)) != DMERR_OK) |
230 return DMERR_MALLOC; | 233 goto err; |
231 | 234 |
232 dst = *mem; | 235 // Perform RLE decode |
233 dstEnd = *mem + C64_RAM_SIZE; | 236 while (src < srcEnd) |
234 | |
235 while (src <= srcEnd && dst <= dstEnd) | |
236 { | 237 { |
237 Uint8 c = *src++; | 238 Uint8 c = *src++; |
238 if (c == rleMarker && src + 2 <= srcEnd) | 239 int cnt = 1; |
239 { | 240 |
240 int cnt = *src++; | 241 switch (rleType) |
241 c = *src++; | 242 { |
242 while (cnt-- && dst <= dstEnd) | 243 case DM_RLE_MARKER: |
243 *dst++ = c; | 244 if (c == rleMarker) |
244 } | 245 { |
245 else | 246 if (srcEnd - src < 2) |
246 *dst++ = c; | 247 { |
247 } | 248 res = dmError(DMERR_INVALID_DATA, |
248 | 249 "Foobar: %d\n", srcEnd - src); |
249 *pdstEnd = dst; | 250 goto err; |
250 | 251 } |
252 cnt = *src++; | |
253 c = *src++; | |
254 } | |
255 break; | |
256 | |
257 case DM_RLE_MASK: | |
258 if ((c & rleMask) == rleMarker) | |
259 { | |
260 if (srcEnd - src < 1) | |
261 { | |
262 res = dmError(DMERR_INVALID_DATA, | |
263 "foobar2\n"); | |
264 goto err; | |
265 } | |
266 // XXX TODO actually we probably want another mask here | |
267 cnt = c & (0xff ^ rleMask); | |
268 c = *src++; | |
269 } | |
270 break; | |
271 } | |
272 | |
273 while (cnt--) | |
274 { | |
275 if (!dmGrowBufPutU8(dst, c)) | |
276 { | |
277 res = dmError(DMERR_MALLOC, | |
278 "bazzooo\n"); | |
279 goto err; | |
280 } | |
281 } | |
282 } | |
283 | |
284 // Reallocate the memory | |
285 if ((res = dmGrowBufResize(dst)) != DMERR_OK) | |
286 goto err; | |
287 | |
288 res = DMERR_OK; | |
289 | |
290 err: | |
291 return res; | |
292 } | |
293 | |
294 | |
295 static int dmEncodeGenericRLE(DMGrowBuf *dst, const Uint8 *src, const Uint8 *srcEnd, const Uint8 rleMarker) | |
296 { | |
297 (void) dst; | |
298 (void) src; | |
299 (void) srcEnd; | |
300 (void) rleMarker; | |
251 return DMERR_OK; | 301 return DMERR_OK; |
252 } | 302 } |
253 | 303 |
254 | 304 |
255 static inline Uint8 dmC64GetGenericSCPixel( | 305 static inline Uint8 dmC64GetGenericSCPixel( |
314 | 364 |
315 | 365 |
316 static int fmtDecodeDrazPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | 366 static int fmtDecodeDrazPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) |
317 { | 367 { |
318 int res; | 368 int res; |
319 Uint8 *mem = NULL, *end; | 369 DMGrowBuf mem; |
320 | 370 |
321 if ((res = dmDecodeGenericRLE(&mem, &end, buf + 0x0e, buf + len - 1, *(buf + 0x0d))) != DMERR_OK) | 371 if ((res = dmDecodeGenericRLE(&mem, buf + 0x0e, buf + len, *(buf + 0x0d), 0, DM_RLE_MARKER)) != DMERR_OK) |
322 goto out; | 372 goto out; |
323 | 373 |
324 res = dmC64DecodeGenericBMP(img, mem, end - mem + 1, fmt); | 374 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); |
325 | 375 |
326 out: | 376 out: |
327 dmFree(mem); | 377 dmGrowBufFree(&mem); |
328 return res; | 378 return res; |
329 } | 379 } |
330 | 380 |
331 | 381 |
332 static int fmtProbeDrazLace10Packed(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | 382 static int fmtProbeDrazLace10Packed(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) |
386 | 436 |
387 | 437 |
388 static int fmtDecodeAmicaPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | 438 static int fmtDecodeAmicaPaintPacked(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) |
389 { | 439 { |
390 int res; | 440 int res; |
391 Uint8 *mem = NULL, *end; | 441 DMGrowBuf mem, tmp; |
392 | 442 |
393 if ((res = dmDecodeGenericRLE(&mem, &end, buf, buf + len - 1, 0xC2)) != DMERR_OK) | 443 // Amica Paint apparently is broken and stores one byte less than it should |
444 // so we need to do some crappy buffer expansion here .. | |
445 if ((res = dmGrowBufAlloc(&tmp, len + 4, 4)) != DMERR_OK) | |
446 return res; | |
447 | |
448 tmp.len = len; | |
449 memcpy(tmp.data, buf, len); | |
450 tmp.data[tmp.len++] = 0; | |
451 | |
452 // Now do an RLE decode on the enlarged buffer | |
453 if ((res = dmDecodeGenericRLE(&mem, tmp.data, tmp.data + tmp.len, 0xC2, 0, DM_RLE_MARKER)) != DMERR_OK) | |
394 goto out; | 454 goto out; |
395 | 455 |
396 res = dmC64DecodeGenericBMP(img, mem, end - mem + 1, fmt); | 456 // And finally decode to bitmap struct |
457 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); | |
397 | 458 |
398 out: | 459 out: |
399 dmFree(mem); | 460 dmGrowBufFree(&tmp); |
461 dmGrowBufFree(&mem); | |
400 return res; | 462 return res; |
401 } | 463 } |
402 | 464 |
403 | 465 |
404 static int fmtProbeFLIDesigner(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | 466 static int fmtProbeFLIDesigner(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) |
500 | 562 |
501 | 563 |
502 static int fmtDecodeFunPaint2Packed(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) | 564 static int fmtDecodeFunPaint2Packed(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) |
503 { | 565 { |
504 int res; | 566 int res; |
505 Uint8 *mem = NULL, *end; | 567 DMGrowBuf mem; |
506 | 568 dmGrowBufInit(&mem); |
507 if ((res = dmDecodeGenericRLE(&mem, &end, buf + FUNPAINT2_HEADER_SIZE, buf + len - 1, *(buf + 15))) != DMERR_OK) | 569 |
570 if ((res = dmDecodeGenericRLE(&mem, buf + FUNPAINT2_HEADER_SIZE, buf + len, *(buf + 15), 0, DM_RLE_MARKER)) != DMERR_OK) | |
508 goto out; | 571 goto out; |
509 | 572 |
510 res = dmC64DecodeGenericBMP(img, mem, end - mem + 1, fmt); | 573 res = dmC64DecodeGenericBMP(img, mem.data, mem.len, fmt); |
511 | 574 |
512 out: | 575 out: |
513 dmFree(mem); | 576 dmGrowBufFree(&mem); |
514 return res; | 577 return res; |
515 } | 578 } |
516 | 579 |
517 | 580 |
518 static Uint8 fmtGetPixelFunPaint2( | 581 static Uint8 fmtGetPixelFunPaint2( |