-
Notifications
You must be signed in to change notification settings - Fork 0
/
jp2box.py
164 lines (137 loc) · 4.76 KB
/
jp2box.py
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#!/usr/bin/python
# $Id: jp2box.py,v 1.16 2016/06/01 16:18:58 thor Exp $
import sys
import string
from jp2utils import *
class UnexpectedEOF(JP2Error):
def __init__(self):
JP2Error.__init__(self, "unexpected end of file")
class InvalidBoxLength(JP2Error):
def __init__(self, box):
JP2Error.__init__(self, "box %s has invalid box length " % box)
self.box = box
class JP2Box:
def __init__(self, box, infile, offs = 0):
self.infile = infile
if box == None:
self.indent = 0
self.offset = 0
self.end = 0
else:
self.indent = box.indent
self.offset = box.offset + offs
self.end = box.target
self.hdrsize = 0
self.boxsize = 0
self.target = 0
self.bodysize = 0
def print_indent(self, buffer, nl = 1):
print_indent(buffer, self.indent, nl)
def print_versflags(self,buffer):
self.print_indent("Version : %d" % version(buffer))
self.print_indent("Flags : 0x%06x" % flags(buffer))
def new_box(self, description):
if self.indent == 0:
self.print_indent("%-8s: New Box: %s" % (str(self.offset - self.hdrsize),description),0)
else:
self.print_indent("%-8s: Sub Box: %s" % (str(self.offset - self.hdrsize),description),0)
self.indent += 1
def end_box(self):
self.indent -= 1
print()
def print_hex(self, buffer):
print_hex(buffer,self.indent)
def boxname(self, id):
try:
for i in range(4):
string.index(string.letters + string.digits, id[i])
return id
except ValueError:
return "0x%02x%02x%02x%02x" % (ord(id[0]), ord(id[1]), ord(id[2]), ord(id[3]))
def parse_string_header(self,buffer):
length = ordl(buffer)
id = buffer[4:8]
buffer = buffer[8:len(buffer)]
# Read XLBox (extra box length, if any)
if length == 1:
xlength = buffer[0:8]
buffer = buffer[8:len(buffer)]
if len(xlength) < 8:
raise UnexpectedEOF
length = ordq(xlength)
if length < 16:
raise InvalidBoxLength(self.boxname(id))
else:
length = length - 16
elif length > 0 and length < 8:
raise InvalidBoxLength(self.boxname(id))
elif length > 0:
length = length - 8
return (buffer,length,id)
def parse_header(self):
if self.end > 0:
if self.infile.tell() == self.end:
return []
elif self.infile.tell() > self.end:
raise InvalidBoxLength("unknown box")
length = self.infile.read(4)
if len(length) == 0:
return []
elif len(length) < 4:
raise UnexpectedEOF()
length = ordl(length)
id = self.infile.read(4)
if len(id) < 4:
raise UnexpectedEOF
self.offset += 8
self.hdrsize = 8
# Read XLBox (extra box length, if any)
if length == 1:
xlength = self.infile.read(8)
self.offset += 8
self.hdrsize = 16
if len(xlength) < 8:
raise UnexpectedEOF
length = ordq(xlength)
if length < 16:
raise InvalidBoxLength(self.boxname(id))
else:
length = length - 16
elif length > 0 and length < 8:
raise InvalidBoxLength(self.boxname(id))
elif length > 0:
length = length - 8
elif length == 0:
return id,
self.boxsize = length
return (length,id)
def readbody(self):
# Read Box Content
if self.bodysize > 0:
buf = self.infile.read(self.bodysize)
else:
buf = self.infile.read()
return buf
def parse(self, hook):
"Parse a container box and call the hook for each sub-box."
while 1:
# Read LBox (box length)
header = self.parse_header()
if len(header) == 0:
return
if len(header) == 1:
id = header[0].decode('utf-8')
self.new_box("\"%s\"" % (id))
hook(self,id,"all up to EOF")
self.end_box()
continue
length = header[0]
id = header[1].decode('utf-8')
self.bodysize = length
self.target = self.infile.tell() + length
# Call hook
self.new_box("\"%s\"" % (id))
hook(self,id,"%d" % length)
self.infile.seek(self.target)
self.offset += length
self.end_box()