tif_packbits.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  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. #include "tiffiop.h"
  25. #ifdef PACKBITS_SUPPORT
  26. /*
  27. * TIFF Library.
  28. *
  29. * PackBits Compression Algorithm Support
  30. */
  31. #include <stdio.h>
  32. #ifndef PACKBITS_READ_ONLY
  33. static int PackBitsPreEncode(TIFF *tif, uint16_t s)
  34. {
  35. (void)s;
  36. tif->tif_data = (uint8_t *)_TIFFmallocExt(tif, sizeof(tmsize_t));
  37. if (tif->tif_data == NULL)
  38. return (0);
  39. /*
  40. * Calculate the scanline/tile-width size in bytes.
  41. */
  42. if (isTiled(tif))
  43. *(tmsize_t *)tif->tif_data = TIFFTileRowSize(tif);
  44. else
  45. *(tmsize_t *)tif->tif_data = TIFFScanlineSize(tif);
  46. return (1);
  47. }
  48. static int PackBitsPostEncode(TIFF *tif)
  49. {
  50. if (tif->tif_data)
  51. _TIFFfreeExt(tif, tif->tif_data);
  52. return (1);
  53. }
  54. /*
  55. * Encode a run of pixels.
  56. */
  57. static int PackBitsEncode(TIFF *tif, uint8_t *buf, tmsize_t cc, uint16_t s)
  58. {
  59. unsigned char *bp = (unsigned char *)buf;
  60. uint8_t *op;
  61. uint8_t *ep;
  62. uint8_t *lastliteral;
  63. long n, slop;
  64. int b;
  65. enum
  66. {
  67. BASE,
  68. LITERAL,
  69. RUN,
  70. LITERAL_RUN
  71. } state;
  72. (void)s;
  73. op = tif->tif_rawcp;
  74. ep = tif->tif_rawdata + tif->tif_rawdatasize;
  75. state = BASE;
  76. lastliteral = NULL;
  77. while (cc > 0)
  78. {
  79. /*
  80. * Find the longest string of identical bytes.
  81. */
  82. b = *bp++;
  83. cc--;
  84. n = 1;
  85. for (; cc > 0 && b == *bp; cc--, bp++)
  86. n++;
  87. again:
  88. if (op + 2 >= ep)
  89. { /* insure space for new data */
  90. /*
  91. * Be careful about writing the last
  92. * literal. Must write up to that point
  93. * and then copy the remainder to the
  94. * front of the buffer.
  95. */
  96. if (state == LITERAL || state == LITERAL_RUN)
  97. {
  98. slop = (long)(op - lastliteral);
  99. tif->tif_rawcc += (tmsize_t)(lastliteral - tif->tif_rawcp);
  100. if (!TIFFFlushData1(tif))
  101. return (0);
  102. op = tif->tif_rawcp;
  103. while (slop-- > 0)
  104. *op++ = *lastliteral++;
  105. lastliteral = tif->tif_rawcp;
  106. }
  107. else
  108. {
  109. tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
  110. if (!TIFFFlushData1(tif))
  111. return (0);
  112. op = tif->tif_rawcp;
  113. }
  114. }
  115. switch (state)
  116. {
  117. case BASE: /* initial state, set run/literal */
  118. if (n > 1)
  119. {
  120. state = RUN;
  121. if (n > 128)
  122. {
  123. *op++ = (uint8_t)-127;
  124. *op++ = (uint8_t)b;
  125. n -= 128;
  126. goto again;
  127. }
  128. *op++ = (uint8_t)(-(n - 1));
  129. *op++ = (uint8_t)b;
  130. }
  131. else
  132. {
  133. lastliteral = op;
  134. *op++ = 0;
  135. *op++ = (uint8_t)b;
  136. state = LITERAL;
  137. }
  138. break;
  139. case LITERAL: /* last object was literal string */
  140. if (n > 1)
  141. {
  142. state = LITERAL_RUN;
  143. if (n > 128)
  144. {
  145. *op++ = (uint8_t)-127;
  146. *op++ = (uint8_t)b;
  147. n -= 128;
  148. goto again;
  149. }
  150. *op++ = (uint8_t)(-(n - 1)); /* encode run */
  151. *op++ = (uint8_t)b;
  152. }
  153. else
  154. { /* extend literal */
  155. if (++(*lastliteral) == 127)
  156. state = BASE;
  157. *op++ = (uint8_t)b;
  158. }
  159. break;
  160. case RUN: /* last object was run */
  161. if (n > 1)
  162. {
  163. if (n > 128)
  164. {
  165. *op++ = (uint8_t)-127;
  166. *op++ = (uint8_t)b;
  167. n -= 128;
  168. goto again;
  169. }
  170. *op++ = (uint8_t)(-(n - 1));
  171. *op++ = (uint8_t)b;
  172. }
  173. else
  174. {
  175. lastliteral = op;
  176. *op++ = 0;
  177. *op++ = (uint8_t)b;
  178. state = LITERAL;
  179. }
  180. break;
  181. case LITERAL_RUN: /* literal followed by a run */
  182. /*
  183. * Check to see if previous run should
  184. * be converted to a literal, in which
  185. * case we convert literal-run-literal
  186. * to a single literal.
  187. */
  188. if (n == 1 && op[-2] == (uint8_t)-1 && *lastliteral < 126)
  189. {
  190. state = (((*lastliteral) += 2) == 127 ? BASE : LITERAL);
  191. op[-2] = op[-1]; /* replicate */
  192. }
  193. else
  194. state = RUN;
  195. goto again;
  196. }
  197. }
  198. tif->tif_rawcc += (tmsize_t)(op - tif->tif_rawcp);
  199. tif->tif_rawcp = op;
  200. return (1);
  201. }
  202. /*
  203. * Encode a rectangular chunk of pixels. We break it up
  204. * into row-sized pieces to insure that encoded runs do
  205. * not span rows. Otherwise, there can be problems with
  206. * the decoder if data is read, for example, by scanlines
  207. * when it was encoded by strips.
  208. */
  209. static int PackBitsEncodeChunk(TIFF *tif, uint8_t *bp, tmsize_t cc, uint16_t s)
  210. {
  211. tmsize_t rowsize = *(tmsize_t *)tif->tif_data;
  212. while (cc > 0)
  213. {
  214. tmsize_t chunk = rowsize;
  215. if (cc < chunk)
  216. chunk = cc;
  217. if (PackBitsEncode(tif, bp, chunk, s) < 0)
  218. return (-1);
  219. bp += chunk;
  220. cc -= chunk;
  221. }
  222. return (1);
  223. }
  224. #endif
  225. static int PackBitsDecode(TIFF *tif, uint8_t *op, tmsize_t occ, uint16_t s)
  226. {
  227. static const char module[] = "PackBitsDecode";
  228. int8_t *bp;
  229. tmsize_t cc;
  230. long n;
  231. int b;
  232. (void)s;
  233. bp = (int8_t *)tif->tif_rawcp;
  234. cc = tif->tif_rawcc;
  235. while (cc > 0 && occ > 0)
  236. {
  237. n = (long)*bp++;
  238. cc--;
  239. if (n < 0)
  240. { /* replicate next byte -n+1 times */
  241. if (n == -128) /* nop */
  242. continue;
  243. n = -n + 1;
  244. if (occ < (tmsize_t)n)
  245. {
  246. TIFFWarningExtR(tif, module,
  247. "Discarding %" TIFF_SSIZE_FORMAT
  248. " bytes to avoid buffer overrun",
  249. (tmsize_t)n - occ);
  250. n = (long)occ;
  251. }
  252. if (cc == 0)
  253. {
  254. TIFFWarningExtR(
  255. tif, module,
  256. "Terminating PackBitsDecode due to lack of data.");
  257. break;
  258. }
  259. occ -= n;
  260. b = *bp++;
  261. cc--;
  262. while (n-- > 0)
  263. *op++ = (uint8_t)b;
  264. }
  265. else
  266. { /* copy next n+1 bytes literally */
  267. if (occ < (tmsize_t)(n + 1))
  268. {
  269. TIFFWarningExtR(tif, module,
  270. "Discarding %" TIFF_SSIZE_FORMAT
  271. " bytes to avoid buffer overrun",
  272. (tmsize_t)n - occ + 1);
  273. n = (long)occ - 1;
  274. }
  275. if (cc < (tmsize_t)(n + 1))
  276. {
  277. TIFFWarningExtR(
  278. tif, module,
  279. "Terminating PackBitsDecode due to lack of data.");
  280. break;
  281. }
  282. _TIFFmemcpy(op, bp, ++n);
  283. op += n;
  284. occ -= n;
  285. bp += n;
  286. cc -= n;
  287. }
  288. }
  289. tif->tif_rawcp = (uint8_t *)bp;
  290. tif->tif_rawcc = cc;
  291. if (occ > 0)
  292. {
  293. memset(op, 0, (size_t)occ);
  294. TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32,
  295. tif->tif_row);
  296. return (0);
  297. }
  298. return (1);
  299. }
  300. int TIFFInitPackBits(TIFF *tif, int scheme)
  301. {
  302. (void)scheme;
  303. tif->tif_decoderow = PackBitsDecode;
  304. tif->tif_decodestrip = PackBitsDecode;
  305. tif->tif_decodetile = PackBitsDecode;
  306. #ifndef PACKBITS_READ_ONLY
  307. tif->tif_preencode = PackBitsPreEncode;
  308. tif->tif_postencode = PackBitsPostEncode;
  309. tif->tif_encoderow = PackBitsEncode;
  310. tif->tif_encodestrip = PackBitsEncodeChunk;
  311. tif->tif_encodetile = PackBitsEncodeChunk;
  312. #endif
  313. return (1);
  314. }
  315. #endif /* PACKBITS_SUPPORT */