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 2081 : int _TIFFNoPreCode(TIFF *tif, uint16_t s)
129 : {
130 : (void)tif;
131 : (void)s;
132 2081 : return (1);
133 : }
134 :
135 17252 : static int _TIFFtrue(TIFF *tif)
136 : {
137 : (void)tif;
138 17252 : return (1);
139 : }
140 250811 : static void _TIFFvoid(TIFF *tif) { (void)tif; }
141 :
142 373720 : void _TIFFSetDefaultPostDecode(TIFF *tif)
143 : {
144 373720 : 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 373720 : 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 373720 : }
171 :
172 279413 : void _TIFFSetDefaultCompressionState(TIFF *tif)
173 : {
174 279413 : tif->tif_fixuptags = _TIFFNoFixupTags;
175 279413 : tif->tif_decodestatus = TRUE;
176 279413 : tif->tif_setupdecode = _TIFFtrue;
177 279413 : tif->tif_predecode = _TIFFNoPreCode;
178 279413 : _TIFFSetDefaultPostDecode(tif);
179 279370 : tif->tif_decoderow = _TIFFNoRowDecode;
180 279370 : tif->tif_decodestrip = _TIFFNoStripDecode;
181 279370 : tif->tif_decodetile = _TIFFNoTileDecode;
182 279370 : tif->tif_encodestatus = TRUE;
183 279370 : tif->tif_setupencode = _TIFFtrue;
184 279370 : tif->tif_preencode = _TIFFNoPreCode;
185 279370 : tif->tif_postencode = _TIFFtrue;
186 279370 : tif->tif_encoderow = _TIFFNoRowEncode;
187 279370 : tif->tif_encodestrip = _TIFFNoStripEncode;
188 279370 : tif->tif_encodetile = _TIFFNoTileEncode;
189 279370 : tif->tif_close = _TIFFvoid;
190 279370 : tif->tif_seek = _TIFFNoSeek;
191 279370 : tif->tif_cleanup = _TIFFvoid;
192 279370 : tif->tif_defstripsize = _TIFFDefaultStripSize;
193 279370 : tif->tif_deftilesize = _TIFFDefaultTileSize;
194 279370 : tif->tif_flags &= ~(TIFF_NOBITREV | TIFF_NOREADRAW);
195 279370 : }
196 :
197 172537 : int TIFFSetCompressionScheme(TIFF *tif, int scheme)
198 : {
199 172537 : const TIFFCodec *c = TIFFFindCODEC((uint16_t)scheme);
200 :
201 172536 : _TIFFSetDefaultCompressionState(tif);
202 : /*
203 : * Don't treat an unknown compression scheme as an error.
204 : * This permits applications to open files with data that
205 : * the library does not have builtin support for, but which
206 : * may still be meaningful.
207 : */
208 172536 : return (c ? (*c->init)(tif, scheme) : 1);
209 : }
210 :
211 : /*
212 : * Other compression schemes may be registered. Registered
213 : * schemes can also override the builtin versions provided
214 : * by this library.
215 : */
216 : typedef struct _codec
217 : {
218 : struct _codec *next;
219 : TIFFCodec *info;
220 : } codec_t;
221 : static codec_t *registeredCODECS = NULL;
222 :
223 268813 : const TIFFCodec *TIFFFindCODEC(uint16_t scheme)
224 : {
225 : const TIFFCodec *c;
226 : codec_t *cd;
227 :
228 653793 : for (cd = registeredCODECS; cd; cd = cd->next)
229 385877 : if (cd->info->scheme == scheme)
230 897 : return ((const TIFFCodec *)cd->info);
231 1396220 : for (c = _TIFFBuiltinCODECS; c->name; c++)
232 1396200 : if (c->scheme == scheme)
233 267895 : return (c);
234 21 : return ((const TIFFCodec *)0);
235 : }
236 :
237 1398 : TIFFCodec *TIFFRegisterCODEC(uint16_t scheme, const char *name,
238 : TIFFInitMethod init)
239 : {
240 1398 : codec_t *cd = (codec_t *)_TIFFmallocExt(
241 : NULL,
242 1398 : (tmsize_t)(sizeof(codec_t) + sizeof(TIFFCodec) + strlen(name) + 1));
243 :
244 1398 : if (cd != NULL)
245 : {
246 : char *codec_name;
247 1398 : cd->info = (TIFFCodec *)((uint8_t *)cd + sizeof(codec_t));
248 1398 : codec_name = (char *)((uint8_t *)cd->info + sizeof(TIFFCodec));
249 1398 : strcpy(codec_name, name);
250 1398 : cd->info->name = codec_name;
251 1398 : cd->info->scheme = scheme;
252 1398 : cd->info->init = init;
253 1398 : cd->next = registeredCODECS;
254 1398 : registeredCODECS = cd;
255 : }
256 : else
257 : {
258 0 : TIFFErrorExt(0, "TIFFRegisterCODEC",
259 : "No space to register compression scheme %s", name);
260 0 : return NULL;
261 : }
262 1398 : return (cd->info);
263 : }
264 :
265 868 : void TIFFUnRegisterCODEC(TIFFCodec *c)
266 : {
267 : codec_t *cd;
268 : codec_t **pcd;
269 :
270 1302 : for (pcd = ®isteredCODECS; (cd = *pcd) != NULL; pcd = &cd->next)
271 1302 : if (cd->info == c)
272 : {
273 868 : *pcd = cd->next;
274 868 : _TIFFfreeExt(NULL, cd);
275 868 : return;
276 : }
277 0 : TIFFErrorExt(0, "TIFFUnRegisterCODEC",
278 : "Cannot remove compression scheme %s; not registered",
279 : c->name);
280 : }
281 :
282 : /************************************************************************/
283 : /* TIFFGetConfiguredCODECs() */
284 : /************************************************************************/
285 :
286 : /**
287 : * Get list of configured codecs, both built-in and registered by user.
288 : * Caller is responsible to free this structure.
289 : *
290 : * @return returns array of TIFFCodec records (the last record should be NULL)
291 : * or NULL if function failed.
292 : */
293 :
294 3837 : TIFFCodec *TIFFGetConfiguredCODECs(void)
295 : {
296 3837 : int i = 1;
297 : codec_t *cd;
298 : const TIFFCodec *c;
299 3837 : TIFFCodec *codecs = NULL;
300 : TIFFCodec *new_codecs;
301 :
302 4329 : for (cd = registeredCODECS; cd; cd = cd->next)
303 : {
304 : new_codecs =
305 492 : (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec));
306 492 : if (!new_codecs)
307 : {
308 0 : _TIFFfreeExt(NULL, codecs);
309 0 : return NULL;
310 : }
311 492 : codecs = new_codecs;
312 492 : _TIFFmemcpy(codecs + i - 1, cd->info, sizeof(TIFFCodec));
313 492 : i++;
314 : }
315 84414 : for (c = _TIFFBuiltinCODECS; c->name; c++)
316 : {
317 80577 : if (TIFFIsCODECConfigured(c->scheme))
318 : {
319 76740 : new_codecs = (TIFFCodec *)_TIFFreallocExt(NULL, codecs,
320 76740 : i * sizeof(TIFFCodec));
321 76740 : if (!new_codecs)
322 : {
323 0 : _TIFFfreeExt(NULL, codecs);
324 0 : return NULL;
325 : }
326 76740 : codecs = new_codecs;
327 76740 : _TIFFmemcpy(codecs + i - 1, (const void *)c, sizeof(TIFFCodec));
328 76740 : i++;
329 : }
330 : }
331 :
332 : new_codecs =
333 3837 : (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec));
334 3837 : if (!new_codecs)
335 : {
336 0 : _TIFFfreeExt(NULL, codecs);
337 0 : return NULL;
338 : }
339 3837 : codecs = new_codecs;
340 3837 : _TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec));
341 :
342 3837 : return codecs;
343 : }
|