示例#1
0
        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());
        }
示例#2
0
        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();
        }