private ImageListStreamer (SerializationInfo info, StreamingContext context)
{
byte [] data = (byte []) info.GetValue ("Data", typeof (byte []));
if (data == null || data.Length <= 4) { // 4 is the signature
return;
}
// check the signature ( 'MSFt' )
if (data [0] != 77 || data [1] != 83 || data [2] != 70 || data [3] != 116) {
return;
}
MemoryStream decoded = GetDecodedStream (data, 4, data.Length - 4);
decoded.Position = 4; // jumps over 'magic' and 'version', which are 16-bits each
BinaryReader reader = new BinaryReader (decoded);
ushort nimages = reader.ReadUInt16 ();
reader.ReadUInt16 (); // cMaxImage
ushort grow = reader.ReadUInt16 (); // cGrow
ushort cx = reader.ReadUInt16 ();
ushort cy = reader.ReadUInt16 ();
uint bkcolor = reader.ReadUInt32 ();
back_color = Color.FromArgb ((int) bkcolor);
reader.ReadUInt16 (); // flags
short [] ovls = new short [4];
for (int i = 0; i < 4; i++) {
ovls[i] = reader.ReadInt16 ();
}
byte [] decoded_buffer = decoded.GetBuffer ();
int bmp_offset = 28;
// FileSize field from the bitmap file header
int filesize = decoded_buffer [bmp_offset + 2] + (decoded_buffer [bmp_offset + 3] << 8) +
(decoded_buffer [bmp_offset + 4] << 16) + (decoded_buffer [bmp_offset + 5] << 24);
// ImageSize field from the info header (can be 0)
int imagesize = decoded_buffer [bmp_offset + 34] + (decoded_buffer [bmp_offset + 35] << 8) +
(decoded_buffer [bmp_offset + 36] << 16) + (decoded_buffer [bmp_offset + 37] << 24);
int bmp_length = imagesize + filesize;
MemoryStream bmpms = new MemoryStream (decoded_buffer, bmp_offset, bmp_length);
Bitmap bmp = null;
Bitmap mask = null;
bmp = new Bitmap (bmpms);
MemoryStream mask_stream = new MemoryStream (decoded_buffer,
bmp_offset + bmp_length,
(int) (decoded.Length - bmp_offset - bmp_length));
if (mask_stream.Length > 0)
mask = new Bitmap (mask_stream);
if (bkcolor == 0xFFFFFFFF)
back_color = bmp.GetPixel (0, 0);
if (mask != null) {
int width = bmp.Width;
int height = bmp.Height;
Bitmap newbmp = new Bitmap (bmp);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Color mcolor = mask.GetPixel (x, y);
if (mcolor.B != 0) {
newbmp.SetPixel (x, y, Color.Transparent);
}
}
}
bmp.Dispose ();
bmp = newbmp;
mask.Dispose ();
mask = null;
}
images = new Image [nimages];
image_size = new Size (cx, cy);
Rectangle dest_rect = new Rectangle (0, 0, cx, cy);
if (grow * bmp.Width > cx) // Some images store a wrong 'grow' factor
grow = (ushort) (bmp.Width / cx);
for (int r = 0 ; r < nimages ; r++) {
int col = r % grow;
int row = r / grow;
Rectangle area = new Rectangle (col * cx, row * cy, cx, cy);
Bitmap b = new Bitmap (cx, cy);
using (Graphics g = Graphics.FromImage (b)) {
g.DrawImage (bmp, dest_rect, area, GraphicsUnit.Pixel);
}
images [r] = b;
}
bmp.Dispose ();
}