예제 #1
0
파일: DCCFile.cs 프로젝트: mofr/SharpD2
        // ==========================================================================
        // stage 2 of the decompression of the direction frames
        // return 0 on success, non-zero if error
        List <Image> dcc_make_frame(int d)
        {
            List <Image> bitmaps = new List <Image>();

            DCC_DIRECTION_HEADER_S dir = dcc_direction_headers[d];
            int            pbei        = 0;
            DCC_PB_ENTRY_S pbe         = dir.pixel_buffer[pbei++];


            DCC_CELL_S buff_cell, cell;
            uint       pix;
            int        nb_cell, nb_bit,
                       cell_x, cell_y, cell_idx,
                       x, y, c;
            //Bitmap frm_bmp;
            //char            add_error[256];

            BitArray pixelCodesAndDisplacementBits       = new BitArray(dcc_direction_headers[d].PixelCodesAndDisplacementBitstream);
            int      pixelCodesAndDisplacementBitsOffset = dcc_direction_headers[d].pco;

            // initialised the last_w & last_h of the buffer cells
            for (c = 0; c < dir.nb_cells_w * dir.nb_cells_h; c++)
            {
                dir.cells[c].last_w = -1;
                dir.cells[c].last_h = -1;
            }



            // for all frames
            for (int f = 0; f < dcc_header.frames_per_dir; f++)
            {
                // create the temp frame bitmap (size = current direction box)
                //DCC_FRAME_HEADER_S frame = dir.frame_headers[f];

                var frm_bmp = new Bitmap(dir.box.width, dir.box.height);
                using (var g = Graphics.FromImage(frm_bmp))
                {
                    g.Clear(Color.Transparent);
                }

                //clear(frm_bmp); // clear the final frame bitmap (to index 0)

                nb_cell = dir.frame_headers[f].nb_cells_w * dir.frame_headers[f].nb_cells_h;

                // for all cells of this frame
                for (c = 0; c < nb_cell; c++)
                {
                    // frame cell
                    cell = dir.frame_headers[f].cells[c];

                    // buffer cell
                    cell_x   = cell.x0 / 4;
                    cell_y   = cell.y0 / 4;
                    cell_idx = cell_x + (cell_y * (dir.nb_cells_w - 1));

                    buff_cell = dir.cells[cell_idx];

                    // equal cell checks
                    if ((pbe.frame != f) || (pbe.frame_cell_index != c))
                    {
                        // this buffer cell have an equalcell bit set to 1
                        //    so either copy the frame cell or clear it

                        if ((cell.w != buff_cell.last_w) || (cell.h != buff_cell.last_h))
                        {
                            // different sizes
                            //clear(cell.bmp); // set all pixels of the frame cell to 0

                            using (var g = Graphics.FromImage(dir.frame_headers[f].cells[c].bmp))
                            {
                                g.Clear(Color.Magenta);
                            }
                        }
                        else
                        {
                            // same sizes

                            //// copy the old frame cell into its new position
                            //blit(dir.bmp, dir.bmp,
                            //    buff_cell.last_x0, buff_cell.last_y0,
                            //    cell.x0, cell.y0,
                            //    cell.w, cell.h
                            //);

                            using (var fg = Graphics.FromImage(dcc_direction_headers[d].bmp))
                            {
                                fg.DrawImage(dcc_direction_headers[d].bmp, cell.x0, cell.y0);
                            }

                            //// copy it again, into the final frame bitmap
                            //blit(cell.bmp, frm_bmp,
                            //    0, 0,
                            //    cell.x0, cell.y0,
                            //    cell.w, cell.h
                            //);

                            using (var fg = Graphics.FromImage(frm_bmp))
                            {
                                fg.DrawImage(dir.frame_headers[f].cells[c].bmp, cell.x0, cell.y0);
                            }
                        }
                    }
                    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]);

                            byte color = pbe.val[0];
                            using (var g = Graphics.FromImage(dir.frame_headers[f].cells[c].bmp))
                            {
                                g.Clear(palette[color]);
                            }
                        }
                        else
                        {
                            if (pbe.val[1] == pbe.val[2])
                            {
                                nb_bit = 1;
                            }
                            else
                            {
                                nb_bit = 2;
                            }

                            //// fill FRAME cell with pixels
                            for (y = 0; y < cell.h; y++)
                            {
                                for (x = 0; x < cell.w; x++)
                                {
                                    //if (dcc_read_bits(
                                    //& dcc.direction[d].pixel_code_and_displacment_bitstream,
                                    //nb_bit, FALSE, & pix))
                                    //{
                                    //sprintf(add_error, "dcc_make_frame() :\n   "
                                    //    "pixel_code_and_displacment bitstream, direction %i, frame %i, "
                                    //    "curr_cell %i\n",
                                    //d, pbe.frame, pbe.frame_cell_index);
                                    //strcat(dcc_error, add_error);
                                    //return 1;
                                    //}

                                    pix = pixelCodesAndDisplacementBits.ToUInt32(ref pixelCodesAndDisplacementBitsOffset, (uint)nb_bit);

                                    byte color = pbe.val[pix];
                                    //if (pix < 3)
                                    {
                                        dir.frame_headers[f].cells[c].bmp.SetPixel(x, y, palette[color]);
                                    }

                                    //putpixel(cell.bmp, x, y, pbe.val[pix]);
                                }
                            }
                        }

                        //// copy the frame cell into the frame bitmap
                        //blit(cell.bmp, frm_bmp,
                        //        0, 0,
                        //        cell.x0, cell.y0,
                        //        cell.w, cell.h
                        //);

                        using (var fg = Graphics.FromImage(frm_bmp))
                        {
                            fg.DrawImage(dir.frame_headers[f].cells[c].bmp, cell.x0, cell.y0);
                        }

                        // next pixelbuffer entry
                        pbe = dir.pixel_buffer[pbei++];
                    }

                    // 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)
                    buff_cell.last_w = cell.w;
                    buff_cell.last_h = cell.h;

                    // and save its origin, for further copy when equalcell
                    buff_cell.last_x0 = cell.x0;
                    buff_cell.last_y0 = cell.y0;
                }

                // save frame
                bitmaps.Add(frm_bmp);
                //return frm_bmp;
            }

            return(bitmaps);
        }
예제 #2
0
파일: DCCFile.cs 프로젝트: mofr/SharpD2
        void LoadHeader()
        {
            long nb, s;

            int    size   = Marshal.SizeOf(typeof(DCC_Header_S));
            IntPtr buffer = Marshal.AllocHGlobal(size);

            try
            {
                Marshal.Copy(dc6_file, 0, buffer, size);
                dcc_header = (DCC_Header_S)Marshal.PtrToStructure(buffer, typeof(DCC_Header_S));
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }

            //nb = dcc_header.directions; // *dcc_header.frames_per_dir;
            dcc_direction_ptr     = new int[dcc_header.directions];
            dcc_direction_headers = new DCC_DIRECTION_HEADER_S[dcc_header.directions];

            s = sizeof(int) * dcc_header.directions;

            size   = Marshal.SizeOf(s);
            buffer = Marshal.AllocHGlobal(size);
            try
            {
                //Marshal.Copy(dc6_file, Marshal.SizeOf(typeof(DC6_Header_S)), buffer, (int)s);
                //var dptr = (int)Marshal.PtrToStructure(buffer, typeof(int));


                for (int i = 0; i < dcc_header.directions; i++)
                {
                    var ptr = BitConverter.ToInt32(dc6_file, Marshal.SizeOf(typeof(DCC_Header_S)) + (i * 4));
                    dcc_direction_ptr[i] = ptr;
                }
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }


            int      bitOffset = (int)((Marshal.SizeOf(typeof(DCC_Header_S)) + ((dcc_header.directions) * 4)) * 8);
            BitArray bits      = new BitArray(dc6_file);

            uint[] widthTable = { 0, 1, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 26, 28, 30, 32 };

            for (int i = 0; i < dcc_header.directions; i++)
            {
                int offsetStart = bitOffset;
                int directionBufferSize;
                if (i == dcc_header.directions - 1)
                {
                    directionBufferSize = 8 * (dc6_file.Length - dcc_direction_ptr[i]);
                }
                else
                {
                    directionBufferSize = 8 * (dcc_direction_ptr[i + 1] - dcc_direction_ptr[i]);
                }

                var directionHeader = new DCC_DIRECTION_HEADER_S();
                directionHeader.PixelValues   = new byte[256];
                directionHeader.frame_headers = new DCC_FRAME_HEADER_S[dcc_header.frames_per_dir];

                directionHeader.OutSizeCoded = bits.ToInt32(ref bitOffset);

                directionHeader.CompressionFlags = bits.ToByte(ref bitOffset, 2);

                directionHeader.Variable0Bits    = bits.ToUInt32(ref bitOffset, 4);
                directionHeader.WidthBits        = bits.ToUInt32(ref bitOffset, 4);
                directionHeader.HeightBits       = bits.ToUInt32(ref bitOffset, 4);
                directionHeader.XOffsetBits      = bits.ToUInt32(ref bitOffset, 4);
                directionHeader.YOffsetBits      = bits.ToUInt32(ref bitOffset, 4);
                directionHeader.OptionalDataBits = bits.ToUInt32(ref bitOffset, 4);
                directionHeader.CodedBytesBits   = bits.ToUInt32(ref bitOffset, 4);

                // Calculate box sizes
                // init direction box min & max (NOT ZERO !)
                directionHeader.box.xmin = directionHeader.box.ymin = int.MaxValue;
                directionHeader.box.xmax = directionHeader.box.ymax = int.MinValue;


                for (int j = 0; j < dcc_header.frames_per_dir; j++)
                {
                    var frameHeader = new DCC_FRAME_HEADER_S();
                    frameHeader.Variable0    = bits.ToUInt32(ref bitOffset, widthTable[directionHeader.Variable0Bits]);
                    frameHeader.width        = bits.ToUInt32(ref bitOffset, widthTable[directionHeader.WidthBits]);
                    frameHeader.height       = bits.ToUInt32(ref bitOffset, widthTable[directionHeader.HeightBits]);
                    frameHeader.offset_x     = bits.ToInt32(ref bitOffset, widthTable[directionHeader.XOffsetBits]);
                    frameHeader.offset_y     = bits.ToInt32(ref bitOffset, widthTable[directionHeader.YOffsetBits]);
                    frameHeader.optionalData = bits.ToUInt32(ref bitOffset, widthTable[directionHeader.OptionalDataBits]);
                    frameHeader.codedBytes   = bits.ToUInt32(ref bitOffset, widthTable[directionHeader.CodedBytesBits]);

                    frameHeader.FrameBottomUp = bits.ToBool(ref bitOffset);

                    // frame box
                    frameHeader.box.xmin = frameHeader.offset_x;
                    frameHeader.box.xmax = (int)(frameHeader.box.xmin + frameHeader.width - 1);

                    if (frameHeader.FrameBottomUp) // bottom-up
                    {
                        frameHeader.box.ymin = frameHeader.offset_y;
                        frameHeader.box.ymax = (int)(frameHeader.box.ymin + frameHeader.height - 1);
                    }
                    else // top-down
                    {
                        frameHeader.box.ymax = frameHeader.offset_y;
                        frameHeader.box.ymin = (int)(frameHeader.box.ymax - frameHeader.height + 1);
                    }
                    frameHeader.box.width  = frameHeader.box.xmax - frameHeader.box.xmin + 1;
                    frameHeader.box.height = frameHeader.box.ymax - frameHeader.box.ymin + 1;


                    // direction box
                    if (frameHeader.box.xmin < directionHeader.box.xmin)
                    {
                        directionHeader.box.xmin = frameHeader.box.xmin;
                    }

                    if (frameHeader.box.ymin < directionHeader.box.ymin)
                    {
                        directionHeader.box.ymin = frameHeader.box.ymin;
                    }

                    if (frameHeader.box.xmax > directionHeader.box.xmax)
                    {
                        directionHeader.box.xmax = frameHeader.box.xmax;
                    }

                    if (frameHeader.box.ymax > directionHeader.box.ymax)
                    {
                        directionHeader.box.ymax = frameHeader.box.ymax;
                    }

                    directionHeader.frame_headers[j] = frameHeader;
                }


                directionHeader.box.width  = directionHeader.box.xmax - directionHeader.box.xmin + 1;
                directionHeader.box.height = directionHeader.box.ymax - directionHeader.box.ymin + 1;



                //TODO OptionalData
                if (directionHeader.OptionalDataBits > 0)
                {
                    throw new NotImplementedException();
                }

                if ((directionHeader.CompressionFlags & 0x02) == 0x02)
                {
                    directionHeader.EqualCellsBitstreamSize = bits.ToUInt32(ref bitOffset, 20);
                }

                directionHeader.PixelMaskBitstreamSize = bits.ToUInt32(ref bitOffset, 20);

                if ((directionHeader.CompressionFlags & 0x01) == 0x01)
                {
                    directionHeader.EncodingTypeBitsreamSize   = bits.ToUInt32(ref bitOffset, 20);
                    directionHeader.RawPixelCodesBitstreamSize = bits.ToUInt32(ref bitOffset, 20);
                }

                directionHeader.PixelValuesKey = bits.ToBitArray(ref bitOffset, 256);

                int pi = 0;
                for (int p = 0; p < 256; p++)
                {
                    if (directionHeader.PixelValuesKey[p])
                    {
                        directionHeader.PixelValues[pi++] = (byte)p;
                    }
                }

                directionHeader.EqualCellsBitstream    = bits.ToBytes(ref bitOffset, directionHeader.EqualCellsBitstreamSize);
                directionHeader.PixelMaskBitstream     = bits.ToBytes(ref bitOffset, directionHeader.PixelMaskBitstreamSize);
                directionHeader.EncodingTypeBitsream   = bits.ToBytes(ref bitOffset, directionHeader.EncodingTypeBitsreamSize);
                directionHeader.RawPixelCodesBitstream = bits.ToBytes(ref bitOffset, directionHeader.RawPixelCodesBitstreamSize);


                directionHeader.PixelCodesAndDisplacementBitstream = bits.ToBytes(ref bitOffset, (uint)(directionBufferSize - (bitOffset - offsetStart)));

                dcc_direction_headers[i] = directionHeader;

                //size = Marshal.SizeOf(typeof(DC6_FRAME_HEADER_S));
                //buffer = Marshal.AllocHGlobal(size);
                //try
                //{
                //    Marshal.Copy(dc6_file, dcc_frame_ptr[i], buffer, size);
                //    var dc6_frame_header = (DC6_FRAME_HEADER_S)Marshal.PtrToStructure(buffer, typeof(DC6_FRAME_HEADER_S));

                //    dcc_frame_headers[i] = dc6_frame_header;
                //}
                //finally
                //{
                //    Marshal.FreeHGlobal(buffer);
                //}
            }
        }