internal static Result TryGetColorContexts(ColorContextsProvider getColorContexts, ImagingFactory imagingFactory, out ColorContext[] colorContexts) { colorContexts = null; int count; Result result = getColorContexts(0, null, out count); if (result.Success) { colorContexts = new ColorContext[count]; if (count > 0) { // http://msdn.microsoft.com/en-us/library/windows/desktop/ee690135(v=vs.85).aspx // The ppIColorContexts array must be filled with valid data: each IWICColorContext* in the array must // have been created using IWICImagingFactory::CreateColorContext. for (int i = 0; i < count; i++) colorContexts[i] = new ColorContext(imagingFactory); int actualCount; getColorContexts(count, colorContexts, out actualCount); Debug.Assert(count == actualCount); } } return result; }
/// <summary>Tries the get color contexts.</summary> /// <param name="getColorContexts">The get color contexts.</param> /// <param name="imagingFactory">The imaging factory.</param> /// <param name="colorContexts">The color contexts.</param> /// <returns>Result.</returns> internal static Result TryGetColorContexts(ColorContextsProvider getColorContexts, ImagingFactory imagingFactory, out ColorContext[] colorContexts) { colorContexts = null; int count; Result result = getColorContexts(0, null, out count); if (result.Success) { colorContexts = new ColorContext[count]; if (count > 0) { // http://msdn.microsoft.com/en-us/library/windows/desktop/ee690135(v=vs.85).aspx // The ppIColorContexts array must be filled with valid data: each IWICColorContext* in the array must // have been created using IWICImagingFactory::CreateColorContext. for (int i = 0; i < count; i++) { colorContexts[i] = new ColorContext(imagingFactory); } int actualCount; getColorContexts(count, colorContexts, out actualCount); Debug.Assert(count == actualCount); } } return(result); }
/// <summary> /// Get the <see cref="ColorContext"/> of the image (if any) /// </summary> /// <param name="imagingFactory">The factory for creating new color contexts</param> /// <param name="colorContexts">The color context array, or null</param> /// <remarks> /// When the image format does not support color contexts, /// <see cref="ResultCode.UnsupportedOperation"/> is returned. /// </remarks> /// <unmanaged>HRESULT IWICBitmapDecoder::GetColorContexts([In] unsigned int cCount,[Out, Buffer, Optional] IWICColorContext** ppIColorContexts,[Out] unsigned int* pcActualCount)</unmanaged> public Result TryGetColorContexts(ImagingFactory imagingFactory, out ColorContext[] colorContexts) { return ColorContextsHelper.TryGetColorContexts(GetColorContexts, imagingFactory, out colorContexts); }
/// <summary> /// Function to perform conversion/transformation of a bitmap. /// </summary> /// <param name="sourceData">WIC bitmap to transform.</param> /// <param name="destData">Destination data buffer.</param> /// <param name="rowPitch">Number of bytes per row in the image.</param> /// <param name="slicePitch">Number of bytes in total for the image.</param> /// <param name="destFormat">Destination format for transformation.</param> /// <param name="isSourcesRGB">TRUE if the source format is sRGB.</param> /// <param name="isDestsRGB">TRUE if the destination format is sRGB.</param> /// <param name="dither">Dithering to apply to images that get converted to a lower bit depth.</param> /// <param name="destRect">Rectangle containing the area to scale or clip</param> /// <param name="clip">TRUE to perform clipping instead of scaling.</param> /// <param name="scaleFilter">Filter to apply to scaled data.</param> public void TransformImageData(WIC.BitmapSource sourceData, IntPtr destData, int rowPitch, int slicePitch, Guid destFormat, bool isSourcesRGB, bool isDestsRGB, ImageDithering dither, Rectangle destRect, bool clip, ImageFilter scaleFilter) { WIC.BitmapSource source = sourceData; WIC.FormatConverter converter = null; WIC.BitmapClipper clipper = null; WIC.BitmapScaler scaler = null; WIC.ColorContext sourceContext = null; WIC.ColorContext destContext = null; WIC.ColorTransform sRGBTransform = null; try { if (destFormat != Guid.Empty) { if (sourceData.PixelFormat != destFormat) { converter = new WIC.FormatConverter(Factory); if (!converter.CanConvert(sourceData.PixelFormat, destFormat)) { throw new GorgonException(GorgonResult.FormatNotSupported, string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, destFormat)); } converter.Initialize(source, destFormat, (WIC.BitmapDitherType)dither, null, 0, WIC.BitmapPaletteType.Custom); source = converter; } if ((isDestsRGB) || (isSourcesRGB)) { sRGBTransform = new WIC.ColorTransform(Factory); sourceContext = new WIC.ColorContext(Factory); destContext = new WIC.ColorContext(Factory); sourceContext.InitializeFromExifColorSpace(isSourcesRGB ? 1 : 2); destContext.InitializeFromExifColorSpace(isDestsRGB ? 1 : 2); sRGBTransform.Initialize(source, sourceContext, destContext, destFormat); source = sRGBTransform; } } if (destRect.IsEmpty) { source.CopyPixels(rowPitch, destData, slicePitch); return; } Guid pixelFormat = source.PixelFormat; if (!clip) { scaler = new WIC.BitmapScaler(Factory); scaler.Initialize(source, destRect.Width, destRect.Height, (WIC.BitmapInterpolationMode)scaleFilter); source = scaler; } else { destRect.Width = destRect.Width.Min(source.Size.Width); destRect.Height = destRect.Height.Min(source.Size.Height); if ((destRect.Width < source.Size.Width) || (destRect.Height < source.Size.Height)) { clipper = new WIC.BitmapClipper(Factory); clipper.Initialize(source, new DX.Rectangle(destRect.X, destRect.Y, destRect.Width, destRect.Height)); source = clipper; destRect.X = 0; destRect.Y = 0; } } // We have a change of format (probably due to the filter when scaling)... so we need to convert. if (source.PixelFormat != pixelFormat) { converter = new WIC.FormatConverter(Factory); if (!converter.CanConvert(source.PixelFormat, pixelFormat)) { throw new GorgonException(GorgonResult.FormatNotSupported, string.Format(Resources.GORGFX_FORMAT_NOT_SUPPORTED, pixelFormat)); } converter.Initialize(source, pixelFormat, WIC.BitmapDitherType.None, null, 0, WIC.BitmapPaletteType.Custom); source = converter; } source.CopyPixels(rowPitch, destData, slicePitch); } finally { if (converter != null) { converter.Dispose(); } if (sourceContext != null) { sourceContext.Dispose(); } if (destContext != null) { destContext.Dispose(); } if (sRGBTransform != null) { sRGBTransform.Dispose(); } if (scaler != null) { scaler.Dispose(); } if (clipper != null) { clipper.Dispose(); } } }