Mercurial > hg > dmlib
comparison tools/lib64gfx.c @ 931:2270d7f3af77
Refactor the DMC64Image handling to be more dynamic, and start
work on allowing non 320/160 x 200 formats, and charmode based formats.
There is still work to be done, and some problems to sort out.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 25 Feb 2015 19:37:59 +0200 |
parents | db495f421242 |
children | 6320bf08e302 |
comparison
equal
deleted
inserted
replaced
930:efbad8817b79 | 931:2270d7f3af77 |
---|---|
8 */ | 8 */ |
9 #include "lib64gfx.h" | 9 #include "lib64gfx.h" |
10 | 10 |
11 #define BUF_SIZE_INITIAL (16*1024) | 11 #define BUF_SIZE_INITIAL (16*1024) |
12 #define BUF_SIZE_GROW (4*1024) | 12 #define BUF_SIZE_GROW (4*1024) |
13 | |
14 | |
15 DMC64Image * dmC64ImageAlloc(int width, int height, int ch_width, int ch_height) | |
16 { | |
17 int i; | |
18 DMC64Image *img = dmMalloc0(sizeof(DMC64Image)); | |
19 | |
20 if (img == NULL) | |
21 return NULL; | |
22 | |
23 img->width = width; | |
24 img->height = height; | |
25 img->ch_width = ch_width; | |
26 img->ch_height = ch_height; | |
27 | |
28 for (i = 0; i < C64_SCR_MAX_BANK; i++) | |
29 { | |
30 if ((img->color[i] = dmMalloc0(ch_width * ch_height)) == NULL) | |
31 goto err; | |
32 | |
33 if ((img->bitmap[i] = dmMalloc0(ch_width * ch_height * 8)) == NULL) | |
34 goto err; | |
35 | |
36 if ((img->screen[i] = dmMalloc0(ch_width * ch_height)) == NULL) | |
37 goto err; | |
38 | |
39 if ((img->charmem[i] = dmMalloc0(C64_MAX_CHARS * C64_CHR_SIZE)) == NULL) | |
40 goto err; | |
41 } | |
42 | |
43 return img; | |
44 | |
45 err: | |
46 dmC64ImageFree(img); | |
47 return NULL; | |
48 } | |
49 | |
50 | |
51 void dmC64ImageFree(DMC64Image *img) | |
52 { | |
53 if (img != NULL) | |
54 { | |
55 int i; | |
56 for (i = 0; i < C64_SCR_MAX_BANK; i++) | |
57 { | |
58 dmFree(img->color[i]); | |
59 dmFree(img->bitmap[i]); | |
60 dmFree(img->screen[i]); | |
61 } | |
62 memset(img, 0, sizeof(DMC64Image)); | |
63 dmFree(img); | |
64 } | |
65 } | |
13 | 66 |
14 | 67 |
15 char * dmC64GetImageTypeString(char *buf, const size_t len, const int type) | 68 char * dmC64GetImageTypeString(char *buf, const size_t len, const int type) |
16 { | 69 { |
17 *buf = 0; | 70 *buf = 0; |
517 { DT_COLOR_RAM, 0x2400, 0, 0, NULL, NULL }, | 570 { DT_COLOR_RAM, 0x2400, 0, 0, NULL, NULL }, |
518 { DT_COLOR_SET, 0x00 , 0, DC_BGCOL, NULL, NULL }, | 571 { DT_COLOR_SET, 0x00 , 0, DC_BGCOL, NULL, NULL }, |
519 } | 572 } |
520 }, | 573 }, |
521 | 574 |
522 #define XX2_WIDTH_CH 40 | 575 #define XX2_WIDTH_CH 40 |
523 #define XX2_HEIGHT_CH 10 | 576 #define XX2_HEIGHT_CH 10 |
524 | 577 #define XX2_SIZE (XX2_WIDTH_CH * XX2_HEIGHT_CH) |
525 #define XX2_SIZE (XX2_WIDTH_CH * XX2_HEIGHT_CH) | 578 #define XX2_BSIZE (XX2_SIZE * 8) |
526 #define XX2_BSIZE (XX2_SIZE * 8) | 579 |
527 | |
528 #if 0 | |
529 { | 580 { |
530 D64_FMT_MC, "xx2", "Unknown $2000 format (unpacked)", 0x2000, 4002, | 581 D64_FMT_MC, "xx2", "Unknown $2000 format (unpacked)", 0x2000, 4002, |
531 XX2_WIDTH_CH * 4, XX2_HEIGHT_CH * 8, | 582 XX2_WIDTH_CH * 4, XX2_HEIGHT_CH * 8, |
532 XX2_WIDTH_CH , XX2_HEIGHT_CH, | 583 XX2_WIDTH_CH , XX2_HEIGHT_CH, |
533 NULL, NULL, | 584 NULL, NULL, |
540 | 591 |
541 { DT_COLOR_SET, 11 , 0, DC_BGCOL, NULL, NULL }, | 592 { DT_COLOR_SET, 11 , 0, DC_BGCOL, NULL, NULL }, |
542 } | 593 } |
543 }, | 594 }, |
544 | 595 |
545 #else | 596 #if 0 |
546 | 597 { |
547 { | 598 D64_FMT_MC | D64_FMT_CHAR, "xx3", "??? (unpacked)", 0x2000, 0, |
548 D64_FMT_MC | D64_FMT_CHAR, "xx2", "Unknown $2000 char format (unpacked)", 0x2000, 4002, | 599 XX3_WIDTH_CH * 4, XX3_HEIGHT_CH * 8, |
549 XX2_WIDTH_CH * 4, XX2_HEIGHT_CH * 8, | 600 XX3_WIDTH_CH , XX3_HEIGHT_CH, |
550 XX2_WIDTH_CH , XX2_HEIGHT_CH, | |
551 NULL, NULL, | 601 NULL, NULL, |
552 NULL, NULL, NULL, | 602 NULL, NULL, NULL, |
553 4, | 603 4, |
554 { | 604 { |
555 { DT_CHAR_DATA, 0x0000, 0, XX2_BSIZE, NULL, NULL }, | 605 { DT_CHAR_DATA, 0x0000, 0, XX3_BSIZE, NULL, NULL }, |
556 { DT_COLOR_RAM, XX2_BSIZE + XX2_SIZE , 0, XX2_SIZE, NULL, NULL }, | 606 { DT_COLOR_RAM, XX3_BSIZE + XX3_SIZE , 0, XX3_SIZE, NULL, NULL }, |
557 | 607 |
558 { DT_CHAR_CONFIG, D64_CHCFG_LINEAR, 0, XX2_SIZE, NULL, NULL }, | 608 { DT_CHAR_CONFIG, D64_CHCFG_LINEAR, 0, XX3_SIZE, NULL, NULL }, |
559 { DT_COLOR_SET, 1 , 0, DC_BGCOL, NULL, NULL }, | 609 { DT_COLOR_SET, 1 , 0, DC_BGCOL, NULL, NULL }, |
560 { DT_COLOR_SET, 3 , 0, DC_D022, NULL, NULL }, | 610 { DT_COLOR_SET, 3 , 0, DC_D022, NULL, NULL }, |
561 { DT_COLOR_SET, 4 , 0, DC_D023, NULL, NULL }, | 611 { DT_COLOR_SET, 4 , 0, DC_D023, NULL, NULL }, |
562 } | 612 } |
563 }, | 613 }, |
623 | 673 |
624 return DMERR_OK; | 674 return DMERR_OK; |
625 } | 675 } |
626 | 676 |
627 | 677 |
628 static int dmC64GetOpSize(const DMC64EncDecOp *op, const DMC64ImageFormat *fmt) | 678 static BOOL dmC64GetOpSize(const DMC64EncDecOp *op, const DMC64ImageFormat *fmt, size_t *size) |
629 { | 679 { |
680 BOOL check; | |
681 switch (op->type) | |
682 { | |
683 case DT_SCREEN_RAM: | |
684 case DT_COLOR_RAM: | |
685 *size = fmt->ch_height * fmt->ch_width; | |
686 check = TRUE; | |
687 break; | |
688 | |
689 case DT_BITMAP: | |
690 *size = fmt->ch_height * fmt->ch_width * 8; | |
691 check = TRUE; | |
692 break; | |
693 | |
694 case DT_EXTRADATA: | |
695 *size = C64_SCR_EXTRADATA; | |
696 check = TRUE; | |
697 break; | |
698 | |
699 case DT_CHAR_DATA: | |
700 *size = C64_MAX_CHARS * C64_CHR_SIZE; | |
701 check = TRUE; | |
702 break; | |
703 | |
704 case DT_COLOR_REG: | |
705 *size = 1; | |
706 check = FALSE; | |
707 break; | |
708 | |
709 default: | |
710 *size = 0; | |
711 check = FALSE; | |
712 } | |
713 | |
630 if (op->size != 0) | 714 if (op->size != 0) |
631 return op->size; | 715 { |
632 | 716 if (check && op->size > *size) |
633 switch (op->type) | 717 return FALSE; |
634 { | 718 |
635 case DT_SCREEN_RAM: | 719 *size = op->size; |
636 return C64_SCREEN_SIZE; | 720 } |
637 | 721 |
638 case DT_COLOR_RAM: | 722 return TRUE; |
639 return C64_COLOR_SIZE; | |
640 | |
641 case DT_BITMAP: | |
642 return C64_BITMAP_SIZE; | |
643 | |
644 case DT_EXTRADATA: | |
645 return C64_SCR_EXTRADATA; | |
646 | |
647 case DT_CHAR_DATA: | |
648 return C64_MAX_CHARS * C64_CHR_HEIGHT * C64_CHR_WIDTH; | |
649 | |
650 case DT_COLOR_REG: | |
651 return 1; | |
652 | |
653 default: | |
654 return 0; | |
655 } | |
656 } | 723 } |
657 | 724 |
658 | 725 |
659 int dmC64DecodeGenericBMP(DMC64Image *img, const Uint8 *buf, | 726 int dmC64DecodeGenericBMP(DMC64Image *img, const Uint8 *buf, |
660 const size_t len, const DMC64ImageFormat *fmt) | 727 const size_t len, const DMC64ImageFormat *fmt) |
669 dmError("Invalid number of enc/dec ops in format. Internal error.\n"); | 736 dmError("Invalid number of enc/dec ops in format. Internal error.\n"); |
670 return DMERR_INTERNAL; | 737 return DMERR_INTERNAL; |
671 } | 738 } |
672 | 739 |
673 // Clear the image structure, set basics | 740 // Clear the image structure, set basics |
674 memset(img, 0, sizeof(*img)); | 741 img->type = fmt->type; |
675 img->type = fmt->type; | 742 img->width = fmt->width; |
743 img->height = fmt->height; | |
744 img->ch_width = fmt->ch_width; | |
745 img->ch_height = fmt->ch_height; | |
676 | 746 |
677 // Perform decoding | 747 // Perform decoding |
678 for (i = 0; i < fmt->nencdecOps; i++) | 748 for (i = 0; i < fmt->nencdecOps; i++) |
679 { | 749 { |
680 const DMC64EncDecOp *op = &fmt->encdecOps[i]; | 750 const DMC64EncDecOp *op = &fmt->encdecOps[i]; |
685 // Check operation validity | 755 // Check operation validity |
686 if ((res = dmC64SanityCheckEncDecOp(i, op)) != DMERR_OK) | 756 if ((res = dmC64SanityCheckEncDecOp(i, op)) != DMERR_OK) |
687 return res; | 757 return res; |
688 | 758 |
689 // Check size | 759 // Check size |
690 size = dmC64GetOpSize(op, fmt); | 760 if (!dmC64GetOpSize(op, fmt, &size)) |
761 { | |
762 dmError("Decode op SIZE out of bounds, op #%d type=%d, offs=%d ($%04x), " | |
763 "bank=%d, size=%d ($%04x) vs. allocated %d ($%04x)\n", | |
764 i, op->type, op->offs, op->offs, op->bank, size, size, op->size, op->size); | |
765 return DMERR_INVALID_DATA; | |
766 } | |
691 | 767 |
692 // Do we need to reallocate some more space? | 768 // Do we need to reallocate some more space? |
693 if (op->offs + size > len) | 769 if (op->offs + size > len) |
694 { | 770 { |
695 dmError("Decode out of bounds, op #%d type=%d, offs=%d ($%04x), " | 771 dmError("Decode out of bounds, op #%d type=%d, offs=%d ($%04x), " |
704 switch (op->type) | 780 switch (op->type) |
705 { | 781 { |
706 case DT_COLOR_RAM: memcpy(img->color[op->bank], src, size); break; | 782 case DT_COLOR_RAM: memcpy(img->color[op->bank], src, size); break; |
707 case DT_BITMAP: memcpy(img->bitmap[op->bank], src, size); break; | 783 case DT_BITMAP: memcpy(img->bitmap[op->bank], src, size); break; |
708 case DT_SCREEN_RAM: memcpy(img->screen[op->bank], src, size); break; | 784 case DT_SCREEN_RAM: memcpy(img->screen[op->bank], src, size); break; |
785 case DT_CHAR_DATA: memcpy(img->charmem[op->bank], src, size); break; | |
709 case DT_EXTRADATA: memcpy(img->extradata, src, size); break; | 786 case DT_EXTRADATA: memcpy(img->extradata, src, size); break; |
710 case DT_CHAR_DATA: memcpy(img->charmem, src, size); break; | |
711 | 787 |
712 case DT_COLOR_REG: | 788 case DT_COLOR_REG: |
713 switch (op->size) | 789 switch (op->size) |
714 { | 790 { |
715 case DC_D020: img->d020 = *src; break; | 791 case DC_D020: img->d020 = *src; break; |
749 case D64_CHCFG_SCREEN: | 825 case D64_CHCFG_SCREEN: |
750 break; | 826 break; |
751 | 827 |
752 case D64_CHCFG_LINEAR: | 828 case D64_CHCFG_LINEAR: |
753 { | 829 { |
754 size_t bank, offs; | 830 int bank, offs; |
755 for (bank = 0; bank < C64_SCR_MAX_BANK; bank++) | 831 for (bank = 0; bank < C64_SCR_MAX_BANK; bank++) |
756 for (offs = 0; offs < C64_SCR_SCREEN_SIZE; offs++) | 832 for (offs = 0; offs < fmt->ch_height * fmt->ch_width; offs++) |
757 img->screen[bank][offs] = offs & 0xff; | 833 img->screen[bank][offs] = offs & 0xff; |
758 } | 834 } |
759 break; | 835 break; |
760 | 836 |
761 default: | 837 default: |
829 // Check operation validity | 905 // Check operation validity |
830 if ((res = dmC64SanityCheckEncDecOp(i, op)) != DMERR_OK) | 906 if ((res = dmC64SanityCheckEncDecOp(i, op)) != DMERR_OK) |
831 goto error; | 907 goto error; |
832 | 908 |
833 // Check size | 909 // Check size |
834 size = dmC64GetOpSize(op, fmt); | 910 if (!dmC64GetOpSize(op, fmt, &size)) |
911 { | |
912 dmError("Decode op SIZE out of bounds, op #%d type=%d, offs=%d ($%04x), " | |
913 "bank=%d, size=%d ($%04x) vs. allocated %d ($%04x)\n", | |
914 i, op->type, op->offs, op->offs, op->bank, size, size, op->size, op->size); | |
915 return DMERR_INVALID_DATA; | |
916 } | |
835 | 917 |
836 // Do we need to reallocate some more space? | 918 // Do we need to reallocate some more space? |
837 if (2 + op->offs + size > allocated) | 919 if (2 + op->offs + size > allocated) |
838 { | 920 { |
839 size_t diff = allocated - (op->offs + size + 2), | 921 size_t diff = allocated - (op->offs + size + 2), |
856 switch (op->type) | 938 switch (op->type) |
857 { | 939 { |
858 case DT_COLOR_RAM: memcpy(dst, img->color[op->bank], size); break; | 940 case DT_COLOR_RAM: memcpy(dst, img->color[op->bank], size); break; |
859 case DT_BITMAP: memcpy(dst, img->bitmap[op->bank], size); break; | 941 case DT_BITMAP: memcpy(dst, img->bitmap[op->bank], size); break; |
860 case DT_SCREEN_RAM: memcpy(dst, img->screen[op->bank], size); break; | 942 case DT_SCREEN_RAM: memcpy(dst, img->screen[op->bank], size); break; |
943 case DT_CHAR_DATA: memcpy(dst, img->charmem[op->bank], size); break; | |
861 case DT_EXTRADATA: memcpy(dst, img->extradata, size); break; | 944 case DT_EXTRADATA: memcpy(dst, img->extradata, size); break; |
862 case DT_CHAR_DATA: memcpy(dst, img->charmem, size); break; | |
863 | 945 |
864 case DT_COLOR_REG: | 946 case DT_COLOR_REG: |
865 switch (op->size) | 947 switch (op->size) |
866 { | 948 { |
867 case DC_D020: *dst = img->d020; break; | 949 case DC_D020: *dst = img->d020; break; |
936 | 1018 |
937 // Sanity check arguments | 1019 // Sanity check arguments |
938 if (dst == NULL || src == NULL) | 1020 if (dst == NULL || src == NULL) |
939 return DMERR_NULLPTR; | 1021 return DMERR_NULLPTR; |
940 | 1022 |
941 if (dst->width < 8) | 1023 if (dst->width < src->width || dst->height < src->height) |
942 return DMERR_INVALID_ARGS; | 1024 return DMERR_INVALID_DATA; |
943 | 1025 |
944 if (src->type & D64_FMT_CHAR) | 1026 memset(dst->data, 0, dst->size); |
945 for (yc = 0; yc < dst->height; yc++) | 1027 |
1028 // Perform conversion | |
1029 for (yc = 0; yc < src->height; yc++) | |
946 { | 1030 { |
947 Uint8 *d = dp; | 1031 Uint8 *d = dp; |
948 const int y = yc / 8, yb = yc & 7; | 1032 const int y = yc / 8, yb = yc & 7; |
949 const int scroffsy = y * C64_SCR_CH_WIDTH; | 1033 const int scroffsy = y * src->ch_width; |
950 int xc; | 1034 int xc; |
951 | 1035 |
952 if ((src->type & D64_FMT_MC) == D64_FMT_HIRES) | 1036 if (src->type & D64_FMT_CHAR) |
953 { | 1037 { |
1038 // Charmode conversion | |
1039 if ((src->type & D64_FMT_MC) == D64_FMT_HIRES) | |
954 // Hi-res charmap | 1040 // Hi-res charmap |
955 for (xc = 0; xc < dst->width; xc++) | 1041 for (xc = 0; xc < src->width; xc++) |
956 { | 1042 { |
957 const int x = xc / 8; | 1043 const int x = xc / 8; |
958 const int scroffs = scroffsy + x; | 1044 const int scroffs = scroffsy + x; |
959 const int chr = src->screen[0][scroffs]; | 1045 const int chr = src->screen[0][scroffs]; |
960 const int v = 7 - (xc & 7); | 1046 const int v = 7 - (xc & 7); |
961 | 1047 |
962 if ((src->charmem[chr][yb] >> v) & 1) | 1048 if ((src->charmem[0][chr * C64_CHR_SIZE + yb] >> v) & 1) |
963 *d++ = src->color[0][scroffs]; | 1049 *d++ = src->color[0][scroffs]; |
964 else | 1050 else |
965 *d++ = src->bgcolor; | 1051 *d++ = src->bgcolor; |
966 } | 1052 } |
967 } | 1053 else |
968 else | |
969 { | |
970 // Multicolor variants | 1054 // Multicolor variants |
971 for (xc = 0; xc < dst->width / wdivisor; xc++) | 1055 for (xc = 0; xc < src->width / wdivisor; xc++) |
972 { | 1056 { |
973 const int x = xc / 4; | 1057 const int x = xc / 4; |
974 const int scroffs = scroffsy + x; | 1058 const int scroffs = scroffsy + x; |
975 const int chr = src->screen[0][scroffs]; | 1059 const int chr = src->screen[0][scroffs]; |
976 const int v = 6 - ((xc * 2) & 6); | 1060 const int v = 6 - ((xc * 2) & 6); |
977 Uint8 c; | 1061 Uint8 c; |
978 | 1062 |
979 switch ((src->charmem[chr][yb] >> v) & 3) | 1063 switch ((src->charmem[0][chr * C64_CHR_SIZE + yb] >> v) & 3) |
980 { | 1064 { |
981 case 0: c = src->bgcolor; break; | 1065 case 0: c = src->bgcolor; break; |
982 case 1: c = src->d022; break; | 1066 case 1: c = src->d022; break; |
983 case 2: c = src->d023; break; | 1067 case 2: c = src->d023; break; |
984 case 3: c = src->color[0][scroffs]; | 1068 case 3: c = src->color[0][scroffs]; |
987 *d++ = c; | 1071 *d++ = c; |
988 if (doubleMC) | 1072 if (doubleMC) |
989 *d++ = c; | 1073 *d++ = c; |
990 } | 1074 } |
991 } | 1075 } |
992 dp += dst->pitch; | 1076 else |
993 } | 1077 { |
994 else | 1078 // Perform generic BITMAP conversion |
995 // Perform generic BITMAP conversion | 1079 const int bmoffsy = y * src->width; |
996 for (yc = 0; yc < dst->height; yc++) | 1080 |
997 { | 1081 if ((src->type & D64_FMT_MC) == D64_FMT_HIRES) |
998 Uint8 *d = dp; | |
999 const int y = yc / 8, yb = yc & 7; | |
1000 const int scroffsy = y * C64_SCR_CH_WIDTH; | |
1001 const int bmoffsy = y * C64_SCR_WIDTH; | |
1002 int xc; | |
1003 | |
1004 if ((src->type & D64_FMT_MC) == D64_FMT_HIRES) | |
1005 { | |
1006 // Hi-res bitmap | 1082 // Hi-res bitmap |
1007 for (xc = 0; xc < dst->width; xc++) | 1083 for (xc = 0; xc < src->width; xc++) |
1008 { | 1084 { |
1009 const int x = xc / 8; | 1085 const int x = xc / 8; |
1010 const int scroffs = scroffsy + x; | 1086 const int scroffs = scroffsy + x; |
1011 const int bmoffs = bmoffsy + (x * 8) + yb; | 1087 const int bmoffs = bmoffsy + (x * 8) + yb; |
1012 const int v = 7 - (xc & 7); | 1088 const int v = 7 - (xc & 7); |
1014 if ((src->bitmap[0][bmoffs] >> v) & 1) | 1090 if ((src->bitmap[0][bmoffs] >> v) & 1) |
1015 *d++ = src->screen[0][scroffs] >> 4; | 1091 *d++ = src->screen[0][scroffs] >> 4; |
1016 else | 1092 else |
1017 *d++ = src->screen[0][scroffs] & 15; | 1093 *d++ = src->screen[0][scroffs] & 15; |
1018 } | 1094 } |
1019 } | 1095 else |
1020 else | 1096 // Multicolor bitmap and variants |
1021 { | 1097 for (xc = 0; xc < src->width / wdivisor; xc++) |
1022 // Multicolor variants | |
1023 for (xc = 0; xc < dst->width / wdivisor; xc++) | |
1024 { | 1098 { |
1025 const int x = xc / 4; | 1099 const int x = xc / 4; |
1026 const int scroffs = scroffsy + x; | 1100 const int scroffs = scroffsy + x; |
1027 const int bmoffs = bmoffsy + (x * 8) + yb; | 1101 const int bmoffs = bmoffsy + (x * 8) + yb; |
1028 const int v = 6 - ((xc * 2) & 6); | 1102 const int v = 6 - ((xc * 2) & 6); |
1102 | 1176 |
1103 return res; | 1177 return res; |
1104 } | 1178 } |
1105 | 1179 |
1106 | 1180 |
1107 int dmC64DecodeBMP(DMC64Image *img, const Uint8 *buf, const size_t len, | 1181 int dmC64DecodeBMP(DMC64Image **img, const Uint8 *buf, const size_t len, |
1108 const size_t probeOffs, const size_t loadOffs, | 1182 const size_t probeOffs, const size_t loadOffs, |
1109 const DMC64ImageFormat **fmt, const DMC64ImageFormat *forced) | 1183 const DMC64ImageFormat **fmt, const DMC64ImageFormat *forced) |
1110 { | 1184 { |
1185 if (img == NULL) | |
1186 return DMERR_NULLPTR; | |
1187 | |
1111 // Check for forced format | 1188 // Check for forced format |
1112 if (forced != NULL) | 1189 if (forced != NULL) |
1113 *fmt = forced; | 1190 *fmt = forced; |
1114 else | 1191 else |
1115 { | 1192 { |
1116 // Nope, perform a generic probe | 1193 // Nope, perform a generic probe |
1117 if (probeOffs >= len) | 1194 if (probeOffs >= len) |
1118 return -200; | 1195 return DMERR_INVALID_DATA; |
1119 | 1196 |
1120 if (dmC64ProbeBMP(buf + probeOffs, len - probeOffs, fmt) == DM_PROBE_SCORE_FALSE) | 1197 if (dmC64ProbeBMP(buf + probeOffs, len - probeOffs, fmt) == DM_PROBE_SCORE_FALSE) |
1121 return -201; | 1198 return DMERR_INVALID_DATA; |
1122 } | 1199 } |
1123 | 1200 |
1124 if (loadOffs >= len) | 1201 if (loadOffs >= len) |
1125 return -203; | 1202 return DMERR_INVALID_ARGS; |
1203 | |
1204 if (*fmt == NULL) | |
1205 return DMERR_INVALID_DATA; | |
1206 | |
1207 // Allocate memory | |
1208 if ((*img = dmC64ImageAlloc((*fmt)->width, (*fmt)->height, | |
1209 (*fmt)->ch_width, (*fmt)->ch_height)) == NULL) | |
1210 return DMERR_MALLOC; | |
1126 | 1211 |
1127 // Decode the bitmap to memory layout | 1212 // Decode the bitmap to memory layout |
1128 if ((*fmt)->decode != NULL) | 1213 if ((*fmt)->decode != NULL) |
1129 return (*fmt)->decode(img, buf + loadOffs, len - loadOffs, *fmt); | 1214 return (*fmt)->decode(*img, buf + loadOffs, len - loadOffs, *fmt); |
1130 else | 1215 else |
1131 return dmC64DecodeGenericBMP(img, buf + loadOffs, len - loadOffs, *fmt); | 1216 return dmC64DecodeGenericBMP(*img, buf + loadOffs, len - loadOffs, *fmt); |
1132 } | 1217 } |