File: ppmrotate.py

package info (click to toggle)
grass 8.4.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 277,040 kB
  • sloc: ansic: 460,798; python: 227,732; cpp: 42,026; sh: 11,262; makefile: 7,007; xml: 3,637; sql: 968; lex: 520; javascript: 484; yacc: 450; asm: 387; perl: 157; sed: 25; objc: 6; ruby: 4
file content (134 lines) | stat: -rwxr-xr-x 3,140 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env python3
#
# ppmrotate.py: Rotate PPM images
#
#  AUTHOR: Glynn Clements (Python version)
#          Vaclav Petras (separate script)
#      Earlier Bourne script version by Hamish Bowman,
#      https://grasswiki.osgeo.org/wiki/Talk:Color_tables
#
#   (C) 2009-2017 by the GRASS Development Team
#       This program is free software under the GNU General Public
#       License (>=v2). Read the file COPYING that comes with GRASS
#       for details.
#

import sys
import os
import atexit
import array
import grass.script as grass

tmp_img = None

height = None
width = None


def cleanup():
    if tmp_img:
        grass.try_remove(tmp_img)


# def rotate(src, dst):
#     grass.call(["convert", "-rotate", "90", src, dst])


def read_ppm(src):
    global width, height

    fh = open(src, "rb")
    text = fh.read()
    fh.close()
    i = 0
    j = text.find("\n", i)
    if text[i:j] != "P6":
        raise OSError(text[i:j] + " != P6. Is the file PPM?")
    i = j + 1
    j = text.find("\n", i)
    w, h = text[i:j].split()
    width = int(w)
    height = int(h)
    i = j + 1
    j = text.find("\n", i)
    maxval = text[i:j]
    if int(maxval) != 255:
        raise OSError("Max value in image != 255")
    i = j + 1
    return array.array("B", text[i:])


def write_ppm(dst, data):
    w = height
    h = width
    fh = open(dst, "wb")
    fh.write("P6\n%d %d\n%d\n" % (w, h, 255))
    data.tofile(fh)
    fh.close()


def rotate_ppm(srcd):
    dstd = array.array("B", len(srcd) * "\0")
    for y in range(height):
        for x in range(width):
            for c in range(3):
                old_pos = (y * width + x) * 3 + c
                new_pos = (x * height + (height - 1 - y)) * 3 + c
                dstd[new_pos] = srcd[old_pos]
    return dstd


def flip_ppm(srcd):
    dstd = array.array("B", len(srcd) * "\0")
    stride = width * 3
    for y in range(height):
        dy = height - 1 - y
        dstd[dy * stride : (dy + 1) * stride] = srcd[y * stride : (y + 1) * stride]
    return dstd


def ppmtopng(dst, src):
    if grass.find_program("g.ppmtopng", "--help"):
        grass.run_command("g.ppmtopng", input=src, output=dst, quiet=True)
    elif grass.find_program("pnmtopng"):
        fh = open(dst, "wb")
        grass.call(["pnmtopng", src], stdout=fh)
        fh.close()
    elif grass.find_program("convert"):
        grass.call(["convert", src, dst])
    else:
        grass.fatal(_("Cannot find g.ppmtopng, pnmtopng or convert"))


def convert_and_rotate(src, dst, flip=False):
    global tmp_img

    ppm = read_ppm(src)
    if flip:
        ppm = flip_ppm(ppm)
    ppm = rotate_ppm(ppm)
    to_png = False
    if dst.lower().endswith(".png"):
        to_png = True
    if to_png:
        tmp_img = grass.tempfile() + ".ppm"
        # TODO: clean up the file
    else:
        tmp_img = dst
    write_ppm(tmp_img, ppm)
    if to_png:
        ppmtopng(dst, tmp_img)


def main():
    os.environ["GRASS_OVERWRITE"] = "1"

    infile = sys.argv[1]
    outfile = sys.argv[2]

    convert_and_rotate(infile, outfile, flip=False)


if __name__ == "__main__":
    atexit.register(cleanup)
    main()