tif_next.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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 NEXT_SUPPORT
  26. /*
  27. * TIFF Library.
  28. *
  29. * NeXT 2-bit Grey Scale Compression Algorithm Support
  30. */
  31. #define SETPIXEL(op, v) \
  32. { \
  33. switch (npixels++ & 3) \
  34. { \
  35. case 0: \
  36. op[0] = (unsigned char)((v) << 6); \
  37. break; \
  38. case 1: \
  39. op[0] |= (v) << 4; \
  40. break; \
  41. case 2: \
  42. op[0] |= (v) << 2; \
  43. break; \
  44. case 3: \
  45. *op++ |= (v); \
  46. op_offset++; \
  47. break; \
  48. } \
  49. }
  50. #define LITERALROW 0x00
  51. #define LITERALSPAN 0x40
  52. #define WHITE ((1 << 2) - 1)
  53. static int NeXTDecode(TIFF *tif, uint8_t *buf, tmsize_t occ, uint16_t s)
  54. {
  55. static const char module[] = "NeXTDecode";
  56. unsigned char *bp, *op;
  57. tmsize_t cc;
  58. uint8_t *row;
  59. tmsize_t scanline, n;
  60. (void)s;
  61. /*
  62. * Each scanline is assumed to start off as all
  63. * white (we assume a PhotometricInterpretation
  64. * of ``min-is-black'').
  65. */
  66. for (op = (unsigned char *)buf, cc = occ; cc-- > 0;)
  67. *op++ = 0xff;
  68. bp = (unsigned char *)tif->tif_rawcp;
  69. cc = tif->tif_rawcc;
  70. scanline = tif->tif_scanlinesize;
  71. if (occ % scanline)
  72. {
  73. TIFFErrorExtR(tif, module, "Fractional scanlines cannot be read");
  74. return (0);
  75. }
  76. for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline)
  77. {
  78. n = *bp++;
  79. cc--;
  80. switch (n)
  81. {
  82. case LITERALROW:
  83. /*
  84. * The entire scanline is given as literal values.
  85. */
  86. if (cc < scanline)
  87. goto bad;
  88. _TIFFmemcpy(row, bp, scanline);
  89. bp += scanline;
  90. cc -= scanline;
  91. break;
  92. case LITERALSPAN:
  93. {
  94. tmsize_t off;
  95. /*
  96. * The scanline has a literal span that begins at some
  97. * offset.
  98. */
  99. if (cc < 4)
  100. goto bad;
  101. off = (bp[0] * 256) + bp[1];
  102. n = (bp[2] * 256) + bp[3];
  103. if (cc < 4 + n || off + n > scanline)
  104. goto bad;
  105. _TIFFmemcpy(row + off, bp + 4, n);
  106. bp += 4 + n;
  107. cc -= 4 + n;
  108. break;
  109. }
  110. default:
  111. {
  112. uint32_t npixels = 0, grey;
  113. tmsize_t op_offset = 0;
  114. uint32_t imagewidth = tif->tif_dir.td_imagewidth;
  115. if (isTiled(tif))
  116. imagewidth = tif->tif_dir.td_tilewidth;
  117. /*
  118. * The scanline is composed of a sequence of constant
  119. * color ``runs''. We shift into ``run mode'' and
  120. * interpret bytes as codes of the form
  121. * <color><npixels> until we've filled the scanline.
  122. */
  123. op = row;
  124. for (;;)
  125. {
  126. grey = (uint32_t)((n >> 6) & 0x3);
  127. n &= 0x3f;
  128. /*
  129. * Ensure the run does not exceed the scanline
  130. * bounds, potentially resulting in a security
  131. * issue.
  132. */
  133. while (n-- > 0 && npixels < imagewidth &&
  134. op_offset < scanline)
  135. SETPIXEL(op, grey);
  136. if (npixels >= imagewidth)
  137. break;
  138. if (op_offset >= scanline)
  139. {
  140. TIFFErrorExtR(tif, module,
  141. "Invalid data for scanline %" PRIu32,
  142. tif->tif_row);
  143. return (0);
  144. }
  145. if (cc == 0)
  146. goto bad;
  147. n = *bp++;
  148. cc--;
  149. }
  150. break;
  151. }
  152. }
  153. }
  154. tif->tif_rawcp = (uint8_t *)bp;
  155. tif->tif_rawcc = cc;
  156. return (1);
  157. bad:
  158. TIFFErrorExtR(tif, module, "Not enough data for scanline %" PRIu32,
  159. tif->tif_row);
  160. return (0);
  161. }
  162. static int NeXTPreDecode(TIFF *tif, uint16_t s)
  163. {
  164. static const char module[] = "NeXTPreDecode";
  165. TIFFDirectory *td = &tif->tif_dir;
  166. (void)s;
  167. if (td->td_bitspersample != 2)
  168. {
  169. TIFFErrorExtR(tif, module, "Unsupported BitsPerSample = %" PRIu16,
  170. td->td_bitspersample);
  171. return (0);
  172. }
  173. return (1);
  174. }
  175. int TIFFInitNeXT(TIFF *tif, int scheme)
  176. {
  177. (void)scheme;
  178. tif->tif_predecode = NeXTPreDecode;
  179. tif->tif_decoderow = NeXTDecode;
  180. tif->tif_decodestrip = NeXTDecode;
  181. tif->tif_decodetile = NeXTDecode;
  182. return (1);
  183. }
  184. #endif /* NEXT_SUPPORT */