blob: a8ef7d5f432f119f8914e5258fe0dc5a0e132977 [file] [log] [blame]
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.IO.Compression;
using FreeImageAPI;
using FreeImageAPI.IO;
using FreeImageAPI.Plugins;
namespace Sample08
{
public sealed class SerializationPlugin : LocalPlugin
{
// Header for the file
private byte[] header = new byte[] { 0xff, 0x12, 0x0f, 0xff, 0x01, 0x00 };
// Structure that will store all bitmap data.
[Serializable]
private struct SerialDib
{
public uint width;
public uint height;
public int pitch;
public uint bpp;
public uint red_mask;
public uint green_mask;
public uint blue_mask;
public byte[] data;
}
// Implementation of 'GetImplementedMethods()'
// All implemented methods are listed.
protected override LocalPlugin.MethodFlags GetImplementedMethods()
{
return
MethodFlags.DescriptionProc |
MethodFlags.SupportsExportBPPProc |
MethodFlags.SupportsExportTypeProc |
MethodFlags.SupportsICCProfilesProc |
MethodFlags.LoadProc |
MethodFlags.SaveProc |
MethodFlags.ValidateProc |
MethodFlags.ExtensionListProc;
}
// Returns a format string.
protected override string FormatProc()
{
return "Serialization";
}
// Returns a more specific description
protected override string DescriptionProc()
{
return "Serializes bitmaps for .NET";
}
// Returns whether a color depth is supported.
protected override bool SupportsExportBPPProc(int bpp)
{
return ((bpp == 1) ||
(bpp == 4) ||
(bpp == 8) ||
(bpp == 16) ||
(bpp == 24) ||
(bpp == 32));
}
// This plugin can only export standard bitmaps
protected override bool SupportsExportTypeProc(FREE_IMAGE_TYPE type)
{
return (type == FREE_IMAGE_TYPE.FIT_BITMAP);
}
// This plugin does not support icc profiles
protected override bool SupportsICCProfilesProc()
{
return false;
}
// 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;
}
// 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;
}
// 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;
}
// Return a list of supported file extensions (comma seperated)
protected override string ExtensionListProc()
{
return "ser";
}
// Implementation of 'ToString()'
public override string ToString()
{
return DescriptionProc();
}
}
}