www.pudn.com > BloodVessel.rar > ximaj2k.cpp


/* 
 * File:	ximaj2k.cpp 
 * Purpose:	Platform Independent J2K Image Class Loader and Writer 
 * 12/Jul/2002 Davide Pizzolato - www.xdp.it 
 * CxImage version 5.99c 17/Oct/2004 
 */ 
 
#include "ximaj2k.h" 
 
#if CXIMAGE_SUPPORT_J2K 
 
#define CEILDIV(a,b) ((a+b-1)/b) 
 
//////////////////////////////////////////////////////////////////////////////// 
bool CxImageJ2K::Decode(CxFile *hFile) 
{ 
	if (hFile == NULL) return false; 
 
  try 
  { 
	BYTE* src; 
	long len; 
	j2k_image_t *img=NULL; 
	j2k_cp_t *cp=NULL; 
	long i,x,y,w,h,max; 
 
	len=hFile->Size(); 
	src=(BYTE*)malloc(len); 
	hFile->Read(src, len, 1); 
 
	if (!j2k_decode(src, len, &img, &cp)) { 
		free(src); 
		throw "failed to decode J2K image!"; 
	} 
 
	free(src); 
 
    if (img->numcomps==3 && 
		img->comps[0].dx==img->comps[1].dx && 
		img->comps[1].dx==img->comps[2].dx && 
		img->comps[0].dy==img->comps[1].dy && 
		img->comps[1].dy==img->comps[2].dy && 
		img->comps[0].prec==img->comps[1].prec && 
		img->comps[1].prec==img->comps[2].prec) 
	{ 
        w=CEILDIV(img->x1-img->x0, img->comps[0].dx); 
        h=CEILDIV(img->y1-img->y0, img->comps[0].dy); 
        max=(1<comps[0].prec)-1; 
 
		Create(w,h,24,CXIMAGE_FORMAT_J2K); 
 
		RGBQUAD c; 
        for (i=0,y=0; ycomps[0].data[i]; 
				c.rgbGreen = img->comps[1].data[i]; 
				c.rgbBlue  = img->comps[2].data[i]; 
				SetPixelColor(x,h-1-y,c); 
			} 
		} 
	} else { 
		int compno; 
		info.nNumFrames = img->numcomps; 
		if ((info.nFrame<0)||(info.nFrame>=info.nNumFrames)){ 
			j2k_destroy(&img,&cp); 
			throw "wrong frame!"; 
		} 
		for (compno=0; compno<=info.nFrame; compno++) { 
			w=CEILDIV(img->x1-img->x0, img->comps[compno].dx); 
			h=CEILDIV(img->y1-img->y0, img->comps[compno].dy); 
			max=(1<comps[compno].prec)-1; 
			Create(w,h,8,CXIMAGE_FORMAT_J2K); 
			SetGrayPalette(); 
			for (i=0,y=0; ycomps[compno].data[i]); 
				} 
			} 
		} 
	} 
 
	j2k_destroy(&img,&cp); 
 
  } catch (char *message) { 
	strncpy(info.szLastError,message,255); 
	return FALSE; 
  } 
	return true; 
} 
//////////////////////////////////////////////////////////////////////////////// 
bool CxImageJ2K::Encode(CxFile * hFile) 
{ 
	if (EncodeSafeCheck(hFile)) return false; 
 
	if (head.biClrUsed!=0 && !IsGrayScale()){ 
		strcpy(info.szLastError,"J2K can save only RGB or GrayScale images"); 
		return false; 
	} 
 
    int i,x,y; 
    j2k_image_t *img; 
    j2k_cp_t *cp; 
    j2k_tcp_t *tcp; 
    j2k_tccp_t *tccp; 
 
	img = (j2k_image_t *)calloc(sizeof(j2k_image_t),1); 
	cp = (j2k_cp_t *)calloc(sizeof(j2k_cp_t),1); 
 
    cp->tx0=0; cp->ty0=0; 
    cp->tw=1; cp->th=1; 
    cp->tcps=(j2k_tcp_t*)calloc(sizeof(j2k_tcp_t),1); 
    tcp=&cp->tcps[0]; 
 
	long w=head.biWidth; 
	long h=head.biHeight; 
  
	tcp->numlayers=1; 
	for (i=0;inumlayers;i++) tcp->rates[i]=(w*h*GetJpegQuality())/600; 
 
 
    if (IsGrayScale()) { 
        img->x0=0; 
		img->y0=0; 
		img->x1=w; 
		img->y1=h; 
        img->numcomps=1; 
        img->comps=(j2k_comp_t*)calloc(sizeof(j2k_comp_t),1); 
        img->comps[0].data=(int*)calloc(w*h*sizeof(int),1); 
        img->comps[0].prec=8; 
        img->comps[0].sgnd=0; 
        img->comps[0].dx=1; 
        img->comps[0].dy=1; 
		for (i=0,y=0; ycomps[0].data[i]=GetPixelIndex(x,h-1-y); 
			} 
		} 
    } else if (!IsIndexed()) { 
        img->x0=0; 
		img->y0=0; 
		img->x1=w; 
		img->y1=h; 
        img->numcomps=3; 
        img->comps=(j2k_comp_t*)calloc(img->numcomps*sizeof(j2k_comp_t),1); 
        for (i=0; inumcomps; i++) { 
            img->comps[i].data=(int*)calloc(w*h*sizeof(int),1); 
            img->comps[i].prec=8; 
            img->comps[i].sgnd=0; 
            img->comps[i].dx=1; 
            img->comps[i].dy=1; 
        } 
		RGBQUAD c; 
        for (i=0,y=0; ycomps[0].data[i]=c.rgbRed; 
				img->comps[1].data[i]=c.rgbGreen; 
				img->comps[2].data[i]=c.rgbBlue; 
			} 
		} 
    } else { 
        return 0; 
    } 
	 
    cp->tdx=img->x1-img->x0; 
	cp->tdy=img->y1-img->y0; 
 
    tcp->csty=0; 
    tcp->prg=0; 
    tcp->mct=img->numcomps==3?1:0; 
    tcp->tccps=(j2k_tccp_t*)calloc(img->numcomps*sizeof(j2k_tccp_t),1); 
 
    int ir=0; /* or 1 ???*/ 
 
    for (i=0; inumcomps; i++) { 
        tccp=&tcp->tccps[i]; 
        tccp->csty=0; 
        tccp->numresolutions=6; 
        tccp->cblkw=6; 
        tccp->cblkh=6; 
        tccp->cblksty=0; 
        tccp->qmfbid=ir?0:1; 
        tccp->qntsty=ir?J2K_CCP_QNTSTY_SEQNT:J2K_CCP_QNTSTY_NOQNT; 
        tccp->numgbits=2; 
        tccp->roishift=0; 
        j2k_calc_explicit_stepsizes(tccp, img->comps[i].prec); 
    } 
 
    BYTE* dest=(BYTE*)calloc(tcp->rates[tcp->numlayers-1]+2,1); 
    long len = j2k_encode(img, cp, dest, tcp->rates[tcp->numlayers-1]+2); 
 
    if (len==0) { 
		strcpy(info.szLastError,"J2K failed to encode image"); 
    } else { 
		hFile->Write(dest, len, 1); 
	} 
	 
	free(dest); 
	j2k_destroy(&img,&cp); 
 
	return (len!=0); 
} 
//////////////////////////////////////////////////////////////////////////////// 
 
static const double dwt_norms_97[4][10]={ 
    {1.000, 1.965, 4.177, 8.403, 16.90, 33.84, 67.69, 135.3, 270.6, 540.9}, 
    {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0}, 
    {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0}, 
    {2.080, 3.865, 8.307, 17.18, 34.71, 69.59, 139.3, 278.6, 557.2} 
}; 
 
//////////////////////////////////////////////////////////////////////////////// 
void CxImageJ2K::j2k_calc_explicit_stepsizes(j2k_tccp_t *tccp, int prec) { 
    int numbands, bandno; 
    numbands=3*tccp->numresolutions-2; 
    for (bandno=0; bandnonumresolutions-1-resno; 
        gain=tccp->qmfbid==0?0:(orient==0?0:(orient==1||orient==2?1:2)); 
        if (tccp->qntsty==J2K_CCP_QNTSTY_NOQNT) { 
            stepsize=1.0; 
        } else { 
            double norm=dwt_norms_97[orient][level]; 
            stepsize=(1<<(gain+1))/norm; 
        } 
        j2k_encode_stepsize((int)floor(stepsize*8192.0), prec+gain, &tccp->stepsizes[bandno].expn, &tccp->stepsizes[bandno].mant); 
    } 
} 
//////////////////////////////////////////////////////////////////////////////// 
void CxImageJ2K::j2k_encode_stepsize(int stepsize, int numbps, int *expn, int *mant) { 
    int p, n; 
    p=j2k_floorlog2(stepsize)-13; 
    n=11-j2k_floorlog2(stepsize); 
    *mant=(n<0?stepsize>>-n:stepsize<1; l++) { 
        a>>=1; 
    } 
    return l; 
} 
//////////////////////////////////////////////////////////////////////////////// 
#endif 	// CXIMAGE_SUPPORT_J2K