]> git.ipfire.org Git - thirdparty/cups-filters.git/commitdiff
libppd: In ppdFilterUniversal() set output data type also if no PPD supplied
authorTill Kamppeter <till.kamppeter@gmail.com>
Tue, 30 Aug 2022 18:02:49 +0000 (20:02 +0200)
committerTill Kamppeter <till.kamppeter@gmail.com>
Tue, 30 Aug 2022 18:02:49 +0000 (20:02 +0200)
Now both cfFilterUniversal() and its PPD file support wrapper
ppdFilterUniversal() are absolutely compatible if no PPD file got
supplied via named extension to the filter data.

Before, if no PPD was supplied and no actual_output_type in the
parameters, the output data type stayed undetermined and the function
errored out not being able to find a filter combination for the
requested conversion.

Now always final_content_type of thef ilter data is used if there is
no actual_output_type specified in the parameters, regardless of
whether we have a PPD file or not.

ppd/ppd-filter.c

index 98cb5d84131d07a85643e41643c50f4ce1caf219..370e4f720a699ac150da333a7a7e187dce355352 100644 (file)
@@ -2002,130 +2002,132 @@ ppdFilterUniversal(int inputfd,         /* I - File descriptor input stream */
   if (universal_parameters.actual_output_type)
     strncpy(output, universal_parameters.actual_output_type,
            sizeof(output) - 1);
-  else if (ppd)
+  else
   {
     strncpy(output, data->final_content_type, sizeof(output) - 1);
 
-    cache = ppd ? ppd->cache : NULL;
-
-    /* Check whether our output format (under CUPS it is taken from
-       the FINAL_CONTENT_TYPE env variable) is the destination format
-       (2nd word) of a "*cupsFilter2: ..." line (string has 4 words),
-       in this case the specified filter (4th word) does the last
-       step, converting from the input format (1st word) of the line
-       to the destination format and so we only need to convert to the
-       input format. In this case we need to correct our output
-       format.
-
-       If there is more than one line with the given output format and
-       an inpout format we can produce, we select the one with the
-       lowest cost value (3rd word) as this is the one which CUPS
-       should have chosen for this job.
-
-       If we have "*cupsFilter: ..." lines (without "2", string with 3
-       words) we do not need to do anything special, as the input
-       format specified is the FIMAL_CONTENT_TYPE which CUPS supplies
-       to us and into which we have to convert. So we quit parsing if
-       the first line has only 3 words, as if CUPS uses the
-       "*cupsFilter: ..."  lines only if there is no "*cupsFilter2:
-       ..." line min the PPD, so if we encounter a line with only 3
-       words the other lines will have only 3 words, too and nothing
-       has to be done. */
-
-    if (ppd && ppd->num_filters && cache)
+    if (ppd)
     {
-      int lowest_cost = INT_MAX;
-      char *filter;
-
-      if (log) log(ld, CF_LOGLEVEL_DEBUG,
-                  "ppdFilterUniversal: \"*cupsFilter(2): ...\" lines in the PPD file:");
-
-      for (filter = (char *)cupsArrayFirst(cache->filters);
-          filter;
-          filter = (char *)cupsArrayNext(cache->filters))
+      cache = ppd ? ppd->cache : NULL;
+
+      /* Check whether our output format (under CUPS it is taken from
+        the FINAL_CONTENT_TYPE env variable) is the destination format
+        (2nd word) of a "*cupsFilter2: ..." line (string has 4 words),
+        in this case the specified filter (4th word) does the last
+        step, converting from the input format (1st word) of the line
+        to the destination format and so we only need to convert to the
+        input format. In this case we need to correct our output
+        format.
+
+        If there is more than one line with the given output format and
+        an inpout format we can produce, we select the one with the
+        lowest cost value (3rd word) as this is the one which CUPS
+        should have chosen for this job.
+
+        If we have "*cupsFilter: ..." lines (without "2", string with 3
+        words) we do not need to do anything special, as the input
+        format specified is the FIMAL_CONTENT_TYPE which CUPS supplies
+        to us and into which we have to convert. So we quit parsing if
+        the first line has only 3 words, as if CUPS uses the
+        "*cupsFilter: ..."  lines only if there is no "*cupsFilter2:
+        ..." line min the PPD, so if we encounter a line with only 3
+        words the other lines will have only 3 words, too and nothing
+        has to be done. */
+
+      if (ppd && ppd->num_filters && cache)
       {
-       char buf[256];
-       char *ptr,
-         *in = NULL,
-          *out = NULL,
-         *coststr = NULL;
-       int cost;
+       int lowest_cost = INT_MAX;
+       char *filter;
 
        if (log) log(ld, CF_LOGLEVEL_DEBUG,
-                    "ppdFilterUniversal:    %s", filter);
-
-       /* String of the "*cupsfilter:" or "*cupsfilter2:" line */
-       strncpy(buf, filter, sizeof(buf) - 1);
-
-       /* Separate the words */
-       in = ptr = buf;
-       while (*ptr && !isspace(*ptr)) ptr ++;
-       if (!*ptr) goto error;
-       *ptr = '\0';
-       ptr ++;
-       while (*ptr && isspace(*ptr)) ptr ++;
-       if (!*ptr) goto error;
-       out = ptr;
-       while (*ptr && !isspace(*ptr)) ptr ++;
-       if (!*ptr) goto error;
-       *ptr = '\0';
-       ptr ++;
-       while (*ptr && isspace(*ptr)) ptr ++;
-       if (!*ptr) goto error;
-       coststr = ptr;
-       if (!isdigit(*ptr)) goto error;
-       while (*ptr && !isspace(*ptr)) ptr ++;
-       if (!*ptr) goto error;
-       *ptr = '\0';
-       ptr ++;
-       while (*ptr && isspace(*ptr)) ptr ++;
-       if (!*ptr) goto error;
-       cost = atoi(coststr);
-
-       /* Valid "*cupsFilter2: ..." line ... */
-       if (/* Must be of lower cost than what we selected before */
-           cost < lowest_cost &&
-           /* Must have our FINAL_CONTENT_TYPE as output */
-           strcasecmp(out, final_output) == 0 &&
-           /* Must have as input a format we are able to produce */
-           (strcasecmp(in, "application/vnd.cups-raster") == 0 ||
-            strcasecmp(in, "application/vnd.cups-pdf") == 0 ||
-            strcasecmp(in, "application/vnd.cups-postscript") == 0 ||
-            strcasecmp(in, "application/pdf") == 0 ||
-            strcasecmp(in, "image/pwg-raster") == 0 ||
-            strcasecmp(in, "image/urf") == 0 ||
-            strcasecmp(in, "application/PCLm") == 0 ||
-            strcasecmp(in, "application/postscript") == 0))
+                    "ppdFilterUniversal: \"*cupsFilter(2): ...\" lines in the PPD file:");
+
+       for (filter = (char *)cupsArrayFirst(cache->filters);
+            filter;
+            filter = (char *)cupsArrayNext(cache->filters))
        {
+         char buf[256];
+         char *ptr,
+           *in = NULL,
+           *out = NULL,
+           *coststr = NULL;
+         int cost;
+
          if (log) log(ld, CF_LOGLEVEL_DEBUG,
-                      "ppdFilterUniversal:       --> Selecting this line");
-         /* Take the input format of the line as output format for us */
-         strncpy(output, in, sizeof(output));
-         /* Update the minimum cost found */
-         lowest_cost = cost;
-         /* We cannot find a "better" solution ... */
-         if (lowest_cost == 0)
+                      "ppdFilterUniversal:    %s", filter);
+
+         /* String of the "*cupsfilter:" or "*cupsfilter2:" line */
+         strncpy(buf, filter, sizeof(buf) - 1);
+
+         /* Separate the words */
+         in = ptr = buf;
+         while (*ptr && !isspace(*ptr)) ptr ++;
+         if (!*ptr) goto error;
+         *ptr = '\0';
+         ptr ++;
+         while (*ptr && isspace(*ptr)) ptr ++;
+         if (!*ptr) goto error;
+         out = ptr;
+         while (*ptr && !isspace(*ptr)) ptr ++;
+         if (!*ptr) goto error;
+         *ptr = '\0';
+         ptr ++;
+         while (*ptr && isspace(*ptr)) ptr ++;
+         if (!*ptr) goto error;
+         coststr = ptr;
+         if (!isdigit(*ptr)) goto error;
+         while (*ptr && !isspace(*ptr)) ptr ++;
+         if (!*ptr) goto error;
+         *ptr = '\0';
+         ptr ++;
+         while (*ptr && isspace(*ptr)) ptr ++;
+         if (!*ptr) goto error;
+         cost = atoi(coststr);
+
+         /* Valid "*cupsFilter2: ..." line ... */
+         if (/* Must be of lower cost than what we selected before */
+             cost < lowest_cost &&
+             /* Must have our FINAL_CONTENT_TYPE as output */
+             strcasecmp(out, final_output) == 0 &&
+             /* Must have as input a format we are able to produce */
+             (strcasecmp(in, "application/vnd.cups-raster") == 0 ||
+              strcasecmp(in, "application/vnd.cups-pdf") == 0 ||
+              strcasecmp(in, "application/vnd.cups-postscript") == 0 ||
+              strcasecmp(in, "application/pdf") == 0 ||
+              strcasecmp(in, "image/pwg-raster") == 0 ||
+              strcasecmp(in, "image/urf") == 0 ||
+              strcasecmp(in, "application/PCLm") == 0 ||
+              strcasecmp(in, "application/postscript") == 0))
          {
            if (log) log(ld, CF_LOGLEVEL_DEBUG,
-                        "ppdFilterUniversal:    Cost value is down to zero, stopping reading further lines");
-           break;
+                        "ppdFilterUniversal:       --> Selecting this line");
+           /* Take the input format of the line as output format for us */
+           strncpy(output, in, sizeof(output));
+           /* Update the minimum cost found */
+           lowest_cost = cost;
+           /* We cannot find a "better" solution ... */
+           if (lowest_cost == 0)
+           {
+             if (log) log(ld, CF_LOGLEVEL_DEBUG,
+                          "ppdFilterUniversal:    Cost value is down to zero, stopping reading further lines");
+             break;
+           }
          }
-       }
 
-       continue;
+         continue;
 
-      error:
-       if (lowest_cost == INT_MAX && coststr)
-       {
-         if (log) log(ld, CF_LOGLEVEL_DEBUG,
-                      "ppdFilterUniversal: PPD uses \"*cupsFilter: ...\" lines, so we always convert to format given by FINAL_CONTENT_TYPE");
-         break;
+       error:
+         if (lowest_cost == INT_MAX && coststr)
+         {
+           if (log) log(ld, CF_LOGLEVEL_DEBUG,
+                        "ppdFilterUniversal: PPD uses \"*cupsFilter: ...\" lines, so we always convert to format given by FINAL_CONTENT_TYPE");
+           break;
+         }
+         if (log) log(ld, CF_LOGLEVEL_ERROR,
+                      "ppdFilterUniversal: Invalid \"*cupsFilter2: ...\" line in PPD: %s",
+                      filter);
        }
-       if (log) log(ld, CF_LOGLEVEL_ERROR,
-                    "ppdFilterUniversal: Invalid \"*cupsFilter2: ...\" line in PPD: %s",
-                    filter);
       }
-
     }
   }