1 /* $Id: tif_compress.c,v 1.22 2010-03-10 18:56:48 bfriesen 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 TIFFNoEncode(TIFF* tif, const char* method) 36 { 37 const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); 38 39 if (c) { 40 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 41 "%s %s encoding is not implemented", 42 c->name, method); 43 } else { 44 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 45 "Compression scheme %u %s encoding is not implemented", 46 tif->tif_dir.td_compression, method); 47 } 48 return (-1); 49 } 50 51 int 52 _TIFFNoRowEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) 53 { 54 (void) pp; (void) cc; (void) s; 55 return (TIFFNoEncode(tif, "scanline")); 56 } 57 58 int 59 _TIFFNoStripEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) 60 { 61 (void) pp; (void) cc; (void) s; 62 return (TIFFNoEncode(tif, "strip")); 63 } 64 65 int 66 _TIFFNoTileEncode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) 67 { 68 (void) pp; (void) cc; (void) s; 69 return (TIFFNoEncode(tif, "tile")); 70 } 71 72 static int 73 TIFFNoDecode(TIFF* tif, const char* method) 74 { 75 const TIFFCodec* c = TIFFFindCODEC(tif->tif_dir.td_compression); 76 77 if (c) 78 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 79 "%s %s decoding is not implemented", 80 c->name, method); 81 else 82 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 83 "Compression scheme %u %s decoding is not implemented", 84 tif->tif_dir.td_compression, method); 85 return (-1); 86 } 87 88 int 89 _TIFFNoFixupTags(TIFF* tif) 90 { 91 (void) tif; 92 return (1); 93 } 94 95 int 96 _TIFFNoRowDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) 97 { 98 (void) pp; (void) cc; (void) s; 99 return (TIFFNoDecode(tif, "scanline")); 100 } 101 102 int 103 _TIFFNoStripDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) 104 { 105 (void) pp; (void) cc; (void) s; 106 return (TIFFNoDecode(tif, "strip")); 107 } 108 109 int 110 _TIFFNoTileDecode(TIFF* tif, uint8* pp, tmsize_t cc, uint16 s) 111 { 112 (void) pp; (void) cc; (void) s; 113 return (TIFFNoDecode(tif, "tile")); 114 } 115 116 int 117 _TIFFNoSeek(TIFF* tif, uint32 off) 118 { 119 (void) off; 120 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 121 "Compression algorithm does not support random access"); 122 return (0); 123 } 124 125 int 126 _TIFFNoPreCode(TIFF* tif, uint16 s) 127 { 128 (void) tif; (void) s; 129 return (1); 130 } 131 132 static int _TIFFtrue(TIFF* tif) { (void) tif; return (1); } 133 static void _TIFFvoid(TIFF* tif) { (void) tif; } 134 135 void 136 _TIFFSetDefaultCompressionState(TIFF* tif) 137 { 138 tif->tif_fixuptags = _TIFFNoFixupTags; 139 tif->tif_decodestatus = TRUE; 140 tif->tif_setupdecode = _TIFFtrue; 141 tif->tif_predecode = _TIFFNoPreCode; 142 tif->tif_decoderow = _TIFFNoRowDecode; 143 tif->tif_decodestrip = _TIFFNoStripDecode; 144 tif->tif_decodetile = _TIFFNoTileDecode; 145 tif->tif_encodestatus = TRUE; 146 tif->tif_setupencode = _TIFFtrue; 147 tif->tif_preencode = _TIFFNoPreCode; 148 tif->tif_postencode = _TIFFtrue; 149 tif->tif_encoderow = _TIFFNoRowEncode; 150 tif->tif_encodestrip = _TIFFNoStripEncode; 151 tif->tif_encodetile = _TIFFNoTileEncode; 152 tif->tif_close = _TIFFvoid; 153 tif->tif_seek = _TIFFNoSeek; 154 tif->tif_cleanup = _TIFFvoid; 155 tif->tif_defstripsize = _TIFFDefaultStripSize; 156 tif->tif_deftilesize = _TIFFDefaultTileSize; 157 tif->tif_flags &= ~(TIFF_NOBITREV|TIFF_NOREADRAW); 158 } 159 160 int 161 TIFFSetCompressionScheme(TIFF* tif, int scheme) 162 { 163 const TIFFCodec *c = TIFFFindCODEC((uint16) scheme); 164 165 _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 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 TIFFFindCODEC(uint16 scheme) 188 { 189 const TIFFCodec* c; 190 codec_t* cd; 191 192 for (cd = registeredCODECS; cd; cd = cd->next) 193 if (cd->info->scheme == scheme) 194 return ((const TIFFCodec*) cd->info); 195 for (c = _TIFFBuiltinCODECS; c->name; c++) 196 if (c->scheme == scheme) 197 return (c); 198 return ((const TIFFCodec*) 0); 199 } 200 201 TIFFCodec* 202 TIFFRegisterCODEC(uint16 scheme, const char* name, TIFFInitMethod init) 203 { 204 codec_t* cd = (codec_t*) 205 _TIFFmalloc((tmsize_t)(sizeof (codec_t) + sizeof (TIFFCodec) + strlen(name)+1)); 206 207 if (cd != NULL) { 208 cd->info = (TIFFCodec*) ((uint8*) cd + sizeof (codec_t)); 209 cd->info->name = (char*) 210 ((uint8*) cd->info + sizeof (TIFFCodec)); 211 strcpy(cd->info->name, name); 212 cd->info->scheme = scheme; 213 cd->info->init = init; 214 cd->next = registeredCODECS; 215 registeredCODECS = cd; 216 } else { 217 TIFFErrorExt(0, "TIFFRegisterCODEC", 218 "No space to register compression scheme %s", name); 219 return NULL; 220 } 221 return (cd->info); 222 } 223 224 void 225 TIFFUnRegisterCODEC(TIFFCodec* c) 226 { 227 codec_t* cd; 228 codec_t** pcd; 229 230 for (pcd = ®isteredCODECS; (cd = *pcd); pcd = &cd->next) 231 if (cd->info == c) { 232 *pcd = cd->next; 233 _TIFFfree(cd); 234 return; 235 } 236 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 TIFFGetConfiguredCODECs() 254 { 255 int i = 1; 256 codec_t *cd; 257 const TIFFCodec* c; 258 TIFFCodec* codecs = NULL; 259 TIFFCodec* new_codecs; 260 261 for (cd = registeredCODECS; cd; cd = cd->next) { 262 new_codecs = (TIFFCodec *) 263 _TIFFrealloc(codecs, i * sizeof(TIFFCodec)); 264 if (!new_codecs) { 265 _TIFFfree (codecs); 266 return NULL; 267 } 268 codecs = new_codecs; 269 _TIFFmemcpy(codecs + i - 1, cd, sizeof(TIFFCodec)); 270 i++; 271 } 272 for (c = _TIFFBuiltinCODECS; c->name; c++) { 273 if (TIFFIsCODECConfigured(c->scheme)) { 274 new_codecs = (TIFFCodec *) 275 _TIFFrealloc(codecs, i * sizeof(TIFFCodec)); 276 if (!new_codecs) { 277 _TIFFfree (codecs); 278 return NULL; 279 } 280 codecs = new_codecs; 281 _TIFFmemcpy(codecs + i - 1, (const void*)c, sizeof(TIFFCodec)); 282 i++; 283 } 284 } 285 286 new_codecs = (TIFFCodec *) _TIFFrealloc(codecs, i * sizeof(TIFFCodec)); 287 if (!new_codecs) { 288 _TIFFfree (codecs); 289 return NULL; 290 } 291 codecs = new_codecs; 292 _TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec)); 293 294 return codecs; 295 } 296 297 /* vim: set ts=8 sts=8 sw=8 noet: */ 298 /* 299 * Local Variables: 300 * mode: c 301 * c-basic-offset: 8 302 * fill-column: 78 303 * End: 304 */ 305