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 041/** 042 * @author Gunter Zeilinger <gunterze@gmail.com> 043 */ 044public class ByteUtils { 045 046 public static final byte[] EMPTY_BYTES = {}; 047 public static final int[] EMPTY_INTS = {}; 048 public static final float[] EMPTY_FLOATS = {}; 049 public static final double[] EMPTY_DOUBLES = {}; 050 051 public static int bytesToVR(byte[] bytes, int off) { 052 return bytesToUShortBE(bytes, off); 053 } 054 055 public static int bytesToUShort(byte[] bytes, int off, boolean bigEndian) { 056 return bigEndian ? bytesToUShortBE(bytes, off) 057 : bytesToUShortLE(bytes, off); 058 } 059 060 public static int bytesToUShortBE(byte[] bytes, int off) { 061 return ((bytes[off] & 255) << 8) + (bytes[off + 1] & 255); 062 } 063 064 public static int bytesToUShortLE(byte[] bytes, int off) { 065 return ((bytes[off + 1] & 255) << 8) + (bytes[off] & 255); 066 } 067 068 public static int bytesToShort(byte[] bytes, int off, boolean bigEndian) { 069 return bigEndian ? bytesToShortBE(bytes, off) 070 : bytesToShortLE(bytes, off); 071 } 072 073 public static int bytesToShortBE(byte[] bytes, int off) { 074 return (bytes[off] << 8) + (bytes[off + 1] & 255); 075 } 076 077 public static int bytesToShortLE(byte[] bytes, int off) { 078 return (bytes[off + 1] << 8) + (bytes[off] & 255); 079 } 080 081 public static void bytesToShorts(byte[] src, int srcPos, short[] dest, int destPos, int length, boolean bigEndian) { 082 if (bigEndian) 083 bytesToShortsBE(src, srcPos, dest, destPos, length); 084 else 085 bytesToShortsLE(src, srcPos, dest, destPos, length); 086 } 087 088 public static void bytesToShortsBE(byte[] src, int srcPos, short[] dest, int destPos, int length) { 089 for (int i = 0; i < length; i++) 090 dest[destPos+i] = (short) bytesToShortBE(src, srcPos + (i << 1)); 091 } 092 093 public static void bytesToShortsLE(byte[] src, int srcPos, short[] dest, int destPos, int length) { 094 for (int i = 0; i < length; i++) 095 dest[destPos+i] = (short) bytesToShortLE(src, srcPos+(i<<1)); 096 } 097 098 public static int bytesToInt(byte[] bytes, int off, boolean bigEndian) { 099 return bigEndian ? bytesToIntBE(bytes, off) : bytesToIntLE(bytes, off); 100 } 101 102 public static int bytesToIntBE(byte[] bytes, int off) { 103 return (bytes[off] << 24) + ((bytes[off + 1] & 255) << 16) 104 + ((bytes[off + 2] & 255) << 8) + (bytes[off + 3] & 255); 105 } 106 107 public static int bytesToIntLE(byte[] bytes, int off) { 108 return (bytes[off + 3] << 24) + ((bytes[off + 2] & 255) << 16) 109 + ((bytes[off + 1] & 255) << 8) + (bytes[off] & 255); 110 } 111 112 public static int bytesToTag(byte[] bytes, int off, boolean bigEndian) { 113 return bigEndian ? bytesToTagBE(bytes, off) : bytesToTagLE(bytes, off); 114 } 115 116 public static int bytesToTagBE(byte[] bytes, int off) { 117 return bytesToIntBE(bytes, off); 118 } 119 120 public static int bytesToTagLE(byte[] bytes, int off) { 121 return (bytes[off + 1] << 24) + ((bytes[off] & 255) << 16) 122 + ((bytes[off + 3] & 255) << 8) + (bytes[off + 2] & 255); 123 } 124 125 public static float bytesToFloat(byte[] bytes, int off, boolean bigEndian) { 126 return bigEndian ? bytesToFloatBE(bytes, off) 127 : bytesToFloatLE(bytes, off); 128 } 129 130 public static float bytesToFloatBE(byte[] bytes, int off) { 131 return Float.intBitsToFloat(bytesToIntBE(bytes, off)); 132 } 133 134 public static float bytesToFloatLE(byte[] bytes, int off) { 135 return Float.intBitsToFloat(bytesToIntLE(bytes, off)); 136 } 137 138 public static long bytesToLong(byte[] bytes, int off, boolean bigEndian) { 139 return bigEndian ? bytesToLongBE(bytes, off) 140 : bytesToLongLE(bytes, off); 141 } 142 143 public static long bytesToLongBE(byte[] bytes, int off) { 144 return ((long) bytes[off] << 56) 145 + ((long) (bytes[off + 1] & 255) << 48) 146 + ((long) (bytes[off + 2] & 255) << 40) 147 + ((long) (bytes[off + 3] & 255) << 32) 148 + ((long) (bytes[off + 4] & 255) << 24) 149 + ((bytes[off + 5] & 255) << 16) 150 + ((bytes[off + 6] & 255) << 8) 151 + (bytes[off + 7] & 255); 152 } 153 154 public static long bytesToLongLE(byte[] bytes, int off) { 155 return ((long) bytes[off + 7] << 56) 156 + ((long) (bytes[off + 6] & 255) << 48) 157 + ((long) (bytes[off + 5] & 255) << 40) 158 + ((long) (bytes[off + 4] & 255) << 32) 159 + ((long) (bytes[off + 3] & 255) << 24) 160 + ((bytes[off + 2] & 255) << 16) 161 + ((bytes[off + 1] & 255) << 8) 162 + (bytes[off] & 255); 163 } 164 165 public static double bytesToDouble(byte[] bytes, int off, boolean bigEndian) { 166 return bigEndian ? bytesToDoubleBE(bytes, off) 167 : bytesToDoubleLE(bytes, off); 168 } 169 170 public static double bytesToDoubleBE(byte[] bytes, int off) { 171 return Double.longBitsToDouble(bytesToLongBE(bytes, off)); 172 } 173 174 public static double bytesToDoubleLE(byte[] bytes, int off) { 175 return Double.longBitsToDouble(bytesToLongLE(bytes, off)); 176 } 177 178 public static byte[] shortToBytes(int i, byte[] bytes, int off, 179 boolean bigEndian) { 180 return bigEndian ? shortToBytesBE(i, bytes, off) 181 : shortToBytesLE(i, bytes, off); 182 } 183 184 public static byte[] shortToBytesBE(int i, byte[] bytes, int off) { 185 bytes[off] = (byte) (i >> 8); 186 bytes[off + 1] = (byte) i; 187 return bytes; 188 } 189 190 public static byte[] shortToBytesLE(int i, byte[] bytes, int off) { 191 bytes[off + 1] = (byte) (i >> 8); 192 bytes[off] = (byte) i; 193 return bytes; 194 } 195 196 public static byte[] intToBytes(int i, byte[] bytes, int off, 197 boolean bigEndian) { 198 return bigEndian ? intToBytesBE(i, bytes, off) 199 : intToBytesLE(i, bytes, off); 200 } 201 202 public static byte[] intToBytesBE(int i, byte[] bytes, int off) { 203 bytes[off] = (byte) (i >> 24); 204 bytes[off + 1] = (byte) (i >> 16); 205 bytes[off + 2] = (byte) (i >> 8); 206 bytes[off + 3] = (byte) i; 207 return bytes; 208 } 209 210 public static byte[] intToBytesLE(int i, byte[] bytes, int off) { 211 bytes[off + 3] = (byte) (i >> 24); 212 bytes[off + 2] = (byte) (i >> 16); 213 bytes[off + 1] = (byte) (i >> 8); 214 bytes[off] = (byte) i; 215 return bytes; 216 } 217 218 public static byte[] tagToBytes(int i, byte[] bytes, int off, 219 boolean bigEndian) { 220 return bigEndian ? tagToBytesBE(i, bytes, off) 221 : tagToBytesLE(i, bytes, off); 222 } 223 224 public static byte[] tagToBytesBE(int i, byte[] bytes, int off) { 225 return intToBytesBE(i, bytes, off); 226 } 227 228 public static byte[] tagToBytesLE(int i, byte[] bytes, int off) { 229 bytes[off + 1] = (byte) (i >> 24); 230 bytes[off] = (byte) (i >> 16); 231 bytes[off + 3] = (byte) (i >> 8); 232 bytes[off + 2] = (byte) i; 233 return bytes; 234 } 235 236 public static byte[] floatToBytes(float f, byte[] bytes, int off, 237 boolean bigEndian) { 238 return bigEndian ? floatToBytesBE(f, bytes, off) 239 : floatToBytesLE(f, bytes, off); 240 } 241 242 public static byte[] floatToBytesBE(float f, byte[] bytes, int off) { 243 return intToBytesBE(Float.floatToIntBits(f), bytes, off); 244 } 245 246 public static byte[] floatToBytesLE(float f, byte[] bytes, int off) { 247 return intToBytesLE(Float.floatToIntBits(f), bytes, off); 248 } 249 250 public static byte[] doubleToBytes(double d, byte[] bytes, int off, 251 boolean bigEndian) { 252 return bigEndian ? doubleToBytesBE(d, bytes, off) 253 : doubleToBytesLE(d, bytes, off); 254 } 255 256 public static byte[] doubleToBytesBE(double d, byte[] bytes, int off) { 257 return longToBytesBE(Double.doubleToLongBits(d), bytes, off); 258 } 259 260 public static byte[] doubleToBytesLE(double d, byte[] bytes, int off) { 261 return longToBytesLE(Double.doubleToLongBits(d), bytes, off); 262 } 263 264 public static byte[] longToBytes(long l, byte[] bytes, int off, 265 boolean bigEndian) { 266 return bigEndian ? longToBytesBE(l, bytes, off) 267 : longToBytesLE(l, bytes, off); 268 } 269 270 public static byte[] longToBytesBE(long l, byte[] bytes, int off) { 271 bytes[off] = (byte) (l >> 56); 272 bytes[off + 1] = (byte) (l >> 48); 273 bytes[off + 2] = (byte) (l >> 40); 274 bytes[off + 3] = (byte) (l >> 32); 275 bytes[off + 4] = (byte) (l >> 24); 276 bytes[off + 5] = (byte) (l >> 16); 277 bytes[off + 6] = (byte) (l >> 8); 278 bytes[off + 7] = (byte) l; 279 return bytes; 280 } 281 282 public static byte[] longToBytesLE(long l, byte[] bytes, int off) { 283 bytes[off + 7] = (byte) (l >> 56); 284 bytes[off + 6] = (byte) (l >> 48); 285 bytes[off + 5] = (byte) (l >> 40); 286 bytes[off + 4] = (byte) (l >> 32); 287 bytes[off + 3] = (byte) (l >> 24); 288 bytes[off + 2] = (byte) (l >> 16); 289 bytes[off + 1] = (byte) (l >> 8); 290 bytes[off] = (byte) l; 291 return bytes; 292 } 293 294 public static byte[][] swapShorts(byte bs[][]) { 295 int carry = 0; 296 for (int i = 0; i < bs.length; i++) { 297 byte[] b = bs[i]; 298 if (carry != 0) 299 swapLastFirst(bs[i-1], b); 300 int len = b.length - carry; 301 swapShorts(b, carry, len & ~1); 302 carry = len & 1; 303 } 304 return bs; 305 } 306 307 public static byte[] swapShorts(byte b[], int off, int len) { 308 checkLength(len, 2); 309 for (int i = off, n = off + len; i < n; i += 2) 310 swap(b, i, i+1); 311 return b; 312 } 313 314 public static byte[] swapInts(byte b[], int off, int len) { 315 checkLength(len, 4); 316 for (int i = off, n = off + len; i < n; i += 4) { 317 swap(b, i, i+3); 318 swap(b, i+1, i+2); 319 } 320 return b; 321 } 322 323 public static byte[] swapLongs(byte b[], int off, int len) { 324 checkLength(len, 8); 325 for (int i = off, n = off + len; i < n; i += 8) { 326 swap(b, i, i+7); 327 swap(b, i+1, i+6); 328 swap(b, i+2, i+5); 329 swap(b, i+3, i+4); 330 } 331 return b; 332 } 333 334 private static void checkLength(int len, int numBytes) { 335 if (len < 0 || (len % numBytes) != 0) 336 throw new IllegalArgumentException("length: " + len); 337 } 338 339 private static void swap(byte[] bytes, int a, int b) { 340 byte t = bytes[a]; 341 bytes[a] = bytes[b]; 342 bytes[b] = t; 343 } 344 345 private static void swapLastFirst(byte[] b1, byte[] b2) { 346 int last = b1.length - 1; 347 byte t = b2[0]; 348 b2[0] = b1[last]; 349 b1[last] = t; 350 } 351 352}