Пример #1
0
    /// <summary>
    /// Resizes the texture. (If original texture has mipmaps, all mipmap levels are automatically
    /// recreated.)
    /// </summary>
    /// <param name="width">The new width.</param>
    /// <param name="height">The new height.</param>
    /// <param name="depth">The new depth. Must be 1 for 2D textures and cube map textures.</param>
    /// <param name="filter">The filter to use for resizing.</param>
    /// <param name="alphaTransparency">
    /// <see langword="true"/> if the image contains uses non-premultiplied alpha; otherwise,
    /// <see langword="false"/> if the image uses premultiplied alpha or has no alpha.
    /// </param>
    /// <param name="wrapMode">
    /// The texture address mode that will be used for sampling the at runtime.
    /// </param>
    /// <returns>The resized texture.</returns>
    public Texture Resize(int width, int height, int depth, ResizeFilter filter, bool alphaTransparency, TextureAddressMode wrapMode)
    {
      var description = Description;
      description.Width = width;
      description.Height = height;
      description.Depth = depth;

      var resizedTexture = new Texture(description);

      // Resize mipmap level 0.
      for (int arrayIndex = 0; arrayIndex < description.ArraySize; arrayIndex++)
        TextureHelper.Resize(this, 0, arrayIndex, resizedTexture, 0, arrayIndex, filter, alphaTransparency, wrapMode);

      // Regenerate mipmap levels, if necessary.
      if (description.MipLevels > 1)
        resizedTexture.GenerateMipmaps(filter, alphaTransparency, wrapMode);

      return resizedTexture;
    }
Пример #2
0
        private static void EncodeMetadata(BitmapFrameEncode frame, Guid containerFormat, DataFormat format)
        {
            var metawriter = frame.MetadataQueryWriter;

            if (metawriter != null)
            {
                bool sRgb = TextureHelper.IsSRgb(format);

                if (containerFormat == ContainerFormatGuids.Png)
                {
                    metawriter.SetMetadataByName("/tEXt/{str=Software}", "DirectXTex");
                    if (sRgb)
                    {
                        metawriter.SetMetadataByName("/sRGB/RenderingIntent", (byte)0);
                    }
                }
                else if (containerFormat == ContainerFormatGuids.Jpeg)
                {
                    metawriter.SetMetadataByName("/app1/ifd/{ushort=305}", "DirectXTex");
                    if (sRgb)
                    {
                        metawriter.SetMetadataByName("/app1/ifd/exif/{ushort=40961}", (ushort)1);
                    }
                }
                else if (containerFormat == ContainerFormatGuids.Tiff)
                {
                    metawriter.SetMetadataByName("/ifd/{ushort=305}", "DirectXTex");
                    if (sRgb)
                    {
                        metawriter.SetMetadataByName("/ifd/exif/{ushort=40961}", (ushort)1);
                    }
                }
                else
                {
                    metawriter.SetMetadataByName("System.ApplicationName", "DirectXTex");
                    if (sRgb)
                    {
                        metawriter.SetMetadataByName("System.Image.ColorSpace", (ushort)1);
                    }
                }
            }
        }
Пример #3
0
    /// <summary>
    /// Determines whether conversion to the specified texture format is supported.
    /// </summary>
    /// <param name="format">The desired texture format.</param>
    /// <returns>
    /// <see langword="true"/> if the conversion from the current format to <paramref name="format"/>
    /// is supported; otherwise, <see langword="false"/>.
    /// </returns>
    public bool CanConvertTo(DataFormat format)
    {
      var srcFormat = Description.Format;
      var dstFormat = format;

      // srcFormat -> dstFormat
      if (TextureHelper.CanConvert(srcFormat, dstFormat))
        return true;

      // srcFormat -> R32G32B32A32_FLOAT -> dstFormat
      if (TextureHelper.CanConvert(srcFormat, DataFormat.R32G32B32A32_FLOAT)
          && TextureHelper.CanConvert(DataFormat.R32G32B32A32_FLOAT, dstFormat))
        return true;

      // srcFormat -> R8G8B8A8_UNORM -> dstFormat
      if (TextureHelper.CanConvert(srcFormat, DataFormat.R8G8B8A8_UNORM)
          && TextureHelper.CanConvert(DataFormat.R8G8B8A8_UNORM, dstFormat))
        return true;

      return false;
    }
Пример #4
0
        /// <summary>
        /// Gets the pixel at the specified position.
        /// </summary>
        /// <param name="x">The x position.</param>
        /// <param name="y">The y position.</param>
        /// <param name="wrapMode">The wrap mode.</param>
        /// <returns>The pixel color.</returns>
        public Vector4F GetPixel(int x, int y, TextureAddressMode wrapMode)
        {
            switch (wrapMode)
            {
            case TextureAddressMode.Clamp:
                x = TextureHelper.WrapClamp(x, _width);
                y = TextureHelper.WrapClamp(y, _height);
                break;

            case TextureAddressMode.Repeat:
                x = TextureHelper.WrapRepeat(x, _width);
                y = TextureHelper.WrapRepeat(y, _height);
                break;

            case TextureAddressMode.Mirror:
                x = TextureHelper.WrapMirror(x, _width);
                y = TextureHelper.WrapMirror(y, _height);
                break;
            }

            return(GetPixel(y * _width + x));
        }
Пример #5
0
    /// <summary>
    /// (Re-)Generates all mipmap levels.
    /// </summary>
    /// <param name="filter">The filter to use for resizing.</param>
    /// <param name="alphaTransparency">
    /// <see langword="true"/> if the image contains uses non-premultiplied alpha; otherwise,
    /// <see langword="false"/> if the image uses premultiplied alpha or has no alpha.
    /// </param>
    /// <param name="wrapMode">
    /// The texture address mode that will be used for sampling the at runtime.
    /// </param>
    public void GenerateMipmaps(ResizeFilter filter, bool alphaTransparency, TextureAddressMode wrapMode)
    {
      var oldDescription = Description;
      var newDescription = Description;

      // Determine number of mipmap levels.
      if (oldDescription.Dimension == TextureDimension.Texture3D)
        newDescription.MipLevels = TextureHelper.CalculateMipLevels(oldDescription.Width, oldDescription.Height, oldDescription.Depth);
      else
        newDescription.MipLevels = TextureHelper.CalculateMipLevels(oldDescription.Width, oldDescription.Height);

      if (oldDescription.MipLevels != newDescription.MipLevels)
      {
        // Update Description and Images.
        var oldImages = Images;
        Description = newDescription;
#if DEBUG
        ValidateTexture(newDescription);
#endif
        // Recreate image collection. (Mipmap level 0 is copied from existing image collection.)
        Images = CreateImageCollection(newDescription, true);
        for (int arrayIndex = 0; arrayIndex < newDescription.ArraySize; arrayIndex++)
        {
          for (int zIndex = 0; zIndex < newDescription.Depth; zIndex++)
          {
            int oldIndex = oldDescription.GetImageIndex(0, arrayIndex, zIndex);
            int newIndex = newDescription.GetImageIndex(0, arrayIndex, zIndex);
            Images[newIndex] = oldImages[oldIndex];
          }
        }
      }

      // Downsample mipmap levels.
      for (int arrayIndex = 0; arrayIndex < newDescription.ArraySize; arrayIndex++)
        for (int mipIndex = 0; mipIndex < newDescription.MipLevels - 1; mipIndex++)
          TextureHelper.Resize(this, mipIndex, arrayIndex, this, mipIndex + 1, arrayIndex, filter, alphaTransparency, wrapMode);
    }
Пример #6
0
    /// <summary>
    /// Determines the number of image array entries and pixel size.
    /// </summary>
    /// <param name="description">The texture description.</param>
    /// <param name="nImages">The number of entries in the image array.</param>
    /// <param name="pixelSize">The total pixel size.</param>
    private static void DetermineImages(TextureDescription description, out int nImages, out int pixelSize)
    {
      Debug.Assert(description.Width > 0 && description.Height > 0 && description.Depth > 0);
      Debug.Assert(description.ArraySize > 0);
      Debug.Assert(description.MipLevels > 0);

      pixelSize = 0;
      nImages = 0;

      switch (description.Dimension)
      {
        case TextureDimension.Texture1D:
        case TextureDimension.Texture2D:
        case TextureDimension.TextureCube:
          for (int item = 0; item < description.ArraySize; item++)
          {
            int w = description.Width;
            int h = description.Height;

            for (int level = 0; level < description.MipLevels; level++)
            {
              int rowPitch, slicePitch;
              TextureHelper.ComputePitch(description.Format, w, h, out rowPitch, out slicePitch, ComputePitchFlags.None);
              pixelSize += slicePitch;
              nImages++;

              if (h > 1)
                h >>= 1;

              if (w > 1)
                w >>= 1;
            }
          }
          break;

        case TextureDimension.Texture3D:
          {
            int w = description.Width;
            int h = description.Height;
            int d = description.Depth;

            for (int level = 0; level < description.MipLevels; level++)
            {
              int rowPitch, slicePitch;
              TextureHelper.ComputePitch(description.Format, w, h, out rowPitch, out slicePitch, ComputePitchFlags.None);

              for (int slice = 0; slice < d; slice++)
              {
                pixelSize += slicePitch;
                nImages++;
              }

              if (h > 1)
                h >>= 1;

              if (w > 1)
                w >>= 1;

              if (d > 1)
                d >>= 1;
            }
          }
          break;

        default:
          Debug.Fail("Unexpected texture dimension");
          break;
      }
    }
Пример #7
0
        private static TextureDescription DecodeMetadata(ImagingFactory imagingFactory, WicFlags flags, BitmapDecoder decoder, BitmapFrameDecode frame, out Guid pixelFormat)
        {
            var size = frame.Size;

            var description = new TextureDescription
            {
                Dimension = TextureDimension.Texture2D,
                Width     = size.Width,
                Height    = size.Height,
                Depth     = 1,
                MipLevels = 1,
                ArraySize = (flags & WicFlags.AllFrames) != 0 ? decoder.FrameCount : 1,
                Format    = DetermineFormat(imagingFactory, frame.PixelFormat, flags, out pixelFormat)
            };

            if (description.Format == DataFormat.Unknown)
            {
                throw new NotSupportedException("The pixel format is not supported.");
            }

            if ((flags & WicFlags.IgnoreSrgb) == 0)
            {
                // Handle sRGB.
#pragma warning disable 168
                try
                {
                    Guid containerFormat = decoder.ContainerFormat;
                    var  metareader      = frame.MetadataQueryReader;
                    if (metareader != null)
                    {
                        // Check for sRGB color space metadata.
                        bool sRgb = false;

                        if (containerFormat == ContainerFormatGuids.Png)
                        {
                            // Check for sRGB chunk.
                            if (metareader.GetMetadataByName("/sRGB/RenderingIntent") != null)
                            {
                                sRgb = true;
                            }
                        }
                        else if (containerFormat == ContainerFormatGuids.Jpeg)
                        {
                            if (Equals(metareader.GetMetadataByName("/app1/ifd/exif/{ushort=40961}"), 1))
                            {
                                sRgb = true;
                            }
                        }
                        else if (containerFormat == ContainerFormatGuids.Tiff)
                        {
                            if (Equals(metareader.GetMetadataByName("/ifd/exif/{ushort=40961}"), 1))
                            {
                                sRgb = true;
                            }
                        }
                        else
                        {
                            if (Equals(metareader.GetMetadataByName("System.Image.ColorSpace"), 1))
                            {
                                sRgb = true;
                            }
                        }

                        if (sRgb)
                        {
                            description.Format = TextureHelper.MakeSRgb(description.Format);
                        }
                    }
                }
                // ReSharper disable once EmptyGeneralCatchClause
                catch (Exception exception)
                {
                    // Some formats just don't support metadata (BMP, ICO, etc.).
                }
            }
#pragma warning restore 168

            return(description);
        }