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