diff --git a/tools/imagecon/color.c b/tools/imagecon/color.c index 934793f..b624a3a 100644 --- a/tools/imagecon/color.c +++ b/tools/imagecon/color.c @@ -55,61 +55,6 @@ color_findClosestPalettePixel(imagecon_image_t* ic, amiga_color_t color) return ic->palette[color_findClosestPaletteIndex(ic, color)]; } -ham_control_t -color_findClosestHamPixel(imagecon_image_t* ic, amiga_color_t color, amiga_color_t last) -{ - int delta = INT_MAX; - - ham_control_t ham = {0}; - - for (int i = 0; i < ic->numColors; i++) { - int dc = color_delta(color, ic->palette[i]); - if (dc < delta) { - delta = dc; - ham.data = i; - ham.pixel = ic->palette[i]; - } - } - - delta = color_delta(color, ham.pixel); - if (last.r != -1) { - for (int c = 0; c <= 0xF; c++) { - amiga_color_t copy = last; - copy.r = c<<4; - int dc = color_delta(color, copy); - if (dc < delta) { - ham.control = 2; - ham.data = c; - ham.pixel = copy; - delta = dc; - } - } - for (int c = 0; c <= 0xF; c++) { - amiga_color_t copy = last; - copy.g = c<<4; - int dc = color_delta(color, copy); - if (dc < delta) { - ham.control = 3; - ham.data = c; - ham.pixel = copy; - delta = dc; - } - } - for (int c = 0; c <= 0xF; c++) { - amiga_color_t copy = last; - copy.b = c<<4; - int dc = color_delta(color, copy); - if (dc < delta) { - ham.control = 1; - ham.data = c; - ham.pixel = copy; - delta = dc; - } - } - } - - return ham; -} amiga_color_t @@ -215,6 +160,7 @@ color_ditheredToAmiga(dither_color_t color) return c; } + dither_color_t color_amigaToDithered(amiga_color_t color) { diff --git a/tools/imagecon/color.h b/tools/imagecon/color.h index ebc6c9e..a939792 100644 --- a/tools/imagecon/color.h +++ b/tools/imagecon/color.h @@ -12,9 +12,6 @@ color_findClosestPalettePixel(imagecon_image_t* ic, amiga_color_t color); int color_findClosestPaletteIndex(imagecon_image_t* ic, amiga_color_t color); -ham_control_t -color_findClosestHamPixel(imagecon_image_t* ic, amiga_color_t color, amiga_color_t last); - amiga_color_t color_getPalettedPixel(imagecon_image_t* ic, int x, int y); diff --git a/tools/imagecon/dither.c b/tools/imagecon/dither.c index 565abce..f2cd6e4 100644 --- a/tools/imagecon/dither.c +++ b/tools/imagecon/dither.c @@ -10,20 +10,13 @@ dither_getPalettedColor(imagecon_image_t* ic, amiga_color_t color, amiga_color_t } -amiga_color_t -dither_getHamColor(imagecon_image_t* ic, amiga_color_t color, amiga_color_t last) -{ - ham_control_t ham = color_findClosestHamPixel(ic, color, last); - return ham.pixel; -} - float _gamma(float x) { - return x * 0.55; - // return x; + return x * 0.55; } + static void _propagateError(imagecon_image_t* ic, float factor, int x, int y, dither_color_t error) { @@ -36,6 +29,7 @@ _propagateError(imagecon_image_t* ic, float factor, int x, int y, dither_color_t } } + void dither_image(imagecon_image_t* ic, amiga_color_t (*selector)(imagecon_image_t*, amiga_color_t color, amiga_color_t last)) { @@ -62,9 +56,7 @@ dither_image(imagecon_image_t* ic, amiga_color_t (*selector)(imagecon_image_t*, _propagateError(ic, 5.0/16.0, x , y+1, error); _propagateError(ic, 1.0/16.0, x+1, y+1, error); } - } - } @@ -79,24 +71,6 @@ dither_transferToPaletted(imagecon_image_t* ic) } -ham_control_t* -dither_createHams(imagecon_image_t* ic) -{ - ham_control_t* hams = malloc(sizeof(ham_control_t)*ic->width*ic->height); - - for (int y = 0; y < ic->height; y++) { - amiga_color_t lastPixel = { -1, -1, -1, -1}; - for (int x = 0; x < ic->width; x++) { - amiga_color_t orig = color_ditheredToAmiga(color_getDitheredPixel(ic, x, y)); - ham_control_t ham = color_findClosestHamPixel(ic, orig, lastPixel); - lastPixel = ham.pixel; - hams[(y*ic->width)+x] = ham; - } - } - - return hams; -} - static void _dither_createDither(imagecon_image_t* ic) diff --git a/tools/imagecon/dither.h b/tools/imagecon/dither.h index b3d09df..9751c32 100644 --- a/tools/imagecon/dither.h +++ b/tools/imagecon/dither.h @@ -3,9 +3,6 @@ amiga_color_t dither_getPalettedColor(imagecon_image_t* ic, amiga_color_t color, amiga_color_t last); -amiga_color_t -dither_getHamColor(imagecon_image_t* ic, amiga_color_t color, amiga_color_t last); - void dither_image(imagecon_image_t* ic, amiga_color_t (*selector)(imagecon_image_t* ic, amiga_color_t color, amiga_color_t last)); diff --git a/tools/imagecon/ham.c b/tools/imagecon/ham.c index 73e5bf5..7e18305 100644 --- a/tools/imagecon/ham.c +++ b/tools/imagecon/ham.c @@ -1,5 +1,89 @@ #include "imagecon.h" +static ham_control_t +_ham_findClosestPixel(imagecon_image_t* ic, amiga_color_t color, amiga_color_t last) +{ + int delta = INT_MAX; + + ham_control_t ham = {0}; + + for (int i = 0; i < ic->numColors; i++) { + int dc = color_delta(color, ic->palette[i]); + if (dc < delta) { + delta = dc; + ham.data = i; + ham.pixel = ic->palette[i]; + } + } + + delta = color_delta(color, ham.pixel); + if (last.r != -1) { + for (int c = 0; c <= 0xF; c++) { + amiga_color_t copy = last; + copy.r = c<<4; + int dc = color_delta(color, copy); + if (dc < delta) { + ham.control = 2; + ham.data = c; + ham.pixel = copy; + delta = dc; + } + } + for (int c = 0; c <= 0xF; c++) { + amiga_color_t copy = last; + copy.g = c<<4; + int dc = color_delta(color, copy); + if (dc < delta) { + ham.control = 3; + ham.data = c; + ham.pixel = copy; + delta = dc; + } + } + for (int c = 0; c <= 0xF; c++) { + amiga_color_t copy = last; + copy.b = c<<4; + int dc = color_delta(color, copy); + if (dc < delta) { + ham.control = 1; + ham.data = c; + ham.pixel = copy; + delta = dc; + } + } + } + + return ham; +} + + +static amiga_color_t +_ham_getHamColor(imagecon_image_t* ic, amiga_color_t color, amiga_color_t last) +{ + ham_control_t ham = _ham_findClosestPixel(ic, color, last); + return ham.pixel; +} + + +static ham_control_t* +_ham_createHams(imagecon_image_t* ic) +{ + ham_control_t* hams = malloc(sizeof(ham_control_t)*ic->width*ic->height); + + for (int y = 0; y < ic->height; y++) { + amiga_color_t lastPixel = { -1, -1, -1, -1}; + for (int x = 0; x < ic->width; x++) { + amiga_color_t orig = color_ditheredToAmiga(color_getDitheredPixel(ic, x, y)); + ham_control_t ham = _ham_findClosestPixel(ic, orig, lastPixel); + lastPixel = ham.pixel; + hams[(y*ic->width)+x] = ham; + } + } + + return hams; +} + + static void _ham_outputBitplanes(char* outFilename, imagecon_image_t* ic) { @@ -18,8 +102,8 @@ _ham_outputBitplanes(char* outFilename, imagecon_image_t* ic) ham_control_t* hams; if (config.dither) { - dither_image(ic, dither_getHamColor); - hams = dither_createHams(ic); + dither_image(ic, _ham_getHamColor); + hams = _ham_createHams(ic); } else { hams = malloc(sizeof(ham_control_t)*ic->width*ic->height); @@ -27,7 +111,7 @@ _ham_outputBitplanes(char* outFilename, imagecon_image_t* ic) amiga_color_t lastPixel = { -1, -1, -1, -1}; for (int x = 0; x < ic->width; x++) { amiga_color_t orig = color_getOriginalPixel(ic, x, y); - ham_control_t ham = color_findClosestHamPixel(ic, orig, lastPixel); + ham_control_t ham = _ham_findClosestPixel(ic, orig, lastPixel); lastPixel = ham.pixel; hams[(y*ic->width)+x] = ham; } @@ -81,7 +165,7 @@ _score(imagecon_image_t* ic) amiga_color_t lastPixel = { -1, -1, -1, -1}; for (int x = 0; x < ic->width; x++) { amiga_color_t color = color_getOriginalPixel(ic, x, y); - ham_control_t ham = color_findClosestHamPixel(ic, color, lastPixel); + ham_control_t ham = _ham_findClosestPixel(ic, color, lastPixel); error += color_delta(color, color_findClosestPalettePixel(ic, ham.pixel)); lastPixel = ham.pixel; } diff --git a/tools/imagecon/palette.c b/tools/imagecon/palette.c index b81865d..200068b 100644 --- a/tools/imagecon/palette.c +++ b/tools/imagecon/palette.c @@ -23,6 +23,7 @@ void palette_loadFile(imagecon_image_t* ic) ic->numColors = paletteIndex; } +#define RGB24TORGB12(x) (x >> 4) void palette_output(char* outFilename, imagecon_image_t* ic) @@ -63,19 +64,19 @@ palette_output(char* outFilename, imagecon_image_t* ic) printf("%02d: hex=%03x r=%03d g=%03d b=%03d a=%03d\n", i , ic->palette[i].r << 8 | ic->palette[i].g << 4 | ic->palette[i].b, ic->palette[i].r, ic->palette[i].g, ic->palette[i].b, ic->palette[i].a); } if (paletteFP) { - fprintf(paletteFP, "%03x\n", (ic->palette[i].r >> 4) << 8 | (ic->palette[i].g >>4) << 4 | (ic->palette[i].b >>4)); + fprintf(paletteFP, "%03x\n", RGB24TORGB12(ic->palette[i].r) << 8 | RGB24TORGB12(ic->palette[i].g) << 4 | RGB24TORGB12(ic->palette[i].b)); } if (paletteAsmFP) { - fprintf(paletteAsmFP, "\tlea COLOR%02d(a6),a0\n\tmove.w #$%03x,(a0)\n", i, (ic->palette[i].r >> 4) << 8 | (ic->palette[i].g >>4) << 4 | (ic->palette[i].b >>4)); + fprintf(paletteAsmFP, "\tlea COLOR%02d(a6),a0\n\tmove.w #$%03x,(a0)\n", i, RGB24TORGB12(ic->palette[i].r) << 8 | RGB24TORGB12(ic->palette[i].g) << 4 | RGB24TORGB12(ic->palette[i].b)); } if (paletteGreyFP) { // TODO: this is for compat, can be better - unsigned grey = (((ic->palette[i].r>>4) + (ic->palette[i].g>>4) + (ic->palette[i].b>>4))/3); + unsigned grey = ((RGB24TORGB12(ic->palette[i].r) + RGB24TORGB12(ic->palette[i].g) + RGB24TORGB12(ic->palette[i].b))/3); fprintf(paletteGreyFP, "\tlea COLOR%02d(a6),a0\n\tmove.w #$%03x,(a0)\n", i, grey << 8 | grey << 4 | grey); } if (fp) { - fprintf(fp, "\tdc.w $%x,$%x\n", 0x180+(i*2), (ic->palette[i].r >> 4) << 8 | (ic->palette[i].g >>4) << 4 | (ic->palette[i].b >>4)); + fprintf(fp, "\tdc.w $%x,$%x\n", 0x180+(i*2), RGB24TORGB12(ic->palette[i].r) << 8 | RGB24TORGB12(ic->palette[i].g) << 4 | RGB24TORGB12(ic->palette[i].b)); } }