content: 
  
  
  import ij.*;
  import ij.io.FileInfo;
  import ij.io.ImageReader;
  import ij.io.OpenDialog;
  import ij.io.RandomAccessStream;
  import ij.io.TiffDecoder;
  import ij.process.*;
  
  import java.awt.image.ColorModel;
  import java.awt.image.IndexColorModel;
  import java.io.BufferedInputStream;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.util.ArrayList;
  import java.util.Properties;
  import java.util.zip.GZIPInputStream;
  import java.util.zip.ZipEntry;
  import java.util.zip.ZipInputStream;
  
  import ij.plugin.*;
  import ij.util.Tools;
  
  
  public class ZIP_Reader_Standalone extends ImagePlus implements PlugIn {
  
  	public void run(String arg) {
  		boolean display = false;
  		File test = new File(arg);
  		display = !test.exists();
  		OpenDialog od = new OpenDialog("Open zip file...", arg);
  		if(od!=null){
  			String file = od.getFileName();
  			if (file == null) return;
  			String directory = od.getDirectory();
  			directory = directory.replace('\\', '/'); // Windows safe   
  	        if (!directory.endsWith("/")) directory += "/";   
  			arg = directory + file;
  		}
  		
  		try {
  			ZipProjectionSource fileSource = new ZipProjectionSource();
  			
  			fileSource.initStream(arg);
  			ImagePlusDataSink sink = new ImagePlusDataSink();
  			ImageProcessor imp = fileSource.getNextProjection();
  			int i =0;
  			while (imp != null){
  				sink.process(imp, i);
  				i++;
  				imp = fileSource.getNextProjection();
  			}
  			sink.close();
  			setStack(sink.getResult().getStack());
  			setTitle(new File(arg).getName());
  			fileSource.close();	
  			if(display) show();
  	
  		} catch (IOException e) {
  			// TODO Auto-generated catch block
  			e.printStackTrace();
  		} catch (Exception e) {
  			// TODO Auto-generated catch block
  			e.printStackTrace();
  		}
  	}
  	
  	
  	private class ZipProjectionSource extends FileProjectionSource {
  
  		boolean DICOMMultiFrameMode = false;
  		ZipInputStream zis = null;
  		
  		@SuppressWarnings("unused")
  		public void initStream (String filename) throws IOException{
  			zis = new ZipInputStream(new FileInputStream(filename));
  			is = zis;
  			if (zis==null) {
  				throw new IOException("Could not read zip header");
  			}
  			ZipEntry entry = zis.getNextEntry();
  			if (entry==null) throw new IOException("Zip was empty");
  			String name = entry.getName();
  			if (name.endsWith(".tif")) {
  				TiffDecoder td = new TiffDecoder(zis, name);
  				if (IJ.debugMode) td.enableDebugging();
  				FileInfo [] info = td.getTiffInfo();
  				fi = info[0];
  			} else if (name.endsWith(".ima")) {
  				DicomProjectionSource dicomSource = new DicomProjectionSource();
  				dicomSource.initStream(zis);
  				fi = dicomSource.fi;
  			} else if (name.endsWith(".dcm")) {
  				DICOMMultiFrameMode = true;
  				DicomProjectionSource dicomSource = new DicomProjectionSource();
  				dicomSource.initStream(zis);
  				fi = dicomSource.fi;
  			} else {
  				zis.close();
  				throw new IOException("No matching fileformat found in zip file");
  			}
  			File f = new File(filename);
  			fi.fileFormat = FileInfo.ZIP_ARCHIVE;
  			fi.fileName = f.getName();
  			fi.directory = f.getParent()+File.separator;
  
  			if (fi!=null && fi.width>0 && fi.height>0 && fi.offset>0) {
  				init();
  			} else {
  				throw new IOException("Format does not match");
  			}
  		}	
  
  		@Override
  		public ImageProcessor getNextProjection(){
  			if (!DICOMMultiFrameMode){
  				return super.getNextProjection();
  			} else {
  				try {
  					ZipEntry entry = zis.getNextEntry();
  					if (entry == null){
  						return null;
  					}
  					DicomProjectionSource dicomSource = new DicomProjectionSource();
  					dicomSource.initStream(zis);
  					fi = dicomSource.fi;
  					ImageProcessor ip = dicomSource.getNextProjection();
  					currentIndex++;
  					if (showProgress){
  						IJ.showProgress((0.0 + currentIndex) / fi.nImages);
  					}
  					return ip;
  				} catch (IOException e1) {
  					e1.printStackTrace();
  					throw new RuntimeException("Error while reading projection " + this.currentIndex);
  				}
  			}
  		}
  		
  	}
  	
  	public class DicomProjectionSource extends FileProjectionSource {
  
  		public void initStream (String filename) throws IOException{
  			File file = new File(filename);
  			String fileName = file.getName();
  			if (fileName==null)
  				return;
  			BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file));
  			initStream(inputStream);
  		}
  		
  		public void initStream(InputStream inputStream) throws IOException{
  			DicomDecoder dd = new DicomDecoder(inputStream);
  			fi = dd.getFileInfo();
  			if (fi!=null && fi.width>0 && fi.height>0 && fi.offset>0) {
  				init();
  			} else {
  				throw new IOException("Format does not match");
  			}
  		}
  		
  	}
  
  	public class ImagePlusDataSink {
  
  		/**
  		 * 
  		 */
  		private static final long serialVersionUID = -931042578800415977L;
  		private ImageProcessorBuffer imageBuffer;
  		private ImageStack stack = null;
  		private boolean closed = false;
  		private boolean init = false;
  		private boolean debug = false;
  		ImagePlus projectionVolume;
  
  
  
  		public String getName() {
  			return "Image Plus Projection Data Sink";
  		}
  
  
  		public ImagePlus getResult() {
  			//System.out.println("get result called: " + closed);
  			while (!closed){
  				try {
  					Thread.sleep(1);
  				} catch (InterruptedException e) {
  					// TODO Auto-generated catch block
  					e.printStackTrace();
  				}
  			}
  			//System.out.println("Image returned." + closed);
  			projectionVolume = new ImagePlus(); 
  			if (stack != null)
  				projectionVolume.setStack("Projection Data Sink", stack);
  			adjustViewRange();
  			return projectionVolume;
  		}
  
  		public void adjustViewRange(){
  			if (projectionVolume != null){
  				if (projectionVolume.getChannelProcessor() != null){
  					double [] stats = minAndMaxOfImageProcessor(projectionVolume.getChannelProcessor());
  					if (stats[0] != stats[1]) {
  						projectionVolume.setDisplayRange(stats[0], stats[1]);
  						projectionVolume.updateAndDraw();
  					}
  				}
  			}
  		}
  
  		public double [] minAndMaxOfImageProcessor(ImageProcessor imp){
  			double [] revan = new double [2];
  			revan[0] = Double.MAX_VALUE;
  			revan[1] = -Double.MAX_VALUE;
  			for (int i = 0; i < imp.getWidth(); i++){
  				for (int j = 0; j < imp.getHeight(); j++){
  					if (imp.getPixelValue(i, j) < revan[0]) {
  						revan[0] = imp.getPixelValue(i, j);
  					}
  					if (imp.getPixelValue(i, j) > revan[1]) {
  						revan[1] = imp.getPixelValue(i, j);
  					}
  				}
  
  			}
  			return revan;
  		}
  		
  		private synchronized void updateStack(ImageProcessor image, int projectionNumber){
  			if (stack == null) {
  				int stackSize = imageBuffer.size();
  				stack = new ImageStack(image.getWidth(), image.getHeight(), stackSize);
  			}
  			stack.setPixels(image.getPixels(), projectionNumber + 1);
  		}
  
  
  		public void process(ImageProcessor projection, int projectionNumber)
  		throws Exception {
  			if ((!init) || (imageBuffer == null)){
  				if (debug) System.out.println("ImagePlusDataSink: got projection " + projectionNumber);
  				imageBuffer = new ImageProcessorBuffer();
  				init = true;
  				closed = false;
  			}
  			if (debug) System.out.println("ImagePlusDataSink: got projection " + projectionNumber + " buffersize " + imageBuffer.size());
  			imageBuffer.add(projection, projectionNumber);
  		}
  
  		@Override
  		public String toString() {
  			return getName();
  		}
  
  
  
  		public void prepareForSerialization(){
  			stack = null;
  			init = false;
  			closed = false;
  			imageBuffer = null;
  		}
  
  	
  		public void close() throws Exception {
  			if (!closed) {
  				if (debug) System.out.println("ImagePlusDataSink: Closing Stream at " + imageBuffer.size());
  				ImageProcessor [] process = imageBuffer.toArray();
  				int newWidth = process[0].getWidth();
  				int newHeight = process[0].getHeight();
  				for (int i=1; i < process.length; i++){
  					int check = process[i].getWidth();
  					newWidth = (check > newWidth) ? check: newWidth;
  					check = process[i].getHeight();
  					newHeight = (check > newHeight)? check: newHeight;
  				}
  				// make sure the thread pool is done
  				for (int i = 0; i < process.length; i++){
  					ImageProcessor ip = process[i];
  					if (process[i] == null) {
  						System.out.println("ImagePlusDataSink: Image " + i + " was null");
  					}
  					if ((ip.getHeight() != newHeight)|| (ip.getWidth() != newWidth)) {
  						FloatProcessor newIP = new FloatProcessor(newWidth, newHeight);
  						for(int k = 0; k < ip.getHeight();k++){
  							for (int l= 0; l < ip.getWidth();l++){
  								newIP.putPixelValue(l, k, ip.getPixelValue(l, k));
  							}
  						}
  						ip = newIP;
  					}
  					updateStack(ip, i);
  				}
  				closed = true;
  			}
  		}
  
  	}
  
  	public abstract class FileProjectionSource {
  
  		protected FileInfo fi = null;
  		protected long skip;
  		protected int currentIndex = -1;
  		protected boolean showProgress;
  		protected ImageReader reader;
  		protected InputStream is;
  		protected ColorModel cm;
  
  
  
  		public FileProjectionSource [] getProjectionSources(){
  			FileProjectionSource [] sources = {new ZipProjectionSource(), new DicomProjectionSource()};
  			return sources;
  		}
  
  		public FileProjectionSource openProjectionStream(String filename) throws IOException {
  			FileProjectionSource [] sources = getProjectionSources();
  			FileProjectionSource source = null;
  			for (int i = 0; i < sources.length; i++){
  				try {
  					sources[i].initStream(filename);
  					source = sources[i];
  					break;
  				} catch (Exception e) {
  					// May throw some exception, if it is the wrong file type.
  					System.out.println(sources[i] +" failed because " +e.getLocalizedMessage());
  					//e.printStackTrace();
  				}
  			}
  			if (source == null) {
  				throw new IOException("No matching file format found.");
  			}
  			return source;	
  		}
  		
  		public abstract void initStream(String filename) throws IOException;
  
  /*
  		public synchronized void getNextProjection(IndividualImagePipelineFilteringTool tool){
  			ImageProcessor proc = getNextProjection();
  			if (proc != null){
  				tool.setImageProcessor(proc);
  				tool.setImageIndex(getCurrentProjectionNumber());
  			} else {
  				tool.setImageProcessor(null);
  				tool.setImageIndex(-1);
  			}
  		}
  */
  		public void setShowProgress(boolean showProgress) {
  			this.showProgress = showProgress;
  		}
  
  		public boolean isShowProgress() {
  			return showProgress;
  		}
  
  		public int getCurrentProjectionNumber(){
  			return currentIndex;
  		}
  
  		public ImageProcessor getNextProjection() {
  			ImageProcessor ip;
  			Object pixels = reader.readPixels(is, skip);
  			if (pixels == null) {
  				return null;
  			}
  			if (pixels instanceof byte[])
  				ip = new ByteProcessor(fi.width, fi.height, (byte[]) pixels, cm);
  			else if (pixels instanceof short[])
  				ip = new ShortProcessor(fi.width, fi.height, (short[]) pixels, cm);
  			else if (pixels instanceof int[])
  				ip = new ColorProcessor(fi.width, fi.height, (int[]) pixels);
  			else if (pixels instanceof float[])
  				ip = new FloatProcessor(fi.width, fi.height, (float[]) pixels, cm);		
  			else
  				throw new IllegalArgumentException("Unknown stack type");
  			skip = fi.gapBetweenImages;
  			currentIndex++;
  			if (showProgress){
  				IJ.showProgress((0.0 + currentIndex) / fi.nImages);
  			}
  			return ip;
  		}
  
  
  		protected void init() {
  			cm = createColorModel(fi);
  			//if (fi.nImages>1){
  				initStack();
  			//}
  		}
  
  
  		/** Returns an IndexColorModel for the image specified by this FileInfo. */
  		protected ColorModel createColorModel(FileInfo fi) {
  			if (fi.fileType==FileInfo.COLOR8 && fi.lutSize>0)
  				return new IndexColorModel(8, fi.lutSize, fi.reds, fi.greens, fi.blues);
  			else
  				return LookUpTable.createGrayscaleColorModel(fi.whiteIsZero);
  		}
  
  
  
  		/** Opens a stack of images. */
  		protected void initStack() {
  			skip = fi.getOffset();
  			try {
  				reader = new ImageReader(fi);
  				is = createInputStream(fi);
  				if (is==null) return ;
  			}
  			catch (Exception e) {
  				IJ.log("" + e);
  				e.printStackTrace();
  			}
  			catch(OutOfMemoryError e) {
  				e.printStackTrace();
  				IJ.outOfMemory(fi.fileName);
  			}
  		}
  
  		/** Returns an InputStream for the image described by this FileInfo. */
  		protected InputStream createInputStream(FileInfo fi) throws IOException, MalformedURLException {
  			InputStream is = null;
  			boolean gzip = fi.fileName!=null && (fi.fileName.endsWith(".gz")||fi.fileName.endsWith(".GZ"));
  			if (fi.inputStream!=null)
  				is = fi.inputStream;
  			else if (fi.url!=null && !fi.url.equals(""))
  				is = new URL(fi.url+fi.fileName).openStream();
  			else {
  				if (fi.directory.length()>0 && !fi.directory.endsWith(Prefs.separator))
  					fi.directory += Prefs.separator;
  				File f = new File(fi.directory + fi.fileName);
  				if (gzip) fi.compression = FileInfo.COMPRESSION_UNKNOWN;
  				if (f==null || f.isDirectory() || !validateFileInfo(f, fi))
  					is = null;
  				else
  					is = new FileInputStream(f);
  			}
  			if (is!=null) {
  				if (fi.compression>=FileInfo.LZW)
  					is = new RandomAccessStream(is);
  				else if (gzip)
  					is = new GZIPInputStream(is, 50000);
  			}
  			return is;
  		}
  
  		protected boolean validateFileInfo(File f, FileInfo fi) {
  			long offset = fi.getOffset();
  			long length = 0;
  			if (fi.width<=0 || fi.height<0) {
  				error("Width or height <= 0.", fi, offset, length);
  				return false;
  			}
  			if (offset>=0 && offset<1000L)
  				return true;
  			if (offset<0L) {
  				error("Offset is negative.", fi, offset, length);
  				return false;
  			}
  			if (fi.fileType==FileInfo.BITMAP || fi.compression!=FileInfo.COMPRESSION_NONE)
  				return true;
  			length = f.length();
  			long size = fi.width*fi.height*fi.getBytesPerPixel();
  			size = fi.nImages>1?size:size/4;
  			if (fi.height==1) size = 0; // allows plugins to read info of unknown length at end of file
  			if (offset+size>length) {
  				error("Offset + image size > file length.", fi, offset, length);
  				return false;
  			}
  			return true;
  		}
  
  		protected void error(String msg, FileInfo fi, long offset, long length) {
  			IJ.error("FileOpener", "FileInfo parameter error. \n"
  					+msg + "\n \n"
  					+"  Width: " + fi.width + "\n"
  					+"  Height: " + fi.height + "\n"
  					+"  Offset: " + offset + "\n"
  					+"  Bytes/pixel: " + fi.getBytesPerPixel() + "\n"
  					+(length>0?"  File length: " + length + "\n":"")
  			);
  		}
  
  
  
  		/** Reads the pixel data from an image described by a FileInfo object. */
  		protected Object readPixels(FileInfo fi) {
  			Object pixels = null;
  			try {
  				InputStream is = createInputStream(fi);
  				if (is==null)
  					return null;
  				ImageReader reader = new ImageReader(fi);
  				pixels = reader.readPixels(is);
  				is.close();
  			}
  			catch (Exception e) {
  				if (!Macro.MACRO_CANCELED.equals(e.getMessage()))
  					IJ.handleException(e);
  			}
  			return pixels;
  		}
  
  		public void close() throws IOException{
  			is.close();
  		}
  
  		/**
  		 * converts a byte sequence to integer
  		 * @param values the byte array
  		 * @param index the index in 32bit integer metric
  		 * @return the integer
  		 */
  		public long convertToUnsignedInt(byte[] values, int index) {
  			int offset = index * 4;  
  			//System.out.println(values[offset +0] + " " + values[offset +1] + " " + values[offset +2] + " " +values[offset +3]);
  			int val = values[offset+3];
  			if (val < 0) val += 256;
  			long value = val;
  			value = value << 8;
  			val = values[offset+2];
  			if (val < 0) val += 256;
  			value += val;
  			value = value << 8;
  			val = values[offset+1];
  			if (val < 0) val += 256;
  			value += val;
  			value = value << 8;
  			val = values[offset];
  			if (val < 0) val += 256;
  			value += val;
  			return value;
  		}
  		
  		/**
  		 * converts a byte sequence to integer
  		 * @param values the byte array
  		 * @param index the index in 32bit integer metric
  		 * @return the integer
  		 */
  		public int convertToUnsignedShort(byte[] values, int index) {
  			int offset = index * 2;  
  			//System.out.println(values[offset +0] + " " + values[offset +1] + " " + values[offset +2] + " " +values[offset +3]);
  			int val = values[offset+1];
  			if (val < 0) val += 256;
  			int value = val;
  			value = value << 8;
  			val = values[offset];
  			if (val < 0) val += 256;
  			value += val;
  			return value;
  		}
  		
  
  	}
  	
  	public class ImageProcessorBuffer {
  
  		ArrayList<ImageProcessor> images;
  		ArrayList<Integer> indices;
  		private boolean debug = false;
  
  		/**
  		 * creates a new ImageProcessorBuffer object.
  		 */
  		public ImageProcessorBuffer (){
  			images = new ArrayList<ImageProcessor>();
  			indices = new ArrayList<Integer>();
  		}
  
  		/**
  		 * adds the Image at index i; Previous entry will be overwritten.
  		 * @param image
  		 * @param index
  		 */
  		public synchronized void add(ImageProcessor image, int index){
  			Integer key = new Integer(index);
  			if (!indices.contains(key)){ // Insert
  				if (debug) System.out.println("ImageProcessorBuffer: Duplicate Index replacing " + key);
  				images.add(image);
  				indices.add(key);
  			} else { // Overwrite
  				for (int i = 0; i < indices.size(); i++){
  					if (indices.get(i).equals(key)){
  						if (debug) System.out.println("ImageProcessorBuffer: Duplicate Index replacing " + key);
  						images.set(i, image);
  						break;
  					}
  				}
  			}
  		}
  
  		/**
  		 * Returns the internal index of the given external index.
  		 * It is used to access the arrayLists.
  		 * 
  		 * @param externalIndex the external index position
  		 * @return the position in the internal ArrayList.
  		 */
  		private synchronized int internalIndex(int externalIndex){
  			int internalIndex = -1;
  			if (debug) System.out.println("ImageProcessorBuffer: Requested Index " + externalIndex + "; current size = " +indices.size());
  			for (int i = 0; i < indices.size(); i++){
  				if (indices.get(i) != null) {
  					if (indices.get(i).intValue() == externalIndex){
  						internalIndex = i;
  						if (debug) System.out.println("ImageProcessorBuffer: Index delivered " + externalIndex + "; current size = " +indices.size());
  						break;
  					}
  				} else {
  					System.out.println("ImageProcessorBuffer internal error.");
  					System.exit(-1);
  				}
  			}
  			return internalIndex;
  		}
  
  		/**
  		 * Returns the ImageProcessor at index index.
  		 * Returns null if the index is not found.
  		 * @param index the index
  		 * @return the ImageProcessor
  		 */
  		public synchronized ImageProcessor get(int index){
  			ImageProcessor revan = null;
  			int pos = internalIndex(index);
  			if (pos != -1) revan = images.get(pos);
  			return revan;
  		}
  
  		/**
  		 * Removes the image at the given index.
  		 * @param index the index.
  		 */
  		public synchronized void remove (int index){
  			int pos = internalIndex(index);
  			images.set(pos, null);
  		}
  
  		/**
  		 * Returns a sorted array of the buffered ImageProcessors 
  		 * @return the array.
  		 */
  		public synchronized ImageProcessor [] toArray(){
  			if (debug) System.out.println("ImageProcessorBuffer: Creating array with length " + images.size());
  			ImageProcessor[] array = new ImageProcessor[images.size()];
  			for (int i = 0; i< array.length; i++){
  				int index = indices.get(i).intValue();
  				array[index] = images.get(i);
  			}
  			return array;
  		}
  		
  		/**
  		 * Returns a sorted ImagePlus of the buffered ImageProcessors 
  		 * @return the ImagePlus.
  		 */
  		/*
  		public synchronized ImagePlus toImagePlus(String title){
  			if (debug) System.out.println("ImageProcessorBuffer: Creating ImagePlus with length " + images.size());
  			ImagePlus image = new ImagePlus();
  			ImageStack stack = new ImageStack(images.get(0).getWidth(), images.get(0).getHeight(), images.size());
  			stack.setColorModel(ImageUtil.getDefaultColorModel());
  			for (int i = 0; i< images.size(); i++){
  				int index = indices.get(i).intValue();
  				stack.setPixels(images.get(i).getPixels(), index + 1);
  			}
  			image.setStack(title, stack);
  			return image;
  		}
  */
  		/**
  		 * returns the number of stored ImageProcessors
  		 * @return the number
  		 */
  		public synchronized int size(){
  			return images.size();
  		}
  
  
  
  	}
  
  	public class DicomDecoder {
  
  		private static final int PIXEL_REPRESENTATION = 0x00280103;
  		private static final int TRANSFER_SYNTAX_UID = 0x00020010;
  		private static final int SLICE_THICKNESS = 0x00180050;
  		private static final int SLICE_SPACING = 0x00180088;
  		private static final int SAMPLES_PER_PIXEL = 0x00280002;
  		private static final int PHOTOMETRIC_INTERPRETATION = 0x00280004;
  		private static final int PLANAR_CONFIGURATION = 0x00280006;
  		private static final int NUMBER_OF_FRAMES = 0x00280008;
  		private static final int ROWS = 0x00280010;
  		private static final int COLUMNS = 0x00280011;
  		private static final int PIXEL_SPACING = 0x00280030;
  		private static final int BITS_ALLOCATED = 0x00280100;
  		private static final int WINDOW_CENTER = 0x00281050;
  		private static final int WINDOW_WIDTH = 0x00281051;	
  		private static final int RESCALE_INTERCEPT = 0x00281052;
  		private static final int RESCALE_SLOPE = 0x00281053;
  		private static final int RED_PALETTE = 0x00281201;
  		private static final int GREEN_PALETTE = 0x00281202;
  		private static final int BLUE_PALETTE = 0x00281203;
  		private static final int ICON_IMAGE_SEQUENCE = 0x00880200;
  		private static final int ITEM = 0xFFFEE000;
  		private static final int ITEM_DELIMINATION = 0xFFFEE00D;
  		private static final int SEQUENCE_DELIMINATION = 0xFFFEE0DD;
  		private static final int PIXEL_DATA = 0x7FE00010;
  		
  		
  		private static final int AE=0x4145, AS=0x4153, AT=0x4154, CS=0x4353, DA=0x4441, DS=0x4453, DT=0x4454,
  		FD=0x4644, FL=0x464C, IS=0x4953, LO=0x4C4F, LT=0x4C54, PN=0x504E, SH=0x5348, SL=0x534C, 
  		SS=0x5353, ST=0x5354, TM=0x544D, UI=0x5549, UL=0x554C, US=0x5553, UT=0x5554,
  		OB=0x4F42, OW=0x4F57, SQ=0x5351, UN=0x554E, QQ=0x3F3F;
  
  		private Properties dictionary;
  
  		private String directory, fileName;
  		private static final int ID_OFFSET = 128;  //location of "DICM"
  		private static final String DICM = "DICM";
  
  		private BufferedInputStream f;
  		private int location = 0;
  		private boolean littleEndian = true;
  
  		private int elementLength;
  		private int vr;  // Value Representation
  		private static final int IMPLICIT_VR = 0x2D2D; // '--' 
  		private byte[] vrLetters = new byte[2];
  
  		private double[] voltage;
  		private double[] current;
  		private double[] time;
  		private double dCU;
  		private double dose;
  		
  		private int previousGroup;
  		public int getPreviousGroup() {
  			return previousGroup;
  		}
  
  		public String getPreviousInfo() {
  			return previousInfo;
  		}
  
  		private String previousInfo;
  		private StringBuffer dicomInfo = new StringBuffer(1000);
  		private boolean dicmFound; // "DICM" found at offset 128
  		private boolean oddLocations;  // one or more tags at odd locations
  		private boolean bigEndianTransferSyntax = false;
  		double windowCenter, windowWidth;
  		double rescaleIntercept, rescaleSlope;
  		boolean inSequence;
  		private BufferedInputStream inputStream;
  		private boolean debug = false;
  
  		public DicomDecoder(String directory, String fileName) {
  			this.directory = directory;
  			this.fileName = fileName;
  			String path = null;
  			if (dictionary==null && IJ.getApplet()==null) {
  				path = Prefs.getHomeDir()+File.separator+"DICOM_Dictionary.txt";
  				File f = new File(path);
  				if (f.exists()) try {
  					dictionary = new Properties();
  					InputStream is = new BufferedInputStream(new FileInputStream(f));
  					dictionary.load(is);
  					is.close();
  					if (debug) IJ.log("DicomDecoder: using "+dictionary.size()+" tag dictionary at "+path);
  				} catch (Exception e) {
  					dictionary = null;
  				}
  			}
  			if (dictionary==null) {
  				DicomDictionary d = new DicomDictionary();
  				dictionary = d.getDictionary();
  				if (debug) IJ.log("DicomDecoder: "+path+" not found; using "+dictionary.size()+" tag built in dictionary");
  			}
  		}
  		
  		public DicomDecoder(InputStream inputStream) {
  			String path = null;
  			if (dictionary==null && IJ.getApplet()==null) {
  				path = Prefs.getHomeDir()+File.separator+"DICOM_Dictionary.txt";
  				File f = new File(path);
  				if (f.exists()) try {
  					dictionary = new Properties();
  					InputStream is = new BufferedInputStream(new FileInputStream(f));
  					dictionary.load(is);
  					is.close();
  					if (debug) IJ.log("DicomDecoder: using "+dictionary.size()+" tag dictionary at "+path);
  				} catch (Exception e) {
  					dictionary = null;
  				}
  			}
  			this.inputStream = new BufferedInputStream(inputStream);
  			if (dictionary==null) {
  				DicomDictionary d = new DicomDictionary();
  				dictionary = d.getDictionary();
  				if (debug) IJ.log("DicomDecoder: "+path+" not found; using "+dictionary.size()+" tag built in dictionary");
  			}
  		}
  		
  
  		String getString(int length) throws IOException {
  			byte[] buf = new byte[length];
  			int pos = 0;
  			while (pos<length) {
  				int count = f.read(buf, pos, length-pos);
  				if (count == -1) throw new IOException("End of Stream reached");
  				pos += count;
  			}
  			location += length;
  			return new String(buf);
  		}
  
  		int getByte() throws IOException {
  			int b = f.read();
  			if (b ==-1) throw new IOException("unexpected EOF");
  			++location;
  			//System.out.println(b);
  			return b;
  		}
  
  		int getShort() throws IOException {
  			int b0 = getByte();
  			int b1 = getByte();
  			if (littleEndian)
  				return ((b1 << 8) + b0);
  			else
  				return ((b0 << 8) + b1);
  		}
  
  		final int getInt() throws IOException {
  			int b0 = getByte();
  			int b1 = getByte();
  			int b2 = getByte();
  			int b3 = getByte();
  			if (littleEndian)
  				return ((b3<<24) + (b2<<16) + (b1<<8) + b0);
  			else
  				return ((b0<<24) + (b1<<16) + (b2<<8) + b3);
  		}
  
  		double getDouble() throws IOException {
  			int b0 = getByte();
  			int b1 = getByte();
  			int b2 = getByte();
  			int b3 = getByte();
  			int b4 = getByte();
  			int b5 = getByte();
  			int b6 = getByte();
  			int b7 = getByte();
  			long res = 0;
  			if (littleEndian) {
  				res += b0;
  				res += ( ((long)b1) << 8);
  				res += ( ((long)b2) << 16);
  				res += ( ((long)b3) << 24);
  				res += ( ((long)b4) << 32);
  				res += ( ((long)b5) << 40);
  				res += ( ((long)b6) << 48);
  				res += ( ((long)b7) << 56);         
  			} else {
  				res += b7;
  				res += ( ((long)b6) << 8);
  				res += ( ((long)b5) << 16);
  				res += ( ((long)b4) << 24);
  				res += ( ((long)b3) << 32);
  				res += ( ((long)b2) << 40);
  				res += ( ((long)b1) << 48);
  				res += ( ((long)b0) << 56);
  			}
  			return Double.longBitsToDouble(res);
  		}
  
  		float getFloat() throws IOException {
  			int b0 = getByte();
  			int b1 = getByte();
  			int b2 = getByte();
  			int b3 = getByte();
  			int res = 0;
  			if (littleEndian) {
  				res += b0;
  				res += ( ((long)b1) << 8);
  				res += ( ((long)b2) << 16);
  				res += ( ((long)b3) << 24);     
  			} else {
  				res += b3;
  				res += ( ((long)b2) << 8);
  				res += ( ((long)b1) << 16);
  				res += ( ((long)b0) << 24);
  			}
  			return Float.intBitsToFloat(res);
  		}
  
  		byte[] getLut(int length) throws IOException {
  			if ((length&1)!=0) { // odd
  				getString(length);
  				return null;
  			}
  			length /= 2;
  			byte[] lut = new byte[length];
  			for (int i=0; i<length; i++)
  				lut[i] = (byte)(getShort()>>>8);
  			return lut;
  		}
  
  		int getLength() throws IOException {
  			int b0 = getByte();
  			int b1 = getByte();
  			int b2 = getByte();
  			int b3 = getByte();
  
  			// We cannot know whether the VR is implicit or explicit
  			// without the full DICOM Data Dictionary for public and
  			// private groups.
  
  			// We will assume the VR is explicit if the two bytes
  			// match the known codes. It is possible that these two
  			// bytes are part of a 32-bit length for an implicit VR.
  
  			vr = (b0<<8) + b1;
  
  			switch (vr) {
  			case OB: case OW: case SQ: case UN: case UT:
  				// Explicit VR with 32-bit length if other two bytes are zero
  				if ( (b2 == 0) || (b3 == 0) ) return getInt();
  				// Implicit VR with 32-bit length
  				vr = IMPLICIT_VR;
  				if (littleEndian)
  					return ((b3<<24) + (b2<<16) + (b1<<8) + b0);
  				else
  					return ((b0<<24) + (b1<<16) + (b2<<8) + b3);		
  			case AE: case AS: case AT: case CS: case DA: case DS: case DT:  case FD:
  			case FL: case IS: case LO: case LT: case PN: case SH: case SL: case SS:
  			case ST: case TM:case UI: case UL: case US: case QQ:
  				// Explicit vr with 16-bit length
  				if (littleEndian)
  					return ((b3<<8) + b2);
  				else
  					return ((b2<<8) + b3);
  			default:
  				// Implicit VR with 32-bit length...
  				vr = IMPLICIT_VR;
  				if (littleEndian)
  					return ((b3<<24) + (b2<<16) + (b1<<8) + b0);
  				else
  					return ((b0<<24) + (b1<<16) + (b2<<8) + b3);
  			}
  		}
  
  		int getNextTag() throws IOException {
  			int groupWord = getShort();
  			if (groupWord==0x0800 && bigEndianTransferSyntax) {
  				littleEndian = false;
  				groupWord = 0x0008;
  			}
  			int elementWord = getShort();
  			int tag = groupWord<<16 | elementWord;
  			elementLength = getLength();
  
  			// hack needed to read some GE files
  			// The element length must be even!
  			if (elementLength==13 && !oddLocations) elementLength = 10; 
  
  			// "Undefined" element length.
  			// This is a sort of bracket that encloses a sequence of elements.
  			if (elementLength==-1) {
  				elementLength = 0;
  				inSequence = true;
  			}
  			//IJ.log("getNextTag: "+tag+" "+elementLength);		
  				
  			return tag;
  		}
  
  		public FileInfo getFileInfo() throws IOException {
  			long skipCount;
  			FileInfo fi = new FileInfo();
  			int bitsAllocated = 16;
  			fi.fileFormat = FileInfo.RAW;
  			fi.fileName = fileName;
  			if (directory != null) {
  				if (directory.indexOf("://")>0) { // is URL
  				URL u = new URL(directory+fileName);
  				setInputStream(new BufferedInputStream(u.openStream()));
  				fi.inputStream = getInputStream();
  				} else if (getInputStream()!=null)
  					fi.inputStream = getInputStream();
  				else
  					fi.directory = directory;
  			} else if (getInputStream()!=null)
  				fi.inputStream = getInputStream();
  			fi.width = 0;
  			fi.height = 0;
  			fi.offset = 0;
  			fi.intelByteOrder = true;
  			fi.fileType = FileInfo.GRAY16_UNSIGNED;
  			fi.fileFormat = FileInfo.DICOM;
  			int samplesPerPixel = 1;
  			int planarConfiguration = 0;
  			String photoInterpretation = "";
  
  			if (getInputStream()!=null) {
  				// Use large buffer to allow URL stream to be reset after reading header
  				f = getInputStream();
  				f.mark(400000);
  			} else
  				f = new BufferedInputStream(new FileInputStream(directory + fileName));
  			if (IJ.debugMode) {
  				IJ.log("");
  				IJ.log("DicomDecoder: decoding "+fileName);
  			}
  
  			skipCount = (long)ID_OFFSET;
  			while (skipCount > 0) skipCount -= f.skip( skipCount );
  			location += ID_OFFSET;
  
  			if (!getString(4).equals(DICM)) {
  				if (getInputStream()==null) f.close();
  				if (getInputStream()!=null)
  					f.reset();
  				else
  					f = new BufferedInputStream(new FileInputStream(directory + fileName));
  				location = 0;
  				if (IJ.debugMode) IJ.log(DICM + " not found at offset "+ID_OFFSET+"; reseting to offset 0");
  			} else {
  				dicmFound = true;
  				if (IJ.debugMode) IJ.log(DICM + " found at offset " + ID_OFFSET);
  			}
  
  			boolean decodingTags = true;
  			boolean signed = false;
  
  			while (decodingTags) {
  				int tag = getNextTag();
  				if ((location&1)!=0) // DICOM tags must be at even locations
  					oddLocations = true;
  				if (inSequence) {
  					addInfo(tag, null);
  					continue;
  				}
  				String s;
  				switch (tag) {
  				case 0x00181020:
  					s = getString(elementLength);
  					addInfo(tag, s);
  					break;
  				case TRANSFER_SYNTAX_UID:
  					s = getString(elementLength);
  					addInfo(tag, s);
  					if (s.indexOf("1.2.4")>-1||s.indexOf("1.2.5")>-1) {
  						f.close();
  						String msg = "ImageJ cannot open compressed DICOM images.\n \n";
  						msg += "Transfer Syntax UID = "+s;
  						throw new IOException(msg);
  					}
  					if (s.indexOf("1.2.840.10008.1.2.2")>=0)
  						bigEndianTransferSyntax = true;
  					break;
  				case NUMBER_OF_FRAMES:
  					s = getString(elementLength);
  					addInfo(tag, s);
  					double frames = s2d(s);
  					if (frames>1.0)
  						fi.nImages = (int)frames;
  					break;
  				case SAMPLES_PER_PIXEL:
  					samplesPerPixel = getShort();
  					addInfo(tag, samplesPerPixel);
  					break;
  				case PHOTOMETRIC_INTERPRETATION:
  					photoInterpretation = getString(elementLength);
  					addInfo(tag, photoInterpretation);
  					break;
  				case PLANAR_CONFIGURATION:
  					planarConfiguration = getShort();
  					addInfo(tag, planarConfiguration);
  					break;
  				case ROWS:
  					fi.height = getShort();
  					//Configuration.getGlobalConfiguration().setIntensifierSize(fi.height);
  					addInfo(tag, fi.height);
  					break;
  				case COLUMNS:
  					fi.width = getShort();
  					addInfo(tag, fi.width);
  					break;
  				case PIXEL_SPACING:
  					String scale = getString(elementLength);
  					getSpatialScale(fi, scale);
  					addInfo(tag, scale);
  					break;
  				case SLICE_THICKNESS: case SLICE_SPACING:
  					String spacing = getString(elementLength);
  					fi.pixelDepth = s2d(spacing);
  					addInfo(tag, spacing);
  					break;
  				case BITS_ALLOCATED:
  					bitsAllocated = getShort();
  					if (bitsAllocated==8)
  						fi.fileType = FileInfo.GRAY8;
  					else if (bitsAllocated==32)
  						fi.fileType = FileInfo.GRAY32_UNSIGNED;
  					addInfo(tag, bitsAllocated);
  					break;
  				case PIXEL_REPRESENTATION:
  					int pixelRepresentation = getShort();
  					if (pixelRepresentation==1) {
  						fi.fileType = FileInfo.GRAY16_SIGNED;
  						signed = true;
  					}
  					addInfo(tag, pixelRepresentation);
  					break;
  				case WINDOW_CENTER:
  					String center = getString(elementLength);
  					int index = center.indexOf('\\');
  					if (index!=-1) center = center.substring(index+1);
  					windowCenter = s2d(center);
  					addInfo(tag, center);
  					break;
  				case WINDOW_WIDTH:
  					String width = getString(elementLength);
  					index = width.indexOf('\\');
  					if (index!=-1) width = width.substring(index+1);
  					windowWidth = s2d(width);
  					addInfo(tag, width);
  					break;
  				case RESCALE_INTERCEPT:
  					String intercept = getString(elementLength);
  					rescaleIntercept = s2d(intercept);
  					addInfo(tag, intercept);
  					break;
  				case RESCALE_SLOPE:
  					String slop = getString(elementLength);
  					rescaleSlope = s2d(slop);
  					addInfo(tag, slop);
  					break;
  				case RED_PALETTE:
  					fi.reds = getLut(elementLength);
  					addInfo(tag, elementLength/2);
  					break;
  				case GREEN_PALETTE:
  					fi.greens = getLut(elementLength);
  					addInfo(tag, elementLength/2);
  					break;
  				case BLUE_PALETTE:
  					fi.blues = getLut(elementLength);
  					addInfo(tag, elementLength/2);
  					break;
  				case PIXEL_DATA:
  					// Start of image data...
  					if (elementLength!=0) {
  						fi.offset = location;
  						addInfo(tag, location);
  						decodingTags = false;
  					} else
  						addInfo(tag, null);
  					break;
  				case 0x7F880010:
  					// What is this? - RAK
  					if (elementLength!=0) {
  						fi.offset = location+4;
  						decodingTags = false;
  					}
  					addInfo(tag, null);
  					break;
  				default:
  					boolean exploreMode = false;
  					if (exploreMode){
  						System.out.println(tag2hex(tag) + " " + elementLength+ " Bytes: " + this.getString(elementLength));
  					} else {
  						addInfo(tag, null);
  					}
  				}
  			} // while(decodingTags)
  			
  			if (fi.fileType==FileInfo.GRAY8) {
  				if (fi.reds!=null && fi.greens!=null && fi.blues!=null
  						&& fi.reds.length==fi.greens.length
  						&& fi.reds.length==fi.blues.length) {
  					fi.fileType = FileInfo.COLOR8;
  					fi.lutSize = fi.reds.length;
  
  				}
  			}
  
  			if (fi.fileType==FileInfo.GRAY32_UNSIGNED && signed)
  				fi.fileType = FileInfo.GRAY32_INT;
  
  			if (samplesPerPixel==3 && photoInterpretation.startsWith("RGB")) {
  				if (planarConfiguration==0)
  					fi.fileType = FileInfo.RGB;
  				else if (planarConfiguration==1)
  					fi.fileType = FileInfo.RGB_PLANAR;
  			} else if (photoInterpretation.endsWith("1 "))
  				fi.whiteIsZero = true;
  
  			if (!littleEndian)
  				fi.intelByteOrder = false;
  
  			if (IJ.debugMode) {
  				IJ.log("width: " + fi.width);
  				IJ.log("height: " + fi.height);
  				IJ.log("images: " + fi.nImages);
  				IJ.log("bits allocated: " + bitsAllocated);
  				IJ.log("offset: " + fi.offset);
  			}
  
  			if (getInputStream()!=null)
  				f.reset();
  			else
  				f.close();
  			return fi;
  		}
  
  		public double[] getVoltage() {
  			return voltage;
  		}
  
  		public double[] getCurrent() {
  			return current;
  		}
  
  		public double[] getTime() {
  			return time;
  		}
  
  		public double getdCU() {
  			return dCU;
  		}
  
  		public double getDose() {
  			return dose;
  		}
  
  		String getDicomInfo() {
  			String s = new String(dicomInfo);
  			char[] chars = new char[s.length()];
  			s.getChars(0, s.length(), chars, 0);
  			for (int i=0; i<chars.length; i++) {
  				if (chars[i]<' ' && chars[i]!='\n') chars[i] = ' ';
  			}
  			return new String(chars);
  		}
  
  		void addInfo(int tag, String value) throws IOException {
  
  			String info = getHeaderInfo(tag, value);
  			
  			if (inSequence && info!=null && vr!=SQ) info = ">" + info;
  			if (info!=null &&  tag!=ITEM) {
  				int group = tag>>>16;
  			//if (group!=previousGroup && (previousInfo!=null&&previousInfo.indexOf("Sequence:")==-1))
  			//	dicomInfo.append("\n");
  			previousGroup = group;
  			previousInfo = info;
  			dicomInfo.append(tag2hex(tag)+info+"\n");
  			}
  			if (debug) {
  				if (info==null) info = "";
  				vrLetters[0] = (byte)(vr >> 8);
  				vrLetters[1] = (byte)(vr & 0xFF);
  				String VR = new String(vrLetters);
  				IJ.log("(" + tag2hex(tag) + VR
  						+ " " + elementLength
  						+ " bytes from "
  						+ (location-elementLength)+") "
  						+ info);
  			}
  		}
  
  		void addInfo(int tag, int value) throws IOException {
  			addInfo(tag, Integer.toString(value));
  		}
  
  		String getHeaderInfo(int tag, String value) throws IOException {
  			if (tag==ITEM_DELIMINATION || tag==SEQUENCE_DELIMINATION) {
  				inSequence = false;
  				if (!IJ.debugMode) return null;
  			}
  			String key = i2hex(tag);
  			//while (key.length()<8)
  			//	key = '0' + key;
  			String id = (String)dictionary.get(key);
  			if (id!=null) {
  				if (vr==IMPLICIT_VR && id!=null)
  					vr = (id.charAt(0)<<8) + id.charAt(1);
  				id = id.substring(2);
  			}
  			if (tag==ITEM)
  				return id!=null?id+":":null;
  			if (value!=null)
  				return id+": "+value;
  			switch (vr) {
  			case FD:
  				if (elementLength==8)
  					value = Double.toString(getDouble());
  				else
  					for (int i=0; i<elementLength; i++) getByte();
  				break;
  			case FL:
  				if (elementLength==4)
  					value = Float.toString(getFloat());
  				else
  					for (int i=0; i<elementLength; i++) getByte();
  				break;
  				//case UT:
  				//throw new IOException("ImageJ cannot read UT (unlimited text) DICOMs");
  			case AE: case AS: case AT: case CS: case DA: case DS: case DT:  case IS: case LO: 
  			case LT: case PN: case SH: case ST: case TM: case UI:
  				value = getString(elementLength);
  				break;
  			case US:
  				if (elementLength==2)
  					value = Integer.toString(getShort());
  				else {
  					value = "";
  					int n = elementLength/2;
  					for (int i=0; i<n; i++)
  						value += Integer.toString(getShort())+" ";
  				}
  				break;
  			case IMPLICIT_VR:
  				value = getString(elementLength);
  				if (elementLength>44) value=null;
  				break;
  			case SQ:
  				value = "";
  				boolean privateTag = ((tag>>16)&1)!=0;
  				if (tag!=ICON_IMAGE_SEQUENCE && !privateTag)
  					break;
  				// else fall through and skip icon image sequence or private sequence
  			default:
  				long skipCount = (long)elementLength;
  				while (skipCount > 0) skipCount -= f.skip(skipCount);
  				location += elementLength;
  				value = "";
  			}
  			if (value!=null && id==null && !value.equals(""))
  				return "---: "+value;
  			else if (id==null)
  				return null;
  			else
  				return id+": "+value;
  		}
  
  		char[] buf8 = new char[8];
  
  		/** Converts an int to an 8 byte hex string. */
  		String i2hex(int i) {
  			for (int pos=7; pos>=0; pos--) {
  				buf8[pos] = Tools.hexDigits[i&0xf];
  				i >>>= 4;
  			}
  			return new String(buf8);
  		}
  
  		char[] buf10;
  
  		String tag2hex(int tag) {
  			if (buf10==null) {
  				buf10 = new char[11];
  				buf10[4] = ',';
  				buf10[9] = ' ';
  			}
  			int pos = 8;
  			while (pos>=0) {
  				buf10[pos] = Tools.hexDigits[tag&0xf];
  				tag >>>= 4;
  					pos--;
  					if (pos==4) pos--; // skip coma
  			}
  			return new String(buf10);
  		}
  
  		double s2d(String s) {
  			Double d;
  			try {d = new Double(s);}
  			catch (NumberFormatException e) {d = null;}
  			if (d!=null)
  				return(d.doubleValue());
  			else
  				return(0.0);
  		}
  
  		void getSpatialScale(FileInfo fi, String scale) {
  			double xscale=0, yscale=0;
  			int i = scale.indexOf('\\');
  			if (i>0) {
  				yscale = s2d(scale.substring(0, i));
  				xscale = s2d(scale.substring(i+1));
  			}
  			if (xscale!=0.0 && yscale!=0.0) {
  				fi.pixelWidth = xscale;
  				fi.pixelHeight = yscale;
  				fi.unit = "mm";
  			}
  		}
  
  		public boolean dicmFound() {
  			return dicmFound;
  		}
  
  		public void setInputStream(BufferedInputStream inputStream) {
  			this.inputStream = inputStream;
  		}
  
  		public BufferedInputStream getInputStream() {
  			return inputStream;
  		}
  
  	}
  
  
  	class DicomDictionary {
  
  		Properties getDictionary() {
  			Properties p = new Properties();
  			for (int i=0; i<dict.length; i++) {
  				p.put(dict[i].substring(0,8), dict[i].substring(9));
  			}
  			return p;
  		}
  
  		String[] dict = {
  				"00020002=UIMedia Storage SOP Class UID", 
  				"00020003=UIMedia Storage SOP Inst UID",
  				"00020010=UITransfer Syntax UID",
  				"00020012=UIImplementation Class UID",
  				"00020013=SHImplementation Version Name",
  				"00020016=AESource Application Entity Title",
  
  				"00080005=CSSpecific Character Set",
  				"00080008=CSImage Type",
  				"00080010=CSRecognition Code",
  				"00080012=DAInstance Creation Date",
  				"00080013=TMInstance Creation Time",
  				"00080014=UIInstance Creator UID",
  				"00080016=UISOP Class UID",
  				"00080018=UISOP Instance UID",
  				"00080020=DAStudy Date",
  				"00080021=DASeries Date",
  				"00080022=DAAcquisition Date",
  				"00080023=DAImage Date",
  				"00080024=DAOverlay Date",
  				"00080025=DACurve Date",
  				"00080030=TMStudy Time",
  				"00080031=TMSeries Time",
  				"00080032=TMAcquisition Time",
  				"00080033=TMImage Time",
  				"00080034=TMOverlay Time",
  				"00080035=TMCurve Time",
  				"00080040=USData Set Type",
  				"00080041=LOData Set Subtype",
  				"00080042=CSNuclear Medicine Series Type",
  				"00080050=SHAccession Number",
  				"00080052=CSQuery/Retrieve Level",
  				"00080054=AERetrieve AE Title",
  				"00080058=AEFailed SOP Instance UID List",
  				"00080060=CSModality",
  				"00080064=CSConversion Type",
  				"00080068=CSPresentation Intent Type",
  				"00080070=LOManufacturer",
  				"00080080=LOInstitution Name",
  				"00080081=STInstitution Address",
  				"00080082=SQInstitution Code Sequence",
  				"00080090=PNReferring Physician's Name",
  				"00080092=STReferring Physician's Address",
  				"00080094=SHReferring Physician's Telephone Numbers",
  				"00080100=SHCode Value",
  				"00080102=SHCoding Scheme Designator",
  				"00080104=LOCode Meaning",
  				"00080201=SHTimezone Offset From UTC",
  				"00081010=SHStation Name",
  				"00081030=LOStudy Description",
  				"00081032=SQProcedure Code Sequence",
  				"0008103E=LOSeries Description",
  				"00081040=LOInstitutional Department Name",
  				"00081048=PNPhysician(s) of Record",
  				"00081050=PNAttending Physician's Name",
  				"00081060=PNName of Physician(s) Reading Study",
  				"00081070=PNOperator's Name",
  				"00081080=LOAdmitting Diagnoses Description",
  				"00081084=SQAdmitting Diagnosis Code Sequence",
  				"00081090=LOManufacturer's Model Name",
  				"00081100=SQReferenced Results Sequence",
  				"00081110=SQReferenced Study Sequence",
  				"00081111=SQReferenced Study Component Sequence",
  				"00081115=SQReferenced Series Sequence",
  				"00081120=SQReferenced Patient Sequence",
  				"00081125=SQReferenced Visit Sequence",
  				"00081130=SQReferenced Overlay Sequence",
  				"00081140=SQReferenced Image Sequence",
  				"00081145=SQReferenced Curve Sequence",
  				"00081150=UIReferenced SOP Class UID",
  				"00081155=UIReferenced SOP Instance UID",
  				"00082111=STDerivation Description",
  				"00082112=SQSource Image Sequence",
  				"00082120=SHStage Name",
  				"00082122=ISStage Number",
  				"00082124=ISNumber of Stages",
  				"00082129=ISNumber of Event Timers",
  				"00082128=ISView Number",
  				"0008212A=ISNumber of Views in Stage",
  				"00082130=DSEvent Elapsed Time(s)",
  				"00082132=LOEvent Timer Name(s)",
  				"00082142=ISStart Trim",
  				"00082143=ISStop Trim",
  				"00082144=ISRecommended Display Frame Rate",
  				"00082200=CSTransducer Position",
  				"00082204=CSTransducer Orientation",
  				"00082208=CSAnatomic Structure",
  
  				"00100010=PNPatient's Name",
  				"00100020=LOPatient ID",
  				"00100021=LOIssuer of Patient ID",
  				"00100030=DAPatient's Birth Date",
  				"00100032=TMPatient's Birth Time",
  				"00100040=CSPatient's Sex",
  				"00101000=LOOther Patient IDs",
  				"00101001=PNOther Patient Names",
  				"00101005=PNPatient's Maiden Name",
  				"00101010=ASPatient's Age",
  				"00101020=DSPatient's Size",
  				"00101030=DSPatient's Weight",
  				"00101040=LOPatient's Address",
  				"00102150=LOCountry of Residence",
  				"00102152=LORegion of Residence",
  				"00102180=SHOccupation",
  				"001021A0=CSSmoking Status",
  				"001021B0=LTAdditional Patient History",
  				"00104000=LTPatient Comments",
  
  				"00180010=LOContrast/Bolus Agent",
  				"00180015=CSBody Part Examined",
  				"00180020=CSScanning Sequence",
  				"00180021=CSSequence Variant",
  				"00180022=CSScan Options",
  				"00180023=CSMR Acquisition Type",
  				"00180024=SHSequence Name",
  				"00180025=CSAngio Flag",
  				"00180030=LORadionuclide",
  				"00180031=LORadiopharmaceutical",
  				"00180032=DSEnergy Window Centerline",
  				"00180033=DSEnergy Window Total Width",
  				"00180034=LOIntervention Drug Name",
  				"00180035=TMIntervention Drug Start Time",
  				"00180040=ISCine Rate",
  				"00180050=DSSlice Thickness",
  				"00180060=DSkVp",
  				"00180070=ISCounts Accumulated",
  				"00180071=CSAcquisition Termination Condition",
  				"00180072=DSEffective Series Duration",
  				"00180073=CSAcquisition Start Condition",
  				"00180074=ISAcquisition Start Condition Data",
  				"00180075=ISAcquisition Termination Condition Data",
  				"00180080=DSRepetition Time",
  				"00180081=DSEcho Time",
  				"00180082=DSInversion Time",
  				"00180083=DSNumber of Averages",
  				"00180084=DSImaging Frequency",
  				"00180085=SHImaged Nucleus",
  				"00180086=ISEcho Numbers(s)",
  				"00180087=DSMagnetic Field Strength",
  				"00180088=DSSpacing Between Slices",
  				"00180089=ISNumber of Phase Encoding Steps",
  				"00180090=DSData Collection Diameter",
  				"00180091=ISEcho Train Length",
  				"00180093=DSPercent Sampling",
  				"00180094=DSPercent Phase Field of View",
  				"00180095=DSPixel Bandwidth",
  				"00181000=LODevice Serial Number",
  				"00181004=LOPlate ID",
  				"00181010=LOSecondary Capture Device ID",
  				"00181012=DADate of Secondary Capture",
  				"00181014=TMTime of Secondary Capture",
  				"00181016=LOSecondary Capture Device Manufacturer",
  				"00181018=LOSecondary Capture Device Manufacturer's Model Name",
  				"00181019=LOSecondary Capture Device Software Version(s)",
  				"00181020=LOSoftware Versions(s)",
  				"00181022=SHVideo Image Format Acquired",
  				"00181023=LODigital Image Format Acquired",
  				"00181030=LOProtocol Name",
  				"00181040=LOContrast/Bolus Route",
  				"00181041=DSContrast/Bolus Volume",
  				"00181042=TMContrast/Bolus Start Time",
  				"00181043=TMContrast/Bolus Stop Time",
  				"00181044=DSContrast/Bolus Total Dose",
  				"00181045=ISSyringe Counts",
  				"00181050=DSSpatial Resolution",
  				"00181060=DSTrigger Time",
  				"00181061=LOTrigger Source or Type",
  				"00181062=ISNominal Interval",
  				"00181063=DSFrame Time",
  				"00181064=LOFraming Type",
  				"00181065=DSFrame Time Vector",
  				"00181066=DSFrame Delay",
  				"00181070=LORadionuclide Route",
  				"00181071=DSRadionuclide Volume",
  				"00181072=TMRadionuclide Start Time",
  				"00181073=TMRadionuclide Stop Time",
  				"00181074=DSRadionuclide Total Dose",
  				"00181075=DSRadionuclide Half Life",
  				"00181076=DSRadionuclide Positron Fraction",
  				"00181080=CSBeat Rejection Flag",
  				"00181081=ISLow R-R Value",
  				"00181082=ISHigh R-R Value",
  				"00181083=ISIntervals Acquired",
  				"00181084=ISIntervals Rejected",
  				"00181085=LOPVC Rejection",
  				"00181086=ISSkip Beats",
  				"00181088=ISHeart Rate",
  				"00181090=ISCardiac Number of Images",
  				"00181094=ISTrigger Window",
  				"00181100=DSReconstruction Diameter",
  				"00181110=DSDistance Source to Detector",
  				"00181111=DSDistance Source to Patient",
  				"00181120=DSGantry/Detector Tilt",
  				"00181130=DSTable Height",
  				"00181131=DSTable Traverse",
  				"00181140=CSRotation Direction",
  				"00181141=DSAngular Position",
  				"00181142=DSRadial Position",
  				"00181143=DSScan Arc",
  				"00181144=DSAngular Step",
  				"00181145=DSCenter of Rotation Offset",
  				"00181146=DSRotation Offset",
  				"00181147=CSField of View Shape",
  				"00181149=ISField of View Dimensions(s)",
  				"00181150=ISExposure Time",
  				"00181151=ISX-ray Tube Current",
  				"00181152=ISExposure",
  				"00181153=ISExposure in uAs",
  				"00181154=DSAverage Pulse Width",
  				"00181155=CSRadiation Setting",
  				"00181156=CSRectification Type",
  				"0018115A=CSRadiation Mode",
  				"0018115E=DSImage Area Dose Product",
  				"00181160=SHFilter Type",
  				"00181161=LOType of Filters",
  				"00181162=DSIntensifier Size",
  				"00181164=DSImager Pixel Spacing",
  				"00181166=CSGrid",
  				"00181170=ISGenerator Power",
  				"00181180=SHCollimator/grid Name",
  				"00181181=CSCollimator Type",
  				"00181182=ISFocal Distance",
  				"00181183=DSX Focus Center",
  				"00181184=DSY Focus Center",
  				"00181190=DSFocal Spot(s)",
  				"00181191=CSAnode Target Material",
  				"001811A0=DSBody Part Thickness",
  				"001811A2=DSCompression Force",
  				"00181200=DADate of Last Calibration",
  				"00181201=TMTime of Last Calibration",
  				"00181210=SHConvolution Kernel",
  				"00181242=ISActual Frame Duration",
  				"00181243=ISCount Rate",
  				"00181250=SHReceiving Coil",
  				"00181251=SHTransmitting Coil",
  				"00181260=SHPlate Type",
  				"00181261=LOPhosphor Type",
  				"00181300=ISScan Velocity",
  				"00181301=CSWhole Body Technique",
  				"00181302=ISScan Length",
  				"00181310=USAcquisition Matrix",
  				"00181312=CSPhase Encoding Direction",
  				"00181314=DSFlip Angle",
  				"00181315=CSVariable Flip Angle Flag",
  				"00181316=DSSAR",
  				"00181318=DSdB/dt",
  				"00181400=LOAcquisition Device Processing Description",
  				"00181401=LOAcquisition Device Processing Code",
  				"00181402=CSCassette Orientation",
  				"00181403=CSCassette Size",
  				"00181404=USExposures on Plate",
  				"00181405=ISRelative X-ray Exposure",
  				"00181450=CSColumn Angulation",
  				"00181500=CSPositioner Motion",
  				"00181508=CSPositioner Type",
  				"00181510=DSPositioner Primary Angle",
  				"00181511=DSPositioner Secondary Angle",
  				"00181520=DSPositioner Primary Angle Increment",
  				"00181521=DSPositioner Secondary Angle Increment",
  				"00181530=DSDetector Primary Angle",
  				"00181531=DSDetector Secondary Angle",
  				"00181600=CSShutter Shape",
  				"00181602=ISShutter Left Vertical Edge",
  				"00181604=ISShutter Right Vertical Edge",
  				"00181606=ISShutter Upper Horizontal Edge",
  				"00181608=ISShutter Lower Horizontal Edge",
  				"00181610=ISCenter of Circular Shutter",
  				"00181612=ISRadius of Circular Shutter",
  				"00181620=ISVertices of the Polygonal Shutter",
  				"00181700=ISCollimator Shape",
  				"00181702=ISCollimator Left Vertical Edge",
  				"00181704=ISCollimator Right Vertical Edge",
  				"00181706=ISCollimator Upper Horizontal Edge",
  				"00181708=ISCollimator Lower Horizontal Edge",
  				"00181710=ISCenter of Circular Collimator",
  				"00181712=ISRadius of Circular Collimator",
  				"00181720=ISVertices of the Polygonal Collimator",
  				"00185000=SHOutput Power",
  				"00185010=LOTransducer Data",
  				"00185012=DSFocus Depth",
  				"00185020=LOPreprocessing Function",
  				"00185021=LOPostprocessing Function",
  				"00185022=DSMechanical Index",
  				"00185024=DSThermal Index",
  				"00185026=DSCranial Thermal Index",
  				"00185027=DSSoft Tissue Thermal Index",
  				"00185028=DSSoft Tissue-focus Thermal Index",
  				"00185029=DSSoft Tissue-surface Thermal Index",
  				"00185050=ISDepth of Scan Field",
  				"00185100=CSPatient Position",
  				"00185101=CSView Position",
  				"00185104=SQProjection Eponymous Name Code Sequence",
  				"00185210=DSImage Transformation Matrix",
  				"00185212=DSImage Translation Vector",
  				"00186000=DSSensitivity",
  				"00186011=SQSequence of Ultrasound Regions",
  				"00186012=USRegion Spatial Format",
  				"00186014=USRegion Data Type",
  				"00186016=ULRegion Flags",
  				"00186018=ULRegion Location Min X0",
  				"0018601A=ULRegion Location Min Y0",
  				"0018601C=ULRegion Location Max X1",
  				"0018601E=ULRegion Location Max Y1",
  				"00186020=SLReference Pixel X0",
  				"00186022=SLReference Pixel Y0",
  				"00186024=USPhysical Units X Direction",
  				"00186026=USPhysical Units Y Direction",
  				"00181628=FDReference Pixel Physical Value X",
  				"0018602A=FDReference Pixel Physical Value Y",
  				"0018602C=FDPhysical Delta X",
  				"0018602E=FDPhysical Delta Y",
  				"00186030=ULTransducer Frequency",
  				"00186031=CSTransducer Type",
  				"00186032=ULPulse Repetition Frequency",
  				"00186034=FDDoppler Correction Angle",
  				"00186036=FDSterring Angle",
  				"00186038=ULDoppler Sample Volume X Position",
  				"0018603A=ULDoppler Sample Volume Y Position",
  				"0018603C=ULTM-Line Position X0",
  				"0018603E=ULTM-Line Position Y0",
  				"00186040=ULTM-Line Position X1",
  				"00186042=ULTM-Line Position Y1",
  				"00186044=USPixel Component Organization",
  				"00186046=ULPixel Component Mask",
  				"00186048=ULPixel Component Range Start",
  				"0018604A=ULPixel Component Range Stop",
  				"0018604C=USPixel Component Physical Units",
  				"0018604E=USPixel Component Data Type",
  				"00186050=ULNumber of Table Break Points",
  				"00186052=ULTable of X Break Points",
  				"00186054=FDTable of Y Break Points",
  				"00186056=ULNumber of Table Entries",
  				"00186058=ULTable of Pixel Values",
  				"0018605A=ULTable of Parameter Values",
  				"00187000=CSDetector Conditions Nominal Flag",
  				"00187001=DSDetector Temperature",
  				"00187004=CSDetector Type",
  				"00187005=CSDetector Configuration",
  				"00187006=LTDetector Description",
  				"00187008=LTDetector Mode",
  				"0018700A=SHDetector ID",
  				"0018700C=DADate of Last Detector Calibration",
  				"0018700E=TMTime of Last Detector Calibration",
  				"00187010=ISExposures on Detector Since Last Calibration",
  				"00187011=ISExposures on Detector Since Manufactured",
  				"00187012=DSDetector Time Since Last Exposure",
  				"00187014=DSDetector Active Time",
  				"00187016=DSDetector Activation Offset From Exposure",
  				"0018701A=DSDetector Binning",
  				"00187020=DSDetector Element Physical Size",
  				"00187022=DSDetector Element Spacing",
  				"00187024=CSDetector Active Shape",
  				"00187026=DSDetector Active Dimension(s)",
  				"00187028=DSDetector Active Origin",
  				"00187030=DSField of View Origin",
  				"00187032=DSField of View Rotation",
  				"00187034=CSField of View Horizontal Flip",
  				"00187040=LTGrid Absorbing Material",
  				"00187041=LTGrid Spacing Material",
  				"00187042=DSGrid Thickness",
  				"00187044=DSGrid Pitch",
  				"00187046=ISGrid Aspect Ratio",
  				"00187048=DSGrid Period",
  				"0018704C=DSGrid Focal Distance",
  				"00187050=LTFilter Material LT",
  				"00187052=DSFilter Thickness Minimum",
  				"00187054=DSFilter Thickness Maximum",
  				"00187060=CSExposure Control Mode",
  				"00187062=LTExposure Control Mode Description",
  				"00187064=CSExposure Status",
  				"00187065=DSPhototimer Setting",
  
  				"0020000D=UIStudy Instance UID",
  				"0020000E=UISeries Instance UID",
  				"00200010=SHStudy ID",
  				"00200011=ISSeries Number",
  				"00200012=ISAcquisition Number",
  				"00200013=ISImage Number",
  				"00200014=ISIsotope Number",
  				"00200015=ISPhase Number",
  				"00200016=ISInterval Number",
  				"00200017=ISTime Slot Number",
  				"00200018=ISAngle Number",
  				"00200020=CSPatient Orientation",
  				"00200022=USOverlay Number",
  				"00200024=USCurve Number",
  				"00200030=DSImage Position",
  				"00200032=DSImage Position (Patient)",
  				"00200037=DSImage Orientation (Patient)",
  				"00200050=DSLocation",
  				"00200052=UIFrame of Reference UID",
  				"00200060=CSLaterality",
  				"00200070=LOImage Geometry Type",
  				"00200080=UIMasking Image UID",
  				"00200100=ISTemporal Position Identifier",
  				"00200105=ISNumber of Temporal Positions",
  				"00200110=DSTemporal Resolution",
  				"00201000=ISSeries in Study",
  				"00201002=ISImages in Acquisition",
  				"00201004=ISAcquisition in Study",
  				"00201040=LOPosition Reference Indicator",
  				"00201041=DSSlice Location",
  				"00201070=ISOther Study Numbers",
  				"00201200=ISNumber of Patient Related Studies",
  				"00201202=ISNumber of Patient Related Series",
  				"00201204=ISNumber of Patient Related Images",
  				"00201206=ISNumber of Study Related Series",
  				"00201208=ISNumber of Study Related Images",
  				"00204000=LTImage Comments",
  				
  				"00211002=FLtest X",
  				
  				"00211005=UTDose",
  				"0021100A=UTdCU",
  				"0021100F=UTX-Ray Tube Voltage Current and Time",
  				
  				"00280002=USSamples per Pixel",
  				"00280004=CSPhotometric Interpretation",
  				"00280006=USPlanar Configuration",
  				"00280008=ISNumber of Frames",
  				"00280009=ATFrame Increment Pointer",
  				"00280010=USRows",
  				"00280011=USColumns",
  				"00280030=DSPixel Spacing",
  				"00280031=DSZoom Factor",
  				"00280032=DSZoom Center",
  				"00280034=ISPixel Aspect Ratio",
  				"00280051=CSCorrected Image",
  				"00280100=USBits Allocated",
  				"00280101=USBits Stored",
  				"00280102=USHigh Bit",
  				"00280103=USPixel Representation",
  				"00280106=USSmallest Image Pixel Value",
  				"00280107=USLargest Image Pixel Value",
  				"00280108=USSmallest Pixel Value in Series",
  				"00280109=USLargest Pixel Value in Series",
  				"00280120=USPixel Padding Value",
  				"00280300=CSQuality Control Image",
  				"00280301=CSBurned In Annotation",
  				"00281040=CSPixel Intensity Relationship",
  				"00281041=SSPixel Intensity Relationship Sign",
  				"00281050=DSWindow Center",
  				"00281051=DSWindow Width",
  				"00281052=DSRescale Intercept",
  				"00281053=DSRescale Slope",
  				"00281054=LORescale Type",
  				"00281055=LOWindow Center & Width Explanation",
  				"00281101=USRed Palette Color Lookup Table Descriptor",
  				"00281102=USGreen Palette Color Lookup Table Descriptor",
  				"00281103=USBlue Palette Color Lookup Table Descriptor",
  				"00281201=USRed Palette Color Lookup Table Data",
  				"00281202=USGreen Palette Color Lookup Table Data",
  				"00281203=USBlue Palette Color Lookup Table Data",
  				"00282110=CSLossy Image Compression",
  				"00283000=SQModality LUT Sequence",
  				"00283002=USLUT Descriptor",
  				"00283003=LOLUT Explanation",
  				"00283004=LOMadality LUT Type",
  				"00283006=USLUT Data",
  				"00283010=SQVOI LUT Sequence",
  
  				"30020011=DSImage Plane Pixel Spacing",
  				"30020022=DSRadiation Machine SAD",
  				"30020026=DSRT IMAGE SID",
  
  				"0032000A=CSStudy Status ID",
  				"0032000C=CSStudy Priority ID",
  				"00320012=LOStudy ID Issuer",
  				"00320032=DAStudy Verified Date",
  				"00320033=TMStudy Verified Time",
  				"00320034=DAStudy Read Date",
  				"00320035=TMStudy Read Time",
  				"00321000=DAScheduled Study Start Date",
  				"00321001=TMScheduled Study Start Time",
  				"00321010=DAScheduled Study Stop Date",
  				"00321011=TMScheduled Study Stop Time",
  				"00321020=LOScheduled Study Location",
  				"00321021=AEScheduled Study Location AE Title(s)",
  				"00321030=LOReason for Study",
  				"00321032=PNRequesting Physician",
  				"00321033=LORequesting Service",
  				"00321040=DAStudy Arrival Date",
  				"00321041=TMStudy Arrival Time",
  				"00321050=DAStudy Completion Date",
  				"00321051=TMStudy Completion Time",
  				"00321055=CSStudy Component Status ID",
  				"00321060=LORequested Procedure Description",
  				"00321064=SQRequested Procedure Code Sequence",
  				"00321070=LORequested Contrast Agent",
  				"00324000=LTStudy Comments",
  
  				"00400001=AEScheduled Station AE Title",
  				"00400002=DAScheduled Procedure Step Start Date",
  				"00400003=TMScheduled Procedure Step Start Time",
  				"00400004=DAScheduled Procedure Step End Date",
  				"00400005=TMScheduled Procedure Step End Time",
  				"00400006=PNScheduled Performing Physician's Name",
  				"00400007=LOScheduled Procedure Step Description",
  				"00400008=SQScheduled Action Item Code Sequence",
  				"00400009=SHScheduled Procedure Step ID",
  				"00400010=SHScheduled Station Name",
  				"00400011=SHScheduled Procedure Step Location",
  				"00400012=LOPre-Medication",
  				"00400020=CSScheduled Procedure Step Status",
  				"00400100=SQScheduled Procedure Step Sequence",
  				"00400220=SQReferenced Standalone SOP Instance Sequence",
  				"00400241=AEPerformed Station AE Title",
  				"00400242=SHPerformed Station Name",
  				"00400243=SHPerformed Location",
  				"00400244=DAPerformed Procedure Step Start Date",
  				"00400245=TMPerformed Procedure Step Start Time",
  				"00400250=DAPerformed Procedure Step End Date",
  				"00400251=TMPerformed Procedure Step End Time",
  				"00400252=CSPerformed Procedure Step Status",
  				"00400253=SHPerformed Procedure Step ID",
  				"00400254=LOPerformed Procedure Step Description",
  				"00400255=LOPerformed Procedure Type Description",
  				"00400260=SQPerformed Action Item Sequence",
  				"00400270=SQScheduled Step Attributes Sequence",
  				"00400275=SQRequest Attributes Sequence",
  				"00400280=STComments on the Performed Procedure Steps",
  				"00400293=SQQuantity Sequence",
  				"00400294=DSQuantity",
  				"00400295=SQMeasuring Units Sequence",
  				"00400296=SQBilling Item Sequence",
  				"00400300=USTotal Time of Fluoroscopy",
  				"00400301=USTotal Number of Exposures",
  				"00400302=USEntrance Dose",
  				"00400303=USExposed Area",
  				"00400306=DSDistance Source to Entrance",
  				"00400307=DSDistance Source to Support",
  				"00400310=STComments on Radiation Dose",
  				"00400312=DSX-Ray Output",
  				"00400314=DSHalf Value Layer",
  				"00400316=DSOrgan Dose",
  				"00400318=CSOrgan Exposed",
  				"00400320=SQBilling Procedure Step Sequence",
  				"00400321=SQFilm Consumption Sequence",
  				"00400324=SQBilling Supplies and Devices Sequence",
  				"00400330=SQReferenced Procedure Step Sequence",
  				"00400340=SQPerformed Series Sequence",
  				"00400400=LTComments on the Scheduled Procedure Step",
  				"0040050A=LOSpecimen Accession Number",
  				"00400550=SQSpecimen Sequence",
  				"00400551=LOSpecimen Identifier",
  				"0040059A=SQSpecimen Type Code Sequence",
  				"00400555=SQAcquisition Context Sequence",
  				"00400556=STAcquisition Context Description",
  				"004006FA=LOSlide Identifier",
  				"0040071A=SQImage Center Point Coordinates Sequence",
  				"0040072A=DSX offset in Slide Coordinate System",
  				"0040073A=DSY offset in Slide Coordinate System",
  				"0040074A=DSZ offset in Slide Coordinate System",
  				"004008D8=SQPixel Spacing Sequence",
  				"004008DA=SQCoordinate System Axis Code Sequence",
  				"004008EA=SQMeasurement Units Code Sequence",
  				"00401001=SHRequested Procedure ID",
  				"00401002=LOReason for the Requested Procedure",
  				"00401003=SHRequested Procedure Priority",
  				"00401004=LOPatient Transport Arrangements",
  				"00401005=LORequested Procedure Location",
  				"00401006= 1Placer Order Number / Procedure S",
  				"00401007= 1Filler Order Number / Procedure S",
  				"00401008=LOConfidentiality Code",
  				"00401009=SHReporting Priority",
  				"00401010=PNNames of Intended Recipients of Results",
  				"00401400=LTRequested Procedure Comments",
  				"00402001=LOReason for the Imaging Service Request",
  				"00402004=DAIssue Date of Imaging Service Request",
  				"00402005=TMIssue Time of Imaging Service Request",
  				"00402006= 1Placer Order Number / Imaging Service Request S",
  				"00402007= 1Filler Order Number / Imaging Service Request S",
  				"00402008=PNOrder Entered By",
  				"00402009=SHOrder Enterers Location",
  				"00402010=SHOrder Callback Phone Number",
  				"00402016=LOPlacer Order Number / Imaging Service Request",
  				"00402017=LOFiller Order Number / Imaging Service Request",
  				"00402400=LTImaging Service Request Comments",
  				"00403001=LOConfidentiality Constraint on Patient Data Description",
  				"00408302=DSEntrance Dose in mGy",
  				"0040A010=CSRelationship Type",
  				"0040A027=LOVerifying Organization",
  				"0040A030=DTVerification DateTime",
  				"0040A032=DTObservation DateTime",
  				"0040A040=CSValue Type",
  				"0040A043=SQConcept-name Code Sequence",
  				"0040A050=CSContinuity Of Content",
  				"0040A073=SQVerifying Observer Sequence",
  				"0040A075=PNVerifying Observer Name",
  				"0040A088=SQVerifying Observer Identification Code Sequence",
  				"0040A0B0=USReferenced Waveform Channels",
  				"0040A120=DTDateTime",
  				"0040A121=DADate",
  				"0040A122=TMTime",
  				"0040A123=PNPerson Name",
  				"0040A124=UIUID",
  				"0040A130=CSTemporal Range Type",
  				"0040A132=ULReferenced Sample Positions",
  				"0040A136=USReferenced Frame Numbers",
  				"0040A138=DSReferenced Time Offsets",
  				"0040A13A=DTReferenced Datetime",
  				"0040A160=UTText Value",
  				"0040A168=SQConcept Code Sequence",
  				"0040A180=USAnnotation Group Number",
  				"0040A195=SQModifier Code Sequence",
  				"0040A300=SQMeasured Value Sequence",
  				"0040A30A=DSNumeric Value",
  				"0040A360=SQPredecessor Documents Sequence",
  				"0040A370=SQReferenced Request Sequence",
  				"0040A372=SQPerformed Procedure Code Sequence",
  				"0040A375=SQCurrent Requested Procedure Evidence Sequence",
  				"0040A385=SQPertinent Other Evidence Sequence",
  				"0040A491=CSCompletion Flag",
  				"0040A492=LOCompletion Flag Description",
  				"0040A493=CSVerification Flag",
  				"0040A504=SQContent Template Sequence",
  				"0040A525=SQIdentical Documents Sequence",
  				"0040A730=SQContent Sequence",
  				"0040B020=SQAnnotation Sequence",
  				"0040DB00=CSTemplate Identifier",
  				"0040DB06=DTTemplate Version",
  				"0040DB07=DTTemplate Local Version",
  				"0040DB0B=CSTemplate Extension Flag",
  				"0040DB0C=UITemplate Extension Organization UID",
  				"0040DB0D=UITemplate Extension Creator UID",
  				"0040DB73=ULReferenced Content Item Identifier",
  
  				"00540011=USNumber of Energy Windows",
  				"00540012=SQEnergy Window Information Sequence",
  				"00540013=SQEnergy Window Range Sequence",
  				"00540014=DSEnergy Window Lower Limit",
  				"00540015=DSEnergy Window Upper Limit",
  				"00540016=SQRadiopharmaceutical Information Sequence",
  				"00540017=ISResidual Syringe Counts",
  				"00540018=SHEnergy Window Name",
  				"00540020=USDetector Vector",
  				"00540021=USNumber of Detectors",
  				"00540022=SQDetector Information Sequence",
  				"00540030=USPhase Vector",
  				"00540031=USNumber of Phases",
  				"00540032=SQPhase Information Sequence",
  				"00540033=USNumber of Frames in Phase",
  				"00540036=ISPhase Delay",
  				"00540038=ISPause Between Frames",
  				"00540039=CSPhase Description",
  				"00540050=USRotation Vector",
  				"00540051=USNumber of Rotations",
  				"00540052=SQRotation Information Sequence",
  				"00540053=USNumber of Frames in Rotation",
  				"00540060=USR-R Interval Vector",
  				"00540061=USNumber of R-R Intervals",
  				"00540062=SQGated Information Sequence",
  				"00540063=SQData Information Sequence",
  				"00540070=USTime Slot Vector",
  				"00540071=USNumber of Time Slots",
  				"00540072=SQTime Slot Information Sequence",
  				"00540073=DSTime Slot Time",
  				"00540080=USSlice Vector",
  				"00540081=USNumber of Slices",
  				"00540090=USAngular View Vector",
  				"00540100=USTime Slice Vector",
  				"00540101=USNumber of Time Slices",
  				"00540200=DSStart Angle",
  				"00540202=CSType of Detector Motion",
  				"00540210=ISTrigger Vector",
  				"00540211=USNumber of Triggers in Phase",
  				"00540220=SQView Code Sequence",
  				"00540222=SQView Modifier Code Sequence",
  				"00540300=SQRadionuclide Code Sequence",
  				"00540302=SQAdministration Route Code Sequence",
  				"00540304=SQRadiopharmaceutical Code Sequence",
  				"00540306=SQCalibration Data Sequence",
  				"00540308=USEnergy Window Number",
  				"00540400=SHImage ID",
  				"00540410=SQPatient Orientation Code Sequence",
  				"00540412=SQPatient Orientation Modifier Code Sequence",
  				"00540414=SQPatient Gantry Relationship Code Sequence",
  				"00540500=CSSlice Progression Direction",
  				"00541000=CSSeries Type",
  				"00541001=CSUnits",
  				"00541002=CSCounts Source",
  				"00541004=CSReprojection Method",
  				"00541100=CSRandoms Correction Method",
  				"00541101=LOAttenuation Correction Method",
  				"00541102=CSDecay Correction",
  				"00541103=LOReconstruction Method",
  				"00541104=LODetector Lines of Response Used",
  				"00541105=LOScatter Correction Method",
  				"00541200=DSAxial Acceptance",
  				"00541201=ISAxial Mash",
  				"00541202=ISTransverse Mash",
  				"00541203=DSDetector Element Size",
  				"00541210=DSCoincidence Window Width",
  				"00541220=CSSecondary Counts Type",
  				"00541300=DSFrame Reference Time",
  				"00541310=ISPrimary (Prompts) Counts Accumulated",
  				"00541311=ISSecondary Counts Accumulated",
  				"00541320=DSSlice Sensitivity Factor",
  				"00541321=DSDecay Factor",
  				"00541322=DSDose Calibration Factor",
  				"00541323=DSScatter Fraction Factor",
  				"00541324=DSDead Time Factor",
  				"00541330=USImage Index",
  				"00541400=CSCounts Included",
  				"00541401=CSDead Time Correction Flag",
  
  				"30020002=SHRT Image Label",
  				"30020003=LORT Image Name",
  				"30020004=STRT Image Description",
  				"3002000A=CSReported Values Origin",
  				"3002000C=CSRT Image Plane",
  				"3002000D=DSX-Ray Image Receptor Translation",
  				"3002000E=DSX-Ray Image Receptor Angle",
  				"30020011=DSImage Plane Pixel Spacing",
  				"30020012=DSRT Image Position",
  				"30020020=SHRadiation Machine Name",
  				"30020022=DSRadiation Machine SAD",
  				"30020026=DSRT Image SID",
  				"30020029=ISFraction Number",
  				"30020030=SQExposure Sequence",
  				"30020032=DSMeterset Exposure",
  
  				"300A011E=DSGantry Angle",
  				"300A0120=DSBeam Limiting Device Angle",
  				"300A0122=DSPatient Support Angle",
  				"300A0128=DSTable Top Vertical Position",
  				"300A0129=DSTable Top Longitudinal Position",
  				"300A012A=DSTable Top Lateral Position",
  				"300A00B3=CSPrimary Dosimeter Unit",
  				"300A00F0=ISNumber of Blocks",
  
  				"300C0006=ISReferenced Beam Number",
  				"300C0008=DSStart Cumulative Meterset Weight",
  				"300C0022=ISReferenced Fraction Group Number",
  
  				"7FE00010=OXPixel Data",
  
  				"FFFEE000=DLItem",
  				"FFFEE00D=DLItem Delimitation Item",
  				"FFFEE0DD=DLSequence Delimitation Item"
  		};
  
  	}
  
  	
  }
  
  /*
   * Copyright (C) 2010-2014 - Andreas Maier 
   * CONRAD is developed as an Open Source project under the GNU General Public License (GPL).
  */
  