# HG changeset patch # User Matti Hamalainen # Date 1506258077 -10800 # Node ID f5368c13a8725e6c3d99beefabfd920134cb144b # Parent 9edb17aa4a0a210873c678052cf6d05b3ec84916 Implement more flexible generic format decoding by separating the pixel decoding functions into function pointers. diff -r 9edb17aa4a0a -r f5368c13a872 tools/lib64gfx.c --- a/tools/lib64gfx.c Sun Sep 24 15:22:45 2017 +0300 +++ b/tools/lib64gfx.c Sun Sep 24 16:01:17 2017 +0300 @@ -374,7 +374,7 @@ C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, fmtProbeDrazPaint20Packed, fmtDecodeDrazPaintPacked, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, { { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, { DT_BITMAP, 0x0800, 0, 0, NULL, NULL }, @@ -389,7 +389,7 @@ C64_SCR_WIDTH , C64_SCR_HEIGHT, C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT, fmtProbeDrazLace10Packed, fmtDecodeDrazPaintPacked, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, { { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, { DT_BITMAP, 0x0800, 0, 0, NULL, NULL }, @@ -406,7 +406,7 @@ C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, NULL, NULL, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, { { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, { DT_BITMAP, 0x0800, 0, 0, NULL, NULL }, @@ -421,7 +421,7 @@ C64_SCR_WIDTH , C64_SCR_HEIGHT, C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT, NULL, NULL, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, { { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, { DT_BITMAP, 0x0800, 0, 0, NULL, NULL }, @@ -438,7 +438,7 @@ C64_SCR_WIDTH , C64_SCR_HEIGHT, C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT, NULL, NULL, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, { { DT_SCREEN_RAM, 0x0000, 0, 0, NULL, NULL }, { DT_COLOR_REG, 0x03e8, 0, DC_BGCOL, NULL, NULL }, @@ -456,7 +456,7 @@ C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, NULL, NULL, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, { { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, @@ -471,7 +471,7 @@ C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, NULL, NULL, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, { { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, @@ -486,7 +486,7 @@ C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, fmtProbeAmicaPaintPacked, fmtDecodeAmicaPaintPacked, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, { { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL }, { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, @@ -501,7 +501,7 @@ C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, NULL, NULL, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, { { DT_COLOR_RAM, 0x2328, 0, 0, NULL, NULL }, { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, @@ -516,7 +516,7 @@ C64_SCR_WIDTH , C64_SCR_HEIGHT, C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, NULL, NULL, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, { { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, @@ -529,7 +529,7 @@ C64_SCR_WIDTH , C64_SCR_HEIGHT, C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT, NULL, NULL, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, { { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, @@ -541,7 +541,7 @@ C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT, NULL, NULL, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, { { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, { DT_SCREEN_RAM, 0x1f40, 0, 0, NULL, NULL }, @@ -556,7 +556,7 @@ C64_SCR_WIDTH , C64_SCR_HEIGHT, C64_SCR_CH_WIDTH, C64_SCR_CH_HEIGHT, NULL, NULL, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, { { DT_SCREEN_RAM, 0x0000, 0, 0, NULL, NULL }, { DT_BITMAP, 0x0400, 0, 0, NULL, NULL }, @@ -569,7 +569,7 @@ C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, NULL, NULL, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, { { DT_COLOR_RAM, 0x0100, 0, 0, NULL, NULL }, @@ -594,7 +594,7 @@ C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, NULL, NULL, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, { { DT_COLOR_RAM, 0x0000, 0, 0, NULL, NULL }, { DT_SCREEN_RAM, 0x0400, 0, 0, NULL, NULL }, @@ -616,7 +616,7 @@ C64_SCR_WIDTH / 2, C64_SCR_HEIGHT, C64_SCR_CH_WIDTH , C64_SCR_CH_HEIGHT, NULL, NULL, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, { { DT_BITMAP, 0x0000, 0, 0, NULL, NULL }, { DT_SCREEN_RAM, 0x2000, 0, 0, NULL, NULL }, @@ -636,7 +636,7 @@ XX2_WIDTH_CH * 4, XX2_HEIGHT_CH * 8, XX2_WIDTH_CH , XX2_HEIGHT_CH, fmtProbeFormatXX2, fmtDecodeFormatXX2, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, { { DT_BITMAP, 0x0000, 0, XX2_BSIZE, NULL, NULL }, { DT_COLOR_RAM, XX2_BSIZE + XX2_SIZE, 0, XX2_SIZE, NULL, NULL }, @@ -1080,9 +1080,24 @@ } -static inline Uint8 dmC64GetMCColor(const DMC64Image *img, - const int bits, const int cbank, const int vbank, const int scroffs) +static inline Uint8 dmC64GetSCPixel( + const DMC64Image *img, const int bmoffs, const int vshift, + const int vbank, const int scroffs, const int raster) { + (void) raster; + if ((img->bitmap[vbank][bmoffs] >> vshift) & 1) + return img->screen[vbank][scroffs] >> 4; + else + return img->screen[vbank][scroffs] & 15; +} + + +static inline Uint8 dmC64GetMCColor( + const DMC64Image *img, + const int bits, const int cbank, const int vbank, + const int scroffs, const int raster) +{ + (void) raster; switch (bits) { case 0: return img->bgcolor; break; @@ -1093,12 +1108,40 @@ } +static inline Uint8 dmC64GetMCPixel( + const DMC64Image *img, const int bmoffs, const int vshift, + const int vbank, const int scroffs, const int raster) +{ + if (img->type & D64_FMT_FLI) + { + const int yb = raster & 7; + int vbank = 0; + switch (img->fliType) + { + case D64_FLI_2BANK: + vbank = yb / 4; + break; + case D64_FLI_4BANK: + vbank = yb / 2; + break; + case D64_FLI_8BANK: + vbank = yb; + break; + } + return dmC64GetMCColor(img, (img->bitmap[0][bmoffs] >> vshift) & 3, 0, vbank, scroffs, raster); + } + else + return dmC64GetMCColor(img, (img->bitmap[0][bmoffs] >> vshift) & 3, 0, vbank, scroffs, raster); +} + + // Convert a generic "C64" format bitmap in DMC64Image struct to // a indexed/paletted bitmap image. -int dmC64ConvertGenericBMP2Image(DMImage *dst, const DMC64Image *src) +int dmC64ConvertGenericBMP2Image(DMImage *dst, const DMC64Image *src, const DMC64ImageFormat *fmt) { Uint8 *dp = dst->data; int yc; + DMC64GetPixelFunc getPixel; // Sanity check arguments if (dst == NULL || src == NULL) @@ -1109,6 +1152,12 @@ dmMemset(dst->data, 0, dst->size); + // Check pixel getter function + if (fmt->getPixel != NULL) + getPixel = fmt->getPixel; + else + getPixel = (fmt->type & D64_FMT_MC) ? dmC64GetMCPixel : dmC64GetSCPixel; + // Resolution interlaced pics need to halve the source width int rwidth = src->width; if ((src->type & D64_FMT_ILACE) && src->laceType == D64_ILACE_RES) @@ -1181,12 +1230,9 @@ const int x = xc / 8; const int scroffs = scroffsy + x; const int bmoffs = bmoffsy + (x * 8); - const int v = 7 - (xc & 7); + const int vshift = 7 - (xc & 7); - if ((src->bitmap[0][bmoffs] >> v) & 1) - *d++ = src->screen[0][scroffs] >> 4; - else - *d++ = src->screen[0][scroffs] & 15; + *d++ = getPixel(src, bmoffs, vshift, 0, scroffs, yc); } else // Multicolor bitmap and variants @@ -1195,35 +1241,15 @@ const int x = xc / 4; const int scroffs = scroffsy + x; const int bmoffs = bmoffsy + (x * 8); - const int v = 6 - ((xc * 2) & 6); - Uint8 c; + const int vshift = 6 - ((xc * 2) & 6); - if (src->type & D64_FMT_FLI) - { - int vbank = 0; - switch (src->fliType) - { - case D64_FLI_2BANK: - vbank = yb / 4; - break; - case D64_FLI_4BANK: - vbank = yb / 2; - break; - case D64_FLI_8BANK: - vbank = yb; - break; - } - c = dmC64GetMCColor(src, (src->bitmap[0][bmoffs] >> v) & 3, 0, vbank, scroffs); - *d++ = c; - } - else if (src->type & D64_FMT_ILACE) { switch (src->laceType) { case D64_ILACE_RES: - *d++ = dmC64GetMCColor(src, (src->bitmap[0][bmoffs] >> v) & 3, 0, src->laceBank1, scroffs); - *d++ = dmC64GetMCColor(src, (src->bitmap[1][bmoffs] >> v) & 3, 0, src->laceBank2, scroffs); + *d++ = getPixel(src, bmoffs, vshift, src->laceBank1, scroffs, yc); + *d++ = getPixel(src, bmoffs, vshift, src->laceBank2, scroffs, yc); break; default: @@ -1232,8 +1258,7 @@ } else { - c = dmC64GetMCColor(src, (src->bitmap[0][bmoffs] >> v) & 3, 0, 0, scroffs); - *d++ = c; + *d++ = getPixel(src, bmoffs, vshift, 0, scroffs, yc); } } } @@ -1263,9 +1288,9 @@ // Convert if (fmt->convertFrom != NULL) - res = fmt->convertFrom(dst, src); + res = fmt->convertFrom(dst, src, fmt); else - res = dmC64ConvertGenericBMP2Image(dst, src); + res = dmC64ConvertGenericBMP2Image(dst, src, fmt); return res; } diff -r 9edb17aa4a0a -r f5368c13a872 tools/lib64gfx.h --- a/tools/lib64gfx.h Sun Sep 24 15:22:45 2017 +0300 +++ b/tools/lib64gfx.h Sun Sep 24 16:01:17 2017 +0300 @@ -107,8 +107,6 @@ }; -typedef struct _DMC64Image DMC64Image; - typedef struct _DMC64Image { int type, // Image type (D64_FMT_*) @@ -133,6 +131,11 @@ } DMC64Image; +typedef Uint8 (*DMC64GetPixelFunc)( + const DMC64Image *img, + const int bits, const int cbank, const int vbank, + const int scroffs, const int raster); + enum { DT_COLOR_RAM, @@ -180,8 +183,9 @@ int (*probe)(const Uint8 *buf, const size_t len, const struct _DMC64ImageFormat *fmt); int (*decode)(DMC64Image *img, const Uint8 *buf, const size_t len, const struct _DMC64ImageFormat *fmt); int (*encode)(DMC64Image *img, Uint8 **buf, size_t *len, const struct _DMC64ImageFormat *fmt); - int (*convertFrom)(DMImage *, const DMC64Image *); - int (*convertTo)(DMImage *, DMC64Image *); + int (*convertFrom)(DMImage *, const DMC64Image *, const struct _DMC64ImageFormat *fmt); + int (*convertTo)(DMImage *, DMC64Image *, const struct _DMC64ImageFormat *fmt); + DMC64GetPixelFunc getPixel; DMC64EncDecOp encdecOps[D64_MAX_ENCDEC_OPS]; } DMC64ImageFormat; @@ -201,7 +205,7 @@ int dmC64DecodeGenericBMP(DMC64Image *img, const Uint8 *buf, const size_t len, const DMC64ImageFormat *fmt); int dmC64EncodeGenericBMP(Uint8 **pbuf, size_t *plen, const DMC64Image *img, const DMC64ImageFormat *fmt); -int dmC64ConvertGenericBMP2Image(DMImage *dst, const DMC64Image *src); +int dmC64ConvertGenericBMP2Image(DMImage *dst, const DMC64Image *src, const DMC64ImageFormat *fmt); int dmC64ConvertBMP2Image(DMImage **pdst, const DMC64Image *src, const DMC64ImageFormat *fmt); int dmC64ProbeBMP(const Uint8 *buf, const size_t len, const DMC64ImageFormat **fmt); diff -r 9edb17aa4a0a -r f5368c13a872 tools/view64.c --- a/tools/view64.c Sun Sep 24 15:22:45 2017 +0300 +++ b/tools/view64.c Sun Sep 24 16:01:17 2017 +0300 @@ -302,9 +302,9 @@ bmap.constpal = TRUE; if (fmt->convertFrom != NULL) - ret = fmt->convertFrom(&bmap, cimage); + ret = fmt->convertFrom(&bmap, cimage, fmt); else - ret = dmC64ConvertGenericBMP2Image(&bmap, cimage); + ret = dmC64ConvertGenericBMP2Image(&bmap, cimage, fmt); // Set window title and caption