Mercurial > hg > dmlib
comparison tools/lib64gfx.c @ 2388:2dbbc1c91231
Refactor error handling in dmC64DecodeGenericBMP() and
dmC64EncodeGenericBMP() by adding helper functions dmC64EncDecError() and
dmC64EncDecErrorMsg() and using them through out.
Also various printf() format specifier fixes.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Thu, 09 Jan 2020 20:11:41 +0200 |
parents | f543475ea0eb |
children | 0b1928ed902f |
comparison
equal
deleted
inserted
replaced
2387:68efae89c034 | 2388:2dbbc1c91231 |
---|---|
867 | 867 |
868 return NULL; | 868 return NULL; |
869 } | 869 } |
870 | 870 |
871 | 871 |
872 typedef struct | |
873 { | |
874 int opn; | |
875 const DMC64EncDecOp *op; | |
876 size_t size; | |
877 const DMGrowBuf *buf; | |
878 const char *subjname; | |
879 } DMC64EncDecCtx; | |
880 | |
881 | |
882 static void dmC64EncDecErrorMsg(DMC64EncDecCtx *ctx, const char *msg) | |
883 { | |
884 dmErrorMsg( | |
885 "%s in op #%d, subject='%s', " | |
886 "offs=%d ($%04x), bank=%d, " | |
887 "size=%" DM_PRIu_SIZE_T " ($%04" DM_PRIx_SIZE_T ") " | |
888 "@ %" DM_PRIu_SIZE_T " ($%04" DM_PRIx_SIZE_T ")\n", | |
889 msg, ctx->opn, ctx->subjname, | |
890 ctx->op->offs, ctx->op->offs, | |
891 ctx->op->bank, | |
892 ctx->size, ctx->size, | |
893 ctx->buf->len, ctx->buf->len); | |
894 } | |
895 | |
896 | |
897 DM_ATTR_PRINTF_FMT(3, 4) | |
898 static int dmC64EncDecError(DMC64EncDecCtx *ctx, const int res, const char *fmt, ...) | |
899 { | |
900 char *msg; | |
901 va_list ap; | |
902 | |
903 va_start(ap, fmt); | |
904 msg = dm_strdup_vprintf(fmt, ap); | |
905 va_end(ap); | |
906 | |
907 dmC64EncDecErrorMsg(ctx, msg); | |
908 | |
909 dmFree(msg); | |
910 return res; | |
911 } | |
912 | |
913 | |
872 int dmC64DecodeGenericBMP(DMC64Image *img, const DMGrowBuf *buf, const DMC64ImageFormat *fmt) | 914 int dmC64DecodeGenericBMP(DMC64Image *img, const DMGrowBuf *buf, const DMC64ImageFormat *fmt) |
873 { | 915 { |
916 DMC64EncDecCtx ctx; | |
874 int res = DMERR_OK; | 917 int res = DMERR_OK; |
875 | 918 |
876 if (buf == NULL || buf->data == NULL || img == NULL || fmt == NULL) | 919 if (buf == NULL || buf->data == NULL || img == NULL || fmt == NULL) |
877 return DMERR_NULLPTR; | 920 return DMERR_NULLPTR; |
878 | 921 |
879 dmC64SetupImageData(img, fmt); | 922 dmC64SetupImageData(img, fmt); |
880 | 923 |
881 // Perform decoding | 924 // Perform decoding |
882 for (int i = 0; i < D64_MAX_ENCDEC_OPS; i++) | 925 for (ctx.opn = 0; ctx.opn < D64_MAX_ENCDEC_OPS; ctx.opn++) |
883 { | 926 { |
884 const DMC64EncDecOp *op = fmtGetEncDecOp(fmt, i); | 927 DMC64MemBlock *blk = NULL; |
885 const Uint8 *src; | 928 const Uint8 *src; |
886 DMC64MemBlock *blk = NULL; | |
887 const char *subjname = dmC64GetOpSubjectName(op->subject); | |
888 size_t size; | |
889 Uint8 value; | 929 Uint8 value; |
890 | 930 |
931 ctx.op = fmtGetEncDecOp(fmt, ctx.opn); | |
932 ctx.subjname = dmC64GetOpSubjectName(ctx.op->subject); | |
933 | |
891 // Check for last operator | 934 // Check for last operator |
892 if (op->type == DO_LAST) | 935 if (ctx.op->type == DO_LAST) |
893 break; | 936 break; |
894 | 937 |
895 // Check operation validity | 938 // Check operation validity |
896 if ((res = dmC64SanityCheckEncDecOp(i, op, img)) != DMERR_OK) | 939 if ((res = dmC64SanityCheckEncDecOp(ctx.opn, ctx.op, img)) != DMERR_OK) |
897 return res; | 940 return res; |
898 | 941 |
899 // Check flags | 942 // Check flags |
900 if ((op->flags & DF_DECODE) == 0) | 943 if ((ctx.op->flags & DF_DECODE) == 0) |
901 continue; | 944 continue; |
902 | 945 |
903 // Is the operation inside the bounds? | 946 // Is the operation inside the bounds? |
904 size = dmC64GetOpSubjectSize(op, fmt->format); | 947 ctx.size = dmC64GetOpSubjectSize(ctx.op, fmt->format); |
905 if (op->type == DO_COPY && op->offs + size > buf->len + 1) | 948 if (ctx.op->type == DO_COPY && ctx.op->offs + ctx.size > buf->len + 1) |
906 { | 949 { |
907 return dmError(DMERR_INVALID_DATA, | 950 return dmC64EncDecError(&ctx, DMERR_INVALID_DATA, |
908 "Decode SRC out of bounds, op #%d type=%s, subj=%s, offs=%d ($%04x), " | 951 "Decode SRC out of bounds"); |
909 "bank=%d, size=%d ($%04x) @ %d ($%04x)\n", | 952 } |
910 i, dmC64GetOpType(op->type), subjname, op->offs, op->offs, op->bank, | 953 |
911 size, size, buf->len, buf->len); | 954 src = buf->data + ctx.op->offs; |
912 } | |
913 | |
914 src = buf->data + op->offs; | |
915 | 955 |
916 // Perform operation | 956 // Perform operation |
917 switch (op->type) | 957 switch (ctx.op->type) |
918 { | 958 { |
919 case DO_COPY: | 959 case DO_COPY: |
920 case DO_SET_MEM: | 960 case DO_SET_MEM: |
921 case DO_SET_MEM_HI: | 961 case DO_SET_MEM_HI: |
922 case DO_SET_MEM_LO: | 962 case DO_SET_MEM_LO: |
923 case DO_SET_OP: | 963 case DO_SET_OP: |
924 switch (op->subject) | 964 switch (ctx.op->subject) |
925 { | 965 { |
926 case DS_COLOR_RAM: | 966 case DS_COLOR_RAM: |
927 case DS_SCREEN_RAM: | 967 case DS_SCREEN_RAM: |
928 case DS_BITMAP_RAM: | 968 case DS_BITMAP_RAM: |
929 case DS_CHAR_DATA: | 969 case DS_CHAR_DATA: |
930 case DS_EXTRA_DATA: | 970 case DS_EXTRA_DATA: |
931 // XXX BZZZT .. a nasty cast here | 971 // XXX BZZZT .. a nasty cast here |
932 blk = (DMC64MemBlock *) dmC64GetOpMemBlock(img, op->subject, op->bank); | 972 blk = (DMC64MemBlock *) dmC64GetOpMemBlock(img, ctx.op->subject, ctx.op->bank); |
933 | 973 |
934 if ((dmC64MemBlockReAlloc(blk, op->blkoffs + size)) != DMERR_OK) | 974 if ((dmC64MemBlockReAlloc(blk, ctx.op->blkoffs + ctx.size)) != DMERR_OK) |
935 { | 975 { |
936 return dmError(DMERR_MALLOC, | 976 return dmC64EncDecError(&ctx, DMERR_MALLOC, |
937 "Could not allocate '%s' block! " | 977 "Could not allocate '%s' block", |
938 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", | 978 ctx.subjname); |
939 subjname, i, op->offs, op->offs, op->bank, | |
940 op->blkoffs + size, op->blkoffs + size, buf->len, buf->len); | |
941 } | 979 } |
942 switch (op->type) | 980 switch (ctx.op->type) |
943 { | 981 { |
944 case DO_COPY: | 982 case DO_COPY: |
945 memcpy(blk->data + op->blkoffs, src, size); | 983 memcpy(blk->data + ctx.op->blkoffs, src, ctx.size); |
946 break; | 984 break; |
947 | 985 |
948 case DO_SET_MEM: | 986 case DO_SET_MEM: |
949 dmMemset(blk->data + op->blkoffs, *src, size); | 987 dmMemset(blk->data + ctx.op->blkoffs, *src, ctx.size); |
950 break; | 988 break; |
951 | 989 |
952 case DO_SET_MEM_HI: | 990 case DO_SET_MEM_HI: |
953 dmMemset(blk->data + op->blkoffs, (*src >> 4) & 0x0f, size); | 991 dmMemset(blk->data + ctx.op->blkoffs, (*src >> 4) & 0x0f, ctx.size); |
954 break; | 992 break; |
955 | 993 |
956 case DO_SET_MEM_LO: | 994 case DO_SET_MEM_LO: |
957 dmMemset(blk->data + op->blkoffs, *src & 0x0f, size); | 995 dmMemset(blk->data + ctx.op->blkoffs, *src & 0x0f, ctx.size); |
958 break; | 996 break; |
959 | 997 |
960 case DO_SET_OP: | 998 case DO_SET_OP: |
961 dmMemset(blk->data + op->blkoffs, op->offs, size); | 999 dmMemset(blk->data + ctx.op->blkoffs, ctx.op->offs, ctx.size); |
962 break; | 1000 break; |
963 | 1001 |
964 default: | 1002 default: |
965 return dmError(DMERR_INTERNAL, | 1003 return dmC64EncDecError(&ctx, DMERR_INTERNAL, |
966 "Unhandled op type %s in " | 1004 "Unhandled op type '%s'", |
967 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", | 1005 dmC64GetOpType(ctx.op->type)); |
968 dmC64GetOpType(op->type), i, op->offs, op->offs, op->bank, | |
969 size, size, buf->len, buf->len); | |
970 } | 1006 } |
971 break; | 1007 break; |
972 | 1008 |
973 case DS_D020: | 1009 case DS_D020: |
974 case DS_BGCOL: | 1010 case DS_BGCOL: |
975 case DS_D021: | 1011 case DS_D021: |
976 case DS_D022: | 1012 case DS_D022: |
977 case DS_D023: | 1013 case DS_D023: |
978 case DS_D024: | 1014 case DS_D024: |
979 case DS_EXTRA_INFO: | 1015 case DS_EXTRA_INFO: |
980 switch (op->type) | 1016 switch (ctx.op->type) |
981 { | 1017 { |
982 case DO_COPY: | 1018 case DO_COPY: |
983 case DO_SET_MEM: | 1019 case DO_SET_MEM: |
984 value = *src; | 1020 value = *src; |
985 break; | 1021 break; |
986 | 1022 |
987 case DO_SET_OP: | 1023 case DO_SET_OP: |
988 value = op->offs; | 1024 value = ctx.op->offs; |
989 break; | 1025 break; |
990 | 1026 |
991 case DO_SET_MEM_HI: | 1027 case DO_SET_MEM_HI: |
992 value = (*src >> 4) & 0x0f; | 1028 value = (*src >> 4) & 0x0f; |
993 break; | 1029 break; |
995 case DO_SET_MEM_LO: | 1031 case DO_SET_MEM_LO: |
996 value = *src & 0x0f; | 1032 value = *src & 0x0f; |
997 break; | 1033 break; |
998 | 1034 |
999 default: | 1035 default: |
1000 return dmError(DMERR_INTERNAL, | 1036 return dmC64EncDecError(&ctx, DMERR_INTERNAL, |
1001 "Unhandled op type %s in " | 1037 "Unhandled op type '%s'", |
1002 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", | 1038 dmC64GetOpType(ctx.op->type)); |
1003 dmC64GetOpType(op->type), i, op->offs, op->offs, | |
1004 op->bank, size, size, buf->len, buf->len); | |
1005 } | 1039 } |
1006 switch (op->subject) | 1040 switch (ctx.op->subject) |
1007 { | 1041 { |
1008 case DS_D020: img->d020 = value; break; | 1042 case DS_D020: img->d020 = value; break; |
1009 case DS_BGCOL: | 1043 case DS_BGCOL: |
1010 case DS_D021: img->bgcolor = value; break; | 1044 case DS_D021: img->bgcolor = value; break; |
1011 case DS_D022: img->d022 = value; break; | 1045 case DS_D022: img->d022 = value; break; |
1012 case DS_D023: img->d023 = value; break; | 1046 case DS_D023: img->d023 = value; break; |
1013 case DS_D024: img->d024 = value; break; | 1047 case DS_D024: img->d024 = value; break; |
1014 case DS_EXTRA_INFO: img->extraInfo[op->blkoffs] = value; break; | 1048 case DS_EXTRA_INFO: img->extraInfo[ctx.op->blkoffs] = value; break; |
1015 } | 1049 } |
1016 break; | 1050 break; |
1017 | 1051 |
1018 default: | 1052 default: |
1019 return dmError(DMERR_INTERNAL, | 1053 return dmC64EncDecError(&ctx, DMERR_INTERNAL, |
1020 "Unhandled subject %d in " | 1054 "Unhandled subject '%s'", |
1021 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", | 1055 ctx.subjname); |
1022 op->subject, i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); | |
1023 } | 1056 } |
1024 break; | 1057 break; |
1025 | 1058 |
1026 case DO_CHAR_CFG: | 1059 case DO_CHAR_CFG: |
1027 switch (op->subject) | 1060 switch (ctx.op->subject) |
1028 { | 1061 { |
1029 case D64_CHCFG_SCREEN: | 1062 case D64_CHCFG_SCREEN: |
1030 break; | 1063 break; |
1031 | 1064 |
1032 case D64_CHCFG_LINEAR: | 1065 case D64_CHCFG_LINEAR: |
1036 img->screen[bank].data[offs] = offs & 0xff; | 1069 img->screen[bank].data[offs] = offs & 0xff; |
1037 } | 1070 } |
1038 break; | 1071 break; |
1039 | 1072 |
1040 default: | 1073 default: |
1041 return dmError(DMERR_INTERNAL, | 1074 return dmC64EncDecError(&ctx, DMERR_INTERNAL, |
1042 "Unhandled DO_CHAR_CFG mode %d in ", | 1075 "Unhandled DO_CHAR_CFG mode %d", |
1043 "op #%d, bank=%d, size=%d ($%04x) @ %d ($%04x)\n", | 1076 ctx.op->subject); |
1044 op->subject, i, op->bank, size, size, buf->len, buf->len); | |
1045 } | 1077 } |
1046 break; | 1078 break; |
1047 | 1079 |
1048 case DO_FUNC: | 1080 case DO_FUNC: |
1049 if (op->decFunction != NULL && | 1081 if (ctx.op->decFunction != NULL && |
1050 (res = op->decFunction(op, img, buf, fmt->format)) != DMERR_OK) | 1082 (res = ctx.op->decFunction(ctx.op, img, buf, fmt->format)) != DMERR_OK) |
1051 { | 1083 { |
1052 return dmError(res, | 1084 return dmC64EncDecError(&ctx, res, |
1053 "Decode op custom function failed: op #%d, " | 1085 "Decode op custom function failed"); |
1054 "offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", | |
1055 i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); | |
1056 } | 1086 } |
1057 break; | 1087 break; |
1058 } | 1088 } |
1059 } | 1089 } |
1060 | 1090 |
1071 } | 1101 } |
1072 | 1102 |
1073 | 1103 |
1074 int dmC64EncodeGenericBMP(const BOOL allocate, DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt) | 1104 int dmC64EncodeGenericBMP(const BOOL allocate, DMGrowBuf *buf, const DMC64Image *img, const DMC64ImageFormat *fmt) |
1075 { | 1105 { |
1106 DMC64EncDecCtx ctx; | |
1076 int res = DMERR_OK; | 1107 int res = DMERR_OK; |
1077 | 1108 |
1078 if (img == NULL || fmt == NULL) | 1109 if (img == NULL || fmt == NULL) |
1079 return DMERR_NULLPTR; | 1110 return DMERR_NULLPTR; |
1080 | 1111 |
1081 // Allocate the output buffer if requested | 1112 // Allocate the output buffer if requested |
1082 if (allocate && (res = dmGrowBufAlloc(buf, BUF_SIZE_INITIAL, BUF_SIZE_GROW)) != DMERR_OK) | 1113 if (allocate && (res = dmGrowBufAlloc(buf, BUF_SIZE_INITIAL, BUF_SIZE_GROW)) != DMERR_OK) |
1083 { | 1114 { |
1084 dmError(res, | 1115 return dmError(res, |
1085 "Could not allocate %d bytes of memory for C64 image encoding buffer.\n", | 1116 "Could not allocate %" DM_PRIu_SIZE_T " bytes of memory for C64 image encoding buffer.\n", |
1086 fmt->size); | 1117 fmt->size); |
1087 goto out; | |
1088 } | 1118 } |
1089 | 1119 |
1090 if (buf->backwards) | 1120 if (buf->backwards) |
1091 { | 1121 { |
1092 dmError(DMERR_INVALID_DATA, | 1122 return dmError(DMERR_INVALID_DATA, |
1093 "Buffer specified for dmC64EncodeGenericBMP() is in backwards mode, which is not supported.\n"); | 1123 "Buffer specified for dmC64EncodeGenericBMP() is in backwards mode, which is not supported.\n"); |
1094 goto out; | |
1095 } | 1124 } |
1096 | 1125 |
1097 // Perform encoding | 1126 // Perform encoding |
1098 for (int i = 0; i < D64_MAX_ENCDEC_OPS; i++) | 1127 for (ctx.opn = 0; ctx.opn < D64_MAX_ENCDEC_OPS; ctx.opn++) |
1099 { | 1128 { |
1100 const DMC64EncDecOp *op = fmtGetEncDecOp(fmt, i); | |
1101 size_t size, chksize; | |
1102 const DMC64MemBlock *blk = NULL; | 1129 const DMC64MemBlock *blk = NULL; |
1103 const char *subjname = dmC64GetOpSubjectName(op->subject); | 1130 size_t chksize; |
1104 Uint8 value; | 1131 Uint8 value; |
1105 | 1132 |
1133 ctx.op = fmtGetEncDecOp(fmt, ctx.opn); | |
1134 ctx.subjname = dmC64GetOpSubjectName(ctx.op->subject); | |
1135 | |
1106 // Check for last operator | 1136 // Check for last operator |
1107 if (op->type == DO_LAST) | 1137 if (ctx.op->type == DO_LAST) |
1108 break; | 1138 break; |
1109 | 1139 |
1110 // Check operation validity | 1140 // Check operation validity |
1111 if ((res = dmC64SanityCheckEncDecOp(i, op, img)) != DMERR_OK) | 1141 if ((res = dmC64SanityCheckEncDecOp(ctx.opn, ctx.op, img)) != DMERR_OK) |
1112 goto out; | 1142 return res; |
1113 | 1143 |
1114 // Check flags | 1144 // Check flags |
1115 if ((op->flags & DF_ENCODE) == 0) | 1145 if ((ctx.op->flags & DF_ENCODE) == 0) |
1116 continue; | 1146 continue; |
1117 | 1147 |
1118 // Do we need to reallocate some more space? | 1148 // Do we need to reallocate some more space? |
1119 size = dmC64GetOpSubjectSize(op, fmt->format); | 1149 ctx.size = dmC64GetOpSubjectSize(ctx.op, fmt->format); |
1120 chksize = buf->offs + op->offs + size; | 1150 chksize = buf->offs + ctx.op->offs + ctx.size; |
1121 if (!dmGrowBufCheckGrow(buf, chksize)) | 1151 if (!dmGrowBufCheckGrow(buf, chksize)) |
1122 { | 1152 { |
1123 res = dmError(DMERR_MALLOC, | 1153 return dmError(DMERR_MALLOC, |
1124 "Could not re-allocate %d bytes of memory for C64 image encoding buffer.\n", | 1154 "Could not re-allocate %" DM_PRIu_SIZE_T " bytes of memory for C64 image encoding buffer.\n", |
1125 chksize); | 1155 chksize); |
1126 goto out; | |
1127 } | 1156 } |
1128 | 1157 |
1129 // Perform operation | 1158 // Perform operation |
1130 Uint8 *dst = buf->data + buf->offs + op->offs; | 1159 Uint8 *dst = buf->data + buf->offs + ctx.op->offs; |
1131 switch (op->type) | 1160 switch (ctx.op->type) |
1132 { | 1161 { |
1133 case DO_COPY: | 1162 case DO_COPY: |
1134 case DO_SET_MEM: | 1163 case DO_SET_MEM: |
1135 case DO_SET_MEM_HI: | 1164 case DO_SET_MEM_HI: |
1136 case DO_SET_MEM_LO: | 1165 case DO_SET_MEM_LO: |
1137 case DO_SET_OP: | 1166 case DO_SET_OP: |
1138 switch (op->subject) | 1167 switch (ctx.op->subject) |
1139 { | 1168 { |
1140 case DS_COLOR_RAM: | 1169 case DS_COLOR_RAM: |
1141 case DS_SCREEN_RAM: | 1170 case DS_SCREEN_RAM: |
1142 case DS_BITMAP_RAM: | 1171 case DS_BITMAP_RAM: |
1143 case DS_CHAR_DATA: | 1172 case DS_CHAR_DATA: |
1144 case DS_EXTRA_DATA: | 1173 case DS_EXTRA_DATA: |
1145 blk = dmC64GetOpMemBlock(img, op->subject, op->bank); | 1174 blk = dmC64GetOpMemBlock(img, ctx.op->subject, ctx.op->bank); |
1146 switch (op->type) | 1175 switch (ctx.op->type) |
1147 { | 1176 { |
1148 case DO_COPY: | 1177 case DO_COPY: |
1149 if (blk->data == NULL) | 1178 if (blk->data == NULL) |
1150 { | 1179 { |
1151 res = dmError(DMERR_NULLPTR, | 1180 return dmC64EncDecError(&ctx, DMERR_NULLPTR, |
1152 "'%s' block is NULL in " | 1181 "'%s' block is NULL", |
1153 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", | 1182 ctx.subjname); |
1154 subjname, i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); | |
1155 goto out; | |
1156 } | 1183 } |
1157 if (op->blkoffs + size > blk->size) | 1184 if (ctx.op->blkoffs + ctx.size > blk->size) |
1158 { | 1185 { |
1159 res = dmError(DMERR_INTERNAL, | 1186 return dmC64EncDecError(&ctx, DMERR_INTERNAL, |
1160 "'%s' size mismatch %d <> %d in " | 1187 "'%s' size mismatch %" DM_PRIu_SIZE_T " <> %" DM_PRIu_SIZE_T, |
1161 "op #%d, offs=%d ($%04x), bank=%d, offs2=%d ($%02x), size=%d ($%04x)\n", | 1188 ctx.subjname, ctx.op->blkoffs + ctx.size, blk->size); |
1162 subjname, op->blkoffs + size, blk->size, i, op->offs, op->offs, op->bank, op->blkoffs, op->blkoffs, size, size); | |
1163 goto out; | |
1164 } | 1189 } |
1165 memcpy(dst, blk->data + op->blkoffs, size); | 1190 memcpy(dst, blk->data + ctx.op->blkoffs, ctx.size); |
1166 break; | 1191 break; |
1167 | 1192 |
1168 case DO_SET_MEM: | 1193 case DO_SET_MEM: |
1169 case DO_SET_MEM_HI: | 1194 case DO_SET_MEM_HI: |
1170 case DO_SET_MEM_LO: | 1195 case DO_SET_MEM_LO: |
1171 case DO_SET_OP: | 1196 case DO_SET_OP: |
1172 // This operation makes no sense in encoding, so do nothing | 1197 // This operation makes no sense in encoding, so do nothing |
1173 break; | 1198 break; |
1174 | 1199 |
1175 default: | 1200 default: |
1176 return dmError(DMERR_INTERNAL, | 1201 return dmC64EncDecError(&ctx, DMERR_INTERNAL, |
1177 "Unhandled op type %s in " | 1202 "Unhandled op type '%s'", |
1178 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", | 1203 dmC64GetOpType(ctx.op->type)); |
1179 dmC64GetOpType(op->type), i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); | |
1180 } | 1204 } |
1181 break; | 1205 break; |
1182 | 1206 |
1183 case DS_D020: | 1207 case DS_D020: |
1184 case DS_BGCOL: | 1208 case DS_BGCOL: |
1185 case DS_D021: | 1209 case DS_D021: |
1186 case DS_D022: | 1210 case DS_D022: |
1187 case DS_D023: | 1211 case DS_D023: |
1188 case DS_D024: | 1212 case DS_D024: |
1189 case DS_EXTRA_INFO: | 1213 case DS_EXTRA_INFO: |
1190 switch (op->subject) | 1214 switch (ctx.op->subject) |
1191 { | 1215 { |
1192 case DS_D020: value = img->d020; break; | 1216 case DS_D020: value = img->d020; break; |
1193 case DS_BGCOL: | 1217 case DS_BGCOL: |
1194 case DS_D021: value = img->bgcolor; break; | 1218 case DS_D021: value = img->bgcolor; break; |
1195 case DS_D022: value = img->d022; break; | 1219 case DS_D022: value = img->d022; break; |
1196 case DS_D023: value = img->d023; break; | 1220 case DS_D023: value = img->d023; break; |
1197 case DS_D024: value = img->d024; break; | 1221 case DS_D024: value = img->d024; break; |
1198 case DS_EXTRA_INFO: value = img->extraInfo[op->blkoffs]; break; | 1222 case DS_EXTRA_INFO: value = img->extraInfo[ctx.op->blkoffs]; break; |
1199 } | 1223 } |
1200 switch (op->type) | 1224 switch (ctx.op->type) |
1201 { | 1225 { |
1202 case DO_COPY: | 1226 case DO_COPY: |
1203 case DO_SET_MEM: | 1227 case DO_SET_MEM: |
1204 *dst = value; | 1228 *dst = value; |
1205 break; | 1229 break; |
1216 // Do nothing in this case | 1240 // Do nothing in this case |
1217 // XXX TODO: what about DS_EXTRA_INFO? | 1241 // XXX TODO: what about DS_EXTRA_INFO? |
1218 break; | 1242 break; |
1219 | 1243 |
1220 default: | 1244 default: |
1221 return dmError(DMERR_INTERNAL, | 1245 return dmC64EncDecError(&ctx, DMERR_INTERNAL, |
1222 "Unhandled op type %s in " | 1246 "Unhandled op type '%s'", |
1223 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", | 1247 dmC64GetOpType(ctx.op->type)); |
1224 dmC64GetOpType(op->type), i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); | |
1225 } | 1248 } |
1226 break; | 1249 break; |
1227 | 1250 |
1228 default: | 1251 default: |
1229 return dmError(DMERR_INTERNAL, | 1252 return dmC64EncDecError(&ctx, DMERR_INTERNAL, |
1230 "Unhandled subject '%s' in " | 1253 "Unhandled subject '%s'", ctx.subjname); |
1231 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", | |
1232 subjname, i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); | |
1233 } | 1254 } |
1234 break; | 1255 break; |
1235 | 1256 |
1236 case DO_FUNC: | 1257 case DO_FUNC: |
1237 if (op->encFunction != NULL && | 1258 if (ctx.op->encFunction != NULL && |
1238 (res = op->encFunction(op, buf, img, fmt->format)) != DMERR_OK) | 1259 (res = ctx.op->encFunction(ctx.op, buf, img, fmt->format)) != DMERR_OK) |
1239 { | 1260 { |
1240 dmErrorMsg( | 1261 return dmC64EncDecError(&ctx, res, |
1241 "Encode op custom function failed: op #%d, " | 1262 "Encode op custom function failed"); |
1242 "offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n", | |
1243 i, op->offs, op->offs, op->bank, size, size, buf->len, buf->len); | |
1244 goto out; | |
1245 } | 1263 } |
1246 break; | 1264 break; |
1247 } | 1265 } |
1248 } | 1266 } |
1249 | 1267 |
1250 res = DMERR_OK; | 1268 return DMERR_OK; |
1251 | |
1252 out: | |
1253 return res; | |
1254 } | 1269 } |
1255 | 1270 |
1256 | 1271 |
1257 // | 1272 // |
1258 // Helper functions for pixel format decoding | 1273 // Helper functions for pixel format decoding |
1575 int res; | 1590 int res; |
1576 | 1591 |
1577 if ((res = dmC64MemBlockAlloc(blk, size)) != DMERR_OK) | 1592 if ((res = dmC64MemBlockAlloc(blk, size)) != DMERR_OK) |
1578 { | 1593 { |
1579 return dmError(res, | 1594 return dmError(res, |
1580 "Could not allocate '%s' block with size %d bytes.\n", | 1595 "Could not allocate '%s' block with size %" DM_PRIu_SIZE_T " bytes.\n", |
1581 subjname, size); | 1596 subjname, size); |
1582 } | 1597 } |
1583 | 1598 |
1584 return DMERR_OK; | 1599 return DMERR_OK; |
1585 } | 1600 } |