00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 #include <stdio.h>
00061 #include <stdlib.h>
00062 #include <string.h>
00063 #include <sys/types.h>
00064 #include <errno.h>
00065 #include <stdlib.h>
00066 #include <stdarg.h>
00067 #include <ctype.h>
00068
00069 #include "mri_dicom_hdr.h"
00070
00071 #include "mcw_malloc.h"
00072 #include "Amalloc.h"
00073 #include "debugtrace.h"
00074
00075
00076
00077
00078 #define BYTEORDER_SAME 1
00079 #define BYTEORDER_REVERSE 2
00080 #define NATIVE_ORDER BYTEORDER_SAME
00081
00082 static int LITTLE_ORDER ;
00083 static int BIG_ORDER ;
00084 static int LITTLE_ENDIAN_ARCHITECTURE = -1 ;
00085
00086 static void RWC_set_endianosity(void)
00087 {
00088 union { unsigned char bb[2] ;
00089 short ss ; } fred ;
00090
00091 if( LITTLE_ENDIAN_ARCHITECTURE < 0 ){
00092 fred.bb[0] = 1 ; fred.bb[1] = 0 ;
00093
00094 LITTLE_ENDIAN_ARCHITECTURE = (fred.ss == 1) ;
00095
00096 if( LITTLE_ENDIAN_ARCHITECTURE ){
00097 LITTLE_ORDER = BYTEORDER_SAME ;
00098 BIG_ORDER = BYTEORDER_REVERSE ;
00099 } else {
00100 BIG_ORDER = BYTEORDER_SAME ;
00101 LITTLE_ORDER = BYTEORDER_REVERSE ;
00102 }
00103 }
00104 }
00105
00106
00107
00108
00109 static char *pbuf = NULL ;
00110 static int npbuf = 0 ;
00111
00112 #define NPBUF 1024
00113
00114 static void RWC_clear_pbuf(void)
00115 {
00116 if( pbuf != NULL ){ free(pbuf); pbuf = NULL; npbuf = 0; }
00117 }
00118
00119 static int RWC_printf( char *fmt , ... )
00120 {
00121 static char *sbuf = NULL ;
00122 int nsbuf , nn , lpbuf ;
00123 va_list vararg_ptr ;
00124
00125 va_start( vararg_ptr , fmt ) ;
00126
00127 if( sbuf == NULL ) sbuf = AFMALL( char, NPBUF) ;
00128
00129 sbuf[0] = '\0' ;
00130 nn = vsprintf( sbuf , fmt , vararg_ptr ) ;
00131 va_end( vararg_ptr ) ;
00132 nsbuf = strlen(sbuf) ;
00133 if( nsbuf == 0 ) return(0);
00134
00135 if( npbuf == 0 ){
00136 pbuf = AFMALL(char,NPBUF) ; npbuf = NPBUF ; pbuf[0] = '\0' ;
00137 }
00138
00139 lpbuf = strlen(pbuf) ;
00140 if( lpbuf+nsbuf+8 > npbuf ){
00141 npbuf += NPBUF; pbuf = AFREALL( pbuf, char, npbuf);
00142 }
00143
00144 strcat(pbuf,sbuf) ;
00145 return(nn);
00146 }
00147
00148
00149
00150 static off_t pxl_off = 0 ;
00151 static unsigned int pxl_len = 0 ;
00152
00153 void mri_dicom_pxlarr( off_t *poff , unsigned int *plen )
00154 {
00155 *poff = pxl_off ; *plen = pxl_len ;
00156 }
00157
00158
00159
00160 static int rwc_opt = 0 ;
00161
00162 #define RWC_NONAME_MASK 1
00163 #define RWC_NOHEX_MASK 2
00164
00165 void mri_dicom_noname( int ii )
00166 {
00167 if( ii )
00168 rwc_opt |= RWC_NONAME_MASK ;
00169 else if( rwc_opt & RWC_NONAME_MASK )
00170 rwc_opt ^= RWC_NONAME_MASK ;
00171 }
00172
00173 void mri_dicom_nohex( int ii )
00174 {
00175 if( ii )
00176 rwc_opt |= RWC_NOHEX_MASK ;
00177 else if( rwc_opt & RWC_NOHEX_MASK )
00178 rwc_opt ^= RWC_NOHEX_MASK ;
00179 }
00180
00181
00182
00183 static int rwc_vm=0 ;
00184
00185 void mri_dicom_setvm( int vv )
00186 {
00187 rwc_vm = vv ;
00188 }
00189
00190
00191
00192 static int rwc_err=1 ;
00193
00194 void mri_dicom_seterr( int vv )
00195 {
00196 rwc_err = vv ;
00197 }
00198
00199
00200
00201 static int rwc_fd ;
00202
00203 char * mri_dicom_header( char *fname )
00204 {
00205 DCM_OBJECT * object;
00206 CONDITION cond;
00207 CTNBOOLEAN verbose = FALSE ,
00208 exitFlag = FALSE,
00209 formatFlag = FALSE;
00210 unsigned long
00211 options = DCM_ORDERLITTLEENDIAN;
00212 long vmLimit = rwc_vm ;
00213 LST_HEAD* fileNames = 0;
00214 UTL_FILEITEM* p = NULL;
00215
00216 char *ppp=NULL ;
00217
00218 ENTRY("mri_dicom_header") ;
00219
00220 if( fname == NULL ) RETURN(NULL) ;
00221
00222 RWC_set_endianosity() ;
00223
00224 { char *eee = getenv("AFNI_TRACE") ;
00225 if( eee!=NULL && (*eee=='y' || *eee=='Y') ) verbose = TRUE ;
00226 }
00227
00228 DCM_Debug(verbose);
00229
00230 RWC_clear_pbuf() ; pxl_len = 0 ; pxl_off = 0 ;
00231
00232 STATUS(fname) ;
00233 rwc_fd = -1 ;
00234 cond = DCM_OpenFile(fname, options, &object);
00235 if (cond != DCM_NORMAL && ((options & DCM_PART10FILE) == 0)) {
00236 STATUS("DCM_OpenFile open failed; try again as Part 10") ;
00237 (void) DCM_CloseObject(&object);
00238 (void) COND_PopCondition(TRUE);
00239 if( rwc_fd >= 0 ){ close(rwc_fd); rwc_fd = -1; }
00240 cond = DCM_OpenFile(fname, options | DCM_PART10FILE, &object);
00241 }
00242 if (cond == DCM_NORMAL) {
00243 STATUS("DCM_OpenFile is good") ;
00244 RWC_printf("DICOM File: %s\n", fname);
00245 if (formatFlag)
00246 cond = DCM_FormatElements(&object, vmLimit, "");
00247 else
00248 cond = DCM_DumpElements(&object, vmLimit);
00249 } else {
00250 STATUS("DCM_OpenFile failed") ;
00251 }
00252 (void) DCM_CloseObject(&object);
00253 (void) COND_PopCondition(TRUE);
00254
00255 if( pbuf != NULL ){
00256 ppp = strdup(pbuf) ; RWC_clear_pbuf() ;
00257 }
00258
00259 if( rwc_fd >= 0 ){ close(rwc_fd); rwc_fd = -1; }
00260
00261 RETURN(ppp);
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 typedef struct {
00348 CONDITION statusCode;
00349 char statusText[256];
00350 } EDB;
00351
00352 #define MAXEDB 100
00353
00354 static int stackPtr = -1;
00355 static EDB EDBStack[MAXEDB];
00356 static void (*ErrorCallback) () = NULL;
00357 static void dumpstack(FILE * fp);
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 CONDITION
00394 COND_PushCondition(CONDITION cond, char *controlString,...)
00395 {
00396 va_list
00397 args;
00398 char
00399 buffer[1024];
00400
00401
00402 va_start(args, controlString);
00403 if (controlString == NULL)
00404 controlString = "NULL Control string passedto PushCondition";
00405 (void) vsprintf(buffer, controlString, args);
00406 va_end(args);
00407
00408
00409 stackPtr++;
00410 EDBStack[stackPtr].statusCode = cond;
00411 buffer[256] = '\0';
00412
00413 (void) strcpy(EDBStack[stackPtr].statusText, buffer);
00414 if (ErrorCallback != NULL)
00415 #if 0
00416 ErrorCallback(EDBStack[stackPtr].statusCode,
00417 EDBStack[stackPtr].statusText);
00418 #else
00419 AFNI_CALL_VOID_2ARG( ErrorCallback ,
00420 CONDITION,EDBStack[stackPtr].statusCode ,
00421 char * ,EDBStack[stackPtr].statusText ) ;
00422 #endif
00423
00424 if (stackPtr >= MAXEDB - 2) {
00425 dumpstack(stderr);
00426 fprintf(stderr, "CONDITION Stack overflow\n");
00427 stackPtr = 0;
00428 }
00429
00430 return cond;
00431
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 CONDITION
00466 COND_ExtractConditions(CTNBOOLEAN(*callback) ())
00467 {
00468 int
00469 index,
00470 returnflag;
00471
00472 for (index = stackPtr, returnflag = 1; index >= 0 && returnflag != 0;
00473 index--) {
00474 #if 0
00475 returnflag = callback(EDBStack[index].statusCode,
00476 EDBStack[index].statusText);
00477 #else
00478 AFNI_CALL_VALU_2ARG( callback , int,returnflag ,
00479 CONDITION,EDBStack[index].statusCode ,
00480 char * ,EDBStack[index].statusText ) ;
00481 #endif
00482 }
00483
00484 return COND_NORMAL;
00485 }
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 CONDITION
00519 COND_TopCondition(CONDITION * code, char *text, unsigned long maxlength)
00520 {
00521 CONDITION rtnValue;
00522
00523 if (stackPtr >= 0) {
00524 *code = EDBStack[stackPtr].statusCode;
00525 (void) strncpy(text, EDBStack[stackPtr].statusText, maxlength - 1);
00526 text[maxlength - 1] = '\0';
00527 rtnValue = EDBStack[stackPtr].statusCode;
00528 } else {
00529 *code = COND_NORMAL;
00530 *text = '\0';
00531 rtnValue = COND_NORMAL;
00532 }
00533
00534 return rtnValue;
00535 }
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564 CONDITION
00565 COND_PopCondition(CTNBOOLEAN clearstack)
00566 {
00567 CONDITION
00568 value;
00569
00570 if (stackPtr >= 0)
00571 value = EDBStack[stackPtr].statusCode;
00572 else
00573 value = COND_NORMAL;
00574
00575 if (clearstack) {
00576 stackPtr = -1;
00577 } else if (stackPtr <= 0) {
00578 stackPtr = -1;
00579 } else {
00580 stackPtr--;
00581 }
00582
00583 return value;
00584 }
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611 CONDITION
00612 COND_EstablishCallback(void (*callback) ())
00613 {
00614
00615 ErrorCallback = callback;
00616
00617 return COND_NORMAL;
00618 }
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635 void
00636 COND_DumpConditions(void)
00637 {
00638
00639 dumpstack(stderr);
00640 stackPtr = -1;
00641 }
00642
00643 static void
00644 dumpstack(FILE * lfp)
00645 {
00646 int
00647 index;
00648
00649 for (index = 0; index <= stackPtr; index++)
00650 fprintf(lfp, "%8x %s\n", (unsigned int)EDBStack[index].statusCode,
00651 EDBStack[index].statusText);
00652 }
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678 void
00679 COND_CopyText(char *txt, size_t length)
00680 {
00681 size_t i;
00682 int j;
00683
00684 txt[0] = '\0';
00685
00686 j = stackPtr;
00687 while (length > 2 && j >= 0) {
00688 i = strlen(EDBStack[j].statusText);
00689 if (i > length)
00690 i = length - 2;
00691 strncpy(txt, EDBStack[j].statusText, i);
00692 txt[i++] = '\n';
00693 txt[i] = '\0';
00694 length -= i;
00695 txt += i;
00696 j--;
00697 }
00698 }
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714 void
00715 COND_WriteConditions(FILE * lfp)
00716 {
00717 dumpstack(lfp);
00718 stackPtr = -1;
00719 }
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864 static CTNBOOLEAN debug = FALSE;
00865
00866
00867
00868 static CONDITION
00869 newElementItem(DCM_ELEMENT * src, CTNBOOLEAN allocateData,
00870 PRV_ELEMENT_ITEM ** dst);
00871 static CONDITION
00872 findCreateGroup(PRIVATE_OBJECT ** object, unsigned short group,
00873 PRV_GROUP_ITEM ** groupPtr);
00874 static CONDITION
00875 insertNewElement(PRIVATE_OBJECT ** object,
00876 DCM_ELEMENT * element);
00877 static CONDITION
00878 updateObjectType(PRIVATE_OBJECT ** object,
00879 DCM_ELEMENT * element);
00880 static CONDITION
00881 updateSpecialElements(PRIVATE_OBJECT ** object,
00882 PRV_ELEMENT_ITEM * item);
00883 static void
00884 exportFixedFields(DCM_ELEMENT * element,
00885 unsigned char *b, U32 length, int byteOrder,
00886 CTNBOOLEAN explicitVR, U32 * rtnLength);
00887 static CONDITION
00888 exportData(PRIVATE_OBJECT ** object, PRV_ELEMENT_ITEM * item,
00889 unsigned char *src,
00890 unsigned char *dst, U32 length, int byteOrder,
00891 U32 * rtnLength);
00892 #ifdef MACOS
00893 static long fileSize(int fd);
00894 #else
00895 static int fileSize(int fd);
00896 #endif
00897 static void swapInPlace(PRIVATE_OBJECT ** object, DCM_ELEMENT * e);
00898 static CONDITION checkObject(PRIVATE_OBJECT ** object, char *caller);
00899 static CONDITION
00900 writeFile(void *buffer, U32 length, int flag, void *fd);
00901 static CONDITION
00902 countBytes(void *buffer, U32 length, int flag,
00903 void *sizePtr);
00904 static CONDITION
00905 exportStream(DCM_OBJECT ** callerObject, unsigned long opt,
00906 void *buffer, U32 bufferlength, CONDITION(*callback) (),
00907 void *ctx, int sequenceLevel);
00908
00909 static CONDITION
00910 verifyFormat(PRV_ELEMENT_ITEM * item);
00911 static CONDITION
00912 readFile(char *name, unsigned char *callerBuf, int fd, long size,
00913 off_t fileOffset, int recursionLevel,
00914 unsigned long opt, DCM_OBJECT ** callerObject,
00915 U32 * scannedLength, CTNBOOLEAN * remainOpenFlag,
00916 void *ctx,
00917 CONDITION(*rd) (void *ctx, void *buf, int toRead, int *bytesRead),
00918 CONDITION(*sk) (void *ctx, int offset, int flag));
00919 static CONDITION
00920 readFile1(const char *name, unsigned char *callerBuf, int fd, U32 size,
00921 off_t * fileOffset, int recursionLevel,
00922 unsigned long opt, PRIVATE_OBJECT ** parentObject,
00923 DCM_OBJECT ** callerObject,
00924 U32 * scannedLength, CTNBOOLEAN * remainOpenFlag,
00925 void *ctx,
00926 CONDITION(*rd) (void *ctx, void *buf, int toRead, int *bytesRead),
00927 CONDITION(*sk) (void *ctx, int offset, int flag));
00928
00929 static PRV_ELEMENT_ITEM *locateElement(PRIVATE_OBJECT ** obj, DCM_TAG tag);
00930 static void computeVM(PRIVATE_OBJECT ** object, DCM_ELEMENT * element);
00931 static void ctxSensitiveLookup(PRIVATE_OBJECT ** object, DCM_ELEMENT * element);
00932 static CONDITION
00933 copyData(PRIVATE_OBJECT ** object, PRV_ELEMENT_ITEM * item,
00934 DCM_ELEMENT * to, U32 * rtnLength);
00935 static CONDITION
00936 readLengthToEnd(int fd, const char *fileName,
00937 unsigned long opt, U32 * lengthToEnd);
00938
00939 static void swapATGroupElement(DCM_ELEMENT * e);
00940
00941 static void
00942 dumpBinaryData(void *d, DCM_VALUEREPRESENTATION vr,
00943 long vm, long vmLimit);
00944 static void
00945 compareGroup(PRV_GROUP_ITEM * g1, PRV_GROUP_ITEM * g2,
00946 void (*callback) (const DCM_ELEMENT * e1,
00947 const DCM_ELEMENT * e2,
00948 void *ctx),
00949 void *ctx);
00950 static void remapFileName(const char *name, char *mapName);
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000 CONDITION
01001 DCM_OpenFile(const char *name, unsigned long opt, DCM_OBJECT ** callerObject)
01002 {
01003 CONDITION cond;
01004 int fd;
01005 off_t fileOffset = 0;
01006 U32 lengthToEnd;
01007 U32 size;
01008 CTNBOOLEAN
01009 remainFileOpen = FALSE;
01010
01011 ENTRY("DCM_OpenFile") ;
01012
01013 if ((opt & (DCM_ORDERMASK | DCM_FILEFORMATMASK)) == 0)
01014 RETURN(COND_PushCondition(DCM_ILLEGALOPTION,
01015 DCM_Message(DCM_ILLEGALOPTION), "Byte order",
01016 "DCM_OpenFile"));
01017
01018 #ifdef _MSC_VER
01019 fd = open(name, O_RDONLY | O_BINARY);
01020 #else
01021 rwc_fd = fd = open(name, O_RDONLY);
01022 #endif
01023 if ((fd < 0) && ((opt & DCM_FILENAMEMASK) == DCM_TRYFILENAMECHANGE)) {
01024 char mapName[1024];
01025 remapFileName(name, mapName);
01026 #ifdef _MSC_VER
01027 fd = open(mapName, O_RDONLY | O_BINARY);
01028 #else
01029 fd = open(mapName, O_RDONLY);
01030 if (fd < 0) {
01031 strcat(mapName, ".");
01032 fd = open(mapName, O_RDONLY);
01033 }
01034 #endif
01035 }
01036 if (fd < 0) {
01037 char msg[1024] ;
01038 sprintf(msg,"DCM_OpenFile open(%s) fails",name) ;
01039 perror(msg) ;
01040 RETURN(COND_PushCondition(DCM_FILEOPENFAILED,
01041 DCM_Message(DCM_FILEOPENFAILED), name,
01042 "DCM_OpenFile"));
01043 }
01044 size = fileSize(fd);
01045 if (size <= 0)
01046 RETURN(DCM_FILEACCESSERROR);
01047
01048 if ((opt & DCM_LENGTHTOENDMASK) == DCM_USELENGTHTOEND) {
01049 cond = readLengthToEnd(fd, name,
01050 opt & (~DCM_LENGTHTOENDMASK), &lengthToEnd);
01051 if (cond != DCM_NORMAL) {
01052 (void) close(fd); rwc_fd = -1 ;
01053 RETURN(COND_PushCondition(DCM_FILEOPENFAILED,
01054 DCM_Message(DCM_FILEOPENFAILED), name, "DCM_OpenFile"));
01055 }
01056 size = lengthToEnd;
01057 fileOffset = 24;
01058 (void) lseek(fd, 24, SEEK_SET);
01059 }
01060 #ifdef OLDSMM
01061 cond = readFile(name, NULL, fd, size, 0, 0, opt, callerObject, NULL,
01062 &remainFileOpen, NULL, NULL, NULL);
01063 #endif
01064 cond = readFile1(name, NULL, fd, size, &fileOffset, 0, opt, NULL,
01065 callerObject, NULL, &remainFileOpen, NULL, NULL, NULL);
01066 if ((cond != DCM_NORMAL) || !remainFileOpen){
01067 (void) close(fd); rwc_fd = -1 ;
01068 }
01069 if (cond != DCM_NORMAL) {
01070 if (debug)
01071 DCM_DumpElements(callerObject, 1);
01072 RETURN(COND_PushCondition(DCM_FILEOPENFAILED,
01073 DCM_Message(DCM_FILEOPENFAILED), name, "DCM_OpenFile"));
01074 } else
01075 RETURN(DCM_NORMAL);
01076 }
01077
01078 CONDITION
01079 DCM_ReadStream(DCM_OBJECT ** callerObject, unsigned long opt, long size,
01080 void *ctx,
01081 CONDITION(*rd) (void *ctx, void *buf, int toRead, int *bytesRead),
01082 CONDITION(*sk) (void *ctx, int offset, int flag))
01083 {
01084 CONDITION cond;
01085 int fd = -1;
01086 CTNBOOLEAN
01087 remainFileOpen = FALSE;
01088 off_t fileOffset = 0;
01089
01090 if ((opt & (DCM_ORDERMASK | DCM_FILEFORMATMASK)) == 0)
01091 return COND_PushCondition(DCM_ILLEGALOPTION,
01092 DCM_Message(DCM_ILLEGALOPTION), "Byte order",
01093 "DCM_ReadStream");
01094
01095 cond = readFile1("", NULL, fd, size, &fileOffset, 0, opt, NULL,
01096 callerObject, NULL, &remainFileOpen, ctx, rd, sk);
01097 if (cond != DCM_NORMAL)
01098 return COND_PushCondition(DCM_READSTREAMFAILED,
01099 DCM_Message(DCM_READSTREAMFAILED), "DCM_ReadStream");
01100 else
01101 return DCM_NORMAL;
01102 }
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124 CONDITION
01125 DCM_CreateObject(DCM_OBJECT ** object, unsigned long opt)
01126 {
01127 PRIVATE_OBJECT
01128 * obj;
01129
01130 if (object == NULL) {
01131 (void) COND_PushCondition(DCM_NULLADDRESS,
01132 DCM_Message(DCM_NULLADDRESS), "DCM_CreateObject");
01133 return COND_PushCondition(DCM_OBJECTCREATEFAILED,
01134 DCM_Message(DCM_OBJECTCREATEFAILED), "DCM_CreateObject");
01135 }
01136 obj = (PRIVATE_OBJECT *) CTN_MALLOC(sizeof(PRIVATE_OBJECT));
01137 if (obj == NULL) {
01138 (void) COND_PushCondition(DCM_MALLOCFAILURE,
01139 DCM_Message(DCM_MALLOCFAILURE), sizeof(PRIVATE_OBJECT),
01140 "DCM_CreateObject");
01141 *object = NULL;
01142 return COND_PushCondition(DCM_OBJECTCREATEFAILED,
01143 DCM_Message(DCM_OBJECTCREATEFAILED), "DCM_CreateObject");
01144 }
01145 (void) memset(obj, 0, sizeof(PRIVATE_OBJECT));
01146 (void) strcpy(obj->keyType, KEY_DCM_OBJECT);
01147
01148
01149 obj->objectType = DCM_OBJECTUNKNOWN;
01150 obj->accessMethod = DCM_MEMORY_ACCESS;
01151 obj->deleteFlag = FALSE;
01152 if ((opt & DCM_GROUPLENGTHMASK) == DCM_NOGROUPLENGTH)
01153 obj->groupLengthFlag = FALSE;
01154 else
01155 obj->groupLengthFlag = TRUE;
01156 obj->objectSize = 0;
01157 obj->offset = 0;
01158 obj->pixelSize = 0;
01159 obj->pixelOffset = 0;
01160 obj->pixelBitsAllocated = 0;
01161 obj->pixelRepresentation = 0xffff;
01162 obj->groupCtx = NULL;
01163 obj->elementCtx = NULL;
01164 obj->fd = -1;
01165 obj->fileName[0] = '\0';
01166 obj->preambleFlag = FALSE;
01167 obj->preamble[0] = '\0';
01168 obj->dataOptions = 0;
01169 obj->metaHeaderLength = 0xffffffff;
01170 obj->longVRAttributes = 0;
01171 obj->waveformDataVR[0] = '\0';
01172
01173 obj->groupList = LST_Create();
01174 if (obj->groupList == NULL) {
01175 CTN_FREE(obj);
01176 *object = NULL;
01177 return COND_PushCondition(DCM_LISTFAILURE,
01178 DCM_Message(DCM_LISTFAILURE),
01179 "DCM_CreateObject");
01180 }
01181 *object = (DCM_OBJECT *) obj;
01182 return DCM_NORMAL;
01183 }
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206 CONDITION
01207 DCM_CloseObject(DCM_OBJECT ** callerObject)
01208 {
01209 CONDITION
01210 cond;
01211 PRV_GROUP_ITEM
01212 * group;
01213 PRV_ELEMENT_ITEM
01214 * element;
01215 PRIVATE_OBJECT
01216 ** object;
01217 DCM_SEQUENCE_ITEM
01218 * sequenceItem;
01219 DCM_FRAGMENT_ITEM* fragmentItem;
01220
01221 if (debug)
01222 fprintf(stderr, "Starting DCM_CloseObject\n");
01223
01224 object = (PRIVATE_OBJECT **) callerObject;
01225 cond = checkObject(object, "DCM_CloseObject");
01226 if (cond != DCM_NORMAL)
01227 return cond;
01228
01229 if ((*object)->fd > 0)
01230 (void) close((*object)->fd);
01231
01232 if (debug)
01233 fprintf(stderr, "DCM_CloseObject: Legal object and file closed\n");
01234
01235 while ((group = (void *)LST_Pop(&(*object)->groupList)) != NULL) {
01236 if (debug)
01237 fprintf(stderr, "DCM_CloseObject: group %04x\n", group->group);
01238
01239 while ((element = (void *)LST_Pop(&group->elementList)) != NULL) {
01240 if (debug)
01241 fprintf(stderr, "DCM_CloseObject: Element %08x\n",
01242 element->element.tag);
01243 if (element->element.representation == DCM_SQ) {
01244 if (debug)
01245 fprintf(stderr, "Sequence List Address: %p\n",
01246 element->element.d.sq);
01247 if (element->element.d.sq != NULL) {
01248 while ((sequenceItem = (void *)LST_Pop(&element->element.d.sq)) != NULL) {
01249 (void) DCM_CloseObject(&sequenceItem->object);
01250 CTN_FREE(sequenceItem);
01251 }
01252 (void) LST_Destroy(&element->element.d.sq);
01253 }
01254 } else if (element->fragmentFlag) {
01255 if (debug)
01256 fprintf(stderr, "Fragment List Address: %p\n",
01257 element->element.d.fragments);
01258 if (element->element.d.fragments != NULL) {
01259 while ((fragmentItem = (void *)LST_Pop(&element->element.d.fragments)) != NULL) {
01260 CTN_FREE(fragmentItem);
01261 }
01262 (void) LST_Destroy(&element->element.d.fragments);
01263 }
01264 }
01265 if (debug)
01266 fprintf(stderr, "DCM_CloseObject: free %8p\n", element);
01267
01268 CTN_FREE(element);
01269 }
01270 cond = LST_Destroy(&group->elementList);
01271 if (cond != LST_NORMAL)
01272 return COND_PushCondition(DCM_LISTFAILURE,
01273 DCM_Message(DCM_LISTFAILURE), "DCM_CloseObject");
01274 CTN_FREE(group);
01275 }
01276 cond = LST_Destroy(&(*object)->groupList);
01277 if (cond != LST_NORMAL)
01278 return COND_PushCondition(DCM_LISTFAILURE,
01279 DCM_Message(DCM_LISTFAILURE), "DCM_CloseObject");
01280
01281 cond = DCM_NORMAL;
01282 if ((*object)->deleteFlag) {
01283 if (unlink((*object)->fileName) != 0) {
01284
01285 cond = COND_PushCondition(DCM_FILEDELETEFAILED,
01286 DCM_Message(DCM_FILEDELETEFAILED), (*object)->fileName, strerror(errno),
01287 "DCM_CloseObject");
01288
01289 }
01290 }
01291 CTN_FREE(*object);
01292 *object = NULL;
01293 return cond;
01294 }
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333 CONDITION
01334 DCM_AddElement(DCM_OBJECT ** callerObject, DCM_ELEMENT * element)
01335 {
01336 CONDITION
01337 cond;
01338 DCM_ELEMENT
01339 localElement;
01340 PRIVATE_OBJECT
01341 ** object;
01342 PRV_GROUP_ITEM
01343 * groupItem;
01344
01345 object = (PRIVATE_OBJECT **) callerObject;
01346
01347 cond = checkObject(object, "DCM_AddElement");
01348 if (cond != DCM_NORMAL)
01349 return cond;
01350
01351 if ((DCM_TAG_ELEMENT(element->tag) == 0x0000))
01352 return COND_PushCondition(DCM_ILLEGALADD,
01353 DCM_Message(DCM_ILLEGALADD), DCM_TAG_GROUP(element->tag),
01354 DCM_TAG_ELEMENT(element->tag), "DCM_AddElement");
01355
01356
01357 localElement = *element;
01358
01359 cond = DCM_LookupElement(&localElement);
01360 if (cond != DCM_NORMAL) {
01361 (void) COND_PopCondition(0);
01362 localElement = *element;
01363 } else {
01364 if (localElement.representation == DCM_OT ||
01365 localElement.representation == DCM_CTX)
01366 localElement.representation = element->representation;
01367 if (element->representation != DCM_UN &&
01368 element->representation != localElement.representation) {
01369 return COND_PushCondition(DCM_ILLEGALREPRESENTATION,
01370 DCM_Message(DCM_ILLEGALREPRESENTATION),
01371 DCM_TAG_GROUP(element->tag),
01372 DCM_TAG_ELEMENT(element->tag),
01373 "DCM_AddElement");
01374 }
01375 }
01376
01377 cond = findCreateGroup(object, DCM_TAG_GROUP(localElement.tag), &groupItem);
01378 if (cond != DCM_NORMAL)
01379 return COND_PushCondition(DCM_INSERTFAILED,
01380 DCM_Message(DCM_INSERTFAILED), DCM_TAG_GROUP(element->tag),
01381 DCM_TAG_ELEMENT(element->tag),
01382 "DCM_AddElement");
01383
01384 cond = insertNewElement(object, &localElement);
01385 if (cond != DCM_NORMAL)
01386 return COND_PushCondition(DCM_INSERTFAILED,
01387 DCM_Message(DCM_INSERTFAILED), DCM_TAG_GROUP(element->tag),
01388 DCM_TAG_ELEMENT(element->tag),
01389 "DCM_AddElement");
01390
01391 cond = updateObjectType(object, &localElement);
01392 if (cond != DCM_NORMAL)
01393 return COND_PushCondition(DCM_INSERTFAILED,
01394 DCM_Message(DCM_INSERTFAILED), DCM_TAG_GROUP(element->tag),
01395 DCM_TAG_ELEMENT(element->tag),
01396 "DCM_AddElement");
01397
01398 return DCM_NORMAL;
01399 }
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424 CONDITION
01425 DCM_AddSequenceElement(DCM_OBJECT ** callerObject, DCM_ELEMENT * element)
01426 {
01427 CONDITION cond;
01428 DCM_ELEMENT localElement;
01429 PRIVATE_OBJECT **object;
01430 PRV_GROUP_ITEM *groupItem;
01431
01432 object = (PRIVATE_OBJECT **) callerObject;
01433
01434 cond = checkObject(object, "DCM_AddSequenceElement");
01435 if (cond != DCM_NORMAL)
01436 return cond;
01437
01438 if ((DCM_TAG_ELEMENT(element->tag) == 0x0000))
01439 return COND_PushCondition(DCM_ILLEGALADD,
01440 DCM_Message(DCM_ILLEGALADD), DCM_TAG_GROUP(element->tag),
01441 DCM_TAG_ELEMENT(element->tag), "DCM_AddElement");
01442
01443
01444 localElement = *element;
01445
01446 cond = DCM_LookupElement(&localElement);
01447 if (cond != DCM_NORMAL) {
01448 (void) COND_PopCondition(0);
01449 localElement = *element;
01450 } else {
01451 localElement.representation = element->representation;
01452 }
01453 if (localElement.representation != DCM_SQ) {
01454 return COND_PushCondition(DCM_NOTASEQUENCE,
01455 DCM_Message(DCM_NOTASEQUENCE),
01456 DCM_TAG_GROUP(localElement.tag),
01457 DCM_TAG_ELEMENT(localElement.tag),
01458 "DCM_AddSequenceElement");
01459 }
01460 cond = findCreateGroup(object, DCM_TAG_GROUP(localElement.tag), &groupItem);
01461 if (cond != DCM_NORMAL)
01462 return COND_PushCondition(DCM_INSERTFAILED,
01463 DCM_Message(DCM_INSERTFAILED), DCM_TAG_GROUP(element->tag),
01464 DCM_TAG_ELEMENT(element->tag),
01465 "DCM_AddSequenceElement");
01466
01467 cond = insertNewElement(object, &localElement);
01468 if (cond != DCM_NORMAL)
01469 return COND_PushCondition(DCM_INSERTFAILED,
01470 DCM_Message(DCM_INSERTFAILED), DCM_TAG_GROUP(element->tag),
01471 DCM_TAG_ELEMENT(element->tag),
01472 "DCM_AddElement");
01473
01474 cond = updateObjectType(object, &localElement);
01475 if (cond != DCM_NORMAL)
01476 return COND_PushCondition(DCM_INSERTFAILED,
01477 DCM_Message(DCM_INSERTFAILED), DCM_TAG_GROUP(element->tag),
01478 DCM_TAG_ELEMENT(element->tag),
01479 "DCM_AddSequenceElement");
01480
01481
01482
01483
01484
01485 element->d.sq = NULL;
01486
01487 return DCM_NORMAL;
01488 }
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510 CONDITION
01511 DCM_RemoveElement(DCM_OBJECT ** callerObject, DCM_TAG tag)
01512 {
01513 PRIVATE_OBJECT
01514 ** object;
01515 PRV_GROUP_ITEM
01516 * groupItem;
01517 PRV_ELEMENT_ITEM
01518 * elementItem,
01519 *groupLengthItem;
01520 CONDITION
01521 cond;
01522 CTNBOOLEAN
01523 flag;
01524 unsigned short
01525 group,
01526 element;
01527
01528 object = (PRIVATE_OBJECT **) callerObject;
01529 cond = checkObject(object, "DCM_RemoveElement");
01530 if (cond != DCM_NORMAL)
01531 return cond;
01532
01533 group = DCM_TAG_GROUP(tag);
01534 element = DCM_TAG_ELEMENT(tag);
01535
01536 groupItem = (void *)LST_Head(&((*object)->groupList));
01537 if (groupItem == NULL)
01538 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
01539 DCM_Message(DCM_ELEMENTNOTFOUND), group, element,
01540 "DCM_RemoveElement");
01541
01542 (void) LST_Position(&((*object)->groupList), (void *)groupItem);
01543
01544 flag = FALSE;
01545 while ((groupItem != NULL) && (flag == FALSE)) {
01546 if (groupItem->group == group)
01547 flag = TRUE;
01548 else
01549 groupItem = (void *)LST_Next(&(*object)->groupList);
01550 }
01551 if (flag == FALSE)
01552 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
01553 DCM_Message(DCM_ELEMENTNOTFOUND), group, element,
01554 "DCM_RemoveElement");
01555
01556 elementItem = (void *)LST_Head(&groupItem->elementList);
01557 if (elementItem == NULL)
01558 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
01559 DCM_Message(DCM_ELEMENTNOTFOUND), group, element,
01560 "DCM_RemoveElement");
01561
01562 (void) LST_Position(&groupItem->elementList, (void *)elementItem);
01563
01564 groupLengthItem = elementItem;
01565 if (DCM_TAG_ELEMENT(groupLengthItem->element.tag) != 0x0000)
01566 groupLengthItem = NULL;
01567
01568
01569 flag = FALSE;
01570 while ((elementItem != NULL) && (flag == FALSE)) {
01571 if (DCM_TAG_ELEMENT(elementItem->element.tag) == element)
01572 flag = TRUE;
01573 else
01574 elementItem = (void *)LST_Next(&groupItem->elementList);
01575 }
01576
01577 if (flag == FALSE)
01578 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
01579 DCM_Message(DCM_ELEMENTNOTFOUND), group, element,
01580 "DCM_RemoveElement");
01581
01582 if (groupItem->baseLength != DCM_UNSPECIFIEDLENGTH) {
01583 groupItem->baseLength -= elementItem->paddedDataLength + 2 + 2 + 4;
01584 if (groupLengthItem != NULL) {
01585 *groupLengthItem->element.d.ul = groupItem->baseLength;
01586 }
01587 }
01588 if ((*object)->objectSize != DCM_UNSPECIFIEDLENGTH)
01589 (*object)->objectSize -= elementItem->paddedDataLength + 2 + 2 + 4;
01590 if (elementItem->element.representation == DCM_OW ||
01591 elementItem->element.representation == DCM_OB ||
01592 elementItem->element.representation == DCM_SQ) {
01593 groupItem->longVRAttributes--;
01594 (*object)->longVRAttributes--;
01595 }
01596 (void) LST_Remove(&(groupItem->elementList), LST_K_AFTER);
01597 CTN_FREE(elementItem);
01598 return DCM_NORMAL;
01599 }
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650 CONDITION
01651 DCM_GetElementValue(DCM_OBJECT ** callerObject, DCM_ELEMENT * element,
01652 U32 * rtnLength, void **ctx)
01653 {
01654 PRIVATE_OBJECT
01655 ** object;
01656 PRV_GROUP_ITEM
01657 * groupItem;
01658 PRV_ELEMENT_ITEM
01659 * elementItem;
01660 int
01661 nBytes;
01662 CONDITION
01663 cond;
01664
01665 object = (PRIVATE_OBJECT **) callerObject;
01666 cond = checkObject(object, "DCM_GetElementValue");
01667 if (cond != DCM_NORMAL)
01668 return cond;
01669
01670 groupItem = (void *)LST_Head(&(*object)->groupList);
01671 if (groupItem == NULL)
01672 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
01673 DCM_Message(DCM_ELEMENTNOTFOUND), DCM_TAG_GROUP(element->tag),
01674 DCM_TAG_ELEMENT(element->tag),
01675 "DCM_GetElementValue");
01676
01677 (void) LST_Position(&(*object)->groupList, (void *)groupItem);
01678 while (groupItem != NULL) {
01679 if (groupItem->group == DCM_TAG_GROUP(element->tag))
01680 break;
01681
01682 groupItem = (void *)LST_Next(&(*object)->groupList);
01683 }
01684 if (groupItem == NULL)
01685 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
01686 DCM_Message(DCM_ELEMENTNOTFOUND), DCM_TAG_GROUP(element->tag),
01687 DCM_TAG_ELEMENT(element->tag),
01688 "DCM_GetElementValue");
01689
01690 elementItem = (void *)LST_Head(&groupItem->elementList);
01691 if (elementItem == NULL)
01692 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
01693 DCM_Message(DCM_ELEMENTNOTFOUND), DCM_TAG_GROUP(element->tag),
01694 DCM_TAG_GROUP(element->tag),
01695 "DCM_GetElementValue");
01696
01697 (void) LST_Position(&groupItem->elementList, (void *)elementItem);
01698 while (elementItem != NULL) {
01699 if (elementItem->element.tag == element->tag) {
01700 unsigned char *p;
01701 U32 l;
01702
01703 if (element->representation == DCM_SQ)
01704 return COND_PushCondition(DCM_CANNOTGETSEQUENCEVALUE,
01705 DCM_Message(DCM_CANNOTGETSEQUENCEVALUE),
01706 element->tag, "DCM_GetElementValue");
01707
01708 p = *ctx;
01709 if ((U32) p > elementItem->element.length)
01710 return COND_PushCondition(DCM_ILLEGALCONTEXT,
01711 DCM_Message(DCM_ILLEGALCONTEXT),
01712 "DCM_GetElementValue");
01713
01714 l = MIN(element->length, (elementItem->element.length - (U32) p));
01715
01716 *rtnLength = l;
01717 {
01718 if (elementItem->element.d.ot == NULL) {
01719 if ((*object)->fd != -1) {
01720 (void) lseek((*object)->fd,
01721 elementItem->dataOffset + (off_t) p, SEEK_SET);
01722 nBytes = read((*object)->fd, element->d.ot, (int) l);
01723 } else {
01724 (*object)->sk((*object)->userCtx,
01725 (long) (elementItem->dataOffset + (off_t) p), SEEK_SET);
01726 cond = (*object)->rd((*object)->userCtx, element->d.ot, l,
01727 &nBytes);
01728 }
01729 if ((unsigned) nBytes != l) {
01730 return COND_PushCondition(DCM_FILEACCESSERROR,
01731 DCM_Message(DCM_FILEACCESSERROR),
01732 (*object)->fileName,
01733 "DCM_GetElementValue");
01734 }
01735 if( LITTLE_ENDIAN_ARCHITECTURE ){
01736 if (elementItem->element.representation == DCM_AT) {
01737 DCM_ELEMENT e;
01738 e = elementItem->element;
01739 e.length = l;
01740 e.d.ot = element->d.ot;
01741 swapATGroupElement(&e);
01742 }
01743 }
01744 if (elementItem->byteOrder == BYTEORDER_REVERSE) {
01745 DCM_ELEMENT e;
01746 e = elementItem->element;
01747 e.length = l;
01748 e.d.ot = element->d.ot;
01749 swapInPlace(object, &e);
01750 }
01751 } else {
01752 unsigned char *q;
01753 q = (unsigned char *) elementItem->element.d.ot +
01754 (U32) p;
01755 (void) memcpy(element->d.ot, q, l);
01756 if (elementItem->byteOrder == BYTEORDER_REVERSE) {
01757 DCM_ELEMENT e;
01758 e = elementItem->element;
01759 e.length = l;
01760 e.d.ot = element->d.ot;
01761 swapInPlace(object, &e);
01762 }
01763 }
01764 p += l;
01765 *ctx = (void *) p;
01766 if ((unsigned) p == elementItem->element.length)
01767 return DCM_NORMAL;
01768 else
01769 return DCM_GETINCOMPLETE;
01770 }
01771
01772 }
01773 elementItem = (void *)LST_Next(&groupItem->elementList);
01774 }
01775 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
01776 DCM_Message(DCM_ELEMENTNOTFOUND), DCM_TAG_GROUP(element->tag),
01777 DCM_TAG_ELEMENT(element->tag),
01778 "DCM_GetElementValue");
01779 }
01780
01781 char*
01782 DCM_GetString(DCM_OBJECT** callerObject, DCM_TAG tag)
01783 {
01784 DCM_ELEMENT e;
01785 CONDITION cond;
01786 char* s;
01787 char tmp[64] = "";
01788 char b[64] = "";
01789
01790 e.tag = tag;
01791 cond = DCM_GetElement(callerObject, tag, &e);
01792 if (cond != DCM_NORMAL) {
01793 COND_PopCondition(TRUE);
01794 return 0;
01795 }
01796
01797 if (DCM_IsString(e.representation)) {
01798 s = AFMALL( char, e.length + 1);
01799 e.d.string = s;
01800 cond = DCM_ParseObject(callerObject, &e, 1, 0, 0, 0);
01801 if (cond != DCM_NORMAL) {
01802 free(s);
01803 s = 0;
01804 }
01805 return s;
01806 }
01807
01808 if (e.representation == DCM_SQ) {
01809 return 0;
01810 }
01811
01812 if (e.length > sizeof(b))
01813 return 0;
01814
01815 e.d.ot = b;
01816 cond = DCM_ParseObject(callerObject, &e, 1, 0, 0, 0);
01817 if (cond != DCM_NORMAL) {
01818 COND_PopCondition(TRUE);
01819 return 0;
01820 }
01821
01822 switch (e.representation) {
01823 case DCM_AT:
01824 case DCM_FD:
01825 case DCM_FL:
01826 strcpy(tmp, "<Unimplemented>");
01827 break;
01828 case DCM_SL:
01829 sprintf(tmp, "%d", *e.d.sl);
01830 break;
01831 case DCM_SQ:
01832 strcpy(tmp, "<Unimplemented>");
01833 break;
01834 case DCM_SS:
01835 sprintf(tmp, "%d", *e.d.ss);
01836 break;
01837 case DCM_UL:
01838 sprintf(tmp, "%d", *e.d.ul);
01839 break;
01840 case DCM_UN:
01841 strcpy(tmp, "<Unimplemented>");
01842 break;
01843 case DCM_US:
01844 sprintf(tmp, "%d", *e.d.us);
01845 break;
01846
01847 case DCM_RET:
01848 case DCM_CTX:
01849 case DCM_OB:
01850 case DCM_OW:
01851 case DCM_DLM:
01852 default:
01853 strcpy(tmp, "<Unimplemented>");
01854 break;
01855 }
01856
01857 s = (char*) malloc(strlen(tmp) + 1);
01858 strcpy(s, tmp);
01859
01860 return s;
01861 }
01862
01863
01864
01865 CONDITION
01866 DCM_GetElementValueOffset(DCM_OBJECT ** callerObject, DCM_ELEMENT * element,
01867 unsigned long offset)
01868 {
01869 PRIVATE_OBJECT **object;
01870 PRV_ELEMENT_ITEM *elementItem;
01871 int nBytes;
01872 CONDITION cond;
01873
01874 object = (PRIVATE_OBJECT **) callerObject;
01875 cond = checkObject(object, "DCM_GetElementValue");
01876 if (cond != DCM_NORMAL)
01877 return cond;
01878
01879 elementItem = locateElement(object, element->tag);
01880 if (elementItem == NULL)
01881 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
01882 DCM_Message(DCM_ELEMENTNOTFOUND), DCM_TAG_GROUP(element->tag),
01883 DCM_TAG_ELEMENT(element->tag),
01884 "DCM_GetElementValueOffset");
01885
01886
01887 {
01888 unsigned char *p;
01889 U32 l;
01890
01891 if (element->representation == DCM_SQ)
01892 return COND_PushCondition(DCM_CANNOTGETSEQUENCEVALUE,
01893 DCM_Message(DCM_CANNOTGETSEQUENCEVALUE),
01894 element->tag, "DCM_GetElementValueOffset");
01895
01896 p = (unsigned char *) offset;;
01897 if ((U32) p > elementItem->element.length)
01898 return COND_PushCondition(DCM_BADOFFSET,
01899 DCM_Message(DCM_BADOFFSET),
01900 (int) offset,
01901 (int) elementItem->element.length,
01902 "DCM_GetElementValueLength");
01903
01904 l = element->length;
01905 if (l + offset > elementItem->element.length) {
01906 return COND_PushCondition(DCM_BADLENGTH,
01907 DCM_Message(DCM_BADLENGTH),
01908 (int) offset, (int) l,
01909 (int) elementItem->element.length,
01910 "DCM_GetElementValueLength");
01911 } {
01912 if (elementItem->element.d.ot == NULL) {
01913 if ((*object)->fd != -1) {
01914 (void) lseek((*object)->fd,
01915 elementItem->dataOffset + (off_t) p, SEEK_SET);
01916 nBytes = read((*object)->fd, element->d.ot, (int) l);
01917 } else {
01918 (*object)->sk((*object)->userCtx,
01919 (long) (elementItem->dataOffset + (off_t) p), SEEK_SET);
01920 cond = (*object)->rd((*object)->userCtx, element->d.ot, l,
01921 &nBytes);
01922 }
01923 if ((unsigned) nBytes != l) {
01924 return COND_PushCondition(DCM_FILEACCESSERROR,
01925 DCM_Message(DCM_FILEACCESSERROR),
01926 (*object)->fileName,
01927 "DCM_GetElementValueValue");
01928 }
01929 if( LITTLE_ENDIAN_ARCHITECTURE ){
01930 if (elementItem->element.representation == DCM_AT) {
01931 DCM_ELEMENT e;
01932 e = elementItem->element;
01933 e.length = l;
01934 e.d.ot = element->d.ot;
01935 swapATGroupElement(&e);
01936 }
01937 }
01938 if (elementItem->byteOrder == BYTEORDER_REVERSE) {
01939 DCM_ELEMENT e;
01940 e = elementItem->element;
01941 e.length = l;
01942 e.d.ot = element->d.ot;
01943 swapInPlace(object, &e);
01944 }
01945 } else {
01946 unsigned char *q;
01947 q = (unsigned char *) elementItem->element.d.ot +
01948 (U32) p;
01949 (void) memcpy(element->d.ot, q, l);
01950 if (elementItem->byteOrder == BYTEORDER_REVERSE) {
01951 DCM_ELEMENT e;
01952 e = elementItem->element;
01953 e.length = l;
01954 e.d.ot = element->d.ot;
01955 swapInPlace(object, &e);
01956 }
01957 }
01958 return DCM_NORMAL;
01959 }
01960
01961 }
01962 }
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989 CONDITION
01990 DCM_GetElementSize(DCM_OBJECT ** callerObject, DCM_TAG tag,
01991 U32 * rtnLength)
01992 {
01993 PRIVATE_OBJECT
01994 ** object;
01995 PRV_GROUP_ITEM
01996 * groupItem;
01997 PRV_ELEMENT_ITEM
01998 * elementItem;
01999 CONDITION
02000 cond;
02001 CTNBOOLEAN
02002 flag;
02003 unsigned short
02004 group,
02005 element;
02006
02007 object = (PRIVATE_OBJECT **) callerObject;
02008 cond = checkObject(object, "DCM_GetElementSize");
02009 if (cond != DCM_NORMAL)
02010 return cond;
02011
02012 group = DCM_TAG_GROUP(tag);
02013 element = DCM_TAG_ELEMENT(tag);
02014
02015 groupItem = (void *)LST_Head(&((*object)->groupList));
02016 if (groupItem == NULL)
02017 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
02018 DCM_Message(DCM_ELEMENTNOTFOUND), group, element,
02019 "DCM_GetElementSize");
02020
02021 (void) LST_Position(&((*object)->groupList), (void *)groupItem);
02022
02023 flag = FALSE;
02024 while ((groupItem != NULL) && (flag == FALSE)) {
02025 if (groupItem->group == group)
02026 flag = TRUE;
02027 else
02028 groupItem = (void *)LST_Next(&(*object)->groupList);
02029 }
02030 if (flag == FALSE)
02031 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
02032 DCM_Message(DCM_ELEMENTNOTFOUND), group, element,
02033 "DCM_GetElementSize");
02034
02035 elementItem = (void *)LST_Head(&groupItem->elementList);
02036 if (elementItem == NULL)
02037 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
02038 DCM_Message(DCM_ELEMENTNOTFOUND), group, element,
02039 "DCM_GetElementSize");
02040
02041 (void) LST_Position(&groupItem->elementList, (void *)elementItem);
02042
02043 flag = FALSE;
02044 while ((elementItem != NULL) && (flag == FALSE)) {
02045 if (elementItem->element.tag == tag)
02046 flag = TRUE;
02047 else
02048 elementItem = (void *)LST_Next(&groupItem->elementList);
02049 }
02050
02051 if (flag == FALSE)
02052 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
02053 DCM_Message(DCM_ELEMENTNOTFOUND), group, element,
02054 "DCM_GetElementSize");
02055
02056
02057 *rtnLength = elementItem->element.length;
02058 return DCM_NORMAL;
02059 }
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103 CONDITION
02104 DCM_ScanParseObject(DCM_OBJECT ** callerObject, void *buf, size_t bufferSize,
02105 DCM_FLAGGED_ELEMENT * elementVector, int vectorLength,
02106 CONDITION(*callback) (const DCM_ELEMENT* e, void* ctx),
02107 void *ctx)
02108 {
02109 PRIVATE_OBJECT
02110 ** object;
02111 PRV_GROUP_ITEM
02112 * groupItem;
02113 PRV_ELEMENT_ITEM
02114 * elementItem;
02115 CONDITION
02116 cond;
02117 CTNBOOLEAN
02118 done = FALSE;
02119 DCM_ELEMENT
02120 e;
02121 int
02122 i;
02123 CTNBOOLEAN
02124 found;
02125 U32
02126 l;
02127 char
02128 *p;
02129
02130 object = (PRIVATE_OBJECT **) callerObject;
02131 cond = checkObject(object, "DCM_ScanParseObject");
02132 if (cond != DCM_NORMAL)
02133 return cond;
02134
02135 groupItem = (void *)LST_Head(&((*object)->groupList));
02136 (void) LST_Position(&((*object)->groupList), (void *)groupItem);
02137 while (groupItem != NULL && !done) {
02138 elementItem = (void *)LST_Head(&groupItem->elementList);
02139 (void) LST_Position(&groupItem->elementList, (void *)elementItem);
02140 while (elementItem != NULL && !done) {
02141 for (found = FALSE, i = 0; !found && i < vectorLength; i++) {
02142 if (elementItem->element.tag == elementVector[i].e.tag) {
02143 found = TRUE;
02144 (void)copyData(object,elementItem,&elementVector[i].e, &l);
02145 *elementVector[i].flagAddress |= elementVector[i].flag;
02146
02147 if (DCM_IsString(elementVector[i].e.representation)) {
02148 elementVector[i].e.d.string[l] = '\0';
02149 p = elementVector[i].e.d.string + l - 1;
02150 while (p >= elementVector[i].e.d.string && (*p == ' '))
02151 *p-- = '\0';
02152 }
02153 }
02154 }
02155 if (!found) {
02156 e = elementItem->element;
02157 cond = callback(&e, ctx);
02158 if (cond != DCM_NORMAL)
02159 done = TRUE;
02160 }
02161 elementItem = (void *)LST_Next(&groupItem->elementList);
02162 }
02163 groupItem = (void *)LST_Next(&((*object)->groupList));
02164 }
02165 return DCM_NORMAL;
02166 }
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202 CONDITION
02203 DCM_ImportStream(unsigned char *buf, unsigned long length,
02204 unsigned long opt, DCM_OBJECT ** callerObject)
02205 {
02206 #ifdef DEBUG
02207 if (debug)
02208 (void) fprintf(stderr, "DCM_ImportStream, %ld bytes\n", length);
02209 #endif
02210
02211 if ((opt & DCM_ORDERMASK) == 0)
02212 return COND_PushCondition(DCM_ILLEGALOPTION,
02213 DCM_Message(DCM_ILLEGALOPTION), "Byte order",
02214 "DCM_ImportStream");
02215
02216 return readFile("", buf, -1, length, 0, 0, opt, callerObject, NULL, NULL,
02217 NULL, NULL, NULL);
02218 }
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241 CONDITION
02242 DCM_GetObjectSize(DCM_OBJECT ** callerObject, unsigned long *returnlength)
02243 {
02244 PRIVATE_OBJECT
02245 ** object;
02246 CONDITION
02247 cond;
02248
02249 object = (PRIVATE_OBJECT **) callerObject;
02250 cond = checkObject(object, "DCM_GetObjectSize");
02251 if (cond != DCM_NORMAL)
02252 return cond;
02253
02254 *returnlength = (*object)->objectSize;
02255 return DCM_NORMAL;
02256 }
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286 CONDITION
02287 DCM_DumpElements(DCM_OBJECT ** callerObject, long vm)
02288 {
02289 PRV_GROUP_ITEM
02290 * groupItem;
02291 PRV_ELEMENT_ITEM
02292 * elementItem;
02293 PRIVATE_OBJECT
02294 ** object;
02295 CONDITION
02296 cond;
02297 DCM_SEQUENCE_ITEM
02298 * sq;
02299 char
02300 scratch[128];
02301 int
02302 stringLength;
02303
02304 object = (PRIVATE_OBJECT **) callerObject;
02305
02306 cond = checkObject(object, "DCM_DumpElements");
02307 if (cond != DCM_NORMAL)
02308 return cond;
02309
02310 switch ((*object)->objectType) {
02311 case DCM_OBJECTUNKNOWN:
02312 RWC_printf("Object type: UNKNOWN\n");
02313 break;
02314 case DCM_OBJECTCOMMAND:
02315 RWC_printf("Object type: COMMAND\n");
02316 break;
02317 case DCM_OBJECTIMAGE:
02318 RWC_printf("Object type: IMAGE\n");
02319 break;
02320 case DCM_OBJECTELEMENTLIST:
02321 RWC_printf("Object type: ELEMENT LIST\n");
02322 break;
02323 default:
02324 RWC_printf("Object type: Unknown (error)\n");
02325 break;
02326 }
02327 RWC_printf("Object size: %ld\n", (*object)->objectSize);
02328
02329 groupItem = (void *)LST_Head(&(*object)->groupList);
02330 if (groupItem != NULL)
02331 (void) LST_Position(&(*object)->groupList, (void *)groupItem);
02332
02333 while (groupItem != NULL) {
02334 #ifdef MACOS
02335 RWC_printf("Group: %04x, Length: %8ld\n", groupItem->group,
02336 groupItem->baseLength);
02337 #else
02338 RWC_printf("Group: %04x, Length: %8d\n", groupItem->group,
02339 groupItem->baseLength);
02340 #endif
02341 elementItem = (void *)LST_Head(&groupItem->elementList);
02342 if (elementItem != NULL)
02343 (void) LST_Position(&groupItem->elementList, (void *)elementItem);
02344 while (elementItem != NULL) {
02345 #ifdef MACOS
02346 (void) RWC_printf("%04x %04x %8ld [%-8lu] ",
02347 DCM_TAG_GROUP(elementItem->element.tag),
02348 DCM_TAG_ELEMENT(elementItem->element.tag),
02349 elementItem->element.length ,
02350 (unsigned long) elementItem->element.data_offset );
02351 #else
02352 (void) RWC_printf("%04x %04x %8d [%-8lu] ",
02353 DCM_TAG_GROUP(elementItem->element.tag),
02354 DCM_TAG_ELEMENT(elementItem->element.tag),
02355 elementItem->element.length ,
02356 (unsigned long) elementItem->element.data_offset );
02357 #endif
02358
02359 if( (rwc_opt & RWC_NONAME_MASK) == 0 )
02360 (void) RWC_printf("//%31s//", elementItem->element.description);
02361 else
02362 (void) RWC_printf("//") ;
02363
02364 if (elementItem->element.d.ot == NULL)
02365 (void) RWC_printf("Data on disk\n");
02366 else {
02367 switch (elementItem->element.representation) {
02368 case DCM_AE:
02369 case DCM_AS:
02370 case DCM_CS:
02371 case DCM_DA:
02372 case DCM_DT:
02373 stringLength = MIN(sizeof(scratch) - 1, elementItem->element.length);
02374 strncpy(scratch, elementItem->element.d.string, stringLength);
02375 scratch[stringLength] = '\0';
02376 (void) RWC_printf("%s\n", scratch);
02377 break;
02378 case DCM_DD:
02379 case DCM_FD:
02380 case DCM_FL:
02381 (void) RWC_printf("Unimplemented\n");
02382 break;
02383 case DCM_DS:
02384 case DCM_IS:
02385 case DCM_LO:
02386 case DCM_LT:
02387 case DCM_PN:
02388 case DCM_SH:
02389 case DCM_UT:
02390 stringLength = MIN(sizeof(scratch) - 1, elementItem->element.length);
02391 strncpy(scratch, elementItem->element.d.string, stringLength);
02392 scratch[stringLength] = '\0';
02393 (void) RWC_printf("%s\n", scratch);
02394 break;
02395 case DCM_SL:
02396 #ifdef MACOS
02397 (void) RWC_printf("%8lx %ld\n", *elementItem->element.d.sl,
02398 *elementItem->element.d.sl);
02399 #else
02400 if( (rwc_opt & RWC_NOHEX_MASK) == 0 )
02401 (void) RWC_printf("%8x %d\n", *elementItem->element.d.sl,
02402 *elementItem->element.d.sl);
02403 else
02404 (void) RWC_printf(" %d\n", *elementItem->element.d.sl ) ;
02405
02406 if (vm > 1)
02407 dumpBinaryData(elementItem->element.d.ot,
02408 elementItem->element.representation,
02409 elementItem->element.length / sizeof(U32), vm);
02410 #endif
02411 break;
02412 case DCM_SS:
02413 if( (rwc_opt & RWC_NOHEX_MASK) == 0 )
02414 (void) RWC_printf("%4x %d\n", *elementItem->element.d.ss,
02415 *elementItem->element.d.ss);
02416 else
02417 (void) RWC_printf(" %d\n", *elementItem->element.d.ss ) ;
02418
02419 if (vm > 1)
02420 dumpBinaryData(elementItem->element.d.ot,
02421 elementItem->element.representation,
02422 elementItem->element.length / sizeof(short), vm);
02423 break;
02424 case DCM_SQ:
02425 (void) RWC_printf("SEQUENCE\n");
02426 sq = (void *)LST_Head(&elementItem->element.d.sq);
02427 if (sq != NULL)
02428 (void) LST_Position(&elementItem->element.d.sq, (void *)sq);
02429 RWC_printf("DCM Dump SEQUENCE\n");
02430 while (sq != NULL) {
02431 (void) DCM_DumpElements(&sq->object, vm);
02432 sq = (void *)LST_Next(&elementItem->element.d.sq);
02433 }
02434 RWC_printf("DCM Dump SEQUENCE Complete\n");
02435 break;
02436 case DCM_ST:
02437 stringLength = MIN(sizeof(scratch) - 1, elementItem->element.length);
02438 strncpy(scratch, elementItem->element.d.string, stringLength);
02439 scratch[stringLength] = '\0';
02440 (void) RWC_printf("%s\n", scratch);
02441 break;
02442 case DCM_TM:
02443 case DCM_UI:
02444 stringLength = MIN(sizeof(scratch) - 1, elementItem->element.length);
02445 strncpy(scratch, elementItem->element.d.string, stringLength);
02446 scratch[stringLength] = '\0';
02447 (void) RWC_printf("%s\n", scratch);
02448 break;
02449 case DCM_AT:
02450 case DCM_UL:
02451 #ifdef MACOS
02452 (void) RWC_printf("%8lx %ld\n", *elementItem->element.d.ul,
02453 *elementItem->element.d.ul);
02454 #else
02455 if( (rwc_opt & RWC_NOHEX_MASK) == 0 )
02456 (void) RWC_printf("%8x %d\n", *elementItem->element.d.ul,
02457 *elementItem->element.d.ul);
02458 else
02459 (void) RWC_printf(" %d\n", *elementItem->element.d.ul ) ;
02460
02461 if (vm > 1)
02462 dumpBinaryData(elementItem->element.d.ot,
02463 elementItem->element.representation,
02464 elementItem->element.length / sizeof(U32), vm);
02465 #endif
02466 break;
02467 case DCM_US:{
02468 int nel = elementItem->element.length / sizeof(unsigned short) , rr ;
02469 for( rr=0 ; rr < nel ; rr++ ){
02470 if( (rwc_opt & RWC_NOHEX_MASK) == 0 )
02471 (void) RWC_printf("%4x %d", elementItem->element.d.us[rr],
02472 elementItem->element.d.us[rr]);
02473 else
02474 (void) RWC_printf(" %d", elementItem->element.d.us[rr] ) ;
02475 }
02476 RWC_printf("\n") ;
02477
02478 if (vm > 1)
02479 dumpBinaryData(elementItem->element.d.ot,
02480 elementItem->element.representation,
02481 elementItem->element.length / sizeof(unsigned short), vm);
02482 }
02483 break;
02484 case DCM_OB:
02485 case DCM_UN:
02486 dumpBinaryData(elementItem->element.d.ot,
02487 elementItem->element.representation,
02488 elementItem->element.length , MAX(rwc_vm,8));
02489 break;
02490
02491 case DCM_OT:
02492 case DCM_OW:
02493
02494 case DCM_RET:
02495 (void) RWC_printf("Unimplemented\n");
02496 break;
02497 default:
02498 (void) RWC_printf("Some unimplemented logic if here\n");
02499 break;
02500 }
02501 }
02502 elementItem = (void *)LST_Next(&groupItem->elementList);
02503 }
02504 groupItem = (void *)LST_Next(&(*object)->groupList);
02505 }
02506
02507 RWC_printf("DCM Dump Elements Complete\n");
02508 return DCM_NORMAL;
02509 }
02510
02511 CONDITION
02512 DCM_FormatElements(DCM_OBJECT ** callerObject, long vm, const char* prefix)
02513 {
02514 PRV_GROUP_ITEM
02515 * groupItem;
02516 PRV_ELEMENT_ITEM
02517 * elementItem;
02518 PRIVATE_OBJECT
02519 ** object;
02520 CONDITION
02521 cond;
02522 DCM_SEQUENCE_ITEM
02523 * sq;
02524 char
02525 scratch[128];
02526 int
02527 stringLength;
02528 char localPrefix[128];
02529
02530 object = (PRIVATE_OBJECT **) callerObject;
02531
02532 cond = checkObject(object, "DCM_DumpElements");
02533 if (cond != DCM_NORMAL)
02534 return cond;
02535
02536 RWC_printf("\n%sDCM Dump Elements\n", prefix);
02537 switch ((*object)->objectType) {
02538 case DCM_OBJECTUNKNOWN:
02539 RWC_printf("%sObject type: UNKNOWN\n", prefix);
02540 break;
02541 case DCM_OBJECTCOMMAND:
02542 RWC_printf("%sObject type: COMMAND\n", prefix);
02543 break;
02544 case DCM_OBJECTIMAGE:
02545 RWC_printf("%sObject type: IMAGE\n", prefix);
02546 break;
02547 case DCM_OBJECTELEMENTLIST:
02548 RWC_printf("%sObject type: ELEMENT LIST\n", prefix);
02549 break;
02550 default:
02551 RWC_printf("%sObject type: Unknown (error)\n", prefix);
02552 break;
02553 }
02554 RWC_printf("%sObject size: %ld\n", prefix, (*object)->objectSize);
02555
02556 groupItem = (void *)LST_Head(&(*object)->groupList);
02557 if (groupItem != NULL)
02558 (void) LST_Position(&(*object)->groupList, (void *)groupItem);
02559
02560 while (groupItem != NULL) {
02561 RWC_printf("%sGroup: %04x, Length: %8d\n", prefix, groupItem->group,
02562 groupItem->baseLength);
02563 elementItem = (void *)LST_Head(&groupItem->elementList);
02564 if (elementItem != NULL)
02565 (void) LST_Position(&groupItem->elementList, (void *)elementItem);
02566 while (elementItem != NULL) {
02567 (void) RWC_printf("%s%04x %04x %8d ",
02568 prefix,
02569 DCM_TAG_GROUP(elementItem->element.tag),
02570 DCM_TAG_ELEMENT(elementItem->element.tag),
02571 elementItem->element.length);
02572 (void) RWC_printf("//%31s//", elementItem->element.description);
02573 if (elementItem->element.d.ot == NULL)
02574 (void) RWC_printf("Data on disk\n");
02575 else {
02576 switch (elementItem->element.representation) {
02577 case DCM_AE:
02578 case DCM_AS:
02579 case DCM_CS:
02580 case DCM_DA:
02581 case DCM_DT:
02582 stringLength = MIN(sizeof(scratch) - 1, elementItem->element.length);
02583 strncpy(scratch, elementItem->element.d.string, stringLength);
02584 scratch[stringLength] = '\0';
02585 (void) RWC_printf("%s\n", scratch);
02586 break;
02587 case DCM_DD:
02588 case DCM_FD:
02589 case DCM_FL:
02590 (void) RWC_printf("Unimplemented\n");
02591 break;
02592 case DCM_DS:
02593 case DCM_IS:
02594 case DCM_LO:
02595 case DCM_LT:
02596 case DCM_PN:
02597 case DCM_SH:
02598 case DCM_UT:
02599 stringLength = MIN(sizeof(scratch) - 1, elementItem->element.length);
02600 strncpy(scratch, elementItem->element.d.string, stringLength);
02601 scratch[stringLength] = '\0';
02602 (void) RWC_printf("%s\n", scratch);
02603 break;
02604 case DCM_SL:
02605 #ifdef MACOS
02606 (void) RWC_printf("%8lx %ld\n", *elementItem->element.d.sl,
02607 *elementItem->element.d.sl);
02608 #else
02609 (void) RWC_printf("%8x %d\n", *elementItem->element.d.sl,
02610 *elementItem->element.d.sl);
02611 if (vm > 1)
02612 dumpBinaryData(elementItem->element.d.ot,
02613 elementItem->element.representation,
02614 elementItem->element.length / sizeof(U32), vm);
02615 #endif
02616 break;
02617 case DCM_SS:
02618 (void) RWC_printf("%4x %d\n", *elementItem->element.d.ss,
02619 *elementItem->element.d.ss);
02620 if (vm > 1)
02621 dumpBinaryData(elementItem->element.d.ot,
02622 elementItem->element.representation,
02623 elementItem->element.length / sizeof(short), vm);
02624 break;
02625 case DCM_SQ:
02626 (void) RWC_printf("SEQUENCE\n");
02627 sq = (void *)LST_Head(&elementItem->element.d.sq);
02628 if (sq != NULL)
02629 (void) LST_Position(&elementItem->element.d.sq, (void *)sq);
02630 RWC_printf("%sDCM Dump SEQUENCE\n", prefix);
02631 strcpy(localPrefix, prefix);
02632 strcat(localPrefix, " ");
02633 while (sq != NULL) {
02634 (void) DCM_FormatElements(&sq->object, vm, localPrefix);
02635 sq = (void *)LST_Next(&elementItem->element.d.sq);
02636 }
02637 RWC_printf("%sDCM Dump SEQUENCE Complete\n", prefix);
02638 break;
02639 case DCM_ST:
02640 stringLength = MIN(sizeof(scratch) - 1, elementItem->element.length);
02641 strncpy(scratch, elementItem->element.d.string, stringLength);
02642 scratch[stringLength] = '\0';
02643 (void) RWC_printf("%s\n", scratch);
02644 break;
02645 case DCM_TM:
02646 case DCM_UI:
02647 stringLength = MIN(sizeof(scratch) - 1, elementItem->element.length);
02648 strncpy(scratch, elementItem->element.d.string, stringLength);
02649 scratch[stringLength] = '\0';
02650 (void) RWC_printf("%s\n", scratch);
02651 break;
02652 case DCM_AT:
02653 case DCM_UL:
02654 (void) RWC_printf("%8x %d\n", *elementItem->element.d.ul,
02655 *elementItem->element.d.ul);
02656 if (vm > 1)
02657 dumpBinaryData(elementItem->element.d.ot,
02658 elementItem->element.representation,
02659 elementItem->element.length / sizeof(U32), vm);
02660 break;
02661 case DCM_US:
02662 (void) RWC_printf("%4x %d\n", *elementItem->element.d.us,
02663 *elementItem->element.d.us);
02664 if (vm > 1)
02665 dumpBinaryData(elementItem->element.d.ot,
02666 elementItem->element.representation,
02667 elementItem->element.length / sizeof(unsigned short), vm);
02668 break;
02669 case DCM_OT:
02670 case DCM_OW:
02671 case DCM_OB:
02672
02673 case DCM_RET:
02674 (void) RWC_printf("Unimplemented\n");
02675 break;
02676 default:
02677 (void) RWC_printf("Some unimplemented logic if here\n");
02678 break;
02679 }
02680 }
02681 elementItem = (void *)LST_Next(&groupItem->elementList);
02682 }
02683 groupItem = (void *)LST_Next(&(*object)->groupList);
02684 }
02685
02686 RWC_printf("%sDCM Dump Elements Complete\n\n", prefix);
02687 return DCM_NORMAL;
02688 }
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705
02706 void
02707 DCM_Debug(CTNBOOLEAN flag)
02708 {
02709 debug = flag;
02710 }
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740 CONDITION
02741 DCM_ExportStream(DCM_OBJECT ** callerObject, unsigned long opt,
02742 void *buffer, unsigned long bufferlength,
02743 DCM_EXPORT_STREAM_CALLBACK* callback,
02744 void *ctx) ;
02745
02746 CONDITION
02747 DCM_WriteFile(DCM_OBJECT ** callerObject, unsigned long opt, const char *file)
02748 {
02749 PRIVATE_OBJECT
02750 ** object;
02751 int
02752 fd;
02753 unsigned char
02754 buf[2048];
02755 CONDITION
02756 cond;
02757
02758 object = (PRIVATE_OBJECT **) callerObject;
02759 cond = checkObject(object, "DCM_WriteFile");
02760 if (cond != DCM_NORMAL)
02761 return cond;
02762 #ifdef MACOS
02763 fd = open(file, O_WRONLY | O_CREAT | O_TRUNC);
02764 #elif _MSC_VER
02765 fd = _open(file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
02766 _S_IREAD | _S_IWRITE);
02767 #else
02768 fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0666);
02769 #endif
02770 if (fd < 0) {
02771 return COND_PushCondition(DCM_FILECREATEFAILED,
02772 DCM_Message(DCM_FILECREATEFAILED), file, strerror(errno),
02773 "DCM_WriteFile");
02774 }
02775 cond = DCM_ExportStream(callerObject, opt, buf,
02776 (unsigned long) sizeof(buf), writeFile, &fd);
02777 if (cond != DCM_NORMAL)
02778 return cond;
02779
02780 (void) close(fd);
02781 return DCM_NORMAL;
02782 }
02783
02784
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826 CONDITION
02827 DCM_ModifyElements(DCM_OBJECT ** callerObject, DCM_ELEMENT * vector, int count,
02828 DCM_FLAGGED_ELEMENT * flaggedVector, int flaggedCount,
02829 int *updateCount)
02830 {
02831 PRIVATE_OBJECT
02832 ** object;
02833 CONDITION
02834 cond;
02835 DCM_ELEMENT
02836 e;
02837 int
02838 c = 0;
02839
02840 object = (PRIVATE_OBJECT **) callerObject;
02841 cond = checkObject(object, "DCM_ModifyElement");
02842 if (cond != DCM_NORMAL)
02843 return cond;
02844
02845 while (count-- > 0) {
02846 cond = DCM_RemoveElement(callerObject, vector->tag);
02847 if (cond != DCM_NORMAL)
02848 (void) COND_PopCondition(FALSE);
02849
02850 e = *vector;
02851 if (DCM_IsString(e.representation))
02852 e.length = strlen(e.d.string);
02853
02854 cond = DCM_AddElement(callerObject, &e);
02855 if (cond != DCM_NORMAL)
02856 return cond;
02857
02858 c++;
02859 vector++;
02860 }
02861
02862 while (flaggedCount-- > 0) {
02863 if ((*(flaggedVector->flagAddress) & flaggedVector->flag) != 0) {
02864 cond = DCM_RemoveElement(callerObject, flaggedVector->e.tag);
02865 if (cond != DCM_NORMAL)
02866 (void) COND_PopCondition(FALSE);
02867
02868 e = flaggedVector->e;
02869 if (DCM_IsString(e.representation))
02870 e.length = strlen(e.d.string);
02871 cond = DCM_AddElement(callerObject, &e);
02872 if (cond != DCM_NORMAL)
02873 return cond;
02874 c++;
02875 }
02876 flaggedVector++;
02877 }
02878
02879 if (updateCount != NULL)
02880 *updateCount = c;
02881 return DCM_NORMAL;
02882 }
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906
02907
02908
02909
02910
02911
02912
02913
02914
02915
02916 CONDITION
02917 DCM_ParseObject(DCM_OBJECT ** callerObject, DCM_ELEMENT * vector,
02918 int count, DCM_FLAGGED_ELEMENT * flaggedVector, int flagCount,
02919 int *parseCount)
02920 {
02921 PRIVATE_OBJECT
02922 ** object;
02923 CONDITION
02924 cond;
02925 void
02926 *ctx;
02927 U32
02928 l;
02929 int
02930 c = 0;
02931 char
02932 *p;
02933
02934 object = (PRIVATE_OBJECT **) callerObject;
02935 cond = checkObject(object, "DCM_ParseObject");
02936 if (cond != DCM_NORMAL)
02937 return cond;
02938
02939 while (count-- > 0) {
02940 ctx = NULL;
02941 cond = DCM_GetElementValue(callerObject, vector, &l, &ctx);
02942 if (cond != DCM_NORMAL)
02943 return cond;
02944 if (DCM_IsString(vector->representation)) {
02945 vector->d.string[l] = '\0';
02946 p = vector->d.string + l - 1;
02947 while (p >= vector->d.string && (*p == ' '))
02948 *p-- = '\0';
02949 }
02950 c++;
02951 vector++;
02952 }
02953
02954 while (flagCount-- > 0) {
02955 ctx = NULL;
02956 cond = DCM_GetElementValue(callerObject, &flaggedVector->e, &l, &ctx);
02957 if (cond != DCM_NORMAL) {
02958 (void) COND_PopCondition(FALSE);
02959 } else {
02960 c++;
02961 if (DCM_IsString(flaggedVector->e.representation)) {
02962 flaggedVector->e.d.string[l] = '\0';
02963 p = flaggedVector->e.d.string + l - 1;
02964 while (p >= flaggedVector->e.d.string && (*p == ' '))
02965 *p-- = '\0';
02966 }
02967 *(flaggedVector->flagAddress) |= flaggedVector->flag;
02968 }
02969 flaggedVector++;
02970 }
02971
02972 if (parseCount != NULL)
02973 *parseCount = c;
02974 return DCM_NORMAL;
02975 }
02976
02977
02978
02979
02980
02981
02982
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001 CONDITION
03002 DCM_RemoveGroup(DCM_OBJECT ** callerObject, unsigned short group)
03003 {
03004 PRIVATE_OBJECT
03005 ** object;
03006 CONDITION
03007 cond;
03008 PRV_GROUP_ITEM
03009 * groupItem;
03010 PRV_ELEMENT_ITEM
03011 * elementItem;
03012 CTNBOOLEAN
03013 found = FALSE;
03014
03015 object = (PRIVATE_OBJECT **) callerObject;
03016 cond = checkObject(object, "DCM_RemoveGroup");
03017 if (cond != DCM_NORMAL)
03018 return cond;
03019
03020 groupItem = (void *)LST_Head(&(*object)->groupList);
03021 if (groupItem == NULL)
03022 return COND_PushCondition(DCM_GROUPNOTFOUND,
03023 DCM_Message(DCM_GROUPNOTFOUND), (int) group, "DCM_RemoveGroup");
03024
03025 (void) LST_Position(&(*object)->groupList, (void *)groupItem);
03026
03027 while (!found && (groupItem != NULL)) {
03028 if (groupItem->group == group)
03029 found = TRUE;
03030 else
03031 groupItem = (void *)LST_Next(&(*object)->groupList);
03032 }
03033 if (groupItem == NULL)
03034 return COND_PushCondition(DCM_GROUPNOTFOUND,
03035 DCM_Message(DCM_GROUPNOTFOUND), (int) group, "DCM_RemoveGroup");
03036
03037
03038 while ((elementItem = (void *)LST_Pop(&groupItem->elementList)) != NULL)
03039 CTN_FREE(elementItem);
03040
03041 groupItem = (void *)LST_Remove(&(*object)->groupList, LST_K_AFTER);
03042 cond = LST_Destroy(&groupItem->elementList);
03043 if (cond != LST_NORMAL)
03044 return COND_PushCondition(DCM_LISTFAILURE,
03045 DCM_Message(DCM_LISTFAILURE), "DCM_RemoveGroup");
03046 CTN_FREE(groupItem);
03047 return DCM_NORMAL;
03048 }
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065
03066
03067
03068
03069
03070
03071
03072
03073
03074
03075 CONDITION
03076 DCM_GetSequenceList(DCM_OBJECT ** object, DCM_TAG tag, LST_HEAD ** list)
03077 {
03078 PRIVATE_OBJECT
03079 ** obj;
03080 CONDITION
03081 cond;
03082 PRV_GROUP_ITEM
03083 * groupItem;
03084 PRV_ELEMENT_ITEM
03085 * elementItem;
03086 CTNBOOLEAN
03087 found = FALSE;
03088
03089 obj = (PRIVATE_OBJECT **) object;
03090 cond = checkObject(obj, "DCM_GetSequenceList");
03091 if (cond != DCM_NORMAL)
03092 return cond;
03093
03094 groupItem = (void *)LST_Head(&(*obj)->groupList);
03095 if (groupItem == NULL)
03096 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
03097 DCM_Message(DCM_ELEMENTNOTFOUND), DCM_TAG_GROUP(tag),
03098 DCM_TAG_ELEMENT(tag),
03099 "DCM_GetSequenceList");
03100
03101 (void) LST_Position(&(*obj)->groupList, (void *)groupItem);
03102 while (groupItem != NULL) {
03103 if (groupItem->group == DCM_TAG_GROUP(tag))
03104 break;
03105
03106 groupItem = (void *)LST_Next(&(*obj)->groupList);
03107 }
03108 if (groupItem == NULL)
03109 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
03110 DCM_Message(DCM_ELEMENTNOTFOUND), DCM_TAG_GROUP(tag),
03111 DCM_TAG_ELEMENT(tag),
03112 "DCM_GetSequenceList");
03113
03114 elementItem = (void *)LST_Head(&groupItem->elementList);
03115 if (elementItem == NULL)
03116 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
03117 DCM_Message(DCM_ELEMENTNOTFOUND), DCM_TAG_GROUP(tag),
03118 DCM_TAG_GROUP(tag),
03119 "DCM_GetSequenceTag");
03120
03121 (void) LST_Position(&groupItem->elementList, (void *)elementItem);
03122 while (!found && (elementItem != NULL)) {
03123 if (elementItem->element.tag == tag) {
03124 *list = elementItem->element.d.sq;
03125 found = TRUE;
03126 }
03127 elementItem = (void *)LST_Next(&groupItem->elementList);
03128 }
03129 if (found)
03130 return DCM_NORMAL;
03131 else
03132 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
03133 DCM_Message(DCM_ELEMENTNOTFOUND), DCM_TAG_GROUP(tag),
03134 DCM_TAG_ELEMENT(tag),
03135 "DCM_GetSequenceList");
03136 }
03137
03138 CONDITION
03139 DCM_GetSequenceElement(DCM_OBJECT ** object, DCM_TAG top, DCM_ELEMENT * e)
03140 {
03141 PRIVATE_OBJECT **obj;
03142 CONDITION cond;
03143 PRV_GROUP_ITEM *groupItem;
03144 PRV_ELEMENT_ITEM *elementItem;
03145 DCM_SEQUENCE_ITEM *seqItem;
03146
03147 CTNBOOLEAN found = FALSE;
03148
03149 obj = (PRIVATE_OBJECT **) object;
03150 cond = checkObject(obj, "DCM_GetSequenceElement");
03151 if (cond != DCM_NORMAL)
03152 return cond;
03153
03154 elementItem = locateElement(obj, top);
03155 if (elementItem == NULL) {
03156 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
03157 DCM_Message(DCM_ELEMENTNOTFOUND),
03158 DCM_TAG_GROUP(top),
03159 DCM_TAG_ELEMENT(top),
03160 "DCM_GetElementSequence");
03161 }
03162 if (elementItem->element.representation != DCM_SQ) {
03163 return COND_PushCondition(DCM_UNEXPECTEDREPRESENTATION,
03164 DCM_Message(DCM_UNEXPECTEDREPRESENTATION),
03165 "DCM_GetSequenceElement", "sequence");
03166 }
03167 seqItem = (void *)LST_Head(&elementItem->element.d.sq);
03168 cond = DCM_ParseObject(&seqItem->object, e, 1, NULL, 0, NULL);
03169 return cond;
03170
03171 #if 0
03172 return DCM_NORMAL;
03173 #endif
03174 }
03175
03176
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193
03194
03195
03196
03197 CONDITION
03198 DCM_GetElementValueList(DCM_OBJECT ** object, DCM_TAG tag,
03199 size_t structureSize, long stringOffset, LST_HEAD ** list)
03200 {
03201 PRIVATE_OBJECT
03202 ** obj;
03203 CONDITION
03204 cond;
03205 PRV_GROUP_ITEM
03206 * groupItem;
03207 PRV_ELEMENT_ITEM
03208 * elementItem;
03209 CTNBOOLEAN
03210 found = FALSE;
03211 char
03212 *src,
03213 *dst,
03214 *p;
03215 U32
03216 l;
03217
03218 obj = (PRIVATE_OBJECT **) object;
03219 cond = checkObject(obj, "DCM_GetSequenceList");
03220 if (cond != DCM_NORMAL)
03221 return cond;
03222
03223 groupItem = (void *)LST_Head(&(*obj)->groupList);
03224 if (groupItem == NULL)
03225 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
03226 DCM_Message(DCM_ELEMENTNOTFOUND), DCM_TAG_GROUP(tag),
03227 DCM_TAG_ELEMENT(tag),
03228 "DCM_GetSequenceList");
03229
03230 (void) LST_Position(&(*obj)->groupList, (void *)groupItem);
03231 while (groupItem != NULL) {
03232 if (groupItem->group == DCM_TAG_GROUP(tag))
03233 break;
03234
03235 groupItem = (void *)LST_Next(&(*obj)->groupList);
03236 }
03237 if (groupItem == NULL)
03238 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
03239 DCM_Message(DCM_ELEMENTNOTFOUND), DCM_TAG_GROUP(tag),
03240 DCM_TAG_ELEMENT(tag),
03241 "DCM_GetSequenceList");
03242
03243 elementItem = (void *)LST_Head(&groupItem->elementList);
03244 if (elementItem == NULL)
03245 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
03246 DCM_Message(DCM_ELEMENTNOTFOUND), DCM_TAG_GROUP(tag),
03247 DCM_TAG_GROUP(tag),
03248 "DCM_GetSequenceTag");
03249
03250 (void) LST_Position(&groupItem->elementList, (void *)elementItem);
03251 while (!found && (elementItem != NULL)) {
03252 if (elementItem->element.tag == tag) {
03253 found = TRUE;
03254 } else
03255 elementItem = (void *)LST_Next(&groupItem->elementList);
03256 }
03257 if (!found)
03258 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
03259 DCM_Message(DCM_ELEMENTNOTFOUND), DCM_TAG_GROUP(tag),
03260 DCM_TAG_ELEMENT(tag),
03261 "DCM_GetElementValueList");
03262
03263 if (!DCM_IsString(elementItem->element.representation)) {
03264 return COND_PushCondition(DCM_UNEXPECTEDREPRESENTATION,
03265 DCM_Message(DCM_UNEXPECTEDREPRESENTATION), "DCM_GetElementValueList",
03266 "string");
03267 }
03268 src = elementItem->element.d.string;
03269 l = elementItem->element.length;
03270 while (l > 0) {
03271 while (l > 1 && (*src == ' ' || *src == DCM_DELIMITOR)) {
03272 l--;
03273 src++;
03274 }
03275 if ((l == 1) && (*src == ' ' || *src == DCM_DELIMITOR))
03276 l--;
03277
03278 if (l != 0) {
03279 p = CTN_MALLOC(structureSize);
03280 if (p == NULL)
03281 return COND_PushCondition(DCM_MALLOCFAILURE,
03282 DCM_Message(DCM_MALLOCFAILURE), structureSize,
03283 "DCM_GetElementValueList");
03284 dst = p + stringOffset;
03285 while ((l > 1) && (*src != DCM_DELIMITOR)) {
03286 *dst++ = *src++;
03287 l--;
03288 }
03289 if ((l == 1) && (*src != ' ')) {
03290 *dst++ = *src++;
03291 l--;
03292 }
03293 *dst = '\0';;
03294 cond = LST_Enqueue(list, (void *)p);
03295 if (cond != LST_NORMAL)
03296 return COND_PushCondition(DCM_LISTFAILURE,
03297 DCM_Message(DCM_LISTFAILURE), "DCM_GetElementValueList");
03298 }
03299 }
03300 return DCM_NORMAL;
03301 }
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328
03329
03330
03331
03332
03333 CONDITION
03334 DCM_AddElementList(DCM_OBJECT ** callerObject, DCM_ELEMENT * element,
03335 LST_HEAD * list, long offset)
03336 {
03337 DCM_ELEMENT
03338 e;
03339 CONDITION
03340 cond;
03341 char
03342 *s;
03343
03344 e = *element;
03345 cond = DCM_ListToString(list, offset, &s);
03346 if (cond != DCM_NORMAL)
03347 return cond;
03348
03349 e.d.string = s;
03350 e.length = strlen(s);
03351 cond = DCM_AddElement(callerObject, &e);
03352 CTN_FREE(s);
03353 return cond;
03354 }
03355
03356
03357
03358
03359
03360
03361
03362
03363
03364
03365
03366
03367
03368
03369
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380 CONDITION
03381 DCM_GetElement(DCM_OBJECT ** callerObject, DCM_TAG tag, DCM_ELEMENT * element)
03382 {
03383 PRIVATE_OBJECT
03384 ** obj;
03385 CONDITION
03386 cond;
03387 PRV_ELEMENT_ITEM
03388 * elementItem;
03389
03390 obj = (PRIVATE_OBJECT **) callerObject;
03391 cond = checkObject(obj, "DCM_GetElementVM");
03392 if (cond != DCM_NORMAL)
03393 return cond;
03394
03395 elementItem = locateElement(obj, tag);
03396 if (elementItem == NULL)
03397 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
03398 DCM_Message(DCM_ELEMENTNOTFOUND), DCM_TAG_GROUP(tag),
03399 DCM_TAG_ELEMENT(tag),
03400 "DCM_GetElementVM");
03401 *element = elementItem->element;
03402 element->d.ot = NULL;
03403 return DCM_NORMAL;
03404 }
03405
03406 CONDITION
03407 DCM_ComputeExportLength(DCM_OBJECT ** callerObject, unsigned long opt,
03408 unsigned long *length)
03409 {
03410 PRIVATE_OBJECT
03411 ** object;
03412 unsigned char
03413 buf[2048];
03414 CONDITION
03415 cond;
03416
03417 object = (PRIVATE_OBJECT **) callerObject;
03418 cond = checkObject(object, "DCM_ComputeExportSize");
03419 if (cond != DCM_NORMAL)
03420 return cond;
03421
03422 *length = 0;
03423 cond = DCM_ExportStream(callerObject, opt, buf,
03424 (unsigned long) sizeof(buf), countBytes, length);
03425 if (cond != DCM_NORMAL)
03426 return cond;
03427
03428 return DCM_NORMAL;
03429 }
03430
03431 CONDITION
03432 DCM_CompareAttributes(DCM_OBJECT ** o1, DCM_OBJECT ** o2,
03433 void (*callback) (const DCM_ELEMENT * e1,
03434 const DCM_ELEMENT * e2,
03435 void *ctx),
03436 void *ctx)
03437 {
03438 PRIVATE_OBJECT **object1,
03439 **object2;
03440 PRV_GROUP_ITEM *groupItem1,
03441 *groupItem2;
03442 CONDITION cond;
03443
03444 object1 = (PRIVATE_OBJECT **) o1;
03445 cond = checkObject(object1, "DCM_CompareAttributes");
03446 if (cond != DCM_NORMAL)
03447 return cond;
03448
03449 object2 = (PRIVATE_OBJECT **) o2;
03450 cond = checkObject(object1, "DCM_CompareAttributes");
03451 if (cond != DCM_NORMAL)
03452 return cond;
03453
03454 groupItem1 = (void *)LST_Head(&(*object1)->groupList);
03455 if (groupItem1 != NULL)
03456 (void) LST_Position(&(*object1)->groupList, (void *)groupItem1);
03457
03458 groupItem2 = (void *)LST_Head(&(*object2)->groupList);
03459 if (groupItem2 != NULL)
03460 (void) LST_Position(&(*object2)->groupList, (void *)groupItem2);
03461
03462
03463 while (groupItem1 != NULL) {
03464 if (groupItem2 == NULL) {
03465 compareGroup(groupItem1, NULL, callback, ctx);
03466 groupItem1 = (void *)LST_Next(&(*object1)->groupList);
03467 } else if (groupItem1->group == groupItem2->group) {
03468 compareGroup(groupItem1, groupItem2, callback, ctx);
03469 groupItem1 = (void *)LST_Next(&(*object1)->groupList);
03470 groupItem2 = (void *)LST_Next(&(*object2)->groupList);
03471 } else if (groupItem1->group > groupItem2->group) {
03472 compareGroup(NULL, groupItem2, callback, ctx);
03473 groupItem2 = (void *)LST_Next(&(*object2)->groupList);
03474 } else {
03475 compareGroup(groupItem1, NULL, callback, ctx);
03476 groupItem1 = (void *)LST_Next(&(*object1)->groupList);
03477 }
03478 }
03479
03480 while (groupItem2 != NULL) {
03481 compareGroup(NULL, groupItem2, callback, ctx);
03482 groupItem2 = (void *)LST_Next(&(*object2)->groupList);
03483 }
03484 return DCM_NORMAL;
03485 }
03486
03487 CTNBOOLEAN
03488 DCM_GroupPresent(DCM_OBJECT ** o1, U16 group)
03489 {
03490 PRIVATE_OBJECT **object;
03491 PRV_GROUP_ITEM * item;
03492 CONDITION cond;
03493 CTNBOOLEAN tooFar = FALSE;
03494
03495 object = (PRIVATE_OBJECT **) o1;
03496 cond = checkObject(object, "DCM_CompareAttributes");
03497 if (cond != DCM_NORMAL)
03498 return FALSE;
03499
03500
03501 item = (void *)LST_Head(&(*object)->groupList);
03502 if (item != NULL)
03503 (void) LST_Position(&(*object)->groupList, (void *)item);
03504
03505 while (item != NULL && !tooFar) {
03506 if (item->group == group) {
03507 return TRUE;
03508 } else if (item->group > group) {
03509 tooFar = TRUE;
03510 } else {
03511 item = (void *)LST_Next(&(*object)->groupList);
03512 }
03513 }
03514 return FALSE;
03515 }
03516
03517
03518
03519
03520
03521
03522
03523
03524
03525
03526
03527
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540
03541
03542
03543
03544
03545
03546 static CONDITION
03547 newElementItem(DCM_ELEMENT * src, CTNBOOLEAN allocateData,
03548 PRV_ELEMENT_ITEM ** dst)
03549 {
03550 U32
03551 l;
03552
03553 if (allocateData && (src->representation != DCM_SQ)) {
03554 l = src->length;
03555 if (l & 1)
03556 l++;
03557 } else
03558 l = 0;
03559
03560 if (debug)
03561 fprintf(stderr, "newElementItem: CTN_MALLOC %8d %8d ", l,
03562 (int)(sizeof(PRV_ELEMENT_ITEM) + l));
03563
03564 *dst = (PRV_ELEMENT_ITEM *) CTN_MALLOC(sizeof(PRV_ELEMENT_ITEM) + l);
03565 if (debug)
03566 fprintf(stderr, "%8p\n", *dst);
03567
03568 if (*dst == NULL) {
03569 return COND_PushCondition(DCM_ELEMENTCREATEFAILED,
03570 DCM_Message(DCM_ELEMENTCREATEFAILED), "newElementItem",
03571 DCM_TAG_GROUP(src->tag),
03572 DCM_TAG_ELEMENT(src->tag),
03573 l);
03574 }
03575 memset(*dst, 0, sizeof(PRV_ELEMENT_ITEM));
03576 (*dst)->element = *src;
03577 (*dst)->byteOrder = NATIVE_ORDER;
03578 (*dst)->allocatedDataLength = (size_t) l;
03579 (*dst)->originalDataLength = src->length;
03580 (*dst)->paddedDataLength = src->length;
03581 if (allocateData)
03582 (*dst)->element.d.ot = ((char *) (*dst)) + sizeof(PRV_ELEMENT_ITEM);
03583 else
03584 (*dst)->element.d.ot = NULL;
03585
03586 (*dst)->fragmentFlag = 0;
03587 return DCM_NORMAL;
03588 }
03589
03590
03591
03592
03593
03594
03595
03596
03597
03598
03599
03600
03601
03602
03603
03604
03605
03606
03607
03608
03609
03610
03611
03612
03613
03614
03615
03616
03617
03618
03619
03620
03621
03622
03623
03624
03625
03626
03627
03628
03629
03630
03631
03632
03633
03634
03635
03636 static CONDITION
03637 findCreateGroup(PRIVATE_OBJECT ** object, unsigned short group,
03638 PRV_GROUP_ITEM ** groupItem)
03639 {
03640 PRV_GROUP_ITEM
03641 * item;
03642 CONDITION
03643 cond;
03644 CTNBOOLEAN
03645 tooFar = FALSE;
03646
03647 item = (void *)LST_Head(&(*object)->groupList);
03648 if (item != NULL)
03649 (void) LST_Position(&(*object)->groupList, (void *)item);
03650
03651 while (item != NULL && !tooFar) {
03652 if (item->group == group) {
03653 *groupItem = item;
03654 return DCM_NORMAL;
03655 } else if (item->group > group) {
03656 tooFar = TRUE;
03657 } else {
03658 item = (void *)LST_Next(&(*object)->groupList);
03659 }
03660 }
03661
03662 {
03663 U32 l;
03664 PRV_GROUP_ITEM *newGroupItem;
03665 DCM_ELEMENT groupLength = {0, DCM_UL, "", 1, sizeof(l), NULL};
03666 PRV_ELEMENT_ITEM *groupLengthItem;
03667
03668 newGroupItem = CTN_MALLOC(sizeof(*newGroupItem));
03669 if (newGroupItem == NULL)
03670 return COND_PushCondition(DCM_ELEMENTCREATEFAILED,
03671 DCM_Message(DCM_ELEMENTCREATEFAILED),
03672 "findCreateGroup",
03673 group, 0xffff, sizeof(*newGroupItem));
03674
03675
03676 *groupItem = newGroupItem;
03677 newGroupItem->group = group;
03678 newGroupItem->baseLength = 0;
03679 newGroupItem->longVRAttributes = 0;
03680 newGroupItem->elementList = LST_Create();
03681 if (newGroupItem->elementList == NULL)
03682 return COND_PushCondition(DCM_LISTFAILURE,
03683 DCM_Message(DCM_LISTFAILURE),
03684 "findCreateGroup");
03685
03686 if (tooFar)
03687 cond = LST_Insert(&(*object)->groupList, (void *)newGroupItem, LST_K_BEFORE);
03688 else
03689 cond = LST_Enqueue(&(*object)->groupList, (void *)newGroupItem);
03690 if (cond != LST_NORMAL)
03691 return COND_PushCondition(DCM_LISTFAILURE,
03692 DCM_Message(DCM_LISTFAILURE),
03693 "findCreateGroup");
03694 (void) LST_Position(&(*object)->groupList, (void *)newGroupItem);
03695 if (cond != LST_NORMAL)
03696 return COND_PushCondition(DCM_LISTFAILURE,
03697 DCM_Message(DCM_LISTFAILURE),
03698 "findCreateGroup");
03699
03700 groupLength.d.ul = &l;
03701 l = 0;
03702 if ((*object)->groupLengthFlag) {
03703 groupLength.tag = DCM_MAKETAG(group, 0);
03704 cond = newElementItem(&groupLength, TRUE, &groupLengthItem);
03705 (void) memcpy(groupLengthItem->element.d.ot, &l, sizeof(l));
03706
03707 if (LST_Insert(&newGroupItem->elementList, (void *)groupLengthItem, LST_K_AFTER) !=
03708 LST_NORMAL)
03709 return COND_PushCondition(DCM_LISTFAILURE,
03710 DCM_Message(DCM_LISTFAILURE),
03711 "findCreateGroup");
03712
03713 (*object)->objectSize += 8 + groupLengthItem->element.length;
03714 }
03715 }
03716 return DCM_NORMAL;
03717 }
03718
03719
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730
03731
03732
03733
03734
03735
03736
03737
03738
03739
03740
03741
03742
03743
03744
03745
03746
03747
03748
03749
03750
03751
03752
03753
03754
03755
03756 static CONDITION
03757 insertNewElement(PRIVATE_OBJECT ** object, DCM_ELEMENT * element)
03758 {
03759 PRV_ELEMENT_ITEM
03760 * nextItem,
03761 *newItem;
03762 PRV_GROUP_ITEM
03763 * groupItem;
03764 CONDITION
03765 cond;
03766 char
03767 *p;
03768
03769 cond = newElementItem(element, TRUE, &newItem);
03770 if (cond != DCM_NORMAL) {
03771 return cond;
03772 }
03773 newItem->byteOrder = DCM_ORDERNATIVE;
03774 if ((newItem->element.length & 1) != 0) {
03775 if (newItem->element.representation == DCM_AE) {
03776 p = newItem->element.d.string;
03777 p[newItem->element.length] = ' ';
03778 newItem->paddedDataLength = element->length + 1;
03779 (void) memcpy(p, element->d.string, element->length);
03780 } else if (newItem->element.representation == DCM_AS) {
03781 p = newItem->element.d.string;
03782 p[newItem->element.length] = ' ';
03783 newItem->paddedDataLength = element->length + 1;
03784 (void) memcpy(p, element->d.string, element->length);
03785 } else if (newItem->element.representation == DCM_CS) {
03786 p = newItem->element.d.string;
03787 p[newItem->element.length] = ' ';
03788 newItem->paddedDataLength = element->length + 1;
03789 (void) memcpy(p, element->d.string, element->length);
03790 } else if (newItem->element.representation == DCM_DA) {
03791 p = newItem->element.d.string;
03792 p[newItem->element.length] = ' ';
03793 newItem->paddedDataLength = element->length + 1;
03794 (void) memcpy(p, element->d.string, element->length);
03795 } else if (newItem->element.representation == DCM_DS) {
03796 p = newItem->element.d.string;
03797 p[newItem->element.length] = ' ';
03798 newItem->paddedDataLength = element->length + 1;
03799 (void) memcpy(p, element->d.string, element->length);
03800 } else if (newItem->element.representation == DCM_IS) {
03801 p = newItem->element.d.string;
03802 p[newItem->element.length] = ' ';
03803 newItem->paddedDataLength = element->length + 1;
03804 (void) memcpy(p, element->d.string, element->length);
03805 } else if (newItem->element.representation == DCM_LT) {
03806 p = newItem->element.d.string;
03807 p[newItem->element.length] = ' ';
03808 newItem->paddedDataLength = element->length + 1;
03809 (void) memcpy(p, element->d.string, element->length);
03810 } else if (newItem->element.representation == DCM_LO) {
03811 p = newItem->element.d.string;
03812 p[newItem->element.length] = ' ';
03813 newItem->paddedDataLength = element->length + 1;
03814 (void) memcpy(p, element->d.string, element->length);
03815 } else if (newItem->element.representation == DCM_PN) {
03816 p = newItem->element.d.string;
03817 p[newItem->element.length] = ' ';
03818 newItem->paddedDataLength = element->length + 1;
03819 (void) memcpy(p, element->d.string, element->length);
03820 } else if (newItem->element.representation == DCM_SH) {
03821 p = newItem->element.d.string;
03822 p[newItem->element.length] = ' ';
03823 newItem->paddedDataLength = element->length + 1;
03824 (void) memcpy(p, element->d.string, element->length);
03825 } else if (newItem->element.representation == DCM_ST) {
03826 p = newItem->element.d.string;
03827 p[newItem->element.length] = ' ';
03828 newItem->paddedDataLength = element->length + 1;
03829 (void) memcpy(p, element->d.string, element->length);
03830 } else if (newItem->element.representation == DCM_TM) {
03831 p = newItem->element.d.string;
03832 p[newItem->element.length] = ' ';
03833 newItem->paddedDataLength = element->length + 1;
03834 (void) memcpy(p, element->d.string, element->length);
03835 } else if (newItem->element.representation == DCM_UI) {
03836 p = newItem->element.d.string;
03837 p[newItem->element.length] = '\0';
03838 newItem->paddedDataLength = element->length + 1;
03839 (void) memcpy(p, element->d.string, element->length);
03840 } else if (newItem->element.representation == DCM_UT) {
03841 p = newItem->element.d.string;
03842 p[newItem->element.length] = ' ';
03843 newItem->paddedDataLength = element->length + 1;
03844 (void) memcpy(p, element->d.string, element->length);
03845 } else if (newItem->element.representation == DCM_SQ) {
03846
03847 newItem->element.d.sq = element->d.sq;
03848 } else {
03849 CTN_FREE(newItem);
03850 return COND_PushCondition(DCM_UNEVENELEMENTLENGTH,
03851 DCM_Message(DCM_UNEVENELEMENTLENGTH),
03852 DCM_TAG_GROUP(element->tag),
03853 DCM_TAG_ELEMENT(element->tag), element->length,
03854 "insertNewElement");
03855 }
03856 } else if (newItem->element.representation != DCM_SQ) {
03857 (void) memcpy(newItem->element.d.ot, element->d.ot, element->length);
03858 } else {
03859
03860 newItem->element.d.sq = element->d.sq;
03861 }
03862 if ((*object)->objectSize != DCM_UNSPECIFIEDLENGTH)
03863 (*object)->objectSize += 8 + newItem->paddedDataLength;
03864
03865
03866 cond = updateSpecialElements(object, newItem);
03867 if (cond != DCM_NORMAL)
03868 return cond;
03869
03870 groupItem = (void *)LST_Current(&(*object)->groupList);
03871 if (groupItem == NULL)
03872 return COND_PushCondition(DCM_LISTFAILURE,
03873 DCM_Message(DCM_LISTFAILURE), "insertNewElement");
03874
03875 if (groupItem->baseLength != DCM_UNSPECIFIEDLENGTH)
03876 groupItem->baseLength += 2 + 2 + 4 + newItem->paddedDataLength;
03877
03878 if (newItem->element.representation == DCM_OW ||
03879 newItem->element.representation == DCM_OB ||
03880 newItem->element.representation == DCM_SQ) {
03881 groupItem->longVRAttributes++;
03882 (*object)->longVRAttributes++;
03883 }
03884 if ((nextItem = (void *)LST_Head(&groupItem->elementList)) == NULL) {
03885 cond = LST_Enqueue(&groupItem->elementList, (void *)newItem);
03886 if (cond != LST_NORMAL)
03887 return COND_PushCondition(DCM_LISTFAILURE,
03888 DCM_Message(DCM_LISTFAILURE),
03889 "insertNewElement");
03890 else
03891 return DCM_NORMAL;
03892 }
03893 (void) LST_Position(&groupItem->elementList, (void *)nextItem);
03894 if (DCM_TAG_ELEMENT(nextItem->element.tag) == 0x0000)
03895 (void) memcpy(nextItem->element.d.ot, &groupItem->baseLength,
03896 sizeof(groupItem->baseLength));
03897
03898
03899
03900
03901
03902 while (nextItem != NULL) {
03903 if (DCM_TAG_GROUP(element->tag) !=
03904 DCM_TAG_GROUP(nextItem->element.tag)) {
03905 return COND_PushCondition(DCM_BADELEMENTINGROUP,
03906 DCM_Message(DCM_BADELEMENTINGROUP),
03907 DCM_TAG_GROUP(nextItem->element.tag),
03908 DCM_TAG_ELEMENT(nextItem->element.tag),
03909 groupItem->group, "insertNewElement");
03910 } else if (DCM_TAG_ELEMENT(element->tag) <
03911 DCM_TAG_ELEMENT(nextItem->element.tag)) {
03912 cond = LST_Insert(&groupItem->elementList, (void *)newItem, LST_K_BEFORE);
03913 if (cond != LST_NORMAL)
03914 return COND_PushCondition(DCM_LISTFAILURE,
03915 DCM_Message(DCM_LISTFAILURE),
03916 "insertNewElement");
03917 else
03918 return DCM_NORMAL;
03919 }
03920 nextItem = (void *)LST_Next(&groupItem->elementList);
03921 }
03922
03923
03924
03925
03926
03927
03928 cond = LST_Enqueue(&groupItem->elementList, (void *)newItem);
03929 if (cond != LST_NORMAL)
03930 return COND_PushCondition(DCM_LISTFAILURE,
03931 DCM_Message(DCM_LISTFAILURE),
03932 "insertNewElement");
03933 else
03934 return DCM_NORMAL;
03935 }
03936
03937 static CONDITION
03938 insertThisElementItem(PRIVATE_OBJECT ** object, PRV_ELEMENT_ITEM* newItem)
03939 {
03940 PRV_ELEMENT_ITEM * nextItem;
03941 PRV_GROUP_ITEM * groupItem = 0;
03942 CONDITION cond;
03943
03944
03945 cond = updateSpecialElements(object, newItem);
03946 if (cond != DCM_NORMAL)
03947 return cond;
03948
03949 cond = findCreateGroup(object, DCM_TAG_GROUP(newItem->element.tag),
03950 &groupItem);
03951
03952 if (groupItem == NULL)
03953 return COND_PushCondition(DCM_LISTFAILURE,
03954 DCM_Message(DCM_LISTFAILURE), "insertThisElementItem");
03955
03956 if (groupItem->baseLength != DCM_UNSPECIFIEDLENGTH)
03957 groupItem->baseLength += 2 + 2 + 4 + newItem->paddedDataLength;
03958
03959 if (newItem->element.representation == DCM_OW ||
03960 newItem->element.representation == DCM_OB ||
03961 newItem->element.representation == DCM_SQ) {
03962 groupItem->longVRAttributes++;
03963 (*object)->longVRAttributes++;
03964 }
03965
03966 if ((nextItem = (void *)LST_Head(&groupItem->elementList)) == NULL) {
03967 cond = LST_Enqueue(&groupItem->elementList, (void *)newItem);
03968 if (cond != LST_NORMAL)
03969 return COND_PushCondition(DCM_LISTFAILURE,
03970 DCM_Message(DCM_LISTFAILURE),
03971 "insertThisElementItem");
03972 else
03973 return DCM_NORMAL;
03974 }
03975
03976 (void) LST_Position(&groupItem->elementList, (void *)nextItem);
03977 if (DCM_TAG_ELEMENT(nextItem->element.tag) == 0x0000)
03978 (void) memcpy(nextItem->element.d.ot, &groupItem->baseLength,
03979 sizeof(groupItem->baseLength));
03980
03981
03982
03983
03984
03985 while (nextItem != NULL) {
03986 if (DCM_TAG_GROUP(newItem->element.tag) !=
03987 DCM_TAG_GROUP(nextItem->element.tag)) {
03988 return COND_PushCondition(DCM_BADELEMENTINGROUP,
03989 DCM_Message(DCM_BADELEMENTINGROUP),
03990 DCM_TAG_GROUP(nextItem->element.tag),
03991 DCM_TAG_ELEMENT(nextItem->element.tag),
03992 groupItem->group, "insertThisElementItem");
03993 } else if (DCM_TAG_ELEMENT(newItem->element.tag) <
03994 DCM_TAG_ELEMENT(nextItem->element.tag)) {
03995 cond = LST_Insert(&groupItem->elementList, (void *)newItem, LST_K_BEFORE);
03996 if (cond != LST_NORMAL)
03997 return COND_PushCondition(DCM_LISTFAILURE,
03998 DCM_Message(DCM_LISTFAILURE),
03999 "insertThisElementItem");
04000 else
04001 return DCM_NORMAL;
04002 }
04003 nextItem = (void *)LST_Next(&groupItem->elementList);
04004 }
04005
04006
04007
04008
04009
04010
04011 cond = LST_Enqueue(&groupItem->elementList, (void *)newItem);
04012 if (cond != LST_NORMAL)
04013 return COND_PushCondition(DCM_LISTFAILURE,
04014 DCM_Message(DCM_LISTFAILURE),
04015 "insertThisElementItem");
04016 else
04017 return DCM_NORMAL;
04018 }
04019
04020
04021
04022
04023
04024
04025
04026
04027
04028
04029
04030
04031
04032
04033
04034
04035
04036
04037
04038
04039 static CONDITION
04040 updateObjectType(PRIVATE_OBJECT ** object, DCM_ELEMENT * element)
04041 {
04042 switch ((*object)->objectType) {
04043 case DCM_OBJECTUNKNOWN:
04044 if (DCM_TAG_GROUP(element->tag) == DCM_GROUPCOMMAND)
04045 (*object)->objectType = DCM_OBJECTCOMMAND;
04046 else
04047 (*object)->objectType = DCM_OBJECTELEMENTLIST;
04048 break;
04049 case DCM_OBJECTCOMMAND:
04050 if (DCM_TAG_GROUP(element->tag) != DCM_GROUPCOMMAND)
04051 (*object)->objectType = DCM_OBJECTELEMENTLIST;
04052 break;
04053 case DCM_OBJECTELEMENTLIST:
04054 case DCM_OBJECTIMAGE:
04055 break;
04056 default:
04057 break;
04058 }
04059 return DCM_NORMAL;
04060 }
04061
04062
04063
04064
04065
04066
04067
04068
04069
04070
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080
04081
04082 static CONDITION
04083 updateSpecialElements(PRIVATE_OBJECT ** object,
04084 PRV_ELEMENT_ITEM * item)
04085 {
04086 int idx;
04087
04088 switch (item->element.tag) {
04089 case DCM_IMGBITSALLOCATED:
04090 (*object)->pixelBitsAllocated = *item->element.d.us;
04091 break;
04092 case DCM_IMGPIXELREPRESENTATION:
04093 (*object)->pixelRepresentation = *item->element.d.us;
04094 break;
04095 case DCM_METAGROUPLENGTH:
04096 (*object)->metaHeaderLength = *item->element.d.ul;
04097 break;
04098 case DCM_METATRANSFERSYNTAX:
04099 if (strcmp(item->element.d.string, DICOM_TRANSFERLITTLEENDIAN) == 0) {
04100 (*object)->dataOptions = DCM_ORDERLITTLEENDIAN;
04101 } else if (strcmp(item->element.d.string, DICOM_TRANSFERLITTLEENDIANEXPLICIT) == 0) {
04102 (*object)->dataOptions = DCM_EXPLICITLITTLEENDIAN;
04103 } else if (strcmp(item->element.d.string, DICOM_TRANSFERBIGENDIANEXPLICIT) == 0) {
04104 (*object)->dataOptions = DCM_EXPLICITBIGENDIAN;
04105 } else {
04106 (*object)->dataOptions = DCM_EXPLICITLITTLEENDIAN;
04107 }
04108 break;
04109 case DCM_MAKETAG(0x003a, 0x0103):
04110 strncpy((*object)->waveformDataVR, item->element.d.string,
04111 item->element.length);
04112 (*object)->waveformDataVR[item->element.length] = '\0';
04113 idx = item->element.length - 1;
04114 while (idx >= 0 && (*object)->waveformDataVR[idx] == ' ') {
04115 (*object)->waveformDataVR[idx] = '\0';
04116 idx--;
04117 }
04118 break;
04119 default:
04120 break;
04121 }
04122 return DCM_NORMAL;
04123 }
04124
04125 typedef struct {
04126 DCM_VALUEREPRESENTATION representation;
04127 char code[3];
04128 } VRMAP;
04129
04130 static VRMAP vrMap[] = {
04131 {DCM_AE, "AE"},
04132 {DCM_AS, "AS"},
04133 {DCM_AT, "AT"},
04134 {DCM_CS, "CS"},
04135 {DCM_DA, "DA"},
04136 {DCM_DD, "DD"},
04137 {DCM_DS, "DS"},
04138 {DCM_FD, "FD"},
04139 {DCM_FL, "FL"},
04140 {DCM_IS, "IS"},
04141 {DCM_LO, "LO"},
04142 {DCM_LT, "LT"},
04143 {DCM_OT, "OT"},
04144 {DCM_SH, "SH"},
04145 {DCM_SL, "SL"},
04146 {DCM_SQ, "SQ"},
04147 {DCM_SS, "SS"},
04148 {DCM_ST, "ST"},
04149 {DCM_TM, "TM"},
04150 {DCM_UI, "UI"},
04151 {DCM_UL, "UL"},
04152 {DCM_UN, "UN"},
04153 {DCM_US, "US"},
04154 {DCM_UT, "UT"},
04155
04156 {DCM_RET, "RT"},
04157 {DCM_CTX, " "},
04158 {DCM_PN, "PN"},
04159 {DCM_OB, "OB"},
04160 {DCM_OW, "OW"},
04161 {DCM_DT, "DT"},
04162 {DCM_DLM, ""}
04163 };
04164
04165 static VRMAP *
04166 lookupVRCode(const char *code)
04167 {
04168 int i;
04169
04170 for (i = 0; i < (int) DIM_OF(vrMap); i++) {
04171 if (strcmp(code, vrMap[i].code) == 0)
04172 return &vrMap[i];
04173 }
04174
04175 return NULL;
04176 }
04177
04178 static void
04179 mapVRtoASCII(DCM_VALUEREPRESENTATION vr, char *s)
04180 {
04181 int i;
04182
04183 for (i = 0; i < (int) DIM_OF(vrMap); i++) {
04184 if (vr == vrMap[i].representation) {
04185 strcpy(s, vrMap[i].code);
04186 return;
04187 }
04188 }
04189
04190 strcpy(s, "");
04191 return;
04192 }
04193
04194 static void
04195 exportVRLength(DCM_ELEMENT * e, unsigned char *b, int byteOrder,
04196 U32 * rtnLength)
04197 {
04198 int i;
04199 char *c = "xx";
04200 unsigned char *p;
04201 U16 shortLength;
04202 DCM_VALUEREPRESENTATION vr;
04203
04204 vr = e->representation;
04205 if (e->tag == DCM_MAKETAG(0x003a, 0x1000))
04206 vr = DCM_OB;
04207
04208 for (i = 0; i < DIM_OF(vrMap); i++) {
04209 if (vr == vrMap[i].representation) {
04210 c = vrMap[i].code;
04211 break;
04212 }
04213 }
04214
04215 *b++ = *c++;
04216 *b++ = *c++;
04217 *rtnLength += 2;
04218
04219 if (vr == DCM_OB || vr == DCM_OW || vr == DCM_SQ || vr == DCM_UN) {
04220 *b++ = 0x00;
04221 *b++ = 0x00;
04222 if (byteOrder == BYTEORDER_SAME) {
04223 p = (unsigned char *) &e->length;
04224 *b++ = *p++;
04225 *b++ = *p++;
04226 *b++ = *p++;
04227 *b++ = *p++;
04228 } else {
04229 p = (unsigned char *) &e->length;
04230 *b++ = p[3];
04231 *b++ = p[2];
04232 *b++ = p[1];
04233 *b++ = p[0];
04234 }
04235 *rtnLength += 6;
04236 } else {
04237 shortLength = (U16) e->length;
04238 if (byteOrder == BYTEORDER_SAME) {
04239 p = (unsigned char *) &shortLength;
04240 *b++ = *p++;
04241 *b++ = *p++;
04242 } else {
04243 p = (unsigned char *) &shortLength;
04244 *b++ = p[1];
04245 *b++ = p[0];
04246 }
04247 *rtnLength += 2;
04248 }
04249 }
04250
04251 static CONDITION
04252 exportPreamble(PRIVATE_OBJECT ** obj, unsigned char *dst,
04253 U32 bufferLength, U32 * rtnLength)
04254 {
04255 *rtnLength = 0;
04256 if (bufferLength < (DCM_PREAMBLELENGTH + 4))
04257 return COND_PushCondition(DCM_EXPORTBUFFERTOOSMALL,
04258 DCM_Message(DCM_EXPORTBUFFERTOOSMALL), (int) bufferLength,
04259 "exportPreamble");
04260
04261 (void) memcpy(dst, (*obj)->preamble, DCM_PREAMBLELENGTH);
04262 dst += DCM_PREAMBLELENGTH;
04263 (void) memcpy(dst, "DICM", 4);
04264 *rtnLength += DCM_PREAMBLELENGTH + 4;
04265
04266 return DCM_NORMAL;
04267 }
04268
04269
04270
04271
04272
04273
04274
04275
04276
04277
04278
04279
04280
04281
04282
04283
04284
04285
04286
04287
04288
04289
04290
04291
04292
04293
04294
04295
04296
04297
04298
04299
04300
04301
04302
04303
04304
04305 static void
04306 exportFixedFields(DCM_ELEMENT * e,
04307 unsigned char *b, U32 length, int byteOrder,
04308 CTNBOOLEAN explicitVR, U32 * rtnLength)
04309 {
04310 unsigned char
04311 *p;
04312 unsigned short
04313 group,
04314 element;
04315 U32
04316 minimumLength;
04317
04318 group = DCM_TAG_GROUP(e->tag);
04319 element = DCM_TAG_ELEMENT(e->tag);
04320 if (e->representation == DCM_DLM)
04321 explicitVR = FALSE;
04322
04323 minimumLength = sizeof(group) + sizeof(element) + sizeof(e->length);
04324 if (explicitVR)
04325 minimumLength += 4;
04326
04327 *rtnLength = 0;
04328 if (length >= minimumLength) {
04329 if (byteOrder == BYTEORDER_SAME) {
04330 p = (unsigned char *) &group;
04331 *b++ = *p++;
04332 *b++ = *p++;
04333 p = (unsigned char *) &element;
04334 *b++ = *p++;
04335 *b++ = *p++;
04336 *rtnLength += 4;
04337 if (explicitVR) {
04338 exportVRLength(e, b, byteOrder, rtnLength);
04339 } else {
04340 p = (unsigned char *) &e->length;
04341 *b++ = *p++;
04342 *b++ = *p++;
04343 *b++ = *p++;
04344 *b++ = *p++;
04345 *rtnLength += 4;
04346 }
04347 } else {
04348 p = (unsigned char *) &group;
04349 *b++ = p[1];
04350 *b++ = p[0];
04351 p = (unsigned char *) &element;
04352 *b++ = p[1];
04353 *b++ = p[0];
04354 *rtnLength += 4;
04355 if (explicitVR) {
04356 exportVRLength(e, b, byteOrder, rtnLength);
04357 } else {
04358 p = (unsigned char *) &e->length;
04359 *b++ = p[3];
04360 *b++ = p[2];
04361 *b++ = p[1];
04362 *b++ = p[0];
04363 *rtnLength += 4;
04364 }
04365 }
04366 }
04367 }
04368
04369
04370
04371
04372
04373
04374
04375
04376
04377
04378
04379
04380
04381
04382
04383
04384
04385
04386
04387
04388
04389
04390
04391
04392
04393
04394
04395
04396
04397
04398
04399
04400
04401
04402
04403
04404
04405
04406
04407
04408
04409
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419
04420
04421
04422
04423
04424
04425
04426
04427
04428
04429
04430
04431
04432
04433
04434 union {
04435 unsigned short sh[2];
04436 unsigned char ch[4];
04437 } groupElement;
04438
04439 static CONDITION
04440 exportData(PRIVATE_OBJECT ** object, PRV_ELEMENT_ITEM * item,
04441 unsigned char *src,
04442 unsigned char *b, U32 length, int byteOrder,
04443 U32 * rtnLength)
04444 {
04445
04446 unsigned char
04447 *p;
04448 DCM_TAG
04449 * tag;
04450 DCM_ELEMENT
04451 * element;
04452 int nBytes;
04453 CONDITION cond;
04454
04455 element = &item->element;
04456
04457 *rtnLength = 0;
04458 if (element->d.ot == NULL) {
04459 if ((*object)->fd != -1) {
04460 (void) lseek((*object)->fd, item->currentOffset, SEEK_SET);
04461 nBytes = read((*object)->fd, b, (int) length);
04462 } else {
04463 (*object)->sk((*object)->userCtx, item->currentOffset, SEEK_SET);
04464 cond = (*object)->rd((*object)->userCtx, b, (long) length, &nBytes);
04465 }
04466 if ((U32) nBytes != length) {
04467 char b[512];
04468 sprintf(b, "byte count: %d %d, errno: %d", nBytes, length, errno);
04469 (void) COND_PushCondition(DCM_GENERALWARNING,
04470 DCM_Message(DCM_GENERALWARNING), "exportData", b);
04471 return COND_PushCondition(DCM_FILEACCESSERROR,
04472 DCM_Message(DCM_FILEACCESSERROR), (*object)->fileName,
04473 "exportData");
04474 }
04475 if( LITTLE_ENDIAN_ARCHITECTURE ){
04476 if (item->element.representation == DCM_AT) {
04477 DCM_ELEMENT e;
04478 e = *element;
04479 e.length = length;
04480 e.d.ot = b;
04481 swapATGroupElement(&e);
04482 }
04483 }
04484 if (byteOrder != item->byteOrder) {
04485 DCM_ELEMENT e;
04486 e = *element;
04487 e.length = length;
04488 e.d.ot = b;
04489 swapInPlace(object, &e);
04490 }
04491 *rtnLength = (U32) nBytes;
04492 item->currentOffset += nBytes;
04493 } else {
04494 p = src;
04495 switch (element->representation) {
04496 case DCM_AE:
04497 case DCM_AS:
04498 case DCM_CS:
04499 case DCM_DA:
04500 case DCM_DT:
04501 case DCM_DD:
04502 case DCM_DS:
04503 case DCM_FD:
04504 case DCM_IS:
04505 case DCM_LO:
04506 case DCM_LT:
04507 case DCM_OB:
04508 case DCM_OT:
04509 case DCM_PN:
04510 case DCM_SH:
04511 case DCM_SQ:
04512 case DCM_ST:
04513 case DCM_TM:
04514 case DCM_UI:
04515 case DCM_UT:
04516 (void) memcpy(b, p, length);
04517 *rtnLength = length;
04518 break;
04519 case DCM_AT:
04520 tag = (DCM_TAG *) p;
04521 while (length >= 4) {
04522 groupElement.sh[0] = DCM_TAG_GROUP(*tag);
04523 groupElement.sh[1] = DCM_TAG_ELEMENT(*tag);
04524 if (byteOrder == BYTEORDER_SAME) {
04525 *b++ = groupElement.ch[0];
04526 *b++ = groupElement.ch[1];
04527 *b++ = groupElement.ch[2];
04528 *b++ = groupElement.ch[3];
04529 } else {
04530 *b++ = groupElement.ch[1];
04531 *b++ = groupElement.ch[0];
04532 *b++ = groupElement.ch[3];
04533 *b++ = groupElement.ch[2];
04534 }
04535 tag++;
04536 length -= 4;
04537 *rtnLength += 4;
04538 }
04539 break;
04540 case DCM_SL:
04541 case DCM_UL:
04542 case DCM_FL:
04543 while (length >= 4) {
04544 if (byteOrder == BYTEORDER_SAME) {
04545 *b++ = *p++;
04546 *b++ = *p++;
04547 *b++ = *p++;
04548 *b++ = *p++;
04549 } else {
04550 *b++ = p[3];
04551 *b++ = p[2];
04552 *b++ = p[1];
04553 *b++ = p[0];
04554 p += 4;
04555 }
04556 length -= 4;
04557 *rtnLength += 4;
04558 }
04559 break;
04560 case DCM_SS:
04561 case DCM_US:
04562 case DCM_OW:
04563
04564
04565
04566
04567 length &= ~1;
04568 *rtnLength += length;
04569 if (element->tag == DCM_PXLPIXELDATA) {
04570 if (byteOrder == item->byteOrder)
04571 (void) memcpy(b, p, length);
04572 else
04573 #ifdef SOLARIS
04574 swab((char *) p, (char *) b, length);
04575 #elif defined AIXV3
04576 swab((short *) p, (short *) b, length);
04577 #elif defined MACOS
04578
04579 #else
04580 swab(p, b, length);
04581 #endif
04582 } else {
04583 if (byteOrder == BYTEORDER_SAME)
04584 (void) memcpy(b, p, length);
04585 else
04586 #ifdef SOLARIS
04587 swab((char *) p, (char *) b, length);
04588 #elif defined AIXV3
04589 swab((short *) p, (short *) b, length);
04590 #elif defined MACOS
04591
04592 #else
04593 swab(p, b, length);
04594 #endif
04595 }
04596 break;
04597
04598 case DCM_UN:
04599 default:
04600 #if 0
04601 fprintf(stderr, "Should not get to default in exportData: %08x\n",
04602 element->tag);
04603 #endif
04604 (void) memcpy(b, p, length);
04605 *rtnLength = length;
04606 break;
04607 }
04608 }
04609 return DCM_NORMAL;
04610 }
04611
04612 static CONDITION
04613 exportEncapsulatedPixels(PRIVATE_OBJECT ** object, PRV_ELEMENT_ITEM * item,
04614 unsigned char* buffer, U32 bufferlength, DCM_EXPORT_STREAM_CALLBACK* callback,
04615 void* ctx)
04616 {
04617 DCM_ELEMENT * element;
04618 int nBytes;
04619 CONDITION cond;
04620 U32 toExport;
04621 int length;
04622 DCM_FRAGMENT_ITEM* fragmentItem = 0;
04623 DCM_ELEMENT e;
04624 U32 rtnLength = 0;
04625
04626 element = &item->element;
04627 if (element->d.ot == NULL) {
04628 if ((*object)->fd != -1) {
04629
04630
04631
04632 (void) lseek((*object)->fd, item->dataOffset-12, SEEK_SET);
04633 } else {
04634 (*object)->sk((*object)->userCtx, item->dataOffset-12, SEEK_SET);
04635 }
04636
04637 toExport = item->originalDataLength + 12;
04638 while(toExport > 0) {
04639 length = (toExport < bufferlength) ? toExport : bufferlength;
04640
04641 if ((*object)->fd != -1) {
04642 nBytes = read((*object)->fd, buffer, length);
04643 } else {
04644 cond = (*object)->rd((*object)->userCtx, buffer, (long) length, &nBytes);
04645 }
04646 if ((U32) nBytes != length) {
04647 char b[512];
04648 sprintf(b, "byte count: %d %d, errno: %d", nBytes, length, errno);
04649 (void) COND_PushCondition(DCM_GENERALWARNING,
04650 DCM_Message(DCM_GENERALWARNING), "exportEncapsualtedPixels", b);
04651 return COND_PushCondition(DCM_FILEACCESSERROR,
04652 DCM_Message(DCM_FILEACCESSERROR), (*object)->fileName,
04653 "exportEncapsualtedPixels");
04654 }
04655 cond = callback(buffer, length, 0, ctx);
04656 if (cond != DCM_NORMAL) {
04657 return COND_PushCondition(DCM_CALLBACKABORTED,
04658 DCM_Message(DCM_CALLBACKABORTED), "exportStream");
04659 }
04660 toExport -= length;
04661 }
04662 } else {
04663 if (item->fragmentFlag != 1) {
04664 return COND_PushCondition(DCM_NOFRAGMENTSINOBJECT,
04665 "DCM Exporting pixels but did not find expected fragments in object");
04666 }
04667 e.tag = DCM_PXLPIXELDATA;
04668 e.d.ot = 0;
04669 e.representation = DCM_OB;
04670 e.length = 0xffffffff;
04671 exportFixedFields(&e, buffer, bufferlength,
04672 LITTLE_ORDER ,
04673 1 ,
04674 &rtnLength);
04675 toExport = rtnLength;
04676 e.tag = 0xfffee000;
04677 e.length = 0;
04678 e.representation = DCM_DLM;
04679 e.d.ot = 0;
04680 exportFixedFields(&e, buffer+toExport, bufferlength,
04681 LITTLE_ORDER ,
04682 1 ,
04683 &rtnLength);
04684 toExport += rtnLength;
04685
04686 cond = callback(buffer, toExport, 0, ctx);
04687 if (cond != DCM_NORMAL) {
04688 return COND_PushCondition(DCM_CALLBACKABORTED,
04689 DCM_Message(DCM_CALLBACKABORTED), "exportEncapsulatedPixels");
04690 }
04691
04692 fragmentItem = (DCM_FRAGMENT_ITEM*)LST_Head(&item->element.d.fragments);
04693 (void)LST_Position(&item->element.d.fragments, (void *)fragmentItem);
04694 while (fragmentItem != NULL) {
04695 RWC_printf("Fragment size: %6d\n", fragmentItem->length);
04696 e.tag = 0xfffee000;
04697 e.length = fragmentItem->length;
04698 e.representation = DCM_DLM;
04699 exportFixedFields(&e, buffer, bufferlength,
04700 LITTLE_ORDER ,
04701 1 ,
04702 &rtnLength);
04703 cond = callback(buffer, rtnLength, 0, ctx);
04704 if (cond != DCM_NORMAL) {
04705 return COND_PushCondition(DCM_CALLBACKABORTED,
04706 DCM_Message(DCM_CALLBACKABORTED), "exportEncapsulatedPixels");
04707 }
04708 cond = callback(fragmentItem->fragment, fragmentItem->length, 0, ctx);
04709 if (cond != DCM_NORMAL) {
04710 return COND_PushCondition(DCM_CALLBACKABORTED,
04711 DCM_Message(DCM_CALLBACKABORTED), "exportEncapsulatedPixels");
04712 }
04713
04714 fragmentItem = (void *)LST_Next(&item->element.d.fragments);
04715 }
04716 e.tag = 0xfffee0dd;
04717 e.length = 0;
04718 e.representation = DCM_DLM;
04719 e.d.ot = 0;
04720 exportFixedFields(&e, buffer, bufferlength,
04721 LITTLE_ORDER ,
04722 1 ,
04723 &rtnLength);
04724 cond = callback(buffer, rtnLength, 0, ctx);
04725 if (cond != DCM_NORMAL) {
04726 return COND_PushCondition(DCM_CALLBACKABORTED,
04727 DCM_Message(DCM_CALLBACKABORTED), "exportEncapsulatedPixels");
04728 }
04729 }
04730 return DCM_NORMAL;
04731 }
04732
04733 static CONDITION
04734 exportPixels(PRIVATE_OBJECT ** object, PRV_ELEMENT_ITEM * item,
04735 int encapsulatedPixels,
04736 unsigned char* buffer, U32 bufferlength, DCM_EXPORT_STREAM_CALLBACK* callback,
04737 void* ctx,
04738 int byteOrder, int explicitVR)
04739 {
04740 DCM_ELEMENT * element;
04741 int nBytes;
04742 CONDITION cond;
04743 U32 toExport;
04744 U32 bytesExported = 0;
04745 U32 exportLength = 0;
04746 int length;
04747 U32 rtnLength;
04748 U32 remainingData;
04749 unsigned char* dst;
04750 unsigned char* src;
04751 int c;
04752
04753 if (encapsulatedPixels) {
04754 return exportEncapsulatedPixels(object, item, buffer,
04755 bufferlength, callback, ctx);
04756 }
04757
04758 element = &item->element;
04759 rtnLength = 0;
04760 dst = buffer;
04761 c = bufferlength;
04762 exportFixedFields(element, dst, bufferlength, byteOrder,
04763 explicitVR, &rtnLength);
04764 dst += rtnLength;
04765 c -= rtnLength;
04766 bytesExported = rtnLength;
04767
04768 remainingData = element->length;
04769 src = element->d.ot;
04770 item->currentOffset = item->dataOffset;
04771
04772 while (remainingData > 0) {
04773 if (debug) {
04774 fprintf(stderr, "Export: (%08x) %d\n", element->tag, element->length);
04775 }
04776
04777 if (element->d.ot != NULL) {
04778 remainingData = element->length -
04779 (src - ((unsigned char *) element->d.ot));
04780 } else {
04781 remainingData = element->length -
04782 (item->currentOffset - item->dataOffset);
04783 }
04784
04785 exportLength = (remainingData < c) ? remainingData : c;
04786 cond = exportData(object, item, src, dst,
04787 exportLength, byteOrder, &rtnLength);
04788 if (cond != DCM_NORMAL)
04789 return cond;
04790
04791 src += rtnLength;
04792 dst += rtnLength;
04793 bytesExported += rtnLength;
04794 c -= rtnLength;
04795
04796 if (c <= 20) {
04797 cond = callback(buffer, bytesExported, 0, ctx);
04798 if (cond != DCM_NORMAL) {
04799 return COND_PushCondition(DCM_CALLBACKABORTED,
04800 DCM_Message(DCM_CALLBACKABORTED), "exportPixels");
04801 }
04802 bytesExported = 0;
04803 c = bufferlength;
04804 dst = (unsigned char *) buffer;
04805 }
04806 }
04807 if (bytesExported > 0) {
04808 cond = callback(buffer, bytesExported, 0, ctx);
04809 if (cond != DCM_NORMAL) {
04810 return COND_PushCondition(DCM_CALLBACKABORTED,
04811 DCM_Message(DCM_CALLBACKABORTED), "exportPixels");
04812 }
04813 }
04814
04815 return DCM_NORMAL;
04816
04817 #if 0
04818 if (element->d.ot == NULL) {
04819 if ((*object)->fd != -1) {
04820
04821
04822
04823 (void) lseek((*object)->fd, item->dataOffset-12, SEEK_SET);
04824 } else {
04825 (*object)->sk((*object)->userCtx, item->dataOffset-12, SEEK_SET);
04826 }
04827
04828 toExport = item->originalDataLength + 12;
04829 while(toExport > 0) {
04830 length = (toExport < bufferlength) ? toExport : bufferlength;
04831
04832 if ((*object)->fd != -1) {
04833 nBytes = read((*object)->fd, buffer, length);
04834 } else {
04835 cond = (*object)->rd((*object)->userCtx, buffer, (long) length, &nBytes);
04836 }
04837 if ((U32) nBytes != length) {
04838 char b[512];
04839 sprintf(b, "byte count: %d %d, errno: %d", nBytes, length, errno);
04840 (void) COND_PushCondition(DCM_GENERALWARNING,
04841 DCM_Message(DCM_GENERALWARNING), "exportPixels", b);
04842 return COND_PushCondition(DCM_FILEACCESSERROR,
04843 DCM_Message(DCM_FILEACCESSERROR), (*object)->fileName,
04844 "exportPixels");
04845 }
04846 cond = callback(buffer, length, 0, ctx);
04847 if (cond != DCM_NORMAL) {
04848 return COND_PushCondition(DCM_CALLBACKABORTED,
04849 DCM_Message(DCM_CALLBACKABORTED), "exportStream");
04850 }
04851 toExport -= length;
04852 }
04853 } else {
04854 }
04855 return DCM_NORMAL;
04856 #endif
04857
04858 }
04859
04860
04861
04862
04863
04864
04865
04866
04867
04868
04869
04870
04871
04872
04873
04874
04875
04876
04877
04878
04879 #ifdef MACOS
04880 static long
04881 #else
04882 static int
04883 #endif
04884 fileSize(int fd)
04885 {
04886 int
04887 status;
04888 struct stat
04889 im_stat;
04890
04891 status = fstat(fd, &im_stat);
04892 if (status < 0) {
04893 return status;
04894 } else
04895 return im_stat.st_size;
04896 }
04897
04898
04899
04900
04901
04902
04903
04904
04905
04906
04907
04908
04909
04910
04911
04912
04913
04914
04915
04916
04917
04918
04919
04920
04921
04922
04923 static void
04924 swapInPlace(PRIVATE_OBJECT ** object, DCM_ELEMENT * e)
04925 {
04926 U32
04927 length;
04928 unsigned char
04929 tmp,
04930 *p1;
04931
04932 length = e->length;
04933 p1 = e->d.ot;
04934 if (e->representation == DCM_US || e->representation == DCM_SS ||
04935 e->representation == DCM_OW || e->representation == DCM_AT) {
04936 if (e->tag == DCM_PXLPIXELDATA &&
04937 (*object)->pixelBitsAllocated != 16)
04938 return;
04939
04940 while (length > 0) {
04941 tmp = p1[0];
04942 p1[0] = p1[1];
04943 p1[1] = tmp;
04944 p1 += 2;
04945 length -= 2;
04946 }
04947 } else if (e->representation == DCM_UL || e->representation == DCM_SL) {
04948 while (length > 0) {
04949 tmp = p1[0];
04950 p1[0] = p1[3];
04951 p1[3] = tmp;
04952 tmp = p1[1];
04953 p1[1] = p1[2];
04954 p1[2] = tmp;
04955 length -= 4;
04956 p1 += 4;
04957 }
04958 }
04959 }
04960
04961
04962
04963
04964
04965
04966
04967
04968
04969
04970
04971
04972
04973
04974
04975
04976
04977
04978
04979
04980
04981
04982
04983
04984
04985
04986 static CONDITION
04987 checkObject(PRIVATE_OBJECT ** object, char *caller)
04988 {
04989 if (object == NULL)
04990 return COND_PushCondition(DCM_NULLOBJECT, DCM_Message(DCM_NULLOBJECT),
04991 caller);
04992 if (*object == NULL)
04993 return COND_PushCondition(DCM_NULLOBJECT, DCM_Message(DCM_NULLOBJECT),
04994 caller);
04995
04996 if (strcmp((*object)->keyType, KEY_DCM_OBJECT) != 0)
04997 return COND_PushCondition(DCM_ILLEGALOBJECT,
04998 DCM_Message(DCM_ILLEGALOBJECT), caller);
04999 return DCM_NORMAL;
05000 }
05001
05002
05003
05004
05005
05006
05007
05008
05009
05010
05011
05012
05013
05014
05015
05016
05017
05018
05019
05020
05021
05022
05023
05024
05025
05026 static CONDITION
05027 writeFile(void *buffer, U32 length, int flag,
05028 void *fdPtr)
05029 {
05030 int
05031 bytesWritten;
05032 int *fd;
05033
05034 fd = (int *) fdPtr;
05035
05036 bytesWritten = write(*fd, buffer, (int) length);
05037 if (bytesWritten != (int) length)
05038 return COND_PushCondition(DCM_FILEIOERROR,
05039 DCM_Message(DCM_FILEIOERROR), "", strerror(errno),
05040 "writeFile");
05041 else
05042 return DCM_NORMAL;
05043 }
05044
05045 static CONDITION
05046 countBytes(void *buffer, U32 length, int flag,
05047 void *sizePtr)
05048 {
05049 unsigned long *size;
05050
05051 size = (unsigned long *) sizePtr;
05052
05053 *size += length;
05054
05055 return DCM_NORMAL;
05056 }
05057
05058 static CONDITION
05059 setFileOptions(DCM_OBJECT ** obj, unsigned long *opt)
05060 {
05061 CONDITION cond;
05062 char xferSyntax[DICOM_UI_LENGTH + 1];
05063 DCM_ELEMENT e = {DCM_METATRANSFERSYNTAX, DCM_UI, "", 1, sizeof(xferSyntax),
05064 NULL};
05065
05066 e.d.string = xferSyntax;
05067 cond = DCM_ParseObject(obj, &e, 1, NULL, 0, NULL);
05068 if (cond != DCM_NORMAL)
05069 return cond;
05070
05071 *opt = 0;
05072 if (strcmp(xferSyntax, DICOM_TRANSFERLITTLEENDIAN) == 0) {
05073 *opt = DCM_ORDERLITTLEENDIAN;
05074 } else if (strcmp(xferSyntax, DICOM_TRANSFERLITTLEENDIANEXPLICIT) == 0) {
05075 *opt = DCM_EXPLICITLITTLEENDIAN;
05076 } else if (strcmp(xferSyntax, DICOM_TRANSFERBIGENDIANEXPLICIT) == 0) {
05077 *opt = DCM_EXPLICITBIGENDIAN;
05078 } else {
05079 *opt = DCM_ENCAPSULATEDPIXELS;
05080 }
05081
05082 return DCM_NORMAL;
05083 }
05084
05085 static CONDITION
05086 extractFileOptions(unsigned long opt, CTNBOOLEAN * part10File,
05087 CTNBOOLEAN * explicitVR, int *byteOrder,
05088 CTNBOOLEAN* encapsulatedPixels)
05089 {
05090 *part10File = *explicitVR = FALSE;
05091
05092 if ((opt & DCM_FILEFORMATMASK) == DCM_PART10FILE) {
05093 *part10File = TRUE;
05094 opt &= ~DCM_ORDERMASK;
05095 opt |= DCM_EXPLICITLITTLEENDIAN;
05096 }
05097 if ((opt & DCM_ORDERMASK) == 0)
05098 return COND_PushCondition(DCM_ILLEGALOPTION,
05099 DCM_Message(DCM_ILLEGALOPTION), "Byte order",
05100 "extractFileOptions");
05101
05102 switch (opt & DCM_ORDERMASK) {
05103 case DCM_ORDERNATIVE:
05104 *byteOrder = NATIVE_ORDER;
05105 *encapsulatedPixels = FALSE;
05106 break;
05107 case DCM_ORDERLITTLEENDIAN:
05108 *byteOrder = LITTLE_ORDER;
05109 *encapsulatedPixels = FALSE;
05110 break;
05111 case DCM_EXPLICITLITTLEENDIAN:
05112 *byteOrder = LITTLE_ORDER;
05113 *explicitVR = TRUE;
05114 *encapsulatedPixels = FALSE;
05115 break;
05116 case DCM_ORDERBIGENDIAN:
05117 *byteOrder = BIG_ORDER;
05118 *encapsulatedPixels = FALSE;
05119 break;
05120 case DCM_EXPLICITBIGENDIAN:
05121 *byteOrder = BIG_ORDER;
05122 *explicitVR = TRUE;
05123 *encapsulatedPixels = FALSE;
05124 break;
05125 case DCM_ENCAPSULATEDPIXELS:
05126 *byteOrder = LITTLE_ORDER;
05127 *explicitVR = TRUE;
05128 *encapsulatedPixels = TRUE;
05129 break;
05130 default:
05131 *byteOrder = LITTLE_ORDER;
05132 *encapsulatedPixels = FALSE;
05133 break;
05134 }
05135
05136 return DCM_NORMAL;
05137 }
05138
05139 static U32
05140 computeGroupLength(PRV_GROUP_ITEM * groupItem,
05141 CTNBOOLEAN explicitVR)
05142 {
05143 return (explicitVR) ?
05144 groupItem->baseLength + 4 * groupItem->longVRAttributes :
05145 groupItem->baseLength;
05146
05147 }
05148
05149
05150
05151
05152
05153
05154
05155
05156
05157
05158
05159
05160
05161
05162
05163
05164
05165
05166
05167
05168
05169
05170
05171
05172
05173
05174
05175
05176
05177
05178
05179
05180
05181 static CONDITION
05182 exportStream(DCM_OBJECT ** callerObject, unsigned long opt,
05183 void *buffer, U32 bufferlength, DCM_EXPORT_STREAM_CALLBACK* callback,
05184 void *ctx, int sequenceLevel)
05185 {
05186 PRIVATE_OBJECT
05187 ** object;
05188 PRV_GROUP_ITEM
05189 * groupItem;
05190 PRV_ELEMENT_ITEM
05191 * elementItem;
05192 DCM_ELEMENT
05193 element;
05194 int
05195 byteOrder;
05196 int
05197 lastFlag = 0;
05198 unsigned char
05199 *src,
05200 *dst;
05201 U32
05202 c,
05203 bytesExported = 0,
05204 rtnLength,
05205 remainingData,
05206 exportLength;
05207 CONDITION
05208 cond;
05209 DCM_SEQUENCE_ITEM
05210 * sequenceItem;
05211 DCM_ELEMENT
05212 itemMarker = {
05213 DCM_DLMITEM, DCM_DLM, "", 1, DCM_UNSPECIFIEDLENGTH, NULL
05214 },
05215 itemDelimiter = {
05216 DCM_DLMITEMDELIMITATIONITEM, DCM_DLM, "", 1, 0, NULL
05217 },
05218 sequenceDelimiter = {
05219 DCM_DLMSEQUENCEDELIMITATIONITEM, DCM_DLM, "", 1, 0, NULL
05220 };
05221 CTNBOOLEAN
05222 unspecifiedSQLength = FALSE,
05223 explicitVR = FALSE,
05224 part10File = FALSE,
05225 encapsulatedPixels = FALSE;
05226 unsigned long fileOptions = 0;
05227
05228 object = (PRIVATE_OBJECT **) callerObject;
05229 cond = checkObject(object, "exportStream");
05230 if (cond != DCM_NORMAL)
05231 return cond;
05232
05233 if ((opt & DCM_FILEFORMATMASK) == DCM_PART10FILE) {
05234 part10File = TRUE;
05235 opt &= ~DCM_ORDERMASK;
05236 opt |= DCM_EXPLICITLITTLEENDIAN;
05237 cond = setFileOptions(callerObject, &fileOptions);
05238 if (cond != DCM_NORMAL)
05239 return cond;
05240 }
05241 if ((opt & DCM_ORDERMASK) == 0)
05242 return COND_PushCondition(DCM_ILLEGALOPTION,
05243 DCM_Message(DCM_ILLEGALOPTION), "Byte order",
05244 "exportStream");
05245
05246 switch (opt & DCM_ORDERMASK) {
05247 case DCM_ORDERNATIVE:
05248 byteOrder = NATIVE_ORDER;
05249 break;
05250 case DCM_ORDERLITTLEENDIAN:
05251 byteOrder = LITTLE_ORDER;
05252 break;
05253 case DCM_EXPLICITLITTLEENDIAN:
05254 byteOrder = LITTLE_ORDER;
05255 explicitVR = TRUE;
05256 break;
05257 case DCM_ORDERBIGENDIAN:
05258 byteOrder = BIG_ORDER;
05259 break;
05260 case DCM_EXPLICITBIGENDIAN:
05261 byteOrder = BIG_ORDER;
05262 explicitVR = TRUE;
05263 break;
05264 case DCM_ENCAPSULATEDPIXELS:
05265 byteOrder = LITTLE_ORDER;
05266 explicitVR = TRUE;
05267 encapsulatedPixels = TRUE;
05268 break;
05269 default:
05270 byteOrder = LITTLE_ORDER;
05271 break;
05272 }
05273
05274
05275
05276 opt &= ~DCM_SEQUENCELENGTHMASK;
05277 opt |= DCM_UNSPECIFIEDLENGTHFLAG;
05278
05279
05280
05281 if ((opt & DCM_SEQUENCELENGTHMASK) == DCM_UNSPECIFIEDLENGTHFLAG)
05282 unspecifiedSQLength = TRUE;
05283
05284 dst = (unsigned char *) buffer;
05285 c = bufferlength;
05286
05287 if (part10File) {
05288 cond = exportPreamble(object, dst, c, &rtnLength);
05289 if (cond != DCM_NORMAL)
05290 return cond;
05291
05292 dst += rtnLength;
05293 c -= rtnLength;
05294 bytesExported += rtnLength;
05295 }
05296 if (sequenceLevel != 0) {
05297 if (!unspecifiedSQLength)
05298 itemMarker.length = (*object)->objectSize;
05299 exportFixedFields(&itemMarker, dst, bufferlength, byteOrder,
05300 explicitVR, &rtnLength);
05301 dst += rtnLength;
05302 c -= rtnLength;
05303 bytesExported += rtnLength;
05304 }
05305 groupItem = (void *)LST_Head(&(*object)->groupList);
05306
05307
05308 #if 0
05309 if (groupItem == NULL)
05310 return COND_PushCondition(DCM_LISTFAILURE,
05311 DCM_Message(DCM_LISTFAILURE), "exportStream");
05312 #endif
05313 if (groupItem != NULL)
05314 (void) LST_Position(&(*object)->groupList, (void *)groupItem);
05315
05316 while (groupItem != NULL) {
05317 if (part10File && groupItem->group != DCM_GROUPFILEMETA) {
05318 if (opt != fileOptions) {
05319 opt = fileOptions;
05320 cond = extractFileOptions(opt, &part10File,
05321 &explicitVR, &byteOrder,
05322 &encapsulatedPixels);
05323 if (cond != DCM_NORMAL)
05324 return cond;
05325 }
05326 }
05327 elementItem = (void *)LST_Head(&groupItem->elementList);
05328 if (elementItem != NULL)
05329 (void) LST_Position(&groupItem->elementList, (void *)elementItem);
05330 if (DCM_TAG_ELEMENT(elementItem->element.tag) == 0x0000) {
05331 U32 l;
05332 l = computeGroupLength(groupItem, explicitVR);
05333 *elementItem->element.d.ul = l;
05334
05335
05336
05337
05338 if (groupItem->group != 0x0000 && groupItem->group != 0x0002)
05339 elementItem = (void *)LST_Next(&groupItem->elementList);
05340 }
05341 while (elementItem != NULL) {
05342 if (c <= 20) {
05343 cond = callback(buffer, bytesExported, 0, ctx);
05344 if (cond != DCM_NORMAL)
05345 return COND_PushCondition(DCM_CALLBACKABORTED,
05346 DCM_Message(DCM_CALLBACKABORTED), "exportStream");
05347
05348 bytesExported = 0;
05349 c = bufferlength;
05350 dst = (unsigned char *) buffer;
05351 }
05352 element = elementItem->element;
05353
05354 if (element.tag == DCM_PXLPIXELDATA) {
05355
05356
05357 cond = callback(buffer, bytesExported, 0, ctx);
05358 if (cond != DCM_NORMAL)
05359 return COND_PushCondition(DCM_CALLBACKABORTED,
05360 DCM_Message(DCM_CALLBACKABORTED), "exportStream");
05361
05362 cond = exportPixels(object, elementItem, encapsulatedPixels,
05363 buffer, bufferlength, callback, ctx, byteOrder, explicitVR);
05364 if (cond != DCM_NORMAL)
05365 return cond;
05366
05367 bytesExported = 0;
05368 c = bufferlength;
05369 dst = (unsigned char *) buffer;
05370 rtnLength = 0;
05371 } else if (element.representation == DCM_SQ) {
05372 if (unspecifiedSQLength)
05373 element.length = DCM_UNSPECIFIEDLENGTH;
05374
05375 exportFixedFields(&element, dst, bufferlength, byteOrder,
05376 explicitVR, &rtnLength);
05377 } else {
05378 element.length = elementItem->paddedDataLength;
05379 exportFixedFields(&element, dst, bufferlength, byteOrder,
05380 explicitVR, &rtnLength);
05381 }
05382 dst += rtnLength;
05383 c -= rtnLength;
05384 bytesExported += rtnLength;
05385
05386 remainingData = element.length;
05387 src = element.d.ot;
05388 elementItem->currentOffset = elementItem->dataOffset;
05389
05390 if (element.tag == DCM_PXLPIXELDATA) {
05391
05392 ;
05393 } else if (element.representation == DCM_SQ) {
05394
05395 cond = callback(buffer, bytesExported, 0, ctx);
05396 if (cond != DCM_NORMAL)
05397 return COND_PushCondition(DCM_CALLBACKABORTED,
05398 DCM_Message(DCM_CALLBACKABORTED), "exportStream");
05399
05400 bytesExported = 0;
05401 c = bufferlength;
05402 dst = (unsigned char *) buffer;
05403
05404 if (element.d.sq != NULL) {
05405 sequenceItem = (void *)LST_Head(&element.d.sq);
05406 if (sequenceItem != NULL)
05407 (void) LST_Position(&element.d.sq, (void *)sequenceItem);
05408 while (sequenceItem != NULL) {
05409 cond = exportStream(&sequenceItem->object, opt,
05410 buffer, bufferlength, callback, ctx,
05411 sequenceLevel + 1);
05412 if (cond != DCM_NORMAL)
05413 return cond;
05414 sequenceItem = (void *)LST_Next(&element.d.sq);
05415 }
05416 }
05417 if (element.length == DCM_UNSPECIFIEDLENGTH) {
05418 sequenceDelimiter.length = 0;
05419 exportFixedFields(&sequenceDelimiter, dst, bufferlength,
05420 byteOrder, explicitVR, &rtnLength);
05421 dst += rtnLength;
05422 c -= rtnLength;
05423 bytesExported += rtnLength;
05424 }
05425 } else {
05426 while (remainingData > 0) {
05427 if (debug)
05428 fprintf(stderr, "Export: (%08x) %d\n",
05429 element.tag, element.length);
05430 if (element.d.ot != NULL)
05431 remainingData = element.length -
05432 (src - ((unsigned char *) element.d.ot));
05433 else
05434 remainingData = element.length -
05435 (elementItem->currentOffset - elementItem->dataOffset);
05436
05437 exportLength = (remainingData < c) ? remainingData : c;
05438 cond = exportData(object, elementItem, src, dst,
05439 exportLength, byteOrder, &rtnLength);
05440 if (cond != DCM_NORMAL)
05441 return cond;
05442
05443 src += rtnLength;
05444 dst += rtnLength;
05445 bytesExported += rtnLength;
05446 c -= rtnLength;
05447
05448 if (c <= 20) {
05449 cond = callback(buffer, bytesExported, 0, ctx);
05450 if (cond != DCM_NORMAL)
05451 return COND_PushCondition(DCM_CALLBACKABORTED,
05452 DCM_Message(DCM_CALLBACKABORTED), "exportStream");
05453
05454 bytesExported = 0;
05455 c = bufferlength;
05456 dst = (unsigned char *) buffer;
05457 }
05458 }
05459 }
05460 elementItem = (void *)LST_Next(&groupItem->elementList);
05461 }
05462 groupItem = (void *)LST_Next(&(*object)->groupList);
05463 }
05464 if ((sequenceLevel != 0) && unspecifiedSQLength) {
05465 if (c <= 20) {
05466 cond = callback(buffer, bytesExported, 0, ctx);
05467 if (cond != DCM_NORMAL)
05468 return COND_PushCondition(DCM_CALLBACKABORTED,
05469 DCM_Message(DCM_CALLBACKABORTED), "exportStream");
05470
05471 bytesExported = 0;
05472 c = bufferlength;
05473 dst = (unsigned char *) buffer;
05474 }
05475 exportFixedFields(&itemDelimiter, dst, bufferlength, byteOrder,
05476 explicitVR, &rtnLength);
05477 dst += rtnLength;
05478 c -= rtnLength;
05479 bytesExported += rtnLength;
05480 }
05481 lastFlag = (sequenceLevel == 0) ? 1 : 0;
05482 cond = callback(buffer, bytesExported, lastFlag, ctx);
05483 if (cond != DCM_NORMAL)
05484 return COND_PushCondition(DCM_CALLBACKABORTED,
05485 DCM_Message(DCM_CALLBACKABORTED), "exportStream");
05486
05487 return DCM_NORMAL;
05488 }
05489
05490
05491
05492
05493
05494
05495
05496
05497
05498
05499
05500
05501
05502
05503
05504
05505
05506
05507
05508
05509
05510
05511
05512
05513
05514
05515
05516
05517
05518
05519
05520
05521
05522
05523
05524
05525
05526
05527 static CONDITION
05528 verifyFormat(PRV_ELEMENT_ITEM * item)
05529 {
05530 int
05531 i,
05532 l;
05533 char
05534 *src,
05535 *dst,
05536 *p;
05537 DCM_ELEMENT
05538 * element;
05539 CTNBOOLEAN
05540 stopFlag = FALSE;
05541
05542 element = &item->element;
05543 if (element->length > 0) {
05544 switch (element->representation) {
05545 case DCM_DA:
05546 src = dst = element->d.string;
05547 l = (int) element->length;
05548 for (i = 0; i < l; i++) {
05549 if (isdigit(*src) || (*src == '-') || (*src == '\\')) {
05550 *dst++ = *src++;
05551 } else {
05552 src++;
05553 element->length--;
05554 }
05555 }
05556 item->paddedDataLength = element->length;
05557 if (element->length & 1) {
05558 *dst = ' ';
05559 item->paddedDataLength++;
05560 }
05561 break;
05562 case DCM_TM:
05563 l = (int) element->length;
05564 src = dst = element->d.string;
05565 for (i = 0; i < l; i++) {
05566 if (isdigit(*src) || (*src == '.') || (*src == '-') || (*src == '\\')) {
05567 *dst++ = *src++;
05568 } else {
05569 src++;
05570 element->length--;
05571 }
05572 }
05573 item->paddedDataLength = element->length;
05574 if (element->length & 1) {
05575 *dst = ' ';
05576 item->paddedDataLength++;
05577 }
05578 break;
05579
05580
05581
05582 case DCM_CS:
05583 case DCM_AS:
05584 case DCM_DS:
05585 case DCM_IS:
05586 case DCM_LO:
05587 case DCM_SH:
05588 case DCM_UT:
05589 l = (int) element->length;
05590 src = dst = element->d.string;
05591 for (i = 0; i < l; i++) {
05592 if ((*src == ' ') && !stopFlag) {
05593 src++;
05594 element->length--;
05595 } else {
05596 stopFlag = TRUE;
05597 *dst++ = *src++;
05598 }
05599 }
05600
05601
05602
05603
05604 stopFlag = FALSE;
05605 l = (int) element->length;
05606 p = dst - 1;
05607 for (i = l; (i > 0) && !stopFlag; i--) {
05608 if ((*p == ' ') && !stopFlag) {
05609 p--;
05610 dst--;
05611 element->length--;
05612 } else
05613 stopFlag = TRUE;
05614 }
05615 item->paddedDataLength = element->length;
05616 if (element->length & 1) {
05617 *dst = ' ';
05618 item->paddedDataLength++;
05619 }
05620 break;
05621
05622
05623
05624 case DCM_LT:
05625 case DCM_ST:
05626 l = (int) element->length;
05627 src = element->d.string + l - 1;
05628 for (i = l; (i > 0) && !stopFlag; i--) {
05629 if ((*src == ' ') && !stopFlag) {
05630 src--;
05631 element->length--;
05632 } else
05633 stopFlag = TRUE;
05634 }
05635 item->paddedDataLength = element->length;
05636 if (element->length & 1) {
05637 *++src = ' ';
05638 item->paddedDataLength++;
05639 }
05640 break;
05641 case DCM_PN:
05642
05643
05644
05645 l = (int) element->length;
05646 src = element->d.string + l - 1;
05647 for (i = l; (i > 0) && !stopFlag; i--) {
05648 if ((*src == ' ') && !stopFlag) {
05649 src--;
05650 element->length--;
05651 } else
05652 stopFlag = TRUE;
05653 }
05654
05655
05656
05657 src = dst = element->d.string;
05658 l = element->length;
05659 for (i = 0; i < l;) {
05660 if ((src[i] == ',') || (src[i] == '^')) {
05661 *dst++ = '^';
05662 i++;
05663 while ((i < l) && (src[i] == ' ')) {
05664 element->length--;
05665 i++;
05666 }
05667 } else {
05668 *dst++ = src[i++];
05669 }
05670 }
05671
05672 item->paddedDataLength = element->length;
05673 if (element->length & 1) {
05674 *dst = ' ';
05675 item->paddedDataLength++;
05676 }
05677 break;
05678 case DCM_UI:
05679 if (element->d.string[element->length - 1] == '\0')
05680 element->length--;
05681 if (element->d.string[element->length - 1] == ' ') {
05682 element->d.string[element->length - 1] = '\0';
05683 element->length--;
05684 }
05685 break;
05686 default:
05687 break;
05688 }
05689 }
05690 return DCM_NORMAL;
05691 }
05692
05693
05694
05695
05696
05697
05698
05699
05700
05701
05702
05703
05704
05705
05706
05707
05708
05709
05710
05711
05712
05713
05714
05715
05716
05717
05718
05719
05720
05721
05722
05723
05724
05725
05726
05727 static CONDITION
05728 readFile(char *name, unsigned char *callerBuf, int fd, long size,
05729 off_t fileOffset, int recursionLevel,
05730 unsigned long opt, DCM_OBJECT ** callerObject,
05731 U32 * scannedLength, CTNBOOLEAN * remainOpenFlag,
05732 void *ctx,
05733 CONDITION(*rd) (void *ctx, void *buf, int toRead, int *bytesRead),
05734 CONDITION(*sk) (void *ctx, int offset, int flag))
05735 {
05736 CONDITION
05737 cond;
05738 int
05739 byteOrder;
05740 long
05741 lastGroup = -1,
05742 lastElement = -1;
05743 U32
05744 sequenceLength,
05745 localLength;
05746 PRIVATE_OBJECT
05747 ** object;
05748 PRV_GROUP_ITEM
05749 * groupItem = NULL;
05750 unsigned short
05751 group,
05752 element,
05753 tagGroup,
05754 tagElement;
05755 DCM_ELEMENT
05756 e,
05757 tagE;
05758 CTNBOOLEAN
05759 pixelFlag,
05760 convertFlag = FALSE,
05761 done = FALSE,
05762 knownLength = TRUE,
05763 sequenceDone = FALSE,
05764 createGroupFlag,
05765 explicitVR = FALSE;
05766 unsigned char
05767 buf[8],
05768 *ptr;
05769 int
05770 nBytes;
05771 PRV_ELEMENT_ITEM
05772 * elementItem = NULL;
05773 DCM_OBJECT
05774 * sequenceObject;
05775 DCM_SEQUENCE_ITEM
05776 * sequenceItem;
05777 CTNBOOLEAN
05778 fileFlag = TRUE;
05779
05780 if (callerBuf != NULL) {
05781 ptr = callerBuf;
05782 fileFlag = FALSE;
05783 } else
05784 ptr = buf;
05785
05786 switch (opt & DCM_ORDERMASK) {
05787 case DCM_ORDERNATIVE:
05788 byteOrder = NATIVE_ORDER;
05789 break;
05790 case DCM_ORDERLITTLEENDIAN:
05791 byteOrder = LITTLE_ORDER;
05792 break;
05793 case DCM_EXPLICITLITTLEENDIAN:
05794 byteOrder = LITTLE_ORDER;
05795 explicitVR = TRUE;
05796 break;
05797 case DCM_ORDERBIGENDIAN:
05798 byteOrder = BIG_ORDER;
05799 break;
05800 case DCM_EXPLICITBIGENDIAN:
05801 byteOrder = BIG_ORDER;
05802 explicitVR = TRUE;
05803 break;
05804 default:
05805 byteOrder = NATIVE_ORDER;
05806 break;
05807 }
05808 if ((opt & DCM_CONVERTMASK) == DCM_FORMATCONVERSION)
05809 convertFlag = TRUE;
05810
05811 if (scannedLength != NULL)
05812 *scannedLength = 0;
05813
05814 cond = DCM_CreateObject(callerObject, opt);
05815 if (cond != DCM_NORMAL)
05816 return cond;
05817
05818 object = (PRIVATE_OBJECT **) callerObject;
05819 if (fileFlag)
05820 strcpy((*object)->fileName, name);
05821
05822 (*object)->fd = -1;
05823 (*object)->rd = rd;
05824 (*object)->sk = sk;
05825 (*object)->userCtx = ctx;
05826 if (size == (long) DCM_UNSPECIFIEDLENGTH)
05827 knownLength = FALSE;
05828
05829 if ((fileFlag) && ((opt & DCM_DELETEMASK) == DCM_DELETEONCLOSE) && (recursionLevel == 0))
05830 (*object)->deleteFlag = TRUE;
05831
05832 if (knownLength && (size == 0))
05833 done = TRUE;
05834
05835 while (!done) {
05836
05837 if ((size < 8) && knownLength) {
05838 if (debug)
05839 (void) DCM_DumpElements(callerObject, 0);
05840 (void) DCM_CloseObject(callerObject);
05841 return COND_PushCondition(DCM_ILLEGALSTREAMLENGTH,
05842 DCM_Message(DCM_ILLEGALSTREAMLENGTH), size,
05843 "readFile");
05844 }
05845 if (fileFlag) {
05846 if (fd != -1) {
05847 nBytes = read(fd, buf, 4);
05848 } else {
05849 cond = (*object)->rd((*object)->userCtx, buf, 4, &nBytes);
05850 }
05851
05852 if (nBytes != 4)
05853 return COND_PushCondition(DCM_FILEACCESSERROR,
05854 DCM_Message(DCM_FILEACCESSERROR), name,
05855 "readFile");
05856 ptr = buf;
05857 }
05858 if (knownLength)
05859 size -= 4;
05860 fileOffset += (off_t) 4;
05861 if (scannedLength != NULL)
05862 (*scannedLength) += 4;
05863 (*object)->objectSize += 4;
05864
05865 if (byteOrder == BYTEORDER_SAME) {
05866 GET_SHORT_SAME_ORDER(ptr, group);
05867 GET_SHORT_SAME_ORDER(ptr + 2, element);
05868 e.tag = DCM_MAKETAG(group, element);
05869 } else {
05870 GET_SHORT_REVERSE_ORDER(ptr, group);
05871 GET_SHORT_REVERSE_ORDER(ptr + 2, element);
05872 e.tag = DCM_MAKETAG(group, element);
05873 }
05874 ptr += 4;
05875
05876 if (explicitVR) {
05877 if (fileFlag) {
05878 if (fd != -1) {
05879 nBytes = read(fd, buf, 4);
05880 } else {
05881 cond = (*object)->rd((*object)->userCtx, buf, 4, &nBytes);
05882 }
05883
05884 if (nBytes != 4)
05885 return COND_PushCondition(DCM_FILEACCESSERROR,
05886 DCM_Message(DCM_FILEACCESSERROR), name,
05887 "readFile");
05888 ptr = buf;
05889 }
05890 if (knownLength)
05891 size -= 4;
05892 fileOffset += (off_t) 4;
05893 if (scannedLength != NULL)
05894 (*scannedLength) += 4;
05895 (*object)->objectSize += 4;
05896 if ((strncmp((char *) ptr, "OB", 2) == 0) ||
05897 (strncmp((char *) ptr, "OW", 2) == 0) ||
05898 (strncmp((char *) ptr, "SQ", 2) == 0)) {
05899 } else {
05900 }
05901 } else {
05902
05903 if (fileFlag) {
05904 if (fd != -1) {
05905 nBytes = read(fd, buf, 4);
05906 } else {
05907 cond = (*object)->rd((*object)->userCtx, buf, 4, &nBytes);
05908 }
05909
05910 if (nBytes != 4)
05911 return COND_PushCondition(DCM_FILEACCESSERROR,
05912 DCM_Message(DCM_FILEACCESSERROR), name,
05913 "readFile");
05914 ptr = buf;
05915 }
05916 if (knownLength)
05917 size -= 4;
05918 fileOffset += (off_t) 4;
05919 if (scannedLength != NULL)
05920 (*scannedLength) += 4;
05921 (*object)->objectSize += 4;
05922
05923
05924 if (byteOrder == BYTEORDER_SAME) {
05925 GET_LONG_SAME_ORDER(ptr, e.length);
05926 } else {
05927 GET_LONG_REVERSE_ORDER(ptr, e.length);
05928 }
05929 ptr += 4;
05930 }
05931
05932 if (((e.length & 1) != 0) && (e.length != DCM_UNSPECIFIEDLENGTH)) {
05933 if (debug)
05934 (void) DCM_DumpElements(callerObject, 0);
05935 (void) DCM_CloseObject(callerObject);
05936 return COND_PushCondition(DCM_UNEVENELEMENTLENGTH,
05937 DCM_Message(DCM_UNEVENELEMENTLENGTH),
05938 group, element, e.length,
05939 "readFile");
05940 }
05941 if ((e.length != (U32) DCM_UNSPECIFIEDLENGTH) && (e.length > (U32) size)) {
05942 if (debug)
05943 (void) DCM_DumpElements(callerObject, 0);
05944 (void) DCM_CloseObject(callerObject);
05945 return COND_PushCondition(DCM_ELEMENTLENGTHERROR,
05946 DCM_Message(DCM_ELEMENTLENGTHERROR),
05947 group, element, e.length, size, "readFile");
05948 }
05949 if ((e.tag == DCM_DLMITEMDELIMITATIONITEM) ||
05950 (e.tag == DCM_DLMSEQUENCEDELIMITATIONITEM)) {
05951 return DCM_NORMAL;
05952 }
05953 cond = DCM_LookupElement(&e);
05954 if (cond != DCM_NORMAL)
05955 (void) COND_PopCondition(0);
05956 if (e.representation == DCM_CTX)
05957 ctxSensitiveLookup(object, &e);
05958
05959 if (e.representation == DCM_SQ) {
05960 cond = newElementItem(&e, FALSE, &elementItem);
05961 if (cond != DCM_NORMAL)
05962 return cond;
05963 elementItem->element.d.sq = LST_Create();
05964 if (elementItem->element.d.sq == NULL)
05965 return COND_PushCondition(DCM_LISTFAILURE,
05966 DCM_Message(DCM_LISTFAILURE), "readFile");
05967
05968 localLength = elementItem->element.length;
05969 sequenceDone = (localLength == 0);
05970
05971 while (!sequenceDone) {
05972 if (debug)
05973 fprintf(stderr, "Sequence Length: %d %x\n", localLength,
05974 localLength);
05975 if (fileFlag) {
05976 if (fd != -1) {
05977 nBytes = read(fd, buf, 8);
05978 } else {
05979 cond = (*object)->rd((*object)->userCtx, buf, 8, &nBytes);
05980 }
05981 if (nBytes != 8)
05982 return COND_PushCondition(DCM_FILEACCESSERROR,
05983 DCM_Message(DCM_FILEACCESSERROR), name,
05984 "readFile");
05985 ptr = buf;
05986 }
05987 if (size != (long) DCM_UNSPECIFIEDLENGTH)
05988 size -= 8;
05989 fileOffset += (off_t) 8;
05990 if (scannedLength != NULL)
05991 (*scannedLength) += 8;
05992 (*object)->objectSize += 8;
05993 if (localLength != DCM_UNSPECIFIEDLENGTH)
05994 localLength -= 8;
05995
05996 if (byteOrder == BYTEORDER_SAME) {
05997 GET_SHORT_SAME_ORDER(ptr, tagGroup);
05998 GET_SHORT_SAME_ORDER(ptr + 2, tagElement);
05999 tagE.tag = DCM_MAKETAG(tagGroup, tagElement);
06000 GET_LONG_SAME_ORDER(ptr + 4, tagE.length);
06001 } else {
06002 GET_SHORT_REVERSE_ORDER(ptr, tagGroup);
06003 GET_SHORT_REVERSE_ORDER(ptr + 2, tagElement);
06004 tagE.tag = DCM_MAKETAG(tagGroup, tagElement);
06005 GET_LONG_REVERSE_ORDER(ptr + 4, tagE.length);
06006 }
06007 ptr += 8;
06008 if (debug)
06009 fprintf(stderr, "Sequence item: %4x %4x %d (%x)\n",
06010 tagGroup, tagElement, tagE.length, tagE.length);
06011 if (tagE.tag == DCM_DLMITEM) {
06012
06013
06014
06015
06016
06017 cond = readFile(name,
06018 (fileFlag) ? NULL : ptr,
06019 fd, tagE.length,
06020 fileOffset, recursionLevel + 1, opt,
06021 &sequenceObject, &sequenceLength,
06022 remainOpenFlag, ctx, rd, sk);
06023 if (cond == DCM_NORMAL) {
06024 sequenceItem = CTN_MALLOC(sizeof(*sequenceItem));
06025 if (sequenceItem == NULL)
06026 return COND_PushCondition(DCM_MALLOCFAILURE,
06027 DCM_Message(DCM_MALLOCFAILURE),
06028 sizeof(*sequenceItem), "readFile");
06029
06030 sequenceItem->object = sequenceObject;
06031 cond = LST_Enqueue(&elementItem->element.d.sq,
06032 (void *)sequenceItem);
06033 if (cond != LST_NORMAL)
06034 return COND_PushCondition(DCM_LISTFAILURE,
06035 DCM_Message(DCM_LISTFAILURE), "readFile");
06036 if (size != (long) DCM_UNSPECIFIEDLENGTH)
06037 size -= sequenceLength;
06038 fileOffset += (off_t) sequenceLength;
06039 if (scannedLength != NULL)
06040 *scannedLength += sequenceLength;
06041 (*object)->objectSize += sequenceLength;
06042 if (localLength != DCM_UNSPECIFIEDLENGTH)
06043 localLength -= sequenceLength;
06044 ptr += sequenceLength;
06045 } else
06046 return cond;
06047 } else {
06048 sequenceDone = TRUE;
06049 }
06050 if (localLength == 0)
06051 sequenceDone = TRUE;
06052 }
06053 } else {
06054 pixelFlag = (e.tag == DCM_PXLPIXELDATA);
06055 cond = newElementItem(&e, (pixelFlag == FALSE), &elementItem);
06056 if (cond != DCM_NORMAL) {
06057 (void) DCM_CloseObject(callerObject);
06058 return cond;
06059 }
06060 if (pixelFlag) {
06061 if (fileFlag)
06062 *remainOpenFlag = TRUE;
06063 elementItem->byteOrder = byteOrder;
06064 elementItem->dataOffset = fileOffset;
06065 elementItem->currentOffset = 0;
06066 if (fileFlag)
06067 elementItem->element.d.ot = NULL;
06068 else
06069 elementItem->element.d.ot = (void *) ptr;
06070 if ((*object)->pixelBitsAllocated == 8)
06071 elementItem->element.representation = DCM_OB;
06072 else
06073 elementItem->element.representation = DCM_OW;
06074 if (fileFlag) {
06075 if (fd != -1) {
06076 (void) lseek(fd, (off_t) elementItem->element.length, SEEK_CUR);
06077 } else {
06078 (*object)->sk((*object)->userCtx,
06079 elementItem->element.length, SEEK_CUR);
06080 }
06081 (*object)->fd = fd;
06082 }
06083 } else {
06084 if (fileFlag) {
06085 if (fd != -1) {
06086 nBytes = read(fd, elementItem->element.d.ot,
06087 (int) elementItem->element.length);
06088 } else {
06089 cond = (*object)->rd((*object)->userCtx,
06090 elementItem->element.d.ot,
06091 (long) elementItem->element.length, &nBytes);
06092 }
06093 if (nBytes != (int) elementItem->element.length) {
06094 (void) DCM_CloseObject(callerObject);
06095 return COND_PushCondition(DCM_FILEACCESSERROR,
06096 DCM_Message(DCM_FILEACCESSERROR), name, "readFile");
06097 }
06098 } else {
06099 (void) memcpy(elementItem->element.d.ot, ptr,
06100 elementItem->element.length);
06101 ptr += elementItem->originalDataLength;
06102 }
06103
06104 if( LITTLE_ENDIAN_ARCHITECTURE ){
06105 if (elementItem->element.representation == DCM_AT)
06106 swapATGroupElement(&elementItem->element);
06107 }
06108 if (byteOrder != BYTEORDER_SAME)
06109 swapInPlace(object, &elementItem->element);
06110 if (convertFlag) {
06111 cond = verifyFormat(elementItem);
06112 if (cond != DCM_NORMAL)
06113 return cond;
06114 }
06115 }
06116 if (size != (long) DCM_UNSPECIFIEDLENGTH)
06117 size -= elementItem->originalDataLength;
06118 fileOffset += (off_t) elementItem->originalDataLength;
06119 if (scannedLength != NULL)
06120 (*scannedLength) += elementItem->originalDataLength;
06121
06122 elementItem->paddedDataLength = elementItem->element.length;
06123 if (elementItem->paddedDataLength & 1)
06124 elementItem->paddedDataLength += 1;
06125 (*object)->objectSize += elementItem->paddedDataLength;
06126 }
06127
06128 computeVM(object, &elementItem->element);
06129
06130 if ((long) DCM_TAG_GROUP(e.tag) == lastGroup) {
06131 if ((long) DCM_TAG_ELEMENT(e.tag) <= lastElement)
06132 return COND_PushCondition(DCM_ELEMENTOUTOFORDER,
06133 DCM_Message(DCM_ELEMENTOUTOFORDER),
06134 group, element, "readFile");
06135 } else if ((long) DCM_TAG_GROUP(e.tag) > lastGroup) {
06136 } else {
06137 return COND_PushCondition(DCM_ELEMENTOUTOFORDER,
06138 DCM_Message(DCM_ELEMENTOUTOFORDER), group, element,
06139 "readFile");
06140 }
06141 lastGroup = (long) group;
06142 lastElement = (long) element;
06143
06144 if (groupItem == NULL)
06145 createGroupFlag = TRUE;
06146 else if (groupItem->group != group)
06147 createGroupFlag = TRUE;
06148 else
06149 createGroupFlag = FALSE;
06150
06151 if (createGroupFlag == TRUE) {
06152 groupItem = CTN_MALLOC(sizeof(*groupItem));
06153 if (groupItem == NULL) {
06154 (void) DCM_CloseObject(callerObject);
06155 return COND_PushCondition(DCM_ELEMENTCREATEFAILED,
06156 DCM_Message(DCM_ELEMENTCREATEFAILED),
06157 "readFile",
06158 group, 0xffff, sizeof(*groupItem));
06159 }
06160 groupItem->group = group;
06161 groupItem->baseLength = 0;
06162 groupItem->longVRAttributes = 0;
06163 groupItem->elementList = LST_Create();
06164 if (groupItem->elementList == NULL) {
06165 (void) DCM_CloseObject(callerObject);
06166 return COND_PushCondition(DCM_LISTFAILURE,
06167 DCM_Message(DCM_LISTFAILURE),
06168 "readFile");
06169 }
06170 if (LST_Enqueue(&(*object)->groupList, (void *)groupItem) != LST_NORMAL) {
06171 (void) DCM_CloseObject(callerObject);
06172 return COND_PushCondition(DCM_LISTFAILURE,
06173 DCM_Message(DCM_LISTFAILURE),
06174 "readFile");
06175 }
06176 }
06177 if (element != 0x0000)
06178 groupItem->baseLength += 8 + elementItem->paddedDataLength;
06179 if ((element == 0x0000) && ((*object)->groupLengthFlag == FALSE)) {
06180 CTN_FREE(elementItem);
06181 } else {
06182 cond = LST_Enqueue(&groupItem->elementList, (void *)elementItem);
06183 if (cond != LST_NORMAL) {
06184 (void) DCM_CloseObject(callerObject);
06185 return COND_PushCondition(DCM_LISTFAILURE,
06186 DCM_Message(DCM_LISTFAILURE),
06187 "readFile");
06188 }
06189 cond = updateObjectType(object, &elementItem->element);
06190
06191 cond = updateSpecialElements(object, elementItem);
06192 }
06193
06194 if (size == 0)
06195 done = TRUE;
06196
06197 #ifdef DEBUG
06198 if (debug) {
06199
06200 (void) fprintf(stderr, "Address: %px Group %2x, element %2x, length %ld ",
06201 elementItem,
06202 DCM_TAG_GROUP(elementItem->element.tag),
06203 DCM_TAG_ELEMENT(elementItem->element.tag),
06204 elementItem->element.length);
06205
06206 (void) fprintf(stderr, "Object size: %d\n", (*object)->objectSize);
06207 }
06208 #endif
06209 }
06210
06211 groupItem = (void *)LST_Head(&(*object)->groupList);
06212 if (groupItem != NULL) {
06213 (void) LST_Position(&(*object)->groupList, (void *)groupItem);
06214 while (groupItem != NULL) {
06215 elementItem = (void *)LST_Head(&groupItem->elementList);
06216 if (elementItem != NULL) {
06217 if (DCM_TAG_ELEMENT(elementItem->element.tag) == 0x0000) {
06218 *elementItem->element.d.ul = groupItem->baseLength;
06219 }
06220 }
06221 groupItem = (void *)LST_Next(&(*object)->groupList);
06222 }
06223 }
06224 return DCM_NORMAL;
06225 }
06226
06227 static CONDITION
06228 readPreamble(const char *name, unsigned char **ptr, int fd, U32 * size,
06229 off_t * fileOffset, CTNBOOLEAN knownLength,
06230 PRIVATE_OBJECT ** object, U32 * scannedLength)
06231 {
06232 int nBytes,
06233 tmp;
06234 CONDITION cond;
06235 char label[4];
06236
06237 if (*size == 0)
06238 return DCM_STREAMCOMPLETE;
06239
06240 if ((*size < DCM_PREAMBLELENGTH + 4) && knownLength) {
06241 if (debug)
06242 (void) DCM_DumpElements((DCM_OBJECT **) object, 0);
06243 (void) DCM_CloseObject((DCM_OBJECT **) object);
06244 return COND_PushCondition(DCM_ILLEGALSTREAMLENGTH,
06245 DCM_Message(DCM_ILLEGALSTREAMLENGTH), *size,
06246 "readPreamble");
06247 }
06248 if (*ptr == NULL) {
06249 if (fd != -1) {
06250 nBytes = read(fd, (*object)->preamble, DCM_PREAMBLELENGTH);
06251 nBytes += read(fd, label, sizeof(label));
06252 } else {
06253 cond = (*object)->rd((*object)->userCtx, (*object)->preamble,
06254 DCM_PREAMBLELENGTH, &nBytes);
06255 cond = (*object)->rd((*object)->userCtx, label,
06256 sizeof(label), &tmp);
06257 nBytes += tmp;
06258 }
06259
06260 if (nBytes != DCM_PREAMBLELENGTH + sizeof(label))
06261 return COND_PushCondition(DCM_FILEACCESSERROR,
06262 DCM_Message(DCM_FILEACCESSERROR), name,
06263 "readPreamble");
06264 } else {
06265 (void) memcpy((*object)->preamble, *ptr, DCM_PREAMBLELENGTH);
06266 (void) memcpy(label, (*ptr) + DCM_PREAMBLELENGTH, sizeof(label));
06267 }
06268
06269 if (knownLength)
06270 *size -= DCM_PREAMBLELENGTH + sizeof(label);
06271 *fileOffset += (off_t) DCM_PREAMBLELENGTH + sizeof(label);
06272 if (*ptr != NULL)
06273 *ptr += DCM_PREAMBLELENGTH + sizeof(label);
06274 (*object)->objectSize += DCM_PREAMBLELENGTH + sizeof(label);
06275
06276 if (strncmp(label, "DICM", 4) != 0)
06277 return 0;
06278
06279 (*object)->preambleFlag = TRUE;
06280 return DCM_NORMAL;
06281 }
06282
06283
06284 static CONDITION
06285 readGroupElement(const char *name, unsigned char **ptr, int fd, U32 * size,
06286 off_t * fileOffset, CTNBOOLEAN knownLength, int byteOrder,
06287 CTNBOOLEAN explicitVR, CTNBOOLEAN acceptVRMismatch,
06288 PRIVATE_OBJECT ** object, U32 * scannedLength,
06289 DCM_ELEMENT * e)
06290 {
06291 unsigned char *localPtr;
06292 unsigned char buf[4];
06293 int nBytes;
06294 CONDITION cond;
06295 unsigned short group,
06296 element;
06297
06298 if (*size == 0)
06299 return DCM_STREAMCOMPLETE;
06300
06301 if ((*size < 4) && knownLength) {
06302 if (debug)
06303 (void) DCM_DumpElements((DCM_OBJECT **) object, 0);
06304 (void) DCM_CloseObject((DCM_OBJECT **) object);
06305 return COND_PushCondition(DCM_ILLEGALSTREAMLENGTH,
06306 DCM_Message(DCM_ILLEGALSTREAMLENGTH), *size,
06307 "readFile");
06308 }
06309 if (*ptr == NULL) {
06310 if (fd != -1) {
06311 nBytes = read(fd, buf, 4);
06312 } else {
06313 cond = (*object)->rd((*object)->userCtx, buf, 4, &nBytes);
06314 }
06315
06316 if (nBytes != 4)
06317 return COND_PushCondition(DCM_FILEACCESSERROR,
06318 DCM_Message(DCM_FILEACCESSERROR), name,
06319 "readGroupElement");
06320 localPtr = buf;
06321 } else {
06322 localPtr = *ptr;
06323 }
06324
06325 if (knownLength)
06326 *size -= 4;
06327 *fileOffset += (off_t) 4;
06328 if (scannedLength != NULL)
06329 (*scannedLength) += 4;
06330 (*object)->objectSize += 4;
06331
06332 if (byteOrder == BYTEORDER_SAME) {
06333 GET_SHORT_SAME_ORDER(localPtr, group);
06334 GET_SHORT_SAME_ORDER(localPtr + 2, element);
06335 e->tag = DCM_MAKETAG(group, element);
06336 } else {
06337 GET_SHORT_REVERSE_ORDER(localPtr, group);
06338 GET_SHORT_REVERSE_ORDER(localPtr + 2, element);
06339 e->tag = DCM_MAKETAG(group, element);
06340 }
06341 if (*ptr != NULL)
06342 *ptr += 4;
06343
06344 if (debug)
06345 fprintf(stderr, "%04x %04x ", group, element);
06346
06347 cond = DCM_LookupElement(e);
06348 if (cond != DCM_NORMAL)
06349 (void) COND_PopCondition(0);
06350 if (e->representation == DCM_CTX)
06351 ctxSensitiveLookup(object, e);
06352
06353 return DCM_NORMAL;
06354 }
06355
06356 static CONDITION
06357 readVRLength(const char *name, unsigned char **ptr, int fd, U32 * size,
06358 off_t * fileOffset,
06359 CTNBOOLEAN knownLength, int byteOrder, CTNBOOLEAN explicitVR,
06360 CTNBOOLEAN acceptVRMismatch,
06361 PRIVATE_OBJECT ** object, U32 * scannedLength, DCM_ELEMENT * e)
06362 {
06363 unsigned char *localPtr;
06364 unsigned char buf[4];
06365 char vrCode[3];
06366 VRMAP *vrPtr;
06367 int nBytes;
06368 CONDITION cond;
06369 CTNBOOLEAN calculatedLength = FALSE;
06370
06371 ENTRY("readVRLength") ;
06372
06373 if (*size == 0)
06374 RETURN( DCM_STREAMCOMPLETE );
06375
06376 if ((*size < 4) && knownLength) {
06377 if (debug)
06378 (void) DCM_DumpElements((DCM_OBJECT **) object, 0);
06379 (void) DCM_CloseObject((DCM_OBJECT **) object);
06380 RETURN( COND_PushCondition(DCM_ILLEGALSTREAMLENGTH,
06381 DCM_Message(DCM_ILLEGALSTREAMLENGTH), *size,
06382 "readVRLength") );
06383 }
06384 if (*ptr == NULL) {
06385 if (fd != -1) {
06386 nBytes = read(fd, buf, 4);
06387 } else {
06388 cond = (*object)->rd((*object)->userCtx, buf, 4, &nBytes);
06389 }
06390
06391 if (nBytes != 4)
06392 RETURN( COND_PushCondition(DCM_FILEACCESSERROR,
06393 DCM_Message(DCM_FILEACCESSERROR), name,
06394 "readVRLength") ) ;
06395 localPtr = buf;
06396 } else
06397 localPtr = *ptr;
06398
06399 if (knownLength)
06400 *size -= 4;
06401 *fileOffset += (off_t) 4;
06402 if (scannedLength != NULL)
06403 (*scannedLength) += 4;
06404 (*object)->objectSize += 4;
06405
06406 e->length = 0;
06407 if (e->representation == DCM_DLM) {
06408 explicitVR = FALSE;
06409 }
06410 if (explicitVR) {
06411 vrCode[0] = buf[0];
06412 vrCode[1] = buf[1];
06413 vrCode[2] = '\0';
06414 vrPtr = lookupVRCode(vrCode);
06415 if (vrPtr == NULL){
06416 if( rwc_err ){
06417 fprintf(stderr,"** DICOM ERROR: unknown VR code %s in element (%04x,%04x)\n",
06418 vrCode,DCM_TAG_GROUP(e->tag), DCM_TAG_ELEMENT(e->tag) ) ; rwc_err-- ;
06419 }
06420 RETURN( COND_PushCondition(DCM_UNRECOGNIZEDVRCODE,
06421 DCM_Message(DCM_UNRECOGNIZEDVRCODE), vrCode,
06422 "readVRLength") );
06423 }
06424
06425 if (vrPtr->representation != e->representation) {
06426 if (vrPtr->representation == DCM_OB) {
06427
06428
06429
06430
06431 e->representation = vrPtr->representation;
06432 } else if (e->representation == DCM_UN ||
06433 e->representation == DCM_CTX ||
06434 e->representation == DCM_RET ||
06435 vrPtr->representation == DCM_OW ||
06436 acceptVRMismatch) {
06437 e->representation = vrPtr->representation;
06438 } else {
06439 #if 0
06440 if (e->tag != DCM_PXLPIXELDATA){
06441 STATUS("VR mismatch") ;
06442 RETURN( COND_PushCondition(DCM_VRMISMATCH,
06443 DCM_Message(DCM_VRMISMATCH), vrCode, e->tag));
06444 }
06445 #else
06446 if( rwc_err ){
06447 fprintf(stderr,"++ DICOM WARNING: VR mismatch in element (%04x,%04x)\n",
06448 DCM_TAG_GROUP(e->tag), DCM_TAG_ELEMENT(e->tag) ) ; rwc_err-- ;
06449 }
06450 e->representation = vrPtr->representation;
06451 #endif
06452 }
06453 }
06454 if (vrPtr->representation != DCM_OW &&
06455 vrPtr->representation != DCM_OB &&
06456 vrPtr->representation != DCM_UN &&
06457 vrPtr->representation != DCM_UT &&
06458 vrPtr->representation != DCM_SQ) {
06459 unsigned short shortLength;
06460 if (byteOrder == BYTEORDER_SAME) {
06461 GET_SHORT_SAME_ORDER(localPtr + 2, shortLength);
06462 } else {
06463 GET_SHORT_REVERSE_ORDER(localPtr + 2, shortLength);
06464 }
06465 e->length = shortLength;
06466 if (*ptr != NULL)
06467 *ptr += 4;
06468 calculatedLength = TRUE;
06469 } else {
06470 if ((*size < 4) && knownLength) {
06471 if (debug)
06472 (void) DCM_DumpElements((DCM_OBJECT **) object, 0);
06473 (void) DCM_CloseObject((DCM_OBJECT **) object);
06474 RETURN( COND_PushCondition(DCM_ILLEGALSTREAMLENGTH,
06475 DCM_Message(DCM_ILLEGALSTREAMLENGTH), *size,
06476 "readVRLength"));
06477 }
06478 if (*ptr == NULL) {
06479 if (fd != -1) {
06480 nBytes = read(fd, buf, 4);
06481 } else {
06482 cond = (*object)->rd((*object)->userCtx, buf, 4, &nBytes);
06483 }
06484
06485 if (nBytes != 4)
06486 RETURN( COND_PushCondition(DCM_FILEACCESSERROR,
06487 DCM_Message(DCM_FILEACCESSERROR), name,
06488 "readVRLength"));
06489 localPtr = buf;
06490 } else
06491 localPtr = *ptr;
06492
06493 if (knownLength)
06494 *size -= 4;
06495 *fileOffset += (off_t) 4;
06496 if (scannedLength != NULL)
06497 (*scannedLength) += 4;
06498 (*object)->objectSize += 4;
06499 }
06500 }
06501 if (!calculatedLength) {
06502 if (byteOrder == BYTEORDER_SAME) {
06503 GET_LONG_SAME_ORDER(localPtr, e->length);
06504 } else {
06505 GET_LONG_REVERSE_ORDER(localPtr, e->length);
06506 }
06507 if (*ptr != NULL)
06508 *ptr += 4;
06509 }
06510 if (debug) {
06511 char localVR[10];
06512 mapVRtoASCII(e->representation, localVR);
06513 fprintf(stderr, "%2s %6d %06x %s\n", localVR, e->length,
06514 (unsigned int)*fileOffset, e->description);
06515 }
06516 if (((e->length & 1) != 0) && (e->length != DCM_UNSPECIFIEDLENGTH)) {
06517 if (debug)
06518 (void) DCM_DumpElements((DCM_OBJECT **) object, 0);
06519 (void) DCM_CloseObject((DCM_OBJECT **) object);
06520 if( rwc_err ){
06521 fprintf(stderr,"** DICOM ERROR: illegal odd length=%d in element (%04x,%04x)\n",
06522 e->length,DCM_TAG_GROUP(e->tag), DCM_TAG_ELEMENT(e->tag) ) ; rwc_err-- ;
06523 }
06524 RETURN( COND_PushCondition(DCM_UNEVENELEMENTLENGTH,
06525 DCM_Message(DCM_UNEVENELEMENTLENGTH),
06526 DCM_TAG_GROUP(e->tag), DCM_TAG_ELEMENT(e->tag),
06527 e->length, "readFile"));
06528 }
06529 if ((e->length != (U32) DCM_UNSPECIFIEDLENGTH) && (e->length > (U32) (*size))) {
06530 if (debug)
06531 (void) DCM_DumpElements((DCM_OBJECT **) object, 0);
06532 (void) DCM_CloseObject((DCM_OBJECT **) object);
06533 if( rwc_err ){
06534 fprintf(stderr,"** DICOM ERROR: oversize length=%d in element (%04x,%04x)\n",
06535 e->length,DCM_TAG_GROUP(e->tag), DCM_TAG_ELEMENT(e->tag) ) ; rwc_err-- ;
06536 }
06537 RETURN( COND_PushCondition(DCM_ELEMENTLENGTHERROR,
06538 DCM_Message(DCM_ELEMENTLENGTHERROR),
06539 DCM_TAG_GROUP(e->tag), DCM_TAG_ELEMENT(e->tag),
06540 e->length, *size, "readFile"));
06541 }
06542 RETURN( DCM_NORMAL);
06543 }
06544
06545 static CONDITION
06546 readSequence(const char *name, unsigned char **ptr, int fd, U32 * size,
06547 off_t * fileOffset, int recursionLevel, unsigned long opt,
06548 int byteOrder, CTNBOOLEAN explicitVR, CTNBOOLEAN acceptVRMismatch,
06549 CTNBOOLEAN fileFlag, CTNBOOLEAN * remainOpenFlag,
06550 CTNBOOLEAN convertFlag, PRIVATE_OBJECT ** object,
06551 U32 * scannedLength, DCM_ELEMENT * e,
06552 PRV_ELEMENT_ITEM ** elementItem)
06553 {
06554 CTNBOOLEAN knownLength = TRUE;
06555 CONDITION cond;
06556 U32 sequenceLength;
06557
06558 U32 localLength;
06559 CTNBOOLEAN sequenceDone;
06560 DCM_ELEMENT tagE;
06561 DCM_OBJECT
06562 * sequenceObject;
06563 DCM_SEQUENCE_ITEM *sequenceItem;
06564 CONDITION flag;
06565 unsigned char *localPtr;
06566 off_t itemTagOffset;
06567
06568 if (*size == (long) DCM_UNSPECIFIEDLENGTH)
06569 knownLength = FALSE;
06570
06571 cond = newElementItem(e, FALSE, elementItem);
06572 if (cond != DCM_NORMAL)
06573 return cond;
06574 (*elementItem)->element.d.sq = LST_Create();
06575 if ((*elementItem)->element.d.sq == NULL)
06576 return COND_PushCondition(DCM_LISTFAILURE,
06577 DCM_Message(DCM_LISTFAILURE), "readSequence");
06578
06579 localLength = (*elementItem)->element.length;
06580 sequenceDone = (localLength == 0);
06581
06582 while (!sequenceDone) {
06583 if (debug)
06584 fprintf(stderr, "Sequence Length: %d %x\n", localLength,
06585 localLength);
06586
06587 sequenceLength = 0;
06588 itemTagOffset = *fileOffset;
06589
06590 flag = readGroupElement(name, ptr, fd, &localLength, fileOffset, knownLength,
06591 byteOrder, explicitVR, acceptVRMismatch, object, &sequenceLength, &tagE);
06592 if (flag == DCM_STREAMCOMPLETE)
06593 break;
06594 else if (flag != DCM_NORMAL)
06595 return flag;
06596
06597 flag = readVRLength(name, ptr, fd, &localLength, fileOffset, knownLength,
06598 byteOrder, explicitVR, acceptVRMismatch, object,
06599 &sequenceLength, &tagE);
06600 if (flag != DCM_NORMAL)
06601 return flag;
06602
06603 if (*size != (long) DCM_UNSPECIFIEDLENGTH)
06604 *size -= sequenceLength;
06605 if (scannedLength != NULL)
06606 *scannedLength += sequenceLength;
06607
06608 sequenceLength = 0;
06609
06610
06611 if (debug)
06612 fprintf(stderr, "Sequence item: %4x %4x %d (%x)\n",
06613 DCM_TAG_GROUP(tagE.tag),
06614 DCM_TAG_ELEMENT(tagE.tag), tagE.length, tagE.length);
06615 if (tagE.tag == DCM_DLMITEM) {
06616 localPtr = *ptr;
06617 cond = readFile1(name,
06618 localPtr,
06619 fd, tagE.length,
06620 fileOffset, recursionLevel + 1, opt,
06621 object, &sequenceObject, &sequenceLength,
06622 remainOpenFlag, (*object)->userCtx, (*object)->rd,
06623 (*object)->sk);
06624 *ptr = localPtr;
06625 if (cond == DCM_NORMAL) {
06626 sequenceItem = CTN_MALLOC(sizeof(*sequenceItem));
06627 if (sequenceItem == NULL)
06628 return COND_PushCondition(DCM_MALLOCFAILURE,
06629 DCM_Message(DCM_MALLOCFAILURE),
06630 sizeof(*sequenceItem), "readFile");
06631
06632 ((PRIVATE_OBJECT *) sequenceObject)->offset = itemTagOffset;
06633 sequenceItem->object = sequenceObject;
06634 cond = LST_Enqueue(&(*elementItem)->element.d.sq,
06635 (void *)sequenceItem);
06636 if (cond != LST_NORMAL)
06637 return COND_PushCondition(DCM_LISTFAILURE,
06638 DCM_Message(DCM_LISTFAILURE), "readFile");
06639 if (*size != (long) DCM_UNSPECIFIEDLENGTH)
06640 *size -= sequenceLength;
06641 if (scannedLength != NULL)
06642 *scannedLength += sequenceLength;
06643 (*object)->objectSize += sequenceLength;
06644 if (localLength != DCM_UNSPECIFIEDLENGTH)
06645 localLength -= sequenceLength;
06646 } else
06647 return cond;
06648 } else {
06649 sequenceDone = TRUE;
06650 }
06651 if (localLength == 0)
06652 sequenceDone = TRUE;
06653 }
06654 return DCM_NORMAL;
06655 }
06656
06657 static CONDITION
06658 scanCompressedPixels(char *name, unsigned char **ptr, int fd, U32 * size,
06659 off_t * fileOffset, int recursionLevel, unsigned long opt,
06660 int byteOrder, CTNBOOLEAN explicitVR,
06661 CTNBOOLEAN acceptVRMismatch,
06662 CTNBOOLEAN fileFlag, CTNBOOLEAN * remainOpenFlag,
06663 CTNBOOLEAN convertFlag, PRIVATE_OBJECT ** object,
06664 U32 * scannedLength, DCM_ELEMENT * e,
06665 PRV_ELEMENT_ITEM ** elementItem)
06666 {
06667 CTNBOOLEAN knownLength = TRUE;
06668 U32 sequenceLength;
06669 U32 scannedBytes = 0;
06670
06671 U32 localLength;
06672 CTNBOOLEAN sequenceDone;
06673 DCM_ELEMENT tagE;
06674 CONDITION flag;
06675 unsigned char *localPtr;
06676
06677 if (*size == (long) DCM_UNSPECIFIEDLENGTH)
06678 knownLength = FALSE;
06679
06680 localLength = (*elementItem)->element.length;
06681 sequenceDone = (localLength == 0);
06682
06683 while (!sequenceDone) {
06684 sequenceLength = 0;
06685 flag = readGroupElement(name, ptr, fd, &localLength, fileOffset,
06686 FALSE, byteOrder, explicitVR, acceptVRMismatch,
06687 object, &sequenceLength, &tagE);
06688 if (flag == DCM_STREAMCOMPLETE)
06689 break;
06690 else if (flag != DCM_NORMAL)
06691 return flag;
06692
06693 flag = readVRLength(name, ptr, fd, &localLength, fileOffset, knownLength,
06694 byteOrder, explicitVR, acceptVRMismatch, object,
06695 &sequenceLength, &tagE);
06696 if (flag != DCM_NORMAL)
06697 return flag;
06698
06699 if (*size != (long) DCM_UNSPECIFIEDLENGTH)
06700 *size -= sequenceLength;
06701 if (scannedLength != NULL)
06702 *scannedLength += sequenceLength;
06703 scannedBytes += sequenceLength;
06704
06705 if (debug)
06706 fprintf(stderr, "Sequence item: %4x %4x %d (%x)\n",
06707 DCM_TAG_GROUP(tagE.tag),
06708 DCM_TAG_ELEMENT(tagE.tag), tagE.length, tagE.length);
06709 if (tagE.tag == DCM_DLMITEM) {
06710 localPtr = *ptr;
06711 if (tagE.length != 0) {
06712 lseek(fd, tagE.length, SEEK_CUR);
06713 *fileOffset += tagE.length;
06714 if (*size != (long) DCM_UNSPECIFIEDLENGTH)
06715 *size -= tagE.length;
06716 if (scannedLength != NULL)
06717 *scannedLength += tagE.length;
06718 }
06719 } else {
06720 sequenceDone = TRUE;
06721 }
06722 if (localLength == 0)
06723 sequenceDone = TRUE;
06724
06725 if (debug)
06726 fprintf(stderr, "Scanned Bytes: %d\n", scannedBytes);
06727 }
06728 if ((scannedBytes & 1) != 0) {
06729 lseek(fd, 1, SEEK_CUR);
06730 *fileOffset += 1;
06731 if (*size != (long) DCM_UNSPECIFIEDLENGTH)
06732 *size -= 1;
06733 }
06734 return DCM_NORMAL;
06735 }
06736
06737 static CONDITION
06738 readData(const char *name, unsigned char **ptr, int fd, U32 * size,
06739 off_t * fileOffset,
06740 CTNBOOLEAN knownLength, int byteOrder, CTNBOOLEAN explicitVR,
06741 CTNBOOLEAN acceptVRMismatch,
06742 CTNBOOLEAN fileFlag, CTNBOOLEAN * remainOpenFlag,
06743 CTNBOOLEAN convertFlag, PRIVATE_OBJECT ** object,
06744 U32 * scannedLength, DCM_ELEMENT * e,
06745 PRV_ELEMENT_ITEM ** elementItem)
06746 {
06747 CTNBOOLEAN pixelFlag;
06748 CONDITION cond;
06749 int nBytes;
06750
06751 pixelFlag = (e->tag == DCM_PXLPIXELDATA);
06752 cond = newElementItem(e, (pixelFlag == FALSE), elementItem);
06753 if (cond != DCM_NORMAL) {
06754 (void) DCM_CloseObject((DCM_OBJECT **) object);
06755 return cond;
06756 }
06757 (*elementItem)->element.data_offset = 0 ;
06758 if (pixelFlag) {
06759 if (fileFlag)
06760 *remainOpenFlag = TRUE;
06761 (*elementItem)->byteOrder = byteOrder;
06762 (*elementItem)->dataOffset = *fileOffset;
06763 (*elementItem)->currentOffset = 0;
06764 (*elementItem)->element.d.ot = NULL;
06765 if ((*object)->pixelBitsAllocated == 8)
06766 (*elementItem)->element.representation = DCM_OB;
06767 else
06768 (*elementItem)->element.representation = DCM_OW;
06769 if (fileFlag) {
06770 if (fd != -1) {
06771 if ((*elementItem)->element.length != DCM_UNSPECIFIEDLENGTH){
06772
06773 pxl_off = lseek( fd , 0 , SEEK_CUR ) ;
06774 pxl_len = (*elementItem)->element.length ;
06775
06776 (*elementItem)->element.data_offset = pxl_off ;
06777
06778 (void) lseek(fd,
06779 (off_t) (*elementItem)->element.length,
06780 SEEK_CUR);
06781 } else {
06782 U32 l1 = 0;
06783 U32 s1;
06784 off_t f1 = 0;
06785
06786 s1 = *size;
06787 scanCompressedPixels("", ptr, fd,
06788 &s1,
06789 &f1,
06790 0, 0,
06791 byteOrder, explicitVR,
06792 acceptVRMismatch,
06793 fileFlag, remainOpenFlag,
06794 convertFlag, object,
06795 &l1,
06796 e, elementItem);
06797 (*elementItem)->originalDataLength = l1;
06798 (*elementItem)->paddedDataLength = l1;
06799 }
06800 } else {
06801 (*object)->sk((*object)->userCtx,
06802 (*elementItem)->element.length, SEEK_CUR);
06803 }
06804 (*object)->fd = fd;
06805 }
06806 } else {
06807 if (fileFlag) {
06808 if (fd != -1) {
06809 (*elementItem)->element.data_offset = lseek(fd,0,SEEK_CUR);
06810 nBytes = read(fd, (*elementItem)->element.d.ot,
06811 (int) (*elementItem)->element.length);
06812 } else {
06813 cond = (*object)->rd((*object)->userCtx,
06814 (*elementItem)->element.d.ot,
06815 (long) (*elementItem)->element.length, &nBytes);
06816 }
06817 if (nBytes != (int) (*elementItem)->element.length) {
06818 (void) DCM_CloseObject((DCM_OBJECT **) object);
06819 return COND_PushCondition(DCM_FILEACCESSERROR,
06820 DCM_Message(DCM_FILEACCESSERROR), name, "readFile");
06821 }
06822 } else {
06823 (void) memcpy((*elementItem)->element.d.ot, ptr,
06824 (*elementItem)->element.length);
06825 ptr += (*elementItem)->originalDataLength;
06826 }
06827 if( LITTLE_ENDIAN_ARCHITECTURE ){
06828 if ((*elementItem)->element.representation == DCM_AT)
06829 swapATGroupElement(&(*elementItem)->element);
06830 }
06831 if (byteOrder != BYTEORDER_SAME)
06832 swapInPlace(object, &(*elementItem)->element);
06833 if (convertFlag) {
06834 cond = verifyFormat(*elementItem);
06835 if (cond != DCM_NORMAL)
06836 return cond;
06837 }
06838 }
06839 if (*size != (long) DCM_UNSPECIFIEDLENGTH)
06840 *size -= (*elementItem)->originalDataLength;
06841 *fileOffset += (off_t) (*elementItem)->originalDataLength;
06842 if (scannedLength != NULL)
06843 (*scannedLength) += (*elementItem)->originalDataLength;
06844
06845 if ((*elementItem)->element.length != DCM_UNSPECIFIEDLENGTH) {
06846 (*elementItem)->paddedDataLength = (*elementItem)->element.length;
06847 }
06848 if (((*elementItem)->paddedDataLength != DCM_UNSPECIFIEDLENGTH) &&
06849 ((*elementItem)->paddedDataLength & 1) )
06850 (*elementItem)->paddedDataLength += 1;
06851 (*object)->objectSize += (*elementItem)->paddedDataLength;
06852
06853 return DCM_NORMAL;
06854
06855 }
06856
06857 static CONDITION
06858 checkAttributeOrder(DCM_ELEMENT * e, long *lastGroup, long *lastElement,
06859 CTNBOOLEAN allowRepeatElements)
06860 {
06861 unsigned short group;
06862 unsigned short element;
06863
06864 group = DCM_TAG_GROUP(e->tag);
06865 element = DCM_TAG_ELEMENT(e->tag);
06866
06867 if ((long) group == *lastGroup) {
06868 if (((long) element == *lastElement) && allowRepeatElements) {
06869 return DCM_REPEATEDELEMENT;
06870 }
06871 if ((long) element <= *lastElement)
06872 return COND_PushCondition(DCM_ELEMENTOUTOFORDER,
06873 DCM_Message(DCM_ELEMENTOUTOFORDER),
06874 group, element, "checkAttributeOrder");
06875 } else if ((long) group > *lastGroup) {
06876 } else {
06877 return COND_PushCondition(DCM_ELEMENTOUTOFORDER,
06878 DCM_Message(DCM_ELEMENTOUTOFORDER),
06879 group, element, "checkAttributeOrder");
06880 }
06881 *lastGroup = (long) group;
06882 *lastElement = (long) element;
06883
06884 return DCM_NORMAL;
06885 }
06886
06887 static CONDITION
06888 handleGroupItem(PRIVATE_OBJECT ** obj, PRV_GROUP_ITEM ** groupItem,
06889 unsigned short group)
06890 {
06891 CTNBOOLEAN createGroupFlag;
06892
06893 if (*groupItem == NULL)
06894 createGroupFlag = TRUE;
06895 else if ((*groupItem)->group != group)
06896 createGroupFlag = TRUE;
06897 else
06898 createGroupFlag = FALSE;
06899
06900 if (createGroupFlag == TRUE) {
06901 *groupItem = CTN_MALLOC(sizeof(**groupItem));
06902 if (*groupItem == NULL) {
06903 (void) DCM_CloseObject((DCM_OBJECT **) obj);
06904 return COND_PushCondition(DCM_ELEMENTCREATEFAILED,
06905 DCM_Message(DCM_ELEMENTCREATEFAILED),
06906 "handleGroupItem",
06907 group, 0xffff, sizeof(**groupItem));
06908 }
06909 (*groupItem)->group = group;
06910 (*groupItem)->baseLength = 0;
06911 (*groupItem)->longVRAttributes = 0;
06912 (*groupItem)->elementList = LST_Create();
06913 if ((*groupItem)->elementList == NULL) {
06914 (void) DCM_CloseObject((DCM_OBJECT **) obj);
06915 return COND_PushCondition(DCM_LISTFAILURE,
06916 DCM_Message(DCM_LISTFAILURE),
06917 "handleGroupItem");
06918 }
06919 if (LST_Enqueue(&(*obj)->groupList, (void *)*groupItem) != LST_NORMAL) {
06920 (void) DCM_CloseObject((DCM_OBJECT **) obj);
06921 return COND_PushCondition(DCM_LISTFAILURE,
06922 DCM_Message(DCM_LISTFAILURE),
06923 "handleGroupItem");
06924 }
06925 }
06926 return DCM_NORMAL;
06927 }
06928
06929 static CONDITION
06930 readFile1(const char *name, unsigned char *callerBuf, int fd, U32 size,
06931 off_t * fileOffset, int recursionLevel,
06932 unsigned long opt, PRIVATE_OBJECT ** parentObject,
06933 DCM_OBJECT ** callerObject,
06934 U32 * scannedLength, CTNBOOLEAN * remainOpenFlag,
06935 void *ctx,
06936 CONDITION(*rd) (void *ctx, void *buf, int toRead, int *bytesRead),
06937 CONDITION(*sk) (void *ctx, int offset, int flag))
06938 {
06939 CONDITION
06940 cond;
06941 int
06942 byteOrder;
06943 long
06944 lastGroup = -1,
06945 lastElement = -1;
06946 U32
06947 sequenceLength,
06948 scannedSequenceLength;
06949 PRIVATE_OBJECT
06950 ** object;
06951 PRV_GROUP_ITEM
06952 * groupItem = NULL;
06953 DCM_ELEMENT
06954 e;
06955 CTNBOOLEAN
06956 convertFlag = FALSE,
06957 done = FALSE,
06958 knownLength = TRUE,
06959 explicitVR = FALSE,
06960 acceptVRMismatch = FALSE,
06961 part10Flag = FALSE;
06962 unsigned char
06963 *ptr = NULL;
06964 PRV_ELEMENT_ITEM
06965 * elementItem = NULL;
06966 CTNBOOLEAN
06967 fileFlag = TRUE;
06968 CONDITION flag;
06969 CTNBOOLEAN allowRepeatElements = FALSE;
06970
06971 ENTRY("readFile1") ;
06972
06973 ptr = callerBuf;
06974 if (ptr != NULL)
06975 fileFlag = FALSE;
06976
06977 if ((opt & DCM_FILEFORMATMASK) == DCM_PART10FILE) {
06978 part10Flag = TRUE;
06979 opt &= ~DCM_ORDERMASK;
06980 opt &= ~DCM_FILEFORMATMASK;
06981 opt |= DCM_EXPLICITLITTLEENDIAN;
06982 }
06983 if ((opt & DCM_SPECIALFORMATMASK) == DCM_EFILM) {
06984 part10Flag = TRUE;
06985 opt &= ~DCM_ORDERMASK;
06986 opt &= ~DCM_FILEFORMATMASK;
06987 opt |= DCM_ORDERLITTLEENDIAN;
06988 }
06989 if ((opt & DCM_REPEATELEMENTSMASK) == DCM_ALLOWREPEATELEMENTS) {
06990 allowRepeatElements = TRUE;
06991 }
06992
06993 switch (opt & DCM_ORDERMASK) {
06994 case DCM_ORDERNATIVE:
06995 byteOrder = NATIVE_ORDER;
06996 break;
06997 case DCM_ORDERLITTLEENDIAN:
06998 byteOrder = LITTLE_ORDER;
06999 break;
07000 case DCM_EXPLICITLITTLEENDIAN:
07001 byteOrder = LITTLE_ORDER;
07002 explicitVR = TRUE;
07003 break;
07004 case DCM_ORDERBIGENDIAN:
07005 byteOrder = BIG_ORDER;
07006 break;
07007 case DCM_EXPLICITBIGENDIAN:
07008 byteOrder = BIG_ORDER;
07009 explicitVR = TRUE;
07010 break;
07011 default:
07012 byteOrder = NATIVE_ORDER;
07013 break;
07014 }
07015 if ((opt & DCM_CONVERTMASK) == DCM_FORMATCONVERSION)
07016 convertFlag = TRUE;
07017 if ((opt & DCM_VRMASK) == DCM_ACCEPTVRMISMATCH)
07018 acceptVRMismatch = TRUE;
07019
07020 if (scannedLength != NULL)
07021 *scannedLength = 0;
07022
07023 cond = DCM_CreateObject(callerObject, opt);
07024 if (cond != DCM_NORMAL)
07025 RETURN( cond ) ;
07026
07027 object = (PRIVATE_OBJECT **) callerObject;
07028 if (fileFlag)
07029 strcpy((*object)->fileName, name);
07030
07031 (*object)->fd = -1;
07032 (*object)->rd = rd;
07033 (*object)->sk = sk;
07034 (*object)->userCtx = ctx;
07035 (*object)->dataOptions = 0;
07036 if (size == (long) DCM_UNSPECIFIEDLENGTH)
07037 knownLength = FALSE;
07038
07039 if ((fileFlag) && ((opt & DCM_DELETEMASK) == DCM_DELETEONCLOSE) && (recursionLevel == 0))
07040 (*object)->deleteFlag = TRUE;
07041
07042 if (parentObject != NULL)
07043 (*object)->pixelRepresentation = (*parentObject)->pixelRepresentation;
07044
07045 if (recursionLevel == 0 && part10Flag) {
07046 flag = readPreamble(name, &ptr, fd, &size, fileOffset, knownLength,
07047 object, scannedLength);
07048 if (flag != DCM_NORMAL)
07049 { STATUS("readPreamble fails"); goto abort; }
07050 }
07051 while (!done) {
07052 flag = readGroupElement(name, &ptr, fd, &size, fileOffset, knownLength,
07053 byteOrder, explicitVR, acceptVRMismatch, object,
07054 scannedLength, &e);
07055 if (flag == DCM_STREAMCOMPLETE)
07056 break;
07057 else if (flag != DCM_NORMAL)
07058 { STATUS("readGroupElement fails"); goto abort; }
07059 #if 0
07060 if (e.tag == DCM_MAKETAG(0x003a, 0x1000)) {
07061 fprintf(stderr, "Found waveform\n");
07062 }
07063 #endif
07064 flag = readVRLength(name, &ptr, fd, &size, fileOffset, knownLength,
07065 byteOrder, explicitVR, acceptVRMismatch, object,
07066 scannedLength, &e);
07067 if (flag != DCM_NORMAL)
07068 { STATUS("readVRLength fails"); goto abort; }
07069
07070 if ((e.representation == DCM_UN) &&
07071 (e.length == DCM_UNSPECIFIEDLENGTH)) {
07072 e.representation = DCM_SQ;
07073 }
07074 #ifndef SMM
07075 if ((e.tag == DCM_DLMITEMDELIMITATIONITEM) ||
07076 (e.tag == DCM_DLMSEQUENCEDELIMITATIONITEM)) {
07077 RETURN( DCM_NORMAL) ;
07078 }
07079 #else
07080 if (e.tag == DCM_DLMITEMDELIMITATIONITEM) {
07081 (*object)->objectSize -= 8;
07082 RETURN( DCM_NORMAL );
07083 }
07084 if (e.tag == DCM_DLMSEQUENCEDELIMITATIONITEM)
07085 RETURN( DCM_NORMAL );
07086 #endif
07087
07088 if (e.representation == DCM_SQ) {
07089 sequenceLength = e.length;
07090 scannedSequenceLength = 0;
07091 flag = readSequence(name, &ptr, fd, &sequenceLength,
07092 fileOffset, recursionLevel, opt,
07093 byteOrder, explicitVR, acceptVRMismatch,
07094 fileFlag, remainOpenFlag,
07095 convertFlag, object, &scannedSequenceLength,
07096 &e, &elementItem);
07097 if (flag != DCM_NORMAL)
07098 { STATUS("readSequence fails"); goto abort; }
07099 if (size != (long) DCM_UNSPECIFIEDLENGTH)
07100 size -= scannedSequenceLength;
07101 if (scannedLength != NULL)
07102 *scannedLength += scannedSequenceLength;
07103
07104 } else {
07105
07106 flag = readData(name, &ptr, fd, &size, fileOffset, knownLength,
07107 byteOrder, explicitVR, acceptVRMismatch, fileFlag,
07108 remainOpenFlag, convertFlag,
07109 object, scannedLength, &e, &elementItem);
07110 if (flag != DCM_NORMAL)
07111 { STATUS("readData fails"); goto abort; }
07112 }
07113 computeVM(object, &elementItem->element);
07114
07115 cond = checkAttributeOrder(&e, &lastGroup, &lastElement, allowRepeatElements);
07116 if (cond != DCM_NORMAL) {
07117 if (cond == DCM_REPEATEDELEMENT) {
07118 CTN_FREE(elementItem);
07119 continue;
07120 } else {
07121 CTN_FREE(elementItem);
07122 RETURN( cond ) ;
07123 }
07124 }
07125
07126 cond = handleGroupItem(object, &groupItem, DCM_TAG_GROUP(e.tag));
07127 if (cond != DCM_NORMAL)
07128 RETURN( cond );
07129
07130 if (DCM_TAG_ELEMENT(e.tag) != 0x0000) {
07131 groupItem->baseLength += 8 + elementItem->paddedDataLength;
07132 if (elementItem->element.representation == DCM_OB ||
07133 elementItem->element.representation == DCM_OW ||
07134 elementItem->element.representation == DCM_SQ) {
07135 groupItem->longVRAttributes++;
07136 (*object)->longVRAttributes++;
07137 }
07138 }
07139 if ((DCM_TAG_ELEMENT(e.tag) == 0x0000) && ((*object)->groupLengthFlag == FALSE)) {
07140 CTN_FREE(elementItem);
07141 } else {
07142 cond = LST_Enqueue(&groupItem->elementList, (void *)elementItem);
07143 if (cond != LST_NORMAL) {
07144 (void) DCM_CloseObject(callerObject);
07145 RETURN( COND_PushCondition(DCM_LISTFAILURE,
07146 DCM_Message(DCM_LISTFAILURE),
07147 "readFile") );
07148 }
07149 cond = updateObjectType(object, &elementItem->element);
07150
07151 cond = updateSpecialElements(object, elementItem);
07152 }
07153
07154 if (size == 0)
07155 done = TRUE;
07156
07157 if (part10Flag) {
07158 if ((*object)->objectSize == (DCM_PREAMBLELENGTH + 4 + 12 + (*object)->metaHeaderLength)) {
07159 opt &= ~DCM_ORDERMASK;
07160 opt |= (*object)->dataOptions & DCM_ORDERMASK;
07161 explicitVR = FALSE;
07162 switch (opt & DCM_ORDERMASK) {
07163 case DCM_ORDERNATIVE:
07164 byteOrder = NATIVE_ORDER;
07165 break;
07166 case DCM_ORDERLITTLEENDIAN:
07167 byteOrder = LITTLE_ORDER;
07168 break;
07169 case DCM_EXPLICITLITTLEENDIAN:
07170 byteOrder = LITTLE_ORDER;
07171 explicitVR = TRUE;
07172 break;
07173 case DCM_ORDERBIGENDIAN:
07174 byteOrder = BIG_ORDER;
07175 break;
07176 case DCM_EXPLICITBIGENDIAN:
07177 byteOrder = BIG_ORDER;
07178 explicitVR = TRUE;
07179 break;
07180 default:
07181 byteOrder = LITTLE_ORDER;
07182 explicitVR = TRUE;
07183 break;
07184 }
07185 }
07186 }
07187 }
07188
07189 #ifdef SMM
07190 #endif
07191
07192 groupItem = (void *)LST_Head(&(*object)->groupList);
07193 if (groupItem != NULL) {
07194 (void) LST_Position(&(*object)->groupList, (void *)groupItem);
07195 while (groupItem != NULL) {
07196 elementItem = (void *)LST_Head(&groupItem->elementList);
07197 if (elementItem != NULL) {
07198 if (DCM_TAG_ELEMENT(elementItem->element.tag) == 0x0000) {
07199 *elementItem->element.d.ul = groupItem->baseLength;
07200 }
07201 }
07202 groupItem = (void *)LST_Next(&(*object)->groupList);
07203 }
07204 }
07205 RETURN( DCM_NORMAL );
07206
07207 abort:
07208 RETURN (flag);
07209 }
07210
07211
07212
07213
07214
07215
07216
07217
07218
07219
07220
07221
07222
07223
07224
07225
07226
07227
07228
07229 static PRV_ELEMENT_ITEM *
07230 locateElement(PRIVATE_OBJECT ** obj, DCM_TAG tag)
07231 {
07232 PRV_GROUP_ITEM
07233 * groupItem;
07234 PRV_ELEMENT_ITEM
07235 * elementItem;
07236 CTNBOOLEAN
07237 found = FALSE;
07238
07239 groupItem = (void *)LST_Head(&(*obj)->groupList);
07240 if (groupItem == NULL)
07241 return NULL;
07242
07243 (void) LST_Position(&(*obj)->groupList, (void *)groupItem);
07244 while (groupItem != NULL) {
07245 if (groupItem->group == DCM_TAG_GROUP(tag))
07246 break;
07247
07248 groupItem = (void *)LST_Next(&(*obj)->groupList);
07249 }
07250 if (groupItem == NULL)
07251 return NULL;
07252
07253 elementItem = (void *)LST_Head(&groupItem->elementList);
07254 if (elementItem == NULL)
07255 return NULL;
07256
07257 (void) LST_Position(&groupItem->elementList, (void *)elementItem);
07258 while (!found && (elementItem != NULL)) {
07259 if (elementItem->element.tag == tag) {
07260 found = TRUE;
07261 } else
07262 elementItem = (void *)LST_Next(&groupItem->elementList);
07263 }
07264 if (found)
07265 return elementItem;
07266 else
07267 return NULL;
07268 }
07269
07270
07271
07272
07273
07274
07275
07276
07277
07278
07279
07280
07281
07282
07283
07284
07285
07286
07287
07288 static void
07289 computeVM(PRIVATE_OBJECT ** object, DCM_ELEMENT * element)
07290 {
07291 char
07292 *c;
07293 int
07294 i;
07295
07296 switch (element->representation) {
07297 case DCM_AE:
07298 case DCM_AS:
07299 case DCM_CS:
07300 case DCM_DA:
07301 case DCM_DS:
07302 case DCM_DT:
07303 case DCM_IS:
07304 case DCM_LO:
07305 case DCM_PN:
07306 case DCM_SH:
07307 case DCM_TM:
07308 case DCM_UI:
07309 case DCM_UT:
07310 element->multiplicity = 1;
07311 c = element->d.string;
07312 for (i = 0; i < (int) element->length; i++)
07313 if (*c++ == '\\')
07314 element->multiplicity++;
07315 break;
07316
07317 case DCM_FD:
07318 element->multiplicity = element->length / 8;
07319 break;
07320 case DCM_AT:
07321 case DCM_FL:
07322 case DCM_SL:
07323 case DCM_UL:
07324 element->multiplicity = element->length / 4;
07325 break;
07326 case DCM_SS:
07327 case DCM_US:
07328 element->multiplicity = element->length / 2;
07329 break;
07330 case DCM_LT:
07331 case DCM_OT:
07332 case DCM_SQ:
07333 case DCM_ST:
07334
07335 case DCM_UN:
07336 case DCM_RET:
07337 case DCM_CTX:
07338 case DCM_DD:
07339 default:
07340 element->multiplicity = 1;
07341 break;
07342 }
07343 }
07344
07345
07346
07347
07348
07349
07350
07351
07352
07353
07354
07355
07356
07357
07358
07359 static void
07360 ctxSensitiveLookup(PRIVATE_OBJECT ** object, DCM_ELEMENT * element)
07361 {
07362 switch (element->tag) {
07363 case DCM_IMGSMALLESTIMAGEPIXELVALUE:
07364 case DCM_IMGLARGESTIMAGEPIXELVALUE:
07365 case DCM_IMGSMALLESTPIXELVALUESERIES:
07366 case DCM_IMGLARGESTPIXELVALUESERIES:
07367 case DCM_IMGSMALLESTIMAGEPIXELVALUEPLANE:
07368 case DCM_IMGLARGESTIMAGEPIXELVALUEPLANE:
07369 case DCM_IMGLUTDESCRIPTOR:
07370 case DCM_IMGLUTDATA:
07371 case DCM_IMGLOOKUPDATARED:
07372 case DCM_IMGLOOKUPDATAGREEN:
07373 case DCM_IMGLOOKUPDATABLUE:
07374 if ((*object)->pixelRepresentation == 0x0000)
07375 element->representation = DCM_US;
07376 else if ((*object)->pixelRepresentation == 0x0001)
07377 element->representation = DCM_SS;
07378 else
07379 element->representation = DCM_US;
07380 break;
07381 case DCM_MAKETAG(0x003a, 0x1000):
07382 if (strcmp((*object)->waveformDataVR, "SS") == 0)
07383 element->representation = DCM_SS;
07384 break;
07385
07386 default:
07387 break;
07388 }
07389 }
07390
07391 static CONDITION
07392 copyData(PRIVATE_OBJECT ** object, PRV_ELEMENT_ITEM * from,
07393 DCM_ELEMENT * to, U32 * rtnLength)
07394 {
07395 unsigned char *p = NULL;
07396 U32 l;
07397 int nBytes;
07398 CONDITION cond;
07399
07400 if (from->element.representation == DCM_SQ)
07401 return COND_PushCondition(DCM_CANNOTGETSEQUENCEVALUE,
07402 DCM_Message(DCM_CANNOTGETSEQUENCEVALUE),
07403 from->element.tag, "copyData (DCM internal)");
07404
07405 l = MIN(from->element.length, to->length);
07406 if (rtnLength != NULL)
07407 *rtnLength = l;
07408
07409 if (from->element.d.ot == NULL) {
07410 if ((*object)->fd != -1) {
07411 (void) lseek((*object)->fd,
07412 from->dataOffset + (off_t) p, SEEK_SET);
07413 nBytes = read((*object)->fd, to->d.ot, (int) l);
07414 } else {
07415 (*object)->sk((*object)->userCtx,
07416 (long) (from->dataOffset + (off_t) p), SEEK_SET);
07417 cond = (*object)->rd((*object)->userCtx, to->d.ot, (long) l, &nBytes);
07418 }
07419 if (nBytes != (int) l) {
07420 return COND_PushCondition(DCM_FILEACCESSERROR,
07421 DCM_Message(DCM_FILEACCESSERROR),
07422 (*object)->fileName,
07423 "copyData (DCM internal)");
07424 }
07425 if( LITTLE_ENDIAN_ARCHITECTURE ){
07426 if (from->element.representation == DCM_AT) {
07427 DCM_ELEMENT e;
07428 e = from->element;
07429 e.length = l;
07430 e.d.ot = to->d.ot;
07431 swapATGroupElement(&e);
07432 }
07433 }
07434 if (from->byteOrder == BYTEORDER_REVERSE) {
07435 DCM_ELEMENT e;
07436 e = from->element;
07437 e.length = l;
07438 e.d.ot = to->d.ot;
07439 swapInPlace(object, &e);
07440 }
07441 } else {
07442 unsigned char *q;
07443 q = (unsigned char *) from->element.d.ot +
07444 (U32) p;
07445 (void) memcpy(to->d.ot, q, l);
07446 }
07447 p += l;
07448 if ((unsigned) p == from->element.length)
07449 return DCM_NORMAL;
07450 else
07451 return DCM_GETINCOMPLETE;
07452 }
07453
07454 static CONDITION
07455 readLengthToEnd(int fd, const char *fileName,
07456 unsigned long opt, U32 * lengthToEnd)
07457 {
07458 unsigned char buf[24];
07459 DCM_OBJECT *obj;
07460 CONDITION cond;
07461 DCM_ELEMENT e = {DCM_MAKETAG(0x0008, 0x0001), DCM_UL, "", 1, 4, NULL};
07462 void *ctx = NULL;
07463 U32 rtnLength = 0;
07464
07465 if (read(fd, buf, 24) != 24)
07466 return COND_PushCondition(DCM_FILEACCESSERROR,
07467 DCM_Message(DCM_FILEACCESSERROR), fileName,
07468 "(DCM)readLengthToEnd");
07469
07470 cond = DCM_ImportStream(buf, 24, opt, &obj);
07471 if (cond != DCM_NORMAL)
07472 return cond;
07473
07474 e.d.ul = lengthToEnd;
07475 cond = DCM_GetElementValue(&obj, &e, &rtnLength, &ctx);
07476
07477 (void) DCM_CloseObject(&obj);
07478
07479 return cond;
07480 }
07481
07482 static void
07483 swapATGroupElement(DCM_ELEMENT * e)
07484 {
07485 U32
07486 length;
07487 unsigned short
07488 tmp,
07489 *us;
07490
07491 length = e->length;
07492 us = e->d.us;
07493 while (length >= 4) {
07494 tmp = us[0];
07495 us[0] = us[1];
07496 us[1] = tmp;
07497 us += 2;
07498 length -= 4;
07499 }
07500 }
07501
07502 static void
07503 dumpSS(short *ss, long vm)
07504 {
07505 long index = 0;
07506 RWC_printf("decimal SS:") ;
07507 while (index < vm) {
07508 RWC_printf("%7d ", *(ss++));
07509 if ((++index) % 8 == 0)
07510 RWC_printf("\n");
07511 }
07512 RWC_printf("\n");
07513 }
07514
07515 static void
07516 dumpSL(S32 * sl, long vm)
07517 {
07518 long index = 0;
07519 RWC_printf("decimal SL:") ;
07520 while (index < vm) {
07521 RWC_printf("%7d ", *(sl++));
07522 if ((++index) % 8 == 0)
07523 RWC_printf("\n");
07524 }
07525 RWC_printf("\n");
07526 }
07527
07528 static void
07529 dumpUS(unsigned short *us, long vm)
07530 {
07531 long index = 0;
07532 RWC_printf("decimal US:") ;
07533 while (index < vm) {
07534 RWC_printf("%7d ", *(us++));
07535 if ((++index) % 8 == 0)
07536 RWC_printf("\n");
07537 }
07538 RWC_printf("\n");
07539 }
07540 static void
07541 dumpUL(U32 * ul, long vm)
07542 {
07543 long index = 0;
07544 RWC_printf("decimal UL:") ;
07545 while (index < vm) {
07546 RWC_printf("%7d ", *(ul++));
07547 if ((++index) % 8 == 0)
07548 RWC_printf("\n");
07549 }
07550 RWC_printf("\n");
07551 }
07552 static void
07553 dumpOB(unsigned char* c, long vm)
07554 {
07555 long index = 0;
07556 RWC_printf("hex OB:") ;
07557 while (index < vm) {
07558 RWC_printf("%02x ", *(c++));
07559 if ((++index) % 8 == 0)
07560 RWC_printf("\n");
07561 }
07562 if( index%8 != 0 ) RWC_printf("\n");
07563 }
07564
07565 static void
07566 dumpBinaryData(void *d, DCM_VALUEREPRESENTATION vr, long vm,
07567 long vmLimit)
07568 {
07569 vm = (vm < vmLimit) ? vm : vmLimit;
07570
07571 if (vm <= 1)
07572 return;
07573
07574 switch (vr) {
07575 case DCM_SL:
07576 dumpSL((S32 *) d, vm);
07577 break;
07578 case DCM_UL:
07579 dumpUL((U32 *) d, vm);
07580 break;
07581 case DCM_SS:
07582 dumpSS((short *) d, vm);
07583 break;
07584 case DCM_US:
07585 dumpUS((unsigned short *) d, vm);
07586 break;
07587 case DCM_OB:
07588 case DCM_UN:
07589 dumpOB((unsigned char*) d, vm);
07590 break;
07591 default:
07592 break;
07593 }
07594 }
07595
07596 static void
07597 compareGroup(PRV_GROUP_ITEM * g1, PRV_GROUP_ITEM * g2,
07598 void (*callback) (const DCM_ELEMENT * e1,
07599 const DCM_ELEMENT * e2,
07600 void *ctx),
07601 void *ctx)
07602 {
07603 PRV_ELEMENT_ITEM *e1 = NULL,
07604 *e2 = NULL;
07605
07606 if (g1 != NULL) {
07607 e1 = (void *)LST_Head(&g1->elementList);
07608 if (e1 != NULL)
07609 LST_Position(&g1->elementList, (void *)e1);
07610 }
07611 if (g2 != NULL) {
07612 e2 = (void *)LST_Head(&g2->elementList);
07613 if (e2 != NULL)
07614 LST_Position(&g2->elementList, (void *)e2);
07615 }
07616 while (e1 != NULL) {
07617 if (e2 == NULL) {
07618 callback(&e1->element, NULL, ctx);
07619 e1 = (void *)LST_Next(&g1->elementList);
07620 } else if (e1->element.tag == e2->element.tag) {
07621 callback(&e1->element, &e2->element, ctx);
07622 e1 = (void *)LST_Next(&g1->elementList);
07623 e2 = (void *)LST_Next(&g2->elementList);
07624 } else if (e1->element.tag < e2->element.tag) {
07625 callback(&e1->element, NULL, ctx);
07626 e1 = (void *)LST_Next(&g1->elementList);
07627 } else {
07628 callback(NULL, &e2->element, ctx);
07629 e2 = (void *)LST_Next(&g2->elementList);
07630 }
07631 }
07632
07633 while (e2 != NULL) {
07634 callback(NULL, &e2->element, ctx);
07635 e2 = (void *)LST_Next(&g2->elementList);
07636 }
07637 }
07638
07639 static void
07640 remapFileName(const char *name, char *mapName)
07641 {
07642 char c;
07643
07644 while ((c = *name++) != '\0') {
07645 if (c == '\\')
07646 *mapName++ = '/';
07647 else if (isupper(c))
07648 *mapName++ = tolower(c);
07649 else
07650 *mapName++ = c;
07651 }
07652 *mapName = '\0';
07653 }
07654
07655 static void
07656 copySequence(PRIVATE_OBJECT ** dstObj, DCM_ELEMENT * e)
07657 {
07658 LST_HEAD *lst;
07659 DCM_SEQUENCE_ITEM *sqItem;
07660 DCM_ELEMENT newElement;
07661
07662 lst = LST_Create();
07663 if (e->d.sq != NULL) {
07664 sqItem = (void *)LST_Head(&e->d.sq);
07665 (void) LST_Position(&e->d.sq, (void *)sqItem);
07666 }
07667 while (sqItem != NULL) {
07668 DCM_OBJECT *copy;
07669 DCM_SEQUENCE_ITEM *copyItem;
07670
07671 DCM_CopyObject(&sqItem->object, ©);
07672 copyItem = AFMALL( DCM_SEQUENCE_ITEM, sizeof(*copyItem));
07673 copyItem->object = copy;
07674 (void) LST_Enqueue(&lst, (void *)copyItem);
07675
07676 sqItem = (void *)LST_Next(&e->d.sq);
07677 }
07678
07679 memset(&newElement, 0, sizeof(newElement));
07680 newElement.tag = e->tag;
07681 newElement.representation = e->representation;
07682 newElement.d.sq = lst;
07683 DCM_AddSequenceElement((DCM_OBJECT **) dstObj, &newElement);
07684 }
07685
07686
07687
07688 CONDITION
07689 DCM_GetCompressedValue(DCM_OBJECT ** callerObject, DCM_TAG tag, void *buf,
07690 size_t bufSize, DCM_GET_COMPRESSED_CALLBACK* callback,
07691 void *ctx)
07692 {
07693 PRIVATE_OBJECT
07694 ** object;
07695 PRV_ELEMENT_ITEM
07696 * elementItem;
07697 S32 nBytes;
07698 S32 toRead;
07699 CONDITION cond;
07700 int doneFlag = 0;
07701 size_t elementLength;
07702 unsigned char *ptr;
07703 U32 size = 0;
07704 off_t fileOffset = 0;
07705 unsigned long opt;
07706 int byteOrder;
07707 int explicitVR;
07708 CTNBOOLEAN acceptVRMismatch = FALSE;
07709 DCM_ELEMENT e;
07710 U32 sequenceLength = 0;
07711 CONDITION flag;
07712 int index = 0;
07713 CTNBOOLEAN firstBuffer = TRUE;
07714 U32 *offsetBuffer = NULL;
07715 U32 offsetBufferCount = 0;
07716 U32 streamOffset = 0;
07717 int startOfFragment = 1;
07718
07719 object = (PRIVATE_OBJECT **) callerObject;
07720 cond = checkObject(object, "DCM_GetCompressedValue");
07721 if (cond != DCM_NORMAL)
07722 return cond;
07723
07724 elementItem = locateElement(object, tag);
07725
07726 if (elementItem == NULL)
07727 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
07728 DCM_Message(DCM_ELEMENTNOTFOUND), DCM_TAG_GROUP(tag),
07729 DCM_TAG_ELEMENT(tag),
07730 "DCM_GetEncodedValue");
07731
07732 elementLength = elementItem->originalDataLength;
07733 ptr = NULL;
07734 size = DCM_UNSPECIFIEDLENGTH;
07735 fileOffset = elementItem->dataOffset;
07736
07737 opt |= (*object)->dataOptions & DCM_ORDERMASK;
07738 explicitVR = FALSE;
07739 switch (opt & DCM_ORDERMASK) {
07740 case DCM_ORDERNATIVE:
07741 byteOrder = NATIVE_ORDER;
07742 break;
07743 case DCM_ORDERLITTLEENDIAN:
07744 byteOrder = LITTLE_ORDER;
07745 break;
07746 case DCM_EXPLICITLITTLEENDIAN:
07747 byteOrder = LITTLE_ORDER;
07748 explicitVR = TRUE;
07749 break;
07750 case DCM_ORDERBIGENDIAN:
07751 byteOrder = BIG_ORDER;
07752 break;
07753 case DCM_EXPLICITBIGENDIAN:
07754 byteOrder = BIG_ORDER;
07755 explicitVR = TRUE;
07756 break;
07757 default:
07758 byteOrder = LITTLE_ORDER;
07759 explicitVR = TRUE;
07760 break;
07761 }
07762 if ((opt & DCM_VRMASK) == DCM_ACCEPTVRMISMATCH)
07763 acceptVRMismatch = TRUE;
07764
07765 (void) lseek((*object)->fd, elementItem->dataOffset, SEEK_SET);
07766 while (elementLength != 0) {
07767 sequenceLength = 0;
07768 memset(&e, 0, sizeof(e));
07769 flag = readGroupElement("", &ptr, (*object)->fd, &size, &fileOffset,
07770 FALSE, byteOrder, explicitVR, acceptVRMismatch,
07771 object, &sequenceLength, &e);
07772 if (flag == DCM_STREAMCOMPLETE)
07773 break;
07774 else if (flag != DCM_NORMAL)
07775 return flag;
07776
07777 flag = readVRLength("", &ptr, (*object)->fd, &size, &fileOffset,
07778 FALSE,
07779 byteOrder, explicitVR, acceptVRMismatch, object,
07780 &sequenceLength, &e);
07781 if (flag != DCM_NORMAL)
07782 return flag;
07783
07784 elementLength -= sequenceLength + e.length;
07785
07786 if (firstBuffer) {
07787 firstBuffer = FALSE;
07788 if (e.length != 0) {
07789 offsetBuffer = CTN_MALLOC(e.length);
07790 offsetBufferCount = e.length / sizeof(U32);
07791 if (offsetBuffer == NULL)
07792 exit(1);
07793 nBytes = read((*object)->fd, offsetBuffer, e.length);
07794 if (nBytes != e.length) {
07795 exit(1);
07796 }
07797 if (byteOrder == BYTEORDER_REVERSE) {
07798 DCM_ELEMENT offsetBufferElement;
07799 memset(&offsetBufferElement, 0, sizeof(DCM_ELEMENT));
07800 offsetBufferElement.length = e.length;
07801 offsetBufferElement.d.ul = offsetBuffer;
07802 offsetBufferElement.representation = DCM_UL;
07803 swapInPlace(object, &offsetBufferElement);
07804 }
07805 callback(offsetBuffer, e.length, index, 1, 0, 1, ctx);
07806 streamOffset = 0;
07807 } else {
07808 streamOffset = 0xffffffff;
07809 }
07810 } else {
07811 U32 l = e.length;
07812 int j;
07813 int lastIndex;
07814
07815 lastIndex = index;
07816 for (j = 0; j < offsetBufferCount; j++) {
07817 if (streamOffset == offsetBuffer[j])
07818 index = j + 1;
07819 }
07820 startOfFragment = 1;
07821 while (l != 0) {
07822 toRead = MIN(bufSize, l);
07823 nBytes = read((*object)->fd, buf, toRead);
07824 if (nBytes != toRead) {
07825 exit(1);
07826 }
07827 callback(buf, toRead, index,
07828 (index != lastIndex) ? 1 : 0,
07829 0, startOfFragment, ctx);
07830 l -= toRead;
07831 lastIndex = index;
07832 startOfFragment = 0;
07833 }
07834 streamOffset += sequenceLength + e.length;
07835 }
07836 fileOffset += e.length;
07837 index++;
07838 }
07839 callback(buf, 0, index, 0, 1, 1, ctx);
07840 return DCM_NORMAL;
07841 }
07842
07843 CONDITION
07844 DCM_PrintSequenceList(DCM_OBJECT ** object, DCM_TAG tag)
07845 {
07846 PRIVATE_OBJECT **obj,
07847 *sqObject;
07848 CONDITION cond;
07849 PRV_ELEMENT_ITEM *elementItem;
07850 LST_HEAD *lst;
07851 DCM_SEQUENCE_ITEM *sqItem;
07852
07853 obj = (PRIVATE_OBJECT **) object;
07854 cond = checkObject(obj, "DCM_PrintSequenceList");
07855 if (cond != DCM_NORMAL)
07856 return cond;
07857
07858 elementItem = locateElement(obj, tag);
07859
07860 if (elementItem == NULL)
07861 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
07862 DCM_Message(DCM_ELEMENTNOTFOUND), DCM_TAG_GROUP(tag),
07863 DCM_TAG_ELEMENT(tag),
07864 "DCM_PrintSequenceList");
07865
07866 lst = elementItem->element.d.sq;
07867 sqItem = (void *)LST_Head(&lst);
07868 (void) LST_Position(&lst, (void *)sqItem);
07869 while (sqItem != NULL) {
07870 sqObject = (PRIVATE_OBJECT *) sqItem->object;
07871 RWC_printf("size: %6d offset: %6d, pixel offset: %6d\n",
07872 sqObject->objectSize,
07873 sqObject->offset,
07874 sqObject->pixelOffset);
07875 sqItem = (void *)LST_Next(&lst);
07876 }
07877 }
07878
07879 CONDITION
07880 DCM_GetSequenceByOffset(DCM_OBJECT ** object, DCM_TAG tag, unsigned long offset,
07881 DCM_OBJECT ** rtnObject)
07882 {
07883 PRIVATE_OBJECT **obj,
07884 *sqObject;
07885 CONDITION cond;
07886 PRV_ELEMENT_ITEM *elementItem;
07887 LST_HEAD *lst;
07888 DCM_SEQUENCE_ITEM *sqItem;
07889
07890 obj = (PRIVATE_OBJECT **) object;
07891 cond = checkObject(obj, "DCM_PrintSequenceList");
07892 if (cond != DCM_NORMAL)
07893 return cond;
07894
07895 elementItem = locateElement(obj, tag);
07896
07897 if (elementItem == NULL)
07898 return COND_PushCondition(DCM_ELEMENTNOTFOUND,
07899 DCM_Message(DCM_ELEMENTNOTFOUND), DCM_TAG_GROUP(tag),
07900 DCM_TAG_ELEMENT(tag),
07901 "DCM_PrintSequenceList");
07902
07903 lst = elementItem->element.d.sq;
07904 sqItem = (void *)LST_Head(&lst);
07905 (void) LST_Position(&lst, (void *)sqItem);
07906 while (sqItem != NULL) {
07907 sqObject = (PRIVATE_OBJECT *) sqItem->object;
07908 if (sqObject->offset == offset) {
07909 *rtnObject = sqItem->object;
07910 return DCM_NORMAL;
07911 }
07912 sqItem = (void *)LST_Next(&lst);
07913 }
07914 return 0;
07915 }
07916
07917 CONDITION
07918 DCM_CopyObject(DCM_OBJECT ** src, DCM_OBJECT ** dst)
07919 {
07920 PRIVATE_OBJECT **srcObj;
07921 PRIVATE_OBJECT *dstObj;
07922 PRV_GROUP_ITEM *groupItem;
07923 PRV_ELEMENT_ITEM *elementItem;
07924
07925 if (src == NULL) {
07926 (void) COND_PushCondition(DCM_NULLADDRESS,
07927 DCM_Message(DCM_NULLADDRESS), "DCM_CopyObject");
07928 return COND_PushCondition(DCM_OBJECTCREATEFAILED,
07929 DCM_Message(DCM_OBJECTCREATEFAILED), "DCM_CopyObject");
07930 }
07931 dstObj = (PRIVATE_OBJECT *) CTN_MALLOC(sizeof(PRIVATE_OBJECT));
07932 if (dstObj == NULL) {
07933 (void) COND_PushCondition(DCM_MALLOCFAILURE,
07934 DCM_Message(DCM_MALLOCFAILURE), sizeof(PRIVATE_OBJECT),
07935 "DCM_CopyObject");
07936 *dst = NULL;
07937 return COND_PushCondition(DCM_OBJECTCREATEFAILED,
07938 DCM_Message(DCM_OBJECTCREATEFAILED), "DCM_CopyObject");
07939 }
07940 (void) memset(dstObj, 0, sizeof(PRIVATE_OBJECT));
07941 (void) strcpy(dstObj->keyType, KEY_DCM_OBJECT);
07942
07943 dstObj->objectType = DCM_OBJECTUNKNOWN;
07944 dstObj->accessMethod = DCM_MEMORY_ACCESS;
07945 dstObj->deleteFlag = FALSE;
07946 dstObj->groupLengthFlag = FALSE;
07947 dstObj->objectSize = 0;
07948 dstObj->offset = 0;
07949 dstObj->pixelSize = 0;
07950 dstObj->pixelOffset = 0;
07951 dstObj->pixelBitsAllocated = 0;
07952 dstObj->pixelRepresentation = 0xffff;
07953 dstObj->groupCtx = NULL;
07954 dstObj->elementCtx = NULL;
07955 dstObj->fd = -1;
07956 dstObj->fileName[0] = '\0';
07957 dstObj->preambleFlag = FALSE;
07958 dstObj->preamble[0] = '\0';
07959 dstObj->dataOptions = 0;
07960 dstObj->metaHeaderLength = 0xffffffff;
07961 dstObj->longVRAttributes = 0;
07962 dstObj->waveformDataVR[0] = '\0';
07963
07964 dstObj->groupList = LST_Create();
07965 if (dstObj->groupList == NULL) {
07966 CTN_FREE(dstObj);
07967 *dst = NULL;
07968 return COND_PushCondition(DCM_LISTFAILURE,
07969 DCM_Message(DCM_LISTFAILURE),
07970 "DCM_CreateObject");
07971 }
07972 srcObj = (PRIVATE_OBJECT **) src;
07973
07974 groupItem = (void *)LST_Head(&(*srcObj)->groupList);
07975 if (groupItem != NULL)
07976 (void) LST_Position(&(*srcObj)->groupList, (void *)groupItem);
07977
07978 while (groupItem != NULL) {
07979 elementItem = (void *)LST_Head(&groupItem->elementList);
07980 if (elementItem != NULL)
07981 (void) LST_Position(&groupItem->elementList, (void *)elementItem);
07982 while (elementItem != NULL) {
07983 if (elementItem->element.representation == DCM_SQ) {
07984 copySequence(&dstObj, &elementItem->element);
07985 } else {
07986 DCM_AddElement((DCM_OBJECT **) & dstObj, &elementItem->element);
07987 }
07988 elementItem = (void *)LST_Next(&groupItem->elementList);
07989 }
07990 groupItem = (void *)LST_Next(&(*srcObj)->groupList);
07991 }
07992
07993 *dst = (DCM_OBJECT *) dstObj;
07994 return DCM_NORMAL;
07995 }
07996
07997 CONDITION
07998 DCM_MergeObject(DCM_OBJECT ** src, DCM_OBJECT ** dst)
07999 {
08000 PRIVATE_OBJECT **srcObj;
08001 PRIVATE_OBJECT *dstObj;
08002 PRV_GROUP_ITEM *groupItem;
08003 PRV_ELEMENT_ITEM *elementItem;
08004
08005 if (src == NULL) {
08006 (void) COND_PushCondition(DCM_NULLADDRESS,
08007 DCM_Message(DCM_NULLADDRESS), "DCM_MergeObject");
08008 return COND_PushCondition(DCM_OBJECTCREATEFAILED,
08009 DCM_Message(DCM_OBJECTCREATEFAILED), "DCM_MergeObject");
08010 }
08011 dstObj = *((PRIVATE_OBJECT **)dst);
08012 if (dstObj == NULL) {
08013 (void) COND_PushCondition(DCM_MALLOCFAILURE,
08014 DCM_Message(DCM_MALLOCFAILURE), sizeof(PRIVATE_OBJECT),
08015 "DCM_MergeObject");
08016 *dst = NULL;
08017 return COND_PushCondition(DCM_OBJECTCREATEFAILED,
08018 DCM_Message(DCM_OBJECTCREATEFAILED), "DCM_MergeObject");
08019 }
08020 srcObj = (PRIVATE_OBJECT **) src;
08021
08022 groupItem = (void *)LST_Head(&(*srcObj)->groupList);
08023 if (groupItem != NULL)
08024 (void) LST_Position(&(*srcObj)->groupList, (void *)groupItem);
08025
08026 while (groupItem != NULL) {
08027 elementItem = (void *)LST_Head(&groupItem->elementList);
08028 if (elementItem != NULL)
08029 (void) LST_Position(&groupItem->elementList, (void *)elementItem);
08030 while (elementItem != NULL) {
08031 if (elementItem->element.representation == DCM_SQ) {
08032 copySequence(&dstObj, &elementItem->element);
08033 } else {
08034 DCM_AddElement((DCM_OBJECT **) & dstObj, &elementItem->element);
08035 }
08036 elementItem = (void *)LST_Next(&groupItem->elementList);
08037 }
08038 groupItem = (void *)LST_Next(&(*srcObj)->groupList);
08039 }
08040
08041
08042 return DCM_NORMAL;
08043 }
08044
08045
08046 CONDITION
08047 DCM_GetFirstElement(DCM_OBJECT ** callerObject, DCM_ELEMENT** e)
08048 {
08049 PRIVATE_OBJECT** object;
08050 PRV_GROUP_ITEM* groupItem;
08051 PRV_ELEMENT_ITEM* elementItem;
08052 CONDITION cond;
08053
08054 object = (PRIVATE_OBJECT **) callerObject;
08055 cond = checkObject(object, "DCM_GetFirstElement");
08056 if (cond != DCM_NORMAL)
08057 return cond;
08058
08059 groupItem = (void *)LST_Head(&(*object)->groupList);
08060
08061 if (groupItem == NULL) {
08062 *e = 0;
08063 return DCM_EMPTYOBJECT;
08064 }
08065 (void) LST_Position(&(*object)->groupList, (void *)groupItem);
08066 (*object)->groupCtx = groupItem;
08067
08068 elementItem = (void *)LST_Head(&groupItem->elementList);
08069 (*object)->elementCtx = elementItem;
08070 if (elementItem == NULL) {
08071 return DCM_GetNextElement(callerObject, e);
08072 }
08073
08074 *e = &elementItem->element;
08075 return DCM_NORMAL;
08076 }
08077
08078 CONDITION
08079 DCM_GetNextElement(DCM_OBJECT ** callerObject, DCM_ELEMENT** e)
08080 {
08081 PRIVATE_OBJECT** object;
08082 PRV_GROUP_ITEM* groupItem;
08083 PRV_ELEMENT_ITEM* elementItem;
08084 CONDITION cond;
08085
08086 object = (PRIVATE_OBJECT **) callerObject;
08087 cond = checkObject(object, "DCM_GetNextElement");
08088 if (cond != DCM_NORMAL)
08089 return cond;
08090
08091 groupItem = (*object)->groupCtx;
08092 elementItem = (*object)->elementCtx;
08093
08094 if (elementItem != 0) {
08095 (void)LST_Position(&groupItem->elementList, (void *)elementItem);
08096 elementItem = (PRV_ELEMENT_ITEM*)LST_Next(&groupItem->elementList);
08097 }
08098
08099 if (elementItem == 0) {
08100 (void)LST_Position(&(*object)->groupList, (void *)groupItem);
08101 groupItem = (PRV_GROUP_ITEM*)LST_Next(&(*object)->groupList);
08102 if (groupItem != 0) {
08103 elementItem = (PRV_ELEMENT_ITEM*)LST_Head(&groupItem->elementList);
08104 }
08105 }
08106
08107 if (groupItem == 0) {
08108 *e = 0;
08109 return DCM_GETNEXTELEMENTCOMPLETE;
08110 }
08111
08112 (*object)->groupCtx = groupItem;
08113 (*object)->elementCtx = elementItem;
08114
08115 if (elementItem == 0)
08116 return DCM_GetNextElement(callerObject, e);
08117
08118 *e = &elementItem->element;
08119 return DCM_NORMAL;
08120 }
08121
08122 CONDITION
08123 DCM_AddFragment(DCM_OBJECT** callerObject, void* fragment, U32 fragmentLength)
08124 {
08125 PRIVATE_OBJECT** object;
08126 PRV_ELEMENT_ITEM* elementItem;
08127 PRV_ELEMENT_ITEM* newItem;
08128 CONDITION cond;
08129 PRV_GROUP_ITEM *groupItem = 0;
08130 DCM_FRAGMENT_ITEM* fragmentItem;
08131 U32 mallocLength;
08132
08133 if ((fragmentLength & 1) != 0) {
08134 return COND_PushCondition(DCM_UNEVENFRAGMENTLENGTH,
08135 DCM_Message(DCM_UNEVENFRAGMENTLENGTH), fragmentLength, "DCM_AddFragment");
08136 }
08137
08138 object = (PRIVATE_OBJECT **) callerObject;
08139 cond = checkObject(object, "DCM_AddFragment");
08140 if (cond != DCM_NORMAL)
08141 return cond;
08142
08143 cond = findCreateGroup(object, 0x7fe0, &groupItem);
08144 if (cond != DCM_NORMAL)
08145 return COND_PushCondition(DCM_INSERTFAILED,
08146 DCM_Message(DCM_INSERTFAILED), 0x7fe0, 0x0010, "DCM_AddFragment");
08147
08148 elementItem = locateElement(object, 0x7fe00010);
08149 if (elementItem == NULL) {
08150 DCM_ELEMENT e;
08151 memset(&e, 0, sizeof(e));
08152 e.tag = DCM_PXLPIXELDATA;
08153 e.representation = DCM_OB;
08154 e.multiplicity = 1;
08155 e.length = 0;
08156 e.d.fragments = 0;
08157 cond = newElementItem(&e, FALSE, &newItem);
08158 if (cond != DCM_NORMAL)
08159 return cond;
08160 newItem->element.d.fragments = LST_Create();
08161 if (newItem->element.d.fragments == NULL) {
08162 return COND_PushCondition(DCM_LISTFAILURE,
08163 DCM_Message(DCM_LISTFAILURE), "DCM_AddFragment");
08164 }
08165 cond = insertThisElementItem(object, newItem);
08166 if (cond != DCM_NORMAL)
08167 return cond;
08168 }
08169
08170 elementItem = locateElement(object, 0x7fe00010);
08171
08172 mallocLength = sizeof(DCM_FRAGMENT_ITEM) + fragmentLength;
08173 fragmentItem = CTN_MALLOC(mallocLength);
08174 if (fragmentItem == NULL) {
08175 return COND_PushCondition(DCM_MALLOCFAILURE,
08176 DCM_Message(DCM_MALLOCFAILURE), mallocLength,
08177 "DCM_AddFragment");
08178 }
08179
08180 fragmentItem->fragment = ((char*)fragmentItem)+ sizeof(DCM_FRAGMENT_ITEM);
08181 fragmentItem->length = fragmentLength;
08182 memcpy(fragmentItem->fragment, fragment, fragmentLength);
08183 elementItem->fragmentFlag = 1;
08184 LST_Enqueue(&elementItem->element.d.fragments, (void *)fragmentItem);
08185
08186 return DCM_NORMAL;
08187 }
08188
08189
08190
08191
08192
08193
08194
08195
08196
08197
08198
08199
08200
08201
08202
08203
08204
08205
08206
08207
08208
08209
08210
08211
08212
08213
08214
08215
08216
08217
08218
08219
08220
08221
08222
08223
08224
08225
08226
08227
08228
08229
08230
08231
08232
08233
08234
08235
08236
08237
08238 typedef struct vector {
08239 CONDITION cond;
08240 char *message;
08241 } VECTOR;
08242
08243 static VECTOR messageVector[] = {
08244 {DCM_NORMAL, "Normal return from DCM routine"},
08245 {DCM_FILEOPENFAILED, "DCM failed to open file: %s in %s"},
08246 {DCM_FILEACCESSERROR, "DCM failed to access file: %s in %s"},
08247 {DCM_OBJECTCREATEFAILED, "DCM failed to create object in %s"},
08248 {DCM_NULLOBJECT, "NULL object passed to routine %s"},
08249 {DCM_ILLEGALOBJECT, "Illegal object passed to routine %s"},
08250 {DCM_ELEMENTNOTFOUND, "Requested element (%x %x) not found in %s"},
08251 {DCM_ILLEGALSTREAMLENGTH,
08252 "DCM Illegal Stream Length (%ld) (Not enough data to define a full element) in %s"},
08253 {DCM_ELEMENTCREATEFAILED, "DCM failed to create element in %s (%04x %04x %d)"},
08254 {DCM_UNRECOGNIZEDGROUP, "DCM unrecognized group: %04x in %s"},
08255 {DCM_UNRECOGNIZEDELEMENT, "DCM unrecognized element: (%04x %04x) in %s"},
08256 {DCM_ELEMENTOUTOFORDER, "DCM group/element out of order (%04x %04x) in %s"},
08257 {DCM_LISTFAILURE, "DCM routine failed on list operation in %s"},
08258 {DCM_ILLEGALOPTION, "DCM illegal stream option: %s"},
08259 {DCM_ILLEGALADD, "DCM attempt to add illegal element: %x %x in %s"},
08260 {DCM_GETINCOMPLETE, "DCM Get Element incomplete in %s"},
08261 {DCM_ILLEGALCONTEXT, "DCM Illegal context value in %s"},
08262 {DCM_ILLEGALREPRESENTATION,
08263 "DCM Caller specified illegal representation for element (%04x %04x) in %s"},
08264 {DCM_UNEVENELEMENTLENGTH,
08265 "DCM attempt to add data element (%x %x) with uneven length (%ld) in %s"},
08266 {DCM_ELEMENTLENGTHERROR,
08267 "DCM Data Element (%04x %04x) longer (%ld) than remaining length (%ld) of \
08268 data in stream or file in %s"},
08269 {DCM_GROUPNOTFOUND, "Requested group (%x) not found in %s"},
08270 {DCM_FILECREATEFAILED, "DCM failed to create file %s (%s)"},
08271 {DCM_FILEIOERROR, "DCM io error on file %s (%s)"},
08272 {DCM_INSERTFAILED,
08273 "DCM failed to insert new element (%04x %04x) in %s"},
08274 {DCM_CANNOTGETSEQUENCEVALUE,
08275 "DCM Cannot retrieve value of element with SQ representation (%08x) in (%s)"},
08276 {DCM_FILEDELETEFAILED, "DCM Failed to delete file %s in %s"},
08277 {DCM_MALLOCFAILURE, "DCM Failed to malloc %ld bytes in %s"},
08278 {DCM_NULLADDRESS, "DCM NULL address passed to routine %s"},
08279 {DCM_UNEXPECTEDREPRESENTATION,
08280 "DCM Routine %s expected %s representation for element %04x %04x"},
08281 {DCM_BADELEMENTINGROUP,
08282 "DCM Bad element (%04x %04x) found in group %04x in %s"},
08283 {DCM_CALLBACKABORTED, "DCM Callback aborted by user in %s"},
08284 {DCM_READSTREAMFAILED, "DCM Failed to read stream in %s"},
08285 {DCM_UNRECOGNIZEDVRCODE, "DCM Unrecognized VR code (%s) in %s"},
08286 {DCM_VRMISMATCH, "DCM Incorrect VR (%s) for attribute with tag %08x"},
08287 {DCM_EXPORTBUFFERTOOSMALL,
08288 "DCM Caller's export buffer length (%d) is too short in %s"},
08289 {DCM_BADOFFSET,
08290 "DCM Offset value (%d) larger than attribute length (%d) in %s"},
08291 {DCM_BADLENGTH,
08292 "DCM Combination of offset, length (%d %d) is longer than element length (%d) in %s"},
08293 {DCM_NOTASEQUENCE,
08294 "DCM Attempt to perform sequence operation on element (%04x %04x) not a sequence in %s"},
08295 {DCM_GENERALWARNING, "DCM General warning in %s: %s"},
08296 {DCM_UNEVENFRAGMENTLENGTH,
08297 "DCM attempt to add fragment with uneven length (%ld) in %s"},
08298 {0, NULL}
08299
08300 };
08301
08302
08303
08304
08305
08306
08307
08308
08309
08310
08311
08312
08313
08314
08315
08316
08317
08318
08319
08320 char *
08321 DCM_Message(CONDITION condition)
08322 {
08323 int
08324 index;
08325
08326 for (index = 0; messageVector[index].message != NULL; index++)
08327 if (condition == messageVector[index].cond)
08328 return messageVector[index].message;
08329
08330 return NULL;
08331 }
08332
08333 DCM_DumpVector()
08334 {
08335 int index;
08336
08337 for (index = 0; index < (int) DIM_OF(messageVector); index++) {
08338 if (messageVector[index].message != NULL)
08339 RWC_printf("%8x %8d %s\n", messageVector[index].cond,
08340 messageVector[index].cond,
08341 messageVector[index].message);
08342 }
08343 }
08344
08345
08346
08347
08348
08349
08350
08351
08352
08353
08354
08355
08356
08357
08358
08359
08360
08361
08362
08363
08364
08365
08366
08367
08368
08369
08370
08371
08372
08373
08374
08375
08376
08377
08378
08379
08380
08381
08382
08383
08384
08385
08386
08387
08388
08389
08390
08391
08392
08393
08394
08395
08396
08397
08398
08399
08400
08401
08402
08403
08404
08405
08406
08407
08408
08409 typedef struct {
08410 DCM_TAG tag;
08411 DCM_VALUEREPRESENTATION representation;
08412 char englishDescription[48];
08413 } DCMDICT;
08414
08415 typedef struct {
08416 unsigned short group;
08417 unsigned long entries;
08418 DCMDICT *dict;
08419 } GROUPPTR;
08420
08421
08422
08423
08424 static DCMDICT CMD_dictionary[] = {
08425 {DCM_CMDGROUPLENGTH, DCM_UL, "CMD Group Length"},
08426 {DCM_CMDAFFECTEDCLASSUID, DCM_UI, "CMD Affected SOP Class UID"},
08427 {DCM_CMDREQUESTEDCLASSUID, DCM_UI, "CMD Requested SOP Class UID"},
08428 {DCM_CMDCOMMANDFIELD, DCM_US, "CMD Command Field"},
08429 {DCM_CMDMSGID, DCM_US, "CMD Message ID"},
08430 {DCM_CMDMSGIDRESPOND, DCM_US, "CMD Message ID Responded to"},
08431 {DCM_CMDMOVEDESTINATION, DCM_AE, "CMD Move Destination"},
08432 {DCM_CMDPRIORITY, DCM_US, "CMD Priority"},
08433 {DCM_CMDDATASETTYPE, DCM_US, "CMD Data Set Type"},
08434 {DCM_CMDSTATUS, DCM_US, "CMD Status"},
08435 {DCM_CMDOFFENDINGELEMENT, DCM_AT, "CMD Offending Element"},
08436 {DCM_CMDERRORCOMMENT, DCM_LO, "CMD Error Comment"},
08437 {DCM_CMDERRORID, DCM_US, "CMD Error ID"},
08438 {DCM_CMDREQUESTEDINSTANCEUID, DCM_UI, "CMD SOP Requested Instance UID"},
08439 {DCM_CMDAFFECTEDINSTANCEUID, DCM_UI, "CMD SOP Affected Instance UID"},
08440 {DCM_CMDEVENTTYPEID, DCM_US, "CMD Event Type ID"},
08441 {DCM_CMDACTIONTYPEID, DCM_US, "CMD Action Type ID"},
08442 {DCM_CMDREMAININGSUBOPERATIONS, DCM_US, "CMD Remaining Suboperations"},
08443 {DCM_CMDCOMPLETEDSUBOPERATIONS, DCM_US, "CMD Completed Suboperations"},
08444 {DCM_CMDFAILEDSUBOPERATIONS, DCM_US, "CMD Failed Suboperations"},
08445 {DCM_CMDWARNINGSUBOPERATIONS, DCM_US, "CMD Warning Suboperations"},
08446 {DCM_CMDMOVEAETITLE, DCM_AE, "CMD AE Title"},
08447 {DCM_CMDMOVEMESSAGEID, DCM_US, "CMD Message ID"},
08448 {DCM_CMDATTRIBUTEIDLIST, DCM_AT, "CMD Attribute Identifier List"},
08449
08450 };
08451
08452
08453
08454
08455 static DCMDICT META_dictionary[] = {
08456 {DCM_METAGROUPLENGTH, DCM_UL, "META Group Length"},
08457 {DCM_METAINFORMATIONVERSION, DCM_OB, "META File Meta Information Version"},
08458 {DCM_METAMEDIASTORAGESOPCLASS, DCM_UI, "META Media Stored SOP Class UID"},
08459 {DCM_METAMEDIASTORAGESOPINSTANCE, DCM_UI, "META Media Stored SOP Instance UID"},
08460 {DCM_METATRANSFERSYNTAX, DCM_UI, "META Transfer Syntax UID"},
08461 {DCM_METAIMPLEMENTATIONCLASS, DCM_UI, "META Implementation Class UID"},
08462 {DCM_METAIMPLEMENTATIONVERSION, DCM_SH, "META Implementation Version Name"},
08463 {DCM_METASOURCEAETITLE, DCM_AE, "META Source Application Entity Title"},
08464 {DCM_METAPRIVATEINFORMATIONCREATOR, DCM_UI, "META Private Information Creator"},
08465 {DCM_METAPRIVATEINFORMATION, DCM_OB, "META Private Information"}
08466 };
08467
08468
08469
08470 static DCMDICT BASICDIR_dictionary[] = {
08471 {DCM_DIRFILESETID, DCM_CS, "DIR File-set ID"},
08472 {DCM_DIRFILESETDESCRFILEID, DCM_CS, "DIR File-set descriptor ID"},
08473 {DCM_DIRSPECIFICCHARACTER, DCM_CS, "DIR Specific character set"},
08474 {DCM_DIRFIRSTOFFSET, DCM_UL, "DIR Offset of the first dir of root dir entity"},
08475 {DCM_DIRLASTOFFSET, DCM_UL, "DIR Offset of the last dir of root dir entity"},
08476 {DCM_DIRFILESETCONSISTENCY, DCM_US, "DIR File-set consistency flag"},
08477 {DCM_DIRRECORDSEQUENCE, DCM_SQ, "DIR Directory record sequence"},
08478 {DCM_DIRNEXTRECORDOFFSET, DCM_UL, "DIR Offset of next directory record"},
08479 {DCM_DIRRECORDINUSE, DCM_US, "DIR Record in use flag"},
08480 {DCM_DIRLOWERLEVELOFFSET, DCM_UL, "DIR Offset of referenced lower-level dir entity"},
08481 {DCM_DIRRECORDTYPE, DCM_CS, "DIR Directory Record Type"},
08482 {DCM_DIRPRIVATERECORDUID, DCM_UI, "DIR Private Record UID"},
08483 {DCM_DIRREFERENCEDFILEID, DCM_CS, "DIR Referenced File ID"},
08484 {DCM_DIRMRDRRECORDOFFSET, DCM_UL, "DIR Directory Record Offset"},
08485 {DCM_DIRREFSOPCLASSUID, DCM_UI, "DIR Referenced SOP Class UID in File"},
08486 {DCM_DIRREFSOPINSTANCEUID, DCM_UI, "DIR Referenced SOP Instance UID in File"},
08487 {DCM_DIRREFTRANSFERSYNTAXUID, DCM_UI, "DIR Referenced Transfer Syntax in File"},
08488 {DCM_DIRNUMREFERENCES, DCM_UL, "DIR Number of References"}
08489 };
08490
08491
08492
08493 static DCMDICT ID_dictionary[] = {
08494 {DCM_IDGROUPLENGTH, DCM_UL, "ID Group Length"},
08495
08496 {DCM_IDLENGTHTOEND, DCM_UL, "ID Length to End (RET)"},
08497 {DCM_IDSPECIFICCHARACTER, DCM_CS, "ID Specific Character Set"},
08498 {DCM_IDIMAGETYPE, DCM_CS, "ID Image Type"},
08499 {DCM_IDRECOGNITIONCODE, DCM_RET, "ID Recognition Code (RET)"},
08500 {DCM_IDINSTANCECREATEDATE, DCM_DA, "ID Instance Creation Date"},
08501 {DCM_IDINSTANCECREATETIME, DCM_TM, "ID Instance Creation Time"},
08502 {DCM_IDINSTANCECREATORUID, DCM_UI, "ID Instance Creator UID"},
08503 {DCM_IDSOPCLASSUID, DCM_UI, "ID SOP Class UID"},
08504 {DCM_IDSOPINSTANCEUID, DCM_UI, "ID SOP Instance UID"},
08505 {DCM_IDSTUDYDATE, DCM_DA, "ID Study Date"},
08506 {DCM_IDSERIESDATE, DCM_DA, "ID Series Date"},
08507 {DCM_IDACQUISITIONDATE, DCM_DA, "ID Acquisition Date"},
08508 {DCM_IDIMAGEDATE, DCM_DA, "ID Image Date"},
08509 {DCM_IDOVERLAYDATE, DCM_DA, "ID Overlay Date"},
08510 {DCM_IDCURVEDATE, DCM_DA, "ID Curve Date"},
08511 {DCM_IDSTUDYTIME, DCM_TM, "ID Study Time"},
08512 {DCM_IDSERIESTIME, DCM_TM, "ID Series Time"},
08513 {DCM_IDACQUISITIONTIME, DCM_TM, "ID Acquisition Time"},
08514 {DCM_IDIMAGETIME, DCM_TM, "ID Image Time"},
08515 {DCM_IDOVERLAYTIME, DCM_TM, "ID Overlay Time"},
08516 {DCM_IDCURVETIME, DCM_TM, "ID Curve Time"},
08517 {DCM_IDDATASETTYPE, DCM_RET, "ID Data Set Type (RET)"},
08518 {DCM_IDDATASETSUBTYPE, DCM_RET, "ID Data Set Subtype (RET)"},
08519 {DCM_IDNMSERIESTYPE, DCM_CS, "ID Nuc Med Series Type (RET)"},
08520 {DCM_IDACCESSIONNUMBER, DCM_SH, "ID Accession Number"},
08521 {DCM_IDQUERYLEVEL, DCM_CS, "ID Query Level"},
08522 {DCM_IDRETRIEVEAETITLE, DCM_AE, "ID Retrieve AE Title"},
08523 {DCM_IDINSTANCEAVAILABILITY, DCM_CS, "ID Instance Availability"},
08524 {DCM_IDFAILEDINSTANCEUIDLIST, DCM_UI, "ID Failed SOP Instances"},
08525 {DCM_IDMODALITY, DCM_CS, "ID Modality"},
08526 {DCM_IDMODALITIESINSTUDY, DCM_CS, "ID Modalities in Study"},
08527 {DCM_IDMODALITYSUBTYPE, DCM_SQ, "ID Modality Subtype"},
08528 {DCM_IDPRESENTATIONINTENTTYPE, DCM_CS, "ID Presentation Intent Type"},
08529 {DCM_IDCONVERSIONTYPE, DCM_CS, "ID Conversion Type"},
08530 {DCM_IDMANUFACTURER, DCM_LO, "ID Manufacturer"},
08531 {DCM_IDINSTITUTIONNAME, DCM_LO, "ID Institution Name"},
08532 {DCM_IDINSTITUTIONADDR, DCM_ST, "ID Institution Address"},
08533 {DCM_IDINSTITUTECODESEQUENCE, DCM_SQ, "ID Institution Code Sequence"},
08534 {DCM_IDREFERRINGPHYSICIAN, DCM_PN, "ID Referring Physician's Name"},
08535 {DCM_IDREFERRINGPHYSADDR, DCM_ST, "ID Referring Physician's Address"},
08536 {DCM_IDREFERRINGPHYSPHONE, DCM_SH, "ID Referring Physician's Telephone"},
08537 {DCM_IDCODEVALUE, DCM_SH, "ID Code Value"},
08538 {DCM_IDCODINGSCHEMEDESIGNATOR, DCM_SH, "ID Coding Scheme Designator"},
08539 {DCM_IDCODINGSCHEMEVERSION, DCM_SH, "ID Coding Scheme Version"},
08540
08541 {DCM_IDCODEMEANING, DCM_LO, "ID Code Meaning"},
08542 {DCM_IDMAPPINGRESOURCE, DCM_CS, "ID Mapping Resource"},
08543 {DCM_IDCONTEXTGROUPVERSION, DCM_DT, "ID Context Group Version"},
08544
08545 {DCM_IDCODESETEXTENSIONFLAG, DCM_CS, "ID Code Set Extension Flag"},
08546
08547 {DCM_IDPRIVATECODINGSCHEMECREATORUID, DCM_UI, "ID Private Coding Scheme Creator UID"},
08548
08549 {DCM_IDCODESETEXTENSIONCREATORUID, DCM_UI, "ID Coding Scheme Creator UID"},
08550
08551 {DCM_IDMAPPINGRESOURCESEQ, DCM_SQ, "ID Mapping Resource Sequence"},
08552
08553 {DCM_IDCONTEXTIDENTIFIER, DCM_CS, "ID Context Identifier"},
08554 {DCM_IDNETWORKID, DCM_LO, "ID Network ID (RET)"},
08555 {DCM_IDSTATIONNAME, DCM_SH, "ID Station Name"},
08556 {DCM_IDSTUDYDESCRIPTION, DCM_LO, "ID Study Description"},
08557 {DCM_IDPROCEDURECODESEQUENCE, DCM_SQ, "ID Procedure Code Sequence"},
08558 {DCM_IDSERIESDESCR, DCM_LO, "ID Series Description"},
08559 {DCM_IDINSTITUTIONALDEPT, DCM_LO, "ID Institutional Department Name"},
08560 {DCM_IDPHYSICIANOFRECORD, DCM_PN, "ID Physician of Record"},
08561 {DCM_IDPERFORMINGPHYSICIAN, DCM_PN, "ID Performing Physician's Name"},
08562 {DCM_IDPHYSREADINGSTUDY, DCM_PN, "ID Name of Physician(s) Reading Study"},
08563 {DCM_IDOPERATORNAME, DCM_PN, "ID Operator's Name"},
08564 {DCM_IDADMITTINGDIAGDESCR, DCM_LO, "ID Admitting Diagnoses Description"},
08565 {DCM_IDADMITDIAGCODESEQUENCE, DCM_SQ, "ID Admitting Diagnosis Code Sequence"},
08566 {DCM_IDMANUFACTURERMODEL, DCM_LO, "ID Manufacturer Model Name"},
08567 {DCM_IDREFERENCEDRESULTSSEQ, DCM_SQ, "ID Referenced Results Sequence"},
08568 {DCM_IDREFERENCEDSTUDYSEQ, DCM_SQ, "ID Referenced Study Sequence"},
08569 {DCM_IDREFERENCEDSTUDYCOMPONENTSEQ, DCM_SQ, "ID Referenced Study Component Sequence"},
08570 {DCM_IDREFERENCEDSERIESSEQ, DCM_SQ, "ID Referenced Series Sequence"},
08571 {DCM_IDREFERENCEDPATIENTSEQ, DCM_SQ, "ID Referenced Patient Sequence"},
08572 {DCM_IDREFERENCEDVISITSEQ, DCM_SQ, "ID Referenced Visit Sequence"},
08573 {DCM_IDREFERENCEDOVERLAYSEQ, DCM_SQ, "ID Referenced Overlay Sequence"},
08574 {DCM_IDREFERENCEDIMAGESEQ, DCM_SQ, "ID Referenced Image Sequence"},
08575 {DCM_IDREFERENCEDCURVESEQ, DCM_SQ, "ID Referenced Curve Sequence"},
08576 {DCM_IDREFERENCEDPREVIOUSWAVEFORM, DCM_SQ, "ID Referenced Previous Waveform"},
08577 {DCM_IDREFERENCEDSIMULTANEOUSWAVEFORMS, DCM_SQ, "ID Referenced Simultaneous Waveforms"},
08578 {DCM_IDREFERENCEDSUBSEQUENTWAVEFORM, DCM_SQ, "ID Referenced Subsequent Waveform"},
08579 {DCM_IDREFERENCEDSOPCLASSUID, DCM_UI, "ID Referenced SOP Class UID"},
08580 {DCM_IDREFERENCEDSOPINSTUID, DCM_UI, "ID Referenced SOP Instance UID"},
08581 {DCM_IDREFERENCEDFRAMENUMBER, DCM_IS, "ID Referenced Frame Number"},
08582 {DCM_IDTRANSACTIONUID, DCM_UI, "ID Transaction UID"},
08583 {DCM_IDFAILUREREASON, DCM_US, "ID Failure Reason"},
08584 {DCM_IDFAILEDSOPSEQUENCE, DCM_SQ, "ID Failed SOP Sequence"},
08585 {DCM_IDREFERENCEDSOPSEQUENCE, DCM_SQ, "ID Referenced SOP Sequence"},
08586 {DCM_IDLOSSYIMAGECOMPRESSION, DCM_CS, "ID Lossy Image Compression (RET)"},
08587 {DCM_IDDERIVATIONDESCR, DCM_ST, "ID Derivation Description"},
08588 {DCM_IDSOURCEIMAGESEQ, DCM_SQ, "ID Source Image Sequence"},
08589 {DCM_IDSTAGENAME, DCM_SH, "ID Stage Name"},
08590 {DCM_IDSTAGENUMBER, DCM_IS, "ID Stage Number"},
08591 {DCM_IDNUMBEROFSTAGES, DCM_IS, "ID Number of Stages"},
08592 {DCM_IDVIEWNUMBER, DCM_IS, "ID View Number"},
08593 {DCM_IDNUMBEROFEVENTTIMERS, DCM_IS, "ID Number of Event Timers"},
08594 {DCM_IDNUMBERVIEWSINSTAGE, DCM_IS, "ID Number of Views in Stage"},
08595 {DCM_IDEVENTELAPSEDTIME, DCM_DS, "ID Event Elapsed Time(s)"},
08596 {DCM_IDEVENTTIMERNAME, DCM_LO, "ID Event Event Timer Name(s)"},
08597 {DCM_IDSTARTTRIM, DCM_IS, "ID Start Trim"},
08598 {DCM_IDSTOPTRIM, DCM_IS, "ID Stop Trim"},
08599 {DCM_IDDISPLAYFRAMERATE, DCM_IS, "ID Recommended Display Frame Rate"},
08600 {DCM_IDTRANSDUCERPOSITION, DCM_CS, "ID Transducer Position (RET)"},
08601 {DCM_IDTRANSDUCERORIENTATION, DCM_CS, "ID Transducer Orientation (RET)"},
08602 {DCM_IDANATOMICSTRUCTURE, DCM_CS, "ID Anatomic Structure (RET)"},
08603 {DCM_IDANATOMICREGIONSEQUENCE, DCM_SQ, "ID Anatomic Region of Interest Sequence"},
08604 {DCM_IDANATOMICREGIONMODIFIERSEQ, DCM_SQ,
08605 "ID Anatomic Region Modifier Sequence"},
08606 {DCM_IDPRIMARYANATOMICSTRUCTURESEQ, DCM_SQ,
08607 "ID Primary Anatomic Structure Sequence"},
08608 {DCM_IDPRIMARYANATOMICSTRUCTUREMODIFIERSEQ, DCM_SQ,
08609 "ID Primary Anatomic Structure Modifier Sequence"},
08610 {DCM_IDTRANSDUCERPOSITIONSEQ, DCM_SQ, "ID Transducer Position Sequence"},
08611 {DCM_IDTRANSDUCERPOSITIONMODIFIERSEQ, DCM_SQ, "ID Transducer Position Modifer Sequence"},
08612 {DCM_IDTRANSDUCERORIENTATIONSEQ, DCM_SQ, "ID Transducer Orientation Sequence"},
08613 {DCM_IDTRANSDUCERORIENTATIONMODIFIERSEQ, DCM_SQ, "ID Transducer Orientation Modifer Sequence"},
08614 {DCM_IDCOMMENTS, DCM_RET, "ID Comments (RET)"}
08615 };
08616
08617
08618
08619 static DCMDICT PAT_dictionary[] = {
08620 {DCM_PATGROUPLENGTH, DCM_UL, "PAT Group Length"},
08621 {DCM_PATNAME, DCM_PN, "PAT Patient Name"},
08622 {DCM_PATID, DCM_LO, "PAT Patient ID"},
08623 {DCM_ISSUERPATIENTID, DCM_LO, "PAT Issuer of Patient ID"},
08624 {DCM_PATBIRTHDATE, DCM_DA, "PAT Patient Birthdate"},
08625 {DCM_PATBIRTHTIME, DCM_TM, "PAT Patient Birth Time"},
08626 {DCM_PATSEX, DCM_CS, "PAT Patient Sex"},
08627 {DCM_PATINSURANCEPLANCODESEQ, DCM_SQ, "PAT Patient's Insurance Plan Code Sequence"},
08628 {DCM_PATOTHERIDS, DCM_LO, "PAT Other Patient IDs"},
08629 {DCM_PATOTHERNAMES, DCM_PN, "PAT Other Patient Names"},
08630 {DCM_PATBIRTHNAME, DCM_PN, "PAT Patient's Birth Name "},
08631 {DCM_PATAGE, DCM_AS, "PAT Patient Age"},
08632 {DCM_PATSIZE, DCM_DS, "PAT Patient Size"},
08633 {DCM_PATWEIGHT, DCM_DS, "PAT Patient Weight"},
08634 {DCM_PATADDRESS, DCM_LO, "PAT Patient Address"},
08635 {DCM_PATINSURANCEPLANID, DCM_RET, "PAT Insurance Plan Identifier"},
08636 {DCM_PATMOTHERBIRTHNAME, DCM_PN, "PAT Patient's Mother's Birth Name"},
08637 {DCM_PATMILITARYRANK, DCM_LO, "PAT Military Rank"},
08638 {DCM_PATBRANCHOFSERVICE, DCM_LO, "PAT Branch of Service"},
08639 {DCM_PATMEDICALRECORDLOCATOR, DCM_LO, "PAT Medical Record Locator"},
08640 {DCM_PATMEDICALALERTS, DCM_LO, "PAT Medical Alerts"},
08641 {DCM_PATCONTRASTALLERGIES, DCM_LO, "PAT Contrast Allergies"},
08642 {DCM_COUNTRYOFRESIDENCE, DCM_LO, "PAT Country of Residence"},
08643 {DCM_REGIONOFRESIDENCE, DCM_LO, "PAT Region of Residence"},
08644 {DCM_PATTELEPHONENUMBER, DCM_SH, "PAT Patient's Telephone Numbers"},
08645 {DCM_PATETHNICGROUP, DCM_SH, "PAT Ethnic Group"},
08646 {DCM_PATOCCUPATION, DCM_SH, "PAT Occupation"},
08647 {DCM_PATSMOKINGSTATUS, DCM_CS, "PAT Smoking Status"},
08648 {DCM_PATADDITIONALPATHISTORY, DCM_LT, "PAT Additional Patient History"},
08649 {DCM_PATPREGNANCYSTATUS, DCM_US, "PAT Pregnancy Status"},
08650 {DCM_PATLASTMENSTRUALDATE, DCM_DA, "PAT Last Menstrual Date"},
08651 {DCM_PATRELIGIOUSPREFERENCE, DCM_LO, "PAT Religious Preference"},
08652 {DCM_PATCOMMENTS, DCM_LT, "PAT Comments"}
08653 };
08654
08655
08656
08657
08658 static DCMDICT ACQ_dictionary[] = {
08659 {DCM_ACQGROUPLENGTH, DCM_UL, "ACQ Group Length"},
08660 {DCM_ACQCONTRASTBOLUSAGENT, DCM_LO, "ACQ Contrast/Bolus Agent"},
08661 {DCM_ACQCONTRASTBOLUSAGENTSEQ, DCM_SQ, "ACQ Contrast/Bolus Agent Sequence"},
08662 {DCM_ACQCONTRASTBOLUSADMINROUTESEQ, DCM_SQ, "ACQ Contrast/Bolus Administration Route Seq"},
08663 {DCM_ACQBODYPARTEXAMINED, DCM_CS, "ACQ Body Part Examined"},
08664 {DCM_ACQSCANNINGSEQUENCE, DCM_CS, "ACQ Scanning Sequence"},
08665 {DCM_ACQSEQUENCEVARIANT, DCM_CS, "ACQ Sequence Variant"},
08666 {DCM_ACQSCANOPTIONS, DCM_CS, "ACQ Scan Options"},
08667 {DCM_ACQMRACQUISITIONTYPE, DCM_CS, "ACQ MR Acquisition Type "},
08668 {DCM_ACQSEQUENCENAME, DCM_SH, "ACQ Sequence Name"},
08669 {DCM_ACQANGIOFLAG, DCM_CS, "ACQ Angio Flag"},
08670 {DCM_ACQINTERVENTIONDRUGINFOSEQ, DCM_SQ, "ACQ Intervention Drug Information Sequence"},
08671 {DCM_ACQINTERVENTIONDRUGSTOPTIME, DCM_TM, "ACQ Intervention Drug Stop Time"},
08672 {DCM_ACQINTERVENTIONDRUGDOSE, DCM_DS, "ACQ Intervention Drug Dose"},
08673 {DCM_ACQINTERVENTIONDRUGCODESEQ, DCM_SQ, "ACQ Intervention Drug Code Sequence"},
08674 {DCM_ACQADDITIONALDRUGSEQ, DCM_SQ, "ACQ Additional Drug Sequence"},
08675 {DCM_ACQRADIONUCLIDE, DCM_LO, "ACQ Radionuclide (RET)"},
08676 {DCM_ACQRADIOPHARMACEUTICAL, DCM_LO, "ACQ Radiopharmaceutical"},
08677 {DCM_ACQENERGYWCENTERLINE, DCM_DS, "ACQ Energy Window Centerline (RET)"},
08678 {DCM_ACQENERGYWTOTALWIDTH, DCM_DS, "ACQ Energy Window Total Width (RET)"},
08679 {DCM_ACQINTERVENTIONDRUGNAME, DCM_LO, "ACQ Intervention Drug Name"},
08680 {DCM_ACQINTERVENTIONDRUGSTART, DCM_TM, "ACQ Intervention Drug Start Time"},
08681 {DCM_ACQINTERVENTIONALTHERAPYSEQ, DCM_SQ, "ACQ Interventional Therapy Sequence"},
08682 {DCM_ACQTHERAPYTYPE, DCM_CS, "ACQ Therapy type"},
08683 {DCM_ACQINTERVENTIONALSTATUS, DCM_CS, "ACQ Interventional status"},
08684 {DCM_ACQTHERAPYDESCRIPTION, DCM_CS, "ACQ Therapy descriptionm"},
08685 {DCM_ACQCINERATE, DCM_IS, "ACQ Cine Rate"},
08686 {DCM_ACQSLICETHICKNESS, DCM_DS, "ACQ Slice Thickness"},
08687 {DCM_ACQKVP, DCM_DS, "ACQ KVP"},
08688 {DCM_ACQCOUNTSACCUMULATED, DCM_IS, "ACQ Counts Accumulated"},
08689 {DCM_ACQTERMINATIONCONDITION, DCM_CS, "ACQ Acquisition Termination Condition"},
08690 {DCM_ACQEFFECTIVESERIESDURATION, DCM_DS, "ACQ Effective Series Duration"},
08691 {DCM_ACQSTARTCONDITION, DCM_CS, "ACQ Start Condition"},
08692 {DCM_ACQSTARTCONDITIONDATA, DCM_IS, "ACQ Start Condition Data"},
08693 {DCM_ACQTERMINATIONCONDITIONDATA, DCM_IS, "ACQ Termination Condition Data"},
08694 {DCM_ACQREPETITIONTIME, DCM_DS, "ACQ Repetition Time"},
08695 {DCM_ACQECHOTIME, DCM_DS, "ACQ Echo Time"},
08696 {DCM_ACQINVERSIONTIME, DCM_DS, "ACQ Inversion Time"},
08697 {DCM_ACQNUMBEROFAVERAGES, DCM_DS, "ACQ Number of Averages"},
08698 {DCM_ACQIMAGINGFREQUENCY, DCM_DS, "ACQ Imaging Frequency"},
08699 {DCM_ACQIMAGEDNUCLEUS, DCM_SH, "ACQ Imaged Nucleus"},
08700 {DCM_ACQECHONUMBER, DCM_IS, "ACQ Echo Number"},
08701 {DCM_ACQMAGNETICFIELDSTRENGTH, DCM_DS, "ACQ Magnetic Field Strength"},
08702 {DCM_ACQSLICESPACING, DCM_DS, "ACQ Spacing Between Slices"},
08703 {DCM_ACQPHASEENCODINGSTEPS, DCM_IS, "ACQ Number of Phase Encoding Steps"},
08704 {DCM_ACQDATACOLLECTIONDIAMETER, DCM_DS, "ACQ Data Collection Diameter"},
08705 {DCM_ACQECHOTRAINLENGTH, DCM_IS, "ACQ Echo Train Length"},
08706 {DCM_ACQPERCENTSAMPLING, DCM_DS, "ACQ Percent Sampling"},
08707 {DCM_ACQPERCENTPHASEFIELDVIEW, DCM_DS, "ACQ Percent Phase Field of View"},
08708 {DCM_ACQPIXELBANDWIDTH, DCM_DS, "ACQ Pixel Bandwidth"},
08709 {DCM_ACQDEVICESERIALNUM, DCM_LO, "ACQ Device Serial Number"},
08710 {DCM_ACQPLATEID, DCM_LO, "ACQ Plate ID"},
08711 {DCM_ACQSECONDARYCAPTUREDEVID, DCM_LO, "ACQ Secondary Capture Device ID"},
08712 {DCM_ACQDATESECONDARYCAPTURE, DCM_DA, "ACQ Date of Secondary Capture"},
08713 {DCM_ACQTIMESECONDARYCAPTURE, DCM_TM, "ACQ Time of Secondary Capture"},
08714 {DCM_ACQSECONDARYCAPTMANUFACTURER, DCM_LO,
08715 "ACQ Secondary Capture Device Manufacturer"},
08716 {DCM_ACQSECONDARYCAPTMODEL, DCM_LO, "ACQ Secondary Capture Device Model Name"},
08717 {DCM_ACQSECONDARYCAPTSOFTWAREVERSION, DCM_LO,
08718 "ACQ Secondary Capture Device Software Version"},
08719 {DCM_ACQSOFTWAREVERSION, DCM_LO, "ACQ Software Version"},
08720 {DCM_ACQVIDEOIMAGEFORMATACQ, DCM_SH, "ACQ Video Image Format Acquired"},
08721 {DCM_ACQDIGITALIMAGEFORMATACQ, DCM_LO, "ACQ Digital Image Format Acquired"},
08722 {DCM_ACQPROTOCOLNAME, DCM_LO, "ACQ Protocol Name"},
08723 {DCM_ACQCONTRASTBOLUSROUTE, DCM_LO, "ACQ Contrast/Bolus Route"},
08724 {DCM_ACQCONTRASTBOLUSVOL, DCM_DS, "ACQ Contrast/Bolus Volume"},
08725 {DCM_ACQCONTRASTBOLUSSTARTTIME, DCM_TM, "ACQ Contrast/Bolus Start Time"},
08726 {DCM_ACQCONTRASTBOLUSSTOPTIME, DCM_TM, "ACQ Contrast/Bolus Stop Time"},
08727 {DCM_ACQCONTRASTBOLUSTOTALDOSE, DCM_DS, "ACQ Contrast/Bolus Total Dose"},
08728 {DCM_ACQSYRINGECOUNTS, DCM_IS, "ACQ Syringe Counts"},
08729 {DCM_ACQCONTRASTFLOWRATE, DCM_DS, "ACQ Contrast Flow Rate (ml/sec)"},
08730 {DCM_ACQCONTRASTFLOWDURATION, DCM_DS, "ACQ Contrast Flow Duration (sec)"},
08731 {DCM_ACQCONTRASTBOLUSINGREDIENT, DCM_CS, "ACQ Contrast Bolus Ingredient"},
08732 {DCM_ACQCONTRASTBOLUSINGREDIENTCONCENTRATION, DCM_DS, "ACQ Contrast Bolus Ingredient Concentration"},
08733 {DCM_ACQSPATIALRESOLUTION, DCM_DS, "ACQ Spatial Resolution"},
08734 {DCM_ACQTRIGGERTIME, DCM_DS, "ACQ Trigger Time"},
08735 {DCM_ACQTRIGGERSRCTYPE, DCM_LO, "ACQ Trigger Source or Type"},
08736 {DCM_ACQNOMINALINTERVAL, DCM_IS, "ACQ Nominal Interval"},
08737 {DCM_ACQFRAMETIME, DCM_DS, "ACQ Frame Time"},
08738 {DCM_ACQFRAMINGTYPE, DCM_LO, "ACQ Framing Type"},
08739 {DCM_ACQFRAMETIMEVECTOR, DCM_DS, "ACQ Frame Time Vector"},
08740 {DCM_ACQFRAMEDELAY, DCM_DS, "ACQ Frame Delay"},
08741 {DCM_ACQIMAGETRIGGERDELAY, DCM_DS, "ACQ Image Trigger Delay"},
08742 {DCM_ACQGROUPTIMEOFFSET, DCM_DS, "ACQ Group Time Offset"},
08743 {DCM_ACQTRIGGERTIMEOFFSET, DCM_DS, "ACQ Trigger Time Offset"},
08744 {DCM_ACQSYNCTRIGGER, DCM_CS, "ACQ Synchronization Trigger"},
08745 {DCM_ACQSYNCFRAMEOFREFERENCE, DCM_UI, "ACQ Synchronization Frame of Reference"},
08746 {DCM_ACQTRIGGERSAMPLEPOSITION, DCM_UL, "ACQ Trigger Sample Position"},
08747 {DCM_ACQRADIOPHARMROUTE, DCM_LO, "ACQ Radiopharmaceutical Route"},
08748 {DCM_ACQRADIOPHARMVOLUME, DCM_DS, "ACQ Radiopharmaceutical Volume"},
08749 {DCM_ACQRADIOPHARMSTARTTIME, DCM_TM, "ACQ Radiopharmaceutical Start Time"},
08750 {DCM_ACQRADIOPHARMSTOPTIME, DCM_TM, "ACQ Radiopharmaceutical Stop Time"},
08751 {DCM_ACQRADIONUCLIDETOTALDOSE, DCM_DS, "ACQ Radionuclide Total Dose"},
08752 {DCM_ACQRADIONUCLIDEHALFLIFE, DCM_DS, "ACQ Radionuclide Half Life"},
08753 {DCM_ACQRADIONUCLIDEPOSITRONFRACTION, DCM_DS, "ACQ Radionuclide Positron Fraction"},
08754 {DCM_ACQRADIOPHARMACEUTICALSPECIFICACTIVITY, DCM_DS,
08755 "ACQ Radiopharmaceutical Specific Activity"},
08756 {DCM_ACQBEATREJECTIONFLAG, DCM_CS, "ACQ Beat Rejection Flag"},
08757 {DCM_ACQLOWRRVALUE, DCM_IS, "ACQ Low R-R Value"},
08758 {DCM_ACQHIGHRRVALUE, DCM_IS, "ACQ High R-R Value"},
08759 {DCM_ACQINTERVALSACQUIRED, DCM_IS, "ACQ Intervals Acquired"},
08760 {DCM_ACQINTERVALSREJECTED, DCM_IS, "ACQ Intervals Rejected"},
08761 {DCM_ACQPVCREJECTION, DCM_LO, "ACQ PVC Rejection"},
08762 {DCM_ACQSKIPBEATS, DCM_IS, "ACQ Skip Beats"},
08763 {DCM_ACQHEARTRATE, DCM_IS, "ACQ Heart Rate"},
08764 {DCM_ACQCARDIACNUMBEROFIMAGES, DCM_IS, "ACQ Cardiac Number of Images"},
08765 {DCM_ACQTRIGGERWINDOW, DCM_IS, "ACQ Trigger Window"},
08766 {DCM_ACQRECONSTRUCTIONDIAMETER, DCM_DS, "ACQ Reconstruction Diameter"},
08767 {DCM_ACQDISTANCESRCTODETECTOR, DCM_DS, "ACQ Distance Source-Detector"},
08768 {DCM_ACQDISTANCESRCTOPATIENT, DCM_DS, "ACQ Distance Source-Patient"},
08769 {DCM_ACQESTIMATEDRADIOGRAPHICMAGFACTOR, DCM_DS, "ACQ Estimated Radiographic Mag Factor"},
08770 {DCM_ACQGANTRYTILT, DCM_DS, "ACQ Gantry/Detector Tilt"},
08771 {DCM_ACQGANTRYSLEW, DCM_DS, "ACQ Gantry/Detector Slew"},
08772 {DCM_ACQTABLEHEIGHT, DCM_DS, "ACQ Table Height"},
08773 {DCM_ACQTABLETRAVERSE, DCM_DS, "ACQ Table Traverse"},
08774 {DCM_ACQTABLEMOTION, DCM_CS, "ACQ Table Motion (STATIC, DYNAMIC)"},
08775 {DCM_ACQTABLEVERTICALINCREMENT, DCM_DS, "ACQ Table Vertical Increment (mm)"},
08776 {DCM_ACQTABLELATERALINCREMENT, DCM_DS, "ACQ Table Lateral Increment (mm)"},
08777 {DCM_ACQTABLELONGITUDINALINCREMENT, DCM_DS, "ACQ Table Longitudinal Increment (mm)"},
08778 {DCM_ACQTABLEANGLE, DCM_DS, "ACQ Table Angle (relative to horizontal: deg)"},
08779 {DCM_ACQROTATIONDIRECTION, DCM_CS, "ACQ Rotation Direction"},
08780 {DCM_ACQANGULARPOSITION, DCM_DS, "ACQ Angular Position"},
08781 {DCM_ACQRADIALPOSITION, DCM_DS, "ACQ Radial Position"},
08782 {DCM_ACQSCANARC, DCM_DS, "ACQ Scan Arc"},
08783 {DCM_ACQANGULARSTEP, DCM_DS, "ACQ Angular Step"},
08784 {DCM_ACQCENTERROTATIONOFFSET, DCM_DS, "ACQ Center of Rotation Offset"},
08785 {DCM_ACQROTATIONOFFSET, DCM_DS, "ACQ Rotation Offset (RET)"},
08786 {DCM_ACQFIELDOFVIEWSHAPE, DCM_CS, "ACQ Field of View Shape"},
08787 {DCM_ACQFIELDOFVIEWDIMENSION, DCM_IS, "ACQ Field of View Dimension(s)"},
08788 {DCM_ACQEXPOSURETIME, DCM_IS, "ACQ Exposure Time"},
08789 {DCM_ACQXRAYTUBECURRENT, DCM_IS, "ACQ X-ray Tube Current"},
08790 {DCM_ACQEXPOSURE, DCM_IS, "ACQ Exposure"},
08791 {DCM_ACQAVERAGEPULSEWIDTH, DCM_DS, "ACQ Average width of X-Ray pulse (ms)"},
08792 {DCM_ACQRADIATIONSETTING, DCM_CS, "ACQ General level of X-Ray dose exposure"},
08793 {DCM_ACQRADIATIONMODE, DCM_CS, "ACQ X-Ray radiation mode (CONTINUOUS, PULSED)"},
08794 {DCM_ACQIMAGEAREADOSEPRODUCT, DCM_DS, "ACQ X-Ray dose to which patient was exposed"},
08795 {DCM_ACQFILTERTYPE, DCM_SH, "ACQ Filter Type, extremity"},
08796 {DCM_ACQTYPEOFFILTERS, DCM_LO, "ACQ Type of filter(s) inserted into X-Ray beam"},
08797 {DCM_ACQINTENSIFIERSIZE, DCM_DS, "ACQ Intensifier Size (mm)"},
08798 {DCM_ACQIMAGERPIXELSPACING, DCM_DS, "ACQ Image Pixel Spacing"},
08799 {DCM_ACQGRID, DCM_CS, "ACQ Grid (IN, NONE)"},
08800 {DCM_ACQGENERATORPOWER, DCM_IS, "ACQ Generator Power"},
08801 {DCM_ACQCOLLIMATORGRIDNAME, DCM_SH, "ACQ Collimator/Grid Name"},
08802 {DCM_ACQCOLLIMATORTYPE, DCM_CS, "ACQ Collimator Type"},
08803 {DCM_ACQFOCALDISTANCE, DCM_IS, "ACQ Focal Distance"},
08804 {DCM_ACQXFOCUSCENTER, DCM_DS, "ACQ X Focus Center"},
08805 {DCM_ACQYFOCUSCENTER, DCM_DS, "ACQ Y Focus Center"},
08806 {DCM_ACQFOCALSPOT, DCM_DS, "ACQ Focal Spot"},
08807 {DCM_ACQDATELASTCALIBRATION, DCM_DA, "ACQ Date of Last Calibration"},
08808 {DCM_ACQTIMELASTCALIBRATION, DCM_TM, "ACQ Time of Last Calibration"},
08809 {DCM_ACQCONVOLUTIONKERNEL, DCM_SH, "ACQ Convolution Kernel"},
08810 {DCM_ACQUPPERLOWERPIXELVALUES, DCM_RET, "ACQ Upper/Lower Pixel Values (RET)"},
08811 {DCM_ACQACTUALFRAMEDURATION, DCM_IS, "ACQ Actual Frame Duration"},
08812 {DCM_ACQCOUNTRATE, DCM_IS, "ACQ Count Rate"},
08813 {DCM_ACQPREFPLAYBACKSEQUENCING, DCM_US, "ACQ Preferred Playback Sequencing"},
08814 {DCM_ACQRECEIVINGCOIL, DCM_SH, "ACQ Receiving Coil"},
08815 {DCM_ACQTRANSMITTINGCOIL, DCM_SH, "ACQ Transmitting Coil"},
08816 {DCM_ACQPLATETYPE, DCM_SH, "ACQ Plate Type"},
08817 {DCM_ACQPHOSPHORTYPE, DCM_LO, "ACQ Phosphor Type"},
08818 #if STANDARD_VERSION < VERSION_APR1995
08819 {DCM_ACQSCANVELOCITY, DCM_IS, "ACQ Scan Velocity"},
08820 #else
08821 {DCM_ACQSCANVELOCITY, DCM_DS, "ACQ Scan Velocity"},
08822 #endif
08823 {DCM_ACQWHOLEBODYTECHNIQUE, DCM_CS, "ACQ Whole Body Technique"},
08824 {DCM_ACQSCANLENGTH, DCM_IS, "ACQ Scan Length"},
08825 {DCM_ACQACQUISITIONMATRIX, DCM_US, "ACQ Acquisition Matrix"},
08826 {DCM_ACQPHASEENCODINGDIRECTION, DCM_CS, "ACQ Phase Encoding Direction"},
08827 {DCM_ACQFLIPANGLE, DCM_DS, "ACQ Flip Angle"},
08828 {DCM_ACQVARIABLEFLIPANGLE, DCM_CS, "ACQ Variable Flip Angle"},
08829 {DCM_ACQSAR, DCM_DS, "ACQ SAR"},
08830 {DCM_ACQDBDT, DCM_DS, "ACQ DB/DT"},
08831 {DCM_ACQDEVICEPROCESSINGDESCR, DCM_LO, "ACQ Acquisition Device Processing Description"},
08832 {DCM_ACQDEVICEPROCESSINGCODE, DCM_LO, "ACQ Acquisition Device Processing Code"},
08833 {DCM_ACQCASSETTEORIENTATION, DCM_CS, "ACQ Cassette Orientation"},
08834 {DCM_ACQCASSETTESIZE, DCM_CS, "ACQ Cassette Size"},
08835 {DCM_ACQEXPOSURESONPLATE, DCM_US, "ACQ Exposures on Plate"},
08836 {DCM_ACQRELATIVEXRAYEXPOSURE, DCM_IS, "ACQ Relative X-ray Exposure"},
08837 {DCM_ACQCOLUMNANGULATION, DCM_CS, "ACQ Column Angulation"},
08838 {DCM_ACQTOMOLAYERHEIGHT, DCM_DS, "ACQ Tomo Layer Height (mm)"},
08839 {DCM_ACQTOMOANGLE, DCM_DS, "ACQ Tomo Angle"},
08840 {DCM_ACQTOMOTIME, DCM_DS, "ACQ Tomo Time"},
08841 {0x00181490, DCM_CS, "ACQ Tomo Type"},
08842 {0x00181491, DCM_CS, "ACQ Tomo Class"},
08843 {0x00181495, DCM_IS, "ACQ Number of Tomosynthesis Source Images"},
08844 {DCM_ACQPOSITIONERMOTION, DCM_CS, "ACQ Positioner Motion"},
08845 {0x00181508, DCM_CS, "ACQ Positioner Type"},
08846 {DCM_ACQPOSITIONERPRIMARYANGLE, DCM_DS, "ACQ Positioner Primary Angle"},
08847 {DCM_ACQPOSITIONERSECONDARYANGLE, DCM_DS, "ACQ Positioner Secondary Angle"},
08848 {DCM_ACQPOSITIONERPRIMARYANGLEINCR, DCM_DS, "ACQ Positioner Primary Angle Increment"},
08849 {DCM_ACQPOSITIONERSECONDARYANGLEINCR, DCM_DS, "ACQ Positioner Secondary Angle Increment"},
08850 {DCM_ACQDETECTORPRIMARYANGLE, DCM_DS, "ACQ Detector Primary Angle"},
08851 {DCM_ACQDETECTORSECONDARYANGLE, DCM_DS, "ACQ Detector Secondary Angle"},
08852 {DCM_ACQSHUTTERSHAPE, DCM_CS, "ACQ Shutter Shape"},
08853 {DCM_ACQSHUTTERLEFTVERTICALEDGE, DCM_IS, "ACQ Shutter Left Vertical Edge"},
08854 {DCM_ACQSHUTTERRIGHTVERTICALEDGE, DCM_IS, "ACQ Shutter Right Vertical Edge"},
08855 {DCM_ACQSHUTTERUPPERHORIZONTALEDGE, DCM_IS, "ACQ Shutter Upper Horizontal Edge"},
08856 {DCM_ACQSHUTTERLOWERHORIZONTALEDGE, DCM_IS, "ACQ Shutter Lower Horizontal Edge"},
08857 {DCM_ACQCENTEROFCIRCULARSHUTTER, DCM_IS, "ACQ Center of Circular Shutter"},
08858 {DCM_ACQRADIUSOFCIRCULARSHUTTER, DCM_IS, "ACQ Radius of Circular Shutter"},
08859 {DCM_ACQVERTICESOFPOLYGONALSHUTTER, DCM_IS, "ACQ Vertices of the Polygonal Shutter"},
08860 {DCM_ACQCOLLIMATORSHAPE, DCM_CS, "ACQ Collimator Shape"},
08861 {DCM_ACQCOLLIMATORLEFTVERTICALEDGE, DCM_IS, "ACQ Collimator Left Vertical Edge"},
08862 {DCM_ACQCOLLIMATORRIGHTVERTICALEDGE, DCM_IS, "ACQ Collimator Right Vertical Edge"},
08863 {DCM_ACQCOLLIMATORUPPERHORIZONTALEDGE, DCM_IS, "ACQ Collimator Upper Horizontal Edge"},
08864 {DCM_ACQCOLLIMATORLOWERHORIZONTALEDGE, DCM_IS, "ACQ Collimator Lower Horizontal Edge"},
08865 {DCM_ACQCENTEROFCIRCULARCOLLIMATOR, DCM_IS, "ACQ Center of Circular Collimator"},
08866 {DCM_ACQRADIUSOFCIRCULARCOLLIMATOR, DCM_IS, "ACQ Radius of Circular Collimator"},
08867 {DCM_ACQVERTICESOFPOLYGONALCOLLIMATOR, DCM_IS, "ACQ Vertices of the Polygonal Collimator"},
08868 {DCM_ACQACQUISITIONTIMESYNCHRONIZED, DCM_CS,
08869 "ACQ Acquisition Time Synchronized"},
08870 {DCM_ACQTIMESOURCE, DCM_SH, "ACQ Time Source"},
08871 {DCM_ACQTIMEDISTRIBUTIONPROTOCOL, DCM_CS,
08872 "ACQ Time Distribution Protocol"},
08873 {DCM_ACQCOMMENTS, DCM_RET, "ACQ Comments"},
08874 {DCM_ACQOUTPUTPOWER, DCM_SH, "ACQ Output Power"},
08875 {DCM_ACQTRANSDUCERDATA, DCM_LO, "ACQ Transducer Data"},
08876 {DCM_ACQFOCUSDEPTH, DCM_DS, "ACQ Focus Depth"},
08877 #if STANDARD_VERSION < VERSION_APR1995
08878 {DCM_ACQPREPROCESSINGFUNCTION, DCM_LO, "ACQ Preprocessing Function"},
08879 #else
08880 {DCM_ACQPROCESSINGFUNCTION, DCM_LO, "ACQ Processing Function"},
08881 #endif
08882 {DCM_ACQPOSTPROCESSINGFUNCTION, DCM_LO, "ACQ Postprocessing Function"},
08883 {DCM_ACQMECHANICALINDEX, DCM_DS, "ACQ Mechanical Index"},
08884 {DCM_ACQTHERMALINDEX, DCM_DS, "ACQ Thermal Index"},
08885 {DCM_ACQCRANIALTHERMALINDEX, DCM_DS, "ACQ Cranial Thermal Index"},
08886 {DCM_ACQSOFTTISSUETHERMALINDEX, DCM_DS, "ACQ Soft Tissue Thermal Index"},
08887 {DCM_ACQSOFTTISSUEFOCUSTHERMALINDEX, DCM_DS,
08888 "ACQ Soft Tissue-focus Thermal Index"},
08889 {DCM_ACQSOFTTISSUESURFACETHERMALINDEX, DCM_CS,
08890 "ACQ Soft Tissue-surface Thermal Index"},
08891 {DCM_ACQDEPTHOFSCANFIELD, DCM_IS, "ACQ Depth of Scan Field"},
08892 {DCM_ACQPATIENTPOSITION, DCM_CS, "ACQ Patient Position"},
08893 {DCM_ACQVIEWPOSITION, DCM_CS, "ACQ View Position"},
08894 {DCM_ACQIMAGETRANSFORMATIONMATRIX, DCM_DS,
08895 "ACQ Image Transformation Matrix"},
08896 {DCM_ACQIMAGETRANSLATIONVECTOR, DCM_DS,
08897 "ACQ Image Translation Vector"},
08898 {DCM_ACQSENSITIVITY, DCM_DS, "ACQ Sensitivity"},
08899 {DCM_ACQUSREGIONSEQUENCE, DCM_SQ, "ACQ Ultrasound Region Sequence"},
08900 {DCM_ACQREGIONSPATIALFORMAT, DCM_US, "ACQ Region Spatial Format"},
08901 {DCM_ACQREGIONDATATYPE, DCM_US, "ACQ Region Data Type"},
08902 {DCM_ACQREGIONFLAGS, DCM_UL, "ACQ Region Flags"},
08903 {DCM_ACQREGIONLOCATIONMINX0, DCM_UL, "ACQ Region Location Min X(0)"},
08904 {DCM_ACQREGIONLOCATIONMINY0, DCM_UL, "ACQ Region Location Min Y(0)"},
08905 {DCM_ACQREGIONLOCATIONMAXX1, DCM_UL, "ACQ Region Location Max X(1)"},
08906 {DCM_ACQREGIONLOCATIONMAXY1, DCM_UL, "ACQ Region Location Max Y(1)"},
08907 {DCM_ACQREFERENCEPIXELX, DCM_SL, "ACQ Reference Pixel X"},
08908 {DCM_ACQREFERENCEPIXELY, DCM_SL, "ACQ Reference Pixel Y"},
08909 {DCM_ACQPHYSICALUNITSXDIRECTION, DCM_US, "ACQ Physical Units X Direction"},
08910 {DCM_ACQPHYSICALUNITSYDIRECTION, DCM_US, "ACQ Physical Units Y Direction"},
08911 {DCM_ACQREFPIXELPHYSICALVALUEX, DCM_FD, "ACQ Reference Pixel Physical Value X"},
08912 {DCM_ACQREFPIXELPHYSICALVALUEY, DCM_FD, "ACQ Reference Pixel Physical Value Y"},
08913 {DCM_ACQPHYSICALDELTAX, DCM_FD, "ACQ Physical Delta X"},
08914 {DCM_ACQPHYSICALDELTAY, DCM_FD, "ACQ Physical Delta Y"},
08915 {DCM_ACQTRANSDUCERFREQUENCY, DCM_UL, "ACQ Transducer Frequency"},
08916 {DCM_ACQTRANSDUCERTYPE, DCM_CS, "ACQ Transducer Type"},
08917 {DCM_ACQPULSEREPETITIONFREQ, DCM_UL, "ACQ Pulse Repetition Frequency"},
08918 {DCM_ACQDOPPLERCORRECTIONANGLE, DCM_FD, "ACQ Doppler Correction Angle"},
08919 {DCM_ACQSTERRINGANGLE, DCM_FD, "ACQ Sterring Angle"},
08920 {DCM_ACQDOPPLERSAMPLEVOLXPOS, DCM_UL, "ACQ Doppler Sample Volume X Position"},
08921 {DCM_ACQDOPPLERSAMPLEVOLYPOS, DCM_UL, "ACQ Doppler Sample Volume Y Position"},
08922 {DCM_ACQTMLINEPOSITIONX0, DCM_UL, "ACQ TM-Line Position X(0)"},
08923 {DCM_ACQTMLINEPOSITIONY0, DCM_UL, "ACQ TM-Line Position Y(0)"},
08924 {DCM_ACQTMLINEPOSITIONX1, DCM_UL, "ACQ TM-Line Position X(1)"},
08925 {DCM_ACQTMLINEPOSITIONY1, DCM_UL, "ACQ TM-Line Position Y(1)"},
08926 {DCM_ACQPIXELCOMPORGANIZATION, DCM_US, "ACQ Pixel Component Organization"},
08927 {DCM_ACQPIXELCOMPMASK, DCM_UL, "ACQ Pixel Component Mask"},
08928 {DCM_ACQPIXELCOMPRANGESTART, DCM_UL, "ACQ Pixel Component Range Start"},
08929 {DCM_ACQPIXELCOMPRANGESTOP, DCM_UL, "ACQ Pixel Component Range Stop"},
08930 {DCM_ACQPIXELCOMPPHYSUNITS, DCM_US, "ACQ Pixel Component Physical Units"},
08931 {DCM_ACQPIXELCOMPDATATYPE, DCM_US, "ACQ Pixel Component Data Type"},
08932 {DCM_ACQNUMBERTABLEBREAKPOINTS, DCM_UL, "ACQ Number of Table Break Points"},
08933 {DCM_ACQTABLEXBREAKPOINTS, DCM_UL, "ACQ Table of X Break Points"},
08934 {DCM_ACQTABLEYBREAKPOINTS, DCM_FD, "ACQ Table of Y Break Points"},
08935 {DCM_ACQNUMBEROFTABLEENTRIES, DCM_UL, "ACQ Number of Table Entries"},
08936 {DCM_ACQTABLEOFPIXELVALUES, DCM_UL, "ACQ Table of Pixel Values"},
08937 {DCM_ACQTABLEOFPARAMETERVALUES, DCM_FL, "ACQ Table of Parameter Values"},
08938
08939 {0x00187000, DCM_CS, "ACQ Detector Conditions Nominal Flag"},
08940 {0x00187001, DCM_DS, "ACQ Detector Temperature"},
08941 {0x00187004, DCM_CS, "ACQ Detector Type"},
08942 {0x00187005, DCM_CS, "ACQ Detector Configuration"},
08943 {0x00187006, DCM_LT, "ACQ Detector Description"},
08944 {0x00187008, DCM_LT, "ACQ Detector Mode"},
08945 {0x0018700A, DCM_SH, "ACQ Detector ID"},
08946
08947 {0x00187028, DCM_DS, "ACQ Detector Active Origin"}
08948 };
08949
08950
08951
08952 static DCMDICT REL_dictionary[] = {
08953 {DCM_RELGROUPLENGTH, DCM_UL, "REL Group Length"},
08954 {DCM_RELSTUDYINSTANCEUID, DCM_UI, "REL Study Instance UID"},
08955 {DCM_RELSERIESINSTANCEUID, DCM_UI, "REL Series Instance UID"},
08956 {DCM_RELSTUDYID, DCM_SH, "REL Study ID"},
08957 {DCM_RELSERIESNUMBER, DCM_IS, "REL Series Number"},
08958 {DCM_RELACQUISITIONNUMBER, DCM_IS, "REL Acquisition Number"},
08959 {DCM_RELIMAGENUMBER, DCM_IS, "REL Instance Number"},
08960
08961 {DCM_RELISOTOPENUMBER, DCM_IS, "REL Isotope Number (RET)"},
08962 {DCM_RELPHASENUMBER, DCM_IS, "REL Phase Number (RET)"},
08963 {DCM_RELINTERVALNUMBER, DCM_IS, "REL Interval Number (RET)"},
08964 {DCM_RELTIMESLOTNUMBER, DCM_IS, "REL Time Slot Number (RET)"},
08965 {DCM_RELANGLENUMBER, DCM_IS, "REL Angle Number (RET)"},
08966
08967 {DCM_RELPATIENTORIENTATION, DCM_CS, "REL Patient Orientation"},
08968 {DCM_RELOVERLAYNUMBER, DCM_IS, "REL Overlay Number"},
08969 {DCM_RELCURVENUMBER, DCM_IS, "REL Curve Number"},
08970 {DCM_RELLOOKUPTABLENUMBER, DCM_IS, "REL Looup Table Number"},
08971 {DCM_RELIMAGEPOSITION, DCM_RET, "REL Image Position (RET)"},
08972 {DCM_RELIMAGEPOSITIONPATIENT, DCM_DS, "REL Image Position Patient"},
08973 {DCM_RELIMAGEORIENTATION, DCM_RET, "REL Image Orientation"},
08974 {DCM_RELIMAGEORIENTATIONPATIENT, DCM_DS, "REL Image Orientation (Patient)"},
08975 {DCM_RELLOCATION, DCM_RET, "REL Location (RET)"},
08976 {DCM_RELFRAMEOFREFERENCEUID, DCM_UI, "REL Frame of Reference UID"},
08977 {DCM_RELLATERALITY, DCM_CS, "REL Laterality"},
08978 { DCM_MAKETAG(0x0020, 0x0062), DCM_CS, "REL Image Laterality"},
08979 {DCM_RELIMAGEGEOMETRYTYPE, DCM_RET, "REL Image Geometry Type (RET)"},
08980 {DCM_RELMASKINGIMAGE, DCM_RET, "REL Masking Image (RET)"},
08981 {DCM_RELTEMPORALPOSITIONID, DCM_IS, "REL Temporal Position Identifier"},
08982 {DCM_RELNUMBERTEMPORALPOSITIONS, DCM_IS, "REL Number of Temporal Positions"},
08983 {DCM_RELTEMPORALRESOLUTION, DCM_DS, "REL Temporal Resolution"},
08984 {DCM_RELSERIESINSTUDY, DCM_IS, "REL Series in Study"},
08985 {DCM_RELACQUISITIONSINSERIES, DCM_RET, "REL Acquisitions in Series"},
08986 {DCM_RELIMAGESINACQUISITION, DCM_IS, "REL Images in Acquisition"},
08987 {DCM_RELACQUISITIONSINSTUDY, DCM_IS, "REL Acquisitions in Study"},
08988 {DCM_RELREFERENCE, DCM_RET, "REL Reference (RET)"},
08989 {DCM_RELPOSITIONREFINDICATOR, DCM_LO, "REL Position Reference Indicator"},
08990 {DCM_RELSLICELOCATION, DCM_DS, "REL Slice Location"},
08991 {DCM_RELOTHERSTUDYNUMBERS, DCM_IS, "REL Other Study Numbers"},
08992 {DCM_RELNUMBERPATRELATEDSTUDIES, DCM_IS,
08993 "REL Number of Patient Related Studies"},
08994 {DCM_RELNUMBERPATRELATEDSERIES, DCM_IS, "REL Number of Patient Related Series"},
08995 {DCM_RELNUMBERPATRELATEDIMAGES, DCM_IS, "REL Number of Patient Related Instances"},
08996 {DCM_RELNUMBERSTUDYRELATEDSERIES, DCM_IS, "REL Number of Study Related Series"},
08997 {DCM_RELNUMBERSTUDYRELATEDIMAGES, DCM_IS, "REL Number of Study Related Instances"},
08998 {DCM_RELNUMBERSERIESRELATEDINST, DCM_IS, "REL Number of Series Related Instances"},
08999 {DCM_RELSOURCEIMAGEID, DCM_RET, "REL Source Image IDs (RET)"},
09000 {DCM_RELMODIFYINGDEVICEID, DCM_RET, "REL Modifying Device ID (RET)"},
09001 {DCM_RELMODIFIEDIMAGEID, DCM_RET, "REL Modified Image ID (RET)"},
09002 {DCM_RELMODIFIEDIMAGEDATE, DCM_RET, "REL Modified Image Date (RET)"},
09003 {DCM_RELMODIFYINGDEVICEMFR, DCM_RET, "REL Modifying Device Mfr (RET)"},
09004 {DCM_RELMODIFIEDIMAGETIME, DCM_RET, "REL Modified Image Time"},
09005 {DCM_RELMODIFIEDIMAGEDESCRIPTION, DCM_RET,
09006 "REL Modified Image Description (RET)"},
09007 {DCM_RELIMAGECOMMENTS, DCM_LT, "REL Image Comments"},
09008 {DCM_RELORIGINALIMAGEID, DCM_RET, "REL Original Image ID (RET)"},
09009 {DCM_RELORIGINALIMAGEIDNOMENCLATURE, DCM_RET,
09010 "REL Orig Image ID Nomenclature (RET)"}
09011 };
09012
09013
09014
09015 static DCMDICT IMG_dictionary[] = {
09016 {DCM_IMGGROUPLENGTH, DCM_UL, "IMG Group Length"},
09017 {DCM_IMGSAMPLESPERPIXEL, DCM_US, "IMG Samples Per Pixel"},
09018 {DCM_IMGPHOTOMETRICINTERP, DCM_CS, "IMG Photometric Interpretation"},
09019 {DCM_IMGIMAGEDIMENSIONS, DCM_RET, "IMG Image Dimensions (RET)"},
09020 {DCM_IMGPLANARCONFIGURATION, DCM_US, "IMG Planar Configuration"},
09021 {DCM_IMGNUMBEROFFRAMES, DCM_IS, "IMG Number of Frames"},
09022 {DCM_IMGFRAMEINCREMENTPOINTER, DCM_AT, "IMG Frame Increment Pointer"},
09023 {DCM_IMGROWS, DCM_US, "IMG Rows"},
09024 {DCM_IMGCOLUMNS, DCM_US, "IMG Columns"},
09025 {DCM_IMGPLANES, DCM_US, "IMG Planes"},
09026 {DCM_IMGUSOUNDCOLORDATAPRESENT, DCM_US, "IMG Ultrasound Color Data Present"},
09027 {DCM_IMGPIXELSPACING, DCM_DS, "IMG Pixel Spacing"},
09028 {DCM_IMGZOOMFACTOR, DCM_DS, "IMG Zoom Factor"},
09029 {DCM_IMGZOOMCENTER, DCM_DS, "IMG Zoom Center"},
09030 {DCM_IMGPIXELASPECTRATIO, DCM_IS, "IMG Pixel Aspect Ratio"},
09031 {DCM_IMGIMAGEFORMAT, DCM_RET, "IMG Image Format (RET)"},
09032 {DCM_IMGMANIPULATEDIMAGE, DCM_RET, "IMG Manipulated Image (RET)"},
09033 {DCM_IMGCORRECTEDIMAGE, DCM_CS, "IMG Corrected Image"},
09034 {DCM_IMGCOMPRESSIONCODE, DCM_RET, "IMG Compression Code"},
09035 {DCM_IMGBITSALLOCATED, DCM_US, "IMG Bits Allocated"},
09036 {DCM_IMGBITSSTORED, DCM_US, "IMG Bits Stored"},
09037 {DCM_IMGHIGHBIT, DCM_US, "IMG High Bit"},
09038 {DCM_IMGPIXELREPRESENTATION, DCM_US, "IMG Pixel Representation"},
09039 {DCM_IMGSMALLESTPIXELVALUE, DCM_RET, "IMG Smallest Pixel Value (RET)"},
09040 {DCM_IMGLARGESTPIXELVALUE, DCM_RET, "IMG Largest Pixel Vaue (RET)"},
09041 {DCM_IMGSMALLESTIMAGEPIXELVALUE, DCM_CTX, "IMG Smallest Image Pixel Value"},
09042 {DCM_IMGLARGESTIMAGEPIXELVALUE, DCM_CTX, "IMG Largest Image Pixel Value"},
09043 {DCM_IMGSMALLESTPIXELVALUESERIES, DCM_CTX, "IMG Smallest Pixel Value in Series"},
09044 {DCM_IMGLARGESTPIXELVALUESERIES, DCM_CTX, "IMG Largest Pixel Value in Series"},
09045 {DCM_IMGSMALLESTIMAGEPIXELVALUEPLANE, DCM_CTX, "IMG Smallest Pixel Value in Plane"},
09046 {DCM_IMGLARGESTIMAGEPIXELVALUEPLANE, DCM_CTX, "IMG Largest Pixel Value in Plane"},
09047 {DCM_IMGPIXELPADDINGVALUE, DCM_CTX, "IMG Pixel Padding Value"},
09048 {DCM_IMGWAVEFORMPADDINGVALUE, DCM_CTX, "IMG Waveform Padding Value"},
09049 {DCM_IMGIMAGELOCATION, DCM_RET, "IMG Image Location"},
09050 {DCM_MAKETAG(0x0028, 0x0300), DCM_CS, "IMG Quality Control Image"},
09051 {DCM_MAKETAG(0x0028, 0x0301), DCM_CS, "IMG Burned In Annotation"},
09052 {DCM_IMGPIXELINTENSITYRELATIONSHIP, DCM_CS, "IMG Pixel Intensity Relationship"},
09053 {DCM_MAKETAG(0x0028, 0x1041), DCM_SS, "IMG Pixel Intensity Relationship Sign"},
09054 {DCM_IMGWINDOWCENTER, DCM_DS, "IMG Window Center"},
09055 {DCM_IMGWINDOWWIDTH, DCM_DS, "IMG Window Width"},
09056 {DCM_IMGRESCALEINTERCEPT, DCM_DS, "IMG Rescale Intercept"},
09057 {DCM_IMGRESCALESLOPE, DCM_DS, "IMG Rescale Slope"},
09058 {DCM_IMGRESCALETYPE, DCM_LO, "IMG Rescale Type"},
09059 {DCM_IMGWINDOWCWEXPLANATION, DCM_LO, "IMG Window Center & Width Explanation"},
09060 {DCM_IMGGRAYSCALE, DCM_RET, "IMG Gray Scale (RET)"},
09061 {DCM_IMGRECOMMENDEDVIEWINGMODE, DCM_CS, "IMG Recommended Viewing Mode"},
09062 {DCM_IMGLUTDESCRIPTGRAY, DCM_RET, "IMG Lookup Table Desc-Gray (RET)"},
09063 {DCM_IMGLUTDESCRIPTRED, DCM_US, "IMG Lookup Table Desc-Red"},
09064 {DCM_IMGLUTDESCRIPTGREEN, DCM_US, "IMG Lookup Table Desc-Green"},
09065 {DCM_IMGLUTDESCRIPTBLUE, DCM_US, "IMG Lookup Table Desc-Blue"},
09066 {DCM_IMGPALETTECOLORLUTUID, DCM_UI, "IMG Palette Color Lookup Table UID"},
09067 {DCM_IMGLOOKUPDATAGRAY, DCM_RET, "IMG Lookup Data-Gray"},
09068
09069 #if 0
09070
09071 {DCM_IMGLOOKUPDATARED, DCM_US, "IMG Lookup Data-Red"},
09072 {DCM_IMGLOOKUPDATAGREEN, DCM_US, "IMG Lookup Data-Green"},
09073 {DCM_IMGLOOKUPDATABLUE, DCM_US, "IMG Lookup Data-Blue"},
09074 #endif
09075
09076 {DCM_IMGLOOKUPDATARED, DCM_CTX, "IMG Lookup Data-Red"},
09077 {DCM_IMGLOOKUPDATAGREEN, DCM_CTX, "IMG Lookup Data-Green"},
09078 {DCM_IMGLOOKUPDATABLUE, DCM_CTX, "IMG Lookup Data-Blue"},
09079
09080 {DCM_IMGSEGMENTEDREDLUTDATA, DCM_OW, "IMG Segmented Red Palette Color LUT Data"},
09081 {DCM_IMGSEGMENTEDGREENLUTDATA, DCM_OW, "IMG Segmented Green Palette Color LUT Data"},
09082 {DCM_IMGSEGMENTEDBLUELUTDATA, DCM_OW, "IMG Segmented Blue Palette Color LUT Data"},
09083
09084 {DCM_IMGLOSSYIMAGECOMPRESSION, DCM_CS, "IMG Lossy Image Compression"},
09085 {DCM_IMGMODALITYLUTSEQUENCE, DCM_SQ, "IMG Modality LUT Sequence"},
09086 {DCM_IMGLUTDESCRIPTOR, DCM_CTX, "IMG LUT Descriptor"},
09087 {DCM_IMGLUTEXPLANATION, DCM_LO, "IMG LUT Explanation"},
09088 {DCM_IMGMODALITYLUTTYPE, DCM_LO, "IMG Modality LUT Type"},
09089 {DCM_IMGLUTDATA, DCM_CTX, "IMG LUT Data"},
09090 {DCM_IMGVOILUTSEQUENCE, DCM_SQ, "IMG VOI LUT Sequence"},
09091 {DCM_IMGCOMMENTS, DCM_RET, "IMG Comments (RET)"},
09092 {DCM_IMGBIPLANEACQSEQUENCE, DCM_SQ, "IMG Bi-Plane Acquisition Sequence"},
09093 {DCM_IMGREPRESENTATIVEFRAMENUMBER, DCM_US, "IMG Representative Frame Number"},
09094 {DCM_IMGFRAMENUMBERSOFINTEREST, DCM_US, "IMG Frame Numbers of Interest"},
09095 {DCM_IMGFRAMEOFINTERESTDESCRIPTION, DCM_LO, "IMG Frame of Interest Description"},
09096 {DCM_IMGMASKPOINTER, DCM_US, "IMG Mask Pointer(s)"},
09097 {DCM_IMGRWAVEPOINTER, DCM_US, "IMG R Wave Pointer"},
09098 {DCM_IMGMASKSUBTRACTIONSEQ, DCM_SQ, "IMG Mask Subtraction Sequence"},
09099 {DCM_IMGMASKOPERATION, DCM_CS, "IMG Mask Operation"},
09100 {DCM_IMGAPPLICABLEFRAMERANGE, DCM_US, "IMG Applicable Frame Range"},
09101 {DCM_IMGMASKFRAMENUMBERS, DCM_US, "IMG Mask Frame Numbers"},
09102 {DCM_IMGCONTRASTFRAMEAVERAGING, DCM_US, "IMG Contrast Frame Averaging"},
09103 {DCM_IMGMASKSUBPIXELSHIFT, DCM_FL, "IMG Mask Sub-pixel shift"},
09104 {DCM_IMGTIDOFFSET, DCM_SS, "IMG TID Offset"},
09105 {DCM_MASKOPERATIONEXPLANATION, DCM_ST, "IMG Mask Operation Explanation"}
09106 };
09107
09108
09109
09110 static DCMDICT SDY_dictionary[] = {
09111 {DCM_SDYGROUPLENGTH, DCM_UL, "SDY Study Group length"},
09112 {DCM_SDYSTATUSID, DCM_CS, "SDY Study Status ID"},
09113 {DCM_SDYPRIORITYID, DCM_CS, "SDY Study Priority ID"},
09114 {DCM_SDYIDISSUER, DCM_LO, "SDY Study ID Issuer"},
09115 {DCM_SDYVERIFIEDDATE, DCM_DA, "SDY Study Verified Date"},
09116 {DCM_SDYVERIFIEDTIME, DCM_TM, "SDY Study Verified Time"},
09117 {DCM_SDYREADDATE, DCM_DA, "SDY Study Read Date"},
09118 {DCM_SDYREADTIME, DCM_TM, "SDY Study Read Time"},
09119 {DCM_SDYSCHEDULEDSTARTDATE, DCM_DA, "SDY Scheduled Study Start Date"},
09120 {DCM_SDYSCHEDULEDSTARTTIME, DCM_TM, "SDY Scheduled Study Start Time"},
09121 {DCM_SDYSCHEDULEDSTOPDATE, DCM_DA, "SDY Scheduled Study Stop Date"},
09122 {DCM_SDYSCHEDULEDSTOPTIME, DCM_TM, "SDY Scheduled Study Stop Time"},
09123 {DCM_SDYSCHEDULEDLOCATION, DCM_LO, "SDY Scheduled Study Location"},
09124 {DCM_SDYSCHEDULEDLOCATIONAETITLE, DCM_AE,
09125 "SDY Scheduled Study Location AE Title(s)"},
09126 {DCM_SDYREASON, DCM_LO, "SDY Study Reason"},
09127 {DCM_SDYREQUESTINGPHYSICIAN, DCM_PN, "SDY Requesting Physician "},
09128 {DCM_SDYREQUESTINGSERVICE, DCM_LO, "SDY Requesting Service"},
09129 {DCM_SDYARRIVALDATE, DCM_DA, "SDY Study Arrival Date"},
09130 {DCM_SDYARRIVALTIME, DCM_TM, "SDY Study Arrival Time"},
09131 {DCM_SDYCOMPLETIONDATE, DCM_DA, "SDY Study Completion Date"},
09132 {DCM_SDYCOMPLETIONTIME, DCM_TM, "SDY Study Completion Time"},
09133 {DCM_SDYSTUDYCOMPONENTSTATUSID, DCM_CS, "SDY Study Component Status ID"},
09134 {DCM_SDYREQUESTEDPRODESCRIPTION, DCM_LO, "SDY Requested Procedure Description"},
09135 {DCM_SDYREQUESTEDPROCODESEQ, DCM_SQ, "SDY Requested Procedure Code Seq"},
09136 {DCM_SDYREQUESTEDCONTRASTAGENT, DCM_LO, "SDY Requested Contrast Agent"},
09137 {DCM_SDYCOMMENTS, DCM_LT, "SDY Comments"}
09138 };
09139
09140
09141
09142 static DCMDICT VIS_dictionary[] = {
09143 {DCM_VISGROUPLENGTH, DCM_UL, "VIS Group Length"},
09144 {DCM_VISREFERENCEDPATALIASSEQ, DCM_SQ, "VIS Referenced Patient Alias Sequence"},
09145 {DCM_VISSTATUSID, DCM_CS, "VIS Visit Status ID"},
09146 {DCM_VISADMISSIONID, DCM_LO, "VIS Admission ID"},
09147 {DCM_VISISSUEROFADMISSIONID, DCM_LO, "VIS Issuer of Admission ID"},
09148 {DCM_VISROUTEOFADMISSION, DCM_LO, "VIS Route of Admission"},
09149 {DCM_VISSCHEDULEDADMISSIONDATE, DCM_DA, "VIS Scheduled Admission Date"},
09150 {DCM_VISSCHEDULEDADMISSIONTIME, DCM_TM, "VIS Scheduled Admission Time"},
09151 {DCM_VISSCHEDULEDDISCHARGEDATE, DCM_DA, "VIS Scheduled Discharge Date"},
09152 {DCM_VISSCHEDULEDDISCHARGETIME, DCM_TM, "VIS Scheduled Discharge Time"},
09153 {DCM_VISSCHEDULEDPATINSTRESIDENCE, DCM_LO, "VIS Scheduled Patient Institution Residence"},
09154 {DCM_VISADMITTINGDATE, DCM_DA, "VIS Admitting Date"},
09155 {DCM_VISADMITTINGTIME, DCM_TM, "VIS Admitting Time"},
09156 {DCM_VISDISCHARGEDATE, DCM_DA, "VIS Discharge Date"},
09157 {DCM_VISDISCHARGETIME, DCM_TM, "VIS Discharge Time"},
09158 {DCM_VISDISCHARGEDIAGDESCRIPTION, DCM_LO, "VIS Discharge Diagnosis Description"},
09159 {DCM_VISDISCHARGEDIAGNOSISCODESEQ, DCM_SQ, "VIS Discharge Diagnosis Code Sequence"},
09160 {DCM_VISSPECIALNEEDS, DCM_LO, "VIS Special Needs"},
09161 {DCM_VISCURRENTPATIENTLOCATION, DCM_LO, "VIS Current Patient Location"},
09162 {DCM_VISPATIENTSINSTRESIDENCE, DCM_LO, "VIS Patient's Institution Residence"},
09163 {DCM_VISPATIENTSTATE, DCM_LO, "VIS Patient State"},
09164 {DCM_VISCOMMENTS, DCM_LT, "VIS Comments"}
09165 };
09166
09167
09168
09169 static DCMDICT WAV_dictionary[] = {
09170 {DCM_MAKETAG(0x003a, 0x0000), DCM_UL, "WAV Group Length"},
09171 {DCM_MAKETAG(0x003a, 0x0002), DCM_SQ, "WAV Waveform Sequence"},
09172 {DCM_MAKETAG(0x003a, 0x0005), DCM_US, "WAV Number of Channels"},
09173 {DCM_MAKETAG(0x003a, 0x0010), DCM_UL, "WAV Number of Samples"},
09174 {DCM_MAKETAG(0x003a, 0x001a), DCM_DS, "WAV Sampling Frequency"},
09175 {DCM_MAKETAG(0x003a, 0x0020), DCM_SH, "WAV Group Label"},
09176 {DCM_MAKETAG(0x003a, 0x0103), DCM_CS, "WAV Data Value Representation"},
09177 {DCM_MAKETAG(0x003a, 0x0200), DCM_SQ, "WAV Channel Definition"},
09178 {DCM_MAKETAG(0x003a, 0x0202), DCM_IS, "WAV Channel Number"},
09179 {DCM_MAKETAG(0x003a, 0x0203), DCM_SH, "WAV Channel Label"},
09180 {DCM_MAKETAG(0x003a, 0x0205), DCM_CS, "WAV Channel Status"},
09181 {DCM_MAKETAG(0x003a, 0x0208), DCM_SQ, "WAV Waveform Source"},
09182 {DCM_MAKETAG(0x003a, 0x0209), DCM_SQ, "WAV Waveform Source Modifiers"},
09183 {DCM_MAKETAG(0x003a, 0x020a), DCM_SQ, "WAV Differential Waveform Source"},
09184 {DCM_MAKETAG(0x003a, 0x020b), DCM_SQ, "WAV Differential Waveform Source Modifiers"},
09185 {DCM_MAKETAG(0x003a, 0x0210), DCM_DS, "WAV Channel Sensitivity"},
09186 {DCM_MAKETAG(0x003a, 0x0211), DCM_SQ, "WAV Channel Sensitivity Units"},
09187 {DCM_MAKETAG(0x003a, 0x0212), DCM_DS, "WAV Channel Sensitivity Correction Factor"},
09188 {DCM_MAKETAG(0x003a, 0x0213), DCM_DS, "WAV Channel Baseline"},
09189 {DCM_MAKETAG(0x003a, 0x0214), DCM_DS, "WAV Channel Time Skew"},
09190 {DCM_MAKETAG(0x003a, 0x0215), DCM_DS, "WAV Channel Sample Skew"},
09191 {DCM_MAKETAG(0x003a, 0x0218), DCM_DS, "WAV Channel Offset"},
09192 {DCM_MAKETAG(0x003a, 0x021a), DCM_US, "WAV Bits Per Sample"},
09193 {DCM_MAKETAG(0x003a, 0x0216), DCM_CTX, "WAV Channel Minimum Value"},
09194 {DCM_MAKETAG(0x003a, 0x0217), DCM_CTX, "WAV Channel Maximum Value"},
09195 {DCM_MAKETAG(0x003a, 0x0220), DCM_DS, "WAV Filter Low Frequency"},
09196 {DCM_MAKETAG(0x003a, 0x0221), DCM_DS, "WAV Filter High Frequency"},
09197 {DCM_MAKETAG(0x003a, 0x0222), DCM_DS, "WAV Notch Filter Frequency"},
09198 {DCM_MAKETAG(0x003a, 0x0223), DCM_DS, "WAV Notch Filter Bandwidth"},
09199 {DCM_MAKETAG(0x003a, 0x1000), DCM_CTX, "WAV Waveform Data"}
09200 };
09201
09202
09203
09204
09205 static DCMDICT PRC_dictionary[] = {
09206 {DCM_PRCGROUPLENGTH, DCM_UL, "PRC Group Length"},
09207 {DCM_PRCSCHEDULEDSTATIONAETITLE, DCM_AE, "PRC Scheduled Station AE Title"},
09208 {DCM_PRCSCHEDULEDPROCSTEPSTARTDATE, DCM_DA, "PRC Scheduled Procedure Step Start Date"},
09209 {DCM_PRCSCHEDULEDPROCSTEPSTARTTIME, DCM_TM, "PRC Scheduled Procedure Step Start Time"},
09210 {DCM_PRCSCHEDULEDPROCSTEPENDDATE, DCM_DA, "PRC Scheduled Procedure Step End Date"},
09211 {DCM_PRCSCHEDULEDPROCSTEPENDTIME, DCM_TM, "PRC Scheduled Procedure Step End Time"},
09212 {DCM_PRCSCHEDULEDPERFORMINGPHYSNAME, DCM_PN, "PRC Scheduled Performing Physician's Name"},
09213 {DCM_PRCSCHEDULEDPROCSTEPDESCRIPTION, DCM_LO, "PRC Scheduled Step Description"},
09214 {DCM_PRCSCHEDULEDACTIONITEMCODESEQ, DCM_SQ, "PRC Scheduled Action Item Code Sequence"},
09215 {DCM_PRCSCHEDULEDPROCSTEPID, DCM_SH, "PRC Scheduled Procedure Step ID"},
09216 {DCM_PRCSCHEDULEDSTATIONNAME, DCM_SH, "PRC Scheduled Station Name"},
09217 {DCM_PRCSCHEDULEDPROCSTEPLOCATION, DCM_SH, "PRC Scheduled Procedure Step Location"},
09218 {DCM_PRCPREMEDICATION, DCM_LO, "PRC Pre-Medication"},
09219 {DCM_PRCSTATUS, DCM_CS, "PRC SPStep Status"},
09220 {DCM_PRCREFSTANDALONESOPSEQ, DCM_SQ, "PRC Ref Standalone SOP Inst Seq"},
09221 {DCM_PRCPERFORMEDSTATIONAET, DCM_AE, "PRC Performed Station AE Title"},
09222 {DCM_PRCPERFORMEDSTATIONNAME, DCM_SH, "PRC Performed Station Name"},
09223 {DCM_PRCPERFORMEDLOCATION, DCM_SH, "PRC Performed Location"},
09224 {DCM_PRCPPSSTARTDATE, DCM_DA, "PRC PPS Start Date"},
09225 {DCM_PRCPPSSTARTTIME, DCM_TM, "PRC PPS Start Time"},
09226 {DCM_PRCPPSENDDATE, DCM_DA, "PRC PPS End Date"},
09227 {DCM_PRCPPSENDTIME, DCM_TM, "PRC PPS End Time"},
09228 {DCM_PRCPPSSTATUS, DCM_CS, "PRC PPS Status"},
09229 #if 0
09230 {DCM_PRCPPSID, DCM_CS, "PRC PPS ID"},
09231 #else
09232 {DCM_PRCPPSID, DCM_SH, "PRC PPS ID"},
09233 #endif
09234 {DCM_PRCPPSDESCRIPTION, DCM_LO, "PRC PPS Description"},
09235 {DCM_PRCPPTYPEDESCRIPTION, DCM_LO, "PRC Perf Procedure Type Description"},
09236 {DCM_PRCPERFORMEDAISEQUENCE, DCM_SQ, "PRC Perf AI Sequence"},
09237 {DCM_PRCSCHEDSTEPATTRSEQ, DCM_SQ, "PRC Scheduled Step Attr Seq"},
09238 {DCM_PRCREQUESTATTRIBUTESSEQ, DCM_SQ, "PRC Request Attributes Seq"},
09239 {DCM_PRCCOMMENTSPPS, DCM_ST, "PRC Comments on PPS"},
09240 {DCM_PRCQUANTITYSEQ, DCM_SQ, "PRC Quantity Sequence"},
09241 {DCM_PRCQUANTITY, DCM_DS, "PRC Quantity"},
09242 {DCM_PRCMEASURINGUNITSSEQ, DCM_SQ, "PRC Measuring Units Sequence"},
09243 {DCM_PRCBILLINGITEMSEQ, DCM_SQ, "PRC Billing Item Seq"},
09244 {DCM_PRCTOTALTIMEFLUOROSCOPY, DCM_US, "PRC Total Time Fluoroscopy"},
09245 {DCM_PRCTOTALNUMBEREXPOSURES, DCM_US, "PRC Total Number Exposures"},
09246 {DCM_PRCENTRANCEDOSE, DCM_US, "PRC Entrance Dose"},
09247 {DCM_PRCEXPOSEDAREA, DCM_US, "PRC Exposed Area"},
09248 {DCM_PRCDISTANCESOURCEENTRANCE, DCM_DS, "PRC Distance Source to Entrance"},
09249 {DCM_PRCCOMMENTSRADIATIONDOSE, DCM_ST, "PRC Comments on Radiation Dose"},
09250
09251 {0x00400312, DCM_DS, "PRC X-Ray Output"},
09252 {0x00400314, DCM_DS, "PRC Half Value Layer"},
09253 {0x00400316, DCM_DS, "PRC Organ Dose"},
09254 {0x00400318, DCM_CS, "PRC Organ Exposed"},
09255
09256 {DCM_PRCBILLINGPROCEDURESTEPSEQ, DCM_SQ, "PRC Billing Proc Step Seq"},
09257 {DCM_PRCFILMCONSUMPTIONSEQ, DCM_SQ, "PRC Film Consumption Seq"},
09258 {DCM_PRCBILLINGSUPPLIESDEVICESEQ, DCM_SQ, "PRC Billing Supplies/Devices Seq"},
09259 {DCM_PRCREFERENCEDPPS, DCM_SQ, "PRC Ref Procedure Step Seq"},
09260 {DCM_PRCPERFORMEDSERIESSEQ, DCM_SQ, "PRC Performed Series Seq"},
09261 {DCM_PRCSCHEDULEDPROCSTEPSEQ, DCM_SQ, "PRC Scheduled Procedure Step Sequence"},
09262 {DCM_PRCCOMMENTSONSCHEDULEDPROCSTEP, DCM_LT, "PRC Comments on the Scheduled Procedure Step"},
09263 {DCM_MAKETAG(0x0040, 0x050a), DCM_LO, "PRC Specimen Accession Number"},
09264 {DCM_MAKETAG(0x0040, 0x0550), DCM_SQ, "PRC Specimen Sequence"},
09265 {DCM_MAKETAG(0x0040, 0x0551), DCM_LO, "PRC Specimen Identifier"},
09266 {DCM_MAKETAG(0x0040, 0x0552), DCM_SQ, "PRC Specimen Description Sequence"},
09267 {DCM_MAKETAG(0x0040, 0x0553), DCM_ST, "PRC Specimen Description"},
09268 {DCM_MAKETAG(0x0040, 0x0555), DCM_SQ, "PRC Acquisition Context Sequence"},
09269 {DCM_MAKETAG(0x0040, 0x0556), DCM_ST, "PRC Acquisition Context Description"},
09270 {DCM_MAKETAG(0x0040, 0x059a), DCM_SQ, "PRC Specimen Type Code Sequence"},
09271 {DCM_MAKETAG(0x0040, 0x06fa), DCM_LO, "PRC Slide Identifier"},
09272 {DCM_MAKETAG(0x0040, 0x071a), DCM_SQ, "PRC Image Center Point Coordinates Sequence"},
09273 {DCM_MAKETAG(0x0040, 0x072a), DCM_DS, "PRC X offset in Slide Coordinate System"},
09274 {DCM_MAKETAG(0x0040, 0x073a), DCM_DS, "PRC Y offset in Slide Coordinate System"},
09275 {DCM_MAKETAG(0x0040, 0x074a), DCM_DS, "PRC Z offset in Slide Coordinate System"},
09276 {DCM_MAKETAG(0x0040, 0x08d8), DCM_SQ, "PRC Pixel Spacing Sequence"},
09277 {DCM_MAKETAG(0x0040, 0x08da), DCM_SQ, "PRC Coordinate System Axis Code Sequence"},
09278 {DCM_MAKETAG(0x0040, 0x08ea), DCM_SQ, "PRC Measurement Units Code Sequence"},
09279 {DCM_MAKETAG(0x0040, 0x09f8), DCM_SQ, "PRC Vital Stain Code Sequence"},
09280 {DCM_PRCREQUESTEDPROCEDUREID, DCM_SH, "PRC Requested Procedure ID"},
09281 {DCM_PRCREASONFORREQUESTEDPROC, DCM_LO, "PRC Reason for the Requested Procedure"},
09282 {DCM_PRCREQUESTEDPROCPRIORITY, DCM_SH, "PRC Patient Transport Arrangements"},
09283 {DCM_PRCPATIENTTRANSPORTARRANGEMENTS, DCM_LO, "PRC Patient Transport Arrangements"},
09284 {DCM_PRCREQUESTEDPROCLOCATION, DCM_LO, "PRC Requested Procedure Location"},
09285 {DCM_PRCPLACERORDERNUMBERPROC, DCM_SH, "PRC Placer Order Number / Procedure"},
09286
09287 {DCM_PRCFILLERORDERNUMBERPROC, DCM_SH, "PRC Filler Order Number / Procedure"},
09288 {DCM_PRCCONFIDENTIALITYCODE, DCM_LO, "PRC Confidentiality Code"},
09289 {DCM_PRCREPORTINGPRIORITY, DCM_SH, "PRC Reporting Priority"},
09290 {DCM_PRCNAMESINTENDEDRECIPIENTSRESULTS, DCM_PN, "PRC Names of Intended Recipients of Results"},
09291 {DCM_PRCREQUESTEDPROCCOMMENTS, DCM_LT, "PRC Requested Procedure Comments"},
09292 {DCM_PRCREASONFORIMAGINGSERVICEREQ, DCM_LO, "PRC Reason for the Imaging Service Request"},
09293 {DCM_PRCISSUEDATEIMAGINGSERVICEREQ, DCM_DA, "PRC Issue Date of Imaging Service Request"},
09294 {DCM_PRCISSUETIMEIMAGINGSERVICEREQ, DCM_TM, "PRC Issue Time of Imaging Service Request"},
09295 {DCM_PRCPLACERORDERNUMBERIMAGINGSRVREQ, DCM_SH, "PRC Placer Order Number/Imaging Service Request"},
09296 {DCM_PRCFILLERORDERNUMBERIMAGINGSRVREQ, DCM_SH, "PRC Filler Order Number/Imaging Service Request"},
09297 {DCM_PRCORDERENTEREDBY, DCM_PN, "PRC Order Entered By"},
09298 {DCM_PRCORDERENTERERSLOCATION, DCM_SH, "PRC Order Enterer's Location"},
09299 {DCM_PRCORDERCALLBACKPHONENUMBER, DCM_SH, "PRC Order Callback Phone Number"},
09300 {DCM_MAKETAG(0x0040, 0x2016), DCM_LO, "PRC Placer Order Number/ISR"},
09301 {DCM_MAKETAG(0x0040, 0x2017), DCM_LO, "PRC Filler Order Number/ISR"},
09302
09303 {DCM_PRCIMAGINGSERVICEREQCOMMENTS, DCM_LT, "PRC Imaging Service Request Comments"},
09304 {DCM_PRCCONFIDIENTIALITYCONSTRAINTPATIENTDATADES, DCM_LO, "PRC Confidientiality Constraint Patient Data..."},
09305
09306 {DCM_PRCGPSPSSTATUS, DCM_CS, "PRC General Purpose Sched Procedure Step Status"},
09307 {DCM_PRCGPPPSSTATUS, DCM_CS, "PRC Gen. Purpose Perf Procedure Step Status"},
09308 {DCM_PRCGPSPSPRIORITY, DCM_CS, "PRC Gen. Purpose Sched Procedure Step Priority"},
09309 {DCM_PRCSCHEDULEDPROCAPPCODESEQ, DCM_SQ, "PRC Scheduled Proccessing Application Code Seq"},
09310 {DCM_PRCGPSPSSTARTDATETIME, DCM_DT, "PRC Sched Procedure Step Start Date and Time"},
09311 {DCM_PRCGPSPSMULTIPLECOPIESFLAG, DCM_CS, "PRC Multiple Copies Flag"},
09312 {DCM_PRCPERFORMEDPROCAPPCODESEQ, DCM_SQ, "PRC Performed Proccessing Applications Code Seq"},
09313 {DCM_PRCHUMANPERFORMERCODESEQ, DCM_SQ, "PRC Human Performer Code Sequence"},
09314 {DCM_PRCGPSPSEXPECTEDCOMPLETEDATETIME, DCM_DT, "PRC Expected Completion Date and Time"},
09315 {DCM_PRCRESULTINGGPPERFPROCSTEPSEQ, DCM_SQ, "PRC Resulting Gen Purpose Perf Proc Steps Seq"},
09316 {DCM_PRCREFERENCEDGPSCHEDPROCSTEPSEQ, DCM_SQ, "PRC Referenced Gen Purp Sched Proc Steps Seq"},
09317 {DCM_PRCSCHEDWORKITEMCODESEQ, DCM_SQ, "PRC Scheduled Workitem Code Sequence"},
09318 {DCM_PRCPERFORMEDWORKITEMCODESEQ, DCM_SQ, "PRC Performed Workitem Code Sequence"},
09319 {DCM_PRCINPUTAVAILFLAG, DCM_CS, "PRC Input Availability Flag"},
09320 {DCM_PRCINPUTINFOSEQ, DCM_SQ, "PRC Input Information Sequence"},
09321 {DCM_PRCRELEVANTINFOSEQ, DCM_SQ, "PRC Relevant Information Sequence"},
09322 {DCM_PRCREFERENCEDGPSPSTRANSACTIONUID, DCM_UI, "PRC Referenced Gen Purp SPS Transaction UID"},
09323 {DCM_PRCSCHEDSTATIONNAMECODESEQ, DCM_SQ, "PRC Scheduled Station Name Code Sequence"},
09324 {DCM_PRCSCHEDSTATIONCLASSCODESEQ, DCM_SQ, "PRC Scheduled Station Class Code Sequence"},
09325 {DCM_PRCSCHEDSTATIONLOCCODESEQ, DCM_SQ, "PRC Sched Station Geographic Location Code Seq"},
09326 {DCM_PRCPERFORMEDSTATIONNAMECODESEQ, DCM_SQ, "PRC Performed Station Name Code Seq"},
09327 {DCM_PRCPERFORMEDSTATIONCLASSCODESEQ, DCM_SQ, "PRC Performed Station Class Code Sequence"},
09328 {DCM_PRCPERFORMEDSTATIONLOCCODESEQ, DCM_SQ, "PRC Perf Station Geographic Location Code Seq"},
09329 {DCM_PRCREQSUBSWORKITEMCODESEQ, DCM_SQ, "PRC Requested Subsequent Workitem Code Sequence"},
09330 {DCM_PRCNONDICOMOUTPUTCODESEQ, DCM_SQ, "PRC Non-DICOM Output Code Sequence"},
09331 {DCM_PRCOUTPUTINFOSEQ, DCM_SQ, "PRC Output Information Sequence"},
09332 {DCM_PRCSCHEDHUMANPERFORMERSSEQ, DCM_SQ, "PRC Scheduled Human Performers Sequence"},
09333 {DCM_PRCHUMANPERFORMERSORG, DCM_LO, "PRC Human Performer's Organization"},
09334 {DCM_PRCHUMANPERFORMERSNAME, DCM_PN, "PRC Human Performer's Name"},
09335
09336
09337 {DCM_MAKETAG(0x0040, 0xa010), DCM_CS, "PRC Relationship Type"},
09338 {DCM_MAKETAG(0x0040, 0xa027), DCM_LO, "PRC Verifying Organization"},
09339 {DCM_MAKETAG(0x0040, 0xa030), DCM_DT, "PRC Verification DateTime"},
09340 {DCM_MAKETAG(0x0040, 0xa032), DCM_DT, "PRC Observation DateTime"},
09341 {DCM_MAKETAG(0x0040, 0xa040), DCM_CS, "PRC Value Type"},
09342
09343 {DCM_MAKETAG(0x0040, 0xa043), DCM_SQ, "PRC Concept-name Code Sequence"},
09344 {DCM_MAKETAG(0x0040, 0xa050), DCM_CS, "PRC Continuity of Content"},
09345 {DCM_MAKETAG(0x0040, 0xa073), DCM_SQ, "PRC Verifying Observer Sequence"},
09346 {DCM_MAKETAG(0x0040, 0xa075), DCM_PN, "PRC Verifying Observer Name"},
09347 {DCM_MAKETAG(0x0040, 0xa088), DCM_SQ, "PRC Verifying Observer Identification Code Seq"},
09348 {DCM_MAKETAG(0x0040, 0xa0a0), DCM_CS, "PRC Referenced Type of Data"},
09349 {DCM_MAKETAG(0x0040, 0xa0b0), DCM_US, "PRC Referenced Waveform Channels"},
09350 {DCM_MAKETAG(0x0040, 0xa120), DCM_DT, "PRC Date Time"},
09351 {DCM_MAKETAG(0x0040, 0xa121), DCM_DA, "PRC Date"},
09352 {DCM_MAKETAG(0x0040, 0xa122), DCM_TM, "PRC Time"},
09353 {DCM_MAKETAG(0x0040, 0xa123), DCM_PN, "PRC Person Name"},
09354 {DCM_MAKETAG(0x0040, 0xa124), DCM_UI, "PRC UID"},
09355 {DCM_MAKETAG(0x0040, 0xa130), DCM_CS, "PRC Temporal Range Type"},
09356 {DCM_MAKETAG(0x0040, 0xa132), DCM_UL, "PRC Referenced Sample Offsets"},
09357 {DCM_MAKETAG(0x0040, 0xa138), DCM_DS, "PRC Referenced Time Offsets"},
09358 {DCM_MAKETAG(0x0040, 0xa13a), DCM_DT, "PRC Referenced Datetime"},
09359 {DCM_MAKETAG(0x0040, 0xa160), DCM_UT, "PRC Text Value"},
09360 {DCM_MAKETAG(0x0040, 0xa168), DCM_SQ, "PRC Concept Code Sequence"},
09361 {DCM_MAKETAG(0x0040, 0xa16a), DCM_ST, "PRC Bibliographics Citation"},
09362 {DCM_MAKETAG(0x0040, 0xa180), DCM_US, "PRC Annotation Group Number"},
09363 {DCM_MAKETAG(0x0040, 0xa195), DCM_SQ, "PRC Concept-name Code Sequence Modifier"},
09364
09365 {DCM_MAKETAG(0x0040, 0xa300), DCM_SQ, "PRC Measured Value Sequence"},
09366 {DCM_MAKETAG(0x0040, 0xa30a), DCM_DS, "PRC Numeric Value"},
09367 {DCM_MAKETAG(0x0040, 0xa353), DCM_ST, "PRC Address"},
09368 {DCM_MAKETAG(0x0040, 0xa354), DCM_LO, "PRC Telephone Number"},
09369 {DCM_MAKETAG(0x0040, 0xa360), DCM_SQ, "PRC Predecessor Documents Sequence"},
09370 {DCM_MAKETAG(0x0040, 0xa370), DCM_SQ, "PRC Referenced Request Sequence"},
09371 {DCM_MAKETAG(0x0040, 0xa372), DCM_SQ, "PRC Performed Procedure Code Sequence"},
09372 {DCM_MAKETAG(0x0040, 0xa375), DCM_SQ, "PRC Current Reqeusted Procedure Evidence Seq"},
09373 {DCM_MAKETAG(0x0040, 0xa385), DCM_SQ, "PRC Pertinent Other Evidence Sequence"},
09374 {DCM_MAKETAG(0x0040, 0xa491), DCM_CS, "PRC Completion Flag"},
09375 {DCM_MAKETAG(0x0040, 0xa492), DCM_LO, "PRC Completion Flag Description"},
09376 {DCM_MAKETAG(0x0040, 0xa493), DCM_CS, "PRC Verification Flag"},
09377 {DCM_MAKETAG(0x0040, 0xa504), DCM_SQ, "PRC Content Template Sequence"},
09378 {DCM_MAKETAG(0x0040, 0xa525), DCM_SQ, "PRC Identical Documents Sequence"},
09379 {DCM_MAKETAG(0x0040, 0xa730), DCM_SQ, "PRC Content Sequence"},
09380 {DCM_MAKETAG(0x0040, 0xa992), DCM_ST, "PRC Uniform Resource Locator"},
09381 {DCM_MAKETAG(0x0040, 0xb020), DCM_SQ, "PRC Annotation Sequence"},
09382 {DCM_MAKETAG(0x0040, 0xadb00), DCM_CS, "PRC Template Identifier"},
09383 {DCM_MAKETAG(0x0040, 0xadb06), DCM_DT, "PRC Template Version"},
09384 {DCM_MAKETAG(0x0040, 0xadb07), DCM_DT, "PRC Template Local Version"},
09385 {DCM_MAKETAG(0x0040, 0xadb0b), DCM_CS, "PRC Template Extension Flag"},
09386 {DCM_MAKETAG(0x0040, 0xadb0c), DCM_UI, "PRC Template Extension Organization UID"},
09387 {DCM_MAKETAG(0x0040, 0xadb0d), DCM_UI, "PRC Template Extension Creator UID"},
09388 {DCM_MAKETAG(0x0040, 0xadb73), DCM_UL, "PRC Referenced Content Item Identifier"}
09389 };
09390
09391
09392
09393 static DCMDICT DEV_dictionary[] = {
09394 {DCM_DEVCALIBRATIONOBJECT, DCM_CS, "DEV Calibration Object"},
09395 {DCM_DEVDEVICESEQUENCE, DCM_SQ, "DEV Device Sequence"},
09396 {DCM_DEVDEVICELENGTH, DCM_DS, "DEV Device Length"},
09397 {DCM_DEVDEVICEDIAMETER, DCM_DS, "DEV Device Diameter"},
09398 {DCM_DEVDEVICEDIAMETERUNITS, DCM_CS, "DEV Device Diameter Units"},
09399 {DCM_DEVDEVICEVOLUME, DCM_DS, "DEV Device Volume"},
09400 {DCM_DEVINTERMARKERDISTANCE, DCM_DS, "DEV Inter-Marker Distance"},
09401 {DCM_DEVDEVICEDESCRIPTION, DCM_LO, "DEV Device Description"},
09402 };
09403
09404
09405
09406 static DCMDICT RES_dictionary[] = {
09407 {DCM_RESGROUPLENGTH, DCM_UL, "RES Group Length"},
09408 {DCM_RESID, DCM_SH, "RES Results ID"},
09409 {DCM_RESIDISSUER, DCM_LO, "RES Results ID Issuer"},
09410 {DCM_RESREFERENCEDINTERPSEQ, DCM_SQ, "RES Referenced Interpretation Sequence"},
09411 {DCM_RESINTERPRECORDEDDATE, DCM_DA, "RES Interpretation Recorded Date"},
09412 {DCM_RESINTERPRECORDEDTIME, DCM_TM, "RES Interpretation Recorded Time"},
09413 {DCM_RESINTERPRECORDER, DCM_PN, "RES Interpretation Recorder"},
09414 {DCM_RESREFERENCETORECORDEDSOUND, DCM_LO, "RES Reference to Recorded Sound"},
09415 {DCM_RESINTERPTRANSCRIPTIONDATE, DCM_DA, "RES Interpretation Transcription Date"},
09416 {DCM_RESINTERPTRANSCRIPTIONTIME, DCM_TM, "RES Interpretation Transcription Time"},
09417 {DCM_RESINTERPTRANSCRIBER, DCM_PN, "RES Interpretation Transcriber"},
09418 {DCM_RESINTERPTEXT, DCM_ST, "RES Interpretation Text"},
09419 {DCM_RESINTERPAUTHOR, DCM_PN, "RES Interpretation Author"},
09420 {DCM_RESINTERPAPPROVERSEQUENCE, DCM_SQ, "RES Interpretation Approver Sequence"},
09421 {DCM_RESINTERPAPPROVALDATE, DCM_DA, "RES Interpretation Approval Date"},
09422 {DCM_RESINTERPAPPROVALTIME, DCM_TM, "RES Interpretation Approval Time"},
09423 {DCM_RESPHYSICIANAPPROVINGINTERP, DCM_PN, "RES Physician Approving Interpretation"},
09424 {DCM_RESDIAGNOSIS, DCM_LT, "RES Diagnosis"},
09425 {DCM_RESDIAGNOSISCODESEQ, DCM_SQ, "RES Diagnosis Code Sequence"},
09426 {DCM_RESDISTRIBUTIIONLISTSEQUENCE, DCM_SQ, "RES Results Distribution List Sequence"},
09427 {DCM_RESDISTRIBUTIONNAME, DCM_PN, "RES Distribution Name"},
09428 {DCM_RESDISTRIBUTIONADDRESS, DCM_LO, "RES Distribution Address"},
09429 {DCM_RESINTERPID, DCM_SH, "RES Interpretation ID"},
09430 {DCM_RESINTERPIDISSUER, DCM_LO, "RES Interpretation ID Issuer"},
09431 {DCM_RESINTERPTYPEID, DCM_CS, "RES Interpretation Type ID"},
09432 {DCM_RESINTERPSTATUSID, DCM_CS, "RES Interpretation Status ID"},
09433 {DCM_RESIMPRESSIONS, DCM_ST, "RES Impressions"},
09434 {DCM_RESCOMMENTS, DCM_ST, "RES Comments"}
09435 };
09436
09437
09438 static DCMDICT CRV_dictionary[] = {
09439 {DCM_CURVEGROUPLENGTH, DCM_UL, "CRV Group Length"},
09440 {DCM_CURVEDIMENSIONS, DCM_US, "CRV Curve Dimensions"},
09441 {DCM_CURVENUMBEROFPOINTS, DCM_US, "CRV Number of points"},
09442 {DCM_CURVETYPEOFDATA, DCM_CS, "CRV Type of Data"},
09443 {DCM_CURVEDESCRIPTION, DCM_LO, "CRV Curve Description"},
09444 {DCM_CURVEAXISUNITS, DCM_SH, "CRV Axis Units"},
09445 {DCM_CURVEAXISLABELS, DCM_SH, "CRV Axis Labels"},
09446 {DCM_CURVEDATAVALUEREPRESENTATION, DCM_US, "CRV Data Value Representation"},
09447 {DCM_CURVEMINCOORDINATEVALUE, DCM_US, "CRV Minimum Coordinate Value"},
09448 {DCM_CURVEMAXCOORDINATEVALUE, DCM_US, "CRV Maximum Coordinate Value"},
09449 {DCM_CURVERANGE, DCM_SH, "CRV Curve Range"},
09450 {DCM_CURVEDATADESCRIPTOR, DCM_US, "CRV Data Descriptor"},
09451 {DCM_CURVECOORDINATESTARTVALUE, DCM_US, "CRV Coordinate Start Value"},
09452 {DCM_CURVECOORDINATESTEPVALUE, DCM_US, "CRV Coordinate Step Value"},
09453 {DCM_CURVEAUDIOTYPE, DCM_US, "CRV Audio Type"},
09454 {DCM_CURVEAUDIOSAMPLEFORMAT, DCM_US, "CRV Audio Sample Format"},
09455 {DCM_CURVENUMBEROFCHANNELS, DCM_US, "CRV Number of Channels"},
09456 {DCM_CURVENUMBEROFSAMPLES, DCM_UL, "CRV Number of Samples"},
09457 {DCM_CURVESAMPLERATE, DCM_UL, "CRV Sample Rate"},
09458 {DCM_CURVETOTALTIME, DCM_UL, "CRV Total Time"},
09459 {DCM_CURVEAUDIOSAMPLEDATA, DCM_OW, "CRV Audio Sample Data"},
09460 {DCM_CURVEAUDIOCOMMENTS, DCM_LT, "CRV Audio Comments"},
09461 {DCM_CURVELABEL, DCM_LO, "CRV Curve Label"},
09462 {DCM_CURVEREFOVERLAYSEQUENCE, DCM_SQ, "CRV Referenced Overlay Sequence"},
09463 {DCM_CURVEREFOVERLAYGROUP, DCM_US, "CRV Referenced Overlay Group"},
09464 {DCM_CURVEDATA, DCM_OW, "CRV Curve Data"}
09465 };
09466
09467
09468 static DCMDICT NMI_dictionary[] = {
09469 {DCM_NMIGROUPLENGTH, DCM_UL, "NMI Group Length"},
09470 {DCM_NMIENERGYWINDOWVECTOR, DCM_US, "NMI Energy Window Vector"},
09471 {DCM_NMINUMBEROFENERGYWINDOWS, DCM_US, "NMI Number of Energy Windows"},
09472 {DCM_NMIENERGYWINDOWINFOSEQ, DCM_SQ, "NMI Energy Window Information Sequence"},
09473 {DCM_NMIENERGYWINDOWRANGESEQ, DCM_SQ, "NMI Energy Window Range Sequence"},
09474 {DCM_NMIENERGYWINDOWLOWERLIMIT, DCM_DS, "NMI Energy Window Lower Limit"},
09475 {DCM_NMIENERGYWINDOWUPPERLIMIT, DCM_DS, "NMI Energy Window Upper Limit"},
09476 {DCM_NMIRADIOPHARMINFOSEQ, DCM_SQ, "NMI Radiopharmaceutical Information Sequence"},
09477 {DCM_NMIRESIDUALSYRINGECOUNTS, DCM_IS, "NMI Residual Syringe Counts"},
09478 {DCM_NMIENERGYWINDOWNAME, DCM_SH, "NMI Energy Window Name"},
09479 {DCM_NMIDETECTORVECTOR, DCM_US, "NMI Detector Vector"},
09480 {DCM_NMINUMBEROFDETECTORS, DCM_US, "NMI Number of Detectors"},
09481 {DCM_NMIDETECTORINFOSEQUENCE, DCM_SQ, "NMI Detector Information Sequence"},
09482 {DCM_NMIPHASEVECTOR, DCM_US, "NMI Phase Vector"},
09483 {DCM_NMINUMBEROFPHASES, DCM_US, "NMI Number of Phases"},
09484 {DCM_NMIPHASEINFOSEQUENCE, DCM_SQ, "NMI Phase Information Sequence"},
09485 {DCM_NMINUMBEROFFRAMESINPHASE, DCM_US, "NMI Number of Frames in Phase"},
09486 {DCM_NMIPHASEDELAY, DCM_IS, "NMI Phase Delay"},
09487 {DCM_NMIPAUSEBETWEENFRAMES, DCM_IS, "NMI Pause between Frames"},
09488 {DCM_NMIROTATIONVECTOR, DCM_US, "NMI Rotation Vector"},
09489 {DCM_NMINUMBEROFROTATIONS, DCM_US, "NMI Number of rotations"},
09490 {DCM_NMIROTATIONINFOSEQUENCE, DCM_SQ, "NMI Rotation Information Sequence"},
09491 {DCM_NMINUMBEROFFRAMESINROTATION, DCM_US, "NMI Number of frames in rotation"},
09492 {DCM_NMIRRINTERVALVECTOR, DCM_US, "NMI R-R Interval Vector"},
09493 {DCM_NMINUMBEROFRRINTERVALS, DCM_US, "NMI Number of R-R Intervals"},
09494 {DCM_NMIGATEDINFOSEQUENCE, DCM_SQ, "NMI Gated Information Sequence"},
09495 {DCM_NMIDATAINFORMATIONSEQUENCE, DCM_SQ, "NMI Data Information Sequence"},
09496 {DCM_NMITIMESLOTVECTOR, DCM_US, "NMI Time Slot Vector"},
09497 {DCM_NMINUMBEROFTIMESLOTS, DCM_US, "NMI Number of Time Slots"},
09498 {DCM_NMITIMESLOTINFOSEQUENCE, DCM_SQ, "NMI Time Slot Information Sequence"},
09499 {DCM_NMITIMESLOTTIME, DCM_DS, "NMI Time Slot Time"},
09500 {DCM_NMISLICEVECTOR, DCM_US, "NMI Slice Vector"},
09501 {DCM_NMINUMBEROFSLICES, DCM_US, "NMI Number of Slices"},
09502 {DCM_NMIANGULARVIEWVECTOR, DCM_US, "NMI Angular View Vector"},
09503 {DCM_NMITIMESLICEVECTOR, DCM_US, "NMI Time Slice Vector"},
09504 {DCM_NMINUMBEROFTIMESLICES, DCM_US, "NMI Number of Time Slices"},
09505 {DCM_NMISTARTANGLE, DCM_DS, "NMI Start Angle"},
09506 {DCM_NMITYPEOFDETECTORMOTION, DCM_CS, "NMI Type of Detector Motion"},
09507 {DCM_NMITRIGGERVECTOR, DCM_IS, "NMI Trigger Vector"},
09508 {DCM_NMINUMBEROFTRIGGERSINPHASE, DCM_US, "NMI Number of Triggers in Phase"},
09509 {DCM_NMIVIEWCODESEQUENCE, DCM_SQ, "NMI View Code Sequence"},
09510 {DCM_NMIVIEWANGULATIONMODIFIERCODESEQ, DCM_SQ, "NMI View Angulation Modifer Code Sequence"},
09511 {DCM_NMIRADIONUCLIDECODESEQUENCE, DCM_SQ, "NMI Radionuclide Code Sequence"},
09512 {DCM_NMIRADIOPHARMROUTECODESEQUENCE, DCM_SQ, "NMI Radiopharmaceutical Route Code Sequence"},
09513 {DCM_NMIRADIOPHARMCODESEQUENCE, DCM_SQ, "NMI Radiopahrmaceutical Code Sequence"},
09514 {DCM_NMICALIBRATIONDATASEQUENCE, DCM_SQ, "NMI Calibration Data Sequence"},
09515 {DCM_NMIENERGYWINDOWNUMBER, DCM_US, "NMI Energy Window Number"},
09516 {DCM_NMIIMAGEID, DCM_SH, "NMI Image ID"},
09517 {DCM_NMIPATIENTORIENTATIONCODESEQ, DCM_SQ, "NMI Patient Orientation Code Sequence"},
09518 {DCM_NMIPATIENTORIENTATIONMODIFIERCODESEQ, DCM_SQ, "NMI Patient Orientation Modifier Code Sequence"},
09519 {DCM_NMIPATIENTGANTRYRELATIONSHIPCODESEQ, DCM_SQ, "NMI Patient Gantry Relationship Code Sequence"},
09520 {DCM_NMISERIESTYPE, DCM_CS, "NMI Series Type"},
09521 {DCM_NMIUNITS, DCM_CS, "NMI Units"},
09522 {DCM_NMICOUNTSSOURCE, DCM_CS, "NMI Counts Source"},
09523 {DCM_NMIREPROJECTIONMETHOD, DCM_CS, "NMI Reprojection Method"},
09524 {DCM_NMIRANDOMSCORRECTIONMETHOD, DCM_CS,
09525 "NMI Randoms Correction Method"},
09526 {DCM_NMIATTENUATIONCORRECTIONMETHOD, DCM_LO,
09527 "NMI Attenuation Correction Method"},
09528 {DCM_NMIDECAYCORRECTION, DCM_CS, "NMI Decay Correction"},
09529 {DCM_NMIRECONSTRUCTIONMETHOD, DCM_LO, "NMI Reconstruction Method"},
09530 {DCM_NMIDETECTORLINESRESPONSEUSED, DCM_LO,
09531 "NMI Detector Lines of Response Used"},
09532 {DCM_NMISCATTERCORRECTIONMETHOD, DCM_LO, "NMI Scatter Correction Method"},
09533 {DCM_NMIAXIALACCEPTANCE, DCM_DS, "NMI Axial Acceptance"},
09534 {DCM_NMIAXIALMASH, DCM_IS, "NMI Axial Mash"},
09535 {DCM_NMITRANSVERSEMASH, DCM_IS, "NMI Transverse Mash"},
09536 {DCM_NMIDETECTORELEMENTSIZE, DCM_DS, "NMI Detector Element Size"},
09537 {DCM_NMICOINCIDENCEWINDOWWIDTH, DCM_DS, "NMI Coincidence Window Width"},
09538 {DCM_NMISECONDARYCOUNTSTYPE, DCM_CS, "NMI Secondary Counts Type"},
09539 {DCM_NMIFRAMEREFERENCETIME, DCM_DS, "NMI Frame Reference Time"},
09540 {DCM_NMIPRIMARYCOUNTSACCUMULATED, DCM_IS,
09541 "NMI Primary (Prompts) Counts Accumulated"},
09542 {DCM_NMISECONDARYCOUNTSACCUMULATED, DCM_IS,
09543 "NMI Secondary Counts Accumulated"},
09544 {DCM_NMISLICESENSITIVITYFACTOR, DCM_DS, "NMI Slice Sensitivity Factor"},
09545 {DCM_NMIDECAYFACTOR, DCM_DS, "NMI Decay Factor"},
09546 {DCM_NMIDOSECALIBRATIONFACTOR, DCM_DS, "NMI Dose Calibration Factor"},
09547 {DCM_NMISCATTERFRACTIONFACTOR, DCM_DS, "NMI Scatter Fraction Factor"},
09548 {DCM_NMIDEADTIMEFACTOR, DCM_DS, "NMI Dead Time Factor"},
09549 {DCM_NMIIMAGEINDEX, DCM_US, "NMI Image Index"},
09550 {DCM_NMICOUNTSINCLUDED, DCM_CS, "NMI Counts Included"},
09551 {DCM_NMIDEADTIMECORRECTIONFLAG, DCM_CS,
09552 "NMI Dead Time Correction Flag"},
09553 };
09554
09555
09556 static DCMDICT GRP_dictionary[] = {
09557 {DCM_MAKETAG(0x0070, 0x0000), DCM_UL, "GRP Group Length"},
09558 {DCM_MAKETAG(0x0070, 0x0022), DCM_FL, "GRP Graphic Data"},
09559 {DCM_MAKETAG(0x0070, 0x0023), DCM_CS, "GRP Graphic Type"},
09560 {DCM_MAKETAG(0x0070, 0x0024), DCM_CS, "GRP Graphic Filled"},
09561 {DCM_MAKETAG(0x0070, 0x0041), DCM_CS, "GRP Image Horizontal Flip"},
09562 {DCM_MAKETAG(0x0070, 0x0042), DCM_US, "GRP Image Rotation"},
09563 {DCM_MAKETAG(0x0070, 0x0052), DCM_SL, "GRP Displayed Area Top LH Corner"},
09564 {DCM_MAKETAG(0x0070, 0x0053), DCM_SL, "GRP Displayed Area Bottom RH Corner"},
09565 {DCM_MAKETAG(0x0070, 0x005a), DCM_SQ, "GRP Display Area Selection Seq"},
09566 {DCM_MAKETAG(0x0070, 0x0060), DCM_SQ, "GRP Graphic Layer Sequence"},
09567 {DCM_MAKETAG(0x0070, 0x0062), DCM_IS, "GRP Graphic Layer Order"},
09568 {DCM_MAKETAG(0x0070, 0x0066), DCM_US, "GRP Graphic Layer Rec Disp GS Val"},
09569 {DCM_MAKETAG(0x0070, 0x0067), DCM_US, "GRP Graphic Layer Rec Disp RGB Val"},
09570 {DCM_MAKETAG(0x0070, 0x0068), DCM_LO, "GRP Graphic Layer Description"},
09571
09572 {DCM_MAKETAG(0x0070, 0x0080), DCM_CS, "GRP Presentation Label"},
09573 {DCM_MAKETAG(0x0070, 0x0081), DCM_LO, "GRP Presentation Description"},
09574 {DCM_MAKETAG(0x0070, 0x0082), DCM_DA, "GRP Presentation Creation Date"},
09575 {DCM_MAKETAG(0x0070, 0x0083), DCM_TM, "GRP Presentation Creation Time"},
09576 {DCM_MAKETAG(0x0070, 0x0084), DCM_PN, "GRP Presentation Creators Name"},
09577 {DCM_MAKETAG(0x0070, 0x0100), DCM_CS, "GRP Presentation Size Mode"},
09578 {DCM_MAKETAG(0x0070, 0x0101), DCM_DS, "GRP Presentation Pixel Spacing"},
09579 {DCM_MAKETAG(0x0070, 0x0102), DCM_IS, "GRP Presentation Pixel Aspect Ratio"},
09580 {DCM_MAKETAG(0x0070, 0x0103), DCM_FL, "GRP Presentation Pixel Magnification Ratio"},
09581 };
09582
09583
09584 static DCMDICT OLY_dictionary[] = {
09585 {DCM_OLYGROUPLENGTH, DCM_UL, "OLY Group Length"},
09586 {DCM_OLYROWS, DCM_US, "OLY Rows"},
09587 {DCM_OLYCOLUMNS, DCM_US, "OLY Columns"},
09588 {DCM_OLYPLANES, DCM_US, "OLY Planes"},
09589 {DCM_OLYNUMBEROFFRAMESINOVERLAY, DCM_IS, "OLY Number of frames in Overlay"},
09590 {DCM_OLYOVERLAYDESCRIPTION, DCM_LO, "OLY Overlay Description"},
09591 {DCM_OLYTYPE, DCM_CS, "OLY Type"},
09592 {DCM_OLYSUBTYPE, DCM_LO, "OLY Subtype"},
09593 {DCM_OLYORIGIN, DCM_SS, "OLY Origin"},
09594 {DCM_OLYIMAGEFRAMEORIGIN, DCM_US, "OLY Image Frame Origin"},
09595 {DCM_OLYOVERLAYPLANEORIGIN, DCM_US, "OLY Overlay Plane Origin"},
09596 {DCM_OLYCOMPRESSIONCODE, DCM_LO, "OLY Compression Code (RET)"},
09597 {DCM_OLYBITSALLOCATED, DCM_US, "OLY Overlay Bits Allocated"},
09598 {DCM_OLYBITPOSITION, DCM_US, "OLY Overlay Bit Position"},
09599 {DCM_OLYOVERLAYFORMAT, DCM_LO, "OLY Overlay Format (RET)"},
09600 {DCM_OLYOVERLAYLOCATION, DCM_US, "OLY Overlay Location (RET)"},
09601 {DCM_OLYDESCRIPTORGRAY, DCM_US, "OLY Overlay Descriptor - Gray"},
09602 {DCM_OLYDESCRIPTORRED, DCM_US, "OLY Overlay Descriptor - Red"},
09603 {DCM_OLYDESCRIPTORGREEN, DCM_US, "OLY Overlay Descriptor - Green"},
09604 {DCM_OLYDESCRIPTORBLUE, DCM_US, "OLY Overlay Descriptor - Blue"},
09605 {DCM_OLYGRAY, DCM_US, "OLY Overlays - Gray"},
09606 {DCM_OLYRED, DCM_US, "OLY Overlays - Red"},
09607 {DCM_OLYGREEN, DCM_US, "OLY Overlays - Green"},
09608 {DCM_OLYBLUE, DCM_US, "OLY Overlays - Blue"},
09609 {DCM_OLYROIAREA, DCM_IS, "OLY ROI Area"},
09610 {DCM_OLYROIMEAN, DCM_DS, "OLY ROI Mean"},
09611 {DCM_OLYROISTANDARDDEVIATION, DCM_DS, "OLY ROI Standard Deviation"},
09612 {DCM_OLYOVERLAYLABEL, DCM_LO, "OLY Overlay Label"},
09613 {DCM_OLYDATA, DCM_OW, "OLY Data"},
09614 {DCM_OLYCOMMENTS, DCM_LO, "OLY Comments (RET)"}
09615 };
09616
09617
09618
09619 static DCMDICT PXL_dictionary[] = {
09620 {DCM_PXLGROUPLENGTH, DCM_UL, "PXL Group Length"},
09621 {DCM_PXLPIXELDATA, DCM_OT, "PXL Pixel Data"}
09622 };
09623
09624
09625 static DCMDICT MED_dictionary[] = {
09626 {DCM_MEDIAGROUPLENGTH, DCM_UL, "MED Media Group Length "},
09627 {DCM_MEDIASTORAGEFILESETID, DCM_SH, "MED Storage Media File-set ID"},
09628 {DCM_MEDIASTORAGEFILESETUID, DCM_UI, "MED Storage Media File-setUID"},
09629 {DCM_MEDIAICONIMAGE, DCM_SQ, "MED Icon Image Sequence"},
09630 {DCM_MEDIATOPICTITLE, DCM_LO, "MED Topic Title"},
09631 {DCM_MEDIATOPICSUBJECT, DCM_ST, "MED Topic Subject"},
09632 {DCM_MEDIATOPICAUTHOR, DCM_LO, "MED Topic Author"},
09633 {DCM_MEDIATOPICKEYWORD, DCM_LO, "MED Topic Keywords"}
09634 };
09635
09636
09637
09638 static DCMDICT BFS_dictionary[] = {
09639 {DCM_BFSGROUPLENGTH, DCM_UL, "BFS Group Length"},
09640 {DCM_BFSCOPIES, DCM_IS, "BFS Number of copies printed for each film"},
09641 {DCM_BFSPRINTPRIORITY, DCM_CS, "BFS Specifies priority of print job"},
09642 {DCM_BFSMEDIUMTYPE, DCM_CS, "BFS Medium on which page will be printed"},
09643 {DCM_BFSFILMDESTINATION, DCM_CS, "BFS Film destination"},
09644 {DCM_BFSFILMSESSIONLABEL, DCM_LO, "BFS Human readable label to identify film"},
09645 {DCM_BFSMEMORYALLOCATION, DCM_IS, "BFS Amount of mem allocated for film session"},
09646 {DCM_BFSREFERENCEDFILMBOXSEQ, DCM_SQ, "BFS seq of UIDs of diff FILMBOX instances"}
09647 };
09648
09649
09650
09651 static DCMDICT BFB_dictionary[] = {
09652 {DCM_BFBGROUPLENGTH, DCM_UL, "BFB Group Length"},
09653 {DCM_BFBIMAGEDISPLAYFORMAT, DCM_ST, "BFB Type of image display format"},
09654 {DCM_BFBANNOTATIONDISPLAYFORMAT, DCM_CS, "BFB Id of annotation display format"},
09655 {DCM_BFBFILMORIENTATION, DCM_CS, "BFB Film orientation"},
09656 {DCM_BFBFILMSIZEID, DCM_CS, "BFB Film size identification"},
09657 {DCM_BFBMAGNIFICATIONTYPE, DCM_CS, "BFB Interpol. type by which printer mag image"},
09658 {DCM_BFBSMOOTHINGTYPE, DCM_CS, "BFB Specifies type of interpolation function"},
09659 {DCM_BFBBORDERDENSITY, DCM_CS, "BFB density of film areas around/between images"},
09660 {DCM_BFBEMPTYIMAGEDENSITY, DCM_CS, "BFB density of image box area having no image"},
09661 {DCM_BFBMINDENSITY, DCM_US, "BFB Minimum density of images on the film"},
09662 {DCM_BFBMAXDENSITY, DCM_US, "BFB Maximum density of images on the film"},
09663 {DCM_BFBTRIM, DCM_CS, "BFB specifies whether to trim or not"},
09664 {DCM_BFBCONFIGURATIONINFO, DCM_ST, "BFB ID of configuration table"},
09665 {DCM_BFBREFBASICFILMSESSIONSEQ, DCM_SQ, "BFB seq. of film session instance"},
09666 {DCM_BFBREFBASICIMAGEBOXSEQ, DCM_SQ, "BFB seq. of basic image box SOP instance"},
09667 {DCM_BFBREFBASICANNOTBOXSEQ, DCM_SQ, "BFB seq. of basic annotation box SOP instance"},
09668 };
09669
09670
09671
09672 static DCMDICT BIB_dictionary[] = {
09673 {DCM_BIBGROUPLENGTH, DCM_UL, "BIB Group Length"},
09674 {DCM_BIBIMAGEPOSITION, DCM_US, "BIB Specifies position of the image in the film"},
09675 {DCM_BIBPOLARITY, DCM_CS, "BIB Specifies image polarity"},
09676 {DCM_BIBREQUESTEDIMAGESIZE, DCM_DS, "BIB Requested image size"},
09677 {DCM_BIBPREFORMATGREYSCALEIMAGESEQ, DCM_SQ, "BIB Preformatted Greyscale image"},
09678 {DCM_BIBPREFORMATCOLORIMAGESEQ, DCM_SQ, "BIB Preformatted Color image"},
09679 {DCM_BIBREFIMAGEOVERLAYBOXSEQ, DCM_SQ, "BIB Referenced Image Overlay Box seq"},
09680 {DCM_BIBREFVOILUTSEQ, DCM_SQ, "BIB Referenced VOI LUT seq."}
09681 };
09682
09683
09684
09685 static DCMDICT BAB_dictionary[] = {
09686 {DCM_BABGROUPLENGTH, DCM_UL, "BAB Group Length"},
09687 {DCM_BABANNOTATIONPOSITION, DCM_US, "BAB posn of the annot. box in parent film box"},
09688 {DCM_BABTEXTSTRING, DCM_LO, "BAB text string"}
09689 };
09690
09691
09692
09693 static DCMDICT IOB_dictionary[] = {
09694 {DCM_IOBGROUPLENGTH, DCM_UL, "IOB Group Length"},
09695 {DCM_IOBREFOVERLAYPLANESEQ, DCM_SQ, "IOB Ref Overlay Plane Sequence"},
09696 {DCM_IOBREFOVERLAYPLANEGROUPS, DCM_US, "IOB Ref Overlay Plane Groups"},
09697 {DCM_IOBOVERLAYMAGNIFICATIONTYPE, DCM_CS, "IOB Overlay Magnification Type"},
09698 {DCM_IOBOVERLAYSMOOTHINGTYPE, DCM_CS, "IOB Overlay Smoothing Type"},
09699 {DCM_IOBOVERLAYFOREGROUNDDENSITY, DCM_CS, "IOB Overlay Foreground Density"},
09700 {DCM_IOBOVERLAYMODE, DCM_CS, "IOB Overlay Mode"},
09701 {DCM_IOBTHRESHOLDDENSITY, DCM_CS, "IOB Threshold Density"},
09702 {DCM_IOBREFIMAGEBOXSEQUENCE, DCM_SQ, "IOB Ref Image Box Sequence (RET)"}
09703 };
09704
09705
09706
09707 static DCMDICT PLUT_dictionary[] = {
09708 {DCM_MAKETAG(0x2050, 0x0000), DCM_UL, "PLUT Group Length"},
09709 {DCM_MAKETAG(0x2050, 0x0010), DCM_SQ, "PLUT Presentation LUT Sequence"},
09710 {DCM_MAKETAG(0x2050, 0x0020), DCM_CS, "PLUT Presentation LUT Shape"},
09711 {DCM_MAKETAG(0x2050, 0x0500), DCM_SQ, "PLUT Referenced Presentation LUT Sequence"}
09712 };
09713
09714
09715
09716 static DCMDICT PJ_dictionary[] = {
09717 {DCM_PJGROUPLENGTH, DCM_UL, "PJ Group Length"},
09718 {DCM_PJEXECUTIONSTATUS, DCM_CS, "PJ execution status of print job"},
09719 {DCM_PJEXECUTIONSTATUSINFO, DCM_CS, "PJ additional information"},
09720 {DCM_PJCREATIONDATE, DCM_DA, "PJ date of print job creation"},
09721 {DCM_PJCREATIONTIME, DCM_TM, "PJ time of print job creation"},
09722 {DCM_PJORIGINATOR, DCM_AE, "PJ Appln entity title that issued the print opn"},
09723 {DCM_PJREFPRINTJOBSEQ, DCM_SQ, "PJ Referenced print job seq."}
09724 };
09725
09726
09727
09728 static DCMDICT PRN_dictionary[] = {
09729 {DCM_PRINTERGROUPLENGTH, DCM_UL, "PRINTER Group Length"},
09730 {DCM_PRINTERSTATUS, DCM_CS, "PRINTER printer device status"},
09731 {DCM_PRINTERSTATUSINFO, DCM_CS, "PRINTER additional information"},
09732 {DCM_PRINTERNAME, DCM_LO, "PRINTER printer name"},
09733 {DCM_PRINTERQUEUEID, DCM_SH, "Printer Queue ID"}
09734 };
09735
09736
09737
09738 static DCMDICT G3002_dictionary[] = {
09739 {DCM_MAKETAG(0x3002, 0x0000), DCM_UL, "RT Group Length"},
09740 {DCM_MAKETAG(0x3002, 0x0002), DCM_SH, "RT Image Label"},
09741 {DCM_MAKETAG(0x3002, 0x0003), DCM_LO, "RT Image Name"},
09742 {DCM_MAKETAG(0x3002, 0x0004), DCM_ST, "RT Image Description"},
09743 {DCM_MAKETAG(0x3002, 0x000a), DCM_CS, "RT Reported Values Origin"},
09744 {DCM_MAKETAG(0x3002, 0x000c), DCM_CS, "RT Image Plane"},
09745 {DCM_MAKETAG(0x3002, 0x000e), DCM_DS, "RT X-Ray Image Receptor Angle"},
09746 {DCM_MAKETAG(0x3002, 0x0010), DCM_DS, "RT Image Orientation"},
09747 {DCM_MAKETAG(0x3002, 0x0011), DCM_DS, "RT Image Plane Pixel Spacing"},
09748 {DCM_MAKETAG(0x3002, 0x0012), DCM_DS, "RT Image Position"},
09749 {DCM_MAKETAG(0x3002, 0x0020), DCM_SH, "RT Radiation Machine Name"},
09750 {DCM_MAKETAG(0x3002, 0x0022), DCM_DS, "RT Radiation Machine SAD"},
09751 {DCM_MAKETAG(0x3002, 0x0024), DCM_DS, "RT Radiation Machine SSD"},
09752 {DCM_MAKETAG(0x3002, 0x0026), DCM_DS, "RT Image SID"},
09753 {DCM_MAKETAG(0x3002, 0x0028), DCM_DS, "RT Source to Reference Object Distance"},
09754 {DCM_MAKETAG(0x3002, 0x0029), DCM_IS, "RT Fraction Number"},
09755 {DCM_MAKETAG(0x3002, 0x0030), DCM_SQ, "RT Exposure Sequence"},
09756 {DCM_MAKETAG(0x3002, 0x0032), DCM_DS, "RT Meterset Exposure"}
09757 };
09758
09759
09760
09761
09762 static DCMDICT DVH_dictionary[] = {
09763 {DCM_MAKETAG(0x3004, 0x0000), DCM_UL, "DVH Group Length"},
09764 {DCM_MAKETAG(0x3004, 0x0001), DCM_CS, "DVH Type"},
09765 {DCM_MAKETAG(0x3004, 0x0002), DCM_CS, "DVH Dose Units"},
09766 {DCM_MAKETAG(0x3004, 0x0004), DCM_CS, "DVH Dose Type"},
09767 {DCM_MAKETAG(0x3004, 0x0006), DCM_LO, "DVH Dose Comment"},
09768 {DCM_MAKETAG(0x3004, 0x0008), DCM_DS, "DVH Normalization Point"},
09769 {DCM_MAKETAG(0x3004, 0x000a), DCM_CS, "DVH Dose Summation Type"},
09770 {DCM_MAKETAG(0x3004, 0x000c), DCM_DS, "DVH Grid Frame Offset Vector"},
09771 {DCM_MAKETAG(0x3004, 0x000e), DCM_DS, "DVH Dose Grid Scaling"},
09772 {DCM_MAKETAG(0x3004, 0x0010), DCM_SQ, "DVH RT Dose ROI Sequence"},
09773 {DCM_MAKETAG(0x3004, 0x0012), DCM_DS, "DVH Dose Value"},
09774 {DCM_MAKETAG(0x3004, 0x0040), DCM_DS, "DVH Normalization Point"},
09775 {DCM_MAKETAG(0x3004, 0x0042), DCM_DS, "DVH Normalization Dose Value"},
09776 {DCM_MAKETAG(0x3004, 0x0050), DCM_SQ, "DVH Sequence"},
09777 {DCM_MAKETAG(0x3004, 0x0052), DCM_DS, "DVH Dose Scaling"},
09778 {DCM_MAKETAG(0x3004, 0x0054), DCM_CS, "DVH Volume Units"},
09779 {DCM_MAKETAG(0x3004, 0x0056), DCM_IS, "DVH Number of Bins"},
09780 {DCM_MAKETAG(0x3004, 0x0058), DCM_DS, "DVH Data"},
09781 {DCM_MAKETAG(0x3004, 0x0060), DCM_SQ, "DVH Referenced ROI Sequence"},
09782 {DCM_MAKETAG(0x3004, 0x0062), DCM_CS, "DVH ROI Contribution Type"},
09783 {DCM_MAKETAG(0x3004, 0x0070), DCM_DS, "DVH Minimum Dose"},
09784 {DCM_MAKETAG(0x3004, 0x0072), DCM_DS, "DVH Maximum Dose"},
09785 {DCM_MAKETAG(0x3004, 0x0074), DCM_DS, "DVH Mean Dose"}
09786 };
09787
09788
09789
09790
09791 static DCMDICT SSET_dictionary[] = {
09792 {DCM_MAKETAG(0x3006, 0x0000), DCM_UL, "SSET Group Length"},
09793 {DCM_MAKETAG(0x3006, 0x0002), DCM_SH, "SSET Structure Set Label"},
09794 {DCM_MAKETAG(0x3006, 0x0004), DCM_LO, "SSET Structure Set Name"},
09795 {DCM_MAKETAG(0x3006, 0x0006), DCM_ST, "SSET Structure Set Description"},
09796 {DCM_MAKETAG(0x3006, 0x0008), DCM_DA, "SSET Structure Set Date"},
09797 {DCM_MAKETAG(0x3006, 0x0009), DCM_TM, "SSET Structure Set Time"},
09798 {DCM_MAKETAG(0x3006, 0x0010), DCM_SQ, "SSET Referenced Frame of Reference Sequence"},
09799 {DCM_MAKETAG(0x3006, 0x0012), DCM_SQ, "SSET RT Referenced Study Sequence"},
09800 {DCM_MAKETAG(0x3006, 0x0014), DCM_SQ, "SSET RT Referenced Series Sequence"},
09801 {DCM_MAKETAG(0x3006, 0x0016), DCM_SQ, "SSET Contour Image Sequence"},
09802 {DCM_MAKETAG(0x3006, 0x0020), DCM_SQ, "SSET Structure Set ROI Sequence"},
09803 {DCM_MAKETAG(0x3006, 0x0022), DCM_IS, "SSET ROI Number"},
09804 {DCM_MAKETAG(0x3006, 0x0024), DCM_UI, "SSET Referenced Frame of Reference UID"},
09805 {DCM_MAKETAG(0x3006, 0x0026), DCM_LO, "SSET ROI Name"},
09806 {DCM_MAKETAG(0x3006, 0x0028), DCM_ST, "SSET ROI Description"},
09807 {DCM_MAKETAG(0x3006, 0x002a), DCM_IS, "SSET ROI Display Color"},
09808 {DCM_MAKETAG(0x3006, 0x002c), DCM_DS, "SSET ROI Volume"},
09809 {DCM_MAKETAG(0x3006, 0x0030), DCM_SQ, "SSET RT Related ROI Sequence"},
09810 {DCM_MAKETAG(0x3006, 0x0033), DCM_CS, "SSET RT ROI Relationship"},
09811 {DCM_MAKETAG(0x3006, 0x0036), DCM_CS, "SSET ROI Generation Algorithm"},
09812 {DCM_MAKETAG(0x3006, 0x0038), DCM_LO, "SSET ROI Generation Description"},
09813 {DCM_MAKETAG(0x3006, 0x0039), DCM_SQ, "SSET ROI Contour Sequence"},
09814 {DCM_MAKETAG(0x3006, 0x0040), DCM_SQ, "SSET Contour Sequence"},
09815 {DCM_MAKETAG(0x3006, 0x0042), DCM_CS, "SSET Contour Geometric Type"},
09816 {DCM_MAKETAG(0x3006, 0x0044), DCM_DS, "SSET Contour Slab Thickness"},
09817 {DCM_MAKETAG(0x3006, 0x0045), DCM_DS, "SSET Contour Offset Vector"},
09818 {DCM_MAKETAG(0x3006, 0x0046), DCM_IS, "SSET Number of Contour Points"},
09819 {DCM_MAKETAG(0x3006, 0x0050), DCM_DS, "SSET Contour Data"},
09820 {DCM_MAKETAG(0x3006, 0x0080), DCM_SQ, "SSET RT ROI Observations Sequence"},
09821 {DCM_MAKETAG(0x3006, 0x0082), DCM_IS, "SSET Observation Number"},
09822 {DCM_MAKETAG(0x3006, 0x0084), DCM_IS, "SSET Referenced ROI Number"},
09823 {DCM_MAKETAG(0x3006, 0x0085), DCM_SH, "SSET ROI Observation Label"},
09824 {DCM_MAKETAG(0x3006, 0x0086), DCM_SQ, "SSET RT ROI Identification Code Sequence"},
09825 {DCM_MAKETAG(0x3006, 0x0088), DCM_ST, "SSET ROI Observation Description"},
09826 {DCM_MAKETAG(0x3006, 0x00a0), DCM_SQ, "SSET Relation RT ROI Observations Sequence"},
09827 {DCM_MAKETAG(0x3006, 0x00a4), DCM_CS, "SSET RT ROI Interpreted Type"},
09828 {DCM_MAKETAG(0x3006, 0x00a6), DCM_PN, "SSET ROI Interpreter"},
09829 {DCM_MAKETAG(0x3006, 0x00b0), DCM_SQ, "SSET ROI Physical Properties Sequence"},
09830 {DCM_MAKETAG(0x3006, 0x00b2), DCM_CS, "SSET ROI Physical Property"},
09831 {DCM_MAKETAG(0x3006, 0x00b4), DCM_DS, "SSET ROI Physical Property Value"},
09832 {DCM_MAKETAG(0x3006, 0x00c0), DCM_SQ, "SSET Frame of Referenced Relationship Sequence"},
09833 {DCM_MAKETAG(0x3006, 0x00c2), DCM_UI, "SSET Related Frame of Reference UID"},
09834 {DCM_MAKETAG(0x3006, 0x00c4), DCM_CS, "SSET Frame of Reference Transformation Type"},
09835 {DCM_MAKETAG(0x3006, 0x00c6), DCM_DS, "SSET Frame of Reference Transformation Matrix"},
09836 {DCM_MAKETAG(0x3006, 0x00c8), DCM_LO, "SSET Frame of Reference Transformation Comment"}
09837 };
09838
09839
09840
09841 static DCMDICT G300A_dictionary[] = {
09842 {DCM_MAKETAG(0x300a, 0x0000), DCM_UL, " Group Length"},
09843 {DCM_MAKETAG(0x300a, 0x0002), DCM_SH, " RT Plan Label"},
09844 {DCM_MAKETAG(0x300a, 0x0003), DCM_LO, " RT Plan Name"},
09845 {DCM_MAKETAG(0x300a, 0x0004), DCM_ST, " RT Plan Description"},
09846 {DCM_MAKETAG(0x300a, 0x0006), DCM_DA, " RT Plan Date"},
09847 {DCM_MAKETAG(0x300a, 0x0007), DCM_TM, " RT Plan Time"},
09848 {DCM_MAKETAG(0x300a, 0x0009), DCM_LO, " RT Treatment Protocols"},
09849 {DCM_MAKETAG(0x300a, 0x000a), DCM_CS, " Treatment Intent"},
09850 {DCM_MAKETAG(0x300a, 0x000b), DCM_LO, " Treatment Sites"},
09851 {DCM_MAKETAG(0x300a, 0x000c), DCM_CS, " RT Plan Geometry"},
09852 {DCM_MAKETAG(0x300a, 0x000e), DCM_ST, " Prescription Description"},
09853 {DCM_MAKETAG(0x300a, 0x0010), DCM_SQ, " Dose Reference Sequence"},
09854 {DCM_MAKETAG(0x300a, 0x0012), DCM_IS, " Dose Reference Number"},
09855 {DCM_MAKETAG(0x300a, 0x0014), DCM_CS, " Dose Reference Structure Type"},
09856 {DCM_MAKETAG(0x300a, 0x0016), DCM_LO, " Dose Reference Description"},
09857 {DCM_MAKETAG(0x300a, 0x0018), DCM_DS, " Dose Reference Point Coordinates"},
09858 {DCM_MAKETAG(0x300a, 0x001a), DCM_DS, " Nominal Prior Dose"},
09859 {DCM_MAKETAG(0x300a, 0x0020), DCM_CS, " Dose Reference Type"},
09860 {DCM_MAKETAG(0x300a, 0x0021), DCM_DS, " Constraint Weight"},
09861 {DCM_MAKETAG(0x300a, 0x0022), DCM_DS, " Delivery Warning Dose"},
09862 {DCM_MAKETAG(0x300a, 0x0023), DCM_DS, " Delivery Maximum Dose"},
09863 {DCM_MAKETAG(0x300a, 0x0025), DCM_DS, " Target Minimum Dose"},
09864 {DCM_MAKETAG(0x300a, 0x0026), DCM_DS, " Target Prescription Dose"},
09865 {DCM_MAKETAG(0x300a, 0x0027), DCM_DS, " Target Maximum Dose"},
09866 {DCM_MAKETAG(0x300a, 0x0028), DCM_DS, " Target Underdose Volume Fraction"},
09867 {DCM_MAKETAG(0x300a, 0x002a), DCM_DS, " Organ at Risk Full-volume Dose"},
09868 {DCM_MAKETAG(0x300a, 0x002b), DCM_DS, " Organ at Risk Limit Dose"},
09869 {DCM_MAKETAG(0x300a, 0x002c), DCM_DS, " Organ at Risk Maximum Dose"},
09870 {DCM_MAKETAG(0x300a, 0x002d), DCM_DS, " Organ at Risk Overdose Volume Fraction"},
09871 {DCM_MAKETAG(0x300a, 0x0040), DCM_SQ, " Tolerance Table Sequence"},
09872 {DCM_MAKETAG(0x300a, 0x0042), DCM_IS, " Tolerance Table Number"},
09873 {DCM_MAKETAG(0x300a, 0x0043), DCM_SH, " Tolerance Table Label"},
09874 {DCM_MAKETAG(0x300a, 0x0044), DCM_DS, " Gantry Angle Tolerance"},
09875 {DCM_MAKETAG(0x300a, 0x0046), DCM_DS, " Beam Limiting Device Angle Tolerance"},
09876 {DCM_MAKETAG(0x300a, 0x0048), DCM_SQ, " Beam Limiting Device Tolerance Sequence"},
09877 {DCM_MAKETAG(0x300a, 0x004a), DCM_DS, " Beam Limiting Device Position Tolerance"},
09878 {DCM_MAKETAG(0x300a, 0x004c), DCM_DS, " Patient Support Angle Tolerance"},
09879 {DCM_MAKETAG(0x300a, 0x004e), DCM_DS, " Table Top Eccentric Angle Tolerance"},
09880 {DCM_MAKETAG(0x300a, 0x0051), DCM_DS, " Table Top Vertical Position Tolerance"},
09881 {DCM_MAKETAG(0x300a, 0x0052), DCM_DS, " Table Top Longitudinal Position Tolerance"},
09882 {DCM_MAKETAG(0x300a, 0x0053), DCM_DS, " Table Top Lateral Position Tolerance"},
09883 {DCM_MAKETAG(0x300a, 0x0055), DCM_CS, " RT Plan Relationship"},
09884 {DCM_MAKETAG(0x300a, 0x0070), DCM_SQ, " Fraction Group Sequence"},
09885 {DCM_MAKETAG(0x300a, 0x0071), DCM_IS, " Fraction Group Number"},
09886 {DCM_MAKETAG(0x300a, 0x0078), DCM_IS, " Number of Fractions Planned"},
09887 {DCM_MAKETAG(0x300a, 0x0079), DCM_IS, " Number of Fractions Per Day"},
09888 {DCM_MAKETAG(0x300a, 0x007a), DCM_IS, " Repeat Fraction Cycle Length"},
09889 {DCM_MAKETAG(0x300a, 0x007b), DCM_LT, " Fraction Pattern"},
09890 {DCM_MAKETAG(0x300a, 0x0080), DCM_IS, " Number of Beams"},
09891 {DCM_MAKETAG(0x300a, 0x0082), DCM_DS, " Beam Dose Specification Point"},
09892 {DCM_MAKETAG(0x300a, 0x0084), DCM_DS, " Beam Dose"},
09893 {DCM_MAKETAG(0x300a, 0x0086), DCM_DS, " Beam Meterset"},
09894 {DCM_MAKETAG(0x300a, 0x00a0), DCM_IS, " Number of Brachy Application Setups"},
09895 {DCM_MAKETAG(0x300a, 0x00a2), DCM_DS, " Brachy App Setup Dose Specification Point"},
09896 {DCM_MAKETAG(0x300a, 0x00a4), DCM_DS, " Brachy Application Setup Dose"},
09897 {DCM_MAKETAG(0x300a, 0x00b0), DCM_SQ, " Beam Sequence"},
09898 {DCM_MAKETAG(0x300a, 0x00b2), DCM_SH, " Treatment Machine Name"},
09899 {DCM_MAKETAG(0x300a, 0x00b3), DCM_CS, " Primary Dosimeter Unit"},
09900 {DCM_MAKETAG(0x300a, 0x00b4), DCM_DS, " Source-Axis Distance"},
09901 {DCM_MAKETAG(0x300a, 0x00b6), DCM_SQ, " Beam Limiting Device Sequence"},
09902 {DCM_MAKETAG(0x300a, 0x00b8), DCM_CS, " RT Beam Limiting Device Type"},
09903 {DCM_MAKETAG(0x300a, 0x00ba), DCM_DS, " Source to Beam Limiting Device Distance"},
09904 {DCM_MAKETAG(0x300a, 0x00bc), DCM_IS, " Number of Leaf/Jaw Pairs"},
09905 {DCM_MAKETAG(0x300a, 0x00be), DCM_DS, " Leaf Position Boundaries"},
09906 {DCM_MAKETAG(0x300a, 0x00c0), DCM_IS, " Beam Number"},
09907 {DCM_MAKETAG(0x300a, 0x00c2), DCM_LO, " Beam Name"},
09908 {DCM_MAKETAG(0x300a, 0x00c3), DCM_ST, " Beam Description"},
09909 {DCM_MAKETAG(0x300a, 0x00c4), DCM_CS, " Beam Type"},
09910 {DCM_MAKETAG(0x300a, 0x00c6), DCM_CS, " Radiation Type"},
09911 {DCM_MAKETAG(0x300a, 0x00c8), DCM_IS, " Reference Image Number"},
09912 {DCM_MAKETAG(0x300a, 0x00ca), DCM_SQ, " Planned Verification Image Sequence"},
09913 {DCM_MAKETAG(0x300a, 0x00cc), DCM_LO, " Imaging Device-Specific Acq Parameters"},
09914 {DCM_MAKETAG(0x300a, 0x00ce), DCM_CS, " Treatment Delivery Type"},
09915 {DCM_MAKETAG(0x300a, 0x00d0), DCM_IS, " Number of Wedges"},
09916 {DCM_MAKETAG(0x300a, 0x00d1), DCM_SQ, " Wedge Sequence"},
09917 {DCM_MAKETAG(0x300a, 0x00d2), DCM_IS, " Wedge Number"},
09918 {DCM_MAKETAG(0x300a, 0x00d3), DCM_CS, " Wedge Type"},
09919 {DCM_MAKETAG(0x300a, 0x00d4), DCM_SH, " Wedge ID"},
09920 {DCM_MAKETAG(0x300a, 0x00d5), DCM_IS, " Wedge Angle"},
09921 {DCM_MAKETAG(0x300a, 0x00d6), DCM_DS, " Wedge Factor"},
09922 {DCM_MAKETAG(0x300a, 0x00d8), DCM_DS, " Wedge Orientation"},
09923 {DCM_MAKETAG(0x300a, 0x00da), DCM_DS, " Source to Wedge Tray Distance"},
09924 {DCM_MAKETAG(0x300a, 0x00e0), DCM_IS, " Number of Compensators"},
09925 {DCM_MAKETAG(0x300a, 0x00e1), DCM_SH, " Material ID"},
09926 {DCM_MAKETAG(0x300a, 0x00e2), DCM_DS, " Total Compensator Tray Factor"},
09927 {DCM_MAKETAG(0x300a, 0x00e3), DCM_SQ, " Compensator Sequence"},
09928 {DCM_MAKETAG(0x300a, 0x00e4), DCM_IS, " Compensator Number"},
09929 {DCM_MAKETAG(0x300a, 0x00e5), DCM_SH, " Compensator ID"},
09930 {DCM_MAKETAG(0x300a, 0x00e6), DCM_DS, " Source to Compensator Tray Distance"},
09931 {DCM_MAKETAG(0x300a, 0x00e7), DCM_IS, " Compensator Rows"},
09932 {DCM_MAKETAG(0x300a, 0x00e8), DCM_IS, " Compensator Columns"},
09933 {DCM_MAKETAG(0x300a, 0x00e9), DCM_DS, " Compensator Pixel Spacing"},
09934 {DCM_MAKETAG(0x300a, 0x00ea), DCM_DS, " Compensator Position"},
09935 {DCM_MAKETAG(0x300a, 0x00eb), DCM_DS, " Compensator Transmission Data"},
09936 {DCM_MAKETAG(0x300a, 0x00ec), DCM_DS, " Compensator Thickness Data"},
09937 {DCM_MAKETAG(0x300a, 0x00ed), DCM_IS, " Number of Boli"},
09938 {DCM_MAKETAG(0x300a, 0x00f0), DCM_IS, " Number of Blocks"},
09939 {DCM_MAKETAG(0x300a, 0x00f2), DCM_DS, " Total Block Tray Factor"},
09940 {DCM_MAKETAG(0x300a, 0x00f4), DCM_SQ, " Block Sequence"},
09941 {DCM_MAKETAG(0x300a, 0x00f5), DCM_SH, " Block Tray ID"},
09942 {DCM_MAKETAG(0x300a, 0x00f6), DCM_DS, " Source to Block Tray Distance"},
09943 {DCM_MAKETAG(0x300a, 0x00f8), DCM_CS, " Block Type"},
09944 {DCM_MAKETAG(0x300a, 0x00fa), DCM_CS, " Block Divergence"},
09945 {DCM_MAKETAG(0x300a, 0x00fc), DCM_IS, " Block Number"},
09946 {DCM_MAKETAG(0x300a, 0x00fe), DCM_LO, " Block Name"},
09947 {DCM_MAKETAG(0x300a, 0x0100), DCM_DS, " Block Thickness"},
09948 {DCM_MAKETAG(0x300a, 0x0102), DCM_DS, " Block Transmission"},
09949 {DCM_MAKETAG(0x300a, 0x0104), DCM_IS, " Block Number of Points"},
09950 {DCM_MAKETAG(0x300a, 0x0106), DCM_DS, " Block Data"},
09951 {DCM_MAKETAG(0x300a, 0x0107), DCM_SQ, " Applicator Sequence"},
09952 {DCM_MAKETAG(0x300a, 0x0108), DCM_SH, " Applicator ID"},
09953 {DCM_MAKETAG(0x300a, 0x0109), DCM_CS, " Applicator Type"},
09954 {DCM_MAKETAG(0x300a, 0x010a), DCM_LO, " Applicator Description"},
09955 {DCM_MAKETAG(0x300a, 0x010c), DCM_DS, " Cumulative Dose Reference COefficient"},
09956 {DCM_MAKETAG(0x300a, 0x010e), DCM_DS, " Final Cumulative Meterset Weight"},
09957 {DCM_MAKETAG(0x300a, 0x0110), DCM_IS, " Number of Control Points"},
09958 {DCM_MAKETAG(0x300a, 0x0111), DCM_SQ, " Control Point Sequence"},
09959 {DCM_MAKETAG(0x300a, 0x0112), DCM_IS, " Control Point Index"},
09960 {DCM_MAKETAG(0x300a, 0x0114), DCM_DS, " Nominal Beam Energy"},
09961 {DCM_MAKETAG(0x300a, 0x0115), DCM_DS, " Dose Rate Set"},
09962 {DCM_MAKETAG(0x300a, 0x0116), DCM_SQ, " Wedge Position Sequence"},
09963 {DCM_MAKETAG(0x300a, 0x0118), DCM_CS, " Wedge Position"},
09964 {DCM_MAKETAG(0x300a, 0x011a), DCM_SQ, " Beam Limiting Device Position Sequence"},
09965 {DCM_MAKETAG(0x300a, 0x011c), DCM_DS, " Leaf/Jaw Positions"},
09966 {DCM_MAKETAG(0x300a, 0x011e), DCM_DS, " Gantry Angle"},
09967 {DCM_MAKETAG(0x300a, 0x011f), DCM_CS, " Gantry Rotation Direction"},
09968 {DCM_MAKETAG(0x300a, 0x0120), DCM_DS, " Beam Limiting Device Angle"},
09969 {DCM_MAKETAG(0x300a, 0x0121), DCM_CS, " Beam Limiting Device Rotation Direction"},
09970 {DCM_MAKETAG(0x300a, 0x0122), DCM_DS, " Patient Support Angle"},
09971 {DCM_MAKETAG(0x300a, 0x0123), DCM_CS, " Patient Support Rotation Direction"},
09972 {DCM_MAKETAG(0x300a, 0x0124), DCM_DS, " Table Top Eccentric Axis Distance"},
09973 {DCM_MAKETAG(0x300a, 0x0125), DCM_DS, " Table Top Eccentric Angle"},
09974 {DCM_MAKETAG(0x300a, 0x0126), DCM_CS, " Table Top Eccentric Rotation Direction"},
09975 {DCM_MAKETAG(0x300a, 0x0128), DCM_DS, " Table Top Vertical Position"},
09976 {DCM_MAKETAG(0x300a, 0x0129), DCM_DS, " Table Top Longitudinal Position"},
09977 {DCM_MAKETAG(0x300a, 0x012a), DCM_DS, " Table Top Lateral Position"},
09978 {DCM_MAKETAG(0x300a, 0x012c), DCM_DS, " Isocenter Position"},
09979 {DCM_MAKETAG(0x300a, 0x012e), DCM_DS, " Surface Entry Point"},
09980 {DCM_MAKETAG(0x300a, 0x0130), DCM_DS, " Source to Surface Distance"},
09981 {DCM_MAKETAG(0x300a, 0x0134), DCM_DS, " Cumulative Meterset Weight"},
09982 {DCM_MAKETAG(0x300a, 0x0180), DCM_SQ, " Patient Setup Sequence"},
09983 {DCM_MAKETAG(0x300a, 0x0182), DCM_IS, " Patient Setup Number"},
09984 {DCM_MAKETAG(0x300a, 0x0184), DCM_LO, " Patient Additional Position"},
09985 {DCM_MAKETAG(0x300a, 0x0190), DCM_SQ, " Fixation Device Sequence"},
09986 {DCM_MAKETAG(0x300a, 0x0192), DCM_CS, " Fixation Device Type"},
09987 {DCM_MAKETAG(0x300a, 0x0194), DCM_SH, " Fixation Device Label"},
09988 {DCM_MAKETAG(0x300a, 0x0196), DCM_ST, " Fixation Device Description"},
09989 {DCM_MAKETAG(0x300a, 0x0198), DCM_SH, " Fixation Device Position"},
09990 {DCM_MAKETAG(0x300a, 0x01a0), DCM_SQ, " Shielding Device Sequence"},
09991 {DCM_MAKETAG(0x300a, 0x01a2), DCM_CS, " Shielding Device Type"},
09992 {DCM_MAKETAG(0x300a, 0x01a4), DCM_SH, " Shielding Device Label"},
09993 {DCM_MAKETAG(0x300a, 0x01a6), DCM_ST, " Shielding Device Description"},
09994 {DCM_MAKETAG(0x300a, 0x01a8), DCM_SH, " Shielding Device Position"},
09995 {DCM_MAKETAG(0x300a, 0x01b0), DCM_CS, " Setup Technique"},
09996 {DCM_MAKETAG(0x300a, 0x01b2), DCM_ST, " Setup Technique Description"},
09997 {DCM_MAKETAG(0x300a, 0x01b4), DCM_SQ, " Setup Device Sequence"},
09998 {DCM_MAKETAG(0x300a, 0x01b6), DCM_CS, " Setup Device Type"},
09999 {DCM_MAKETAG(0x300a, 0x01b8), DCM_SH, " Setup Device Label"},
10000 {DCM_MAKETAG(0x300a, 0x01ba), DCM_ST, " Setup Device Description"},
10001 {DCM_MAKETAG(0x300a, 0x01bc), DCM_DS, " Setup Device Parameter"},
10002 {DCM_MAKETAG(0x300a, 0x01d0), DCM_ST, " Setup Reference Description"},
10003 {DCM_MAKETAG(0x300a, 0x01d2), DCM_DS, " Table Top Vertical Setup Displacement"},
10004 {DCM_MAKETAG(0x300a, 0x01d4), DCM_DS, " Table Top Longitudinal Setup Displacement"},
10005 {DCM_MAKETAG(0x300a, 0x01d6), DCM_DS, " Table Top Lateral Setup Displacement"},
10006 {DCM_MAKETAG(0x300a, 0x0200), DCM_CS, " Brachy Treatment Technique"},
10007 {DCM_MAKETAG(0x300a, 0x0202), DCM_CS, " Brachy Treatment Type"},
10008 {DCM_MAKETAG(0x300a, 0x0206), DCM_SQ, " Treatment Machine Sequence"},
10009 {DCM_MAKETAG(0x300a, 0x0210), DCM_SQ, " Source Sequence"},
10010 {DCM_MAKETAG(0x300a, 0x0212), DCM_IS, " Source Number"},
10011 {DCM_MAKETAG(0x300a, 0x0214), DCM_CS, " Source Type"},
10012 {DCM_MAKETAG(0x300a, 0x0216), DCM_LO, " Source Manufacturer"},
10013 {DCM_MAKETAG(0x300a, 0x0218), DCM_DS, " Active Source Diameter"},
10014 {DCM_MAKETAG(0x300a, 0x021a), DCM_DS, " Active Source Length"},
10015 {DCM_MAKETAG(0x300a, 0x0222), DCM_DS, " Source Encapsulation Nominal Thickness"},
10016 {DCM_MAKETAG(0x300a, 0x0224), DCM_DS, " Source Encapsulation Nominal Transmission"},
10017 {DCM_MAKETAG(0x300a, 0x0226), DCM_LO, " Source Isotope Name"},
10018 {DCM_MAKETAG(0x300a, 0x0228), DCM_DS, " Source Isotope Half Life"},
10019 {DCM_MAKETAG(0x300a, 0x022a), DCM_DS, " Reference Air Kerma Rate"},
10020 {DCM_MAKETAG(0x300a, 0x022c), DCM_DA, " Air Kerma Rate Reference Date"},
10021 {DCM_MAKETAG(0x300a, 0x022e), DCM_TM, " Air Kerma Rate Reference Time"},
10022 {DCM_MAKETAG(0x300a, 0x0230), DCM_SQ, " Application Setup Sequence"},
10023 {DCM_MAKETAG(0x300a, 0x0232), DCM_CS, " Application Setup Type"},
10024 {DCM_MAKETAG(0x300a, 0x0234), DCM_IS, " Application Setup Number"},
10025 {DCM_MAKETAG(0x300a, 0x0236), DCM_LO, " Application Setup Name"},
10026 {DCM_MAKETAG(0x300a, 0x0238), DCM_LO, " Application Setup Manufacturer"},
10027 {DCM_MAKETAG(0x300a, 0x0240), DCM_IS, " Template Number"},
10028 {DCM_MAKETAG(0x300a, 0x0242), DCM_SH, " Template Type"},
10029 {DCM_MAKETAG(0x300a, 0x0244), DCM_LO, " Template Name"},
10030 {DCM_MAKETAG(0x300a, 0x0250), DCM_DS, " Total Reference Air Kerma"},
10031 {DCM_MAKETAG(0x300a, 0x0260), DCM_SQ, " Brachy Acessory Device Sequence"},
10032 {DCM_MAKETAG(0x300a, 0x0262), DCM_IS, " Brachy Accessory Device Number"},
10033 {DCM_MAKETAG(0x300a, 0x0263), DCM_SH, " Brachy Accessory Device ID"},
10034 {DCM_MAKETAG(0x300a, 0x0264), DCM_CS, " Brachy Accessory Device Type"},
10035 {DCM_MAKETAG(0x300a, 0x0266), DCM_LO, " Brachy Accessory Device Name"},
10036 {DCM_MAKETAG(0x300a, 0x026a), DCM_DS, " Brachy Accessory Device Nominal Thickness"},
10037 {DCM_MAKETAG(0x300a, 0x026c), DCM_DS, " Brachy Acc'ry Device Nominal Transmission"},
10038 {DCM_MAKETAG(0x300a, 0x0280), DCM_SQ, " Channel Sequence"},
10039 {DCM_MAKETAG(0x300a, 0x0282), DCM_IS, " Channel Number"},
10040 {DCM_MAKETAG(0x300a, 0x0284), DCM_DS, " Channel Length"},
10041 {DCM_MAKETAG(0x300a, 0x0286), DCM_DS, " Channel Total Time"},
10042 {DCM_MAKETAG(0x300a, 0x0288), DCM_CS, " Source Movement Type"},
10043 {DCM_MAKETAG(0x300a, 0x028a), DCM_IS, " Number of Pulses"},
10044 {DCM_MAKETAG(0x300a, 0x028c), DCM_DS, " Pulse Repetition Interval"},
10045 {DCM_MAKETAG(0x300a, 0x0290), DCM_IS, " Source Applicator Number"},
10046 {DCM_MAKETAG(0x300a, 0x0291), DCM_SH, " Source Applicator ID"},
10047 {DCM_MAKETAG(0x300a, 0x0292), DCM_CS, " Source Applicator Type"},
10048 {DCM_MAKETAG(0x300a, 0x0294), DCM_LO, " Source Applicator Name"},
10049 {DCM_MAKETAG(0x300a, 0x0296), DCM_DS, " Source Applicator Length"},
10050 {DCM_MAKETAG(0x300a, 0x0298), DCM_LO, " Source Applicator Manufacturer"},
10051 {DCM_MAKETAG(0x300a, 0x029c), DCM_DS, " Source Applicator Wall Nominal Thickness"},
10052 {DCM_MAKETAG(0x300a, 0x029e), DCM_DS, " Src Applicator Wall Nominal Transmission"},
10053 {DCM_MAKETAG(0x300a, 0x02a0), DCM_DS, " Source Applicator Step Size"},
10054 {DCM_MAKETAG(0x300a, 0x02a2), DCM_IS, " Transfer Tube Number"},
10055 {DCM_MAKETAG(0x300a, 0x02a4), DCM_DS, " Transfer Tube Length"},
10056 {DCM_MAKETAG(0x300a, 0x02b0), DCM_SQ, " Channel Shield Sequence"},
10057 {DCM_MAKETAG(0x300a, 0x02b2), DCM_IS, " Channel Shield Number"},
10058 {DCM_MAKETAG(0x300a, 0x02b3), DCM_SH, " Channel Shield ID"},
10059 {DCM_MAKETAG(0x300a, 0x02b4), DCM_LO, " Channel Shield Name"},
10060 {DCM_MAKETAG(0x300a, 0x02b8), DCM_DS, " Channel Shield Nominal Thickness"},
10061 {DCM_MAKETAG(0x300a, 0x02ba), DCM_DS, " Channel Shield Nominal Transmission"},
10062 {DCM_MAKETAG(0x300a, 0x02c8), DCM_DS, " Final Cumulative Time Weight"},
10063 {DCM_MAKETAG(0x300a, 0x02d0), DCM_SQ, " Brachy Control Point Sequence"},
10064 {DCM_MAKETAG(0x300a, 0x02d2), DCM_DS, " Control Point Relative Position"},
10065 {DCM_MAKETAG(0x300a, 0x02d4), DCM_DS, " Control Point 3D Position"},
10066 {DCM_MAKETAG(0x300a, 0x02d6), DCM_DS, " Cumulative Time Weight"}
10067 };
10068
10069
10070
10071 static DCMDICT G300C_dictionary[] = {
10072 {DCM_MAKETAG(0x300c, 0x0000), DCM_UL, " Group Length"},
10073 {DCM_MAKETAG(0x300c, 0x0002), DCM_SQ, " Referenced RT Plan Sequence"},
10074 {DCM_MAKETAG(0x300c, 0x0004), DCM_SQ, " Referenced Beam Sequence"},
10075 {DCM_MAKETAG(0x300c, 0x0006), DCM_IS, " Referenced Beam Number"},
10076 {DCM_MAKETAG(0x300c, 0x0007), DCM_IS, " Referenced Reference Image Number"},
10077 {DCM_MAKETAG(0x300c, 0x0008), DCM_DS, " Start Cumulative Meterset Weight"},
10078 {DCM_MAKETAG(0x300c, 0x0009), DCM_DS, " End Cumulative Meterset Weight"},
10079 {DCM_MAKETAG(0x300c, 0x000a), DCM_SQ, " Referenced Brachy Application Setup Seq"},
10080 {DCM_MAKETAG(0x300c, 0x000c), DCM_IS, " Referenced Brachy Application Setup Number"},
10081 {DCM_MAKETAG(0x300c, 0x000e), DCM_IS, " Referenced Source Number"},
10082 {DCM_MAKETAG(0x300c, 0x0020), DCM_SQ, " Referenced Fraction Group Sequence"},
10083 {DCM_MAKETAG(0x300c, 0x0022), DCM_IS, " Referenced Fraction Group Number"},
10084 {DCM_MAKETAG(0x300c, 0x0040), DCM_SQ, " Referenced Verification Image Sequence"},
10085 {DCM_MAKETAG(0x300c, 0x0042), DCM_SQ, " Referenced Reference Image Sequence"},
10086 {DCM_MAKETAG(0x300c, 0x0050), DCM_SQ, " Referenced Dose Reference Sequence"},
10087 {DCM_MAKETAG(0x300c, 0x0051), DCM_IS, " Referenced Dose Reference Numer"},
10088 {DCM_MAKETAG(0x300c, 0x0055), DCM_SQ, " Brachy Referenced Dose Reference Sequence"},
10089 {DCM_MAKETAG(0x300c, 0x0060), DCM_SQ, " Referenced Structure Set Sequence"},
10090 {DCM_MAKETAG(0x300c, 0x006a), DCM_IS, " Referenced Patient Setup Number"},
10091 {DCM_MAKETAG(0x300c, 0x0080), DCM_SQ, " Referenced Dose Sequence"},
10092 {DCM_MAKETAG(0x300c, 0x00a0), DCM_IS, " Referenced Tolerance Table Number"},
10093 {DCM_MAKETAG(0x300c, 0x00b0), DCM_SQ, " Referenced Bolus Sequence"},
10094 {DCM_MAKETAG(0x300c, 0x00c0), DCM_IS, " Referenced Wedge Number"},
10095 {DCM_MAKETAG(0x300c, 0x00d0), DCM_IS, " Referenced Compensator Number"},
10096 {DCM_MAKETAG(0x300c, 0x00e0), DCM_IS, " Referenced Block Number"},
10097 {DCM_MAKETAG(0x300c, 0x00f0), DCM_IS, " Referenced Control Point Index"}
10098 };
10099
10100
10101
10102
10103 static DCMDICT G300E_dictionary[] = {
10104 {DCM_MAKETAG(0x300e, 0x0000), DCM_UL, " Group Length"},
10105 {DCM_MAKETAG(0x300e, 0x0002), DCM_CS, " Approval Status"},
10106 {DCM_MAKETAG(0x300e, 0x0004), DCM_DA, " Review Date"},
10107 {DCM_MAKETAG(0x300e, 0x0005), DCM_TM, " Review Time"},
10108 {DCM_MAKETAG(0x300e, 0x0008), DCM_PN, " Reviewer Name"}
10109 };
10110
10111
10112
10113 #if 0
10114 static DCMDICT TXT_dictionary[] = {
10115 };
10116 #endif
10117
10118
10119
10120
10121 static DCMDICT PAD_dictionary[] = {
10122 {DCM_PADITEM, DCM_OB, "Pad item"}
10123 };
10124
10125
10126
10127
10128 static DCMDICT DLM_dictionary[] = {
10129 {DCM_DLMITEM, DCM_DLM, "DELIMITER Item"},
10130 {DCM_DLMITEMDELIMITATIONITEM, DCM_DLM, "DELIMITER Item Delimitation Item"},
10131 {DCM_DLMSEQUENCEDELIMITATIONITEM, DCM_DLM, "DELIMITER Sequence Delimitation Item"}
10132 };
10133
10134
10135
10136
10137
10138 static GROUPPTR group_dictionary[] = {
10139 {DCM_GROUPCOMMAND, sizeof(CMD_dictionary) / sizeof(DCMDICT), CMD_dictionary},
10140 {DCM_GROUPFILEMETA, sizeof(META_dictionary) / sizeof(DCMDICT), META_dictionary},
10141 {DCM_GROUPBASICDIRINFO, sizeof(BASICDIR_dictionary) / sizeof(DCMDICT), BASICDIR_dictionary},
10142 {DCM_GROUPIDENTIFYING,
10143 sizeof(ID_dictionary) / sizeof(DCMDICT), ID_dictionary},
10144 {DCM_GROUPPATIENTINFO,
10145 sizeof(PAT_dictionary) / sizeof(DCMDICT), PAT_dictionary},
10146 {DCM_GROUPACQUISITION,
10147 sizeof(ACQ_dictionary) / sizeof(DCMDICT), ACQ_dictionary},
10148 {DCM_GROUPRELATIONSHIP,
10149 sizeof(REL_dictionary) / sizeof(DCMDICT), REL_dictionary},
10150 {DCM_GROUPIMAGE,
10151 sizeof(IMG_dictionary) / sizeof(DCMDICT), IMG_dictionary},
10152 {DCM_GROUPSTUDY,
10153 sizeof(SDY_dictionary) / sizeof(DCMDICT), SDY_dictionary},
10154 {DCM_GROUPVISIT,
10155 sizeof(VIS_dictionary) / sizeof(DCMDICT), VIS_dictionary},
10156 {DCM_GROUPWAVEFORM,
10157 sizeof(WAV_dictionary) / sizeof(DCMDICT), WAV_dictionary},
10158 {DCM_GRPPROCEDURE,
10159 sizeof(PRC_dictionary) / sizeof(DCMDICT), PRC_dictionary},
10160 {DCM_GROUPDEVICE,
10161 sizeof(DEV_dictionary) / sizeof(DCMDICT), DEV_dictionary},
10162 {DCM_GROUPNMIMAGE,
10163 sizeof(NMI_dictionary) / sizeof(DCMDICT), NMI_dictionary},
10164 {DCM_GROUPGRAPHICS,
10165 sizeof(GRP_dictionary) / sizeof(DCMDICT), GRP_dictionary},
10166 {DCM_GROUPMEDIA,
10167 sizeof(MED_dictionary) / sizeof(DCMDICT), MED_dictionary},
10168 {DCM_GROUPBASICFILMSESSION,
10169 sizeof(BFS_dictionary) / sizeof(DCMDICT), BFS_dictionary},
10170 {DCM_GROUPBASICFILMBOX,
10171 sizeof(BFB_dictionary) / sizeof(DCMDICT), BFB_dictionary},
10172 {DCM_GROUPBASICIMAGEBOX,
10173 sizeof(BIB_dictionary) / sizeof(DCMDICT), BIB_dictionary},
10174 {DCM_GROUPBASICANNOTATIONBOX,
10175 sizeof(BAB_dictionary) / sizeof(DCMDICT), BAB_dictionary},
10176
10177 {DCM_GROUPBASICIMAGEOVERLAYBOX,
10178 sizeof(IOB_dictionary) / sizeof(DCMDICT), IOB_dictionary},
10179
10180 {0x2050,
10181 sizeof(PLUT_dictionary) / sizeof(DCMDICT), PLUT_dictionary},
10182
10183 {DCM_GROUPPRINTJOB,
10184 sizeof(PJ_dictionary) / sizeof(DCMDICT), PJ_dictionary},
10185
10186 {DCM_GROUPPRINTER,
10187 sizeof(PRN_dictionary) / sizeof(DCMDICT), PRN_dictionary},
10188 {0x3002,
10189 sizeof(G3002_dictionary) / sizeof(DCMDICT), G3002_dictionary},
10190 {0x3004,
10191 sizeof(DVH_dictionary) / sizeof(DCMDICT), DVH_dictionary},
10192 {0x3006,
10193 sizeof(SSET_dictionary) / sizeof(DCMDICT), SSET_dictionary},
10194 {0x300a,
10195 sizeof(G300A_dictionary) / sizeof(DCMDICT), G300A_dictionary},
10196 {0x300c,
10197 sizeof(G300C_dictionary) / sizeof(DCMDICT), G300C_dictionary},
10198 {0x300e,
10199 sizeof(G300E_dictionary) / sizeof(DCMDICT), G300E_dictionary},
10200
10201
10202
10203
10204 #if 0
10205 {DCM_GROUPTEXT,
10206 sizeof(TXT_dictionary) / sizeof(DCMDICT), TXT_dictionary},
10207 #endif
10208 {DCM_GROUPRESULTS,
10209 sizeof(RES_dictionary) / sizeof(DCMDICT), RES_dictionary},
10210 {DCM_GROUPCURVE,
10211 sizeof(CRV_dictionary) / sizeof(DCMDICT), CRV_dictionary},
10212 {DCM_GROUPOVERLAY,
10213 sizeof(OLY_dictionary) / sizeof(DCMDICT), OLY_dictionary},
10214 {DCM_GROUPPIXEL,
10215 sizeof(PXL_dictionary) / sizeof(DCMDICT), PXL_dictionary},
10216 {DCM_GROUPPAD,
10217 sizeof(PAD_dictionary) / sizeof(DCMDICT), PAD_dictionary},
10218 {DCM_GROUPDELIMITER,
10219 sizeof(DLM_dictionary) / sizeof(DCMDICT), DLM_dictionary}
10220 };
10221
10222
10223
10224
10225
10226
10227
10228
10229
10230
10231
10232
10233
10234
10235
10236
10237
10238
10239
10240
10241
10242
10243
10244
10245
10246
10247
10248
10249
10250
10251
10252
10253
10254
10255 CONDITION
10256 DCM_LookupElement(DCM_ELEMENT * element)
10257 {
10258 int
10259 found;
10260 unsigned long
10261 index,
10262 entries;
10263 GROUPPTR
10264 * p;
10265 DCMDICT
10266 * dictionaryPtr;
10267
10268 element->representation = DCM_UN;
10269 (void) strcpy(element->description, "");
10270
10271 for (index = 0, p = NULL;
10272 index < sizeof(group_dictionary) / sizeof(group_dictionary[0]) && p == NULL;
10273 index++)
10274 if (DCM_TAG_GROUP(element->tag) == group_dictionary[index].group)
10275 p = &group_dictionary[index];
10276
10277 if (p == NULL) {
10278 if (DCM_TAG_ELEMENT(element->tag) == 0x0000) {
10279 element->representation = DCM_UL;
10280 (void) strcpy(element->description, "Unknown group length");
10281 return DCM_NORMAL;
10282 }
10283 return COND_PushCondition(DCM_UNRECOGNIZEDGROUP,
10284 DCM_Message(DCM_UNRECOGNIZEDGROUP),
10285 DCM_TAG_GROUP(element->tag),
10286 "DCM_LookupElement");
10287 }
10288 entries = p->entries;
10289 dictionaryPtr = p->dict;
10290
10291 for (found = 0; !found && entries > 0; entries--)
10292 if (element->tag == dictionaryPtr->tag)
10293 found++;
10294 else
10295 dictionaryPtr++;
10296
10297 if (!found)
10298 return COND_PushCondition(DCM_UNRECOGNIZEDELEMENT,
10299 DCM_Message(DCM_UNRECOGNIZEDELEMENT),
10300 DCM_TAG_GROUP(element->tag),
10301 DCM_TAG_ELEMENT(element->tag),
10302 "DCM_LookupElement");
10303
10304
10305 element->representation = dictionaryPtr->representation;
10306 (void) strcpy(element->description, dictionaryPtr->englishDescription);
10307 return DCM_NORMAL;
10308 }
10309
10310 typedef struct {
10311 unsigned short group;
10312 char *description;
10313 } GROUP_DESCRIPTION;
10314
10315 static GROUP_DESCRIPTION groupTable[] = {
10316 {0x0000, "Command"},
10317 {0x0002, "File Meta"},
10318 {0x0004, "Basic Directory Information"},
10319 {0x0008, "Identifying"},
10320 {0x0010, "Patient Information"},
10321 {0x0018, "Acquisition"},
10322 {0x0020, "Relationship"},
10323 {0x0028, "Image"},
10324 {0x0032, "Study"},
10325 {0x0038, "Visit"},
10326 {0x003a, "Waveform"},
10327 {0x0040, "Procedure Step"},
10328 {0x0050, "Device"},
10329 {0x0054, "NM Image"},
10330 {0x0070, "Graphics"},
10331 {0x0088, "Media"},
10332 {0x2000, "Basic Film Session"},
10333 {0x2010, "Basic Film Box"},
10334 {0x2020, "Basic Image Box"},
10335 {0x2030, "Basic Annotation Box"},
10336 {0x2040, "Basic Image Overlay Box"},
10337 {0x2050, "Presentation LUT"},
10338 {0x2100, "Print Job"},
10339 {0x2110, "Printer"},
10340 {0x3002, "RT"},
10341 {0x3004, "Dose Volume Histogram"},
10342 {0x3006, "Structure Set"},
10343 {0x300a, "300a"},
10344 {0x300c, "300c"},
10345 {0x300e, "300e"},
10346 #if 0
10347 {0x4000, "Text"},
10348 #endif
10349 {0x4008, "Results"},
10350 {0x5000, "Curve"},
10351 {0x6000, "Overlay"},
10352 {0x7fe0, "Pixel"}
10353 };
10354
10355
10356
10357
10358
10359
10360
10361
10362
10363
10364
10365
10366
10367
10368
10369
10370
10371
10372
10373
10374
10375
10376
10377
10378
10379
10380
10381
10382
10383 CONDITION
10384 DCM_GroupDictionary(unsigned short group, void *ctx,
10385 void (*callback) (unsigned short g, char *description, void *ctx))
10386 {
10387 int i;
10388
10389 for (i = 0; i < (int) DIM_OF(groupTable); i++) {
10390 if ((group == 0xffff) || (group == groupTable[i].group)) {
10391 callback(groupTable[i].group, groupTable[i].description, ctx);
10392 }
10393 }
10394 return DCM_NORMAL;
10395 }
10396
10397
10398
10399
10400
10401
10402
10403
10404
10405
10406
10407
10408
10409
10410
10411
10412
10413
10414
10415
10416
10417
10418
10419
10420
10421
10422
10423
10424
10425
10426
10427
10428
10429
10430
10431 CONDITION
10432 DCM_ElementDictionary(DCM_TAG tag, void *ctx,
10433 void (*callback) (DCM_TAG t, char *description, DCM_VALUEREPRESENTATION r,
10434 void *ctx))
10435 {
10436 int i;
10437 unsigned long j;
10438 GROUPPTR *p;
10439 DCMDICT *dictionaryPtr;
10440
10441 for (i = 0; i < (int) DIM_OF(group_dictionary); i++) {
10442 if ((DCM_TAG_GROUP(tag) == group_dictionary[i].group) ||
10443 (DCM_TAG_GROUP(tag) == 0xffff)) {
10444 p = &group_dictionary[i];
10445 dictionaryPtr = p->dict;
10446 for (j = 0; j < p->entries; j++, dictionaryPtr++) {
10447 if ((DCM_TAG_ELEMENT(tag) == 0xffff) ||
10448 (DCM_TAG_ELEMENT(tag) == DCM_TAG_ELEMENT(dictionaryPtr->tag))) {
10449 callback(dictionaryPtr->tag,
10450 dictionaryPtr->englishDescription,
10451 dictionaryPtr->representation,
10452 ctx);
10453 }
10454 }
10455 }
10456 }
10457 return DCM_NORMAL;
10458 }
10459
10460
10461
10462
10463
10464
10465
10466
10467
10468
10469
10470
10471
10472
10473
10474
10475
10476
10477
10478
10479
10480
10481
10482
10483
10484
10485
10486
10487
10488
10489
10490
10491
10492
10493
10494
10495
10496
10497
10498
10499
10500
10501
10502
10503
10504
10505
10506
10507
10508
10509
10510
10511
10512
10513
10514
10515
10516
10517
10518
10519
10520
10521
10522
10523
10524
10525
10526
10527
10528
10529
10530
10531
10532
10533 typedef struct {
10534 void *reserved[2];
10535 char *s;
10536 } GENERIC;
10537
10538 CONDITION
10539 DCM_ListToString(LST_HEAD * list, long offset, char **string)
10540 {
10541 GENERIC
10542 * g;
10543 char
10544 *c,
10545 *p;
10546 long
10547 length;
10548
10549 *string = NULL;
10550 if (list == NULL)
10551 return DCM_NORMAL;
10552
10553 g = (void *)LST_Head(&list);
10554 if (g == NULL)
10555 return DCM_NORMAL;
10556
10557 (void) LST_Position(&list, (void *)g);
10558
10559 length = 0;
10560 while (g != NULL) {
10561 c = ((char *) g) + offset;
10562 length += strlen(c) + 1;
10563 g = (void *)LST_Next(&list);
10564 }
10565
10566 p = CTN_MALLOC(length);
10567 if (p == NULL)
10568 return COND_PushCondition(DCM_MALLOCFAILURE,
10569 DCM_Message(DCM_MALLOCFAILURE), length, "DCM_ListToString");
10570
10571 *string = p;
10572 g = (void *)LST_Head(&list);
10573 if (g == NULL)
10574 return COND_PushCondition(DCM_LISTFAILURE, DCM_Message(DCM_LISTFAILURE),
10575 "DCM_ListToString");
10576 (void) LST_Position(&list, (void *)g);
10577
10578 length = 0;
10579 while (g != NULL) {
10580 c = ((char *) g) + offset;
10581 length = strlen(c);
10582 (void) memcpy(p, c, length);
10583 p += length;
10584 *p++ = '\\';
10585 g = (void *)LST_Next(&list);
10586 }
10587 *--p = '\0';
10588 return DCM_NORMAL;
10589 }
10590
10591
10592
10593
10594
10595
10596
10597
10598
10599
10600
10601
10602
10603
10604
10605
10606
10607
10608
10609
10610 CTNBOOLEAN
10611 DCM_IsString(DCM_VALUEREPRESENTATION representation)
10612 {
10613 CTNBOOLEAN
10614 flag = FALSE;
10615
10616 switch (representation) {
10617 case DCM_AE:
10618 case DCM_AS:
10619 flag = TRUE;
10620 break;
10621 case DCM_AT:
10622 break;
10623 case DCM_CS:
10624 case DCM_DA:
10625 flag = TRUE;
10626 break;
10627 case DCM_DD:
10628 break;
10629 case DCM_DS:
10630 case DCM_DT:
10631 flag = TRUE;
10632 break;
10633 case DCM_FD:
10634 case DCM_FL:
10635 break;
10636 case DCM_IS:
10637 case DCM_LO:
10638 case DCM_LT:
10639 flag = TRUE;
10640 break;
10641 case DCM_OB:
10642 case DCM_OT:
10643 case DCM_OW:
10644 break;
10645 case DCM_SH:
10646 flag = TRUE;
10647 break;
10648 case DCM_SL:
10649 case DCM_SQ:
10650 case DCM_SS:
10651 break;
10652 case DCM_ST:
10653 case DCM_TM:
10654 flag = TRUE;
10655 break;
10656 case DCM_UL:
10657 case DCM_US:
10658
10659 case DCM_RET:
10660 case DCM_CTX:
10661 break;
10662 case DCM_PN:
10663 case DCM_UI:
10664 case DCM_UT:
10665 flag = TRUE;
10666 break;
10667 };
10668 return flag;
10669 }
10670
10671
10672
10673
10674
10675
10676
10677
10678
10679
10680
10681
10682
10683
10684
10685
10686
10687
10688
10689
10690
10691
10692
10693
10694
10695
10696
10697
10698
10699
10700
10701
10702
10703
10704
10705
10706
10707
10708
10709
10710
10711
10712
10713
10714
10715
10716
10717
10718
10719
10720 #define CURRENT (*list)->current
10721 #define OLD_NEXT (*list)->current->next
10722 #define OLD_PREV (*list)->current->previous
10723
10724
10725
10726 LST_HEAD *
10727 LST_Create(void)
10728
10729
10730
10731
10732 {
10733 LST_HEAD
10734 * ptr;
10735
10736 ptr = CTN_MALLOC(sizeof(LST_HEAD));
10737 if (ptr == NULL)
10738 return NULL;
10739
10740 ptr->head = NULL;
10741 ptr->tail = NULL;
10742 ptr->current = NULL;
10743 ptr->count = 0;
10744 return ptr;
10745 }
10746
10747
10748
10749 CONDITION
10750 LST_Destroy(LST_HEAD ** list)
10751
10752
10753
10754
10755
10756 {
10757
10758 if ((*list)->count != 0)
10759 return LST_LISTNOTEMPTY;
10760
10761 CTN_FREE(*list);
10762 *list = NULL;
10763 return LST_NORMAL;
10764 }
10765
10766
10767
10768 CONDITION
10769 LST_Enqueue(LST_HEAD ** list, LST_NODE * node)
10770
10771
10772
10773
10774
10775 {
10776 node->next = NULL;
10777 node->previous = (*list)->tail;
10778 if ((*list)->head == NULL)
10779 (*list)->head = node;
10780 else
10781 (*list)->tail->next = node;
10782
10783 (*list)->tail = node;
10784 (*list)->count++;
10785 return LST_NORMAL;
10786 }
10787
10788 CONDITION
10789 LST_Push(LST_HEAD ** list, LST_NODE * node)
10790
10791
10792
10793
10794
10795
10796 {
10797 node->next = (*list)->head;
10798 node->previous = NULL;
10799 if ((*list)->tail == NULL)
10800 (*list)->tail = node;
10801 else
10802 (*list)->head->previous = node;
10803
10804 (*list)->head = node;
10805 (*list)->count++;
10806 return LST_NORMAL;
10807
10808 }
10809
10810 LST_NODE *
10811 LST_Dequeue(LST_HEAD ** list)
10812
10813
10814
10815
10816
10817 {
10818 LST_NODE
10819 * ptr;
10820
10821 if ((*list)->head == NULL) {
10822 (*list)->count = 0;
10823 return NULL;
10824 }
10825 ptr = (*list)->head;
10826 (*list)->head = ptr->next;
10827 if ((*list)->head == NULL)
10828 (*list)->tail = NULL;
10829 else
10830 (*list)->head->previous = NULL;
10831 ptr->next = NULL;
10832 (*list)->count--;
10833
10834 return ptr;
10835 }
10836
10837
10838
10839 LST_NODE *
10840 LST_Pop(LST_HEAD ** list)
10841
10842
10843
10844
10845
10846 {
10847 LST_NODE
10848 * ptr;
10849
10850 if ((*list)->head == NULL) {
10851 (*list)->count = 0;
10852 return NULL;
10853 }
10854 ptr = (*list)->head;
10855 (*list)->head = ptr->next;
10856 if ((*list)->head == NULL)
10857 (*list)->tail = NULL;
10858 else
10859 (*list)->head->previous = NULL;
10860 ptr->next = NULL;
10861 (*list)->count--;
10862
10863 return ptr;
10864 }
10865
10866
10867
10868 unsigned long
10869 LST_Count(LST_HEAD ** list)
10870
10871
10872
10873
10874 {
10875 return (*list)->count;
10876 }
10877
10878
10879
10880 LST_NODE *
10881 LST_Head(LST_HEAD ** list)
10882
10883
10884
10885
10886
10887 {
10888 return (*list)->head;
10889 }
10890
10891
10892 LST_NODE *
10893 LST_Current(LST_HEAD ** list)
10894
10895
10896
10897
10898
10899 {
10900 return (*list)->current;
10901 }
10902
10903
10904
10905 LST_NODE *
10906 LST_Tail(LST_HEAD ** list)
10907
10908
10909
10910
10911
10912 {
10913 return (*list)->tail;
10914 }
10915
10916
10917 CONDITION
10918 LST_Insert(LST_HEAD ** list, LST_NODE * node, LST_END where)
10919
10920
10921
10922
10923
10924
10925
10926 {
10927 if ((where != LST_K_BEFORE) && (where != LST_K_AFTER))
10928 goto badend;
10929
10930 if ((*list)->head == NULL) {
10931 (*list)->tail = node;
10932 (*list)->head = node;
10933 (*list)->count = 0;
10934 (node)->next = NULL;
10935 (node)->previous = NULL;
10936
10937 } else if (CURRENT == NULL)
10938 goto nocurrent;
10939
10940 else if ((CURRENT == (*list)->head) &&
10941 (where == LST_K_BEFORE)) {
10942 node->next = CURRENT;
10943 CURRENT->previous = node;
10944 node->previous = NULL;
10945 (*list)->head = node;
10946
10947 } else if ((CURRENT == (*list)->tail) &&
10948 (where == LST_K_AFTER)) {
10949 node->next = NULL;
10950 node->previous = (*list)->tail;
10951 CURRENT->next = node;
10952 (*list)->tail = node;
10953
10954 } else if (where == LST_K_AFTER) {
10955 OLD_NEXT->previous = node;
10956 node->next = OLD_NEXT;
10957 node->previous = CURRENT;
10958 CURRENT->next = node;
10959
10960 } else {
10961 OLD_PREV->next = node;
10962 node->previous = OLD_PREV;
10963 node->next = CURRENT;
10964 CURRENT->previous = node;
10965 };
10966
10967 (*list)->count++;
10968 (*list)->current = node;
10969 return LST_NORMAL;
10970
10971 badend:
10972 return LST_BADEND;
10973
10974 nocurrent:
10975 return LST_NOCURRENT;
10976 }
10977
10978
10979
10980 LST_NODE *
10981 LST_Remove(LST_HEAD ** list, LST_END dir)
10982
10983
10984
10985
10986
10987
10988
10989
10990
10991 {
10992 LST_NODE
10993 * ptr;
10994
10995 if ((dir != LST_K_BEFORE) && (dir != LST_K_AFTER))
10996 goto baddir;
10997 if (CURRENT == NULL)
10998 goto nocurrent;
10999 if ((*list)->head == NULL)
11000 goto listempty;
11001
11002 ptr = CURRENT;
11003
11004 if (CURRENT == (*list)->head) {
11005 (*list)->head = OLD_NEXT;
11006 if ((*list)->head == NULL)
11007 (*list)->tail = NULL;
11008 else
11009 (*list)->head->previous = NULL;
11010 if (dir == LST_K_BEFORE)
11011 (*list)->current = NULL;
11012 else
11013 (*list)->current = (*list)->head;
11014
11015 } else if (CURRENT == (*list)->tail) {
11016 (*list)->tail = OLD_PREV;
11017 (*list)->tail->next = NULL;
11018 if (dir == LST_K_AFTER)
11019 (*list)->current = NULL;
11020 else
11021 (*list)->current = (*list)->tail;
11022
11023 } else {
11024 OLD_PREV->next = CURRENT->next;
11025 OLD_NEXT->previous = CURRENT->previous;
11026 if (dir == LST_K_BEFORE)
11027 (*list)->current = CURRENT->previous;
11028 else
11029 (*list)->current = CURRENT->next;
11030 }
11031
11032 (*list)->count--;
11033 ptr->previous = NULL;
11034 ptr->next = NULL;
11035 return ptr;
11036
11037 baddir:
11038 return NULL;
11039
11040 nocurrent:
11041 return NULL;
11042
11043 listempty:
11044 (*list)->count = 0;
11045 (*list)->current = NULL;
11046 (*list)->head = (*list)->tail = NULL;
11047 return NULL;
11048 }
11049
11050
11051
11052 LST_NODE *
11053 LST_Next(LST_HEAD ** list)
11054
11055
11056
11057
11058
11059 {
11060 if ((*list)->head == NULL) {
11061 (*list)->count = 0;
11062 return NULL;
11063 }
11064 if (CURRENT == NULL) {
11065 return NULL;
11066 }
11067 CURRENT = CURRENT->next;
11068 return CURRENT;
11069 }
11070
11071
11072
11073 LST_NODE *
11074 LST_Previous(LST_HEAD ** list)
11075
11076
11077
11078
11079
11080 {
11081 if ((*list)->head == NULL) {
11082 (*list)->count = 0;
11083 return NULL;
11084 }
11085 if (CURRENT == NULL) {
11086 return NULL;
11087 }
11088 if (CURRENT->previous == NULL) {
11089 return NULL;
11090 }
11091 CURRENT = CURRENT->previous;
11092 return CURRENT;
11093 }
11094
11095
11096
11097 LST_NODE *
11098 LST_Position(LST_HEAD ** list, LST_NODE * node)
11099
11100
11101
11102
11103
11104
11105
11106
11107
11108
11109
11110
11111
11112 {
11113 if ((*list)->head == NULL) {
11114 return NULL;
11115 }
11116 if (node == NULL)
11117 return NULL;
11118 if (((node->previous == NULL) && ((*list)->head == node)) ||
11119 ((node->next == NULL) && ((*list)->tail == node)) ||
11120 (node->previous->next == node)) {
11121
11122 CURRENT = node;
11123 return CURRENT;
11124 };
11125
11126 return NULL;
11127 }
11128
11129
11130
11131
11132
11133
11134 CONDITION
11135 LST_Sort(LST_HEAD ** list, size_t nodeSize, int (*compare) ())
11136 {
11137 LST_NODE
11138 * n1,
11139 *n2;
11140 LST_HEAD
11141 temp,
11142 *head;
11143 CTNBOOLEAN
11144 inserted;
11145 int ccc ;
11146
11147 if ((*list)->head == NULL) {
11148 return LST_NORMAL;
11149 }
11150 head = &temp;
11151 head->head = NULL;
11152 head->tail = NULL;
11153 head->current = NULL;
11154 head->count = 0;
11155
11156 while ((n1 = LST_Dequeue(list)) != NULL) {
11157 n2 = LST_Head(&head);
11158 if (n2 != NULL)
11159 (void) LST_Position(&head, n2);
11160 inserted = FALSE;
11161 while (n2 != NULL && !inserted) {
11162 #if 0
11163 if (compare(n1, n2) < 0) {
11164 #else
11165 AFNI_CALL_VALU_2ARG(compare,int,ccc,LST_NODE *,n1,LST_NODE *,n2) ;
11166 if( ccc < 0 ){
11167 #endif
11168 (void) LST_Insert(&head, n1, LST_K_BEFORE);
11169 inserted = TRUE;
11170 } else
11171 n2 = LST_Next(&head);
11172 }
11173 if (n2 == NULL)
11174 (void) LST_Enqueue(&head, n1);
11175 }
11176 **list = *head;
11177 return LST_NORMAL;
11178 }
11179
11180
11181
11182
11183
11184
11185 LST_NODE *
11186 LST_Index(LST_HEAD ** l, int index)
11187 {
11188 LST_NODE
11189 * n;
11190
11191 n = LST_Head(l);
11192 if (n == NULL)
11193 return NULL;
11194
11195 index--;
11196 LST_Position(l, n);
11197 while (index-- > 0 && n != NULL)
11198 n = LST_Next(l);
11199
11200 return n;
11201 }
11202
11203
11204
11205
11206
11207
11208
11209
11210
11211
11212
11213
11214
11215
11216
11217
11218
11219
11220
11221
11222
11223
11224
11225
11226
11227
11228
11229
11230
11231
11232
11233
11234
11235
11236
11237
11238
11239
11240
11241
11242
11243
11244
11245
11246
11247
11248
11249
11250
11251
11252
11253
11254
11255
11256 #if 0
11257
11258
11259
11260
11261
11262
11263
11264
11265
11266
11267
11268
11269
11270
11271
11272
11273
11274
11275
11276
11277
11278
11279
11280 #ifdef DARWIN
11281 #define USEREGCOMP
11282 #endif
11283
11284 #ifdef USEREGCOMP
11285 #include <regex.h>
11286 #endif
11287
11288 CONDITION
11289 UTL_RegexMatch(char *regex, char *stm)
11290 {
11291 #ifdef USEREGCOMP
11292
11293 int
11294 ret,
11295 regexReturn;
11296 char
11297 *new_rstring;
11298 regex_t preg;
11299 char errorBuff[256];
11300 regmatch_t pmatch;
11301
11302 new_rstring = UTL_ConvertRegex(regex);
11303
11304 regexReturn = regcomp(&preg, new_rstring, 0);
11305 if (regexReturn != 0) {
11306 regerror(regexReturn, &preg, errorBuff, sizeof(errorBuff));
11307 fprintf(stderr, "%d\n", regexReturn);
11308 fprintf(stderr, "%s\n", errorBuff);
11309
11310 free(new_rstring);
11311 return (UTL_NOMATCH);
11312 } else {
11313 ret = regexec(&preg, stm, 1, &pmatch, 0);
11314
11315 switch (ret) {
11316 case 0:
11317 free(new_rstring);
11318 return (UTL_MATCH);
11319 break;
11320 default:
11321 free(new_rstring);
11322 return (UTL_NOMATCH);
11323 break;
11324 }
11325 }
11326 #else
11327 int
11328 ret;
11329 char
11330 *new_rstring;
11331
11332 new_rstring = UTL_ConvertRegex(regex);
11333 if (re_comp(new_rstring) != (char *) 0) {
11334 free(new_rstring);
11335 return (UTL_NOMATCH);
11336 } else {
11337 ret = re_exec(stm);
11338 switch (ret) {
11339 case 0:
11340 case -1:
11341 free(new_rstring);
11342 return (UTL_NOMATCH);
11343 break;
11344 case 1:
11345 free(new_rstring);
11346 return (UTL_MATCH);
11347 break;
11348 }
11349 }
11350 #endif
11351 }
11352
11353
11354
11355
11356
11357
11358
11359
11360
11361
11362
11363
11364
11365
11366
11367
11368
11369
11370
11371
11372
11373
11374
11375
11376
11377
11378
11379
11380
11381 char *
11382 UTL_ConvertRegex(char *regex)
11383 {
11384
11385 char
11386 *new_regex = (char *) NULL;
11387 int
11388 malloced_size = 0;
11389 int
11390 i,
11391 j,
11392 escape_on;
11393
11394 if (new_regex == (char *) NULL) {
11395 malloced_size = REGEX_SIZE;
11396 if ((new_regex = (char *) malloc(malloced_size)) == (char *) NULL) {
11397 return ((char *) NULL);
11398 }
11399 }
11400 i = j = 0;
11401 escape_on = OFF;
11402 new_regex[j++] = '^';
11403 while (regex[i] != '\000') {
11404 switch (regex[i]) {
11405 case '*':
11406
11407 switch (escape_on) {
11408 case OFF:
11409 new_regex[j++] = '.';
11410 break;
11411 case ON:
11412 new_regex[j++] = '\\';
11413 escape_on = OFF;
11414 break;
11415 }
11416 new_regex[j++] = '*';
11417 i++;
11418 break;
11419 case '?':
11420 switch (escape_on) {
11421 case OFF:
11422 new_regex[j++] = '.';
11423 break;
11424 case ON:
11425 new_regex[j++] = '?';
11426 escape_on = OFF;
11427 break;
11428 }
11429 i++;
11430 break;
11431 case '\\':
11432
11433 switch (escape_on) {
11434 case OFF:
11435 escape_on = ON;
11436 break;
11437 case ON:
11438 escape_on = OFF;
11439 new_regex[j++] = '\\';
11440 new_regex[j++] = '\\';
11441 break;
11442 }
11443 i++;
11444 break;
11445 case '.':
11446 case '[':
11447
11448 case ']':
11449 new_regex[j++] = '\\';
11450 new_regex[j++] = regex[i++];
11451 escape_on = OFF;
11452 break;
11453 default:
11454 switch (escape_on) {
11455 case ON:
11456 new_regex[j++] = '\\';
11457 escape_on = OFF;
11458 break;
11459 case OFF:
11460 break;
11461 }
11462 new_regex[j++] = regex[i++];
11463 break;
11464 }
11465 if (j >= (malloced_size - 2)) {
11466 malloced_size += REGEX_SIZE;
11467 if ((new_regex = (char *) realloc(new_regex, malloced_size)) ==
11468 (char *) NULL) {
11469 return ((char *) NULL);
11470 }
11471 }
11472 }
11473 new_regex[j++] = '$';
11474 new_regex[j] = '\000';
11475 return (new_regex);
11476 }
11477 #endif
11478
11479
11480
11481 long
11482 UTL_ConvertDatetoLong(const char *date)
11483 {
11484
11485 char
11486 year[5],
11487 month[3],
11488 day[3];
11489
11490 strncpy(year, date, 4);
11491 year[4] = '\000';
11492 strncpy(month, date + 4, 2);
11493 month[2] = '\000';
11494 strncpy(day, date + 6, 2);
11495 day[2] = '\000';
11496
11497 return ((atol(year) * 10000) + (atol(month) * 100) + atol(day));
11498 }
11499
11500
11501
11502
11503 void
11504 UTL_ConvertLongtoDate(long ld, char *date)
11505 {
11506
11507 int
11508 year,
11509 month,
11510 day;
11511
11512 year = ld / 10000;
11513 ld -= (year * 10000);
11514 month = ld / 100;
11515 ld -= (month * 100);
11516 day = ld;
11517
11518 sprintf(date, "%04d%02d%02d", year, month, day);
11519
11520 return;
11521 }
11522
11523
11524
11525
11526 double
11527 UTL_ConvertTimetoFloat(const char *time)
11528 {
11529
11530 size_t
11531 i;
11532 char
11533 hour[3],
11534 minute[3],
11535 second[3],
11536 fracsec[7];
11537 const char *p;
11538 double
11539 divisor,
11540 hh,
11541 mm,
11542 ss,
11543 fs;
11544
11545 hh = mm = ss = fs = 0.0;
11546 hour[0] = minute[0] = second[0] = fracsec[0] = '\000';
11547
11548 p = time;
11549
11550
11551
11552
11553
11554 hour[0] = *p++;
11555 hour[1] = *p++;
11556 hour[2] = '\000';
11557 if (isdigit(*p)) {
11558 minute[0] = *p++;
11559 minute[1] = *p++;
11560 minute[2] = '\000';
11561 if (isdigit(*p)) {
11562 second[0] = *p++;
11563 second[1] = *p++;
11564 second[2] = '\000';
11565 if (*p == '.') {
11566 p++;
11567 fracsec[0] = *p++;
11568 if ((*p != '\000') && (isdigit(*p))) {
11569 fracsec[1] = *p++;
11570 if ((*p != '\000') && (isdigit(*p))) {
11571 fracsec[2] = *p++;
11572 if ((*p != '\000') && (isdigit(*p))) {
11573 fracsec[3] = *p++;
11574 if ((*p != '\000') && (isdigit(*p))) {
11575 fracsec[4] = *p++;
11576 if ((*p != '\000') && (isdigit(*p))) {
11577 fracsec[5] = *p++;
11578 fracsec[6] = '\000';
11579 } else
11580 fracsec[5] = '\000';
11581 } else
11582 fracsec[4] = '\000';
11583 } else
11584 fracsec[3] = '\000';
11585 } else
11586 fracsec[2] = '\000';
11587 } else
11588 fracsec[1] = '\000';
11589 }
11590 }
11591 }
11592 hh = atof(hour);
11593 mm = atof(minute);
11594 ss = atof(second);
11595 divisor = 1;
11596 for (i = 0; i < strlen(fracsec); i++)
11597 divisor *= 10;
11598 fs = atof(fracsec) / divisor;
11599
11600 return ((hh * 3600.0) + (mm * 60.0) + ss + fs);
11601 }
11602
11603
11604
11605
11606 void
11607 UTL_ConvertFloattoTime(double dt, char *time)
11608 {
11609 int
11610 hour,
11611 minute,
11612 second,
11613 fracsec;
11614
11615 hour = (int) (dt / 3600.0);
11616 dt -= (hour * 3600);
11617
11618 minute = (int) (dt / 60.);
11619 dt -= (minute * 60);
11620
11621 second = (int) dt;
11622 dt -= second;
11623
11624 fracsec = (int) ((dt * 1000000) + 0.5);
11625
11626 sprintf(time, "%02d%02d%02d.%06d", hour, minute, second, fracsec);
11627
11628 return;
11629 }
11630
11631
11632
11633
11634
11635 void
11636 UTL_SqueezeBlanks(char *s)
11637 {
11638
11639 char
11640 *t1,
11641 *t2;
11642
11643 t1 = t2 = s;
11644 while (*t2 != '\000') {
11645 if (*t2 != ' ') {
11646 *t1 = *t2;
11647 t1++;
11648 }
11649 t2++;
11650 }
11651 *t1 = '\000';
11652
11653 return;
11654 }
11655
11656
11657
11658 CONDITION
11659 UTL_DateMatch(char *datestring, char *stm)
11660 {
11661
11662 int
11663 match;
11664 char
11665 *ndate;
11666 long
11667 start_date,
11668 end_date,
11669 date_in_question;
11670
11671 if ((ndate = (char *) malloc(strlen(datestring) + 1)) == (char *) NULL)
11672 return (UTL_NOMATCH);
11673
11674 strcpy(ndate, datestring);
11675 UTL_SqueezeBlanks(ndate);
11676 UTL_SqueezeBlanks(stm);
11677
11678 match = 0;
11679 if (strchr(ndate, (int) '-') == (char *) NULL) {
11680 if (strcmp(ndate, stm) == 0)
11681 match = 1;
11682 } else {
11683 date_in_question = UTL_ConvertDatetoLong(stm);
11684 if (ndate[0] == '-') {
11685 end_date = UTL_ConvertDatetoLong(ndate + 1);
11686 if (date_in_question <= end_date)
11687 match = 1;
11688 } else if (ndate[strlen(ndate) - 1] == '-') {
11689 start_date = UTL_ConvertDatetoLong(ndate);
11690 if (date_in_question >= start_date)
11691 match = 1;
11692 } else {
11693 start_date = UTL_ConvertDatetoLong(ndate);
11694 end_date = UTL_ConvertDatetoLong(strchr(ndate, (int) '-') + 1);
11695 if ((date_in_question >= start_date) &&
11696 (date_in_question <= end_date))
11697 match = 1;
11698 }
11699 }
11700 free(ndate);
11701 if (match)
11702 return (UTL_MATCH);
11703 else
11704 return (UTL_NOMATCH);
11705 }
11706
11707
11708
11709 CONDITION
11710 UTL_TimeMatch(char *timestring, char *stm)
11711 {
11712
11713 int
11714 match;
11715 char
11716 *ntime;
11717 double
11718 start_time,
11719 end_time,
11720 time_in_question;
11721
11722 if ((ntime = (char *) malloc(strlen(timestring) + 2)) == (char *) NULL)
11723 return (UTL_NOMATCH);
11724
11725 strcpy(ntime, timestring);
11726 UTL_SqueezeBlanks(ntime);
11727 UTL_SqueezeBlanks(stm);
11728
11729 match = 0;
11730 if (strchr(ntime, (int) '-') == (char *) NULL) {
11731 if (strcmp(ntime, stm) == 0)
11732 match = 1;
11733 } else {
11734 time_in_question = UTL_ConvertTimetoFloat(stm);
11735 if (ntime[0] == '-') {
11736 end_time = UTL_ConvertTimetoFloat(ntime + 1);
11737 if (time_in_question <= end_time)
11738 match = 1;
11739 } else if (ntime[strlen(ntime) - 1] == '-') {
11740 start_time = UTL_ConvertTimetoFloat(ntime);
11741 if (time_in_question >= start_time)
11742 match = 1;
11743 } else {
11744 start_time = UTL_ConvertTimetoFloat(ntime);
11745 end_time = UTL_ConvertTimetoFloat(strchr(ntime, (int) '-') + 1);
11746 if ((time_in_question >= start_time) &&
11747 (time_in_question <= end_time))
11748 match = 1;
11749 }
11750 }
11751 free(ntime);
11752 if (match)
11753 return (UTL_MATCH);
11754 else
11755 return (UTL_NOMATCH);
11756 }
11757
11758
11759
11760
11761 void
11762 UTL_GetDicomDate(char *datestr)
11763 {
11764
11765 struct tm
11766 *tf;
11767 time_t
11768 loctime;
11769
11770 loctime = time((time_t *) NULL);
11771 tf = localtime(&loctime);
11772
11773 sprintf(datestr, "%04d%02d%02d", (tf->tm_year) + 1900, (tf->tm_mon) + 1, tf->tm_mday);
11774 return;
11775
11776 }
11777
11778
11779
11780
11781 void
11782 UTL_GetDicomTime(char *timestr)
11783 {
11784
11785 struct tm
11786 *tf;
11787 time_t
11788 loctime;
11789
11790 loctime = time((time_t *) NULL);
11791 tf = localtime(&loctime);
11792
11793 sprintf(timestr, "%02d%02d%02d.%06d", (tf->tm_hour), (tf->tm_min), (tf->tm_sec), 0);
11794 return;
11795 }
11796
11797 #ifdef _MSC_VER
11798 typedef struct {
11799 char key[10];
11800 struct _timeb t;
11801 } UTL_TIMESTRUCTURE;
11802 #else
11803 typedef struct {
11804 char key[10];
11805 struct timeval t;
11806 } UTL_TIMESTRUCTURE;
11807 #endif
11808
11809 void *
11810 UTL_GetTimeStamp()
11811 {
11812 UTL_TIMESTRUCTURE *t;
11813
11814 t = AFMALL( UTL_TIMESTRUCTURE, sizeof(*t));
11815 if (t == NULL)
11816 return NULL;
11817
11818 strcpy(t->key, "UTL STAMP");
11819
11820 gettimeofday(&t->t, NULL);
11821
11822 return t;
11823 }
11824
11825 double
11826 UTL_DeltaTime(void *timeStamp)
11827 {
11828 struct timeval timeNow;
11829 UTL_TIMESTRUCTURE *t;
11830 double delta = 0.;
11831
11832 gettimeofday(&timeNow, NULL);
11833
11834 t = (UTL_TIMESTRUCTURE *) timeStamp;
11835 if (t == NULL)
11836 return -1.0;
11837
11838 if (strcmp(t->key, "UTL STAMP") != 0)
11839 return -1.0;
11840
11841 delta = timeNow.tv_sec - t->t.tv_sec;
11842 delta += (timeNow.tv_usec - t->t.tv_usec) / 1000000.;
11843
11844 return delta;
11845 }
11846
11847 void
11848 UTL_ReleaseTimeStamp(void *timeStamp)
11849 {
11850 UTL_TIMESTRUCTURE *t;
11851
11852 t = (UTL_TIMESTRUCTURE *) timeStamp;
11853 if (t == NULL)
11854 return;
11855
11856 if (strcmp(t->key, "UTL STAMP") != 0)
11857 return;
11858
11859 free(timeStamp);
11860 }
11861
11862 CONDITION
11863 UTL_VerifyCreatePath(const char *path)
11864 {
11865 int i;
11866 #ifdef _MSC_VER
11867 struct _stat buf;
11868 #else
11869 struct stat buf;
11870 #endif
11871 char
11872 *p,
11873 temp[1024];
11874 int flag = 0;
11875 static int statCount = 0;
11876
11877 #ifdef _MSC_VER
11878 statCount++;
11879 i = _stat(path, &buf);
11880 #else
11881 i = stat(path, &buf);
11882 #endif
11883
11884
11885 if (i == 0) {
11886 #ifdef _MSC_VER
11887 flag = ((buf.st_mode & _S_IFDIR) != 0);
11888 #else
11889 flag = (S_ISDIR(buf.st_mode));
11890 #endif
11891 if (flag)
11892 return UTL_NORMAL;
11893 else
11894 return UTL_PATHNOTDIR;
11895 }
11896 p = temp;
11897
11898 while (*path != '\0') {
11899 *p++ = *path++;
11900 while (*path != '/' && *path != '\\' && *path != '\0') {
11901 #ifdef _MSC_VER
11902 if (*path == ':') {
11903 *p++ = *path++;
11904 if (*path == '\0')
11905
11906 break;
11907 }
11908 #endif
11909 *p++ = *path++;
11910 }
11911
11912 *p = '\0';
11913 #ifdef _MSC_VER
11914 statCount++;
11915 i = _stat(temp, &buf);
11916 #else
11917 i = stat(temp, &buf);
11918 #endif
11919
11920 if (i == 0) {
11921 #ifdef _MSC_VER
11922 flag = ((buf.st_mode & _S_IFDIR) != 0);
11923 #else
11924 flag = (S_ISDIR(buf.st_mode));
11925 #endif
11926 if (!flag)
11927 return UTL_PATHNOTDIR;
11928 } else {
11929 #ifdef _MSC_VER
11930 int e1;
11931 e1 = errno;
11932 memset(&buf, 0, sizeof(buf));
11933
11934 statCount++;
11935 i = _stat(temp, &buf);
11936 e1 = errno;
11937 i = _mkdir(temp);
11938 #else
11939 i = mkdir(temp, 0777);
11940 #endif
11941 if (i != 0) {
11942 int e1;
11943 e1 = errno;
11944 fprintf(stderr, "Stat Count = %d\n", statCount);
11945 perror(temp);
11946 return UTL_FILECREATEFAILED;
11947 }
11948 }
11949 }
11950 return UTL_NORMAL;
11951 }
11952
11953 CTNBOOLEAN UTL_IsDirectory(const char* path)
11954 {
11955 int i;
11956 #ifdef _MSC_VER
11957 struct _stat buf;
11958 #else
11959 struct stat buf;
11960 #endif
11961
11962 int flag = 0;
11963
11964 #ifdef _MSC_VER
11965 i = _stat(path, &buf);
11966 #else
11967 i = stat(path, &buf);
11968 #endif
11969
11970
11971 if (i == 0) {
11972 #ifdef _MSC_VER
11973 flag = ((buf.st_mode & _S_IFDIR) != 0);
11974 #else
11975 flag = (S_ISDIR(buf.st_mode));
11976 #endif
11977 if (flag)
11978 return TRUE;
11979 }
11980 return FALSE;
11981 }
11982
11983
11984 #if 0
11985 CONDITION UTL_ScanDirectory(const char* path,
11986 LST_HEAD** lst)
11987 {
11988 UTL_FILEITEM* item = 0;
11989
11990 #ifdef _WIN32
11991 long hFile = 0;
11992 struct _finddata_t fileInfo;
11993 char directoryText[1024];
11994 *lst = LST_Create();
11995 strcpy(directoryText, path);
11996 strcat(directoryText, "/*");
11997 if( (hFile = _findfirst(directoryText, &fileInfo)) == -1L)
11998 return 0;
11999
12000 item = malloc(sizeof(*item));
12001 strcpy(item->path, fileInfo.name);
12002 LST_Enqueue(lst, item);
12003
12004 while(_findnext(hFile, &fileInfo) == 0) {
12005 item = malloc(sizeof(*item));
12006 strcpy(item->path, fileInfo.name);
12007 LST_Enqueue(lst, item);
12008 }
12009 _findclose(hFile);
12010
12011 #else
12012 DIR* dirp;
12013 struct dirent* dp;
12014
12015 *lst = LST_Create();
12016 dirp = opendir(path);
12017 if (dirp == 0)
12018 return 0;
12019
12020 while ((dp = readdir(dirp)) != NULL) {
12021 item = malloc(sizeof(*item));
12022 strcpy(item->path, dp->d_name);
12023 LST_Enqueue(lst, (void *)item);
12024 }
12025 closedir(dirp);
12026 #endif
12027
12028 return UTL_NORMAL;
12029 }
12030 #endif
12031
12032 static char* UTL_configFile = 0;
12033 static LST_HEAD* UTL_configList = 0;
12034 typedef struct {
12035 void* reserved[2];
12036 char *pName;
12037 char *pValue;
12038 } CONFIG_ITEM;
12039
12040 CONDITION UTL_ReadConfigFile( )
12041 {
12042 FILE* f;
12043 char buf[1024];
12044
12045 if (UTL_configList != 0)
12046 return UTL_NORMAL;
12047
12048 UTL_configList = LST_Create();
12049 if (UTL_configList == NULL)
12050 return 0;
12051
12052 if (UTL_configFile == 0)
12053 return UTL_NORMAL;
12054
12055 if (UTL_configFile[0] == '\0')
12056 return UTL_NORMAL;
12057
12058 f = fopen(UTL_configFile, "r");
12059 if (f == NULL)
12060 return 0;
12061
12062 while (fgets(buf, sizeof(buf), f) != NULL) {
12063 char* token1;
12064 char* token2;
12065 CONFIG_ITEM* item;
12066
12067 if (buf[0] == '#') continue;
12068 if (buf[0] == '\n') continue;
12069 token1 = strtok(buf, " \t\n");
12070 token2 = strtok(0, " \t\n");
12071 if (token2 == NULL) continue;
12072
12073 item = (CONFIG_ITEM*)malloc(sizeof(*item) + strlen(token1) +
12074 strlen(token2) + 2);
12075 item->pName = ((char*)item) + sizeof(*item);
12076 strcpy(item->pName, token1);
12077 item->pValue = item->pName + strlen(token1) + 1;
12078 strcpy(item->pValue, token2);
12079
12080 LST_Enqueue(&UTL_configList, (void *)item);
12081 }
12082
12083 fclose(f);
12084
12085 return UTL_NORMAL;
12086 }
12087
12088 CONDITION UTL_SetConfigFile(const char* configFile)
12089 {
12090 if (UTL_configFile != 0) {
12091 CTN_FREE(UTL_configFile);
12092 }
12093
12094 if (configFile == 0 || configFile[0] == '\0') {
12095 char* p = getenv("CTN_TARGET");
12096 if (p == NULL) {
12097 return UTL_NO_CTN_TARGET;
12098 }
12099 UTL_configFile = (char*) malloc(strlen(p) + strlen("/runtime/ctn_cfg.txt") + 1);
12100 strcpy(UTL_configFile, p);
12101 strcat(UTL_configFile, "/runtime/ctn_cfg.txt");
12102 } else {
12103 UTL_configFile = (char*) malloc(strlen(configFile)+1);
12104 strcpy(UTL_configFile, configFile);
12105 }
12106
12107 return UTL_NORMAL;
12108 }
12109
12110 CONDITION UTL_TestConfigFile(const char* configFile)
12111 {
12112 return UTL_NORMAL;
12113 }
12114 char* UTL_GetConfigParameter(const char* paramName)
12115 {
12116 CONDITION cond;
12117 char nameCopy[256];
12118 CONFIG_ITEM* item;
12119 int idx;
12120
12121 cond = UTL_ReadConfigFile( );
12122 if (cond != UTL_NORMAL)
12123 return NULL;
12124
12125 item = (void *)LST_Head(&UTL_configList);
12126 if (item == NULL)
12127 return NULL;
12128
12129 (void) LST_Position(&UTL_configList, (void *)item);
12130 while(item != NULL) {
12131 if (strcmp(item->pName, paramName) == 0)
12132 return item->pValue;
12133
12134 item = (void *)LST_Next(&UTL_configList);
12135 }
12136
12137 strcpy(nameCopy, paramName);
12138 idx = strlen(nameCopy) - 1;
12139 while (idx > 0) {
12140 if (nameCopy[idx] == '/') {
12141 nameCopy[idx] = '\0';
12142 idx = -1;
12143 break;
12144 } else {
12145 idx--;
12146 }
12147 }
12148
12149 if (idx < 0) {
12150 return UTL_GetConfigParameter(nameCopy);
12151 } else {
12152 return NULL;
12153 }
12154 }
12155
12156 char**
12157 UTL_ExpandToPointerArray(const char* inputText,
12158 const char* delimiters,
12159 int* numberOfEntries)
12160 {
12161 int idx;
12162 int memorySize = 0;
12163 int arrayIndex = 0;
12164 char** array;
12165 char* outputPtr;
12166 char* token;
12167
12168 *numberOfEntries = 1;
12169 for (idx = 0; inputText[idx] != '\0'; idx++) {
12170 int j;
12171 for (j = 0; delimiters[j] != '\0'; j++) {
12172 if (inputText[idx] == delimiters[j]) {
12173 (*numberOfEntries)++;
12174 break;
12175 }
12176 }
12177 }
12178
12179 memorySize = (sizeof(char*)) * (*numberOfEntries);
12180 memorySize += strlen(inputText) + 1;
12181
12182 array = (char**)CTN_MALLOC(memorySize);
12183 outputPtr = ((char*) array) + ((sizeof(char*)) * (*numberOfEntries));
12184 strcpy(outputPtr, inputText);
12185
12186 token = strtok(outputPtr, delimiters);
12187 while(token != NULL) {
12188 array[arrayIndex++] = token;
12189 token = strtok(NULL, delimiters);
12190 }
12191
12192 return array;
12193 }
12194
12195 CTNBOOLEAN UTL_IsFile(const char* path)
12196 {
12197 int i;
12198 CTNBOOLEAN rtnValue = FALSE;
12199
12200 #ifdef _WIN32
12201 struct _stat buf;
12202
12203 i = _stat(path, &buf);
12204 if (i == 0) {
12205 rtnValue = ((buf.st_mode & _S_IFREG) != 0);
12206 }
12207 #else
12208 struct stat buf;
12209 i = stat(path, &buf);
12210 if (i == 0) {
12211 rtnValue = (S_ISREG(buf.st_mode));
12212 }
12213 #endif
12214
12215 return rtnValue;
12216 }
12217
12218 CONDITION UTL_DeleteFile(const char* path)
12219 {
12220 int i = 0;
12221
12222 i = unlink(path);
12223
12224 if (i == 0)
12225 return UTL_NORMAL;
12226
12227 return COND_PushCondition(UTL_DELETEFILEFAILED, "");
12228 }
12229
12230
12231 CONDITION
12232 UTL_FileSize(const char* path, U32* size)
12233 {
12234 int status;
12235 struct stat im_stat;
12236
12237 status = stat(path, &im_stat);
12238 if (status < 0) {
12239 *size = 0;
12240 return 0;
12241 } else {
12242 *size = im_stat.st_size;
12243 return UTL_NORMAL;
12244 }
12245 }
12246
12247
12248
12249
12250
12251
12252
12253
12254
12255
12256
12257
12258
12259
12260
12261
12262
12263
12264
12265
12266
12267
12268
12269
12270
12271
12272
12273
12274
12275
12276
12277
12278
12279
12280
12281 CONDITION
12282 DCM_ExportStream(DCM_OBJECT ** callerObject, unsigned long opt,
12283 void *buffer, unsigned long bufferlength,
12284 DCM_EXPORT_STREAM_CALLBACK* callback,
12285 void *ctx)
12286 {
12287
12288
12289 PRIVATE_OBJECT
12290 ** object;
12291 CONDITION
12292 cond;
12293
12294 object = (PRIVATE_OBJECT **) callerObject;
12295 cond = checkObject(object, "DCM_ExportStream");
12296 if (cond != DCM_NORMAL)
12297 return cond;
12298
12299 return exportStream(callerObject, opt, buffer, bufferlength, callback,
12300 ctx, 0);
12301 }