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