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