/// <summary> /// Ensures all Mipmaps are generated in MipMaps. /// </summary> /// <param name="MipMaps">MipMaps to check.</param> /// <returns>Number of mipmaps present in MipMaps.</returns> internal static int BuildMipMaps(List <MipMap> MipMaps) { if (MipMaps?.Count == 0) { return(0); } MipMap currentMip = MipMaps[0]; // KFreon: Check if mips required int estimatedMips = DDSGeneral.EstimateNumMipMaps(currentMip.Width, currentMip.Height); if (MipMaps.Count > 1) { return(estimatedMips); } // KFreon: Half dimensions until one == 1. MipMap[] newmips = new MipMap[estimatedMips]; // TODO: Component size - pixels //var baseBMP = UsefulThings.WPF.Images.CreateWriteableBitmap(currentMip.Pixels, currentMip.Width, currentMip.Height); //baseBMP.Freeze(); Action <int> action = new Action <int>(item => { int index = item; MipMap newmip; var scale = 1d / (2 << (index - 1)); // Shifting is 2^index - Math.Pow seems extraordinarly slow. //newmip = ImageEngine.Resize(baseBMP, scale, scale, currentMip.Width, currentMip.Height, currentMip.LoadedFormatDetails); newmip = ImageEngine.Resize(currentMip, scale, scale); newmips[index - 1] = newmip; }); // Start at 1 to skip top mip if (ImageEngine.EnableThreading) { Parallel.For(1, estimatedMips + 1, new ParallelOptions { MaxDegreeOfParallelism = ImageEngine.NumThreads }, action); } else { for (int item = 1; item < estimatedMips + 1; item++) { action(item); } } MipMaps.AddRange(newmips); return(MipMaps.Count); }