/// <summary>
        /// Function to expand a 16BPP scan line in an image to a 32BPP RGBA line.
        /// </summary>
        /// <param name="src">The pointer to the source data.</param>
        /// <param name="srcPitch">The pitch of the source data.</param>
        /// <param name="srcFormat">Format to convert from.</param>
        /// <param name="dest">The pointer to the destination data.</param>
        /// <param name="destPitch">The pitch of the destination data.</param>
        /// <param name="bitFlags">Image bit conversion control flags.</param>
        /// <exception cref="ArgumentException">Thrown when the <paramref name="srcFormat" /> is not a 16 BPP format.</exception>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="src"/> or the <paramref name="dest"/> parameter is <b>null</b>.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when the <paramref name="srcPitch"/> or the <paramref name="destPitch"/> parameter is less than 0.</exception>
        /// <remarks>
        /// <para>
        /// Use this to expand a 16 BPP (B5G6R5 or B5G5R5A1 format) into a 32 BPP R8G8B8A8 (normalized unsigned integer) format.
        /// </para>
        /// </remarks>
        public static unsafe void Expand16BPPScanline(void *src, int srcPitch, BufferFormat srcFormat, void *dest, int destPitch, ImageBitFlags bitFlags)
        {
            ushort *srcPtr  = (ushort *)src;
            uint *  destPtr = (uint *)dest;

            if ((srcFormat != BufferFormat.B5G5R5A1_UNorm) && (srcFormat != BufferFormat.B5G6R5_UNorm) && (srcFormat != BufferFormat.B4G4R4A4_UNorm))
            {
                throw new ArgumentException(string.Format(Resources.GORIMG_ERR_FORMAT_IS_NOT_16BPP, srcFormat), nameof(srcFormat));
            }

            if (src == null)
            {
                throw new ArgumentNullException(nameof(src));
            }

            if (dest == null)
            {
                throw new ArgumentNullException(nameof(dest));
            }

            for (int srcCount = 0, destCount = 0; ((srcCount < srcPitch) && (destCount < destPitch)); srcCount += 2, destCount += 4)
            {
                ushort srcPixel = *(srcPtr++);
                uint   R = 0, G = 0, B = 0, A = 0;

                switch (srcFormat)
                {
                case BufferFormat.B5G6R5_UNorm:
                    R = (uint)((srcPixel & 0xF800) >> 11);
                    G = (uint)((srcPixel & 0x07E0) >> 5);
                    B = (uint)(srcPixel & 0x001F);
                    R = ((R << 3) | (R >> 2));
                    G = ((G << 2) | (G >> 4)) << 8;
                    B = ((B << 3) | (B >> 2)) << 16;
                    A = 0xFF000000;
                    break;

                case BufferFormat.B5G5R5A1_UNorm:
                    R = (uint)((srcPixel & 0x7C00) >> 10);
                    G = (uint)((srcPixel & 0x03E0) >> 5);
                    B = (uint)(srcPixel & 0x001F);
                    R = ((R << 3) | (R >> 2));
                    G = ((G << 3) | (G >> 2)) << 8;
                    B = ((B << 3) | (B >> 2)) << 16;
                    A = ((bitFlags & ImageBitFlags.OpaqueAlpha) == ImageBitFlags.OpaqueAlpha)
                                                                ? 0xFF000000
                                                                : (((srcPixel & 0x8000) != 0) ? 0xFF000000 : 0);
                    break;

                case BufferFormat.B4G4R4A4_UNorm:
                    A = (uint)((srcPixel & 0xF000) >> 12);
                    R = (uint)((srcPixel & 0xF00) >> 8);
                    G = (uint)((srcPixel & 0xF0) >> 4);
                    B = (uint)(srcPixel & 0xF);
                    R = ((R << 4) | R);
                    G = ((G << 4) | G) << 8;
                    B = ((B << 4) | B) << 16;
                    A = ((bitFlags & ImageBitFlags.OpaqueAlpha) == ImageBitFlags.OpaqueAlpha)
                                                                ? 0xFF000000
                                                                : ((A << 4) | A) << 24;
                    break;
                }

                *(destPtr++) = R | G | B | A;
            }
        }
        /// <summary>
        /// Function to copy (or update in-place) with bits swizzled to match another format.
        /// </summary>
        /// <param name="src">The pointer to the source data.</param>
        /// <param name="srcPitch">The pitch of the source data.</param>
        /// <param name="dest">The pointer to the destination data.</param>
        /// <param name="destPitch">The pitch of the destination data.</param>
        /// <param name="format">Format of the destination buffer.</param>
        /// <param name="bitFlags">Image bit conversion control flags.</param>
        /// <exception cref="ArgumentException">Thrown when the <paramref name="format"/> parameter is Unknown.</exception>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="src"/> or the <paramref name="dest"/> parameter is <b>null</b>.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when the <paramref name="srcPitch"/> or the <paramref name="destPitch"/> parameter is less than 0.</exception>
        /// <remarks>
        /// <para>
        /// Use this method to copy a single scanline and swizzle the bits of an image and (optionally) set an opaque constant alpha value.
        /// </para>
        /// </remarks>
        public static unsafe void SwizzleScanline(void *src, int srcPitch, void *dest, int destPitch, BufferFormat format, ImageBitFlags bitFlags)
        {
            int  size = srcPitch.Min(destPitch);
            uint r, g, b, a, pixel;

            if (src == null)
            {
                throw new ArgumentNullException(nameof(src));
            }

            if (dest == null)
            {
                throw new ArgumentNullException(nameof(dest));
            }

            if (format == BufferFormat.Unknown)
            {
                throw new ArgumentException(string.Format(Resources.GORIMG_ERR_FORMAT_NOT_SUPPORTED, format),
                                            nameof(format));
            }

            uint *srcPtr  = (uint *)src;
            uint *destPtr = (uint *)dest;

            switch (format)
            {
            case BufferFormat.R10G10B10A2_Typeless:
            case BufferFormat.R10G10B10A2_UInt:
            case BufferFormat.R10G10B10A2_UNorm:
            case BufferFormat.R10G10B10_Xr_Bias_A2_UNorm:
                for (int i = 0; i < size; i += 4)
                {
                    if (src != dest)
                    {
                        pixel = *(srcPtr++);
                    }
                    else
                    {
                        pixel = *(destPtr);
                    }

                    r = ((pixel & 0x3FF00000) >> 20);
                    g = (pixel & 0x000FFC00);
                    b = ((pixel & 0x000003FF) << 20);
                    a = ((bitFlags & ImageBitFlags.OpaqueAlpha) == ImageBitFlags.OpaqueAlpha) ? 0xC0000000 : pixel & 0xC0000000;

                    *destPtr = r | g | b | a;
                    destPtr++;
                }
                return;

            case BufferFormat.R8G8B8A8_Typeless:
            case BufferFormat.R8G8B8A8_UNorm:
            case BufferFormat.R8G8B8A8_UNorm_SRgb:
            case BufferFormat.B8G8R8A8_UNorm:
            case BufferFormat.B8G8R8X8_UNorm:
            case BufferFormat.B8G8R8A8_Typeless:
            case BufferFormat.B8G8R8A8_UNorm_SRgb:
            case BufferFormat.B8G8R8X8_Typeless:
            case BufferFormat.B8G8R8X8_UNorm_SRgb:
                for (int i = 0; i < size; i += 4)
                {
                    if (src != dest)
                    {
                        pixel = *(srcPtr++);
                    }
                    else
                    {
                        pixel = *(destPtr);
                    }

                    r = ((pixel & 0xFF0000) >> 16);
                    g = (pixel & 0x00FF00);
                    b = ((pixel & 0x0000FF) << 16);
                    a = ((bitFlags & ImageBitFlags.OpaqueAlpha) == ImageBitFlags.OpaqueAlpha) ? 0xFF000000 : pixel & 0xFF000000;

                    *destPtr = r | g | b | a;
                    destPtr++;
                }
                return;
            }

            if (src != dest)
            {
                Unsafe.CopyBlock(dest, src, (uint)size);
            }
        }
        /// <summary>
        /// Function to copy (or update in-place) a line with opaque alpha substituion (if required).
        /// </summary>
        /// <param name="src">The pointer to the source data.</param>
        /// <param name="srcPitch">The pitch of the source data.</param>
        /// <param name="dest">The pointer to the destination data.</param>
        /// <param name="destPitch">The pitch of the destination data.</param>
        /// <param name="format">Format of the destination buffer.</param>
        /// <param name="bitFlags">Image bit conversion control flags.</param>
        /// <exception cref="ArgumentEmptyException">Thrown when the <paramref name="format"/> parameter is Unknown.</exception>
        /// <exception cref="ArgumentNullException">Thrown when the <paramref name="src"/> or the <paramref name="dest"/> parameter is <b>null</b>.</exception>
        /// <exception cref="ArgumentOutOfRangeException">Thrown when the <paramref name="srcPitch"/> or the <paramref name="destPitch"/> parameter is less than 0.</exception>
        /// <remarks>Use this method to copy a single scanline of an image and (optionally) set an opaque constant alpha value.</remarks>
        public static unsafe void CopyScanline(void *src, int srcPitch, void *dest, int destPitch, BufferFormat format, ImageBitFlags bitFlags)
        {
            if (src == null)
            {
                throw new ArgumentNullException(nameof(src));
            }

            if (dest == null)
            {
                throw new ArgumentNullException(nameof(dest));
            }

            if (format == BufferFormat.Unknown)
            {
                throw new ArgumentException(string.Format(Resources.GORIMG_ERR_FORMAT_NOT_SUPPORTED, format), nameof(format));
            }

            int size = (src == dest) ? destPitch : (srcPitch.Min(destPitch));

            if ((bitFlags & ImageBitFlags.OpaqueAlpha) == ImageBitFlags.OpaqueAlpha)
            {
                // Do a straight copy.
                switch (format)
                {
                case BufferFormat.R32G32B32A32_Typeless:
                case BufferFormat.R32G32B32A32_Float:
                case BufferFormat.R32G32B32A32_UInt:
                case BufferFormat.R32G32B32A32_SInt:
                {
                    uint alpha = (format == BufferFormat.R32G32B32_Float) ? 0x3F800000
                                                                                                : ((format == BufferFormat.R32G32B32_SInt) ? 0x7FFFFFFF : 0xFFFFFFFF);

                    uint *srcPtr  = (uint *)src;
                    uint *destPtr = (uint *)dest;

                    for (int i = 0; i < size; i += 16)
                    {
                        // If not in-place copy, then copy from the source.
                        if (src != dest)
                        {
                            *(destPtr++) = *(srcPtr++);
                            *(destPtr++) = *(srcPtr++);
                            *(destPtr++) = *(srcPtr++);
                        }

                        *(destPtr++) = alpha;
                    }
                }
                    return;

                case BufferFormat.R16G16B16A16_Typeless:
                case BufferFormat.R16G16B16A16_Float:
                case BufferFormat.R16G16B16A16_UNorm:
                case BufferFormat.R16G16B16A16_UInt:
                case BufferFormat.R16G16B16A16_SNorm:
                case BufferFormat.R16G16B16A16_SInt:
                {
                    ushort alpha = 0xFFFF;

                    switch (format)
                    {
                    case BufferFormat.R16G16B16A16_Float:
                        alpha = 0x3C00;
                        break;

                    case BufferFormat.R16G16B16A16_SInt:
                    case BufferFormat.R16G16B16A16_SNorm:
                        alpha = 0x7FFF;
                        break;
                    }

                    ushort *srcPtr  = (ushort *)src;
                    ushort *destPtr = (ushort *)dest;

                    for (int i = 0; i < size; i += 8)
                    {
                        // If not in-place copy, then copy from the source.
                        if (src != dest)
                        {
                            *destPtr = *srcPtr;
                            srcPtr += 4;
                        }
                        *destPtr += 3;
                        *(destPtr++) = alpha;
                    }
                }
                    return;

                case BufferFormat.R10G10B10A2_Typeless:
                case BufferFormat.R10G10B10A2_UNorm:
                case BufferFormat.R10G10B10A2_UInt:
                case BufferFormat.R10G10B10_Xr_Bias_A2_UNorm:
                {
                    uint *srcPtr  = (uint *)src;
                    uint *destPtr = (uint *)dest;

                    for (int i = 0; i < size; i += 4)
                    {
                        // If not in-place copy, then copy from the source.
                        if (src != dest)
                        {
                            *destPtr = (*srcPtr) & 0x3FFFFFFF;
                            srcPtr++;
                        }
                        *destPtr |= 0xC0000000;
                        destPtr++;
                    }
                }
                    return;

                case BufferFormat.R8G8B8A8_Typeless:
                case BufferFormat.R8G8B8A8_UNorm:
                case BufferFormat.R8G8B8A8_UNorm_SRgb:
                case BufferFormat.R8G8B8A8_UInt:
                case BufferFormat.R8G8B8A8_SNorm:
                case BufferFormat.R8G8B8A8_SInt:
                case BufferFormat.B8G8R8A8_UNorm:
                case BufferFormat.B8G8R8A8_Typeless:
                case BufferFormat.B8G8R8A8_UNorm_SRgb:
                {
                    uint alpha = ((format == BufferFormat.R8G8B8A8_SInt) || (format == BufferFormat.R8G8B8A8_SNorm)) ? 0x7F000000 : 0xFF000000;

                    uint *srcPtr  = (uint *)src;
                    uint *destPtr = (uint *)dest;

                    for (int i = 0; i < size; i += 4)
                    {
                        // If not in-place copy, then copy from the source.
                        if (src != dest)
                        {
                            *destPtr = (*srcPtr) & 0xFFFFFF;
                            srcPtr++;
                        }
                        *destPtr |= alpha;
                        destPtr++;
                    }
                }
                    return;

                case BufferFormat.B4G4R4A4_UNorm:
                {
                    ushort *srcPtr  = (ushort *)src;
                    ushort *destPtr = (ushort *)dest;

                    for (int i = 0; i < size; i += 2)
                    {
                        // If not in-place copy, then copy from the source.
                        if (src != dest)
                        {
                            *(destPtr++) = (ushort)((*srcPtr++) | 0xF000);
                        }
                        else
                        {
                            *(destPtr++) |= 0xF000;
                        }
                    }
                }
                    return;

                case BufferFormat.B5G5R5A1_UNorm:
                {
                    ushort *srcPtr  = (ushort *)src;
                    ushort *destPtr = (ushort *)dest;

                    for (int i = 0; i < size; i += 2)
                    {
                        // If not in-place copy, then copy from the source.
                        if (src != dest)
                        {
                            *(destPtr++) = (ushort)((*srcPtr++) | 0x8000);
                        }
                        else
                        {
                            *(destPtr++) |= 0x8000;
                        }
                    }
                }
                    return;

                case BufferFormat.A8_UNorm:
                    Unsafe.InitBlock(dest, 0xff, (uint)size);
                    return;
                }
            }

            // Copy if not doing an in-place update.
            if (dest != src)
            {
                Unsafe.CopyBlock(dest, src, (uint)size);
            }
        }
Exemple #4
0
        /// <summary>
        /// Function to copy (or update in-place) a line with opaque alpha substituion (if required).
        /// </summary>
        /// <param name="src">The pointer to the source data.</param>
        /// <param name="srcPitch">The pitch of the source data.</param>
        /// <param name="dest">The pointer to the destination data.</param>
        /// <param name="destPitch">The pitch of the destination data.</param>
        /// <param name="format">Format of the destination buffer.</param>
        /// <param name="bitFlags">Image bit conversion control flags.</param>
        /// <exception cref="System.ArgumentException">Thrown when the <paramref name="format"/> parameter is Unknown.</exception>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="src"/> or the <paramref name="dest"/> parameter is NULL.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="srcPitch"/> or the <paramref name="destPitch"/> parameter is less than 0.</exception>
        /// <remarks>Use this method to copy a single scanline of an image and (optionally) set an opaque constant alpha value.</remarks>
        protected unsafe void CopyScanline(void *src, int srcPitch, void *dest, int destPitch, BufferFormat format, ImageBitFlags bitFlags)
        {
            if (src == null)
            {
                throw new ArgumentNullException("src");
            }

            if (dest == null)
            {
                throw new ArgumentNullException("dest");
            }

            if (format == BufferFormat.Unknown)
            {
                throw new ArgumentException(string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, BufferFormat.Unknown),
                                            "format");
            }

            int size = (src == dest) ? destPitch : (srcPitch.Min(destPitch));

            if ((bitFlags & ImageBitFlags.OpaqueAlpha) == ImageBitFlags.OpaqueAlpha)
            {
                // Do a straight copy.
                switch (format)
                {
                case BufferFormat.R32G32B32A32:
                case BufferFormat.R32G32B32A32_Float:
                case BufferFormat.R32G32B32A32_UInt:
                case BufferFormat.R32G32B32A32_Int:
                {
                    uint alpha = (format == BufferFormat.R32G32B32_Float) ? 0x3F800000
                                                                                                : ((format == BufferFormat.R32G32B32_Int) ? 0x7FFFFFFF : 0xFFFFFFFF);

                    var srcPtr  = (uint *)src;
                    var destPtr = (uint *)dest;

                    for (int i = 0; i < size; i += 16)
                    {
                        // If not in-place copy, then copy from the source.
                        if (src != dest)
                        {
                            *destPtr = *srcPtr;
                            srcPtr += 4;
                        }

                        *destPtr += 3;
                        *(destPtr++) = alpha;
                    }
                }
                    return;

                case BufferFormat.R16G16B16A16:
                case BufferFormat.R16G16B16A16_Float:
                case BufferFormat.R16G16B16A16_UIntNormal:
                case BufferFormat.R16G16B16A16_UInt:
                case BufferFormat.R16G16B16A16_IntNormal:
                case BufferFormat.R16G16B16A16_Int:
                {
                    ushort alpha = 0xFFFF;

                    switch (format)
                    {
                    case BufferFormat.R16G16B16A16_Float:
                        alpha = 0x3C00;
                        break;

                    case BufferFormat.R16G16B16A16_Int:
                    case BufferFormat.R16G16B16A16_IntNormal:
                        alpha = 0x7FFF;
                        break;
                    }

                    var srcPtr  = (ushort *)src;
                    var destPtr = (ushort *)dest;

                    for (int i = 0; i < size; i += 8)
                    {
                        // If not in-place copy, then copy from the source.
                        if (src != dest)
                        {
                            *destPtr = *srcPtr;
                            srcPtr += 4;
                        }
                        *destPtr += 3;
                        *(destPtr++) = alpha;
                    }
                }
                    return;

                case BufferFormat.R10G10B10A2:
                case BufferFormat.R10G10B10A2_UIntNormal:
                case BufferFormat.R10G10B10A2_UInt:
                case BufferFormat.R10G10B10_XR_BIAS_A2_UIntNormal:
                {
                    var srcPtr  = (uint *)src;
                    var destPtr = (uint *)dest;

                    for (int i = 0; i < size; i += 4)
                    {
                        // If not in-place copy, then copy from the source.
                        if (src != dest)
                        {
                            *destPtr = (*srcPtr) & 0x3FFFFFFF;
                            srcPtr++;
                        }
                        *destPtr |= 0xC0000000;
                        destPtr++;
                    }
                }
                    return;

                case BufferFormat.R8G8B8A8:
                case BufferFormat.R8G8B8A8_UIntNormal:
                case BufferFormat.R8G8B8A8_UIntNormal_sRGB:
                case BufferFormat.R8G8B8A8_UInt:
                case BufferFormat.R8G8B8A8_IntNormal:
                case BufferFormat.R8G8B8A8_Int:
                case BufferFormat.B8G8R8A8_UIntNormal:
                case BufferFormat.B8G8R8A8:
                case BufferFormat.B8G8R8A8_UIntNormal_sRGB:
                {
                    uint alpha = ((format == BufferFormat.R8G8B8A8_Int) || (format == BufferFormat.R8G8B8A8_IntNormal)) ? 0x7F000000 : 0xFF000000;

                    var srcPtr  = (uint *)src;
                    var destPtr = (uint *)dest;

                    for (int i = 0; i < size; i += 4)
                    {
                        // If not in-place copy, then copy from the source.
                        if (src != dest)
                        {
                            *destPtr = (*srcPtr) & 0xFFFFFF;
                            srcPtr++;
                        }
                        *destPtr |= alpha;
                        destPtr++;
                    }
                }
                    return;

                case BufferFormat.B5G5R5A1_UIntNormal:
                {
                    var srcPtr  = (ushort *)src;
                    var destPtr = (ushort *)dest;

                    for (int i = 0; i < size; i += 2)
                    {
                        // If not in-place copy, then copy from the source.
                        if (src != dest)
                        {
                            *(destPtr++) = (ushort)((*srcPtr++) | 0x8000);
                        }
                        else
                        {
                            *(destPtr++) |= 0x8000;
                        }
                    }
                }
                    return;

                case BufferFormat.A8_UIntNormal:
                    DirectAccess.FillMemory(dest, 0xFF, size);
                    return;
                }
            }

            // Copy if not doing an in-place update.
            if (dest != src)
            {
                DirectAccess.MemoryCopy(dest, src, size);
            }
        }
Exemple #5
0
        /// <summary>
        /// Function to copy (or update in-place) with bits swizzled to match another format.
        /// </summary>
        /// <param name="src">The pointer to the source data.</param>
        /// <param name="srcPitch">The pitch of the source data.</param>
        /// <param name="dest">The pointer to the destination data.</param>
        /// <param name="destPitch">The pitch of the destination data.</param>
        /// <param name="format">Format of the destination buffer.</param>
        /// <param name="bitFlags">Image bit conversion control flags.</param>
        /// <exception cref="System.ArgumentException">Thrown when the <paramref name="format"/> parameter is Unknown.</exception>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="src"/> or the <paramref name="dest"/> parameter is NULL.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="srcPitch"/> or the <paramref name="destPitch"/> parameter is less than 0.</exception>
        /// <remarks>Use this method to copy a single scanline and swizzle the bits of an image and (optionally) set an opaque constant alpha value.</remarks>
        protected unsafe void SwizzleScanline(void *src, int srcPitch, void *dest, int destPitch, BufferFormat format, ImageBitFlags bitFlags)
        {
            int  size = srcPitch.Min(destPitch);
            uint r, g, b, a, pixel;

            if (src == null)
            {
                throw new ArgumentNullException("src");
            }

            if (dest == null)
            {
                throw new ArgumentNullException("dest");
            }

            if (format == BufferFormat.Unknown)
            {
                throw new ArgumentException(string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, BufferFormat.Unknown),
                                            "format");
            }

            var srcPtr  = (uint *)src;
            var destPtr = (uint *)dest;

            switch (format)
            {
            case BufferFormat.R10G10B10A2:
            case BufferFormat.R10G10B10A2_UInt:
            case BufferFormat.R10G10B10A2_UIntNormal:
            case BufferFormat.R10G10B10_XR_BIAS_A2_UIntNormal:
                for (int i = 0; i < size; i += 4)
                {
                    if (src != dest)
                    {
                        pixel = *(srcPtr++);
                    }
                    else
                    {
                        pixel = *(destPtr);
                    }

                    r = ((pixel & 0x3FF00000) >> 20);
                    g = (pixel & 0x000FFC00);
                    b = ((pixel & 0x000003FF) << 20);
                    a = ((bitFlags & ImageBitFlags.OpaqueAlpha) == ImageBitFlags.OpaqueAlpha) ? 0xC0000000 : pixel & 0xC0000000;

                    *destPtr = r | g | b | a;
                    destPtr++;
                }
                return;

            case BufferFormat.R8G8B8A8:
            case BufferFormat.R8G8B8A8_UIntNormal:
            case BufferFormat.R8G8B8A8_UIntNormal_sRGB:
            case BufferFormat.B8G8R8A8_UIntNormal:
            case BufferFormat.B8G8R8X8_UIntNormal:
            case BufferFormat.B8G8R8A8:
            case BufferFormat.B8G8R8A8_UIntNormal_sRGB:
            case BufferFormat.B8G8R8X8:
            case BufferFormat.B8G8R8X8_UIntNormal_sRGB:
                for (int i = 0; i < size; i += 4)
                {
                    if (src != dest)
                    {
                        pixel = *(srcPtr++);
                    }
                    else
                    {
                        pixel = *(destPtr);
                    }

                    r = ((pixel & 0xFF0000) >> 16);
                    g = (pixel & 0x00FF00);
                    b = ((pixel & 0x0000FF) << 16);
                    a = ((bitFlags & ImageBitFlags.OpaqueAlpha) == ImageBitFlags.OpaqueAlpha) ? 0xFF000000 : pixel & 0xFF000000;

                    *destPtr = r | g | b | a;
                    destPtr++;
                }
                return;
            }

            if (src != dest)
            {
                DirectAccess.MemoryCopy(dest, src, size);
            }
        }
Exemple #6
0
 /// <summary>
 /// Function to copy (or update in-place) with bits swizzled to match another format.
 /// </summary>
 /// <param name="src">The pointer to the source data.</param>
 /// <param name="srcPitch">The pitch of the source data.</param>
 /// <param name="dest">The pointer to the destination data.</param>
 /// <param name="destPitch">The pitch of the destination data.</param>
 /// <param name="format">Format of the destination buffer.</param>
 /// <param name="bitFlags">Image bit conversion control flags.</param>
 /// <exception cref="System.ArgumentException">Thrown when the <paramref name="format"/> parameter is Unknown.</exception>
 /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="src"/> or the <paramref name="dest"/> parameter is NULL.</exception>
 /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="srcPitch"/> or the <paramref name="destPitch"/> parameter is less than 0.</exception>
 /// <remarks>Use this method to copy a single scanline and swizzle the bits of an image and (optionally) set an opaque constant alpha value.</remarks>
 protected unsafe void SwizzleScanline(IntPtr src, int srcPitch, IntPtr dest, int destPitch, BufferFormat format, ImageBitFlags bitFlags)
 {
     SwizzleScanline(src.ToPointer(), srcPitch, dest.ToPointer(), destPitch, format, bitFlags);
 }
Exemple #7
0
        /// <summary>
        /// Function to expand a 16BPP scan line in an image to a 32BPP RGBA line.
        /// </summary>
        /// <param name="src">The pointer to the source data.</param>
        /// <param name="srcPitch">The pitch of the source data.</param>
        /// <param name="srcFormat">Format to convert from.</param>
        /// <param name="dest">The pointer to the destination data.</param>
        /// <param name="destPitch">The pitch of the destination data.</param>
        /// <param name="bitFlags">Image bit conversion control flags.</param>
        /// <exception cref="System.ArgumentException">Thrown when the <paramref name="srcFormat" /> is not a 16 BPP format.</exception>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="src"/> or the <paramref name="dest"/> parameter is NULL.</exception>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="srcPitch"/> or the <paramref name="destPitch"/> parameter is less than 0.</exception>
        /// <remarks>
        /// Use this to expand a 16 BPP (B5G6R5 or B5G5R5A1 format) into a 32 BPP R8G8B8A8 (normalized unsigned integer) format.
        /// </remarks>
        protected unsafe void Expand16BPPScanline(void *src, int srcPitch, BufferFormat srcFormat, void *dest, int destPitch, ImageBitFlags bitFlags)
        {
            var srcPtr  = (ushort *)src;
            var destPtr = (uint *)dest;

            if ((srcFormat != BufferFormat.B5G5R5A1_UIntNormal) && (srcFormat != BufferFormat.B5G6R5_UIntNormal))
            {
                throw new ArgumentException(string.Format(Resources.GORGFX_IMAGE_NOT_16BPP, srcFormat), "srcFormat");
            }

            if (src == null)
            {
                throw new ArgumentNullException("src");
            }

            if (dest == null)
            {
                throw new ArgumentNullException("dest");
            }

            for (int srcCount = 0, destCount = 0; ((srcCount < srcPitch) && (destCount < destPitch)); srcCount += 2, destCount += 4)
            {
                ushort srcPixel = *(srcPtr++);
                uint   R = 0, G = 0, B = 0, A = 0;

                switch (srcFormat)
                {
                case BufferFormat.B5G6R5_UIntNormal:
                    R = (uint)((srcPixel & 0xF800) >> 11);
                    G = (uint)((srcPixel & 0x07E0) >> 5);
                    B = (uint)(srcPixel & 0x001F);
                    R = ((R << 3) | (R >> 2));
                    G = ((G << 2) | (G >> 4)) << 8;
                    B = ((B << 3) | (B >> 2)) << 16;
                    A = 0xFF000000;
                    break;

                case BufferFormat.B5G5R5A1_UIntNormal:
                    R = (uint)((srcPixel & 0x7C00) >> 10);
                    G = (uint)((srcPixel & 0x03E0) >> 5);
                    B = (uint)(srcPixel & 0x001F);
                    R = ((R << 3) | (R >> 2));
                    G = ((G << 3) | (G >> 2)) << 8;
                    B = ((B << 3) | (B >> 2)) << 16;
                    A = ((bitFlags & ImageBitFlags.OpaqueAlpha) == ImageBitFlags.OpaqueAlpha)
                                                            ? 0xFF000000
                                                            : (((srcPixel & 0x8000) != 0) ? 0xFF000000 : 0);
                    break;
                }

                *(destPtr++) = R | G | B | A;
            }
        }
Exemple #8
0
 /// <summary>
 /// Function to expand a 16BPP line in an image to a 32BPP RGBA line.
 /// </summary>
 /// <param name="src">The pointer to the source data.</param>
 /// <param name="srcPitch">The pitch of the source data.</param>
 /// <param name="srcFormat">Format to convert from.</param>
 /// <param name="dest">The pointer to the destination data.</param>
 /// <param name="destPitch">The pitch of the destination data.</param>
 /// <param name="bitFlags">Image bit conversion control flags.</param>
 /// <exception cref="System.ArgumentException">Thrown when the <paramref name="srcFormat"/> is not a 16 BPP format.</exception>
 /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="src"/> or the <paramref name="dest"/> parameter is IntPtr.Zero.</exception>
 /// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="srcPitch"/> or the <paramref name="destPitch"/> parameter is less than 0.</exception>
 /// <remarks>Use this to expand a 16 BPP (B5G6R5 or B5G5R5A1 format) into a 32 BPP R8G8B8A8 (normalized unsigned integer) format.
 /// <para>This overload is for languages that don't support unsafe code (e.g. Visual Basic .NET).</para>
 /// </remarks>
 protected unsafe void Expand16BPPScanline(IntPtr src, int srcPitch, BufferFormat srcFormat, IntPtr dest, int destPitch, ImageBitFlags bitFlags)
 {
     Expand16BPPScanline(src.ToPointer(), srcPitch, srcFormat, dest.ToPointer(), destPitch, bitFlags);
 }