Exemplo n.º 1
0
 def dump(x):
     c = palette[x]
     out.write(
         strtoio(
             pack([
                 (getbit(c, 5) * 2 + getbit(c, 2)) * 85,
                 (getbit(c, 4) * 2 + getbit(c, 1)) * 85,
                 (getbit(c, 3) * 2 + getbit(c, 0)) * 85,
             ])))
Exemplo n.º 2
0
 def test_getbit(self):
     self.assertEqual(getbit(33, 0), 1)
     self.assertEqual(getbit(32, 0), 0)
     self.assertEqual(getbit(128, 7), 1)
     self.assertEqual(getbit(128, 0), 0)
Exemplo n.º 3
0
def convert(
    input_image_stream,
    output_image_stream,
    arte,
    newsroom,
    cols,
    rows,
    skip,
    ignore_header_errors,
):
    def clip(v):
        return 255 if v > 255 else (0 if v < 0 else v)

    # imitate +I and -I colours using Coco palette
    br2 = [
        pack(x)
        for x in [[0, 0, 0], [255, 85, 0], [0, 170, 255], [255, 255, 255]]
    ]
    # take names "blue" and "red" too literally like many "patched for Coco3"
    # programs
    br3 = [
        pack(x) for x in [[0, 0, 0], [255, 0, 0], [0, 0, 255], [255, 255, 255]]
    ]
    # probably not exact...
    semig = [
        pack(x) for x in [
            [0, 0, 0],
            [0, 255, 0],
            [255, 255, 0],
            [0, 0, 255],
            [255, 0, 0],
            [255, 255, 255],
            [0, 211, 170],
            [204, 0, 255],
            [255, 128, 0],
        ]
    ]

    f = input_image_stream
    out = output_image_stream

    if skip:
        f.read(skip)

    if newsroom:
        head = iotostr(f.read(2))
        cols = ord(head[0]) * 8
        rows = ord(head[1])
    else:
        head = iotostr(f.read(5))
        if ord(head[0]) != 0:
            sys.stderr.write("bad first byte in header\n")
            if not ignore_header_errors:
                return False
        if not rows:
            size = ord(head[1]) * 256 + ord(head[2])
            rows = 8 * size // cols
            if cols * rows // 8 != size:
                sys.stderr.write(
                    "data length {} in header would be closest to {}x{} but "
                    "that would be {} bytes\n".format(size, cols, rows,
                                                      cols * rows // 8))
                if not ignore_header_errors:
                    return False

    out.write(strtoio("P6\n{} {}\n255\n".format(cols, rows)))
    for jj in range(rows):
        row = iotostr(f.read(cols >> 3))
        oy = r2 = g2 = b2 = 0
        for vv in row:
            v = ord(vv)
            if arte == PIXEL_MODE_BW:
                for k in range(8):
                    out.write(strtoio(br2[getbit(v, 7 - k) * 3]))
            elif (arte == PIXEL_MODE_BR) or (arte == PIXEL_MODE_RB):
                x = -100 if arte == PIXEL_MODE_BR else 100
                # this is using the exact YIQ-to-RGB formula, but the rest is
                # just trial-and-error of what looks ok, without actually using
                # the spec of NTSC and/or VDG/GIME.  more pixel options could
                # be added to allow variants on : brightness/contrast ;
                # saturation ; double-resolution for greater detail in
                # emulation ; different smoothing and horiz phase ; and
                # replacing ±I colours by ±V colours (green-purple of PAL and
                # of SECAM).
                for k in range(8):
                    ny = getbit(v, 7 - k) * 255
                    y = (oy + ny + (ny >> 2)) >> 1
                    i = (x * (y - oy)) >> 7
                    r = clip(int((y + 0.9563 * i)))
                    g = clip(int((y - 0.2721 * i)))
                    b = clip(int((y - 1.1070 * i)))
                    out.write(
                        strtoio(
                            pack([(r + r2) >> 1, (g + g2) >> 1,
                                  (b + b2) >> 1])))
                    oy = ny
                    x = -x
                    r2 = r
                    g2 = g
                    b2 = b
            elif arte == PIXEL_MODE_BR2:
                for k in range(4):
                    out.write(
                        strtoio(br2[getbit(v, 7 - k - k) * 2 +
                                    getbit(v, 6 - k - k)] * 2))
            elif arte == PIXEL_MODE_RB2:
                for k in range(4):
                    out.write(
                        strtoio(br2[getbit(v, 7 - k - k) +
                                    getbit(v, 6 - k - k) * 2] * 2))
            elif arte == PIXEL_MODE_BR3:
                for k in range(4):
                    out.write(
                        strtoio(br3[getbit(v, 7 - k - k) * 2 +
                                    getbit(v, 6 - k - k)] * 2))
            elif arte == PIXEL_MODE_RB3:
                for k in range(4):
                    out.write(
                        strtoio(br3[getbit(v, 7 - k - k) +
                                    getbit(v, 6 - k - k) * 2] * 2))
            elif arte == PIXEL_MODE_S10:
                for k in range(4):
                    out.write(
                        strtoio(semig[1 + getbit(v, 7 - k - k) +
                                      getbit(v, 6 - k - k) * 2] * 2))
            elif arte == PIXEL_MODE_S11:
                for k in range(4):
                    out.write(
                        strtoio(semig[5 + getbit(v, 7 - k - k) +
                                      getbit(v, 6 - k - k) * 2] * 2))
    return True
Exemplo n.º 4
0
def convert(input_image_stream, output_image_stream):
    def debug(x):
        sys.stderr.write("{}\n".format(x))

    def dump(x):
        c = palette[x]
        out.write(
            strtoio(
                pack([
                    (getbit(c, 5) * 2 + getbit(c, 2)) * 85,
                    (getbit(c, 4) * 2 + getbit(c, 1)) * 85,
                    (getbit(c, 3) * 2 + getbit(c, 0)) * 85,
                ])))

    # Read basic structure
    #   - is is a 192 or 384 row image?
    #   - motifs - patterns used for filling shapes stored in the image file
    f = input_image_stream
    cols = 320
    pictyp = ord(iotostr(f.read(1)))
    rows = (getbit(pictyp, 7) + 1) * 192
    sans_motifs = getbit(pictyp, 0) != 0
    debug("{}x{}, 16 couleurs, sans_motifs={}".format(cols, rows, sans_motifs))

    # Get palette information
    palette = [ord(iotostr(f.read(1))) for ii in range(16)]
    anirat = ord(iotostr(f.read(1)))
    cycrat = ord(iotostr(f.read(1)))
    cm3cyc = [ord(iotostr(f.read(1))) for ii in range(8)]
    aniflg = ord(iotostr(f.read(1))) & 0x80 != 0
    cycflg = ord(iotostr(f.read(1))) & 0x80 != 0
    debug("palette={}".format(palette))
    debug("cm3cyc={} cycrat={} cycflg={} anirat={} aniflg={}".format(
        cm3cyc, cycrat, cycflg, anirat, aniflg))
    if not sans_motifs:
        iotostr(f.read(243))
    linbuf = [0] * 160
    buff1 = [0] * 20
    buff2 = []

    # Start outputting image
    out = output_image_stream
    out.write(strtoio("P6\n{} {}\n255\n".format(cols, rows)))

    for ii in range(getbit(pictyp, 7) + 1):
        lines = ord(iotostr(f.read(1)))
        for jj in range(lines):
            u = 0
            y = 0
            bitu = 7
            bity = 7
            x = 0
            a = None
            contr = ord(iotostr(f.read(1)))
            if contr < 128:
                for kk in range(20):
                    buff1[kk] = ord(iotostr(f.read(1)))
                buff2 = []
                for kk in range(contr):
                    buff2.append(ord(iotostr(f.read(1))))
            for kk in range(160):
                if contr >= 128:
                    a = ord(iotostr(f.read(1)))
                else:
                    cc = getbit(buff1[u], bitu)
                    bitu = bitu - 1
                    if bitu < 0:
                        bitu = 7
                        u = u + 1
                    if cc == 0:
                        a = linbuf[(x - 1) % 160]
                    else:
                        cc = getbit(buff2[y], bity)
                        bity = bity - 1
                        if bity < 0:
                            bity = 7
                            y = y + 1
                        if cc == 0:
                            a = linbuf[x]
                        else:
                            a = ord(iotostr(f.read(1)))
                linbuf[x] = a
                dump(a >> 4)
                dump(a & 15)
                x = x + 1

    # Look for extra junk at the end of the file
    extra = 0
    while iotostr(f.read(1)) != "":
        extra = extra + 1
        pass
    if extra > 0:
        debug("{} octets de trop".format(extra))