001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.imaging.common; 018 019import java.nio.ByteOrder; 020 021/** 022 * Convenience methods for converting data types to and from 023 * byte arrays. 024 */ 025public final class ByteConversions { 026 private ByteConversions() { 027 } 028 029 public static byte[] toBytes(final short value, final ByteOrder byteOrder) { 030 final byte[] result = new byte[2]; 031 toBytes(value, byteOrder, result, 0); 032 return result; 033 } 034 035 public static byte[] toBytes(final short[] values, final ByteOrder byteOrder) { 036 return toBytes(values, 0, values.length, byteOrder); 037 } 038 039 private static byte[] toBytes(final short[] values, final int offset, final int length, final ByteOrder byteOrder) { 040 final byte[] result = new byte[length * 2]; 041 for (int i = 0; i < length; i++) { 042 toBytes(values[offset + i], byteOrder, result, i * 2); 043 } 044 return result; 045 } 046 047 private static void toBytes(final short value, final ByteOrder byteOrder, final byte[] result, final int offset) { 048 if (byteOrder == ByteOrder.BIG_ENDIAN) { 049 result[offset + 0] = (byte) (value >> 8); 050 result[offset + 1] = (byte) (value >> 0); 051 } else { 052 result[offset + 1] = (byte) (value >> 8); 053 result[offset + 0] = (byte) (value >> 0); 054 } 055 } 056 057 public static byte[] toBytes(final int value, final ByteOrder byteOrder) { 058 final byte[] result = new byte[4]; 059 toBytes(value, byteOrder, result, 0); 060 return result; 061 } 062 063 public static byte[] toBytes(final int[] values, final ByteOrder byteOrder) { 064 return toBytes(values, 0, values.length, byteOrder); 065 } 066 067 private static byte[] toBytes(final int[] values, final int offset, final int length, final ByteOrder byteOrder) { 068 final byte[] result = new byte[length * 4]; 069 for (int i = 0; i < length; i++) { 070 toBytes(values[offset + i], byteOrder, result, i * 4); 071 } 072 return result; 073 } 074 075 private static void toBytes(final int value, final ByteOrder byteOrder, final byte[] result, final int offset) { 076 if (byteOrder == ByteOrder.BIG_ENDIAN) { 077 result[offset + 0] = (byte) (value >> 24); 078 result[offset + 1] = (byte) (value >> 16); 079 result[offset + 2] = (byte) (value >> 8); 080 result[offset + 3] = (byte) (value >> 0); 081 } else { 082 result[offset + 3] = (byte) (value >> 24); 083 result[offset + 2] = (byte) (value >> 16); 084 result[offset + 1] = (byte) (value >> 8); 085 result[offset + 0] = (byte) (value >> 0); 086 } 087 } 088 089 public static byte[] toBytes(final float value, final ByteOrder byteOrder) { 090 final byte[] result = new byte[4]; 091 toBytes(value, byteOrder, result, 0); 092 return result; 093 } 094 095 public static byte[] toBytes(final float[] values, final ByteOrder byteOrder) { 096 return toBytes(values, 0, values.length, byteOrder); 097 } 098 099 private static byte[] toBytes(final float[] values, final int offset, final int length, final ByteOrder byteOrder) { 100 final byte[] result = new byte[length * 4]; 101 for (int i = 0; i < length; i++) { 102 toBytes(values[offset + i], byteOrder, result, i * 4); 103 } 104 return result; 105 } 106 107 private static void toBytes(final float value, final ByteOrder byteOrder, final byte[] result, final int offset) { 108 final int bits = Float.floatToRawIntBits(value); 109 if (byteOrder == ByteOrder.LITTLE_ENDIAN) { 110 result[offset + 0] = (byte) (0xff & (bits >> 0)); 111 result[offset + 1] = (byte) (0xff & (bits >> 8)); 112 result[offset + 2] = (byte) (0xff & (bits >> 16)); 113 result[offset + 3] = (byte) (0xff & (bits >> 24)); 114 } else { 115 result[offset + 3] = (byte) (0xff & (bits >> 0)); 116 result[offset + 2] = (byte) (0xff & (bits >> 8)); 117 result[offset + 1] = (byte) (0xff & (bits >> 16)); 118 result[offset + 0] = (byte) (0xff & (bits >> 24)); 119 } 120 } 121 122 public static byte[] toBytes(final double value, final ByteOrder byteOrder) { 123 final byte[] result = new byte[8]; 124 toBytes(value, byteOrder, result, 0); 125 return result; 126 } 127 128 public static byte[] toBytes(final double[] values, final ByteOrder byteOrder) { 129 return toBytes(values, 0, values.length, byteOrder); 130 } 131 132 private static byte[] toBytes(final double[] values, final int offset, 133 final int length, final ByteOrder byteOrder) { 134 final byte[] result = new byte[length * 8]; 135 for (int i = 0; i < length; i++) { 136 toBytes(values[offset + i], byteOrder, result, i * 8); 137 } 138 return result; 139 } 140 141 private static void toBytes(final double value, final ByteOrder byteOrder, final byte[] result, final int offset) { 142 final long bits = Double.doubleToRawLongBits(value); 143 if (byteOrder == ByteOrder.LITTLE_ENDIAN) { 144 result[offset + 0] = (byte) (0xff & (bits >> 0)); 145 result[offset + 1] = (byte) (0xff & (bits >> 8)); 146 result[offset + 2] = (byte) (0xff & (bits >> 16)); 147 result[offset + 3] = (byte) (0xff & (bits >> 24)); 148 result[offset + 4] = (byte) (0xff & (bits >> 32)); 149 result[offset + 5] = (byte) (0xff & (bits >> 40)); 150 result[offset + 6] = (byte) (0xff & (bits >> 48)); 151 result[offset + 7] = (byte) (0xff & (bits >> 56)); 152 } else { 153 result[offset + 7] = (byte) (0xff & (bits >> 0)); 154 result[offset + 6] = (byte) (0xff & (bits >> 8)); 155 result[offset + 5] = (byte) (0xff & (bits >> 16)); 156 result[offset + 4] = (byte) (0xff & (bits >> 24)); 157 result[offset + 3] = (byte) (0xff & (bits >> 32)); 158 result[offset + 2] = (byte) (0xff & (bits >> 40)); 159 result[offset + 1] = (byte) (0xff & (bits >> 48)); 160 result[offset + 0] = (byte) (0xff & (bits >> 56)); 161 } 162 } 163 164 public static byte[] toBytes(final RationalNumber value, final ByteOrder byteOrder) { 165 final byte[] result = new byte[8]; 166 toBytes(value, byteOrder, result, 0); 167 return result; 168 } 169 170 public static byte[] toBytes(final RationalNumber[] values, final ByteOrder byteOrder) { 171 return toBytes(values, 0, values.length, byteOrder); 172 } 173 174 private static byte[] toBytes(final RationalNumber[] values, final int offset, 175 final int length, final ByteOrder byteOrder) { 176 final byte[] result = new byte[length * 8]; 177 for (int i = 0; i < length; i++) { 178 toBytes(values[offset + i], byteOrder, result, i * 8); 179 } 180 return result; 181 } 182 183 private static void toBytes(final RationalNumber value, final ByteOrder byteOrder, 184 final byte[] result, final int offset) { 185 if (byteOrder == ByteOrder.BIG_ENDIAN) { 186 result[offset + 0] = (byte) (value.numerator >> 24); 187 result[offset + 1] = (byte) (value.numerator >> 16); 188 result[offset + 2] = (byte) (value.numerator >> 8); 189 result[offset + 3] = (byte) (value.numerator >> 0); 190 result[offset + 4] = (byte) (value.divisor >> 24); 191 result[offset + 5] = (byte) (value.divisor >> 16); 192 result[offset + 6] = (byte) (value.divisor >> 8); 193 result[offset + 7] = (byte) (value.divisor >> 0); 194 } else { 195 result[offset + 3] = (byte) (value.numerator >> 24); 196 result[offset + 2] = (byte) (value.numerator >> 16); 197 result[offset + 1] = (byte) (value.numerator >> 8); 198 result[offset + 0] = (byte) (value.numerator >> 0); 199 result[offset + 7] = (byte) (value.divisor >> 24); 200 result[offset + 6] = (byte) (value.divisor >> 16); 201 result[offset + 5] = (byte) (value.divisor >> 8); 202 result[offset + 4] = (byte) (value.divisor >> 0); 203 } 204 } 205 206 public static short toShort(final byte[] bytes, final ByteOrder byteOrder) { 207 return toShort(bytes, 0, byteOrder); 208 } 209 210 private static short toShort(final byte[] bytes, final int offset, final ByteOrder byteOrder) { 211 return (short) toUInt16(bytes, offset, byteOrder); 212 } 213 214 public static short[] toShorts(final byte[] bytes, final ByteOrder byteOrder) { 215 return toShorts(bytes, 0, bytes.length, byteOrder); 216 } 217 218 private static short[] toShorts(final byte[] bytes, final int offset, 219 final int length, final ByteOrder byteOrder) { 220 final short[] result = new short[length / 2]; 221 for (int i = 0; i < result.length; i++) { 222 result[i] = toShort(bytes, offset + 2 * i, byteOrder); 223 } 224 return result; 225 } 226 227 public static int toUInt16(final byte[] bytes, final ByteOrder byteOrder) { 228 return toUInt16(bytes, 0, byteOrder); 229 } 230 231 public static int toUInt16(final byte[] bytes, final int offset, final ByteOrder byteOrder) { 232 final int byte0 = 0xff & bytes[offset + 0]; 233 final int byte1 = 0xff & bytes[offset + 1]; 234 if (byteOrder == ByteOrder.BIG_ENDIAN) { 235 return ((byte0 << 8) | byte1); 236 } else { 237 return ((byte1 << 8) | byte0); 238 } 239 } 240 241 public static int[] toUInt16s(final byte[] bytes, final ByteOrder byteOrder) { 242 return toUInt16s(bytes, 0, bytes.length, byteOrder); 243 } 244 245 private static int[] toUInt16s(final byte[] bytes, final int offset, final int length, 246 final ByteOrder byteOrder) { 247 final int[] result = new int[length / 2]; 248 for (int i = 0; i < result.length; i++) { 249 result[i] = toUInt16(bytes, offset + 2 * i, byteOrder); 250 } 251 return result; 252 } 253 254 public static int toInt(final byte[] bytes, final ByteOrder byteOrder) { 255 return toInt(bytes, 0, byteOrder); 256 } 257 258 public static int toInt(final byte[] bytes, final int offset, final ByteOrder byteOrder) { 259 final int byte0 = 0xff & bytes[offset + 0]; 260 final int byte1 = 0xff & bytes[offset + 1]; 261 final int byte2 = 0xff & bytes[offset + 2]; 262 final int byte3 = 0xff & bytes[offset + 3]; 263 if (byteOrder == ByteOrder.BIG_ENDIAN) { 264 return (byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3; 265 } else { 266 return (byte3 << 24) | (byte2 << 16) | (byte1 << 8) | byte0; 267 } 268 } 269 270 public static int[] toInts(final byte[] bytes, final ByteOrder byteOrder) { 271 return toInts(bytes, 0, bytes.length, byteOrder); 272 } 273 274 private static int[] toInts(final byte[] bytes, final int offset, final int length, 275 final ByteOrder byteOrder) { 276 final int[] result = new int[length / 4]; 277 for (int i = 0; i < result.length; i++) { 278 result[i] = toInt(bytes, offset + 4 * i, byteOrder); 279 } 280 return result; 281 } 282 283 public static float toFloat(final byte[] bytes, final ByteOrder byteOrder) { 284 return toFloat(bytes, 0, byteOrder); 285 } 286 287 private static float toFloat(final byte[] bytes, final int offset, final ByteOrder byteOrder) { 288 final int byte0 = 0xff & bytes[offset + 0]; 289 final int byte1 = 0xff & bytes[offset + 1]; 290 final int byte2 = 0xff & bytes[offset + 2]; 291 final int byte3 = 0xff & bytes[offset + 3]; 292 final int bits; 293 if (byteOrder == ByteOrder.BIG_ENDIAN) { 294 bits = (byte0 << 24) | (byte1 << 16) | (byte2 << 8) | (byte3 << 0); 295 } else { 296 bits = (byte3 << 24) | (byte2 << 16) | (byte1 << 8) | (byte0 << 0); 297 } 298 return Float.intBitsToFloat(bits); 299 } 300 301 public static float[] toFloats(final byte[] bytes, final ByteOrder byteOrder) { 302 return toFloats(bytes, 0, bytes.length, byteOrder); 303 } 304 305 private static float[] toFloats(final byte[] bytes, final int offset, 306 final int length, final ByteOrder byteOrder) { 307 final float[] result = new float[length / 4]; 308 for (int i = 0; i < result.length; i++) { 309 result[i] = toFloat(bytes, offset + 4 * i, byteOrder); 310 } 311 return result; 312 } 313 314 public static double toDouble(final byte[] bytes, final ByteOrder byteOrder) { 315 return toDouble(bytes, 0, byteOrder); 316 } 317 318 private static double toDouble(final byte[] bytes, final int offset, final ByteOrder byteOrder) { 319 final long byte0 = 0xffL & bytes[offset + 0]; 320 final long byte1 = 0xffL & bytes[offset + 1]; 321 final long byte2 = 0xffL & bytes[offset + 2]; 322 final long byte3 = 0xffL & bytes[offset + 3]; 323 final long byte4 = 0xffL & bytes[offset + 4]; 324 final long byte5 = 0xffL & bytes[offset + 5]; 325 final long byte6 = 0xffL & bytes[offset + 6]; 326 final long byte7 = 0xffL & bytes[offset + 7]; 327 final long bits; 328 if (byteOrder == ByteOrder.BIG_ENDIAN) { 329 bits = (byte0 << 56) | (byte1 << 48) | (byte2 << 40) 330 | (byte3 << 32) | (byte4 << 24) | (byte5 << 16) 331 | (byte6 << 8) | (byte7 << 0); 332 } else { 333 bits = (byte7 << 56) | (byte6 << 48) | (byte5 << 40) 334 | (byte4 << 32) | (byte3 << 24) | (byte2 << 16) 335 | (byte1 << 8) | (byte0 << 0); 336 } 337 return Double.longBitsToDouble(bits); 338 } 339 340 public static double[] toDoubles(final byte[] bytes, final ByteOrder byteOrder) { 341 return toDoubles(bytes, 0, bytes.length, byteOrder); 342 } 343 344 private static double[] toDoubles(final byte[] bytes, final int offset, 345 final int length, final ByteOrder byteOrder) { 346 final double[] result = new double[length / 8]; 347 for (int i = 0; i < result.length; i++) { 348 result[i] = toDouble(bytes, offset + 8 * i, byteOrder); 349 } 350 return result; 351 } 352 353 public static RationalNumber toRational(final byte[] bytes, final ByteOrder byteOrder) { 354 return toRational(bytes, 0, byteOrder); 355 } 356 357 private static RationalNumber toRational(final byte[] bytes, final int offset, final ByteOrder byteOrder) { 358 final int byte0 = 0xff & bytes[offset + 0]; 359 final int byte1 = 0xff & bytes[offset + 1]; 360 final int byte2 = 0xff & bytes[offset + 2]; 361 final int byte3 = 0xff & bytes[offset + 3]; 362 final int byte4 = 0xff & bytes[offset + 4]; 363 final int byte5 = 0xff & bytes[offset + 5]; 364 final int byte6 = 0xff & bytes[offset + 6]; 365 final int byte7 = 0xff & bytes[offset + 7]; 366 final int numerator; 367 final int divisor; 368 if (byteOrder == ByteOrder.BIG_ENDIAN) { 369 numerator = (byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3; 370 divisor = (byte4 << 24) | (byte5 << 16) | (byte6 << 8) | byte7; 371 } else { 372 numerator = (byte3 << 24) | (byte2 << 16) | (byte1 << 8) | byte0; 373 divisor = (byte7 << 24) | (byte6 << 16) | (byte5 << 8) | byte4; 374 } 375 return new RationalNumber(numerator, divisor); 376 } 377 378 public static RationalNumber[] toRationals(final byte[] bytes, final ByteOrder byteOrder) { 379 return toRationals(bytes, 0, bytes.length, byteOrder); 380 } 381 382 private static RationalNumber[] toRationals(final byte[] bytes, 383 final int offset, final int length, final ByteOrder byteOrder) { 384 final RationalNumber[] result = new RationalNumber[length / 8]; 385 for (int i = 0; i < result.length; i++) { 386 result[i] = toRational(bytes, offset + 8 * i, byteOrder); 387 } 388 return result; 389 } 390}