⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jbigdec.c

📁 硬件jbig 压缩算法
💻 C
字号:
/*Copyright (c) 2002, 2005 Zoran Corporation. All rights reserved.*/

/** @file jbigdec.c
* A module to decode JBIG data.
*/
#undef PLUS
#include "sys.h"
#define PLUS

#include "jbig.h"
#include "jbighw.h"
#include "string.h"
#include "mallocaligned.h"
#include "printmgr.h"

/**A four byte module id 'decd'*/
#define DECODE_ID (Uint32)(('d' << 24) | ('e' << 16) | ('c' << 8) | 'd')

/**A private structure to hold the state infomation of a decoder.
@ingroup JBIGDEC*/
struct _DECODER
{
	struct _DECODER *self;/**<Should always point to this.*/
	Uint32 id;/**<Should always be DECODE_ID*/
	Uint8 *jmem;/**<Saved jmem from last operation.  Make sure
	jmem is eight byte aligned in this struct.*/
	Uint32 CurrentLine;
	Uint32 LinesInStripe;
	Uint32 CurrentStripe;
	Uint32 StripesInImage;
	Uint32 LineSizeInBytes;
	Uint32 LastEscCode;
	JBIG_BIH bih;/**<The bih for this stream.*/
	Bool HaveLockOnJbig;
	Bool Initialized;
	Bool AlignBuffers; /**<Move unaligned data to eight byte aligned buffers.*/
};

typedef struct _DECODER DECODER;



static Bool IsThisFirstStripeOfImage(DECODER *d);
static Bool IsThisFirstLineOfStripe(DECODER *d);
static void LockJbig(DECODER *d);
static void UnLockJbig(DECODER *d);
static Bool IsInitialized(DECODER *d);
static void TestDecoderPointer(DECODER *d);
static Uint32 JbigBihUnPackLong(Uint8 *src);


/**Test for a bad handle.*/
static void TestDecoderPointer(DECODER *d)
{
	ASSERT(d && (d==d->self) && (d->id == DECODE_ID));
}


/**Read an unsigned long in MSB format.*/
static Uint32 JbigBihUnPackLong(Uint8 *src)
{
	volatile Uint32 l;
	Uint8 *dst = (Uint8*)&l;
	
	dst[0] = src[3];
	dst[1] = src[2];
	dst[2] = src[1];
	dst[3] = src[0];
	
	return l;
}


/**Get the height of the image.  Only call after JbigDecInit().*/
Uint32 JbigDecGetImageHeight(void *decoder)
{
	DECODER *d = (DECODER *)decoder;
	TestDecoderPointer(d);
	ASSERT(IsInitialized(d));
	return d->bih.yd;
}


/**Get the width of the image.  Only call after JbigDecInit().*/
Uint32 JbigDecGetImageWidth(void *decoder)
{
	DECODER *d = (DECODER *)decoder;
	TestDecoderPointer(d);
	ASSERT(IsInitialized(d));
	return d->bih.xd;
}

/**Get the size in bytes of the image.  Only call after JbigDecInit().*/
Uint32 JbigDecGetImageSizeInBytes(void *decoder)
{
	DECODER *d = (DECODER *)decoder;
	TestDecoderPointer(d);
	ASSERT(IsInitialized(d));
	return (d->bih.yd * d->bih.xd)/8;
}

/**Get the stripe size in bytes of the image.  Only call after JbigDecInit().*/
Uint32 JbigDecGetStripeSizeInBytes(void *decoder)
{
	DECODER *d = (DECODER *)decoder;
	TestDecoderPointer(d);
	ASSERT(IsInitialized(d));
	return (d->bih.l0 * d->bih.xd)/8;
}

/**Get the number of stripes in the image.  Only call after JbigDecInit().*/
Uint32 JbigDecGetStripesInImage(void *decoder)
{
	DECODER *d = (DECODER *)decoder;
	TestDecoderPointer(d);
	ASSERT(IsInitialized(d));
	return d->StripesInImage;
}

/**Get the stripe height of the image.  Only call after JbigDecInit().*/
Uint32 JbigDecGetStripeHeight(void *decoder)
{
	DECODER *d = (DECODER *)decoder;
	TestDecoderPointer(d);
	ASSERT(IsInitialized(d));
	return d->bih.l0;
}

/**
* Create a new decoder instance.
*
* @return An opaque pointer to the new decoder.
*/
void *JbigDecNew(void)
{
	DECODER *d = (DECODER *)MallocAligned(sizeof(DECODER),8);
	ASSERT(d!=NULL);
	d->self = d;
	d->id = DECODE_ID;
	d->Initialized = FALSE;
	d->jmem = (Uint8*)MallocAligned(SizeOfJmem, 8);
	ASSERT(d->jmem);
	return (void*)d;
}
/**
* Delete decoder instance.  Cleans up any memory or hw used by this
* decoder.
*
* @param decoder The decoder to delete.
*/
void JbigDecDelete(void *decoder)
{
	DECODER *d = (DECODER *)decoder;
	TestDecoderPointer(d);
	d->self = (DECODER*)-1;
	d->id = 0;
	FreeAligned(d->jmem);
	FreeAligned(d);
}


/**
Read in a BIH.  BIH is a 20 byte structure at the start of JBIG
stream. JbigDecReadBih gives the decoder the image parameters.

@param decoder - the decoder
@param src - pointer to a twenty byte JBIG BIH.

@return JbigStatus;
*/
JbigStatus JbigDecReadBih(void *decoder, Uint8 *src)
{
	DECODER *d = (DECODER *)decoder;
	
	TestDecoderPointer(d);
	
	/*read the BIH from src*/
	d->bih.dl = src[0];
	d->bih.d = src[1];
	d->bih.p = src[2];
	/*if this isn't zero then this isn't a jbig header*/
	d->bih.reserved=src[3];
	ASSERT(d->bih.reserved==0);
	
	d->bih.xd = JbigBihUnPackLong(&src[4]);
	d->bih.yd = JbigBihUnPackLong(&src[8]);
	d->bih.l0 = JbigBihUnPackLong(&src[12]);
	
	d->bih.mx = src[16];
	d->bih.my = src[17];
	d->bih.order = (JbigBihOrder)src[18];
	d->bih.options = (JbigBihOptions)((Uint8)(src[19]& 0x7f));
	
	return JbigSuccess;
}



/**
Initialize the decoder from a bih.  The bih is a 20 byte structure at the start of JBIG
stream. JbigDecReadBih gives the decoder the image parameters.

@param decoder A decoder created with JbigDecNew()
@param src     A pointer to a twenty byte JBIG BIH.

@return JbigStatus;
*/
JbigStatus JbigDecInitFromBih(void *decoder, Uint8 *bih)
{
	DECODER *d = (DECODER *)decoder;
	
	TestDecoderPointer(d);
	
	JbigDecReadBih(decoder, bih);
	
	d->LinesInStripe = d->bih.l0;
	d->StripesInImage = d->bih.yd/d->bih.l0;
	d->CurrentLine = 0;
	d->CurrentStripe = 0;
	d->LineSizeInBytes = d->bih.xd/8;
	d->Initialized = TRUE;
	d->AlignBuffers = TRUE;
	d->LastEscCode = SDRESET;
	
	return JbigSuccess;
}

/**
Initialize the decoder from the height, width, and stripe height.

@param decoder A decoder created with JbigDecNew()
@param h       The hieght of the image in pixels.
@param w       The width of the image in pixels.
@param l0      The number of lines per stripe.

@return JbigStatus;
*/
JbigStatus JbigDecInit(void *decoder, Uint32 h, Uint32 w, Uint32 l0)
{
	DECODER *d = (DECODER *)decoder;
	
	TestDecoderPointer(d);
	
	d->bih.dl		= 0;
	d->bih.d		= 0;
	d->bih.p		= 1;
	d->bih.reserved	= 0;
	d->bih.xd		= 0x12C0;
	d->bih.yd		= 0x80;
	d->bih.l0		= 0x80;
	d->bih.mx		= 0;
	d->bih.my		= 0;
	d->bih.order	= (JbigBihOrder)(JBIG_ILEAVE | JBIG_SMID);
	d->bih.options = (JbigBihOptions)(JBIG_LRLTWO | JBIG_TPBON);	// by Cellming
	//d->bih.options	= (JbigBihOptions)(JBIG_LRLTWO);				// by Cellming
	
	d->LinesInStripe	= d->bih.l0;
	d->StripesInImage	= d->bih.yd / d->bih.l0;
	d->CurrentLine		= 0;
	d->CurrentStripe	= 0;
	d->LineSizeInBytes	= d->bih.xd / 8;
	d->Initialized		= TRUE;
	d->AlignBuffers		= TRUE;
	d->LastEscCode		= SDNORM;
	
	return JbigSuccess;
}

JbigStatus JbigDecInit_ACC(void *decoder, Uint32 h, Uint32 w, Uint32 l0)
{
	DECODER *d = (DECODER *)decoder;
	
	TestDecoderPointer(d);


		
	
	d->bih.dl		= 0;
	d->bih.d		= 0;
	d->bih.p		= 1;
	d->bih.reserved	= 0;
	d->bih.xd		= w;
	d->bih.yd		= h;
	d->bih.l0		= h;
	d->bih.mx		= 0;
	d->bih.my		= 0;
	d->bih.order	= JBIG_ILEAVE;
	d->bih.options = (JbigBihOptions)(JBIG_TPBON | JBIG_TPDON | JBIG_DPON);	// by Cellming
	//d->bih.options	= (JbigBihOptions)(JBIG_LRLTWO);				// by Cellming
	
	d->LinesInStripe	= d->bih.l0;
	d->StripesInImage	= d->bih.yd / d->bih.l0;
	d->CurrentLine		= 0;
	d->CurrentStripe	= 0;
	d->LineSizeInBytes	= d->bih.xd / 8;
	d->Initialized		= TRUE;
	d->AlignBuffers		= TRUE;
	d->LastEscCode		= SDNORM;
	
	return JbigSuccess;
}

// by Cellming
// 2006-04-18

JbigStatus JbigDecoderInit(void *decoder, JBIG_BIH* BJH)
{
	DECODER *d = (DECODER *)decoder;
	
	TestDecoderPointer(d);
	
	d->bih.dl		= BJH->dl;
	d->bih.d		= BJH->d;
	d->bih.p		= BJH->p;
	d->bih.reserved	= BJH->reserved;
	d->bih.xd		= BJH->xd;
	d->bih.yd		= BJH->yd;
	d->bih.l0		= BJH->l0;
	d->bih.mx		= BJH->mx;
	d->bih.my		= BJH->my;
	d->bih.order	= (JbigBihOrder)BJH->order;
	d->bih.options	= (JbigBihOptions)BJH->options;
	
	d->LinesInStripe	= d->bih.l0;
	d->StripesInImage	= d->bih.yd / d->bih.l0;
	d->CurrentLine		= 0;
	d->CurrentStripe	= 0;
	d->LineSizeInBytes	= d->bih.xd / 8;
	d->Initialized		= TRUE;
	d->AlignBuffers		= TRUE;
	d->LastEscCode		= SDNORM;
	
	return JbigSuccess;
}

/*
{
	DECODER *d = (DECODER *)decoder;
	
	TestDecoderPointer(d);
	
	d->bih.xd = w;
	d->bih.yd = h;
	d->bih.p = 1;
	d->bih.d = 0;
	d->bih.dl = 0;
	d->bih.l0 = l0;
	d->bih.mx = 0;
	d->bih.my = 0;
	d->bih.order = JBIG_ILEAVE;
	d->bih.options = (JbigBihOptions)(JBIG_TPBON | JBIG_TPDON | JBIG_DPON);
	
	d->LinesInStripe = d->bih.l0;
	d->StripesInImage = d->bih.yd/d->bih.l0;
	d->CurrentLine = 0;
	d->CurrentStripe = 0;
	d->LineSizeInBytes = d->bih.xd/8;
	d->Initialized = TRUE;
	d->AlignBuffers = TRUE;
	d->LastEscCode = SDRESET;
	
	return JbigSuccess;
}
*/


static Bool IsThisFirstStripeOfImage(DECODER *d)
{
	return (d->CurrentStripe == 0);
}


static Bool IsThisFirstLineOfStripe(DECODER *d)
{
	return (d->CurrentLine == 0);
}


/**Give this decoder exclusive access to jbig hardware by taking the jbig semaphore.*/
static void LockJbig(DECODER *d)
{
	JbigTakeSem();
	d->HaveLockOnJbig = TRUE;
}

/**Allow other modules to use the jbig hardware.*/
static void UnLockJbig(DECODER *d)
{
	JbigGiveSem();
	d->HaveLockOnJbig = FALSE;
}

/**Return true if decoder has been initialized with a call to JbigEncInit(). */
static Bool IsInitialized(DECODER *d)
{
	return (d->Initialized);
}

/**Decode a stripe.
*
* @param decoder An decoder created with JbigDecNew() and
*                initialized with JbigDecInit().
*
* @param dst A buffer to hold decoded data.
*            - Must be aligned on an eight byte boundary.
*
* @param dstsize The size in bytes of dst.
*                - Must be equal to one full stripe.
*
* @param src A buffer that holds JBIG encoded data.
*              - Must be aligned on an eight byte boundary.
*
* @param srcsize The size in bytes of JBIG encoded data.
*                - Must be engough encoded data to make one full stripe.
*
* @param dstused Returns the number of bytes of decoded data written to dst.
*
* @param srcused Returns the number of bytes of encoded data read from src.
*
* @return JbigStatus*/

JbigStatus JbigDecDecodeStripe(void *decoder,
			       Uint8 *dst, Uint32 dstsize,
			       Uint8 *src, Uint32 srcsize,
			       Uint32 *dstused, Uint32 *srcused)
{
	DECODER *d = (DECODER *)decoder;
	Bool FirstLine, FirstStripe;
	Uint32 srcoffset, dstoffset;
	Uint32 nlines;
	Bool PreserveCoder = FALSE;
	
	TestDecoderPointer(d);
	
	ASSERT(IsInitialized(d));
	
	FirstLine = IsThisFirstLineOfStripe(d);
	FirstStripe = IsThisFirstStripeOfImage(d);
	
	if(FirstLine)
		{
		/*If this is the first line of the stripe take the sem.  No one can interrupts
		this decoder until it is done with this stripe.*/
		LockJbig(d);
		JbigReset();
		
		if(FirstStripe || d->LastEscCode==SDRESET)
			JbigJmemErase();
		else
			JbigJmemLoad(d->jmem);
		}
	
	ASSERT(d->HaveLockOnJbig==TRUE);
	
	nlines = dstsize/d->LineSizeInBytes;
	
	JbigSetImageDimentions((Uint16)nlines, (Uint16)d->bih.xd);
	
	JbigUseTwoLineTemplate();
	
	JbigSetSrcAddress(src);
	JbigSetDstAddress(dst);
	
	srcoffset = (Uint32)src & 0x7;
	dstoffset = (Uint32)dst & 0x7;
	
	JbigStartDecode(FirstStripe,
			PreserveCoder,
			SDNORM,
			dstoffset,srcoffset);
	//GPIO35Set(1, GPIO35MODE_PFHPARSER);
	JbigWaitForDone();
	//GPIO35Set(0, GPIO35MODE_PFHPARSER);
	*dstused = JbigGetBytesWritten() - dstoffset;
	*srcused = JbigGetBytesRead() - srcoffset;

	// cm start

	// check status register
	
	ASSERT(!(JbigStripeCorrupted()));		// by Cellming
	ASSERT(!(JbigOverFlow()));				// by Cellming

	// cm end
	
	
	d->LastEscCode = JbigGetEscapeCode();
	
	//  ASSERT(d->LastEscCode==SDRESET || d->LastEscCode==SDNORM);
	if(! (d->LastEscCode==SDRESET || d->LastEscCode==SDNORM))
		{
		PSPRINTF("!!!!!!!!!!!!!!!!!!!!!!!!!!!! Would ASSERT jbigdec.c:378 : d->LastEscCode=%d !!!!!!!!!!!!!!!!!!!\n", d->LastEscCode);
		d->LastEscCode=SDRESET;
		JbigJmemErase();
		UnLockJbig(d);
		return JbigError;
		}
	d->CurrentLine += nlines;
	
	
	if(d->LastEscCode==SDRESET)
		JbigJmemErase();
	
	JbigJmemSave(d->jmem);
	
	UnLockJbig(d);
	d->CurrentStripe++;
	d->CurrentLine = 0;
	
	
	return JbigSuccess;
	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -