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

📄 jbigenc.c

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

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

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

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

/**A private structure to hold the state information of an encoder
@ingroup JBIGENC
*/
struct _ENCODER
{
	struct _ENCODER *self;	// Should always point to this.
	Uint32 id;				// Should always be ENCODE_ID
	Uint8 *jmem;			// Saved jmem from last operation.  
							// Make sure jmem is 8 bytes aligned in this struct.
	Uint32 CurrentLine;		// The next line of the image to encode.
	Uint32 LinesInStripe;	// The number of lines per stripe.
	Uint32 CurrentStripe;	// The next stripe to encode.
	Uint32 StripesInImage;	// The number of stripes in the image.
	Uint32 LineSizeInBytes;
	Uint32 StripeEndBehavior;
	Bool HaveLockOnJbig;	// Do we have the jbig hw locked?
	Bool AlignBuffers;		// Move unaligned data to eight byte aligned buffers.
	Bool Initialized;
	
	JBIG_BIH bih;			// The bih for this stream.
};

typedef struct _ENCODER ENCODER;

static Bool IsThisFirstStripeOfImage(ENCODER *e);
static Bool IsThisFirstLineOfStripe(ENCODER *e);
static void LockJbig(ENCODER *e);
static void UnLockJbig(ENCODER *e);
static Bool IsInitialized(ENCODER *e);
static void TestEncoderPointer(ENCODER *e);

/**Test for a bad handle.*/
static void TestEncoderPointer(ENCODER *e)
{
	ASSERT(e && (e==e->self) && (e->id == ENCODE_ID));
}




// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// ~~~ create a new encoder instance ~~~

/*
*
*
* @return	An opaque pointer to the new instance.
*
*
*/

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


void *JbigEncNew(void)
{
	ENCODER *e = (ENCODER *)MallocAligned(sizeof(ENCODER),4);
	ASSERT(e!=NULL);
	
	e->self				= e;
	e->id				= ENCODE_ID;
	e->HaveLockOnJbig	= FALSE;
	e->Initialized		= FALSE;
	e->jmem				= MallocAligned(SizeOfJmem, 8);
	ASSERT(e->jmem);
	
	return (void*)e;
}



// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// ~~~ initialize a new encoder instance ~~~

/*
* Initialize an encoder with the image hieght, with, stripe hieght,
* and number of bit planes.  The number of bit planes must be 1.
*
* @param encoder	An encoder created with JbigEncNew().
* @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 JbigEncInit(void *encoder, Uint32 h, Uint32 w, Uint16 l0)
{
	ENCODER *e = (ENCODER *)encoder;
	TestEncoderPointer(e);
	
	e->bih.yd		= h;
	e->bih.xd		= w;
	e->bih.l0		= l0;
	e->bih.p		= 1;
	e->bih.d		= 0;
	e->bih.dl		= 0;
	e->bih.mx		= 0;
	e->bih.my		= 0;
	e->bih.order	= JBIG_ILEAVE;
	e->bih.options	= (JbigBihOptions)(JBIG_TPBON | JBIG_TPDON | JBIG_DPON);
	
	e->LinesInStripe	= e->bih.l0;
	e->StripesInImage	= e->bih.yd/e->bih.l0;
	e->CurrentLine		= 0;
	e->CurrentStripe	= 0;
	e->LineSizeInBytes	= e->bih.xd/8;
	e->AlignBuffers		= TRUE;
	e->Initialized		= TRUE;
	e->StripeEndBehavior= SDRESET;
	
	return JbigSuccess;
}


/**
* Write a long, l, to dst in most significant byte first order.
*
* @param dst Where to write the result.
* @param l   The value to write.
*/
static void JbigBihPackLong(Uint8 *dst, Uint32 l)
{
	Uint8 *src = (Uint8*)&l;
	
	dst[0] = src[3];
	dst[1] = src[2];
	dst[2] = src[1];
	dst[3] = src[0];
	
}
/**
* Write the BIH for this encoder to dst.
*
* @param encoder An encoder created with JbigEncNew() and
*                Initialized with JbigEncInit().
* @param dst Where to write the BIH.  dst must have at least 20 bytes
*             of storage.
*
* @return JbigStatus*/
JbigStatus JbigEncWriteBih(void *encoder, Uint8 *dst)
{
	ENCODER *e = (ENCODER *)encoder;
	
	TestEncoderPointer(e);
	
	/*write the BIH to dst*/
	dst[0] = e->bih.dl;
	dst[1] = e->bih.d;
	dst[2] = e->bih.p;
	dst[3] = 0;
	
	JbigBihPackLong(&dst[4], e->bih.xd);
	JbigBihPackLong(&dst[8], e->bih.yd);
	JbigBihPackLong(&dst[12], e->bih.l0);
	
	dst[16] = e->bih.mx;
	dst[17] = e->bih.my;
	dst[18] = (Uint8)e->bih.order;
	dst[19] = (Uint8)(e->bih.options & 0x7f);
	
	return JbigSuccess;
}



/**
* Delete encoder instance.  Cleans up any memory or hw used by this encoder.
*
* @param encoder An encoder created with JbigEncNew() and
*                initialized with JbigEncInit().
*/
void JbigEncDelete(void *encoder)
{
	ENCODER *e = (ENCODER *)encoder;
	TestEncoderPointer(e);
	
	ASSERT(e->HaveLockOnJbig==FALSE);
	
	e->self = (ENCODER*)-1;
	e->id = 0;
	
	FreeAligned(e->jmem);
	FreeAligned(e);
}




/**Return true if this is the first stripe of the encoded image.*/
static Bool IsThisFirstStripeOfImage(ENCODER *e)
{
	return (e->CurrentStripe == 0);
}

/**Return true if this is the first line of the current stripe.*/
static Bool IsThisFirstLineOfStripe(ENCODER *e)
{
	return (e->CurrentLine == 0);
}

/**Return true if there are no more lines left in this stripe to encode.*/
static Bool IsStripeDone(ENCODER *e)
{
	return (e->CurrentLine == e->LinesInStripe);
}


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


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


/**Get the height of the image.  Only call after JbigEncInit().*/
Uint32 JbigEncGetImageHeight(void *encoder)
{
	ENCODER *e = (ENCODER *)encoder;
	TestEncoderPointer(e);
	return e->bih.yd;
}


/**Get the width of the image.  Only call after JbigEncInit().*/
Uint32 JbigEncGetImageWidth(void *encoder)
{
	ENCODER *e = (ENCODER *)encoder;
	TestEncoderPointer(e);
	ASSERT(IsInitialized(e));
	return e->bih.xd;
}

/**Get the size in bytes of the image.  Only call after JbigEncInit().*/
Uint32 JbigEncGetImageSizeInBytes(void *encoder)
{
	ENCODER *e = (ENCODER *)encoder;
	TestEncoderPointer(e);
	ASSERT(IsInitialized(e));
	return (e->bih.xd * e->bih.yd)/8;
}

/**Get the stripe size in bytes of the image.  Only call after JbigEncInit().*/
Uint32 JbigEncGetStripeSizeInBytes(void *encoder)
{
	ENCODER *e = (ENCODER *)encoder;
	TestEncoderPointer(e);
	ASSERT(IsInitialized(e));
	return (e->bih.l0 * e->bih.xd)/8;
}

/**Get the number of stripes in the image.  Only call after JbigEncInit().*/
Uint32 JbigEncGetStripesInImage(void *encoder)
{
	ENCODER *e = (ENCODER *)encoder;
	TestEncoderPointer(e);
	ASSERT(IsInitialized(e));
	return e->StripesInImage;
}

/**Get the stripe height of the image.  Only call after JbigEncInit().*/
Uint32 JbigEncGetStripeHeight(void *encoder)
{
	ENCODER *e = (ENCODER *)encoder;
	TestEncoderPointer(e);
	ASSERT(IsInitialized(e));
	return e->bih.l0;
}


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


/**Look at the encoded band for the esc sequence for SDNOR it's {0xFF,
0x2}; and for SDRESET it is {0xFF, 0x3}.  Return the first byte
after the escape code, so we can start the nex stripe there.*/
static Uint32 JbigAddEscCode(Uint8* start, Uint32 cc, Uint8 esc)
{
	/*look to see if esc is already there*/
	if( start[cc-2] == 0xFF &&
		start[cc-1] == 0x02)
		{
		/*We usually end up here...*/
		return cc;
		}
	
	/*but this is copied from the users guide, just in case.*/
	while(start[cc]==0) cc--;
	
	start[cc-2] = 0xFF;
	start[cc-1] = 0x02;
	
	return cc;
}


// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// ~~~ encode a stripe ~~~

/*
* @param encoder	An encoder created with JbigEncNew() and
*					initialized with JbigEncInit().
* @param dst		A buffer to hold JBIG encoded data.
*					- Must be aligned on an eight byte boundary.
* @param dstsize	The size in bytes of dst.
*					- A safe dstsize is size of the unencoded stripe.
* @param src		A buffer that holds raw data.
*					- Must be aligned on an eight byte boundary.
* @param srcsize	The size in bytes of raw data.
*					- Must be equal to one full stripe.
* @param dstused	Returns the number of bytes of encoded data written to dst.
* @param srcused	Returns the number of bytes of raw data read from src.
*
* @return	JbigStatus
*/

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


JbigStatus JbigEncEncodeStripe( void *encoder,
								Uint8 *dst,
								Uint32 dstsize,
								Uint8 *src,
								Uint32 srcsize,
								Uint32 *dstused,
								Uint32 *srcused )
{
	
	ENCODER *e = (ENCODER *)encoder;
	Bool FirstLine, FirstStripe;
	Uint32 srcoffset, dstoffset;
	Uint32 nlines;
	Bool PreserveCoder;
	
	TestEncoderPointer(e);
	
	ASSERT(IsInitialized(e));
	
	FirstLine = IsThisFirstLineOfStripe(e);
	FirstStripe = IsThisFirstStripeOfImage(e);
	
	if(FirstLine)
		{
		LockJbig(e);
		JbigReset();
		if(FirstStripe || e->StripeEndBehavior==SDRESET)
			JbigJmemErase();
		else
			JbigJmemLoad(e->jmem);
		
		}
	
	ASSERT(e->HaveLockOnJbig);
	
	nlines = srcsize/e->LineSizeInBytes;
	
	JbigSetImageDimentions((Uint16)nlines, (Uint16)e->bih.xd);
	
	JbigUseTwoLineTemplate();
	
	JbigSetSrcAddress(src);
	JbigSetDstAddress(dst);
	
	srcoffset = (Uint32)src & 0x7;
	dstoffset = (Uint32)dst & 0x7;
	
	
	// If this is not the last band of line
	// then preserve the coders internal state.
	
	PreserveCoder = FALSE; //!((e->CurrentLine + nlines) == e->LinesInStripe);
	
	JbigStartEncode( FirstStripe,
					 PreserveCoder,
					 SDNORM,
					 dstoffset,
					 srcoffset );
	
	JbigWaitForDone();
	
	// It's important to remember that counts
	// like source used and destination used
	// are offsets from the eight byte alinged base address.
	
	*dstused = JbigGetBytesWritten() - dstoffset;
	*srcused = JbigGetBytesRead() - srcoffset;
	
	ASSERT(!(JbigStripeCorrupted()));
	
	*dstused = JbigAddEscCode(dst, *dstused, SDNORM);
	
	e->CurrentLine += nlines;
	
	JbigJmemSave(e->jmem);
	
	// End of this stripe release the hw.
	
	if(IsStripeDone(e))
		{
		UnLockJbig(e);
		e->CurrentStripe++;
		e->CurrentLine = 0;
		}
	
	return JbigSuccess;
}








⌨️ 快捷键说明

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