using System; using System.Runtime.InteropServices; using System.Text; namespace NetVips; /// /// An input connection. /// public partial class Source : Connection { /// /// Secret ref for . /// private GCHandle _dataHandle; /// internal Source(nint pointer) : base(pointer) { } /// /// Make a new source from a file descriptor (a small integer). /// /// /// Make a new source that is attached to the descriptor. For example: /// /// using var source = Source.NewFromDescriptor(0); /// /// Makes a descriptor attached to stdin. /// /// You can pass this source to (for example) . /// /// Read from this file descriptor. /// A new . /// If unable to create a new from . public static Source NewFromDescriptor(int descriptor) { var pointer = Internal.VipsSource.NewFromDescriptor(descriptor); if (pointer == IntPtr.Zero) { throw new VipsException($"can't create source from descriptor {descriptor}"); } return new Source(pointer); } /// /// Make a new source from a filename. /// /// /// Make a new source that is attached to the named file. For example: /// /// using var source = Source.NewFromFile("myfile.jpg"); /// /// You can pass this source to (for example) . /// /// Read from this filename. /// A new . /// If unable to create a new from . public static Source NewFromFile(string filename) { var bytes = Encoding.UTF8.GetBytes(filename + char.MinValue); // Ensure null-terminated string var pointer = Internal.VipsSource.NewFromFile(bytes); if (pointer == IntPtr.Zero) { throw new VipsException($"can't create source from filename {filename}"); } return new Source(pointer); } /// /// Make a new source from a memory object. /// /// /// Make a new source that is attached to the memory object. For example: /// /// using var source = Source.NewFromMemory(data); /// /// You can pass this source to (for example) . /// /// The memory object. /// A new . /// If unable to create a new from . public static Source NewFromMemory(byte[] data) { var handle = GCHandle.Alloc(data, GCHandleType.Pinned); var pointer = Internal.VipsSource.NewFromMemory(handle.AddrOfPinnedObject(), (nuint)data.Length); if (pointer == IntPtr.Zero) { if (handle.IsAllocated) { handle.Free(); } throw new VipsException("can't create input source from memory"); } return new Source(pointer) { _dataHandle = handle }; } /// /// Make a new source from a memory object. /// /// /// Make a new source that is attached to the memory object. For example: /// /// using var source = Source.NewFromMemory(data); /// /// You can pass this source to (for example) . /// /// The memory object. /// A new . /// If unable to create a new from . public static Source NewFromMemory(string data) => NewFromMemory(Encoding.UTF8.GetBytes(data)); /// /// Make a new source from a memory object. /// /// /// Make a new source that is attached to the memory object. For example: /// /// using var source = Source.NewFromMemory(data); /// /// You can pass this source to (for example) . /// /// The memory object. /// A new . /// If unable to create a new from . public static Source NewFromMemory(char[] data) => NewFromMemory(Encoding.UTF8.GetBytes(data)); /// protected override void Dispose(bool disposing) { // release reference to our secret ref if (_dataHandle.IsAllocated) { _dataHandle.Free(); } // Call our base Dispose method base.Dispose(disposing); } }