Home | History | Annotate | Download | only in filter
      1 /*
      2  * Raster test program routines for CUPS.
      3  *
      4  * Copyright 2007-2016 by Apple Inc.
      5  * Copyright 1997-2007 by Easy Software Products.
      6  *
      7  * These coded instructions, statements, and computer programs are the
      8  * property of Apple Inc. and are protected by Federal copyright
      9  * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
     10  * which should have been included with this file.  If this file is
     11  * missing or damaged, see the license at "http://www.cups.org/".
     12  *
     13  * This file is subject to the Apple OS-Developed Software exception.
     14  */
     15 
     16 /*
     17  * Include necessary headers...
     18  */
     19 
     20 #include <cups/raster-private.h>
     21 #include <cups/ppd.h>
     22 #include <math.h>
     23 
     24 
     25 /*
     26  * Test PS commands and header...
     27  */
     28 
     29 static const char *dsc_code =
     30 "[{\n"
     31 "%%BeginFeature: *PageSize Tabloid\n"
     32 "<</PageSize[792 1224]>>setpagedevice\n"
     33 "%%EndFeature\n"
     34 "} stopped cleartomark\n";
     35 static const char *setpagedevice_code =
     36 "<<"
     37 "/MediaClass(Media Class)"
     38 "/MediaColor((Media Color))"
     39 "/MediaType(Media\\\\Type)"
     40 "/OutputType<416263>"
     41 "/AdvanceDistance 1000"
     42 "/AdvanceMedia 1"
     43 "/Collate false"
     44 "/CutMedia 2"
     45 "/Duplex true"
     46 "/HWResolution[100 200]"
     47 "/InsertSheet true"
     48 "/Jog 3"
     49 "/LeadingEdge 1"
     50 "/ManualFeed true"
     51 "/MediaPosition 8#777"
     52 "/MediaWeight 16#fe01"
     53 "/MirrorPrint true"
     54 "/NegativePrint true"
     55 "/NumCopies 1"
     56 "/Orientation 1"
     57 "/OutputFaceUp true"
     58 "/PageSize[612 792.1]"
     59 "/Separations true"
     60 "/TraySwitch true"
     61 "/Tumble true"
     62 "/cupsMediaType 2"
     63 "/cupsColorOrder 1"
     64 "/cupsColorSpace 1"
     65 "/cupsCompression 1"
     66 "/cupsRowCount 1"
     67 "/cupsRowFeed 1"
     68 "/cupsRowStep 1"
     69 "/cupsBorderlessScalingFactor 1.001"
     70 "/cupsInteger0 1"
     71 "/cupsInteger1 2"
     72 "/cupsInteger2 3"
     73 "/cupsInteger3 4"
     74 "/cupsInteger4 5"
     75 "/cupsInteger5 6"
     76 "/cupsInteger6 7"
     77 "/cupsInteger7 8"
     78 "/cupsInteger8 9"
     79 "/cupsInteger9 10"
     80 "/cupsInteger10 11"
     81 "/cupsInteger11 12"
     82 "/cupsInteger12 13"
     83 "/cupsInteger13 14"
     84 "/cupsInteger14 15"
     85 "/cupsInteger15 16"
     86 "/cupsReal0 1.1"
     87 "/cupsReal1 2.1"
     88 "/cupsReal2 3.1"
     89 "/cupsReal3 4.1"
     90 "/cupsReal4 5.1"
     91 "/cupsReal5 6.1"
     92 "/cupsReal6 7.1"
     93 "/cupsReal7 8.1"
     94 "/cupsReal8 9.1"
     95 "/cupsReal9 10.1"
     96 "/cupsReal10 11.1"
     97 "/cupsReal11 12.1"
     98 "/cupsReal12 13.1"
     99 "/cupsReal13 14.1"
    100 "/cupsReal14 15.1"
    101 "/cupsReal15 16.1"
    102 "/cupsString0(1)"
    103 "/cupsString1(2)"
    104 "/cupsString2(3)"
    105 "/cupsString3(4)"
    106 "/cupsString4(5)"
    107 "/cupsString5(6)"
    108 "/cupsString6(7)"
    109 "/cupsString7(8)"
    110 "/cupsString8(9)"
    111 "/cupsString9(10)"
    112 "/cupsString10(11)"
    113 "/cupsString11(12)"
    114 "/cupsString12(13)"
    115 "/cupsString13(14)"
    116 "/cupsString14(15)"
    117 "/cupsString15(16)"
    118 "/cupsMarkerType(Marker Type)"
    119 "/cupsRenderingIntent(Rendering Intent)"
    120 "/cupsPageSizeName(Letter)"
    121 "/cupsPreferredBitsPerColor 17"
    122 ">> setpagedevice";
    123 
    124 static cups_page_header2_t setpagedevice_header =
    125 {
    126   "Media Class",			/* MediaClass */
    127   "(Media Color)",			/* MediaColor */
    128   "Media\\Type",			/* MediaType */
    129   "Abc",				/* OutputType */
    130   1000,					/* AdvanceDistance */
    131   CUPS_ADVANCE_FILE,			/* AdvanceMedia */
    132   CUPS_FALSE,				/* Collate */
    133   CUPS_CUT_JOB,				/* CutMedia */
    134   CUPS_TRUE,				/* Duplex */
    135   { 100, 200 },				/* HWResolution */
    136   { 0, 0, 0, 0 },			/* ImagingBoundingBox */
    137   CUPS_TRUE,				/* InsertSheet */
    138   CUPS_JOG_SET,				/* Jog */
    139   CUPS_EDGE_RIGHT,			/* LeadingEdge */
    140   { 0, 0 },				/* Margins */
    141   CUPS_TRUE,				/* ManualFeed */
    142   0777,					/* MediaPosition */
    143   0xfe01,				/* MediaWeight */
    144   CUPS_TRUE,				/* MirrorPrint */
    145   CUPS_TRUE,				/* NegativePrint */
    146   1,					/* NumCopies */
    147   CUPS_ORIENT_90,			/* Orientation */
    148   CUPS_TRUE,				/* OutputFaceUp */
    149   { 612, 792 },				/* PageSize */
    150   CUPS_TRUE,				/* Separations */
    151   CUPS_TRUE,				/* TraySwitch */
    152   CUPS_TRUE,				/* Tumble */
    153   0,					/* cupsWidth */
    154   0,					/* cupsHeight */
    155   2,					/* cupsMediaType */
    156   0,					/* cupsBitsPerColor */
    157   0,					/* cupsBitsPerPixel */
    158   0,					/* cupsBytesPerLine */
    159   CUPS_ORDER_BANDED,			/* cupsColorOrder */
    160   CUPS_CSPACE_RGB,			/* cupsColorSpace */
    161   1,					/* cupsCompression */
    162   1,					/* cupsRowCount */
    163   1,					/* cupsRowFeed */
    164   1,					/* cupsRowStep */
    165   0,					/* cupsNumColors */
    166   1.001f,				/* cupsBorderlessScalingFactor */
    167   { 612.0f, 792.1f },			/* cupsPageSize */
    168   { 0.0f, 0.0f, 0.0f, 0.0f },		/* cupsImagingBBox */
    169   { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 },
    170 					/* cupsInteger[16] */
    171   { 1.1f, 2.1f, 3.1f, 4.1f, 5.1f, 6.1f, 7.1f, 8.1f, 9.1f, 10.1f, 11.1f, 12.1f, 13.1f, 14.1f, 15.1f, 16.1f },			/* cupsReal[16] */
    172   { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",
    173     "14", "15", "16" },			/* cupsString[16] */
    174   "Marker Type",			/* cupsMarkerType */
    175   "Rendering Intent",			/* cupsRenderingIntent */
    176   "Letter"				/* cupsPageSizeName */
    177 };
    178 
    179 
    180 /*
    181  * Local functions...
    182  */
    183 
    184 static int	do_ppd_tests(const char *filename, int num_options,
    185 		             cups_option_t *options);
    186 static int	do_ps_tests(void);
    187 static int	do_ras_file(const char *filename);
    188 static int	do_raster_tests(cups_mode_t mode);
    189 static void	print_changes(cups_page_header2_t *header,
    190 		              cups_page_header2_t *expected);
    191 
    192 
    193 /*
    194  * 'main()' - Test the raster functions.
    195  */
    196 
    197 int					/* O - Exit status */
    198 main(int  argc,				/* I - Number of command-line args */
    199      char *argv[])			/* I - Command-line arguments */
    200 {
    201   int		errors;			/* Number of errors */
    202   const char	*ext;			/* Filename extension */
    203 
    204 
    205   if (argc == 1)
    206   {
    207     errors = do_ps_tests();
    208     errors += do_raster_tests(CUPS_RASTER_WRITE);
    209     errors += do_raster_tests(CUPS_RASTER_WRITE_COMPRESSED);
    210     errors += do_raster_tests(CUPS_RASTER_WRITE_PWG);
    211     errors += do_raster_tests(CUPS_RASTER_WRITE_APPLE);
    212   }
    213   else
    214   {
    215     int			i;		/* Looping var */
    216     int			num_options;	/* Number of options */
    217     cups_option_t	*options;	/* Options */
    218 
    219 
    220     for (errors = 0, num_options = 0, options = NULL, i = 1; i < argc; i ++)
    221     {
    222       if (argv[i][0] == '-')
    223       {
    224         if (argv[i][1] == 'o')
    225         {
    226           if (argv[i][2])
    227             num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
    228           else
    229           {
    230             i ++;
    231             if (i < argc)
    232               num_options = cupsParseOptions(argv[i], num_options, &options);
    233             else
    234             {
    235               puts("Usage: testraster [-o name=value ...] [filename.ppd ...]");
    236               puts("       testraster [filename.ras ...]");
    237               return (1);
    238             }
    239           }
    240         }
    241         else
    242         {
    243           puts("Usage: testraster [-o name=value ...] [filename.ppd ...]");
    244 	  puts("       testraster [filename.ras ...]");
    245           return (1);
    246         }
    247       }
    248       else if ((ext = strrchr(argv[i], '.')) != NULL)
    249       {
    250         if (!strcmp(ext, ".ppd"))
    251 	  errors += do_ppd_tests(argv[i], num_options, options);
    252 	else
    253 	  errors += do_ras_file(argv[i]);
    254       }
    255       else
    256       {
    257 	puts("Usage: testraster [-o name=value ...] [filename.ppd ...]");
    258 	puts("       testraster [filename.ras ...]");
    259 	return (1);
    260       }
    261     }
    262 
    263     cupsFreeOptions(num_options, options);
    264   }
    265 
    266   return (errors);
    267 }
    268 
    269 
    270 /*
    271  * 'do_ppd_tests()' - Test the default option commands in a PPD file.
    272  */
    273 
    274 static int				/* O - Number of errors */
    275 do_ppd_tests(const char    *filename,	/* I - PPD file */
    276              int           num_options,	/* I - Number of options */
    277              cups_option_t *options)	/* I - Options */
    278 {
    279   ppd_file_t		*ppd;		/* PPD file data */
    280   cups_page_header2_t	header;		/* Page header */
    281 
    282 
    283   printf("\"%s\": ", filename);
    284   fflush(stdout);
    285 
    286   if ((ppd = ppdOpenFile(filename)) == NULL)
    287   {
    288     ppd_status_t	status;		/* Status from PPD loader */
    289     int			line;		/* Line number containing error */
    290 
    291 
    292     status = ppdLastError(&line);
    293 
    294     puts("FAIL (bad PPD file)");
    295     printf("    %s on line %d\n", ppdErrorString(status), line);
    296 
    297     return (1);
    298   }
    299 
    300   ppdMarkDefaults(ppd);
    301   cupsMarkOptions(ppd, num_options, options);
    302 
    303   if (cupsRasterInterpretPPD(&header, ppd, 0, NULL, NULL))
    304   {
    305     puts("FAIL (error from function)");
    306     puts(cupsRasterErrorString());
    307 
    308     return (1);
    309   }
    310   else
    311   {
    312     puts("PASS");
    313 
    314     return (0);
    315   }
    316 }
    317 
    318 
    319 /*
    320  * 'do_ps_tests()' - Test standard PostScript commands.
    321  */
    322 
    323 static int
    324 do_ps_tests(void)
    325 {
    326   cups_page_header2_t	header;		/* Page header */
    327   int			preferred_bits;	/* Preferred bits */
    328   int			errors = 0;	/* Number of errors */
    329 
    330 
    331  /*
    332   * Test PS exec code...
    333   */
    334 
    335   fputs("_cupsRasterExecPS(\"setpagedevice\"): ", stdout);
    336   fflush(stdout);
    337 
    338   memset(&header, 0, sizeof(header));
    339   header.Collate = CUPS_TRUE;
    340   preferred_bits = 0;
    341 
    342   if (_cupsRasterExecPS(&header, &preferred_bits, setpagedevice_code))
    343   {
    344     puts("FAIL (error from function)");
    345     puts(cupsRasterErrorString());
    346     errors ++;
    347   }
    348   else if (preferred_bits != 17 ||
    349            memcmp(&header, &setpagedevice_header, sizeof(header)))
    350   {
    351     puts("FAIL (bad header)");
    352 
    353     if (preferred_bits != 17)
    354       printf("    cupsPreferredBitsPerColor %d, expected 17\n",
    355              preferred_bits);
    356 
    357     print_changes(&setpagedevice_header, &header);
    358     errors ++;
    359   }
    360   else
    361     puts("PASS");
    362 
    363   fputs("_cupsRasterExecPS(\"roll\"): ", stdout);
    364   fflush(stdout);
    365 
    366   if (_cupsRasterExecPS(&header, &preferred_bits,
    367                         "792 612 0 0 0\n"
    368 			"pop pop pop\n"
    369                 	"<</PageSize[5 -2 roll]/ImagingBBox null>>"
    370 			"setpagedevice\n"))
    371   {
    372     puts("FAIL (error from function)");
    373     puts(cupsRasterErrorString());
    374     errors ++;
    375   }
    376   else if (header.PageSize[0] != 792 || header.PageSize[1] != 612)
    377   {
    378     printf("FAIL (PageSize [%d %d], expected [792 612])\n", header.PageSize[0],
    379            header.PageSize[1]);
    380     errors ++;
    381   }
    382   else
    383     puts("PASS");
    384 
    385   fputs("_cupsRasterExecPS(\"dup index\"): ", stdout);
    386   fflush(stdout);
    387 
    388   if (_cupsRasterExecPS(&header, &preferred_bits,
    389                         "true false dup\n"
    390 			"<</Collate 4 index"
    391 			"/Duplex 5 index"
    392 			"/Tumble 6 index>>setpagedevice\n"
    393 			"pop pop pop"))
    394   {
    395     puts("FAIL (error from function)");
    396     puts(cupsRasterErrorString());
    397     errors ++;
    398   }
    399   else
    400   {
    401     if (!header.Collate)
    402     {
    403       printf("FAIL (Collate false, expected true)\n");
    404       errors ++;
    405     }
    406 
    407     if (header.Duplex)
    408     {
    409       printf("FAIL (Duplex true, expected false)\n");
    410       errors ++;
    411     }
    412 
    413     if (header.Tumble)
    414     {
    415       printf("FAIL (Tumble true, expected false)\n");
    416       errors ++;
    417     }
    418 
    419     if(header.Collate && !header.Duplex && !header.Tumble)
    420       puts("PASS");
    421   }
    422 
    423   fputs("_cupsRasterExecPS(\"%%Begin/EndFeature code\"): ", stdout);
    424   fflush(stdout);
    425 
    426   if (_cupsRasterExecPS(&header, &preferred_bits, dsc_code))
    427   {
    428     puts("FAIL (error from function)");
    429     puts(cupsRasterErrorString());
    430     errors ++;
    431   }
    432   else if (header.PageSize[0] != 792 || header.PageSize[1] != 1224)
    433   {
    434     printf("FAIL (bad PageSize [%d %d], expected [792 1224])\n",
    435            header.PageSize[0], header.PageSize[1]);
    436     errors ++;
    437   }
    438   else
    439     puts("PASS");
    440 
    441   return (errors);
    442 }
    443 
    444 
    445 /*
    446  * 'do_ras_file()' - Test reading of a raster file.
    447  */
    448 
    449 static int				/* O - Number of errors */
    450 do_ras_file(const char *filename)	/* I - Filename */
    451 {
    452   unsigned		y;		/* Looping vars */
    453   int			fd;		/* File descriptor */
    454   cups_raster_t		*ras;		/* Raster stream */
    455   cups_page_header2_t	header;		/* Page header */
    456   unsigned char		*data;		/* Raster data */
    457   int			errors = 0;	/* Number of errors */
    458   unsigned		pages = 0;	/* Number of pages */
    459 
    460 
    461   if ((fd = open(filename, O_RDONLY)) < 0)
    462   {
    463     printf("%s: %s\n", filename, strerror(errno));
    464     return (1);
    465   }
    466 
    467   if ((ras = cupsRasterOpen(fd, CUPS_RASTER_READ)) == NULL)
    468   {
    469     printf("%s: cupsRasterOpen failed.\n", filename);
    470     close(fd);
    471     return (1);
    472   }
    473 
    474   printf("%s:\n", filename);
    475 
    476   while (cupsRasterReadHeader2(ras, &header))
    477   {
    478     pages ++;
    479     data = malloc(header.cupsBytesPerLine);
    480 
    481     printf("    Page %u: %ux%ux%u@%ux%udpi", pages,
    482            header.cupsWidth, header.cupsHeight, header.cupsBitsPerPixel,
    483            header.HWResolution[0], header.HWResolution[1]);
    484     fflush(stdout);
    485 
    486     for (y = 0; y < header.cupsHeight; y ++)
    487       if (cupsRasterReadPixels(ras, data, header.cupsBytesPerLine) <
    488               header.cupsBytesPerLine)
    489         break;
    490 
    491     if (y < header.cupsHeight)
    492       printf(" ERROR AT LINE %d\n", y);
    493     else
    494       putchar('\n');
    495 
    496     free(data);
    497   }
    498 
    499   printf("EOF at %ld\n", (long)lseek(fd, SEEK_CUR, 0));
    500 
    501   cupsRasterClose(ras);
    502   close(fd);
    503 
    504   return (errors);
    505 }
    506 
    507 
    508 /*
    509  * 'do_raster_tests()' - Test reading and writing of raster data.
    510  */
    511 
    512 static int				/* O - Number of errors */
    513 do_raster_tests(cups_mode_t mode)	/* O - Write mode */
    514 {
    515   unsigned		page, x, y;	/* Looping vars */
    516   FILE			*fp;		/* Raster file */
    517   cups_raster_t		*r;		/* Raster stream */
    518   cups_page_header2_t	header,		/* Page header */
    519 			expected;	/* Expected page header */
    520   unsigned char		data[2048];	/* Raster data */
    521   int			errors = 0;	/* Number of errors */
    522 
    523 
    524  /*
    525   * Test writing...
    526   */
    527 
    528   printf("cupsRasterOpen(%s): ",
    529          mode == CUPS_RASTER_WRITE ? "CUPS_RASTER_WRITE" :
    530 	     mode == CUPS_RASTER_WRITE_COMPRESSED ? "CUPS_RASTER_WRITE_COMPRESSED" :
    531 	     mode == CUPS_RASTER_WRITE_PWG ? "CUPS_RASTER_WRITE_PWG" :
    532 				             "CUPS_RASTER_WRITE_APPLE");
    533   fflush(stdout);
    534 
    535   if ((fp = fopen("test.raster", "wb")) == NULL)
    536   {
    537     printf("FAIL (%s)\n", strerror(errno));
    538     return (1);
    539   }
    540 
    541   if ((r = cupsRasterOpen(fileno(fp), mode)) == NULL)
    542   {
    543     printf("FAIL (%s)\n", strerror(errno));
    544     fclose(fp);
    545     return (1);
    546   }
    547 
    548   puts("PASS");
    549 
    550   for (page = 0; page < 4; page ++)
    551   {
    552     memset(&header, 0, sizeof(header));
    553     header.cupsWidth        = 256;
    554     header.cupsHeight       = 256;
    555     header.cupsBytesPerLine = 256;
    556     header.HWResolution[0]  = 64;
    557     header.HWResolution[1]  = 64;
    558     header.PageSize[0]      = 288;
    559     header.PageSize[1]      = 288;
    560     header.cupsPageSize[0]  = 288.0f;
    561     header.cupsPageSize[1]  = 288.0f;
    562 
    563     if (page & 1)
    564     {
    565       header.cupsBytesPerLine *= 4;
    566       header.cupsColorSpace = CUPS_CSPACE_CMYK;
    567       header.cupsColorOrder = CUPS_ORDER_CHUNKED;
    568       header.cupsNumColors  = 4;
    569     }
    570     else
    571     {
    572       header.cupsColorSpace = CUPS_CSPACE_W;
    573       header.cupsColorOrder = CUPS_ORDER_CHUNKED;
    574       header.cupsNumColors  = 1;
    575     }
    576 
    577     if (page & 2)
    578     {
    579       header.cupsBytesPerLine *= 2;
    580       header.cupsBitsPerColor = 16;
    581       header.cupsBitsPerPixel = (page & 1) ? 64 : 16;
    582     }
    583     else
    584     {
    585       header.cupsBitsPerColor = 8;
    586       header.cupsBitsPerPixel = (page & 1) ? 32 : 8;
    587     }
    588 
    589     if (cupsRasterWriteHeader2(r, &header))
    590       puts("cupsRasterWriteHeader2: PASS");
    591     else
    592     {
    593       puts("cupsRasterWriteHeader2: FAIL");
    594       errors ++;
    595     }
    596 
    597     fputs("cupsRasterWritePixels: ", stdout);
    598     fflush(stdout);
    599 
    600     memset(data, 0, header.cupsBytesPerLine);
    601     for (y = 0; y < 64; y ++)
    602       if (!cupsRasterWritePixels(r, data, header.cupsBytesPerLine))
    603         break;
    604 
    605     if (y < 64)
    606     {
    607       puts("FAIL");
    608       errors ++;
    609     }
    610     else
    611     {
    612       for (x = 0; x < header.cupsBytesPerLine; x ++)
    613 	data[x] = (unsigned char)x;
    614 
    615       for (y = 0; y < 64; y ++)
    616 	if (!cupsRasterWritePixels(r, data, header.cupsBytesPerLine))
    617 	  break;
    618 
    619       if (y < 64)
    620       {
    621 	puts("FAIL");
    622 	errors ++;
    623       }
    624       else
    625       {
    626 	memset(data, 255, header.cupsBytesPerLine);
    627 	for (y = 0; y < 64; y ++)
    628 	  if (!cupsRasterWritePixels(r, data, header.cupsBytesPerLine))
    629 	    break;
    630 
    631 	if (y < 64)
    632 	{
    633 	  puts("FAIL");
    634 	  errors ++;
    635 	}
    636 	else
    637 	{
    638 	  for (x = 0; x < header.cupsBytesPerLine; x ++)
    639 	    data[x] = (unsigned char)(x / 4);
    640 
    641 	  for (y = 0; y < 64; y ++)
    642 	    if (!cupsRasterWritePixels(r, data, header.cupsBytesPerLine))
    643 	      break;
    644 
    645 	  if (y < 64)
    646 	  {
    647 	    puts("FAIL");
    648 	    errors ++;
    649 	  }
    650 	  else
    651 	    puts("PASS");
    652         }
    653       }
    654     }
    655   }
    656 
    657   cupsRasterClose(r);
    658   fclose(fp);
    659 
    660  /*
    661   * Test reading...
    662   */
    663 
    664   fputs("cupsRasterOpen(CUPS_RASTER_READ): ", stdout);
    665   fflush(stdout);
    666 
    667   if ((fp = fopen("test.raster", "rb")) == NULL)
    668   {
    669     printf("FAIL (%s)\n", strerror(errno));
    670     return (1);
    671   }
    672 
    673   if ((r = cupsRasterOpen(fileno(fp), CUPS_RASTER_READ)) == NULL)
    674   {
    675     printf("FAIL (%s)\n", strerror(errno));
    676     fclose(fp);
    677     return (1);
    678   }
    679 
    680   puts("PASS");
    681 
    682   for (page = 0; page < 4; page ++)
    683   {
    684     memset(&expected, 0, sizeof(expected));
    685     expected.cupsWidth        = 256;
    686     expected.cupsHeight       = 256;
    687     expected.cupsBytesPerLine = 256;
    688     expected.HWResolution[0]  = 64;
    689     expected.HWResolution[1]  = 64;
    690     expected.PageSize[0]      = 288;
    691     expected.PageSize[1]      = 288;
    692 
    693     if (mode != CUPS_RASTER_WRITE_PWG)
    694     {
    695       expected.cupsPageSize[0] = 288.0f;
    696       expected.cupsPageSize[1] = 288.0f;
    697     }
    698 
    699     if (mode >= CUPS_RASTER_WRITE_PWG)
    700     {
    701       strlcpy(expected.MediaClass, "PwgRaster", sizeof(expected.MediaClass));
    702       expected.cupsInteger[7] = 0xffffff;
    703     }
    704 
    705     if (page & 1)
    706     {
    707       expected.cupsBytesPerLine *= 4;
    708       expected.cupsColorSpace = CUPS_CSPACE_CMYK;
    709       expected.cupsColorOrder = CUPS_ORDER_CHUNKED;
    710       expected.cupsNumColors  = 4;
    711     }
    712     else
    713     {
    714       expected.cupsColorSpace = CUPS_CSPACE_W;
    715       expected.cupsColorOrder = CUPS_ORDER_CHUNKED;
    716       expected.cupsNumColors  = 1;
    717     }
    718 
    719     if (page & 2)
    720     {
    721       expected.cupsBytesPerLine *= 2;
    722       expected.cupsBitsPerColor = 16;
    723       expected.cupsBitsPerPixel = (page & 1) ? 64 : 16;
    724     }
    725     else
    726     {
    727       expected.cupsBitsPerColor = 8;
    728       expected.cupsBitsPerPixel = (page & 1) ? 32 : 8;
    729     }
    730 
    731     fputs("cupsRasterReadHeader2: ", stdout);
    732     fflush(stdout);
    733 
    734     if (!cupsRasterReadHeader2(r, &header))
    735     {
    736       puts("FAIL (read error)");
    737       errors ++;
    738       break;
    739     }
    740 
    741     if (memcmp(&header, &expected, sizeof(header)))
    742     {
    743       puts("FAIL (bad page header)");
    744       errors ++;
    745       print_changes(&header, &expected);
    746     }
    747 
    748     fputs("cupsRasterReadPixels: ", stdout);
    749     fflush(stdout);
    750 
    751     for (y = 0; y < 64; y ++)
    752     {
    753       if (!cupsRasterReadPixels(r, data, header.cupsBytesPerLine))
    754       {
    755         puts("FAIL (read error)");
    756 	errors ++;
    757 	break;
    758       }
    759 
    760       if (data[0] != 0 || memcmp(data, data + 1, header.cupsBytesPerLine - 1))
    761       {
    762         printf("FAIL (raster line %d corrupt)\n", y);
    763 	errors ++;
    764 	break;
    765       }
    766     }
    767 
    768     if (y == 64)
    769     {
    770       for (y = 0; y < 64; y ++)
    771       {
    772 	if (!cupsRasterReadPixels(r, data, header.cupsBytesPerLine))
    773 	{
    774 	  puts("FAIL (read error)");
    775 	  errors ++;
    776 	  break;
    777 	}
    778 
    779 	for (x = 0; x < header.cupsBytesPerLine; x ++)
    780           if (data[x] != (x & 255))
    781 	    break;
    782 
    783 	if (x < header.cupsBytesPerLine)
    784 	{
    785 	  printf("FAIL (raster line %d corrupt)\n", y + 64);
    786 	  errors ++;
    787 	  break;
    788 	}
    789       }
    790 
    791       if (y == 64)
    792       {
    793 	for (y = 0; y < 64; y ++)
    794 	{
    795 	  if (!cupsRasterReadPixels(r, data, header.cupsBytesPerLine))
    796 	  {
    797 	    puts("FAIL (read error)");
    798 	    errors ++;
    799 	    break;
    800 	  }
    801 
    802 	  if (data[0] != 255 || memcmp(data, data + 1, header.cupsBytesPerLine - 1))
    803           {
    804 	    printf("fail (raster line %d corrupt)\n", y + 128);
    805 	    errors ++;
    806 	    break;
    807 	  }
    808 	}
    809 
    810         if (y == 64)
    811 	{
    812 	  for (y = 0; y < 64; y ++)
    813 	  {
    814 	    if (!cupsRasterReadPixels(r, data, header.cupsBytesPerLine))
    815 	    {
    816 	      puts("FAIL (read error)");
    817 	      errors ++;
    818 	      break;
    819 	    }
    820 
    821 	    for (x = 0; x < header.cupsBytesPerLine; x ++)
    822               if (data[x] != ((x / 4) & 255))
    823 		break;
    824 
    825 	    if (x < header.cupsBytesPerLine)
    826             {
    827 	      printf("FAIL (raster line %d corrupt)\n", y + 192);
    828 	      errors ++;
    829 	      break;
    830 	    }
    831 	  }
    832 
    833 	  if (y == 64)
    834 	    puts("PASS");
    835 	}
    836       }
    837     }
    838   }
    839 
    840   cupsRasterClose(r);
    841   fclose(fp);
    842 
    843   return (errors);
    844 }
    845 
    846 
    847 /*
    848  * 'print_changes()' - Print differences in the page header.
    849  */
    850 
    851 static void
    852 print_changes(
    853     cups_page_header2_t *header,	/* I - Actual page header */
    854     cups_page_header2_t *expected)	/* I - Expected page header */
    855 {
    856   int	i;				/* Looping var */
    857 
    858 
    859   if (strcmp(header->MediaClass, expected->MediaClass))
    860     printf("    MediaClass (%s), expected (%s)\n", header->MediaClass,
    861            expected->MediaClass);
    862 
    863   if (strcmp(header->MediaColor, expected->MediaColor))
    864     printf("    MediaColor (%s), expected (%s)\n", header->MediaColor,
    865            expected->MediaColor);
    866 
    867   if (strcmp(header->MediaType, expected->MediaType))
    868     printf("    MediaType (%s), expected (%s)\n", header->MediaType,
    869            expected->MediaType);
    870 
    871   if (strcmp(header->OutputType, expected->OutputType))
    872     printf("    OutputType (%s), expected (%s)\n", header->OutputType,
    873            expected->OutputType);
    874 
    875   if (header->AdvanceDistance != expected->AdvanceDistance)
    876     printf("    AdvanceDistance %d, expected %d\n", header->AdvanceDistance,
    877            expected->AdvanceDistance);
    878 
    879   if (header->AdvanceMedia != expected->AdvanceMedia)
    880     printf("    AdvanceMedia %d, expected %d\n", header->AdvanceMedia,
    881            expected->AdvanceMedia);
    882 
    883   if (header->Collate != expected->Collate)
    884     printf("    Collate %d, expected %d\n", header->Collate,
    885            expected->Collate);
    886 
    887   if (header->CutMedia != expected->CutMedia)
    888     printf("    CutMedia %d, expected %d\n", header->CutMedia,
    889            expected->CutMedia);
    890 
    891   if (header->Duplex != expected->Duplex)
    892     printf("    Duplex %d, expected %d\n", header->Duplex,
    893            expected->Duplex);
    894 
    895   if (header->HWResolution[0] != expected->HWResolution[0] ||
    896       header->HWResolution[1] != expected->HWResolution[1])
    897     printf("    HWResolution [%d %d], expected [%d %d]\n",
    898            header->HWResolution[0], header->HWResolution[1],
    899            expected->HWResolution[0], expected->HWResolution[1]);
    900 
    901   if (memcmp(header->ImagingBoundingBox, expected->ImagingBoundingBox,
    902              sizeof(header->ImagingBoundingBox)))
    903     printf("    ImagingBoundingBox [%d %d %d %d], expected [%d %d %d %d]\n",
    904            header->ImagingBoundingBox[0],
    905            header->ImagingBoundingBox[1],
    906            header->ImagingBoundingBox[2],
    907            header->ImagingBoundingBox[3],
    908            expected->ImagingBoundingBox[0],
    909            expected->ImagingBoundingBox[1],
    910            expected->ImagingBoundingBox[2],
    911            expected->ImagingBoundingBox[3]);
    912 
    913   if (header->InsertSheet != expected->InsertSheet)
    914     printf("    InsertSheet %d, expected %d\n", header->InsertSheet,
    915            expected->InsertSheet);
    916 
    917   if (header->Jog != expected->Jog)
    918     printf("    Jog %d, expected %d\n", header->Jog,
    919            expected->Jog);
    920 
    921   if (header->LeadingEdge != expected->LeadingEdge)
    922     printf("    LeadingEdge %d, expected %d\n", header->LeadingEdge,
    923            expected->LeadingEdge);
    924 
    925   if (header->Margins[0] != expected->Margins[0] ||
    926       header->Margins[1] != expected->Margins[1])
    927     printf("    Margins [%d %d], expected [%d %d]\n",
    928            header->Margins[0], header->Margins[1],
    929            expected->Margins[0], expected->Margins[1]);
    930 
    931   if (header->ManualFeed != expected->ManualFeed)
    932     printf("    ManualFeed %d, expected %d\n", header->ManualFeed,
    933            expected->ManualFeed);
    934 
    935   if (header->MediaPosition != expected->MediaPosition)
    936     printf("    MediaPosition %d, expected %d\n", header->MediaPosition,
    937            expected->MediaPosition);
    938 
    939   if (header->MediaWeight != expected->MediaWeight)
    940     printf("    MediaWeight %d, expected %d\n", header->MediaWeight,
    941            expected->MediaWeight);
    942 
    943   if (header->MirrorPrint != expected->MirrorPrint)
    944     printf("    MirrorPrint %d, expected %d\n", header->MirrorPrint,
    945            expected->MirrorPrint);
    946 
    947   if (header->NegativePrint != expected->NegativePrint)
    948     printf("    NegativePrint %d, expected %d\n", header->NegativePrint,
    949            expected->NegativePrint);
    950 
    951   if (header->NumCopies != expected->NumCopies)
    952     printf("    NumCopies %d, expected %d\n", header->NumCopies,
    953            expected->NumCopies);
    954 
    955   if (header->Orientation != expected->Orientation)
    956     printf("    Orientation %d, expected %d\n", header->Orientation,
    957            expected->Orientation);
    958 
    959   if (header->OutputFaceUp != expected->OutputFaceUp)
    960     printf("    OutputFaceUp %d, expected %d\n", header->OutputFaceUp,
    961            expected->OutputFaceUp);
    962 
    963   if (header->PageSize[0] != expected->PageSize[0] ||
    964       header->PageSize[1] != expected->PageSize[1])
    965     printf("    PageSize [%d %d], expected [%d %d]\n",
    966            header->PageSize[0], header->PageSize[1],
    967            expected->PageSize[0], expected->PageSize[1]);
    968 
    969   if (header->Separations != expected->Separations)
    970     printf("    Separations %d, expected %d\n", header->Separations,
    971            expected->Separations);
    972 
    973   if (header->TraySwitch != expected->TraySwitch)
    974     printf("    TraySwitch %d, expected %d\n", header->TraySwitch,
    975            expected->TraySwitch);
    976 
    977   if (header->Tumble != expected->Tumble)
    978     printf("    Tumble %d, expected %d\n", header->Tumble,
    979            expected->Tumble);
    980 
    981   if (header->cupsWidth != expected->cupsWidth)
    982     printf("    cupsWidth %d, expected %d\n", header->cupsWidth,
    983            expected->cupsWidth);
    984 
    985   if (header->cupsHeight != expected->cupsHeight)
    986     printf("    cupsHeight %d, expected %d\n", header->cupsHeight,
    987            expected->cupsHeight);
    988 
    989   if (header->cupsMediaType != expected->cupsMediaType)
    990     printf("    cupsMediaType %d, expected %d\n", header->cupsMediaType,
    991            expected->cupsMediaType);
    992 
    993   if (header->cupsBitsPerColor != expected->cupsBitsPerColor)
    994     printf("    cupsBitsPerColor %d, expected %d\n", header->cupsBitsPerColor,
    995            expected->cupsBitsPerColor);
    996 
    997   if (header->cupsBitsPerPixel != expected->cupsBitsPerPixel)
    998     printf("    cupsBitsPerPixel %d, expected %d\n", header->cupsBitsPerPixel,
    999            expected->cupsBitsPerPixel);
   1000 
   1001   if (header->cupsBytesPerLine != expected->cupsBytesPerLine)
   1002     printf("    cupsBytesPerLine %d, expected %d\n", header->cupsBytesPerLine,
   1003            expected->cupsBytesPerLine);
   1004 
   1005   if (header->cupsColorOrder != expected->cupsColorOrder)
   1006     printf("    cupsColorOrder %d, expected %d\n", header->cupsColorOrder,
   1007            expected->cupsColorOrder);
   1008 
   1009   if (header->cupsColorSpace != expected->cupsColorSpace)
   1010     printf("    cupsColorSpace %d, expected %d\n", header->cupsColorSpace,
   1011            expected->cupsColorSpace);
   1012 
   1013   if (header->cupsCompression != expected->cupsCompression)
   1014     printf("    cupsCompression %d, expected %d\n", header->cupsCompression,
   1015            expected->cupsCompression);
   1016 
   1017   if (header->cupsRowCount != expected->cupsRowCount)
   1018     printf("    cupsRowCount %d, expected %d\n", header->cupsRowCount,
   1019            expected->cupsRowCount);
   1020 
   1021   if (header->cupsRowFeed != expected->cupsRowFeed)
   1022     printf("    cupsRowFeed %d, expected %d\n", header->cupsRowFeed,
   1023            expected->cupsRowFeed);
   1024 
   1025   if (header->cupsRowStep != expected->cupsRowStep)
   1026     printf("    cupsRowStep %d, expected %d\n", header->cupsRowStep,
   1027            expected->cupsRowStep);
   1028 
   1029   if (header->cupsNumColors != expected->cupsNumColors)
   1030     printf("    cupsNumColors %d, expected %d\n", header->cupsNumColors,
   1031            expected->cupsNumColors);
   1032 
   1033   if (fabs(header->cupsBorderlessScalingFactor - expected->cupsBorderlessScalingFactor) > 0.001)
   1034     printf("    cupsBorderlessScalingFactor %g, expected %g\n",
   1035            header->cupsBorderlessScalingFactor,
   1036            expected->cupsBorderlessScalingFactor);
   1037 
   1038   if (fabs(header->cupsPageSize[0] - expected->cupsPageSize[0]) > 0.001 ||
   1039       fabs(header->cupsPageSize[1] - expected->cupsPageSize[1]) > 0.001)
   1040     printf("    cupsPageSize [%g %g], expected [%g %g]\n",
   1041            header->cupsPageSize[0], header->cupsPageSize[1],
   1042            expected->cupsPageSize[0], expected->cupsPageSize[1]);
   1043 
   1044   if (fabs(header->cupsImagingBBox[0] - expected->cupsImagingBBox[0]) > 0.001 ||
   1045       fabs(header->cupsImagingBBox[1] - expected->cupsImagingBBox[1]) > 0.001 ||
   1046       fabs(header->cupsImagingBBox[2] - expected->cupsImagingBBox[2]) > 0.001 ||
   1047       fabs(header->cupsImagingBBox[3] - expected->cupsImagingBBox[3]) > 0.001)
   1048     printf("    cupsImagingBBox [%g %g %g %g], expected [%g %g %g %g]\n",
   1049            header->cupsImagingBBox[0], header->cupsImagingBBox[1],
   1050            header->cupsImagingBBox[2], header->cupsImagingBBox[3],
   1051            expected->cupsImagingBBox[0], expected->cupsImagingBBox[1],
   1052            expected->cupsImagingBBox[2], expected->cupsImagingBBox[3]);
   1053 
   1054   for (i = 0; i < 16; i ++)
   1055     if (header->cupsInteger[i] != expected->cupsInteger[i])
   1056       printf("    cupsInteger%d %d, expected %d\n", i, header->cupsInteger[i],
   1057              expected->cupsInteger[i]);
   1058 
   1059   for (i = 0; i < 16; i ++)
   1060     if (fabs(header->cupsReal[i] - expected->cupsReal[i]) > 0.001)
   1061       printf("    cupsReal%d %g, expected %g\n", i, header->cupsReal[i],
   1062              expected->cupsReal[i]);
   1063 
   1064   for (i = 0; i < 16; i ++)
   1065     if (strcmp(header->cupsString[i], expected->cupsString[i]))
   1066       printf("    cupsString%d (%s), expected (%s)\n", i,
   1067 	     header->cupsString[i], expected->cupsString[i]);
   1068 
   1069   if (strcmp(header->cupsMarkerType, expected->cupsMarkerType))
   1070     printf("    cupsMarkerType (%s), expected (%s)\n", header->cupsMarkerType,
   1071            expected->cupsMarkerType);
   1072 
   1073   if (strcmp(header->cupsRenderingIntent, expected->cupsRenderingIntent))
   1074     printf("    cupsRenderingIntent (%s), expected (%s)\n",
   1075            header->cupsRenderingIntent,
   1076            expected->cupsRenderingIntent);
   1077 
   1078   if (strcmp(header->cupsPageSizeName, expected->cupsPageSizeName))
   1079     printf("    cupsPageSizeName (%s), expected (%s)\n",
   1080            header->cupsPageSizeName,
   1081            expected->cupsPageSizeName);
   1082 }
   1083