NScumm.Scumm.Audio.IMuse.IMuseDigital.BundleCodecs.DecompressCodec C# (CSharp) Method

DecompressCodec() public static method

public static DecompressCodec ( int codec, byte compInput, byte compOutput, int inputSize ) : int
codec int
compInput byte
compOutput byte
inputSize int
return int
        public static int DecompressCodec(int codec, byte[] compInput, byte[] compOutput, int inputSize)
        {
            int outputSize;
            int offset1, offset2, offset3, length, k, c, s, j, r, t, z;
            int ptr;
            byte t_tmp1, t_tmp2;

            switch (codec)
            {
                case 0:
                    Array.Copy(compOutput, compOutput, inputSize);
                    outputSize = inputSize;
                    break;

                case 1:
                    outputSize = CompDecode(compInput, compOutput);
                    break;

                case 2:
                    outputSize = CompDecode(compInput, compOutput);
                    for (z = 1; z < outputSize; z++)
                        compOutput[z] += compOutput[z - 1];
                    break;

                case 3:
                    outputSize = CompDecode(compInput, compOutput);
                    for (z = 2; z < outputSize; z++)
                        compOutput[z] += compOutput[z - 1];
                    for (z = 1; z < outputSize; z++)
                        compOutput[z] += compOutput[z - 1];
                    break;

                case 4:
                    outputSize = CompDecode(compInput, compOutput);
                    for (z = 2; z < outputSize; z++)
                        compOutput[z] += compOutput[z - 1];
                    for (z = 1; z < outputSize; z++)
                        compOutput[z] += compOutput[z - 1];

                    var t_table = new byte[outputSize];

                    var src = compOutput;
                    length = (outputSize << 3) / 12;
                    k = 0;
                    if (length > 0)
                    {
                        c = -12;
                        s = 0;
                        j = 0;
                        do
                        {
                            ptr = length + (k >> 1);
                            t_tmp2 = src[j];
                            if ((k & 1) != 0)
                            {
                                r = c >> 3;
                                t_table[r + 2] = (byte)(((t_tmp2 & 0x0f) << 4) | (src[ptr + 1] >> 4));
                                t_table[r + 1] = (byte)((t_tmp2 & 0xf0) | (t_table[r + 1]));
                            }
                            else
                            {
                                r = s >> 3;
                                t_table[r + 0] = (byte)(((t_tmp2 & 0x0f) << 4) | (src[ptr] & 0x0f));
                                t_table[r + 1] = (byte)(t_tmp2 >> 4);
                            }
                            s += 12;
                            c += 12;
                            k++;
                            j++;
                        } while (k < length);
                    }
                    offset1 = ((length - 1) * 3) >> 1;
                    t_table[offset1 + 1] = (byte)((t_table[offset1 + 1]) | (src[length - 1] & 0xf0));
                    Array.Copy(t_table, src, outputSize);
                    break;

                case 5:
                    outputSize = CompDecode(compInput, compOutput);
                    for (z = 2; z < outputSize; z++)
                        compOutput[z] += compOutput[z - 1];
                    for (z = 1; z < outputSize; z++)
                        compOutput[z] += compOutput[z - 1];

                    t_table = new byte[outputSize];

                    src = compOutput;
                    length = (outputSize << 3) / 12;
                    k = 1;
                    c = 0;
                    s = 12;
                    t_table[0] = (byte)(src[length] >> 4);
                    t = length + k;
                    j = 1;
                    if (t > k)
                    {
                        do
                        {
                            t_tmp1 = src[length + (k >> 1)];
                            t_tmp2 = src[j - 1];
                            if ((k & 1) != 0)
                            {
                                r = c >> 3;
                                t_table[r + 0] = (byte)((t_tmp2 & 0xf0) | t_table[r]);
                                t_table[r + 1] = (byte)(((t_tmp2 & 0x0f) << 4) | (t_tmp1 & 0x0f));
                            }
                            else
                            {
                                r = s >> 3;
                                t_table[r + 0] = (byte)(t_tmp2 >> 4);
                                t_table[r - 1] = (byte)(((t_tmp2 & 0x0f) << 4) | (t_tmp1 >> 4));
                            }
                            s += 12;
                            c += 12;
                            k++;
                            j++;
                        } while (k < t);
                    }
                    Array.Copy(t_table, src, outputSize);
                    break;

                case 6:
                    outputSize = CompDecode(compInput, compOutput);
                    for (z = 2; z < outputSize; z++)
                        compOutput[z] += compOutput[z - 1];
                    for (z = 1; z < outputSize; z++)
                        compOutput[z] += compOutput[z - 1];

                    t_table = new byte[outputSize];

                    src = compOutput;
                    length = (outputSize << 3) / 12;
                    k = 0;
                    c = 0;
                    j = 0;
                    s = -12;
                    t_table[0] = src[outputSize - 1];
                    t_table[outputSize - 1] = src[length - 1];
                    t = length - 1;
                    if (t > 0)
                    {
                        do
                        {
                            t_tmp1 = src[length + (k >> 1)];
                            t_tmp2 = src[j];
                            if ((k & 1) != 0)
                            {
                                r = s >> 3;
                                t_table[r + 2] = (byte)((t_tmp2 & 0xf0) | t_table[r + 2]);
                                t_table[r + 3] = (byte)(((t_tmp2 & 0x0f) << 4) | (t_tmp1 >> 4));
                            }
                            else
                            {
                                r = c >> 3;
                                t_table[r + 2] = (byte)(t_tmp2 >> 4);
                                t_table[r + 1] = (byte)(((t_tmp2 & 0x0f) << 4) | (t_tmp1 & 0x0f));
                            }
                            s += 12;
                            c += 12;
                            k++;
                            j++;
                        } while (k < t);
                    }
                    Array.Copy(t_table, src, outputSize);
                    break;

                case 10:
                    outputSize = CompDecode(compInput, compOutput);
                    for (z = 2; z < outputSize; z++)
                        compOutput[z] += compOutput[z - 1];
                    for (z = 1; z < outputSize; z++)
                        compOutput[z] += compOutput[z - 1];

                    t_table = new byte[outputSize];
                    Array.Copy(compOutput, t_table, outputSize);

                    offset1 = outputSize / 3;
                    offset2 = offset1 << 1;
                    offset3 = offset2;
                    src = compOutput;

                    while ((offset1--) != 0)
                    {
                        offset2 -= 2;
                        offset3--;
                        t_table[offset2 + 0] = src[offset1];
                        t_table[offset2 + 1] = src[offset3];
                    }

                    src = compOutput;
                    length = (outputSize << 3) / 12;
                    k = 0;
                    if (length > 0)
                    {
                        c = -12;
                        s = 0;
                        do
                        {
                            j = length + (k >> 1);
                            t_tmp1 = t_table[k];
                            if ((k & 1) != 0)
                            {
                                r = c >> 3;
                                t_tmp2 = t_table[j + 1];
                                src[r + 2] = (byte)(((t_tmp1 & 0x0f) << 4) | (t_tmp2 >> 4));
                                src[r + 1] = (byte)((src[r + 1]) | (t_tmp1 & 0xf0));
                            }
                            else
                            {
                                r = s >> 3;
                                t_tmp2 = t_table[j];
                                src[r + 0] = (byte)(((t_tmp1 & 0x0f) << 4) | (t_tmp2 & 0x0f));
                                src[r + 1] = (byte)(t_tmp1 >> 4);
                            }
                            s += 12;
                            c += 12;
                            k++;
                        } while (k < length);
                    }
                    offset1 = ((length - 1) * 3) >> 1;
                    src[offset1 + 1] = (byte)((t_table[length] & 0xf0) | src[offset1 + 1]);
                    break;

                case 11:
                    outputSize = CompDecode(compInput, compOutput);
                    for (z = 2; z < outputSize; z++)
                        compOutput[z] += compOutput[z - 1];
                    for (z = 1; z < outputSize; z++)
                        compOutput[z] += compOutput[z - 1];

                    t_table = new byte[outputSize];
                    Array.Copy(compOutput, t_table, outputSize);

                    offset1 = outputSize / 3;
                    offset2 = offset1 << 1;
                    offset3 = offset2;
                    src = compOutput;

                    while ((offset1--) != 0)
                    {
                        offset2 -= 2;
                        offset3--;
                        t_table[offset2 + 0] = src[offset1];
                        t_table[offset2 + 1] = src[offset3];
                    }

                    src = compOutput;
                    length = (outputSize << 3) / 12;
                    k = 1;
                    c = 0;
                    s = 12;
                    t_tmp1 = (byte)(t_table[length] >> 4);
                    src[0] = t_tmp1;
                    t = length + k;
                    if (t > k)
                    {
                        do
                        {
                            j = length + (k >> 1);
                            t_tmp1 = t_table[k - 1];
                            t_tmp2 = t_table[j];
                            if ((k & 1) != 0)
                            {
                                r = c >> 3;
                                src[r + 0] = (byte)((src[r]) | (t_tmp1 & 0xf0));
                                src[r + 1] = (byte)(((t_tmp1 & 0x0f) << 4) | (t_tmp2 & 0x0f));
                            }
                            else
                            {
                                r = s >> 3;
                                src[r + 0] = (byte)(t_tmp1 >> 4);
                                src[r - 1] = (byte)(((t_tmp1 & 0x0f) << 4) | (t_tmp2 >> 4));
                            }
                            s += 12;
                            c += 12;
                            k++;
                        } while (k < t);
                    }
                    break;

                case 12:
                    outputSize = CompDecode(compInput, compOutput);
                    for (z = 2; z < outputSize; z++)
                        compOutput[z] += compOutput[z - 1];
                    for (z = 1; z < outputSize; z++)
                        compOutput[z] += compOutput[z - 1];

                    t_table = new byte[outputSize];
                    Array.Copy(compOutput, t_table, outputSize);

                    offset1 = outputSize / 3;
                    offset2 = offset1 << 1;
                    offset3 = offset2;
                    src = compOutput;

                    while ((offset1--) != 0)
                    {
                        offset2 -= 2;
                        offset3--;
                        t_table[offset2 + 0] = src[offset1];
                        t_table[offset2 + 1] = src[offset3];
                    }

                    src = compOutput;
                    length = (outputSize << 3) / 12;
                    k = 0;
                    c = 0;
                    s = -12;
                    src[0] = t_table[outputSize - 1];
                    src[outputSize - 1] = t_table[length - 1];
                    t = length - 1;
                    if (t > 0)
                    {
                        do
                        {
                            j = length + (k >> 1);
                            t_tmp1 = t_table[k];
                            t_tmp2 = t_table[j];
                            if ((k & 1) != 0)
                            {
                                r = s >> 3;
                                src[r + 2] = (byte)((src[r + 2]) | (t_tmp1 & 0xf0));
                                src[r + 3] = (byte)(((t_tmp1 & 0x0f) << 4) | (t_tmp2 >> 4));
                            }
                            else
                            {
                                r = c >> 3;
                                src[r + 2] = (byte)(t_tmp1 >> 4);
                                src[r + 1] = (byte)(((t_tmp1 & 0x0f) << 4) | (t_tmp2 & 0x0f));
                            }
                            s += 12;
                            c += 12;
                            k++;
                        } while (k < t);
                    }
                    break;

                case 13:
                case 15:
                    outputSize = DecompressADPCM(compInput, compOutput, (codec == 13) ? 1 : 2);
                    break;

                default:
//                    Console.Error.WriteLine("BundleCodecs::decompressCodec() Unknown codec {0}", codec);
                    outputSize = 0;
                    break;
            }

            return outputSize;
        }

Usage Example

コード例 #1
0
        public int DecompressSampleByIndex(int index, int offset, int size, out byte[] compFinal, int headerSize, bool headerOutside)
        {
            int finalSize, outputSize;
            int skip, firstBlock, lastBlock;

            Debug.Assert(0 <= index && index < _numFiles);

            if (_curSampleId == -1)
            {
                _curSampleId = index;
            }

            Debug.Assert(_curSampleId == index);

            if (!_compTableLoaded)
            {
                _compTableLoaded = LoadCompTable(index);
                if (!_compTableLoaded)
                {
                    compFinal = null;
                    return(0);
                }
            }

            firstBlock = (offset + headerSize) / 0x2000;
            lastBlock  = (offset + headerSize + size - 1) / 0x2000;

            // Clip last_block by the total number of blocks (= "comp items")
            if ((lastBlock >= _numCompItems) && (_numCompItems > 0))
            {
                lastBlock = _numCompItems - 1;
            }

            int blocksFinalSize = 0x2000 * (1 + lastBlock - firstBlock);

            compFinal = new byte[blocksFinalSize];
            finalSize = 0;

            skip = (offset + headerSize) % 0x2000;

            for (var i = firstBlock; i <= lastBlock; i++)
            {
                if (_lastBlock != i)
                {
                    // CMI hack: one more zero byte at the end of input buffer
                    _compInputBuff[_compTable[i].Size] = 0;
                    _file.BaseStream.Seek(_bundleTable[index].Offset + _compTable[i].Offset, SeekOrigin.Begin);
                    _file.BaseStream.Read(_compInputBuff, 0, _compTable[i].Size);
                    _outputSize = BundleCodecs.DecompressCodec(_compTable[i].Codec, _compInputBuff, _compOutputBuff, _compTable[i].Size);
                    if (_outputSize > 0x2000)
                    {
//                        Console.Error.WriteLine("_outputSize: {0}", _outputSize);
                    }
                    _lastBlock = i;
                }

                outputSize = _outputSize;

                if (headerOutside)
                {
                    outputSize -= skip;
                }
                else
                {
                    if ((headerSize != 0) && (skip >= headerSize))
                    {
                        outputSize -= skip;
                    }
                }

                if ((outputSize + skip) > 0x2000) // workaround
                {
                    outputSize -= (outputSize + skip) - 0x2000;
                }

                if (outputSize > size)
                {
                    outputSize = size;
                }

                Debug.Assert(finalSize + outputSize <= blocksFinalSize);

                Array.Copy(_compOutputBuff, skip, compFinal, finalSize, outputSize);
                finalSize += outputSize;

                size -= outputSize;
                Debug.Assert(size >= 0);
                if (size == 0)
                {
                    break;
                }

                skip = 0;
            }

            return(finalSize);
        }