001    /*
002     * Copyright (c) Andrey Kuznetsov. All Rights Reserved.
003     *
004     * http://uio.imagero.com
005     *
006     * Redistribution and use in source and binary forms, with or without
007     * modification, are permitted provided that the following conditions are met:
008     *
009     *  o Redistributions of source code must retain the above copyright notice,
010     *    this list of conditions and the following disclaimer.
011     *
012     *  o Redistributions in binary form must reproduce the above copyright notice,
013     *    this list of conditions and the following disclaimer in the documentation
014     *    and/or other materials provided with the distribution.
015     *
016     *  o Neither the name of Andrey Kuznetsov nor the names of
017     *    its contributors may be used to endorse or promote products derived
018     *    from this software without specific prior written permission.
019     *
020     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
021     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
022     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
023     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
024     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
027     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
028     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
029     * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
030     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031     */
032    package com.imagero.uio.xform;
033    
034    
035    /**
036     * Primitive type conversion, array copying, etc.
037     * The difference to Transformer is that XTransformer does not restricted to big and little endiannes.
038     * User may read bytes in any order.
039     *
040     * @author Andrey Kuznetsov
041     */
042    public class XTransformer {
043    
044        protected static final int[] shifts = new int[]{0, 8, 16, 24, 32, 40, 48, 56};
045        protected static final int[] POSITIONS_BE = {0, 1, 2, 3, 4, 5, 6, 7};
046        protected static final int[] POSITIONS_LE_SHORT = {1, 0};
047        protected static final int[] POSITIONS_LE_INT = {3, 2, 1, 0};
048        protected static final int[] POSITIONS_LE_LONG = {7, 6, 5, 4, 3, 2, 1, 0};
049        protected static final int[][] POSITIONS_LE = {POSITIONS_BE, POSITIONS_LE_SHORT, POSITIONS_LE_INT, POSITIONS_LE_LONG};
050    
051        public static final int TYPE_BE = 0;
052        public static final int TYPE_LE_SHORT = 1;
053        public static final int TYPE_LE_INT = 2;
054        public static final int TYPE_LE_LONG = 3;
055    
056        public static final int[] get(int type) {
057            return POSITIONS_LE[type];
058        }
059    
060        /**
061         * write int in BIG_ENDIAN order
062         *
063         * @param source       source byte array
064         * @param sourceOffset offset in source array
065         * @param destOffset   offset in destination array
066         *
067         * @return new offset in source array (for next writeUnitXX)
068         */
069        public static final int byteToInt(byte[] source, int sourceOffset, int[] dest, int destOffset, int[] positions) {
070            int p = 0;
071            int v = ((source[sourceOffset + positions[p++]] & 0xFF) << 24)
072                    | ((source[sourceOffset + positions[p++]] & 0xFF) << 16)
073                    | ((source[sourceOffset + positions[p++]] & 0xFF) << 8)
074                    | (source[sourceOffset + positions[p++]] & 0xFF);
075            dest[destOffset] = v;
076            return sourceOffset + p;
077        }
078    
079        public static final int byteToInt(byte[] source, int sourceOffset, int[] positions) {
080            int p = 0;
081            return ((source[sourceOffset + positions[p++]] & 0xFF) << 24)
082                    | ((source[sourceOffset + positions[p++]] & 0xFF) << 16)
083                    | ((source[sourceOffset + positions[p++]] & 0xFF) << 8)
084                    | (source[sourceOffset + positions[p++]] & 0xFF);
085        }
086    
087        /**
088         * read int in BIG_ENDIAN order
089         *
090         * @param sourceOffset     offset in source array
091         * @param dest       byte array (destination)
092         * @param destOffset offset in destination array
093         *
094         * @return offset in destination array (updated)
095         */
096        public static final int intToByte(int[] source, int sourceOffset, byte[] dest, int destOffset, int[] positions) {
097            int p = 0;
098            int v = source[sourceOffset];
099            dest[destOffset + positions[p++]] = (byte) ((v >> 24) & 0xFF);
100            dest[destOffset + positions[p++]] = (byte) ((v >> 16) & 0xFF);
101            dest[destOffset + positions[p++]] = (byte) ((v >> 8) & 0xFF);
102            dest[destOffset + positions[p++]] = (byte) (v & 0xFF);
103            return destOffset + 4;
104        }
105    
106        public static final int intToByte(int v, byte[] dest, int destOffset, int[] positions) {
107            int p = 0;
108            dest[destOffset + positions[p++]] = (byte) ((v >> 24) & 0xFF);
109            dest[destOffset + positions[p++]] = (byte) ((v >> 16) & 0xFF);
110            dest[destOffset + positions[p++]] = (byte) ((v >> 8) & 0xFF);
111            dest[destOffset + positions[p++]] = (byte) (v & 0xFF);
112            return destOffset + 4;
113        }
114    
115        /**
116         * convert <code>count</code> ints to bytes (Big Endian)
117         * @param source int array
118         * @param srcOffset start offset in <code>source</code> array
119         * @param count how much ints to process
120         * @param dest destination byte array
121         * @param destOffset
122         */
123        public static final void intToByte(int[] source, int srcOffset, int count, byte[] dest, int destOffset, int[] positions) {
124            for (int i = 0; i < count; i++) {
125                int p = 0;
126                int v = source[srcOffset + i];
127                dest[destOffset + positions[p++]] = (byte) ((v >>> 24) & 0xFF);
128                dest[destOffset + positions[p++]] = (byte) ((v >>> 16) & 0xFF);
129                dest[destOffset + positions[p++]] = (byte) ((v >>> 8) & 0xFF);
130                dest[destOffset + positions[p++]] = (byte) (v & 0xFF);
131            }
132        }
133    
134    
135        public static final void byteToInt(byte[] source, int sourceOffset, int count, int[] dest, int destOffset, int[] positions) {
136            for (int i = 0; i < count; i++) {
137                int p = 0;
138                int v = ((source[sourceOffset + positions[p++]] & 0xFF) << 24)
139                        | ((source[sourceOffset + positions[p++]] & 0xFF) << 16)
140                        | ((source[sourceOffset + positions[p++]] & 0xFF) << 8)
141                        | (source[sourceOffset + positions[p++]] & 0xFF);
142                dest[destOffset + i] = v;
143                sourceOffset += 4;
144            }
145        }
146    
147    
148    /* **********************************************************************/
149    
150        public static int byteToChar(byte[] source, int sourceOffset, char[] dest, int destOffset, int[] positions) {
151            int p = 0;
152            int v = ((source[sourceOffset + positions[p++]] & 0xFF) << 8)
153                    | (source[sourceOffset + positions[p++]] & 0xFF);
154            dest[destOffset] = (char) v;
155            return sourceOffset + 2;
156        }
157    
158        public static int byteToChar(byte[] source, int sourceOffset, int[] positions) {
159            int p = 0;
160            return ((source[sourceOffset + positions[p++]] & 0xFF) << 8) | (source[sourceOffset + positions[p++]] & 0xFF);
161        }
162    
163        public static void byteToChar(byte[] source, int sourceOffset, int count, char[] dest, int destOffset, int[] positions) {
164            for (int i = 0; i < count; i++) {
165                int p = 0;
166                int v = ((source[sourceOffset + positions[p++]] & 0xFF) << 8)
167                        | (source[sourceOffset + positions[p++]] & 0xFF);
168                dest[destOffset + i] = (char) v;
169            }
170        }
171    
172    /* **********************************************************************/
173    
174        public static int charToByte(char[] source, int srcOffset, byte[] dest, int destOffset, int[] positions) {
175            int p = 0;
176            int v = source[srcOffset];
177            dest[destOffset + positions[p++]] = (byte) ((v >>> 8) & 0xFF);
178            dest[destOffset + positions[p++]] = (byte) (v & 0xFF);
179            return destOffset + 2;
180        }
181    
182        public static int charToByte(char v, byte[] dest, int destOffset, int[] positions) {
183            int p = 0;
184            dest[destOffset + positions[p++]] = (byte) ((v >>> 8) & 0xFF);
185            dest[destOffset + positions[p++]] = (byte) (v & 0xFF);
186            return destOffset + 2;
187        }
188    
189        public static void charToByte(char[] source, int srcOffset, int count, byte[] dest, int destOffset, int[] positions) {
190            for (int i = 0; i < count; i++) {
191                int p = 0;
192                int v = source[srcOffset + i];
193                dest[destOffset + positions[p++]] = (byte) ((v >>> 8) & 0xFF);
194                dest[destOffset + positions[p++]] = (byte) (v & 0xFF);
195            }
196        }
197    
198    /* **********************************************************************/
199    
200        public static int byteToDouble(byte[] source, int sourceOffset, double[] dest, int destOffset, int[] positions) {
201            int p = 0;
202            long v = ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 56)
203                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 48)
204                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 40)
205                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 32)
206                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 24)
207                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 16)
208                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 8)
209                    | (source[sourceOffset + positions[p++]] & 0xFF);
210            dest[destOffset] = Double.longBitsToDouble(v);
211            return sourceOffset + 8;
212        }
213    
214        public static double byteToDouble(byte[] source, int sourceOffset, int[] positions) {
215            int p = 0;
216            long v = ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 56)
217                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 48)
218                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 40)
219                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 32)
220                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 24)
221                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 16)
222                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 8)
223                    | (source[sourceOffset + positions[p++]] & 0xFF);
224            return Double.longBitsToDouble(v);
225        }
226    
227        public static void byteToDouble(byte[] source, int sourceOffset, int count, double[] dest, int destOffset, int[] positions) {
228            for (int i = 0; i < count; i++) {
229                int p = 0;
230                long v = ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 56)
231                        | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 48)
232                        | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 40)
233                        | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 32)
234                        | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 24)
235                        | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 16)
236                        | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 8)
237                        | (source[sourceOffset + positions[p++]] & 0xFF);
238                dest[destOffset + i] = Double.longBitsToDouble(v);
239            }
240        }
241    
242    /* **********************************************************************/
243    
244        public static int doubleToByte(double[] source, int srcOffset, byte[] dest, int destOffset, int[] positions) {
245            int p = 0;
246            double d = source[srcOffset];
247            long v = Double.doubleToLongBits(d);
248            dest[destOffset + positions[p++]] = (byte) ((v >>> 56) & 0xFF);
249            dest[destOffset + positions[p++]] = (byte) ((v >>> 48) & 0xFF);
250            dest[destOffset + positions[p++]] = (byte) ((v >>> 40) & 0xFF);
251            dest[destOffset + positions[p++]] = (byte) ((v >>> 32) & 0xFF);
252            dest[destOffset + positions[p++]] = (byte) ((v >>> 24) & 0xFF);
253            dest[destOffset + positions[p++]] = (byte) ((v >>> 16) & 0xFF);
254            dest[destOffset + positions[p++]] = (byte) ((v >>> 8) & 0xFF);
255            dest[destOffset + positions[p++]] = (byte) (v & 0xFF);
256            return destOffset + 8;
257        }
258    
259        public static int doubleToByte(double d, byte[] dest, int destOffset, int[] positions) {
260            int p = 0;
261            long v = Double.doubleToLongBits(d);
262            dest[destOffset + positions[p++]] = (byte) ((v >>> 56) & 0xFF);
263            dest[destOffset + positions[p++]] = (byte) ((v >>> 48) & 0xFF);
264            dest[destOffset + positions[p++]] = (byte) ((v >>> 40) & 0xFF);
265            dest[destOffset + positions[p++]] = (byte) ((v >>> 32) & 0xFF);
266            dest[destOffset + positions[p++]] = (byte) ((v >>> 24) & 0xFF);
267            dest[destOffset + positions[p++]] = (byte) ((v >>> 16) & 0xFF);
268            dest[destOffset + positions[p++]] = (byte) ((v >>> 8) & 0xFF);
269            dest[destOffset + positions[p++]] = (byte) (v & 0xFF);
270            return destOffset + 8;
271        }
272    
273        public static void doubleToByte(double[] source, int srcOffset, int count, byte[] dest, int destOffset, int[] positions) {
274            for (int i = 0; i < count; i++) {
275                int p = 0;
276                double d = source[srcOffset + i];
277                long v = Double.doubleToLongBits(d);
278                dest[destOffset + positions[p++]] = (byte) ((v >>> 56) & 0xFF);
279                dest[destOffset + positions[p++]] = (byte) ((v >>> 48) & 0xFF);
280                dest[destOffset + positions[p++]] = (byte) ((v >>> 40) & 0xFF);
281                dest[destOffset + positions[p++]] = (byte) ((v >>> 32) & 0xFF);
282                dest[destOffset + positions[p++]] = (byte) ((v >>> 24) & 0xFF);
283                dest[destOffset + positions[p++]] = (byte) ((v >>> 16) & 0xFF);
284                dest[destOffset + positions[p++]] = (byte) ((v >>> 8) & 0xFF);
285                dest[destOffset + positions[p++]] = (byte) (v & 0xFF);
286            }
287        }
288    
289    /* **********************************************************************/
290    
291        public static int byteToFloat(byte[] source, int sourceOffset, float[] dest, int destOffset, int[] positions) {
292            int p = 0;
293            int v = ((source[sourceOffset + positions[p++]] & 0xFF) << 24)
294                    | ((source[sourceOffset + positions[p++]] & 0xFF) << 16)
295                    | ((source[sourceOffset + positions[p++]] & 0xFF) << 8)
296                    | (source[sourceOffset + positions[p++]] & 0xFF);
297            dest[destOffset] = Float.intBitsToFloat(v);
298            return sourceOffset;
299        }
300    
301        public static float byteToFloat(byte[] source, int sourceOffset, int[] positions) {
302            int p = 0;
303            int v = ((source[sourceOffset + positions[p++]] & 0xFF) << 24)
304                    | ((source[sourceOffset + positions[p++]] & 0xFF) << 16)
305                    | ((source[sourceOffset + positions[p++]] & 0xFF) << 8)
306                    | (source[sourceOffset + positions[p++]] & 0xFF);
307            return Float.intBitsToFloat(v);
308        }
309    
310        public static void byteToFloat(byte[] source, int sourceOffset, int count, float[] dest, int destOffset, int[] positions) {
311            for (int i = 0; i < count; i++) {
312                int p = 0;
313                int v = ((source[sourceOffset + positions[p++]] & 0xFF) << 24)
314                        | ((source[sourceOffset + positions[p++]] & 0xFF) << 16)
315                        | ((source[sourceOffset + positions[p++]] & 0xFF) << 8)
316                        | (source[sourceOffset + positions[p++]] & 0xFF);
317                dest[destOffset + i] = Float.intBitsToFloat(v);
318            }
319        }
320    
321    /* **********************************************************************/
322    
323        public static int floatToByte(float[] source, int offset, byte[] dest, int destOffset, int[] positions) {
324            int p = 0;
325            float f = source[offset];
326            int v = Float.floatToIntBits(f);
327            dest[destOffset + positions[p++]] = (byte) ((v >>> 24) & 0xFF);
328            dest[destOffset + positions[p++]] = (byte) ((v >>> 16) & 0xFF);
329            dest[destOffset + positions[p++]] = (byte) ((v >>> 8) & 0xFF);
330            dest[destOffset + positions[p++]] = (byte) (v & 0xFF);
331            return destOffset + 4;
332        }
333    
334        public static int floatToByte(float f, byte[] dest, int destOffset, int[] positions) {
335            int p = 0;
336            int v = Float.floatToIntBits(f);
337            dest[destOffset + positions[p++]] = (byte) ((v >>> 24) & 0xFF);
338            dest[destOffset + positions[p++]] = (byte) ((v >>> 16) & 0xFF);
339            dest[destOffset + positions[p++]] = (byte) ((v >>> 8) & 0xFF);
340            dest[destOffset + positions[p++]] = (byte) (v & 0xFF);
341            return destOffset + 4;
342        }
343    
344        public static void floatToByte(float[] source, int offset, int count, byte[] dest, int destOffset, int[] positions) {
345            for (int i = 0; i < count; i++) {
346                int p = 0;
347                float f = source[offset + i];
348                int v = Float.floatToIntBits(f);
349                dest[destOffset + positions[p++]] = (byte) ((v >>> 24) & 0xFF);
350                dest[destOffset + positions[p++]] = (byte) ((v >>> 16) & 0xFF);
351                dest[destOffset + positions[p++]] = (byte) ((v >>> 8) & 0xFF);
352                dest[destOffset + positions[p++]] = (byte) (v & 0xFF);
353            }
354        }
355    
356    /* **********************************************************************/
357    
358        public static int byteToLong(byte[] source, int sourceOffset, long[] dest, int destOffset, int[] positions) {
359            int p = 0;
360            long v = ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 56)
361                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 48)
362                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 40)
363                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 32)
364                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 24)
365                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 16)
366                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 8)
367                    | (source[sourceOffset + positions[p++]] & 0xFF);
368    
369            dest[destOffset] = v;
370            return sourceOffset + 8;
371        }
372    
373        public static long byteToLong(byte[] source, int sourceOffset, int[] positions) {
374            int p = 0;
375            return ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 56)
376                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 48)
377                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 40)
378                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 32)
379                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 24)
380                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 16)
381                    | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 8)
382                    | (source[sourceOffset + positions[p++]] & 0xFF);
383        }
384    
385        public static void byteToLong(byte[] source, int sourceOffset, int count, long[] dest, int destOffset, int[] positions) {
386            for (int i = 0; i < count; i++) {
387                int p = 0;
388                long v = ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 56)
389                        | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 48)
390                        | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 40)
391                        | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 32)
392                        | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 24)
393                        | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 16)
394                        | ((long) (source[sourceOffset + positions[p++]] & 0xFF) << 8)
395                        | (source[sourceOffset + positions[p++]] & 0xFF);
396    
397                dest[destOffset + i] = v;
398            }
399        }
400    
401    /* **********************************************************************/
402    
403        public static int longToByte(long[] source, int offset, byte[] dest, int destOffset, int[] positions) {
404            int p = 0;
405            long v = source[offset];
406            dest[destOffset + positions[p++]] = (byte) ((v >>> 56) & 0xFF);
407            dest[destOffset + positions[p++]] = (byte) ((v >>> 48) & 0xFF);
408            dest[destOffset + positions[p++]] = (byte) ((v >>> 40) & 0xFF);
409            dest[destOffset + positions[p++]] = (byte) ((v >>> 32) & 0xFF);
410            dest[destOffset + positions[p++]] = (byte) ((v >>> 24) & 0xFF);
411            dest[destOffset + positions[p++]] = (byte) ((v >>> 16) & 0xFF);
412            dest[destOffset + positions[p++]] = (byte) ((v >>> 8) & 0xFF);
413            dest[destOffset + positions[p++]] = (byte) (v & 0xFF);
414    
415            return destOffset + 8;
416        }
417    
418        public static int longToByte(long v, byte[] dest, int destOffset, int[] positions) {
419            int p = 0;
420            dest[destOffset + positions[p++]] = (byte) ((v >>> 56) & 0xFF);
421            dest[destOffset + positions[p++]] = (byte) ((v >>> 48) & 0xFF);
422            dest[destOffset + positions[p++]] = (byte) ((v >>> 40) & 0xFF);
423            dest[destOffset + positions[p++]] = (byte) ((v >>> 32) & 0xFF);
424            dest[destOffset + positions[p++]] = (byte) ((v >>> 24) & 0xFF);
425            dest[destOffset + positions[p++]] = (byte) ((v >>> 16) & 0xFF);
426            dest[destOffset + positions[p++]] = (byte) ((v >>> 8) & 0xFF);
427            dest[destOffset + positions[p++]] = (byte) (v & 0xFF);
428    
429            return destOffset;
430        }
431    
432        public static void longToByte(long[] source, int offset, int count, byte[] dest, int destOffset, int[] positions) {
433            for (int i = 0; i < count; i++) {
434                int p = 0;
435                long v = source[offset + i];
436                dest[destOffset + positions[p++]] = (byte) ((v >>> 56) & 0xFF);
437                dest[destOffset + positions[p++]] = (byte) ((v >>> 48) & 0xFF);
438                dest[destOffset + positions[p++]] = (byte) ((v >>> 40) & 0xFF);
439                dest[destOffset + positions[p++]] = (byte) ((v >>> 32) & 0xFF);
440                dest[destOffset + positions[p++]] = (byte) ((v >>> 24) & 0xFF);
441                dest[destOffset + positions[p++]] = (byte) ((v >>> 16) & 0xFF);
442                dest[destOffset + positions[p++]] = (byte) ((v >>> 8) & 0xFF);
443                dest[destOffset + positions[p++]] = (byte) (v & 0xFF);
444            }
445        }
446    
447    /* **********************************************************************/
448    
449        public static int byteToShort(byte[] source, int sourceOffset, short[] dest, int destOffset, int[] positions) {
450            int p = 0;
451            int v = ((source[sourceOffset + positions[p++]] & 0xFF) << 8)
452                    | (source[sourceOffset + positions[p++]] & 0xFF);
453            dest[destOffset] = (short) v;
454            return sourceOffset + 2;
455        }
456    
457        public static int byteToShort(byte[] source, int sourceOffset, int[] positions) {
458            int p = 0;
459            return ((source[sourceOffset + positions[p++]] & 0xFF) << 8) | (source[sourceOffset + positions[p++]] & 0xFF);
460        }
461    
462        public static void byteToShort(byte[] source, int sourceOffset, int count, short[] dest, int destOffset, int[] positions) {
463            for (int i = 0; i < count; i++) {
464                int p = 0;
465                int v = ((source[sourceOffset + positions[p++]] & 0xFF) << 8)
466                        | (source[sourceOffset + positions[p++]] & 0xFF);
467                dest[destOffset + i] = (short) v;
468            }
469        }
470    
471    /* **********************************************************************/
472    
473        public static int shortToByte(short[] source, int offset, byte[] dest, int destOffset, int[] positions) {
474            int p = 0;
475            int v = source[offset];
476            dest[destOffset + positions[p++]] = (byte) ((v >>> 8) & 0xFF);
477            dest[destOffset + positions[p++]] = (byte) (v & 0xFF);
478            return destOffset + 2;
479        }
480    
481        public static int shortToByte(short v, byte[] dest, int destOffset, int[] positions) {
482            int p = 0;
483            dest[destOffset + positions[p++]] = (byte) ((v >>> 8) & 0xFF);
484            dest[destOffset + positions[p++]] = (byte) (v & 0xFF);
485            return destOffset + 2;
486        }
487    
488        public static void shortToByte(short[] source, int offset, int count, byte[] dest, int destOffset, int[] positions) {
489            for (int i = 0; i < count; i++) {
490                int p = 0;
491                int v = source[offset + i];
492                dest[destOffset + positions[p++]] = (byte) ((v >>> 8) & 0xFF);
493                dest[destOffset + positions[p++]] = (byte) (v & 0xFF);
494            }
495        }
496    
497        /* **********************************************************************/
498    
499        public static final void byteToInt(final int bytesInInt, byte[] source, int sourceOffset, final int count, int[] dest, int destOffset, int[] positions) {
500            for (int i = 0; i < count; i++) {
501                int v = 0;
502                for (int j = 0; j < bytesInInt; j++) {
503                    v = (v << 8) | (source[sourceOffset + positions[j]] & 0xFF);
504                }
505                dest[destOffset++] = v & 0xFFFFFFFF;
506                sourceOffset += bytesInInt;
507            }
508        }
509    
510        public static final void byteToShort(final int bytesInShort, byte[] source, int sourceOffset, final int count, short[] dest, int destOffset, int[] positions) {
511            for (int i = 0; i < count; i++) {
512                int v = 0;
513                for (int j = 0; j < bytesInShort; j++) {
514                    v = (v << 8) | (source[sourceOffset + positions[j]] & 0xFF);
515                }
516                dest[destOffset++] = (short) v;
517                sourceOffset += bytesInShort;
518            }
519        }
520    
521        public static final void byteToLong(final int bytesInLong, byte[] source, int sourceOffset, final int count, long[] dest, int destOffset, int[] positions) {
522            for (int i = 0; i < count; i++) {
523                long v = 0;
524                for (int j = 0; j < bytesInLong; j++) {
525                    v = (v << 8) | (source[sourceOffset + positions[j]] & 0xFF);
526                }
527                dest[destOffset++] = v;
528                sourceOffset += bytesInLong;
529            }
530        }
531    
532    /* **********************************************************************/
533    
534    
535        public static final int byteToInt(int bytesInInt, byte[] source, int sourceOffset, int[] dest, int destOffset, int[] positions) {
536            int v = 0;
537            for (int i = 0; i < bytesInInt; i++) {
538                v = (v << 8) | (source[sourceOffset + positions[i]] & 0xFF);
539            }
540            dest[destOffset] = v & 0xFFFFFFFF;
541            return sourceOffset + bytesInInt;
542        }
543    
544        public static final int byteToShort(int bytesInShort, byte[] source, int sourceOffset, short[] dest, int destOffset, int[] positions) {
545            int v = 0;
546            for (int i = 0; i < bytesInShort; i++) {
547                v = (v << 8) | (source[sourceOffset + positions[i]] & 0xFF);
548            }
549            dest[destOffset] = (short) v;
550            return sourceOffset + bytesInShort;
551        }
552    
553        public static final int byteToLong(int bytesInLong, byte[] source, int sourceOffset, long[] dest, int destOffset, int[] positions) {
554            long v = 0;
555            for (int i = 0; i < bytesInLong; i++) {
556                v = (v << 8) | (source[sourceOffset + positions[i]] & 0xFF);
557            }
558            dest[destOffset] = v;
559            return sourceOffset + bytesInLong;
560        }
561    }