comparison tools/lib64fmts.c @ 1646:415c732dc14c

Implement support for packed TruePaint images.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 30 May 2018 01:07:07 +0300
parents 710961d02b8a
children 52cd979d63fd
comparison
equal deleted inserted replaced
1645:262300a0359b 1646:415c732dc14c
307 (void) raster; 307 (void) raster;
308 return dmC64GetGenericMCPixel(img, bmoffs, scroffs, vshift, 0, vbitmap, 0, img->bgcolor); 308 return dmC64GetGenericMCPixel(img, bmoffs, scroffs, vshift, 0, vbitmap, 0, img->bgcolor);
309 } 309 }
310 310
311 311
312 static int fmtProbeTruePaintPacked(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
313 {
314 // The beginning/un-changing part of the BASIC bootstrap and
315 // relocation of decompression code
316 static const Uint8 signature[] = {
317 0x0b, 0x08, 0x09, 0x00, 0x9e, 0x32, 0x30, 0x35,
318 0x39, 0x00, 0xa2, 0x00, 0x78, 0xbd, 0x1c, 0x08,
319 0x9d, 0xf5, 0x00, 0xe8, 0xd0, 0xf7, 0xe6, 0x01,
320 0x4c, 0x01, 0x01, 0xa5, 0xfe, 0xd0, 0x02, 0xc6,
321 0xff, 0xc6, 0xfe
322 };
323
324 if (len >= 512 && dmCompareAddr16(buf, 0, fmt->addr) &&
325 memcmp(buf + 2, signature, sizeof(signature)) == 0)
326 return DM_PROBE_SCORE_MAX;
327
328 return DM_PROBE_SCORE_FALSE;
329 }
330
331
332 //
333 // Based on disassembly of the depacker routine. Encoding seems to be
334 // some kind of "improved RLE" variant.
335 //
336 static int fmtDecodeTruePaintPacked(DMC64Image *img, const Uint8 *src, const size_t srcLen, const DMC64ImageFormat *fmt)
337 {
338 int res = DMERR_OK;
339 Uint8 *dst = NULL;
340 const Uint8 *codeBook1, *codeBook2;
341 size_t
342 srcOffs, dstOffs,
343 dstLen = 0x4be8;
344 // 1b7e-67e8 decoded by original depacker
345 // 1c00-67e8 is the actual area used tho
346
347 // Codebooks: #1 is trampoline table markers, #2 is RLE data table
348 codeBook1 = src + 0x81 - 2;
349 codeBook2 = src + 0x85 - 2;
350
351 // Allocate output buffer
352 if ((dst = dmMalloc0(dstLen)) == NULL)
353 {
354 res = dmError(DMERR_MALLOC,
355 "Could not allocate memory for temporary decompression buffer.\n");
356 goto out;
357 }
358
359 // Begin decompression
360 srcOffs = srcLen;
361 dstOffs = dstLen;
362
363 while (srcOffs > 0 && dstOffs > 0)
364 {
365 Uint8 data;
366 int count = 1, scount;
367 BOOL found = FALSE;
368
369 if (!dmReverseGetByte(src, &srcOffs, &data))
370 {
371 res = dmError(DMERR_INVALID_DATA,
372 "TruePaintRLE: Out of source data.\n");
373 goto out;
374 }
375
376 for (int n = 0; n < 8; n++)
377 if (codeBook1[n] == data && !found)
378 {
379 found = TRUE;
380 switch (n)
381 {
382 case 4: // Y = 4, JTO = $0B
383 if (!dmReverseGetByte(src, &srcOffs, &data))
384 {
385 res = dmError(DMERR_INVALID_DATA,
386 "TruePaintRLE: Y=4, JTO=$0B\n");
387 goto out;
388 }
389
390 count = data;
391 if (data == 0)
392 {
393 fprintf(stderr, "TruePaintRLE: BAILOUT\n");
394 goto finish;
395 }
396 // NOTE: Intentional fall through here!
397
398 case 1: // Y = 1, JTO = $17
399 count += 2;
400 // NOTE: Intentional fallthrough here!
401
402 case 0: // Y = 0, JTO = $19
403 if (!dmReverseGetByte(src, &srcOffs, &data))
404 {
405 res = dmError(DMERR_INVALID_DATA,
406 "TruePaintRLE: Y=0, JTO=$19\n");
407 goto out;
408 }
409 break;
410
411 case 2: // Y = 2, JTO = $07
412 if (!dmReverseGetByte(src, &srcOffs, &data))
413 {
414 res = dmError(DMERR_INVALID_DATA,
415 "foo: Y=2, JTO=$07\n");
416 goto out;
417 }
418 count = data;
419 // NOTE: Intentional fallthrough here!
420
421 case 3: // Y = 3, JTO = $0B
422 count += 2;
423 data = 0;
424 break;
425
426 default: // Y = [5..8], JTO = $00
427 count++;
428 data = codeBook2[n];
429 break;
430 }
431 }
432
433 for (scount = count; count; count--)
434 {
435 if (!dmReversePutByte(dst, &dstOffs, data))
436 {
437 res = dmError(DMERR_INVALID_DATA,
438 "TruePaintRLE: Out of output space for run: %d x $%02x!\n",
439 scount, data);
440 goto out;
441 }
442 }
443 }
444
445 finish:
446 res = dmC64DecodeGenericBMP(img, dst, dstLen, fmt);
447
448 out:
449 dmFree(dst);
450 return res;
451 }
452
453
312 #define XX2_MIN_SIZE 4000 454 #define XX2_MIN_SIZE 4000
313 455
314 static int fmtProbeFormatXX2(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt) 456 static int fmtProbeFormatXX2(const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt)
315 { 457 {
316 if (len >= XX2_MIN_SIZE && len <= XX2_MIN_SIZE + 8 && 458 if (len >= XX2_MIN_SIZE && len <= XX2_MIN_SIZE + 8 &&
600 { DT_BITMAP_RAM, 0x2800, 1, 0, NULL, NULL }, 742 { DT_BITMAP_RAM, 0x2800, 1, 0, NULL, NULL },
601 { DT_DEC_FUNCTION, 0x2742, 0, 1, fmtDrazLaceGetLaceType, NULL }, 743 { DT_DEC_FUNCTION, 0x2742, 0, 1, fmtDrazLaceGetLaceType, NULL },
602 { DT_ENC_FUNCTION, 0x2742, 0, 1, NULL, fmtDrazLaceSetLaceType }, 744 { DT_ENC_FUNCTION, 0x2742, 0, 1, NULL, fmtDrazLaceSetLaceType },
603 { DT_LAST, 0, 0, 0, NULL, NULL }, 745 { DT_LAST, 0, 0, 0, NULL, NULL },
604 }, 746 },
605 }; 747
606 748 {
607 749 // #6: TruePaint
608 //
609 // Array with data for supported formats
610 //
611 const DMC64ImageFormat dmC64ImageFormats[] =
612 {
613 {
614 D64_FMT_MC, "d2p", "DrazPaint 1.4/2.0 (packed)", 0x5800, 0, DM_FMT_RDWR,
615 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,
616 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
617 fmtProbeDrazPaint20Packed,
618 fmtDecodeDrazPaintPacked, fmtEncodeDrazPaintPacked,
619 NULL, NULL,
620 NULL,
621 { }, &dmC64CommonFormatOps[4]
622 },
623
624 {
625 D64_FMT_MC, "drp", "DrazPaint (unpacked)", 0x5800, 10051, DM_FMT_RDWR,
626 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,
627 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
628 NULL,
629 NULL, NULL,
630 NULL, NULL,
631 NULL,
632 { }, &dmC64CommonFormatOps[4]
633 },
634
635 {
636 D64_FMT_MC | D64_FMT_ILACE, "dlp", "DrazLace 1.0 (packed)", 0x5800, 0, DM_FMT_RDWR,
637 C64_SCR_WIDTH , C64_SCR_HEIGHT,
638 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT,
639 fmtProbeDrazLace10Packed,
640 fmtDecodeDrazPaintPacked, fmtEncodeDrazPaintPacked,
641 NULL, NULL,
642 NULL,
643 { }, &dmC64CommonFormatOps[5]
644 },
645
646 {
647 D64_FMT_MC | D64_FMT_ILACE, "drl", "DrazLace 1.0 (unpacked)", 0x5800, 18242, DM_FMT_RDWR,
648 C64_SCR_WIDTH , C64_SCR_HEIGHT,
649 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT,
650 NULL,
651 NULL, NULL,
652 NULL, NULL,
653 NULL,
654 { }, &dmC64CommonFormatOps[5]
655 },
656
657 {
658 D64_FMT_MC, "vid", "Vidcom 64 (unpacked)", 0x5800, 10050, DM_FMT_RDWR,
659 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,
660 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
661 NULL,
662 NULL, NULL,
663 NULL, NULL,
664 NULL,
665 {
666 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL },
667 { DT_COLOR_REG, 0x07e8, 0, DC_BGCOL, NULL, NULL },
668 { DT_BITMAP_RAM, 0x0800, 0, 0, NULL, NULL },
669 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL },
670 { DT_LAST, 0, 0, 0, NULL, NULL },
671 },
672 NULL
673 },
674
675 {
676 D64_FMT_MC, "p64", "Picasso 64 (unpacked)", 0x1800, 10050, DM_FMT_RDWR,
677 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,
678 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
679 NULL,
680 NULL, NULL,
681 NULL, NULL,
682 NULL,
683 {
684 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL },
685 { DT_COLOR_REG, 0x07fe, 0, DC_BGCOL, NULL, NULL },
686 { DT_BITMAP_RAM, 0x0800, 0, 0, NULL, NULL },
687 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL },
688 { DT_LAST, 0, 0, 0, NULL, NULL },
689 },
690 NULL
691 },
692
693 {
694 D64_FMT_MC | D64_FMT_ILACE, "mci", "Truepaint (unpacked)", 0x9c00, 19434, DM_FMT_RD,
695 C64_SCR_WIDTH , C64_SCR_HEIGHT,
696 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT,
697 NULL,
698 NULL, NULL,
699 NULL, NULL,
700 fmtGetPixelTruePaint,
701 {
702 { DT_SCREEN_RAM, 0x0000, 0, 0, NULL, NULL }, 750 { DT_SCREEN_RAM, 0x0000, 0, 0, NULL, NULL },
703 { DT_COLOR_REG, 0x03e8, 0, DC_BGCOL, NULL, NULL }, 751 { DT_COLOR_REG, 0x03e8, 0, DC_BGCOL, NULL, NULL },
704 { DT_BITMAP_RAM, 0x0400, 0, 0, NULL, NULL }, 752 { DT_BITMAP_RAM, 0x0400, 0, 0, NULL, NULL },
705 { DT_BITMAP_RAM, 0x2400, 1, 0, NULL, NULL }, 753 { DT_BITMAP_RAM, 0x2400, 1, 0, NULL, NULL },
706 { DT_SCREEN_RAM, 0x4400, 1, 0, NULL, NULL }, 754 { DT_SCREEN_RAM, 0x4400, 1, 0, NULL, NULL },
707 { DT_COLOR_RAM, 0x4800, 0, 0, NULL, NULL }, 755 { DT_COLOR_RAM, 0x4800, 0, 0, NULL, NULL },
708 { DT_DEC_FUNCTION, 0x0000, 0, 0, fmtTruePaintGetLaceType, NULL }, 756 { DT_DEC_FUNCTION, 0x0000, 0, 0, fmtTruePaintGetLaceType, NULL },
709 { DT_LAST, 0, 0, 0, NULL, NULL }, 757 { DT_LAST, 0, 0, 0, NULL, NULL },
710 }, 758 },
759 };
760
761
762 //
763 // Array with data for supported formats
764 //
765 const DMC64ImageFormat dmC64ImageFormats[] =
766 {
767 {
768 D64_FMT_MC, "d2p", "DrazPaint 1.4/2.0 (packed)", 0x5800, 0, DM_FMT_RDWR,
769 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,
770 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
771 fmtProbeDrazPaint20Packed,
772 fmtDecodeDrazPaintPacked, fmtEncodeDrazPaintPacked,
773 NULL, NULL,
774 NULL,
775 { }, &dmC64CommonFormatOps[4]
776 },
777
778 {
779 D64_FMT_MC, "drp", "DrazPaint (unpacked)", 0x5800, 10051, DM_FMT_RDWR,
780 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,
781 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
782 NULL,
783 NULL, NULL,
784 NULL, NULL,
785 NULL,
786 { }, &dmC64CommonFormatOps[4]
787 },
788
789 {
790 D64_FMT_MC | D64_FMT_ILACE, "dlp", "DrazLace 1.0 (packed)", 0x5800, 0, DM_FMT_RDWR,
791 C64_SCR_WIDTH , C64_SCR_HEIGHT,
792 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT,
793 fmtProbeDrazLace10Packed,
794 fmtDecodeDrazPaintPacked, fmtEncodeDrazPaintPacked,
795 NULL, NULL,
796 NULL,
797 { }, &dmC64CommonFormatOps[5]
798 },
799
800 {
801 D64_FMT_MC | D64_FMT_ILACE, "drl", "DrazLace 1.0 (unpacked)", 0x5800, 18242, DM_FMT_RDWR,
802 C64_SCR_WIDTH , C64_SCR_HEIGHT,
803 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT,
804 NULL,
805 NULL, NULL,
806 NULL, NULL,
807 NULL,
808 { }, &dmC64CommonFormatOps[5]
809 },
810
811 {
812 D64_FMT_MC, "vid", "Vidcom 64 (unpacked)", 0x5800, 10050, DM_FMT_RDWR,
813 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,
814 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
815 NULL,
816 NULL, NULL,
817 NULL, NULL,
818 NULL,
819 {
820 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL },
821 { DT_COLOR_REG, 0x07e8, 0, DC_BGCOL, NULL, NULL },
822 { DT_BITMAP_RAM, 0x0800, 0, 0, NULL, NULL },
823 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL },
824 { DT_LAST, 0, 0, 0, NULL, NULL },
825 },
711 NULL 826 NULL
827 },
828
829 {
830 D64_FMT_MC, "p64", "Picasso 64 (unpacked)", 0x1800, 10050, DM_FMT_RDWR,
831 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,
832 C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT,
833 NULL,
834 NULL, NULL,
835 NULL, NULL,
836 NULL,
837 {
838 { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL },
839 { DT_COLOR_REG, 0x07fe, 0, DC_BGCOL, NULL, NULL },
840 { DT_BITMAP_RAM, 0x0800, 0, 0, NULL, NULL },
841 { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL },
842 { DT_LAST, 0, 0, 0, NULL, NULL },
843 },
844 NULL
845 },
846
847 {
848 D64_FMT_MC | D64_FMT_ILACE, "mci", "Truepaint (unpacked)", 0x9c00, 19434, DM_FMT_RD,
849 C64_SCR_WIDTH , C64_SCR_HEIGHT,
850 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT,
851 NULL,
852 NULL, NULL,
853 NULL, NULL,
854 fmtGetPixelTruePaint,
855 { }, &dmC64CommonFormatOps[6]
856 },
857
858 {
859 D64_FMT_MC | D64_FMT_ILACE, "mcip", "Truepaint (packed)", 0x0801, 0, DM_FMT_RD,
860 C64_SCR_WIDTH , C64_SCR_HEIGHT,
861 C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT,
862 fmtProbeTruePaintPacked,
863 fmtDecodeTruePaintPacked, NULL,
864 NULL, NULL,
865 fmtGetPixelTruePaint,
866 { }, &dmC64CommonFormatOps[6]
712 }, 867 },
713 868
714 { 869 {
715 D64_FMT_MC, "kla", "Koala Paint (unpacked)", 0x6000, 10003, DM_FMT_RDWR, 870 D64_FMT_MC, "kla", "Koala Paint (unpacked)", 0x6000, 10003, DM_FMT_RDWR,
716 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, 871 C64_SCR_WIDTH / 2, C64_SCR_HEIGHT,