tif_compress.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  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. * TIFF Library
  26. *
  27. * Compression Scheme Configuration Support.
  28. */
  29. #include "tiffiop.h"
  30. static int TIFFNoEncode(TIFF *tif, const char *method)
  31. {
  32. const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression);
  33. if (c)
  34. {
  35. TIFFErrorExtR(tif, tif->tif_name, "%s %s encoding is not implemented",
  36. c->name, method);
  37. }
  38. else
  39. {
  40. TIFFErrorExtR(tif, tif->tif_name,
  41. "Compression scheme %" PRIu16
  42. " %s encoding is not implemented",
  43. tif->tif_dir.td_compression, method);
  44. }
  45. return (-1);
  46. }
  47. int _TIFFNoRowEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
  48. {
  49. (void)pp;
  50. (void)cc;
  51. (void)s;
  52. return (TIFFNoEncode(tif, "scanline"));
  53. }
  54. int _TIFFNoStripEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
  55. {
  56. (void)pp;
  57. (void)cc;
  58. (void)s;
  59. return (TIFFNoEncode(tif, "strip"));
  60. }
  61. int _TIFFNoTileEncode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
  62. {
  63. (void)pp;
  64. (void)cc;
  65. (void)s;
  66. return (TIFFNoEncode(tif, "tile"));
  67. }
  68. static int TIFFNoDecode(TIFF *tif, const char *method)
  69. {
  70. const TIFFCodec *c = TIFFFindCODEC(tif->tif_dir.td_compression);
  71. if (c)
  72. TIFFErrorExtR(tif, tif->tif_name, "%s %s decoding is not implemented",
  73. c->name, method);
  74. else
  75. TIFFErrorExtR(tif, tif->tif_name,
  76. "Compression scheme %" PRIu16
  77. " %s decoding is not implemented",
  78. tif->tif_dir.td_compression, method);
  79. return (0);
  80. }
  81. static int _TIFFNoFixupTags(TIFF *tif)
  82. {
  83. (void)tif;
  84. return (1);
  85. }
  86. int _TIFFNoRowDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
  87. {
  88. (void)pp;
  89. (void)cc;
  90. (void)s;
  91. return (TIFFNoDecode(tif, "scanline"));
  92. }
  93. int _TIFFNoStripDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
  94. {
  95. (void)pp;
  96. (void)cc;
  97. (void)s;
  98. return (TIFFNoDecode(tif, "strip"));
  99. }
  100. int _TIFFNoTileDecode(TIFF *tif, uint8_t *pp, tmsize_t cc, uint16_t s)
  101. {
  102. (void)pp;
  103. (void)cc;
  104. (void)s;
  105. return (TIFFNoDecode(tif, "tile"));
  106. }
  107. int _TIFFNoSeek(TIFF *tif, uint32_t off)
  108. {
  109. (void)off;
  110. TIFFErrorExtR(tif, tif->tif_name,
  111. "Compression algorithm does not support random access");
  112. return (0);
  113. }
  114. int _TIFFNoPreCode(TIFF *tif, uint16_t s)
  115. {
  116. (void)tif;
  117. (void)s;
  118. return (1);
  119. }
  120. static int _TIFFtrue(TIFF *tif)
  121. {
  122. (void)tif;
  123. return (1);
  124. }
  125. static void _TIFFvoid(TIFF *tif) { (void)tif; }
  126. void _TIFFSetDefaultCompressionState(TIFF *tif)
  127. {
  128. tif->tif_fixuptags = _TIFFNoFixupTags;
  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 | TIFF_NOREADRAW);
  148. }
  149. int TIFFSetCompressionScheme(TIFF *tif, int scheme)
  150. {
  151. const TIFFCodec *c = TIFFFindCODEC((uint16_t)scheme);
  152. _TIFFSetDefaultCompressionState(tif);
  153. /*
  154. * Don't treat an unknown compression scheme as an error.
  155. * This permits applications to open files with data that
  156. * the library does not have builtin support for, but which
  157. * may still be meaningful.
  158. */
  159. return (c ? (*c->init)(tif, scheme) : 1);
  160. }
  161. /*
  162. * Other compression schemes may be registered. Registered
  163. * schemes can also override the builtin versions provided
  164. * by this library.
  165. */
  166. typedef struct _codec
  167. {
  168. struct _codec *next;
  169. TIFFCodec *info;
  170. } codec_t;
  171. static codec_t *registeredCODECS = NULL;
  172. const TIFFCodec *TIFFFindCODEC(uint16_t scheme)
  173. {
  174. const TIFFCodec *c;
  175. codec_t *cd;
  176. for (cd = registeredCODECS; cd; cd = cd->next)
  177. if (cd->info->scheme == scheme)
  178. return ((const TIFFCodec *)cd->info);
  179. for (c = _TIFFBuiltinCODECS; c->name; c++)
  180. if (c->scheme == scheme)
  181. return (c);
  182. return ((const TIFFCodec *)0);
  183. }
  184. TIFFCodec *TIFFRegisterCODEC(uint16_t scheme, const char *name,
  185. TIFFInitMethod init)
  186. {
  187. codec_t *cd = (codec_t *)_TIFFmallocExt(
  188. NULL,
  189. (tmsize_t)(sizeof(codec_t) + sizeof(TIFFCodec) + strlen(name) + 1));
  190. if (cd != NULL)
  191. {
  192. cd->info = (TIFFCodec *)((uint8_t *)cd + sizeof(codec_t));
  193. cd->info->name = (char *)((uint8_t *)cd->info + sizeof(TIFFCodec));
  194. strcpy(cd->info->name, name);
  195. cd->info->scheme = scheme;
  196. cd->info->init = init;
  197. cd->next = registeredCODECS;
  198. registeredCODECS = cd;
  199. }
  200. else
  201. {
  202. TIFFErrorExt(0, "TIFFRegisterCODEC",
  203. "No space to register compression scheme %s", name);
  204. return NULL;
  205. }
  206. return (cd->info);
  207. }
  208. void TIFFUnRegisterCODEC(TIFFCodec *c)
  209. {
  210. codec_t *cd;
  211. codec_t **pcd;
  212. for (pcd = &registeredCODECS; (cd = *pcd) != NULL; pcd = &cd->next)
  213. if (cd->info == c)
  214. {
  215. *pcd = cd->next;
  216. _TIFFfreeExt(NULL, cd);
  217. return;
  218. }
  219. TIFFErrorExt(0, "TIFFUnRegisterCODEC",
  220. "Cannot remove compression scheme %s; not registered",
  221. c->name);
  222. }
  223. /************************************************************************/
  224. /* TIFFGetConfisuredCODECs() */
  225. /************************************************************************/
  226. /**
  227. * Get list of configured codecs, both built-in and registered by user.
  228. * Caller is responsible to free this structure.
  229. *
  230. * @return returns array of TIFFCodec records (the last record should be NULL)
  231. * or NULL if function failed.
  232. */
  233. TIFFCodec *TIFFGetConfiguredCODECs()
  234. {
  235. int i = 1;
  236. codec_t *cd;
  237. const TIFFCodec *c;
  238. TIFFCodec *codecs = NULL;
  239. TIFFCodec *new_codecs;
  240. for (cd = registeredCODECS; cd; cd = cd->next)
  241. {
  242. new_codecs =
  243. (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec));
  244. if (!new_codecs)
  245. {
  246. _TIFFfreeExt(NULL, codecs);
  247. return NULL;
  248. }
  249. codecs = new_codecs;
  250. _TIFFmemcpy(codecs + i - 1, cd->info, sizeof(TIFFCodec));
  251. i++;
  252. }
  253. for (c = _TIFFBuiltinCODECS; c->name; c++)
  254. {
  255. if (TIFFIsCODECConfigured(c->scheme))
  256. {
  257. new_codecs = (TIFFCodec *)_TIFFreallocExt(NULL, codecs,
  258. i * sizeof(TIFFCodec));
  259. if (!new_codecs)
  260. {
  261. _TIFFfreeExt(NULL, codecs);
  262. return NULL;
  263. }
  264. codecs = new_codecs;
  265. _TIFFmemcpy(codecs + i - 1, (const void *)c, sizeof(TIFFCodec));
  266. i++;
  267. }
  268. }
  269. new_codecs =
  270. (TIFFCodec *)_TIFFreallocExt(NULL, codecs, i * sizeof(TIFFCodec));
  271. if (!new_codecs)
  272. {
  273. _TIFFfreeExt(NULL, codecs);
  274. return NULL;
  275. }
  276. codecs = new_codecs;
  277. _TIFFmemset(codecs + i - 1, 0, sizeof(TIFFCodec));
  278. return codecs;
  279. }