?? dpcmprocess.cpp
字號:
// DpcmProcess.cpp: implementation of the CDpcmProcess class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "CDpcmDemo.h"
#include "DpcmProcess.h"
#include ".\dpcmprocess.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDpcmProcess::CDpcmProcess()
{
}
CDpcmProcess::~CDpcmProcess()
{
}
/* We use a compact representation with 1 byte per statistics bin,
* thus the numbers directly represent byte sizes.
* This 1 byte per statistics bin contains the meaning of the MPS
* (more probable symbol) in the highest bit (mask 0x80), and the
* index into the probability estimation state machine table
* in the lower bits (mask 0x7F).
*/
/* NOTE: Uncomment the following #define if you want to use the
* given formula for calculating the AC conditioning parameter Kx
* for spectral selection progressive coding in section G.1.3.2
* of the spec (Kx = Kmin + SRL (8 + Se - Kmin) 4).
* Although the spec and P&M authors claim that this "has proven
* to give good results for 8 bit precision samples", I'm not
* convinced yet that this is really beneficial.
* Early tests gave only very marginal compression enhancements
* (a few - around 5 or so - bytes even for very large files),
* which would turn out rather negative if we'd suppress the
* DAC (Define Arithmetic Conditioning) marker segments for
* the default parameters in the future.
* Note that currently the marker writing module emits 12-byte
* DAC segments for a full-component scan in a color image.
* This is not worth worrying about IMHO. However, since the
* spec defines the default values to be used if the tables
* are omitted (unlike Huffman tables, which are required
* anyway), one might optimize this behaviour in the future,
* and then it would be disadvantageous to use custom tables if
* they don't provide sufficient gain to exceed the DAC size.
*
* On the other hand, I'd consider it as a reasonable result
* that the conditioning has no significant influence on the
* compression performance. This means that the basic
* statistical model is already rather stable.
*
* Thus, at the moment, we use the default conditioning values
* anyway, and do not use the custom formula.
*
* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32.
* We assume that int right shift is unsigned if INT32 right shift is,
* which should be safe.
*/
/*
* Finish up at the end of an arithmetic-compressed scan.
*/
void CDpcmProcess::Flush_Bits(j_compress_ptr cinfo)
{
arith_entropy_ptr e = (arith_entropy_ptr) cinfo->entropy;
INT32 temp;
/* Section D.1.8: Termination of encoding */
/* Find the e->c in the coding interval with the largest
* number of trailing zero bits */
if ((temp = (e->a - 1 + e->c) & 0xFFFF0000L) < e->c)
e->c = temp + 0x8000L;
else
e->c = temp;
/* Send remaining bytes to output */
e->c <<= e->ct;
if (e->c & 0xF8000000L) {
/* One final overflow has to be handled */
if (e->buffer >= 0) {
if (e->zc)
do Emit_Byte(cinfo,0x00);
while (--e->zc);
Emit_Byte(cinfo,e->buffer + 1);
if (e->buffer + 1 == 0xFF)
Emit_Byte(cinfo,0x00);
}
e->zc += e->sc; /* carry-over converts stacked 0xFF bytes to 0x00 */
e->sc = 0;
} else {
if (e->buffer == 0)
++e->zc;
else if (e->buffer >= 0) {
if (e->zc)
do Emit_Byte(cinfo,0x00);
while (--e->zc);
Emit_Byte(cinfo,e->buffer);
}
if (e->sc) {
if (e->zc)
do Emit_Byte(cinfo,0x00);
while (--e->zc);
do {
Emit_Byte(cinfo,0xFF);
Emit_Byte(cinfo,0x00);
} while (--e->sc);
}
}
/* Output final bytes only if they are not 0x00 */
if (e->c & 0x7FFF800L) {
if (e->zc) /* output final pending zero bytes */
do Emit_Byte(cinfo,0x00);
while (--e->zc);
Emit_Byte(cinfo,(e->c >> 19) & 0xFF);
if (((e->c >> 19) & 0xFF) == 0xFF)
Emit_Byte(cinfo,0x00);
if (e->c & 0x7F800L) {
Emit_Byte(cinfo,(e->c >> 11) & 0xFF);
if (((e->c >> 11) & 0xFF) == 0xFF)
Emit_Byte(cinfo,0x00);
}
}
}
/*
* The core arithmetic encoding routine (common in JPEG and JBIG).
* This needs to go as fast as possible.
* Machine-dependent optimization facilities
* are not utilized in this portable implementation.
* However, this code should be fairly efficient and
* may be a good base for further optimizations anyway.
*
* Parameter 'val' to be encoded may be 0 or 1 (binary decision).
*
* Note: I've added full "Pacman" termination support to the
* byte output routines, which is equivalent to the optional
* Discard_final_zeros procedure (Figure D.15) in the spec.
* Thus, we always produce the shortest possible output
* stream compliant to the spec (no trailing zero bytes,
* except for FF stuffing).
*
* the probability estimation state machine table,
* derived from Markus Kuhn's JBIG implementation.
*/
void CDpcmProcess::Arith_Encode(j_compress_ptr cinfo, unsigned char *st, int val)
{
extern const INT32 jaritab[];
register arith_entropy_ptr e = cinfo->entropy;
register unsigned char nl, nm;
register INT32 qe, temp;
register int sv;
/* Fetch values from our compact representation of Table D.2:
* Qe values and probability estimation state machine
*/
sv = *st;
qe = jaritab[sv & 0x7F]; /* => Qe_Value */
nl = qe & 0xFF; qe >>= 8; /* Next_Index_LPS + Switch_MPS */
nm = qe & 0xFF; qe >>= 8; /* Next_Index_MPS */
/* Encode & estimation procedures per sections D.1.4 & D.1.5 */
e->a -= qe;
if (val != ((sv >> 7) & (0x00000001))) {
/* Encode the less probable symbol */
if (e->a >= qe) {
/* If the interval size (qe) for the less probable symbol (LPS)
* is larger than the interval size for the MPS, then exchange
* the two symbols for coding efficiency, otherwise code the LPS
* as usual: */
e->c += e->a;
e->a = qe;
}
*st = (sv & 0x80) ^ nl; /* Estimate_after_LPS */
} else {
/* Encode the more probable symbol */
if (e->a >= 0x8000L)
return; /* A >= 0x8000 -> ready, no renormalization required */
if (e->a < qe) {
/* If the interval size (qe) for the less probable symbol (LPS)
* is larger than the interval size for the MPS, then exchange
* the two symbols for coding efficiency: ,it is equal to code
* the LPS.*/
e->c += e->a;
e->a = qe;
}
*st = (sv & 0x80) ^ nm ; /* Estimate_after_MPS ,no change of the sense of the MPS*/
}
/* Renormalization & data output per section D.1.6 */
do {
e->a <<= 1;
e->c <<= 1;
if (--e->ct == 0) {
/* The followning is the byte_out programe.*/
/* Another byte is ready for output */
temp = e->c >> 19;
if (temp > 0xFF) {
/*Handle overflow over all stacked 0xFF bytes */
if (e->buffer >= 0) {
Emit_Byte(cinfo,e->buffer + 1);
if (e->buffer + 1 == 0xFF)
Emit_Byte(cinfo,0x00);
}
/*e->zc += e->sc;*/ /* carry-over converts stacked 0xFF bytes to 0x00 and output them*/
while(e->sc-->0)
Emit_Byte(cinfo,0X00);
e->sc = 0;
/* Note: The 3 spacer bits in the C register guarantee
* that the new buffer byte can't be 0xFF here
* (see page 160 in the P&M JPEG book). */
e->buffer = temp & 0xFF; /* new output byte, might overflow later */
} else if (temp == 0xFF) {
++e->sc; /* stack 0xFF byte (which might overflow later) */
} else {
/* Output all stacked 0xFF bytes, they will not overflow any more */
if (e->buffer >= 0) {
Emit_Byte(cinfo,e->buffer);
if (e->sc) {
while (e->sc--) {
Emit_Byte(cinfo,0xFF);
Emit_Byte(cinfo,0x00);
}
e->sc=0;
}
}
e->buffer = temp & 0xFF; /* new output byte (can still overflow) */
}
e->c &= 0x7FFFFL;
e->ct = 8;
}
} while (e->a < 0x8000L);
}
void CDpcmProcess::Encode_Row(j_compress_ptr cinfo, JSAMPROW row, int i)
{
arith_entropy_ptr entropy = (arith_entropy_ptr) cinfo->entropy;
unsigned char * st;
unsigned char context_a=0;
int num;
int v, v2, m,last_val=0,Rc=0;
entropy->context=0;
/* Encode the MCU data blocks */
for (num = 0; num < cinfo->image_width; num++) {
/* Sections F.1.4.1 & F.1.4.4.1: Encoding of DC coefficients */
/* Table F.4: Point to statistics bin S0 for DC coefficient coding */
st =entropy->dc_stats + entropy->context*5+entropy->context_b[num];
/*predic_val=last_val+((entropy->val_b[num]-Rc)>>1);*/
/*predic_val=RIGHT_SHIFT(last_val+entropy->val_b[num],1);*/
v=Get_Errval(cinfo,last_val,entropy->val_b[num],Rc,entropy->val_b[num+1],row+num);
/* if (i==0)
printf("row[%d]:%x v=%d\n",num,row[num],v);*/
/*v=row[num]-predic_val;*/
/* Figure F.4: Encode_DC_DIFF */
if ((v ) == 0) {
Arith_Encode(cinfo, st, 0);
entropy->context = 0; /* zero diff category */
} else {
Arith_Encode(cinfo, st, 1);
/* Figure F.6: Encoding nonzero value v */
/* Figure F.7: Encoding the sign of v */
if (v > 0) {
st +=1;
Arith_Encode(cinfo, st, 0); /* Table F.4: SS = S0 + 1 */
st += 1; /* Table F.4: SP = S0 + 2 */
entropy->context = 4; /* small positive diff category */
} else {
st +=1;
v = -v;
Arith_Encode(cinfo, st, 1); /* Table F.4: SS = S0 + 1 */
st += 2; /* Table F.4: SN = S0 + 3 */
entropy->context = 8; /* small negative diff category */
}
/* Figure F.8: Encoding the magnitude category of v */
m = 0;
if (v -= 1) {
Arith_Encode(cinfo, st, 1);
m = 1;
v2 = v;
if ( entropy->context_b[num]>8 )
st=entropy->dc_stats+129;
else
st = entropy->dc_stats + 100; /* Table H.3: X1 = X1_context(Db)*/
/*st=entropy->dc_stats+20;*/
while (v2 >>= 1) {
Arith_Encode(cinfo, st, 1);
m <<= 1;
st += 1;
}
}
Arith_Encode(cinfo, st, 0);
/* v -=1;
*m=1;
*if (v>m){
*arith_encode(cinfo,st,1);
*if ( entropy->context_b[num]>8 )
* st=entropy->dc_stats+129;
* else
* st = entropy->dc_stats + 100; * Table H.3: X1 = X1_context(Db)*
*m=2;
* while (v>=m){
* arith_encode (cinfo,st,1);
* m <<=1;
*st +=1;
*}
*}
*arith_encode (cinfo,st,0);*/
/* Section F.1.4.4.1.2: Establish dc_context conditioning category */
if ((m) < (int) (((INT32) 1 << cinfo->arith_dc_L) >> 1))
entropy->context = 0; /* zero diff category */
else if ((m) > (int) (((INT32) 1 << cinfo->arith_dc_U)>>1 ))
entropy->context += 8; /* large diff category */
/* Figure F.9: Encoding the magnitude bit pattern of v */
st += 14;
while (m >>= 1)
Arith_Encode(cinfo, st, (m & v) ? 1 : 0);
}
entropy->context_b[num]=entropy->context;
Rc=entropy->val_b[num];
last_val=entropy->val_b[num]=row[num];
}
}
/*
* Basic output routines.
*
* Note that we do not support suspension while writing a marker.
* Therefore, an application using suspension must ensure that there is
* enough buffer space for the initial markers (typ. 600-700 bytes) before
* calling jpeg_start_compress, and enough space to write the trailing EOI
* (a few bytes) before calling jpeg_finish_compress. Multipass compression
* modes are not supported at all with suspension, so those two are the only
* points where markers will be written.
*/
void CDpcmProcess::Empty_Output_Buffer(j_compress_ptr cinfo)
{
jpeg_destination_mgr *dest = cinfo->dest;
if (JFWRITE(cinfo->outputfile, cinfo->outbuffer, OUTPUT_BUF_SIZE) !=
(size_t) OUTPUT_BUF_SIZE)
exit(0);
dest->next_output_byte = cinfo->outbuffer;
dest->free_in_buffer = OUTPUT_BUF_SIZE;
}
void CDpcmProcess::Emit_Byte(j_compress_ptr cinfo, int val)
{
jpeg_destination_mgr *dest = cinfo->dest;
*(dest->next_output_byte)++ = (JOCTET) val;
if (--dest->free_in_buffer == 0)
Empty_Output_Buffer (cinfo);
}
void CDpcmProcess::Emit_Marker(j_compress_ptr cinfo, JPEG_MARKER mark)
{
Emit_Byte(cinfo, 0xFF);
Emit_Byte(cinfo, (int) mark);
}
void CDpcmProcess::Emit_2Bytes(j_compress_ptr cinfo, int value)
{
Emit_Byte(cinfo, (value >> 8) & 0xFF);
Emit_Byte(cinfo, value & 0xFF);
}
/*
* Write datastream header.
* This consists of an SOI and optional APPn markers.
* We recommend use of the JFIF marker, but not the Adobe marker,
* when using YCbCr or grayscale data. The JFIF marker should NOT
* be used for any other JPEG colorspace. The Adobe marker is helpful
* to distinguish RGB, CMYK, and YCCK colorspaces.
* Note that an application can write additional header markers after
* jpeg_start_compress returns.
*/
void CDpcmProcess::Write_File_Header(j_compress_ptr cinfo)
{
Emit_Marker(cinfo, M_SOI); /* first the SOI */
Emit_2Bytes(cinfo,cinfo->image_width);
Emit_2Bytes(cinfo,cinfo->image_height);
}
void CDpcmProcess::Write_File_Trailer(j_compress_ptr cinfo)
{
Emit_Marker(cinfo, M_EOI);
}
int CDpcmProcess::Find_Bin(UNI_TYPE Q1, UNI_TYPE Q2, UNI_TYPE Q3, UNI_TYPE *sign_ptr)
{
int position=0;
if (Q1 != 0) {
PO_OR_NE(Q1);
MAKE_FIRST_POSITIVE(Q1,Q2,Q3);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -