ximaj2k.cpp
Upload User: kairuinn
Upload Date: 2009-02-07
Package Size: 2922k
Code Size: 7k
Category:

Graph program

Development Platform:

Visual C++

  1. /*
  2.  * File: ximaj2k.cpp
  3.  * Purpose: Platform Independent J2K Image Class Loader and Writer
  4.  * 12/Jul/2002 Davide Pizzolato - www.xdp.it
  5.  * CxImage version 5.99a 08/Feb/2004
  6.  */
  7. #include "ximaj2k.h"
  8. #if CXIMAGE_SUPPORT_J2K
  9. #define CEILDIV(a,b) ((a+b-1)/b)
  10. ////////////////////////////////////////////////////////////////////////////////
  11. bool CxImageJ2K::Decode(CxFile *hFile)
  12. {
  13. if (hFile == NULL) return false;
  14.   try
  15.   {
  16. BYTE* src;
  17. long len;
  18. j2k_image_t *img=NULL;
  19. j2k_cp_t *cp=NULL;
  20. long i,x,y,w,h,max;
  21. len=hFile->Size();
  22. src=(BYTE*)malloc(len);
  23. hFile->Read(src, len, 1);
  24. if (!j2k_decode(src, len, &img, &cp)) {
  25. free(src);
  26. throw "failed to decode J2K image!";
  27. }
  28. free(src);
  29.     if (img->numcomps==3 &&
  30. img->comps[0].dx==img->comps[1].dx &&
  31. img->comps[1].dx==img->comps[2].dx &&
  32. img->comps[0].dy==img->comps[1].dy &&
  33. img->comps[1].dy==img->comps[2].dy &&
  34. img->comps[0].prec==img->comps[1].prec &&
  35. img->comps[1].prec==img->comps[2].prec)
  36. {
  37.         w=CEILDIV(img->x1-img->x0, img->comps[0].dx);
  38.         h=CEILDIV(img->y1-img->y0, img->comps[0].dy);
  39.         max=(1<<img->comps[0].prec)-1;
  40. Create(w,h,24,CXIMAGE_FORMAT_J2K);
  41. RGBQUAD c;
  42.         for (i=0,y=0; y<h; y++) {
  43. for (x=0; x<w; x++,i++){
  44. c.rgbRed   = img->comps[0].data[i];
  45. c.rgbGreen = img->comps[1].data[i];
  46. c.rgbBlue  = img->comps[2].data[i];
  47. SetPixelColor(x,h-1-y,c);
  48. }
  49. }
  50. } else {
  51. int compno;
  52. info.nNumFrames = img->numcomps;
  53. if ((info.nFrame<0)||(info.nFrame>=info.nNumFrames)){
  54. j2k_destroy(&img,&cp);
  55. throw "wrong frame!";
  56. }
  57. for (compno=0; compno<=info.nFrame; compno++) {
  58. w=CEILDIV(img->x1-img->x0, img->comps[compno].dx);
  59. h=CEILDIV(img->y1-img->y0, img->comps[compno].dy);
  60. max=(1<<img->comps[compno].prec)-1;
  61. Create(w,h,8,CXIMAGE_FORMAT_J2K);
  62. SetGrayPalette();
  63. for (i=0,y=0; y<h; y++) {
  64. for (x=0; x<w; x++,i++){
  65. SetPixelIndex(x,h-1-y,img->comps[compno].data[i]);
  66. }
  67. }
  68. }
  69. }
  70. j2k_destroy(&img,&cp);
  71.   } catch (char *message) {
  72. strncpy(info.szLastError,message,255);
  73. return FALSE;
  74.   }
  75. return true;
  76. }
  77. ////////////////////////////////////////////////////////////////////////////////
  78. bool CxImageJ2K::Encode(CxFile * hFile)
  79. {
  80. if (EncodeSafeCheck(hFile)) return false;
  81. if (head.biClrUsed!=0 && !IsGrayScale()){
  82. strcpy(info.szLastError,"J2K can save only RGB or GrayScale images");
  83. return false;
  84. }
  85.     int i,x,y;
  86.     j2k_image_t *img;
  87.     j2k_cp_t *cp;
  88.     j2k_tcp_t *tcp;
  89.     j2k_tccp_t *tccp;
  90. img = (j2k_image_t *)calloc(sizeof(j2k_image_t),1);
  91. cp = (j2k_cp_t *)calloc(sizeof(j2k_cp_t),1);
  92.     cp->tx0=0; cp->ty0=0;
  93.     cp->tw=1; cp->th=1;
  94.     cp->tcps=(j2k_tcp_t*)calloc(sizeof(j2k_tcp_t),1);
  95.     tcp=&cp->tcps[0];
  96. long w=head.biWidth;
  97. long h=head.biHeight;
  98.  
  99. tcp->numlayers=1;
  100. for (i=0;i<tcp->numlayers;i++) tcp->rates[i]=(w*h*GetJpegQuality())/600;
  101.     if (IsGrayScale()) {
  102.         img->x0=0;
  103. img->y0=0;
  104. img->x1=w;
  105. img->y1=h;
  106.         img->numcomps=1;
  107.         img->comps=(j2k_comp_t*)calloc(sizeof(j2k_comp_t),1);
  108.         img->comps[0].data=(int*)calloc(w*h*sizeof(int),1);
  109.         img->comps[0].prec=8;
  110.         img->comps[0].sgnd=0;
  111.         img->comps[0].dx=1;
  112.         img->comps[0].dy=1;
  113. for (i=0,y=0; y<h; y++) {
  114. for (x=0; x<w; x++,i++){
  115. img->comps[0].data[i]=GetPixelIndex(x,h-1-y);
  116. }
  117. }
  118.     } else if (!IsIndexed()) {
  119.         img->x0=0;
  120. img->y0=0;
  121. img->x1=w;
  122. img->y1=h;
  123.         img->numcomps=3;
  124.         img->comps=(j2k_comp_t*)calloc(img->numcomps*sizeof(j2k_comp_t),1);
  125.         for (i=0; i<img->numcomps; i++) {
  126.             img->comps[i].data=(int*)calloc(w*h*sizeof(int),1);
  127.             img->comps[i].prec=8;
  128.             img->comps[i].sgnd=0;
  129.             img->comps[i].dx=1;
  130.             img->comps[i].dy=1;
  131.         }
  132. RGBQUAD c;
  133.         for (i=0,y=0; y<h; y++) {
  134. for (x=0; x<w; x++,i++){
  135. c=GetPixelColor(x,h-1-y);
  136. img->comps[0].data[i]=c.rgbRed;
  137. img->comps[1].data[i]=c.rgbGreen;
  138. img->comps[2].data[i]=c.rgbBlue;
  139. }
  140. }
  141.     } else {
  142.         return 0;
  143.     }
  144.     cp->tdx=img->x1-img->x0;
  145. cp->tdy=img->y1-img->y0;
  146.     tcp->csty=0;
  147.     tcp->prg=0;
  148.     tcp->mct=img->numcomps==3?1:0;
  149.     tcp->tccps=(j2k_tccp_t*)calloc(img->numcomps*sizeof(j2k_tccp_t),1);
  150.     int ir=0; /* or 1 ???*/
  151.     for (i=0; i<img->numcomps; i++) {
  152.         tccp=&tcp->tccps[i];
  153.         tccp->csty=0;
  154.         tccp->numresolutions=6;
  155.         tccp->cblkw=6;
  156.         tccp->cblkh=6;
  157.         tccp->cblksty=0;
  158.         tccp->qmfbid=ir?0:1;
  159.         tccp->qntsty=ir?J2K_CCP_QNTSTY_SEQNT:J2K_CCP_QNTSTY_NOQNT;
  160.         tccp->numgbits=2;
  161.         tccp->roishift=0;
  162.         j2k_calc_explicit_stepsizes(tccp, img->comps[i].prec);
  163.     }
  164.     BYTE* dest=(BYTE*)calloc(tcp->rates[tcp->numlayers-1]+2,1);
  165.     long len = j2k_encode(img, cp, dest, tcp->rates[tcp->numlayers-1]+2);
  166.     if (len==0) {
  167. strcpy(info.szLastError,"J2K failed to encode image");
  168.     } else {
  169. hFile->Write(dest, len, 1);
  170. }
  171. free(dest);
  172. j2k_destroy(&img,&cp);
  173. return (len!=0);
  174. }
  175. ////////////////////////////////////////////////////////////////////////////////
  176. static const double dwt_norms_97[4][10]={
  177.     {1.000, 1.965, 4.177, 8.403, 16.90, 33.84, 67.69, 135.3, 270.6, 540.9},
  178.     {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
  179.     {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0},
  180.     {2.080, 3.865, 8.307, 17.18, 34.71, 69.59, 139.3, 278.6, 557.2}
  181. };
  182. ////////////////////////////////////////////////////////////////////////////////
  183. void CxImageJ2K::j2k_calc_explicit_stepsizes(j2k_tccp_t *tccp, int prec) {
  184.     int numbands, bandno;
  185.     numbands=3*tccp->numresolutions-2;
  186.     for (bandno=0; bandno<numbands; bandno++) {
  187.         double stepsize;
  188.         int resno, level, orient, gain;
  189.         resno=bandno==0?0:(bandno-1)/3+1;
  190.         orient=bandno==0?0:(bandno-1)%3+1;
  191.         level=tccp->numresolutions-1-resno;
  192.         gain=tccp->qmfbid==0?0:(orient==0?0:(orient==1||orient==2?1:2));
  193.         if (tccp->qntsty==J2K_CCP_QNTSTY_NOQNT) {
  194.             stepsize=1.0;
  195.         } else {
  196.             double norm=dwt_norms_97[orient][level];
  197.             stepsize=(1<<(gain+1))/norm;
  198.         }
  199.         j2k_encode_stepsize((int)floor(stepsize*8192.0), prec+gain, &tccp->stepsizes[bandno].expn, &tccp->stepsizes[bandno].mant);
  200.     }
  201. }
  202. ////////////////////////////////////////////////////////////////////////////////
  203. void CxImageJ2K::j2k_encode_stepsize(int stepsize, int numbps, int *expn, int *mant) {
  204.     int p, n;
  205.     p=j2k_floorlog2(stepsize)-13;
  206.     n=11-j2k_floorlog2(stepsize);
  207.     *mant=(n<0?stepsize>>-n:stepsize<<n)&0x7ff;
  208.     *expn=numbps-p;
  209. }
  210. ////////////////////////////////////////////////////////////////////////////////
  211. int CxImageJ2K::j2k_floorlog2(int a) {
  212.     int l;
  213.     for (l=0; a>1; l++) {
  214.         a>>=1;
  215.     }
  216.     return l;
  217. }
  218. ////////////////////////////////////////////////////////////////////////////////
  219. #endif  // CXIMAGE_SUPPORT_J2K