Example #1
0
 def test_help(self):
     output = subprocess.check_output(
         [sys.executable, "src/coco/pixtopgm.py", "-h"],
         stderr=subprocess.STDOUT,
     )
     self.assertRegex(iotostr(output), "Convert RS-DOS PIX images to PGM")
     self.assertRegex(iotostr(output), self.VERSION_REGEX)
     self.assertRegex(iotostr(output), self.USAGE_REGEX)
     self.assertRegex(iotostr(output), self.POSITIONAL_ARGS_REGEX)
     self.assertRegex(iotostr(output), self.OPTIONAL_ARGS_REGEX)
Example #2
0
 def test_conflicting_arguments(self):
     with self.assertRaises(subprocess.CalledProcessError) as context:
         subprocess.check_output(
             [sys.executable, "src/coco/maxtoppm.py", "-br", "-rb"],
             stderr=subprocess.STDOUT,
         )
     self.assertRegex(iotostr(context.exception.output), self.USAGE_REGEX)
     self.assertRegex(
         iotostr(context.exception.output),
         r"maxtoppm.py: error: argument -rb: not allowed with argument -br",
     )
Example #3
0
 def test_unknown_argument(self):
     with self.assertRaises(subprocess.CalledProcessError) as context:
         subprocess.check_output(
             [sys.executable, "src/coco/hrstoppm.py", "--oops"],
             stderr=subprocess.STDOUT,
         )
     self.assertRegex(iotostr(context.exception.output), self.USAGE_REGEX)
     self.assertRegex(
         iotostr(context.exception.output),
         r"hrstoppm.py: error: unrecognized arguments: --oops",
     )
Example #4
0
 def test_unknown_argument(self):
     with self.assertRaises(subprocess.CalledProcessError) as context:
         infile = pkg_resources.resource_filename(
             __name__, "fixtures/sue.pix"
         )
         subprocess.check_output(
             [sys.executable, "src/coco/pixtopgm.py", infile, "--oops"],
             stderr=subprocess.STDOUT,
         )
     self.assertRegex(iotostr(context.exception.output), self.USAGE_REGEX)
     self.assertRegex(
         iotostr(context.exception.output),
         r"pixtopgm.py: error: unrecognized arguments: --oops",
     )
Example #5
0
 def test_version(self):
     output = iotostr(
         subprocess.check_output(
             [sys.executable, "src/coco/rattoppm.py", "--version"],
             stderr=subprocess.STDOUT,
         ))
     self.assertRegex(output, self.VERSION_REGEX)
Example #6
0
def convert(input_image_stream, output_image_stream):
    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,
                ])))

    f = input_image_stream
    out = output_image_stream
    escape = ord(iotostr(f.read(1)))
    packed = ord(iotostr(f.read(1)))
    bcolor = ord(iotostr(f.read(1)))
    if packed == 0:
        raise Exception("not packed")
    palette = [ord(ii) for ii in iotostr(f.read(16))]
    out.write(strtoio("P6\n320 199\n255\n"))
    ii = 199 * 160
    while ii > 0:
        c = ord(iotostr(f.read(1)))
        if c != escape:
            repeat = 1
        else:
            repeat = ord(iotostr(f.read(1)))
            c = ord(iotostr(f.read(1)))
        for jj in range(repeat):
            ii = ii - 1
            dump(c >> 4)
            dump(c & 7)
Example #7
0
 def test_too_many_arguments(self):
     infilename = pkg_resources.resource_filename(__name__,
                                                  "fixtures/clip1.cm3")
     with self.assertRaises(subprocess.CalledProcessError) as context:
         subprocess.check_output(
             [
                 sys.executable,
                 "src/coco/cm3toppm.py",
                 infilename,
                 self.outfile.name,
                 "baz",
             ],
             stderr=subprocess.STDOUT,
         )
     self.assertRegex(iotostr(context.exception.output), self.USAGE_REGEX)
     self.assertRegex(
         iotostr(context.exception.output),
         r"cm3toppm.py: error: unrecognized arguments: baz",
     )
Example #8
0
 def test_help(self):
     output = iotostr(
         subprocess.check_output(
             [sys.executable, "src/coco/rattoppm.py", "-h"],
             stderr=subprocess.STDOUT,
         ))
     self.assertRegex(output, "Convert RS-DOS RAT images to PPM")
     self.assertRegex(output, self.VERSION_REGEX)
     self.assertRegex(output, self.USAGE_REGEX)
     self.assertRegex(output, self.POSITIONAL_ARGS_REGEX)
     self.assertRegex(output, self.OPTIONAL_ARGS_REGEX)
Example #9
0
def convert(input_image_stream, output_image_stream):
    f = input_image_stream
    out = output_image_stream
    sz = os.path.getsize(f.name)
    side = int(math.sqrt(sz * 2))
    out.write(strtoio("P5\n{} {}\n255\n".format(side, side)))
    s = ["a"] * (sz * 2)
    for y in range(side):
        for x in range(side // 2):
            v = ord(iotostr(f.read(1)))
            s[(x + x) * side + y] = chr(255 - (v >> 4) * 17)
            s[(x + x + 1) * side + y] = chr(255 - (v & 15) * 17)
    out.write(strtoio("".join(s)))
Example #10
0
def convert(input_image_stream, output_image_stream, width, height, skip):
    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,
                ])))

    f = input_image_stream
    if skip:
        f.read(skip)
    out = output_image_stream
    palette = [ord(ii) for ii in iotostr(f.read(16))]
    out.write(strtoio("P6\n{} {}\n255\n".format(width, height)))
    for jj in range(height):
        for ii in range(width // 2):
            c = ord(iotostr(f.read(1)))
            dump(c >> 4)
            dump(c & 15)
Example #11
0
 def test_iotostr(self):
     self.assertEqual("abc", iotostr(b"abc"))
Example #12
0
def convert(input_image_stream, output_image_stream):
    def debug(x):
        sys.stderr.write("{}\n".format(x))

    def dmp500(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,
                ])))

    f = input_image_stream
    out = output_image_stream

    # Maps composite palette values to RGB
    c2r = [
        0,
        21,
        2,
        20,
        6,
        49,
        35,
        4,
        33,
        5,
        14,
        1,
        12,
        10,
        3,
        28,
        7,
        17,
        16,
        22,
        48,
        34,
        37,
        32,
        44,
        40,
        42,
        13,
        8,
        11,
        24,
        26,
        56,
        19,
        18,
        50,
        54,
        52,
        38,
        36,
        46,
        45,
        41,
        15,
        9,
        25,
        27,
        30,
        63,
        58,
        23,
        51,
        55,
        53,
        39,
        60,
        47,
        61,
        43,
        57,
        29,
        31,
        59,
        62,
    ]

    subtyp = 0
    cols = 320 << subtyp
    rows = 200
    colors = 16 if subtyp == 0 else 4
    a = ord(iotostr(f.read(1)))
    if a != 0:
        debug("invalid header")
        sys.exit(1)
    palette = [ord(iotostr(f.read(1))) for ii in range(16)]
    debug(palette)
    is_rgb = ord(iotostr(f.read(1))) == 0
    colorspace = "RGB" if is_rgb else "CMP"
    if not is_rgb:
        for ii in range(16):
            palette[ii] = c2r[palette[ii]]
    packed = ord(iotostr(f.read(1))) != 0
    titbuf = iotostr(f.read(30))
    i = titbuf.index("\0")
    if i:
        titbuf = titbuf[:i]
    titbuf = titbuf.rstrip()
    if subtyp == 0:

        def dump(a):
            dmp500(a >> 4)
            dmp500(a & 0x0F)

    else:

        def dump(a):
            dmp500(a >> 6)
            dmp500((a >> 4) & 3)
            dmp500((a >> 2) & 3)
            dmp500(a & 3)

    cycles = ord(iotostr(f.read(1)))
    a = ord(iotostr(f.read(1)))
    botpal = a & 0xF
    toppal = (a >> 4) & 0xF
    debug("{}x{}, 16 couleurs {}, titre «{}»".format(cols, rows, colorspace,
                                                     titbuf))
    debug("palette={}, cycles={}, botpal={},]\ntoppal={}".format(
        palette, cycles, botpal, toppal))
    out.write(strtoio("P6\n{} {}\n255\n".format(cols, rows)))
    y = 160 * rows
    if not packed:
        while True:
            b = ord(iotostr(f.read(1)))
            if b == 0:
                break
            a = ord(iotostr(f.read(1)))
            for jj in range(b):
                dump(a)
                y = y - 1
                if y <= 0:
                    break
    else:
        for jj in range(y):
            dump(ord(iotostr(f.read(1))))
    # Look for extra junk at the end of the file
    extra = 0
    while f.read(1) != strtoio(""):
        extra = extra + 1
        pass
    if extra > 0:
        debug("{} octets de trop".format(extra))
Example #13
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
Example #14
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))