/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * filename: m-acr.c                                                       *
 *                                                                         *
 * UTIL C-source: Medical Image Conversion Utility                         *
 *                                                                         *
 * purpose      : read and write ACR/NEMA files                            *
 *                                                                         *
 * project      : (X)MedCon by Erik Nolf                                   *
 *                                                                         *
 * Functions    : MdcCheckACR()      - Check ACR/NEMA format               *
 *                MdcSwapTag()       - Swap bytes in tag                   *
 *                MdcFindAcrInfo()   - Find readable tags in hacked file   *
 *                MdcGetAcrInfo()    - Get data from tags in hacked file   *
 *                MdcHackACR()       - Hack a file for ACR/NEMA tags       *
 *                MdcReadACR()       - Read ACR/NEMA file                  *
 *                MdcPrintTag()      - Display tag content                 *
 *                MdcGetStrVM()      - Get VM string from an element       *
 *                MdcDicomInitStuff()- Initialize dicom stuff struct       *
 *                MdcDicomCheckVect()- Check dicom vector tags             *
 *                MdcDicomNrOfVect() - Give true number of vector items    *
 *                MdcDicomDoAcqData()- Check wheter to fill acq  data      *
 *                MdcDicomSOPClass() - Handle SOP Class (modality)         *
 *                MdcGetHHMMSS()     - Get hour, minute, sec from string   *
 *                MdcDoTag()         - Handle the tag                      *
 *                MdcPutGroupLength()- Write the group length              *
 *                MdcPutTag()        - Write tag to file                   *
 *                MdcPutGroup()      - Write group to file                 *
 *                MdcWriteACR()      - Write ACR/NEMA file                 *
 *                                                                         *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
 */

/*
   Copyright (C) 1997-2026 by Erik Nolf

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any later
   version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
   Public License for more details.

   You should have received a copy of the GNU General Public License along
   with this program; if not, write to the Free Software Foundation, Inc.,
   59 Place - Suite 330, Boston, MA 02111-1307, USA.  */

/****************************************************************************
                              H E A D E R S
****************************************************************************/

#include "m-depend.h"

#include <stdio.h>
#include <stdarg.h>
#ifdef LIBMDC_HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef LIBMDC_HAVE_STRING_H
#include <string.h>
#endif
#ifdef LIBMDC_HAVE_STRINGS_H
#ifndef _WIN32
#include <strings.h>
#endif
#endif

#include "medcon.h"


/****************************************************************************
                              D E F I N E S
****************************************************************************/

#define MDC_TAGS_NEEDED   3

static Uint32 MDC_HACK_BYTES = 2048;
static int MDC_HACK_SUCCESS;
static off_t FP_G0008_E0001;

MDC_DICOM_STUFF_T mdc_dicom_stuff;

/****************************************************************************
                            F U N C T I O N S
****************************************************************************/

int MdcCheckACR(FILEINFO *fi)
{
  MDC_ACR_TAG acrtag[3], *tag;
  Int8 FRMT = MDC_FRMT_NONE;
  int r;

  r = fread((Uint8 *)&acrtag[0], 1, MDC_ACR_TAG_SIZE, fi->ifp);
  if (r != MDC_ACR_TAG_SIZE) return (MDC_BAD_READ);

  if (acrtag[0].group == 0x0008)  MDC_FILE_ENDIAN = MDC_HOST_ENDIAN;
  else {
    MDC_FILE_ENDIAN = !MDC_HOST_ENDIAN;
  }
  MdcSwapTag(&acrtag[0]);
  if (acrtag[0].group != 0x0008) return(MDC_FRMT_NONE);

  fseeko(fi->ifp,(off_t)acrtag[0].length,SEEK_CUR);
  r = fread((Uint8 *)&acrtag[1], 1, MDC_ACR_TAG_SIZE, fi->ifp);
  if (r != MDC_ACR_TAG_SIZE) return (MDC_BAD_READ);

  MdcSwapTag(&acrtag[1]);
  fseeko(fi->ifp,(off_t)acrtag[1].length, SEEK_CUR);
  r = fread((Uint8 *)&acrtag[2], 1, MDC_ACR_TAG_SIZE, fi->ifp);
  if (r != MDC_ACR_TAG_SIZE) return (MDC_BAD_READ);
  MdcSwapTag(&acrtag[2]);

  if (acrtag[1].group != 0x0008) return(MDC_FRMT_NONE);

  if (acrtag[2].group != 0x0008) return (MDC_FRMT_NONE);


  /* return(MDC_FRMT_ACR) */

  /* test on Acr/Nema Recognition code as well */
  /* to prevent little implicit DICOM files    */
  fseeko(fi->ifp,(off_t)0,SEEK_SET); tag = (MDC_ACR_TAG *)&acrtag[0];
  while( ftello(fi->ifp) < (off_t)MDC_HACK_BYTES) {

    if (fread((Uint8 *)tag,1,MDC_ACR_TAG_SIZE,fi->ifp) != MDC_ACR_TAG_SIZE)
      return(MDC_BAD_READ);

    MdcSwapTag(tag);

    if (tag->length == 0xffffffff) tag->length = 0;

    if ((tag->group == 0x0008) && (tag->element == 0x0010)) {
      if ((tag->data=malloc(tag->length+1)) == NULL)
        return(MDC_BAD_ALLOC);

      tag->data[tag->length]='\0';

      if (fread(tag->data,1,tag->length,fi->ifp) != tag->length) {
        MdcFree(tag->data);
        return(MDC_BAD_READ);
      }

      MdcLowStr((char *)tag->data);

      if (strstr((char *)tag->data,"acr-nema") != NULL) FRMT = MDC_FRMT_ACR;

      MdcFree(tag->data);

      return(FRMT);

    }else{

      fseeko(fi->ifp,(off_t)tag->length,SEEK_CUR);

    }

    if (ferror(fi->ifp)) return(MDC_BAD_READ);

  }

  return(FRMT);

}

void MdcSwapTag(MDC_ACR_TAG *tag)
{
  MdcSWAP(tag->group); MdcSWAP(tag->element); MdcSWAP(tag->length);
}

int MdcFindAcrInfo(FILEINFO *fi, off_t filesize, off_t *BeginAddress)
{
  FILE *fp=fi->ifp;
  MDC_ACR_TAG acrtag, *tag=NULL;
  off_t AddressFound=(*BeginAddress);
  int HackSuccess=0, i, r;

  tag = (MDC_ACR_TAG *)&acrtag;

  fseeko(fp,AddressFound,SEEK_SET);
  while( (ftello(fp) < (off_t)MDC_HACK_BYTES) && (HackSuccess<MDC_TAGS_NEEDED) ) {

    /* read/test a couple of tags, no error checking necessary */
    for (i=0; i<MDC_TAGS_NEEDED; i++) {

      r = fread((Uint8 *)tag,1,MDC_ACR_TAG_SIZE,fp);
      if (r != MDC_ACR_TAG_SIZE) continue;

      MdcSwapTag(tag);

      if (tag->length == 0xffffffff ) tag->length = 0;

      fseeko(fp,(off_t)tag->length,SEEK_CUR);

      tag->data=NULL; tag->length=0; /* leave data out */
      MdcDoTag(NULL,tag,fi,0);

      if (MDC_HACK_SUCCESS) {
        MDC_HACK_SUCCESS = MDC_NO; HackSuccess+=1;
      }else{
        MDC_HACK_SUCCESS = MDC_NO; HackSuccess=0;
      }
    }

    if (HackSuccess < MDC_TAGS_NEEDED) {
      AddressFound+=1; fseeko(fp,AddressFound,SEEK_SET);
    }

  }

  *BeginAddress = AddressFound;

  if (HackSuccess < MDC_TAGS_NEEDED) return(MDC_NO);

  return(MDC_YES);

}

int MdcGetAcrInfo(FILEINFO *fi, off_t filesize, off_t offset)
{
  FILE *fp = fi->ifp;
  MDC_ACR_TAG acrtag, *tag=NULL;
  Uint32 BytesPerImage;

  tag = (MDC_ACR_TAG *)&acrtag;

  fseeko(fp,offset,SEEK_SET);
  while ( (ftello(fp) + (off_t)MDC_ACR_TAG_SIZE) < filesize ) {

   if (fread((Uint8 *)tag,1,MDC_ACR_TAG_SIZE,fp) != MDC_ACR_TAG_SIZE)
     continue;

   MdcSwapTag(tag);

   if (tag->length == 0xffffffff) tag->length = 0;

   if ((tag->data=malloc(tag->length+1)) == NULL) {
     fseeko(fp,(off_t)tag->length,SEEK_CUR); continue;
   }

   tag->data[tag->length]='\0';

   if (fread(tag->data,1,tag->length,fp) != tag->length) {
     MdcFree(tag->data);
     continue;
   }

   MdcDoTag(NULL,tag,fi,0);

   MdcFree(tag->data);

  }

  BytesPerImage = fi->image[0].width*fi->image[0].height;
  BytesPerImage *= MdcPixels2Bytes(fi->image[0].bits);

  if (BytesPerImage > 0 ) return(MDC_YES);

  return(MDC_NO);

}

/* experimental and will fail for images with different sizes */
char *MdcHackACR(FILEINFO *fi)
{
  FILE *fp = fi->ifp;
  MDC_ACR_TAG acrtag, *tag=NULL;
  off_t filesize, BytesOffset, BeginAddress=0, *ImagesOffsets=NULL;
  Uint32 MaxImages=0, BytesPerImage=0, BytesPerPixel=0;
  Uint32 i, img=0;
  int found=MDC_NO;

  /* initialize some things */

  MDC_INFO = MDC_NO;
  tag = (MDC_ACR_TAG *)&acrtag;

  fseeko(fp,(off_t)0,SEEK_END);
  filesize = ftello(fp);
  fseeko(fp,(off_t)0,SEEK_SET);

  /* MDC_HACK_BYTES = filesize; hack the whole file if you want */

  MdcPrntScrn("\nACR  Hacking <%s> for %u bytes ... ",fi->ifname
                                                        ,MDC_HACK_BYTES);

  /* get an IMG_DATA struct */
  if (!MdcGetStructID(fi,1)) return("ACR  - Hack - Bad malloc IMG_DATA struct");

  /* hack for HostEndian */
  MDC_FILE_ENDIAN = MDC_HOST_ENDIAN; BeginAddress=0;
  while ( (!found) && (BeginAddress < MDC_HACK_BYTES)) {
       found=MdcFindAcrInfo(fi,filesize,&BeginAddress);
       if (found) found=MdcGetAcrInfo(fi,filesize,BeginAddress);
       if (!found) BeginAddress+=1;
  }
  if (found == MDC_NO) {
    /* hack for NoHostEndian */
    MDC_FILE_ENDIAN = !MDC_HOST_ENDIAN; BeginAddress=0;
    while ( (!found) && (BeginAddress < (off_t)MDC_HACK_BYTES)) {
         found=MdcFindAcrInfo(fi,filesize,&BeginAddress);
         if (found) found=MdcGetAcrInfo(fi,filesize,BeginAddress);
         if (!found) BeginAddress+=1;
    }
  }

  MDC_INFO=MDC_YES;
  /* print out/rework the information */
  if (found == MDC_YES) {

    MdcPrntScrn("\n");

    BytesPerPixel = MdcPixels2Bytes(fi->image[0].bits);
    BytesPerImage = fi->image[0].width*fi->image[0].height*BytesPerPixel;
    if (BytesPerImage > 0 ) MaxImages = (Uint32)(filesize/(off_t)BytesPerImage);

    if (MaxImages > 0) {
      ImagesOffsets=(off_t *)malloc((MaxImages+100)*sizeof(off_t));
                                            /* +100 as safe buffer */
      if (ImagesOffsets == NULL) {
        return("ACR  - Hack - Couldn't malloc ImagesOffsets array");
      }else{
        ImagesOffsets[0]=(off_t)0; /* keeps the number of offsets */
      }
    }else{
      return("ACR  - Hack - Failed to find number of images");
    }


    fseeko(fp,BeginAddress,SEEK_SET);
    while ( ((BytesOffset=ftello(fp)) + (off_t)MDC_ACR_TAG_SIZE) <= filesize ) {

       if (fread((Uint8 *)tag,1,MDC_ACR_TAG_SIZE,fp) != MDC_ACR_TAG_SIZE)
         continue;

       MdcSwapTag(tag);

       if (tag->length == 0xffffffff ) tag->length = 0;

       if ((tag->data=malloc(tag->length+1)) == NULL) {
         fseeko(fp,(off_t)tag->length,SEEK_CUR); continue;
       }

       tag->data[tag->length]='\0';

       if (fread(tag->data,1,tag->length,fp) != tag->length) {
         MdcFree(tag->data);
         continue;
       }

       MdcPrntScrn("\n==========>> BYTES OFFSET NEXT TAG: %u\n",BytesOffset);

       MdcDoTag(NULL,tag,fi,0);

       /* real Acr/Nema tag for image => real offset to image */
       if (tag->group == 0x7fe0 && tag->element == 0x0010) {
         ImagesOffsets[img++]=BytesOffset + MDC_ACR_TAG_SIZE;
       }else if ((tag->length / BytesPerImage) == 1) {
         ImagesOffsets[img++]=BytesOffset + MDC_ACR_TAG_SIZE;
       }

       MdcFree(tag->data);

    }

    MdcPrntScrn("\n");
    MdcPrntScrn("===================\n");
    MdcPrntScrn("FINAL ACR-HACK INFO\n");
    MdcPrntScrn("===================\n\n");
    MdcPrntScrn("Patient/Study Info\n");
    MdcPrntScrn("------------------\n");
    MdcPrntScrn("  Patient Name : %s\n",fi->patient_name);
    MdcPrntScrn("  Patient Sex  : %s\n",fi->patient_sex);
    MdcPrntScrn("  Patient ID   : %s\n",fi->patient_id);
    MdcPrntScrn("  Study Descr  : %s\n",fi->study_descr);
    MdcPrntScrn("  Study ID     : %s\n",fi->study_id);
    MdcPrntScrn("  Study Date   : %d/%d/%d [dd/mm/yyyy]\n",fi->study_date_day
                                                     ,fi->study_date_month
                                                     ,fi->study_date_year);
    MdcPrntScrn("  Study Time   : %d:%d:%d [hh/mm/ss]\n",fi->study_time_hour
                                                   ,fi->study_time_minute
                                                   ,fi->study_time_second);
    MdcPrntScrn("\n");
    MdcPrntScrn("Pixel/Slice   Info\n");
    MdcPrntScrn("------------------\n");
    MdcPrntScrn("  Pixel Size   : %+e [mm]\n",fi->image[0].pixel_ysize);
    MdcPrntScrn("  Slice Width  : %+e [mm]\n",fi->image[0].slice_width);
    MdcPrntScrn("\n");
    MdcPrntScrn("Images/Pixel  Info\n");
    MdcPrntScrn("------------------\n");
    MdcPrntScrn("  Host Endian Type : %s\n",MdcGetStrEndian(MDC_HOST_ENDIAN));
    MdcPrntScrn("  File Endian Type : %s\n",MdcGetStrEndian(MDC_FILE_ENDIAN));
    MdcPrntScrn("  Offset First TAG : %u\n",BeginAddress);
    MdcPrntScrn("  Image Columns [X]: %u\n",fi->image[0].width);
    MdcPrntScrn("  Image Rows    [Y]: %u\n",fi->image[0].height);
    MdcPrntScrn("  Bits  / Pixel    : %hd\n",fi->image[0].bits);
    MdcPrntScrn("  Bytes / Pixel    : %u ",BytesPerPixel);
    switch(BytesPerPixel) {
     case 1: MdcPrntScrn("(Int8 , Uint8 , 1bit, ?)\n");   break;
     case 2: MdcPrntScrn("(Int16, Uint16, ?)\n");         break;
     case 4: MdcPrntScrn("(Int32, Uint32, float, ?)\n");  break;
     case 8: MdcPrntScrn("(Int64, Uint64, double, ?)\n"); break;
     default: MdcPrntScrn("(?)\n");
    }
    MdcPrntScrn("  Possible Pix Type: %s\n"
                  ,MdcGetStrPixelType(fi->image[0].type));
    MdcPrntScrn("  Bytes / Image    : %u\n",BytesPerImage);
    MdcPrntScrn("  Filesize         : %jd\n",(intmax_t)filesize);
    if (BytesPerImage > 0)
    MdcPrntScrn("  Maximum Images   : %u\n",MaxImages);
    else
    MdcPrntScrn("  Maximum Images   : <unknown>\n");
    /* where to find the images? */
    MdcPrntScrn("\n");
    MdcPrntScrn("Possible Offsets to Images\n");
    MdcPrntScrn("--------------------------\n");
    MdcPrntScrn("\n   a) tags->length ~ Bytes/Image:\n");
    if (img == 0) {
      MdcPrntScrn("\n\t  <not found>\n");
    }else{
      for (i=0; i<img; i++)
         MdcPrntScrn("\t- offset[%u] : %jd\n",i+1,(intmax_t)ImagesOffsets[i]);
    }
    MdcPrntScrn("\n   b) Images at the end of file :\n");
    MdcPrntScrn("\t- last image: %jd\n",(intmax_t)(filesize-(off_t)BytesPerImage));
    MdcPrntScrn("\t- all images: %jd\n",(intmax_t)(filesize-((off_t)MaxImages*BytesPerImage)));

    MdcFree(ImagesOffsets);

  }else{

    MdcPrntScrn(" No ACR tags found\n\n");

  }

  return(NULL);

}



const char *MdcReadACR(FILEINFO *fi)
{
  FILE *fp = fi->ifp;
  IMG_DATA *id = NULL;
  MDC_ACR_TAG acrtag, *tag = NULL;
  MDC_DICOM_STUFF_T *dicom=&mdc_dicom_stuff;
  off_t filesize;
  Uint32 i, frames=1, t, number=0;
  int IMAGE = MDC_YES, r;
  const char *err=NULL;

  if (MDC_PROGRESS) MdcProgress(MDC_PROGRESS_BEGIN,0.,"Reading Acr/Nema:");

  if (MDC_VERBOSE) MdcPrntMesg("ACR  Reading <%s> ...",fi->ifname);

  fseeko(fp,(off_t)0, SEEK_END);
  filesize = ftello(fp);
  fseeko(fp,(off_t)0, SEEK_SET);

  tag = (MDC_ACR_TAG *)&acrtag;

  /* put some defaults we use */
  fi->reconstructed = MDC_YES;
  fi->acquisition_type = MDC_ACQUISITION_TOMO;

  /* init dicom struct */
  MdcDicomInitStuff(dicom);

  /* init  MOD structs */
  MdcGetStructMOD(fi);

  /* get endian of file */
  r = fread((Uint8 *)tag, 1, MDC_ACR_TAG_SIZE, fi->ifp);
  if (r != MDC_ACR_TAG_SIZE) return("ACR  Failure to read tag (endianness).");

  if (tag->group == 0x0008)  MDC_FILE_ENDIAN = MDC_HOST_ENDIAN;
  else {
    MDC_FILE_ENDIAN = !MDC_HOST_ENDIAN;
  }

  MdcSwapTag(tag);

  if (tag->group != 0x0008) return("ACR  Bad initial group");

  fseeko(fp,(off_t)0,SEEK_SET);

  while ( (ftello(fp) + (off_t)MDC_ACR_TAG_SIZE) <= filesize ) {


#if MDC_INCLUDE_DICM
   /* in case of MOSAIC, follow DICOM path */
   if (MdcCheckMosaic(fi,dicom) == MDC_YES) {
     char filename[MDC_MAX_PATH+1];

     MdcMergePath(fi->ipath,fi->idir,fi->ifname);
     MdcAddCompressionExt(fi->compression,fi->ipath);
     strncpy(filename,fi->ipath,MDC_MAX_PATH);
     filename[MDC_MAX_PATH]='\0'; /* assure string termination */
     MdcCleanUpFI(fi);
     if (MdcOpenFile(fi,filename) == MDC_OK) err = MdcReadDICM(fi);
     return(err);
   }
#endif

   if (IMAGE) {

     if (MDC_PROGRESS) MdcProgress(MDC_PROGRESS_SET,0.0,NULL);

     if (!MdcGetStructID(fi,fi->number+1))
       return("ACR  Bad malloc IMG_DATA struct");

     id = &fi->image[fi->number-1];

     IMAGE = MDC_NO;
   }

   if (fread((Uint8 *)tag,1,MDC_ACR_TAG_SIZE,fp) != MDC_ACR_TAG_SIZE)
     return("ACR  Bad read of tag");

   MdcSwapTag(tag);

   if ((tag->group == 0x7fe0) && (tag->element == 0x0010)) {

     if (MDC_ECHO_ALIAS == MDC_YES) break; /* no interest in images */

     frames = 1; for (t=3;t<MDC_MAX_DIMS;t++) frames*=fi->dim[t];

     if (MDC_PROGRESS) MdcProgress(MDC_PROGRESS_SET,0.5,NULL);

     IMAGE = MDC_YES; tag->data=NULL; number+=1;
     if ((id->buf = MdcGetImgBuffer(tag->length)) == NULL)
       return("ACR  Bad malloc image buffer");
     if (fread(id->buf,1,tag->length,fp) != tag->length) {
       err=MdcHandleTruncated(fi,fi->number,MDC_NO);
       if (err != NULL) return(err);
       break;
     }

     if (id->bits == 12) {
       if (MdcUnpackBIT12(fi,fi->number-1) != MDC_YES) {
         return("ACR  Unpacking 12 bits failed");
       }
     }

     if (MDC_PROGRESS) MdcProgress(MDC_PROGRESS_SET,1.0,NULL);

   }else{

     if (tag->length == 0xffffffff ) tag->length = 0;

     if (filesize - ftello(fp) >= (off_t)tag->length) {
       /* not yet at end of file */
       if ((tag->data=malloc(tag->length+1)) == NULL)
         return("ACR  Bad malloc tag data");

       tag->data[tag->length]='\0';

       if (fread(tag->data,1,tag->length,fp) != tag->length) {
         MdcFree(tag->data);
         return("ACR  Bad read tag data");
       }
     }else{
       /* position at the end of file */
       fseeko(fp,(off_t)0,SEEK_END);
     }

   }

   err=MdcDoTag(NULL,tag,fi,fi->number-1);   if (err!=NULL) return(err);

   MdcFree(tag->data);

  }

  if (MDC_ECHO_ALIAS == MDC_YES) {
    MdcEchoAliasName(fi); return(NULL);
  }

  if (fi->image[0].buf == NULL) return("ACR  No valid images found");

  if (number < fi->number) {
    /* file with some bogus tags after last image */
    /* which incremented fi->number unexpected    */
    if (!MdcGetStructID(fi, number))
      return("Couldn't realloc IMG_DATA structs");
  }

  /* fill in FILEINFO */
  fi->endian = MDC_FILE_ENDIAN;
  fi->bits  = fi->image[0].bits;
  fi->dim[0] = 3;
  fi->dim[3] = fi->number;
  fi->pixdim[0] = 3.;
  fi->pixdim[1] = fi->image[0].pixel_xsize;
  fi->pixdim[2] = fi->image[0].pixel_ysize;
  fi->pixdim[3] = fi->image[0].slice_width;

  /* check Acr/Nema stuff per image */
  for (i=0; i<fi->number; i++) {
     id = &fi->image[i];

     if (MDC_TRUE_GAP == MDC_YES) id->slice_spacing += id->slice_width;

     if (id->image_orient_pat[0] == 0.0 && id->image_orient_pat[1] == 0.0 &&
         id->image_orient_pat[4] == 0.0 && id->image_orient_pat[5] == 0.0 ) {
       /* no patient coordinate system defines in Acr/Nema, try pat_orient */
       fi->pat_slice_orient = MdcTryPatSliceOrient(fi->pat_orient);
       if (fi->pat_slice_orient != MDC_UNKNOWN) {
         MdcFillImgPos(fi,i,fi->dim[3]==0 ? 0 : i%fi->dim[3],0.0);
         MdcFillImgOrient(fi,i);
       }
     }

  }

  MdcCloseFile(fi->ifp);

  if(fi->truncated) return("ACR  Truncated image file");

  return NULL;

}

/* just an experiment, but don't like to lose it */
/*void MdcHandleNUMARIS2(Uint8 *data)
{
  Uint8 *pdata=data;
  char *ps;
  Int16 *i16;
  Int32 *i32;

  Int16 patient_info;

  MdcPrntScrn("\n");
  MdcPrintLine('*',MDC_FULL_LENGTH);
  MdcPrntScrn("\n");

  pdata = data;
  MdcPrntScrn("Entry Table:\n");
  i16=(Int16 *)pdata; pdata+=2;
  MdcPrntScrn("Number of entries: %hd\n",*i16);
  i16=(Int16 *)pdata; pdata+=2;
  MdcPrntScrn("Entry length - words per entry: %hd\n",*i16);
  i16=(Int16 *)pdata; pdata+=2;
  MdcPrntScrn("Block length in byte: %hd\n",*i16);
  i16=(Int16 *)pdata; pdata+=2;
  MdcPrntScrn("First free block in image file: %hd\n",*i16);
  i16=(Int16 *)pdata; pdata+=2;
  MdcPrntScrn("Number of first block of installation: %hd\n",*i16);
  i16=(Int16 *)pdata; pdata+=2;
  MdcPrntScrn("Length of installation in blocks: %hd\n",*i16);
  i16=(Int16 *)pdata; pdata+=2;
  MdcPrntScrn("Number of first block of measurement: %hd\n",*i16);
  i16=(Int16 *)pdata; pdata+=2;
  MdcPrntScrn("Length of measurement in blocks: %hd\n",*i16);
  i16=(Int16 *)pdata; pdata+=2;
  MdcPrntScrn("Number of first block of image text: %hd\n",*i16);
  i16=(Int16 *)pdata; pdata+=2;
  MdcPrntScrn("Length of image text in blocks: %hd\n",*i16);
  i16=(Int16 *)pdata; pdata+=2;
  MdcPrntScrn("Number of first i/r/a/p info: %hd\n",*i16);
  i16=(Int16 *)pdata; pdata+=2;
  MdcPrntScrn("Length of i/r/a/p info in blocks: %hd\n",*i16);
  i16=(Int16 *)pdata; pdata+=2;
  MdcPrntScrn("Number of first block of correction: %hd\n",*i16);
  i16=(Int16 *)pdata; pdata+=2;
  MdcPrntScrn("Length of correction blocks: %hd\n",*i16);
  i16=(Int16 *)pdata; pdata+=2;
  MdcPrntScrn("Number of first block NUMARIS1 #1: %hd\n",*i16);
  i16=(Int16 *)pdata; pdata+=2;
  MdcPrntScrn("Length of NUMARIS1 #1 in blocks: %hd\n",*i16);
  i16=(Int16 *)pdata; pdata+=2;
  MdcPrntScrn("Number of first block NUMARIS1 #2: %hd\n",*i16);
  i16=(Int16 *)pdata; pdata+=2;
  MdcPrntScrn("Length of NUMARIS1 #2 in blocks: %hd\n",*i16);

  MdcPrntScrn("\netc, etc, etc ...\n");

  pdata = data;   pdata+=44;  i16=(Int16 *)pdata;
  patient_info=*i16 - 5;
  MdcPrntScrn("Patient_info block number: %hd\n",patient_info);

  pdata = data+(patient_info*512);
  ps = (char *)pdata;
  MdcPrntScrn("Patient name = %.26s\n",ps);
  pdata = data+(patient_info*512)+28;
  ps = (char *)pdata;
  MdcPrntScrn("Patient ID = %.12s\n",ps);

  MdcPrntScrn("\n");
  MdcPrintLine('*',MDC_FULL_LENGTH);
  MdcPrntScrn("\n");

}

*/


void MdcPrintTag( FILEINFO *fi, MDC_ACR_TAG *tag, char *fmt, ...)
{
  va_list args;

  if (MDC_INFO) {
    if (MDC_DEBUG) {
      MdcPrintLine('-',MDC_HALF_LENGTH);
      MdcPrntScrn("[next offset: %jd]\n",(intmax_t)ftello(fi->ifp));
    }
    MdcPrintLine('-',MDC_HALF_LENGTH);
    MdcPrntScrn("Group   (2): 0x%.4x\n",tag->group);
    MdcPrntScrn("Element (2): 0x%.4x\n",tag->element);
    MdcPrntScrn("Length  (4): %u\n",tag->length);
  }

  va_start(args, fmt);
  vsprintf(mdcbufr,fmt,args);

  if (MDC_INFO) {
    if ( tag->length == 0 )
      MdcPrntScrn("%.30s <no entry>\n",mdcbufr);
    else if ( tag->length > MDC_MAX_CHARS )
      MdcPrntScrn("%.30s <not printed>\n",mdcbufr);
    else
      MdcPrntScrn("%s",mdcbufr);
  }

  va_end(args);

  if (strstr(mdcbufr,"Unknown ") != NULL) {
    MDC_HACK_SUCCESS = MDC_NO;
  }else{
    MDC_HACK_SUCCESS = MDC_YES;
  }

}

/* get nr (one based) element of a multiple value element with strings */
int MdcGetStrVM(char *dest,char *src, Uint32 nr)
{
  int ret;

  ret = MdcGetSubStr(dest,src,MDC_2KB_OFFSET,'\\',(signed)nr);

  return(ret);

}

void MdcDicomInitStuff(MDC_DICOM_STUFF_T *dicom)
{
  int i;

  dicom->type = BIT16_S;
  dicom->modality = M_NM;
  dicom->INVERT  = MDC_NO;
  dicom->si_slope = 1.;
  dicom->si_intercept = 0.;
  dicom->acqnr = 0;
  dicom->dynnr = 0;
  dicom->motion = 0;

  for (i=0; i<MDC_VECT_TOTAL; i++) {
     dicom->VectDO[i] = MDC_PASS0;
     dicom->VectNR[i] = 1;
  }

  dicom->timeslottime = 0.;
  dicom->frametime = 0.;
  dicom->framestart = 0.;
  dicom->frameduration = 0.;
  dicom->nrframes = 0.;
  dicom->window_low = 0.;
  dicom->window_high = 0.;
  dicom->scan_arc = 0.;
  dicom->intervals_acquired = 0.;
  dicom->intervals_rejected = 0.;
  dicom->heart_rate = 0;

  if (MDC_DICOM_MOSAIC_FORCED == MDC_YES) {
    dicom->MOSAIC = MDC_YES;
    dicom->mosaic_interlaced = mdc_mosaic_interlaced;
  }else{
    dicom->MOSAIC = MDC_NO;
    dicom->mosaic_interlaced = MDC_NO;
  }
  dicom->mosaic_width = mdc_mosaic_width;
  dicom->mosaic_height= mdc_mosaic_height;
  dicom->mosaic_number= mdc_mosaic_number;

  dicom->ENCAPSULATED_UNCOMPRESSED = MDC_NO;
}

void MdcDicomCheckVect(MDC_DICOM_STUFF_T *dicom, MDC_ACR_TAG *tag, int VECTOR)
{
  Uint16 *pu16, hval=1, vect;
  Uint32 vm, c;

  if (dicom->VectDO[VECTOR] == MDC_PASS1) {
    vm = tag->length / 2; pu16 = (Uint16 *)tag->data;
    for (c=0; c<vm; c++) {
       vect = pu16[c];
       /* preserve highest value as number of vectors */
       if (vect > hval) hval = vect;
    }
    if (vm > 0 ) {
      dicom->VectNR[VECTOR] = hval;
      dicom->VectDO[VECTOR] = MDC_PASS2;
    }
  }
}

Uint32 MdcDicomNrOfVect(MDC_DICOM_STUFF_T *dicom, Uint16 nr, int VECTOR)
{
  Uint32 rval=(Uint32)nr;

  if (dicom->VectDO[VECTOR] == MDC_PASS2) rval=(Uint32)dicom->VectNR[VECTOR];

  return(rval);

}

int MdcDicomDoAcqData(FILEINFO *fi, MDC_DICOM_STUFF_T *dicom)
{
  if ((dicom->acqnr > 0) && (dicom->acqnr <= fi->acqnr) &&
     (fi->acqdata != NULL)) {
    return(MDC_YES);
  }

  return(MDC_NO);
}

int MdcDicomSOPClass(char *sopclass)
{
  int mod = M_NM;

  if (strcmp(sopclass,"1.2.840.10008.5.1.4.1.1.2")   == 0) mod = M_CT;
  else if (strcmp(sopclass,"1.2.840.10008.5.1.4.1.1.4")   == 0) mod = M_MR;
  else if (strcmp(sopclass,"1.2.840.10008.5.1.4.1.1.20")  == 0) mod = M_NM;
  else if (strcmp(sopclass,"1.2.840.10008.5.1.4.1.1.128") == 0) mod = M_PT;

  return (mod);

}



int MdcGetHHMMSS(char *time, Int16 *hour, Int16 *minute, Int16 *second)
{
  char *pitem=time;

  while (!MdcIsDigit(pitem[0])) {
       if (strlen(pitem) > 1) pitem++;
       else break;
  }
  if (strlen(pitem) >= 2) sscanf(pitem,"%02hd",hour);
  if (strlen(pitem) > 2) pitem+=2;
  while (!MdcIsDigit(pitem[0])) {
       if (strlen(pitem) > 1) pitem++;
       else break;
  }
  if (strlen(pitem) >= 2) sscanf(pitem,"%02hd",minute);
  if (strlen(pitem) > 2) pitem+=2;
  while (!MdcIsDigit(pitem[0])) {
       if (strlen(pitem) > 1) pitem++;
       else break;
  }
  if (strlen(pitem) >= 2) sscanf(pitem,"%02hd",second);

  return(MDC_YES);

}

/* Note: index for IMG_DATA structs is 0-based */
char *MdcDoTag(MDC_SEQ_TAG *seq, MDC_ACR_TAG *tag, FILEINFO *fi, Uint32 index)
{
  IMG_DATA *id;
  DYNAMIC_DATA *dd;
  MDC_DICOM_STUFF_T *dicom=&mdc_dicom_stuff;
  static Int16 bits_allocated = 0, bits_stored = 0;
  char databuffer[MDC_MAX_CHARS+1], *pc=NULL, *ps=NULL, *pitem=NULL;
  Int16 i16=0;
  Int32 i32=0;
  Uint16 ui16=0;
  Uint32 ui32=0;
  double flt64=0.;
  Uint16 group, element, *pu16;
  Uint32 i=index, bytes, c , vm, tmp;
  Uint8 FILL_STATIC_DATA = MDC_NO;
  Uint8 FILL_DYNAMIC_DATA = MDC_NO;
  float flt;

  memset(databuffer,'\0',MDC_MAX_CHARS+1); /*always a nul-terminated string*/

  if (tag->data != NULL) {
    if (tag->length >= MDC_MAX_CHARS) {
      bytes=MDC_MAX_CHARS;
    }else{
      bytes=tag->length;
    }
    if (bytes > 0) memcpy(databuffer,tag->data,bytes);
  }

  ps = databuffer;

  memcpy((char *)&i16,databuffer,sizeof(Int16)); MdcSWAP(i16);
  memcpy((char *)&i32,databuffer,sizeof(Int32)); MdcSWAP(i32);
  memcpy((char *)&ui16,databuffer,sizeof(Uint16)); MdcSWAP(ui16);
  memcpy((char *)&ui32,databuffer,sizeof(Uint32)); MdcSWAP(ui32);
  memcpy((char *)&flt64,databuffer,sizeof(flt64)); MdcSWAP(flt64);

  id = &fi->image[i];

  /* need of filling static data struct? */
  if (id->sdata != NULL) FILL_STATIC_DATA = MDC_YES;

  /* need of filling dynamic data struct? */
  if (fi->dyndata != NULL) FILL_DYNAMIC_DATA = MDC_YES;

  /* handle ordinary tags */

  switch (tag->group) {
   /* group 0x0002 */
   case 0x0002: switch (tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Meta Element - Group 0002\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %d\n",i32);
           break;
       case 0x0002:
           MdcPrintTag(fi,tag,"Media Storage SOPClassUID    : %s\n",ps);
           dicom->modality = MdcDicomSOPClass(ps);
           break;
       case 0x0003:
           MdcPrintTag(fi,tag,"Media Storage SOPInstanceUID : %s\n",ps);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"TransferSyntaxUID            : %s\n",ps);
           break;
       case 0x0012:
           MdcPrintTag(fi,tag,"ImplementationClassUID       : %s\n",ps);
           break;
       case 0x0013:
           MdcPrintTag(fi,tag,"Implementation Version Name  : %s\n",ps);
           break;
       }
       break;
   /* group 0x0008 */
   case 0x0008: switch (tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Identifying Information - Group 0008\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0001:
           MdcPrintTag(fi,tag,"Total Number of Bytes        : %u\n",ui32);
           break;
       case 0x0005:
           MdcPrintTag(fi,tag,"Specific Character Set       : %s\n",ps);
           break;
       case 0x0008:
           MdcPrintTag(fi,tag,"Image Type                   : %s\n",ps);
           if (MdcGetStrVM(mdcbufr,ps,3) == MDC_YES) {
             MdcKillSpaces(mdcbufr);
             if (strcasecmp(mdcbufr,"RECON GATED TOMO") == 0) {
               fi->acquisition_type = MDC_ACQUISITION_GSPECT;
               fi->reconstructed = MDC_YES;
             }else if (strcasecmp(mdcbufr,"RECON TOMO") == 0) {
               fi->acquisition_type = MDC_ACQUISITION_TOMO;
               fi->reconstructed = MDC_YES;
             }else if (strcasecmp(mdcbufr,"GATED TOMO") == 0) {
               fi->acquisition_type = MDC_ACQUISITION_GSPECT;
               fi->reconstructed = MDC_NO;
             }else if (strcasecmp(mdcbufr,"TOMO") == 0)       {
               fi->acquisition_type = MDC_ACQUISITION_TOMO;
               fi->reconstructed = MDC_NO;
             }else if (strcasecmp(mdcbufr,"WHOLE BODY") == 0) {
               fi->acquisition_type = MDC_ACQUISITION_STATIC;
               fi->reconstructed = MDC_YES;
               fi->planar = MDC_YES;
             }else if (strcasecmp(mdcbufr,"GATED") == 0)      {
               fi->acquisition_type = MDC_ACQUISITION_GATED;
               fi->reconstructed = MDC_YES;
               fi->planar = MDC_YES;
             }else if (strcasecmp(mdcbufr,"DYNAMIC") == 0)    {
               fi->acquisition_type = MDC_ACQUISITION_DYNAMIC;
               fi->reconstructed = MDC_YES;
               fi->planar = MDC_YES;
             }else if (strcasecmp(mdcbufr,"STATIC") == 0)     {
               fi->acquisition_type = MDC_ACQUISITION_STATIC;
               fi->reconstructed = MDC_YES;
               fi->planar = MDC_YES;
             }else{
               fi->acquisition_type = MDC_ACQUISITION_TOMO;
               fi->reconstructed = MDC_YES;
             }
           }
           if (fi->acquisition_type == MDC_ACQUISITION_GATED ||
               fi->acquisition_type == MDC_ACQUISITION_GSPECT ) {
             /* MARK: limited to one yet */
             if (!MdcGetStructGD(fi,1)) {
               return("ACR  Couldn't malloc GATED_DATA structs");
             }
           }
           if (fi->acquisition_type == MDC_ACQUISITION_STATIC) {
             if (!MdcGetStructSD(fi,fi->number)) {
               return("ACR  Couldn't malloc STATIC_DATA structs");
             }
           }
           if (fi->reconstructed == MDC_NO) {
             dicom->acqnr = 1;
             if (!MdcGetStructAD(fi,dicom->acqnr)) {
               dicom->acqnr = 0;
               return("ACR  Couldn't malloc ACQ_DATA struct");
             }
           }
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Recognition Code             : %s\n",ps);
           break;
       case 0x0012:
           MdcPrintTag(fi,tag,"Instance Creation Date       : %s\n",ps);
           break;
       case 0x0013:
           MdcPrintTag(fi,tag,"Instance Creation Time       : %s\n",ps);
           break;
       case 0x0014:
           MdcPrintTag(fi,tag,"Instance Creator UID         : %s\n",ps);
           break;
       case 0x0016:
           MdcPrintTag(fi,tag,"SOP Class UID                : %s\n",ps);
           dicom->modality = MdcDicomSOPClass(ps);
           break;
       case 0x0018:
           MdcPrintTag(fi,tag,"SOP Instance UID             : %s\n",ps);
           break;
       case 0x0020:
           MdcPrintTag(fi,tag,"Study Date                   : %s\n",ps);
           if (fi->mod != NULL) {
             MdcStringCopy(fi->mod->gn_info.study_date,ps,MDC_MAXSTR);
           }
           pitem = ps;
           while (!MdcIsDigit(pitem[0])) {
                if (strlen(pitem) > 1) pitem++;
                else break;
           }
           if (strlen(pitem) >= 4) sscanf(pitem,"%04hd",&fi->study_date_year);
           if (strlen(pitem) > 4) pitem+=4;
           while (!MdcIsDigit(pitem[0])) {
                if (strlen(pitem) > 1) pitem++;
                else break;
           }
           if (strlen(pitem) >= 2) sscanf(pitem,"%02hd",&fi->study_date_month);
           if (strlen(pitem) > 2) pitem+=2;
           while (!MdcIsDigit(pitem[0])) {
                if (strlen(pitem) > 1) pitem++;
                else break;
           }
           if (strlen(pitem) >= 2) sscanf(pitem,"%02hd",&fi->study_date_day);
           break;
       case 0x0021:
           MdcPrintTag(fi,tag,"Series Date                  : %s\n",ps);
           if (fi->mod != NULL) {
             MdcStringCopy(fi->mod->gn_info.series_date,ps,MDC_MAXSTR);
           }
           break;
       case 0x0022:
           MdcPrintTag(fi,tag,"Acquisition Date             : %s\n",ps);
           if (fi->mod != NULL) {
             MdcStringCopy(fi->mod->gn_info.acquisition_date,ps,MDC_MAXSTR);
           }
           break;
       case 0x0023:
           MdcPrintTag(fi,tag,"Image Date                   : %s\n",ps);
           if (fi->mod != NULL) {
             MdcStringCopy(fi->mod->gn_info.image_date,ps,MDC_MAXSTR);
           }
           break;
       case 0x0030:
           MdcPrintTag(fi,tag,"Study Time                   : %s\n",ps);
           if (fi->mod != NULL) {
             MdcStringCopy(fi->mod->gn_info.study_time,ps,MDC_MAXSTR);
           }
           MdcGetHHMMSS(ps,&fi->study_time_hour
                          ,&fi->study_time_minute
                          ,&fi->study_time_second);
           break;
       case 0x0031:
           MdcPrintTag(fi,tag,"Series Time                  : %s\n",ps);
           if (fi->mod != NULL) {
             MdcStringCopy(fi->mod->gn_info.series_time,ps,MDC_MAXSTR);
           }
           break;
       case 0x0032:
           MdcPrintTag(fi,tag,"Acquisition Time             : %s\n",ps);
           if (fi->mod != NULL) {
             MdcStringCopy(fi->mod->gn_info.acquisition_time,ps,MDC_MAXSTR);
           }
           if (FILL_STATIC_DATA == MDC_YES) {
             MdcGetHHMMSS(ps,&id->sdata->start_time_hour
                            ,&id->sdata->start_time_minute
                            ,&id->sdata->start_time_second);
           }
           break;
       case 0x0033:
           MdcPrintTag(fi,tag,"Image Time                   : %s\n",ps);
           if (fi->mod != NULL) {
             MdcStringCopy(fi->mod->gn_info.image_time,ps,MDC_MAXSTR);
           }
           break;
       case 0x0040:
           MdcPrintTag(fi,tag,"Data Set Type                : 0x%.4x",ui16);
           if (MDC_INFO)
           switch (ui16) {
                  case 0x0000: MdcPrntScrn(" (= image)\n"); break;
                  case 0x0001: MdcPrntScrn(" (= compressed image)\n"); break;
                  case 0x0002: MdcPrntScrn(" (= graphics)\n"); break;
                  case 0x0003: MdcPrntScrn(" (= text)\n"); break;
                  case 0x0010: MdcPrntScrn(" (= folder/raw)\n"); break;
                  case 0x0100: MdcPrntScrn(" (= other)\n"); break;
                  case 0x0101: MdcPrntScrn(" (= null)\n"); break;
                  case 0x0102: MdcPrntScrn(" (= identifier)\n"); break;
                  case 0x8000: MdcPrntScrn(" (= private image)\n"); break;
                  case 0x8002: MdcPrntScrn(" (= private graphic)\n"); break;
                  case 0x8003: MdcPrntScrn(" (= private text)\n"); break;
                  default    : MdcPrntScrn(" (= unknown)\n"); break;
           }
           break;
       case 0x0041:
           MdcPrintTag(fi,tag,"Data Set Subtype             : %s\n",ps);
           break;
       case 0x0050:
           MdcPrintTag(fi,tag,"Accession Number             : %s\n",ps);
           break;
       case 0x0060:
           MdcPrintTag(fi,tag,"Image Modality               : %s\n",ps);
           fi->modality = MdcGetIntModality(ps);
           break;
       case 0x0070:
           MdcPrintTag(fi,tag,"Manufacturer                 : %s\n",ps);
           MdcStringCopy(fi->manufacturer,ps,tag->length);
           break;
       case 0x0080:
           MdcPrintTag(fi,tag,"Institution ID               : %s\n",ps);
           MdcStringCopy(fi->institution,ps,tag->length);
           break;
       case 0x0090:
           MdcPrintTag(fi,tag,"Referring Physician          : %s\n",ps);
           break;
       case 0x0100:
           MdcPrintTag(fi,tag,"Code Value                   : %s\n",ps);
           break;
       case 0x0102:
           MdcPrintTag(fi,tag,"Coding Scheme Designator     : %s\n",ps);
           break;
       case 0x0104:
           MdcPrintTag(fi,tag,"Code Meaning                 : %s\n",ps);
           if (seq != NULL) {
             switch (seq->group) {
               case 0x0054: switch (seq->element) {
                   case 0x0300: /* radionuclide (isotope) */
                       MdcStringCopy(fi->isotope_code,ps,strlen(ps));
                       break;
                   case 0x0304: /* radiopharma */
                       MdcStringCopy(fi->radiopharma,ps,strlen(ps));
                       break;
                   case 0x0220: /* static label */
                       if (FILL_STATIC_DATA == MDC_YES)
                         MdcStringCopy(id->sdata->label,ps,strlen(ps));
                       break;
               }
               break;
             }
           }
           break;
       case 0x1000:
           MdcPrintTag(fi,tag,"Network ID                   : %s\n",ps);
           break;
       case 0x1010:
           MdcPrintTag(fi,tag,"Station ID                   : %s\n",ps);
           break;
       case 0x1030:
           MdcPrintTag(fi,tag,"Study Description            : %s\n",ps);
           MdcKillSpaces(ps);
           MdcStringCopy(fi->study_descr,ps,tag->length);
           break;
       case 0x103E:
           MdcPrintTag(fi,tag,"Series Description           : %s\n",ps);
           if (tag->length > 0) {
             MdcKillSpaces(ps);
             MdcStringCopy(fi->series_descr,ps,tag->length);
           }
           break;
       case 0x1040:
           MdcPrintTag(fi,tag,"Institutional Department     : %s\n",ps);
           break;
       case 0x1050:
           MdcPrintTag(fi,tag,"Attending Physician          : %s\n",ps);
           break;
       case 0x1060:
           MdcPrintTag(fi,tag,"Radiologist                  : %s\n",ps);
           break;
       case 0x1070:
           MdcPrintTag(fi,tag,"Operator                     : %s\n",ps);
           if (tag->length > 0) {
             MdcKillSpaces(ps);
             MdcStringCopy(fi->operator_name,ps,tag->length);
           }
           break;
       case 0x1080:
           MdcPrintTag(fi,tag,"Admitting Diagnosis          : %s\n",ps);
           break;
       case 0x1090:
           MdcPrintTag(fi,tag,"Manufacturer Model           : %s\n",ps);
           if (tag->length >= 16) { /* check for mosaic */
             if (strncasecmp(ps,"MAGNETOM VISION",15) == 0)
               dicom->MOSAIC = MDC_YES;
           }
           break;
       case 0x1150:
           MdcPrintTag(fi,tag,"SOP Class UID                : %s\n",ps);
           break;
       case 0x1155:
           MdcPrintTag(fi,tag,"SOP Instance UID             : %s\n",ps);
           break;
       case 0x2111:
           MdcPrintTag(fi,tag,"Derivation Description       : %s\n",ps);
           break;
       case 0x4000:
           MdcPrintTag(fi,tag,"Comments                     : %s\n",ps);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   /* group 0x0009 */
   case 0x0009: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Shadow Identifying Information - Group 0009\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Shadow Owner Code            : %s\n",ps);
           break;
       case 0x0011:
           MdcPrintTag(fi,tag,"Shadow Owner Code            : %s\n",ps);
           break;
       case 0x0080:
           MdcPrintTag(fi,tag,"Owner ID                     : %s\n",ps);
           break;
/* MARK BEGIN: GE DISCOVERY */
       case 0x1001:
           MdcPrintTag(fi,tag,"Implentation Name            : %s\n",ps);
           break;
       case 0x1002:
           MdcPrintTag(fi,tag,"Suite ID                     : %s\n",ps);
           break;
       case 0x1004:
           MdcPrintTag(fi,tag,"Product ID                   : %s\n",ps);
           break;
       case 0x1005:
           MdcPrintTag(fi,tag,"Patient DateTime             : %s\n",ps);
           break;
       case 0x1006:
           MdcPrintTag(fi,tag,"Type                         : %s\n",ps);
           break;
       case 0x100a:
           MdcPrintTag(fi,tag,"Scan ID                      : %s\n",ps);
           break;
       case 0x100d:
           MdcPrintTag(fi,tag,"Scan DateTime                : %s\n",ps);
           break;
       case 0x100e:
           MdcPrintTag(fi,tag,"Scan Ready                   : %s\n",ps);
           break;
       case 0x1013:
           MdcPrintTag(fi,tag,"For Identifier               : %s\n",ps);
           break;
       case 0x1014:
           MdcPrintTag(fi,tag,"Landmark Name                : %s\n",ps);
           break;
       case 0x1015:
           /* GE */
           MdcPrintTag(fi,tag,"Landmark Abbreviation        : %s\n",ps);
           /* SIEMENS */
           MdcPrintTag(fi,tag,"Unique SPI Identifier        : %s\n",ps);
           break;
       case 0x1016:
           MdcPrintTag(fi,tag,"Patient Position             : %s\n",ps);
           break;
       case 0x1017:
           MdcPrintTag(fi,tag,"Scan Perspective             : %s\n",ps);
           break;
       case 0x1018:
           MdcPrintTag(fi,tag,"Scan Type                    : %s\n",ps);
           break;
       case 0x1019:
           MdcPrintTag(fi,tag,"Scan Mode                    : %s\n",ps);
           break;
       case 0x101a:
           MdcPrintTag(fi,tag,"Start Condition              : %s\n",ps);
           break;
       case 0x101b:
           MdcPrintTag(fi,tag,"Start Condition Data         : %s\n",ps);
           break;
       case 0x101c:
           MdcPrintTag(fi,tag,"Sel Stop Condition           : %s\n",ps);
           break;
       case 0x101d:
           MdcPrintTag(fi,tag,"Sel Stop Condition Data      : %s\n",ps);
           break;
       case 0x101e:
           MdcPrintTag(fi,tag,"Collect Deadtime             : %s\n",ps);
           break;
       case 0x101f:
           MdcPrintTag(fi,tag,"Collect Singles              : %s\n",ps);
           break;
       case 0x1020:
           MdcPrintTag(fi,tag,"Collect Countrate            : %s\n",ps);
           break;
       case 0x1021:
           MdcPrintTag(fi,tag,"Countrate Period             : %s\n",ps);
           break;
       case 0x1022:
           MdcPrintTag(fi,tag,"Delayed Events               : %s\n",ps);
           break;
       case 0x1023:
           MdcPrintTag(fi,tag,"Delayed Bias                 : %s\n",ps);
           break;
       case 0x1024:
           MdcPrintTag(fi,tag,"Word Size                    : %s\n",ps);
           break;
       case 0x1025:
           MdcPrintTag(fi,tag,"Axial Acceptance             : %s\n",ps);
           break;
       case 0x1026:
           MdcPrintTag(fi,tag,"Axial Angle 3D               : %s\n",ps);
           break;
       case 0x1027:
    /* 0x1027 tag was ambiguously defined in the GE Conformance Statement, */
    /* once as "Image actual date" and once as "Theta Compression".        */
           MdcPrintTag(fi,tag,"Theta Compression            : %s\n",ps);
           break;
       case 0x1028:
           MdcPrintTag(fi,tag,"Axial Compression            : %s\n",ps);
           break;
       case 0x1029:
           MdcPrintTag(fi,tag,"Gantry Tilt Angle            : %s\n",ps);
           break;
       case 0x102a:
           MdcPrintTag(fi,tag,"Collimation                  : %s\n",ps);
           break;
       case 0x102b:
           MdcPrintTag(fi,tag,"Scan FOV                     : %s\n",ps);
           break;
       case 0x102c:
           MdcPrintTag(fi,tag,"Axial FOV                    : %s\n",ps);
           break;
       case 0x102d:
           MdcPrintTag(fi,tag,"Event Separation             : %s\n",ps);
           break;
       case 0x102e:
           MdcPrintTag(fi,tag,"Mask Width                   : %s\n",ps);
           break;
       case 0x102f:
           MdcPrintTag(fi,tag,"Binning Mode                 : %s\n",ps);
           break;
       case 0x1034:
           MdcPrintTag(fi,tag,"Triggers Acquired            : %s\n",ps);
           break;
       case 0x1035:
           MdcPrintTag(fi,tag,"Triggers Rejected            : %s\n",ps);
           break;
       case 0x1036:
           MdcPrintTag(fi,tag,"Tracer Name                  : %s\n",ps);
           break;
       case 0x1037:
           MdcPrintTag(fi,tag,"Batch Description            : %s\n",ps);
           break;
       case 0x1038:
           MdcPrintTag(fi,tag,"Tracer Activity              : %s\n",ps);
           break;
       case 0x1039:
           MdcPrintTag(fi,tag,"Measure DateTime             : %s\n",ps);
           break;
       case 0x103a:
           MdcPrintTag(fi,tag,"Pre Injection Volume         : %s\n",ps);
           break;
       case 0x103b:
           MdcPrintTag(fi,tag,"Admin DateTime               : %s\n",ps);
           break;
       case 0x103c:
           MdcPrintTag(fi,tag,"Post Injection Activity      : %s\n",ps);
           break;
       case 0x103d:
           MdcPrintTag(fi,tag,"Post Injection DateTime      : %s\n",ps);
           break;
       case 0x103e:
           MdcPrintTag(fi,tag,"Radionuclide Name            : %s\n",ps);
           break;
       case 0x103f:
           MdcPrintTag(fi,tag,"Half Life                    : %s\n",ps);
           break;
       case 0x1040:
           MdcPrintTag(fi,tag,"Positron Fraction            : %s\n",ps);
           break;
       case 0x104d:
           MdcPrintTag(fi,tag,"Emission Present             : %s\n",ps);
           break;
       case 0x104e:
           MdcPrintTag(fi,tag,"Lower Axial Acc              : %s\n",ps);
           break;
       case 0x104f:
           MdcPrintTag(fi,tag,"Upper Axial Acc              : %s\n",ps);
           break;
       case 0x1050:
           MdcPrintTag(fi,tag,"Lower Coincidence Limit      : %s\n",ps);
           break;
       case 0x1051:
           MdcPrintTag(fi,tag,"Upper Coincidence Limit      : %s\n",ps);
           break;
       case 0x1052:
           MdcPrintTag(fi,tag,"Coincidence Delay Offset     : %s\n",ps);
           break;
       case 0x1053:
           MdcPrintTag(fi,tag,"Coincidence Output Mode      : %s\n",ps);
           break;
       case 0x1054:
           MdcPrintTag(fi,tag,"Upper Energy Limit           : %s\n",ps);
           break;
       case 0x1055:
           MdcPrintTag(fi,tag,"Lower Energy Limit           : %s\n",ps);
           break;
       case 0x1056:
           MdcPrintTag(fi,tag,"Normal Cal ID                : %s\n",ps);
           break;
       case 0x1057:
           MdcPrintTag(fi,tag,"Normal 2D Cal ID             : %s\n",ps);
           break;
       case 0x1058:
           MdcPrintTag(fi,tag,"Blank Cal ID                 : %s\n",ps);
           break;
       case 0x1059:
           MdcPrintTag(fi,tag,"Well Counter Cal ID          : %s\n",ps);
           break;
       case 0x105a:
           MdcPrintTag(fi,tag,"Derived                      : %s\n",ps);
           break;
       case 0x105c:
           MdcPrintTag(fi,tag,"Frame ID                     : %s\n",ps);
           break;
       case 0x105d:
           MdcPrintTag(fi,tag,"Scan ID                      : %s\n",ps);
           break;
       case 0x105e:
           MdcPrintTag(fi,tag,"Exam ID                      : %s\n",ps);
           break;
       case 0x105f:
           MdcPrintTag(fi,tag,"Patient ID                   : %s\n",ps);
           break;
       case 0x1062:
           MdcPrintTag(fi,tag,"Where is Frame               : %s\n",ps);
           break;
       case 0x1063:
           MdcPrintTag(fi,tag,"Frame Size                   : %s\n",ps);
           break;
       case 0x1064:
           MdcPrintTag(fi,tag,"File Exists                  : %s\n",ps);
           break;
       case 0x1066:
           MdcPrintTag(fi,tag,"Table Height                 : %s\n",ps);
           break;
       case 0x1067:
           MdcPrintTag(fi,tag,"Table Z Position             : %s\n",ps);
           break;
       case 0x1068:
           MdcPrintTag(fi,tag,"Landmark DateTime            : %s\n",ps);
           break;
       case 0x1069:
           MdcPrintTag(fi,tag,"Slice Count                  : %s\n",ps);
           break;
       case 0x106a:
           MdcPrintTag(fi,tag,"Start Location               : %s\n",ps);
           break;
       case 0x106b:
           MdcPrintTag(fi,tag,"Acquisition Delay            : %s\n",ps);
           break;
       case 0x106c:
           MdcPrintTag(fi,tag,"Acquisition Start            : %s\n",ps);
           break;
       case 0x106d:
           MdcPrintTag(fi,tag,"Acquisition Duration         : %s\n",ps);
           break;
       case 0x1070:
           MdcPrintTag(fi,tag,"Actual Stop Condition        : %s\n",ps);
           break;
       case 0x1071:
           MdcPrintTag(fi,tag,"Total Prompts                : %s\n",ps);
           break;
       case 0x1072:
           MdcPrintTag(fi,tag,"Total Delays                 : %s\n",ps);
           break;
       case 0x1073:
           MdcPrintTag(fi,tag,"Frame Valid                  : %s\n",ps);
           break;
       case 0x1074:
           MdcPrintTag(fi,tag,"Validity Info                : %s\n",ps);
           break;
       case 0x107c:
           MdcPrintTag(fi,tag,"Is Source                    : %s\n",ps);
           break;
       case 0x107d:
           MdcPrintTag(fi,tag,"Is Contents                  : %s\n",ps);
           break;
       case 0x107e:
           MdcPrintTag(fi,tag,"Is Type                      : %s\n",ps);
           break;
       case 0x107f:
           MdcPrintTag(fi,tag,"Is Reference                 : %s\n",ps);
           break;
       case 0x1080:
           MdcPrintTag(fi,tag,"Multi Patient                : %s\n",ps);
           break;
       case 0x1081:
           MdcPrintTag(fi,tag,"Number of Normals            : %s\n",ps);
           break;
       case 0x108b:
           MdcPrintTag(fi,tag,"Recon Method                 : %s\n",ps);
           break;
       case 0x108c:
           MdcPrintTag(fi,tag,"Attenuation                  : %s\n",ps);
           break;
       case 0x108d:
           MdcPrintTag(fi,tag,"Attenuation Coefficient      : %s\n",ps);
           break;
       case 0x108e:
           MdcPrintTag(fi,tag,"BP Filter                    : %s\n",ps);
           break;
       case 0x108f:
           MdcPrintTag(fi,tag,"BP Filter Cutoff             : %s\n",ps);
           break;
       case 0x1090:
           MdcPrintTag(fi,tag,"BP Filter Order              : %s\n",ps);
           break;
       case 0x1091:
           MdcPrintTag(fi,tag,"BP Center L                  : %s\n",ps);
           break;
       case 0x1092:
           MdcPrintTag(fi,tag,"BP Center P                  : %s\n",ps);
           break;
       case 0x1093:
           MdcPrintTag(fi,tag,"Attenuation Smooth           : %s\n",ps);
           break;
       case 0x1094:
           MdcPrintTag(fi,tag,"Attenuation Smooth Param     : %s\n",ps);
           break;
       case 0x1095:
           MdcPrintTag(fi,tag,"Angle Smooth Param           : %s\n",ps);
           break;
       case 0x1096:
           MdcPrintTag(fi,tag,"Well Counter Cal ID          : %s\n",ps);
           break;
       case 0x1097:
           MdcPrintTag(fi,tag,"Trans Scan ID                : %s\n",ps);
           break;
       case 0x1098:
           MdcPrintTag(fi,tag,"Norm Cal ID                  : %s\n",ps);
           break;
       case 0x109a:
           MdcPrintTag(fi,tag,"Cac Edge Threshold           : %s\n",ps);
           break;
       case 0x109b:
           MdcPrintTag(fi,tag,"Cac Skull Offset             : %s\n",ps);
           break;
       case 0x109d:
           MdcPrintTag(fi,tag,"Radial Filter 3D             : %s\n",ps);
           break;
       case 0x109e:
           MdcPrintTag(fi,tag,"Radial Cutoff 3D             : %s\n",ps);
           break;
       case 0x109f:
           MdcPrintTag(fi,tag,"Axial Filter 3D              : %s\n",ps);
           break;
       case 0x10a0:
           MdcPrintTag(fi,tag,"Axial Cutoff 3D              : %s\n",ps);
           break;
       case 0x10a1:
           MdcPrintTag(fi,tag,"Axial Start                  : %s\n",ps);
           break;
       case 0x10a2:
           MdcPrintTag(fi,tag,"Axial Spacing                : %s\n",ps);
           break;
       case 0x10a3:
           MdcPrintTag(fi,tag,"Axial Angles Used            : %s\n",ps);
           break;
       case 0x10a6:
           MdcPrintTag(fi,tag,"Slice Number                 : %s\n",ps);
           break;
       case 0x10a7:
           MdcPrintTag(fi,tag,"Total Counts                 : %s\n",ps);
           break;
       case 0x10ab:
           MdcPrintTag(fi,tag,"BP Center X                  : %s\n",ps);
           break;
       case 0x10ac:
           MdcPrintTag(fi,tag,"BP Center Y                  : %s\n",ps);
           break;
       case 0x10b2:
           MdcPrintTag(fi,tag,"IR Number Iterations         : %s\n",ps);
           break;
       case 0x10b3:
           MdcPrintTag(fi,tag,"IR Number Subsets            : %s\n",ps);
           break;
       case 0x10b4:
           MdcPrintTag(fi,tag,"IR Recon FOV                 : %s\n",ps);
           break;
       case 0x10b5:
           MdcPrintTag(fi,tag,"IR Corr Model                : %s\n",ps);
           break;
       case 0x10b6:
           MdcPrintTag(fi,tag,"IR Loop Filter               : %s\n",ps);
           break;
       case 0x10b7:
           MdcPrintTag(fi,tag,"IR Pre Filter Param          : %s\n",ps);
           break;
       case 0x10b8:
           MdcPrintTag(fi,tag,"IR Loop Filter Param         : %s\n",ps);
           break;
       case 0x10b9:
           MdcPrintTag(fi,tag,"Response Filter Param        : %s\n",ps);
           break;
       case 0x10ba:
           MdcPrintTag(fi,tag,"Post Filter                  : %s\n",ps);
           break;
       case 0x10bb:
           MdcPrintTag(fi,tag,"Post Filter Param            : %s\n",ps);
           break;
       case 0x10bc:
           MdcPrintTag(fi,tag,"IR Regularize                : %s\n",ps);
           break;
       case 0x10bd:
           MdcPrintTag(fi,tag,"Regulative Param             : %s\n",ps);
           break;
       case 0x10be:
           MdcPrintTag(fi,tag,"AC BP Filter                 : %s\n",ps);
           break;
       case 0x10bf:
           MdcPrintTag(fi,tag,"AC BP Filter Cut Off         : %s\n",ps);
           break;
       case 0x10c0:
           MdcPrintTag(fi,tag,"AC BP Filter Order           : %s\n",ps);
           break;
       case 0x10c1:
           MdcPrintTag(fi,tag,"AC Image Smooth              : %s\n",ps);
           break;
       case 0x10c2:
           MdcPrintTag(fi,tag,"AC Image Smooth Param        : %s\n",ps);
           break;
       case 0x10c3:
           MdcPrintTag(fi,tag,"Scatter Method               : %s\n",ps);
           break;
       case 0x10c4:
           MdcPrintTag(fi,tag,"Scatter Number Iteration     : %s\n",ps);
           break;
       case 0x10c5:
           MdcPrintTag(fi,tag,"Scatter Param                : %s\n",ps);
           break;
       case 0x10c6:
           MdcPrintTag(fi,tag,"Seq QC Param                 : %s\n",ps);
           break;
       case 0x10c7:
           MdcPrintTag(fi,tag,"Overlap                      : %s\n",ps);
           break;
       case 0x10cb:
           MdcPrintTag(fi,tag,"VQC X Axis Trans             : %s\n",ps);
           break;
       case 0x10cc:
           MdcPrintTag(fi,tag,"VQC X Axis Tilt              : %s\n",ps);
           break;
       case 0x10cd:
           MdcPrintTag(fi,tag,"VQC Y Axis Trans             : %s\n",ps);
           break;
       case 0x10ce:
           MdcPrintTag(fi,tag,"VQC Y Axis Swivel            : %s\n",ps);
           break;
       case 0x10cf:
           MdcPrintTag(fi,tag,"VQC Z Axis Trans             : %s\n",ps);
           break;
       case 0x10d0:
           MdcPrintTag(fi,tag,"VQC Z Axis Roll              : %s\n",ps);
           break;
       case 0x10d5:
           MdcPrintTag(fi,tag,"Loop Filter Param            : %s\n",ps);
           break;
       case 0x10d6:
           MdcPrintTag(fi,tag,"Image One Location           : %s\n",ps);
           break;
       case 0x10d7:
           MdcPrintTag(fi,tag,"Image Index Location         : %s\n",ps);
           break;
       case 0x10d8:
           MdcPrintTag(fi,tag,"Frame Number                 : %s\n",ps);
           break;
       case 0x10d9:
           MdcPrintTag(fi,tag,"List File Exists             : %s\n",ps);
           break;
       case 0x10da:
           MdcPrintTag(fi,tag,"Where is List File           : %s\n",ps);
           break;
       case 0x10db:
           MdcPrintTag(fi,tag,"IR Z Filter Flag             : %s\n",ps);
           break;
       case 0x10dc:
           MdcPrintTag(fi,tag,"IR Z Filter Ratio            : %s\n",ps);
           break;
       case 0x10df:
           MdcPrintTag(fi,tag,"Number of Slices             : %s\n",ps);
           break;
       case 0x10e2:
           MdcPrintTag(fi,tag,"Rest Stress                  : %s\n",ps);
           break;
       case 0x10e5:
           MdcPrintTag(fi,tag,"Left Shift                   : %s\n",ps);
           break;
       case 0x10e6:
           MdcPrintTag(fi,tag,"Posterior Shift              : %s\n",ps);
           break;
       case 0x10e7:
           MdcPrintTag(fi,tag,"Superior Shift               : %s\n",ps);
           break;
       case 0x10e9:
           MdcPrintTag(fi,tag,"Acquisition Bin Dur Percent  : %s\n",ps);
           break;
       case 0x1010:
           MdcPrintTag(fi,tag,"Hospital Name                : %s\n",ps);
/* MARK END: GE DISCOVERY */
/* MARK CONTINUE: SIEMENS */
           MdcPrintTag(fi,tag,"SPI Version                  : %s\n",ps);
           break;
       case 0x1110:
           MdcPrintTag(fi,tag,"Modality Recognition Code    : %s\n",ps);
           break;
       case 0x1130:
           MdcPrintTag(fi,tag,"Header Offset in Bytes       : %hu\n",ui16);
           break;
       case 0x1131:
           MdcPrintTag(fi,tag,"Length of Header in Bytes    : %hu\n",ui16);
           break;
       case 0x1140:
           MdcPrintTag(fi,tag,"Byte Offset to Pixel Field   : %hu\n",ui16);
           break;
       case 0x1141:
           MdcPrintTag(fi,tag,"Length of Pixel Data in Bytes: %u\n",ui32);
           break;
       case 0x8000:
           MdcPrintTag(fi,tag,"Original File Name           : %s\n",ps);
           break;
       case 0x8010:
           MdcPrintTag(fi,tag,"Original File Location       : %s\n",ps);
           break;
       case 0x8018:
           MdcPrintTag(fi,tag,"Data Set Identifier (DSID)   : %s\n",ps);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   /* group 0x0010 */
   case 0x0010: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Patient Information - Group 0010\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Patient Name                 : %s\n",ps);
           MdcKillSpaces(ps);
           MdcStringCopy(fi->patient_name,ps,tag->length);
           /* remove caret signs */
           pc = fi->patient_name;
           while (pc[0] != '\0') {
                if (pc[0] == '^') pc[0] = ' ';
                pc+=1;
           }
           MdcKillSpaces(fi->patient_name);
           break;
       case 0x0020:
           MdcPrintTag(fi,tag,"Patient ID                   : %s\n",ps);
           MdcKillSpaces(ps);
           MdcStringCopy(fi->patient_id,ps,tag->length);
           break;
       case 0x0030:
           MdcPrintTag(fi,tag,"Patient Birthday             : %s\n",ps);
           MdcKillSpaces(ps);
           MdcStringCopy(fi->patient_dob,ps,tag->length);
           break;
       case 0x0040:
           MdcPrintTag(fi,tag,"Patient Sex                  : %s\n",ps);
           MdcKillSpaces(ps);
           MdcStringCopy(fi->patient_sex,ps,tag->length);
           break;
       case 0x1000:
           MdcPrintTag(fi,tag,"Other Patient IDs            : %s\n",ps);
           break;
       case 0x1001:
           MdcPrintTag(fi,tag,"Other Patient Names          : %s\n",ps);
           break;
       case 0x1005:
           MdcPrintTag(fi,tag,"Patient Maiden Name          : %s\n",ps);
           break;
       case 0x1010:
           MdcPrintTag(fi,tag,"Patient Age                  : %s\n",ps);
           break;
       case 0x1020:
           MdcPrintTag(fi,tag,"Patient Size                 : %s\n",ps);
           fi->patient_height = (float)atof(ps);
           break;
       case 0x1030:
           MdcPrintTag(fi,tag,"Patient Weight               : %s\n",ps);
           fi->patient_weight = (float)atof(ps);
           break;
       case 0x1040:
           MdcPrintTag(fi,tag,"Patient Address              : %s\n",ps);
           break;
       case 0x1050:
           MdcPrintTag(fi,tag,"Insurance Plan ID            : %s\n",ps);
           break;
       case 0x1060:
           MdcPrintTag(fi,tag,"Patient Mother's Maiden Name : %s\n",ps);
           break;
       case 0x21b0:
           MdcPrintTag(fi,tag,"Additional Patient History   : %s\n",ps);
           break;
       case 0x4000:
           MdcPrintTag(fi,tag,"Comments                     : %s\n",ps);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   /* group 0x0011 */
   case 0x0011: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Shadow Patient Information - Group 0011\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Shadow owner code            : %s\n",ps);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   /* group 0x0017 */
   case 0x0017: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Calibration - Group 0017\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Private Creator              : %s\n",ps);
           break;
       case 0x1001:
           MdcPrintTag(fi,tag,"Correction Cal ID            : %s\n",ps);
           break;
       case 0x1002:
           MdcPrintTag(fi,tag,"Compatible Version           : %s\n",ps);
           break;
       case 0x1003:
           MdcPrintTag(fi,tag,"Software Version             : %s\n",ps);
           break;
       case 0x1004:
           MdcPrintTag(fi,tag,"Cal DateTime                 : %s\n",ps);
           break;
       case 0x1005:
           MdcPrintTag(fi,tag,"Cal Description              : %s\n",ps);
           break;
       case 0x1006:
           MdcPrintTag(fi,tag,"Cal Type                     : %s\n",ps);
           break;
       case 0x1007:
           MdcPrintTag(fi,tag,"Where is Correction          : %s\n",ps);
           break;
       case 0x1008:
           MdcPrintTag(fi,tag,"Correction File Size         : %s\n",ps);
           break;
       case 0x1009:
           MdcPrintTag(fi,tag,"Scan ID                      : %s\n",ps);
           break;
       case 0x100A:
           MdcPrintTag(fi,tag,"Scan DateTime                : %s\n",ps);
           break;
       case 0x100B:
           MdcPrintTag(fi,tag,"Norm 2D Cal ID               : %s\n",ps);
           break;
       case 0x100C:
           MdcPrintTag(fi,tag,"Hospital Identifier          : %s\n",ps);
           break;
       case 0x100D:
           MdcPrintTag(fi,tag,"Archived                     : %s\n",ps);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   /* group 0x0018 */
   case 0x0018: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Acquisition Information - Group 0018\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Contrast/Bolus Agent         : %s\n",ps);
           break;
       case 0x0015:
           MdcPrintTag(fi,tag,"Body Part Examined           : %s\n",ps);
           if (tag->length > 0) {
             MdcKillSpaces(ps);
             MdcStringCopy(fi->organ_code,ps,tag->length);
           }
           break;
       case 0x0020:
           MdcPrintTag(fi,tag,"Scanning Sequence            : %s\n",ps);
           break;
       case 0x0022:
           MdcPrintTag(fi,tag,"Scan Mode                    : %s\n",ps);
           break;
       case 0x0030:
           MdcPrintTag(fi,tag,"Radionuclide                 : %s\n",ps);
           MdcStringCopy(fi->radiopharma,ps,tag->length);
           break;
       case 0x0031:
           MdcPrintTag(fi,tag,"Radiopharmaceutical          : %s\n",ps);
           MdcStringCopy(fi->radiopharma,ps,tag->length);
           break;
       case 0x0040:
           MdcPrintTag(fi,tag,"Cine Rate                    : %s\n",ps);
           break;
       case 0x0050:
           MdcPrintTag(fi,tag,"Slice Thickness              : %s [mm]\n",ps);
           fi->image[i].slice_width=(float)atof(ps);
           break;
       case 0x0060:
           MdcPrintTag(fi,tag,"KVP                          : %s\n",ps);
           break;
       case 0x0070:
           MdcPrintTag(fi,tag,"Counts Accumulated           : %s\n",ps);
           break;
       case 0x0071:
           MdcPrintTag(fi,tag,"Acquisition Termination Condition : %s\n",ps);
           break;
       case 0x0073:
           MdcPrintTag(fi,tag,"Acquisition Start Condition       : %s\n",ps);
           break;
       case 0x0074:
           MdcPrintTag(fi,tag,"Acquisition Start Condition Data  : %s\n",ps);
           break;
       case 0x0075:
           MdcPrintTag(fi,tag,"Acquisition Termination Condition Data : %s\n"
                                                                        ,ps);
           break;
       case 0x0080:
           MdcPrintTag(fi,tag,"Repetition Time              : %s [ms]\n",ps);
           if (fi->mod != NULL) {
             fi->mod->mr_info.repetition_time = atof(ps);
           }
           break;
       case 0x0081:
           MdcPrintTag(fi,tag,"Echo Time                    : %s [ms]\n",ps);
           if (fi->mod != NULL) {
             fi->mod->mr_info.echo_time = atof(ps);
           }
           break;
       case 0x0082:
           MdcPrintTag(fi,tag,"Inversion Time               : %s [ms]\n",ps);
           if (fi->mod != NULL) {
             fi->mod->mr_info.inversion_time = atof(ps);
           }
           break;
       case 0x0083:
           MdcPrintTag(fi,tag,"Number of Averages           : %s\n",ps);
           if (fi->mod != NULL) {
             fi->mod->mr_info.num_averages = atof(ps);
           }
           break;
       case 0x0084:
           MdcPrintTag(fi,tag,"Imaging Frequency            : %s [MHz]\n",ps);
           if (fi->mod != NULL) {
             fi->mod->mr_info.imaging_freq = atof(ps);
           }
           break;
       case 0x0085:
           MdcPrintTag(fi,tag,"Imaged Nucleus               : %s\n",ps);
           break;
       case 0x0086:
           MdcPrintTag(fi,tag,"Echo Number                  : %s\n",ps);
           break;
       case 0x0088:
           MdcPrintTag(fi,tag,"Slice Spacing                : %s [mm]\n",ps);
           sscanf(ps,"%f",&id->slice_spacing);
           /* MARK: in DICOM, sign = direction, pfff! */
           if (id->slice_spacing < 0.) id->slice_spacing = - id->slice_spacing;
           break;
       case 0x0090:
           MdcPrintTag(fi,tag,"Data Collection Diameter     : %s\n",ps);
           break;
       case 0x0095:
           MdcPrintTag(fi,tag,"Pixel Bandwidth              : %s\n",ps);
           if (fi->mod != NULL) {
             fi->mod->mr_info.pixel_bandwidth = atof(ps);
           }
           break;
       case 0x1000:
           MdcPrintTag(fi,tag,"Device Serial Number         : %s\n",ps);
           break;
       case 0x1010:
           MdcPrintTag(fi,tag,"Film Scanner ID              : %s\n",ps);
           break;
       case 0x1020:
           MdcPrintTag(fi,tag,"Software Version             : %s\n",ps);
           break;
       case 0x1030:
           MdcPrintTag(fi,tag,"Protocol                     : %s\n",ps);
           break;
       case 0x1040:
           MdcPrintTag(fi,tag,"Contrast/Bolus Route         : %s\n",ps);
           break;
       case 0x1041:
           MdcPrintTag(fi,tag,"Contrast/Bolus Volume        : %s\n",ps);
           break;
       case 0x1042:
           MdcPrintTag(fi,tag,"Contrast/Bolus Start Time    : %s\n",ps);
           break;
       case 0x1043:
           MdcPrintTag(fi,tag,"Contrast/Bolus Stop Time     : %s\n",ps);
           break;
       case 0x1044:
           MdcPrintTag(fi,tag,"Contrast/Bolus Total Dose    : %s\n",ps);
           break;
       case 0x1050:
           MdcPrintTag(fi,tag,"Spatial Resolution           : %s\n",ps);
           break;
       case 0x1060:
           MdcPrintTag(fi,tag,"Trigger Time                 : %s\n",ps);
           break;
       case 0x1063:
           MdcPrintTag(fi,tag,"Frame Time                   : %s\n",ps);
           dicom->frametime = (float)atof(ps);
           break;
       case 0x1070:
           MdcPrintTag(fi,tag,"Radionuclide Route           : %s\n",ps);
           break;
       case 0x1071:
           MdcPrintTag(fi,tag,"Radionuclide Volume          : %s\n",ps);
           break;
       case 0x1072:
           MdcPrintTag(fi,tag,"Radionuclide Start Time      : %s\n",ps);
           MdcGetHHMMSS(ps,&fi->dose_time_hour
                          ,&fi->dose_time_minute
                          ,&fi->dose_time_second);
           break;
       case 0x1073:
           MdcPrintTag(fi,tag,"Radionuclide Stop Time       : %s\n",ps);
           break;
       case 0x1074:
           MdcPrintTag(fi,tag,"Radionuclide Total Dose      : %s\n",ps);
           fi->injected_dose = (float)atof(ps);
           break;
       case 0x1075:
           MdcPrintTag(fi,tag,"Radionuclide Half Life       : %s\n",ps);
           fi->isotope_halflife = (float)atof(ps);
           break;
       case 0x1076:
           MdcPrintTag(fi,tag,"Radionuclide Positron Fraction : %s\n",ps);
           break;
       case 0x1081:
           MdcPrintTag(fi,tag,"Low R-R Value                : %s\n",ps);
           dicom->window_low = (float)atof(ps);
           break;
       case 0x1082:
           MdcPrintTag(fi,tag,"High R-R Value               : %s\n",ps);
           dicom->window_high = (float)atof(ps);
           break;
       case 0x1083:
           MdcPrintTag(fi,tag,"Intervals Acquired           : %s\n",ps);
           dicom->intervals_acquired += (float)atof(ps);
           break;
       case 0x1084:
           MdcPrintTag(fi,tag,"Intervals Rejected           : %s\n",ps);
           dicom->intervals_rejected += (float)atof(ps);
           break;
       case 0x1088:
           MdcPrintTag(fi,tag,"Heart Rate                   : %s\n",ps);
           dicom->heart_rate = (Int16)atoi(ps);
           break;
       case 0x1100:
           MdcPrintTag(fi,tag,"Reconstruction Diameter      : %s\n",ps);
           break;
       case 0x1110:
           MdcPrintTag(fi,tag,"Distance Source to Detector  : %s\n",ps);
           break;
       case 0x1111:
           MdcPrintTag(fi,tag,"Distance Source to Patient   : %s\n",ps);
           break;
       case 0x1120:
           MdcPrintTag(fi,tag,"Gantry Tilt                  : %s [degrees]\n"
                                                                   ,ps);
           fi->gantry_tilt = (float)atof(ps);
           break;
       case 0x1130:
           MdcPrintTag(fi,tag,"Table Height                 : %s\n",ps);
           break;
       case 0x1140:
           MdcPrintTag(fi,tag,"Rotation Direction           : %s\n",ps);
           if (MdcDicomDoAcqData(fi,dicom) == MDC_YES) {
             tmp = dicom->acqnr - 1;
             if (strcasecmp(ps,"CW") == 0) {
               fi->acqdata[tmp].rotation_direction = MDC_ROTATION_CW;
             }else if (strcasecmp(ps,"CC") == 0) {
               fi->acqdata[tmp].rotation_direction = MDC_ROTATION_CC;
             }
           }
           break;
       case 0x1142:
           MdcPrintTag(fi,tag,"Radial Position              : %s\n",ps);
           if (MdcDicomDoAcqData(fi,dicom) == MDC_YES) {
             tmp = dicom->acqnr - 1;
             sscanf(ps,"%g",&fi->acqdata[tmp].radial_position);
           }
           break;
       case 0x1143:
           MdcPrintTag(fi,tag,"Scan Arc                     : %s\n",ps);
           if (MdcDicomDoAcqData(fi,dicom) == MDC_YES) {
             tmp = dicom->acqnr - 1;
             sscanf(ps,"%g",&fi->acqdata[tmp].scan_arc);
           }
           sscanf(ps,"%g",&dicom->scan_arc);
           break;
       case 0x1144:
           MdcPrintTag(fi,tag,"Angular Step                 : %s\n",ps);
           if (MdcDicomDoAcqData(fi,dicom) == MDC_YES) {
             tmp = dicom->acqnr - 1;
             sscanf(ps,"%f",&fi->acqdata[tmp].angle_step);
           }
           break;
       case 0x1145:
           MdcPrintTag(fi,tag,"Center of Rotation Offset    : %s\n",ps);
           if (MdcDicomDoAcqData(fi,dicom) == MDC_YES) {
             tmp = dicom->acqnr - 1;
             fi->acqdata[tmp].rotation_offset = atof(ps);
           }
           break;
       case 0x1147:
           MdcPrintTag(fi,tag,"Field of View Share          : %s\n",ps);
           break;
       case 0x1149:
           MdcPrintTag(fi,tag,"Field of View Dimensions     : %s\n",ps);
           break;
       case 0x1150:
           MdcPrintTag(fi,tag,"Exposure Time                : %s\n",ps);
           break;
       case 0x1151:
           MdcPrintTag(fi,tag,"Exposure Rate                : %s\n",ps);
           break;
       case 0x1152:
           MdcPrintTag(fi,tag,"Exposure                     : %s\n",ps);
           break;
       case 0x1160:
           MdcPrintTag(fi,tag,"Filter Type                  : %s\n",ps);
           MdcKillSpaces(ps);
           MdcStringCopy(fi->filter_type,ps,tag->length);
           break;
       case 0x1170:
           MdcPrintTag(fi,tag,"Generator Power              : %s\n",ps);
           break;
       case 0x1180:
           MdcPrintTag(fi,tag,"Collimator/Grid              : %s\n",ps);
           break;
       case 0x1181:
           MdcPrintTag(fi,tag,"Collimator Type              : %s\n",ps);
           break;
       case 0x1190:
           MdcPrintTag(fi,tag,"Focal Spot                   : %s\n",ps);
           break;
       case 0x1200:
           MdcPrintTag(fi,tag,"Date of Last Calibration     : %s\n",ps);
           break;
       case 0x1201:
           MdcPrintTag(fi,tag,"Time of Last Calibration     : %s\n",ps);
           break;
       case 0x1210:
           MdcPrintTag(fi,tag,"Convolution Kernel           : %s\n",ps);
           break;
       case 0x1240:
           MdcPrintTag(fi,tag,"Upper/Lower Pixel Values     : %s\n",ps);
           break;
       case 0x1242:
           MdcPrintTag(fi,tag,"Actual Frame Duration        : %s\n",ps);
           flt = (float)atof(ps);
           if (FILL_STATIC_DATA == MDC_YES) {
             id->sdata->image_duration = flt;
           }
           if (FILL_DYNAMIC_DATA == MDC_YES) {
             dd = &fi->dyndata[dicom->dynnr];
             if (dd->time_frame_duration > 0.) {
               /* safely increment phase counter */
               if (dicom->dynnr < (fi->dynnr - 1)) dicom->dynnr += 1;
             }
             dd = &fi->dyndata[dicom->dynnr];
             dd->time_frame_duration = flt;
           }
           dicom->frameduration = flt;
           break;
       case 0x1243:
           MdcPrintTag(fi,tag,"Count Rate                   : %s\n",ps);
           break;
       case 0x1250:
           MdcPrintTag(fi,tag,"Receiving Coil               : %s\n",ps);
           break;
       case 0x1251:
           MdcPrintTag(fi,tag,"Transmitting Coil            : %s\n",ps);
           break;
       case 0x1260:
           MdcPrintTag(fi,tag,"Screen Type                  : %s\n",ps);
           break;
       case 0x1261:
           MdcPrintTag(fi,tag,"Phosphor Type                : %s\n",ps);
           break;
       case 0x1314:
           MdcPrintTag(fi,tag,"Flip Angle                   : %s\n",ps);
           if (fi->mod != NULL) {
             fi->mod->mr_info.flip_angle = atof(ps);
           }
           break;
       case 0x1318:
           MdcPrintTag(fi,tag,"dBdt                         : %s\n",ps);
           if (fi->mod != NULL) {
             fi->mod->mr_info.dbdt = atof(ps);
           }
           break;
       case 0x4000:
           MdcPrintTag(fi,tag,"Comments                     : %s\n",ps);
           break;
       case 0x5000:
           MdcPrintTag(fi,tag,"Output Power                 : %s\n",ps);
           break;
       case 0x5010:
           MdcPrintTag(fi,tag,"Transducer Data              : %s\n",ps);
           break;
       case 0x5020:
           MdcPrintTag(fi,tag,"Preprocessing Function       : %s\n",ps);
           break;
       case 0x5021:
           MdcPrintTag(fi,tag,"Postprocessing Function      : %s\n",ps);
           break;
       case 0x5030:
           MdcPrintTag(fi,tag,"Dynamic Range                : %s\n",ps);
           break;
       case 0x5040:
           MdcPrintTag(fi,tag,"Total Gain                   : %s\n",ps);
           break;
       case 0x5050:
           MdcPrintTag(fi,tag,"Depth of Scan Field          : %s\n",ps);
           break;
       case 0x5100:
           MdcPrintTag(fi,tag,"Patient Position             : %s\n",ps);
           MdcStringCopy(fi->pat_pos,ps,tag->length);
           MdcUpStr(fi->pat_pos);
           break;
       case 0x6030:
           MdcPrintTag(fi,tag,"Transducer Frequency         : %u\n",ui32);
           if (fi->mod != NULL) {
             fi->mod->mr_info.transducer_freq = ui32;
           }
           break;
       case 0x6031:
           MdcPrintTag(fi,tag,"Transducer Type              : %s\n",ps);
           if (fi->mod != NULL) {
             MdcStringCopy(fi->mod->mr_info.transducer_type,ps,MDC_MAXSTR);
           }
           break;
       case 0x6032:
           MdcPrintTag(fi,tag,"Pulse Repetition Frequency   : %u\n",ui32);
           if (fi->mod != NULL) {
             fi->mod->mr_info.pulse_repetition_freq = ui32;
           }
           break;
       case 0x9005:
           MdcPrintTag(fi,tag,"Pulse Sequence Name          : %s\n",ps);
           if (fi->mod != NULL) {
             MdcStringCopy(fi->mod->mr_info.pulse_seq_name,ps,MDC_MAXSTR);
           }
           break;
       case 0x9017:
           MdcPrintTag(fi,tag,"Steady State Pulse Sequence  : %s\n",ps);
           if (fi->mod != NULL) {
           MdcStringCopy(fi->mod->mr_info.steady_state_pulse_seq,ps,MDC_MAXSTR);
           }
           break;
       case 0x9104:
           MdcPrintTag(fi,tag,"Slab Thickness               : %f\n",flt64);
           if (fi->mod != NULL) {
             fi->mod->mr_info.slab_thickness = flt64;
           }
           break;
       case 0x9305:
           MdcPrintTag(fi,tag,"Revolution Time              : %s\n",ps);
           break;
       case 0x9306:
           MdcPrintTag(fi,tag,"Single Collimation Width     : %s\n",ps);
           break;
       case 0x9307:
           MdcPrintTag(fi,tag,"Total Collimation Width      : %s\n",ps);
           break;
       case 0x9309:
           MdcPrintTag(fi,tag,"Table Speed                  : %s\n",ps);
           break;
       case 0x9310:
           MdcPrintTag(fi,tag,"Table Feed per Rotation      : %s\n",ps);
           break;
       case 0x9311:
           MdcPrintTag(fi,tag,"CT Pitch Factor              : %s\n",ps);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   /* group 0x0019 */
   case 0x0019: switch (tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Shadow Relationship Information - Group 0019\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Private Creator ID           : %s\n",ps);
           break;
       case 0x1002:
           MdcPrintTag(fi,tag,"NumberOfCellsIInDetector     : %s\n",ps);
           break;
       case 0x1003:
           MdcPrintTag(fi,tag,"CellNumberAtTheta            : %s\n",ps);
           break;
       case 0x1004:
           MdcPrintTag(fi,tag,"Cell spacing                 : %s\n",ps);
           break;
       case 0x100F:
           MdcPrintTag(fi,tag,"HorizFrameOfRef              : %s\n",ps);
           break;
       case 0x1011:
           MdcPrintTag(fi,tag,"SeriesContrast               : %s\n",ps);
           break;
       case 0x1018:
           MdcPrintTag(fi,tag,"FirstScanRas                 : %s\n",ps);
           break;
       case 0x101A:
           MdcPrintTag(fi,tag,"LastScanRas                  : %s\n",ps);
           break;
       case 0x1023:
           MdcPrintTag(fi,tag,"TableSpeed                   : %s\n",ps);
           break;
       case 0x1024:
           MdcPrintTag(fi,tag,"MidScanTime                  : %s\n",ps);
           break;
       case 0x1025:
           MdcPrintTag(fi,tag,"MidScanFlag                  : %s\n",ps);
           break;
       case 0x1026:
           MdcPrintTag(fi,tag,"DegreesOfAzimuth             : %s\n",ps);
           break;
       case 0x1027:
           MdcPrintTag(fi,tag,"GantryPeriod                 : %s\n",ps);
           break;
       case 0x102C:
           MdcPrintTag(fi,tag,"NumberOfTriggers             : %s\n",ps);
           break;
       case 0x102E:
           MdcPrintTag(fi,tag,"AngleOfFirstView             : %s\n",ps);
           break;
       case 0x102F:
           MdcPrintTag(fi,tag,"TriggerFrequency             : %s\n",ps);
           break;
       case 0x1039:
           MdcPrintTag(fi,tag,"ScanFOVType                  : %s\n",ps);
           break;
       case 0x1042:
           MdcPrintTag(fi,tag,"SegmentNumber                : %s\n",ps);
           break;
       case 0x1043:
           MdcPrintTag(fi,tag,"TotalSegmentsRequested       : %s\n",ps);
           break;
       case 0x1047:
           MdcPrintTag(fi,tag,"ViewCompressionFactor        : %s\n",ps);
           break;
       case 0x1052:
           MdcPrintTag(fi,tag,"ReconPostProcFlag            : %s\n",ps);
           break;
       case 0x106A:
           MdcPrintTag(fi,tag,"DependentOnNumViewsProcessed : %s\n",ps);
           break;
       case 0x1220:
           MdcPrintTag(fi,tag,"Mosaic Image Width           : %s\n",ps);
           sscanf(ps,"%u",&dicom->mosaic_width);
           break;
       case 0x1221:
           MdcPrintTag(fi,tag,"Mosaic Image Height          : %s\n",ps);
           sscanf(ps,"%u",&dicom->mosaic_height);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   /* group 0x0020 */
   case 0x0020: switch (tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Relationship Information - Group 0020\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x000d:
           MdcPrintTag(fi,tag,"Study Instance UID           : %s\n",ps);
           break;
       case 0x000e:
           MdcPrintTag(fi,tag,"Series Instance UID          : %s\n",ps);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Study ID                     : %s\n",ps);
           MdcStringCopy(fi->study_id,ps,tag->length);
           break;
       case 0x0011:
           MdcPrintTag(fi,tag,"Series Number                : %s\n",ps);
           fi->nr_series = atoi(ps);
           break;
       case 0x0012:
           MdcPrintTag(fi,tag,"Acquisition Number           : %s\n",ps);
           fi->nr_acquisition = atoi(ps);
           break;
       case 0x0013:
           MdcPrintTag(fi,tag,"Image Number                 : %s\n",ps);
           fi->nr_instance = atoi(ps);
           break;
       case 0x0020:
           MdcPrintTag(fi,tag,"Patient Orientation          : %s\n",ps);
           MdcStringCopy(fi->pat_orient,ps,tag->length);
           break;
       case 0x0030:
           MdcPrintTag(fi,tag,"Image Position               : %s [mm]\n",ps);
           sscanf(ps,"%f\\%f\\%f",&id->image_pos_dev[0],
                                  &id->image_pos_dev[1],
                                  &id->image_pos_dev[2]);
           break;
       case 0x0032:
           MdcPrintTag(fi,tag,"Image Position Patient       : %s [mm]\n",ps);
           sscanf(ps,"%f\\%f\\%f",&id->image_pos_pat[0],
                                  &id->image_pos_pat[1],
                                  &id->image_pos_pat[2]);
           break;
       case 0x0035:
           MdcPrintTag(fi,tag,"Image Orientation            : %s [mm]\n",ps);
           sscanf(ps,"%f\\%f\\%f\\%f\\%f\\%f",&id->image_orient_dev[0],
                                              &id->image_orient_dev[1],
                                              &id->image_orient_dev[2],
                                              &id->image_orient_dev[3],
                                              &id->image_orient_dev[4],
                                              &id->image_orient_dev[5]);
           break;
       case 0x0037:
           MdcPrintTag(fi,tag,"Image Orientation Patient    : %s [mm]\n",ps);
           sscanf(ps,"%f\\%f\\%f\\%f\\%f\\%f",&id->image_orient_pat[0],
                                              &id->image_orient_pat[1],
                                              &id->image_orient_pat[2],
                                              &id->image_orient_pat[3],
                                              &id->image_orient_pat[4],
                                              &id->image_orient_pat[5]);
           fi->pat_slice_orient = MdcGetPatSliceOrient(fi,i);
           break;
       case 0x0050:
           MdcPrintTag(fi,tag,"Location                     : %s\n",ps);
           break;
       case 0x0052:
           MdcPrintTag(fi,tag,"Frame of Reference UID       : %s\n",ps);
           break;
       case 0x0060:
           MdcPrintTag(fi,tag,"Laterality                   : %s\n",ps);
           break;
       case 0x0070:
           MdcPrintTag(fi,tag,"Image Geometrie Type         : %s\n",ps);
           break;
       case 0x0080:
           MdcPrintTag(fi,tag,"Masking Image                : %s\n",ps);
           break;
       case 0x1000:
           MdcPrintTag(fi,tag,"Series in Study              : %s\n",ps);
           break;
       case 0x1001:
           MdcPrintTag(fi,tag,"Acquisitions in Series       : %s\n",ps);
           break;
       case 0x1002:
           MdcPrintTag(fi,tag,"Images in Acquisition        : %s\n",ps);
           break;
       case 0x1020:
           MdcPrintTag(fi,tag,"Reference                    : %s\n",ps);
           break;
       case 0x1040:
           MdcPrintTag(fi,tag,"Position Reference Indicator : %s\n",ps);
           break;
       case 0x1041:
           MdcPrintTag(fi,tag,"Slice Location               : %s\n",ps);
           break;
       case 0x1070:
           MdcPrintTag(fi,tag,"Other Study Numbers          : %s\n",ps);
           break;
       case 0x3401:
           MdcPrintTag(fi,tag,"Modifying Device ID          : %s\n",ps);
           break;
       case 0x3402:
           MdcPrintTag(fi,tag,"Modified Image ID            : %s\n",ps);
           break;
       case 0x3403:
           MdcPrintTag(fi,tag,"Modified Image Data          : %s\n",ps);
           break;
       case 0x3404:
           MdcPrintTag(fi,tag,"Modifying Device Manufacturer: %s\n",ps);
           break;
       case 0x3405:
           MdcPrintTag(fi,tag,"Modified Image Time          : %s\n",ps);
           break;
       case 0x3406:
           MdcPrintTag(fi,tag,"Modified Image Description   : %s\n",ps);
           break;
       case 0x4000:
           MdcPrintTag(fi,tag,"Comments                     : %s\n",ps);
           break;
       case 0x5000:
           MdcPrintTag(fi,tag,"Original Image Identification: 0x%.4x\n",ui16);
           break;
       case 0x5002:
           MdcPrintTag(fi,tag,"Original Image Nomenclature  : %s\n",ps);
           break;
       default:
         if ( (tag->element >= 0x3100) && (tag->element <= 0x31ff) ) {
           MdcPrintTag(fi,tag,"Source Image ID              : %s\n",ps);
         }else{
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
         }
     }
     break;
   /* group 0x0021 */
   case 0x0021: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Shadow Relationship Information - Group 0021\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Shadow Owner Code            : %s\n",ps);
           break;
       case 0x0080:
           MdcPrintTag(fi,tag,"Owner ID                     : %s\n",ps);
           break;
       case 0x1003:
           MdcPrintTag(fi,tag,"SeriesFromWhichPrescribed    : %s\n",ps);
           break;
       case 0x1010:
           MdcPrintTag(fi,tag,"Zoom Factor                  : %s\n",ps);
           break;
       case 0x1011:
           MdcPrintTag(fi,tag,"Target Coordinate            : %s\n",ps);
           break;
       case 0x1020:
           MdcPrintTag(fi,tag,"Used ROI (mask)              : %hu\n",ui16);
           break;
       case 0x1035:
           MdcPrintTag(fi,tag,"SeriesPrescribedFrom         : %s\n",ps);
           break;
       case 0x1036:
           MdcPrintTag(fi,tag,"ImagePrescribedFrom          : %s\n",ps);
           break;
       case 0x1091:
           MdcPrintTag(fi,tag,"BiopsyPosition               : %s\n",ps);
           break;
       case 0x1092:
           MdcPrintTag(fi,tag,"BiopsyTLocation              : %s\n",ps);
           break;
       case 0x1093:
           MdcPrintTag(fi,tag,"BiopsyRefLocation            : %s\n",ps);
           break;
       case 0x1340:
           MdcPrintTag(fi,tag,"Number of Mosaic Images      : %s\n",ps);
           sscanf(ps,"%u",&dicom->mosaic_number);
           break;
       case 0x134f:
           MdcPrintTag(fi,tag,"Mosaic Interlace Mode        : %s\n",ps);
           if (strncmp(ps,"INTERL",6) == 0) dicom->mosaic_interlaced = MDC_YES;
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   /* group 0x0023 */
   case 0x0023: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn(" - Group 0023\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Private Creator              : %s\n",ps);
           break;
       case 0x1023:
           MdcPrintTag(fi,tag,"Private Creator              : %s\n",ps);
           break;
       case 0x1070:
           MdcPrintTag(fi,tag,"StartTimeSecsInFirstAxial    : %s\n",ps);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   /* group 0x0027 */
   case 0x0027: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn(" CT Image - Group 0027\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Private Creator              : %s\n",ps);
           break;
       case 0x1010:
           MdcPrintTag(fi,tag,"ScoutType                    : %s\n",ps);
           break;
       case 0x101C:
           MdcPrintTag(fi,tag,"VmaMamp                      : %s\n",ps);
           break;
       case 0x101E:
           MdcPrintTag(fi,tag,"VmaMod                       : %s\n",ps);
           break;
       case 0x101F:
           MdcPrintTag(fi,tag,"VmaClip                      : %s\n",ps);
           break;
       case 0x1020:
           MdcPrintTag(fi,tag,"SmartScanOnOffFlag           : %s\n",ps);
           break;
       case 0x1035:
           MdcPrintTag(fi,tag,"PlaneType                    : %s\n",ps);
           break;
       case 0x1042:
           MdcPrintTag(fi,tag,"CenterRCoordOfPlaneImage     : %s\n",ps);
           break;
       case 0x1043:
           MdcPrintTag(fi,tag,"CenterACoordOfPlaneImage     : %s\n",ps);
           break;
       case 0x1044:
           MdcPrintTag(fi,tag,"CenterSCoordOfPlaneImage     : %s\n",ps);
           break;
       case 0x1045:
           MdcPrintTag(fi,tag,"NormalRCoord                 : %s\n",ps);
           break;
       case 0x1046:
           MdcPrintTag(fi,tag,"NormalACoord                 : %s\n",ps);
           break;
       case 0x1047:
           MdcPrintTag(fi,tag,"NormalSCoord                 : %s\n",ps);
           break;
       case 0x1050:
           MdcPrintTag(fi,tag,"TableStartLocation           : %s\n",ps);
           break;
       case 0x1051:
           MdcPrintTag(fi,tag,"TableEndLocation             : %s\n",ps);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   /* group 0x0028 */
   case 0x0028: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Image Presentation - Group 0028\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0002:
           MdcPrintTag(fi,tag,"Samples Per Pixel            : %hu\n",ui16);
           break;
       case 0x0004:
           MdcPrintTag(fi,tag,"Photometric Interpretation   : %s\n",ps);
           MdcKillSpaces(ps);
           if (strcasecmp(ps,"MONOCHROME1") == 0 ) dicom->INVERT = MDC_YES;
           break;
       case 0x0005:
           MdcPrintTag(fi,tag,"Image Dimensions             : %hu\n",ui16);
           break;
       case 0x0008:
           MdcPrintTag(fi,tag,"Number of Frames             : %s\n",ps);
           fi->dim[3] = (Uint32)atol(ps);
           break;
       case 0x0009:
           MdcPrintTag(fi,tag,"Frame Increment Pointer      : ");
           vm = tag->length / 2; pu16 = (Uint16 *)tag->data;
           for (c=0; c<vm; c+=2) {
              group = pu16[c]; element=pu16[c+1];
              if (group == 0x0054) {
                switch (element) {
                  case 0x0010:
                      dicom->VectDO[MDC_VECT_ENERGYWINDOW]= MDC_PASS1; break;
                  case 0x0020:
                      dicom->VectDO[MDC_VECT_DETECTOR]    = MDC_PASS1; break;
                  case 0x0030:
                      dicom->VectDO[MDC_VECT_PHASE]       = MDC_PASS1; break;
                  case 0x0050:
                      dicom->VectDO[MDC_VECT_ROTATION]    = MDC_PASS1; break;
                  case 0x0060:
                      dicom->VectDO[MDC_VECT_RRINTERVAL]  = MDC_PASS1; break;
                  case 0x0070:
                      dicom->VectDO[MDC_VECT_TIMESLOT]    = MDC_PASS1; break;
                  case 0x0080:
                      dicom->VectDO[MDC_VECT_SLICE]       = MDC_PASS1; break;
                  case 0x0090:
                      dicom->VectDO[MDC_VECT_ANGULARVIEW] = MDC_PASS1; break;
                  case 0x0100:
                      dicom->VectDO[MDC_VECT_TIMESLICE]   = MDC_PASS1; break;
                }
              }
              if (MDC_INFO) MdcPrntScrn("(%.4x:%.4x) ",group,element);
           }
           if (MDC_INFO) MdcPrntScrn("\n");
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Rows                         : %hu\n",ui16);
           fi->image[i].height = (Uint32)ui16;
           if ((Uint32)ui16  > fi->mheight) fi->mheight = ui16;
           if ((Uint32)ui16 != fi->mheight) fi->diff_size = MDC_YES;
           break;
       case 0x0011:
           MdcPrintTag(fi,tag,"Columns                      : %hu\n",ui16);
           fi->image[i].width = (Uint32)ui16;
           if ((Uint32)ui16  > fi->mwidth) fi->mwidth = ui16;
           if ((Uint32)ui16 != fi->mwidth) fi->diff_size = MDC_YES;
           break;
       case 0x0030:
           MdcPrintTag(fi,tag,"Pixel Size                   : %s [mm]\n",ps);
           {
              pc=strchr(ps,'\\');
              if (pc != NULL) {
                pc+=1;
                fi->pixdim[1] = (float)atof(pc);
                pc-=1; pc[0]='\0';
              }else{ /* no second value available */
                fi->pixdim[1] = (float)atof(ps);
              }

              fi->pixdim[2] = (float)atof(ps);
              fi->image[i].pixel_xsize = fi->pixdim[1];
              fi->image[i].pixel_ysize = fi->pixdim[2];
           }
           break;
       case 0x0031:
           MdcPrintTag(fi,tag,"Zoom Factor                  : %s\n",ps);
           fi->image[i].ct_zoom_fctr = (float)atof(ps);
           break;
       case 0x0040:
           MdcPrintTag(fi,tag,"Image Format                 : %s\n",ps);
           break;
       case 0x0050:
           MdcPrintTag(fi,tag,"Manipulated Image            : %s\n",ps);
           break;
       case 0x0051:
           MdcPrintTag(fi,tag,"Corrected Image              : %s\n",ps);
           if (strstr(ps,"DECY") != NULL) fi->decay_corrected = MDC_YES;
           if (strstr(ps,"UNIF") != NULL) fi->flood_corrected = MDC_YES;
           break;
       case 0x0060:
           MdcPrintTag(fi,tag,"Compression Code             : %s\n",ps);
           break;
       case 0x0100:
           MdcPrintTag(fi,tag,"Bits Allocated               : %hu\n",ui16);
           switch (ui16 % 8) {
             case  0 : /* bytes */
             case  1 : /*  1bit */
             case  4 : /* 12bit */
                 bits_allocated = fi->image[i].bits = (Int16)ui16;
                 break;
             default : return("ACR  Unsupported pixel type");
           }
           break;
       case 0x0101:
           MdcPrintTag(fi,tag,"Bits per Pixel               : %hu\n",ui16);
           bits_stored = (Int16)ui16;
           break;
       case 0x0102:
           MdcPrintTag(fi,tag,"High Bit                     : %hu\n",ui16);
           if ((Int16)ui16 != (bits_stored - 1))
             return ("ACR  Unsupported bits packing");
           break;
       case 0x0103:
           MdcPrintTag(fi,tag,"Pixel Representation         : %hu",ui16);
           dicom->sign=(Int16)ui16;
           if (MDC_INFO)
           switch(ui16) {
             case 0: MdcPrntScrn(" (= unsigned)\n"); break;
             case 1: MdcPrntScrn(" (= signed)\n");   break;
           }
           switch (bits_allocated) {
              case  8: if (ui16) fi->image[i].type = BIT8_S;
                       else     fi->image[i].type = BIT8_U;
                       break;
              case 16: if (ui16) fi->image[i].type = BIT16_S;
                       else     fi->image[i].type = BIT16_U;
                       break;
              case 32: if (ui16) fi->image[i].type = BIT32_S;
                       else     fi->image[i].type = BIT32_U;
                       break;
              case 64: if (ui16) fi->image[i].type = BIT64_S;
                       else     fi->image[i].type = BIT64_U;
                       break;
           }
           break;
       case 0x0104:
           MdcPrintTag(fi,tag,"Pixel Minimum                : %hu\n",ui16);
           break;
       case 0x0105:
           MdcPrintTag(fi,tag,"Pixel Maximum                : %hu\n",ui16);
           break;
       case 0x0106:
           MdcPrintTag(fi,tag,"Smallest Image Pixel Value   : %s\n",ps);
           break;
       case 0x0107:
           MdcPrintTag(fi,tag,"Largest Image Pixel Value    : %s\n",ps);
           break;
       case 0x0120:
           MdcPrintTag(fi,tag,"Pixel Padding Value          : %s\n",ps);
           break;
       case 0x0200:
           MdcPrintTag(fi,tag,"Image Location               : 0x%.4x\n",ui16);
           break;
       case 0x1050:
           MdcPrintTag(fi,tag,"Window Center                : %s\n",ps);
           fi->window_centre = (float)atof(ps);
           break;
       case 0x1051:
           MdcPrintTag(fi,tag,"Window Width                 : %s\n",ps);
           fi->window_width = (float)atof(ps);
           break;
       case 0x1052:
           MdcPrintTag(fi,tag,"Rescale Intercept            : %s\n",ps);
           dicom->si_intercept = (float)atof(ps);
           break;
       case 0x1053:
           MdcPrintTag(fi,tag,"Rescale Slope                : %s\n",ps);
           dicom->si_slope = (float)atof(ps);
           break;
       case 0x1054:
           MdcPrintTag(fi,tag,"Rescale Type                 : %s\n",ps);
           break;
       case 0x1080:
           MdcPrintTag(fi,tag,"Gray Scale                   : %s\n",ps);
           break;
       case 0x1100:
           MdcPrintTag(fi,tag,"Lookup Table Descriptor-Gray : 0x%.4x\n",ui16);
           break;
       case 0x1101:
           MdcPrintTag(fi,tag,"Lookup Table Descriptor-Red  : 0x%.4x\n",ui16);
           break;
       case 0x1102:
           MdcPrintTag(fi,tag,"Lookup Table Descriptor-Green: 0x%.4x\n",ui16);
           break;
       case 0x1103:
           MdcPrintTag(fi,tag,"Loopup Table Descriptor-Blue : 0x%.4x\n",ui16);
           break;
       case 0x1200:
           MdcPrintTag(fi,tag,"Lookup Data - Gray           : 0x%.4x\n",ui16);
           break;
       case 0x1201:
           MdcPrintTag(fi,tag,"Lookup Data - Red            : 0x%.4x\n",ui16);
           break;
       case 0x1202:
           MdcPrintTag(fi,tag,"Lookup Data - Green          : 0x%.4x\n",ui16);
           break;
       case 0x1203:
           MdcPrintTag(fi,tag,"Lookup Data - Blue           : 0x%.4x\n",ui16);
           break;
       case 0x2110:
           MdcPrintTag(fi,tag,"Lossy Image Compression      : %s\n",ps);
           break;
       case 0x4000:
           MdcPrintTag(fi,tag,"Comments                     : %s\n",ps);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   /* group 0x0032 */
   case 0x0032: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Request Procedure - Group 0032\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x1032:
           MdcPrintTag(fi,tag,"Requesting Physician         : %s\n",ps);
           break;
       case 0x1033:
           MdcPrintTag(fi,tag,"Requesting Service           : %s\n",ps);
           break;
       case 0x1060:
           MdcPrintTag(fi,tag,"Requested Procedure Description    : %s\n",ps);
           break;
       case 0x1064:
           MdcPrintTag(fi,tag,"Requested Procedure Code Sequence  : %s\n",ps);
           break;
       case 0x1070:
           MdcPrintTag(fi,tag,"Requested Contrast Agent     : %s\n",ps);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   /* group 0x003A */
   case 0x003A: switch(tag->element) {
       case 0x001A:
           MdcPrintTag(fi,tag,"Sampling Frequency           : %s\n",ps);
           if (fi->mod != NULL) {
             fi->mod->mr_info.sampling_freq = atof(ps);
           }
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   /* group 0x0040 */
   case 0x0040: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Text - Group 0040\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0002:
           MdcPrintTag(fi,tag,"Scheduled Procedure Step Start Date  : %s\n",ps);
           break;
       case 0x0003:
           MdcPrintTag(fi,tag,"Scheduled Procedure Step Start Time  : %s\n",ps);
           break;
       case 0x0006:
           MdcPrintTag(fi,tag,"Performing Physician                 : %s\n",ps);
           break;
       case 0x0007:
           MdcPrintTag(fi,tag,"Scheduled Procedure Step Description : %s\n",ps);
           break;
       case 0x0009:
           MdcPrintTag(fi,tag,"Scheduled Procedure Step ID          : %s\n",ps);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Arbitrary                    : %s\n",ps);
           break;
       case 0x0244:
           MdcPrintTag(fi,tag,"Performed Procedure Step Start Date  : %s\n",ps);
           break;
       case 0x0245:
           MdcPrintTag(fi,tag,"Performed Procedure Step Start Time  : %s\n",ps);
           break;
       case 0x0253:
           MdcPrintTag(fi,tag,"Performed Procedure Step ID          : %s\n",ps);
           break;
       case 0x0254:
           MdcPrintTag(fi,tag,"Performed Procedure Step Description : %s\n",ps);
           break;
       case 0x1001:
           MdcPrintTag(fi,tag,"Requested Procedure ID               : %s\n",ps);
           break;
       case 0x4000:
           MdcPrintTag(fi,tag,"Comments                             : %s\n",ps);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element                      : %s\n",ps);
     }
     break;
   /* group 0x0041 */
   case 0x0041: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Folder Information - Group 0041\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0007:
           MdcPrintTag(fi,tag,"Scheduled Procedure Step Description : %s\n",ps);
           break;
       case 0x0009:
           MdcPrintTag(fi,tag,"Scheduled Procedure ID       : %s\n",ps);
           break;
       case 0x0080:
           MdcPrintTag(fi,tag,"Owner ID                     : %s\n",ps);
           break;
       case 0x8000:
           MdcPrintTag(fi,tag,"Comments                     : %s\n",ps);
           break;
       case 0x8010:
           MdcPrintTag(fi,tag,"Folder Type                  : 0x%.4x\n",ui16);
           if (MDC_INFO)
           switch (ui16) {
                 case 0x0001: MdcPrntScrn(" (= data exchange)\n"); break;
                 case 0x0002: MdcPrntScrn(" (= teaching case)\n"); break;
                 case 0x0003: MdcPrntScrn(" (= hard copy)\n"); break;
                 case 0x0004: MdcPrntScrn(" (= history)\n"); break;
                 case 0x0005: MdcPrntScrn(" (= case)\n"); break;
                 case 0x0006: MdcPrntScrn(" (= patient)\n"); break;
                 case 0x0007: MdcPrntScrn(" (= research)\n"); break;
                     default: MdcPrntScrn(" (= unknown)\n");
           }
           break;
       case 0x8011:
           MdcPrintTag(fi,tag,"Parent Folder Data Set ID    : %s\n",ps);
           break;
       case 0x8020:
           MdcPrintTag(fi,tag,"Folder Name                  : %s\n",ps);
           break;
       case 0x8030:
           MdcPrintTag(fi,tag,"Creation Date                : %s\n",ps);
           break;
       case 0x8032:
           MdcPrintTag(fi,tag,"Creation Time                : %s\n",ps);
           break;
       case 0x8034:
           MdcPrintTag(fi,tag,"Modified Date                : %s\n",ps);
           break;
       case 0x8036:
           MdcPrintTag(fi,tag,"Modified Time                : %s\n",ps);
           break;
       case 0x8040:
           MdcPrintTag(fi,tag,"Owner Name                   : %s\n",ps);
           break;
       case 0x8050:
           MdcPrintTag(fi,tag,"Folder Status                : %s\n",ps);
           break;
       case 0x8060:
           MdcPrintTag(fi,tag,"Number of Images             : %u\n",ui32);
           break;
       case 0x8062:
           MdcPrintTag(fi,tag,"Number of Other              : %u\n",ui32);
           break;
       case 0x80a0:
           if (MDC_INFO)
             MdcPrntScrn("\nFolder Elements - External References\n");
           MdcPrintTag(fi,tag,"Folder Element DSID          : %s\n",ps);
           break;
       case 0x80a1:
           MdcPrintTag(fi,tag,"Folder Element Data Set Type : 0x%.4x\n",ui16);
           break;
       case 0x80a2:
           MdcPrintTag(fi,tag,"Folder Element File Location : %s\n",ps);
           break;
       case 0x80a3:
           MdcPrintTag(fi,tag,"Folder Element Length        : %u\n",ui32);
           break;
       case 0x80b0:
           if (MDC_INFO)
             MdcPrntScrn("\nFolder Elements - Internal References\n");
           MdcPrintTag(fi,tag,"Folder Element DSID          : %s\n",ps);
           break;
       case 0x80b1:
           MdcPrintTag(fi,tag,"Folder Element Data Set Type : 0x%.4x\n",ui16);
           break;
       case 0x80b2:
           MdcPrintTag(fi,tag,"Offset to Data Set           : %u\n",ui32);
           break;
       case 0x80b3:
           MdcPrintTag(fi,tag,"Offset to Image              : %u\n",ui32);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   /* group 0x0043 */
   case 0x0043: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn(" CT Params - Group 0043\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Private Creator ID           : %s\n",ps);
           break;
       case 0x1064:
           MdcPrintTag(fi,tag,"ReconFilter                  : %s\n",ps);
           break;
       case 0x1010:
           MdcPrintTag(fi,tag,"WindowValue                  : %s\n",ps);
           break;
       case 0x1012:
           MdcPrintTag(fi,tag,"X-RayChain                   : %s\n",ps);
           break;
       case 0x1016:
           MdcPrintTag(fi,tag,"NumberOfOverranges           : %s\n",ps);
           break;
       case 0x101E:
           MdcPrintTag(fi,tag,"DeltaStartTime               : %s\n",ps);
           break;
       case 0x101F:
           MdcPrintTag(fi,tag,"MaxOverrangesInAView         : %s\n",ps);
           break;
       case 0x1021:
           MdcPrintTag(fi,tag,"CorrectedAfterGlowTerms      : %s\n",ps);
           break;
       case 0x1025:
           MdcPrintTag(fi,tag,"ReferenceChannels            : %s\n",ps);
           break;
       case 0x1026:
           MdcPrintTag(fi,tag,"NoViewsRefChansBlocked       : %s\n",ps);
           break;
       case 0x1027:
           MdcPrintTag(fi,tag,"ScanPitchRatio               : %s\n",ps);
           break;
       case 0x1028:
           MdcPrintTag(fi,tag,"UniqueImageIden              : %s\n",ps);
           break;
       case 0x102B:
           MdcPrintTag(fi,tag,"PrivateScanOptions           : %s\n",ps);
           break;
       case 0x1031:
           MdcPrintTag(fi,tag,"RACordOfTargetReconCenter    : %s\n",ps);
           break;
       case 0x1040:
           MdcPrintTag(fi,tag,"TriggerOnPosition            : %s\n",ps);
           break;
       case 0x1041:
           MdcPrintTag(fi,tag,"DegreeOfRotation             : %s\n",ps);
           break;
       case 0x1042:
           MdcPrintTag(fi,tag,"DASTriggerSource             : %s\n",ps);
           break;
       case 0x1043:
           MdcPrintTag(fi,tag,"DASFpaGain                   : %s\n",ps);
           break;
       case 0x1044:
           MdcPrintTag(fi,tag,"DASOutputSource              : %s\n",ps);
           break;
       case 0x1045:
           MdcPrintTag(fi,tag,"DASAdInput                   : %s\n",ps);
           break;
       case 0x1046:
           MdcPrintTag(fi,tag,"DASCalMode                   : %s\n",ps);
           break;
       case 0x104D:
           MdcPrintTag(fi,tag,"StartScanToX-RayOnDelay      : %s\n",ps);
           break;
       case 0x104E:
           MdcPrintTag(fi,tag,"DurationOfX-RayOn            : %s\n",ps);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   /* group 0x0045 */
   case 0x0045: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn(" HELIOS Cardiac - Group 0045\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Private Creator              : %s\n",ps);
           break;
       case 0x1001:
           MdcPrintTag(fi,tag,"NumberOfMacroRowsInDetector  : %s\n",ps);
           break;
       case 0x1002:
           MdcPrintTag(fi,tag,"MacroWidthAtISOCenter        : %s\n",ps);
           break;
       case 0x1003:
           MdcPrintTag(fi,tag,"DASType                      : %s\n",ps);
           break;
       case 0x1004:
           MdcPrintTag(fi,tag,"DASGain                      : %s\n",ps);
           break;
       case 0x1005:
           MdcPrintTag(fi,tag,"DASTemprature                : %s\n",ps);
           break;
       case 0x1006:
           MdcPrintTag(fi,tag,"TableDirection               : %s\n",ps);
           break;
       case 0x1007:
           MdcPrintTag(fi,tag,"ZSmoothingFactor             : %s\n",ps);
           break;
       case 0x1008:
           MdcPrintTag(fi,tag,"ViewWeightingMode            : %s\n",ps);
           break;
       case 0x1009:
           MdcPrintTag(fi,tag,"SigmaRowNumber               : %s\n",ps);
           break;
       case 0x100A:
           MdcPrintTag(fi,tag,"MinimumDASValue              : %s\n",ps);
           break;
       case 0x100B:
           MdcPrintTag(fi,tag,"MaximumOffsetValue           : %s\n",ps);
           break;
       case 0x100C:
           MdcPrintTag(fi,tag,"NumberOfViewsShifted         : %s\n",ps);
           break;
       case 0x100D:
           MdcPrintTag(fi,tag,"ZTrackingFlag                : %s\n",ps);
           break;
       case 0x100E:
           MdcPrintTag(fi,tag,"MeanZError                   : %s\n",ps);
           break;
       case 0x100F:
           MdcPrintTag(fi,tag,"ZTrackingError               : %s\n",ps);
           break;
       case 0x1010:
           MdcPrintTag(fi,tag,"StartView2A                  : %s\n",ps);
           break;
       case 0x1011:
           MdcPrintTag(fi,tag,"NumberOfViews2A              : %s\n",ps);
           break;
       case 0x1012:
           MdcPrintTag(fi,tag,"StartView1A                  : %s\n",ps);
           break;
       case 0x1013:
           MdcPrintTag(fi,tag,"SigmaMode                    : %s\n",ps);
           break;
       case 0x1014:
           MdcPrintTag(fi,tag,"NumberOfViews1A              : %s\n",ps);
           break;
       case 0x1015:
           MdcPrintTag(fi,tag,"StartView2B                  : %s\n",ps);
           break;
       case 0x1016:
           MdcPrintTag(fi,tag,"NumberViews2B                : %s\n",ps);
           break;
       case 0x1017:
           MdcPrintTag(fi,tag,"StartView1B                  : %s\n",ps);
           break;
       case 0x1018:
           MdcPrintTag(fi,tag,"NumberOfViews1B              : %s\n",ps);
           break;
       case 0x1021:
           MdcPrintTag(fi,tag,"IterboneFlag                 : %s\n",ps);
           break;
       case 0x1022:
           MdcPrintTag(fi,tag,"PerisstalticFlag             : %s\n",ps);
           break;
       case 0x1030:
           MdcPrintTag(fi,tag,"Cardiacreconalgorithm        : %s\n",ps);
           break;
       case 0x1031:
           MdcPrintTag(fi,tag,"Avgheartrateforimage         : %s\n",ps);
           break;
       case 0x1032:
           MdcPrintTag(fi,tag,"Temporalresolution           : %s\n",ps);
           break;
       case 0x1033:
           MdcPrintTag(fi,tag,"Pctrpeakdelay                : %s\n",ps);
           break;
       case 0x1036:
           MdcPrintTag(fi,tag,"Ekgfullmastartphase          : %s\n",ps);
           break;
       case 0x1037:
           MdcPrintTag(fi,tag,"Ekgfullmaendphase            : %s\n",ps);
           break;
       case 0x1038:
           MdcPrintTag(fi,tag,"Kgmodulationmaxma            : %s\n",ps);
           break;
       case 0x1039:
           MdcPrintTag(fi,tag,"Ekgmodulationminma           : %s\n",ps);
           break;
       case 0x103B:
           MdcPrintTag(fi,tag,"Noisereductionimagefilterdesc: %s\n",ps);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   /* group 0x0049 */
   case 0x0049: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn(" CT Cardiac - Group 0049\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                       : %u\n",ui32);
           break;
       case 0x1001:
           MdcPrintTag(fi,tag,"CTCardiacSequence                  : %s\n",ps);
           break;
       case 0x1002:
           MdcPrintTag(fi,tag,"Heartrateatconfirm                 : %s\n",ps);
           break;
       case 0x1003:
           MdcPrintTag(fi,tag,"Avgheartratepriortoconfirm         : %s\n",ps);
           break;
       case 0x1004:
           MdcPrintTag(fi,tag,"Minheartratepriortoconfirm         : %s\n",ps);
           break;
       case 0x1005:
           MdcPrintTag(fi,tag,"Maxheartratepriortoconfirm         : %s\n",ps);
           break;
       case 0x1006:
           MdcPrintTag(fi,tag,"Stddevheartratepriortoconfirm      : %s\n",ps);
           break;
       case 0x1007:
           MdcPrintTag(fi,tag,"Numheartratesamplespriortoconfirm  : %s\n",ps);
           break;
       case 0x1008:
           MdcPrintTag(fi,tag,"Autoheartratedetectpredict         : %s\n",ps);
           break;
       case 0x1009:
           MdcPrintTag(fi,tag,"Systemoptimizedheartrate           : %s\n",ps);
           break;
       case 0x100A:
           MdcPrintTag(fi,tag,"Ekgmonitortype                     : %s\n",ps);
           break;
       case 0x100B:
           MdcPrintTag(fi,tag,"Numreconsectors                    : %s\n",ps);
           break;
       case 0x100C:
           MdcPrintTag(fi,tag,"Rpeaktimestamps                    : %s\n",ps);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element                    : %s\n",ps);
     }
     break;
   /* DICOM specific tags to interpret */
   /* group 0x0054 */
   case 0x0054: switch (tag->element) {

       case 0x0010: /* energy window vector */
           MdcDicomCheckVect(dicom,tag,MDC_VECT_ENERGYWINDOW);
           break;
       case 0x0011: /* number of energy windows */
           MdcPrintTag(fi,tag,"Number of Energy Windows     : %hu\n",ui16);
           fi->dim[7] = MdcDicomNrOfVect(dicom,ui16,MDC_VECT_ENERGYWINDOW);
           break;
       case 0x0020: /* detector vector */
           MdcDicomCheckVect(dicom,tag,MDC_VECT_DETECTOR);
           break;
       case 0x0021: /* number of detectors     */
           MdcPrintTag(fi,tag,"Number of Detectors          : %hu\n",ui16);
           fi->dim[6] = MdcDicomNrOfVect(dicom,ui16,MDC_VECT_DETECTOR);
           break;
       case 0x0030: /* phase vectory */
           MdcDicomCheckVect(dicom,tag,MDC_VECT_PHASE);
           break;
       case 0x0031: /* phases (dyn) */
           MdcPrintTag(fi,tag,"Number of Phases             : %hu\n",ui16);

           MdcGetStructDD(fi,MdcDicomNrOfVect(dicom,ui16,MDC_VECT_PHASE));
           if (fi->planar != MDC_YES) {
             fi->dim[4] = MdcDicomNrOfVect(dicom,ui16,MDC_VECT_PHASE);
           }
           break;
       case 0x0033: /* number of frames in phase */
           MdcPrintTag(fi,tag,"Number of Frames in Phase    : %hu\n",ui16);
           if (FILL_DYNAMIC_DATA == MDC_YES) {
             fi->dyndata[dicom->dynnr].nr_of_slices = (Uint32)ui16;
           }else{
             fi->dim[3] = (Uint32)ui16;
           }
           break;
       case 0x0036:
           MdcPrintTag(fi,tag,"Phase Delay                  : %s\n",ps);
           if (FILL_DYNAMIC_DATA == MDC_YES) {
             fi->dyndata[dicom->dynnr].time_frame_delay = (float)atof(ps);
           }
           break;
       case 0x0038:
           MdcPrintTag(fi,tag,"Pause Between Frames         : %s\n",ps);
           if (FILL_DYNAMIC_DATA == MDC_YES) {
             fi->dyndata[dicom->dynnr].delay_slices = (float)atof(ps);
           }
           break;
       case 0x0050: /* rotation vector */
           MdcDicomCheckVect(dicom,tag,MDC_VECT_ROTATION);
           break;
       case 0x0051: /* number of rotations */
           if (fi->reconstructed == MDC_NO) {
             if (!MdcGetStructAD(fi,(Uint32)ui16)) fi->acqnr = 0;
           }
           break;
       case 0x0052: /* rotation information sequence */
           dicom->acqnr += 1;
           break;
       case 0x0053:
           MdcPrintTag(fi,tag,"Number Frames in Rotation    : %hu\n",ui16);
           dicom->nrframes = (float)ui16;
           break;
       case 0x0060: /* R-R interval vector */
           MdcDicomCheckVect(dicom,tag,MDC_VECT_RRINTERVAL);
           break;
       case 0x0061: /* R-R intervals */
           MdcPrintTag(fi,tag,"Number of R-R intervals      : %hu\n",ui16);
           fi->dim[5] = MdcDicomNrOfVect(dicom,ui16,MDC_VECT_RRINTERVAL);
           break;
       case 0x0070: /* time slot vector */
           MdcDicomCheckVect(dicom,tag,MDC_VECT_TIMESLOT);
           break;
       case 0x0071: /* number of time slots (gated only stuff) */
           MdcPrintTag(fi,tag,"Number of Time Slots         : %hu\n",ui16);
           if (fi->acquisition_type == MDC_ACQUISITION_GATED) {
             /* MARK: for gated, time slot is the last dimension !! */
             fi->dim[3] = MdcDicomNrOfVect(dicom,ui16,MDC_VECT_TIMESLOT);
           }else{
             fi->dim[4] = MdcDicomNrOfVect(dicom,ui16,MDC_VECT_TIMESLOT);
           }
           break;
       case 0x0073: /* timeslottime */
           MdcPrintTag(fi,tag,"Time Slot Time               : %s\n",ps);
           dicom->timeslottime = (float)atof(ps);
           break;
       case 0x0080: /* slice vector */
           MdcDicomCheckVect(dicom,tag,MDC_VECT_SLICE);
           break;
       case 0x0081: /* number of slices */
           MdcPrintTag(fi,tag,"Number of Slices             : %hu\n",ui16);
           fi->dim[3] = MdcDicomNrOfVect(dicom,ui16,MDC_VECT_SLICE);
           break;
       case 0x0090: /* angular view vector */
           MdcDicomCheckVect(dicom,tag,MDC_VECT_ANGULARVIEW);
           fi->dim[3] = dicom->VectNR[MDC_VECT_ANGULARVIEW];
           /* no number of angular views ? 0x0091*/
           break;
       case 0x0100: /* time slice vector */
           MdcDicomCheckVect(dicom,tag,MDC_VECT_TIMESLICE);
           break;
       case 0x0101:
           MdcPrintTag(fi,tag,"Number of Time Slices        : %hu\n",ui16);
           if (dicom->modality == M_PT) {
             fi->dim[4] = MdcDicomNrOfVect(dicom,ui16,MDC_VECT_TIMESLICE);
           }else{
             fi->dim[3] = MdcDicomNrOfVect(dicom,ui16,MDC_VECT_TIMESLICE);
           }
           break;
       case 0x0200:
           MdcPrintTag(fi,tag,"Start Angle                  : %s\n",ps);
           if (MdcDicomDoAcqData(fi,dicom) == MDC_YES) {
             float angle;

             tmp = dicom->acqnr - 1; sscanf(ps,"%f",&angle);
             fi->acqdata[tmp].angle_start = MdcRotateAngle(angle, 180.);
           }
           break;
       case 0x0202:
           MdcPrintTag(fi,tag,"Type of Detector Motion      : %s\n",ps);
           if (MdcDicomDoAcqData(fi,dicom) == MDC_YES) {
             if (strcasecmp(ps,"STEP AND SHOOT") == 0) {
               dicom->motion = MDC_MOTION_STEP;
             }else if (strcasecmp(ps,"CONTINUOUS") == 0) {
               dicom->motion = MDC_MOTION_CONT;
             }else if (strcasecmp(ps,"ACQ DURING STEP") == 0) {
               dicom->motion = MDC_MOTION_DRNG;
             }

             for (tmp=0; tmp < fi->acqnr; tmp ++) {
                fi->acqdata[tmp].detector_motion = dicom->motion;
             }

           }
           break;
       case 0x1000:
           MdcPrintTag(fi,tag,"Series Type                  : %s\n",ps);
           if (MdcGetStrVM(mdcbufr,ps,1) == MDC_YES) {
             MdcKillSpaces(mdcbufr);
             if (strcasecmp(mdcbufr,"STATIC") == 0)          {
               fi->acquisition_type = MDC_ACQUISITION_TOMO;
             }else if (strcasecmp(mdcbufr,"WHOLE_BODY") == 0) {
               fi->acquisition_type = MDC_ACQUISITION_TOMO;
               fi->reconstructed = MDC_NO;
             }else if (strcasecmp(mdcbufr,"DYNAMIC") == 0)    {
               fi->acquisition_type = MDC_ACQUISITION_DYNAMIC;
               fi->reconstructed = MDC_NO;
             }else if (strcasecmp(mdcbufr,"GATED") == 0)      {
               fi->acquisition_type = MDC_ACQUISITION_GSPECT;
             }else{
               fi->acquisition_type = MDC_ACQUISITION_TOMO;
             }
           }
           if (MdcGetStrVM(mdcbufr,ps,2) == MDC_YES) {
             MdcKillSpaces(mdcbufr);
             if (strcasecmp(mdcbufr,"IMAGE") == 0) {
               fi->reconstructed = MDC_YES;
             }else{
               fi->reconstructed = MDC_NO;
             }
           }
           break;
       case 0x1300:
           MdcPrintTag(fi,tag,"Frame Reference Time         : %s\n",ps);
           flt = (float)atof(ps);
           dicom->framestart = flt;
           break;
     }
     break;
   /* group 0x7001 */
   case 0x7001: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Shadow dummy - Group 7001\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Shadow Owner Code            : %s\n",ps);
           break;
       case 0x1010:
           MdcPrintTag(fi,tag,"Dummy Data Zero              : %s\n",ps);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   /* group 0x7003 */
   case 0x7003: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Shadow Header - Group 7003\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Shadow Owner Code            : %s\n",ps);
           break;
       case 0x1010:
           MdcPrintTag(fi,tag,"Original NUMARIS2 Header     : %s\n",ps);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
           break;
     }
     break;
   /* group 0x7005 */
   case 0x7005: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Shadow Dummy - Group 7005\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Shadow Owner Code            : %s\n",ps);
           break;
       case 0x1010:
           MdcPrintTag(fi,tag,"Dummy Data Zero              : %s\n",ps);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   /* group 0x7fe0 */
   case 0x7fe0: switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Pixel Information - Group 7FE0\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Image Data                   : %u\n",ui32);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
     }
     break;
   default:
     if ( (tag->group >= 0x6000) && (tag->group <= 0x60e1) ) {
      switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Overlay - Group %.4x\n",tag->group);
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Group Length                 : %u\n",ui32);
           break;
       case 0x0010:
           MdcPrintTag(fi,tag,"Rows                         : %hu\n",ui16);
           break;
       case 0x0011:
           MdcPrintTag(fi,tag,"Columns                      : %hu\n",ui16);
           break;
       case 0x0040:
           MdcPrintTag(fi,tag,"ROI                          : %s\n",ps);
           break;
       case 0x0050:
           MdcPrintTag(fi,tag,"Origin                       : %s\n",ps);
           break;
       case 0x0060:
           MdcPrintTag(fi,tag,"Compression Code             : %s\n",ps);
           break;
       case 0x0100:
           MdcPrintTag(fi,tag,"Bits Allocated               : %hu\n",ui16);
           break;
       case 0x0102:
           MdcPrintTag(fi,tag,"Bits Position                : %hu\n",ui16);
           break;
       case 0x0110:
           MdcPrintTag(fi,tag,"Overlay Format               : %s\n",ps);
           break;
       case 0x0200:
           MdcPrintTag(fi,tag,"Overlay Location             : 0x%.4x\n",ui16);
           break;
       case 0x1100:
           MdcPrintTag(fi,tag,"Overlay Descriptor Gray      : 0x%.4x\n",ui16);
           break;
       case 0x1101:
           MdcPrintTag(fi,tag,"Overlay Descriptor Red       : 0x%.4x\n",ui16);
           break;
       case 0x1102:
           MdcPrintTag(fi,tag,"Overlay Descriptor Green     : 0x%.4x\n",ui16);
           break;
       case 0x1103:
           MdcPrintTag(fi,tag,"Overlay Descriptor Blue      : 0x%.4x\n",ui16);
           break;
       case 0x1200:
           MdcPrintTag(fi,tag,"Overlays Gray                : 0x%.4x\n",ui16);
           break;
       case 0x1201:
           MdcPrintTag(fi,tag,"Overlays Red                 : 0x%.4x\n",ui16);
           break;
       case 0x1202:
           MdcPrintTag(fi,tag,"Overlays Green               : 0x%.4x\n",ui16);
           break;
       case 0x1203:
           MdcPrintTag(fi,tag,"Overlays Blue                : 0x%.4x\n",ui16);
           break;
       case 0x1301:
           MdcPrintTag(fi,tag,"ROI Area                     : %s\n",ps);
           break;
       case 0x1302:
           MdcPrintTag(fi,tag,"ROI Mean                     : %s\n",ps);
           break;
       case 0x1303:
           MdcPrintTag(fi,tag,"ROI Standard Deviation       : %s\n",ps);
           break;
       case 0x3000:
           MdcPrintTag(fi,tag,"Overlay Data                 : 0x%.4x\n",ui16);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : %s\n",ps);
      }
     }else{
      switch(tag->element) {
       case 0x0000:
           if (MDC_INFO) {
             MdcPrntScrn("\n");
             MdcPrintLine('-',MDC_FULL_LENGTH);
             MdcPrntScrn("Unknown Group - %.4x\n",tag->group);
             MdcPrintLine('-',MDC_FULL_LENGTH);
           }
           MdcPrintTag(fi,tag,"Unknown Group Length         : %d\n",i32);
           break;
       default:
           MdcPrintTag(fi,tag,"Unknown Element              : <not printed>\n");
      }
     }
  }

  return NULL;

}


/* 1 on success  and 0 on error */
int MdcPutTag(FILE *fp,Uint16 group,Uint16 elem,Uint32 length,Uint8 *data)
{
  MDC_ACR_TAG tag;
  Int8 MAKE_EVEN=0;

  if (length%2) MAKE_EVEN = 1;

  tag.group   = group;
  tag.element = elem;
  tag.length  = length + MAKE_EVEN;
  tag.data    = data;

  MdcSwapTag(&tag);

  fwrite((Uint8 *)&tag,1,MDC_ACR_TAG_SIZE,fp);
  if (length > 0) fwrite(tag.data,1,length,fp);
  if (MAKE_EVEN)  fputc('\0',fp);

  if (ferror(fp)) return(MDC_NO);

  return MDC_YES;

}

void MdcPutGroupLength(FILE *fp,Uint16 group, off_t gbegin)
{
  off_t gend, glengtho;
  Uint32 glength;

  /* position */
  gend = ftello(fp);
  fseeko(fp,gbegin,SEEK_SET);

  /* get length and write */
  glengtho = gend - gbegin - (off_t)MDC_SIZE_E0000;

  if (glengtho > (off_t)UINT32_MAX) MdcPrntWarn("ACR  Group length larger than Uint32!");

  glength = (Uint32)glengtho; MdcSWAP(glength);

  MdcPutTag(fp,group,0x0000,4,(Uint8 *)&glength);

  /* get back to end of file */
  fseeko(fp,(off_t)0,SEEK_END);

}

/* 1 on success and 0 on error */
int MdcPutGroup(FILEINFO * fi, Uint16 group, Uint32 img)
{
  IMG_DATA *id = &fi->image[img];
  FILE *fp = fi->ofp;
  Uint16 i16, bits_allocated, bits_stored;
  Uint32 i32;
  Int16 type;
  Uint8 *new_buf=NULL;
  off_t gbegin=(off_t)0;
  char *pchar;

  if (MDC_QUANTIFY || MDC_CALIBRATE) {
    type = BIT16_S;   /* printed as float, still an integer,      */
                      /* for BIT32_S this could be like 2.147e+09 */
                      /* and that's a bit too confusing           */
  }else{
    if ((id->type == FLT32) || (id->type == FLT64)) {
      /* no floats in ACR/NEMA */
      type = BIT16_S; /* same reason as above                      */
    }else{
      type = id->type;
    }
  }

  /* Ola! there was a special integer request */
  if (MDC_FORCE_INT != MDC_NO) {
    switch (MDC_FORCE_INT) {
     case BIT8_U : type = BIT8_U;  break;
     case BIT16_S: type = BIT16_S; break;
     default     : type = BIT16_S;
    }
  }

  switch(group) {

    case 0x0008:
        gbegin = ftello(fp);
        i32 = 0; /* write later */
        MdcPutTag(fp,0x0008,0x0000,4,(Uint8 *)&i32);

        FP_G0008_E0001 = ftello(fp);
        i32 = 0; /* write later */
        MdcPutTag(fp,0x0008,0x0001,4,(Uint8 *)&i32);

        strcpy(mdcbufr,"ACR-NEMA 2.0");
        MdcPutTag(fp,0x0008,0x0010,strlen(mdcbufr),(Uint8 *)mdcbufr);

        sprintf(mdcbufr,"%04d.%02d.%02d",fi->study_date_year
                                        ,fi->study_date_month
                                        ,fi->study_date_day);
        MdcPutTag(fp,0x0008,0x0020,strlen(mdcbufr),(Uint8 *)mdcbufr);

        sprintf(mdcbufr,"%02d.%02d.%02d.0000",fi->study_time_hour
                                             ,fi->study_time_minute
                                             ,fi->study_time_second);
        MdcPutTag(fp,0x0008,0x0030,strlen(mdcbufr),(Uint8 *)mdcbufr);

        i16 = 0; MdcSWAP(i16);
        MdcPutTag(fp,0x0008,0x0040,2,(Uint8 *)&i16);

        pchar = MdcGetStrModality(fi->modality); /* already in mdcbufr */
        MdcPutTag(fp,0x0008,0x0060,2,(Uint8 *)pchar);

        strcpy(mdcbufr,fi->manufacturer);
        MdcPutTag(fp,0x0008,0x0070,strlen(mdcbufr),(Uint8 *)mdcbufr);

        strcpy(mdcbufr,fi->institution);
        MdcPutTag(fp,0x0008,0x0080,strlen(mdcbufr),(Uint8 *)mdcbufr);

        MdcStringCopy(mdcbufr,fi->study_descr,strlen(fi->study_descr));
        MdcPutTag(fp,0x0008,0x1030,strlen(mdcbufr),(Uint8 *)mdcbufr);

        MdcStringCopy(mdcbufr,fi->series_descr,strlen(fi->series_descr));
        MdcPutTag(fp,0x0008,0x103E,strlen(mdcbufr),(Uint8 *)mdcbufr);

        MdcStringCopy(mdcbufr,fi->operator_name,strlen(fi->operator_name));
        MdcPutTag(fp,0x0008,0x1070,strlen(mdcbufr),(Uint8 *)mdcbufr);

        strcpy(mdcbufr,MDC_LIBVERS);
        MdcPutTag(fp,0x0008,0x2111,strlen(mdcbufr),(Uint8 *)mdcbufr);

      break;

    case 0x0010:
        gbegin = ftello(fp);
        i32 = 0; /* write later */
        MdcPutTag(fp,0x0010,0x0000,4,(Uint8 *)&i32);

        MdcStringCopy(mdcbufr,fi->patient_name,strlen(fi->patient_name));
        MdcPutTag(fp,0x0010,0x0010,strlen(mdcbufr),(Uint8 *)mdcbufr);

        MdcStringCopy(mdcbufr,fi->patient_id,strlen(fi->patient_id));
        MdcPutTag(fp,0x0010,0x0020,strlen(mdcbufr),(Uint8 *)mdcbufr);

        MdcStringCopy(mdcbufr,fi->patient_sex,strlen(fi->patient_sex));
        MdcPutTag(fp,0x0010,0x0040,strlen(mdcbufr),(Uint8 *)mdcbufr);

        sprintf(mdcbufr,"%.2f",fi->patient_height);
        MdcPutTag(fp,0x0010,0x1020,strlen(mdcbufr),(Uint8 *)mdcbufr);

        sprintf(mdcbufr,"%.2f",fi->patient_weight);
        MdcPutTag(fp,0x0010,0x1030,strlen(mdcbufr),(Uint8 *)mdcbufr);

     break;

    case 0x0018:

        gbegin = ftello(fp);
        i32 = 0; /* write later */
        MdcPutTag(fp,0x0018,0x0000,4,(Uint8 *)&i32);

        MdcStringCopy(mdcbufr,fi->radiopharma,strlen(fi->radiopharma));
        MdcPutTag(fp,0x0018,0x0030,strlen(mdcbufr),(Uint8 *)mdcbufr);

        MdcStringCopy(mdcbufr,fi->radiopharma,strlen(fi->radiopharma));
        MdcPutTag(fp,0x0018,0x0031,strlen(mdcbufr),(Uint8 *)mdcbufr);

        sprintf(mdcbufr,"%+e",id->slice_width);
        MdcPutTag(fp,0x0018,0x0050,strlen(mdcbufr),(Uint8 *)mdcbufr);

        sprintf(mdcbufr,"%+e",id->slice_spacing);
        MdcPutTag(fp,0x0018,0x0088,strlen(mdcbufr),(Uint8 *)mdcbufr);

        sprintf(mdcbufr,"%g",fi->injected_dose);
        MdcPutTag(fp,0x0018,0x1074,strlen(mdcbufr),(Uint8 *)mdcbufr);

        sprintf(mdcbufr,"%+e",fi->gantry_tilt);
        MdcPutTag(fp,0x0018,0x1120,strlen(mdcbufr),(Uint8 *)mdcbufr);

        MdcStringCopy(mdcbufr,fi->filter_type,strlen(fi->filter_type));
        MdcPutTag(fp,0x0018,0x1160,strlen(mdcbufr),(Uint8 *)mdcbufr);

        MdcStringCopy(mdcbufr,fi->pat_pos,strlen(fi->pat_pos));
        MdcPutTag(fp,0x0018,0x5100,strlen(mdcbufr),(Uint8 *)mdcbufr);

     break;

    case 0x0020:

        gbegin = ftello(fp);
        i32 = 0; /* write later */
        MdcPutTag(fp,0x0020,0x0000,4,(Uint8 *)&i32);

        MdcStringCopy(mdcbufr,fi->study_id,strlen(fi->study_id));
        MdcPutTag(fp,0x0020,0x0010,strlen(mdcbufr),(Uint8 *)mdcbufr);

        if (fi->nr_series >= 0) sprintf(mdcbufr,"%d",fi->nr_series);
        else strcpy(mdcbufr,"0");
        MdcPutTag(fp,0x0020,0x0011,strlen(mdcbufr),(Uint8 *)mdcbufr);

        if (fi->nr_acquisition >= 0) sprintf(mdcbufr,"%d",fi->nr_acquisition);
        else strcpy(mdcbufr,"0");
        MdcPutTag(fp,0x0020,0x0012,strlen(mdcbufr),(Uint8 *)mdcbufr);

        if (fi->nr_instance >= 0) sprintf(mdcbufr,"%d",fi->nr_instance);
        else sprintf(mdcbufr,"%u",img+1);
        MdcPutTag(fp,0x0020,0x0013,6,(Uint8 *)mdcbufr);

        MdcStringCopy(mdcbufr,fi->pat_orient,strlen(fi->pat_orient));
        MdcPutTag(fp,0x0020,0x0020,strlen(mdcbufr),(Uint8 *)mdcbufr);

        sprintf(mdcbufr,"%+e\\%+e\\%+e",id->image_pos_dev[0],
                                        id->image_pos_dev[1],
                                        id->image_pos_dev[2]);
        MdcPutTag(fp,0x0020,0x0030,strlen(mdcbufr),(Uint8 *)mdcbufr);

        sprintf(mdcbufr,"%+e\\%+e\\%+e",id->image_pos_pat[0],
                                        id->image_pos_pat[1],
                                        id->image_pos_pat[2]);
        MdcPutTag(fp,0x0020,0x0032,strlen(mdcbufr),(Uint8 *)mdcbufr);

        sprintf(mdcbufr,"%+e\\%+e\\%+e\\%+e\\%+e\\%+e",
                                         id->image_orient_dev[0],
                                         id->image_orient_dev[1],
                                         id->image_orient_dev[2],
                                         id->image_orient_dev[3],
                                         id->image_orient_dev[4],
                                         id->image_orient_dev[5]);
        MdcPutTag(fp,0x0020,0x0035,strlen(mdcbufr),(Uint8 *)mdcbufr);

        sprintf(mdcbufr,"%+e\\%+e\\%+e\\%+e\\%+e\\%+e",
                                         id->image_orient_pat[0],
                                         id->image_orient_pat[1],
                                         id->image_orient_pat[2],
                                         id->image_orient_pat[3],
                                         id->image_orient_pat[4],
                                         id->image_orient_pat[5]);
        MdcPutTag(fp,0x0020,0x0037,strlen(mdcbufr),(Uint8 *)mdcbufr);

     break;

    case 0x0028:

        gbegin = ftello(fp);
        i32 = 0; /* write later */
        MdcPutTag(fp,0x0028,0x0000,4,(Uint8 *)&i32);

        i16 = 1; MdcSWAP(i16);
        MdcPutTag(fp,0x0028,0x0002,2,(Uint8 *)&i16);

        i16 = 2; MdcSWAP(i16);
        MdcPutTag(fp,0x0028,0x0005,2,(Uint8 *)&i16);

        i16 = (Int16)id->height; MdcSWAP(i16);
        MdcPutTag(fp,0x0028,0x0010,2,(Uint8 *)&i16);

        i16 = (Int16)id->width;  MdcSWAP(i16);
        MdcPutTag(fp,0x0028,0x0011,2,(Uint8 *)&i16);

        sprintf(mdcbufr,"%+e\\%+e",id->pixel_xsize,id->pixel_ysize);
        MdcPutTag(fp,0x0028,0x0030,strlen(mdcbufr),(Uint8 *)mdcbufr);

        strcpy(mdcbufr,"NONE");
        MdcPutTag(fp,0x0028,0x0060,strlen(mdcbufr),(Uint8 *)mdcbufr);

        bits_allocated = (Uint16)MdcType2Bits(type);
        if (MDC_FORCE_INT == BIT16_S) {
          bits_stored = MDC_INT16_BITS_USED;
        }else{
          bits_stored = MdcType2Bits(type);
        }
        i16 = bits_allocated; MdcSWAP(i16);
        MdcPutTag(fp,0x0028,0x0100,2,(Uint8 *)&i16);
        i16 = bits_stored; MdcSWAP(i16);
        MdcPutTag(fp,0x0028,0x0101,2,(Uint8 *)&i16);
        i16 = bits_stored - 1; MdcSWAP(i16);
        MdcPutTag(fp,0x0028,0x0102,2,(Uint8 *)&i16);

        switch (type) {
          case  BIT8_U:
          case BIT16_U:
          case BIT32_U:
          case BIT64_U:  i16 = 0; break;

          case  BIT8_S:
          case BIT16_S:
          case BIT32_S:
          case BIT64_S:  i16 = 1; break;

          default: i16 = 0;
        }
        if (type == BIT16_S && MDC_INT16_BITS_USED < 16) i16 = 0; /* unsigned */
        MdcSWAP(i16);
        MdcPutTag(fp,0x0028,0x0103,2,(Uint8 *)&i16);

        i16 = 0x7fe0; MdcSWAP(i16);
        MdcPutTag(fp,0x0028,0x0200,2,(Uint8 *)&i16);

     break;
    case 0x7fe0:

        gbegin=ftello(fp);
        i32 = 0; /* write later */
        MdcPutTag(fp,0x7fe0,0x0000,4,(Uint8 *)&i32);

        /* imagesize */
        i32 = id->width * id->height * MdcType2Bytes(type);

        if (MDC_QUANTIFY || MDC_CALIBRATE || MDC_FORCE_INT) {
          switch (type) {
            case BIT8_U:  new_buf = MdcGetImgBIT8_U(fi,img);  break;
            case BIT16_S: new_buf = MdcGetImgBIT16_S(fi,img); break;
            default     : new_buf = MdcGetImgBIT16_S(fi,img);
          }
          if (new_buf == NULL) {
            MdcPrntWarn("ACR  Couldn't get normalized image");
            return(MDC_NO);
          }

          if (MDC_FILE_ENDIAN != MDC_HOST_ENDIAN)
            MdcMakeImgSwapped(new_buf,fi,img,id->width,id->height,type);

          MdcPutTag(fp,0x7fe0,0x0010,i32,new_buf);
          MdcFree(new_buf);

        }else{

          if ( (id->type == FLT32) || (id->type == FLT64) ) {
            /* ACR/NEMA doesn't accept float/double */
            new_buf = MdcGetImgBIT16_S(fi,img);
            if (new_buf == NULL) {
              MdcPrntWarn("ACR  Downscaling `float' failed");
              return MDC_NO;
            }
            if (MDC_FILE_ENDIAN != MDC_HOST_ENDIAN)
              MdcMakeImgSwapped(new_buf,fi,img,id->width,id->height,type);

            MdcPutTag(fp,0x7fe0,0x0010,i32,new_buf);
            MdcFree(new_buf);

          }else{
            /* ACR/NEMA accepts any integer */

            if (MDC_FILE_ENDIAN != MDC_HOST_ENDIAN) {
              new_buf = MdcGetImgSwapped(fi,img);
              if (new_buf == NULL) {
                MdcPrntWarn("ACR  Couldn't malloc swapped image");
                return MDC_NO;
              }
              MdcPutTag(fp,0x7fe0,0x0010,i32,new_buf);
              MdcFree(new_buf);
            }else{
              MdcPutTag(fp,0x7fe0,0x0010,i32,id->buf);
            }

          }

        }

  }

  MdcPutGroupLength(fp,group,gbegin);

  if (ferror(fp)) return MDC_NO;


  return MDC_YES;

}


const char *MdcWriteACR(FILEINFO *fi)
{
  Uint32 i, FSIZE;
  off_t FileBegin, FileEnd, FSIZEO;

  MDC_FILE_ENDIAN = MDC_WRITE_ENDIAN;

  if (XMDC_GUI == MDC_NO) {
    MdcDefaultName(fi,MDC_FRMT_ACR,fi->ofname,fi->ifname);
  }

  if (MDC_PROGRESS) MdcProgress(MDC_PROGRESS_BEGIN,0.,"Writing Acr/Nema:");

  if (MDC_VERBOSE) MdcPrntMesg("ACR  Writing <%s> ...",fi->ofname);

  /* check for colored files */
  if (fi->map == MDC_MAP_PRESENT)
    return("ACR  Colored files unsupported");

  if (MDC_FILE_STDOUT == MDC_YES) {
    fi->ofp = stdout;
  }else{
    if (MdcKeepFile(fi->ofname))
      return("ACR  File exists!!");
    if ( (fi->ofp=fopen(fi->ofname,"wb")) == NULL)
      return("ACR  Couldn't open file");
  }

  /* check supported things */
  if (MDC_QUANTIFY || MDC_CALIBRATE) {
    MdcPrntWarn("ACR  Normalization loses quantified values!");
  }
  for (i=0; i<fi->number; i++) {

     if (MDC_PROGRESS) MdcProgress(MDC_PROGRESS_INCR,1./(float)fi->number,NULL);

     FileBegin = ftello(fi->ofp);

     if (!MdcPutGroup(fi,0x0008,i))
       return("ACR  Bad write Identifying Info");
     if (!MdcPutGroup(fi,0x0010,i))
       return("ACR  Bad write Patient Info");
     if (!MdcPutGroup(fi,0x0018,i))
       return("ACR  Bad write Acquisition Info");
     if (!MdcPutGroup(fi,0x0020,i))
       return("ACR  Bad write Relationship Info");
     if (!MdcPutGroup(fi,0x0028,i))
       return("ACR  Bad write Image Presentation");
     if (!MdcPutGroup(fi,0x7fe0,i))
       return("ACR  Bad write Image Array");

     /* rewrite (0x0008,0x0001) tag */
     FileEnd = ftello(fi->ofp);
     FSIZEO = FileEnd - FileBegin - (off_t)MDC_SIZE_E0000 - (off_t)MDC_SIZE_E0001;

     if (FSIZEO > (off_t)UINT32_MAX) MdcPrntWarn("ACR  Group length 0x0008 larger than Uint32!");

     FSIZE = (Uint32) FSIZEO;

     MdcSWAP(FSIZE);
     fseeko(fi->ofp,FP_G0008_E0001,SEEK_SET);
     MdcPutTag(fi->ofp,0x0008,0x0001,4,(Uint8 *)&FSIZE);
     fseeko(fi->ofp,(off_t)0,SEEK_END);

  }

  MdcCloseFile(fi->ofp);

  return NULL;

}
