Java Endian Flip flipEndian(byte[] input, int offset, int len, int bits, int scanLineStride, boolean bigEndian)

Here you can find the source of flipEndian(byte[] input, int offset, int len, int bits, int scanLineStride, boolean bigEndian)

Description

Flip the endian of the input byte-compacted array

License

Open Source License

Parameter

Parameter Description
input the input byte array which is byte compacted
offset the offset to start the reading input
len number of bytes to read
bits number of bits for the data before compaction
scanLineStride scan line stride to skip bits
bigEndian whether or not the input data is in big endian order

Return

a byte array with the endian flipped

Declaration

public static byte[] flipEndian(byte[] input, int offset, int len, int bits, int scanLineStride,
        boolean bigEndian) 

Method Source Code

//package com.java2s;
/**//from   w ww.  ja va  2  s . c  o m
 * Copyright (c) 2014-2015 by Wen Yu.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Any modifications to this file must keep this entire header intact.
 * 
 * Change History - most recent changes go on top of previous changes
 *
 * ArrayUtils.java
 *
 * Who   Date       Description
 * ====  =========  ======================================================================
 * WY    06Apr2015  Added reverse(byte[]) to reverse byte array elements
 * WY    06Jan2015  Added reverse() to reverse array elements
 * WY    10Dec2014  Moved reverseBits() from IMGUtils to here along with BIT_REVERSE_TABLE
 * WY    08Dec2014  Fixed bug for flipEndian() with more than 32 bit sample data 
 * WY    07Dec2014  Changed method names for byte array to other array types conversion
 * WY    07Dec2014  Added new methods to work with floating point TIFF images
 * WY    03Dec2014  Added byteArrayToFloatArray() and byteArrayToDoubleArray()
 * WY    25Nov2014  Added removeDuplicates() to sort and remove duplicates from int arrays
 * WY    12Nov2014  Changed the argument sequence for flipEndian()
 * WY    11Nov2014  Changed flipEndian() to include scan line stride to skip bits
 * WY    11Nov2014  Added toNBits() to convert byte array to nBits data unit
 * WY    28Oct2014  Added flipEndian() to work with TIFTweaker mergeTiffImagesEx()
 */

public class Main {
    private static final int[] MASK = { 0x000, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff, 0x7ff,
            0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff, 0x1ffff, 0x3ffff, 0x7ffff, 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff,
            0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff // 32 bits                
    };

    /**
      * Flip the endian of the input byte-compacted array
      * 
      * @param input the input byte array which is byte compacted
      * @param offset the offset to start the reading input
      * @param len number of bytes to read
      * @param bits number of bits for the data before compaction
      * @param scanLineStride scan line stride to skip bits
      * @param bigEndian whether or not the input data is in big endian order
      *
      * @return a byte array with the endian flipped
      */
    public static byte[] flipEndian(byte[] input, int offset, int len, int bits, int scanLineStride,
            boolean bigEndian) {
        long value = 0;
        int bits_remain = 0;
        long temp_byte = 0; // Must make this long, otherwise will give wrong result for bits > 32
        int empty_bits = 8;

        byte[] output = new byte[input.length];

        int strideCounter = 0;

        int end = offset + len;
        int bufIndex = 0;

        int temp = bits;
        boolean bigEndianOut = !bigEndian;

        loop: while (true) {

            if (!bigEndian)
                value = (temp_byte >> (8 - bits_remain));
            else
                value = (temp_byte & MASK[bits_remain]);

            while (bits > bits_remain) {
                if (offset >= end) {
                    break loop;
                }

                temp_byte = input[offset++] & 0xff;

                if (bigEndian)
                    value = ((value << 8) | temp_byte);
                else
                    value |= (temp_byte << bits_remain);

                bits_remain += 8;
            }

            bits_remain -= bits;

            if (bigEndian)
                value = (value >> bits_remain);

            // Write bits bit length value in opposite endian          
            if (bigEndianOut) {
                temp = bits - empty_bits;
                output[bufIndex] |= ((value >> temp) & MASK[empty_bits]);

                while (temp > 8) {
                    output[++bufIndex] |= ((value >> (temp - 8)) & MASK[8]);
                    temp -= 8;
                }

                if (temp > 0) {
                    output[++bufIndex] |= ((value & MASK[temp]) << (8 - temp));
                    temp -= 8;
                }
            } else { // Little endian
                temp = bits;
                output[bufIndex] |= ((value & MASK[empty_bits]) << (8 - empty_bits));
                value >>= empty_bits;
                temp -= empty_bits;
                // If the code is longer than the empty_bits
                while (temp > 8) {
                    output[++bufIndex] |= (value & 0xff);
                    value >>= 8;
                    temp -= 8;
                }

                if (temp > 0) {
                    output[++bufIndex] |= (value & MASK[temp]);
                    temp -= 8;
                }
            }

            empty_bits = -temp;

            if (++strideCounter % scanLineStride == 0) {
                empty_bits = 0;
                bits_remain = 0;
            }
        }

        return output;
    }
}

Related

  1. flipEndian(byte[] data)
  2. flipEndian(byte[] original, byte[] output)