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 74 : static int _TIFFNoFixupTags(TIFF *tif)
91 : {
92 : (void)tif;
93 74 : 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 2076 : int _TIFFNoPreCode(TIFF *tif, uint16_t s)
129 : {
130 : (void)tif;
131 : (void)s;
132 2076 : return (1);
133 : }
134 :
135 17309 : static int _TIFFtrue(TIFF *tif)
136 : {
137 : (void)tif;
138 17309 : return (1);
139 : }
140 252016 : static void _TIFFvoid(TIFF *tif) { (void)tif; }
141 :
142 375471 : void _TIFFSetDefaultPostDecode(TIFF *tif)
143 : {
144 375471 : tif->tif_postdecode = _TIFFNoPostDecode;
145 : /*
146 : * If the data require post-decoding processing to byte-swap
147 : * samples, set it up here. Note that since tags are required
148 : * to be ordered, compression code can override this behavior
149 : * in the setup method if it wants to roll the post decoding
150 : * work in with its normal work.
151 : */
152 375471 : if (tif->tif_flags & TIFF_SWAB)
153 : {
154 1857 : TIFFDirectory *td = &tif->tif_dir;
155 1857 : if (td->td_bitspersample == 16)
156 153 : tif->tif_postdecode = _TIFFSwab16BitData;
157 1704 : else if (td->td_bitspersample == 24)
158 0 : tif->tif_postdecode = _TIFFSwab24BitData;
159 1704 : else if (td->td_bitspersample == 32)
160 149 : tif->tif_postdecode = _TIFFSwab32BitData;
161 1555 : else if (td->td_bitspersample == 64)
162 21 : tif->tif_postdecode = _TIFFSwab64BitData;
163 1534 : else if (td->td_bitspersample == 128)
164 : {
165 : // Used for Complex 64-bit floating point.
166 : // The real and imaginary parts are byte-swapped separately.
167 7 : tif->tif_postdecode = _TIFFSwab64BitData;
168 : }
169 : }
170 375471 : }
171 :
172 0 : static uint64_t _TIFFDefaultGetMaxCompressionRatio(TIFF *tif)
173 : {
174 : (void)tif;
175 0 : return 0; /* unknown */
176 : }
177 :
178 0 : static uint64_t _TIFFGetMaxCompressionRatioOne(TIFF *tif)
179 : {
180 : (void)tif;
181 0 : return 1; /* no compression */
182 : }
183 :
184 280802 : void _TIFFSetDefaultCompressionState(TIFF *tif)
185 : {
186 280802 : tif->tif_fixuptags = _TIFFNoFixupTags;
187 280802 : tif->tif_decodestatus = TRUE;
188 280802 : tif->tif_setupdecode = _TIFFtrue;
189 280802 : tif->tif_predecode = _TIFFNoPreCode;
190 280802 : _TIFFSetDefaultPostDecode(tif);
191 280675 : tif->tif_decoderow = _TIFFNoRowDecode;
192 280675 : tif->tif_decodestrip = _TIFFNoStripDecode;
193 280675 : tif->tif_decodetile = _TIFFNoTileDecode;
194 280675 : tif->tif_encodestatus = TRUE;
195 280675 : tif->tif_setupencode = _TIFFtrue;
196 280675 : tif->tif_preencode = _TIFFNoPreCode;
197 280675 : tif->tif_postencode = _TIFFtrue;
198 280675 : tif->tif_encoderow = _TIFFNoRowEncode;
199 280675 : tif->tif_encodestrip = _TIFFNoStripEncode;
200 280675 : tif->tif_encodetile = _TIFFNoTileEncode;
201 280675 : tif->tif_close = _TIFFvoid;
202 280675 : tif->tif_seek = _TIFFNoSeek;
203 280675 : tif->tif_cleanup = _TIFFvoid;
204 280675 : tif->tif_defstripsize = _TIFFDefaultStripSize;
205 280675 : tif->tif_deftilesize = _TIFFDefaultTileSize;
206 280675 : tif->tif_getmaxcompressionratio = _TIFFDefaultGetMaxCompressionRatio;
207 280675 : tif->tif_flags &= ~(TIFF_NOBITREV | TIFF_NOREADRAW);
208 280675 : }
209 :
210 173470 : int TIFFSetCompressionScheme(TIFF *tif, int scheme)
211 : {
212 173470 : const TIFFCodec *c = TIFFFindCODEC((uint16_t)scheme);
213 :
214 173404 : _TIFFSetDefaultCompressionState(tif);
215 173399 : if (scheme == COMPRESSION_NONE)
216 136878 : tif->tif_getmaxcompressionratio = _TIFFGetMaxCompressionRatioOne;
217 : /*
218 : * Don't treat an unknown compression scheme as an error.
219 : * This permits applications to open files with data that
220 : * the library does not have builtin support for, but which
221 : * may still be meaningful.
222 : */
223 173399 : return (c ? (*c->init)(tif, scheme) : 1);
224 : }
225 :
226 0 : uint64_t TIFFGetMaxCompressionRatio(TIFF *tif)
227 : {
228 0 : if (tif->tif_getmaxcompressionratio)
229 0 : return tif->tif_getmaxcompressionratio(tif);
230 0 : return 0;
231 : }
232 :
233 : /*
234 : * Other compression schemes may be registered. Registered
235 : * schemes can also override the builtin versions provided
236 : * by this library.
237 : */
238 : typedef struct _codec
239 : {
240 : struct _codec *next;
241 : TIFFCodec *info;
242 : } codec_t;
243 : static codec_t *registeredCODECS = NULL;
244 :
245 270837 : const TIFFCodec *TIFFFindCODEC(uint16_t scheme)
246 : {
247 : const TIFFCodec *c;
248 : codec_t *cd;
249 :
250 657965 : for (cd = registeredCODECS; cd; cd = cd->next)
251 388024 : if (cd->info->scheme == scheme)
252 896 : return ((const TIFFCodec *)cd->info);
253 1410690 : for (c = _TIFFBuiltinCODECS; c->name; c++)
254 1410650 : if (c->scheme == scheme)
255 269904 : return (c);
256 37 : return NULL;
257 : }
258 :
259 1388 : TIFFCodec *TIFFRegisterCODEC(uint16_t scheme, const char *name,
260 : TIFFInitMethod init)
261 : {
262 1388 : codec_t *cd = (codec_t *)_TIFFmallocExt(
263 : NULL,
264 1388 : (tmsize_t)(sizeof(codec_t) + sizeof(TIFFCodec) + strlen(name) + 1));
265 :
266 1388 : if (cd != NULL)
267 : {
268 : char *codec_name;
269 1388 : cd->info = (TIFFCodec *)((uint8_t *)cd + sizeof(codec_t));
270 1388 : codec_name = (char *)((uint8_t *)cd->info + sizeof(TIFFCodec));
271 1388 : strcpy(codec_name, name);
272 1388 : cd->info->name = codec_name;
273 1388 : cd->info->scheme = scheme;
274 1388 : cd->info->init = init;
275 1388 : cd->next = registeredCODECS;
276 1388 : registeredCODECS = cd;
277 : }
278 : else
279 : {
280 0 : TIFFErrorExt(0, "TIFFRegisterCODEC",
281 : "No space to register compression scheme %s", name);
282 0 : return NULL;
283 : }
284 1388 : return (cd->info);
285 : }
286 :
287 1022 : void TIFFUnRegisterCODEC(TIFFCodec *c)
288 : {
289 : codec_t *cd;
290 : codec_t **pcd;
291 :
292 1533 : for (pcd = ®isteredCODECS; (cd = *pcd) != NULL; pcd = &cd->next)
293 1533 : if (cd->info == c)
294 : {
295 1022 : *pcd = cd->next;
296 1022 : _TIFFfreeExt(NULL, cd);
297 1022 : return;
298 : }
299 0 : TIFFErrorExt(0, "TIFFUnRegisterCODEC",
300 : "Cannot remove compression scheme %s; not registered",
301 : c->name);
302 : }
303 :
304 : /************************************************************************/
305 : /* TIFFGetConfiguredCODECs() */
306 : /************************************************************************/
307 :
308 : /**
309 : * Get list of configured codecs, both built-in and registered by user.
310 : * Caller is responsible to free this structure.
311 : *
312 : * @return returns array of TIFFCodec records (the last record should be NULL)
313 : * or NULL if function failed.
314 : */
315 :
316 3885 : TIFFCodec *TIFFGetConfiguredCODECs(void)
317 : {
318 3885 : int i = 1;
319 : codec_t *cd;
320 : const TIFFCodec *c;
321 3885 : TIFFCodec *codecs = NULL;
322 : TIFFCodec *new_codecs;
323 :
324 4385 : for (cd = registeredCODECS; cd; cd = cd->next)
325 : {
326 500 : new_codecs = (TIFFCodec *)_TIFFreallocExt(
327 500 : NULL, codecs, (tmsize_t)((size_t)i * sizeof(TIFFCodec)));
328 500 : if (!new_codecs)
329 : {
330 0 : _TIFFfreeExt(NULL, codecs);
331 0 : return NULL;
332 : }
333 500 : codecs = new_codecs;
334 500 : _TIFFmemcpy(codecs + i - 1, cd->info, sizeof(TIFFCodec));
335 500 : i++;
336 : }
337 85470 : for (c = _TIFFBuiltinCODECS; c->name; c++)
338 : {
339 81585 : if (TIFFIsCODECConfigured(c->scheme))
340 : {
341 77700 : new_codecs = (TIFFCodec *)_TIFFreallocExt(
342 77700 : NULL, codecs, (tmsize_t)((size_t)i * sizeof(TIFFCodec)));
343 77700 : if (!new_codecs)
344 : {
345 0 : _TIFFfreeExt(NULL, codecs);
346 0 : return NULL;
347 : }
348 77700 : codecs = new_codecs;
349 77700 : _TIFFmemcpy(codecs + i - 1, c, sizeof(TIFFCodec));
350 77700 : i++;
351 : }
352 : }
353 :
354 3885 : new_codecs = (TIFFCodec *)_TIFFreallocExt(
355 3885 : NULL, codecs, (tmsize_t)((size_t)i * sizeof(TIFFCodec)));
356 3885 : if (!new_codecs)
357 : {
358 0 : _TIFFfreeExt(NULL, codecs);
359 0 : return NULL;
360 : }
361 3885 : codecs = new_codecs;
362 3885 : _TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec));
363 :
364 3885 : return codecs;
365 : }
|