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