[MPEG-OTSPEC] checksum / 4-byte table offset weasel wording

Peter Constable pgcon6 at msn.com
Mon Aug 31 19:08:51 CEST 2020


I generally like the idea of clearly distinguishing between producer and consumer, though I think the distinction can be described in terms of requirements/recommendations for font data versus software implementations / applications.

The algorithm you provide does allow for non-four-byte alignment and for the last table not being padded to a four-byte boundary before EOF is reached. It's not the algorithm that's been documented for the past 30 years, though. I'd be OK with changing the spec to do that, if there's general consensus it would be a good and non-breaking change.


Peter

-----Original Message-----
From: Simon Cozens <simon at simon-cozens.org> 
Sent: Monday, August 31, 2020 9:43 AM
To: Peter Constable <pgcon6 at msn.com>; MPEG OT Spec list (mpeg-otspec at lists.aau.at) <mpeg-otspec at lists.aau.at>
Subject: Re: [MPEG-OTSPEC] checksum / 4-byte table offset weasel wording

On 31/08/2020 16:41, Peter Constable wrote:
> Either way, there would be one possible edge case that should be
> covered: the last table in a file, and how to calculate a checksum if 
> the table length is not a multiple of four. My inclination would be to 
> cover this -which would also cover the general case - by saying that, 
> if a table length is not a multiple of four, then it must be padded 
> with zero bytes to the next four-byte boundary.

This is another example where it's useful to have the distinction between what font consumers should do and what font producers should do.

CommonType puts it like this (I'm sorry if you're already fed up of hearing that phrase; please get used to it):


2.1.3.1. Implementation notes for font producers

* Tables must aligned to a four byte boundary.

* Table lengths must be a multiple of four bytes. Zero padding should be 
added to the end to make up an integral multiple if necessary.

* Table checksums are computed using the following checksum algorithm 
(in Python):

def calcChecksum(table):
     # Zero-pad table to four-byte boundary
     while len(table) % 4 > 0:
         table += b"\0"

     # Calculate the unsigned sum of all four-byte values
     value = 0
     for i in range(0, len(table), 4):
         long = struct.unpack(">L", table[i:i+4])
         value = (value + long) & 0xffffffff
     return value

[...]

2.1.3.2. Implementation notes for font consumers

* When validating table checksums, the head table must be treated as a 
special case, and its checkSumAdjustment value set to four zero bytes 
for the purposes of checksumming. Font consumers should not assume that 
the table length will be a multiple of four, and should use the above 
checksumming algorithm which adds zero padding to the table data.

S


More information about the mpeg-otspec mailing list