Ejemplo n.º 1
0
        /// <summary>
        /// Function to read multiple frames from a decoder that supports multiple frames.
        /// </summary>
        /// <param name="wic">WIC interface.</param>
        /// <param name="data">Image data to populate.</param>
        /// <param name="decoder">Decoder for the image.</param>
        private void ReadFrames(GorgonWICImage wic, GorgonImageData data, BitmapDecoder decoder)
        {
            Guid bestPixelFormat = wic.GetGUID(data.Settings.Format);

            // Find the best fit pixel format.
            if (bestPixelFormat == Guid.Empty)
            {
                throw new IOException(string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, data.Settings.Format));
            }

            // Use the image array as the frames.
            int arrayCount = _actualArrayCount.Min(data.Settings.ArrayCount);

            for (int array = 0; array < arrayCount; array++)
            {
                var buffer = data.Buffers[0, array];

                // Get the frame data.
                using (var frame = decoder.GetFrame(array))
                {
                    IntPtr bufferPointer = buffer.Data.BasePointer;
                    Guid   frameFormat   = frame.PixelFormat;
                    int    frameWidth    = frame.Size.Width;
                    int    frameHeight   = frame.Size.Height;
                    var    frameOffset   = GetFrameOffset(frame);

                    // Calculate the pointer offset if we have an offset from the frame.  Only offset if we're clipping the image though.
                    if (((frameOffset.Y != 0) || (frameOffset.X != 0)) && (Clip))
                    {
                        bufferPointer = buffer.Data.BasePointer + (frameOffset.Y * buffer.PitchInformation.RowPitch) + (frameOffset.X * (buffer.PitchInformation.RowPitch / buffer.Width));
                    }

                    // Confirm that we actually need to perform clipping.
                    bool needsSizeAdjust = (frameWidth + frameOffset.X > data.Settings.Width) || (frameHeight + frameOffset.Y > data.Settings.Height);

                    // If the formats match, then we don't need to do conversion.
                    if (bestPixelFormat == frameFormat)
                    {
                        // If the width and height are the same then we can just do a straight copy into the buffer.
                        if (((frameWidth == data.Settings.Width) && (frameHeight == data.Settings.Height)) || ((!needsSizeAdjust) && (Clip)))
                        {
                            frame.CopyPixels(buffer.PitchInformation.RowPitch, bufferPointer, buffer.PitchInformation.SlicePitch);

                            continue;
                        }

                        // We need to scale the image up/down to the size of our image data.
                        if (!Clip)
                        {
                            using (var scaler = new BitmapScaler(wic.Factory))
                            {
                                scaler.Initialize(frame, data.Settings.Width, data.Settings.Height, (BitmapInterpolationMode)Filter);
                                scaler.CopyPixels(buffer.PitchInformation.RowPitch, bufferPointer, buffer.PitchInformation.SlicePitch);
                            }
                            continue;
                        }

                        using (var clipper = new BitmapClipper(wic.Factory))
                        {
                            clipper.Initialize(frame, new Rectangle(0, 0, data.Settings.Width, data.Settings.Height));
                            clipper.CopyPixels(buffer.PitchInformation.RowPitch, bufferPointer, buffer.PitchInformation.SlicePitch);
                        }

                        continue;
                    }

                    // Poop.  We need to convert this image.
                    using (var converter = new FormatConverter(wic.Factory))
                    {
                        converter.Initialize(frame,
                                             bestPixelFormat,
                                             (BitmapDitherType)Dithering,
                                             null,
                                             0.0,
                                             BitmapPaletteType.Custom);

                        if (((frameWidth == data.Settings.Width) && (frameHeight == data.Settings.Height)) ||
                            ((!needsSizeAdjust) && (Clip)))
                        {
                            converter.CopyPixels(buffer.PitchInformation.RowPitch,
                                                 bufferPointer,
                                                 buffer.PitchInformation.SlicePitch);
                            continue;
                        }

                        // And we need to scale the image.
                        if (!Clip)
                        {
                            using (var scaler = new BitmapScaler(wic.Factory))
                            {
                                scaler.Initialize(converter,
                                                  data.Settings.Width,
                                                  data.Settings.Height,
                                                  (BitmapInterpolationMode)Filter);
                                scaler.CopyPixels(buffer.PitchInformation.RowPitch,
                                                  bufferPointer,
                                                  buffer.PitchInformation.SlicePitch);
                            }

                            continue;
                        }

                        using (var clipper = new BitmapClipper(wic.Factory))
                        {
                            clipper.Initialize(frame,
                                               new Rectangle(0, 0, data.Settings.Width, data.Settings.Height));
                            clipper.CopyPixels(buffer.PitchInformation.RowPitch,
                                               bufferPointer,
                                               buffer.PitchInformation.SlicePitch);
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
        private static void LoadTexture(Stream input, out Texture output)
        {
            if (input == null)
            {
                output = null;
                return;
            }

            var magic = new byte[4];

            input.Read(magic, 0, 4);
            input.Position = 0;

            var a = (char)magic[0];
            var b = (char)magic[1];
            var c = (char)magic[2];
            var d = (char)magic[3];

            if (VisualC.CompareMemory(magic, DDSImage.MagicBytes, 4) == 0)
            {
                var test = new DDSImage(input);

                output = new Texture(test.Texture2D)
                {
                    Name = "Cubemap (DDS)"
                };
                return;
            }

            var faces = new DataRectangle[6];

            using (var decoder = new BitmapDecoder(Renderer.ImagingFactory, input, DecodeOptions.CacheOnDemand))
            {
                var frame     = decoder.GetFrame(0);
                var converter = new FormatConverter(Renderer.ImagingFactory);

                converter.Initialize(
                    frame,
                    PixelFormat.Format32bppPRGBA,
                    BitmapDitherType.None, null,
                    0.0, BitmapPaletteType.Custom);

                var width  = frame.Size.Width;
                var height = frame.Size.Height;
                var ratio  = width / (float)height;

                if (Math.Abs(ratio - 2) < 0.001)                 // panorama
                {
                    throw new NotImplementedException();
                }
                if (Math.Abs(ratio - 1.333f) < 0.001)                 // cubic
                {
                    var tileDim = (int)(width / 4f);
                    var stride  = tileDim * 4;

                    Action <int, int, int> loadFace = delegate(int index, int coordX, int coordY)
                    {
                        var faceStream = new DataStream(tileDim * stride, false, true);

                        using (var crop = new BitmapClipper(Renderer.ImagingFactory))
                        {
                            crop.Initialize(converter, new RawBox(coordX, coordY, tileDim, tileDim));
                            crop.CopyPixels(stride, faceStream);
                        }

                        faces[index] = new DataRectangle(faceStream.DataPointer, stride);
                    };

                    loadFace(0, tileDim * 2, tileDim);
                    loadFace(1, 0, tileDim);
                    loadFace(2, tileDim, 0);
                    loadFace(3, tileDim, tileDim * 2);
                    loadFace(4, tileDim, tileDim);
                    loadFace(5, tileDim * 3, tileDim);

                    var texture2D = new Texture2D(Renderer.Device, new Texture2DDescription
                    {
                        Width             = tileDim,
                        Height            = tileDim,
                        ArraySize         = 6,
                        BindFlags         = BindFlags.ShaderResource,
                        Usage             = ResourceUsage.Immutable,
                        CpuAccessFlags    = CpuAccessFlags.None,
                        Format            = Format.R8G8B8A8_UNorm,
                        MipLevels         = 1,
                        OptionFlags       = ResourceOptionFlags.TextureCube,
                        SampleDescription = new SampleDescription(1, 0)
                    }, faces);

                    converter.Dispose();

                    output      = new Texture(texture2D);
                    output.Name = output.NativeTexture.Tag.ToString();
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
        }