4d8eae497db6efd1906e2b3f6ecf35c5ce952c5e
[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 from mediagoblin.tools.testing import _activate_testing
27
28 _activate_testing()
29
30
31 def assert_in(a, b):
32 assert a in b, "%r not in %r" % (a, b)
33
34
35 def test_exif_extraction():
36 '''
37 Test EXIF extraction from a good image
38 '''
39 result = extract_exif(GOOD_JPG)
40 clean = clean_exif(result)
41 useful = get_useful(clean)
42 gps = get_gps_data(result)
43
44 # Do we have the result?
45 assert len(result) == 56
46
47 # Do we have clean data?
48 assert len(clean) == 53
49
50 # GPS data?
51 assert gps == {}
52
53 # Do we have the "useful" tags?
54 assert useful == {
55 'EXIF Flash': {
56 'field_type': 3,
57 'printable': u'Flash did not fire',
58 'field_offset': 380,
59 'tag': 37385,
60 'values': [0],
61 'field_length': 2},
62 'EXIF ExposureTime': {
63 'field_type': 5,
64 'printable': '1/125',
65 'field_offset': 700,
66 'tag': 33434,
67 'values': [[1, 125]],
68 'field_length': 8},
69 'EXIF FocalLength': {
70 'field_type': 5,
71 'printable': '18',
72 'field_offset': 780,
73 'tag': 37386,
74 'values': [[18, 1]],
75 'field_length': 8},
76 'Image Model': {
77 'field_type': 2,
78 'printable': 'NIKON D80',
79 'field_offset': 152,
80 'tag': 272,
81 'values': 'NIKON D80',
82 'field_length': 10},
83 'Image Make': {
84 'field_type': 2,
85 'printable': 'NIKON CORPORATION',
86 'field_offset': 134,
87 'tag': 271,
88 'values': 'NIKON CORPORATION',
89 'field_length': 18},
90 'EXIF ExposureMode': {
91 'field_type': 3,
92 'printable': 'Manual Exposure',
93 'field_offset': 584,
94 'tag': 41986,
95 'values': [1],
96 'field_length': 2},
97 'EXIF ISOSpeedRatings': {
98 'field_type': 3,
99 'printable': '100',
100 'field_offset': 260,
101 'tag': 34855,
102 'values': [100],
103 'field_length': 2},
104 'EXIF FNumber': {
105 'field_type': 5,
106 'printable': '10',
107 'field_offset': 708,
108 'tag': 33437,
109 'values': [[10, 1]],
110 'field_length': 8}}
111
112
113 def test_exif_image_orientation():
114 '''
115 Test image reorientation based on EXIF data
116 '''
117 result = extract_exif(GOOD_JPG)
118
119 image = exif_fix_image_orientation(
120 Image.open(GOOD_JPG),
121 result)
122
123 # Are the dimensions correct?
124 assert image.size == (428, 640)
125
126 # If this pixel looks right, the rest of the image probably will too.
127 assert_in(image.getdata()[10000],
128 ((41, 28, 11), (43, 27, 11))
129 )
130
131
132 def test_exif_no_exif():
133 '''
134 Test an image without exif
135 '''
136 result = extract_exif(EMPTY_JPG)
137 clean = clean_exif(result)
138 useful = get_useful(clean)
139 gps = get_gps_data(result)
140
141 assert result == {}
142 assert clean == {}
143 assert gps == {}
144 assert useful == {}
145
146
147 def test_exif_bad_image():
148 '''
149 Test EXIF extraction from a faithful, but bad image
150 '''
151 result = extract_exif(BAD_JPG)
152 clean = clean_exif(result)
153 useful = get_useful(clean)
154 gps = get_gps_data(result)
155
156 assert result == {}
157 assert clean == {}
158 assert gps == {}
159 assert useful == {}
160
161
162 def test_exif_gps_data():
163 '''
164 Test extractiion of GPS data
165 '''
166 result = extract_exif(GPS_JPG)
167 gps = get_gps_data(result)
168
169 assert gps == {
170 'latitude': 59.336666666666666,
171 'direction': 25.674046740467404,
172 'altitude': 37.64365671641791,
173 'longitude': 18.016166666666667}