1d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.orgimport struct
2d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.orgimport sys
3d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org
4d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.orgdef readU32(contents, offset):
5d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org  wordBytes = contents[offset:offset + 4]
6d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org  return struct.unpack('>I', wordBytes)[0]
7d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org
8d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.orgdef readU16(contents, offset):
9d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org  wordBytes = contents[offset:offset + 2]
10d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org  return struct.unpack('>H', wordBytes)[0]
11d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org
12d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.orgdef checkChecksum(infile):
13d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org  contents = infile.read()
14d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org  if len(contents) % 4:
15d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org    print 'File length is not a multiple of 4'
16d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org
17d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org  sum = 0
18d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org  for offset in range(0, len(contents), 4):
19d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org    sum += readU32(contents, offset)
20d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org    while sum >= 2**32:
21d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org      sum -= 2**32
22d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org  print 'Sum of whole file: %x' % sum
23d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org
24d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org  numTables = readU16(contents, 4)
25d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org
26d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org  for offset in range(12, 12 + numTables * 16, 16):
27d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org    tag = contents[offset:offset + 4]
28d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org    chksum = readU32(contents, offset + 4)
29d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org    toffset = readU32(contents, offset + 8)
30d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org    tlength = readU32(contents, offset + 12)
31d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org
32d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org    sum = 0
33d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org    for offset2 in range(toffset, toffset + tlength, 4):
34d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org      sum += readU32(contents, offset2)
35d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org      while sum >= 2**32:
36d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org        sum -= 2**32
37d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org    if sum != chksum:
38d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org      print 'Bad chksum: %s' % tag
39d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org
40d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.orgif __name__ == '__main__':
41d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org  if len(sys.argv) != 2:
42d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org    print 'Usage: %s <ttf filename>' % sys.argv[0]
43d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org  else:
44d257d186ae2a08042a412824678f98241a1a4f3cyusukes@chromium.org    checkChecksum(file(sys.argv[1], 'r'))
45