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

传真(Fax)编程

开发平台:

C/C++

  1. /* $Id: Class2Params.c++,v 1.12 2008/04/26 22:34:29 faxguy Exp $ */
  2. /*
  3.  * Copyright (c) 1990-1996 Sam Leffler
  4.  * Copyright (c) 1991-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. #include "config.h"
  27. #include "Class2Params.h"
  28. #include "Sys.h"
  29. #include "t.30.h"
  30. Class2Params::Class2Params()
  31. {
  32.     vr = (u_int) -1;
  33.     br = (u_int) -1;
  34.     wd = (u_int) -1;
  35.     ln = (u_int) -1;
  36.     df = (u_int) -1;
  37.     ec = (u_int) -1;
  38.     bf = (u_int) -1;
  39.     st = (u_int) -1;
  40.     jp = (u_int) -1;
  41. }
  42. int
  43. Class2Params::operator==(const Class2Params& other) const
  44. {
  45.     return vr == other.vr
  46. && br == other.br
  47. && wd == other.wd
  48. && ln == other.ln
  49. && df == other.df
  50. && ec == other.ec
  51. && bf == other.bf
  52. && st == other.st
  53. && jp == other.jp;
  54. }
  55. int
  56. Class2Params::operator!=(const Class2Params& other) const
  57. {
  58.     return !(*this == other);
  59. }
  60. fxStr
  61. Class2Params::cmd(bool class2UseHex, bool ecm20, bool doDFbitmap, bool useJP) const
  62. {
  63.     u_int unset = (u_int) -1;
  64.     fxStr comma(",");
  65.     fxStr notation;
  66.     if (class2UseHex)
  67.         notation = "%X";
  68.     else
  69.         notation = "%u";
  70.     fxStr s;
  71.     if (vr != unset) s.append(fxStr::format(notation, vr));
  72.     s.append(comma);
  73.     if (br != unset) s.append(fxStr::format(notation, br));
  74.     s.append(comma);
  75.     if (wd != unset) s.append(fxStr::format(notation, wd));
  76.     s.append(comma);
  77.     if (ln != unset) s.append(fxStr::format(notation, ln));
  78.     s.append(comma);
  79.     if (doDFbitmap) {
  80. /*
  81.  * We need to produce a T.32 Amendment 1 data format 
  82.  * extension bitmap rather than a point-value.
  83.  */
  84. u_int dfmap = 0;
  85. if (df &  BIT(DF_2DMR)) dfmap |= 0x1;
  86. if (df & BIT(DF_2DMMR)) dfmap |= 0x3;
  87. if (df &  BIT(DF_JBIG)) dfmap |= 0xC; // JBIG L0 (4) + JBIG (8)
  88. if (df != unset) s.append(fxStr::format(notation, dfmap));
  89.     } else
  90. if (df != unset) s.append(fxStr::format(notation, df != 4 ? df : 8)); // we don't do JBIG L0
  91.     s.append(comma);
  92.     if (ec != unset) s.append(fxStr::format(notation, ec - (ecm20 && ec ? 1 : 0)));
  93.     s.append(comma);
  94.     if (bf != unset) s.append(fxStr::format(notation, bf));
  95.     s.append(comma);
  96.     if (st != unset) s.append(fxStr::format(notation, st));
  97.     if (useJP) {
  98. s.append(comma);
  99. if (df != unset) s.append(fxStr::format(notation, jp));
  100.     }
  101.     return s;
  102. }
  103. bool
  104. Class2Params::is2D() const
  105. {
  106.     return (DF_2DMR <= df && df <= DF_2DMMR);
  107. }
  108. /*
  109.  * Tables for mapping a T.30 DIS to Class 2
  110.  * subparameter code values.
  111.  */
  112. u_int Class2Params::DISdfTab[2] = {
  113.     DF_1DMH, // !DIS_2DENCODE
  114.     DF_2DMR // DIS_2DENCODE
  115. };
  116. u_int Class2Params::DISvrTab[2] = {
  117.     VR_NORMAL, // !DIS_7MMVRES
  118.     VR_FINE // DIS_7MMVRES
  119. };
  120. /*
  121.  * Beware that this table returns the ``best speed''
  122.  * based on the signalling capabilities of the DIS.
  123.  */
  124. u_int Class2Params::DISbrTab[16] = {
  125.     BR_2400, // 0x0 V27ter fall-back (BR_4800 could be assumed, T.30 Table 2 Note 3)
  126.     BR_14400, // 0x1 undefined
  127.     BR_9600, // 0x2 undefined
  128.     BR_14400, // 0x3 undefined
  129.     BR_4800, // 0x4 V27ter
  130.     BR_14400, // 0x5 reserved
  131.     BR_4800, // 0x6 reserved
  132.     BR_14400, // 0x7 reserved
  133.     BR_9600, // 0x8 V29
  134.     BR_14400, // 0x9 undefined
  135.     BR_9600, // 0xA undefined
  136.     BR_14400, // 0xB undefined
  137.     BR_9600, // 0xC V27ter+V29
  138.     BR_14400, // 0xD V27ter+V29+V17 (not V.33, post-1994)
  139.     BR_14400, // 0xE V27ter+V29+V33 (invalid, post-1994, T.30 Table 2 Notes 31, 32)
  140.     BR_14400, // 0xF undefined
  141. };
  142. u_int Class2Params::DISwdTab[4] = {
  143.     WD_A4, // DISWIDTH_A4
  144.     WD_A3, // DISWIDTH_A3
  145.     WD_B4 // DISWIDTH_B4
  146. };
  147. u_int Class2Params::DISlnTab[4] = {
  148.     LN_A4, // DISLENGTH_A4
  149.     LN_INF, // DISLENGTH_UNLIMITED
  150.     LN_B4, // DISLENGTH_B4
  151.     LN_A4 // undefined
  152. };
  153. u_int Class2Params::DISstTab[8] = {
  154.     ST_20MS, // DISMINSCAN_20MS
  155.     ST_40MS, // DISMINSCAN_40MS
  156.     ST_10MS, // DISMINSCAN_10MS
  157.     ST_10MS2, // DISMINSCAN_10MS2
  158.     ST_5MS, // DISMINSCAN_5MS
  159.     ST_40MS2, // DISMINSCAN_40MS2
  160.     ST_20MS2, // DISMINSCAN_20MS2
  161.     ST_0MS // DISMINSCAN_0MS
  162. };
  163. u_int Class2Params::DCSbrTab[16] = {
  164.     BR_2400, // 0x0/2400 V27
  165.     BR_14400, // 0x1/14400 V17
  166.     BR_14400, // 0x2/14400 V33
  167.     0, // 0x3/undefined 
  168.     BR_4800, // 0x4/4800 V27
  169.     BR_12000, // 0x5/12000 V17
  170.     BR_12000, // 0x6/12000 V33
  171.     0, // 0x7/undefined 
  172.     BR_9600, // 0x8/9600 V29
  173.     BR_9600, // 0x9/9600 V17
  174.     BR_9600, // 0xA/9600 V33
  175.     0, // 0xB/undefined
  176.     BR_7200, // 0xC/7200 V29
  177.     BR_7200, // 0xD/7200 V17
  178.     BR_7200, // 0xE/7200 V33
  179.     0, // 0xF/undefined 
  180. };
  181. /*
  182.  * Convert a T.30 DIS to a Class 2 parameter block.
  183.  *
  184.  * Note that DIS is a list of *capabilities* and not necessarily maximums.
  185.  * Thus the values here can be set to bitmaps rather than settings.
  186.  */  
  187. void
  188. Class2Params::setFromDIS(FaxParams& dis_caps)
  189. {  
  190.     assign(dis_caps);
  191.     u_int dis = 0;
  192.     u_int xinfo = 0;
  193.     dis |= getByte(0) << 16;
  194.     dis |= getByte(1) << 8;
  195.     dis |= getByte(2) << 0;
  196.     xinfo |= getByte(3) << 24;
  197.     xinfo |= getByte(4) << 16;
  198.     xinfo |= getByte(5) << 8;
  199.     xinfo |= getByte(6) << 0;
  200.     setFromDIS(dis, xinfo);
  201.     if (ec != EC_DISABLE) {
  202. if (dis_caps.isBitEnabled(FaxParams::BITNUM_JBIG_BASIC)) df |= BIT(DF_JBIG);
  203. if (dis_caps.isBitEnabled(FaxParams::BITNUM_JPEG)) jp |= BIT(JP_GREY);
  204. if (dis_caps.isBitEnabled(FaxParams::BITNUM_FULLCOLOR)) {
  205.     if (jp & BIT(JP_GREY)) jp |= BIT(JP_COLOR);
  206. }
  207.     }
  208. }
  209. /*
  210.  * Convert a T.30 DIS to a Class 2 parameter block.
  211.  */
  212. void
  213. Class2Params::setFromDIS(u_int dis, u_int xinfo)
  214. {
  215.     // VR is a bitmap of available settings, not a maximum
  216.     vr = DISvrTab[(dis & DIS_7MMVRES) >> 9];
  217.     if (xinfo & DIS_METRES) {
  218. if (xinfo & DIS_200X400) vr |= VR_R8;
  219. if (xinfo & DIS_400X400) vr |= VR_R16;
  220.     }
  221.     if (xinfo & DIS_INCHRES) {
  222. vr |= VR_200X100;
  223. if (dis & DIS_7MMVRES) vr |= VR_200X200;
  224. if (xinfo & DIS_200X400) vr |= VR_200X400;
  225.     }
  226.     if (xinfo & DIS_300X300) vr |= VR_300X300;
  227.     /*
  228.      * Beware that some modems (e.g. the Supra) indicate they
  229.      * support the V.17 bit rates, but not the normal V.27+V.29
  230.      * signalling rates.  The DISbrTab is NOT setup to mark the
  231.      * V.27 and V.29 if V.17 is set.  Instead we let the upper
  232.      * layers select appropriate signalling rate knowing that
  233.      * we'll fall back to something that the modem will support.
  234.      */
  235.     if ((dis & DIS_V8) && (xinfo & DIS_ECMODE))
  236. br = BR_33600; // Is V.8 only used by V.34 (SuperG3) faxes?
  237.     else
  238. br = DISbrTab[(dis & DIS_SIGRATE) >> 10];
  239.     wd = DISwdTab[(dis & DIS_PAGEWIDTH) >> 6];
  240.     ln = DISlnTab[(dis & DIS_PAGELENGTH) >> 4];
  241.     // DF here is a bitmap
  242.     df = BIT(DF_1DMH); // required support for all G3 facsimile
  243.     if ((xinfo & DIS_G4COMP) && (xinfo & DIS_ECMODE)) // MMR requires ECM
  244. df |= BIT(DF_2DMMR);
  245.     if (xinfo & DIS_2DUNCOMP)
  246. df |= BIT(DF_2DMRUNCOMP);
  247.     if (dis & DIS_2DENCODE)
  248. df |= BIT(DF_2DMR);
  249.     if (xinfo & DIS_ECMODE)
  250. ec = (dis & DIS_FRAMESIZE) ? EC_ENABLE64 : EC_ENABLE256;
  251.     else
  252. ec = EC_DISABLE;
  253.     bf = BF_DISABLE; // XXX from xinfo
  254.     st = DISstTab[(dis & DIS_MINSCAN) >> 1];
  255.     jp = 0;
  256. }
  257. /*
  258.  * Convert a T.30 DCS to a Class 2 parameter block.
  259.  */
  260. void 
  261. Class2Params::setFromDCS(FaxParams& dcs_caps)
  262. {
  263.     assign(dcs_caps);
  264.     u_int dcs = 0;
  265.     u_int xinfo = 0;
  266.   
  267.     dcs |= getByte(0) << 16;
  268.     dcs |= getByte(1) << 8;
  269.     dcs |= getByte(2) << 0;
  270.     xinfo |= getByte(3) << 24;
  271.     xinfo |= getByte(4) << 16;
  272.     xinfo |= getByte(5) << 8;
  273.     xinfo |= getByte(6) << 0;
  274.     setFromDCS(dcs, xinfo);
  275.     if (dcs_caps.isBitEnabled(FaxParams::BITNUM_LETTER_SIZE) || 
  276. dcs_caps.isBitEnabled(FaxParams::BITNUM_LEGAL_SIZE)) {
  277. // we map letter and legal onto WD_A4 + LN_INF for convenience
  278. wd = WD_A4;
  279. ln = LN_INF;
  280.     }
  281.     // Dex 855 sets MMR when also indicating JBIG.  We deliberately let JBIG override.
  282.     if (dcs_caps.isBitEnabled(FaxParams::BITNUM_JBIG_BASIC)) df = DF_JBIG;
  283.     if (dcs_caps.isBitEnabled(FaxParams::BITNUM_JBIG_L0)) df = DF_JBIG;
  284.     if (dcs_caps.isBitEnabled(FaxParams::BITNUM_JPEG)) jp = JP_GREY;
  285.     if (dcs_caps.isBitEnabled(FaxParams::BITNUM_FULLCOLOR)) {
  286. if (jp == JP_GREY) jp = JP_COLOR;
  287.     }
  288.     if (ec == EC_DISABLE && 
  289. (df == DF_2DMMR || df == DF_JBIG || jp == JP_GREY || jp == JP_COLOR)) {
  290. // MMR, JBIG, and JPEG require ECM... we've seen cases where fax
  291. // senders screw up and don't signal ECM but do send ECM-framed 
  292. // image data in the signalled format, and an RTN will break protocol,
  293. // and thus a failure, so we correct the sender's mistake 
  294. // guessing at 256-byte ECM since 64-byte is so rarely used.
  295. ec = EC_ENABLE256;
  296.     }
  297. }
  298. /*
  299.  * Convert a T.30 DCS to a Class 2 parameter block.
  300.  */
  301. void
  302. Class2Params::setFromDCS(u_int dcs, u_int xinfo)
  303. {
  304.     setFromDIS(dcs, xinfo);
  305.     // override DIS setup
  306.     br = DCSbrTab[(dcs & DCS_SIGRATE) >> 10];
  307.     if (xinfo & DCS_INCHRES) {
  308. if (xinfo & DCS_400X400) vr = VR_R16; // rather than adding a VR_400X400
  309. else if (xinfo & DCS_300X300) vr = VR_300X300;
  310. else if (xinfo & DCS_200X400) vr = VR_200X400;
  311. else if (dcs & DCS_7MMVRES) vr = VR_200X200;
  312. else vr = VR_200X100;
  313.     } else { // bit 44 of DCS is 0
  314. // some manufacturers don't send DCS_INCHRES with DCS_300X300
  315. if (xinfo & DCS_300X300) vr = VR_300X300;
  316. else if (xinfo & DCS_400X400) vr = VR_R16;
  317. else if (xinfo & DCS_200X400) vr = VR_R8;
  318. else vr = DISvrTab[(dcs & DCS_7MMVRES) >> 9];
  319.     }
  320.     // DF here is a setting, not a bitmap, max of DF_2DMMR (JPEG, JBIG set later)
  321.     if (df & BIT(DF_2DMMR)) df = DF_2DMMR;
  322.     else if (df & BIT(DF_2DMR)) df = DF_2DMR;
  323.     else df = DF_1DMH;
  324.     if (xinfo & DCS_ECMODE)
  325. ec = (xinfo & DCSFRAME_64) ? EC_ENABLE64 : EC_ENABLE256;
  326.     else
  327. ec = EC_DISABLE;
  328. }
  329. #define CHECKPARAM(a, b, c) (c ? a & BIT(b) : a == b)
  330. /*
  331.  * Set the T.30 DIS/DCS bits that reflects the parameters.
  332.  * isDIS distinguishes between DIS and DCS
  333.  *
  334.  * Class2Params may be capability bitmaps (modemParams) or may be
  335.  * settings (params), we must be capable of handling both.
  336.  */
  337. void
  338. Class2Params::update(bool isDIS)
  339. {
  340.     setupT30(0,0);
  341.     setBit(BITNUM_T4RCVR, true); // Table 2-T.30 Notes 19 & 20
  342.     /*
  343.      * RESOLUTIONS
  344.      *
  345.      * We set both resolution units preferences in order to
  346.      * allow the sender to choose between them.  If it has
  347.      * prepared an inch-based document, that's how we want it.
  348.      * VR is bitmapped natively in all cases.
  349.      */
  350.     if (vr & VR_FINE || vr & VR_200X200) setBit(BITNUM_VR_FINE, true); // R8  x  7.7 l/mm
  351.     if (vr & VR_R8 || vr & VR_200X400)   setBit(BITNUM_VR_R8, true); // R8  x 15.4 l/mm
  352.     if (vr & VR_R16)  setBit(BITNUM_VR_R16, true); // R16 x 15.4 l/mm
  353.     if (vr & VR_300X300)  setBit(BITNUM_VR_300X300, true);// 300 x 300 dpi
  354.     if (!isDIS && (vr & VR_200X200 || vr & VR_200X400 || vr & VR_300X300)) {
  355. setBit(BITNUM_INCH_RES, true); // indicate inch-based resolution usage
  356.     }
  357.     /*
  358.      * SIGNALING RATE
  359.      *
  360.      * Converting br into a meaningful T.30
  361.      * representation is an inexact science because
  362.      *  1) V.17 speeds overlap V.33 and V.29, and
  363.      *  2) br indicates speed, and T.30
  364.      *     indicates modulation also, and
  365.      *  3) V.34 overlaps V.17, V.33, V.29, and V.27.
  366.      *
  367.      * As V.33 is no longer part of T.30 as of 1994,
  368.      * we do not set it here.
  369.      *
  370.      * V.17 support requires both V.29 and V.27 support.
  371.      * V.29 and V.27 support are independent.
  372.      * V.34 requires V.8 support.
  373.      *
  374.      * The imperfect assumptions are that:
  375.      * BR_2400 -- BR_4800  are V.27
  376.      * BR_7200 -- BR_9600  are V.29
  377.      * BR_12000 - BR_14400 are V.17
  378.      * BR_16800 - BR_33600 are V.34
  379.      *
  380.      * The protocol drivers will certainly need to reproduce
  381.      * this independently.
  382.      */
  383.     if (isDIS) { // DIS
  384. if (CHECKPARAM(br, BR_14400, true)) setBit(BITNUM_SIGRATE_14, true);
  385. if (CHECKPARAM(br, BR_9600, true)) setBit(BITNUM_SIGRATE_11, true);
  386. if (CHECKPARAM(br, BR_4800, true)) setBit(BITNUM_SIGRATE_12, true);
  387. if (CHECKPARAM(br, BR_33600, true)) setBit(BITNUM_V8_CAPABLE, true);
  388.     } else { // DCS
  389. // no bits set for V.34 rates and V.27ter 2400
  390. if (CHECKPARAM(br, BR_14400, false)) setBit(BITNUM_SIGRATE_14, true);
  391. if (CHECKPARAM(br, BR_12000, false)) {
  392.     setBit(BITNUM_SIGRATE_14, true);
  393.     setBit(BITNUM_SIGRATE_12, true);
  394. }
  395. if (CHECKPARAM(br, BR_9600, false)) setBit(BITNUM_SIGRATE_11, true);
  396. if (CHECKPARAM(br, BR_7200, false)) {
  397.     setBit(BITNUM_SIGRATE_11, true);
  398.     setBit(BITNUM_SIGRATE_12, true);
  399. }
  400. if (CHECKPARAM(br, BR_4800, false)) setBit(BITNUM_SIGRATE_12, true);
  401.     }
  402.     /*
  403.      * RECORDING WIDTH
  404.      *
  405.      * Post-1994 T.30 revisions have three page width
  406.      * options: A4 (215 mm), B4 (255 mm), and A3 (303 mm).
  407.      * Earlier revisions also included A5 (151 mm) and
  408.      * A6 (107 mm).
  409.      *
  410.      * Trying to support A5 and A6 is likely to only
  411.      * be counterproductive, thus we do not support them.
  412.      *
  413.      * A3 support requires B4 support.
  414.      * A4 support is required.
  415.      */
  416.     if (CHECKPARAM(wd, WD_A3, isDIS)) setBit(BITNUM_WIDTH_18, true);
  417.     else if (CHECKPARAM(wd, WD_B4, isDIS)) setBit(BITNUM_WIDTH_17, true);
  418.     /*
  419.      * RECORDING LENGTH
  420.      *
  421.      * Three possibilities: A4 (297 mm), B4 (364 mm), and unlimited.
  422.      * A4 page length support is required.
  423.      *
  424.      * Using "unlimited" page length is the only way to get the popular
  425.      * "US-Legal" page size.
  426.      */
  427.     if (CHECKPARAM(ln, LN_INF, isDIS)) setBit(BITNUM_LENGTH_20, true);
  428.     else if (CHECKPARAM(ln, LN_B4, isDIS)) setBit(BITNUM_LENGTH_19, true);
  429.     /*
  430.      * DATA FORMAT
  431.      *
  432.      * Options: MH (required), MR, MMR, JBIG, JPEG.
  433.      *
  434.      * ECM support is required for MMR, JBIG, and JPEG.
  435.      *
  436.      * There are other data format options in T.30
  437.      * such as T.81, and T.43.
  438.      */
  439.     if (CHECKPARAM(df, DF_2DMR, isDIS))  setBit(BITNUM_2DMR, true);
  440.     if (CHECKPARAM(df, DF_2DMMR, isDIS) && (CHECKPARAM(ec, EC_ENABLE64, isDIS) || CHECKPARAM(ec, EC_ENABLE256, isDIS)))
  441. setBit(BITNUM_2DMMR, true);
  442.     if (CHECKPARAM(df, DF_JBIG, isDIS) && (CHECKPARAM(ec, EC_ENABLE64, isDIS) || CHECKPARAM(ec, EC_ENABLE256, isDIS)))
  443. setBit(BITNUM_JBIG_BASIC, true);
  444.     if (CHECKPARAM(jp, JP_GREY, isDIS) && (CHECKPARAM(ec, EC_ENABLE64, isDIS) || CHECKPARAM(ec, EC_ENABLE256, isDIS)))
  445. setBit(BITNUM_JPEG, true);
  446.     if (CHECKPARAM(jp, JP_COLOR, isDIS) && (CHECKPARAM(ec, EC_ENABLE64, isDIS) || CHECKPARAM(ec, EC_ENABLE256, isDIS))) {
  447. setBit(BITNUM_JPEG, true);
  448. setBit(BITNUM_FULLCOLOR, true);
  449.     }
  450.     /*
  451.      * MINIMUM SCANLINE TIME
  452.      */
  453.     if (CHECKPARAM(st, ST_5MS, isDIS) || 
  454.         CHECKPARAM(st, ST_20MS2, isDIS) ||
  455.         CHECKPARAM(st, ST_40MS2, isDIS) ||
  456.         CHECKPARAM(st, ST_0MS, isDIS)) {
  457. setBit(BITNUM_ST_21, true);
  458.     }
  459.     if (CHECKPARAM(st, ST_10MS, isDIS) || 
  460.         CHECKPARAM(st, ST_10MS2, isDIS) ||
  461.         CHECKPARAM(st, ST_20MS2, isDIS) ||
  462.         CHECKPARAM(st, ST_0MS, isDIS)) {
  463. setBit(BITNUM_ST_22, true);
  464.     }
  465.     if (CHECKPARAM(st, ST_40MS, isDIS) || 
  466.         CHECKPARAM(st, ST_10MS2, isDIS) ||
  467.         CHECKPARAM(st, ST_40MS2, isDIS) ||
  468.         CHECKPARAM(st, ST_0MS, isDIS)) {
  469. setBit(BITNUM_ST_23, true);
  470.     }
  471.     
  472.     /*
  473.      * ECM
  474.      *
  475.      * 64-byte and 256-byte frame-size options.
  476.      * A receiver must support both or neither.
  477.      *
  478.      * A sender must support no ECM.  Senders
  479.      * should honor the preference of the receiver.
  480.      */
  481.     if (CHECKPARAM(ec, EC_ENABLE64, isDIS)) {
  482. setBit(BITNUM_ECM, true);
  483. if (isDIS) setBit(BITNUM_FRAMESIZE_DIS, true);
  484. else setBit(BITNUM_FRAMESIZE_DCS, true);
  485.     }
  486.     if (CHECKPARAM(ec, EC_ENABLE256, isDIS)) {
  487. setBit(BITNUM_ECM, true);
  488. if (isDIS) setBit(BITNUM_FRAMESIZE_DIS, false);
  489. else setBit(BITNUM_FRAMESIZE_DCS, false);
  490.     }
  491. }
  492. /*
  493.  * Return the number of bytes that can be
  494.  * transferred at the selected signalling
  495.  * rate in <ms> milliseconds.
  496.  */
  497. u_int
  498. Class2Params::transferSize(u_int ms) const
  499. {
  500.     return (bitRate()/8 * ms) / 1000;
  501. }
  502. /*
  503.  * Return the minimum number of bytes in a
  504.  * scanline as determined by the signalling
  505.  * rate, vertical resolution, and min-scanline
  506.  * time parameters.
  507.  */
  508. u_int
  509. Class2Params::minScanlineSize() const
  510. {
  511.     static const u_int stTimes[8] =
  512. { 0, 5, 10, 10, 20, 20, 40, 40 };
  513.     u_int ms = stTimes[st&7];
  514.     if ((st & 1) == 0 && vr > VR_NORMAL)
  515. ms /= 2;
  516.     return transferSize(ms);
  517. }
  518. u_int
  519. Class2Params::pageWidth() const
  520. {
  521.     u_int widths[8] = {
  522. 1728, // 1728 in 215 mm line
  523. 2048, // 2048 in 255 mm line
  524. 2432, // 2432 in 303 mm line
  525. 1216, // 1216 in 151 mm line
  526. 864, // 864 in 107 mm line
  527. 1728, // undefined
  528. 1728, // undefined
  529. 1728, // undefined
  530.     };
  531.     switch (vr) {
  532. case VR_300X300: 
  533.     widths[0] = 2592;
  534.     widths[1] = 3072;
  535.     widths[2] = 3648;
  536.     widths[3] = 1824;
  537.     widths[4] = 1296;
  538.     break;  
  539. case VR_R16:
  540.     widths[0] = 3456;
  541.     widths[1] = 4096;
  542.     widths[2] = 4864;
  543.     widths[3] = 2432;
  544.     widths[4] = 1728;
  545.     break;
  546. case VR_NORMAL:
  547. case VR_FINE:
  548. case VR_R8:
  549. case VR_200X100:
  550. case VR_200X200:
  551. case VR_200X400:
  552.     // nothing
  553.     break;
  554.     }
  555.     return (widths[wd&7]);
  556. }
  557. void
  558. Class2Params::setPageWidthInMM(u_int w)
  559. {
  560.     /*
  561.      * We get the width in MM from the q file.  Basically,
  562.      * faxing only deals with three page widths defined by
  563.      * pixel-widths: 1728, 2048, and 2432 (in R8 resolution).
  564.      * The associated page size names are A4, B4, and A3.  
  565.      * However, the calculated size in millimeters differs
  566.      * between pixel-widths and page size.
  567.      * 1728 pixels = 215 mm : A4 = 209.903 mm
  568.      * 2048 pixels = 255 mm : B4 = 250.119 mm
  569.      * 2432 pixels = 303 mm : A3 = 297.039 mm
  570.      * The client program may therefore use a range of
  571.      * pagewidth (mm) values.  We must interpret wisely.
  572.      */
  573.     wd = (w > 270 ? WD_A3 : w > 230 ? WD_B4 : WD_A4);
  574. }
  575. void
  576. Class2Params::setPageWidthInPixels(u_int w)
  577. {
  578.     /*
  579.      * Here we attempt to determine the WD parameter with
  580.      * a pixel width which is impossible to be perfect
  581.      * because there are colliding values.  However,
  582.      * since we don't use > WD_A3, this is fine.
  583.      */
  584.     wd = (w == 1728 ? WD_A4 :
  585.   w == 2048 ? WD_B4 :
  586.   w == 2432 ? WD_A3 :
  587.   w == 3456 ? WD_A4 :
  588.   w == 4096 ? WD_B4 :
  589.   w == 4864 ? WD_A3 :
  590.   w == 2592 ? WD_A4 :
  591.   w == 3072 ? WD_B4 :
  592.   w == 3648 ? WD_A3 :
  593.       WD_A4);
  594. }
  595. u_int
  596. Class2Params::pageLength() const
  597. {
  598.     static const u_int lengths[4] = {
  599. 297, // A4 paper
  600. 364, // B4 paper
  601. (u_int) -1, // unlimited
  602. 280, // US letter (used internally)
  603.     };
  604.     return (lengths[ln&3]);
  605. }
  606. void
  607. Class2Params::setPageLengthInMM(u_int l)
  608. {
  609.     ln = (l == (u_int) -1 ?  LN_INF :
  610.   l <= 280 ?      LN_LET :
  611.   l <= 300 ?      LN_A4 :
  612.   l <= 380 ?      LN_B4 :
  613.      LN_INF);
  614. }
  615. u_int
  616. Class2Params::horizontalRes() const
  617. {
  618.     /*
  619.      * Technically horizontal resolution depends upon the
  620.      * the number of pixels across the page and the page width.
  621.      * But, these are just used for writing TIFF tags for 
  622.      * received faxes, so we do this to accomodate the session
  623.      * parameters, even though it may be slightly off.
  624.      */
  625.     return (vr == VR_NORMAL ? 204 :
  626.     vr == VR_FINE ? 204 :
  627.     vr == VR_R8 ? 204 :
  628.     vr == VR_R16 ? 408 :
  629.     vr == VR_200X100 ? 200 :
  630.     vr == VR_200X200 ? 200 :
  631.     vr == VR_200X400 ? 200 :
  632.     vr == VR_300X300 ? 300 :
  633.     (u_int) -1);
  634. }
  635. u_int
  636. Class2Params::verticalRes() const
  637. {
  638.     return (vr == VR_NORMAL ? 98 :
  639.     vr == VR_FINE ? 196 :
  640.     vr == VR_R8 ? 391 :
  641.     vr == VR_R16 ? 391 :
  642.     vr == VR_200X100 ? 100 :
  643.     vr == VR_200X200 ? 200 :
  644.     vr == VR_200X400 ? 400 :
  645.     vr == VR_300X300 ? 300 :
  646.     (u_int) -1);
  647. }
  648. void
  649. Class2Params::setRes(u_int xres, u_int yres)
  650. {
  651.     vr = (xres > 300 && yres > 391 ? VR_R16 : 
  652. xres > 204 && yres > 250 ? VR_300X300 :
  653. yres > 391 ? VR_200X400 : 
  654. yres > 250 ? VR_R8 : 
  655. yres > 196 ? VR_200X200 :
  656. yres > 150 ? VR_FINE : 
  657. yres > 98 ? VR_200X100 : VR_NORMAL);
  658. }
  659. fxStr
  660. Class2Params::encodePage() const
  661. {
  662.     int v = (vr&3) | ((wd&7)<<1) | ((ln&3)<<4) | ((df&3)<<6);
  663.     return fxStr(v, "%02x");
  664. }
  665. void
  666. Class2Params::decodePage(const char* s)
  667. {
  668.     u_int v = (u_int) strtoul(s, NULL, 16);
  669.     vr = (v>>0) & 1;
  670.     wd = (v>>1) & 7;
  671.     ln = (v>>4) & 3;
  672.     if (ln == LN_LET) // force protocol value
  673. ln = LN_A4;
  674.     df = (v>>6) & 3;
  675. }
  676. u_int
  677. Class2Params::encode() const
  678. {
  679.     return  (vr > 4 ? ((vr>>4)&7)<<0 : (vr&7)<<0) // push inch resolutions
  680.   | ((br&15)<<3)
  681.   | ((wd&7)<<9)
  682.   | ((ln&3)<<12)
  683.   | ((df&3)<<14)
  684.   | ((ec == EC_DISABLE ? 0 : 1)<<16) // boolean value
  685.   | ((bf&1)<<17)
  686.   | ((st&7)<<18)
  687.   | (1<<21) // this is the version identifier
  688.   ;
  689. }
  690. void
  691. Class2Params::decode(u_int v)
  692. {
  693.     if (v>>21 == 1) { // check version
  694. vr = ((v>>0) & 7); // VR is a bitmap
  695. br = (v>>3) & 15;
  696. wd = (v>>9) & 7;
  697. ln = (v>>12) & 3;
  698. if (ln == LN_LET) // force protocol value
  699.     ln = LN_A4;
  700. df = (v>>14) & 3;
  701. ec = (v>>16) & 1;
  702. bf = (v>>17) & 1;
  703. st = (v>>18) & 7;
  704.     } else { // original version
  705. vr = (v>>0) & 1;
  706. br = (v>>1) & 7;
  707. wd = (v>>4) & 7;
  708. ln = (v>>7) & 3;
  709. if (ln == LN_LET) // force protocol value
  710.     ln = LN_A4;
  711. df = (v>>9) & 3;
  712. ec = (v>>11) & 1;
  713. bf = (v>>12) & 1;
  714. st = (v>>13) & 7;
  715.     }
  716. }
  717. u_int
  718. Class2Params::getMinSpeed() const
  719. {
  720.     u_int minspeed = BR_14400;
  721.     for (int speed = BR_14400; speed >= BR_2400; speed--) {
  722. if (br & BIT(speed)) minspeed = speed;
  723.     }
  724.     return (minspeed);
  725. }
  726. u_int
  727. Class2Params::encodeCaps() const
  728. {
  729.     // we can't use all of BR_ALL because we're limited to 32 bits
  730.     // all ECM support is reduced to "1" (EC_ENABLE64) if any ECM is available
  731.     return (vr&VR_ALL)
  732.  | ((br&(BR_2400|BR_4800|BR_7200|BR_9600|BR_12000|BR_14400))<<8)
  733.  | ((wd&WD_ALL)<<14)
  734.  | ((ln&LN_ALL)<<19)
  735.  | ((df&DF_ALL)<<22)
  736.  | ((ec&EC_DISABLE)<<26)
  737.  | (((ec&EC_ALL) != 0 ? 1 : 0)<<27)
  738.  | ((bf&BF_ALL)<<28)
  739.  | ((st&ST_ALL)<<30)
  740.  ;
  741. }
  742. void
  743. Class2Params::decodeCaps(u_int v)
  744. {
  745.     vr = (v>>0)  & VR_ALL;
  746.     br = (v>>8)  & (BR_2400|BR_4800|BR_7200|BR_9600|BR_12000|BR_14400); // see encoding
  747.     wd = (v>>14) & WD_ALL;
  748.     ln = (v>>19) & LN_ALL;
  749.     df = (v>>22) & DF_ALL;
  750.     ec = (v>>26) & (EC_DISABLE|EC_ENABLE64); // see encoding
  751.     bf = (v>>28) & BF_ALL;
  752.     st = (v>>30) & ST_ALL;
  753. }
  754. /*
  755.  * Routines for printing some Class 2 capabilities.
  756.  */
  757. const char* Class2Params::verticalResNames[65] = {
  758.     "3.85 line/mm",
  759.     "7.7 line/mm",
  760.     "15.4 line/mm", "",
  761.     "R16 x 15.4 line/mm", "", "", "",
  762.     "200 x 100 dpi", "", "", "", "", "", "", "",
  763.     "200 x 200 dpi", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
  764.     "200 x 400 dpi", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
  765.     "300 x 300 dpi"
  766. };
  767. const char* Class2Params::verticalResName() const
  768.     { return (verticalResNames[(vr & VR_ALL) > 64 ? 0 : (vr & VR_ALL)]); }
  769. const char* Class2Params::bestVerticalResName() const
  770. {
  771.     /*
  772.      * "Best" is determined by comparing pixels per square
  773.      * area of image.  Thus 300x300 is "better" than 200x400.
  774.      */
  775.     u_int res = VR_NORMAL; // required default
  776.     if (vr & VR_200X100) res = VR_200X100;
  777.     if (vr & VR_FINE) res = VR_FINE;
  778.     if (vr & VR_200X200) res = VR_200X200;
  779.     if (vr & VR_R8) res = VR_R8;
  780.     if (vr & VR_200X400) res = VR_200X400;
  781.     if (vr & VR_300X300) res = VR_300X300;
  782.     if (vr & VR_R16) res = VR_R16;
  783.     return(verticalResNames[res]);
  784. }
  785. const char* Class2Params::bitRateNames[16] = {
  786.     "2400 bit/s", // BR_2400
  787.     "4800 bit/s", // BR_4800
  788.     "7200 bit/s", // BR_7200
  789.     "9600 bit/s", // BR_9600
  790.     "12000 bit/s", // BR_12000
  791.     "14400 bit/s", // BR_14400
  792.     "16800 bit/s", // BR_16800
  793.     "19200 bit/s", // BR_19200
  794.     "21600 bit/s", // BR_21600
  795.     "24000 bit/s", // BR_24000
  796.     "26400 bit/s", // BR_26400
  797.     "28800 bit/s", // BR_28800
  798.     "31200 bit/s", // BR_31200
  799.     "33600 bit/s", // BR_33600
  800.     "0 bit/s", // 14 ???
  801.     "0 bit/s", // 15 ???
  802. };
  803. const char* Class2Params::bitRateName() const
  804.     { return (bitRateNames[br&15]); }
  805. u_int
  806. Class2Params::bitRate() const
  807. {
  808.     static const u_int brRates[16] = {
  809. 2400, // BR_2400
  810. 4800, // BR_4800
  811. 7200, // BR_7200
  812. 9600, // BR_9600
  813. 12000, // BR_12000
  814. 14400, // BR_14400
  815. 16800, // BR_16800
  816. 19200, // BR_19200
  817. 21600, // BR_21600
  818. 24000, // BR_24000
  819. 26400, // BR_26400
  820. 28800, // BR_28800
  821. 31200, // BR_31200
  822. 33600, // BR_33600
  823. 14400, // 14? XXX
  824. 14400, // 15? XXX
  825.     };
  826.     return (brRates[br & 15]);
  827. }
  828. const char* Class2Params::dataFormatNames[7] = {
  829.     "1-D MH", // DF_1DMH
  830.     "2-D MR", // DF_2DMR
  831.     "2-D Uncompressed Mode", // DF_2DMRUNCOMP
  832.     "2-D MMR", // DF_2DMMR
  833.     "JBIG", // DF_JBIG
  834.     "JPEG Greyscale", // JP_GREY
  835.     "JPEG Full-Color" // JP_COLOR
  836. };
  837. const char* Class2Params::dataFormatName() const
  838.     u_int dfid = df+(jp > 0 && jp < (u_int) -1 ? jp + 4 : 0);
  839.     return (dataFormatNames[dfid > 6 ? 0 : dfid]);
  840. }
  841. fxStr
  842. Class2Params::dataFormatsName()
  843. {
  844.     fxStr formats = "MH";
  845.     if (df & BIT(DF_2DMR)) formats.append(", MR");
  846.     if (df & BIT(DF_2DMMR)) formats.append(", MMR");
  847.     if (df & BIT(DF_JBIG)) formats.append(", JBIG");
  848.     // since color requires greyscale, just say one or the other
  849.     if (jp & BIT(JP_COLOR)) formats.append(", JPEG Full-Color");
  850.     else if (jp & BIT(JP_GREY))  formats.append(", JPEG Greyscale");
  851.     return (formats);
  852. }
  853. const char* Class2Params::pageWidthNames[8] = {
  854.     "A4 page width (215 mm)",
  855.     "B4 page width (255 mm)",
  856.     "A3 page width (303 mm)",
  857.     "page width 151 mm",
  858.     "page width 107 mm",
  859.     "undefined page width (wd=5)",
  860.     "undefined page width (wd=6)",
  861.     "undefined page width (wd=7)",
  862. };
  863. const char* Class2Params::pageWidthName() const
  864.     { return (pageWidthNames[wd&7]); }
  865. const char* Class2Params::pageLengthNames[4] = {
  866.     "A4 page length (297 mm)",
  867.     "B4 page length (364 mm)",
  868.     "unlimited page length",
  869.     "invalid page length (ln=3)",
  870. };
  871. const char* Class2Params::pageLengthName() const
  872.     { return (pageLengthNames[ln&3]); }
  873. const char* Class2Params::scanlineTimeNames[8] = {
  874.     "0 ms/scanline",
  875.     "5 ms/scanline",
  876.     "10 ms, 5 ms/scanline",
  877.     "10 ms/scanline",
  878.     "20 ms, 10 ms/scanline",
  879.     "20 ms/scanline",
  880.     "40 ms, 20 ms/scanline",
  881.     "40 ms/scanline",
  882. };
  883. const char* Class2Params::scanlineTimeName() const
  884.     { return (scanlineTimeNames[st&7]); }
  885. const char* Class2Params::ecmNames[8] = {
  886.     "no ECM",
  887.     "T.30 Annex A, 64-byte ECM",
  888.     "T.30 Annex A, 256-byte ECM",
  889.     "T.30 Annex C, half duplex ECM",
  890.     "T.30 Annex C, full duplex ECM",
  891.     "undefined ECM",
  892.     "undefined ECM",
  893.     "undefined ECM"
  894. };
  895. const char* Class2Params::ecmName() const
  896.     { return (ecmNames[ec&7]); }