JunkBox_Lib  1.10.2
gio.c
Go to the documentation of this file.
1 
9 #include "gio.h"
10 #include "jbxl_state.h"
11 
12 
14 
15 
17 // ファイル名によるI/Oサポート
18 
34 int write_wsg_file(const char* fname, WSGraph gr)
35 {
36  CmnHead hd;
37  unsigned int i;
38 
39  hd.xsize = gr.xs;
40  hd.ysize = gr.ys;
41  hd.zsize = gr.zs;
42  hd.depth = 16;
43  hd.grptr = (uByte*)gr.gp;
44  hd.kind = CT_3DM;
45 
46  if (hd.zsize<=1){
47  hd.zsize = 1;
48  hd.kind = CT_DATA;
49  }
50  hd.lsize = (hd.depth+7)/8*hd.zsize*hd.ysize*hd.zsize;
51  hd.bsize = sizeof(CTHead);
52  hd.buf = (uByte*)malloc(hd.bsize);
53  if (hd.buf==NULL) {
54  //fprintf(stderr, "WRITE_FILE: no more memory!! %d\n", hd.bsize);
56  }
57  for (i=0; i<hd.bsize; i++) *(hd.buf+i) = (sByte)0;
58  int ret = write_ct_file(fname, &hd);
59 
60  free(hd.buf);
61  return ret;
62 }
63 
64 
77 int write_ras_file(const char* fname, WSGraph gr)
78 {
79  CmnHead hd;
80 
81  init_CmnHead(&hd);
82  hd.xsize = gr.xs;
83  hd.ysize = gr.ys;
84  hd.zsize = gr.zs;
85  hd.depth = 16;
86  hd.grptr = (uByte*)gr.gp;
87 
88  if (hd.zsize>1) {
89  //fprintf(stderr,"WRITE_RAS_FILE: 3D SunRaster is not supported!!\n");
91  }
92  else {
93  hd.zsize = Max(hd.zsize, 1);
94  hd.kind = CT_DATA;
95  hd.lsize = (hd.depth+7)/8*hd.xsize*hd.ysize*hd.zsize;
96  hd.bsize = sizeof(CTHead);
97  hd.buf = (uByte*)malloc(hd.bsize);
98  if (hd.buf==NULL) {
99  //fprintf(stderr,"WRITE_RAS_FILE: no more memory!! %d\n", hd.bsize);
101  }
102  memset(hd.buf, 0, hd.bsize);
103  }
104 
105  int ret = write_ras_file_obit(fname, &hd, 8);
106 
107  free(hd.buf);
108  return ret;
109 }
110 
111 
128 int write_file_rb(const char* fname, WSGraph gr, IRBound rb)
129 {
130  CmnHead hd;
131  CTHead* chd;
132  unsigned int i;
133 
134  init_CmnHead(&hd);
135  hd.xsize = gr.xs;
136  hd.ysize = gr.ys;
137  hd.zsize = gr.zs;
138  hd.depth = 16;
139  hd.grptr = (uByte*)gr.gp;
140  hd.kind = CT_3DM | HAS_RBOUND;
141 
142  if (hd.zsize<=0) {
143  hd.zsize = 1;
144  hd.kind = CT_DATA | HAS_RBOUND;
145  }
146  hd.lsize = (hd.depth+7)/8*hd.zsize*hd.ysize*hd.zsize;
147  hd.bsize = sizeof(CTHead);
148  hd.buf = (uByte*)malloc(hd.bsize);
149  if (hd.buf==NULL) {
150  //fprintf(stderr, "WRITE_FILE_RB: no more memory!! %d\n", hd.bsize);
152  }
153  for (i=0; i<hd.bsize; i++) *(hd.buf+i) = (sByte)0;
154 
155  chd = (CTHead*)hd.buf;
156  chd->cutleft = rb.xmin;
157  chd->cutright = rb.xmax;
158  chd->cutup = rb.ymin;
159  chd->cutdown = rb.ymax;
160  chd->ctmin = rb.zmin;
161  chd->ctmax = rb.zmax;
162 
163  if (RZxy!=1.0 && RZxy<RZXY_RATE && chk_RZxy()) {
164  chd->anydata[0] = (sWord)(RZxy*RZXY_RATE);
165  chd->anydata[1] = (sWord)RZXY_RATE;
166  hd.kind |= HAS_RZXY;
167  }
168 
169  if (ZeroBase!=0) {
170  chd->anydata[2] = (sWord)ZeroBase;
171  hd.kind |= HAS_BASE;
172  }
173 
174  int ret = write_ct_file(fname, &hd);
175 
176  free(hd.buf);
177  return ret;
178 }
179 
180 
197 WSGraph read_wsg_file(const char* fname)
198 {
199  WSGraph gr;
200  CmnHead hd;
201  int i, xs, ys, zs;
202  double rzm;
203  sWord* rz;
204 
205  memset(&gr, 0, sizeof(WSGraph));
206 
207  hd = read_xxx_file(fname);
208  if (hd.kind==HEADER_NONE) {
209  //fprintf(stderr,"READ_FILE: read file %s open error!!\n",fname);
211  return gr;
212  }
213 
214  if (checkBit(hd.kind, HAS_RBOUND)) {
215  //fprintf(stderr,"read_wsg_file: this file %s has RBound data.\n",fname);
216  //fprintf(stderr,"read_wsg_file: I call read_wsg_file_rb() function.\n");
217  //fprintf(stderr,"read_wsg_file: RBound data is in ExRBound.\n");
218  gr = read_wsg_file_rb(fname, &ExRBound);
219  return gr;
220  }
221 
222  xs = hd.xsize;
223  ys = hd.ysize;
224  zs = Max(hd.zsize, 1);
225 
226  if (hd.depth==16){
227  gr.gp = (sWord*)hd.grptr;
228  }
229  else if (hd.depth<16){
230  gr.gp = (sWord*)malloc(xs*ys*zs*sizeof(sWord));
231  if (gr.gp==NULL) {
232  //fprintf(stderr,"READ_FILE: no more memory! %d\n",xs*ys*zs*sizeof(sWord));
233  free_CmnHead(&hd);
235  return gr;
236  }
237  for (i=0; i<xs*ys*zs; i++) gr.gp[i] = (uByte)hd.grptr[i];
238  free(hd.grptr);
239  }
240  else if (hd.depth>16){
241  gr.gp = (sWord*)malloc(xs*ys*zs*sizeof(sWord));
242  if (gr.gp==NULL) {
243  //fprintf(stderr,"READ_FILE: no more memory! %d\n",xs*ys*zs*sizeof(sWord));
244  free_CmnHead(&hd);
246  return gr;
247  }
248  for (i=0;i<xs*ys*zs;i++) gr.gp[i]=(sWord)((uByte)hd.grptr[i]>>(hd.depth-15));
249  free(hd.grptr);
250  }
251 
252  gr.xs = xs;
253  gr.ys = ys;
254  gr.zs = zs;
255  gr.state = JBXL_NORMAL;
256 
257  if (hd.bsize>0 && checkBit(hd.kind, CT_DATA)) {
258  rz = (sWord*)hd.buf;
259  if (rz[9]==RZXY_RATE || checkBit(hd.kind, HAS_RZXY)) {
260  rzm = (double)(rz[8])/rz[9];
261  if (rzm<1.0 && rzm>0.1) set_RZxy(rzm);
262  //else fprintf(stderr,"READ_FILE: RZxy = %f ?????\n",rzm);
263  }
264  if (rz[10]!=0 && checkBit(hd.kind, HAS_BASE)) {
265  ZeroBase = rz[10];
266  }
267  }
268  free(hd.buf);
269 
270  return gr;
271 }
272 
273 
287 WSGraph read_ras_file(const char* fn)
288 {
289  int i, sz;
290  FILE *fp;
291  CmnHead hd;
292  WSGraph gd;
293  size_t rs;
294  UNUSED(rs);
295 
296  memset(&gd, 0, sizeof(WSGraph));
297 
298  if ((fp=fopen(fn,"rb"))==NULL) {
299  //fprintf(stderr,"READ_RAS_FILE: read file open error!! %s\n",fn);
301  return gd;
302  }
303 
304  rs = fread(&hd.entry, sizeof(CmnHead_Entry), 1, fp);
305  ntoh_st(&hd.entry, 4);
306  if (hd.kind!=RAS_MAGIC) {
307  //fprintf(stderr,"READ_RAS_FILE: %s is not sunraster. kind = %d\n",fn,hd.kind);
309  fclose(fp);
310  return gd;
311  }
312 
313  hd = read_ras_data(fp);
314  fclose(fp);
315  if (hd.kind==HEADER_NONE) {
316  free_CmnHead(&hd);
318  return gd;
319  }
320 
321  gd.xs = hd.xsize;
322  gd.ys = hd.ysize;
323  gd.zs = 1;
324 
325  sz = gd.xs*gd.ys*gd.zs;
326  gd.gp = (sWord*)malloc(sz*sizeof(sWord));
327  if (gd.gp==NULL) {
328  //fprintf(stderr,"READ_RAS_FILE: no more memory!! %d\n", sz);
329  memset(&gd, 0, sizeof(WSGraph));
331  return gd;
332  }
333  for (i=0; i<sz; i++) gd.gp[i] = (uByte)hd.grptr[i];
334  free_CmnHead(&hd);
335 
336  gd.state = JBXL_NORMAL;
337  return gd;
338 }
339 
340 
358 WSGraph read_wsg_file_rb(const char* fname, IRBound* rb)
359 {
360  int i, xs, ys, zs;
361  double rzm;
362  WSGraph gr;
363  CmnHead hd;
364  CTHead* chd;
365  sWord* rz;
366 
367  memset(&gr, 0, sizeof(WSGraph));
368 
369  hd = read_xxx_file(fname);
370  if (hd.kind==HEADER_NONE) {
371  //fprintf(stderr,"READ_FILE_RB: read file %s open error!!\n",fname);
372  //fprintf(stderr,"\n");
374  return gr;
375  }
376 
377  xs = hd.xsize;
378  ys = hd.ysize;
379  zs = Max(hd.zsize, 1);
380  rb->xmin = rb->ymin = rb->zmin = 0;
381  rb->xmax = xs - 1;
382  rb->ymax = ys - 1;
383  rb->zmax = zs - 1;
384 
385  if (hd.depth==16){
386  gr.gp = (sWord*)hd.grptr;
387  }
388  else if (hd.depth<16){
389  gr.gp = (sWord*)malloc(xs*ys*zs*sizeof(sWord));
390  if (gr.gp==NULL) {
391  //fprintf(stderr,"READ_FILE_RB: no more memory! %d\n",xs*ys*zs*sizeof(sWord));
393  return gr;
394  }
395  for (i=0; i<xs*ys*zs; i++) gr.gp[i] = (uByte)hd.grptr[i];
396  free(hd.grptr);
397  }
398  else if (hd.depth>16){
399  gr.gp = (sWord*)malloc(xs*ys*zs*sizeof(sWord));
400  if (gr.gp==NULL) {
401  //fprintf(stderr,"READ_FILE_RB: no more miemory! %d\n",xs*ys*zs*sizeof(sWord));
403  return gr;
404  }
405  for (i=0;i<xs*ys*zs;i++) gr.gp[i]=(sWord)((uByte)hd.grptr[i]>>(hd.depth-15));
406  free(hd.grptr);
407  }
408 
409  gr.xs = xs;
410  gr.ys = ys;
411  gr.zs = zs;
412 
413  if (hd.bsize>0 && checkBit(hd.kind, CT_DATA)) {
414  if (checkBit(hd.kind, HAS_RBOUND)) {
415  chd = (CTHead*)hd.buf;
416  rb->xmin = chd->cutleft;
417  rb->xmax = chd->cutright;
418  rb->ymin = chd->cutup;
419  rb->ymax = chd->cutdown;
420  rb->zmin = chd->ctmin;
421  rb->zmax = chd->ctmax;
422  }
423  rz = (sWord*)hd.buf;
424  if (rz[9]==RZXY_RATE || checkBit(hd.kind, HAS_RZXY)) {
425  rzm = (double)(rz[8])/rz[9];
426  if (rzm<1.0 && rzm>0.1) set_RZxy(rzm);
427  //else fprintf(stderr,"READ_FILE_RB: RZxy = %f ?????\n",rzm);
428  }
429  if (rz[10]!=0 && checkBit(hd.kind, HAS_BASE)) {
430  ZeroBase = rz[10];
431  }
432  }
433  free(hd.buf);
434 
435  gr.state = JBXL_NORMAL;
436  return gr;
437 }
438 
439 
440 
442 // ファイル名と共通ヘッダによるI/Oサポート
443 
457 int write_ras_file_obit(const char* fn, CmnHead* hd, int obit)
458 {
459  FILE *fp;
460  RasHead shd;
461  int i, j, k, l, linebyte, databyte, depth, lsize;
462  uByte null=0x00, *ptr, *buf;
463 
464  if ((fp=fopen(fn,"wb"))==NULL) return JBXL_GRAPH_OPFILE_ERROR;
465  obit = Xabs(obit);
466 
467  if (hd->kind == RAS_DATA) {
468  unsigned int u;
469  memcpy((sByte*)&shd, hd->buf, hd->bsize);
470  ptr = (uByte*)malloc(hd->lsize);
471  if (ptr==NULL) {
472  fclose(fp);
474  }
475  lsize = hd->lsize;
476  for (u=0; u<hd->lsize; u++) ptr[u] = hd->grptr[u];
477  }
478  else { // CT -> RAS
479  if (hd->depth==16) {
480 
481  if (obit==8) depth = 8;
482  else depth = 24;
483 
484  lsize = hd->xsize*hd->ysize*depth/8;
485  buf = (uByte*)malloc(lsize);
486  if (buf==NULL) {
487  fclose(fp);
489  }
490  memset(buf, 0, lsize);
491 
492  if (obit==8) {
493  int max = 255; // 8bit mode での最大値
494  uWord* wp = (uWord*)hd->grptr;
495  for (i=0; i<hd->xsize*hd->ysize; i++) {
496  max = Max(max, wp[i]);
497  }
498  for (i=0; i<hd->ysize*hd->xsize; i++) {
499  buf[i] = 255*wp[i]/max;
500  }
501  }
502  else {
503  k = l = 0;
504  for (i=0; i<hd->ysize*hd->xsize; i++) {
505  buf[k++] = hd->grptr[l++];
506  buf[k++] = hd->grptr[l++];
507  buf[k++] = null;
508  }
509  }
510  }
511  else {
512  depth = hd->depth;
513  lsize = hd->lsize;
514  buf = (uByte*)hd->grptr;
515  }
516 
517  databyte = hd->xsize*depth/8;
518  linebyte = lsize/hd->ysize;
519  if (linebyte%2==1) {
520  linebyte++;
521  lsize = linebyte*hd->ysize;
522  }
523 
524  shd.ras_magic = RAS_MAGIC;
525  shd.ras_width = hd->xsize;
526  shd.ras_height = hd->ysize;
527  shd.ras_depth = depth;
528  shd.ras_length = lsize;
529  shd.ras_type = RT_STANDARD;
530  shd.ras_maptype = RMT_NONE;
531  shd.ras_maplength= 0;
532 
533  ptr = (uByte*)malloc(lsize);
534  if (ptr==NULL) {
535  if (hd->depth==16) free(buf);
536  fclose(fp);
538  }
539  memset(ptr, 0, lsize);
540 
541  k = l = 0;
542  for (i=0 ; i<hd->ysize; i++) {
543  for (j=0; j<databyte; j++) ptr[k++] = buf[l++];
544  for (j=0; j<linebyte-databyte; j++) ptr[k++] = null;
545  }
546 
547  if (hd->depth==16) free(buf);
548  }
549 
550  hton_st(&shd, 4);
551  fwrite(&shd, sizeof(RasHead), 1, fp);
552  fwrite(ptr, lsize, 1, fp);
553 
554  fclose(fp);
555  free(ptr);
556  return 0;
557 }
558 
559 
583 int write_ct_file(const char* fn, CmnHead* hd)
584 {
585  CTHead chd;
586  CmnHead cmd;
587  FILE* fp;
588  sByte* ptr;
589  sWord* wp;
590  sByte null=0x00;
591  int i, j, k, l, lsize;
592  int dbyte=2; // sWord TYPE data
593 
594  if ((fp=fopen(fn,"wb"))==NULL) return JBXL_GRAPH_OPFILE_ERROR;
595 
596  hd->zsize = Max(hd->zsize, 1);
597  lsize = hd->xsize*hd->ysize*hd->zsize*dbyte;
598  hd->lsize = lsize;
599  ptr = (sByte*)malloc(lsize);
600  if (ptr==NULL) {
601  fclose(fp);
603  }
604  memset(ptr, 0, lsize);
605 
606  if (checkBit(hd->kind, CT_DATA) || checkBit(hd->kind, CT_3DM)) {
607  memcpy((sByte*)&chd, hd->buf, hd->bsize);
608  hton_st(&chd, 2);
609  chd.xsize = htons((sWord)hd->xsize);
610  chd.ysize = htons((sWord)hd->ysize);
611  for(i=0; i<lsize; i++) ptr[i] = hd->grptr[i];
612  }
613  else { // ANY DATA -> CT_DATA
614  chd.xsize = htons((sWord)hd->xsize);
615  chd.ysize = htons((sWord)hd->ysize);
616  chd.ctmin = 0;
617  chd.ctmax = 0;
618  chd.cutup = 0;
619  chd.cutdown = 0;
620  chd.cutleft = 0;
621  chd.cutright= 0;
622 
623  k = l = 0;
624  if (hd->depth < dbyte*8){
625  for (i=0; i<hd->xsize*hd->ysize; i++) {
626  for (j=0; j<hd->depth/8; j++) ptr[k++] = null;
627  for (j=hd->depth/8; j<dbyte; j++)
628  ptr[k++] = hd->grptr[l++];
629  }
630  }
631  else if (hd->depth == dbyte*8) {
632  for (i=0; i<hd->xsize*hd->ysize; i++) {
633  for (j=0; j<dbyte; j++) ptr[k++] = hd->grptr[l++];
634  }
635  }
636  else {
637  for (i=0; i<hd->xsize*hd->ysize; i++) {
638  for (j=0; j<dbyte; j++) ptr[k++] = hd->grptr[l++];
639  l += (hd->depth)/8 - dbyte;
640  }
641  }
642 
643  }
644 
645  if (RZxy!=1.0 && RZxy<RZXY_RATE && chk_RZxy()) {
646  chd.anydata[0] = htons((sWord)(RZxy*RZXY_RATE));
647  chd.anydata[1] = htons((sWord)RZXY_RATE);
648  hd->kind |= HAS_RZXY;
649  }
650 
651  if (ZeroBase!=0) {
652  chd.anydata[2] = htons((sWord)ZeroBase);
653  hd->kind |= HAS_BASE;
654  }
655 
656  fseek(fp, 0, 0);
657  if (checkBit(hd->kind, CT_3DM)) {
658  cmd = *hd;
659  hton_st(&cmd.entry, 4);
660  fwrite(&cmd.entry, sizeof(CmnHead_Entry), 1, fp);
661  }
662  fwrite(&chd, sizeof(CTHead), 1, fp);
663 
664  wp = (sWord*)ptr;
665  hton_ar(wp, lsize);
666  fwrite(ptr, lsize, 1, fp);
667 
668  fclose(fp);
669  free(ptr);
670 
671  return 0;
672 }
673 
674 
687 int write_cmn_file(const char* fn, CmnHead* hd)
688 {
689  FILE* fp;
690  CmnHead cd;
691 
692  if ((fp=fopen(fn,"wb"))==NULL) return JBXL_GRAPH_OPFILE_ERROR;
693 
694  cd = *hd;
695  hton_st(&cd.entry, 4);
696  fwrite(&cd.entry, sizeof(CmnHead_Entry), 1, fp);
697  if (hd->bsize>0) fwrite(hd->buf, hd->bsize, 1, fp);
698  if (hd->lsize>0) fwrite(hd->grptr, hd->lsize, 1, fp);
699 
700  fclose(fp);
701  return 0;
702 }
703 
704 
722 CmnHead read_xxx_file(const char* fn)
723 {
724  FILE* fp;
725  int i;
726  sWord* wptr;
727  CmnHead hd;
728  size_t rs;
729  UNUSED(rs);
730 
731  init_CmnHead(&hd);
732 
733  int fsz = file_size(fn);
734  if ((fp=fopen(fn,"rb"))==NULL) {
736  return hd;
737  }
738 
739  int hsz = sizeof(CmnHead_Entry);
740  fseek(fp,0,0);
741  rs = fread(&hd.entry, hsz, 1, fp);
742  ntoh_st(&hd.entry, 4);
743  hd.buf = NULL;
744  hd.grptr = NULL;
745 
746  if (hd.kind>=0 && hd.kind<=NUM_KDATA) {
747  hd.zsize = Max(hd.zsize, 1);
748 
749  if (fsz == (int)(hsz + hd.bsize + hd.lsize) + 4 ) hsz = 36; // x86 file
750  if (fsz == (int)(hsz + hd.bsize + hd.lsize) + 16) hsz = 48; // x64 file
751  //
752  if (fsz == (int)(hsz + hd.bsize + hd.lsize)) {
753  fseek(fp, hsz, 0);
754  hd.buf = (uByte*)malloc(hd.bsize);
755  hd.grptr = (uByte*)malloc(hd.lsize);
756  if ((hd.bsize>0 && hd.buf==NULL) || hd.grptr==NULL) {
757  init_CmnHead(&hd);
759  fclose(fp);
760  return hd;
761  }
762  memset(hd.buf, 0, hd.bsize);
763  memset(hd.grptr, 0, hd.lsize);
764 
765  rs = fread(hd.buf, hd.bsize, 1, fp);
766  wptr = (sWord*)hd.buf;
767  ntoh_ar(wptr, hd.bsize);
768 
769  rs = fread(hd.grptr, hd.lsize, 1, fp);
770  if (hd.depth==16) {
771  wptr = (sWord*)hd.grptr;
772  for(i=0; i<hd.xsize*hd.ysize*hd.zsize; i++) wptr[i] = ntohs(wptr[i]);
773  }
774  fclose(fp);
775  return hd;
776  }
777  }
778 
779  if (hd.kind==RAS_MAGIC) {
780  hd = read_ras_data(fp);
781  fclose(fp);
782  return hd;
783  }
784 
785  hd = read_ct_data(fp);
786  if (fsz != (int)(hd.lsize+hd.bsize)) {
787  hd.xsize = hd.ysize = hd.depth = 0;
788  hd = read_user_data(fp, &hd);
789  }
790 
791  fclose(fp);
792  return hd;
793 }
794 
795 
808 CmnHead read_cmn_header(const char* fn)
809 {
810  FILE* fp;
811  CmnHead hd;
812  size_t rs;
813  UNUSED(rs);
814 
815  init_CmnHead(&hd);
816  int fsz = file_size(fn);
817 
818  if ((fp=fopen(fn,"rb"))==NULL) {
820  return hd;
821  }
822 
823  int hsz = sizeof(CmnHead_Entry);
824  fseek(fp, 0, 0);
825  rs = fread(&hd.entry, hsz, 1, fp);
826  ntoh_st(&hd.entry, 4);
827  hd.buf = NULL;
828  hd.grptr = NULL;
829 
830  if (fsz == (int)(hsz + hd.bsize + hd.lsize) + 4 ) hsz = 36; // x86 file
831  if (fsz == (int)(hsz + hd.bsize + hd.lsize) + 16) hsz = 48; // x64 file
832  fseek(fp, hsz, 0);
833 
834  if (hd.bsize>0) {
835  hd.buf = (uByte*)malloc(hd.bsize);
836  if (hd.buf==NULL) {
837  init_CmnHead(&hd);
839  fclose(fp);
840  return hd;
841  }
842  memset(hd.buf, 0, hd.bsize);
843  rs = fread(hd.buf, hd.bsize, 1, fp);
844  }
845  else {
846  hd.bsize = 0;
847  hd.buf = NULL;
848  }
849 
850  fclose(fp);
851  return hd;
852 }
853 
854 
867 CmnHead read_cmn_file(const char* fn)
868 {
869  FILE* fp;
870  CmnHead hd;
871  size_t rs;
872  UNUSED(rs);
873 
874  init_CmnHead(&hd);
875  int fsz = file_size(fn);
876 
877  if ((fp=fopen(fn,"rb"))==NULL) {
879  return hd;
880  }
881 
882  int hsz = sizeof(CmnHead_Entry);
883  fseek(fp, 0, 0);
884  rs = fread(&hd.entry, hsz, 1, fp);
885  ntoh_st(&hd.entry, 4);
886  hd.buf = NULL;
887  hd.grptr = NULL;
888 
889  if (fsz == (int)(hsz + hd.bsize + hd.lsize) + 4 ) hsz = 36; // x86 file
890  if (fsz == (int)(hsz + hd.bsize + hd.lsize) + 16) hsz = 48; // x64 file
891  fseek(fp, hsz, 0);
892 
893  if (hd.bsize>0) {
894  hd.buf = (uByte*)malloc(hd.bsize);
895  if (hd.buf==NULL) {
896  init_CmnHead(&hd);
898  fclose(fp);
899  return hd;
900  }
901  memset(hd.buf, 0, hd.bsize);
902  rs = fread(hd.buf, hd.bsize, 1, fp);
903  }
904  else {
905  hd.bsize = 0;
906  hd.buf = NULL;
907  }
908 
909  if (hd.lsize<=0) hd.lsize = file_size(fn) - hsz - hd.bsize;
910  hd.grptr = (uByte*)malloc(hd.lsize);
911  if (hd.grptr==NULL) {
912  free_CmnHead(&hd);
914  fclose(fp);
915  return hd;
916  }
917  memset(hd.grptr, 0, hd.lsize);
918  rs = fread(hd.grptr, hd.lsize, 1, fp);
919 
920  fclose(fp);
921  return hd;
922 }
923 
924 
925 
927 // ファイル識別子と共通ヘッダによるI/Oサポート
928 
950 {
951  int i;
952  CmnHead hd;
953  size_t rs;
954  UNUSED(rs);
955 
956  init_CmnHead(&hd);
957 
958  if (chd==NULL) {
960  return hd;
961  }
962  else if (!checkBit(chd->kind, USERSET_DATA)) {
964  return hd;
965  }
966  hd = *chd;
967 
968  // ヘッダ読み込み
969  fseek(fp, 0, 0);
970  hd.buf = (uByte*)malloc(hd.bsize);
971  if (hd.buf==NULL) {
972  init_CmnHead(&hd);
974  return hd;
975  }
976  memset(hd.buf, 0, hd.bsize);
977  rs = fread((void*)hd.buf, hd.bsize, 1, fp);
978 
979  hd.grptr = (uByte*)malloc(hd.lsize);
980  if (hd.grptr==NULL) {
981  free_CmnHead(&hd);
983  return hd;
984  }
985  memset(hd.grptr, 0, hd.lsize);
986 
987  fseek(fp, hd.bsize, 0);
988  rs = fread(hd.grptr, hd.lsize, 1, fp);
989  //int psize = hd.xsize*hd.ysize*((hd.depth+7)/8);
990  //for (int i=0; i<hd.zsize; i++) {
991  // rs = fread(hd.grptr+i*psize, psize, 1, fp);
992  //}
993 
994  if (is_little_endian()) {
995  if (hd.depth==16 && !checkBit(chd->kind, HAS_LENDIAN)) {
996  sWord* wptr = (sWord*)hd.grptr;
997  for (i=0; i<hd.xsize*hd.ysize*hd.zsize; i++) wptr[i] = ntohs(wptr[i]);
998  }
999  }
1000  else {
1001  if (hd.depth==16 && checkBit(chd->kind, HAS_LENDIAN)) {
1002  uWord* wptr = (uWord*)hd.grptr;
1003  for (i=0; i<hd.xsize*hd.ysize*hd.zsize; i++) wptr[i] = swaps(wptr[i]);
1004  }
1005  }
1006 
1007  return hd;
1008 }
1009 
1010 
1023 {
1024  RasHead rhd;
1025  CmnHead hd;
1026  int i, linebyte, databyte;
1027  uByte null[2], *buf;
1028  sWord* wptr;
1029  size_t rs;
1030  UNUSED(rs);
1031 
1032  init_CmnHead(&hd);
1033  hd.kind = RAS_DATA;
1034  hd.bsize = 32;
1035 
1036  fseek(fp, 0, 0);
1037  rs = fread(&rhd, hd.bsize, 1, fp);
1038  ntoh_st(&rhd, 4);
1039 
1040  hd.xsize = rhd.ras_width;
1041  hd.ysize = rhd.ras_height;
1042  hd.zsize = 1;
1043  hd.depth = rhd.ras_depth;
1044  hd.lsize = hd.xsize*hd.ysize*((hd.depth+7)/8);
1045  hd.buf = (uByte*)malloc(hd.bsize);
1046  if (hd.buf==NULL) {
1047  init_CmnHead(&hd);
1049  return hd;
1050  }
1051  memcpy(hd.buf, (uByte*)&rhd, hd.bsize);
1052 
1053  hd.grptr = (uByte*)malloc(hd.lsize);
1054  if (hd.grptr==NULL) {
1055  free_CmnHead(&hd);
1057  return hd;
1058  }
1059  memset(hd.grptr, 0, hd.lsize);
1060  buf = (uByte*)hd.grptr;
1061 
1062  fseek(fp, rhd.ras_maplength, 1);
1063 
1064  databyte = hd.xsize*((hd.depth+7)/8);
1065  linebyte = rhd.ras_length/hd.ysize;
1066 
1067  if (databyte==linebyte) {
1068  rs = fread(buf, hd.lsize, 1, fp);
1069  }
1070  else {
1071  for (i=0; i<hd.ysize; i++) {
1072  rs = fread(buf, databyte, 1, fp);
1073  rs = fread(null, linebyte-databyte, 1, fp);
1074  buf += databyte;
1075  }
1076  }
1077 
1078  if (hd.depth==16){
1079  wptr = (sWord*)hd.grptr;
1080  for(i=0; i<hd.xsize*hd.ysize; i++) wptr[i] = ntohs(wptr[i]);
1081  }
1082 
1083  return hd;
1084 }
1085 
1086 
1099 {
1100  int i;
1101  CTHead chd;
1102  CmnHead hd;
1103  sWord *wptr;
1104  size_t rs;
1105  UNUSED(rs);
1106 
1107  init_CmnHead(&hd);
1108 
1109  // ヘッダ読み込み
1110  fseek(fp, 0, 0);
1111  hd.bsize = 64;
1112  rs = fread((void*)&chd, hd.bsize, 1, fp);
1113  ntoh_st(&chd, 2);
1114 
1115  hd.xsize = chd.xsize - chd.cutleft - chd.cutright;
1116  hd.ysize = chd.ysize - chd.cutup - chd.cutdown;
1117  hd.zsize = 1;
1118  hd.depth = 16;
1119  hd.lsize = hd.xsize*hd.ysize*(hd.depth/8);
1120 
1121  hd.buf = (uByte*)malloc(hd.bsize);
1122  if (hd.buf==NULL) {
1123  init_CmnHead(&hd);
1125  return hd;
1126  }
1127  hd.kind = CT_DATA;
1128  memcpy(hd.buf, &chd, hd.bsize);
1129 
1130  hd.grptr = (uByte*)malloc(hd.lsize);
1131  if (hd.grptr==NULL) {
1132  free_CmnHead(&hd);
1134  return hd;
1135  }
1136  memset(hd.grptr, 0, hd.lsize);
1137 
1138  fseek(fp, hd.bsize, 0);
1139  rs = fread(hd.grptr, hd.lsize, 1, fp);
1140 
1141  wptr = (sWord*)hd.grptr;
1142  for (i=0; i<hd.xsize*hd.ysize; i++) wptr[i] = ntohs(wptr[i]);
1143 
1144  return hd;
1145 }
1146 
1147 
1148 
1150 // DICOM
1151 
1170 int dicom_header(FILE* fp, int fsize, int* dsize, int* xsize, int* ysize, int* depth, double* rzxy)
1171 {
1172  int i, j, sz, rp, ef;
1173  int ln, hsize;
1174  int xs = 0, ys = 0, dp = 0;
1175  double rz = 0.0;
1176 
1177  uWord dt, cn[2];
1178  uWord* wp;
1179 
1180  if (fp==NULL || fsize<=0 || dsize==NULL) return JBXL_GRAPH_IVDARG_ERROR;
1181 
1182  *dsize = 0;
1183  if (rzxy!=NULL) *rzxy = 0.0;
1184  ef = OFF;
1185  fseek(fp, 0, 0);
1186 
1188  // ヘッダの区切りを検出
1189  rp = (int)fread(&dt, sizeof(uWord), 1, fp);
1190  while(!feof(fp) && ef!=ON) {
1191  //if ((uWord)ntohs(dt)==0xe07f) {
1192  if (dt==DICOM_PIXEL_GROUP) {
1193  rp += (int)fread(&dt, sizeof(uWord), 1, fp);
1194  //if ((uWord)ntohs(dt)==0x1000) {
1195  if (dt==DICOM_PIXEL_ELEMENT) {
1196  rp += (int)fread(&cn, sizeof(uWord), 2, fp);
1197  //if ((uWord)ntohs(cn[0])==0x4f57 && cn[1]==0x0000) {
1198  if (cn[0]==DICOM_PIXCEL_VR && cn[1]==0x0000) {
1199  rp += (int)fread(&cn, sizeof(uWord), 2, fp);
1200  *dsize = *(int*)cn;
1201  hsize = rp*sizeof(uWord);
1202  if (fsize>=*dsize+hsize) { // footer
1203  ef = ON;
1204  break;
1205  }
1206  }
1207  else {
1208  *dsize = *(int*)cn;
1209  hsize = rp*sizeof(uWord);
1210  if (fsize>=*dsize+hsize) { // footer
1211  ef = ON;
1212  break;
1213  }
1214  }
1215  }
1216  }
1217  rp += (int)fread(&dt, sizeof(uWord), 1, fp);
1218  }
1219 
1220  if (!ef) return 0;
1221 
1222  sz = rp*sizeof(uWord);
1223  wp = (uWord*)malloc(sz);
1224  if (wp==NULL) return JBXL_GRAPH_MEMORY_ERROR;
1225  memset(wp, 0, sz);
1226 
1228  // ヘッダ読み込み
1229  size_t rs;
1230  UNUSED(rs);
1231 
1232  fseek(fp, 0, 0);
1233  rs = fread(wp, sz, 1, fp);
1234 
1235  for (i=0; i<sz/2-3; i++) {
1236  //if ((uWord)ntohs(wp[i])==0x2800 && (uWord)ntohs(wp[i+1])==0x3000) {
1237  if (wp[i]==DICOM_IMAGE_GROUP) {
1238 
1239  // Z方向の歪
1240  if (wp[i+1]==DICOM_PXLSPC_ELEMENT) {
1241  char rx[LNAME], ry[LNAME];
1242  uByte* bp;
1243 
1244  memset(rx, 0, LNAME);
1245  memset(ry, 0, LNAME);
1246 
1247  if (wp[i+2]==DICOM_STR_VR) ln = wp[i+3];
1248  else ln = *(int*)&wp[i+2];
1249 
1250  if (ln<LNAME-1) {
1251  bp = (uByte*)&wp[i+4];
1252  j = 0;
1253  while (j<ln-1 && bp[j]!='\\') {
1254  rx[j] = bp[j];
1255  j++;
1256  }
1257  ln -= j + 1;
1258  bp += j + 1;
1259  j = 0;
1260  while (j<ln-1 && bp[j]!=' ') {
1261  ry[j] = bp[j];
1262  j++;
1263  }
1264  if (!strcmp(rx, ry)) {
1265  rz = atof(rx);
1266  }
1267  }
1268  }
1269 
1270  // X サイズ
1271  else if (wp[i+1]==DICOM_XSIZE_ELEMENT) {
1272  if (wp[i+2]==DICOM_INT_VR) ln = wp[i+3];
1273  else ln = *(int*)&wp[i+2];
1274  if (ln==2) {
1275  xs = (int)*(sWord*)&wp[i+4];
1276  }
1277  else if (ln==4) {
1278  xs = *(int*)&wp[i+4];
1279  }
1280  }
1281 
1282  // Y サイズ
1283  else if (wp[i+1]==DICOM_YSIZE_ELEMENT) {
1284  if (wp[i+2]==DICOM_INT_VR) ln = wp[i+3];
1285  else ln = *(int*)&wp[i+2];
1286  if (ln==2) {
1287  ys = (int)*(sWord*)&wp[i+4];
1288  }
1289  else if (ln==4) {
1290  ys = *(int*)&wp[i+4];
1291  }
1292  }
1293 
1294  // Depth
1295  else if (wp[i+1]==DICOM_DEPTH_ELEMENT) {
1296  if (wp[i+2]==DICOM_INT_VR) ln = wp[i+3];
1297  else ln = *(int*)&wp[i+2];
1298  if (ln==2) {
1299  dp = (int)*(sWord*)&wp[i+4];
1300  }
1301  else if (ln==4) {
1302  dp = *(int*)&wp[i+4];
1303  }
1304  }
1305  }
1306  }
1307  free(wp);
1308 
1309  if (rzxy!=NULL) *rzxy = rz;
1310  if (xsize!=NULL) *xsize = xs;
1311  if (ysize!=NULL) *ysize = ys;
1312  if (depth!=NULL) *depth = dp;
1313 
1314  return sz;
1315 }
1316 
1317 
1322 WSGraph read_dicom_file(const char* fn)
1323 {
1324  int sz, fsize, dsize, xsize, ysize, depth;
1325  double rzxy;
1326  FILE* fp;
1327  size_t rs;
1328  UNUSED(rs);
1329 
1330  WSGraph vp;
1331 
1332  memset(&vp, 0, sizeof(WSGraph));
1333 
1334  fsize = file_size(fn);
1335  if (fsize<=0) {
1337  return vp;
1338  }
1339 
1340  if ((fp=fopen(fn,"rb"))==NULL) {
1342  return vp;
1343  }
1344 
1345  sz = dicom_header(fp, fsize, &dsize, &xsize, &ysize, &depth, &rzxy);
1346  if (sz<=0) {
1347  fclose(fp);
1349  return vp;
1350  }
1351 
1352  DEBUG_MODE PRINT_MESG("read_dicom_file: xsize = %d, ysize = %d, depth = %d, RZxy = %f\n", xsize, ysize, depth, rzxy);
1353 
1354  // Read Data
1355  if (dsize!=xsize*ysize*((depth+7)/8)) {
1356  unset_RZxy();
1357  fclose(fp);
1359  return vp;
1360  }
1361 
1362  if ((depth+7)/8!=2) {
1363  unset_RZxy();
1364  fclose(fp);
1366  return vp;
1367  }
1368 
1369  vp = make_WSGraph(xsize, ysize, 1);
1370  if (vp.gp==NULL) {
1372  return vp;
1373  }
1374 
1375  fseek(fp, sz, 0);
1376  rs = fread(vp.gp, dsize, 1, fp);
1377  fclose(fp);
1378 
1379  if (rzxy>0.0) set_RZxy(rzxy);
1380  vp.state = JBXL_NORMAL;
1381  return vp;
1382 }
1383 
#define LNAME
Definition: common.h:153
char sByte
1Byte
Definition: common.h:333
#define OFF
Definition: common.h:231
unsigned short uWord
2Byte
Definition: common.h:334
#define Max(x, y)
Definition: common.h:247
#define Xabs(x)
Definition: common.h:257
#define UNUSED(x)
Definition: common.h:264
short sWord
2Byte
Definition: common.h:335
unsigned char uByte
1Byte
Definition: common.h:332
#define ON
Definition: common.h:230
#define checkBit(dat, bit)
Definition: common.h:260
WSGraph make_WSGraph(int xs, int ys, int zs)
Definition: gdata.c:108
void set_RZxy(double rzm)
Definition: gdata.c:818
void init_CmnHead(CmnHead *hd)
Definition: gdata.c:44
void free_CmnHead(CmnHead *hd)
Definition: gdata.c:27
double RZxy
Definition: gdata.c:15
int chk_RZxy(void)
Definition: gdata.c:832
int ZeroBase
Definition: gdata.c:14
#define unset_RZxy()
Definition: gdata.h:170
#define RAS_MAGIC
Definition: gheader.h:94
#define DICOM_STR_VR
Z歪
Definition: gheader.h:319
#define HEADER_NONE
0x8000 // ヘッダ種別の指定なし
Definition: gheader.h:212
#define DICOM_PIXEL_GROUP
Definition: gheader.h:309
#define RT_STANDARD
Definition: gheader.h:97
#define CT_3DM
0x0012 // 3D CT DATA(マルチスライス)
Definition: gheader.h:178
#define DICOM_XSIZE_ELEMENT
Definition: gheader.h:312
#define USERSET_DATA
0x0005 // ユーザ指定のデータ形式(ヘッダ形式指定の場合,使用する)
Definition: gheader.h:174
#define DICOM_INT_VR
X, Y.
Definition: gheader.h:320
#define HAS_BASE
0x0400 // 基底(底上げ)値を持つ
Definition: gheader.h:206
#define RZXY_RATE
RZxy をファイルのヘッダに埋め込む際の比率(倍率).
Definition: gheader.h:215
#define RAS_DATA
0x0070 // SUN RASTER 8bit
Definition: gheader.h:198
#define DICOM_PXLSPC_ELEMENT
Definition: gheader.h:314
#define DICOM_YSIZE_ELEMENT
Definition: gheader.h:313
#define CT_DATA
0x0010 // CT DATA (Moon形式)
Definition: gheader.h:177
#define HAS_LENDIAN
0x4000 // リトルエンディアン
Definition: gheader.h:210
#define HAS_RBOUND
0x2000 // with RBound data
Definition: gheader.h:209
#define DICOM_IMAGE_GROUP
Definition: gheader.h:308
#define DICOM_DEPTH_ELEMENT
Definition: gheader.h:315
#define DICOM_PIXEL_ELEMENT
Definition: gheader.h:311
#define RMT_NONE
Definition: gheader.h:100
#define DICOM_PIXCEL_VR
Not.
Definition: gheader.h:318
#define NUM_KDATA
0x7fff // Max Numver of Data Format
Definition: gheader.h:213
#define HAS_RZXY
0x1000 // with RZxy data
Definition: gheader.h:208
CmnHead read_ras_data(FILE *fp)
readRasData() for C++
Definition: gio.c:1022
CmnHead read_cmn_header(const char *fn)
Definition: gio.c:808
WSGraph read_wsg_file(const char *fname)
Definition: gio.c:197
int write_file_rb(const char *fname, WSGraph gr, IRBound rb)
Definition: gio.c:128
int write_ras_file_obit(const char *fn, CmnHead *hd, int obit)
Definition: gio.c:457
int write_ct_file(const char *fn, CmnHead *hd)
Definition: gio.c:583
int write_cmn_file(const char *fn, CmnHead *hd)
Definition: gio.c:687
int write_wsg_file(const char *fname, WSGraph gr)
Definition: gio.c:34
WSGraph read_wsg_file_rb(const char *fname, IRBound *rb)
Definition: gio.c:358
WSGraph read_dicom_file(const char *fn)
Definition: gio.c:1322
CmnHead read_xxx_file(const char *fn)
Definition: gio.c:722
WSGraph read_ras_file(const char *fn)
Definition: gio.c:287
int write_ras_file(const char *fname, WSGraph gr)
Definition: gio.c:77
IRBound ExRBound
Definition: gio.c:13
CmnHead read_ct_data(FILE *fp)
readCTData() for C++
Definition: gio.c:1098
CmnHead read_cmn_file(const char *fn)
Definition: gio.c:867
CmnHead read_user_data(FILE *fp, CmnHead *chd)
readUserSetData() for C++
Definition: gio.c:949
int dicom_header(FILE *fp, int fsize, int *dsize, int *xsize, int *ysize, int *depth, double *rzxy)
Definition: gio.c:1170
グラフィック用ファイル入出力関数ヘッダ
JunkBox_Lib 状態ヘッダ
#define JBXL_GRAPH_IVDARG_ERROR
無効な引数
Definition: jbxl_state.h:178
#define JBXL_GRAPH_OPFILE_ERROR
ファイルのオープンエラー
Definition: jbxl_state.h:173
#define JBXL_NORMAL
正常
Definition: jbxl_state.h:32
#define JBXL_GRAPH_NOFILE_ERROR
ファイルが存在しない
Definition: jbxl_state.h:172
#define JBXL_GRAPH_HEADER_ERROR
画像ヘッダーのエラー
Definition: jbxl_state.h:169
#define JBXL_GRAPH_MEMORY_ERROR
メモリエラー
Definition: jbxl_state.h:170
unsigned char ** buf
Definition: jpeg_tool.h:96
Definition: gheader.h:64
sWord xsize
Definition: gheader.h:65
sWord cutdown
Definition: gheader.h:70
sWord ctmax
Definition: gheader.h:68
sWord ysize
Definition: gheader.h:66
sWord cutright
Definition: gheader.h:72
sWord anydata[23]
Definition: gheader.h:73
sWord cutup
Definition: gheader.h:69
sWord ctmin
Definition: gheader.h:67
sWord cutleft
Definition: gheader.h:71
Definition: gheader.h:110
CmnHead_Entry entry
Definition: gheader.h:125
unsigned int lsize
Size of Graphics Data (byte unit)
Definition: gheader.h:133
uByte * buf
Ture Header buffer
Definition: gheader.h:137
int zsize
For 3D Data (or Color)
Definition: gheader.h:130
int kind
Kind of Graphics Format.
Definition: gheader.h:127
unsigned int bsize
Fllowing buf size or Any Data (byte unit)
Definition: gheader.h:132
uByte * grptr
Pointer to Data.
Definition: gheader.h:138
int ysize
Height of Graphics.
Definition: gheader.h:129
int depth
Color Depth of Graphics (bit unit)
Definition: gheader.h:131
int xsize
Width of Graphics.
Definition: gheader.h:128
Definition: gdata.h:113
int xmax
x軸境界の最大値.
Definition: gdata.h:115
int ymax
y軸境界の最大値.
Definition: gdata.h:117
int xmin
x軸境界の最小値.
Definition: gdata.h:114
int ymin
y軸境界の最小値.
Definition: gdata.h:116
int zmax
z軸境界の最大値.
Definition: gdata.h:119
int zmin
z軸境界の最小値.
Definition: gdata.h:118
int ras_length
Definition: gheader.h:87
int ras_maptype
Definition: gheader.h:89
int ras_magic
Definition: gheader.h:83
int ras_height
Definition: gheader.h:85
int ras_depth
Definition: gheader.h:86
int ras_type
Definition: gheader.h:88
int ras_maplength
Definition: gheader.h:90
int ras_width
Definition: gheader.h:84
Definition: gdata.h:42
int zs
zサイズ. 4Byte. 2Dの場合は 1.
Definition: gdata.h:45
int xs
xサイズ. 4Byte.
Definition: gdata.h:43
int state
状態
Definition: gdata.h:46
sWord * gp
グラフィックデータへのポインタ. xs*ys*zs*2Byte.
Definition: gdata.h:47
int ys
yサイズ. 4Byte.
Definition: gdata.h:44
unsigned long int file_size(const char *fn)
ファイルの大きさを返す.
Definition: tools.c:2309
short swaps(unsigned short p)
16bit の上下8bitを入れ替える.
Definition: tools.c:1872
int is_little_endian(void)
エンディアンの動的チェック
Definition: tools.c:80
#define hton_ar(p, s)
host形式から network形式へ.長さsバイトの配列pに対して変換.
Definition: tools.h:428
#define hton_st(p, s)
host形式から network形式へ.構造体pに対して sバイトづつ変換.
Definition: tools.h:426
#define ntoh_ar(p, s)
network形式から host形式へ.長さsバイトの配列pに対して変換
Definition: tools.h:427
#define ntoh_st(p, s)
network形式から host形式へ.構造体pに対して sバイトづつ変換.
Definition: tools.h:425
#define PRINT_MESG
環境依存用の出力関数.print_message()
Definition: tools.h:475
#define DEBUG_MODE
Definition: tools.h:502