Skip to content

Commit

Permalink
more disposables and tidying, bump version
Browse files Browse the repository at this point in the history
  • Loading branch information
saucecontrol committed Sep 4, 2018
1 parent f3b9457 commit e0b5550
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 61 deletions.
21 changes: 9 additions & 12 deletions src/MagicScaler/Core/PixelFormats.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System.Collections.ObjectModel;

using PhotoSauce.MagicScaler.Interop;
using System.Runtime.InteropServices;

namespace PhotoSauce.MagicScaler
{
Expand Down Expand Up @@ -258,15 +257,17 @@ static PixelFormat()
[Bgrx128BppLinearFloat.FormatGuid] = Bgrx128BppLinearFloat
};

uint fet = 10u;
var oar = new object[fet];
var cen = Wic.Factory.CreateComponentEnumerator(WICComponentType.WICPixelFormat, WICComponentEnumerateOptions.WICComponentEnumerateDefault);
uint count = 10u;
var formats = new object[count];

using (var cenum = new ComHandle<IEnumUnknown>(Wic.Factory.CreateComponentEnumerator(WICComponentType.WICPixelFormat, WICComponentEnumerateOptions.WICComponentEnumerateDefault)))
do
{
fet = cen.Next(fet, oar);
for (int i = 0; i < fet; i++)
count = cenum.ComObject.Next(count, formats);
for (int i = 0; i < count; i++)
using (var pixh = new ComHandle<IWICPixelFormatInfo2>(formats[i]))
{
var pix = oar[i] as IWICPixelFormatInfo2;
var pix = pixh.ComObject;
uint cch = pix.GetFriendlyName(0, null);
var sbn = new StringBuilder((int)cch);
pix.GetFriendlyName(cch, sbn);
Expand All @@ -289,16 +290,12 @@ static PixelFormat()
PixelAlphaRepresentation.None
};

Marshal.ReleaseComObject(pix);

if (fmt.ColorRepresentation == PixelColorRepresentation.Grey || fmt.ColorRepresentation == PixelColorRepresentation.Bgr || fmt.ColorRepresentation == PixelColorRepresentation.Rgb)
fmt.Colorspace = fmt.NumericRepresentation == PixelNumericRepresentation.Fixed || fmt.NumericRepresentation == PixelNumericRepresentation.Float ? PixelColorspace.scRgb : PixelColorspace.sRgb;

dic.Add(fmt.FormatGuid, fmt);
}
} while (fet > 0);

Marshal.ReleaseComObject(cen);
} while (count > 0);

Cache = new ReadOnlyDictionary<Guid, PixelFormat>(dic);
}
Expand Down
11 changes: 6 additions & 5 deletions src/MagicScaler/Interop/PropVariant.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

using System;
using System.Linq;
using System.Buffers;
using System.Collections;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
Expand Down Expand Up @@ -136,7 +137,7 @@ public bool Equals(PropVariant other)
if ((Value is Array) != (other.Value is Array))
return false;

if ((Value is Array))
if (Value is Array)
return ((IEnumerable)Value).Cast<object>().SequenceEqual(((IEnumerable)other.Value).Cast<object>());

return Equals(Value, other.Value);
Expand All @@ -145,9 +146,9 @@ public bool Equals(PropVariant other)
public static bool operator ==(PropVariant left, PropVariant right) => left?.Equals(right) ?? ReferenceEquals(left, right);
public static bool operator !=(PropVariant left, PropVariant right) => !(left == right);

public override bool Equals(object o) => Equals(o as PropVariant);
public override bool Equals(object o) => o is PropVariant other && Equals(other);
public override int GetHashCode() => Value?.GetHashCode() ?? 0;
public override string ToString() => $"{(UnmanagedType & ~VarEnum.VT_VECTOR)}: {(Value is Array ? string.Join(" ", (Array)Value) : Value)}";
public override string ToString() => $"{UnmanagedType & ~VarEnum.VT_VECTOR}: {(Value is Array ? string.Join(" ", (Array)Value) : Value)}";

internal sealed class Marshaler : ICustomMarshaler
{
Expand Down Expand Up @@ -244,8 +245,8 @@ unsafe public IntPtr MarshalManagedToNative(object o)
else
{
var gch = GCHandle.Alloc(a, GCHandleType.Pinned);
Unsafe.CopyBlockUnaligned(pNativeBuffer.ToPointer(), Marshal.UnsafeAddrOfPinnedArrayElement(a, 0).ToPointer(), (uint)bufflen);
gch.Free();
using (var mh = new MemoryHandle(Marshal.UnsafeAddrOfPinnedArrayElement(a, 0).ToPointer(), gch))
Unsafe.CopyBlock(pNativeBuffer.ToPointer(), mh.Pointer, (uint)bufflen);
}

var upv = new UnmanagedPropVariant { vt = unmanagedType };
Expand Down
2 changes: 2 additions & 0 deletions src/MagicScaler/Magic/PadTransform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ void IPixelTransformInternal.Init(WicProcessingContext ctx)
{
if (!padRect.IsEmpty)
{
MagicTransforms.AddExternalFormatConverter(ctx);

var innerRect = new Rectangle(padRect.Left, padRect.Top, (int)ctx.Source.Width, (int)ctx.Source.Height);
var outerRect = Rectangle.FromLTRB(0, 0, innerRect.Right + padRect.Right, innerRect.Bottom + padRect.Bottom);
ctx.Source = new PadTransformInternal(ctx.Source, padColor, innerRect, outerRect);
Expand Down
6 changes: 3 additions & 3 deletions src/MagicScaler/MagicScaler.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
<Features>strict</Features>
<VersionPrefix>0.9.0</VersionPrefix>
<VersionPrefix>0.9.1</VersionPrefix>
<Authors>Clinton Ingram</Authors>
<Company>PhotoSauce</Company>
<Product>MagicScaler</Product>
<Copyright>Copyright © 2015-2018 Clinton Ingram</Copyright>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/saucecontrol/PhotoSauce</RepositoryUrl>
<PackageIconUrl>http://photosauce.net/icon64x64.png</PackageIconUrl>
<PackageProjectUrl>http://photosauce.net/</PackageProjectUrl>
<PackageIconUrl>https://photosauce.net/icon64x64.png</PackageIconUrl>
<PackageProjectUrl>https://photosauce.net/</PackageProjectUrl>
<PackageLicenseUrl>https://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
<PackageReleaseNotes>See https://github.com/saucecontrol/PhotoSauce/releases</PackageReleaseNotes>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
Expand Down
24 changes: 24 additions & 0 deletions src/MagicScaler/Utilities/ComHandle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Runtime.InteropServices;

namespace PhotoSauce.MagicScaler.Interop
{
internal readonly struct ComHandle<T> : IDisposable where T : class
{
public T ComObject { get; }

public ComHandle(object obj)
{
if (!Marshal.IsComObject(obj)) throw new ArgumentException("Must be a COM object", nameof(obj));
if (!(obj is T com)) throw new ArgumentException("Interface not supported: " + typeof(T).Name, nameof(obj));

ComObject = com;
}

public void Dispose()
{
if (!(ComObject is null) && Marshal.IsComObject(ComObject))
Marshal.ReleaseComObject(ComObject);
}
}
}
13 changes: 3 additions & 10 deletions src/MagicScaler/Utilities/StreamAsIStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,10 @@ private class StreamAsIStream : IStream
{
private readonly Stream stream;

internal StreamAsIStream(Stream backingStream)
{
internal StreamAsIStream(Stream backingStream) =>
stream = backingStream ?? throw new ArgumentNullException(nameof(backingStream));
}

void IStream.Read(byte[] pv, int cb, IntPtr pcbRead)
{
Marshal.WriteInt32(pcbRead, stream.Read(pv, 0, cb));
}
void IStream.Read(byte[] pv, int cb, IntPtr pcbRead) => Marshal.WriteInt32(pcbRead, stream.Read(pv, 0, cb));

void IStream.Write(byte[] pv, int cb, IntPtr pcbWritten)
{
Expand All @@ -38,10 +33,8 @@ void IStream.Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition)
Marshal.WriteInt64(plibNewPosition, pos);
}

void IStream.Stat(out STATSTG pstatstg, int grfStatFlag)
{
void IStream.Stat(out STATSTG pstatstg, int grfStatFlag) =>
pstatstg = new STATSTG { cbSize = stream.Length, type = 2 /*STGTY_STREAM*/ };
}

void IStream.SetSize(long libNewSize) => stream.SetLength(libNewSize);

Expand Down
23 changes: 9 additions & 14 deletions src/MagicScaler/Utilities/WinCodecExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,26 @@ internal static class Wic
{
private static IWICColorContext getDefaultColorContext(Guid pixelFormat)
{
var pfi = Factory.CreateComponentInfo(pixelFormat) as IWICPixelFormatInfo;
var cc = pfi.GetColorContext();
Marshal.ReleaseComObject(pfi);

return cc;
using (var pfi = new ComHandle<IWICPixelFormatInfo>(Factory.CreateComponentInfo(pixelFormat)))
return pfi.ComObject.GetColorContext();
}

private static IWICColorContext getResourceColorContext(string name)
{
string resName = nameof(PhotoSauce) + "." + nameof(MagicScaler) + ".Resources." + name;
var asm = typeof(IWICColorContext).GetTypeInfo().Assembly;
using (var stm = asm.GetManifestResourceStream(resName))
using (var stm = typeof(Wic).GetTypeInfo().Assembly.GetManifestResourceStream(resName))
using (var buff = MemoryPool<byte>.Shared.Rent((int)stm.Length))
{
var cc = Factory.CreateColorContext();

byte[] prof = ArrayPool<byte>.Shared.Rent((int)stm.Length);
stm.Read(prof, 0, (int)stm.Length);
cc.InitializeFromMemory(prof, (uint)stm.Length);
ArrayPool<byte>.Shared.Return(prof);
MemoryMarshal.TryGetArray(buff.Memory.Slice(0, (int)stm.Length), out ArraySegment<byte> cca);
stm.Read(cca.Array, cca.Offset, cca.Count);

var cc = Factory.CreateColorContext();
cc.InitializeFromMemory(cca.Array, (uint)cca.Count);
return cc;
}
}

public static readonly IWICImagingFactory Factory = new WICImagingFactory2() as IWICImagingFactory;
public static readonly IWICImagingFactory Factory = new WICImagingFactory2() as IWICImagingFactory ?? throw new PlatformNotSupportedException();

public static readonly Lazy<IWICColorContext> CmykContext = new Lazy<IWICColorContext>(() => getDefaultColorContext(Consts.GUID_WICPixelFormat32bppCMYK));
public static readonly Lazy<IWICColorContext> SrgbContext = new Lazy<IWICColorContext>(() => getResourceColorContext("sRGB-v4.icc"));
Expand Down
36 changes: 19 additions & 17 deletions src/MagicScaler/WIC/WicTransforms.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,28 +150,30 @@ public static void AddMetadataReader(WicProcessingContext ctx, bool basicOnly =
var cct = cc.GetType();
if (cct == WICColorContextType.WICColorContextProfile)
{
uint ccs = cc.GetProfileBytes(0, null);
int ccs = (int)cc.GetProfileBytes(0, null);

// don't try to read giant profiles. 4MiB is more than enough
if (ccs > (1024 * 1024 * 4))
if ((uint)ccs > (1024 * 1024 * 4))
continue;

var ccb = ArrayPool<byte>.Shared.Rent((int)ccs);
cc.GetProfileBytes(ccs, ccb);
var cpi = ColorProfile.Cache.GetOrAdd(new ArraySegment<byte>(ccb, 0, (int)ccs));
ArrayPool<byte>.Shared.Return(ccb);

// match only color profiles that match our intended use. if we have a standard sRGB profile, don't save it; we don't need to convert
if (cpi.IsValid && (
(cpi.DataColorSpace == ColorProfile.ProfileColorSpace.Rgb && (fmt.ColorRepresentation == PixelColorRepresentation.Bgr || fmt.ColorRepresentation == PixelColorRepresentation.Rgb) && !cpi.IsSrgb)
|| (cpi.DataColorSpace == ColorProfile.ProfileColorSpace.Grey && fmt.ColorRepresentation == PixelColorRepresentation.Grey && !cpi.IsSrgbCurve)
|| (cpi.DataColorSpace == ColorProfile.ProfileColorSpace.Cmyk && fmt.ColorRepresentation == PixelColorRepresentation.Cmyk)
))
using (var ccb = MemoryPool<byte>.Shared.Rent(ccs))
{
profile = cc;
if (cpi.IsRgbMatrix || cpi.IsGreyTrc)
ctx.SourceColorProfile = cpi;
break;
MemoryMarshal.TryGetArray(ccb.Memory.Slice(0, ccs), out ArraySegment<byte> cca);
cc.GetProfileBytes((uint)cca.Count, cca.Array);
var cpi = ColorProfile.Cache.GetOrAdd(cca);

// match only color profiles that match our intended use. if we have a standard sRGB profile, don't save it; we don't need to convert
if (cpi.IsValid && (
(cpi.DataColorSpace == ColorProfile.ProfileColorSpace.Rgb && (fmt.ColorRepresentation == PixelColorRepresentation.Bgr || fmt.ColorRepresentation == PixelColorRepresentation.Rgb) && !cpi.IsSrgb)
|| (cpi.DataColorSpace == ColorProfile.ProfileColorSpace.Grey && fmt.ColorRepresentation == PixelColorRepresentation.Grey && !cpi.IsSrgbCurve)
|| (cpi.DataColorSpace == ColorProfile.ProfileColorSpace.Cmyk && fmt.ColorRepresentation == PixelColorRepresentation.Cmyk)
))
{
profile = cc;
if (cpi.IsRgbMatrix || cpi.IsGreyTrc)
ctx.SourceColorProfile = cpi;
break;
}
}
}
else if (cct == WICColorContextType.WICColorContextExifColorSpace && cc.GetExifColorSpace() == ExifColorSpace.AdobeRGB)
Expand Down

0 comments on commit e0b5550

Please sign in to comment.