From: Nick Downing Date: Fri, 19 Jul 2024 13:15:19 +0000 (-0800) Subject: Simplify /shape/shape_color_to_mono.py so it correctly handles the new processing... X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=69345013360c7beb7d5c8c8625293ec6a7b98913;p=star_disasm.git Simplify /shape/shape_color_to_mono.py so it correctly handles the new processing steps (mono, colour, rounded) but does not handle the old shape_(d)hgr.png anymore, revert shape3.png to the un-enhanced version and add shape4.png as the enhanced version (because enhancing loses the ability to recreate the original source), replace /shape/shape_hgr.png with a new version based on shape1.png for mono (parachute, derrick, part of radar, digits) and shape3.png for colour (others), replace /shape/shape_dhgr.png with a new version based on /shape/shape_hgr.png with the shifted STAR BLAZER text added but losing manually re-coloured shapes --- diff --git a/.gitignore b/.gitignore index 4712116..e830bcc 100644 --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,7 @@ /shape/shape1.png /shape/shape2.png /shape/shape3.png +/shape/shape4.png /shape/shape_data.inc /shape/shape_index.inc /shape/sky_blazer_shape.png diff --git a/shape/Makefile b/shape/Makefile index c199a84..6cdae21 100644 --- a/shape/Makefile +++ b/shape/Makefile @@ -18,6 +18,7 @@ shape0d.png \ shape1.png \ shape2.png \ shape3.png \ +shape4.png \ sky_blazer_shape.png dhgr_pixel_shape_index.inc: pixel.txt dhgr_shape.txt shape0c.png @@ -56,6 +57,9 @@ shape2.png: shape0.png ./shape_mono_to_color.py $< $@ shape3.png: shape2.png + ./shape_round.py $< $@ + +shape4.png: shape2.png ./shape_round.py --enhance $< $@ shape0a.png: shape_hgr.png @@ -120,7 +124,7 @@ pixel_shape_data.inc \ shape_index.inc \ shape_data.inc \ shape0[abcd].png \ -shape[0123].png \ +shape[01234].png \ sky_blazer_shape.png \ Sky\ Blazer\ \(4am\ and\ san\ inc\ crack\).dsk \ Sky\ Blazer\ \(4am\ and\ san\ inc\ crack\).nib diff --git a/shape/shape_color_to_mono.py b/shape/shape_color_to_mono.py index b279495..e9354cd 100755 --- a/shape/shape_color_to_mono.py +++ b/shape/shape_color_to_mono.py @@ -1,5 +1,14 @@ #!/usr/bin/env python3 +# this can be run on any shape file from the pipeline (mono, colour, rounded), +# it auto detects which processing steps have been done and trims extra padding + +# resulting file is normalized for the Apple II: vertical pixels are doubled, +# and if HGR mode, horizontal pixels are doubled and each line is hibit or not + +# it has been tested to restore the original file (undoes colour and rounding), +# but does not restore the original file if it has been rounded with --enhance + import numpy import sys import PIL.Image @@ -81,28 +90,22 @@ for i in range(0x100): continue shape = shape[:ys, :xs] - # temporary, for shape_(d)hgr.png - if (ys & 1) == 1: - shape = shape[1:, :] - ys -= 1 - if (xs & 3) == 0: - assert False - elif (xs & 3) == 1: + # normal file has ys even with pairs of identical lines + # rounded file has ys odd and we will only use the odd lines + if (ys & 1) == 0: + assert numpy.all(shape[::2, :] == shape[1::2, :]) + shape = shape[1::2, :] + ys //= 2 + + # mono file has xs = a multiple of 4 + 1 + # colour file has xs = a multiple of 4 + 3, trim the sides + if (xs & 3) == 1: + pass + elif (xs & 3) == 3: shape = shape[:, 1:-1] xs -= 2 - elif (xs & 3) == 2: - shape = shape[:, 1:-2] - xs -= 3 - - # only look at even lines, they will be duplicated again at the end - shape = shape[::2] - ys >>= 1 - - # remove 2 pixels that were added by shape_colour_to_mono.py decoder - assert xs >= 2 - shape = shape[:, 1:-1] - xs -= 2 - assert (xs & 3) == 1 + else: + assert False # take a single bit from each 4-bit colour value, according to x % 4 shape = ( diff --git a/shape/shape_dhgr.png b/shape/shape_dhgr.png index 0d73f00..b514702 100644 Binary files a/shape/shape_dhgr.png and b/shape/shape_dhgr.png differ diff --git a/shape/shape_hgr.png b/shape/shape_hgr.png index a446e06..3b5ed8e 100644 Binary files a/shape/shape_hgr.png and b/shape/shape_hgr.png differ diff --git a/shape/shape_mono_to_mono.py b/shape/shape_mono_to_mono.py new file mode 100755 index 0000000..8cadd87 --- /dev/null +++ b/shape/shape_mono_to_mono.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 + +# hack to pad mono image with one black pixel to left and right +# makes it easier to put mono images (parachute, derrick, etc) alongside color + +import numpy +import sys +import PIL.Image + +EXIT_SUCCESS = 0 +EXIT_FAILURE = 1 + +PITCH_X = 256 +PITCH_Y = 64 + +# see palette.py +PALETTE = numpy.array( + [ + [0x00, 0x00, 0x00], + [0xbc, 0x00, 0x89], + [0x00, 0x00, 0xbc], + [0xbc, 0x00, 0xe1], + [0x00, 0xbc, 0x89], + [0x80, 0x80, 0x80], #[0xbc, 0xbc, 0xbc], + [0x00, 0xbc, 0xe1], + [0xbc, 0xbc, 0xff], + [0xbc, 0xbc, 0x00], + [0xff, 0xbc, 0x89], + [0xc0, 0xc0, 0xc0], #[0xbc, 0xbc, 0xbc], + [0xff, 0xbc, 0xe1], + [0xbc, 0xff, 0x89], + [0xff, 0xff, 0xbc], + [0xbc, 0xff, 0xe1], + [0xff, 0xff, 0xff], + ], + numpy.uint8 +) + +if len(sys.argv) < 3: + print(f'usage: {sys.argv[0]:s} in.png out.png') + sys.exit(EXIT_FAILURE) +in_png = sys.argv[1] +out_png = sys.argv[2] + +image_in_pil = PIL.Image.open(in_png) +assert image_in_pil.mode == 'P' +image_in = numpy.frombuffer( + image_in_pil.tobytes(), + dtype = numpy.uint8 +).reshape((image_in_pil.size[1], image_in_pil.size[0])) + +image_out = numpy.zeros((PITCH_Y * 32, PITCH_X * 8), numpy.uint8) +assert image_out.shape == image_in.shape + +for i in range(0x100): + j = i & 7 + k = i >> 3 + x = j * PITCH_X + y = k * PITCH_Y + bg = 0xa if (j ^ k) & 1 else 5 + image_out[y:y + PITCH_Y, x:x + PITCH_X] = bg + + shape = image_in[y:y + PITCH_Y, x:x + PITCH_X] + xs = shape.shape[1] + while xs: + if numpy.any(shape[:, xs - 1] != bg): + break + xs -= 1 + else: + continue + ys = shape.shape[0] + while ys: + if numpy.any(shape[ys - 1, :] != bg): + break + ys -= 1 + else: + continue + shape = shape[:ys, :xs] + + shape1 = numpy.zeros((ys, xs + 2), numpy.uint8) + shape1[:, 1:-1] = shape + shape = shape1 + xs += 2 + + image_out[y:y + ys, x:x + xs] = shape + +image_out_pil = PIL.Image.new( + 'P', + (image_out.shape[1], image_out.shape[0]), + None +) +image_out_pil.frombytes(image_out.tobytes()) +image_out_pil.putpalette(list(PALETTE.reshape((0x30,)))) +image_out_pil.save(out_png)