tif_next.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /* $Id: tif_next.c,v 1.19 2016-09-04 21:32:56 erouault Exp $ */
  2. /*
  3. * Copyright (c) 1988-1997 Sam Leffler
  4. * Copyright (c) 1991-1997 Silicon Graphics, Inc.
  5. *
  6. * Permission to use, copy, modify, distribute, and sell this software and
  7. * its documentation for any purpose is hereby granted without fee, provided
  8. * that (i) the above copyright notices and this permission notice appear in
  9. * all copies of the software and related documentation, and (ii) the names of
  10. * Sam Leffler and Silicon Graphics may not be used in any advertising or
  11. * publicity relating to the software without the specific, prior written
  12. * permission of Sam Leffler and Silicon Graphics.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
  15. * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  16. * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  17. *
  18. * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19. * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20. * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21. * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  22. * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  23. * OF THIS SOFTWARE.
  24. */
  25. #include "tiffiop.h"
  26. #ifdef NEXT_SUPPORT
  27. /*
  28. * TIFF Library.
  29. *
  30. * NeXT 2-bit Grey Scale Compression Algorithm Support
  31. */
  32. #define SETPIXEL(op, v) { \
  33. switch (npixels++ & 3) { \
  34. case 0: op[0] = (unsigned char) ((v) << 6); break; \
  35. case 1: op[0] |= (v) << 4; break; \
  36. case 2: op[0] |= (v) << 2; break; \
  37. case 3: *op++ |= (v); op_offset++; break; \
  38. } \
  39. }
  40. #define LITERALROW 0x00
  41. #define LITERALSPAN 0x40
  42. #define WHITE ((1<<2)-1)
  43. static int
  44. NeXTDecode(TIFF* tif, uint8* buf, tmsize_t occ, uint16 s)
  45. {
  46. static const char module[] = "NeXTDecode";
  47. unsigned char *bp, *op;
  48. tmsize_t cc;
  49. uint8* row;
  50. tmsize_t scanline, n;
  51. (void) s;
  52. /*
  53. * Each scanline is assumed to start off as all
  54. * white (we assume a PhotometricInterpretation
  55. * of ``min-is-black'').
  56. */
  57. for (op = (unsigned char*) buf, cc = occ; cc-- > 0;)
  58. *op++ = 0xff;
  59. bp = (unsigned char *)tif->tif_rawcp;
  60. cc = tif->tif_rawcc;
  61. scanline = tif->tif_scanlinesize;
  62. if (occ % scanline)
  63. {
  64. TIFFErrorExt(tif->tif_clientdata, module, "Fractional scanlines cannot be read");
  65. return (0);
  66. }
  67. for (row = buf; cc > 0 && occ > 0; occ -= scanline, row += scanline) {
  68. n = *bp++;
  69. cc--;
  70. switch (n) {
  71. case LITERALROW:
  72. /*
  73. * The entire scanline is given as literal values.
  74. */
  75. if (cc < scanline)
  76. goto bad;
  77. _TIFFmemcpy(row, bp, scanline);
  78. bp += scanline;
  79. cc -= scanline;
  80. break;
  81. case LITERALSPAN: {
  82. tmsize_t off;
  83. /*
  84. * The scanline has a literal span that begins at some
  85. * offset.
  86. */
  87. if( cc < 4 )
  88. goto bad;
  89. off = (bp[0] * 256) + bp[1];
  90. n = (bp[2] * 256) + bp[3];
  91. if (cc < 4+n || off+n > scanline)
  92. goto bad;
  93. _TIFFmemcpy(row+off, bp+4, n);
  94. bp += 4+n;
  95. cc -= 4+n;
  96. break;
  97. }
  98. default: {
  99. uint32 npixels = 0, grey;
  100. tmsize_t op_offset = 0;
  101. uint32 imagewidth = tif->tif_dir.td_imagewidth;
  102. if( isTiled(tif) )
  103. imagewidth = tif->tif_dir.td_tilewidth;
  104. /*
  105. * The scanline is composed of a sequence of constant
  106. * color ``runs''. We shift into ``run mode'' and
  107. * interpret bytes as codes of the form
  108. * <color><npixels> until we've filled the scanline.
  109. */
  110. op = row;
  111. for (;;) {
  112. grey = (uint32)((n>>6) & 0x3);
  113. n &= 0x3f;
  114. /*
  115. * Ensure the run does not exceed the scanline
  116. * bounds, potentially resulting in a security
  117. * issue.
  118. */
  119. while (n-- > 0 && npixels < imagewidth && op_offset < scanline)
  120. SETPIXEL(op, grey);
  121. if (npixels >= imagewidth)
  122. break;
  123. if (op_offset >= scanline ) {
  124. TIFFErrorExt(tif->tif_clientdata, module, "Invalid data for scanline %ld",
  125. (long) tif->tif_row);
  126. return (0);
  127. }
  128. if (cc == 0)
  129. goto bad;
  130. n = *bp++;
  131. cc--;
  132. }
  133. break;
  134. }
  135. }
  136. }
  137. tif->tif_rawcp = (uint8*) bp;
  138. tif->tif_rawcc = cc;
  139. return (1);
  140. bad:
  141. TIFFErrorExt(tif->tif_clientdata, module, "Not enough data for scanline %ld",
  142. (long) tif->tif_row);
  143. return (0);
  144. }
  145. static int
  146. NeXTPreDecode(TIFF* tif, uint16 s)
  147. {
  148. static const char module[] = "NeXTPreDecode";
  149. TIFFDirectory *td = &tif->tif_dir;
  150. (void)s;
  151. if( td->td_bitspersample != 2 )
  152. {
  153. TIFFErrorExt(tif->tif_clientdata, module, "Unsupported BitsPerSample = %d",
  154. td->td_bitspersample);
  155. return (0);
  156. }
  157. return (1);
  158. }
  159. int
  160. TIFFInitNeXT(TIFF* tif, int scheme)
  161. {
  162. (void) scheme;
  163. tif->tif_predecode = NeXTPreDecode;
  164. tif->tif_decoderow = NeXTDecode;
  165. tif->tif_decodestrip = NeXTDecode;
  166. tif->tif_decodetile = NeXTDecode;
  167. return (1);
  168. }
  169. #endif /* NEXT_SUPPORT */
  170. /* vim: set ts=8 sts=8 sw=8 noet: */
  171. /*
  172. * Local Variables:
  173. * mode: c
  174. * c-basic-offset: 8
  175. * fill-column: 78
  176. * End:
  177. */