Merge remote-tracking branch 'refs/remotes/elrond/misc/pytest_enable_testing'
[mediagoblin.git] / mediagoblin / tests / test_exif.py
1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
3 #
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU Affero General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17 import os
18 try:
19 from PIL import Image
20 except ImportError:
21 import Image
22
23 from mediagoblin.tools.exif import exif_fix_image_orientation, \
24 extract_exif, clean_exif, get_gps_data, get_useful
25 from .resources import GOOD_JPG, EMPTY_JPG, BAD_JPG, GPS_JPG
26
27
28 def assert_in(a, b):
29 assert a in b, "%r not in %r" % (a, b)
30
31
32 def test_exif_extraction():
33 '''
34 Test EXIF extraction from a good image
35 '''
36 result = extract_exif(GOOD_JPG)
37 clean = clean_exif(result)
38 useful = get_useful(clean)
39 gps = get_gps_data(result)
40
41 # Do we have the result?
42 assert len(result) == 56
43
44 # Do we have clean data?
45 assert len(clean) == 53
46
47 # GPS data?
48 assert gps == {}
49
50 # Do we have the "useful" tags?
51 assert useful == {
52 'EXIF Flash': {
53 'field_type': 3,
54 'printable': u'Flash did not fire',
55 'field_offset': 380,
56 'tag': 37385,
57 'values': [0],
58 'field_length': 2},
59 'EXIF ExposureTime': {
60 'field_type': 5,
61 'printable': '1/125',
62 'field_offset': 700,
63 'tag': 33434,
64 'values': [[1, 125]],
65 'field_length': 8},
66 'EXIF FocalLength': {
67 'field_type': 5,
68 'printable': '18',
69 'field_offset': 780,
70 'tag': 37386,
71 'values': [[18, 1]],
72 'field_length': 8},
73 'Image Model': {
74 'field_type': 2,
75 'printable': 'NIKON D80',
76 'field_offset': 152,
77 'tag': 272,
78 'values': 'NIKON D80',
79 'field_length': 10},
80 'Image Make': {
81 'field_type': 2,
82 'printable': 'NIKON CORPORATION',
83 'field_offset': 134,
84 'tag': 271,
85 'values': 'NIKON CORPORATION',
86 'field_length': 18},
87 'EXIF ExposureMode': {
88 'field_type': 3,
89 'printable': 'Manual Exposure',
90 'field_offset': 584,
91 'tag': 41986,
92 'values': [1],
93 'field_length': 2},
94 'EXIF ISOSpeedRatings': {
95 'field_type': 3,
96 'printable': '100',
97 'field_offset': 260,
98 'tag': 34855,
99 'values': [100],
100 'field_length': 2},
101 'EXIF FNumber': {
102 'field_type': 5,
103 'printable': '10',
104 'field_offset': 708,
105 'tag': 33437,
106 'values': [[10, 1]],
107 'field_length': 8}}
108
109
110 def test_exif_image_orientation():
111 '''
112 Test image reorientation based on EXIF data
113 '''
114 result = extract_exif(GOOD_JPG)
115
116 image = exif_fix_image_orientation(
117 Image.open(GOOD_JPG),
118 result)
119
120 # Are the dimensions correct?
121 assert image.size == (428, 640)
122
123 # If this pixel looks right, the rest of the image probably will too.
124 assert_in(image.getdata()[10000],
125 ((41, 28, 11), (43, 27, 11))
126 )
127
128
129 def test_exif_no_exif():
130 '''
131 Test an image without exif
132 '''
133 result = extract_exif(EMPTY_JPG)
134 clean = clean_exif(result)
135 useful = get_useful(clean)
136 gps = get_gps_data(result)
137
138 assert result == {}
139 assert clean == {}
140 assert gps == {}
141 assert useful == {}
142
143
144 def test_exif_bad_image():
145 '''
146 Test EXIF extraction from a faithful, but bad image
147 '''
148 result = extract_exif(BAD_JPG)
149 clean = clean_exif(result)
150 useful = get_useful(clean)
151 gps = get_gps_data(result)
152
153 assert result == {}
154 assert clean == {}
155 assert gps == {}
156 assert useful == {}
157
158
159 def test_exif_gps_data():
160 '''
161 Test extractiion of GPS data
162 '''
163 result = extract_exif(GPS_JPG)
164 gps = get_gps_data(result)
165
166 assert gps == {
167 'latitude': 59.336666666666666,
168 'direction': 25.674046740467404,
169 'altitude': 37.64365671641791,
170 'longitude': 18.016166666666667}