]> git.ipfire.org Git - thirdparty/HylaFAX.git/commitdiff
Class1: Fix occasional incorrect EOFB formatting on sending MMR data
authorAidan Van Dyk <aidan@ifax.com>
Mon, 26 Nov 2007 14:02:33 +0000 (14:02 +0000)
committerAidan Van Dyk <aidan@ifax.com>
Mon, 26 Nov 2007 14:02:33 +0000 (14:02 +0000)
From Lee:
| commit 6443b26c32748dec0ce045821d694ad3257cc5fb
| Author: Lee Howard <faxguy@howardsilvan.com>
| Date:   Wed Oct 10 23:52:05 2007 +0000
|
|     This seems necessary now... didn't seem necessary before... but...  who knows.

and
| commit 0bcc521e68c6d031f0d9a6cb2940e06e7ee64770
| Author: Lee Howard <faxguy@howardsilvan.com>
| Date:   Sun Nov 4 01:45:29 2007 +0000
|
|     This removes all of the "lastbyte" code for sending MMR use as well as removes
|     MMR support from correctPhaseCData.
|
|     Long ago I had made an incorrect conclusion that all 2D code words ended with a
|     "1".  And to follow the pattern in the MH and MR contexts sending RTC... in
|     order to send a properly-encoded EOFB I therefore used the "lastbyte" code and
|     such to determine exactly how many zero bits needed to lead the EOFB signal.
|     And because of the incorrect initial conclusion about 2D code words it thus
|     meant that whenever an MMR image ended with a 2D code word ending with a "0"
|     that the EOFB would be corrupt through sendRTC().
|
|     Our MMR encoder puts EOFB correctly at the end of the data stream.  There is no
|     need to try to second-guess our own MMR encoder.  Since we're sticking a tagline
|     at the top of every page (virtually, only not when the page is a very, very thin
|     strip) it means that EOFB will be properly there because when we do that we must
|     reprocess the entire MMR image.
|
|     This is different with MH and MR because in those cases we're not re-encoding
|     the entire page.  And thus a faulty RTC signal (or a duplicate RTC) in the image
|     data can creep in from the source TIFF file which supposedly can be corrupt from
|     Ghostscript or from the client.  So with MH and MMR we are wise to use
|     correctPhaseCData to try to ensure a proper RTC; in the case of MMR it's simply
|     a waste: there's nothing to correct that hasn't already been corrected by the
|     same encoder either in tagline generation or in soft-RTFCC.
|
|     So this ultimately will fix a few cases, perhaps rare, where the receiver was
|     signalling DCN after PPS.

faxd/Class1.h
faxd/Class1Send.c++
faxd/Class2.h
faxd/Class2Send.c++
faxd/FaxModem.c++
faxd/FaxModem.h
faxd/MemoryDecoder.c++
faxd/MemoryDecoder.h

index 1b5c6d2f8115227191c76a08dcef3049ce8609d4..41b451454ecc5c7a9457b015ce9bd30832585fdc 100644 (file)
@@ -132,7 +132,7 @@ protected:
     bool       sendTCF(const Class2Params&, u_int ms);
     bool       sendPage(TIFF* tif, Class2Params&, u_int, u_int, Status& eresult);
     bool       sendPageData(u_char* data, u_int cc, const u_char* bitrev, bool ecm, Status& eresult);
-    bool       sendRTC(Class2Params params, u_int ppmcmd, int lastbyte, uint32 rowsperstrip, Status& eresult);
+    bool       sendRTC(Class2Params params, u_int ppmcmd, uint32 rowsperstrip, Status& eresult);
     bool       sendPPM(u_int ppm, HDLCFrame& mcf, Status& eresult);
     bool       decodePPM(const fxStr& pph, u_int& ppm, Status& eresult);
 // reception support
index 00e00ac948f94b9b42eea10891227e63ab7d6ad7..1311322b312d0db6f09d421fdef5add6cd1c4bc0 100644 (file)
@@ -1613,9 +1613,9 @@ Class1Modem::sendPageData(u_char* data, u_int cc, const u_char* bitrev, bool ecm
  * send all the data they are presented.
  */
 bool
-Class1Modem::sendRTC(Class2Params params, u_int ppmcmd, int lastbyte, uint32 rows, Status& eresult)
+Class1Modem::sendRTC(Class2Params params, u_int ppmcmd, uint32 rows, Status& eresult)
 {
-    if (params.df == DF_JBIG) {
+    if (params.df > DF_2DMR) {
        /*
         * If we ever needed to send NEWLEN or other JBIG-terminating
         * markers this is where we would do it.
@@ -1626,13 +1626,6 @@ Class1Modem::sendRTC(Class2Params params, u_int ppmcmd, int lastbyte, uint32 row
        //return sendClass1ECMData(newlen, 8, rtcRev, true, ppmcmd, eresult);
        return sendClass1ECMData(NULL, 0, rtcRev, true, ppmcmd, eresult);
     }
-
-    // determine the number of trailing zeros on the last byte of data
-    u_short zeros = 0;
-    for (short i = 7; i >= 0; i--) {
-       if (lastbyte & (1<<i)) break;
-       else zeros++;
-    }
     /*
      * These are intentionally reverse-encoded in order to keep
      * rtcRev and bitrev in sendPage() in agreement.  They are also
@@ -1649,15 +1642,6 @@ Class1Modem::sendRTC(Class2Params params, u_int ppmcmd, int lastbyte, uint32 row
        { 0x00,0x18,0x00,0x03,0x60,0x00,0x0C,0x80,0x01,0x30,
          0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
          0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
-    // T.6 does not allow zero-fill until after EOFB and not before.
-    u_char EOFB[3];
-       EOFB[0] = (0x0800 >> zeros) & 0xFF;
-       EOFB[1] = (0x8008 >> zeros) & 0xFF;
-       EOFB[2] = 0x80 >> zeros;
-    if (params.df == DF_2DMMR) {
-       protoTrace("SEND EOFB");
-       return sendClass1ECMData(EOFB, 3, rtcRev, true, ppmcmd, eresult);
-    }
     if (params.is2D()) {
        protoTrace("SEND 2D RTC");
        if (params.ec != EC_DISABLE)
@@ -1714,7 +1698,6 @@ EOLcode(u_long& w)
 bool
 Class1Modem::sendPage(TIFF* tif, Class2Params& params, u_int pageChop, u_int ppmcmd, Status& eresult)
 {
-    int lastbyte = 0;
     if (params.ec == EC_DISABLE) {     // ECM does it later
        /*
         * Set high speed carrier & start transfer.  If the
@@ -1838,10 +1821,10 @@ Class1Modem::sendPage(TIFF* tif, Class2Params& params, u_int pageChop, u_int ppm
        }
 
         /*
-         * correct broken Phase C (T.4/T.6) data if neccessary 
+         * correct broken Phase C (T.4) data if neccessary
          */
-       if (params.df <= DF_2DMMR)
-           lastbyte = correctPhaseCData(dp, &totdata, fillorder, params, rowsperstrip);
+       if (params.df < DF_2DMMR)
+           correctPhaseCData(dp, totdata, fillorder, params, rowsperstrip);
 
        /*
         * Send the page of data.  This is slightly complicated
@@ -1857,7 +1840,6 @@ Class1Modem::sendPage(TIFF* tif, Class2Params& params, u_int pageChop, u_int ppm
         */
        if (params.df <= DF_2DMMR && fillorder != FILLORDER_LSB2MSB) {
            TIFFReverseBits(dp, totdata);
-           lastbyte = frameRev[lastbyte];
        }
        u_int minLen = params.minScanlineSize();
        if (minLen > 0) {                       // only in non-ECM
@@ -1953,7 +1935,7 @@ Class1Modem::sendPage(TIFF* tif, Class2Params& params, u_int pageChop, u_int ppm
        delete data;
     }
     if (rc || abortRequested())
-       rc = sendRTC(params, ppmcmd, lastbyte, rowsperstrip, eresult);
+       rc = sendRTC(params, ppmcmd, rowsperstrip, eresult);
     protoTrace("SEND end page");
     if (params.ec == EC_DISABLE) {
        // these were already done by ECM protocol
index ede53a7ff3b4a3117421741bb74eb18a6c48e2d9..d6f3da9c0424bbf1ee6d78b29ed112f707974e44 100644 (file)
@@ -165,6 +165,5 @@ public:
     bool       reset(long ms);                 // reset modem
     void       setLID(const fxStr& number);    // set local id string
     bool       supportsPolling() const;        // modem capability
-    int                lastByte;
 };
 #endif /* _CLASS2_ */
index 8c1a4fce7c3f5c6d594698029ad295b8aba5cca7..a376ad5cf760adb40adbaf0df7f0353cf64ad2b4 100644 (file)
@@ -495,11 +495,13 @@ Class2Modem::sendPageData(TIFF* tif, u_int pageChop)
        }
 
         /*
-         * correct broken Phase C (T.4/T.6) data if necessary
+         * correct broken Phase C (T.4) data if necessary
          */
-        if (params.df <= DF_2DMMR) {
-           lastByte = correctPhaseCData(dp, &totdata, fillorder, params, rows);
-           lastByte = bitrev[lastByte];
+        if (params.df < DF_2DMMR) {
+           correctPhaseCData(dp, totdata, fillorder, params, rows);
+       } else if (params.df == DF_JBIG) {
+           // JBIG needs the data bit-reversed as we get it backwards from the library
+           TIFFReverseBits(dp, totdata);
        }
 
        beginTimedTransfer();
@@ -516,35 +518,19 @@ Class2Modem::sendPageData(TIFF* tif, u_int pageChop)
 bool
 Class2Modem::sendRTC(Class2Params params)
 {
-    if (params.df == DF_JBIG) return (true);   // nothing to do
+    if (params.df > DF_2DMR) return (true);    // nothing to do
 
-    // determine the number of trailing zeros on the last byte of data
-    u_short zeros = 0;
-    for (short i = 7; i >= 0; i--) {
-       if (lastByte & (1<<i)) break;
-       else zeros++;
-    }
     // these are intentionally reverse-encoded in order to keep
     // rtcRev and bitrev in sendPage() in agreement
     static const u_char RTC1D[9] =
        { 0x00,0x08,0x80,0x00,0x08,0x80,0x00,0x08,0x80 };
     static const u_char RTC2D[10] =
        { 0x00,0x18,0x00,0x03,0x60,0x00,0x0C,0x80,0x01,0x30 };
-    // T.6 does not allow zero-fill until after EOFB and not before.
-    u_char EOFB[3];
-       EOFB[0] = (0x0800 >> zeros) & 0xFF;
-       EOFB[1] = (0x8008 >> zeros) & 0xFF;
-       EOFB[2] = 0x80 >> zeros;
-    if (params.df == DF_2DMMR) {
-       protoTrace("SEND EOFB");
-        return putModemDLEData(EOFB, sizeof (EOFB), rtcRev, getDataTimeout());
-    } else {
-       protoTrace("SEND %s RTC", params.is2D() ? "2D" : "1D");
-       if (params.is2D())
-           return putModemDLEData(RTC2D, sizeof (RTC2D), rtcRev, getDataTimeout());
-       else
-           return putModemDLEData(RTC1D, sizeof (RTC1D), rtcRev, getDataTimeout());
-    }
+    protoTrace("SEND %s RTC", params.is2D() ? "2D" : "1D");
+    if (params.is2D())
+       return putModemDLEData(RTC2D, sizeof (RTC2D), rtcRev, getDataTimeout());
+    else
+       return putModemDLEData(RTC1D, sizeof (RTC1D), rtcRev, getDataTimeout());
 }
 
 /*
index 1140053622db939fd12df41c61ca053b48f7432a..2cad1e78540c284cbf91314d876a73c3e117cf76 100644 (file)
@@ -768,30 +768,21 @@ FaxModem::notifyPageSent(TIFF* tif)
 
 #include "MemoryDecoder.h"
 
-int
-FaxModem::correctPhaseCData(u_char* buf, u_long* pBufSize,
+void
+FaxModem::correctPhaseCData(u_char* buf, u_long& pBufSize,
                             u_int fillorder, const Class2Params& params, uint32& rows)
 {
     u_char* endOfData;
-    int lastbyte = 0;
-    if (params.df == DF_2DMMR) {
-       MemoryDecoder dec1(buf, params.pageWidth(), *pBufSize, fillorder, params.is2D(), true);
-       endOfData = dec1.cutExtraEOFB();
-       lastbyte = dec1.getLastByte();
-       rows = dec1.getRows();
-    } else {
-       MemoryDecoder dec1(buf, params.pageWidth(), *pBufSize, fillorder, params.is2D(), false);
-       dec1.fixFirstEOL();
-       /*
-        * We have to construct new decoder. See comments to cutExtraRTC().
-        */
-       MemoryDecoder dec2(buf, params.pageWidth(), *pBufSize, fillorder, params.is2D(), false);
-       endOfData = dec2.cutExtraRTC();
-       // we don't update rows because we don't decode the entire image
-    }
+    MemoryDecoder dec1(buf, params.pageWidth(), pBufSize, fillorder, params.is2D(), false);
+    dec1.fixFirstEOL();
+    /*
+     * We have to construct new decoder. See comments to cutExtraRTC().
+     */
+    MemoryDecoder dec2(buf, params.pageWidth(), pBufSize, fillorder, params.is2D(), false);
+    endOfData = dec2.cutExtraRTC();
+    // we don't update rows because we don't decode the entire image
     if( endOfData )
-        *pBufSize = endOfData - buf;
-    return lastbyte;
+        pBufSize = endOfData - buf;
 }
 
 u_char*
index 87b91deb3c4f907a0eff3e3ec17b66318c1652d4..17c9e1d2dc75b672a0499dfa77ddc65ee0f95829 100644 (file)
@@ -169,7 +169,7 @@ protected:
 /*
  * Correct if neccessary Phase C (T.4/T.6) data (remove extra RTC/EOFB etc.)
  */
-    int                correctPhaseCData(u_char* buf, u_long* pBufSize,
+    void       correctPhaseCData(u_char* buf, u_long& pBufSize,
                                   u_int fillorder, const Class2Params& params, uint32& rows);
 /*
  * Convert Phase C data...
index 1e06af16718e3e8247261d910540c5e6888fefd4..40e6c1fa2bcda0e40f009798b161fc24503eea4c 100644 (file)
@@ -79,12 +79,6 @@ MemoryDecoder::decodeNextByte()
     return (*bp++);
 }
 
-int
-MemoryDecoder::getLastByte()
-{
-    return (*(endOfData - 1));
-}
-
 void
 MemoryDecoder::invalidCode(const char* type, int x)
 {
index 84066d9fb3e46ec9e222668b4eb242dbe0406aef..a3064bbf1ad29342d2120b944677fc5876667825 100644 (file)
@@ -59,7 +59,6 @@ public:
     u_char* cutExtraEOFB();
     u_char* encodeTagLine (u_long* raster, u_int th, u_int slop);
     u_char* convertDataFormat(const Class2Params& params);
-    int                getLastByte();
 
     void scanPageForBlanks(u_int fillorder, const Class2Params& params);
     const u_char* getEndOfPage()                       { return endOfData; }