Ejemplo n.º 1
0
        /// <summary>
        /// Function to decode an uncompressed run of pixel data.
        /// </summary>
        /// <param name="reader">The reader used to read the data in the stream.</param>
        /// <param name="dest">The destination buffer pointer.</param>
        /// <param name="x">The current horizontal position in the scanline.</param>
        /// <param name="runLength">The size of the run, in pixels.</param>
        /// <param name="width">The total width of the run.</param>
        /// <param name="expand"><b>true</b> to expand a 24bpp scanline to 32bpp, or <b>false</b> if no expansion is needed.</param>
        /// <param name="flipHorizontal"><b>true</b> to decode the pixels from right to left, or <b>false</b> to decode from left to right.</param>
        /// <param name="format">The pixel format.</param>
        /// <returns><b>true</b> if the run contains entirely transparent pixels, or <b>false</b> if not.</returns>
        private unsafe bool DecodeRleEncodedRun(GorgonBinaryReader reader, ref byte *dest, ref int x, int runLength, int width, bool expand, bool flipHorizontal, BufferFormat format)
        {
            bool result = true;

            switch (format)
            {
            case BufferFormat.R8_UNorm:
                for (; runLength > 0; --runLength, ++x)
                {
                    if (x >= width)
                    {
                        throw new IOException(string.Format(Resources.GORIMG_ERR_FILE_FORMAT_NOT_CORRECT, Codec));
                    }

                    if (!flipHorizontal)
                    {
                        *(dest++) = reader.ReadByte();
                    }
                    else
                    {
                        *(dest--) = reader.ReadByte();
                    }
                }
                break;

            case BufferFormat.B5G5R5A1_UNorm:
            {
                ushort *destPtr = (ushort *)dest;
                ushort  pixel   = reader.ReadUInt16();

                if ((pixel & 0x8000) != 0)
                {
                    result = false;
                }

                for (; runLength > 0; runLength--, ++x)
                {
                    if (x >= width)
                    {
                        throw new IOException(string.Format(Resources.GORIMG_ERR_FILE_FORMAT_NOT_CORRECT, Codec));
                    }

                    if (!flipHorizontal)
                    {
                        *(destPtr++) = pixel;
                    }
                    else
                    {
                        *(destPtr--) = pixel;
                    }
                }

                dest = (byte *)destPtr;
            }
                return(result);

            case BufferFormat.R8G8B8A8_UNorm:
            {
                uint pixel;

                // Do expansion.
                if (expand)
                {
                    pixel  = (uint)((reader.ReadByte() << 16) | (reader.ReadByte() << 8) | reader.ReadByte() | 0xFF000000);
                    result = false;
                }
                else
                {
                    pixel = reader.ReadUInt32();

                    if ((pixel & 0xFF000000) != 0)
                    {
                        result = false;
                    }
                }

                uint *destPtr = (uint *)dest;

                for (; runLength > 0; --runLength, ++x)
                {
                    if (x >= width)
                    {
                        throw new IOException(string.Format(Resources.GORIMG_ERR_FILE_FORMAT_NOT_CORRECT, Codec));
                    }

                    if (!flipHorizontal)
                    {
                        *(destPtr++) = pixel;
                    }
                    else
                    {
                        *(destPtr--) = pixel;
                    }
                }

                dest = (byte *)destPtr;
            }
                return(result);
            }

            return(false);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Function to decode an uncompressed run of pixel data.
        /// </summary>
        /// <param name="reader">The reader used to read the data from the stream.</param>
        /// <param name="dest">The destination buffer pointer.</param>
        /// <param name="x">The current horizontal position in the scanline.</param>
        /// <param name="runLength">The size of the run, in pixels.</param>
        /// <param name="width">The total width of the run.</param>
        /// <param name="expand"><b>true</b> to expand a 24bpp scanline to 32bpp, or <b>false</b> if no expansion is needed.</param>
        /// <param name="flipHorizontal"><b>true</b> to decode the pixels from right to left, or <b>false</b> to decode from left to right.</param>
        /// <param name="format">The pixel format.</param>
        /// <returns><b>true</b> if the run contains entirely transparent pixels, or <b>false</b> if not.</returns>
        private unsafe bool DecodeUncompressedRun(GorgonBinaryReader reader, ref byte *dest, ref int x, int runLength, int width, bool expand, bool flipHorizontal, BufferFormat format)
        {
            bool result = true;

            switch (format)
            {
            case BufferFormat.R8_UNorm:
                for (; runLength > 0; --runLength, ++x)
                {
                    if (x >= width)
                    {
                        throw new IOException(string.Format(Resources.GORIMG_ERR_FILE_FORMAT_NOT_CORRECT, Codec));
                    }

                    if (!flipHorizontal)
                    {
                        *(dest++) = reader.ReadByte();
                    }
                    else
                    {
                        *(dest--) = reader.ReadByte();
                    }
                }
                break;

            case BufferFormat.B5G5R5A1_UNorm:
            {
                ushort *destPtr = (ushort *)dest;

                for (; runLength > 0; runLength--, ++x)
                {
                    if (x >= width)
                    {
                        throw new IOException(string.Format(Resources.GORIMG_ERR_FILE_FORMAT_NOT_CORRECT, Codec));
                    }

                    ushort pixel = reader.ReadUInt16();

                    if ((pixel & 0x8000) != 0)
                    {
                        result = false;
                    }

                    if (!flipHorizontal)
                    {
                        *(destPtr++) = pixel;
                    }
                    else
                    {
                        *(destPtr--) = pixel;
                    }
                }

                // Send the updated destination address back to the calling function.
                // This is kind of ugly, but too lazy to make it nice.
                dest = (byte *)destPtr;
            }
                return(result);

            case BufferFormat.R8G8B8A8_UNorm:
            {
                uint *destPtr = (uint *)dest;

                for (; runLength > 0; --runLength, ++x)
                {
                    if (x >= width)
                    {
                        throw new IOException(string.Format(Resources.GORIMG_ERR_FILE_FORMAT_NOT_CORRECT, Codec));
                    }

                    uint pixel;

                    if (expand)
                    {
                        pixel  = (uint)((reader.ReadByte() << 16) | (reader.ReadByte() << 8) | reader.ReadByte() | 0xFF000000);
                        result = false;
                    }
                    else
                    {
                        pixel = reader.ReadUInt32();

                        if ((pixel & 0xFF000000) != 0)
                        {
                            result = false;
                        }
                    }

                    if (!flipHorizontal)
                    {
                        *(destPtr++) = pixel;
                    }
                    else
                    {
                        *(destPtr--) = pixel;
                    }
                }

                // Send the updated destination address back to the calling function.
                // This is kind of ugly, but too lazy to make it nice.
                dest = (byte *)destPtr;
            }
                return(result);
            }

            return(false);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Function to determine if the assembly defined in the assembly path is a .NET managed assembly or not.
        /// </summary>
        /// <param name="assemblyPath">The path to the assembly.</param>
        /// <returns>A tuple containing <b>true</b> if the file is a .NET managed assembly, <b>false</b> if not, and the type of expected platform that the assembly code is supposed to work under.</returns>
        public static (bool isManaged, AssemblyPlatformType platform) IsManagedAssembly(string assemblyPath)
        {
            if (!File.Exists(assemblyPath))
            {
                return(false, AssemblyPlatformType.Unknown);
            }

            uint cor2HeaderPtr = 0;
            AssemblyPlatformType platformType;

            // For this, we'll go into the guts of the file and read the data required instead of loading the assembly data and using exceptions to determine
            // the assembly type.
            //
            // This code is adapted from this stack overflow answer:
            // https://stackoverflow.com/questions/367761/how-to-determine-whether-a-dll-is-a-managed-assembly-or-native-prevent-loading

            using (FileStream stream = File.Open(assemblyPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                using (var reader = new GorgonBinaryReader(stream, false))
                {
                    // File is less than 64 bytes, not a portable executable.
                    if (stream.Length < 64)
                    {
                        return(false, AssemblyPlatformType.Unknown);
                    }

                    stream.Position = 0x3C;
                    uint headerPointer = reader.ReadUInt32();

                    if (headerPointer == 0)
                    {
                        headerPointer = 0x80;
                    }

                    if (headerPointer > stream.Length - 256)
                    {
                        return(false, AssemblyPlatformType.Unknown);
                    }

                    stream.Position = headerPointer;
                    uint signature = reader.ReadUInt32();

                    if (signature != PeHeaderSignature)
                    {
                        return(false, AssemblyPlatformType.Unknown);
                    }

                    stream.Position += 20;

                    ushort exePlatform = reader.ReadUInt16();

                    if ((exePlatform != Pe32Bit) && (exePlatform != Pe64bit))
                    {
                        return(false, AssemblyPlatformType.Unknown);
                    }

                    uint rvaPointer = 0;

                    switch (exePlatform)
                    {
                    case Pe32Bit:
                        platformType = AssemblyPlatformType.x86;
                        rvaPointer   = headerPointer + 232;
                        break;

                    case Pe64bit:
                        platformType = AssemblyPlatformType.x64;
                        rvaPointer   = headerPointer + 248;
                        break;

                    default:
                        return(false, AssemblyPlatformType.Unknown);
                    }

                    stream.Position = rvaPointer;
                    cor2HeaderPtr   = reader.ReadUInt32();
                }

            // AnyCPU assemblies are marked as x86.  We need to read the cor20 header, but I'm lazy and it's a lot of work.
            // So, we'll use the old tried and true method of reading the assembly metadata.  We shouldn't exception here because
            // we've already determined that we're not using a native DLL.  GetAssemblyName doesn't care if our executing platform
            // environment is x64 or x86 and our DLL doesn't match, it just reads the metadata (tested and confirmed).
            if ((cor2HeaderPtr != 0) && (platformType == AssemblyPlatformType.x86))
            {
                var name = AssemblyName.GetAssemblyName(assemblyPath);

                if (name.ProcessorArchitecture == ProcessorArchitecture.MSIL)
                {
                    platformType = AssemblyPlatformType.AnyCpu;
                }
            }

            return(cor2HeaderPtr != 0, platformType);
        }