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