Add new script to partially dump DPX headers.
[dcpomatic.git] / hacks / dump_j2k.py
1 #!/usr/bin/python
2
3 import sys
4
5 def read(f, n):
6     r = []
7     for i in range(0, n):
8         r.append(ord(f.read(1)))
9     return r
10
11 def read_8(f):
12     r = read(f, 1)
13     return r[0]
14
15 def read_16(f):
16     r = read(f, 2)
17     return r[0] << 8 | r[1]
18
19 def read_32(f):
20     r = read(f, 4)
21     return r[0] << 24 | r[1] << 16 | r[2] << 8 | r[3];
22
23 def require(f, data, what):
24     r = read(f, len(data))
25     if r != data:
26         print r
27         raise Exception()
28     print what
29
30 f = open(sys.argv[1], 'rb')
31
32 require(f, [0xff, 0x4f], 'SOC')
33 require(f, [0xff, 0x51], 'SIZ')
34 size = read_16(f)
35 print '\tlength', size
36 f.seek(size - 2, 1)
37 require(f, [0xff, 0x52], 'COD')
38 size = read_16(f)
39 print '\tlength', size
40 coding_style = read_8(f)
41 print '\tcoding style %2x' % coding_style
42 print '\tprogression order',
43 po = read_8(f)
44 if po == 0:
45     print 'LRCP'
46 elif po == 1:
47     print 'RLCP'
48 elif po == 2:
49     print 'RPCL'
50 elif po == 3:
51     print 'PCRL'
52 elif po == 4:
53     print 'CPRL'
54 print '\tlayers', read_16(f)
55 print '\tmulti-component transform', read_8(f)
56 levels = read_8(f)
57 print '\ttransform levels', levels
58 print '\tcode-block sizes %dx%d' % (read_8(f), read_8(f))
59 print '\tmode switches %2x' % read_8(f)
60 print '\twavelet transform',
61 wt = read_8(f)
62 if wt == 0:
63     print '9/7 irreversible'
64 else:
65     print '5/3 reversible'
66 if coding_style & 1:
67     print '\tprecinct sizes ',
68     for i in range(0, levels + 1):
69         print read_8(f),
70     print
71 require(f, [0xff, 0x5C], 'QCD')
72 size = read_16(f)
73 print '\tlength', size
74 f.seek(size - 2, 1)
75
76 tile_part_length = None
77
78 while True:
79     r = read(f, 2)
80     if r == [0xff, 0x53]:
81         print 'COC'
82         size = read_16(f)
83         print '\tlength', size
84         f.seek(size - 2, 1)
85     elif r == [0xff, 0x5c]:
86         print 'QCD'
87         size = read_16(f)
88         print '\tlength', size
89         f.seek(size - 2, 1)
90     elif r == [0xff, 0x5d]:
91         print 'QCC'
92         size = read_16(f)
93         print '\tlength', size
94         f.seek(size - 2, 1)
95     elif r == [0xff, 0x64]:
96         print 'COM'
97         size = read_16(f)
98         print '\tlength', size
99         f.seek(size - 2, 1)
100     elif r == [0xff, 0x55]:
101         print 'TLM'
102         size = read_16(f)
103         print '\tlength', size
104         f.seek(size - 2, 1)
105     elif r == [0xff, 0x90]:
106         print 'SOT'
107         size = read_16(f)
108         print '\tlength', size
109         print '\ttile index', read_16(f)
110         tile_part_length = read_32(f)
111         print '\ttile-part length', tile_part_length
112         print '\ttile-part index', read_8(f)
113         print '\tnumber of tile-parts', read_8(f)
114     elif r == [0xff, 0x93]:
115         print 'SOD'
116         f.seek(tile_part_length - 14, 1)
117     elif r == [0xff, 0xd9]:
118         print 'EOC'
119         sys.exit(0)
120     else:
121         print r
122         raise Exception()