]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - filter/rastertopwg.c
Fix source file header text duplication text duplication.
[thirdparty/cups.git] / filter / rastertopwg.c
index 6f6497c091cb1b797b9f02231faef36fbee7eac0..5026f565432f8aab306168c5e639fb2cb1d546ce 100644 (file)
@@ -1,31 +1,24 @@
 /*
- * "$Id$"
+ * CUPS raster to PWG raster format filter for CUPS.
  *
- *   CUPS raster to PWG raster format filter for CUPS.
+ * Copyright 2011, 2014-2016 Apple Inc.
  *
- *   Copyright 2011 Apple Inc.
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright law.
+ * Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file.  If this file is
+ * missing or damaged, see the license at "http://www.cups.org/".
  *
- *   These coded instructions, statements, and computer programs are the
- *   property of Apple Inc. and are protected by Federal copyright law.
- *   Distribution and use rights are outlined in the file "LICENSE.txt"
- *   which should have been included with this file.  If this file is
- *   file is missing or damaged, see the license at "http://www.cups.org/".
- *
- *   This file is subject to the Apple OS-Developed Software exception.
- *
- * Contents:
- *
- *   main() - Main entry for filter.
+ * This file is subject to the Apple OS-Developed Software exception.
  */
 
 /*
  * Include necessary headers...
  */
 
-#include <cups/cups.h>
-#include <cups/language-private.h>
+#include <cups/cups-private.h>
+#include <cups/ppd-private.h>
 #include <cups/raster.h>
-#include <cups/string-private.h>
 #include <unistd.h>
 #include <fcntl.h>
 
@@ -38,14 +31,16 @@ int                                 /* O - Exit status */
 main(int  argc,                                /* I - Number of command-line args */
      char *argv[])                     /* I - Command-line arguments */
 {
+  const char           *final_content_type;
+                                       /* FINAL_CONTENT_TYPE env var */
   int                  fd;             /* Raster file */
   cups_raster_t                *inras,         /* Input raster stream */
                        *outras;        /* Output raster stream */
   cups_page_header2_t  inheader,       /* Input raster page header */
                        outheader;      /* Output raster page header */
-  int                  y;              /* Current line */
+  unsigned             y;              /* Current line */
   unsigned char                *line;          /* Line buffer */
-  int                  page = 0,       /* Current page */
+  unsigned             page = 0,       /* Current page */
                        page_width,     /* Actual page width */
                        page_height,    /* Actual page height */
                        page_top,       /* Top margin */
@@ -54,6 +49,14 @@ main(int  argc,                              /* I - Number of command-line args */
                        linesize,       /* Bytes per line */
                        lineoffset;     /* Offset into line */
   unsigned char                white;          /* White pixel */
+  ppd_file_t           *ppd;           /* PPD file */
+  ppd_attr_t           *back;          /* cupsBackSide attribute */
+  _ppd_cache_t         *cache;         /* PPD cache */
+  pwg_size_t           *pwg_size;      /* PWG media size */
+  pwg_media_t          *pwg_media;     /* PWG media name */
+  int                  num_options;    /* Number of options */
+  cups_option_t                *options = NULL;/* Options */
+  const char           *val;           /* Option value */
 
 
   if (argc < 6 || argc > 7)
@@ -72,11 +75,47 @@ main(int  argc,                             /* I - Number of command-line args */
   else
     fd = 0;
 
+  if ((final_content_type = getenv("FINAL_CONTENT_TYPE")) == NULL)
+    final_content_type = "image/pwg-raster";
+
   inras  = cupsRasterOpen(fd, CUPS_RASTER_READ);
-  outras = cupsRasterOpen(1, CUPS_RASTER_WRITE_PWG);
+  outras = cupsRasterOpen(1, !strcmp(final_content_type, "image/pwg-raster") ? CUPS_RASTER_WRITE_PWG : CUPS_RASTER_WRITE_APPLE);
+
+  ppd   = ppdOpenFile(getenv("PPD"));
+  back  = ppdFindAttr(ppd, "cupsBackSide", NULL);
+
+  num_options = cupsParseOptions(argv[5], 0, &options);
+
+  ppdMarkDefaults(ppd);
+  cupsMarkOptions(ppd, num_options, options);
+
+  cache = ppd ? ppd->cache : NULL;
 
   while (cupsRasterReadHeader2(inras, &inheader))
   {
+   /*
+    * Show page device dictionary...
+    */
+
+    fprintf(stderr, "DEBUG: Duplex = %d\n", inheader.Duplex);
+    fprintf(stderr, "DEBUG: HWResolution = [ %d %d ]\n", inheader.HWResolution[0], inheader.HWResolution[1]);
+    fprintf(stderr, "DEBUG: ImagingBoundingBox = [ %d %d %d %d ]\n", inheader.ImagingBoundingBox[0], inheader.ImagingBoundingBox[1], inheader.ImagingBoundingBox[2], inheader.ImagingBoundingBox[3]);
+    fprintf(stderr, "DEBUG: Margins = [ %d %d ]\n", inheader.Margins[0], inheader.Margins[1]);
+    fprintf(stderr, "DEBUG: ManualFeed = %d\n", inheader.ManualFeed);
+    fprintf(stderr, "DEBUG: MediaPosition = %d\n", inheader.MediaPosition);
+    fprintf(stderr, "DEBUG: NumCopies = %d\n", inheader.NumCopies);
+    fprintf(stderr, "DEBUG: Orientation = %d\n", inheader.Orientation);
+    fprintf(stderr, "DEBUG: PageSize = [ %d %d ]\n", inheader.PageSize[0], inheader.PageSize[1]);
+    fprintf(stderr, "DEBUG: cupsWidth = %d\n", inheader.cupsWidth);
+    fprintf(stderr, "DEBUG: cupsHeight = %d\n", inheader.cupsHeight);
+    fprintf(stderr, "DEBUG: cupsMediaType = %d\n", inheader.cupsMediaType);
+    fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", inheader.cupsBitsPerColor);
+    fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", inheader.cupsBitsPerPixel);
+    fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", inheader.cupsBytesPerLine);
+    fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", inheader.cupsColorOrder);
+    fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", inheader.cupsColorSpace);
+    fprintf(stderr, "DEBUG: cupsCompression = %d\n", inheader.cupsCompression);
+
    /*
     * Compute the real raster size...
     */
@@ -85,18 +124,21 @@ main(int  argc,                            /* I - Number of command-line args */
 
     fprintf(stderr, "PAGE: %d %d\n", page, inheader.NumCopies);
 
-    page_width  = (int)(inheader.cupsPageSize[0] * inheader.HWResolution[0] /
-                        72.0);
-    page_height = (int)(inheader.cupsPageSize[1] * inheader.HWResolution[1] /
-                        72.0);
-    page_left   = (int)(inheader.cupsImagingBBox[0] *
-                        inheader.HWResolution[0] / 72.0);
-    page_bottom = (int)(inheader.cupsImagingBBox[1] *
-                        inheader.HWResolution[1] / 72.0);
+    page_width  = (unsigned)(inheader.cupsPageSize[0] * inheader.HWResolution[0] / 72.0);
+    page_height = (unsigned)(inheader.cupsPageSize[1] * inheader.HWResolution[1] / 72.0);
+    page_left   = (unsigned)(inheader.cupsImagingBBox[0] * inheader.HWResolution[0] / 72.0);
+    page_bottom = (unsigned)(inheader.cupsImagingBBox[1] * inheader.HWResolution[1] / 72.0);
     page_top    = page_height - page_bottom - inheader.cupsHeight;
     linesize    = (page_width * inheader.cupsBitsPerPixel + 7) / 8;
     lineoffset  = page_left * inheader.cupsBitsPerPixel / 8; /* Round down */
 
+    if (page_left > page_width || page_top > page_height || page_bottom > page_height)
+    {
+      _cupsLangPrintFilter(stderr, "ERROR", _("Unsupported raster data."));
+      fprintf(stderr, "DEBUG: Bad bottom/left/top margin on page %d.\n", page);
+      return (1);
+    }
+
     switch (inheader.cupsColorSpace)
     {
       case CUPS_CSPACE_W :
@@ -126,6 +168,7 @@ main(int  argc,                             /* I - Number of command-line args */
       case CUPS_CSPACE_DEVICEF :
           white = 0;
          break;
+
       default :
          _cupsLangPrintFilter(stderr, "ERROR", _("Unsupported raster data."));
          fprintf(stderr, "DEBUG: Unsupported cupsColorSpace %d on page %d.\n",
@@ -151,10 +194,233 @@ main(int  argc,                          /* I - Number of command-line args */
     }
 
     memcpy(&outheader, &inheader, sizeof(outheader));
-    outheader.cupsWidth  = page_width;
+    outheader.cupsWidth        = page_width;
     outheader.cupsHeight       = page_height;
     outheader.cupsBytesPerLine = linesize;
 
+    outheader.cupsInteger[14]  = 0;    /* VendorIdentifier */
+    outheader.cupsInteger[15]  = 0;    /* VendorLength */
+
+    if ((val = cupsGetOption("print-content-optimize", num_options,
+                             options)) != NULL)
+    {
+      if (!strcmp(val, "automatic"))
+        strlcpy(outheader.OutputType, "Automatic",
+                sizeof(outheader.OutputType));
+      else if (!strcmp(val, "graphics"))
+        strlcpy(outheader.OutputType, "Graphics", sizeof(outheader.OutputType));
+      else if (!strcmp(val, "photo"))
+        strlcpy(outheader.OutputType, "Photo", sizeof(outheader.OutputType));
+      else if (!strcmp(val, "text"))
+        strlcpy(outheader.OutputType, "Text", sizeof(outheader.OutputType));
+      else if (!strcmp(val, "text-and-graphics"))
+        strlcpy(outheader.OutputType, "TextAndGraphics",
+                sizeof(outheader.OutputType));
+      else
+      {
+        fputs("DEBUG: Unsupported print-content-optimize value.\n", stderr);
+        outheader.OutputType[0] = '\0';
+      }
+    }
+
+    if ((val = cupsGetOption("print-quality", num_options, options)) != NULL)
+    {
+      unsigned quality = (unsigned)atoi(val);          /* print-quality value */
+
+      if (quality >= IPP_QUALITY_DRAFT && quality <= IPP_QUALITY_HIGH)
+       outheader.cupsInteger[8] = quality;
+      else
+      {
+       fprintf(stderr, "DEBUG: Unsupported print-quality %d.\n", quality);
+       outheader.cupsInteger[8] = 0;
+      }
+    }
+
+    if ((val = cupsGetOption("print-rendering-intent", num_options,
+                             options)) != NULL)
+    {
+      if (!strcmp(val, "absolute"))
+        strlcpy(outheader.cupsRenderingIntent, "Absolute",
+                sizeof(outheader.cupsRenderingIntent));
+      else if (!strcmp(val, "automatic"))
+        strlcpy(outheader.cupsRenderingIntent, "Automatic",
+                sizeof(outheader.cupsRenderingIntent));
+      else if (!strcmp(val, "perceptual"))
+        strlcpy(outheader.cupsRenderingIntent, "Perceptual",
+                sizeof(outheader.cupsRenderingIntent));
+      else if (!strcmp(val, "relative"))
+        strlcpy(outheader.cupsRenderingIntent, "Relative",
+                sizeof(outheader.cupsRenderingIntent));
+      else if (!strcmp(val, "relative-bpc"))
+        strlcpy(outheader.cupsRenderingIntent, "RelativeBpc",
+                sizeof(outheader.cupsRenderingIntent));
+      else if (!strcmp(val, "saturation"))
+        strlcpy(outheader.cupsRenderingIntent, "Saturation",
+                sizeof(outheader.cupsRenderingIntent));
+      else
+      {
+        fputs("DEBUG: Unsupported print-rendering-intent value.\n", stderr);
+        outheader.cupsRenderingIntent[0] = '\0';
+      }
+    }
+
+    if (inheader.cupsPageSizeName[0] &&
+        (pwg_size = _ppdCacheGetSize(cache, inheader.cupsPageSizeName)) != NULL)
+    {
+      strlcpy(outheader.cupsPageSizeName, pwg_size->map.pwg,
+             sizeof(outheader.cupsPageSizeName));
+    }
+    else
+    {
+      pwg_media = pwgMediaForSize((int)(2540.0 * inheader.cupsPageSize[0] / 72.0),
+                                 (int)(2540.0 * inheader.cupsPageSize[1] / 72.0));
+
+      if (pwg_media)
+        strlcpy(outheader.cupsPageSizeName, pwg_media->pwg,
+                sizeof(outheader.cupsPageSizeName));
+      else
+      {
+        fprintf(stderr, "DEBUG: Unsupported PageSize %.2fx%.2f.\n",
+                inheader.cupsPageSize[0], inheader.cupsPageSize[1]);
+        outheader.cupsPageSizeName[0] = '\0';
+      }
+    }
+
+    if (inheader.Duplex && !(page & 1) &&
+        back && _cups_strcasecmp(back->value, "Normal"))
+    {
+      if (_cups_strcasecmp(back->value, "Flipped"))
+      {
+        if (inheader.Tumble)
+        {
+         outheader.cupsInteger[1] = ~0U;/* CrossFeedTransform */
+         outheader.cupsInteger[2] = 1; /* FeedTransform */
+
+         outheader.cupsInteger[3] = page_width - page_left -
+                                    inheader.cupsWidth;
+                                       /* ImageBoxLeft */
+         outheader.cupsInteger[4] = page_top;
+                                       /* ImageBoxTop */
+         outheader.cupsInteger[5] = page_width - page_left;
+                                       /* ImageBoxRight */
+         outheader.cupsInteger[6] = page_height - page_bottom;
+                                       /* ImageBoxBottom */
+        }
+        else
+        {
+         outheader.cupsInteger[1] = 1; /* CrossFeedTransform */
+         outheader.cupsInteger[2] = ~0U;/* FeedTransform */
+
+         outheader.cupsInteger[3] = page_left;
+                                       /* ImageBoxLeft */
+         outheader.cupsInteger[4] = page_bottom;
+                                       /* ImageBoxTop */
+         outheader.cupsInteger[5] = page_left + inheader.cupsWidth;
+                                       /* ImageBoxRight */
+         outheader.cupsInteger[6] = page_height - page_top;
+                                       /* ImageBoxBottom */
+        }
+      }
+      else if (_cups_strcasecmp(back->value, "ManualTumble"))
+      {
+        if (inheader.Tumble)
+        {
+         outheader.cupsInteger[1] = ~0U;/* CrossFeedTransform */
+         outheader.cupsInteger[2] = ~0U;/* FeedTransform */
+
+         outheader.cupsInteger[3] = page_width - page_left -
+                                    inheader.cupsWidth;
+                                       /* ImageBoxLeft */
+         outheader.cupsInteger[4] = page_bottom;
+                                       /* ImageBoxTop */
+         outheader.cupsInteger[5] = page_width - page_left;
+                                       /* ImageBoxRight */
+         outheader.cupsInteger[6] = page_height - page_top;
+                                       /* ImageBoxBottom */
+        }
+        else
+        {
+         outheader.cupsInteger[1] = 1; /* CrossFeedTransform */
+         outheader.cupsInteger[2] = 1; /* FeedTransform */
+
+         outheader.cupsInteger[3] = page_left;
+                                       /* ImageBoxLeft */
+         outheader.cupsInteger[4] = page_top;
+                                       /* ImageBoxTop */
+         outheader.cupsInteger[5] = page_left + inheader.cupsWidth;
+                                       /* ImageBoxRight */
+         outheader.cupsInteger[6] = page_height - page_bottom;
+                                       /* ImageBoxBottom */
+        }
+      }
+      else if (_cups_strcasecmp(back->value, "Rotated"))
+      {
+        if (inheader.Tumble)
+        {
+         outheader.cupsInteger[1] = ~0U;/* CrossFeedTransform */
+         outheader.cupsInteger[2] = ~0U;/* FeedTransform */
+
+         outheader.cupsInteger[3] = page_width - page_left -
+                                    inheader.cupsWidth;
+                                       /* ImageBoxLeft */
+         outheader.cupsInteger[4] = page_bottom;
+                                       /* ImageBoxTop */
+         outheader.cupsInteger[5] = page_width - page_left;
+                                       /* ImageBoxRight */
+         outheader.cupsInteger[6] = page_height - page_top;
+                                       /* ImageBoxBottom */
+        }
+        else
+        {
+         outheader.cupsInteger[1] = 1; /* CrossFeedTransform */
+         outheader.cupsInteger[2] = 1; /* FeedTransform */
+
+         outheader.cupsInteger[3] = page_left;
+                                       /* ImageBoxLeft */
+         outheader.cupsInteger[4] = page_top;
+                                       /* ImageBoxTop */
+         outheader.cupsInteger[5] = page_left + inheader.cupsWidth;
+                                       /* ImageBoxRight */
+         outheader.cupsInteger[6] = page_height - page_bottom;
+                                       /* ImageBoxBottom */
+        }
+      }
+      else
+      {
+       /*
+        * Unsupported value...
+        */
+
+        fputs("DEBUG: Unsupported cupsBackSide value.\n", stderr);
+
+       outheader.cupsInteger[1] = 1;   /* CrossFeedTransform */
+       outheader.cupsInteger[2] = 1;   /* FeedTransform */
+
+       outheader.cupsInteger[3] = page_left;
+                                       /* ImageBoxLeft */
+       outheader.cupsInteger[4] = page_top;
+                                       /* ImageBoxTop */
+       outheader.cupsInteger[5] = page_left + inheader.cupsWidth;
+                                       /* ImageBoxRight */
+       outheader.cupsInteger[6] = page_height - page_bottom;
+                                       /* ImageBoxBottom */
+      }
+    }
+    else
+    {
+      outheader.cupsInteger[1] = 1;    /* CrossFeedTransform */
+      outheader.cupsInteger[2] = 1;    /* FeedTransform */
+
+      outheader.cupsInteger[3] = page_left;
+                                       /* ImageBoxLeft */
+      outheader.cupsInteger[4] = page_top;
+                                       /* ImageBoxTop */
+      outheader.cupsInteger[5] = page_left + inheader.cupsWidth;
+                                       /* ImageBoxRight */
+      outheader.cupsInteger[6] = page_height - page_bottom;
+                                       /* ImageBoxBottom */
+    }
+
     if (!cupsRasterWriteHeader2(outras, &outheader))
     {
       _cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data."));
@@ -166,6 +432,9 @@ main(int  argc,                             /* I - Number of command-line args */
     * Copy raster data...
     */
 
+    if (linesize < inheader.cupsBytesPerLine)
+      linesize = inheader.cupsBytesPerLine;
+
     line = malloc(linesize);
 
     memset(line, white, linesize);
@@ -180,7 +449,14 @@ main(int  argc,                            /* I - Number of command-line args */
 
     for (y = inheader.cupsHeight; y > 0; y --)
     {
-      cupsRasterReadPixels(inras, line + lineoffset, inheader.cupsBytesPerLine);
+      if (cupsRasterReadPixels(inras, line + lineoffset, inheader.cupsBytesPerLine) != inheader.cupsBytesPerLine)
+      {
+       _cupsLangPrintFilter(stderr, "ERROR", _("Error reading raster data."));
+       fprintf(stderr, "DEBUG: Unable to read line %d for page %d.\n",
+               inheader.cupsHeight - y + page_top + 1, page);
+       return (1);
+      }
+
       if (!cupsRasterWritePixels(outras, line, outheader.cupsBytesPerLine))
       {
        _cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data."));
@@ -191,7 +467,7 @@ main(int  argc,                             /* I - Number of command-line args */
     }
 
     memset(line, white, linesize);
-    for (y = page_top; y > 0; y --)
+    for (y = page_bottom; y > 0; y --)
       if (!cupsRasterWritePixels(outras, line, outheader.cupsBytesPerLine))
       {
        _cupsLangPrintFilter(stderr, "ERROR", _("Error sending raster data."));
@@ -211,8 +487,3 @@ main(int  argc,                             /* I - Number of command-line args */
 
   return (0);
 }
-
-
-/*
- * End of "$Id$".
- */