/* You may freely copy, distribute, modify and use this class as long as the original author attribution remains intact. See message below. Copyright (C) 2001-2003 Christian Pesch. All Rights Reserved. */ package slash.metamusic.mp3.util; import java.io.IOException; import java.io.InputStream; /** * Some useful functions for * <ul> * <li>shifting bits * <li>converting byte arrays to int and vica versa * <li>endianess handling * </ul> * * @author Christian Pesch * @version $Id: BitConversion.java 938 2007-01-05 18:22:34Z cpesch $ */ public class BitConversion { public static int powN(int pow, double base) { return new Double(Math.pow(base, pow)).intValue(); } public static int pow2(int value) { return 1 << value; } public static int bitmask(int numberOfBits) { return pow2(numberOfBits) - 1; } public static int shiftAnd(int value, int firstBit, int numberOfBits) { return (value >>> firstBit) & bitmask(numberOfBits); } /** * Check if selected bit is set in <code>input</code>. * * @param value Value to check * @param bit Bit number to check (0..7 with 7 MSB) * @return 1 if bit is set, 0 otherwise */ public static int getBit(int value, int bit) { return ((value & (1 << bit)) > 0) ? 1 : 0; } /** * Sets the bit at the specified location in the byte given. Location * should be between 0 and 7. If an invalid location is specified, 0 * will be returned. * * @param b the byte to set the index in * @param location the index to set in b * @return b with the bit at location set to 1 */ public static byte setBit(byte b, int location) { byte ret = 0; if ((location >= 0) && (location < 8)) { ret = (byte) (b | (byte) (1 << location)); } return ret; } public static int stringToInt(String value) { int result; try { result = new Integer(value.trim()).intValue(); } catch (NumberFormatException e) { result = -1; } return result; } public static int unsignedByteToInt(byte value) { return value & 0xFF; } public static void printBits(int value) { for (int i = 0; i < 32; i++) { System.out.print(" " + i + (i < 10 ? " " : "")); } System.out.println(); for (int i = 0; i < 32; i++) { System.out.print(" " + shiftAnd(value, i, 1) + " "); } System.out.println(); } public static boolean findString(InputStream in, String find, String encoding) throws IOException { byte[] header = new byte[find.length()]; in.read(header); return find.equals(new String(header, encoding)); } public static byte[] swapEndianess(byte[] buffer) { byte[] temp = new byte[buffer.length]; for (int i = 0; i < buffer.length; i++) { System.arraycopy(buffer, i, temp, temp.length - 1 - i, 1); } return temp; } // -- big endian operations ------------------------------------------------------- public static int extract2BigEndian(InputStream in) throws IOException { byte[] buffer = new byte[2]; in.read(buffer); return extract2Endian(buffer); } public static long extract4BigEndian(InputStream in) throws IOException { byte[] buffer = new byte[4]; in.read(buffer); return extract4BigEndian(buffer); } public static int extract4BigEndian(byte[] buffer, int offset) { byte[] temp = new byte[4]; System.arraycopy(buffer, offset, temp, 0, temp.length); return extract4BigEndian(temp); } public static int extract4BigEndian(byte[] buffer) { return unsignedByteToInt(buffer[0]) << 24 | unsignedByteToInt(buffer[1]) << 16 | extract2BigEndian(buffer, 2); } public static int extract3BigEndian(byte[] buffer, int offset) { byte[] temp = new byte[4]; System.arraycopy(buffer, offset, temp, 1, 3); return extract4BigEndian(temp); } public static int extract2BigEndian(byte[] buffer, int offset) { byte[] temp = new byte[2]; System.arraycopy(buffer, offset, temp, 0, temp.length); return extract2Endian(temp); } public static int extract2Endian(byte[] buffer) { return unsignedByteToInt(buffer[0]) << 8 | unsignedByteToInt(buffer[1]); } public static byte[] create2BigEndian(int number) { return new byte[]{(byte) (number >> 8), (byte) number}; } public static byte[] create3BigEndian(int number) { return new byte[]{(byte) (number >> 16), (byte) (number >> 8), (byte) number}; } public static byte[] create4BigEndian(int number) { return new byte[]{(byte) (number >> 24), (byte) (number >> 16), (byte) (number >> 8), (byte) number}; } // -- little endian operations ---------------------------------------------------- public static int extract2LittleEndian(byte[] buffer) { return extract2Endian(swapEndianess(buffer)); } public static int extract2LittleEndian(byte[] buffer, int offset) { byte[] temp = new byte[2]; System.arraycopy(buffer, offset, temp, 0, temp.length); return extract2LittleEndian(temp); } public static int extract4LittleEndian(byte[] buffer) { return extract2LittleEndian(buffer, 0) | unsignedByteToInt(buffer[2]) << 16 + unsignedByteToInt(buffer[3]) << 24; } public static int extract4LittleEndian(byte[] buffer, int offset) { byte[] temp = new byte[4]; System.arraycopy(buffer, offset, temp, 0, temp.length); return extract4LittleEndian(temp); } public static int extract2LittleEndian(InputStream in) throws IOException { byte[] buffer = new byte[2]; in.read(buffer); return extract2LittleEndian(buffer); } public static long extract4LittleEndian(InputStream in) throws IOException { byte[] buffer = new byte[4]; in.read(buffer); return extract4LittleEndian(buffer); } }