public void Update(byte[] data, bool bigEndian)
        {
            VersionInfo versionInfo = bigEndian
                                          ? BigEndianMarshal.ByteArrayToStructureBigEndian <VersionInfo>(data)
                                          : BigEndianMarshal.ByteArrayToStructureLittleEndian <VersionInfo>(data);

            txtMajorVersion.Text  = $"{versionInfo.major}";
            txtMiddleVersion.Text = $"{versionInfo.middle}";
            txtMinorVersion.Text  = $"{versionInfo.minor}";
            txtVariety.Text       = $"{versionInfo.variety}";
            txtInternal.Text      = $"{versionInfo.interna1}";
            txtShortInfo.Text     = StringHandlers.CToString(versionInfo.short_info, Encoding.UTF8);
            txtLongInfo.Text      = StringHandlers.CToString(versionInfo.long_info, Encoding.UTF8);
        }
Beispiel #2
0
        static ResourceTypeBlock[] ResourceDecode(byte[] data)
        {
            uint pos = 0;

            byte[] buffer = new byte[Marshal.SizeOf(typeof(ResourcesHeader))];
            Array.Copy(data, pos, buffer, 0, buffer.Length);
            ResourcesHeader header = BigEndianMarshal.ByteArrayToStructureLittleEndian <ResourcesHeader>(buffer);

            if (header.magic != Consts.RESOURCES_HEADER_MAGIC)
            {
                return(null);
            }

            pos    = header.index_section_offset;
            buffer = new byte[Marshal.SizeOf(typeof(ResourceIndexSectionHeader))];
            if (pos + buffer.Length > data.Length)
            {
                return(null);
            }

            Array.Copy(data, pos, buffer, 0, buffer.Length);
            ResourceIndexSectionHeader indexHeader =
                BigEndianMarshal.ByteArrayToStructureLittleEndian <ResourceIndexSectionHeader>(buffer);

            pos += (uint)buffer.Length;

            ResourceIndexEntry[] indexes =
                new ResourceIndexEntry[(indexHeader.index_section_size -
                                        Marshal.SizeOf(typeof(ResourceIndexSectionHeader))) /
                                       Marshal.SizeOf(typeof(ResourceIndexEntry))];
            for (int i = 0; i < indexes.Length; i++)
            {
                buffer = new byte[Marshal.SizeOf(typeof(ResourceIndexEntry))];
                Array.Copy(data, pos, buffer, 0, buffer.Length);
                indexes[i] = BigEndianMarshal.ByteArrayToStructureLittleEndian <ResourceIndexEntry>(buffer);
                pos       += (uint)buffer.Length;
            }

            pos = indexHeader.info_table_offset;
            string[] types       = new string[header.resource_count];
            bool     terminated  = true;
            string   currentType = null;

            string[]       names = new string[header.resource_count];
            ResourceInfo[] infos = new ResourceInfo[header.resource_count];

            for (int i = 0; i < header.resource_count; i++)
            {
                if (terminated)
                {
                    buffer = new byte[4];
                    Array.Copy(data, pos, buffer, 0, 4);
                    currentType = Encoding.ASCII.GetString(buffer.Reverse().ToArray());
                    terminated  = false;
                    pos        += 4;
                }

                buffer = new byte[Marshal.SizeOf(typeof(ResourceInfo))];
                Array.Copy(data, pos, buffer, 0, buffer.Length);
                infos[i] = BigEndianMarshal.ByteArrayToStructureLittleEndian <ResourceInfo>(buffer);
                pos     += (uint)buffer.Length;
                buffer   = new byte[infos[i].name_size - 1];
                Array.Copy(data, pos, buffer, 0, buffer.Length);
                names[i] = Encoding.ASCII.GetString(buffer);
                pos     += (uint)(buffer.Length + 1);
                types[i] = currentType;

                if (BitConverter.ToInt32(data, (int)pos) != -1 ||
                    BitConverter.ToInt32(data, (int)pos + 4) != -1)
                {
                    continue;
                }

                terminated = true;
                pos       += 8;
            }

            Dictionary <string, List <Resource> > rezzes = new Dictionary <string, List <Resource> >();

            for (int i = 0; i < header.resource_count; i++)
            {
                rezzes.TryGetValue(types[i], out List <Resource> thisRezzes);

                if (thisRezzes == null)
                {
                    thisRezzes = new List <Resource>();
                }

                Resource rez = new Resource
                {
                    id    = infos[i].id,
                    index = infos[i].index,
                    name  = names[i],
                    data  = new byte[indexes[infos[i].index - 1].size]
                };

                Array.Copy(data, indexes[infos[i].index - 1].offset, rez.data, 0, rez.data.Length);

                thisRezzes.Add(rez);
                rezzes.Remove(types[i]);
                rezzes.Add(types[i], thisRezzes);
            }

            List <ResourceTypeBlock> result = new List <ResourceTypeBlock>();

            foreach (KeyValuePair <string, List <Resource> > kvp in rezzes)
            {
                ResourceTypeBlock block = new ResourceTypeBlock {
                    type = kvp.Key, resources = kvp.Value.ToArray()
                };
                result.Add(block);
            }

            return(result.ToArray());
        }
Beispiel #3
0
        /// <summary>
        ///     This will decode a bitmap array, or if data is not an array, return an array with the single bitmap element
        /// </summary>
        /// <param name="data">Data</param>
        /// <returns>Array of <see cref="DecodedBitmap" />, one per bitmap, null if the bitmap could not be decoded</returns>
        public static DecodedBitmap[] DecodeBitmap(byte[] data)
        {
            long pos = 0;
            BitmapArrayHeader bitmapArrayHeader;

            byte[] buffer = new byte[Marshal.SizeOf(typeof(BitmapInfoHeader))];

            List <DecodedBitmap> bitmaps = new List <DecodedBitmap>();

            do
            {
                Array.Copy(data, pos, buffer, 0, buffer.Length);
                bitmapArrayHeader = BigEndianMarshal.ByteArrayToStructureLittleEndian <BitmapArrayHeader>(buffer);
                long remaining;

                if (bitmapArrayHeader.Type == TYPE_BITMAP_ARRAY)
                {
                    remaining = bitmapArrayHeader.Size - Marshal.SizeOf(typeof(BitmapArrayHeader));
                    pos      += Marshal.SizeOf(typeof(BitmapArrayHeader));
                }
                else
                {
                    remaining = 1;
                    pos       = 0;
                    bitmapArrayHeader.Next = 0;
                }

                while (remaining > 0)
                {
                    buffer = new byte[Marshal.SizeOf(typeof(BitmapInfoHeader))];
                    Array.Copy(data, pos, buffer, 0, buffer.Length);
                    BitmapInfoHeader bitmapFileHeader =
                        BigEndianMarshal.ByteArrayToStructureLittleEndian <BitmapInfoHeader>(buffer);

                    // Stop at unknown header
                    if (bitmapFileHeader.Fix != 12)
                    {
                        break;
                    }

                    // Multiplanes not supported
                    if (bitmapFileHeader.Planes != 1)
                    {
                        break;
                    }

                    // TODO: Non paletted?
                    pos += Marshal.SizeOf(typeof(BitmapInfoHeader));
                    Rgb[] palette = new Rgb[1 << bitmapFileHeader.BitsPerPlane];
                    buffer = new byte[Marshal.SizeOf(typeof(Rgb))];
                    for (int i = 0; i < palette.Length; i++)
                    {
                        Array.Copy(data, pos, buffer, 0, buffer.Length);
                        pos       += buffer.Length;
                        palette[i] = BigEndianMarshal.ByteArrayToStructureLittleEndian <Rgb>(buffer);
                    }

                    remaining -= bitmapFileHeader.Fix;
                    // rgb[1];
                    remaining -= 1;

                    // TODO (Optimize): Calculate real data length considering that every line is word-aligned (2-byte)
                    long dataLength = 0;
                    for (int y = 0; y < bitmapFileHeader.Y; y++)
                    {
                        int x = 0;
                        while (x < bitmapFileHeader.X)
                        {
                            for (int k = 8 - bitmapFileHeader.BitsPerPlane; k >= 0;
                                 k -= (int)bitmapFileHeader.BitsPerPlane)
                            {
                                x++;
                            }

                            dataLength++;
                        }

                        dataLength += dataLength % 2;
                    }

                    buffer = new byte[dataLength];
                    Array.Copy(data, bitmapFileHeader.Offset, buffer, 0, buffer.Length);

                    DecodedBitmap bitmap = DecodeBitmap(bitmapFileHeader, palette, buffer);

                    // Mask palette
                    int[] argbPalette = new int[palette.Length];
                    for (int c = 0; c < palette.Length; c++)
                    {
                        argbPalette[c] = (palette[c].Red << 16) + (palette[c].Green << 8) + palette[c].Blue;
                    }

                    // First image, then mask
                    if (bitmapFileHeader.Type == TYPE_ICON || bitmapFileHeader.Type == TYPE_POINTER)
                    {
                        int[] icon = new int[bitmap.Width * bitmap.Height / 2];
                        int[] mask = new int[bitmap.Width * bitmap.Height / 2];
                        Array.Copy(bitmap.Pixels, 0, icon, 0, icon.Length);
                        Array.Copy(bitmap.Pixels, icon.Length, mask, 0, mask.Length);

                        bitmap.Pixels  = new int[bitmap.Width * bitmap.Height / 2];
                        bitmap.Height /= 2;
                        for (int px = 0; px < bitmap.Pixels.Length; px++)
                        {
                            bitmap.Pixels[px] = icon[px] + (mask[px] == argbPalette[0] ? VISIBLE : 0);
                        }
                    }
                    // We got the mask, now we need to read the color
                    else if (bitmapFileHeader.Type == TYPE_COLOR_ICON || bitmapFileHeader.Type == TYPE_COLOR_POINTER)
                    {
                        DecodedBitmap mask = bitmap;

                        buffer = new byte[Marshal.SizeOf(typeof(BitmapInfoHeader))];
                        Array.Copy(data, pos, buffer, 0, buffer.Length);
                        bitmapFileHeader = BigEndianMarshal.ByteArrayToStructureLittleEndian <BitmapInfoHeader>(buffer);

                        // Stop at unknown header
                        if (bitmapFileHeader.Size != Marshal.SizeOf(typeof(BitmapInfoHeader)))
                        {
                            break;
                        }

                        // Multiplanes not supported
                        if (bitmapFileHeader.Planes != 1)
                        {
                            break;
                        }

                        // TODO: Non paletted?
                        pos    += bitmapFileHeader.Size;
                        palette = new Rgb[1 << bitmapFileHeader.BitsPerPlane];
                        buffer  = new byte[Marshal.SizeOf(typeof(Rgb))];
                        for (int i = 0; i < palette.Length; i++)
                        {
                            Array.Copy(data, pos, buffer, 0, buffer.Length);
                            pos       += buffer.Length;
                            palette[i] = BigEndianMarshal.ByteArrayToStructureLittleEndian <Rgb>(buffer);
                        }

                        remaining -= bitmapFileHeader.Fix;
                        // rgb[1];
                        remaining -= 1;

                        // TODO (Optimize): Calculate real data length considering that every line is word-aligned (2-byte)
                        dataLength = 0;
                        for (int y = 0; y < bitmapFileHeader.Y; y++)
                        {
                            int x = 0;
                            while (x < bitmapFileHeader.X)
                            {
                                for (int k = 8 - bitmapFileHeader.BitsPerPlane; k >= 0;
                                     k -= (int)bitmapFileHeader.BitsPerPlane)
                                {
                                    x++;
                                }

                                dataLength++;
                            }

                            dataLength += dataLength % 2;
                        }

                        buffer = new byte[dataLength];
                        Array.Copy(data, bitmapFileHeader.Offset, buffer, 0, buffer.Length);

                        bitmap = DecodeBitmap(bitmapFileHeader, palette, buffer);

                        for (int px = 0; px < bitmap.Pixels.Length; px++)
                        {
                            bitmap.Pixels[px] = bitmap.Pixels[px] +
                                                (mask.Pixels[px + bitmapFileHeader.X * bitmapFileHeader.Y] ==
                                                 argbPalette[0]
                                                     ? VISIBLE
                                                     : 0);
                        }
                    }
                    // Not an icon, all pixels are visible
                    else
                    {
                        for (int px = 0; px < bitmap.Pixels.Length; px++)
                        {
                            bitmap.Pixels[px] = bitmap.Pixels[px] + VISIBLE;
                        }
                    }

                    // Need to reverse first all pixels then by line
                    int[] pixels = bitmap.Pixels.Reverse().ToArray();
                    for (int y = 0; y < bitmap.Height; y++)
                    {
                        for (int x = 0; x < bitmap.Width; x++)
                        {
                            bitmap.Pixels[y * bitmap.Width + (bitmap.Width - x - 1)] = pixels[y * bitmap.Width + x];
                        }
                    }

                    bitmaps.Add(bitmap);
                }

                pos = bitmapArrayHeader.Next;
            }while(bitmapArrayHeader.Next != 0);

            return(bitmaps.ToArray());
        }
Beispiel #4
0
        /// <summary>
        ///     This will decode an icon
        /// </summary>
        /// <param name="data">Data</param>
        /// <returns>A <see cref="DecodedBitmap" /> with the icon, null if the icon could not be decoded</returns>
        public static DecodedBitmap DecodeIcon(byte[] data)
        {
            long pos = 0;

            byte[] buffer = new byte[Marshal.SizeOf(typeof(BitmapInfoHeader))];
            Array.Copy(data, pos, buffer, 0, buffer.Length);
            BitmapInfoHeader bitmapFileHeader =
                BigEndianMarshal.ByteArrayToStructureLittleEndian <BitmapInfoHeader>(buffer);

            // Stop at unknown header
            if (bitmapFileHeader.HeaderSize != 40)
            {
                return(null);
            }

            // Multiplanes not supported
            if (bitmapFileHeader.Planes != 1)
            {
                return(null);
            }

            // TODO: Non paletted?
            pos += bitmapFileHeader.HeaderSize;
            Rgb[] palette = new Rgb[1 << bitmapFileHeader.BitsPerPlane];
            buffer = new byte[Marshal.SizeOf(typeof(Rgb))];
            for (int i = 0; i < palette.Length; i++)
            {
                Array.Copy(data, pos, buffer, 0, buffer.Length);
                pos       += buffer.Length;
                palette[i] = BigEndianMarshal.ByteArrayToStructureLittleEndian <Rgb>(buffer);
            }

            // First let's do the icon itself
            bitmapFileHeader.Height /= 2;
            long dataLength = 0;

            for (int y = 0; y < bitmapFileHeader.Height; y++)
            {
                int x = 0;
                while (x < bitmapFileHeader.Width)
                {
                    for (int k = 8 - bitmapFileHeader.BitsPerPlane; k >= 0; k -= (int)bitmapFileHeader.BitsPerPlane)
                    {
                        x++;
                    }

                    dataLength++;
                }

                dataLength += dataLength % 2;
            }

            buffer = new byte[dataLength];
            Array.Copy(data, pos, buffer, 0, buffer.Length);

            DecodedBitmap icon = DecodeBitmap(bitmapFileHeader, palette, buffer);

            // Then the mask
            pos += dataLength;
            bitmapFileHeader.BitsPerPlane = 1;
            dataLength = 0;
            for (int y = 0; y < bitmapFileHeader.Height; y++)
            {
                int x = 0;
                while (x < bitmapFileHeader.Width)
                {
                    for (int k = 8 - bitmapFileHeader.BitsPerPlane; k >= 0; k -= (int)bitmapFileHeader.BitsPerPlane)
                    {
                        x++;
                    }

                    dataLength++;
                }

                dataLength += dataLength % 2;
            }

            buffer = new byte[dataLength];
            Array.Copy(data, pos, buffer, 0, buffer.Length);

            DecodedBitmap mask = DecodeBitmap(bitmapFileHeader, palette, buffer);

            // Mask palette
            int[] argbPalette = new int[palette.Length];
            for (int c = 0; c < palette.Length; c++)
            {
                argbPalette[c] = (palette[c].Red << 16) + (palette[c].Green << 8) + palette[c].Blue;
            }

            DecodedBitmap bitmap = new DecodedBitmap
            {
                BitsPerPixel = icon.BitsPerPixel,
                Height       = icon.Height,
                Width        = icon.Width,
                Pixels       = new int[icon.Pixels.Length]
            };

            for (int px = 0; px < bitmap.Pixels.Length; px++)
            {
                bitmap.Pixels[px] = icon.Pixels[px] + (mask.Pixels[px] == argbPalette[0] ? VISIBLE : 0);
            }

            // Need to reverse first all pixels then by line
            int[] pixels = bitmap.Pixels.Reverse().ToArray();
            for (int y = 0; y < bitmap.Height; y++)
            {
                for (int x = 0; x < bitmap.Width; x++)
                {
                    bitmap.Pixels[y * bitmap.Width + (bitmap.Width - x - 1)] = pixels[y * bitmap.Width + x];
                }
            }

            return(bitmap);
        }