tif_packbits.c 9.5 KB

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