001/* ***** BEGIN LICENSE BLOCK *****
002 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
003 *
004 * The contents of this file are subject to the Mozilla Public License Version
005 * 1.1 (the "License"); you may not use this file except in compliance with
006 * the License. You may obtain a copy of the License at
007 * http://www.mozilla.org/MPL/
008 *
009 * Software distributed under the License is distributed on an "AS IS" basis,
010 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
011 * for the specific language governing rights and limitations under the
012 * License.
013 *
014 * The Original Code is part of dcm4che, an implementation of DICOM(TM) in
015 * Java(TM), hosted at https://github.com/gunterze/dcm4che.
016 *
017 * The Initial Developer of the Original Code is
018 * Agfa Healthcare.
019 * Portions created by the Initial Developer are Copyright (C) 2011
020 * the Initial Developer. All Rights Reserved.
021 *
022 * Contributor(s):
023 * See @authors listed below
024 *
025 * Alternatively, the contents of this file may be used under the terms of
026 * either the GNU General Public License Version 2 or later (the "GPL"), or
027 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
028 * in which case the provisions of the GPL or the LGPL are applicable instead
029 * of those above. If you wish to allow use of your version of this file only
030 * under the terms of either the GPL or the LGPL, and not to allow others to
031 * use your version of this file under the terms of the MPL, indicate your
032 * decision by deleting the provisions above and replace them with the notice
033 * and other provisions required by the GPL or the LGPL. If you do not delete
034 * the provisions above, a recipient may use your version of this file under
035 * the terms of any one of the MPL, the GPL or the LGPL.
036 *
037 * ***** END LICENSE BLOCK ***** */
038
039package org.dcm4che3.data;
040
041import java.util.Date;
042import java.util.TimeZone;
043
044import org.slf4j.Logger;
045import org.slf4j.LoggerFactory;
046
047/**
048 * @author Gunter Zeilinger <gunterze@gmail.com>
049 */
050public enum VR {
051    /**
052     * Application Entity
053     */
054    AE(0x4145, 8, ' ', StringValueType.ASCII, false),
055
056    /**
057     * Age String
058     */
059    AS(0x4153, 8, ' ', StringValueType.ASCII, false),
060
061    /**
062     * Attribute Tag
063     */
064    AT(0x4154, 8, 0, BinaryValueType.TAG, false),
065
066    /**
067     * Code String
068     */
069    CS(0x4353, 8, ' ', StringValueType.ASCII, false),
070
071    /**
072     * Date
073     */
074    DA(0x4441, 8, ' ', StringValueType.DA, false),
075
076    /**
077     * Decimal String
078     */
079    DS(0x4453, 8, ' ', StringValueType.DS, false),
080
081    /**
082     * Date Time
083     */
084    DT(0x4454, 8, ' ', StringValueType.DT, false),
085
086    /**
087     * Floating Point Double
088     */
089    FD(0x4644, 8, 0, BinaryValueType.DOUBLE, false),
090
091    /**
092     * Floating Point Single
093     */
094    FL(0x464c, 8, 0, BinaryValueType.FLOAT, false),
095
096    /**
097     * Integer String
098     */
099    IS(0x4953, 8, ' ', StringValueType.IS, false),
100
101    /**
102     * Long String
103     */
104    LO(0x4c4f, 8, ' ', StringValueType.STRING, false),
105
106    /**
107     * Long Text
108     */
109    LT(0x4c54, 8, ' ', StringValueType.TEXT, false),
110
111    /**
112     * Other Byte String
113     */
114    OB(0x4f42, 12, 0, BinaryValueType.BYTE, true),
115
116    /**
117     * Other Double String
118     */
119    OD(0x4f44, 12, 0, BinaryValueType.DOUBLE, true),
120
121    /**
122     * Other Float String
123     */
124    OF(0x4f46, 12, 0, BinaryValueType.FLOAT, true),
125
126    /**
127     * Other Long String
128     */
129    OL(0x4f4c, 12, 0, BinaryValueType.INT, true),
130
131    /**
132     * Other Word String
133     */
134    OW(0x4f57, 12, 0, BinaryValueType.SHORT, true),
135
136    /**
137     * Person Name
138     */
139    PN(0x504e, 8, ' ', StringValueType.PN, false),
140
141    /**
142     * Short String
143     */
144    SH(0x5348, 8, ' ', StringValueType.STRING, false),
145
146    /**
147     * Signed Long
148     */
149    SL(0x534c, 8, 0, BinaryValueType.INT, false),
150
151    /**
152     * Sequence of Items
153     */
154    SQ(0x5351, 12, 0, SequenceValueType.SQ, false),
155
156    /**
157     * Signed Short
158     */
159    SS(0x5353, 8, 0, BinaryValueType.SHORT, false),
160
161    /**
162     * Short Text
163     */
164    ST(0x5354, 8, ' ', StringValueType.TEXT, false),
165
166    /**
167     * Time
168     */
169    TM(0x544d, 8, ' ', StringValueType.TM, false),
170
171    /**
172     * Unlimited Characters
173     */
174    UC(0x5543, 12, ' ', StringValueType.STRING, false),
175
176    /**
177     * Unique Identifier (UID)
178     */
179    UI(0x5549, 8, 0, StringValueType.ASCII, false),
180
181    /**
182     * Unsigned Long
183     */
184    UL(0x554c, 8, 0, BinaryValueType.INT, false),
185
186    /**
187     * Unknown
188     */
189    UN(0x554e, 12, 0, BinaryValueType.BYTE, true),
190
191    /**
192     * Universal Resource Identifier or Universal Resource Locator (URI/URL)
193     */
194    UR(0x5552, 12, ' ', StringValueType.UR, false),
195
196    /**
197     * Unsigned Short
198     */
199    US(0x5553, 8, 0, BinaryValueType.USHORT, false),
200
201    /**
202     * Unlimited Text
203     */
204    UT(0x5554, 12, ' ', StringValueType.TEXT, false);
205
206    private static Logger LOG = LoggerFactory.getLogger(VR.class);
207
208    protected final int code;
209    protected final int headerLength;
210    protected final int paddingByte;
211    protected final ValueType valueType;
212    protected final boolean inlineBinary;
213
214    VR(int code, int headerLength, int paddingByte, ValueType valueType,
215            boolean inlineBinary) {
216        this.code = code;
217        this.headerLength = headerLength;
218        this.paddingByte = paddingByte;
219        this.valueType = valueType;
220        this.inlineBinary = inlineBinary;
221    }
222
223    private static int indexOf(int code) {
224        int code1 = code - 0x4141;
225        return (code1 & 0xffffe0e0) == 0 ? ((code1 & 0xff00) >> 3) + (code1 & 0xff) : -1;
226    }
227
228    private static final VR[] VALUE_OF = new VR[indexOf(UT.code)+1];
229    static {
230        for (VR vr : VR.values())
231            VALUE_OF[indexOf(vr.code)] = vr;
232    }
233
234    public static VR valueOf(int code) {
235        try {
236            VR vr = VALUE_OF[indexOf(code)];
237            if (vr != null)
238                return vr;
239        } catch (IndexOutOfBoundsException e) {}
240        LOG.warn("Unrecogniced VR code: {0}H - treat as UN",
241                Integer.toHexString(code));
242        return UN;
243    }
244
245    public int code() {
246        return code;
247    }
248
249    public int headerLength() {
250        return headerLength;
251    }
252
253    public int paddingByte() {
254        return paddingByte;
255    }
256
257    public boolean isTemporalType() {
258        return valueType.isTemporalType();
259    }
260
261    public boolean isStringType() {
262        return valueType.isStringValue();
263    }
264
265    public boolean useSpecificCharacterSet() {
266        return valueType.useSpecificCharacterSet();
267    }
268
269    public boolean isIntType() {
270        return valueType.isIntValue();
271    }
272
273    public boolean isInlineBinary() {
274        return inlineBinary;
275    }
276
277    public int numEndianBytes() {
278        return valueType.numEndianBytes();
279    }
280
281    public byte[] toggleEndian(byte[] b, boolean preserve) {
282        return valueType.toggleEndian(b, preserve);
283    }
284
285    public byte[] toBytes(Object val, SpecificCharacterSet cs) {
286        return valueType.toBytes(val, cs);
287    }
288
289    public Object toStrings(Object val, boolean bigEndian, SpecificCharacterSet cs) {
290        return valueType.toStrings(val, bigEndian, cs);
291    }
292
293    public String toString(Object val, boolean bigEndian, int valueIndex,
294            String defVal) {
295        return valueType.toString(val, bigEndian, valueIndex, defVal);
296    }
297
298    public int toInt(Object val, boolean bigEndian, int valueIndex, int defVal) {
299        return valueType.toInt(val, bigEndian, valueIndex, defVal);
300    }
301
302    public int[] toInts(Object val, boolean bigEndian) {
303        return valueType.toInts(val, bigEndian);
304    }
305
306    public float toFloat(Object  val, boolean bigEndian, int valueIndex, float defVal) {
307        return valueType.toFloat(val, bigEndian, valueIndex, defVal);
308    }
309
310    public float[] toFloats(Object val, boolean bigEndian) {
311        return valueType.toFloats(val, bigEndian);
312    }
313
314    public double toDouble(Object val, boolean bigEndian, int valueIndex,
315            double defVal) {
316        return valueType.toDouble(val, bigEndian, valueIndex, defVal);
317    }
318
319    public double[] toDoubles(Object val, boolean bigEndian) {
320        return valueType.toDoubles(val, bigEndian);
321    }
322
323    public Date toDate(Object val, TimeZone tz, int valueIndex, boolean ceil,
324            Date defVal, DatePrecision precision) {
325        return valueType.toDate(val, tz, valueIndex, ceil, defVal, precision);
326    }
327
328    public Date[] toDates(Object val, TimeZone tz, boolean ceil,
329            DatePrecisions precisions) {
330        return valueType.toDate(val, tz, ceil, precisions);
331    }
332
333    Object toValue(byte[] b) {
334        return valueType.toValue(b);
335    }
336
337    Object toValue(String s, boolean bigEndian) {
338        return valueType.toValue(s, bigEndian);
339    }
340
341    Object toValue(String[] ss, boolean bigEndian) {
342        return valueType.toValue(ss, bigEndian);
343    }
344
345    Object toValue(int[] is, boolean bigEndian) {
346        return valueType.toValue(is, bigEndian);
347    }
348
349    Object toValue(float[] fs, boolean bigEndian) {
350        return valueType.toValue(fs, bigEndian);
351    }
352
353    Object toValue(double[] ds, boolean bigEndian) {
354        return valueType.toValue(ds, bigEndian);
355    }
356
357    public Object toValue(Date[] ds, TimeZone tz, DatePrecision precision) {
358        return valueType.toValue(ds, tz, precision);
359    }
360
361    public boolean prompt(Object val, boolean bigEndian,
362            SpecificCharacterSet cs, int maxChars, StringBuilder sb) {
363        return valueType.prompt(val, bigEndian, cs, maxChars, sb);
364    }
365
366    public int vmOf(Object val) {
367        return headerLength == 12 ? 1 : valueType.vmOf(val);
368    }
369
370    public static class Holder {
371        public VR vr;
372    }
373}