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