00001 
00002 #ifndef  __JBXL_CPP_GRAPHIC_IO_H_
00003 #define  __JBXL_CPP_GRAPHIC_IO_H_
00004 
00005 
00016 #ifdef WIN32
00017 #pragma warning(disable:4995)
00018 #endif
00019 
00020 
00021 #include "Gdata.h"
00022 
00023 
00024 
00025 
00026 namespace jbxl {
00027 
00028 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00090 
00091 CmnHead readUserSetData(FILE* fp, CmnHead* ch, bool cnt=false); 
00092 CmnHead readRasData(FILE* fp);                                  
00093 int     writeRasData(FILE* fp, CmnHead* ch, int obit=8);        
00094 
00095 
00097 
00098 CmnHead readMoonFile(const char* fn, bool no_ntoh=false);   
00099 CmnHead readMoonData(FILE* fp, unsigned int fsz=0, bool no_ntoh=false); 
00100 
00101 int     dicomHeader(FILE* fp, int fsize, int* dsize, int* xsize, int* ysize, int* depth, double* rzxy);
00102 MSGraph<sWord> readDicomFile(const char* fn);
00103 MSGraph<sWord> readDicomData(FILE* fp, int fsz);
00104 
00105 
00107 
00108 
00109 
00110 
00111 
00112 CmnHead readXHead      (const char* fn, CmnHead* ch=NULL);               
00113 CmnHead readXHeadFile  (const char* fn, CmnHead* ch=NULL, bool cnt=false); 
00114 CmnHead readCmnHeadFile(const char* fn, CmnHead* ch, bool cnt=false);        
00115 
00116 int     writeCmnHeadFile(const char* fn, CmnHead* hd, bool cnt=false);
00117 int     writeCmnHeadData(FILE* fp, CmnHead* hd, bool cnt=false);
00118 
00119 
00121 
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131 
00133 
00173 template <typename T>  MSGraph<T> readGraphicFile(const char* fname, CmnHead* chd=NULL, bool cnt=false)
00174 {
00175     MSGraph<T> vp;
00176     CmnHead    hd;
00177     CVCounter* counter = NULL;
00178 
00179     counter = GetUsableGlobalCounter();
00180     if (counter!=NULL) {
00181         counter->SetMax(100);
00182         counter->MakeChildCounter(80);
00183     }
00184 
00185     vp.init();
00186 
00187     hd = readXHeadFile(fname, chd, cnt);
00188     if (counter!=NULL) counter->DeleteChildCounter();   
00189 
00190     
00191     if (hd.kind==HEADER_NONE) {
00192         free_CmnHead(&hd);
00193         if (hd.xsize<0) vp.state = hd.xsize;
00194         else            vp.state = JBXL_GRAPH_HEADER_ERROR;
00195         return vp;
00196     }
00197 
00198     
00199     int chk = hd.kind & 0x00ff;
00200     if (chk==UN_KNOWN_DATA) {
00201         if (chd!=NULL) *chd = hd;
00202         else  free_CmnHead(&hd);
00203         vp.state = JBXL_GRAPH_HEADER_ERROR;
00204         return vp;
00205     }
00206 
00207     if (counter!=NULL) counter->MakeChildCounter(80);
00208 
00209     if (cnt) {
00210         CVCounter* counter = GetUsableGlobalCounter();
00211         if (counter!=NULL) counter->SetTitle("画像データへ変換");
00212     } 
00213 
00214     if (chd!=NULL) {
00215         *chd = hd;
00216         chd->grptr = chd->buf = NULL;
00217     }
00218 
00219     vp = copyCmnHead2MSGraph<T>(hd, CH2MG_NORMAL, cnt);
00220     free_CmnHead(&hd);
00221     if (vp.gp==NULL) return vp;
00222 
00223     if (ZeroBase!=0) {
00224         vp.base += ZeroBase;
00225         for (int i=0; i<vp.xs*vp.ys*vp.zs; i++) vp.gp[i] += (T)ZeroBase;
00226     }
00227 
00228     if (counter!=NULL){
00229         counter->DeleteChildCounter();
00230         counter->PutFill();
00231     }
00232 
00233     return  vp;
00234 }
00235 
00236 
00262 template <typename T>  MSGraph<T>  readGraphicSlices(const char* fmt, int fst, int fnd, CmnHead* chd=NULL, bool cnt=false)
00263 {
00264     int   i, k, l, m, chk, kind;
00265     int   xsize, ysize, zsize, nsize, psize;    
00266                                                 
00267     char* fr_name;                      
00268     CmnHead    dhd, hd;
00269     MSGraph<T> vp, gd;
00270 
00271     if (chd!=NULL) {
00272         DEBUG_MESG("readGraphicSlices: Called with kind = 0x%04x\n", chd->kind);
00273     }
00274     else {
00275         DEBUG_MESG("readGraphicSlices: Called with NULL Header\n");
00276     }
00277 
00278     gd.init();
00279     vp.init();
00280 
00281     
00282     fr_name = numbering_name(fmt, fst);
00283     dhd = readXHead(fr_name, chd);
00284     freeNull(fr_name);
00285 
00286     chk = dhd.kind & 0x00ff;
00287     if (dhd.kind==HEADER_NONE || chk==UN_KNOWN_DATA) {
00288         DEBUG_MODE PRINT_MESG("readGraphicSlices: ヘッダ読み込みエラー: kind = %d\n", dhd.kind);
00289         free_CmnHead(&dhd);
00290         vp.state = JBXL_GRAPH_HEADER_ERROR;
00291         vp.zs = fst;
00292         return vp;
00293     }
00294     kind  = dhd.kind;
00295     xsize = dhd.xsize;
00296     ysize = dhd.ysize;
00297     zsize = Max(dhd.zsize, 1);
00298     nsize = zsize*(Xabs(fnd - fst) + 1);
00299     psize = xsize*ysize*zsize;
00300     if (dhd.depth==16) gd.color = GRAPH_COLOR_MONO16;
00301     else               gd.color = GRAPH_COLOR_MONO;
00302 
00303     
00304     CVCounter* counter = NULL;
00305     if (nsize>=10 && cnt) {
00306         counter = GetUsableGlobalCounter();
00307         if (counter!=NULL) {
00308             
00309             counter->SetMax(nsize/10);
00310             counter->SetPos(1);
00311         }
00312     }
00313 
00314     
00315     if (dhd.buf!=NULL && (chk==CT_DATA || chk==CT_3DM || chk==DICOM_DATA)) {
00316         sWord* rz  = (sWord*)dhd.buf;
00317         if (rz[9]==RZXY_RATE || checkBit(dhd.kind, HAS_RZXY)) {
00318             double rzm = rz[8]/(double)rz[9];
00319             if (rzm<5.0 && rzm>0.) gd.RZxy = rzm;
00320         }
00321 
00322         if (rz[10]!=0 && checkBit(dhd.kind, HAS_BASE)) {
00323             gd.base = (T)rz[10];
00324         }
00325 
00326         if (checkBit(dhd.kind, HAS_RBOUND)) {
00327             gd.rbound.xmin = rz[6];
00328             gd.rbound.xmax = rz[7];
00329             gd.rbound.ymin = rz[4];
00330             gd.rbound.ymax = rz[5];
00331             gd.rbound.zmin = rz[2];
00332             gd.rbound.zmax = rz[3];
00333         }
00334     }
00335     free_CmnHead(&dhd);
00336 
00337     dhd.kind = kind;
00338     if (chd!=NULL) dhd.kind |= chd->kind & 0xff00;      
00339     *chd = getinfo_CmnHead(dhd);
00340 
00341     
00342     gd.getm(xsize, ysize, nsize);
00343     if (gd.isNull()) return gd;
00344 
00345     l = 0;
00346     k = fst;
00347     m = Sign(fnd - fst);
00348     while(k != fnd+m){
00349         fr_name = numbering_name(fmt, k);
00350         hd = readCmnHeadFile(fr_name, &dhd, false); 
00351         free(fr_name);
00352 
00353         chk = hd.kind & 0x00ff;
00354         if (hd.kind==HEADER_NONE || chk==UN_KNOWN_DATA) {
00355             DEBUG_MESG("readGraphicSlices: データ読み込みエラー: n = %d, kind = %d\n", k, hd.kind);
00356             free_CmnHead(&hd);
00357             if (l==0) {     
00358                 gd.free();
00359                 vp.state = JBXL_GRAPH_HEADER_ERROR;
00360                 vp.zs = k;
00361                 return vp;
00362             }
00363             else {          
00364                 gd.state = l;
00365                 gd.zs = l*zsize;
00366                 break;
00367             }
00368         }
00369 
00370         vp = copyCmnHead2MSGraph<T>(hd, CH2MG_NOPARM, false);   
00371         if (vp.isNull()) {
00372             free_CmnHead(&hd);
00373             gd.free();
00374             vp.free();
00375             vp.state = JBXL_GRAPH_MEMORY_ERROR;
00376             vp.zs = k;
00377             return vp;
00378         }
00379 
00380         
00381         for (i=0; i<psize; i++) gd.gp[i + psize*l] = vp.gp[i] + ZeroBase;
00382         if (l==0) {
00383             gd.min = vp.min;
00384             gd.max = vp.max;
00385         }
00386         else {
00387             gd.min = Min(gd.min, vp.min);
00388             gd.max = Max(gd.max, vp.max);
00389         }
00390 
00391         
00392         free_CmnHead(&hd);
00393         vp.free();
00394         k += m;
00395         l++;
00396 
00397         
00398         if (counter!=NULL && l%10==0) {
00399             counter->StepIt();
00400             if (counter->isCanceled()) {    
00401                 gd.free();
00402                 vp.state = JBXL_GRAPH_CANCEL;
00403                 vp.zs = k;
00404                 return vp;
00405             }
00406         }
00407     }
00408     gd.state = l;
00409     gd.base += ZeroBase;
00410 
00411     if (!checkBit(kind, HAS_RBOUND)) gd.rbound.set(0, gd.xs-1, 0, gd.ys-1, 0, gd.zs-1);
00412     if (chd!=NULL) {
00413         if ((chd->kind&0x00ff)==USERSET_DATA) {
00414             CVCounter* counter = GetUsableGlobalCounter();
00415             if (counter!=NULL) counter->SetTitle("Converting Data");
00416             *chd = copyMSGraph2CmnHead(gd);
00417         }
00418     }
00419     if (counter!=NULL) {
00420         counter->PutFill();
00421         
00422     }
00423    
00424     return gd;
00425 }
00426 
00427 
00459 template <typename T>  int  writeGraphicFile(const char *fname, MSGraph<T> vp, int kind=0, int mlt=FALSE, int fnum=0, int tnum=0, bool cnt=false)
00460 {
00461     int     ret;
00462     CmnHead hd;
00463     CTHead* chd;
00464 
00465     if (fnum<0)            fnum = 0;
00466     else if (fnum>vp.zs-1) fnum = vp.zs - 1;
00467     if (tnum<fnum)         tnum = fnum;
00468     else if (tnum>vp.zs-1) tnum = vp.zs - 1;
00469 
00470     
00471     if ((kind&0x00ff)==JPEG_RGB_DATA) {
00472         if      (vp.color==GRAPH_COLOR_ARGB)   kind = (kind&0xff00) + JPEG_ARGB_DATA;
00473         else if (vp.color==GRAPH_COLOR_RGBA)   kind = (kind&0xff00) + JPEG_RGBA_DATA;
00474 
00475         if      (vp.color==GRAPH_COLOR_RGB16)  kind = (kind&0xff00) + JPEG16_RGB_DATA;
00476         else if (vp.color==GRAPH_COLOR_ARGB16) kind = (kind&0xff00) + JPEG16_ARGB_DATA;
00477         else if (vp.color==GRAPH_COLOR_RGBA16) kind = (kind&0xff00) + JPEG16_RGBA_DATA;
00478     }
00479 
00480     
00481     hd.xsize = vp.xs;
00482     hd.ysize = vp.ys;
00483     hd.zsize = tnum - fnum + 1; 
00484     hd.depth = sizeof(T)*8;
00485     hd.grptr = (uByte*)(vp.gp + vp.xs*vp.ys*fnum);
00486     if (kind==0) {
00487         hd.kind  = CT_3DM;
00488         if (hd.zsize==1) hd.kind = CT_DATA;
00489     }
00490     else hd.kind = kind;
00491 
00492     hd.lsize = hd.zsize*hd.ysize*hd.zsize*2;
00493     hd.bsize = sizeof(CTHead);
00494     hd.buf   = (uByte*)malloc(hd.bsize);
00495     if (hd.buf==NULL) return JBXL_GRAPH_OPFILE_ERROR;
00496     memset(hd.buf, 0, hd.bsize);
00497 
00498     chd           = (CTHead*)hd.buf;
00499     chd->xsize    = (sWord)vp.xs;
00500     chd->ysize    = (sWord)vp.ys;
00501     chd->ctmin    = (sWord)vp.rbound.zmin;
00502     chd->ctmax    = (sWord)vp.rbound.zmax;
00503     chd->cutup    = (sWord)vp.rbound.ymin;
00504     chd->cutdown  = (sWord)vp.rbound.ymax;
00505     chd->cutleft  = (sWord)vp.rbound.xmin;
00506     chd->cutright = (sWord)vp.rbound.xmax;
00507     hd.kind      |= HAS_RBOUND;
00508 
00509     if (vp.RZxy!=1.0) {
00510         chd->anydata[0] = (sWord)(vp.RZxy*RZXY_RATE);
00511         chd->anydata[1] = (sWord)RZXY_RATE;
00512         hd.kind        |= HAS_RZXY;
00513     }
00514 
00515     if (vp.base!=0) {
00516         chd->anydata[2] = (sWord)vp.base + TempBase;
00517         hd.kind        |= HAS_BASE;
00518     }
00519 
00520     
00521     if (!mlt) {
00522         ret = writeCmnHeadFile(fname, &hd, cnt);
00523     }
00524 
00525     
00526     else {
00527         
00528         CVCounter* counter = NULL;
00529         if (hd.zsize>=10 && cnt) {
00530             counter = GetUsableGlobalCounter();
00531             if (counter!=NULL) {
00532                 counter->SetMax((hd.zsize+1)/10);
00533                 counter->SetPos(1);
00534             }
00535         }
00536 
00537         char filename[LNAME];
00538         int num = hd.zsize;
00539         int cnt = fnum;
00540         hd.zsize = 1;
00541 
00542         for (int i=0; i<num; i++) {
00543             snprintf(filename, LNAME-2, fname, cnt);
00544             hd.grptr = (uByte*)(vp.gp + vp.xs*vp.ys*cnt);
00545             ret = writeCmnHeadFile(filename, &hd, false);
00546             
00547             if (counter!=NULL && i%10==0) {
00548                 counter->StepIt();
00549                 if (counter->isCanceled()) {    
00550                     if (hd.buf!=NULL) free(hd.buf);
00551                     return JBXL_GRAPH_CANCEL;
00552                 }
00553             }
00554             if (ret<0) break;
00555             cnt++;
00556         }
00557         if (counter!=NULL) counter->PutFill();
00558     }
00559 
00560     if (hd.buf!=NULL) free(hd.buf);
00561     
00562     return ret;
00563 }
00564 
00565 
00569 template <typename T>  int  writeRasFile(const char *fname, MSGraph<T> vp)
00570 {
00571     if (fname==NULL) return JBXL_GRAPH_IVDARG_ERROR;
00572 
00573     FILE* fp = fopen(fname, "wb");
00574     if (fp==NULL) return JBXL_GRAPH_OPFILE_ERROR;
00575 
00576     CmnHead hd = copyMSGraph2CmnHead(vp);
00577     writeRasData(fp, &hd);
00578 
00579     fclose(fp);
00580     return JBXL_NORMAL;
00581 }
00582 
00583 
00587 template <typename T>  MSGraph<T>  readRasFile(const char *fname)
00588 {
00589     MSGraph<T> vp;
00590     CmnHead    hd;
00591     FILE* fp;
00592 
00593     vp.init();
00594     fp = fopen(fname, "rb");
00595     if (fp==NULL) return vp;
00596 
00597     hd = readRasData(fp);
00598     fclose(fp);
00599 
00600     vp = copyCmnHead2MSGraph<T>(hd, CH2MG_NORMAL);
00601     return vp;
00602 }
00603 
00604 
00605 }       
00606 
00607 
00608 #endif