~ubuntu-branches/ubuntu/precise/tiff/precise-security

« back to all changes in this revision

Viewing changes to .pc/CVE-2014-81xx-5.patch/tools/tiffcmp.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2015-03-30 08:11:18 UTC
  • Revision ID: package-import@ubuntu.com-20150330081118-bvaoaii1act27voq
Tags: 3.9.5-2ubuntu1.7
* SECURITY UPDATE: Fix multiple security issues
  - debian/patches/CVE-2014-81xx-1.patch to CVE-2014-81xx-11.patch
  - debian/patches/CVE-2014-8128-5.patch
  - debian/patches/CVE-2014-9655-1.patch to CVE-2014-9655-3.patch
  - debian/patches/read_overrun.patch
  - debian/patches/CVE-2014-8130.patch
  - CVE-2014-8127 (partially)
  - CVE-2014-8128
  - CVE-2014-8129
  - CVE-2014-8130
  - CVE-2014-9330
  - CVE-2014-9655

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: tiffcmp.c,v 1.13.2.1 2010-06-08 18:50:44 bfriesen Exp $ */
 
2
 
 
3
/*
 
4
 * Copyright (c) 1988-1997 Sam Leffler
 
5
 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
 
6
 *
 
7
 * Permission to use, copy, modify, distribute, and sell this software and 
 
8
 * its documentation for any purpose is hereby granted without fee, provided
 
9
 * that (i) the above copyright notices and this permission notice appear in
 
10
 * all copies of the software and related documentation, and (ii) the names of
 
11
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
 
12
 * publicity relating to the software without the specific, prior written
 
13
 * permission of Sam Leffler and Silicon Graphics.
 
14
 * 
 
15
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
 
16
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
 
17
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
 
18
 * 
 
19
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
 
20
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
 
21
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 
22
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
 
23
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
 
24
 * OF THIS SOFTWARE.
 
25
 */
 
26
 
 
27
#include "tif_config.h"
 
28
 
 
29
#include <stdio.h>
 
30
#include <stdlib.h>
 
31
#include <string.h>
 
32
#include <math.h>
 
33
 
 
34
#ifdef HAVE_UNISTD_H
 
35
# include <unistd.h>
 
36
#endif
 
37
 
 
38
#include "tiffio.h"
 
39
 
 
40
#ifndef HAVE_GETOPT
 
41
extern int getopt(int, char**, char*);
 
42
#endif
 
43
 
 
44
static  int stopondiff = 1;
 
45
static  int stoponfirsttag = 1;
 
46
static  uint16 bitspersample = 1;
 
47
static  uint16 samplesperpixel = 1;
 
48
static  uint16 sampleformat = SAMPLEFORMAT_UINT;
 
49
static  uint32 imagewidth;
 
50
static  uint32 imagelength;
 
51
 
 
52
static  void usage(void);
 
53
static  int tiffcmp(TIFF*, TIFF*);
 
54
static  int cmptags(TIFF*, TIFF*);
 
55
static  int ContigCompare(int, uint32, unsigned char*, unsigned char*, int);
 
56
static  int SeparateCompare(int, int, uint32, unsigned char*, unsigned char*);
 
57
static  void PrintIntDiff(uint32, int, uint32, uint32, uint32);
 
58
static  void PrintFloatDiff(uint32, int, uint32, double, double);
 
59
 
 
60
static  void leof(const char*, uint32, int);
 
61
 
 
62
int
 
63
main(int argc, char* argv[])
 
64
{
 
65
        TIFF *tif1, *tif2;
 
66
        int c, dirnum;
 
67
        extern int optind;
 
68
        extern char* optarg;
 
69
 
 
70
        while ((c = getopt(argc, argv, "ltz:")) != -1)
 
71
                switch (c) {
 
72
                case 'l':
 
73
                        stopondiff = 0;
 
74
                        break;
 
75
                case 'z':
 
76
                        stopondiff = atoi(optarg);
 
77
                        break;
 
78
                case 't':
 
79
                        stoponfirsttag = 0;
 
80
                        break;
 
81
                case '?':
 
82
                        usage();
 
83
                        /*NOTREACHED*/
 
84
                }
 
85
        if (argc - optind < 2)
 
86
                usage();
 
87
        tif1 = TIFFOpen(argv[optind], "r");
 
88
        if (tif1 == NULL)
 
89
                return (-1);
 
90
        tif2 = TIFFOpen(argv[optind+1], "r");
 
91
        if (tif2 == NULL)
 
92
                return (-2);
 
93
        dirnum = 0;
 
94
        while (tiffcmp(tif1, tif2)) {
 
95
                if (!TIFFReadDirectory(tif1)) {
 
96
                        if (!TIFFReadDirectory(tif2))
 
97
                                break;
 
98
                        printf("No more directories for %s\n",
 
99
                            TIFFFileName(tif1));
 
100
                        return (1);
 
101
                } else if (!TIFFReadDirectory(tif2)) {
 
102
                        printf("No more directories for %s\n",
 
103
                            TIFFFileName(tif2));
 
104
                        return (1);
 
105
                }
 
106
                printf("Directory %d:\n", ++dirnum);
 
107
        }
 
108
 
 
109
        TIFFClose(tif1);
 
110
        TIFFClose(tif2);
 
111
        return (0);
 
112
}
 
113
 
 
114
char* stuff[] = {
 
115
"usage: tiffcmp [options] file1 file2",
 
116
"where options are:",
 
117
" -l            list each byte of image data that differs between the files",
 
118
" -z #          list specified number of bytes that differs between the files",
 
119
" -t            ignore any differences in directory tags",
 
120
NULL
 
121
};
 
122
 
 
123
static void
 
124
usage(void)
 
125
{
 
126
        char buf[BUFSIZ];
 
127
        int i;
 
128
 
 
129
        setbuf(stderr, buf);
 
130
        fprintf(stderr, "%s\n\n", TIFFGetVersion());
 
131
        for (i = 0; stuff[i] != NULL; i++)
 
132
                fprintf(stderr, "%s\n", stuff[i]);
 
133
        exit(-1);
 
134
}
 
135
 
 
136
#define checkEOF(tif, row, sample) { \
 
137
        leof(TIFFFileName(tif), row, sample); \
 
138
        goto bad; \
 
139
}
 
140
 
 
141
static  int CheckShortTag(TIFF*, TIFF*, int, char*);
 
142
static  int CheckShort2Tag(TIFF*, TIFF*, int, char*);
 
143
static  int CheckShortArrayTag(TIFF*, TIFF*, int, char*);
 
144
static  int CheckLongTag(TIFF*, TIFF*, int, char*);
 
145
static  int CheckFloatTag(TIFF*, TIFF*, int, char*);
 
146
static  int CheckStringTag(TIFF*, TIFF*, int, char*);
 
147
 
 
148
static int
 
149
tiffcmp(TIFF* tif1, TIFF* tif2)
 
150
{
 
151
        uint16 config1, config2;
 
152
        tsize_t size1;
 
153
        uint32 row;
 
154
        tsample_t s;
 
155
        unsigned char *buf1, *buf2;
 
156
 
 
157
        if (!CheckShortTag(tif1, tif2, TIFFTAG_BITSPERSAMPLE, "BitsPerSample"))
 
158
                return (0);
 
159
        if (!CheckShortTag(tif1, tif2, TIFFTAG_SAMPLESPERPIXEL, "SamplesPerPixel"))
 
160
                return (0);
 
161
        if (!CheckLongTag(tif1, tif2, TIFFTAG_IMAGEWIDTH, "ImageWidth"))
 
162
                return (0);
 
163
        if (!cmptags(tif1, tif2))
 
164
                return (1);
 
165
        (void) TIFFGetField(tif1, TIFFTAG_BITSPERSAMPLE, &bitspersample);
 
166
        (void) TIFFGetField(tif1, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
 
167
        (void) TIFFGetField(tif1, TIFFTAG_SAMPLEFORMAT, &sampleformat);
 
168
        (void) TIFFGetField(tif1, TIFFTAG_IMAGEWIDTH, &imagewidth);
 
169
        (void) TIFFGetField(tif1, TIFFTAG_IMAGELENGTH, &imagelength);
 
170
        (void) TIFFGetField(tif1, TIFFTAG_PLANARCONFIG, &config1);
 
171
        (void) TIFFGetField(tif2, TIFFTAG_PLANARCONFIG, &config2);
 
172
        buf1 = (unsigned char *)_TIFFmalloc(size1 = TIFFScanlineSize(tif1));
 
173
        buf2 = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif2));
 
174
        if (buf1 == NULL || buf2 == NULL) {
 
175
                fprintf(stderr, "No space for scanline buffers\n");
 
176
                exit(-1);
 
177
        }
 
178
        if (config1 != config2 && bitspersample != 8 && samplesperpixel > 1) {
 
179
                fprintf(stderr,
 
180
"Can't handle different planar configuration w/ different bits/sample\n");
 
181
                goto bad;
 
182
        }
 
183
#define pack(a,b)       ((a)<<8)|(b)
 
184
        switch (pack(config1, config2)) {
 
185
        case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_CONTIG):
 
186
                for (row = 0; row < imagelength; row++) {
 
187
                        if (TIFFReadScanline(tif2, buf2, row, 0) < 0)
 
188
                                checkEOF(tif2, row, -1)
 
189
                        for (s = 0; s < samplesperpixel; s++) {
 
190
                                if (TIFFReadScanline(tif1, buf1, row, s) < 0)
 
191
                                        checkEOF(tif1, row, s)
 
192
                                if (SeparateCompare(1, s, row, buf2, buf1) < 0)
 
193
                                        goto bad1;
 
194
                        }
 
195
                }
 
196
                break;
 
197
        case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_SEPARATE):
 
198
                for (row = 0; row < imagelength; row++) {
 
199
                        if (TIFFReadScanline(tif1, buf1, row, 0) < 0)
 
200
                                checkEOF(tif1, row, -1)
 
201
                        for (s = 0; s < samplesperpixel; s++) {
 
202
                                if (TIFFReadScanline(tif2, buf2, row, s) < 0)
 
203
                                        checkEOF(tif2, row, s)
 
204
                                if (SeparateCompare(0, s, row, buf1, buf2) < 0)
 
205
                                        goto bad1;
 
206
                        }
 
207
                }
 
208
                break;
 
209
        case pack(PLANARCONFIG_SEPARATE, PLANARCONFIG_SEPARATE):
 
210
                for (s = 0; s < samplesperpixel; s++)
 
211
                        for (row = 0; row < imagelength; row++) {
 
212
                                if (TIFFReadScanline(tif1, buf1, row, s) < 0)
 
213
                                        checkEOF(tif1, row, s)
 
214
                                if (TIFFReadScanline(tif2, buf2, row, s) < 0)
 
215
                                        checkEOF(tif2, row, s)
 
216
                                if (ContigCompare(s, row, buf1, buf2, size1) < 0)
 
217
                                        goto bad1;
 
218
                        }
 
219
                break;
 
220
        case pack(PLANARCONFIG_CONTIG, PLANARCONFIG_CONTIG):
 
221
                for (row = 0; row < imagelength; row++) {
 
222
                        if (TIFFReadScanline(tif1, buf1, row, 0) < 0)
 
223
                                checkEOF(tif1, row, -1)
 
224
                        if (TIFFReadScanline(tif2, buf2, row, 0) < 0)
 
225
                                checkEOF(tif2, row, -1)
 
226
                        if (ContigCompare(-1, row, buf1, buf2, size1) < 0)
 
227
                                goto bad1;
 
228
                }
 
229
                break;
 
230
        }
 
231
        if (buf1) _TIFFfree(buf1);
 
232
        if (buf2) _TIFFfree(buf2);
 
233
        return (1);
 
234
bad:
 
235
        if (stopondiff)
 
236
                exit(1);
 
237
bad1:
 
238
        if (buf1) _TIFFfree(buf1);
 
239
        if (buf2) _TIFFfree(buf2);
 
240
        return (0);
 
241
}
 
242
 
 
243
#define CmpShortField(tag, name) \
 
244
        if (!CheckShortTag(tif1, tif2, tag, name) && stoponfirsttag) return (0)
 
245
#define CmpShortField2(tag, name) \
 
246
        if (!CheckShort2Tag(tif1, tif2, tag, name) && stoponfirsttag) return (0)
 
247
#define CmpLongField(tag, name) \
 
248
        if (!CheckLongTag(tif1, tif2, tag, name) && stoponfirsttag) return (0)
 
249
#define CmpFloatField(tag, name) \
 
250
        if (!CheckFloatTag(tif1, tif2, tag, name) && stoponfirsttag) return (0)
 
251
#define CmpStringField(tag, name) \
 
252
        if (!CheckStringTag(tif1, tif2, tag, name) && stoponfirsttag) return (0)
 
253
#define CmpShortArrayField(tag, name) \
 
254
        if (!CheckShortArrayTag(tif1, tif2, tag, name) && stoponfirsttag) return (0)
 
255
 
 
256
static int
 
257
cmptags(TIFF* tif1, TIFF* tif2)
 
258
{
 
259
        CmpLongField(TIFFTAG_SUBFILETYPE,       "SubFileType");
 
260
        CmpLongField(TIFFTAG_IMAGEWIDTH,        "ImageWidth");
 
261
        CmpLongField(TIFFTAG_IMAGELENGTH,       "ImageLength");
 
262
        CmpShortField(TIFFTAG_BITSPERSAMPLE,    "BitsPerSample");
 
263
        CmpShortField(TIFFTAG_COMPRESSION,      "Compression");
 
264
        CmpShortField(TIFFTAG_PREDICTOR,        "Predictor");
 
265
        CmpShortField(TIFFTAG_PHOTOMETRIC,      "PhotometricInterpretation");
 
266
        CmpShortField(TIFFTAG_THRESHHOLDING,    "Thresholding");
 
267
        CmpShortField(TIFFTAG_FILLORDER,        "FillOrder");
 
268
        CmpShortField(TIFFTAG_ORIENTATION,      "Orientation");
 
269
        CmpShortField(TIFFTAG_SAMPLESPERPIXEL,  "SamplesPerPixel");
 
270
        CmpShortField(TIFFTAG_MINSAMPLEVALUE,   "MinSampleValue");
 
271
        CmpShortField(TIFFTAG_MAXSAMPLEVALUE,   "MaxSampleValue");
 
272
        CmpShortField(TIFFTAG_SAMPLEFORMAT,     "SampleFormat");
 
273
        CmpFloatField(TIFFTAG_XRESOLUTION,      "XResolution");
 
274
        CmpFloatField(TIFFTAG_YRESOLUTION,      "YResolution");
 
275
        CmpLongField(TIFFTAG_GROUP3OPTIONS,     "Group3Options");
 
276
        CmpLongField(TIFFTAG_GROUP4OPTIONS,     "Group4Options");
 
277
        CmpShortField(TIFFTAG_RESOLUTIONUNIT,   "ResolutionUnit");
 
278
        CmpShortField(TIFFTAG_PLANARCONFIG,     "PlanarConfiguration");
 
279
        CmpLongField(TIFFTAG_ROWSPERSTRIP,      "RowsPerStrip");
 
280
        CmpFloatField(TIFFTAG_XPOSITION,        "XPosition");
 
281
        CmpFloatField(TIFFTAG_YPOSITION,        "YPosition");
 
282
        CmpShortField(TIFFTAG_GRAYRESPONSEUNIT, "GrayResponseUnit");
 
283
        CmpShortField(TIFFTAG_COLORRESPONSEUNIT, "ColorResponseUnit");
 
284
#ifdef notdef
 
285
        { uint16 *graycurve;
 
286
          CmpField(TIFFTAG_GRAYRESPONSECURVE, graycurve);
 
287
        }
 
288
        { uint16 *red, *green, *blue;
 
289
          CmpField3(TIFFTAG_COLORRESPONSECURVE, red, green, blue);
 
290
        }
 
291
        { uint16 *red, *green, *blue;
 
292
          CmpField3(TIFFTAG_COLORMAP, red, green, blue);
 
293
        }
 
294
#endif
 
295
        CmpShortField2(TIFFTAG_PAGENUMBER,      "PageNumber");
 
296
        CmpStringField(TIFFTAG_ARTIST,          "Artist");
 
297
        CmpStringField(TIFFTAG_IMAGEDESCRIPTION,"ImageDescription");
 
298
        CmpStringField(TIFFTAG_MAKE,            "Make");
 
299
        CmpStringField(TIFFTAG_MODEL,           "Model");
 
300
        CmpStringField(TIFFTAG_SOFTWARE,        "Software");
 
301
        CmpStringField(TIFFTAG_DATETIME,        "DateTime");
 
302
        CmpStringField(TIFFTAG_HOSTCOMPUTER,    "HostComputer");
 
303
        CmpStringField(TIFFTAG_PAGENAME,        "PageName");
 
304
        CmpStringField(TIFFTAG_DOCUMENTNAME,    "DocumentName");
 
305
        CmpShortField(TIFFTAG_MATTEING,         "Matteing");
 
306
        CmpShortArrayField(TIFFTAG_EXTRASAMPLES,"ExtraSamples");
 
307
        return (1);
 
308
}
 
309
 
 
310
static int
 
311
ContigCompare(int sample, uint32 row,
 
312
              unsigned char* p1, unsigned char* p2, int size)
 
313
{
 
314
    uint32 pix;
 
315
    int ppb = 8 / bitspersample;
 
316
    int  samples_to_test;
 
317
 
 
318
    if (memcmp(p1, p2, size) == 0)
 
319
        return 0;
 
320
 
 
321
    samples_to_test = (sample == -1) ? samplesperpixel : 1;
 
322
 
 
323
    switch (bitspersample) {
 
324
      case 1: case 2: case 4: case 8: 
 
325
      {
 
326
          unsigned char *pix1 = p1, *pix2 = p2;
 
327
 
 
328
          for (pix = 0; pix < imagewidth; pix += ppb) {
 
329
              int               s;
 
330
 
 
331
              for(s = 0; s < samples_to_test; s++) {
 
332
                  if (*pix1 != *pix2) {
 
333
                      if( sample == -1 )
 
334
                          PrintIntDiff(row, s, pix, *pix1, *pix2);
 
335
                      else
 
336
                          PrintIntDiff(row, sample, pix, *pix1, *pix2);
 
337
                  }
 
338
 
 
339
                  pix1++;
 
340
                  pix2++;
 
341
              }
 
342
          }
 
343
          break;
 
344
      }
 
345
      case 16: 
 
346
      {
 
347
          uint16 *pix1 = (uint16 *)p1, *pix2 = (uint16 *)p2;
 
348
 
 
349
          for (pix = 0; pix < imagewidth; pix++) {
 
350
              int       s;
 
351
 
 
352
              for(s = 0; s < samples_to_test; s++) {
 
353
                  if (*pix1 != *pix2)
 
354
                      PrintIntDiff(row, sample, pix, *pix1, *pix2);
 
355
                        
 
356
                  pix1++;
 
357
                  pix2++;
 
358
              }
 
359
          }
 
360
          break;
 
361
      }
 
362
      case 32: 
 
363
        if (sampleformat == SAMPLEFORMAT_UINT
 
364
            || sampleformat == SAMPLEFORMAT_INT) {
 
365
                uint32 *pix1 = (uint32 *)p1, *pix2 = (uint32 *)p2;
 
366
 
 
367
                for (pix = 0; pix < imagewidth; pix++) {
 
368
                        int     s;
 
369
 
 
370
                        for(s = 0; s < samples_to_test; s++) {
 
371
                                if (*pix1 != *pix2) {
 
372
                                        PrintIntDiff(row, sample, pix,
 
373
                                                     *pix1, *pix2);
 
374
                                }
 
375
                        
 
376
                                pix1++;
 
377
                                pix2++;
 
378
                        }
 
379
                }
 
380
        } else if (sampleformat == SAMPLEFORMAT_IEEEFP) {
 
381
                float *pix1 = (float *)p1, *pix2 = (float *)p2;
 
382
 
 
383
                for (pix = 0; pix < imagewidth; pix++) {
 
384
                        int     s;
 
385
 
 
386
                        for(s = 0; s < samples_to_test; s++) {
 
387
                                if (fabs(*pix1 - *pix2) < 0.000000000001) {
 
388
                                        PrintFloatDiff(row, sample, pix,
 
389
                                                       *pix1, *pix2);
 
390
                                }
 
391
                        
 
392
                                pix1++;
 
393
                                pix2++;
 
394
                        }
 
395
                }
 
396
        } else {
 
397
                  fprintf(stderr, "Sample format %d is not supported.\n",
 
398
                          sampleformat);
 
399
                  return -1;
 
400
        }
 
401
        break;
 
402
      default:
 
403
        fprintf(stderr, "Bit depth %d is not supported.\n", bitspersample);
 
404
        return -1;
 
405
    }
 
406
 
 
407
    return 0;
 
408
}
 
409
 
 
410
static void
 
411
PrintIntDiff(uint32 row, int sample, uint32 pix, uint32 w1, uint32 w2)
 
412
{
 
413
        if (sample < 0)
 
414
                sample = 0;
 
415
        switch (bitspersample) {
 
416
        case 1:
 
417
        case 2:
 
418
        case 4:
 
419
            {
 
420
                int32 mask1, mask2, s;
 
421
 
 
422
                mask1 =  ~((-1) << bitspersample);
 
423
                s = (8 - bitspersample);
 
424
                mask2 = mask1 << s;
 
425
                for (; mask2 && pix < imagewidth;
 
426
                     mask2 >>= bitspersample, s -= bitspersample, pix++) {
 
427
                        if ((w1 & mask2) ^ (w2 & mask2)) {
 
428
                                printf(
 
429
                        "Scanline %lu, pixel %lu, sample %d: %01x %01x\n",
 
430
                                        (unsigned long) row,
 
431
                                        (unsigned long) pix,
 
432
                                        sample,
 
433
                                        (unsigned int)((w1 >> s) & mask1),
 
434
                                        (unsigned int)((w2 >> s) & mask1));
 
435
                                if (--stopondiff == 0)
 
436
                                        exit(1);
 
437
                        }
 
438
                }
 
439
                break;
 
440
            }
 
441
        case 8: 
 
442
                printf("Scanline %lu, pixel %lu, sample %d: %02x %02x\n",
 
443
                       (unsigned long) row, (unsigned long) pix, sample,
 
444
                       (unsigned int) w1, (unsigned int) w2);
 
445
                if (--stopondiff == 0)
 
446
                        exit(1);
 
447
                break;
 
448
        case 16:
 
449
                printf("Scanline %lu, pixel %lu, sample %d: %04x %04x\n",
 
450
                    (unsigned long) row, (unsigned long) pix, sample,
 
451
                    (unsigned int) w1, (unsigned int) w2);
 
452
                if (--stopondiff == 0)
 
453
                        exit(1);
 
454
                break;
 
455
        case 32:
 
456
                printf("Scanline %lu, pixel %lu, sample %d: %08x %08x\n",
 
457
                    (unsigned long) row, (unsigned long) pix, sample,
 
458
                    (unsigned int) w1, (unsigned int) w2);
 
459
                if (--stopondiff == 0)
 
460
                        exit(1);
 
461
                break;
 
462
        default:
 
463
                break;
 
464
        }
 
465
}
 
466
 
 
467
static void
 
468
PrintFloatDiff(uint32 row, int sample, uint32 pix, double w1, double w2)
 
469
{
 
470
        if (sample < 0)
 
471
                sample = 0;
 
472
        switch (bitspersample) {
 
473
        case 32: 
 
474
                printf("Scanline %lu, pixel %lu, sample %d: %g %g\n",
 
475
                    (long) row, (long) pix, sample, w1, w2);
 
476
                if (--stopondiff == 0)
 
477
                        exit(1);
 
478
                break;
 
479
        default:
 
480
                break;
 
481
        }
 
482
}
 
483
 
 
484
static int
 
485
SeparateCompare(int reversed, int sample, uint32 row,
 
486
                unsigned char* cp1, unsigned char* p2)
 
487
{
 
488
        uint32 npixels = imagewidth;
 
489
        int pixel;
 
490
 
 
491
        cp1 += sample;
 
492
        for (pixel = 0; npixels-- > 0; pixel++, cp1 += samplesperpixel, p2++) {
 
493
                if (*cp1 != *p2) {
 
494
                        printf("Scanline %lu, pixel %lu, sample %ld: ",
 
495
                            (long) row, (long) pixel, (long) sample);
 
496
                        if (reversed)
 
497
                                printf("%02x %02x\n", *p2, *cp1);
 
498
                        else
 
499
                                printf("%02x %02x\n", *cp1, *p2);
 
500
                        if (--stopondiff == 0)
 
501
                                exit(1);
 
502
                }
 
503
        }
 
504
 
 
505
        return 0;
 
506
}
 
507
 
 
508
static int
 
509
checkTag(TIFF* tif1, TIFF* tif2, int tag, char* name, void* p1, void* p2)
 
510
{
 
511
 
 
512
        if (TIFFGetField(tif1, tag, p1)) {
 
513
                if (!TIFFGetField(tif2, tag, p2)) {
 
514
                        printf("%s tag appears only in %s\n",
 
515
                            name, TIFFFileName(tif1));
 
516
                        return (0);
 
517
                }
 
518
                return (1);
 
519
        } else if (TIFFGetField(tif2, tag, p2)) {
 
520
                printf("%s tag appears only in %s\n", name, TIFFFileName(tif2));
 
521
                return (0);
 
522
        }
 
523
        return (-1);
 
524
}
 
525
 
 
526
#define CHECK(cmp, fmt) {                               \
 
527
        switch (checkTag(tif1,tif2,tag,name,&v1,&v2)) { \
 
528
        case 1: if (cmp)                                \
 
529
        case -1:        return (1);                     \
 
530
                printf(fmt, name, v1, v2);              \
 
531
        }                                               \
 
532
        return (0);                                     \
 
533
}
 
534
 
 
535
static int
 
536
CheckShortTag(TIFF* tif1, TIFF* tif2, int tag, char* name)
 
537
{
 
538
        uint16 v1, v2;
 
539
        CHECK(v1 == v2, "%s: %u %u\n");
 
540
}
 
541
 
 
542
static int
 
543
CheckShort2Tag(TIFF* tif1, TIFF* tif2, int tag, char* name)
 
544
{
 
545
        uint16 v11, v12, v21, v22;
 
546
 
 
547
        if (TIFFGetField(tif1, tag, &v11, &v12)) {
 
548
                if (!TIFFGetField(tif2, tag, &v21, &v22)) {
 
549
                        printf("%s tag appears only in %s\n",
 
550
                            name, TIFFFileName(tif1));
 
551
                        return (0);
 
552
                }
 
553
                if (v11 == v21 && v12 == v22)
 
554
                        return (1);
 
555
                printf("%s: <%u,%u> <%u,%u>\n", name, v11, v12, v21, v22);
 
556
        } else if (TIFFGetField(tif2, tag, &v21, &v22))
 
557
                printf("%s tag appears only in %s\n", name, TIFFFileName(tif2));
 
558
        else
 
559
                return (1);
 
560
        return (0);
 
561
}
 
562
 
 
563
static int
 
564
CheckShortArrayTag(TIFF* tif1, TIFF* tif2, int tag, char* name)
 
565
{
 
566
        uint16 n1, *a1;
 
567
        uint16 n2, *a2;
 
568
 
 
569
        if (TIFFGetField(tif1, tag, &n1, &a1)) {
 
570
                if (!TIFFGetField(tif2, tag, &n2, &a2)) {
 
571
                        printf("%s tag appears only in %s\n",
 
572
                            name, TIFFFileName(tif1));
 
573
                        return (0);
 
574
                }
 
575
                if (n1 == n2) {
 
576
                        char* sep;
 
577
                        uint16 i;
 
578
 
 
579
                        if (memcmp(a1, a2, n1 * sizeof(uint16)) == 0)
 
580
                                return (1);
 
581
                        printf("%s: value mismatch, <%u:", name, n1);
 
582
                        sep = "";
 
583
                        for (i = 0; i < n1; i++)
 
584
                                printf("%s%u", sep, a1[i]), sep = ",";
 
585
                        printf("> and <%u: ", n2);
 
586
                        sep = "";
 
587
                        for (i = 0; i < n2; i++)
 
588
                                printf("%s%u", sep, a2[i]), sep = ",";
 
589
                        printf(">\n");
 
590
                } else
 
591
                        printf("%s: %u items in %s, %u items in %s", name,
 
592
                            n1, TIFFFileName(tif1),
 
593
                            n2, TIFFFileName(tif2)
 
594
                        );
 
595
        } else if (TIFFGetField(tif2, tag, &n2, &a2))
 
596
                printf("%s tag appears only in %s\n", name, TIFFFileName(tif2));
 
597
        else
 
598
                return (1);
 
599
        return (0);
 
600
}
 
601
 
 
602
static int
 
603
CheckLongTag(TIFF* tif1, TIFF* tif2, int tag, char* name)
 
604
{
 
605
        uint32 v1, v2;
 
606
        CHECK(v1 == v2, "%s: %u %u\n");
 
607
}
 
608
 
 
609
static int
 
610
CheckFloatTag(TIFF* tif1, TIFF* tif2, int tag, char* name)
 
611
{
 
612
        float v1, v2;
 
613
        CHECK(v1 == v2, "%s: %g %g\n");
 
614
}
 
615
 
 
616
static int
 
617
CheckStringTag(TIFF* tif1, TIFF* tif2, int tag, char* name)
 
618
{
 
619
        char *v1, *v2;
 
620
        CHECK(strcmp(v1, v2) == 0, "%s: \"%s\" \"%s\"\n");
 
621
}
 
622
 
 
623
static void
 
624
leof(const char* name, uint32 row, int s)
 
625
{
 
626
 
 
627
        printf("%s: EOF at scanline %lu", name, (unsigned long)row);
 
628
        if (s >= 0)
 
629
                printf(", sample %d", s);
 
630
        printf("\n");
 
631
}
 
632
 
 
633
/* vim: set ts=8 sts=8 sw=8 noet: */
 
634
/*
 
635
 * Local Variables:
 
636
 * mode: c
 
637
 * c-basic-offset: 8
 
638
 * fill-column: 78
 
639
 * End:
 
640
 */