Home | History | Annotate | Download | only in tools
      1 /* checksum-icc.c
      2  *
      3  * Copyright (c) 2013 John Cunningham Bowler
      4  *
      5  * Last changed in libpng 1.6.0 [February 14, 2013]
      6  *
      7  * This code is released under the libpng license.
      8  * For conditions of distribution and use, see the disclaimer
      9  * and license in png.h
     10  *
     11  * Generate crc32 and adler32 checksums of the given input files, used to
     12  * generate check-codes for use when matching ICC profiles within libpng.
     13  */
     14 #include <stdio.h>
     15 
     16 #include <zlib.h>
     17 
     18 static int
     19 read_one_file(FILE *ip, const char *name)
     20 {
     21    uLong length = 0;
     22    uLong a32 = adler32(0, NULL, 0);
     23    uLong c32 = crc32(0, NULL, 0);
     24    Byte header[132];
     25 
     26    for (;;)
     27    {
     28       int ch = getc(ip);
     29       Byte b;
     30 
     31       if (ch == EOF) break;
     32 
     33       b = (Byte)ch;
     34 
     35       if (length < sizeof header)
     36          header[length] = b;
     37 
     38       ++length;
     39       a32 = adler32(a32, &b, 1);
     40       c32 = crc32(c32, &b, 1);
     41    }
     42 
     43    if (ferror(ip))
     44       return 0;
     45 
     46    /* Success */
     47    printf("PNG_ICC_CHECKSUM(0x%8.8lx, 0x%8.8lx,\n   PNG_MD5("
     48       "0x%2.2x%2.2x%2.2x%2.2x, 0x%2.2x%2.2x%2.2x%2.2x, 0x%2.2x%2.2x%2.2x%2.2x,"
     49       " 0x%2.2x%2.2x%2.2x%2.2x), %d,\n"
     50       "   \"%4.4d/%2.2d/%2.2d %2.2d:%2.2d:%2.2d\", %lu, \"%s\")\n",
     51       (unsigned long)a32, (unsigned long)c32,
     52       header[84], header[85], header[86], header[87],
     53       header[88], header[89], header[90], header[91],
     54       header[92], header[93], header[94], header[95],
     55       header[96], header[97], header[98], header[99],
     56 #     define u16(x) (header[x] * 256 + header[x+1])
     57 #     define u32(x) (u16(x) * 65536 + u16(x+2))
     58       u32(64), u16(24), u16(26), u16(28), u16(30), u16(32), u16(34),
     59       (unsigned long)length, name);
     60 
     61    return 1;
     62 }
     63 
     64 int main(int argc, char **argv)
     65 {
     66    int err = 0;
     67 
     68    printf("/* adler32, crc32, MD5[16], intent, date, length, file-name */\n");
     69 
     70    if (argc > 1)
     71    {
     72       int i;
     73 
     74       for (i=1; i<argc; ++i)
     75       {
     76          FILE *ip = fopen(argv[i], "rb");
     77 
     78          if (ip == NULL || !read_one_file(ip, argv[i]))
     79          {
     80             err = 1;
     81             perror(argv[i]);
     82             fprintf(stderr, "%s: read error\n", argv[i]);
     83             printf("/* ERROR: %s */\n", argv[i]);
     84          }
     85 
     86          (void)fclose(ip);
     87       }
     88    }
     89 
     90    else
     91    {
     92       if (!read_one_file(stdin, "-"))
     93       {
     94          err = 1;
     95          perror("stdin");
     96          fprintf(stderr, "stdin: read error\n");
     97          printf("/* ERROR: stdin */\n");
     98       }
     99    }
    100 
    101    return err;
    102 }
    103