private void ImportTexture(ITexture tex, string file, GliFormat imgOriginalFormat, string alias)
 {
     try
     {
         models.Images.AddImage(tex, true, file, imgOriginalFormat, alias);
         tex = null; // images is now owner
     }
     catch (ImagesModel.MipmapMismatch e)
     {
         // silently generate mipmaps and import
         if (models.Images.NumMipmaps > 1 && tex.NumMipmaps == 1)
         {
             var tmp = tex.CloneWithMipmaps(models.Images.NumMipmaps);
             models.Scaling.WriteMipmaps(tmp);
             ImportTexture(tmp, file, imgOriginalFormat, alias);
         }
         else
         {
             // don't just discard the mipmaps
             models.Window.ShowErrorDialog(e);
         }
     }
     catch (Exception e)
     {
         models.Window.ShowErrorDialog(e);
     }
     finally
     {
         tex?.Dispose();
     }
 }
        /// <summary>
        /// creates a thumbnail for one image layer/mipmap
        /// </summary>
        /// <param name="size">maximum width/height of the thumbnail</param>
        /// <param name="texture">source texture</param>
        /// <param name="dstFormat">destination texture format</param>
        /// <param name="layer">source layer</param>
        /// <returns>texture with width, height smaller or equal to size. One layer and one mipmap</returns>
        public TextureArray2D CreateThumbnail(int size, ITexture texture,
                                              SharpDX.DXGI.Format dstFormat, int layer, ScalingModel scaling)
        {
            Debug.Assert(ImageFormat.IsSupported(dstFormat));
            Debug.Assert(ImageFormat.IsSupported(texture.Format));

            // determine dimensions of output texture
            var width  = 0;
            var height = 0;

            if (texture.Size.Width > texture.Size.Height)
            {
                width  = size;
                height = (texture.Size.Height * size) / texture.Size.Width;
            }
            else
            {
                height = size;
                width  = (texture.Size.Width * size) / texture.Size.Height;
            }
            Debug.Assert(width <= size);
            Debug.Assert(height <= size);

            var res = new TextureArray2D(LayerMipmapCount.One, new Size3(width, height), dstFormat, false);

            // compute which mipmap has the closest fit
            var mipmap   = 0;
            var curWidth = texture.Size.Width;

            while (curWidth >= width)
            {
                ++mipmap;
                curWidth /= 2;
            }
            // mipmap just jumped over the optimal size
            mipmap = Math.Max(0, mipmap - 1);

            var      dev    = Device.Get();
            ITexture tmpTex = null;

            if (texture.NumMipmaps < mipmap + 1)
            {
                // generate new texture with mipmaps
                tmpTex = texture.CloneWithMipmaps(mipmap + 1);

                scaling.WriteMipmaps(tmpTex);
                dev.Pixel.SetShaderResource(0, tmpTex.GetSrView(new LayerMipmapSlice(layer, mipmap)));
            }
            else
            {
                dev.Pixel.SetShaderResource(0, texture.GetSrView(new LayerMipmapSlice(layer, mipmap)));
            }

            quad.Bind(false);
            if (texture.Is3D)
            {
                dev.Pixel.Set(convert3D.Pixel);
            }
            else
            {
                dev.Pixel.Set(convert2D.Pixel);
            }

            dev.Pixel.SetSampler(0, sampler);

            dev.OutputMerger.SetRenderTargets(res.GetRtView(LayerMipmapSlice.Mip0));
            dev.SetViewScissors(width, height);
            dev.DrawFullscreenTriangle(1);

            // remove bindings
            dev.Pixel.SetShaderResource(0, null);
            dev.OutputMerger.SetRenderTargets((RenderTargetView)null);
            quad.Unbind();

            tmpTex?.Dispose();

            return(res);
        }