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.
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
* 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.
//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
{ 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)
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
}
/*
- * 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
*/
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
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
bool reset(long ms); // reset modem
void setLID(const fxStr& number); // set local id string
bool supportsPolling() const; // modem capability
- int lastByte;
};
#endif /* _CLASS2_ */
}
/*
- * 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();
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());
}
/*
#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*
/*
* 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...
return (*bp++);
}
-int
-MemoryDecoder::getLastByte()
-{
- return (*(endOfData - 1));
-}
-
void
MemoryDecoder::invalidCode(const char* type, int x)
{
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; }