Calculating checksums for different structures.

  • Thread starter grishin-mailing-lists
  • Start date
G

grishin-mailing-lists

Hi there,

I've been writing a program that generates a subfont-file of a given
font and number of needed glyphs. User decides which glyphs to
preserve and which to remove. Though it's not really important.

What is important that I have to rebuild some font tables -> their
checksums will change.
When I start the project I was dealing with tables of plain
structures, like:
typedef struct
{
USHORT MajorVersion;
USHORT MinorVersion;
USHORT NumTables;
USHORT SearchRange;
USHORT EntrySelector;
USHORT RangeShift;
} ttFontHeader;

I used casting to char * and calculated all of the new checksums by
this routine:
ULONG CalcTableChecksum(ULONG *Table, ULONG Length)
{
ULONG Sum = 0L;
ULONG *EndPtr = Table+((Length+3) & ~3) / sizeof(ULONG);
while (Table < EndPtr)
{
Sum += swap32(*Table++);
}

return Sum;
}

It worked well.
I've ended up with rebuilding cmap format 4 table which has a
sophisticated structure. I had to use vectors:
typedef struct
{ /* ÐÏÐÙÔËÁ ÓÄÅÌÁÔØ ÏÂÝÅÅ ÈÒÁÎÉÌÉÝÅ ÄÌÑ ÞÁÓÔÏ ÉÓÐÏÌØÚÕÅÍÙÈ ÆÏÒÍÁÔÏ×
(0 É 4) */
USHORT Format;
USHORT Length;
USHORT Language;
unsigned SegCount;
signed SearchRange;
signed EntrySelector;
signed RangeShift;
std::vector<ttCmapSegment> Segments;
std::vector<USHORT> GlyphIDs;
} ttCmapSubtable;
typedef struct
{
USHORT Version;
USHORT NumTables;
std::vector<ttCmapEncodingRecord> EncRecords;
std::vector<ttCmapSubtable> Subtables;
} ttCmap;
and now I can't just cast this to char* but I still need to calculate
its' checksum somehow.
For now I've written a special routine that calculates checksum
specially for cmap table.
What if I have to rebuild other 31 table? I have to write 31 checksum
functions -- one for the table!
There should be more elegant solution.

Thank you.
 
J

Jonathan Lee

I used casting to char * and calculated all of the new checksums by
this routine:

That's not going to be portable. Even if there isn't padding in
in the struct, endianness can change across platforms. Maybe
you're only supporting one platform, though.
and now I can't just cast this to char* but I still need to calculate
its' checksum somehow.
For now I've written a special routine that calculates checksum
specially for cmap table.

I think it makes more sense to provide a CRC routine that expects
a certain format, and then provide member functions to convert
your structs to this format. Usually a CRC would take raw
"byte data" (I mean an array of unsigned chars). A well defined
structure-to-byte-data conversion is usually named serialize().
If you're exporting your font data to a particular file format
on disk, this is probably identical or very similar. If you're
not doing this, you'll probably want to google for "serialization".

--Jonathan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top