You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
223 lines
6.0 KiB
223 lines
6.0 KiB
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();
|
|
}
|
|
}
|
|
}
|