示例#1
0
        /// <summary>
        /// Determines number of image array entries and pixel size.
        /// </summary>
        /// <param name="imageDesc">Description of the image to create.</param>
        /// <param name="pitchFlags">Pitch flags.</param>
        /// <param name="bufferCount">Output number of mipmap.</param>
        /// <param name="pixelSizeInBytes">Output total size to allocate pixel buffers for all images.</param>
        private static List<int> CalculateImageArray( ImageDescription imageDesc, PitchFlags pitchFlags, int rowStride, out int bufferCount, out int pixelSizeInBytes)
        {
            pixelSizeInBytes = 0;
            bufferCount = 0;

            var mipmapToZIndex = new List<int>();

            for (int j = 0; j < imageDesc.ArraySize; j++)
            {
                int w = imageDesc.Width;
                int h = imageDesc.Height;
                int d = imageDesc.Depth;

                for (int i = 0; i < imageDesc.MipLevels; i++)
                {
                    int rowPitch, slicePitch;
                    int widthPacked;
                    int heightPacked;
                    ComputePitch(imageDesc.Format, w, h, out rowPitch, out slicePitch, out widthPacked, out heightPacked, pitchFlags);

                    if (rowStride > 0)
                    {
                        // Check that stride is ok
                        if (rowStride < rowPitch)
                            throw new InvalidOperationException(string.Format("Invalid stride [{0}]. Value can't be lower than actual stride [{1}]", rowStride, rowPitch));

                        if (widthPacked != w || heightPacked != h)
                            throw new InvalidOperationException("Custom strides is not supported with packed PixelFormats");

                        // Override row pitch
                        rowPitch = rowStride;

                        // Recalculate slice pitch
                        slicePitch = rowStride * h;
                    }

                    // Store the number of z-slicec per miplevels
                    if ( j == 0)
                        mipmapToZIndex.Add(bufferCount);

                    // Keep a trace of indices for the 1st array size, for each mip levels
                    pixelSizeInBytes += d * slicePitch;
                    bufferCount += d;

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

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

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

                // For the last mipmaps, store just the number of zbuffers in total
                if (j == 0)
                    mipmapToZIndex.Add(bufferCount);
            }
            return mipmapToZIndex;
        }
示例#2
0
文件: Image.cs 项目: tomba/Toolkit
        /// <summary>
        /// Determines number of image array entries and pixel size.
        /// </summary>
        /// <param name="imageDesc">Description of the image to create.</param>
        /// <param name="pitchFlags">Pitch flags.</param>
        /// <param name="bufferCount">Output number of mipmap.</param>
        /// <param name="pixelSizeInBytes">Output total size to allocate pixel buffers for all images.</param>
        private static List <int> CalculateImageArray(ImageDescription imageDesc, PitchFlags pitchFlags, out int bufferCount, out int pixelSizeInBytes)
        {
            pixelSizeInBytes = 0;
            bufferCount      = 0;

            var mipmapToZIndex = new List <int>();

            for (int j = 0; j < imageDesc.ArraySize; j++)
            {
                int w = imageDesc.Width;
                int h = imageDesc.Height;
                int d = imageDesc.Depth;

                for (int i = 0; i < imageDesc.MipLevels; i++)
                {
                    int rowPitch, slicePitch;
                    int widthPacked;
                    int heightPacked;
                    ComputePitch(imageDesc.Format, w, h, out rowPitch, out slicePitch, out widthPacked, out heightPacked, pitchFlags);

                    // Store the number of z-slices per miplevel
                    if (j == 0)
                    {
                        mipmapToZIndex.Add(bufferCount);
                    }

                    // Keep a trace of indices for the 1st array size, for each mip levels
                    pixelSizeInBytes += d * slicePitch;
                    bufferCount      += d;

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

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

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

                // For the last mipmaps, store just the number of zbuffers in total
                if (j == 0)
                {
                    mipmapToZIndex.Add(bufferCount);
                }
            }
            return(mipmapToZIndex);
        }
示例#3
0
文件: Image.cs 项目: tomba/Toolkit
        internal unsafe void Initialize(ImageDescription description, IntPtr dataPointer, int offset, GCHandle?handle, bool bufferIsDisposable, PitchFlags pitchFlags = PitchFlags.None)
        {
            if (!FormatHelper.IsValid(description.Format) || FormatHelper.IsVideo(description.Format))
            {
                throw new InvalidOperationException("Unsupported DXGI Format");
            }

            this.handle = handle;

            switch (description.Dimension)
            {
            case TextureDimension.Texture1D:
                if (description.Width <= 0 || description.Height != 1 || description.Depth != 1 || description.ArraySize == 0)
                {
                    throw new InvalidOperationException("Invalid Width/Height/Depth/ArraySize for Image 1D");
                }

                // Check that miplevels are fine
                description.MipLevels = Texture.CalculateMipLevels(description.Width, 1, description.MipLevels);
                break;

            case TextureDimension.Texture2D:
            case TextureDimension.TextureCube:
                if (description.Width <= 0 || description.Height <= 0 || description.Depth != 1 || description.ArraySize == 0)
                {
                    throw new InvalidOperationException("Invalid Width/Height/Depth/ArraySize for Image 2D");
                }

                if (description.Dimension == TextureDimension.TextureCube)
                {
                    if ((description.ArraySize % 6) != 0)
                    {
                        throw new InvalidOperationException("TextureCube must have an arraysize = 6");
                    }
                }

                // Check that miplevels are fine
                description.MipLevels = Texture.CalculateMipLevels(description.Width, description.Height, description.MipLevels);
                break;

            case TextureDimension.Texture3D:
                if (description.Width <= 0 || description.Height <= 0 || description.Depth <= 0 || description.ArraySize != 1)
                {
                    throw new InvalidOperationException("Invalid Width/Height/Depth/ArraySize for Image 3D");
                }

                // Check that miplevels are fine
                description.MipLevels = Texture.CalculateMipLevels(description.Width, description.Height, description.Depth, description.MipLevels);
                break;
            }

            // Calculate mipmaps
            int pixelBufferCount;

            this.mipMapToZIndex       = CalculateImageArray(description, pitchFlags, out pixelBufferCount, out totalSizeInBytes);
            this.mipmapDescriptions   = CalculateMipMapDescription(description, pitchFlags);
            zBufferCountPerArraySlice = this.mipMapToZIndex[this.mipMapToZIndex.Count - 1];

            // Allocate all pixel buffers
            pixelBuffers     = new PixelBuffer[pixelBufferCount];
            pixelBufferArray = new PixelBufferArray(this);

            // Setup all pointers
            // only release buffer that is not pinned and is asked to be disposed.
            this.bufferIsDisposable = !handle.HasValue && bufferIsDisposable;
            this.buffer             = dataPointer;

            if (dataPointer == IntPtr.Zero)
            {
                buffer = Utilities.AllocateMemory(totalSizeInBytes);
                offset = 0;
                this.bufferIsDisposable = true;
            }

            SetupImageArray((IntPtr)((byte *)buffer + offset), totalSizeInBytes, description, pitchFlags, pixelBuffers);

            Description = description;

            // PreCompute databoxes
            dataBoxArray = ComputeDataBox();
        }
示例#4
0
文件: Image.cs 项目: tomba/Toolkit
 /// <summary>
 /// Initializes a new instance of the <see cref="Image" /> class.
 /// </summary>
 /// <param name="description">The image description.</param>
 /// <param name="dataPointer">The pointer to the data buffer.</param>
 /// <param name="offset">The offset from the beginning of the data buffer.</param>
 /// <param name="handle">The handle (optional).</param>
 /// <param name="bufferIsDisposable">if set to <c>true</c> [buffer is disposable].</param>
 /// <exception cref="System.InvalidOperationException">If the format is invalid, or width/height/depth/arraysize is invalid with respect to the dimension.</exception>
 internal unsafe Image(ImageDescription description, IntPtr dataPointer, int offset, GCHandle?handle, bool bufferIsDisposable, PitchFlags pitchFlags = PitchFlags.None)
 {
     Initialize(description, dataPointer, offset, handle, bufferIsDisposable, pitchFlags);
 }
示例#5
0
文件: Image.cs 项目: tomba/Toolkit
        /// <summary>
        /// Allocates PixelBuffers
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="pixelSize"></param>
        /// <param name="imageDesc"></param>
        /// <param name="pitchFlags"></param>
        /// <param name="output"></param>
        private static unsafe void SetupImageArray(IntPtr buffer, int pixelSize, ImageDescription imageDesc, PitchFlags pitchFlags, PixelBuffer[] output)
        {
            int index  = 0;
            var pixels = (byte *)buffer;

            for (uint item = 0; item < imageDesc.ArraySize; ++item)
            {
                int w = imageDesc.Width;
                int h = imageDesc.Height;
                int d = imageDesc.Depth;

                for (uint level = 0; level < imageDesc.MipLevels; ++level)
                {
                    int rowPitch, slicePitch;
                    int widthPacked;
                    int heightPacked;
                    ComputePitch(imageDesc.Format, w, h, out rowPitch, out slicePitch, out widthPacked, out heightPacked, pitchFlags);

                    for (uint zSlice = 0; zSlice < d; ++zSlice)
                    {
                        // We use the same memory organization that Direct3D 11 needs for D3D11_SUBRESOURCE_DATA
                        // with all slices of a given miplevel being continuous in memory
                        output[index] = new PixelBuffer(w, h, imageDesc.Format, rowPitch, slicePitch, (IntPtr)pixels);
                        ++index;

                        pixels += slicePitch;
                    }

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

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

                    if (d > 1)
                    {
                        d >>= 1;
                    }
                }
            }
        }
示例#6
0
            /// <summary>
            /// Function to return pitch information for this format.
            /// </summary>
            /// <param name="width">The width of the pixel data.</param>
            /// <param name="height">The height of the pixel data.</param>
            /// <param name="flags">Legacy flags for counting the bits per pixel and data alignment.</param>
            /// <returns>The pitch information for the format.</returns>
            public GorgonFormatPitch GetPitch(int width, int height, PitchFlags flags)
            {
                int rowPitch;

                // Do calculations for compressed formats.
                if (IsCompressed)
                {
                    int bpb;

                    switch (Format)
                    {
                    case BufferFormat.BC1:
                    case BufferFormat.BC1_UIntNormal:
                    case BufferFormat.BC1_UIntNormal_sRGB:
                    case BufferFormat.BC4:
                    case BufferFormat.BC4_IntNormal:
                    case BufferFormat.BC4_UIntNormal:
                        bpb = 8;
                        break;

                    default:
                        bpb = 16;
                        break;
                    }

                    int widthCounter  = 1.Max((width + 3) / 4);
                    int heightCounter = 1.Max((height + 3) / 4);
                    rowPitch = widthCounter * bpb;

                    return(new GorgonFormatPitch(widthCounter * bpb, heightCounter * rowPitch, new Size(widthCounter, heightCounter)));
                }

                if (IsPacked)
                {
                    rowPitch = ((width + 1) >> 1) >> 2;
                    return(new GorgonFormatPitch(rowPitch, rowPitch * height, Size.Empty));
                }

                int bitsPerPixel = BitDepth;

                if ((flags & PitchFlags.BPP24) == PitchFlags.BPP24)
                {
                    bitsPerPixel = 24;
                }
                else if ((flags & PitchFlags.BPP16) == PitchFlags.BPP16)
                {
                    bitsPerPixel = 16;
                }
                else if ((flags & PitchFlags.BPP8) == PitchFlags.BPP8)
                {
                    bitsPerPixel = 8;
                }

                // This is for handling old DirectDraw DDS files that didn't output
                // properly because of assumptions about pitch alignment.
                if ((flags & PitchFlags.LegacyDWORD) == PitchFlags.LegacyDWORD)
                {
                    rowPitch = ((width * bitsPerPixel + 31) / 32) * sizeof(int);
                }
                else
                {
                    rowPitch = ((width * bitsPerPixel + 7) / 8);
                }

                return(new GorgonFormatPitch(rowPitch, rowPitch * height, Size.Empty));
            }
示例#7
0
文件: Image.cs 项目: Julyuary/paradox
        internal static MipMapDescription[] CalculateMipMapDescription(ImageDescription metadata, PitchFlags cpFlags, out int nImages, out int pixelSize)
        {
            pixelSize = 0;
            nImages = 0;

            int w = metadata.Width;
            int h = metadata.Height;
            int d = metadata.Depth;

            var mipmaps = new MipMapDescription[metadata.MipLevels];

            for (int level = 0; level < metadata.MipLevels; ++level)
            {
                int rowPitch, slicePitch;
                int widthPacked;
                int heightPacked;
                ComputePitch(metadata.Format, w, h, out rowPitch, out slicePitch, out widthPacked, out heightPacked, PitchFlags.None);

                mipmaps[level] = new MipMapDescription(
                    w,
                    h,
                    d,
                    rowPitch,
                    slicePitch,
                    widthPacked,
                    heightPacked
                    );

                pixelSize += d * slicePitch;
                nImages += d;

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

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

                if (d > 1)
                    d >>= 1;
            }
            return mipmaps;
        }
示例#8
0
文件: Image.cs 项目: Julyuary/paradox
        internal static void ComputePitch(PixelFormat fmt, int width, int height, out int rowPitch, out int slicePitch, out int widthCount, out int heightCount, PitchFlags flags = PitchFlags.None)
        {
            widthCount = width;
            heightCount = height;

            if (fmt.IsCompressed())
            {
                int minWidth = 1;
                int minHeight = 1;
                int bpb = 8;

                switch (fmt)
                {
                    case PixelFormat.BC1_Typeless:
                    case PixelFormat.BC1_UNorm:
                    case PixelFormat.BC1_UNorm_SRgb:
                    case PixelFormat.BC4_Typeless:
                    case PixelFormat.BC4_UNorm:
                    case PixelFormat.BC4_SNorm:
                    case PixelFormat.ETC1:
                        bpb = 8;
                        break;
                    case PixelFormat.PVRTC_4bpp_RGB:
                    case PixelFormat.PVRTC_4bpp_RGBA:
                    case PixelFormat.PVRTC_II_4bpp:
                        minWidth = 8;
                        minHeight = 8;
                        break;
                    case PixelFormat.PVRTC_2bpp_RGBA:
                    case PixelFormat.PVRTC_II_2bpp:
                        minWidth = 16;
                        minHeight = 8;
                        bpb = 4;
                        break;
                    default:
                        bpb = 16;
                        break;
                }

                widthCount = Math.Max(1, (Math.Max(minWidth, width) + 3)) / 4;
                heightCount = Math.Max(1, (Math.Max(minHeight, height) + 3)) / 4;
                rowPitch = widthCount*bpb;

                slicePitch = rowPitch*heightCount;
            }
            else if (fmt.IsPacked())
            {
                rowPitch = ((width + 1) >> 1) * 4;

                slicePitch = rowPitch * height;
            }
            else
            {
                int bpp;

                if ((flags & PitchFlags.Bpp24) != 0)
                    bpp = 24;
                else if ((flags & PitchFlags.Bpp16) != 0)
                    bpp = 16;
                else if ((flags & PitchFlags.Bpp8) != 0)
                    bpp = 8;
                else
                    bpp = fmt.SizeInBits();

                if ((flags & PitchFlags.LegacyDword) != 0)
                {
                    // Special computation for some incorrectly created DDS files based on
                    // legacy DirectDraw assumptions about pitch alignment
                    rowPitch = ((width * bpp + 31) / 32) * sizeof(int);
                    slicePitch = rowPitch * height;
                }
                else
                {
                    rowPitch = (width * bpp + 7) / 8;
                    slicePitch = rowPitch * height;
                }
            }
        }
示例#9
0
文件: Image.cs 项目: Julyuary/paradox
 /// <summary>
 /// Initializes a new instance of the <see cref="Image" /> class.
 /// </summary>
 /// <param name="description">The image description.</param>
 /// <param name="dataPointer">The pointer to the data buffer.</param>
 /// <param name="offset">The offset from the beginning of the data buffer.</param>
 /// <param name="handle">The handle (optionnal).</param>
 /// <param name="bufferIsDisposable">if set to <c>true</c> [buffer is disposable].</param>
 /// <exception cref="System.InvalidOperationException">If the format is invalid, or width/height/depth/arraysize is invalid with respect to the dimension.</exception>
 internal unsafe Image(ImageDescription description, IntPtr dataPointer, int offset, GCHandle? handle, bool bufferIsDisposable, PitchFlags pitchFlags = PitchFlags.None, int rowStride = 0)
 {
     Initialize(description, dataPointer, offset, handle, bufferIsDisposable, pitchFlags, rowStride);
 }
示例#10
0
        internal static void ComputePitch(Format fmt, int width, int height, out int rowPitch, out int slicePitch, out int widthCount, out int heightCount, PitchFlags flags = PitchFlags.None)
        {
            widthCount = width;
            heightCount = height;

            if (FormatHelper.IsCompressed(fmt))
            {
                int bpb = (fmt == Format.BC1_Typeless
                             || fmt == Format.BC1_UNorm
                             || fmt == Format.BC1_UNorm_SRgb
                             || fmt == Format.BC4_Typeless
                             || fmt == Format.BC4_UNorm
                             || fmt == Format.BC4_SNorm) ? 8 : 16;
                widthCount = Math.Max(1, (width + 3) / 4);
                heightCount = Math.Max(1, (height + 3) / 4);
                rowPitch = widthCount * bpb;

                slicePitch = rowPitch * heightCount;
            }
            else if (FormatHelper.IsPacked(fmt))
            {
                rowPitch = ((width + 1) >> 1) * 4;

                slicePitch = rowPitch * height;
            }
            else
            {
                int bpp;

                if ((flags & PitchFlags.Bpp24) != 0)
                    bpp = 24;
                else if ((flags & PitchFlags.Bpp16) != 0)
                    bpp = 16;
                else if ((flags & PitchFlags.Bpp8) != 0)
                    bpp = 8;
                else
                    bpp = FormatHelper.SizeOfInBits(fmt);

                if ((flags & PitchFlags.LegacyDword) != 0)
                {
                    // Special computation for some incorrectly created DDS files based on
                    // legacy DirectDraw assumptions about pitch alignment
                    rowPitch = ((width * bpp + 31) / 32) * sizeof(int);
                    slicePitch = rowPitch * height;
                }
                else
                {
                    rowPitch = (width * bpp + 7) / 8;
                    slicePitch = rowPitch * height;
                }
            }
        }
示例#11
0
        /// <summary>
        /// Allocates PixelBuffers 
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="pixelSize"></param>
        /// <param name="imageDesc"></param>
        /// <param name="pitchFlags"></param>
        /// <param name="output"></param>
        private static unsafe void SetupImageArray(IntPtr buffer, int pixelSize, ImageDescription imageDesc, PitchFlags pitchFlags, PixelBuffer[] output)
        {
            int index = 0;
            var pixels = (byte*)buffer;
            for (uint item = 0; item < imageDesc.ArraySize; ++item)
            {
                int w = imageDesc.Width;
                int h = imageDesc.Height;
                int d = imageDesc.Depth;

                for (uint level = 0; level < imageDesc.MipLevels; ++level)
                {
                    int rowPitch, slicePitch;
                    int widthPacked;
                    int heightPacked;
                    ComputePitch(imageDesc.Format, w, h, out rowPitch, out slicePitch, out widthPacked, out heightPacked, pitchFlags);

                    for (uint zSlice = 0; zSlice < d; ++zSlice)
                    {
                        // We use the same memory organization that Direct3D 11 needs for D3D11_SUBRESOURCE_DATA
                        // with all slices of a given miplevel being continuous in memory
                        output[index] = new PixelBuffer(w, h, imageDesc.Format, rowPitch, slicePitch, (IntPtr)pixels);
                        ++index;

                        pixels += slicePitch;
                    }

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

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

                    if (d > 1)
                        d >>= 1;
                }
            }
        }
示例#12
0
        internal static void ComputePitch(PixelFormat fmt, int width, int height, out int rowPitch, out int slicePitch, out int widthCount, out int heightCount, PitchFlags flags = PitchFlags.None)
        {
            widthCount = width;
            heightCount = height;

            if (fmt.IsCompressed())
            {
                int minWidth = 1;
                int minHeight = 1;
                int bpb = 8;

                switch (fmt)
                {
                    case PixelFormat.BC1_Typeless:
                    case PixelFormat.BC1_UNorm:
                    case PixelFormat.BC1_UNorm_SRgb:
                    case PixelFormat.BC4_Typeless:
                    case PixelFormat.BC4_UNorm:
                    case PixelFormat.BC4_SNorm:
                    case PixelFormat.ETC1:
                        bpb = 8;
                        break;
                    case PixelFormat.PVRTC_4bpp_RGB:
                    case PixelFormat.PVRTC_4bpp_RGBA:
                    case PixelFormat.PVRTC_II_4bpp:
                        minWidth = 8;
                        minHeight = 8;
                        break;
                    case PixelFormat.PVRTC_2bpp_RGBA:
                    case PixelFormat.PVRTC_II_2bpp:
                        minWidth = 16;
                        minHeight = 8;
                        bpb = 4;
                        break;
                    default:
                        bpb = 16;
                        break;
                }

                widthCount = Math.Max(1, (Math.Max(minWidth, width) + 3)) / 4;
                heightCount = Math.Max(1, (Math.Max(minHeight, height) + 3)) / 4;
                rowPitch = widthCount*bpb;

                slicePitch = rowPitch*heightCount;
            }
            else if (fmt.IsPacked())
            {
                rowPitch = ((width + 1) >> 1) * 4;

                slicePitch = rowPitch * height;
            }
            else
            {
                int bpp;

                if ((flags & PitchFlags.Bpp24) != 0)
                    bpp = 24;
                else if ((flags & PitchFlags.Bpp16) != 0)
                    bpp = 16;
                else if ((flags & PitchFlags.Bpp8) != 0)
                    bpp = 8;
                else
                    bpp = fmt.SizeInBits();

                if ((flags & PitchFlags.LegacyDword) != 0)
                {
                    // Special computation for some incorrectly created DDS files based on
                    // legacy DirectDraw assumptions about pitch alignment
                    rowPitch = ((width * bpp + 31) / 32) * sizeof(int);
                    slicePitch = rowPitch * height;
                }
                else
                {
                    rowPitch = (width * bpp + 7) / 8;
                    slicePitch = rowPitch * height;
                }
            }
        }
示例#13
0
        /// <summary>
        /// Allocates PixelBuffers 
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="pixelSize"></param>
        /// <param name="imageDesc"></param>
        /// <param name="pitchFlags"></param>
        /// <param name="output"></param>
        private static unsafe void SetupImageArray(IntPtr buffer, int pixelSize, int rowStride, ImageDescription imageDesc, PitchFlags pitchFlags, PixelBuffer[] output)
        {
            int index = 0;
            var pixels = (byte*)buffer;
            for (uint item = 0; item < imageDesc.ArraySize; ++item)
            {
                int w = imageDesc.Width;
                int h = imageDesc.Height;
                int d = imageDesc.Depth;

                for (uint level = 0; level < imageDesc.MipLevels; ++level)
                {
                    int rowPitch, slicePitch;
                    int widthPacked;
                    int heightPacked;
                    ComputePitch(imageDesc.Format, w, h, out rowPitch, out slicePitch, out widthPacked, out heightPacked, pitchFlags);

                    if (rowStride > 0)
                    {
                        // Check that stride is ok
                        if (rowStride < rowPitch)
                            throw new InvalidOperationException(string.Format("Invalid stride [{0}]. Value can't be lower than actual stride [{1}]", rowStride, rowPitch));

                        if (widthPacked != w || heightPacked != h)
                            throw new InvalidOperationException("Custom strides is not supported with packed PixelFormats");

                        // Override row pitch
                        rowPitch = rowStride;

                        // Recalculate slice pitch
                        slicePitch = rowStride * h;
                    }

                    for (uint zSlice = 0; zSlice < d; ++zSlice)
                    {
                        // We use the same memory organization that Direct3D 11 needs for D3D11_SUBRESOURCE_DATA
                        // with all slices of a given miplevel being continuous in memory
                        output[index] = new PixelBuffer(w, h, imageDesc.Format, rowPitch, slicePitch, (IntPtr)pixels);
                        ++index;

                        pixels += slicePitch;
                    }

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

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

                    if (d > 1)
                        d >>= 1;
                }
            }
        }
示例#14
0
        public static void ComputePitch(PixelFormats fmt, int width, int height, out int rowPitch, out int slicePitch,
                                        out int widthCount, out int heightCount, PitchFlags flags = PitchFlags.None)
        {
            widthCount  = width;
            heightCount = height;

            if (IsCompressedFormat(fmt))
            {
                int bpb = (fmt == PixelFormats.BC1_TYPELESS ||
                           fmt == PixelFormats.BC1_UNORM ||
                           fmt == PixelFormats.BC1_UNORM_SRGB ||
                           fmt == PixelFormats.BC4_TYPELESS ||
                           fmt == PixelFormats.BC4_UNORM ||
                           fmt == PixelFormats.BC4_SNORM)
                              ? 8
                              : 16;
                widthCount  = Math.Max(1, (width + 3) / 4);
                heightCount = Math.Max(1, (height + 3) / 4);
                rowPitch    = widthCount * bpb;

                slicePitch = rowPitch * heightCount;
            }
            else if (IsPacked(fmt))
            {
                rowPitch = ((width + 1) >> 1) * 4;

                slicePitch = rowPitch * height;
            }
            else
            {
                int bpp;

                if ((flags & PitchFlags.Bpp24) != 0)
                {
                    bpp = 24;
                }
                else if ((flags & PitchFlags.Bpp16) != 0)
                {
                    bpp = 16;
                }
                else if ((flags & PitchFlags.Bpp8) != 0)
                {
                    bpp = 8;
                }
                else
                {
                    bpp = GetBitsPerPixel(fmt);
                }

                if ((flags & PitchFlags.LegacyDword) != 0)
                {
                    // Special computation for some incorrectly created DDS files based on
                    // legacy DirectDraw assumptions about pitch alignment
                    rowPitch   = ((width * bpp + 31) / 32) * sizeof(int);
                    slicePitch = rowPitch * height;
                }
                else
                {
                    rowPitch   = (width * bpp + 7) / 8;
                    slicePitch = rowPitch * height;
                }
            }
        }
示例#15
0
        public GorgonPitchLayout GetPitchForFormat(int width, int height, PitchFlags flags = PitchFlags.None)
        {
            int rowPitch;

            // Do calculations for compressed formats.
            if (IsCompressed)
            {
                int bpb;

                switch (Format)
                {
                case BufferFormat.BC1_Typeless:
                case BufferFormat.BC1_UNorm:
                case BufferFormat.BC1_UNorm_SRgb:
                case BufferFormat.BC4_Typeless:
                case BufferFormat.BC4_SNorm:
                case BufferFormat.BC4_UNorm:
                    bpb = 8;
                    break;

                default:
                    bpb = 16;
                    break;
                }

                /*
                 *              int widthCounter = 1.Max((width + 3) / 4);
                 *              int heightCounter = 1.Max((height + 3) / 4);
                 *              rowPitch = widthCounter * bpb;*/

                long numBlocksWide = 0;
                if (width > 0)
                {
                    numBlocksWide = (width + 3) / 4;
                }
                long numBlocksHigh = 0;
                if (height > 0)
                {
                    numBlocksHigh = (height + 3) / 4;
                }
                long rowBytes = numBlocksWide * bpb;
                long numBytes = rowBytes * numBlocksHigh;

                return(new GorgonPitchLayout((int)rowBytes, (int)numBytes, (int)numBlocksWide, (int)numBlocksHigh));
            }

            if (IsPacked)
            {
                int slicePitch = 0;

                switch (Format)
                {
                case BufferFormat.R8G8_B8G8_UNorm:
                case BufferFormat.G8R8_G8B8_UNorm:
                case BufferFormat.YUY2:
                    rowPitch   = ((width + 1) >> 1) << 2;
                    slicePitch = rowPitch * height;
                    break;

                case BufferFormat.Y210:
                case BufferFormat.Y216:
                    rowPitch   = ((width + 1) >> 1) << 4;
                    slicePitch = rowPitch * height;
                    break;

                case BufferFormat.NV12:
                case BufferFormat.Opaque420:
                    rowPitch   = ((width + 1) >> 1) << 1;
                    slicePitch = rowPitch * (height + ((height + 1) >> 1));
                    break;

                case BufferFormat.P010:
                case BufferFormat.P016:
                    rowPitch   = ((width + 1) >> 1) << 2;
                    slicePitch = rowPitch * (height + ((height + 1) >> 1));
                    break;

                case BufferFormat.NV11:
                    rowPitch   = ((width + 3) >> 2) << 2;
                    slicePitch = (rowPitch * height) << 1;
                    break;

                default:
                    rowPitch = 0;
                    break;
                }

                Debug.Assert(rowPitch != 0, "Format [" + Format + "] is a packed format. Cannot to extract pitch/slice info.");

                return(new GorgonPitchLayout(rowPitch, slicePitch));
            }

            int bitsPerPixel = BitDepth;

            if ((flags & PitchFlags.BPP24) == PitchFlags.BPP24)
            {
                bitsPerPixel = 24;
            }
            else if ((flags & PitchFlags.BPP16) == PitchFlags.BPP16)
            {
                bitsPerPixel = 16;
            }
            else if ((flags & PitchFlags.BPP8) == PitchFlags.BPP8)
            {
                bitsPerPixel = 8;
            }

            // This is for handling old DirectDraw DDS files that didn't output
            // properly because of assumptions about pitch alignment.
            if ((flags & PitchFlags.LegacyDWORD) == PitchFlags.LegacyDWORD)
            {
                rowPitch = (((width * bitsPerPixel) + 31) / 32) * sizeof(int);
            }
            else if ((flags & PitchFlags.Align4K) == PitchFlags.Align4K)
            {
                rowPitch = (((width * bitsPerPixel) + 32767) / 32768) * 4096;
            }
            else if ((flags & PitchFlags.Align64Byte) == PitchFlags.Align64Byte)
            {
                rowPitch = (((width * bitsPerPixel) + 511) / 512) * 64;
            }
            else if ((flags & PitchFlags.Align32Byte) == PitchFlags.Align32Byte)
            {
                rowPitch = (((width * bitsPerPixel) + 255) / 256) * 32;
            }
            else if ((flags & PitchFlags.Align16Byte) == PitchFlags.Align16Byte)
            {
                rowPitch = (((width * bitsPerPixel) + 127) / 128) * 16;
            }
            else
            {
                rowPitch = (((width * bitsPerPixel) + 7) / 8);
            }

            return(new GorgonPitchLayout(rowPitch, rowPitch * height));
        }
示例#16
0
文件: Image.cs 项目: tomba/Toolkit
        internal static void ComputePitch(Format fmt, int width, int height, out int rowPitch, out int slicePitch, out int widthCount, out int heightCount, PitchFlags flags = PitchFlags.None)
        {
            widthCount  = width;
            heightCount = height;

            if (FormatHelper.IsCompressed(fmt))
            {
                int bpb = (fmt == Format.BC1_Typeless ||
                           fmt == Format.BC1_UNorm ||
                           fmt == Format.BC1_UNorm_SRgb ||
                           fmt == Format.BC4_Typeless ||
                           fmt == Format.BC4_UNorm ||
                           fmt == Format.BC4_SNorm) ? 8 : 16;
                widthCount  = Math.Max(1, (width + 3) / 4);
                heightCount = Math.Max(1, (height + 3) / 4);
                rowPitch    = widthCount * bpb;

                slicePitch = rowPitch * heightCount;
            }
            else if (FormatHelper.IsPacked(fmt))
            {
                rowPitch = ((width + 1) >> 1) * 4;

                slicePitch = rowPitch * height;
            }
            else
            {
                int bpp;

                if ((flags & PitchFlags.Bpp24) != 0)
                {
                    bpp = 24;
                }
                else if ((flags & PitchFlags.Bpp16) != 0)
                {
                    bpp = 16;
                }
                else if ((flags & PitchFlags.Bpp8) != 0)
                {
                    bpp = 8;
                }
                else
                {
                    bpp = FormatHelper.SizeOfInBits(fmt);
                }

                if ((flags & PitchFlags.LegacyDword) != 0)
                {
                    // Special computation for some incorrectly created DDS files based on
                    // legacy DirectDraw assumptions about pitch alignment
                    rowPitch   = ((width * bpp + 31) / 32) * sizeof(int);
                    slicePitch = rowPitch * height;
                }
                else
                {
                    rowPitch   = (width * bpp + 7) / 8;
                    slicePitch = rowPitch * height;
                }
            }
        }
示例#17
0
文件: Image.cs 项目: Julyuary/paradox
        /// <summary>
        /// Allocates PixelBuffers 
        /// </summary>
        /// <param name="buffer"></param>
        /// <param name="pixelSize"></param>
        /// <param name="imageDesc"></param>
        /// <param name="pitchFlags"></param>
        /// <param name="output"></param>
        private static unsafe void SetupImageArray(IntPtr buffer, int pixelSize, int rowStride, ImageDescription imageDesc, PitchFlags pitchFlags, PixelBuffer[] output)
        {
            int index = 0;
            var pixels = (byte*)buffer;
            for (uint item = 0; item < imageDesc.ArraySize; ++item)
            {
                int w = imageDesc.Width;
                int h = imageDesc.Height;
                int d = imageDesc.Depth;

                for (uint level = 0; level < imageDesc.MipLevels; ++level)
                {
                    int rowPitch, slicePitch;
                    int widthPacked;
                    int heightPacked;
                    ComputePitch(imageDesc.Format, w, h, out rowPitch, out slicePitch, out widthPacked, out heightPacked, pitchFlags);

                    if (rowStride > 0)
                    {
                        // Check that stride is ok
                        if (rowStride < rowPitch)
                            throw new InvalidOperationException(string.Format("Invalid stride [{0}]. Value can't be lower than actual stride [{1}]", rowStride, rowPitch));

                        if (widthPacked != w || heightPacked != h)
                            throw new InvalidOperationException("Custom strides is not supported with packed PixelFormats");

                        // Override row pitch
                        rowPitch = rowStride;

                        // Recalculate slice pitch
                        slicePitch = rowStride * h;
                    }

                    for (uint zSlice = 0; zSlice < d; ++zSlice)
                    {
                        // We use the same memory organization that Direct3D 11 needs for D3D11_SUBRESOURCE_DATA
                        // with all slices of a given miplevel being continuous in memory
                        output[index] = new PixelBuffer(w, h, imageDesc.Format, rowPitch, slicePitch, (IntPtr)pixels);
                        ++index;

                        pixels += slicePitch;
                    }

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

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

                    if (d > 1)
                        d >>= 1;
                }
            }
        }
示例#18
0
        /// <summary>
        /// Determines number of image array entries and pixel size.
        /// </summary>
        /// <param name="imageDesc">Description of the image to create.</param>
        /// <param name="pitchFlags">Pitch flags.</param>
        /// <param name="bufferCount">Output number of mipmap.</param>
        /// <param name="pixelSizeInBytes">Output total size to allocate pixel buffers for all images.</param>
        private static List<int> CalculateImageArray( ImageDescription imageDesc, PitchFlags pitchFlags, out int bufferCount, out int pixelSizeInBytes)
        {
            pixelSizeInBytes = 0;
            bufferCount = 0;

            var mipmapToZIndex = new List<int>();

            for (int j = 0; j < imageDesc.ArraySize; j++)
            {
                int w = imageDesc.Width;
                int h = imageDesc.Height;
                int d = imageDesc.Depth; 
                
                for (int i = 0; i < imageDesc.MipLevels; i++)
                {
                    int rowPitch, slicePitch;
                    int widthPacked;
                    int heightPacked;
                    ComputePitch(imageDesc.Format, w, h, out rowPitch, out slicePitch, out widthPacked, out heightPacked, pitchFlags);

                    // Store the number of z-slicec per miplevels
                    if ( j == 0)
                        mipmapToZIndex.Add(bufferCount);

                    // Keep a trace of indices for the 1st array size, for each mip levels
                    pixelSizeInBytes += d * slicePitch;
                    bufferCount += d;

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

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

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

                // For the last mipmaps, store just the number of zbuffers in total
                if (j == 0)
                    mipmapToZIndex.Add(bufferCount);
            }
            return mipmapToZIndex;
        }
示例#19
0
文件: Image.cs 项目: Julyuary/paradox
        internal unsafe void Initialize(ImageDescription description, IntPtr dataPointer, int offset, GCHandle? handle, bool bufferIsDisposable, PitchFlags pitchFlags = PitchFlags.None, int rowStride = 0)
        {
            if (!description.Format.IsValid() || description.Format.IsVideo())
                throw new InvalidOperationException("Unsupported DXGI Format");

            if (rowStride > 0 && description.MipLevels != 1)
                throw new InvalidOperationException("Cannot specify custom stride with mipmaps");


            this.handle = handle;

            switch (description.Dimension)
            {
                case TextureDimension.Texture1D:
                    if (description.Width <= 0 || description.Height != 1 || description.Depth != 1 || description.ArraySize == 0)
                        throw new InvalidOperationException("Invalid Width/Height/Depth/ArraySize for Image 1D");

                    // Check that miplevels are fine
                    description.MipLevels = CalculateMipLevels(description.Width, 1, description.MipLevels);
                    break;

                case TextureDimension.Texture2D:
                case TextureDimension.TextureCube:
                    if (description.Width <= 0 || description.Height <= 0 || description.Depth != 1 || description.ArraySize == 0)
                        throw new InvalidOperationException("Invalid Width/Height/Depth/ArraySize for Image 2D");

                    if (description.Dimension == TextureDimension.TextureCube)
                    {
                        if ((description.ArraySize % 6) != 0)
                            throw new InvalidOperationException("TextureCube must have an arraysize = 6");
                    }

                    // Check that miplevels are fine
                    description.MipLevels = CalculateMipLevels(description.Width, description.Height, description.MipLevels);
                    break;

                case TextureDimension.Texture3D:
                    if (description.Width <= 0 || description.Height <= 0 || description.Depth <= 0 || description.ArraySize != 1)
                        throw new InvalidOperationException("Invalid Width/Height/Depth/ArraySize for Image 3D");

                    // Check that miplevels are fine
                    description.MipLevels = CalculateMipLevels(description.Width, description.Height, description.Depth, description.MipLevels);
                    break;
            }

            // Calculate mipmaps
            int pixelBufferCount;
            this.mipMapToZIndex = CalculateImageArray(description, pitchFlags, rowStride, out pixelBufferCount, out totalSizeInBytes);
            this.mipmapDescriptions = CalculateMipMapDescription(description, pitchFlags);
            zBufferCountPerArraySlice = this.mipMapToZIndex[this.mipMapToZIndex.Count - 1];

            // Allocate all pixel buffers
            pixelBuffers = new PixelBuffer[pixelBufferCount];
            pixelBufferArray = new PixelBufferArray(this);

            // Setup all pointers
            // only release buffer that is not pinned and is asked to be disposed.
            this.bufferIsDisposable = !handle.HasValue && bufferIsDisposable;
            this.buffer = dataPointer;

            if (dataPointer == IntPtr.Zero)
            {
                buffer = Utilities.AllocateMemory(totalSizeInBytes);
                offset = 0;
                this.bufferIsDisposable = true;
            }

            SetupImageArray((IntPtr)((byte*)buffer + offset), totalSizeInBytes, rowStride, description, pitchFlags, pixelBuffers);

            Description = description;

            // PreCompute databoxes
            dataBoxArray = ComputeDataBox();
        }
示例#20
0
文件: Image.cs 项目: tomba/Toolkit
        internal static MipMapDescription[] CalculateMipMapDescription(ImageDescription metadata, PitchFlags cpFlags = PitchFlags.None)
        {
            int nImages;
            int pixelSize;

            return(CalculateMipMapDescription(metadata, cpFlags, out nImages, out pixelSize));
        }
示例#21
0
文件: Image.cs 项目: Julyuary/paradox
 internal static MipMapDescription[] CalculateMipMapDescription(ImageDescription metadata, PitchFlags cpFlags = PitchFlags.None)
 {
     int nImages;
     int pixelSize;
     return CalculateMipMapDescription(metadata, cpFlags, out nImages, out pixelSize);
 }
示例#22
0
文件: Image.cs 项目: tomba/Toolkit
        internal static MipMapDescription[] CalculateMipMapDescription(ImageDescription metadata, PitchFlags cpFlags, out int nImages, out int pixelSize)
        {
            pixelSize = 0;
            nImages   = 0;

            int w = metadata.Width;
            int h = metadata.Height;
            int d = metadata.Depth;

            var mipmaps = new MipMapDescription[metadata.MipLevels];

            for (int level = 0; level < metadata.MipLevels; ++level)
            {
                int rowPitch, slicePitch;
                int widthPacked;
                int heightPacked;
                ComputePitch(metadata.Format, w, h, out rowPitch, out slicePitch, out widthPacked, out heightPacked, PitchFlags.None);

                mipmaps[level] = new MipMapDescription(
                    w,
                    h,
                    d,
                    rowPitch,
                    slicePitch,
                    widthPacked,
                    heightPacked
                    );

                pixelSize += d * slicePitch;
                nImages   += d;

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

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

                if (d > 1)
                {
                    d >>= 1;
                }
            }
            return(mipmaps);
        }
示例#23
0
文件: Image.cs 项目: Julyuary/paradox
        /// <summary>
        /// Determines number of image array entries and pixel size.
        /// </summary>
        /// <param name="imageDesc">Description of the image to create.</param>
        /// <param name="pitchFlags">Pitch flags.</param>
        /// <param name="bufferCount">Output number of mipmap.</param>
        /// <param name="pixelSizeInBytes">Output total size to allocate pixel buffers for all images.</param>
        private static List<int> CalculateImageArray( ImageDescription imageDesc, PitchFlags pitchFlags, int rowStride, out int bufferCount, out int pixelSizeInBytes)
        {
            pixelSizeInBytes = 0;
            bufferCount = 0;

            var mipmapToZIndex = new List<int>();

            for (int j = 0; j < imageDesc.ArraySize; j++)
            {
                int w = imageDesc.Width;
                int h = imageDesc.Height;
                int d = imageDesc.Depth; 
                
                for (int i = 0; i < imageDesc.MipLevels; i++)
                {
                    int rowPitch, slicePitch;
                    int widthPacked;
                    int heightPacked;
                    ComputePitch(imageDesc.Format, w, h, out rowPitch, out slicePitch, out widthPacked, out heightPacked, pitchFlags);

                    if (rowStride > 0)
                    {
                        // Check that stride is ok
                        if (rowStride < rowPitch)
                            throw new InvalidOperationException(string.Format("Invalid stride [{0}]. Value can't be lower than actual stride [{1}]", rowStride, rowPitch));

                        if (widthPacked != w || heightPacked != h)
                            throw new InvalidOperationException("Custom strides is not supported with packed PixelFormats");

                        // Override row pitch
                        rowPitch = rowStride;

                        // Recalculate slice pitch
                        slicePitch = rowStride * h;
                    }

                    // Store the number of z-slicec per miplevels
                    if ( j == 0)
                        mipmapToZIndex.Add(bufferCount);

                    // Keep a trace of indices for the 1st array size, for each mip levels
                    pixelSizeInBytes += d * slicePitch;
                    bufferCount += d;

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

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

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

                // For the last mipmaps, store just the number of zbuffers in total
                if (j == 0)
                    mipmapToZIndex.Add(bufferCount);
            }
            return mipmapToZIndex;
        }
示例#24
0
        public static void ComputePitch(PixelFormats fmt, int width, int height, out int rowPitch, out int slicePitch,
                                  out int widthCount, out int heightCount, PitchFlags flags = PitchFlags.None)
        {
            widthCount = width;
            heightCount = height;

            if (IsCompressedFormat(fmt))
            {
                int bpb = (fmt == PixelFormats.BC1_TYPELESS
                           || fmt == PixelFormats.BC1_UNORM
                           || fmt == PixelFormats.BC1_UNORM_SRGB
                           || fmt == PixelFormats.BC4_TYPELESS
                           || fmt == PixelFormats.BC4_UNORM
                           || fmt == PixelFormats.BC4_SNORM)
                              ? 8
                              : 16;
                widthCount = Math.Max(1, (width + 3)/4);
                heightCount = Math.Max(1, (height + 3)/4);
                rowPitch = widthCount*bpb;

                slicePitch = rowPitch*heightCount;
            }
            else if (IsPacked(fmt))
            {
                rowPitch = ((width + 1) >> 1)*4;

                slicePitch = rowPitch*height;
            }
            else
            {
                int bpp;

                if ((flags & PitchFlags.Bpp24) != 0)
                    bpp = 24;
                else if ((flags & PitchFlags.Bpp16) != 0)
                    bpp = 16;
                else if ((flags & PitchFlags.Bpp8) != 0)
                    bpp = 8;
                else
                    bpp = GetBitsPerPixel(fmt);

                if ((flags & PitchFlags.LegacyDword) != 0)
                {
                    // Special computation for some incorrectly created DDS files based on
                    // legacy DirectDraw assumptions about pitch alignment
                    rowPitch = ((width*bpp + 31)/32)*sizeof (int);
                    slicePitch = rowPitch*height;
                }
                else
                {
                    rowPitch = (width*bpp + 7)/8;
                    slicePitch = rowPitch*height;
                }
            }
        }