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