/// <summary>Copies an <see cref="ArgbColor"/> into another, with forced opaque alpha.</summary> /// <param name="destination">The destination color.</param> /// <param name="source">The source color.</param> internal static unsafe void CopyWithAlpha(ArgbColor *destination, ArgbColor *source, byte alpha) { destination->B = source->B; destination->G = source->G; destination->R = source->R; destination->A = alpha; }
private unsafe void CopyToArgbAlpha1(SurfaceData surfaceData) { fixed(byte *dataPointer = data) fixed(ArgbColor * palettePointer = palette) { byte *destinationRowPointer = (byte *)surfaceData.DataPointer; byte *sourceColorPointer = dataPointer; byte *sourceAlphaPointer = dataPointer + Width * Height; byte alphaData = 0; byte alphaState = 0; for (int i = Height; i-- != 0; destinationRowPointer += surfaceData.Stride) { ArgbColor *destinationPointer = (ArgbColor *)destinationRowPointer; for (int j = Width; j-- != 0; alphaState--, alphaData >>= 1) { if (alphaState == 0) { alphaState = 8; alphaData = *sourceAlphaPointer++; } ArgbColor.CopyWithAlpha(destinationPointer++, palettePointer + *sourceColorPointer++, (alphaData & 1) != 0 ? (byte)255 : (byte)0); } } } }
/// <summary>Copies an <see cref="ArgbColor"/> into another, with forced opaque alpha.</summary> /// <param name="destination">The destination color.</param> /// <param name="source">The source color.</param> internal static unsafe void CopyOpaque(ArgbColor *destination, ArgbColor *source) { destination->B = source->B; destination->G = source->G; destination->R = source->R; destination->A = 255; }
public ArgbSurface(SurfaceData surfaceData, bool alphaPremultiplied = false) : base(surfaceData.Width, surfaceData.Height, 8, alphaPremultiplied) { int rowLength = sizeof(uint) * Width; int dataLength = rowLength * Height; if (surfaceData.Stride < rowLength) { throw new ArgumentException(); } data = new byte[dataLength]; unsafe { fixed(byte *dataPointer = data) { byte *destinationRowPointer = dataPointer; byte *sourceRowPointer = (byte *)surfaceData.DataPointer; for (int i = Height; i-- != 0; destinationRowPointer += rowLength, sourceRowPointer += surfaceData.Stride) { ArgbColor *destinationPointer = (ArgbColor *)destinationRowPointer; ArgbColor *sourcePointer = (ArgbColor *)sourceRowPointer; for (int j = Width; j-- != 0;) { *destinationPointer++ = *sourcePointer++; } } } } }
private unsafe void CopyToArgbAlpha4(SurfaceData surfaceData) { // Use a precalculated alpha table for very fast conversions. var alphaTable = stackalloc byte[16]; for (int i = 0; i < 16; i++) alphaTable[i] = (byte)(i * (255 * 2185) >> 15); // x / 15 = x * 2185 >> 15 (for 0 ≤ x ≤ 15 * 255) fixed(byte *dataPointer = data) fixed(ArgbColor * palettePointer = palette) { byte *destinationRowPointer = (byte *)surfaceData.DataPointer; byte *sourceColorPointer = dataPointer; byte *sourceAlphaPointer = dataPointer + Width * Height; byte alphaData = 0; bool alphaState = false; for (int i = Height; i-- != 0; destinationRowPointer += surfaceData.Stride) { ArgbColor *destinationPointer = (ArgbColor *)destinationRowPointer; for (int j = Width; j-- != 0;) { ArgbColor.CopyWithAlpha(destinationPointer++, palettePointer + *sourceColorPointer++, alphaTable[(alphaState = !alphaState) ? (alphaData = *sourceAlphaPointer++) & 0xF : alphaData >> 4]); } } } }
/// <summary>Merges two colors for DXT decompression.</summary> /// <param name="result">The storage to be used for the result.</param> /// <param name="color1">A color.</param> /// <param name="color2">A color.</param> internal static unsafe void DxtMergeHalves(ArgbColor *result, ArgbColor *color1, ArgbColor *color2) { result->B = (byte)((color1->B + color2->B) >> 1); result->G = (byte)((color1->G + color2->G) >> 1); result->R = (byte)((color1->R + color2->R) >> 1); result->A = 255; }
/// <summary>Merges two colors for DXT decompression.</summary> /// <param name="result">The storage to be used for the result.</param> /// <param name="minColor">The color whose weight will be 1/3.</param> /// <param name="maxColor">The color whose weight will be 2/3.</param> internal static unsafe void DxtMergeThirds(ArgbColor *result, ArgbColor *minColor, ArgbColor *maxColor) { // Formula used here: // x / 3 = x * 683 >> 11 (for 0 ≤ x ≤ 3 * 255) // Need to verify that this is indeed faster, but it'll do the work for now. result->B = (byte)((minColor->B + maxColor->B + maxColor->B) * 683 >> 11); result->G = (byte)((minColor->G + maxColor->G + maxColor->G) * 683 >> 11); result->R = (byte)((minColor->R + maxColor->R + maxColor->R) * 683 >> 11); result->A = 255; }
private unsafe void CopyToArgbAlpha8(SurfaceData surfaceData) { fixed(byte *dataPointer = data) fixed(ArgbColor * palettePointer = palette) { byte *destinationRowPointer = (byte *)surfaceData.DataPointer; byte *sourceColorPointer = dataPointer; byte *sourceAlphaPointer = dataPointer + Width * Height; for (int i = Height; i-- != 0; destinationRowPointer += surfaceData.Stride) { ArgbColor *destinationPointer = (ArgbColor *)destinationRowPointer; for (int j = Width; j-- != 0;) { ArgbColor.CopyWithAlpha(destinationPointer++, palettePointer + *sourceColorPointer++, *sourceAlphaPointer++); } } } }
private unsafe void CopyToArgbTransparent(SurfaceData surfaceData) { int rowLength = Width; fixed(byte *dataPointer = data) fixed(ArgbColor * palettePointer = palette) { byte *destinationRowPointer = (byte *)surfaceData.DataPointer; byte *sourcePointer = dataPointer; for (int i = Height; i-- != 0; destinationRowPointer += surfaceData.Stride) { ArgbColor *destinationPointer = (ArgbColor *)destinationRowPointer; for (int j = Width; j-- != 0;) { *destinationPointer++ = palettePointer[*sourcePointer++]; } } } }
protected unsafe override void CopyToArgbInternal(SurfaceData surfaceData) { int rowLength = sizeof(uint) * Width; fixed(byte *dataPointer = data) { byte *destinationRowPointer = (byte *)surfaceData.DataPointer; byte *sourceRowPointer = dataPointer; for (int i = Height; i-- != 0; destinationRowPointer += surfaceData.Stride, sourceRowPointer += rowLength) { ArgbColor *destinationPointer = (ArgbColor *)destinationRowPointer; ArgbColor *sourcePointer = (ArgbColor *)sourceRowPointer; for (int j = Width; j-- != 0;) { *destinationPointer++ = *sourcePointer++; } } } }