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 1722 : int _TIFFNoPreCode(TIFF *tif, uint16_t s)
129 : {
130 : (void)tif;
131 : (void)s;
132 1722 : return (1);
133 : }
134 :
135 14373 : static int _TIFFtrue(TIFF *tif)
136 : {
137 : (void)tif;
138 14373 : return (1);
139 : }
140 181995 : static void _TIFFvoid(TIFF *tif) { (void)tif; }
141 :
142 248617 : void _TIFFSetDefaultCompressionState(TIFF *tif)
143 : {
144 248617 : tif->tif_fixuptags = _TIFFNoFixupTags;
145 248617 : tif->tif_decodestatus = TRUE;
146 248617 : tif->tif_setupdecode = _TIFFtrue;
147 248617 : tif->tif_predecode = _TIFFNoPreCode;
148 248617 : tif->tif_decoderow = _TIFFNoRowDecode;
149 248617 : tif->tif_decodestrip = _TIFFNoStripDecode;
150 248617 : tif->tif_decodetile = _TIFFNoTileDecode;
151 248617 : tif->tif_encodestatus = TRUE;
152 248617 : tif->tif_setupencode = _TIFFtrue;
153 248617 : tif->tif_preencode = _TIFFNoPreCode;
154 248617 : tif->tif_postencode = _TIFFtrue;
155 248617 : tif->tif_encoderow = _TIFFNoRowEncode;
156 248617 : tif->tif_encodestrip = _TIFFNoStripEncode;
157 248617 : tif->tif_encodetile = _TIFFNoTileEncode;
158 248617 : tif->tif_close = _TIFFvoid;
159 248617 : tif->tif_seek = _TIFFNoSeek;
160 248617 : tif->tif_cleanup = _TIFFvoid;
161 248617 : tif->tif_defstripsize = _TIFFDefaultStripSize;
162 248617 : tif->tif_deftilesize = _TIFFDefaultTileSize;
163 248617 : tif->tif_flags &= ~(TIFF_NOBITREV | TIFF_NOREADRAW);
164 248617 : }
165 :
166 152805 : int TIFFSetCompressionScheme(TIFF *tif, int scheme)
167 : {
168 152805 : const TIFFCodec *c = TIFFFindCODEC((uint16_t)scheme);
169 :
170 152766 : _TIFFSetDefaultCompressionState(tif);
171 : /*
172 : * Don't treat an unknown compression scheme as an error.
173 : * This permits applications to open files with data that
174 : * the library does not have builtin support for, but which
175 : * may still be meaningful.
176 : */
177 152768 : return (c ? (*c->init)(tif, scheme) : 1);
178 : }
179 :
180 : /*
181 : * Other compression schemes may be registered. Registered
182 : * schemes can also override the builtin versions provided
183 : * by this library.
184 : */
185 : typedef struct _codec
186 : {
187 : struct _codec *next;
188 : TIFFCodec *info;
189 : } codec_t;
190 : static codec_t *registeredCODECS = NULL;
191 :
192 223818 : const TIFFCodec *TIFFFindCODEC(uint16_t scheme)
193 : {
194 : const TIFFCodec *c;
195 : codec_t *cd;
196 :
197 561870 : for (cd = registeredCODECS; cd; cd = cd->next)
198 338930 : if (cd->info->scheme == scheme)
199 878 : return ((const TIFFCodec *)cd->info);
200 1098700 : for (c = _TIFFBuiltinCODECS; c->name; c++)
201 1098680 : if (c->scheme == scheme)
202 222918 : return (c);
203 22 : return ((const TIFFCodec *)0);
204 : }
205 :
206 1216 : TIFFCodec *TIFFRegisterCODEC(uint16_t scheme, const char *name,
207 : TIFFInitMethod init)
208 : {
209 1216 : codec_t *cd = (codec_t *)_TIFFmallocExt(
210 : NULL,
211 1216 : (tmsize_t)(sizeof(codec_t) + sizeof(TIFFCodec) + strlen(name) + 1));
212 :
213 1216 : if (cd != NULL)
214 : {
215 1216 : cd->info = (TIFFCodec *)((uint8_t *)cd + sizeof(codec_t));
216 1216 : cd->info->name = (char *)((uint8_t *)cd->info + sizeof(TIFFCodec));
217 1216 : strcpy(cd->info->name, name);
218 1216 : cd->info->scheme = scheme;
219 1216 : cd->info->init = init;
220 1216 : cd->next = registeredCODECS;
221 1216 : registeredCODECS = cd;
222 : }
223 : else
224 : {
225 0 : TIFFErrorExt(0, "TIFFRegisterCODEC",
226 : "No space to register compression scheme %s", name);
227 0 : return NULL;
228 : }
229 1216 : return (cd->info);
230 : }
231 :
232 896 : void TIFFUnRegisterCODEC(TIFFCodec *c)
233 : {
234 : codec_t *cd;
235 : codec_t **pcd;
236 :
237 1344 : for (pcd = ®isteredCODECS; (cd = *pcd) != NULL; pcd = &cd->next)
238 1344 : if (cd->info == c)
239 : {
240 896 : *pcd = cd->next;
241 896 : _TIFFfreeExt(NULL, cd);
242 896 : return;
243 : }
244 0 : TIFFErrorExt(0, "TIFFUnRegisterCODEC",
245 : "Cannot remove compression scheme %s; not registered",
246 : c->name);
247 : }
248 :
249 : /************************************************************************/
250 : /* TIFFGetConfisuredCODECs() */
251 : /************************************************************************/
252 :
253 : /**
254 : * Get list of configured codecs, both built-in and registered by user.
255 : * Caller is responsible to free this structure.
256 : *
257 : * @return returns array of TIFFCodec records (the last record should be NULL)
258 : * or NULL if function failed.
259 : */
260 :
261 2744 : TIFFCodec *TIFFGetConfiguredCODECs()
262 : {
263 2744 : int i = 1;
264 : codec_t *cd;
265 : const TIFFCodec *c;
266 2744 : TIFFCodec *codecs = NULL;
267 : TIFFCodec *new_codecs;
268 :
269 3058 : for (cd = registeredCODECS; cd; cd = cd->next)
270 : {
271 : new_codecs =
272 314 : (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec));
273 314 : if (!new_codecs)
274 : {
275 0 : _TIFFfreeExt(NULL, codecs);
276 0 : return NULL;
277 : }
278 314 : codecs = new_codecs;
279 314 : _TIFFmemcpy(codecs + i - 1, cd->info, sizeof(TIFFCodec));
280 314 : i++;
281 : }
282 60368 : for (c = _TIFFBuiltinCODECS; c->name; c++)
283 : {
284 57624 : if (TIFFIsCODECConfigured(c->scheme))
285 : {
286 54880 : new_codecs = (TIFFCodec *)_TIFFreallocExt(NULL, codecs,
287 54880 : i * sizeof(TIFFCodec));
288 54880 : if (!new_codecs)
289 : {
290 0 : _TIFFfreeExt(NULL, codecs);
291 0 : return NULL;
292 : }
293 54880 : codecs = new_codecs;
294 54880 : _TIFFmemcpy(codecs + i - 1, (const void *)c, sizeof(TIFFCodec));
295 54880 : i++;
296 : }
297 : }
298 :
299 : new_codecs =
300 2744 : (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec));
301 2744 : if (!new_codecs)
302 : {
303 0 : _TIFFfreeExt(NULL, codecs);
304 0 : return NULL;
305 : }
306 2744 : codecs = new_codecs;
307 2744 : _TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec));
308 :
309 2744 : return codecs;
310 : }
|