public void WriteSource(PipelineContext ctx, PixelArea area = default) { var wicFrame = WicEncoderFrame; var wicRect = area.ToWicRect(); if (ctx.PlanarContext is not null) { var oformat = GUID_WICPixelFormat24bppBGR; HRESULT.Check(wicFrame->SetPixelFormat(&oformat)); using var gchY = new WeakGCHandle(ctx.PlanarContext.SourceY); using var gchCb = new WeakGCHandle(ctx.PlanarContext.SourceCb); using var gchCr = new WeakGCHandle(ctx.PlanarContext.SourceCr); var srcY = new IWICBitmapSourceImpl(gchY.Handle); var srcCb = new IWICBitmapSourceImpl(gchCb.Handle); var srcCr = new IWICBitmapSourceImpl(gchCr.Handle); var planes = stackalloc[] {&srcY, &srcCb, &srcCr }; using var pframe = default(ComPtr <IWICPlanarBitmapFrameEncode>); HRESULT.Check(wicFrame->QueryInterface(__uuidof <IWICPlanarBitmapFrameEncode>(), (void **)pframe.GetAddressOf())); HRESULT.Check(pframe.Get()->WriteSource((IWICBitmapSource **)planes, 3, area.IsEmpty ? null : &wicRect)); } else { var oformat = ctx.Source.Format.FormatGuid; HRESULT.Check(wicFrame->SetPixelFormat(&oformat)); if (oformat != ctx.Source.Format.FormatGuid) { var ptt = WICBitmapPaletteType.WICBitmapPaletteTypeCustom; using var pal = default(ComPtr <IWICPalette>); if (PixelFormat.FromGuid(oformat).NumericRepresentation == PixelNumericRepresentation.Indexed) { HRESULT.Check(Wic.Factory->CreatePalette(pal.GetAddressOf())); HRESULT.Check(pal.Get()->InitializePredefined(WICBitmapPaletteType.WICBitmapPaletteTypeFixedGray256, 0)); ptt = WICBitmapPaletteType.WICBitmapPaletteTypeFixedGray256; HRESULT.Check(wicFrame->SetPalette(pal)); } using var conv = default(ComPtr <IWICFormatConverter>); HRESULT.Check(Wic.Factory->CreateFormatConverter(conv.GetAddressOf())); HRESULT.Check(conv.Get()->Initialize(ctx.Source.AsIWICBitmapSource(ctx), &oformat, WICBitmapDitherType.WICBitmapDitherTypeNone, pal, 0.0, ptt)); ctx.Source = ctx.AddDispose(new ComPtr <IWICBitmapSource>((IWICBitmapSource *)conv.Get()).AsPixelSource(null, $"{nameof(IWICFormatConverter)}: {ctx.Source.Format.Name}->{PixelFormat.FromGuid(oformat).Name}", false)); } else if (oformat == PixelFormat.Indexed8Bpp.FormatGuid) { Debug.Assert(ctx.WicContext.DestPalette is not null); HRESULT.Check(wicFrame->SetPalette(ctx.WicContext.DestPalette)); } using var gch = new WeakGCHandle(ctx.Source); var src = new IWICBitmapSourceImpl(gch.Handle); HRESULT.Check(wicFrame->WriteSource((IWICBitmapSource *)&src, area.IsEmpty ? null : &wicRect)); } HRESULT.Check(wicFrame->Commit()); }
public void WriteSource(PipelineContext ctx, PixelArea area = default) { var wicFrame = WicEncoderFrame; var wicRect = area.ToWicRect(); if (ctx.PlanarContext is not null) { var oformat = Consts.GUID_WICPixelFormat24bppBGR; wicFrame.SetPixelFormat(ref oformat); var planes = ArrayPool <IWICBitmapSource> .Shared.Rent(3); planes[0] = ctx.PlanarContext.SourceY.AsIWICBitmapSource(); planes[1] = ctx.PlanarContext.SourceCb.AsIWICBitmapSource(); planes[2] = ctx.PlanarContext.SourceCr.AsIWICBitmapSource(); ((IWICPlanarBitmapFrameEncode)wicFrame).WriteSource(planes, 3, area.IsEmpty ? ref WICRect.Null : ref wicRect); ArrayPool <IWICBitmapSource> .Shared.Return(planes); } else { var oformat = ctx.Source.Format.FormatGuid; wicFrame.SetPixelFormat(ref oformat); if (oformat != ctx.Source.Format.FormatGuid) { var pal = default(IWICPalette); var ptt = WICBitmapPaletteType.WICBitmapPaletteTypeCustom; if (PixelFormat.FromGuid(oformat).NumericRepresentation == PixelNumericRepresentation.Indexed) { pal = ctx.WicContext.AddRef(Wic.Factory.CreatePalette()); pal.InitializePredefined(WICBitmapPaletteType.WICBitmapPaletteTypeFixedGray256, false); ptt = WICBitmapPaletteType.WICBitmapPaletteTypeFixedGray256; wicFrame.SetPalette(pal); } var conv = ctx.WicContext.AddRef(Wic.Factory.CreateFormatConverter()); conv.Initialize(ctx.Source.AsIWICBitmapSource(), oformat, WICBitmapDitherType.WICBitmapDitherTypeNone, pal, 0.0, ptt); ctx.Source = conv.AsPixelSource($"{nameof(IWICFormatConverter)}: {ctx.Source.Format.Name}->{PixelFormat.FromGuid(oformat).Name}", false); } else if (oformat == PixelFormat.Indexed8Bpp.FormatGuid) { Debug.Assert(ctx.WicContext.DestPalette is not null); wicFrame.SetPalette(ctx.WicContext.DestPalette); } wicFrame.WriteSource(ctx.Source.AsIWICBitmapSource(), area.IsEmpty ? ref WICRect.Null : ref wicRect); } wicFrame.Commit(); }