Exemple #1
0
 /// <summary>
 /// Loads DDS that has no header - primarily for ME3Explorer. DDS data is standard, just without a header.
 /// ASSUMES VALID DDS DATA. Also, single mipmap only.
 /// </summary>
 /// <param name="rawDDSData">Standard DDS data but lacking header.</param>
 /// <param name="surfaceFormat">Surface format of DDS.</param>
 /// <param name="width">Width of image.</param>
 /// <param name="height">Height of image.</param>
 public ImageEngineImage(byte[] rawDDSData, ImageEngineFormat surfaceFormat, int width, int height)
 {
     Format = new Format(surfaceFormat);
     DDSGeneral.DDS_HEADER tempHeader = null;
     MipMaps = ImageEngine.LoadImage(rawDDSData, surfaceFormat, width, height, out tempHeader);
     header  = tempHeader;
 }
Exemple #2
0
        private void LoadFromStream(Stream stream, string extension = null, int desiredMaxDimension = 0, bool enforceResize = true)
        {
            Format format = new Format();

            // KFreon: Load image and save useful information including BGRA pixel data - may be processed from original into this form.
            DDSGeneral.DDS_HEADER tempheader = null;
            MipMaps = ImageEngine.LoadImage(stream, out format, extension, desiredMaxDimension, enforceResize, out tempheader, false);
            header  = tempheader;
            Format  = format;
        }
Exemple #3
0
        private void LoadFromFile(string imagePath, int desiredMaxDimension = 0, bool enforceResize = true)
        {
            Format format = new Format();

            FilePath = imagePath;

            // KFreon: Load image and save useful information including BGRA pixel data - may be processed from original into this form.
            DDSGeneral.DDS_HEADER tempheader = null;
            MipMaps = ImageEngine.LoadImage(imagePath, out format, desiredMaxDimension, enforceResize, out tempheader, false);

            // KFreon: Can't pass properties as out :(
            header = tempheader;
            Format = format;
        }
Exemple #4
0
        /// <summary>
        /// Generates a thumbnail image as quickly and efficiently as possible.
        /// </summary>
        /// <param name="stream">Full image stream.</param>
        /// <param name="maxHeight">Max height to decode at. 0 means ignored, and aspect respected.</param>
        /// <param name="maxWidth">Max width to decode at. 0 means ignored, and aspect respected.</param>
        /// <param name="mergeAlpha">DXT1 only. True = Flatten alpha into RGB.</param>
        /// <param name="requireTransparency">True = uses PNG compression instead of JPG.</param>
        public static MemoryStream GenerateThumbnailToStream(Stream stream, int maxWidth, int maxHeight, bool mergeAlpha = false, bool requireTransparency = false)
        {
            Format format = new Format();

            DDSGeneral.DDS_HEADER header = null;
            var mipmaps = LoadImage(stream, out format, null, maxWidth, maxHeight, true, out header, mergeAlpha);

            MemoryStream ms     = new MemoryStream();
            bool         result = Save(mipmaps, requireTransparency ? ImageEngineFormat.PNG : ImageEngineFormat.JPG, ms, MipHandling.KeepTopOnly, mergeAlpha, maxHeight > maxWidth ? maxHeight : maxWidth);

            if (!result)
            {
                ms = null;
            }

            return(ms);
        }
        private MemoryStream buildDdsImage(int mipMapIndex, out ImageEngineFormat imageFormat)
        {
            DomainPropertyByteValue formatProp = PropertyHeader.GetProperty("Format").FirstOrDefault()?.Value as DomainPropertyByteValue;

            imageFormat = ImageEngineFormat.Unknown;

            if (formatProp == null)
            {
                return(null);
            }

            string format = formatProp.PropertyString.Replace("PF_", null);

            switch (format)
            {
            case "DXT1":
            {
                imageFormat = ImageEngineFormat.DDS_DXT1;

                break;
            }

            case "DXT5":
            {
                imageFormat = ImageEngineFormat.DDS_DXT5;

                break;
            }

            case "G8":
            {
                imageFormat = ImageEngineFormat.DDS_G8_L8;

                break;
            }

            case "A8R8G8B8":
            {
                imageFormat = ImageEngineFormat.DDS_ARGB;

                break;
            }

            default:
            {
                return(null);
            }
            }

            DomainMipMap mipMap = MipMaps[mipMapIndex];

            DDSGeneral.DDS_HEADER header = DDSGeneral.Build_DDS_Header(0, mipMap.Height, mipMap.Width, imageFormat);

            MemoryStream stream = new MemoryStream();

            BinaryWriter writer = new BinaryWriter(stream);

            DDSGeneral.Write_DDS_Header(header, writer);

            stream.Write(mipMap.ImageData, 0, mipMap.ImageData.Length);

            stream.Flush();

            stream.Position = 0;

            return(stream);
        }
Exemple #6
0
 /// <summary>
 /// Loads image from file.
 /// </summary>
 /// <param name="imagePath">Path to image file.</param>
 /// <param name="Format">Detected format.</param>
 /// <param name="enforceResize">True = image resized to desiredMaxDimension if no suitable mipmap.</param>
 /// <param name="header">DDS header of image.</param>
 /// <param name="desiredMaxDimension">Largest dimension to load as.</param>
 /// <param name="mergeAlpha">True = Flattens alpha down, directly affecting RGB.</param>
 /// <returns>List of Mipmaps.</returns>
 internal static List <MipMap> LoadImage(string imagePath, out Format Format, int desiredMaxDimension, bool enforceResize, out DDSGeneral.DDS_HEADER header, bool mergeAlpha)
 {
     using (FileStream fs = new FileStream(imagePath, FileMode.Open, FileAccess.Read, FileShare.Read))
         return(LoadImage(fs, out Format, Path.GetExtension(imagePath), desiredMaxDimension, enforceResize, out header, mergeAlpha));
 }
Exemple #7
0
        internal static List <MipMap> LoadImage(byte[] rawDDSData, ImageEngineFormat surfaceFormat, int width, int height, out DDSGeneral.DDS_HEADER header)
        {
            header = DDSGeneral.Build_DDS_Header(1, height, width, surfaceFormat);
            List <MipMap> MipMaps = null;

            // Create new fully formatted DDS i.e. one with a header.
            MemoryStream stream = new MemoryStream();
            BinaryWriter bw     = new BinaryWriter(stream);

            DDSGeneral.Write_DDS_Header(header, bw);
            bw.Write(rawDDSData);

            switch (surfaceFormat)
            {
            case ImageEngineFormat.DDS_DXT1:
            case ImageEngineFormat.DDS_DXT2:
            case ImageEngineFormat.DDS_DXT3:
            case ImageEngineFormat.DDS_DXT4:
            case ImageEngineFormat.DDS_DXT5:
                if (WindowsWICCodecsAvailable)
                {
                    MipMaps = WIC_Codecs.LoadWithCodecs(stream, 0, 0, true);
                }
                else
                {
                    MipMaps = DDSGeneral.LoadDDS(stream, header, new Format(surfaceFormat), 0);
                }
                break;

            case ImageEngineFormat.DDS_ARGB:
            case ImageEngineFormat.DDS_A8L8:
            case ImageEngineFormat.DDS_RGB:
            case ImageEngineFormat.DDS_ATI1:
            case ImageEngineFormat.DDS_ATI2_3Dc:
            case ImageEngineFormat.DDS_G8_L8:
            case ImageEngineFormat.DDS_V8U8:
                MipMaps = DDSGeneral.LoadDDS(stream, header, new Format(surfaceFormat), 0);
                break;

            default:
                throw new InvalidDataException("Image format is unknown.");
            }
            bw.Dispose(); // Also disposes MemoryStream
            return(MipMaps);
        }
Exemple #8
0
        /// <summary>
        /// Loads image from stream.
        /// </summary>
        /// <param name="stream">Full image stream.</param>
        /// <param name="Format">Detected Format.</param>
        /// <param name="extension">File Extension. Used to determine format more easily.</param>
        /// <param name="maxWidth">Maximum width to allow when loading. Resized if enforceResize = true.</param>
        /// <param name="maxHeight">Maximum height to allow when loading. Resized if enforceResize = true.</param>
        /// <param name="enforceResize">True = Resizes image to match either maxWidth or maxHeight.</param>
        /// <param name="header">DDS header of image.</param>
        /// <param name="mergeAlpha">ONLY valid when enforceResize is true. True = Flattens alpha down, directly affecting RGB.</param>
        /// <returns>List of Mipmaps.</returns>
        internal static List <MipMap> LoadImage(Stream stream, out Format Format, string extension, int maxWidth, int maxHeight, bool enforceResize, out DDSGeneral.DDS_HEADER header, bool mergeAlpha)
        {
            // KFreon: See if image is built-in codec agnostic.
            header = null;
            Format = ImageFormats.ParseFormat(stream, extension, ref header);
            List <MipMap> MipMaps = null;

            switch (Format.SurfaceFormat)
            {
            case ImageEngineFormat.BMP:
            case ImageEngineFormat.JPG:
            case ImageEngineFormat.PNG:
                MipMaps = WIC_Codecs.LoadWithCodecs(stream, maxWidth, maxHeight, false);
                break;

            case ImageEngineFormat.DDS_DXT1:
            case ImageEngineFormat.DDS_DXT2:
            case ImageEngineFormat.DDS_DXT3:
            case ImageEngineFormat.DDS_DXT4:
            case ImageEngineFormat.DDS_DXT5:
                if (WindowsWICCodecsAvailable)
                {
                    MipMaps = WIC_Codecs.LoadWithCodecs(stream, maxWidth, maxHeight, true);
                }
                else
                {
                    MipMaps = DDSGeneral.LoadDDS(stream, header, Format, maxHeight > maxWidth ? maxHeight : maxWidth);
                }
                break;

            case ImageEngineFormat.DDS_ARGB:
            case ImageEngineFormat.DDS_A8L8:
            case ImageEngineFormat.DDS_RGB:
            case ImageEngineFormat.DDS_ATI1:
            case ImageEngineFormat.DDS_ATI2_3Dc:
            case ImageEngineFormat.DDS_G8_L8:
            case ImageEngineFormat.DDS_V8U8:
                MipMaps = DDSGeneral.LoadDDS(stream, header, Format, maxHeight > maxWidth ? maxHeight : maxWidth);
                break;

            case ImageEngineFormat.TGA:
                var             img    = new TargaImage(stream);
                byte[]          pixels = UsefulThings.WinForms.Imaging.GetPixelDataFromBitmap(img.Image);
                WriteableBitmap wbmp   = UsefulThings.WPF.Images.CreateWriteableBitmap(pixels, img.Image.Width, img.Image.Height);
                var             mip1   = new MipMap(wbmp);
                MipMaps = new List <MipMap>()
                {
                    mip1
                };
                img.Dispose();
                break;

            default:
                throw new InvalidDataException("Image format is unknown.");
            }

            if (MipMaps == null || MipMaps.Count == 0)
            {
                throw new InvalidDataException("No mipmaps loaded.");
            }


            // KFreon: No resizing requested
            if (maxHeight == 0 && maxWidth == 0)
            {
                return(MipMaps);
            }

            // KFreon: Test if we need to resize
            var top = MipMaps.First();

            if (top.Width == maxWidth || top.Height == maxHeight)
            {
                return(MipMaps);
            }

            int max = maxWidth > maxHeight ? maxWidth : maxHeight;

            // KFreon: Attempt to resize
            var sizedMips = MipMaps.Where(m => m.Width > m.Height ? m.Width <= max : m.Height <= max);

            if (sizedMips != null && sizedMips.Any())  // KFreon: If there's already a mip, return that.
            {
                MipMaps = sizedMips.ToList();
            }
            else if (enforceResize)
            {
                // Get top mip and clear others.
                var mip = MipMaps[0];
                MipMaps.Clear();
                MipMap output = null;

                int divisor = mip.Width > mip.Height ? mip.Width / max : mip.Height / max;

                output = Resize(mip, 1f / divisor, mergeAlpha);

                MipMaps.Add(output);
            }
            return(MipMaps);
        }
Exemple #9
0
 /// <summary>
 /// Loads image from stream.
 /// </summary>
 /// <param name="stream">Full image stream.</param>
 /// <param name="Format">Detected format.</param>
 /// <param name="extension">File extension. Used to determine format more easily.</param>
 /// <param name="mergeAlpha">ONLY valid when enforceResize is true. True = Flattens alpha down, directly affecting RGB.</param>
 /// <param name="enforceResize">True = image resized to desiredMaxDimension if no suitable mipmap.</param>
 /// <param name="header">DDS header of image.</param>
 /// <param name="desiredMaxDimension">Largest dimension to load as. ASSUMES SQUARE.</param>
 /// <returns>List of Mipmaps.</returns>
 internal static List <MipMap> LoadImage(Stream stream, out Format Format, string extension, int desiredMaxDimension, bool enforceResize, out DDSGeneral.DDS_HEADER header, bool mergeAlpha)
 {
     return(LoadImage(stream, out Format, extension, desiredMaxDimension, desiredMaxDimension, enforceResize, out header, mergeAlpha));
 }