public DataType Extract(out object data) { byte[] bdata = ExtractData(); if (bdata == null || bdata.Length < 0) { data = null; return(DataType.None); } data = bdata; int index = 1; index += bdata[0]; if (index + 7 > bdata.Length) { return(DataType.Binary); } int length = BitConverter.ToInt32(bdata, index); index += 4; if (length < 0 || index + 3 + length > bdata.Length) { return(DataType.Binary); } string name = Encoding.ASCII.GetString(bdata, index, 3); index += 3; byte[] ndata = new byte[length]; for (int i = 0; i < length && index < bdata.Length; i++, index++) { ndata[i] = bdata[index]; } switch (name) { case "TXT": data = Encoding.UTF8.GetString(ndata); return(DataType.Text); case "BIN": data = ndata; return(DataType.Binary); case "IMG": System.Drawing.Image img; MemoryStream ms2 = new MemoryStream(ndata); //JPEG and GIF need the stream to be open for some reason, don't know if GC cleans up after MemoryStreams img = System.Drawing.Image.FromStream(ms2); data = img; //Must be disposed by caller return(DataType.Image); case "IDX": using (MemoryStream stream = new MemoryStream(ndata)) { LinkIndex lindex = new LinkIndex(); byte[] ibuffer = new byte[4], sbuffer = new byte[3]; do { if (stream.Read(ibuffer, 0, 4) < 4) { throw new PNGMaskException("IDX chunk is corrupt"); } uint len = BitConverter.ToUInt32(ibuffer, 0); if (stream.Read(sbuffer, 0, 3) < 3) { throw new PNGMaskException("IDX chunk is corrupt"); } string chunkname = Encoding.ASCII.GetString(sbuffer); byte[] dbuffer = new byte[len]; if (stream.Read(dbuffer, 0, (int)len) < (int)len) { throw new PNGMaskException("IDX chunk is corrupt"); } using (MemoryStream ms = new MemoryStream(dbuffer)) { if (chunkname == "IDI") { do { if (ms.Read(ibuffer, 0, 4) < 4) { throw new PNGMaskException("IDI chunk is corrupt"); } int clen = BitConverter.ToInt32(ibuffer, 0); byte[] imgbuffer = new byte[clen]; if (ms.Read(imgbuffer, 0, clen) < clen) { throw new PNGMaskException("IDI chunk is corrupt"); } using (MemoryStream imgstream = new MemoryStream(imgbuffer)) lindex.Images.Add(Image.FromStream(imgstream)); } while (ms.Position < ms.Length - 1); } else if (chunkname == "IDL") { do { if (ms.Read(ibuffer, 0, 4) < 4) { throw new PNGMaskException("IDL chunk is corrupt"); } int imgindex = BitConverter.ToInt32(ibuffer, 0); if (ms.Read(ibuffer, 0, 4) < 4) { throw new PNGMaskException("IDL chunk is corrupt"); } int slen = BitConverter.ToInt32(ibuffer, 0); byte[] strbuffer = new byte[slen]; if (ms.Read(strbuffer, 0, slen) < slen) { throw new PNGMaskException("IDL chunk is corrupt"); } string title = Encoding.UTF8.GetString(strbuffer); if (ms.Read(ibuffer, 0, 4) < 4) { throw new PNGMaskException("IDL chunk is corrupt"); } slen = BitConverter.ToInt32(ibuffer, 0); strbuffer = new byte[slen]; if (ms.Read(strbuffer, 0, slen) < slen) { throw new PNGMaskException("IDL chunk is corrupt"); } string url = Encoding.UTF8.GetString(strbuffer); lindex.Rows.Add(new LinkIndexRow(imgindex, title, url)); } while (ms.Position < ms.Length - 1); } } } while (stream.Position < stream.Length - 1); data = lindex; } return(DataType.Index); default: return(DataType.Binary); } return(DataType.Binary); }
public void Imprint(DataType type, object obj) { List <byte> temp = new List <byte>(); int igarbage = rnd.Next(0x10, 0xFF); temp.Add((byte)igarbage); byte[] garbage = new byte[igarbage]; rnd.NextBytes(garbage); temp.AddRange(garbage); byte[] data; switch (type) { case DataType.Text: data = Encoding.UTF8.GetBytes((string)obj); temp.AddRange(BitConverter.GetBytes(data.Length)); temp.AddRange(HEADER_TXT); temp.AddRange(data); break; case DataType.Binary: data = (byte[])obj; temp.AddRange(BitConverter.GetBytes(data.Length)); temp.AddRange(HEADER_BIN); temp.AddRange(data); break; case DataType.ImageBytes: data = (byte[])obj; temp.AddRange(BitConverter.GetBytes(data.Length)); temp.AddRange(HEADER_IMG); temp.AddRange(data); break; case DataType.Image: using (MemoryStream stream = new MemoryStream()) { ((System.Drawing.Image)obj).Save(stream, System.Drawing.Imaging.ImageFormat.Png); data = stream.ToArray(); } temp.AddRange(BitConverter.GetBytes(data.Length)); temp.AddRange(HEADER_IMG); temp.AddRange(data); break; case DataType.Index: LinkIndex index = (LinkIndex)obj; byte[] buffer; using (MemoryStream stream = new MemoryStream()) { /* Image array serialization */ using (MemoryStream imgliststream = new MemoryStream()) { foreach (Image img in index.Images) { using (MemoryStream imgstream = new MemoryStream()) { img.Save(imgstream, System.Drawing.Imaging.ImageFormat.Png); buffer = BitConverter.GetBytes((int)imgstream.Length); imgliststream.Write(buffer, 0, buffer.Length); buffer = imgstream.ToArray(); imgliststream.Write(buffer, 0, buffer.Length); } } if (imgliststream.Length > 0) { buffer = BitConverter.GetBytes((int)imgliststream.Length); stream.Write(buffer, 0, buffer.Length); stream.Write(HEADER_IDI, 0, HEADER_IDI.Length); buffer = imgliststream.ToArray(); stream.Write(buffer, 0, buffer.Length); } } /* Link item array serialization */ using (MemoryStream linkliststream = new MemoryStream()) { foreach (LinkIndexRow row in index.Rows) { //Image index (4b integer) buffer = BitConverter.GetBytes(row.ImageIndex); linkliststream.Write(buffer, 0, buffer.Length); //Title (4b integer (string length), < string) byte[] charbuffer = Encoding.UTF8.GetBytes(row.Title); buffer = BitConverter.GetBytes(charbuffer.Length); linkliststream.Write(buffer, 0, buffer.Length); linkliststream.Write(charbuffer, 0, charbuffer.Length); //Title (4b integer (string length), < string) charbuffer = Encoding.UTF8.GetBytes(row.URL); buffer = BitConverter.GetBytes(charbuffer.Length); linkliststream.Write(buffer, 0, buffer.Length); linkliststream.Write(charbuffer, 0, charbuffer.Length); } buffer = BitConverter.GetBytes((int)linkliststream.Length); stream.Write(buffer, 0, buffer.Length); stream.Write(HEADER_IDL, 0, HEADER_IDL.Length); buffer = linkliststream.ToArray(); stream.Write(buffer, 0, buffer.Length); } data = stream.ToArray(); } temp.AddRange(BitConverter.GetBytes(data.Length)); temp.AddRange(HEADER_IDX); temp.AddRange(data); break; default: throw new NotImplementedException(); } data = temp.ToArray(); temp = null; ImprintData(data); }
public DataType Extract(out object data) { byte[] bdata = ExtractData(); if (bdata == null || bdata.Length < 0) { data = null; return DataType.None; } data = bdata; int index = 1; index += bdata[0]; if (index + 7 > bdata.Length) return DataType.Binary; int length = BitConverter.ToInt32(bdata, index); index += 4; if (length < 0 || index + 3 + length > bdata.Length) return DataType.Binary; string name = Encoding.ASCII.GetString(bdata, index, 3); index += 3; byte[] ndata = new byte[length]; for (int i = 0; i < length && index < bdata.Length; i++, index++) ndata[i] = bdata[index]; switch (name) { case "TXT": data = Encoding.UTF8.GetString(ndata); return DataType.Text; case "BIN": data = ndata; return DataType.Binary; case "IMG": System.Drawing.Image img; MemoryStream ms2 = new MemoryStream(ndata); //JPEG and GIF need the stream to be open for some reason, don't know if GC cleans up after MemoryStreams img = System.Drawing.Image.FromStream(ms2); data = img; //Must be disposed by caller return DataType.Image; case "IDX": using (MemoryStream stream = new MemoryStream(ndata)) { LinkIndex lindex = new LinkIndex(); byte[] ibuffer = new byte[4], sbuffer = new byte[3]; do { if (stream.Read(ibuffer, 0, 4) < 4) throw new PNGMaskException("IDX chunk is corrupt"); uint len = BitConverter.ToUInt32(ibuffer, 0); if (stream.Read(sbuffer, 0, 3) < 3) throw new PNGMaskException("IDX chunk is corrupt"); string chunkname = Encoding.ASCII.GetString(sbuffer); byte[] dbuffer = new byte[len]; if (stream.Read(dbuffer, 0, (int)len) < (int)len) throw new PNGMaskException("IDX chunk is corrupt"); using (MemoryStream ms = new MemoryStream(dbuffer)) { if (chunkname == "IDI") { do { if (ms.Read(ibuffer, 0, 4) < 4) throw new PNGMaskException("IDI chunk is corrupt"); int clen = BitConverter.ToInt32(ibuffer, 0); byte[] imgbuffer = new byte[clen]; if (ms.Read(imgbuffer, 0, clen) < clen) throw new PNGMaskException("IDI chunk is corrupt"); using (MemoryStream imgstream = new MemoryStream(imgbuffer)) lindex.Images.Add(Image.FromStream(imgstream)); } while (ms.Position < ms.Length - 1); } else if (chunkname == "IDL") { do { if (ms.Read(ibuffer, 0, 4) < 4) throw new PNGMaskException("IDL chunk is corrupt"); int imgindex = BitConverter.ToInt32(ibuffer, 0); if (ms.Read(ibuffer, 0, 4) < 4) throw new PNGMaskException("IDL chunk is corrupt"); int slen = BitConverter.ToInt32(ibuffer, 0); byte[] strbuffer = new byte[slen]; if (ms.Read(strbuffer, 0, slen) < slen) throw new PNGMaskException("IDL chunk is corrupt"); string title = Encoding.UTF8.GetString(strbuffer); if (ms.Read(ibuffer, 0, 4) < 4) throw new PNGMaskException("IDL chunk is corrupt"); slen = BitConverter.ToInt32(ibuffer, 0); strbuffer = new byte[slen]; if (ms.Read(strbuffer, 0, slen) < slen) throw new PNGMaskException("IDL chunk is corrupt"); string url = Encoding.UTF8.GetString(strbuffer); lindex.Rows.Add(new LinkIndexRow(imgindex, title, url)); } while (ms.Position < ms.Length - 1); } } } while (stream.Position < stream.Length - 1); data = lindex; } return DataType.Index; default: return DataType.Binary; } return DataType.Binary; }