Return-Path: <owner-tiff@olympiakos.com>
Received: from nataly.at1895.spb.edu (localhost [127.0.0.1])
	by at1895.spb.edu (8.12.4/8.12.4/Debian-4) with ESMTP id g89Cp7Je023303
	for <dron@at1895.spb.edu>; Mon, 9 Sep 2002 16:51:07 +0400
Received: from olympiakos.com (uucp@localhost)
	by nataly.at1895.spb.edu (8.12.4/8.12.4/Debian-4) with UUCP id g89Cp6OA023297
	for dron@at1895.spb.edu; Mon, 9 Sep 2002 16:51:07 +0400
Received: from knot.pu.ru (knot.pu.ru [193.124.85.214] (may be forged))
	by wg.pu.ru (8.9.1a/8.9.1) with ESMTP id MAA24820
	for <dron@at1895.spb.edu>; Mon, 9 Sep 2002 12:32:42 GMT
Received: from gate7.olympiakos.com (sdsl-64-32-199-150.dsl.iad.megapath.net [64.32.199.150])
	by knot.pu.ru (8.9.3/8.9.0) with ESMTP id QAA24163
	for <dron@at1895.spb.edu>; Mon, 9 Sep 2002 16:32:41 +0400 (MSD)
Received: from localhost (daemon@localhost)
	by gate7.olympiakos.com (8.9.3/8.9.3) with SMTP id IAA07622;
	Mon, 9 Sep 2002 08:29:42 -0400
Received: by gate7.olympiakos.com (bulk_mailer v1.9); Mon, 9 Sep 2002 08:22:21 -0400
Received: (from majordom@localhost)
	by gate7.olympiakos.com (8.9.3/8.9.3) id IAA07549
	for tiff-outgoing; Mon, 9 Sep 2002 08:22:20 -0400
X-Authentication-Warning: gate7.olympiakos.com: majordom set sender to owner-tiff@olympiakos.com using -f
Received: from smtp1.rsv.se (smtp1.rsv.se [137.61.237.10])
	by gate7.olympiakos.com (8.9.3/8.9.3) with ESMTP id IAA07546
	for <tiff@Olympiakos.com>; Mon, 9 Sep 2002 08:22:19 -0400
Message-ID: <000801c257fc$3c894780$7f08090a@A25463>
From: "Jan Edmundson" <janedm@rsv.se>
To: "Frank D. Cringle" <fdc@cliwe.ping.de>
Cc: <tiff@olympiakos.com>
References: <008f01c254c2$941ccfe0$7f08090a@A25463> <m3ofbc91ok.fsf@sabre.ping.de>
Subject: Re: Decode group4
Date: Mon, 9 Sep 2002 14:27:16 +0200
MIME-Version: 1.0
Content-Type: text/plain;
	charset="iso-8859-1"
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 5.50.4133.2400
X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400
Content-Transfer-Encoding: 8bit
X-MIME-Autoconverted: from quoted-printable to 8bit by gate7.olympiakos.com id IAA07547
Sender: owner-tiff@olympiakos.com
Precedence: bulk
Content-Transfer-Encoding: 8bit
Status: RO
Content-Length: 5368
Lines: 223


Thanks for the advices I have received.


> "Jan Edmundson" <janedm@rsv.se> writes:
> > Hi all, I am currently in the process of creating a class
> > implementation of the fax group 4 codec.
> 
> In which language? C++?

C++

> 
> > I have a class namned CCodec
> > with 2 methods Decode and Encode. I am focusing on the decoding bit at
> > the moment. I have a hypothesis that the Decode method would be
> > sufficently declared as follows: Decode( BYTE* pDest, DWORD
> > dwDestSize, BYTE* pSrc, DWORD dwSrcSize, DWORD dwRowSize ); Dest
> > should be uncompressed and Src should be compressed.
> 
> That assumes you will always be decoding the entire image.  You need a
> different interface if line-at-a-time decoding is or becomes a
> requirement.

My intensions was to construct a generig codec that was compression oriented, not so much on what is compressed. But I am open for improvments. I think a pragmatic view that get the it properly working is favorable. 

> 
> > Is there someone out there that has a special intrest in the tiff
> > decoding ?
> 
> The roots of the libtiff g3/g4 decoder go back to my code in viewfax.

I took the liberty to look in to the viewfax code and found it easier to adopt to what I liked to do. At a first glance it looks less interconnected in the code.

> 
> > I have ripped code out of libtiff but would like to get a
> > clearer picture of what some of the variables is for in libtiff group
> > 4 decoding.
> 
> Feel free to ask questions.  Note that the code was originally
> developed in the era of 16MHz machines and the aim was to display
> faxes at acceptable interactive rates, rather than maintainability or
> understandability.
> 

This is the point at were I am right now: 

/*** HEADER

class CCodec  
{
public:
 CCodec();
 virtual ~CCodec();

 virtual int Decode( BYTE* pDest, DWORD dwDestSize, BYTE* pSrc, DWORD dwSrcSize, DWORD dwRowSize );
 virtual int Encode( BYTE* pDest, BYTE* pSrc, DWORD dwSize );

protected:
 HANDLE m_hDecode;

};

class CCodecFax4 : public CCodec
{
public:
 int Decode( BYTE* pDest, DWORD dwDestSize, BYTE* pSrc, DWORD dwSrcSize, DWORD dwRowBytes, DWORD dwRowPixels );
 int Encode( BYTE* pDest, BYTE* pSrc, DWORD dwSize );

 void DecodeLine( pixnum *run, int linenum, struct pagenode *pn );

private:
 void Draw(pixnum *run, int linenum, struct pagenode *pn);

 BYTE* m_pDest;
 DWORD m_dwDestSize;

};

// *** CODE

static void drawline(pixnum *run, int linenum, struct pagenode *pn);


CCodec::CCodec()
{
 m_hDecode = CreateSemaphore( NULL, 1, 1, NULL );
}

CCodec::~CCodec()
{
 CloseHandle( m_hDecode );
}

int CCodec::Decode( BYTE* pDest, DWORD dwDestSize, BYTE* pSrc, DWORD dwSrcSize, DWORD dwRowSize )
{
 return 0;
}

int CCodec::Encode( BYTE* pDest, BYTE* pSrc, DWORD dwSize )
{
 return 0;
}

static CCodecFax4* pCodecFax4;

int CCodecFax4::Encode( BYTE* pDest, BYTE* pSrc, DWORD dwSize )
{
 return 0;
}

int CCodecFax4::Decode( BYTE* pDest, DWORD dwDestSize, BYTE* pSrc, DWORD dwSrcSize, DWORD dwRowBytes, DWORD dwRowPixels )
{
 int iRet = 0;
 struct pagenode pn;

 if ( m_hDecode && WaitForSingleObject( m_hDecode, 0L) == WAIT_OBJECT_0 ) {
  m_pDest = pDest;
  m_dwDestSize = dwDestSize;
  pCodecFax4 = this;

  // Setting up viewfax codec.

  pn.data = (unsigned short*) pSrc;
  pn.length = dwRowBytes;
  pn.width = (SHORT) dwRowPixels;

  // pn->vres
  // pn->stripnum
  // pn->inverse

  // Pimage(pn)->data
  // Pimage(pn)->bytes_per_line

  g4expand( &pn, drawline );

  pCodecFax4 = NULL;
  m_dwDestSize = 0;
  m_pDest = NULL;

  ReleaseSemaphore( m_hDecode, 1, NULL );

  iRet = 1;
  }

 return iRet;
}


// If I am correct this is where it should happen...
// this code doesent compile att the moment. Its pasted from viewfax drawline.
// The setting up of p and p1 seems to be the keys to success.

void CCodecFax4::DecodeLine( pixnum *run, int linenum, struct pagenode *pn )
{

    t32bits *p, *p1;  /* p - current line, p1 - low-res duplicate */
    pixnum *r;   /* pointer to run-lengths */
    t32bits pix;  /* current pixel value */
    t32bits acc;  /* pixel accumulator */
    int nacc;   /* number of valid bits in acc */
    int tot;   /* total pixels in line */
    int n;

    linenum += pn->stripnum * pn->rowsperstrip;
    p = (t32bits *) (Pimage(pn)->data + linenum*(2-pn->vres)*Pimage(pn)->bytes_per_line);
    p1 = pn->vres ? NULL : p + Pimage(pn)->bytes_per_line/sizeof(*p);
    r = run;
    acc = 0;
    nacc = 0;
    pix = pn->inverse ? ~0 : 0;
    tot = 0;
    while (tot < pn->width) {
 n = *r++;
 tot += n;
 if (pix)
     acc |= (~(t32bits)0 >> nacc);
 else if (nacc)
     acc &= (~(t32bits)0 << (32 - nacc));
 else
     acc = 0;
 if (nacc + n < 32) {
     nacc += n;
     pix = ~pix;
     continue;
 }
 *p++ = acc;
 if (p1)
     *p1++ = acc;
 n -= 32 - nacc;
 while (n >= 32) {
     n -= 32;
     *p++ = pix;
     if (p1)
  *p1++ = pix;
 }
 acc = pix;
 nacc = n;
 pix = ~pix;
    }
    if (nacc) {
 *p++ = acc;
 if (p1)
     *p1++ = acc;
    }
}

static void drawline( pixnum *run, int linenum, struct pagenode *pn )
{
 if ( pCodecFax4 )
  pCodecFax4->DecodeLine( run, linenum, pn );
}

// *** END

> -- 
> Frank Cringle,      fdc@cliwe.ping.de
> voice: (+49 7745) 928759; fax: 928761
> 


To subscribe or unsubscribe email tiff-request@olympiakos.com with subscribe
or unsubscribe in the email body.  Libtiff home page: http://www.libtiff.org

