]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/filter.c
Merge changes from CUPS 1.4svn-r7696.
[thirdparty/cups.git] / scheduler / filter.c
index f315910af1872cf1435d8cd9c042b27b26c50f2b..6df0483f9866afa161f127e42e020e86e35e90cd 100644 (file)
@@ -1,34 +1,25 @@
 /*
- * "$Id: filter.c 5083 2006-02-06 02:57:43Z mike $"
+ * "$Id: filter.c 7694 2008-06-26 00:23:20Z mike $"
  *
  *   File type conversion routines for the Common UNIX Printing System (CUPS).
  *
- *   Copyright 1997-2006 by Easy Software Products, all rights reserved.
+ *   Copyright 2007-2008 by Apple Inc.
+ *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   These coded instructions, statements, and computer programs are the
- *   property of Easy Software Products 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 please contact Easy Software Products
- *   at:
- *
- *       Attn: CUPS Licensing Information
- *       Easy Software Products
- *       44141 Airport View Drive, Suite 204
- *       Hollywood, Maryland 20636 USA
- *
- *       Voice: (301) 373-9600
- *       EMail: cups-info@cups.org
- *         WWW: http://www.cups.org
+ *   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/".
  *
  * Contents:
  *
- *   mimeAddFilter()   - Add a filter to the current MIME database.
- *   mimeFilter()      - Find the fastest way to convert from one type to
- *                       another.
- *   compare_filters() - Compare two filters...
- *   find_filters()    - Find the filters to convert from one type to another.
- *   lookup()          - Lookup a filter...
+ *   mimeAddFilter()    - Add a filter to the current MIME database.
+ *   mimeFilter()       - Find the fastest way to convert from one type to
+ *                        another.
+ *   mimeFilterLookup() - Lookup a filter...
+ *   compare_filters()  - Compare two filters...
+ *   find_filters()     - Find the filters to convert from one type to another.
  */
 
 /*
@@ -60,10 +51,10 @@ typedef struct _mime_typelist_s             /**** List of source types ****/
  */
 
 static int             compare_filters(mime_filter_t *, mime_filter_t *);
+static int             compare_srcs(mime_filter_t *, mime_filter_t *);
 static cups_array_t    *find_filters(mime_t *mime, mime_type_t *src,
                                      mime_type_t *dst, int *cost,
                                      _mime_typelist_t *visited);
-static mime_filter_t   *lookup(mime_t *, mime_type_t *, mime_type_t *);
 
 
 /*
@@ -92,7 +83,7 @@ mimeAddFilter(mime_t      *mime,      /* I - MIME database */
   * destination...
   */
 
-  if ((temp = lookup(mime, src, dst)) != NULL)
+  if ((temp = mimeFilterLookup(mime, src, dst)) != NULL)
   {
    /*
     * Yup, does the existing filter have a higher cost?  If so, copy the
@@ -167,6 +158,23 @@ mimeFilter(mime_t      *mime,              /* I - MIME database */
   if (!mime || !src || !dst)
     return (NULL);
 
+ /*
+  * (Re)build the source lookup array as needed...
+  */
+
+  if (!mime->srcs)
+  {
+    mime_filter_t      *current;       /* Current filter */
+
+
+    mime->srcs = cupsArrayNew((cups_array_func_t)compare_srcs, NULL);
+
+    for (current = mimeFirstFilter(mime);
+         current;
+        current = mimeNextFilter(mime))
+      cupsArrayAdd(mime->srcs, current);
+  }
+
  /*
   * Find the filters...
   */
@@ -175,6 +183,25 @@ mimeFilter(mime_t      *mime,              /* I - MIME database */
 }
 
 
+/*
+ * 'mimeFilterLookup()' - Lookup a filter...
+ */
+
+mime_filter_t *                                /* O - Filter for src->dst */
+mimeFilterLookup(mime_t      *mime,    /* I - MIME database */
+                 mime_type_t *src,     /* I - Source type */
+                 mime_type_t *dst)     /* I - Destination type */
+{
+  mime_filter_t        key;                    /* Key record for filter search */
+
+
+  key.src = src;
+  key.dst = dst;
+
+  return ((mime_filter_t *)cupsArrayFind(mime->filters, &key));
+}
+
+
 /*
  * 'compare_filters()' - Compare two filters...
  */
@@ -195,11 +222,29 @@ compare_filters(mime_filter_t *f0,        /* I - First filter */
 }
 
 
+/*
+ * 'compare_srcs()' - Compare two srcs...
+ */
+
+static int                             /* O - Comparison result */
+compare_srcs(mime_filter_t *f0,                /* I - First filter */
+             mime_filter_t *f1)                /* I - Second filter */
+{
+  int  i;                              /* Result of comparison */
+
+
+  if ((i = strcmp(f0->src->super, f1->src->super)) == 0)
+    i = strcmp(f0->src->type, f1->src->type);
+
+  return (i);
+}
+
+
 /*
  * 'find_filters()' - Find the filters to convert from one type to another.
  */
 
-cups_array_t *                         /* O - Array of filters to run */
+static cups_array_t *                  /* O - Array of filters to run */
 find_filters(mime_t           *mime,   /* I - MIME database */
              mime_type_t      *src,    /* I - Source file type */
             mime_type_t      *dst,     /* I - Destination file type */
@@ -210,7 +255,8 @@ find_filters(mime_t           *mime,        /* I - MIME database */
                        mincost;        /* Current minimum */
   cups_array_t         *temp,          /* Temporary filter */
                        *mintemp;       /* Current minimum */
-  mime_filter_t                *current;       /* Current filter */
+  mime_filter_t                *current,       /* Current filter */
+                       srckey;         /* Source type key */
   _mime_typelist_t     listnode,       /* New list node */
                        *listptr;       /* Pointer in list */
 
@@ -223,13 +269,13 @@ find_filters(mime_t           *mime,      /* I - MIME database */
   * See if there is a filter that can convert the files directly...
   */
 
-  if ((current = lookup(mime, src, dst)) != NULL)
+  if ((current = mimeFilterLookup(mime, src, dst)) != NULL)
   {
    /*
     * Got a direct filter!
     */
 
-    DEBUG_puts("Direct filter found!");
+    DEBUG_puts("find_filters: Direct filter found!");
 
     if ((mintemp = cupsArrayNew(NULL, NULL)) == NULL)
       return (NULL);
@@ -238,8 +284,11 @@ find_filters(mime_t           *mime,       /* I - MIME database */
 
     mincost = current->cost;
 
-    DEBUG_puts("    Found direct filter:");
-    DEBUG_printf(("    %s (cost=%d)\n", current->filter, mincost));
+    if (!cost)
+      return (mintemp);
+
+    DEBUG_puts("find_filters: Found direct filter:");
+    DEBUG_printf(("find_filters: %s (cost=%d)\n", current->filter, mincost));
   }
   else
   {
@@ -261,58 +310,69 @@ find_filters(mime_t           *mime,      /* I - MIME database */
   * OK, now look for filters from the source type to any other type...
   */
 
-  for (current = (mime_filter_t *)cupsArrayFirst(mime->filters);
-       current;
-       current = (mime_filter_t *)cupsArrayNext(mime->filters))
-    if (current->src == src)
-    {
-     /*
-      * See if we have already tried the destination type as a source
-      * type (this avoids extra filter looping...)
-      */
+  srckey.src = src;
 
-      for (listptr = list; listptr; listptr = listptr->next)
-        if (current->dst == listptr->src)
-         break;
+  for (current = (mime_filter_t *)cupsArrayFind(mime->srcs, &srckey);
+       current && current->src == src;
+       current = (mime_filter_t *)cupsArrayNext(mime->srcs))
+  {
+   /*
+    * See if we have already tried the destination type as a source
+    * type (this avoids extra filter looping...)
+    */
 
-      if (listptr)
-        continue;
+    mime_type_t *current_dst;          /* Current destination type */
 
-     /*
-      * See if we have any filters that can convert from the destination type
-      * of this filter to the final type...
-      */
 
-      listnode.src = current->src;
+    for (listptr = list, current_dst = current->dst;
+        listptr;
+        listptr = listptr->next)
+      if (current_dst == listptr->src)
+       break;
+
+    if (listptr)
+      continue;
+
+   /*
+    * See if we have any filters that can convert from the destination type
+    * of this filter to the final type...
+    */
+
+    listnode.src = current->src;
+
+    cupsArraySave(mime->srcs);
+    temp = find_filters(mime, current->dst, dst, &tempcost, &listnode);
+    cupsArrayRestore(mime->srcs);
+
+    if (!temp)
+      continue;
 
-      cupsArraySave(mime->filters);
-      temp = find_filters(mime, current->dst, dst, &tempcost, &listnode);
-      cupsArrayRestore(mime->filters);
+    if (!cost)
+      return (temp);
 
-      if (!temp)
-        continue;
+   /*
+    * Found a match; see if this one is less costly than the last (if
+    * any...)
+    */
+
+    tempcost += current->cost;
+
+    if (tempcost < mincost)
+    {
+      cupsArrayDelete(mintemp);
 
      /*
-      * Found a match; see if this one is less costly than the last (if
-      * any...)
+      * Hey, we got a match!  Add the current filter to the beginning of the
+      * filter list...
       */
 
-      if (tempcost < mincost)
-      {
-        cupsArrayDelete(mintemp);
-
-       /*
-       * Hey, we got a match!  Add the current filter to the beginning of the
-       * filter list...
-       */
-
-        mintemp = temp;
-       mincost = tempcost + current->cost;
-       cupsArrayInsert(mintemp, current);
-      }
-      else
-        cupsArrayDelete(temp);
+      mintemp = temp;
+      mincost = tempcost;
+      cupsArrayInsert(mintemp, current);
     }
+    else
+      cupsArrayDelete(temp);
+  }
 
   if (mintemp)
   {
@@ -321,11 +381,13 @@ find_filters(mime_t           *mime,      /* I - MIME database */
     */
 
 #ifdef DEBUG
-    printf("    Returning %d filters:\n", cupsArrayCount(mintemp));
+    DEBUG_printf(("find_filters: Returning %d filters:\n",
+                  cupsArrayCount(mintemp)));
+
     for (current = (mime_filter_t *)cupsArrayFirst(mintemp);
          current;
         current = (mime_filter_t *)cupsArrayNext(mintemp))
-      printf("    %s\n", current->filter);
+      DEBUG_printf(("find_filters: %s\n", current->filter));
 #endif /* DEBUG */
 
     if (cost)
@@ -334,31 +396,12 @@ find_filters(mime_t           *mime,      /* I - MIME database */
     return (mintemp);
   }
 
-  DEBUG_puts("    Returning zippo...");
+  DEBUG_puts("find_filters: Returning zippo...");
 
   return (NULL);
 }
 
 
 /*
- * 'lookup()' - Lookup a filter...
- */
-
-static mime_filter_t *                 /* O - Filter for src->dst */
-lookup(mime_t      *mime,              /* I - MIME database */
-       mime_type_t *src,               /* I - Source type */
-       mime_type_t *dst)               /* I - Destination type */
-{
-  mime_filter_t        key;                    /* Key record for filter search */
-
-
-  key.src = src;
-  key.dst = dst;
-
-  return ((mime_filter_t *)cupsArrayFind(mime->filters, &key));
-}
-
-
-/*
- * End of "$Id: filter.c 5083 2006-02-06 02:57:43Z mike $".
+ * End of "$Id: filter.c 7694 2008-06-26 00:23:20Z mike $".
  */