Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/olpcfr/tools/image.py
blob: cffc15680bde168986a56c98fea535f5b971174d (plain)
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

# python import
import logging, os, struct, StringIO

# atoideweb import
from atoideweb.tools import registry


def compute_width_height(width, height, max_width, max_height, use_max=False):
    # compute ratio
    _ratio_scr = max_width / float(max_height)
    _ratio_img = width / float(height)
    # ..
    if width > max_width\
    or height > max_height:
        if _ratio_img > _ratio_scr:
            width = max_width
            height = int(max_width / _ratio_img)
        elif _ratio_img < _ratio_scr:
            width = int(max_height * _ratio_img)
            height = max_height
        else:
            width = max_width
            height = max_height
        # ..
        return width, height
    # ..
    elif use_max is True:
        return max_width, max_height
    # ..
    else:
        return width, height


def get_image_info(path):
    """Tricky method found on Internet that returns the image info from a given
    raw image data.
    """
    # little check
    _info = registry.InfoRegistry().get_info(path)
    # already exist
    if _info is not None:
        return _info
    elif os.path.exists(path):
        pass
    else:
        return None, 0, 0
    # read file
    _f = open(path)
    _data = _f.read()
    _f.close()
    #
    size = len(_data)
    height = 0
    width = 0
    content_type = None

    # handle GIFs
    if (size >= 10) and _data[:6] in ('GIF87a', 'GIF89a'):
        # Check to see if content_type is correct
        content_type = 'image/gif'
        w, h = struct.unpack("<HH", _data[6:10])
        width = int(w)
        height = int(h)

    # See PNG 2. Edition spec (http://www.w3.org/TR/PNG/)
    # Bytes 0-7 are below, 4-byte chunk length, then 'IHDR'
    # and finally the 4-byte width, height
    elif ((size >= 24) and _data.startswith('\211PNG\r\n\032\n')
          and (_data[12:16] == 'IHDR')):
        content_type = 'image/png'
        w, h = struct.unpack(">LL", _data[16:24])
        width = int(w)
        height = int(h)

    # Maybe this is for an older PNG version.
    elif (size >= 16) and _data.startswith('\211PNG\r\n\032\n'):
        # Check to see if we have the right content type
        content_type = 'image/png'
        w, h = struct.unpack(">LL", _data[8:16])
        width = int(w)
        height = int(h)

    # handle JPEGs
    elif (size >= 2) and _data.startswith('\377\330'):
        content_type = 'image/jpeg'
        jpeg = StringIO.StringIO(_data)
        jpeg.read(2)
        b = jpeg.read(1)
        try:
            while (b and ord(b) != 0xDA):
                while (ord(b) != 0xFF): b = jpeg.read(1)
                while (ord(b) == 0xFF): b = jpeg.read(1)
                if (ord(b) >= 0xC0 and ord(b) <= 0xC3):
                    jpeg.read(3)
                    h, w = struct.unpack(">HH", jpeg.read(4))
                    break
                else:
                    jpeg.read(int(struct.unpack(">H", jpeg.read(2))[0])-2)
                b = jpeg.read(1)
            width = int(w)
            height = int(h)
        except struct.error:
            pass
        except ValueError:
            pass
    # udpate registry
    registry.InfoRegistry().set_info(path, (content_type, width, height))
    # ..
    return content_type, width, height