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