📄 jbigenc.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 + -