NScumm.Core.Video.BigHuffmanTree.Reset C# (CSharp) Method

Reset() public method

public Reset ( ) : void
return void
        public void Reset()
        {
            _tree[_last[0]] = _tree[_last[1]] = _tree[_last[2]] = 0;
        }

Usage Example

Beispiel #1
0
        public void DecodeFrame(BitStream bs)
        {
            _mMapTree.Reset();
            _mClrTree.Reset();
            _fullTree.Reset();
            _typeTree.Reset();

            // Height needs to be doubled if we have flags (Y-interlaced or Y-doubled)
            uint doubleY = (uint)(_flags != 0 ? 2 : 1);

            uint bw = (uint)(Width / 4);
            uint bh = Height / doubleY / 4;
            int  stride = Width;
            uint block = 0, blocks = bw * bh;

            uint type, run, j, mode;
            uint p1, p2, clr, map;
            byte hi, lo;
            uint i;
            int  bOut;

            byte[] pixels = _surface.Pixels;
            while (block < blocks)
            {
                type = _typeTree.GetCode(bs);
                run  = GetBlockRun((int)((type >> 2) & 0x3f));

                switch (type & 3)
                {
                case SmkBlockMono:
                    while (run-- != 0 && block < blocks)
                    {
                        clr = _mClrTree.GetCode(bs);
                        map = _mMapTree.GetCode(bs);

                        bOut = (int)((block / bw) * (stride * 4 * doubleY) + (block % bw) * 4);
                        hi   = (byte)(clr >> 8);
                        lo   = (byte)(clr & 0xff);
                        for (i = 0; i < 4; i++)
                        {
                            for (j = 0; j < doubleY; j++)
                            {
                                pixels[bOut]     = (map & 1) != 0 ? hi : lo;
                                pixels[bOut + 1] = (map & 2) != 0 ? hi : lo;
                                pixels[bOut + 2] = (map & 4) != 0 ? hi : lo;
                                pixels[bOut + 3] = (map & 8) != 0 ? hi : lo;
                                bOut            += stride;
                            }
                            map >>= 4;
                        }
                        ++block;
                    }
                    break;

                case SmkBlockFull:
                    // Smacker v2 has one mode, Smacker v4 has three
                    if (_signature == ScummHelper.MakeTag('S', 'M', 'K', '2'))
                    {
                        mode = 0;
                    }
                    else
                    {
                        // 00 - mode 0
                        // 10 - mode 1
                        // 01 - mode 2
                        mode = 0;
                        if (bs.GetBit() != 0)
                        {
                            mode = 1;
                        }
                        else if (bs.GetBit() != 0)
                        {
                            mode = 2;
                        }
                    }

                    while (run-- != 0 && block < blocks)
                    {
                        bOut = (int)((block / bw) * (stride * 4 * doubleY) + (block % bw) * 4);
                        switch (mode)
                        {
                        case 0:
                            for (i = 0; i < 4; ++i)
                            {
                                p1 = _fullTree.GetCode(bs);
                                p2 = _fullTree.GetCode(bs);
                                for (j = 0; j < doubleY; ++j)
                                {
                                    pixels[bOut + 2] = (byte)(p1 & 0xff);
                                    pixels[bOut + 3] = (byte)(p1 >> 8);
                                    pixels[bOut + 0] = (byte)(p2 & 0xff);
                                    pixels[bOut + 1] = (byte)(p2 >> 8);
                                    bOut            += stride;
                                }
                            }
                            break;

                        case 1:
                            p1 = _fullTree.GetCode(bs);
                            pixels[bOut + 0] = pixels[bOut + 1] = (byte)(p1 & 0xFF);
                            pixels[bOut + 2] = pixels[bOut + 3] = (byte)(p1 >> 8);
                            bOut            += stride;
                            pixels[bOut + 0] = pixels[bOut + 1] = (byte)(p1 & 0xFF);
                            pixels[bOut + 2] = pixels[bOut + 3] = (byte)(p1 >> 8);
                            bOut            += stride;
                            p2 = _fullTree.GetCode(bs);
                            pixels[bOut + 0] = pixels[bOut + 1] = (byte)(p2 & 0xFF);
                            pixels[bOut + 2] = pixels[bOut + 3] = (byte)(p2 >> 8);
                            bOut            += stride;
                            pixels[bOut + 0] = pixels[bOut + 1] = (byte)(p2 & 0xFF);
                            pixels[bOut + 2] = pixels[bOut + 3] = (byte)(p2 >> 8);
                            bOut            += stride;
                            break;

                        case 2:
                            for (i = 0; i < 2; i++)
                            {
                                // We first get p2 and then p1
                                // Check ffmpeg thread "[PATCH] Smacker video decoder bug fix"
                                // http://article.gmane.org/gmane.comp.video.ffmpeg.devel/78768
                                p2 = _fullTree.GetCode(bs);
                                p1 = _fullTree.GetCode(bs);
                                for (j = 0; j < doubleY; ++j)
                                {
                                    pixels[bOut + 0] = (byte)(p1 & 0xff);
                                    pixels[bOut + 1] = (byte)(p1 >> 8);
                                    pixels[bOut + 2] = (byte)(p2 & 0xff);
                                    pixels[bOut + 3] = (byte)(p2 >> 8);
                                    bOut            += stride;
                                }
                                for (j = 0; j < doubleY; ++j)
                                {
                                    pixels[bOut + 0] = (byte)(p1 & 0xff);
                                    pixels[bOut + 1] = (byte)(p1 >> 8);
                                    pixels[bOut + 2] = (byte)(p2 & 0xff);
                                    pixels[bOut + 3] = (byte)(p2 >> 8);
                                    bOut            += stride;
                                }
                            }
                            break;
                        }
                        ++block;
                    }
                    break;

                case SmkBlockSkip:
                    while (run-- != 0 && block < blocks)
                    {
                        block++;
                    }
                    break;

                case SmkBlockFill:
                    uint col;
                    mode = type >> 8;
                    while (run-- != 0 && block < blocks)
                    {
                        bOut = (int)((block / bw) * (stride * 4 * doubleY) + (block % bw) * 4);
                        col  = mode * 0x01010101;
                        for (i = 0; i < 4 * doubleY; ++i)
                        {
                            pixels[bOut + 0] = pixels[bOut + 1] = pixels[bOut + 2] = pixels[bOut + 3] = (byte)col;
                            bOut            += stride;
                        }
                        ++block;
                    }
                    break;
                }
            }
        }