/* stream reading */
        /* supports reading 1 to 16 bits, in big endian format */
        static int readbits_16(AlacFile alac, int bits)
        {
            int result          = 0;
            int new_accumulator = 0;
            int part1           = 0;
            int part2           = 0;
            int part3           = 0;

            part1 = (alac.input_buffer[alac.ibIdx] & 0xff);
            part2 = (alac.input_buffer[alac.ibIdx + 1] & 0xff);
            part3 = (alac.input_buffer[alac.ibIdx + 2] & 0xff);

            result = ((part1 << 16) | (part2 << 8) | part3);

            /* shift left by the number of bits we've already read,
             * so that the top 'n' bits of the 24 bits we read will
             * be the return bits */
            result = result << alac.input_buffer_bitaccumulator;

            result = result & 0x00ffffff;

            /* and then only want the top 'n' bits from that, where
             * n is 'bits' */
            result = result >> (24 - bits);

            new_accumulator = (alac.input_buffer_bitaccumulator + bits);

            /* increase the buffer pointer if we've read over n bytes. */
            alac.ibIdx += (new_accumulator >> 3);

            /* and the remainder goes back into the bit accumulator */
            alac.input_buffer_bitaccumulator = (new_accumulator & 7);

            return(result);
        }
        public static AlacFile create_alac(int samplesize, int numchannels)
        {
            AlacFile newfile = new AlacFile();

            newfile.samplesize     = samplesize;
            newfile.numchannels    = numchannels;
            newfile.bytespersample = (samplesize / 8) * numchannels;

            return(newfile);
        }
        static void unreadbits(AlacFile alac, int bits)
        {
            int new_accumulator = (alac.input_buffer_bitaccumulator - bits);

            alac.ibIdx += (new_accumulator >> 3);

            alac.input_buffer_bitaccumulator = (new_accumulator & 7);
            if (alac.input_buffer_bitaccumulator < 0)
            {
                alac.input_buffer_bitaccumulator *= -1;
            }
        }
        /* supports reading 1 to 32 bits, in big endian format */
        static int readbits(AlacFile alac, int bits)
        {
            int result = 0;

            if (bits > 16)
            {
                bits -= 16;

                result = readbits_16(alac, 16) << bits;
            }

            result |= readbits_16(alac, bits);

            return(result);
        }
        public static int entropy_decode_value(AlacFile alac, int readSampleSize, int k, uint rice_kmodifier_mask)
        {
            int x = 0; // decoded value

            // read x, number of 1s before 0 represent the rice value.
            while (x <= Consts.RICE_THRESHOLD && readbit(alac) != 0)
            {
                x++;
            }

            if (x > Consts.RICE_THRESHOLD)
            {
                // read the number from the bit stream (raw value)
                int value = 0;

                value = readbits(alac, readSampleSize);

                // mask value
                value &= (int)((0xffffffff) >> (32 - readSampleSize));

                x = value;
            }
            else
            {
                if (k != 1)
                {
                    int extraBits = readbits(alac, k);

                    x *= (int)(((1 << k) - 1) & rice_kmodifier_mask);

                    if (extraBits > 1)
                    {
                        x += extraBits - 1;
                    }
                    else
                    {
                        unreadbits(alac, 1);
                    }
                }
            }

            return(x);
        }
        /* reads a single bit */
        static int readbit(AlacFile alac)
        {
            int result          = 0;
            int new_accumulator = 0;
            int part1           = 0;

            part1 = (alac.input_buffer[alac.ibIdx] & 0xff);

            result = part1;

            result = result << alac.input_buffer_bitaccumulator;

            result = result >> 7 & 1;

            new_accumulator = (alac.input_buffer_bitaccumulator + 1);

            alac.ibIdx += new_accumulator / 8;

            alac.input_buffer_bitaccumulator = (new_accumulator % 8);

            return(result);
        }
        public static int DecodeFrame(AlacFile alac, byte[] inbuffer, int[] outbuffer)
        {
            int channels;
            int outputsamples = alac.setinfo_max_samples_per_frame;

            /* setup the stream */
            alac.input_buffer = inbuffer;
            alac.input_buffer_bitaccumulator = 0;
            alac.ibIdx = 0;

            channels = readbits(alac, 3);

            int outputsize = outputsamples * alac.bytespersample;

            if (channels == 0) // 1 channel
            {
                int hassize;
                int isnotcompressed;
                int readsamplesize;

                int uncompressed_bytes;
                int ricemodifier;

                int tempPred = 0;

                /* 2^result = something to do with output waiting.
                 * perhaps matters if we read > 1 frame in a pass?
                 */
                readbits(alac, 4);

                readbits(alac, 12);                     // unknown, skip 12 bits

                hassize = readbits(alac, 1);            // the output sample size is stored soon

                uncompressed_bytes = readbits(alac, 2); // number of bytes in the (compressed) stream that are not compressed

                isnotcompressed = readbits(alac, 1);    // whether the frame is compressed

                if (hassize != 0)
                {
                    /* now read the number of samples,
                     * as a 32bit integer */
                    outputsamples = readbits(alac, 32);
                    outputsize    = outputsamples * alac.bytespersample;
                }

                readsamplesize = alac.setinfo_sample_size - (uncompressed_bytes * 8);

                if (isnotcompressed == 0)
                { // so it is compressed
                    int[] predictor_coef_table = alac.predictor_coef_table;
                    int   predictor_coef_num;
                    int   prediction_type;
                    int   prediction_quantitization;
                    int   i;

                    /* skip 16 bits, not sure what they are. seem to be used in
                     * two channel case */
                    readbits(alac, 8);
                    readbits(alac, 8);

                    prediction_type           = readbits(alac, 4);
                    prediction_quantitization = readbits(alac, 4);

                    ricemodifier       = readbits(alac, 3);
                    predictor_coef_num = readbits(alac, 5);

                    /* read the predictor table */

                    for (i = 0; i < predictor_coef_num; i++)
                    {
                        tempPred = readbits(alac, 16);
                        if (tempPred > 32767)
                        {
                            // the predictor coef table values are only 16 bit signed
                            tempPred = tempPred - 65536;
                        }

                        predictor_coef_table[i] = tempPred;
                    }

                    if (uncompressed_bytes != 0)
                    {
                        for (i = 0; i < outputsamples; i++)
                        {
                            alac.uncompressed_bytes_buffer_a[i] = readbits(alac, uncompressed_bytes * 8);
                        }
                    }


                    entropy_rice_decode(alac, alac.predicterror_buffer_a, outputsamples, readsamplesize, alac.setinfo_rice_initialhistory, alac.setinfo_rice_kmodifier, ricemodifier * (alac.setinfo_rice_historymult / 4), (uint)(1 << alac.setinfo_rice_kmodifier) - 1);

                    if (prediction_type == 0)
                    { // adaptive fir
                        alac.outputsamples_buffer_a = predictor_decompress_fir_adapt(alac.predicterror_buffer_a, outputsamples, readsamplesize, predictor_coef_table, predictor_coef_num, prediction_quantitization);
                    }
                    else
                    {
                        //System.err.println("FIXME: unhandled predicition type: " + prediction_type);

                        /* i think the only other prediction type (or perhaps this is just a
                         * boolean?) runs adaptive fir twice.. like:
                         * predictor_decompress_fir_adapt(predictor_error, tempout, ...)
                         * predictor_decompress_fir_adapt(predictor_error, outputsamples ...)
                         * little strange..
                         */
                    }
                }
                else
                { // not compressed, easy case
                    if (alac.setinfo_sample_size <= 16)
                    {
                        int bitsmove = 0;
                        for (int i = 0; i < outputsamples; i++)
                        {
                            int audiobits = readbits(alac, alac.setinfo_sample_size);
                            bitsmove = 32 - alac.setinfo_sample_size;

                            audiobits = ((audiobits << bitsmove) >> bitsmove);

                            alac.outputsamples_buffer_a[i] = audiobits;
                        }
                    }
                    else
                    {
                        int x;
                        int m = 1 << (24 - 1);
                        for (int i = 0; i < outputsamples; i++)
                        {
                            int audiobits;

                            audiobits = readbits(alac, 16);

                            /* special case of sign extension..
                             * as we'll be ORing the low 16bits into this */
                            audiobits = audiobits << (alac.setinfo_sample_size - 16);
                            audiobits = audiobits | readbits(alac, alac.setinfo_sample_size - 16);
                            x         = audiobits & ((1 << 24) - 1);
                            audiobits = (x ^ m) - m;    // sign extend 24 bits

                            alac.outputsamples_buffer_a[i] = audiobits;
                        }
                    }
                    uncompressed_bytes = 0; // always 0 for uncompressed
                }

                switch (alac.setinfo_sample_size)
                {
                case 16:
                {
                    for (int i = 0; i < outputsamples; i++)
                    {
                        int sample = alac.outputsamples_buffer_a[i];
                        outbuffer[i * alac.numchannels] = sample;

                        /*
                        ** We have to handle the case where the data is actually mono, but the stsd atom says it has 2 channels
                        ** in this case we create a stereo file where one of the channels is silent. If mono and 1 channel this value
                        ** will be overwritten in the next iteration
                        */

                        outbuffer[(i * alac.numchannels) + 1] = 0;
                    }
                    break;
                }

                case 24:
                {
                    for (int i = 0; i < outputsamples; i++)
                    {
                        int sample = alac.outputsamples_buffer_a[i];

                        if (uncompressed_bytes != 0)
                        {
                            int mask = 0;
                            sample = sample << (uncompressed_bytes * 8);
                            mask   = (int)~(0xFFFFFFFF << (uncompressed_bytes * 8));
                            sample = sample | (alac.uncompressed_bytes_buffer_a[i] & mask);
                        }

                        outbuffer[i * alac.numchannels * 3]     = ((sample) & 0xFF);
                        outbuffer[i * alac.numchannels * 3 + 1] = ((sample >> 8) & 0xFF);
                        outbuffer[i * alac.numchannels * 3 + 2] = ((sample >> 16) & 0xFF);

                        /*
                        ** We have to handle the case where the data is actually mono, but the stsd atom says it has 2 channels
                        ** in this case we create a stereo file where one of the channels is silent. If mono and 1 channel this value
                        ** will be overwritten in the next iteration
                        */

                        outbuffer[i * alac.numchannels * 3 + 3] = 0;
                        outbuffer[i * alac.numchannels * 3 + 4] = 0;
                        outbuffer[i * alac.numchannels * 3 + 5] = 0;
                    }
                    break;
                }

                case 20:
                case 32:
                    //System.err.println("FIXME: unimplemented sample size " + alac.setinfo_sample_size);
                    break;

                default:
                    break;
                }
            }
            else if (channels == 1) // 2 channels
            {
                int hassize;
                int isnotcompressed;
                int readsamplesize;

                int uncompressed_bytes;

                int interlacing_shift;
                int interlacing_leftweight;

                /* 2^result = something to do with output waiting.
                 * perhaps matters if we read > 1 frame in a pass?
                 */
                readbits(alac, 4);

                readbits(alac, 12);                     // unknown, skip 12 bits

                hassize = readbits(alac, 1);            // the output sample size is stored soon

                uncompressed_bytes = readbits(alac, 2); // the number of bytes in the (compressed) stream that are not compressed

                isnotcompressed = readbits(alac, 1);    // whether the frame is compressed

                if (hassize != 0)
                {
                    /* now read the number of samples,
                     * as a 32bit integer */
                    outputsamples = readbits(alac, 32);
                    outputsize    = outputsamples * alac.bytespersample;
                }

                readsamplesize = alac.setinfo_sample_size - (uncompressed_bytes * 8) + 1;

                if (isnotcompressed == 0)
                { // compressed
                    int[] predictor_coef_table_a = alac.predictor_coef_table_a;
                    int   predictor_coef_num_a;
                    int   prediction_type_a;
                    int   prediction_quantitization_a;
                    int   ricemodifier_a;

                    int[] predictor_coef_table_b = alac.predictor_coef_table_b;
                    int   predictor_coef_num_b;
                    int   prediction_type_b;
                    int   prediction_quantitization_b;
                    int   ricemodifier_b;

                    int tempPred = 0;

                    interlacing_shift      = readbits(alac, 8);
                    interlacing_leftweight = readbits(alac, 8);

                    /******** channel 1 ***********/
                    prediction_type_a           = readbits(alac, 4);
                    prediction_quantitization_a = readbits(alac, 4);

                    ricemodifier_a       = readbits(alac, 3);
                    predictor_coef_num_a = readbits(alac, 5);

                    /* read the predictor table */

                    for (int i = 0; i < predictor_coef_num_a; i++)
                    {
                        tempPred = readbits(alac, 16);
                        if (tempPred > 32767)
                        {
                            // the predictor coef table values are only 16 bit signed
                            tempPred = tempPred - 65536;
                        }
                        predictor_coef_table_a[i] = tempPred;
                    }

                    /******** channel 2 *********/
                    prediction_type_b           = readbits(alac, 4);
                    prediction_quantitization_b = readbits(alac, 4);

                    ricemodifier_b       = readbits(alac, 3);
                    predictor_coef_num_b = readbits(alac, 5);

                    /* read the predictor table */

                    for (int i = 0; i < predictor_coef_num_b; i++)
                    {
                        tempPred = readbits(alac, 16);
                        if (tempPred > 32767)
                        {
                            // the predictor coef table values are only 16 bit signed
                            tempPred = tempPred - 65536;
                        }
                        predictor_coef_table_b[i] = tempPred;
                    }

                    /*********************/
                    if (uncompressed_bytes != 0)
                    { // see mono case
                        for (int i = 0; i < outputsamples; i++)
                        {
                            alac.uncompressed_bytes_buffer_a[i] = readbits(alac, uncompressed_bytes * 8);
                            alac.uncompressed_bytes_buffer_b[i] = readbits(alac, uncompressed_bytes * 8);
                        }
                    }

                    /* channel 1 */

                    entropy_rice_decode(alac, alac.predicterror_buffer_a, outputsamples, readsamplesize, alac.setinfo_rice_initialhistory, alac.setinfo_rice_kmodifier, ricemodifier_a * (alac.setinfo_rice_historymult / 4), (uint)(1 << alac.setinfo_rice_kmodifier) - 1);

                    if (prediction_type_a == 0)
                    { // adaptive fir
                        alac.outputsamples_buffer_a = predictor_decompress_fir_adapt(alac.predicterror_buffer_a, outputsamples, readsamplesize, predictor_coef_table_a, predictor_coef_num_a, prediction_quantitization_a);
                    }
                    else
                    { // see mono case
                      //System.err.println("FIXME: unhandled predicition type: " + prediction_type_a);
                    }

                    /* channel 2 */
                    entropy_rice_decode(alac, alac.predicterror_buffer_b, outputsamples, readsamplesize, alac.setinfo_rice_initialhistory, alac.setinfo_rice_kmodifier, ricemodifier_b * (alac.setinfo_rice_historymult / 4), (uint)(1 << alac.setinfo_rice_kmodifier) - 1);

                    if (prediction_type_b == 0)
                    { // adaptive fir
                        alac.outputsamples_buffer_b = predictor_decompress_fir_adapt(alac.predicterror_buffer_b, outputsamples, readsamplesize, predictor_coef_table_b, predictor_coef_num_b, prediction_quantitization_b);
                    }
                    else
                    {
                        //System.err.println("FIXME: unhandled predicition type: " + prediction_type_b);
                    }
                }
                else
                { // not compressed, easy case
                    if (alac.setinfo_sample_size <= 16)
                    {
                        int bitsmove;

                        for (int i = 0; i < outputsamples; i++)
                        {
                            int audiobits_a;
                            int audiobits_b;

                            audiobits_a = readbits(alac, alac.setinfo_sample_size);
                            audiobits_b = readbits(alac, alac.setinfo_sample_size);

                            bitsmove = 32 - alac.setinfo_sample_size;

                            audiobits_a = ((audiobits_a << bitsmove) >> bitsmove);
                            audiobits_b = ((audiobits_b << bitsmove) >> bitsmove);

                            alac.outputsamples_buffer_a[i] = audiobits_a;
                            alac.outputsamples_buffer_b[i] = audiobits_b;
                        }
                    }
                    else
                    {
                        int x;
                        int m = 1 << (24 - 1);

                        for (int i = 0; i < outputsamples; i++)
                        {
                            int audiobits_a;
                            int audiobits_b;

                            audiobits_a = readbits(alac, 16);
                            audiobits_a = audiobits_a << (alac.setinfo_sample_size - 16);
                            audiobits_a = audiobits_a | readbits(alac, alac.setinfo_sample_size - 16);
                            x           = audiobits_a & ((1 << 24) - 1);
                            audiobits_a = (x ^ m) - m;        // sign extend 24 bits

                            audiobits_b = readbits(alac, 16);
                            audiobits_b = audiobits_b << (alac.setinfo_sample_size - 16);
                            audiobits_b = audiobits_b | readbits(alac, alac.setinfo_sample_size - 16);
                            x           = audiobits_b & ((1 << 24) - 1);
                            audiobits_b = (x ^ m) - m;        // sign extend 24 bits

                            alac.outputsamples_buffer_a[i] = audiobits_a;
                            alac.outputsamples_buffer_b[i] = audiobits_b;
                        }
                    }
                    uncompressed_bytes     = 0; // always 0 for uncompressed
                    interlacing_shift      = 0;
                    interlacing_leftweight = 0;
                }

                switch (alac.setinfo_sample_size)
                {
                case 16:
                {
                    deinterlace_16(alac.outputsamples_buffer_a, alac.outputsamples_buffer_b, outbuffer, alac.numchannels, outputsamples, interlacing_shift, interlacing_leftweight);
                    break;
                }

                case 24:
                {
                    deinterlace_24(alac.outputsamples_buffer_a, alac.outputsamples_buffer_b, uncompressed_bytes, alac.uncompressed_bytes_buffer_a, alac.uncompressed_bytes_buffer_b, outbuffer, alac.numchannels, outputsamples, interlacing_shift, interlacing_leftweight);
                    break;
                }

                case 20:
                case 32:
                    //System.err.println("FIXME: unimplemented sample size " + alac.setinfo_sample_size);
                    break;

                default:
                    break;
                }
            }
            return(outputsize);
        }
        public static void entropy_rice_decode(AlacFile alac, int[] outputBuffer, int outputSize, int readSampleSize, int rice_initialhistory, int rice_kmodifier, int rice_historymult, uint rice_kmodifier_mask)
        {
            int history      = rice_initialhistory;
            int outputCount  = 0;
            int signModifier = 0;

            while (outputCount < outputSize)
            {
                int decodedValue = 0;
                int finalValue   = 0;
                int k            = 0;

                k = 31 - rice_kmodifier - count_leading_zeros((history >> 9) + 3, alac.lz);

                if (k < 0)
                {
                    k += rice_kmodifier;
                }
                else
                {
                    k = rice_kmodifier;
                }

                // note: don't use rice_kmodifier_mask here (set mask to 0xFFFFFFFF)
                decodedValue = entropy_decode_value(alac, readSampleSize, k, 0xFFFFFFFF);

                decodedValue += signModifier;
                finalValue    = ((decodedValue + 1) / 2); // inc by 1 and shift out sign bit
                if ((decodedValue & 1) != 0)              // the sign is stored in the low bit
                {
                    finalValue *= -1;
                }

                outputBuffer[outputCount] = finalValue;

                signModifier = 0;

                // update history
                history += (decodedValue * rice_historymult) - ((history * rice_historymult) >> 9);

                if (decodedValue > 0xFFFF)
                {
                    history = 0xFFFF;
                }

                // special case, for compressed blocks of 0
                if ((history < 128) && (outputCount + 1 < outputSize))
                {
                    int blockSize = 0;

                    signModifier = 1;

                    k = count_leading_zeros(history, alac.lz) + ((history + 16) / 64) - 24;

                    // note: blockSize is always 16bit
                    blockSize = entropy_decode_value(alac, 16, k, rice_kmodifier_mask);

                    // got blockSize 0s
                    if (blockSize > 0)
                    {
                        int countSize = 0;
                        countSize = blockSize;
                        for (int j = 0; j < countSize; j++)
                        {
                            outputBuffer[outputCount + 1 + j] = 0;
                        }
                        outputCount += blockSize;
                    }

                    if (blockSize > 0xFFFF)
                    {
                        signModifier = 0;
                    }

                    history = 0;
                }

                outputCount++;
            }
        }