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 }