PNG (Portable Network Graphics) Specification, Version 1.2


Previous page
Next page
Table of contents

15. 付録: CRC コードのサンプル

以下のサンプルコードは PNG チャンクで使われる実用的な CRC (Cyclic Redundancy Check) の実装に相当します。(ISO 3309 [ISO-3309] と ITU-T V.42 [ITU-T-V42] も正式な仕様として参照してください)

サンプルコードは ANSI C 言語です。非 C 利用者はこれらのヒントをよむことで簡単だと感じるかもしれません:

&

ビット積演算子.

^

ビット差演算子

>>

右シフト演算子。無符号量に適用されたときはここでは右シフトは左に 0 を挿入します。

!

否定演算子

++

N++ は変数 N をインクリメントします。

0xNNN

0x は 16 進定数を導入します。接尾子 L は(少なくとも 32-bit の)長値を導入します。


   /* Table of CRCs of all 8-bit messages. */
   unsigned long crc_table[256];
   
   /* Flag: has the table been computed? Initially false. */
   int crc_table_computed = 0;
   
   /* Make the table for a fast CRC. */
   void make_crc_table(void)
   {
     unsigned long c;
     int n, k;
   
     for (n = 0; n < 256; n++) {
       c = (unsigned long) n;
       for (k = 0; k < 8; k++) {
         if (c & 1)
           c = 0xedb88320L ^ (c >> 1);
         else
           c = c >> 1;
       }
       crc_table[n] = c;
     }
     crc_table_computed = 1;
   }
   
   /* Update a running CRC with the bytes buf[0..len-1]--the CRC
      should be initialized to all 1's, and the transmitted value
      is the 1's complement of the final running CRC (see the
      crc() routine below)). */
   
   unsigned long update_crc(unsigned long crc, unsigned char *buf,
                            int len)
   {
     unsigned long c = crc;
     int n;
   
     if (!crc_table_computed)
       make_crc_table();
     for (n = 0; n < len; n++) {
       c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
     }
     return c;
   }
   
   /* Return the CRC of the bytes buf[0..len-1]. */
   unsigned long crc(unsigned char *buf, int len)
   {
     return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL;
   }



Previous page
Next page
Table of contents