]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/filter.c
ppdPageSize() incorrectly assumed that the custom page size entry would be
[thirdparty/cups.git] / cups / filter.c
CommitLineData
79df52e3 1/*
8784b6a6 2 * "$Id: filter.c,v 1.8 1999/06/18 18:36:08 mike Exp $"
79df52e3 3 *
0b74af7d 4 * File type conversion routines for the Common UNIX Printing System (CUPS).
79df52e3 5 *
3a193f5e 6 * Copyright 1997-1999 by Easy Software Products, all rights reserved.
79df52e3 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
8784b6a6 17 * 44141 Airport View Drive, Suite 204
79df52e3 18 * Hollywood, Maryland 20636-3111 USA
19 *
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * Contents:
25 *
0b74af7d 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() - Compare two filter types...
29 * lookup() - Lookup a filter...
79df52e3 30 */
31
32/*
33 * Include necessary headers...
34 */
35
3b960317 36#include <stdio.h>
37#include <stdlib.h>
38#include <ctype.h>
39
40#include "string.h"
0b74af7d 41#include "mime.h"
42
43
44/*
45 * Local functions...
46 */
47
48static int compare(mime_filter_t *, mime_filter_t *);
49static mime_filter_t *lookup(mime_t *, mime_type_t *, mime_type_t *);
50
51
52/*
53 * 'mimeAddFilter()' - Add a filter to the current MIME database.
54 */
55
56mime_filter_t * /* O - New filter */
57mimeAddFilter(mime_t *mime, /* I - MIME database */
58 mime_type_t *src, /* I - Source type */
59 mime_type_t *dst, /* I - Destination type */
60 int cost, /* I - Relative time/resource cost */
61 char *filter) /* I - Filter program to run */
62{
63 mime_filter_t *temp; /* New filter */
64
65
66 /*
67 * Range-check the input...
68 */
69
70 if (mime == NULL || src == NULL || dst == NULL || filter == NULL)
71 return (NULL);
72
73 if (strlen(filter) > (MIME_MAX_FILTER - 1))
74 return (NULL);
75
76 /*
77 * See if we already have an existing filter for the given source and
78 * destination...
79 */
80
81 if ((temp = lookup(mime, src, dst)) != NULL)
82 {
83 /*
84 * Yup, does the existing filter have a higher cost? If so, copy the
85 * filter and cost to the existing filter entry and return it...
86 */
87
88 if (temp->cost > cost)
89 {
90 temp->cost = cost;
91 strcpy(temp->filter, filter);
e8fda7b9 92 }
0b74af7d 93 }
94 else
95 {
96 /*
97 * Nope, add a new one...
98 */
99
100 if (mime->num_filters == 0)
101 temp = malloc(sizeof(mime_filter_t));
102 else
103 temp = realloc(mime->filters, sizeof(mime_filter_t) * (mime->num_filters + 1));
104
105 if (temp == NULL)
106 return (NULL);
107
108 mime->filters = temp;
109 temp += mime->num_filters;
110 mime->num_filters ++;
111
112 /*
113 * Copy the information over and sort if necessary...
114 */
115
116 temp->src = src;
117 temp->dst = dst;
118 temp->cost = cost;
119 strcpy(temp->filter, filter);
120
121 if (mime->num_filters > 1)
122 qsort(mime->filters, mime->num_filters, sizeof(mime_filter_t),
123 (int (*)(const void *, const void *))compare);
e8fda7b9 124 }
0b74af7d 125
126 /*
127 * Return the new/updated filter...
128 */
129
130 return (temp);
131}
132
133
134/*
135 * 'mimeFilter()' - Find the fastest way to convert from one type to another.
0b74af7d 136 */
137
138mime_filter_t * /* O - Array of filters to run */
139mimeFilter(mime_t *mime, /* I - MIME database */
140 mime_type_t *src, /* I - Source file type */
141 mime_type_t *dst, /* I - Destination file type */
142 int *num_filters) /* O - Number of filters to run */
143{
75675d7a 144 int i, j, /* Looping vars */
145 num_temp, /* Number of temporary filters */
146 num_mintemp, /* Number of filters in the minimum */
147 cost, /* Current cost */
148 mincost; /* Current minimum */
0b74af7d 149 mime_filter_t *temp, /* Temporary filter */
4ca01b29 150 *mintemp, /* Current minimum */
151 *mincurrent, /* Current filter for minimum */
0b74af7d 152 *current, /* Current filter */
153 *filters; /* Filters to use */
154
155
156 /*
157 * Range-check the input...
158 */
159
160 if (mime == NULL || src == NULL || dst == NULL || num_filters == NULL)
161 return (NULL);
162
163 *num_filters = 0;
164
165 /*
166 * See if there is a filter that can convert the files directly...
167 */
168
169 if ((temp = lookup(mime, src, dst)) != NULL)
170 {
171 /*
172 * Got a direct filter!
173 */
174
175 if ((filters = (mime_filter_t *)malloc(sizeof(mime_filter_t))) == NULL)
176 return (NULL);
177
178 memcpy(filters, temp, sizeof(mime_filter_t));
179 *num_filters = 1;
180 return (filters);
e8fda7b9 181 }
0b74af7d 182
183 /*
184 * OK, now look for filters from the source type to any other type...
185 */
186
75675d7a 187 mincost = 9999999;
188 mintemp = NULL;
4ca01b29 189
0b74af7d 190 for (i = mime->num_filters, current = mime->filters; i > 0; i --, current ++)
191 if (current->src == src)
192 {
193 /*
194 * See if we have any filters that can convert from the destination type
195 * of this filter to the final type...
196 */
197
4ca01b29 198 if ((temp = mimeFilter(mime, current->dst, dst, &num_temp)) == NULL)
0b74af7d 199 continue;
200
201 /*
4ca01b29 202 * Found a match; see if this one is less costly than the last (if
203 * any...)
0b74af7d 204 */
205
75675d7a 206 for (j = 0, cost = 0; j < num_temp; j ++)
207 cost += temp->cost;
208
209 if (cost < mincost)
0b74af7d 210 {
4ca01b29 211 if (mintemp != NULL)
212 free(mintemp);
213
75675d7a 214 mincost = cost;
4ca01b29 215 mintemp = temp;
75675d7a 216 num_mintemp = num_temp;
4ca01b29 217 mincurrent = current;
e8fda7b9 218 }
4ca01b29 219 else
220 free(temp);
221 }
0b74af7d 222
4ca01b29 223 if (mintemp != NULL)
224 {
225 /*
226 * Hey, we got a match! Add the current filter to the beginning of the
227 * filter list...
228 */
0b74af7d 229
4ca01b29 230 filters = (mime_filter_t *)realloc(mintemp, sizeof(mime_filter_t) *
231 (num_mintemp + 1));
0b74af7d 232
4ca01b29 233 if (filters == NULL)
234 {
235 *num_filters = 0;
236 return (NULL);
e8fda7b9 237 }
0b74af7d 238
4ca01b29 239 memmove(filters + 1, filters, num_mintemp * sizeof(mime_filter_t));
240 memcpy(filters, mincurrent, sizeof(mime_filter_t));
241
242 *num_filters = num_mintemp + 1;
243
244 return (filters);
245 }
246
0b74af7d 247 return (NULL);
248}
249
250
251/*
252 * 'compare()' - Compare two filter types...
253 */
254
255static int /* O - Comparison result */
256compare(mime_filter_t *f0, /* I - First filter */
257 mime_filter_t *f1) /* I - Second filter */
258{
259 int i; /* Result of comparison */
260
261
262 if ((i = strcmp(f0->src->super, f1->src->super)) == 0)
263 if ((i = strcmp(f0->src->type, f1->src->type)) == 0)
264 if ((i = strcmp(f0->dst->super, f1->dst->super)) == 0)
265 i = strcmp(f0->dst->type, f1->dst->type);
266
267 return (i);
268}
269
270
271/*
272 * 'lookup()' - Lookup a filter...
273 */
274
275static mime_filter_t * /* O - Filter for src->dst */
276lookup(mime_t *mime, /* I - MIME database */
277 mime_type_t *src, /* I - Source type */
278 mime_type_t *dst) /* I - Destination type */
279{
280 mime_filter_t key; /* Key record for filter search */
281
282
283 if (mime->num_filters == 0)
284 return (NULL);
285
286 key.src = src;
287 key.dst = dst;
288
289 return ((mime_filter_t *)bsearch(&key, mime->filters, mime->num_filters,
290 sizeof(mime_filter_t),
291 (int (*)(const void *, const void *))compare));
292}
79df52e3 293
294
295/*
8784b6a6 296 * End of "$Id: filter.c,v 1.8 1999/06/18 18:36:08 mike Exp $".
79df52e3 297 */