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.util;
040
041import org.dcm4che3.data.Tag;
042
043/**
044 * @author Gunter Zeilinger <gunterze@gmail.com>
045 */
046public class TagUtils {
047
048    private static char[] HEX_DIGITS = {
049        '0', '1', '2', '3', '4', '5', '6', '7',
050        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
051    };
052
053    public static String shortToHexString(int n) {
054        char[] s = {
055                HEX_DIGITS[(n >>> 12) & 0xF],
056                HEX_DIGITS[(n >>> 8) & 0xF],
057                HEX_DIGITS[(n >>> 4) & 0xF],
058                HEX_DIGITS[(n >>> 0) & 0xF] };
059        return new String(s);
060    }
061
062    public static String toHexString(int tag) {
063        char[] s = {
064                HEX_DIGITS[(tag >>> 28)],
065                HEX_DIGITS[(tag >>> 24) & 0xF],
066                HEX_DIGITS[(tag >>> 20) & 0xF],
067                HEX_DIGITS[(tag >>> 16) & 0xF],
068                HEX_DIGITS[(tag >>> 12) & 0xF],
069                HEX_DIGITS[(tag >>> 8) & 0xF],
070                HEX_DIGITS[(tag >>> 4) & 0xF],
071                HEX_DIGITS[(tag >>> 0) & 0xF] };
072        return new String(s);
073    }
074
075    public static String toHexString(byte[] b) {
076        char[] s = new char[b.length << 1];
077        for (int i = 0, j = 0; i < b.length; i++) {
078            s[j++] = HEX_DIGITS[(b[i] >>> 4) & 0xF];
079            s[j++] = HEX_DIGITS[b[i] & 0xF];
080        }
081        return new String(s);
082    }
083
084    public static String toString(int tag) {
085        char[] s = {
086                '(',
087                HEX_DIGITS[(tag >>> 28)],
088                HEX_DIGITS[(tag >>> 24) & 0xF],
089                HEX_DIGITS[(tag >>> 20) & 0xF],
090                HEX_DIGITS[(tag >>> 16) & 0xF],
091                ',',
092                HEX_DIGITS[(tag >>> 12) & 0xF],
093                HEX_DIGITS[(tag >>> 8) & 0xF],
094                HEX_DIGITS[(tag >>> 4) & 0xF],
095                HEX_DIGITS[(tag >>> 0) & 0xF],
096                ')'};
097        return new String(s);
098    }
099
100    public static int groupNumber(int tag) {
101        return tag >>> 16;
102    }
103
104    public static int elementNumber(int tag) {
105        return tag & 0xFFFF;
106    }
107
108    public static boolean isGroupLength(int tag) {
109        return elementNumber(tag) == 0;
110    }
111
112    public static boolean isPrivateCreator(int tag) {
113        return (tag & 0x00010000) != 0
114            && (tag & 0x0000FF00) == 0
115            && (tag & 0x000000F0) != 0;
116    }
117
118    public static boolean isPrivateGroup(int tag) {
119        return (tag & 0x00010000) != 0;
120    }
121
122    public static boolean isPrivateTag(int tag) {
123        return (tag & 0x00010000) != 0
124            && (tag & 0x0000FF00) != 0;
125    }
126
127    public static int toTag(int groupNumber, int elementNumber) {
128        return groupNumber << 16 | elementNumber;
129    }
130
131    public static int toPrivateTag(int creatorTag, int elementNumber) {
132        return (creatorTag & 0xffff0000) 
133             | ((creatorTag & 0xff) << 8
134             | (elementNumber & 0xff));
135    }
136
137    public static int creatorTagOf(int tag) {
138        return (tag & 0xffff0000) | ((tag >>> 8) & 0xff);
139    }
140
141    public static int groupLengthTagOf(int tag) {
142        return tag & 0xffff0000;
143    }
144
145    public static boolean isItem(int tag) {
146        return tag == Tag.Item
147            || tag == Tag.ItemDelimitationItem
148            || tag == Tag.SequenceDelimitationItem;
149    }
150
151    public static boolean isFileMetaInformation(int tag) {
152        return (tag & 0xffff0000) == 0x00020000;
153    }
154
155    public static int normalizeRepeatingGroup(int tag) {
156        int gg000000 = tag & 0xffe00000;
157        return (gg000000 == 0x50000000
158             || gg000000 == 0x60000000)
159                    ? tag & 0xffe0ffff
160                    : tag;
161    }
162
163    public static int forName(String name) {
164        try {
165            return Integer.parseInt(name, 16);
166        } catch (NumberFormatException nfe) {
167            try {
168                return Tag.class.getField(name).getInt(null);
169            } catch (Exception e) {
170                return -1;
171            }
172        }
173    }
174
175    public static int[] parseTagPath(String tagPath) {
176        String[] names = StringUtils.split(tagPath, '.');
177        int[] tags = new int[names.length];
178        for (int i = 0; i < tags.length; i++)
179            if ((tags[i] = forName(names[i])) == -1)
180                throw new IllegalArgumentException("tagPath: " + tagPath);
181        return tags;
182    }
183
184}
185