示例#1
0
文件: DCC.cs 项目: r2d2m/Diablerie
        static void FillPixelBuffer(Header header, FrameBuffer frameBuffer, Direction dir, Streams streams)
        {
            PixelBufferEntry[] cellBuffer = new PixelBufferEntry[frameBuffer.cells.Length];
            int pixelMask = 0;

            int[] read_pixel = new int[4];
            int   pb_idx     = -1;

            for (int f = 0; f < header.framesPerDir; ++f)
            {
                Frame frame   = dir.frames[f];
                int   cell0_x = (frame.box.xMin - dir.box.xMin) / 4;
                int   cell0_y = (frame.box.yMin - dir.box.yMin) / 4;
                CreateFrameCells(dir.box, frame); // dcc_prepare_frame_cells
                int buffCellIndex  = cell0_x + cell0_y * frameBuffer.nb_cell_w;
                int frameCellIndex = 0;
                for (int y = 0; y < frame.nb_cell_h; ++y)
                {
                    for (int x = 0; x < frame.nb_cell_w; ++x, ++frameCellIndex)
                    {
                        int curr_cell = buffCellIndex + x;
                        if (cellBuffer[curr_cell].val != null)
                        {
                            if (streams.equalCell != null && streams.equalCell.ReadBool() != 0)
                            {
                                continue;
                            }

                            pixelMask = streams.pixelMask.ReadLessThanByte(4);
                        }
                        else
                        {
                            pixelMask = 0x0f;
                        }

                        read_pixel[0] = read_pixel[1] = read_pixel[2] = read_pixel[3] = 0;
                        int last_pixel   = 0;
                        int nb_pix       = nb_pix_table[pixelMask];
                        int encodingType = 0;
                        if (nb_pix != 0 && streams.encodingType != null)
                        {
                            encodingType = streams.encodingType.ReadBool();
                        }

                        int decoded_pix = 0;
                        for (int i = 0; i < nb_pix; i++)
                        {
                            if (encodingType != 0)
                            {
                                read_pixel[i] = streams.rawPixel.ReadByte();
                            }
                            else
                            {
                                read_pixel[i] = last_pixel;
                                int pix_displ = streams.pixelCode.ReadLessThanByte(4);
                                read_pixel[i] += pix_displ;
                                while (pix_displ == 15)
                                {
                                    pix_displ      = streams.pixelCode.ReadLessThanByte(4);
                                    read_pixel[i] += pix_displ;
                                }
                            }

                            if (read_pixel[i] == last_pixel)
                            {
                                read_pixel[i] = 0; // discard this pixel
                                break;             // stop the decoding of pixels
                            }
                            else
                            {
                                last_pixel = read_pixel[i];
                                decoded_pix++;
                            }
                        }

                        // we have the 4 pixels code for the new entry in pixel_buffer
                        PixelBufferEntry old_entry = cellBuffer[curr_cell];
                        pb_idx++;
                        var newEntry = new PixelBufferEntry();
                        newEntry.val = new byte[4];
                        int curr_idx = decoded_pix - 1;

                        for (int i = 0; i < 4; i++)
                        {
                            if ((pixelMask & (1 << i)) != 0)
                            {
                                if (curr_idx >= 0) // if stack is not empty, pop it
                                {
                                    newEntry.val[i] = (byte)read_pixel[curr_idx--];
                                }
                            }
                            else
                            {
                                newEntry.val[i] = old_entry.val[i];
                            }
                        }
                        newEntry.frame          = f;
                        newEntry.frameCellIndex = frameCellIndex;
                        pixelBuffer[pb_idx]     = newEntry;
                        cellBuffer[curr_cell]   = newEntry;
                    }

                    buffCellIndex += frameBuffer.nb_cell_w;
                }
            }

            for (int i = 0; i <= pb_idx; i++)
            {
                for (int x = 0; x < 4; x++)
                {
                    int y = pixelBuffer[i].val[x];
                    pixelBuffer[i].val[x] = dir.pixel_values[y];
                }
            }

            pixelBuffer[pb_idx + 1].frame = -1;
        }
示例#2
0
文件: DCC.cs 项目: r2d2m/Diablerie
        static void MakeFrames(Header header, Direction dir, FrameBuffer frameBuffer, Streams streams, List <Texture2D> textures, Sprite[] sprites)
        {
            const int padding       = 2;
            int       textureWidth  = Mathf.NextPowerOfTwo((dir.box.width + padding) * header.framesPerDir);
            int       textureHeight = Mathf.NextPowerOfTwo(dir.box.height + padding);

            textureWidth = Mathf.Min(1024, textureWidth);

            var       packer  = new TexturePacker(textureWidth, textureHeight);
            Texture2D texture = null;

            Color32[] pixels = null;

            for (int c = 0; c < frameBuffer.cells.Length; c++)
            {
                frameBuffer.cells[c].w = -1;
                frameBuffer.cells[c].h = -1;
            }

            int pb_idx           = 0;
            PixelBufferEntry pbe = pixelBuffer[pb_idx];

            for (int f = 0; f < header.framesPerDir; f++)
            {
                Frame frame = dir.frames[f];

                var pack = packer.put(dir.box.width + padding, dir.box.height + padding);
                if (pack.newTexture)
                {
                    if (texture != null)
                    {
                        texture.SetPixels32(pixels);
                        texture.Apply(false);
                    }
                    texture = new Texture2D(textureWidth, textureHeight, TextureFormat.RGBA32, false);
                    pixels  = new Color32[textureWidth * textureHeight];
                    textures.Add(texture);
                }
                frame.texture       = texture;
                frame.texturePixels = pixels;
                frame.textureX      = pack.x;
                frame.textureY      = pack.y;

                var textureRect = new Rect(frame.textureX, frame.textureY, dir.box.width, dir.box.height);
                var pivot       = new Vector2(-dir.box.xMin / (float)dir.box.width, dir.box.yMax / (float)dir.box.height);
                sprites[f] = Sprite.Create(texture, textureRect, pivot, Iso.pixelsPerUnit, extrude: 0, meshType: SpriteMeshType.FullRect);

                int nb_cell = frame.nb_cell_w * frame.nb_cell_h;
                for (int c = 0; c < nb_cell; c++)
                {
                    Cell cell = frame.cells[c];

                    // buffer cell
                    int cell_x   = cell.x0 >> 2;
                    int cell_y   = cell.y0 >> 2;
                    int cell_idx = cell_x + (cell_y * frameBuffer.nb_cell_w);

                    // equal cell checks
                    if ((pbe.frame != f) || (pbe.frameCellIndex != c))
                    {
                        // this buffer cell have an equalcell bit set to 1 so copy the frame cell
                        Cell buff_cell = frameBuffer.cells[cell_idx];
                        if (cell.w == buff_cell.w && cell.h == buff_cell.h)
                        {
                            Frame refFrame  = dir.frames[f - 1];
                            int   textureY  = refFrame.textureY + dir.box.height - buff_cell.y0;
                            int   textureX  = refFrame.textureX + buff_cell.x0;
                            int   srcOffset = textureWidth * textureY + textureX;
                            textureY = frame.textureY + dir.box.height - cell.y0;
                            textureX = frame.textureX + cell.x0;
                            int dstOffset = textureWidth * textureY + textureX;
                            for (int y = 0; y < cell.h; y++)
                            {
                                System.Array.Copy(refFrame.texturePixels, srcOffset, frame.texturePixels, dstOffset, cell.w);
                                srcOffset -= textureWidth;
                                dstOffset -= textureWidth;
                            }
                        }
                    }
                    else
                    {
                        // fill the frame cell with pixels

                        if (pbe.val[0] == pbe.val[1])
                        {
                            // fill FRAME cell to color val[0]
                            //clear_to_color(cell->bmp, pbe->val[0]);
                        }
                        else
                        {
                            int nb_bit;
                            if (pbe.val[1] == pbe.val[2])
                            {
                                nb_bit = 1;
                            }
                            else
                            {
                                nb_bit = 2;
                            }

                            // fill FRAME cell with pixels
                            int textureY = frame.textureY + dir.box.height - cell.y0;
                            int textureX = frame.textureX + cell.x0;
                            int offset   = textureWidth * textureY + textureX;
                            for (int y = 0; y < cell.h; ++y)
                            {
                                for (int x = 0; x < cell.w; ++x)
                                {
                                    int     pix   = streams.pixelCode.ReadLessThanByte(nb_bit);
                                    Color32 color = Palette.palette[pbe.val[pix]];
                                    frame.texturePixels[offset + x] = color;
                                }
                                offset -= textureWidth;
                            }
                        }

                        // next pixelbuffer entry
                        pb_idx++;
                        pbe = pixelBuffer[pb_idx];
                    }

                    // for the buffer cell that was used by this frame cell,
                    // save the width & size of the current frame cell
                    // (needed for further tests about equalcell)
                    // and save its origin, for further copy when equalcell
                    frameBuffer.cells[cell_idx] = cell;
                }
            }

            if (texture != null)
            {
                texture.SetPixels32(pixels);
                texture.Apply(false);
            }
        }
示例#3
0
            private void FillPixelBuffer(BitMuncher pcd, BitMuncher ec, BitMuncher pm, BitMuncher et, BitMuncher rp)
            {
                UInt32 lastPixel = 0;

                var maxCellX = Frames.Sum(x => x.HorizontalCellCount);
                var maxCellY = Frames.Sum(x => x.VerticalCellCount);

                PixelBuffer = new PixelBufferEntry[maxCellX * maxCellY];
                for (var i = 0; i < maxCellX * maxCellY; i++)
                {
                    PixelBuffer[i] = new PixelBufferEntry {
                        Frame = -1, FrameCellIndex = -1, Value = new byte[4]
                    }
                }
                ;

                var cellBuffer = new PixelBufferEntry[HorizontalCellCount * VerticalCellCount];

                var    frameIndex = -1;
                var    pbIndex    = -1;
                UInt32 pixelMask  = 0x00;

                foreach (var frame in Frames)
                {
                    frameIndex++;
                    var originCellX    = (frame.Box.Left - Box.Left) / 4;
                    var originCellY    = (frame.Box.Top - Box.Top) / 4;
                    var frameCellIndex = 0;
                    for (var cellY = 0; cellY < frame.VerticalCellCount; cellY++)
                    {
                        var currentCellY = cellY + originCellY;
                        for (var cellX = 0; cellX < frame.HorizontalCellCount; cellX++, frameCellIndex++)
                        {
                            var currentCell = originCellX + cellX + (currentCellY * HorizontalCellCount);
                            var nextCell    = false;
                            var tmp         = 0;
                            if (cellBuffer[currentCell] != null)
                            {
                                if (EqualCellsBitstreamSize > 0)
                                {
                                    tmp = (int)ec.GetBit();
                                }
                                else
                                {
                                    tmp = 0;
                                }

                                if (tmp == 0)
                                {
                                    pixelMask = pm.GetBits(4);
                                }
                                else
                                {
                                    nextCell = true;
                                }
                            }
                            else
                            {
                                pixelMask = 0x0F;
                            }

                            if (nextCell)
                            {
                                continue;
                            }

                            // Decode the pixels
                            var pixelStack = new UInt32[4];
                            lastPixel = 0;
                            int numberOfPixelBits = pixelMaskLookup[pixelMask];
                            int encodingType      = 0;
                            if ((numberOfPixelBits != 0) && (EncodingTypeBitsreamSize > 0))
                            {
                                encodingType = (int)et.GetBit();
                            }
                            else
                            {
                                encodingType = 0;
                            }

                            int decodedPixel = 0;
                            for (int i = 0; i < numberOfPixelBits; i++)
                            {
                                if (encodingType != 0)
                                {
                                    pixelStack[i] = rp.GetBits(8);
                                }
                                else
                                {
                                    pixelStack[i] = lastPixel;
                                    var pixelDisplacement = pcd.GetBits(4);
                                    pixelStack[i] += pixelDisplacement;
                                    while (pixelDisplacement == 15)
                                    {
                                        pixelDisplacement = pcd.GetBits(4);
                                        pixelStack[i]    += pixelDisplacement;
                                    }
                                }
                                if (pixelStack[i] == lastPixel)
                                {
                                    pixelStack[i] = 0;
                                    i             = numberOfPixelBits; // Just break here....
                                }
                                else
                                {
                                    lastPixel = pixelStack[i];
                                    decodedPixel++;
                                }
                            }

                            var oldEntry = cellBuffer[currentCell];
                            pbIndex++;
                            var newEntry = PixelBuffer[pbIndex];
                            var curIdx   = decodedPixel - 1;

                            for (int i = 0; i < 4; i++)
                            {
                                if ((pixelMask & (1 << i)) != 0)
                                {
                                    if (curIdx >= 0)
                                    {
                                        newEntry.Value[i] = (byte)pixelStack[curIdx--];
                                    }
                                    else
                                    {
                                        newEntry.Value[i] = 0;
                                    }
                                }
                                else
                                {
                                    newEntry.Value[i] = oldEntry.Value[i];
                                }
                            }

                            cellBuffer[currentCell] = newEntry;
                            newEntry.Frame          = frameIndex;
                            newEntry.FrameCellIndex = cellX + (cellY * frame.HorizontalCellCount);
                        }
                    }
                }


                // Convert the palette entry index into actual palette entries
                for (var i = 0; i <= pbIndex; i++)
                {
                    for (var x = 0; x < 4; x++)
                    {
                        PixelBuffer[i].Value[x] = PaletteEntries[PixelBuffer[i].Value[x]];
                    }
                }
            }