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 31 #include <precomp.h> 32 33 static int 34 TIFFNoEncode(TIFF* tif, const char* method) 35 { 36 const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); 37 38 if (c) { 39 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 40 "%s %s encoding is not implemented", 41 c->name, method); 42 } else { 43 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 44 "Compression scheme %u %s encoding is not implemented", 45 tif->tif_dir.td_compression, method); 46 } 47 return (-1); 48 } 49 50 int 51 _TIFFNoRowEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) 52 { 53 (void) pp; (void) cc; (void) s; 54 return (TIFFNoEncode(tif, "scanline")); 55 } 56 57 int 58 _TIFFNoStripEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) 59 { 60 (void) pp; (void) cc; (void) s; 61 return (TIFFNoEncode(tif, "strip")); 62 } 63 64 int 65 _TIFFNoTileEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) 66 { 67 (void) pp; (void) cc; (void) s; 68 return (TIFFNoEncode(tif, "tile")); 69 } 70 71 static int 72 TIFFNoDecode(TIFF* tif, const char* method) 73 { 74 const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); 75 76 if (c) 77 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 78 "%s %s decoding is not implemented", 79 c->name, method); 80 else 81 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 82 "Compression scheme %u %s decoding is not implemented", 83 tif->tif_dir.td_compression, method); 84 return (0); 85 } 86 87 static int 88 _TIFFNoFixupTags(TIFF* tif) 89 { 90 (void) tif; 91 return (1); 92 } 93 94 int 95 _TIFFNoRowDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) 96 { 97 (void) pp; (void) cc; (void) s; 98 return (TIFFNoDecode(tif, "scanline")); 99 } 100 101 int 102 _TIFFNoStripDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) 103 { 104 (void) pp; (void) cc; (void) s; 105 return (TIFFNoDecode(tif, "strip")); 106 } 107 108 int 109 _TIFFNoTileDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) 110 { 111 (void) pp; (void) cc; (void) s; 112 return (TIFFNoDecode(tif, "tile")); 113 } 114 115 int 116 _TIFFNoSeek(TIFF* tif, uint32 off) 117 { 118 (void) off; 119 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 120 "Compression algorithm does not support random access"); 121 return (0); 122 } 123 124 int 125 _TIFFNoPreCode(TIFF* tif, uint16 s) 126 { 127 (void) tif; (void) s; 128 return (1); 129 } 130 131 static int _TIFFtrue(TIFF* tif) { (void) tif; return (1); } 132 static void _TIFFvoid(TIFF* tif) { (void) tif; } 133 134 void 135 _TIFFSetDefaultCompressionState(TIFF* tif) 136 { 137 tif->tif_fixuptags = _TIFFNoFixupTags; 138 tif->tif_decodestatus = TRUE; 139 tif->tif_setupdecode = _TIFFtrue; 140 tif->tif_predecode = _TIFFNoPreCode; 141 tif->tif_decoderow = _TIFFNoRowDecode; 142 tif->tif_decodestrip = _TIFFNoStripDecode; 143 tif->tif_decodetile = _TIFFNoTileDecode; 144 tif->tif_encodestatus = TRUE; 145 tif->tif_setupencode = _TIFFtrue; 146 tif->tif_preencode = _TIFFNoPreCode; 147 tif->tif_postencode = _TIFFtrue; 148 tif->tif_encoderow = _TIFFNoRowEncode; 149 tif->tif_encodestrip = _TIFFNoStripEncode; 150 tif->tif_encodetile = _TIFFNoTileEncode; 151 tif->tif_close = _TIFFvoid; 152 tif->tif_seek = _TIFFNoSeek; 153 tif->tif_cleanup = _TIFFvoid; 154 tif->tif_defstripsize = _TIFFDefaultStripSize; 155 tif->tif_deftilesize = _TIFFDefaultTileSize; 156 tif->tif_flags &= ~(TIFF_NOBITREV|TIFF_NOREADRAW); 157 } 158 159 int 160 TIFFSetCompressionScheme(TIFF* tif, int scheme) 161 { 162 const TIFFCodec *c = TIFFFindCODEC((uint16) scheme); 163 164 _TIFFSetDefaultCompressionState(tif); 165 /* 166 * Don't treat an unknown compression scheme as an error. 167 * This permits applications to open files with data that 168 * the library does not have builtin support for, but which 169 * may still be meaningful. 170 */ 171 return (c ? (*c->init)(tif, scheme) : 1); 172 } 173 174 /* 175 * Other compression schemes may be registered. Registered 176 * schemes can also override the builtin versions provided 177 * by this library. 178 */ 179 typedef struct _codec { 180 struct _codec* next; 181 TIFFCodec* info; 182 } codec_t; 183 static codec_t* registeredCODECS = NULL; 184 185 const TIFFCodec* 186 TIFFFindCODEC(uint16 scheme) 187 { 188 const TIFFCodec* c; 189 codec_t* cd; 190 191 for (cd = registeredCODECS; cd; cd = cd->next) 192 if (cd->info->scheme == scheme) 193 return ((const TIFFCodec*) cd->info); 194 for (c = _TIFFBuiltinCODECS; c->name; c++) 195 if (c->scheme == scheme) 196 return (c); 197 return ((const TIFFCodec*) 0); 198 } 199 200 TIFFCodec* 201 TIFFRegisterCODEC(uint16 scheme, const char* name, TIFFInitMethod init) 202 { 203 codec_t* cd = (codec_t*) 204 _TIFFmalloc((tmsize_t)(sizeof (codec_t) + sizeof (TIFFCodec) + strlen(name)+1)); 205 206 if (cd != NULL) { 207 cd->info = (TIFFCodec*) ((uint8*) cd + sizeof (codec_t)); 208 cd->info->name = (char*) 209 ((uint8*) cd->info + sizeof (TIFFCodec)); 210 strcpy(cd->info->name, name); 211 cd->info->scheme = scheme; 212 cd->info->init = init; 213 cd->next = registeredCODECS; 214 registeredCODECS = cd; 215 } else { 216 TIFFErrorExt(0, "TIFFRegisterCODEC", 217 "No space to register compression scheme %s", name); 218 return NULL; 219 } 220 return (cd->info); 221 } 222 223 void 224 TIFFUnRegisterCODEC(TIFFCodec* c) 225 { 226 codec_t* cd; 227 codec_t** pcd; 228 229 for (pcd = ®isteredCODECS; (cd = *pcd) != NULL; pcd = &cd->next) 230 if (cd->info == c) { 231 *pcd = cd->next; 232 _TIFFfree(cd); 233 return; 234 } 235 TIFFErrorExt(0, "TIFFUnRegisterCODEC", 236 "Cannot remove compression scheme %s; not registered", c->name); 237 } 238 239 /************************************************************************/ 240 /* TIFFGetConfisuredCODECs() */ 241 /************************************************************************/ 242 243 /** 244 * Get list of configured codecs, both built-in and registered by user. 245 * Caller is responsible to free this structure. 246 * 247 * @return returns array of TIFFCodec records (the last record should be NULL) 248 * or NULL if function failed. 249 */ 250 251 TIFFCodec* 252 TIFFGetConfiguredCODECs() 253 { 254 int i = 1; 255 codec_t *cd; 256 const TIFFCodec* c; 257 TIFFCodec* codecs = NULL; 258 TIFFCodec* new_codecs; 259 260 for (cd = registeredCODECS; cd; cd = cd->next) { 261 new_codecs = (TIFFCodec *) 262 _TIFFrealloc(codecs, i * sizeof(TIFFCodec)); 263 if (!new_codecs) { 264 _TIFFfree (codecs); 265 return NULL; 266 } 267 codecs = new_codecs; 268 _TIFFmemcpy(codecs + i - 1, cd, sizeof(TIFFCodec)); 269 i++; 270 } 271 for (c = _TIFFBuiltinCODECS; c->name; c++) { 272 if (TIFFIsCODECConfigured(c->scheme)) { 273 new_codecs = (TIFFCodec *) 274 _TIFFrealloc(codecs, i * sizeof(TIFFCodec)); 275 if (!new_codecs) { 276 _TIFFfree (codecs); 277 return NULL; 278 } 279 codecs = new_codecs; 280 _TIFFmemcpy(codecs + i - 1, (const void*)c, sizeof(TIFFCodec)); 281 i++; 282 } 283 } 284 285 new_codecs = (TIFFCodec *) _TIFFrealloc(codecs, i * sizeof(TIFFCodec)); 286 if (!new_codecs) { 287 _TIFFfree (codecs); 288 return NULL; 289 } 290 codecs = new_codecs; 291 _TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec)); 292 293 return codecs; 294 } 295 296 /* vim: set ts=8 sts=8 sw=8 noet: */ 297 /* 298 * Local Variables: 299 * mode: c 300 * c-basic-offset: 8 301 * fill-column: 78 302 * End: 303 */ 304