|
|
|
#! /usr/bin/env python
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import exif
|
|
|
|
|
|
|
|
def compose(delta, old):
|
|
|
|
map=[0, 4, 2, 6, 5, 1, 7, 3]
|
|
|
|
unmap=[1, 6, 3, 8, 2, 5, 4, 7]
|
|
|
|
x = map[delta-1]
|
|
|
|
y = map[old-1]
|
|
|
|
z = ((x^y)&4) + ((y+(x&3)*(((y&4)>>1)+1))&3)
|
|
|
|
return unmap[z]
|
|
|
|
|
|
|
|
def deg2o(d):
|
|
|
|
map={90:6, 270:8, 180:3}
|
|
|
|
if map.has_key(d):
|
|
|
|
return map[d]
|
|
|
|
else:
|
|
|
|
return 0
|
|
|
|
|
|
|
|
if len(sys.argv) < 2:
|
|
|
|
print 'Usage: %s [[+]orientnum] file\n' % sys.argv[0]
|
|
|
|
sys.exit(1)
|
|
|
|
try:
|
|
|
|
if len(sys.argv) == 2:
|
|
|
|
filename=sys.argv[1]
|
|
|
|
file=open(filename, "r");
|
|
|
|
else:
|
|
|
|
filename=sys.argv[2]
|
|
|
|
mod=sys.argv[1]
|
|
|
|
fd = os.open(filename, os.O_RDWR)
|
|
|
|
file=os.fdopen(fd,'r')
|
|
|
|
# check file exists and is readable
|
|
|
|
file.read(1)
|
|
|
|
file.seek(0,0)
|
|
|
|
except:
|
|
|
|
print 'Cannot open', filename
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
tags=exif.process_file(file,0,1)
|
|
|
|
if not tags:
|
|
|
|
print 'no EXIF information in', filename
|
|
|
|
sys.exit(1)
|
|
|
|
if not tags.has_key('Exif Offset') \
|
|
|
|
or not tags.has_key('Image Qt::Orientation'):
|
|
|
|
print 'cannot get orientation info in', filename
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
exifp = tags['Exif Offset']
|
|
|
|
endian = tags['Exif Endian']
|
|
|
|
tagp = tags['Image Qt::Orientation'].field_offset
|
|
|
|
|
|
|
|
orientp = exifp + tagp
|
|
|
|
|
|
|
|
if endian == 'M': # MM byte order
|
|
|
|
orientp += 1
|
|
|
|
|
|
|
|
file.seek(orientp)
|
|
|
|
o = ord(file.read(1))
|
|
|
|
|
|
|
|
if o < 1 or o > 8:
|
|
|
|
print 'orientation out of range', o
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
if len(sys.argv) == 2:
|
|
|
|
print 'orientation is', o
|
|
|
|
sys.exit(0)
|
|
|
|
|
|
|
|
try:
|
|
|
|
if mod[0] == '+':
|
|
|
|
deltao = int(mod)
|
|
|
|
if 1 <= deltao and deltao <= 8:
|
|
|
|
newo = compose(deltao, o)
|
|
|
|
elif deg2o(deltao) != 0:
|
|
|
|
newo = compose(deg2o(deltao), o)
|
|
|
|
else:
|
|
|
|
print 'cannot understand orientation modification', mod
|
|
|
|
sys.exit(1) # it will still hit the except ... how to fix?
|
|
|
|
else:
|
|
|
|
newo = int(mod)
|
|
|
|
except:
|
|
|
|
print 'expected numeric orientation and got',mod
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
if newo < 1 or newo > 8:
|
|
|
|
newo = deg2o(newo)
|
|
|
|
if newo == 0:
|
|
|
|
print 'cannot understand orientation', deltao
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
os.lseek(fd,orientp,0)
|
|
|
|
os.write(fd,chr(newo))
|
|
|
|
|
|
|
|
# Thumbnail orientation :
|
|
|
|
thumb_ifdp = 0
|
|
|
|
if tags.has_key('Thumbnail Qt::Orientation'):
|
|
|
|
thumb_tagp = tags['Thumbnail Qt::Orientation'].field_offset
|
|
|
|
thumb_orientp = exifp + thumb_tagp
|
|
|
|
if endian == 'M': # MM byte order
|
|
|
|
thumb_orientp += 1
|
|
|
|
os.lseek(fd,thumb_orientp,0)
|
|
|
|
os.write(fd,chr(newo))
|
|
|
|
|
|
|
|
print 'orientation changed from', o, 'to', newo
|