[vorbis-dev] Problem with checksums

Erik Stenborg d99papa at dtek.chalmers.se
Fri Jul 12 16:24:01 PDT 2002



I'm trying to write a program that reads an ogg stream and check all the
CRC values along the way. But I have big trouble with computing the
checksum, or at least I never got checksums that match the one that is in
the ogg file. 

I do set the CRC field in the header to 0 before calculating it. I start
with 0 and have no xor at the end. I feed page header with all lacing
values and the page body to the CRC procedure. I even use the same look up
table in the CRC algo as is used in "framing.c". Still it deos not work.
Is there anything else I have to do?

Thanks,
Erik

============ code =============

CRC routine in C stolen from framing.c:

tatic unsigned int crc_lookup[256]={
  0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,
  [...]
  0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4};

extern void ChecksumCalc(unsigned int *crc_reg, char *buffer, unsigned int
size){
  unsigned int i;
  for(i=0;i<size;i++)
    *crc_reg=(*crc_reg<<8)^crc_lookup[((*crc_reg >>24)&0xff)^buffer[i]];
}

<p>Delphi test code:
type
  TByteArray = packed array of Byte;
  TCharArray = packed array of Char;

  TOggPageHeader = packed record
    CapturePattern: packed array [1..4] of Char;
    StreamStructureVersion,
    HeaderTypeFlag: Byte;
    AbsolutePosition: Int64;
    StreamSerialNumber,
    PageSequenceNumber,
    Checksum: Cardinal;
    PageSegments: Byte;
    SegmentTable: TByteArray;
    PageBodyLength: Cardinal;
  end;

procedure ChecksumCalc(var CRC: Cardinal; buffer: Pointer; size:
Cardinal); pascal; external;

[...]
  InStream.Read(PageHeader, 27);
  I := 0;
  if (PageHeader.CapturePattern <> 'OggS') then
    raise Exception.Create('Not a valid Ogg stream');
  if PageHeader.StreamStructureVersion <> 0 then
    raise Exception.CreateFmt('Not a valid stream structure version: %d',
[PageHeader.StreamStructureVersion]);
  SetLength(PageHeader.SegmentTable, PageHeader.PageSegments);
  InStream.Read(Pointer(PageHeader.SegmentTable)^,
PageHeader.PageSegments);
  PageHeader.PageBodyLength := SumByte(PageHeader.SegmentTable);
  SetLength(PageBody, PageHeader.PageBodyLength);
  InStream.Read(Pointer(PageBody)^, PageHeader.PageBodyLength);

  Temp := PageHeader.Checksum;
  PageHeader.Checksum := 0;

  CRC := 0;
  ChecksumCalc(CRC, @PageHeader, 27);
  ChecksumCalc(CRC, PageHeader.SegmentTable, PageHeader.PageSegments);
  ChecksumCalc(CRC, PageBody, PageHeader.PageBodyLength);

  PageHeader.Checksum := Temp;

<p>Now "CRC" and "PageHeader.Checksum" are different. What did I miss? All
the data is read correctly but there is something that goes wrong when
computing the checksum...

<p><p>--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'vorbis-dev-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the Vorbis-dev mailing list