tif_thunder.c
上传用户:looem2003
上传日期:2014-07-20
资源大小:13733k
文件大小:5k
源码类别:

打印编程

开发平台:

Visual C++

  1. /* $Id: tif_thunder.c,v 1.5 2005/12/21 12:23:13 joris 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 THUNDER_SUPPORT
  27. /*
  28.  * TIFF Library.
  29.  *
  30.  * ThunderScan 4-bit Compression Algorithm Support
  31.  */
  32. /*
  33.  * ThunderScan uses an encoding scheme designed for
  34.  * 4-bit pixel values.  Data is encoded in bytes, with
  35.  * each byte split into a 2-bit code word and a 6-bit
  36.  * data value.  The encoding gives raw data, runs of
  37.  * pixels, or pixel values encoded as a delta from the
  38.  * previous pixel value.  For the latter, either 2-bit
  39.  * or 3-bit delta values are used, with the deltas packed
  40.  * into a single byte.
  41.  */
  42. #define THUNDER_DATA 0x3f /* mask for 6-bit data */
  43. #define THUNDER_CODE 0xc0 /* mask for 2-bit code word */
  44. /* code values */
  45. #define THUNDER_RUN 0x00 /* run of pixels w/ encoded count */
  46. #define THUNDER_2BITDELTAS 0x40 /* 3 pixels w/ encoded 2-bit deltas */
  47. #define     DELTA2_SKIP 2 /* skip code for 2-bit deltas */
  48. #define THUNDER_3BITDELTAS 0x80 /* 2 pixels w/ encoded 3-bit deltas */
  49. #define     DELTA3_SKIP 4 /* skip code for 3-bit deltas */
  50. #define THUNDER_RAW 0xc0 /* raw data encoded */
  51. static const int twobitdeltas[4] = { 0, 1, 0, -1 };
  52. static const int threebitdeltas[8] = { 0, 1, 2, 3, 0, -3, -2, -1 };
  53. #define SETPIXEL(op, v) { 
  54. lastpixel = (v) & 0xf; 
  55. if (npixels++ & 1) 
  56.     *op++ |= lastpixel; 
  57. else 
  58.     op[0] = (tidataval_t) (lastpixel << 4); 
  59. }
  60. static int
  61. ThunderDecode(TIFF* tif, tidata_t op, tsize_t maxpixels)
  62. {
  63. register unsigned char *bp;
  64. register tsize_t cc;
  65. unsigned int lastpixel;
  66. tsize_t npixels;
  67. bp = (unsigned char *)tif->tif_rawcp;
  68. cc = tif->tif_rawcc;
  69. lastpixel = 0;
  70. npixels = 0;
  71. while (cc > 0 && npixels < maxpixels) {
  72. int n, delta;
  73. n = *bp++, cc--;
  74. switch (n & THUNDER_CODE) {
  75. case THUNDER_RUN: /* pixel run */
  76. /*
  77.  * Replicate the last pixel n times,
  78.  * where n is the lower-order 6 bits.
  79.  */
  80. if (npixels & 1) {
  81. op[0] |= lastpixel;
  82. lastpixel = *op++; npixels++; n--;
  83. } else
  84. lastpixel |= lastpixel << 4;
  85. npixels += n;
  86. if (npixels < maxpixels) {
  87. for (; n > 0; n -= 2)
  88. *op++ = (tidataval_t) lastpixel;
  89. }
  90. if (n == -1)
  91. *--op &= 0xf0;
  92. lastpixel &= 0xf;
  93. break;
  94. case THUNDER_2BITDELTAS: /* 2-bit deltas */
  95. if ((delta = ((n >> 4) & 3)) != DELTA2_SKIP)
  96. SETPIXEL(op, lastpixel + twobitdeltas[delta]);
  97. if ((delta = ((n >> 2) & 3)) != DELTA2_SKIP)
  98. SETPIXEL(op, lastpixel + twobitdeltas[delta]);
  99. if ((delta = (n & 3)) != DELTA2_SKIP)
  100. SETPIXEL(op, lastpixel + twobitdeltas[delta]);
  101. break;
  102. case THUNDER_3BITDELTAS: /* 3-bit deltas */
  103. if ((delta = ((n >> 3) & 7)) != DELTA3_SKIP)
  104. SETPIXEL(op, lastpixel + threebitdeltas[delta]);
  105. if ((delta = (n & 7)) != DELTA3_SKIP)
  106. SETPIXEL(op, lastpixel + threebitdeltas[delta]);
  107. break;
  108. case THUNDER_RAW: /* raw data */
  109. SETPIXEL(op, n);
  110. break;
  111. }
  112. }
  113. tif->tif_rawcp = (tidata_t) bp;
  114. tif->tif_rawcc = cc;
  115. if (npixels != maxpixels) {
  116. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  117.     "ThunderDecode: %s data at scanline %ld (%lu != %lu)",
  118.     npixels < maxpixels ? "Not enough" : "Too much",
  119.     (long) tif->tif_row, (long) npixels, (long) maxpixels);
  120. return (0);
  121. }
  122. return (1);
  123. }
  124. static int
  125. ThunderDecodeRow(TIFF* tif, tidata_t buf, tsize_t occ, tsample_t s)
  126. {
  127. tidata_t row = buf;
  128. (void) s;
  129. while ((long)occ > 0) {
  130. if (!ThunderDecode(tif, row, tif->tif_dir.td_imagewidth))
  131. return (0);
  132. occ -= tif->tif_scanlinesize;
  133. row += tif->tif_scanlinesize;
  134. }
  135. return (1);
  136. }
  137. int
  138. TIFFInitThunderScan(TIFF* tif, int scheme)
  139. {
  140. (void) scheme;
  141. tif->tif_decoderow = ThunderDecodeRow;
  142. tif->tif_decodestrip = ThunderDecodeRow;
  143. return (1);
  144. }
  145. #endif /* THUNDER_SUPPORT */
  146. /* vim: set ts=8 sts=8 sw=8 noet: */