]> git.ipfire.org Git - thirdparty/cups.git/blame - scheduler/filter.c
Load cups into easysw/current.
[thirdparty/cups.git] / scheduler / filter.c
CommitLineData
ef416fc2 1/*
fa73b229 2 * "$Id: filter.c 4970 2006-01-24 14:05:45Z mike $"
ef416fc2 3 *
4 * File type conversion routines for the Common UNIX Printing System (CUPS).
5 *
fa73b229 6 * Copyright 1997-2006 by Easy Software Products, all rights reserved.
ef416fc2 7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
19 *
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * Contents:
25 *
fa73b229 26 * mimeAddFilter() - Add a filter to the current MIME database.
27 * mimeFilter() - Find the fastest way to convert from one type to another.
28 * compare_filters() - Compare two filters...
29 * lookup() - Lookup a filter...
ef416fc2 30 */
31
32/*
33 * Include necessary headers...
34 */
35
36#include <stdio.h>
37#include <stdlib.h>
38#include <ctype.h>
39
40#include <cups/debug.h>
41#include <cups/string.h>
42#include "mime.h"
43
44
45/*
46 * Local functions...
47 */
48
fa73b229 49static int compare_filters(mime_filter_t *, mime_filter_t *);
ef416fc2 50static mime_filter_t *lookup(mime_t *, mime_type_t *, mime_type_t *);
51
52
53/*
54 * 'mimeAddFilter()' - Add a filter to the current MIME database.
55 */
56
57mime_filter_t * /* O - New filter */
58mimeAddFilter(mime_t *mime, /* I - MIME database */
59 mime_type_t *src, /* I - Source type */
60 mime_type_t *dst, /* I - Destination type */
61 int cost, /* I - Relative time/resource cost */
62 const char *filter) /* I - Filter program to run */
63{
64 mime_filter_t *temp; /* New filter */
65
66
67 /*
68 * Range-check the input...
69 */
70
fa73b229 71 if (!mime || !src || !dst || !filter)
ef416fc2 72 return (NULL);
73
74 /*
75 * See if we already have an existing filter for the given source and
76 * destination...
77 */
78
79 if ((temp = lookup(mime, src, dst)) != NULL)
80 {
81 /*
82 * Yup, does the existing filter have a higher cost? If so, copy the
83 * filter and cost to the existing filter entry and return it...
84 */
85
86 if (temp->cost > cost)
87 {
88 temp->cost = cost;
89 strlcpy(temp->filter, filter, sizeof(temp->filter));
90 }
91 }
92 else
93 {
94 /*
95 * Nope, add a new one...
96 */
97
fa73b229 98 if (!mime->filters)
99 mime->filters = cupsArrayNew((cups_array_func_t)compare_filters, NULL);
ef416fc2 100
fa73b229 101 if (!mime->filters)
ef416fc2 102 return (NULL);
103
fa73b229 104 if ((temp = calloc(1, sizeof(mime_filter_t))) == NULL)
105 return (NULL);
ef416fc2 106
107 /*
108 * Copy the information over and sort if necessary...
109 */
110
111 temp->src = src;
112 temp->dst = dst;
113 temp->cost = cost;
114 strlcpy(temp->filter, filter, sizeof(temp->filter));
115
fa73b229 116 cupsArrayAdd(mime->filters, temp);
ef416fc2 117 }
118
119 /*
120 * Return the new/updated filter...
121 */
122
123 return (temp);
124}
125
126
127/*
128 * 'mimeFilter()' - Find the fastest way to convert from one type to another.
129 */
130
fa73b229 131cups_array_t * /* O - Array of filters to run */
ef416fc2 132mimeFilter(mime_t *mime, /* I - MIME database */
133 mime_type_t *src, /* I - Source file type */
134 mime_type_t *dst, /* I - Destination file type */
fa73b229 135 int *cost, /* O - Cost of filters */
ef416fc2 136 int max_depth) /* I - Maximum depth of search */
137{
fa73b229 138 int tempcost, /* Temporary cost */
ef416fc2 139 mincost; /* Current minimum */
fa73b229 140 cups_array_t *temp, /* Temporary filter */
141 *mintemp; /* Current minimum */
142 mime_filter_t *current; /* Current filter */
ef416fc2 143
144
145 /*
146 * Range-check the input...
147 */
148
fa73b229 149 DEBUG_printf(("mimeFilter(mime=%p, src=%p(%s/%s), dst=%p(%s/%s), "
150 "cost=%p(%d), max_depth=%d)\n",
ef416fc2 151 mime, src, src ? src->super : "?", src ? src->type : "?",
152 dst, dst ? dst->super : "?", dst ? dst->type : "?",
fa73b229 153 cost, cost ? *cost : 0, max_depth));
ef416fc2 154
fa73b229 155 if (cost)
156 *cost = 0;
ef416fc2 157
fa73b229 158 if (!mime || !src || !dst || !cost || max_depth <= 0)
159 return (NULL);
ef416fc2 160
161 /*
162 * See if there is a filter that can convert the files directly...
163 */
164
fa73b229 165 if ((current = lookup(mime, src, dst)) != NULL)
ef416fc2 166 {
167 /*
168 * Got a direct filter!
169 */
170
fa73b229 171 if ((mintemp = cupsArrayNew(NULL, NULL)) == NULL)
ef416fc2 172 return (NULL);
173
fa73b229 174 cupsArrayAdd(mintemp, current);
175
176 mincost = current->cost;
ef416fc2 177
178 DEBUG_puts(" Found direct filter:");
179 DEBUG_printf((" %s (cost=%d)\n", mintemp->filter, mincost));
180 }
181 else
182 {
183 /*
184 * No direct filter...
185 */
186
fa73b229 187 mintemp = NULL;
188 mincost = 9999999;
ef416fc2 189 }
190
191 /*
192 * OK, now look for filters from the source type to any other type...
193 */
194
fa73b229 195 for (current = (mime_filter_t *)cupsArrayFirst(mime->filters);
196 current;
197 current = (mime_filter_t *)cupsArrayNext(mime->filters))
ef416fc2 198 if (current->src == src)
199 {
200 /*
201 * See if we have any filters that can convert from the destination type
202 * of this filter to the final type...
203 */
204
fa73b229 205 cupsArraySave(mime->filters);
206 temp = mimeFilter(mime, current->dst, dst, &tempcost, max_depth - 1);
207 cupsArrayRestore(mime->filters);
208
209 if (!temp)
ef416fc2 210 continue;
211
212 /*
213 * Found a match; see if this one is less costly than the last (if
214 * any...)
215 */
216
fa73b229 217 if (tempcost < mincost)
ef416fc2 218 {
fa73b229 219 cupsArrayDelete(mintemp);
ef416fc2 220
221 /*
222 * Hey, we got a match! Add the current filter to the beginning of the
223 * filter list...
224 */
225
fa73b229 226 mintemp = temp;
227 mincost = tempcost + current->cost;
228 cupsArrayInsert(mintemp, current);
ef416fc2 229 }
230 else
fa73b229 231 cupsArrayDelete(temp);
ef416fc2 232 }
233
fa73b229 234 if (mintemp)
ef416fc2 235 {
236 /*
237 * Hey, we got a match!
238 */
239
ef416fc2 240#ifdef DEBUG
fa73b229 241 printf(" Returning %d filters:\n", cupsArrayCount(mintemp));
242 for (current = (mime_filter_t *)cupsArrayFirst(mintemp);
243 current;
244 current = (mime_filter_t *)cupsArrayNext(mintemp))
245 printf(" %s\n", current->filter);
ef416fc2 246#endif /* DEBUG */
247
fa73b229 248 *cost = mincost;
249
ef416fc2 250 return (mintemp);
251 }
252
253 DEBUG_puts(" Returning zippo...");
254
255 return (NULL);
256}
257
258
259/*
fa73b229 260 * 'compare_filters()' - Compare two filters...
ef416fc2 261 */
262
fa73b229 263static int /* O - Comparison result */
264compare_filters(mime_filter_t *f0, /* I - First filter */
265 mime_filter_t *f1) /* I - Second filter */
ef416fc2 266{
fa73b229 267 int i; /* Result of comparison */
ef416fc2 268
269
270 if ((i = strcmp(f0->src->super, f1->src->super)) == 0)
271 if ((i = strcmp(f0->src->type, f1->src->type)) == 0)
272 if ((i = strcmp(f0->dst->super, f1->dst->super)) == 0)
273 i = strcmp(f0->dst->type, f1->dst->type);
274
275 return (i);
276}
277
278
279/*
280 * 'lookup()' - Lookup a filter...
281 */
282
fa73b229 283static mime_filter_t * /* O - Filter for src->dst */
284lookup(mime_t *mime, /* I - MIME database */
285 mime_type_t *src, /* I - Source type */
286 mime_type_t *dst) /* I - Destination type */
ef416fc2 287{
fa73b229 288 mime_filter_t key; /* Key record for filter search */
ef416fc2 289
290
ef416fc2 291 key.src = src;
292 key.dst = dst;
293
fa73b229 294 return ((mime_filter_t *)cupsArrayFind(mime->filters, &key));
ef416fc2 295}
296
297
298/*
fa73b229 299 * End of "$Id: filter.c 4970 2006-01-24 14:05:45Z mike $".
ef416fc2 300 */