comparison tools/gfxconv.c @ 1823:02f604264bc4

Improve C64 image format up/down conversion. Might actually work for some formats now.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 22 Jun 2018 12:21:54 +0300
parents 4f141426eb31
children 5639142e0b87
comparison
equal deleted inserted replaced
1822:9bec535956fd 1823:02f604264bc4
979 DMC64Image *dst; 979 DMC64Image *dst;
980 980
981 if (pdst == NULL || dstFmt == NULL || src == NULL || srcFmt == NULL) 981 if (pdst == NULL || dstFmt == NULL || src == NULL || srcFmt == NULL)
982 return DMERR_NULLPTR; 982 return DMERR_NULLPTR;
983 983
984 // Allocate the destination image
984 if ((dst = *pdst = dmC64ImageAlloc(dstFmt)) == NULL) 985 if ((dst = *pdst = dmC64ImageAlloc(dstFmt)) == NULL)
985 return DMERR_MALLOC; 986 return DMERR_MALLOC;
986 987
987 if (src->type == dst->type) 988 // Copy rest of the structure ..
988 { 989 dst->d020 = src->d020;
990 dst->bgcolor = src->bgcolor;
991 dst->d022 = src->d022;
992 dst->d023 = src->d023;
993 dst->d024 = src->d024;
994
995 // Do per opcode copies
996 for (int i = 0; i < D64_MAX_ENCDEC_OPS; i++)
997 {
998 const DMC64EncDecOp *op = fmtGetEncDecOp(dstFmt, i);
999 DMC64MemBlock *srcBlk = NULL, *dstBlk = NULL;
1000 char *blkname = NULL;
1001 size_t size;
1002
1003 if (op->type == DO_LAST)
1004 break;
1005
1006 dmC64GetOpSize(op, dstFmt, &size);
1007 switch (op->type)
1008 {
1009 case DO_COPY:
1010 case DO_SET_MEM:
1011 case DO_SET_MEM_HI:
1012 case DO_SET_MEM_LO:
1013 case DO_SET_OP:
1014 dmC64GetOpMemBlockAndName(src, op->subject, op->bank, (const DMC64MemBlock **) &srcBlk, &blkname);
1015 dmC64GetOpMemBlockAndName(dst, op->subject, op->bank, (const DMC64MemBlock **) &dstBlk, &blkname);
1016 if (srcBlk != NULL && srcBlk->data != NULL && srcBlk->size >= size)
1017 {
1018 // The block exists in source and is of sufficient size, so copy it
1019 dmMsg(2, "Copying block '%s' op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x)\n",
1020 blkname, i, op->offs, op->offs, op->bank, size, size);
1021 dmC64MemBlockCopy(dstBlk, srcBlk);
1022 }
1023 else
1024 switch (op->subject)
1025 {
1026 case DS_COLOR_RAM:
1027 case DS_SCREEN_RAM:
1028 case DS_BITMAP_RAM:
1029 case DS_CHAR_DATA:
1030 case DS_EXTRA_DATA:
1031 if ((dmC64MemBlockAlloc(dstBlk, size)) != DMERR_OK)
1032 {
1033 return dmError(DMERR_MALLOC,
1034 "Could not allocate '%s' block! "
1035 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x)\n",
1036 blkname, i, op->offs, op->offs, op->bank, size, size);
1037 }
1038 if (srcBlk->data == NULL)
1039 {
1040 dmMsg(2, "Creating block '%s' op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x)\n",
1041 blkname, i, op->offs, op->offs, op->bank, size, size);
1042 }
1043 switch (op->type)
1044 {
1045 case DO_COPY:
1046 // If some data exists, copy it. Rest is zero.
1047 // Otherwise just set to zero.
1048 if (srcBlk->data != NULL)
1049 memcpy(dstBlk->data, srcBlk->data, srcBlk->size);
1050 break;
1051
1052 case DO_SET_MEM:
1053 // Leave allocate data to zero.
1054 break;
1055
1056 case DO_SET_OP:
1057 dmMemset(dstBlk->data, op->offs, size);
1058 break;
1059
1060 default:
1061 return dmError(DMERR_INTERNAL,
1062 "Unhandled op type %d in "
1063 "op #%d, offs=%d ($%04x), bank=%d, size=%d ($%04x) @ %d ($%04x)\n",
1064 op->type, i, op->offs, op->offs, op->bank, size, size);
1065 }
1066 break;
1067 }
1068 break;
1069 }
1070 }
1071
1072 // Try to do some simple fixups
1073 if ((dst->type & D64_FMT_FLI) && (src->type & D64_FMT_FLI) == 0)
1074 {
1075 dmMsg(1, "Upconverting multicolor to FLI.\n");
989 for (int i = 0; i < dst->nbanks; i++) 1076 for (int i = 0; i < dst->nbanks; i++)
990 { 1077 {
991 dmC64MemBlockCopy(&dst->color[i], &src->color[i]); 1078 dmC64MemBlockCopy(&dst->color[i], &src->color[0]);
992 dmC64MemBlockCopy(&dst->screen[i], &src->screen[i]); 1079 dmC64MemBlockCopy(&dst->screen[i], &src->screen[0]);
993 dmC64MemBlockCopy(&dst->bitmap[i], &src->bitmap[i]); 1080 dmC64MemBlockCopy(&dst->bitmap[i], &src->bitmap[0]);
994 } 1081 }
995 } 1082 }
996 else 1083 else
997 { 1084 if ((src->type & D64_FMT_FLI) && (dst->type & D64_FMT_FLI) == 0)
998 // Try to do some simple fixups 1085 {
999 if ((dst->type & D64_FMT_FLI) && (src->type & D64_FMT_FLI) == 0) 1086 dmMsg(1, "Downconverting FLI to multicolor.\n");
1000 {
1001 dmMsg(1, "Upconverting multicolor to FLI.\n");
1002 for (int i = 0; i < dst->nbanks; i++)
1003 {
1004 dmC64MemBlockCopy(&dst->color[i], &src->color[0]);
1005 dmC64MemBlockCopy(&dst->screen[i], &src->screen[0]);
1006 dmC64MemBlockCopy(&dst->bitmap[i], &src->bitmap[0]);
1007 }
1008 }
1009
1010 for (int i = 0; i < D64_MAX_ENCDEC_OPS; i++)
1011 {
1012 const DMC64EncDecOp *op = fmtGetEncDecOp(dstFmt, i);
1013 size_t size;
1014
1015 // Check for last operator
1016 if (op->type == DO_LAST)
1017 break;
1018
1019 // Check size
1020 if (!dmC64GetOpSize(op, dstFmt, &size))
1021 return DMERR_INVALID_DATA;
1022
1023 // Perform operation
1024 switch (op->type)
1025 {
1026 case DO_COPY:
1027 switch (op->subject)
1028 {
1029 case DS_EXTRA_DATA:
1030 dmC64MemBlockAlloc(&dst->extraData[op->bank], size);
1031 break;
1032 }
1033 break;
1034 }
1035 }
1036 } 1087 }
1037 1088
1038 return DMERR_OK; 1089 return DMERR_OK;
1039 } 1090 }
1040 1091