Mercurial > hg > dmlib
comparison tools/lib64fmts.c @ 2150:b4fbb90937f7
Fix Cosmos Designs Hires Manager unpacker. What a mess. Ugh.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 04 Jun 2019 15:00:58 +0300 |
parents | 810fc98d9003 |
children | 0a7ebb7198e3 |
comparison
equal
deleted
inserted
replaced
2149:810fc98d9003 | 2150:b4fbb90937f7 |
---|---|
979 | 979 |
980 | 980 |
981 static int fmtDecodeCosmosDesignsHiresManagerPacked(DMC64Image *img, const DMGrowBuf *psrc, const DMC64ImageFormat *fmt) | 981 static int fmtDecodeCosmosDesignsHiresManagerPacked(DMC64Image *img, const DMGrowBuf *psrc, const DMC64ImageFormat *fmt) |
982 { | 982 { |
983 int res; | 983 int res; |
984 DMGrowBuf src, tmp; | 984 DMGrowBuf tmp; |
985 DMCompParams cfg; | 985 Uint8 data, *dstBuf; |
986 Uint8 data, count, *dstBuf; | 986 const size_t baseAddr = 0x4000; |
987 const size_t dstSize = 0x7ff2 - 0x4000; | 987 const size_t dstSize = 0x8000 - baseAddr; |
988 size_t dstOffs; | 988 size_t dstOffs, srcOffs; |
989 BOOL getByte = TRUE; | |
990 | |
991 // Setup the RLE config, only for input | |
992 cfg.func = fmt->name; | |
993 cfg.type = DM_COMP_RLE_MARKER; | |
994 cfg.flags = DM_RLE_BACKWARDS_INPUT; | |
995 | 989 |
996 // Allocate output buffer | 990 // Allocate output buffer |
997 if ((dstBuf = dmMalloc0(dstSize)) == NULL) | 991 if ((dstBuf = dmMalloc0(dstSize)) == NULL) |
998 { | 992 { |
999 return dmError(DMERR_MALLOC, | 993 return dmError(DMERR_MALLOC, |
1000 "%s: Could not allocate memory for RLE decoding buffer.\n", | 994 "Could not allocate memory for RLE decoding buffer.\n"); |
1001 cfg.func); | |
1002 } | 995 } |
1003 | 996 |
1004 // Setup input buffer | 997 // Setup input buffer |
1005 dmGrowBufConstCopy(&src, psrc); | 998 dstOffs = 0x7ff2 - baseAddr - 1; |
1006 dmSetupRLEBuffers(NULL, &src, &cfg); | 999 srcOffs = psrc->len - 1; |
1007 dstOffs = dstSize; | 1000 |
1008 | 1001 while (dstOffs > 0 && srcOffs > 0) |
1009 while (dstOffs > 0 && src.offs > 0) | 1002 { |
1010 { | 1003 data = psrc->data[srcOffs]; |
1011 if (getByte && !dmGrowBufGetU8(&src, &data)) | 1004 |
1012 { | 1005 |
1013 res = dmError(DMERR_INVALID_DATA, | 1006 // Current data byte tells us the mode |
1014 "%s: RLE: Invalid data/out of data for literal sequence.\n", | |
1015 cfg.func); | |
1016 goto out; | |
1017 } | |
1018 | |
1019 // A simple marker byte RLE variant: [Marker] [count] [data] | |
1020 if (data == 0) | 1007 if (data == 0) |
1021 { | 1008 { |
1022 if (!dmGrowBufGetU8(&src, &count) || | 1009 // RLE run |
1023 !dmGrowBufGetU8(&src, &data)) | 1010 if (srcOffs < 3) |
1024 { | 1011 { |
1025 res = dmError(DMERR_INVALID_DATA, | 1012 res = dmError(DMERR_INVALID_DATA, |
1026 "%s: RLE: Invalid data/out of data for run sequence.\n", | 1013 "RLE: Invalid data/out of data for run sequence.\n"); |
1027 cfg.func); | |
1028 goto out; | 1014 goto out; |
1029 } | 1015 } |
1030 | 1016 |
1031 int ncount = (int) count; | 1017 size_t ncount = psrc->data[--srcOffs]; |
1032 for (int n = 1; n < ncount && dstOffs > 0; n++) | 1018 data = psrc->data[--srcOffs]; |
1033 dstBuf[--dstOffs] = data; | 1019 |
1034 | 1020 srcOffs--; |
1035 getByte = TRUE; | 1021 |
1022 if (dstOffs < ncount) | |
1023 goto finish; | |
1024 | |
1025 dstOffs -= ncount; | |
1026 ncount++; | |
1027 for (size_t n = 0; n < ncount; n++) | |
1028 dstBuf[dstOffs + n] = data; | |
1036 } | 1029 } |
1037 else | 1030 else |
1038 // Literal run of data bytes | 1031 { |
1039 { | 1032 // Literal run of data bytes |
1040 int ncount = (int) data; | 1033 size_t ncount = data; |
1041 for (int n = 0; n < ncount; n++) | 1034 if (srcOffs < ncount) |
1042 { | 1035 ncount = srcOffs; |
1043 if (!dmGrowBufGetU8(&src, &data)) | 1036 |
1044 goto finish; | 1037 if (dstOffs < ncount) |
1045 | 1038 ncount = dstOffs; |
1046 if (dstOffs > 0) | 1039 |
1047 dstBuf[--dstOffs] = data; | 1040 srcOffs -= ncount; |
1048 else | 1041 dstOffs -= ncount - 1; |
1049 goto finish; | 1042 |
1043 for (size_t n = 0; n < ncount; n++) | |
1044 { | |
1045 data = psrc->data[srcOffs + n]; | |
1046 dstBuf[dstOffs + n] = data; | |
1050 } | 1047 } |
1051 getByte = FALSE; | |
1052 } | 1048 } |
1053 } | 1049 } |
1054 | 1050 |
1055 finish: | 1051 finish: |
1056 | 1052 |
1057 dmGrowBufConstCreateFrom(&tmp, dstBuf, 0x3fff); | 1053 dmGrowBufConstCreateFrom(&tmp, dstBuf, dstSize); |
1058 res = dmC64DecodeGenericBMP(img, &tmp, fmt); | 1054 res = dmC64DecodeGenericBMP(img, &tmp, fmt); |
1059 | 1055 |
1060 out: | 1056 out: |
1061 dmGrowBufFree(&src); | |
1062 dmFree(dstBuf); | 1057 dmFree(dstBuf); |
1063 return res; | 1058 return res; |
1064 } | 1059 } |
1065 | 1060 |
1066 | 1061 |