/* * 21.04.2004 Original verion. davagin@udm.ru. *----------------------------------------------------------------------- * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *---------------------------------------------------------------------- */ package davaguine.jmac.decoder; import java.io.IOException; /** * Author: Dmitry Vaguine * Date: 04.03.2004 * Time: 14:51:31 */ public class UnBitArrayOld extends UnBitArrayBase { public final static long K_SUM_MIN_BOUNDARY_OLD[] = {0, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648L, 0, 0, 0, 0, 0, 0}; public final static long K_SUM_MAX_BOUNDARY_OLD[] = {128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648L, 0, 0, 0, 0, 0, 0, 0}; public final static long Powers_of_Two[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648L}; public final static long Powers_of_Two_Reversed[] = {2147483648L, 1073741824, 536870912, 268435456, 134217728, 67108864, 33554432, 16777216, 8388608, 4194304, 2097152, 1048576, 524288, 262144, 131072, 65536, 32768, 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1}; public final static long Powers_of_Two_Minus_One[] = {0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215, 33554431, 67108863, 134217727, 268435455, 536870911, 1073741823, 2147483647, 4294967295L}; public final static long Powers_of_Two_Minus_One_Reversed[] = {4294967295L, 2147483647, 1073741823, 536870911, 268435455, 134217727, 67108863, 33554431, 16777215, 8388607, 4194303, 2097151, 1048575, 524287, 262143, 131071, 65535, 32767, 16383, 8191, 4095, 2047, 1023, 511, 255, 127, 63, 31, 15, 7, 3, 1, 0}; public final static long K_SUM_MIN_BOUNDARY[] = {0, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648L, 0, 0, 0, 0}; public final static long K_SUM_MAX_BOUNDARY[] = {32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648L, 0, 0, 0, 0, 0}; //construction/destruction public UnBitArrayOld(IAPEDecompress pAPEDecompress, int nVersion) { int nBitArrayBytes = 262144; //calculate the bytes if (nVersion <= 3880) { int nMaxFrameBytes = (pAPEDecompress.getApeInfoBlocksPerFrame() * 50) / 8; nBitArrayBytes = 65536; while (nBitArrayBytes < nMaxFrameBytes) nBitArrayBytes <<= 1; nBitArrayBytes = Math.max(nBitArrayBytes, 262144); } else if (nVersion <= 3890) nBitArrayBytes = 65536; CreateHelper(pAPEDecompress.getApeInfoIoSource(), nBitArrayBytes, nVersion); //set the refill threshold if (m_nVersion <= 3880) m_nRefillBitThreshold = (m_nBits - (16384 * 8)); else m_nRefillBitThreshold = (m_nBits - 512); } //functions public void GenerateArray(int[] pOutputArray, int nElements, int nBytesRequired) throws IOException { if (m_nVersion < 3860) GenerateArrayOld(pOutputArray, nElements, nBytesRequired); else if (m_nVersion <= 3890) GenerateArrayRice(pOutputArray, nElements, nBytesRequired); } public long DecodeValue(int DecodeMethod, int nParam1, int nParam2) throws IOException { switch (DecodeMethod) { case DecodeValueMethod.DECODE_VALUE_METHOD_UNSIGNED_INT: return DecodeValueXBits(32); case DecodeValueMethod.DECODE_VALUE_METHOD_UNSIGNED_RICE: return DecodeValueRiceUnsigned(nParam1); case DecodeValueMethod.DECODE_VALUE_METHOD_X_BITS: return DecodeValueXBits(nParam1); } return 0; } private void GenerateArrayOld(int[] Output_Array, long Number_of_Elements, int Minimum_nCurrentBitIndex_Array_Bytes) throws IOException { //variable declarations long K_Sum; long q; long kmin, kmax; long k; long Max; int p1, p2; //fill bit array if necessary //could use seek information to determine what the max was... long Max_Bits_Needed = Number_of_Elements * 50; if (Minimum_nCurrentBitIndex_Array_Bytes > 0) //this is actually probably double what is really needed //we can only calculate the space needed for both arrays in multichannel Max_Bits_Needed = ((Minimum_nCurrentBitIndex_Array_Bytes + 4) * 8); if (Max_Bits_Needed > GetBitsRemaining()) FillBitArray(); //decode the first 5 elements (all k = 10) Max = (Number_of_Elements < 5) ? Number_of_Elements : 5; for (q = 0; q < Max; q++) Output_Array[(int) q] = (int) DecodeValueRiceUnsigned(10); //quit if that was all if (Number_of_Elements <= 5) { int tvi; for (int i = 0; i < Number_of_Elements; i++) { tvi = Output_Array[i]; Output_Array[i] = (tvi & 1) > 0 ? (tvi >> 1) + 1 : -(tvi >> 1); } return; } //update k and K_Sum K_Sum = Output_Array[0] + Output_Array[1] + Output_Array[2] + Output_Array[3] + Output_Array[4]; k = Get_K(K_Sum / 10); //work through the rest of the elements before the primary loop Max = (Number_of_Elements < 64) ? Number_of_Elements : 64; for (q = 5; q < Max; q++) { Output_Array[(int) q] = (int) DecodeValueRiceUnsigned(k); K_Sum += Output_Array[(int) q]; k = Get_K(K_Sum / (q + 1) / 2); } //quit if that was all if (Number_of_Elements <= 64) { int tvi; for (int i = 0; i < Number_of_Elements; i++) { tvi = Output_Array[i]; Output_Array[i] = (tvi & 1) > 0 ? (tvi >> 1) + 1 : -(tvi >> 1); } return; } // set all of the variables up for the primary loop long v, Bit_Array_Index; k = Get_K(K_Sum >> 7); kmin = K_SUM_MIN_BOUNDARY_OLD[(int) k]; kmax = K_SUM_MAX_BOUNDARY_OLD[(int) k]; // the primary loop for (p1 = 64, p2 = 0; p1 < Number_of_Elements; p1++, p2++) { // plug through the string of 0's (the overflow) long Bit_Initial = m_nCurrentBitIndex; while ((m_pBitArray[(int) (m_nCurrentBitIndex >> 5)] & Powers_of_Two_Reversed[(int) (m_nCurrentBitIndex++ & 31)]) == 0) ; // if k = 0, your done if (k == 0) v = (m_nCurrentBitIndex - Bit_Initial - 1); else { // put the overflow value into v v = (m_nCurrentBitIndex - Bit_Initial - 1) << k; // store the bit information and incement the bit pointer by 'k' Bit_Array_Index = m_nCurrentBitIndex >> 5; long Bit_Index = m_nCurrentBitIndex & 31; m_nCurrentBitIndex += k; //figure the extra bits on the left and the left value int Left_Extra_Bits = (int) ((32 - k) - Bit_Index); long Left_Value = m_pBitArray[(int) Bit_Array_Index] & Powers_of_Two_Minus_One_Reversed[(int) Bit_Index]; if (Left_Extra_Bits >= 0) v |= (Left_Value >> Left_Extra_Bits); else v |= (Left_Value << -Left_Extra_Bits) | (m_pBitArray[(int) (Bit_Array_Index + 1)] >> (32 + Left_Extra_Bits)); } Output_Array[p1] = (int) v; K_Sum += Output_Array[p1] - Output_Array[p2]; // convert *p2 to unsigned Output_Array[p2] = (Output_Array[p2] % 2) > 0 ? (Output_Array[p2] >> 1) + 1 : -(Output_Array[p2] >> 1); // adjust k if necessary if ((K_Sum < kmin) || (K_Sum >= kmax)) { if (K_Sum < kmin) while (K_Sum < K_SUM_MIN_BOUNDARY_OLD[(int) (--k)]) ; else while (K_Sum >= K_SUM_MAX_BOUNDARY_OLD[(int) (++k)]) ; kmax = K_SUM_MAX_BOUNDARY_OLD[(int) k]; kmin = K_SUM_MIN_BOUNDARY_OLD[(int) k]; } } for (; p2 < Number_of_Elements; p2++) Output_Array[p2] = (Output_Array[p2] & 1) > 0 ? (Output_Array[p2] >> 1) + 1 : -(Output_Array[p2] >> 1); } private void GenerateArrayRice(int[] pOutputArray, long NumberOfElements, int MinimumBitArrayBytes) throws IOException { ///////////////////////////////////////////////////////////////////////////// //decode the bit array ///////////////////////////////////////////////////////////////////////////// k = 10; K_Sum = 1024 * 16; if (m_nVersion <= 3880) { //the primary loop for (int i = 0; i < NumberOfElements; i++) pOutputArray[i] = DecodeValueNew(false); } else { //the primary loop for (int i = 0; i < NumberOfElements; i++) pOutputArray[i] = DecodeValueNew(true); } } private long DecodeValueRiceUnsigned(long k) throws IOException { //variable declares long v; //plug through the string of 0's (the overflow) long BitInitial = m_nCurrentBitIndex; while ((m_pBitArray[(int) (m_nCurrentBitIndex >> 5)] & Powers_of_Two_Reversed[(int) (m_nCurrentBitIndex++ & 31)]) == 0) ; //if k = 0, your done if (k == 0) return (m_nCurrentBitIndex - BitInitial - 1); //put the overflow value into v v = (m_nCurrentBitIndex - BitInitial - 1) << k; return v | DecodeValueXBits(k); } //data private long k; private long K_Sum; private long m_nRefillBitThreshold; //functions private int DecodeValueNew(boolean bCapOverflow) throws IOException { //make sure there is room for the data //this is a little slower than ensuring a huge block to start with, but it's safer if (m_nCurrentBitIndex > m_nRefillBitThreshold) FillBitArray(); long v; //plug through the string of 0's (the overflow) long Bit_Initial = m_nCurrentBitIndex; while ((m_pBitArray[(int) (m_nCurrentBitIndex >> 5)] & Powers_of_Two_Reversed[(int) (m_nCurrentBitIndex++ & 31)]) == 0) ; int nOverflow = (int) (m_nCurrentBitIndex - Bit_Initial - 1); if (bCapOverflow) { while (nOverflow >= 16) { k += 4; nOverflow -= 16; } } //if k = 0, your done if (k != 0) { //put the overflow value into v v = nOverflow << k; //store the bit information and incement the bit pointer by 'k' long Bit_Array_Index = m_nCurrentBitIndex >> 5; long Bit_Index = m_nCurrentBitIndex & 31; m_nCurrentBitIndex += k; //figure the extra bits on the left and the left value int Left_Extra_Bits = (int) ((32 - k) - Bit_Index); long Left_Value = m_pBitArray[(int) Bit_Array_Index] & Powers_of_Two_Minus_One_Reversed[(int) Bit_Index]; if (Left_Extra_Bits >= 0) v |= (Left_Value >> Left_Extra_Bits); else v |= (Left_Value << -Left_Extra_Bits) | (m_pBitArray[(int) (Bit_Array_Index + 1)] >> (32 + Left_Extra_Bits)); } else v = nOverflow; //update K_Sum K_Sum += v - ((K_Sum + 8) >> 4); //update k if (K_Sum < K_SUM_MIN_BOUNDARY[(int) k]) k--; else if (K_Sum >= K_SUM_MAX_BOUNDARY[(int) k]) k++; //convert to unsigned and save return (v & 1) > 0 ? (int) ((v >> 1) + 1) : -((int) (v >> 1)); } private long GetBitsRemaining() { return (m_nElements * 32 - m_nCurrentBitIndex); } private long Get_K(long x) { if (x == 0) return 0; long k = 0; while (x >= Powers_of_Two[(int) (++k)]) ; return k; } }