/// <summary> /// Writes to an unmanaged stream. /// </summary> protected unsafe int Write(FreeImageIO io, fi_handle handle, uint size, uint count, ref byte[] buffer) { fixed(byte *ptr = buffer) { return((int)io.writeProc(new IntPtr(ptr), size, count, handle)); } }
// Saving function protected override bool SaveProc(ref FreeImageIO io, FIBITMAP dib, fi_handle handle, int page, int flags, IntPtr data) { SerialDib sdib; uint size = FreeImage.GetDIBSize(dib); // Store all data needed to recreate the bitmap sdib.width = FreeImage.GetWidth(dib); sdib.height = FreeImage.GetHeight(dib); sdib.pitch = (int)FreeImage.GetPitch(dib); sdib.bpp = FreeImage.GetBPP(dib); sdib.red_mask = FreeImage.GetRedMask(dib); sdib.green_mask = FreeImage.GetGreenMask(dib); sdib.blue_mask = FreeImage.GetBlueMask(dib); sdib.data = new byte[size]; // Copy the bitmaps data into the structures byte-array // The marshaller is used to create an IntPtr for using // 'ConvertToRawBits'. FreeImage.ConvertToRawBits(Marshal.UnsafeAddrOfPinnedArrayElement(sdib.data, 0), dib, sdib.pitch, sdib.bpp, sdib.red_mask, sdib.green_mask, sdib.blue_mask, false); // Use the healper function to write the header to the destination if (Write(io, handle, (uint)header.Length, 1, ref header) != 1) { return(false); } // Create a serializer BinaryFormatter formatter = new BinaryFormatter(); // Create a temporary stream MemoryStream stream = new MemoryStream(); // Create a compression stream GZipStream zipStream = new GZipStream(stream, CompressionMode.Compress); // Serialize the structure into the compression stream formatter.Serialize(zipStream, sdib); // Unload the compression stream zipStream.Dispose(); // Get the result data byte[] buffer = stream.GetBuffer(); // Use the healper function 'Write' to write the data to the destination if (Write(io, handle, 1, (uint)buffer.Length, ref buffer) != buffer.Length) { // Unload the temporary stream stream.Dispose(); return(false); } // Unload the temporary stream stream.Dispose(); return(true); }
// Loading function protected override FIBITMAP LoadProc(ref FreeImageIO io, fi_handle handle, int page, int flags, IntPtr data) { // Check if the data has the correct format if (!ValidateProc(ref io, handle)) { // Create a free-image message FreeImage.OutputMessageProc(format, "Invalid format."); // return 0 (operation failed) return(FIBITMAP.Zero); } SerialDib sdib; int read = 0; System.IO.MemoryStream stream = new System.IO.MemoryStream(); byte[] buffer = new byte[1024]; do { // Use the helper function 'Read' to read from the source read = Read(io, handle, 1, 1024, ref buffer); // Store the data in a temporary buffer stream.Write(buffer, 0, read); }while (read != 0); // Set the memory stream back to the beginning. stream.Position = 0; // Unzip the stream GZipStream zipStream = new GZipStream(stream, CompressionMode.Decompress); // Create a serializer BinaryFormatter formatter = new BinaryFormatter(); // Deserialize the stream sdib = (SerialDib)formatter.Deserialize(zipStream); // Unload the stream zipStream.Dispose(); // Use 'ConvertFromRawBits and the deserialized struct to recreate the bitmap // In this case the marshaller is used to create the needed IntPtr to the data // array. FIBITMAP dib = FreeImage.ConvertFromRawBits( Marshal.UnsafeAddrOfPinnedArrayElement(sdib.data, 0), (int)sdib.width, (int)sdib.height, sdib.pitch, sdib.bpp, sdib.red_mask, sdib.green_mask, sdib.blue_mask, false); // Unload the temporary stream stream.Dispose(); // Return the created bitmap return(dib); }
// The function reads the first bytes of the file and compares it // with the predefined header. protected override bool ValidateProc(ref FreeImageIO io, fi_handle handle) { for (int i = 0; i < header.Length; i++) { if (ReadByte(io, handle) != header[i]) { return(false); } } return(true); }
/// <summary> /// Function that can be implemented. /// </summary> protected virtual bool ValidateProc(ref FreeImageIO io, fi_handle handle) { return(false); }
/// <summary> /// Function that can be implemented. /// </summary> protected virtual bool SaveProc(ref FreeImageIO io, FIBITMAP dib, fi_handle handle, int page, int flags, IntPtr data) { return(false); }
/// <summary> /// Function that can be implemented. /// </summary> protected virtual FIBITMAP LoadProc(ref FreeImageIO io, fi_handle handle, int page, int flags, IntPtr data) { return(FIBITMAP.Zero); }
/// <summary> /// Function that can be implemented. /// </summary> protected virtual int PageCapabilityProc(ref FreeImageIO io, fi_handle handle, IntPtr data) { return(0); }
/// <summary> /// Function that can be implemented. /// </summary> protected virtual void CloseProc(ref FreeImageIO io, fi_handle handle, IntPtr data) { }
/// <summary> /// Function that can be implemented. /// </summary> protected virtual IntPtr OpenProc(ref FreeImageIO io, fi_handle handle, bool read) { return(IntPtr.Zero); }
/// <summary> /// Retrieves the position of an unmanaged stream. /// </summary> protected int Tell(FreeImageIO io, fi_handle handle) { return(io.tellProc(handle)); }
/// <summary> /// Seeks in an unmanaged stream. /// </summary> protected int Seek(FreeImageIO io, fi_handle handle, int offset, SeekOrigin origin) { return(io.seekProc(handle, offset, origin)); }
/// <summary> /// Writes a single byte to an unmanaged stream. /// </summary> protected unsafe int WriteByte(FreeImageIO io, fi_handle handle, byte value) { return((int)io.writeProc(new IntPtr(&value), 1, 1, handle)); }
/// <summary> /// Reads a single byte from an unmanaged stream. /// </summary> protected unsafe int ReadByte(FreeImageIO io, fi_handle handle) { byte buffer = 0; return((int)io.readProc(new IntPtr(&buffer), 1, 1, handle) > 0 ? buffer : -1); }
public void FreeImageStreamIO() { Random rand = new Random(); byte[] bBuffer = new byte[256]; IntPtr buffer = Marshal.AllocHGlobal(256); MemoryStream stream = new MemoryStream(); Assert.IsNotNull(stream); using (fi_handle handle = new fi_handle(stream)) { FreeImageIO io = FreeImageAPI.IO.FreeImageStreamIO.io; Assert.IsNotNull(io.readProc); Assert.IsNotNull(io.writeProc); Assert.IsNotNull(io.seekProc); Assert.IsNotNull(io.tellProc); // // Procs // rand.NextBytes(bBuffer); stream.Write(bBuffer, 0, bBuffer.Length); Assert.That(io.tellProc(handle) == stream.Position); Assert.That(io.seekProc(handle, 0, SeekOrigin.Begin) == 0); Assert.That(io.tellProc(handle) == 0); Assert.That(io.tellProc(handle) == stream.Position); // Read one block Assert.That(io.readProc(buffer, (uint)bBuffer.Length, 1, handle) == 1); for (int i = 0; i < bBuffer.Length; i++) { Assert.That(Marshal.ReadByte(buffer, i) == bBuffer[i]); } Assert.That(io.tellProc(handle) == stream.Position); Assert.That(io.seekProc(handle, 0, SeekOrigin.Begin) == 0); Assert.That(io.tellProc(handle) == stream.Position); // Read 1 byte block Assert.That(io.readProc(buffer, 1, (uint)bBuffer.Length, handle) == bBuffer.Length); for (int i = 0; i < bBuffer.Length; i++) { Assert.That(Marshal.ReadByte(buffer, i) == bBuffer[i]); } Assert.That(io.tellProc(handle) == stream.Position); Assert.That(io.seekProc(handle, 0, SeekOrigin.Begin) == 0); Assert.That(io.tellProc(handle) == stream.Position); rand.NextBytes(bBuffer); for (int i = 0; i < bBuffer.Length; i++) { Marshal.WriteByte(buffer, i, bBuffer[i]); } // Write one block Assert.That(io.writeProc(buffer, (uint)bBuffer.Length, 1, handle) == 1); for (int i = 0; i < bBuffer.Length; i++) { Assert.That(Marshal.ReadByte(buffer, i) == bBuffer[i]); } Assert.That(io.tellProc(handle) == stream.Position); Assert.That(io.seekProc(handle, 0, SeekOrigin.Begin) == 0); Assert.That(io.tellProc(handle) == 0); // write 1 byte block Assert.That(io.writeProc(buffer, 1, (uint)bBuffer.Length, handle) == bBuffer.Length); for (int i = 0; i < bBuffer.Length; i++) { Assert.That(Marshal.ReadByte(buffer, i) == bBuffer[i]); } Assert.That(io.tellProc(handle) == stream.Position); // Seek and tell Assert.That(io.seekProc(handle, 0, SeekOrigin.Begin) == 0); Assert.That(io.tellProc(handle) == 0); Assert.That(io.seekProc(handle, 127, SeekOrigin.Current) == 0); Assert.That(io.tellProc(handle) == 127); Assert.That(io.seekProc(handle, 0, SeekOrigin.End) == 0); Assert.That(io.tellProc(handle) == 256); Marshal.FreeHGlobal(buffer); stream.Dispose(); } }