/src/freeimage-svn/FreeImage/trunk/Source/LibTIFF4/tif_compress.c
Line | Count | Source (jump to first uncovered line) |
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 | | static int TIFFNoEncode(TIFF *tif, const char *method) |
33 | 0 | { |
34 | 0 | const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression); |
35 | |
|
36 | 0 | if (c) |
37 | 0 | { |
38 | 0 | TIFFErrorExtR(tif, tif->tif_name, "%s %s encoding is not implemented", |
39 | 0 | c->name, method); |
40 | 0 | } |
41 | 0 | else |
42 | 0 | { |
43 | 0 | TIFFErrorExtR(tif, tif->tif_name, |
44 | 0 | "Compression scheme %" PRIu16 |
45 | 0 | " %s encoding is not implemented", |
46 | 0 | tif->tif_dir.td_compression, method); |
47 | 0 | } |
48 | 0 | return (-1); |
49 | 0 | } |
50 | | |
51 | | int _TIFFNoRowEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) |
52 | 0 | { |
53 | 0 | (void)pp; |
54 | 0 | (void)cc; |
55 | 0 | (void)s; |
56 | 0 | return (TIFFNoEncode(tif, "scanline")); |
57 | 0 | } |
58 | | |
59 | | int _TIFFNoStripEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) |
60 | 0 | { |
61 | 0 | (void)pp; |
62 | 0 | (void)cc; |
63 | 0 | (void)s; |
64 | 0 | return (TIFFNoEncode(tif, "strip")); |
65 | 0 | } |
66 | | |
67 | | int _TIFFNoTileEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) |
68 | 0 | { |
69 | 0 | (void)pp; |
70 | 0 | (void)cc; |
71 | 0 | (void)s; |
72 | 0 | return (TIFFNoEncode(tif, "tile")); |
73 | 0 | } |
74 | | |
75 | | static int TIFFNoDecode(TIFF *tif, const char *method) |
76 | 0 | { |
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 | 0 | c->name, method); |
82 | 0 | else |
83 | 0 | TIFFErrorExtR(tif, tif->tif_name, |
84 | 0 | "Compression scheme %" PRIu16 |
85 | 0 | " %s decoding is not implemented", |
86 | 0 | tif->tif_dir.td_compression, method); |
87 | 0 | return (0); |
88 | 0 | } |
89 | | |
90 | | static int _TIFFNoFixupTags(TIFF *tif) |
91 | 0 | { |
92 | 0 | (void)tif; |
93 | 0 | return (1); |
94 | 0 | } |
95 | | |
96 | | int _TIFFNoRowDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) |
97 | 0 | { |
98 | 0 | (void)pp; |
99 | 0 | (void)cc; |
100 | 0 | (void)s; |
101 | 0 | return (TIFFNoDecode(tif, "scanline")); |
102 | 0 | } |
103 | | |
104 | | int _TIFFNoStripDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) |
105 | 0 | { |
106 | 0 | (void)pp; |
107 | 0 | (void)cc; |
108 | 0 | (void)s; |
109 | 0 | return (TIFFNoDecode(tif, "strip")); |
110 | 0 | } |
111 | | |
112 | | int _TIFFNoTileDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s) |
113 | 0 | { |
114 | 0 | (void)pp; |
115 | 0 | (void)cc; |
116 | 0 | (void)s; |
117 | 0 | return (TIFFNoDecode(tif, "tile")); |
118 | 0 | } |
119 | | |
120 | | int _TIFFNoSeek(TIFF *tif, uint32_t off) |
121 | 0 | { |
122 | 0 | (void)off; |
123 | 0 | TIFFErrorExtR(tif, tif->tif_name, |
124 | 0 | "Compression algorithm does not support random access"); |
125 | 0 | return (0); |
126 | 0 | } |
127 | | |
128 | | int _TIFFNoPreCode(TIFF *tif, uint16_t s) |
129 | 0 | { |
130 | 0 | (void)tif; |
131 | 0 | (void)s; |
132 | 0 | return (1); |
133 | 0 | } |
134 | | |
135 | | static int _TIFFtrue(TIFF *tif) |
136 | 0 | { |
137 | 0 | (void)tif; |
138 | 0 | return (1); |
139 | 0 | } |
140 | 0 | static void _TIFFvoid(TIFF *tif) { (void)tif; } |
141 | | |
142 | | void _TIFFSetDefaultCompressionState(TIFF *tif) |
143 | 0 | { |
144 | 0 | tif->tif_fixuptags = _TIFFNoFixupTags; |
145 | 0 | tif->tif_decodestatus = TRUE; |
146 | 0 | tif->tif_setupdecode = _TIFFtrue; |
147 | 0 | tif->tif_predecode = _TIFFNoPreCode; |
148 | 0 | tif->tif_decoderow = _TIFFNoRowDecode; |
149 | 0 | tif->tif_decodestrip = _TIFFNoStripDecode; |
150 | 0 | tif->tif_decodetile = _TIFFNoTileDecode; |
151 | 0 | tif->tif_encodestatus = TRUE; |
152 | 0 | tif->tif_setupencode = _TIFFtrue; |
153 | 0 | tif->tif_preencode = _TIFFNoPreCode; |
154 | 0 | tif->tif_postencode = _TIFFtrue; |
155 | 0 | tif->tif_encoderow = _TIFFNoRowEncode; |
156 | 0 | tif->tif_encodestrip = _TIFFNoStripEncode; |
157 | 0 | tif->tif_encodetile = _TIFFNoTileEncode; |
158 | 0 | tif->tif_close = _TIFFvoid; |
159 | 0 | tif->tif_seek = _TIFFNoSeek; |
160 | 0 | tif->tif_cleanup = _TIFFvoid; |
161 | 0 | tif->tif_defstripsize = _TIFFDefaultStripSize; |
162 | 0 | tif->tif_deftilesize = _TIFFDefaultTileSize; |
163 | 0 | tif->tif_flags &= ~(TIFF_NOBITREV | TIFF_NOREADRAW); |
164 | 0 | } |
165 | | |
166 | | int TIFFSetCompressionScheme(TIFF *tif, int scheme) |
167 | 0 | { |
168 | 0 | const TIFFCodec *c = TIFFFindCODEC((uint16_t)scheme); |
169 | |
|
170 | 0 | _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 | 0 | return (c ? (*c->init)(tif, scheme) : 1); |
178 | 0 | } |
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 | | const TIFFCodec *TIFFFindCODEC(uint16_t scheme) |
193 | 0 | { |
194 | 0 | const TIFFCodec *c; |
195 | 0 | codec_t *cd; |
196 | |
|
197 | 0 | for (cd = registeredCODECS; cd; cd = cd->next) |
198 | 0 | if (cd->info->scheme == scheme) |
199 | 0 | return ((const TIFFCodec *)cd->info); |
200 | 0 | for (c = _TIFFBuiltinCODECS; c->name; c++) |
201 | 0 | if (c->scheme == scheme) |
202 | 0 | return (c); |
203 | 0 | return ((const TIFFCodec *)0); |
204 | 0 | } |
205 | | |
206 | | TIFFCodec *TIFFRegisterCODEC(uint16_t scheme, const char *name, |
207 | | TIFFInitMethod init) |
208 | 0 | { |
209 | 0 | codec_t *cd = (codec_t *)_TIFFmallocExt( |
210 | 0 | NULL, |
211 | 0 | (tmsize_t)(sizeof(codec_t) + sizeof(TIFFCodec) + strlen(name) + 1)); |
212 | |
|
213 | 0 | if (cd != NULL) |
214 | 0 | { |
215 | 0 | cd->info = (TIFFCodec *)((uint8_t *)cd + sizeof(codec_t)); |
216 | 0 | cd->info->name = (char *)((uint8_t *)cd->info + sizeof(TIFFCodec)); |
217 | 0 | strcpy(cd->info->name, name); |
218 | 0 | cd->info->scheme = scheme; |
219 | 0 | cd->info->init = init; |
220 | 0 | cd->next = registeredCODECS; |
221 | 0 | registeredCODECS = cd; |
222 | 0 | } |
223 | 0 | else |
224 | 0 | { |
225 | 0 | TIFFErrorExt(0, "TIFFRegisterCODEC", |
226 | 0 | "No space to register compression scheme %s", name); |
227 | 0 | return NULL; |
228 | 0 | } |
229 | 0 | return (cd->info); |
230 | 0 | } |
231 | | |
232 | | void TIFFUnRegisterCODEC(TIFFCodec *c) |
233 | 0 | { |
234 | 0 | codec_t *cd; |
235 | 0 | codec_t **pcd; |
236 | |
|
237 | 0 | for (pcd = ®isteredCODECS; (cd = *pcd) != NULL; pcd = &cd->next) |
238 | 0 | if (cd->info == c) |
239 | 0 | { |
240 | 0 | *pcd = cd->next; |
241 | 0 | _TIFFfreeExt(NULL, cd); |
242 | 0 | return; |
243 | 0 | } |
244 | 0 | TIFFErrorExt(0, "TIFFUnRegisterCODEC", |
245 | 0 | "Cannot remove compression scheme %s; not registered", |
246 | 0 | c->name); |
247 | 0 | } |
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 | | TIFFCodec *TIFFGetConfiguredCODECs() |
262 | 0 | { |
263 | 0 | int i = 1; |
264 | 0 | codec_t *cd; |
265 | 0 | const TIFFCodec *c; |
266 | 0 | TIFFCodec *codecs = NULL; |
267 | 0 | TIFFCodec *new_codecs; |
268 | |
|
269 | 0 | for (cd = registeredCODECS; cd; cd = cd->next) |
270 | 0 | { |
271 | 0 | new_codecs = |
272 | 0 | (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec)); |
273 | 0 | if (!new_codecs) |
274 | 0 | { |
275 | 0 | _TIFFfreeExt(NULL, codecs); |
276 | 0 | return NULL; |
277 | 0 | } |
278 | 0 | codecs = new_codecs; |
279 | 0 | _TIFFmemcpy(codecs + i - 1, cd->info, sizeof(TIFFCodec)); |
280 | 0 | i++; |
281 | 0 | } |
282 | 0 | for (c = _TIFFBuiltinCODECS; c->name; c++) |
283 | 0 | { |
284 | 0 | if (TIFFIsCODECConfigured(c->scheme)) |
285 | 0 | { |
286 | 0 | new_codecs = (TIFFCodec *)_TIFFreallocExt(NULL, codecs, |
287 | 0 | i * sizeof(TIFFCodec)); |
288 | 0 | if (!new_codecs) |
289 | 0 | { |
290 | 0 | _TIFFfreeExt(NULL, codecs); |
291 | 0 | return NULL; |
292 | 0 | } |
293 | 0 | codecs = new_codecs; |
294 | 0 | _TIFFmemcpy(codecs + i - 1, (const void *)c, sizeof(TIFFCodec)); |
295 | 0 | i++; |
296 | 0 | } |
297 | 0 | } |
298 | | |
299 | 0 | new_codecs = |
300 | 0 | (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec)); |
301 | 0 | if (!new_codecs) |
302 | 0 | { |
303 | 0 | _TIFFfreeExt(NULL, codecs); |
304 | 0 | return NULL; |
305 | 0 | } |
306 | 0 | codecs = new_codecs; |
307 | 0 | _TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec)); |
308 | |
|
309 | 0 | return codecs; |
310 | 0 | } |