G3Encoder.c++
上传用户:weiyuanprp
上传日期:2020-05-20
资源大小:1169k
文件大小:12k
源码类别:

传真(Fax)编程

开发平台:

C/C++

  1. /* $Id: G3Encoder.c++,v 1.2 2006/04/18 19:15:55 faxguy Exp $ */
  2. /*
  3.  * Copyright (c) 1994-1996 Sam Leffler
  4.  * Copyright (c) 1994-1996 Silicon Graphics, Inc.
  5.  * HylaFAX is a trademark of Silicon Graphics
  6.  *
  7.  * Permission to use, copy, modify, distribute, and sell this software and 
  8.  * its documentation for any purpose is hereby granted without fee, provided
  9.  * that (i) the above copyright notices and this permission notice appear in
  10.  * all copies of the software and related documentation, and (ii) the names of
  11.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  12.  * publicity relating to the software without the specific, prior written
  13.  * permission of Sam Leffler and Silicon Graphics.
  14.  * 
  15.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  16.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  17.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  18.  * 
  19.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  20.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  21.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  22.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  23.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  24.  * OF THIS SOFTWARE.
  25.  */
  26. /*
  27.  * Group 3 Facsimile Writer Support.
  28.  *
  29.  * The 2-D encoding functionality was taken from the libtiff 3.5.7 distribution.
  30.  */
  31. #include "G3Encoder.h"
  32. #include "StackBuffer.h"
  33. #include "tiffio.h"
  34. #include "t4.h"
  35. G3Encoder::G3Encoder(fxStackBuffer& b) : buf(b) {}
  36. G3Encoder::~G3Encoder() {}
  37. /*
  38.  * Reset encoding state.
  39.  */
  40. void
  41. G3Encoder::setupEncoder(u_int fillOrder, bool is2d, bool isg4)
  42. {
  43.     is2D = is2d;
  44.     isG4 = isg4;
  45.     /*
  46.      * G3-encoded data is generated in MSB2LSB bit order, so we
  47.      * need to bit reverse only if the desired order is different.
  48.      */
  49.     bitmap = TIFFGetBitRevTable(fillOrder != FILLORDER_MSB2LSB);
  50.     data = 0;
  51.     bit = 8;
  52.     firstEOL = true;
  53. }
  54. /*
  55.  * Flush 8-bits of encoded data to the output buffer.
  56.  */
  57. inline void
  58. G3Encoder::flushBits()
  59. {
  60.     buf.put(bitmap[data]);
  61.     data = 0;
  62.     bit = 8;
  63. }
  64. static const tableentry horizcode =
  65.     { 3, 0x1 }; /* 001 */
  66. static const tableentry passcode =
  67.     { 4, 0x1 }; /* 0001 */
  68. static const tableentry vcodes[7] = {   
  69.     { 7, 0x03 }, /* 0000 011 */
  70.     { 6, 0x03 }, /* 0000 11 */
  71.     { 3, 0x03 }, /* 011 */
  72.     { 1, 0x1 }, /* 1 */
  73.     { 3, 0x2 }, /* 010 */
  74.     { 6, 0x02 }, /* 0000 10 */
  75.     { 7, 0x02 } /* 0000 010 */  
  76. };
  77. #define isAligned(p,t)  ((((u_long)(p)) & (sizeof (t)-1)) == 0)
  78. /*
  79.  * Find a span of ones or zeros using the supplied
  80.  * table.  The byte-aligned start of the bit string
  81.  * is supplied along with the start+end bit indices.
  82.  * The table gives the number of consecutive ones or
  83.  * zeros starting from the msb and is indexed by byte
  84.  * value.
  85.  */
  86. int
  87. G3Encoder::findspan(const u_char** bpp, int bs, int be, const u_char* tab)
  88. {
  89.     const u_char *bp = *bpp;
  90.     int bits = be - bs;
  91.     int n, span;
  92.     /*
  93.      * Check partial byte on lhs.
  94.      */
  95.     if (bits > 0 && (n = (bs & 7))) {
  96. span = tab[(*bp << n) & 0xff];
  97. if (span > 8-n)        /* table value too generous */
  98.     span = 8-n;
  99. if (span > bits) /* constrain span to bit range */
  100.     span = bits;
  101. if (n+span < 8)        /* doesn't extend to edge of byte */
  102.     goto done;
  103. bits -= span;
  104. bp++;
  105.     } else
  106. span = 0;
  107.     /*
  108.      * Scan full bytes for all 1's or all 0's.
  109.      */
  110.     while (bits >= 8) {
  111. n = tab[*bp];
  112. span += n;
  113. bits -= n;
  114. if (n < 8)        /* end of run */
  115.     goto done;
  116. bp++;
  117.     }
  118.     /*
  119.      * Check partial byte on rhs.
  120.      */
  121.     if (bits > 0) {
  122. n = tab[*bp];
  123. span += (n > bits ? bits : n);
  124.     }
  125. done:
  126.     *bpp = bp;
  127.     return (span);
  128. }
  129. /*
  130.  * Find a span of ones or zeros using the supplied
  131.  * table.  The ``base'' of the bit string is supplied
  132.  * along with the start+end bit indices.
  133.  */
  134. int
  135. G3Encoder::find0span(const u_char* bp, int bs, int be)
  136. {
  137. int32 bits = be - bs;
  138. int32 n, span;
  139. bp += bs>>3;
  140. /*
  141.  * Check partial byte on lhs.
  142.  */
  143. if (bits > 0 && (n = (bs & 7))) {
  144. span = zeroruns[(*bp << n) & 0xff];
  145. if (span > 8-n) /* table value too generous */
  146. span = 8-n;
  147. if (span > bits) /* constrain span to bit range */
  148. span = bits;
  149. if (n+span < 8) /* doesn't extend to edge of byte */
  150. return (span);
  151. bits -= span;
  152. bp++;
  153. } else
  154. span = 0;
  155. if ((uint32) bits >= 2*8*sizeof (long)) {
  156. long* lp;
  157. /*
  158.  * Align to longword boundary and check longwords.
  159.  */
  160. while (!isAligned(bp, long)) {
  161. if (*bp != 0x00)
  162. return (span + zeroruns[*bp]);
  163. span += 8, bits -= 8;
  164. bp++;
  165. }
  166. lp = (long*) bp;
  167. while ((uint32) bits >= 8*sizeof (long) && *lp == 0) {
  168. span += 8*sizeof (long), bits -= 8*sizeof (long);
  169. lp++;
  170. }
  171. bp = (u_char*) lp;
  172. }
  173. /*
  174.  * Scan full bytes for all 0's.
  175.  */
  176. while (bits >= 8) {
  177. if (*bp != 0x00) /* end of run */
  178. return (span + zeroruns[*bp]);
  179. span += 8, bits -= 8;
  180. bp++;
  181. }
  182. /*
  183.  * Check partial byte on rhs.
  184.  */
  185. if (bits > 0) {
  186. n = zeroruns[*bp];
  187. span += (n > bits ? bits : n);
  188. }
  189. return (span);
  190. }
  191. int
  192. G3Encoder::find1span(const u_char* bp, int bs, int be)
  193. {
  194. int32 bits = be - bs;
  195. int32 n, span;
  196. bp += bs>>3;
  197. /*
  198.  * Check partial byte on lhs.
  199.  */
  200. if (bits > 0 && (n = (bs & 7))) {
  201. span = oneruns[(*bp << n) & 0xff];
  202. if (span > 8-n) /* table value too generous */
  203. span = 8-n;
  204. if (span > bits) /* constrain span to bit range */
  205. span = bits;
  206. if (n+span < 8) /* doesn't extend to edge of byte */
  207. return (span);
  208. bits -= span;
  209. bp++;
  210. } else
  211. span = 0;
  212. if ((uint32) bits >= 2*8*sizeof (long)) {
  213. long* lp;
  214. /*
  215.  * Align to longword boundary and check longwords.
  216.  */
  217. while (!isAligned(bp, long)) {
  218. if (*bp != 0xff)
  219. return (span + oneruns[*bp]);
  220. span += 8, bits -= 8;
  221. bp++;
  222. }
  223. lp = (long*) bp;
  224. while ((uint32) bits >= 8*sizeof (long) && *lp == ~0) {
  225. span += 8*sizeof (long), bits -= 8*sizeof (long);
  226. lp++;
  227. }
  228. bp = (u_char*) lp;
  229. }
  230. /*
  231.  * Scan full bytes for all 1's.
  232.  */
  233. while (bits >= 8) {
  234. if (*bp != 0xff) /* end of run */
  235. return (span + oneruns[*bp]);
  236. span += 8, bits -= 8;
  237. bp++;
  238. }
  239. /*
  240.  * Check partial byte on rhs.
  241.  */
  242. if (bits > 0) {
  243. n = oneruns[*bp];
  244. span += (n > bits ? bits : n);
  245. }
  246. return (span);
  247. }
  248. /*
  249.  * Write a code to the output stream.
  250.  */
  251. inline void
  252. G3Encoder::putcode(const tableentry& te)
  253. {
  254.     putBits(te.code, te.length);
  255. }
  256. /*
  257.  * Return the offset of the next bit in the range
  258.  * [bs..be] that is different from the specified
  259.  * color.  The end, be, is returned if no such bit
  260.  * exists.
  261.  */
  262. #define finddiff(_cp, _bs, _be, _color) 
  263. (_bs + (_color ? find1span(_cp,_bs,_be) : find0span(_cp,_bs,_be)))
  264. /*
  265.  * Like finddiff, but also check the starting bit
  266.  * against the end in case start > end. 
  267.  */
  268. #define finddiff2(_cp, _bs, _be, _color) 
  269. (_bs < _be ? finddiff(_cp,_bs,_be,_color) : _be)
  270. /*
  271.  * Encode a multi-line raster.  For MH and MR we can do everything with
  272.  * 1D-data, if desired, inserting the appropriate tag bits in MR.  For 
  273.  * MMR we must do everything with 2D-data, thus when coding 2D-data a 
  274.  * reference line, rp, is required.
  275.  */
  276. void
  277. G3Encoder::encode(const void* vp, u_int w, u_int h, u_char* rp)
  278. {
  279. #define PIXEL(buf,ix)   ((((buf)[(ix)>>3]) >> (7-((ix)&7))) & 1)
  280.     u_int rowbytes = howmany(w, 8);
  281.     const u_char* bp = (const unsigned char*) vp;
  282.     while (h-- > 0) {
  283. if (!isG4) { // put the EOL
  284.     if( firstEOL ) // according to T.4 first EOL 
  285. firstEOL = false; // should not be aligned
  286.     else if (bit != 4)
  287. putBits(0, (bit < 4) ? bit+4 : bit-4); // byte-align other EOLs
  288.     if (is2D)
  289. if (rp)
  290.     putBits((EOL<<1)|0, 12+1); // T.4 4.2.2
  291. else
  292.     putBits((EOL<<1)|1, 12+1);
  293.     else
  294. putBits(EOL, 12);
  295. }
  296. if (rp) { // 2-D line
  297.     uint32 a0 = 0;
  298.     uint32 a1 = (PIXEL(bp, 0) != 0 ? 0 : finddiff(bp, 0, w, 0));
  299.     uint32 b1 = (PIXEL(rp, 0) != 0 ? 0 : finddiff(rp, 0, w, 0));
  300.     uint32 a2, b2;
  301.     for (;;) {
  302. b2 = finddiff2(rp, b1, w, PIXEL(rp,b1));
  303. if (b2 >= a1) {
  304.     int32 d = b1 - a1;
  305.     if (!(-3 <= d && d <= 3)) { /* horizontal mode */
  306. a2 = finddiff2(bp, a1, w, PIXEL(bp,a1));
  307. putcode(horizcode);
  308. if (a0+a1 == 0 || PIXEL(bp, a0) == 0) {
  309.     putspan(a1-a0, TIFFFaxWhiteCodes);
  310.     putspan(a2-a1, TIFFFaxBlackCodes);
  311. } else {
  312.     putspan(a1-a0, TIFFFaxBlackCodes);
  313.     putspan(a2-a1, TIFFFaxWhiteCodes);
  314. }
  315. a0 = a2;
  316.     } else { /* vertical mode */
  317. putcode(vcodes[d+3]);
  318. a0 = a1;
  319.     }
  320. } else { /* pass mode */
  321.     putcode(passcode);
  322.     a0 = b2;
  323. }
  324. if (a0 >= w)
  325.     break;
  326. a1 = finddiff(bp, a0, w, PIXEL(bp,a0));
  327. b1 = finddiff(rp, a0, w, !PIXEL(bp,a0));
  328. b1 = finddiff(rp, b1, w, PIXEL(bp,a0));
  329.     }
  330.     memcpy(rp, bp, rowbytes);
  331.     bp += rowbytes; // advance raster row
  332. } else { // 1-D line
  333.     int bs = 0, span;
  334.     for (;;) {
  335. span = findspan(&bp, bs, w, zeroruns); // white span
  336. putspan(span, TIFFFaxWhiteCodes);
  337. bs += span;
  338. if ((u_int) bs >= w)
  339.     break;
  340. span = findspan(&bp, bs, w, oneruns); // black span
  341. putspan(span, TIFFFaxBlackCodes);
  342. bs += span;
  343. if ((u_int) bs >= w)
  344.     break;
  345.     }
  346. }
  347.     }
  348. #undef PIXEL
  349. }
  350. void
  351. G3Encoder::encoderCleanup()
  352. {
  353.     if (isG4) {
  354. putBits(EOL, 12);
  355. putBits(EOL, 12);
  356.     }
  357.     if (bit != 8) // flush partial byte
  358. flushBits();
  359. }
  360. /*
  361.  * Write the sequence of codes that describes
  362.  * the specified span of zero's or one's.  The
  363.  * appropriate table that holds the make-up and
  364.  * terminating codes is supplied.
  365.  */
  366. void
  367. G3Encoder::putspan(int span, const tableentry* tab)
  368. {
  369.     while (span >= 2624) {
  370. const tableentry& te = tab[63 + (2560>>6)];
  371. putcode(te);
  372. span -= te.runlen;
  373.     }
  374.     if (span >= 64) {
  375. const tableentry& te = tab[63 + (span>>6)];
  376. putcode(te);
  377. span -= te.runlen;
  378.     }
  379.     putcode(tab[span]);
  380. }
  381. /*
  382.  * Write a variable-length bit-value to the output
  383.  * stream. Values are assumed to be at most 16 bits.
  384.  */
  385. void
  386. G3Encoder::putBits(u_int bits, u_int length)
  387. {
  388.     static const u_int mask[9] =
  389. { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
  390.     while (length > (u_short) bit) {
  391. data |= bits >> (length - bit);
  392. length -= bit;
  393. flushBits();
  394.     }
  395.     data |= (bits & mask[length]) << (bit - length);
  396.     bit -= length;
  397.     if (bit == 0)
  398. flushBits();
  399. }
  400. const u_char G3Encoder::zeroruns[256] = {
  401.     8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,    /* 0x00 - 0x0f */
  402.     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,    /* 0x10 - 0x1f */
  403.     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,    /* 0x20 - 0x2f */
  404.     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,    /* 0x30 - 0x3f */
  405.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,    /* 0x40 - 0x4f */
  406.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,    /* 0x50 - 0x5f */
  407.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,    /* 0x60 - 0x6f */
  408.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,    /* 0x70 - 0x7f */
  409.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0x80 - 0x8f */
  410.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0x90 - 0x9f */
  411.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0xa0 - 0xaf */
  412.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0xb0 - 0xbf */
  413.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0xc0 - 0xcf */
  414.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0xd0 - 0xdf */
  415.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0xe0 - 0xef */
  416.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0xf0 - 0xff */
  417. };
  418. const u_char G3Encoder::oneruns[256] = {
  419.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0x00 - 0x0f */
  420.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0x10 - 0x1f */
  421.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0x20 - 0x2f */
  422.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0x30 - 0x3f */
  423.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0x40 - 0x4f */
  424.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0x50 - 0x5f */
  425.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0x60 - 0x6f */
  426.     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,    /* 0x70 - 0x7f */
  427.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,    /* 0x80 - 0x8f */
  428.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,    /* 0x90 - 0x9f */
  429.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,    /* 0xa0 - 0xaf */
  430.     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,    /* 0xb0 - 0xbf */
  431.     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,    /* 0xc0 - 0xcf */
  432.     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,    /* 0xd0 - 0xdf */
  433.     3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,    /* 0xe0 - 0xef */
  434.     4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8,    /* 0xf0 - 0xff */
  435. };