Mercurial > hg > dmlib
comparison tools/lib64fmts.c @ 1722:de8e0a404c06
Refactor fmtDecodeTruePaintPacked() to use more generic DMGrowBuf functions
now that they support backwards growing buffers, and get rid of
dmReverseGetByte() and dmReversePutByte() helpers.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 06 Jun 2018 15:22:15 +0300 |
parents | 95317672ff00 |
children | 13fe4010623f |
comparison
equal
deleted
inserted
replaced
1721:c9a6f1dae756 | 1722:de8e0a404c06 |
---|---|
421 // | 421 // |
422 // Based on disassembly of the depacker routine. Encoding seems to be | 422 // Based on disassembly of the depacker routine. Encoding seems to be |
423 // some kind of "improved RLE" variant with different modes and a | 423 // some kind of "improved RLE" variant with different modes and a |
424 // simplistic "codebook". | 424 // simplistic "codebook". |
425 // | 425 // |
426 static BOOL fmtTruePaintGetByte(const Uint8 *src, size_t *srcOffs, Uint8 *data, int *res, const int mode) | 426 static int fmtTruePaintGetByte(DMGrowBuf *src, Uint8 *data, const int mode) |
427 { | 427 { |
428 if (!dmReverseGetByte(src, srcOffs, data)) | 428 if (!dmGrowBufGetU8(src, data)) |
429 { | 429 { |
430 *res = dmError(DMERR_INVALID_DATA, | 430 return dmError(DMERR_INVALID_DATA, |
431 "TruePaintRLE: Out of input data (N=%d)\n", mode); | 431 "TruePaintRLE: Out of input data (N=%d)\n", mode); |
432 return FALSE; | |
433 } | 432 } |
434 else | 433 else |
435 return TRUE; | 434 return DMERR_OK; |
436 } | 435 } |
437 | 436 |
438 | 437 |
439 static int fmtDecodeTruePaintPacked(DMC64Image *img, const DMGrowBuf *src, const DMC64ImageFormat *fmt) | 438 static int fmtDecodeTruePaintPacked(DMC64Image *img, const DMGrowBuf *psrc, const DMC64ImageFormat *fmt) |
440 { | 439 { |
441 int res = DMERR_OK; | 440 int res = DMERR_OK; |
442 Uint8 *dst = NULL; | |
443 DMGrowBuf dstTmp; | |
444 const Uint8 *codeBook1, *codeBook2; | 441 const Uint8 *codeBook1, *codeBook2; |
445 size_t | 442 DMGrowBuf dst, src; |
446 srcOffs, dstOffs, | 443 DMCompParams cfg; |
447 dstLen = 0x4be8; | 444 Uint8 data; |
448 // 1b7e-67e8 decoded by original depacker | 445 |
449 // 1c00-67e8 is the actual area used tho | 446 cfg.func = fmt->name; |
447 cfg.type = DM_COMP_RLE_MARKER; | |
448 cfg.flags = DM_RLE_BACKWARDS_OUTPUT | DM_RLE_BACKWARDS_INPUT; | |
449 cfg.rleMarkerB = 0xfe; | |
450 | |
451 // 1b7e-67e8 decoded by original depacker | |
452 // 1c00-67e8 is the actual area used tho | |
453 cfg.flags |= DM_OUT_CROP_END; | |
454 cfg.cropOutLen = 0x67e8 - 0x1c00; | |
450 | 455 |
451 // Codebooks: #1 is trampoline table markers, #2 is RLE data table | 456 // Codebooks: #1 is trampoline table markers, #2 is RLE data table |
452 codeBook1 = src->data + 0x81 - 2; | 457 codeBook1 = psrc->data + 0x81 - 2; |
453 codeBook2 = src->data + 0x85 - 2; | 458 codeBook2 = psrc->data + 0x85 - 2; |
454 | 459 |
455 // Allocate output buffer | 460 // Allocate output buffer |
456 if ((dst = dmMalloc0(dstLen)) == NULL) | 461 if ((res = dmGrowBufAlloc(&dst, 64*1024, 4*1024)) != DMERR_OK) |
457 { | |
458 res = dmError(DMERR_MALLOC, | |
459 "Could not allocate memory for temporary decompression buffer.\n"); | |
460 goto out; | 462 goto out; |
461 } | 463 |
462 | 464 // As we need to modify the offs, etc. but not the data, |
463 // Begin decompression | 465 // we will just make a shallow copy of the DMGrowBuf struct |
464 srcOffs = src->len; | 466 dmGrowBufConstCopy(&src, psrc); |
465 dstOffs = dstLen; | 467 dmSetupRLEBuffers(&dst, &src, &cfg); |
466 | 468 |
467 while (srcOffs > 0 && dstOffs > 0) | 469 while ((res = fmtTruePaintGetByte(&src, &data, -1)) == DMERR_OK) |
468 { | 470 { |
469 Uint8 data; | 471 unsigned int count = 1; |
470 int count = 1, scount; | |
471 BOOL found = FALSE; | 472 BOOL found = FALSE; |
472 | |
473 if (!fmtTruePaintGetByte(src->data, &srcOffs, &data, &res, -1)) | |
474 goto out; | |
475 | 473 |
476 for (int n = 0; n < 8; n++) | 474 for (int n = 0; n < 8; n++) |
477 if (codeBook1[n] == data && !found) | 475 if (codeBook1[n] == data && !found) |
478 { | 476 { |
479 found = TRUE; | 477 found = TRUE; |
480 switch (n) | 478 switch (n) |
481 { | 479 { |
482 case 4: // Y = 4, JTO = $0B | 480 case 4: // Y = 4, JTO = $0B |
483 if (!fmtTruePaintGetByte(src->data, &srcOffs, &data, &res, n)) | 481 if ((res = fmtTruePaintGetByte(&src, &data, n)) != DMERR_OK) |
484 goto out; | 482 goto out; |
485 | 483 |
486 count = data; | 484 count = data; |
487 if (data == 0) | 485 if (data == 0) |
488 goto finish; | 486 goto finish; |
492 case 1: // Y = 1, JTO = $17 | 490 case 1: // Y = 1, JTO = $17 |
493 count += 2; | 491 count += 2; |
494 // fallthrough | 492 // fallthrough |
495 | 493 |
496 case 0: // Y = 0, JTO = $19 | 494 case 0: // Y = 0, JTO = $19 |
497 if (!fmtTruePaintGetByte(src->data, &srcOffs, &data, &res, n)) | 495 if ((res = fmtTruePaintGetByte(&src, &data, n)) != DMERR_OK) |
498 goto out; | 496 goto out; |
499 break; | 497 break; |
500 | 498 |
501 case 2: // Y = 2, JTO = $07 | 499 case 2: // Y = 2, JTO = $07 |
502 if (!fmtTruePaintGetByte(src->data, &srcOffs, &data, &res, n)) | 500 if ((res = fmtTruePaintGetByte(&src, &data, n)) != DMERR_OK) |
503 goto out; | 501 goto out; |
504 | 502 |
505 count = data; | 503 count = data; |
506 // fallthrough | 504 // fallthrough |
507 | 505 |
515 data = codeBook2[n]; | 513 data = codeBook2[n]; |
516 break; | 514 break; |
517 } | 515 } |
518 } | 516 } |
519 | 517 |
520 for (scount = count; count; count--) | 518 if ((res = dmGenericRLEOutputRun(&dst, &cfg, data, count)) != DMERR_OK) |
521 { | 519 goto out; |
522 if (!dmReversePutByte(dst, &dstOffs, data)) | |
523 { | |
524 res = dmError(DMERR_INVALID_DATA, | |
525 "TruePaintRLE: Out of output space for run: %d x $%02x!\n", | |
526 scount, data); | |
527 goto out; | |
528 } | |
529 } | |
530 } | 520 } |
531 | 521 |
532 finish: | 522 finish: |
533 res = dmC64DecodeGenericBMP(img, dmGrowBufCreateFrom(&dstTmp, dst, dstLen), fmt); | 523 dmFinishRLEBuffers(&dst, &src, &cfg); |
524 res = dmC64DecodeGenericBMP(img, &dst, fmt); | |
534 | 525 |
535 out: | 526 out: |
536 dmFree(dst); | 527 dmGrowBufFree(&dst); |
537 return res; | 528 return res; |
538 } | 529 } |
539 | 530 |
540 | 531 |
541 #define XX2_MIN_SIZE 4000 | 532 #define XX2_MIN_SIZE 4000 |