Line data Source code
1 : /*
2 : * Copyright (c) 1988-1997 Sam Leffler
3 : * Copyright (c) 1991-1997 Silicon Graphics, Inc.
4 : *
5 : * Permission to use, copy, modify, distribute, and sell this software and
6 : * its documentation for any purpose is hereby granted without fee, provided
7 : * that (i) the above copyright notices and this permission notice appear in
8 : * all copies of the software and related documentation, and (ii) the names of
9 : * Sam Leffler and Silicon Graphics may not be used in any advertising or
10 : * publicity relating to the software without the specific, prior written
11 : * permission of Sam Leffler and Silicon Graphics.
12 : *
13 : * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14 : * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15 : * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16 : *
17 : * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18 : * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19 : * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20 : * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21 : * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22 : * OF THIS SOFTWARE.
23 : */
24 :
25 : /*
26 : * TIFF Library
27 : *
28 : * Compression Scheme Configuration Support.
29 : */
30 : #include "tiffiop.h"
31 :
32 0 : static int TIFFNoEncode(TIFF *tif, const char *method)
33 : {
34 0 : const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression);
35 :
36 0 : if (c)
37 : {
38 0 : TIFFErrorExtR(tif, tif->tif_name, "%s %s encoding is not implemented",
39 : c->name, method);
40 : }
41 : else
42 : {
43 0 : TIFFErrorExtR(tif, tif->tif_name,
44 : "Compression scheme %" PRIu16
45 : " %s encoding is not implemented",
46 0 : tif->tif_dir.td_compression, method);
47 : }
48 0 : return (-1);
49 : }
50 :
51 0 : int _TIFFNoRowEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
52 : {
53 : (void)pp;
54 : (void)cc;
55 : (void)s;
56 0 : return (TIFFNoEncode(tif, "scanline"));
57 : }
58 :
59 0 : int _TIFFNoStripEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
60 : {
61 : (void)pp;
62 : (void)cc;
63 : (void)s;
64 0 : return (TIFFNoEncode(tif, "strip"));
65 : }
66 :
67 0 : int _TIFFNoTileEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
68 : {
69 : (void)pp;
70 : (void)cc;
71 : (void)s;
72 0 : return (TIFFNoEncode(tif, "tile"));
73 : }
74 :
75 0 : static int TIFFNoDecode(TIFF *tif, const char *method)
76 : {
77 0 : const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression);
78 :
79 0 : if (c)
80 0 : TIFFErrorExtR(tif, tif->tif_name, "%s %s decoding is not implemented",
81 : c->name, method);
82 : else
83 0 : TIFFErrorExtR(tif, tif->tif_name,
84 : "Compression scheme %" PRIu16
85 : " %s decoding is not implemented",
86 0 : tif->tif_dir.td_compression, method);
87 0 : return (0);
88 : }
89 :
90 75 : static int _TIFFNoFixupTags(TIFF *tif)
91 : {
92 : (void)tif;
93 75 : return (1);
94 : }
95 :
96 0 : int _TIFFNoRowDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
97 : {
98 : (void)pp;
99 : (void)cc;
100 : (void)s;
101 0 : return (TIFFNoDecode(tif, "scanline"));
102 : }
103 :
104 0 : int _TIFFNoStripDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
105 : {
106 : (void)pp;
107 : (void)cc;
108 : (void)s;
109 0 : return (TIFFNoDecode(tif, "strip"));
110 : }
111 :
112 0 : int _TIFFNoTileDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
113 : {
114 : (void)pp;
115 : (void)cc;
116 : (void)s;
117 0 : return (TIFFNoDecode(tif, "tile"));
118 : }
119 :
120 0 : int _TIFFNoSeek(TIFF *tif, uint32_t off)
121 : {
122 : (void)off;
123 0 : TIFFErrorExtR(tif, tif->tif_name,
124 : "Compression algorithm does not support random access");
125 0 : return (0);
126 : }
127 :
128 2080 : int _TIFFNoPreCode(TIFF *tif, uint16_t s)
129 : {
130 : (void)tif;
131 : (void)s;
132 2080 : return (1);
133 : }
134 :
135 17385 : static int _TIFFtrue(TIFF *tif)
136 : {
137 : (void)tif;
138 17385 : return (1);
139 : }
140 253108 : static void _TIFFvoid(TIFF *tif) { (void)tif; }
141 :
142 0 : static uint64_t _TIFFDefaultGetMaxCompressionRatio(TIFF *tif)
143 : {
144 : (void)tif;
145 0 : return 0; /* unknown */
146 : }
147 :
148 0 : static uint64_t _TIFFGetMaxCompressionRatioOne(TIFF *tif)
149 : {
150 : (void)tif;
151 0 : return 1; /* no compression */
152 : }
153 :
154 281757 : void _TIFFSetDefaultCompressionState(TIFF *tif)
155 : {
156 281757 : tif->tif_fixuptags = _TIFFNoFixupTags;
157 281757 : tif->tif_decodestatus = TRUE;
158 281757 : tif->tif_setupdecode = _TIFFtrue;
159 281757 : tif->tif_predecode = _TIFFNoPreCode;
160 281757 : tif->tif_decoderow = _TIFFNoRowDecode;
161 281757 : tif->tif_decodestrip = _TIFFNoStripDecode;
162 281757 : tif->tif_decodetile = _TIFFNoTileDecode;
163 281757 : tif->tif_encodestatus = TRUE;
164 281757 : tif->tif_setupencode = _TIFFtrue;
165 281757 : tif->tif_preencode = _TIFFNoPreCode;
166 281757 : tif->tif_postencode = _TIFFtrue;
167 281757 : tif->tif_encoderow = _TIFFNoRowEncode;
168 281757 : tif->tif_encodestrip = _TIFFNoStripEncode;
169 281757 : tif->tif_encodetile = _TIFFNoTileEncode;
170 281757 : tif->tif_close = _TIFFvoid;
171 281757 : tif->tif_seek = _TIFFNoSeek;
172 281757 : tif->tif_cleanup = _TIFFvoid;
173 281757 : tif->tif_defstripsize = _TIFFDefaultStripSize;
174 281757 : tif->tif_deftilesize = _TIFFDefaultTileSize;
175 281757 : tif->tif_getmaxcompressionratio = _TIFFDefaultGetMaxCompressionRatio;
176 281757 : tif->tif_flags &= ~(TIFF_NOBITREV | TIFF_NOREADRAW);
177 281757 : }
178 :
179 174293 : int TIFFSetCompressionScheme(TIFF *tif, int scheme)
180 : {
181 174293 : const TIFFCodec *c = TIFFFindCODEC((uint16_t)scheme);
182 :
183 173920 : _TIFFSetDefaultCompressionState(tif);
184 174047 : if (scheme == COMPRESSION_NONE)
185 137382 : tif->tif_getmaxcompressionratio = _TIFFGetMaxCompressionRatioOne;
186 : /*
187 : * Don't treat an unknown compression scheme as an error.
188 : * This permits applications to open files with data that
189 : * the library does not have builtin support for, but which
190 : * may still be meaningful.
191 : */
192 174047 : return (c ? (*c->init)(tif, scheme) : 1);
193 : }
194 :
195 1 : uint64_t TIFFGetMaxCompressionRatio(TIFF *tif)
196 : {
197 1 : if (tif->tif_getmaxcompressionratio)
198 1 : return tif->tif_getmaxcompressionratio(tif);
199 0 : return 0;
200 : }
201 :
202 : /*
203 : * Other compression schemes may be registered. Registered
204 : * schemes can also override the builtin versions provided
205 : * by this library.
206 : */
207 : typedef struct _codec
208 : {
209 : struct _codec *next;
210 : TIFFCodec *info;
211 : } codec_t;
212 : static codec_t *registeredCODECS = NULL;
213 :
214 274250 : const TIFFCodec *TIFFFindCODEC(uint16_t scheme)
215 : {
216 : const TIFFCodec *c;
217 : codec_t *cd;
218 :
219 662958 : for (cd = registeredCODECS; cd; cd = cd->next)
220 389605 : if (cd->info->scheme == scheme)
221 897 : return ((const TIFFCodec *)cd->info);
222 1442820 : for (c = _TIFFBuiltinCODECS; c->name; c++)
223 1442700 : if (c->scheme == scheme)
224 273240 : return (c);
225 113 : return NULL;
226 : }
227 :
228 1406 : TIFFCodec *TIFFRegisterCODEC(uint16_t scheme, const char *name,
229 : TIFFInitMethod init)
230 : {
231 1406 : codec_t *cd = (codec_t *)_TIFFmallocExt(
232 : NULL,
233 1406 : (tmsize_t)(sizeof(codec_t) + sizeof(TIFFCodec) + strlen(name) + 1));
234 :
235 1406 : if (cd != NULL)
236 : {
237 : char *codec_name;
238 1406 : cd->info = (TIFFCodec *)((uint8_t *)cd + sizeof(codec_t));
239 1406 : codec_name = (char *)((uint8_t *)cd->info + sizeof(TIFFCodec));
240 1406 : strcpy(codec_name, name);
241 1406 : cd->info->name = codec_name;
242 1406 : cd->info->scheme = scheme;
243 1406 : cd->info->init = init;
244 1406 : cd->next = registeredCODECS;
245 1406 : registeredCODECS = cd;
246 : }
247 : else
248 : {
249 0 : TIFFErrorExt(0, "TIFFRegisterCODEC",
250 : "No space to register compression scheme %s", name);
251 0 : return NULL;
252 : }
253 1406 : return (cd->info);
254 : }
255 :
256 1038 : void TIFFUnRegisterCODEC(TIFFCodec *c)
257 : {
258 : codec_t *cd;
259 : codec_t **pcd;
260 :
261 1557 : for (pcd = ®isteredCODECS; (cd = *pcd) != NULL; pcd = &cd->next)
262 1557 : if (cd->info == c)
263 : {
264 1038 : *pcd = cd->next;
265 1038 : _TIFFfreeExt(NULL, cd);
266 1038 : return;
267 : }
268 0 : TIFFErrorExt(0, "TIFFUnRegisterCODEC",
269 : "Cannot remove compression scheme %s; not registered",
270 : c->name);
271 : }
272 :
273 : /************************************************************************/
274 : /* TIFFGetConfiguredCODECs() */
275 : /************************************************************************/
276 :
277 : /**
278 : * Get list of configured codecs, both built-in and registered by user.
279 : * Caller is responsible to free this structure.
280 : *
281 : * @return returns array of TIFFCodec records (the last record should be NULL)
282 : * or NULL if function failed.
283 : */
284 :
285 4002 : TIFFCodec *TIFFGetConfiguredCODECs(void)
286 : {
287 4002 : int i = 1;
288 : codec_t *cd;
289 : const TIFFCodec *c;
290 4002 : TIFFCodec *codecs = NULL;
291 : TIFFCodec *new_codecs;
292 :
293 4504 : for (cd = registeredCODECS; cd; cd = cd->next)
294 : {
295 502 : new_codecs = (TIFFCodec *)_TIFFreallocExt(
296 502 : NULL, codecs, (tmsize_t)((size_t)i * sizeof(TIFFCodec)));
297 502 : if (!new_codecs)
298 : {
299 0 : _TIFFfreeExt(NULL, codecs);
300 0 : return NULL;
301 : }
302 502 : codecs = new_codecs;
303 502 : _TIFFmemcpy(codecs + i - 1, cd->info, sizeof(TIFFCodec));
304 502 : i++;
305 : }
306 88044 : for (c = _TIFFBuiltinCODECS; c->name; c++)
307 : {
308 84042 : if (TIFFIsCODECConfigured(c->scheme))
309 : {
310 80040 : new_codecs = (TIFFCodec *)_TIFFreallocExt(
311 80040 : NULL, codecs, (tmsize_t)((size_t)i * sizeof(TIFFCodec)));
312 80040 : if (!new_codecs)
313 : {
314 0 : _TIFFfreeExt(NULL, codecs);
315 0 : return NULL;
316 : }
317 80040 : codecs = new_codecs;
318 80040 : _TIFFmemcpy(codecs + i - 1, c, sizeof(TIFFCodec));
319 80040 : i++;
320 : }
321 : }
322 :
323 4002 : new_codecs = (TIFFCodec *)_TIFFreallocExt(
324 4002 : NULL, codecs, (tmsize_t)((size_t)i * sizeof(TIFFCodec)));
325 4002 : if (!new_codecs)
326 : {
327 0 : _TIFFfreeExt(NULL, codecs);
328 0 : return NULL;
329 : }
330 4002 : codecs = new_codecs;
331 4002 : _TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec));
332 :
333 4002 : return codecs;
334 : }
|