Skip to content

Instantly share code, notes, and snippets.

@digarok
Created April 10, 2020 15:02
Show Gist options
  • Save digarok/455a23fdf83c1e2c62e7f91f6baf4412 to your computer and use it in GitHub Desktop.
Save digarok/455a23fdf83c1e2c62e7f91f6baf4412 to your computer and use it in GitHub Desktop.
Convert Apple IIgs SHR (Super Hi-Res) images to PNG files
### c1-to-png.py by Dagen Brock
#
# Example: python c1-to-png.py. mypicture.shr output.png
#
from PIL import Image, ImageDraw # `pip3 install pillow` if you don't have it
from sys import argv
def get_scanline_palette(scanline):
scb = shr_buffer[0x7D00+scanline] # SCBs start at $E19D00 (SHR RAM starts offset +$2000)
cur_pal_num = scb & 0x0F
pal_offset = 0x7E00+(cur_pal_num*16*2) # each pal is 16 colors * 2 bytes per color
# now make a dict of each index => (r,g,b) tuple
result = {}
for i in range(0,16):
g = shr_buffer[pal_offset+(i*2)] >> 4 & 0x0F
b = shr_buffer[pal_offset+(i*2)] & 0x0F
r = shr_buffer[pal_offset+(i*2)+1]
# print("{:X},{:X},{:X}".format(r,g,b))
# expand to 24-bit color colorspace for png/rgb
r += (r*16)
g += (g*16)
b += (b*16)
result[i] = (r,g,b)
return result
# Read SHR file
shr_buffer = open(argv[1], "rb").read()
# Open output PNG
img = Image.new('RGB', (320, 200), color = 'red')
d = ImageDraw.Draw(img)
# foreach scanline
for y in range(0,200):
# get scanline palette (as dict k=>(r,g,b))
curPal = get_scanline_palette(y)
# foreach byte (2 pixels)
for x in range(0,160): # 320/2=160 because 2 pixels per byte = 160 bytes per scanline row
data = shr_buffer[(y*160)+x]
px1 = data >> 4
px2 = data & 0x0F
d.point((x*2,y),curPal[px1])
d.point(((x*2)+1,y),curPal[px2])
img.save(argv[2])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment