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