123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404 |
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.IO;
- using System.Collections;
- namespace FastReport.Export.BIFF8
- {
- internal class BIFF8_MSODrawingRecord
- {
- Byte btWin32;
- Byte btMacOS;
- Byte[] uid;
- UInt16 tag;
- UInt32 size;
- UInt32 ref_count;
- UInt32 file_offset;
- Byte usage;
- Byte cbName;
- UInt16 picture_type;
- UInt16 blip_packed;
- // Byte[] UID0;
- Byte[] pic;
- Byte image_tag;
- ushort packed_options;
- internal void AddReference() { ref_count++; }
- internal void Read(StreamHelper stream, ushort packed_options)
- {
- btWin32 = (Byte)stream.ReadByte();
- btMacOS = (Byte)stream.ReadByte();
- uid = stream.ReadBytes(16);
- tag = stream.ReadUshort();
- size = stream.ReadUint();
- ref_count = stream.ReadUint();
- file_offset = stream.ReadUint();
- usage = (Byte)stream.ReadByte();
- cbName = (Byte)stream.ReadByte();
- stream.SkipBytes(2);
- this.packed_options = packed_options;
- }
- internal void Read_Picture(StreamHelper stream, UInt16 blip_packed, UInt16 type, int picture_size)
- {
- // picture_size = (int)blip_record_size - 17;
- Byte[] UID0;
- UID0 = stream.ReadBytes(16);
- //// Byte[] UID1 = ReadBytes(16);
- image_tag = (Byte)stream.ReadByte();
- pic = stream.ReadBytes(picture_size);
- this.picture_type = type;
- this.blip_packed = blip_packed;
- //FileStream f = new FileStream(@"C:\Users\alman\Documents\pict.png", FileMode.Create);
- //f.Write(pic, 0, pic.Length);
- //f.Close();
- }
- internal uint Write_Picture(StreamHelper stream)
- {
- uint payload_size = (uint)(uid.Length + 1 + pic.Length);
- stream.WriteUshort(this.blip_packed); // 0x6e00
- stream.WriteUshort(this.picture_type); // PNG = 0xf01e
- stream.WriteUint(payload_size);
- stream.WriteBytes(uid);
- //// stream.WriteBytes(UID1);
- stream.WriteByte(image_tag);
- stream.WriteBytes(pic);
- //FileStream f = new FileStream(@"C:\Users\alman\Documents\pict.png", FileMode.Create);
- //f.Write(pic, 0, pic.Length);
- //f.Close();
- return payload_size + 8;
- }
- internal void Write(StreamHelper stream)
- {
- stream.WriteUshort(packed_options); // 0x0052
- stream.WriteUshort(0xf007); // BSE
- long bse_size_position = stream.Position;
- stream.WriteUint(0x0000);
- stream.WriteByte(btWin32);
- stream.WriteByte(btMacOS);
- stream.WriteBytes(uid);
- stream.WriteUshort(tag);
- stream.WriteUint(size);
- stream.WriteUint(ref_count);
- stream.WriteUint(file_offset);
- stream.WriteByte(usage);
- stream.WriteByte(cbName);
- stream.SkipBytes(2);
- uint blip_size = Write_Picture(stream);
- long current_position = stream.Position;
- blip_size += 36;
- stream.Position = bse_size_position;
- stream.WriteUint((UInt32)blip_size);
- stream.Position = current_position;
- }
- internal void LoadPicture(FastReport.Export.ExportIEMObject Obj, int index)
- {
- btWin32 = 6; // PNG
- btMacOS = 6; // PNG
- uid = new byte[16];
- tag = 0xff;
- size = (uint)(8 + 16 + 1 + Obj.PictureStream.Length);
- ref_count = 1;
- file_offset = 0;
- usage = 0;
- cbName = 0;
- pic = new byte[Obj.PictureStream.Length];
- Obj.PictureStream.Position = 0;
- Obj.PictureStream.Read(pic, 0, (int)Obj.PictureStream.Length);
- // Take midddle bytes as hash
- int idx = pic.Length / 2;
- for (int i = 0; i < 16; i++)
- uid[i] = pic[i + idx];
- uid[0] = (byte)index;
- uid[15] = (byte)(index >> 4);
- picture_type = 0xf01e;
- blip_packed = 0x6e00;
- image_tag = 0xff;
- packed_options = 0x62;
- }
- }
- class BIFF8_MSODrawingGroup : ArrayList
- {
- UInt32 mso_spid;
- UInt32 cidcl;
- UInt32 cspSaved;
- UInt32 cdgSaved;
- ArrayList prop_list = new ArrayList();
- UInt32 fillColor;
- UInt32 lineColor;
- UInt32 shadowColor;
- UInt32 threeDColor;
- private void Read_BstoreContainer(StreamHelper stream, UInt32 loop_record_size)
- {
- BIFF8_MSODrawingRecord local_record = new BIFF8_MSODrawingRecord();
- while (loop_record_size > 0)
- {
- UInt16 blip_packed_data = stream.ReadUshort();
- UInt16 blip_fbt = stream.ReadUshort();
- UInt32 blip_record_size = stream.ReadUint();
- // Get BLIP data
- switch (blip_fbt)
- {
- case 0xf007: // msofbtBSE
- local_record = new BIFF8_MSODrawingRecord();
- local_record.Read(stream, blip_packed_data);
- this.Add(local_record);
- loop_record_size -= 36 /*blip_record_size*/;
- break;
- case 0xf01e: // PNG
- case 0xf01d: // JPEG
- local_record.Read_Picture(stream, blip_packed_data, blip_fbt, (int)blip_record_size - 17);
- loop_record_size -= blip_record_size;
- break;
- default:
- throw new Exception("BLIP not parsed yet");
- }
- loop_record_size -= 8; //HEADER SIZE
- }
- }
- internal int Read(StreamHelper stream, int RecordSize)
- {
- long stored_position = stream.Position;
- UInt16 packed_data = stream.ReadUshort();
- UInt16 fbt = stream.ReadUshort();
- UInt32 total_record_size = stream.ReadUint();
- RecordSize -= sizeof(UInt16) + sizeof(UInt16) + sizeof(UInt32);
- if (RecordSize > total_record_size)
- {
- throw new Exception("MSODRAWINGGROUP: Data layout error");
- }
- if (RecordSize < total_record_size)
- {
- StreamHelper virtual_stream = new StreamHelper();
- int tail = (int)total_record_size;
- do
- {
- byte[] record = stream.ReadBytes(RecordSize);
- virtual_stream.WriteBytes(record);
- //stream.Position += RecordSize;
- tail -= RecordSize;
- if (tail == 0) break;
- UInt16 RecordID = stream.ReadUshort();
- if (RecordID != 0x0003c && RecordID != 0x000eb) // CONTINUE record
- {
- throw new Exception("MSODRAWINGGROUP: Data layout error");
- }
- RecordSize = stream.ReadUshort();
- }
- while (tail > 0);
- RecordSize = (int)(stream.Position - stored_position);
- stream = virtual_stream;
- stream.Position = 0;
- }
- else
- {
- RecordSize += sizeof(UInt16) + sizeof(UInt16) + sizeof(UInt32);
- }
- while (total_record_size > 0)
- {
- UInt16 dgg_packed_data = stream.ReadUshort();
- UInt16 dgg_fbt = stream.ReadUshort();
- UInt32 dgg_record_size = stream.ReadUint();
- long shift = stream.Position - stored_position;
- switch (dgg_fbt)
- {
- case 0xf001: // msofbtBstoreContainer
- this.Read_BstoreContainer(stream, dgg_record_size);
- break;
- case 0xf006: // msofbtDgg
- mso_spid = stream.ReadUint();
- cidcl = stream.ReadUint();
- cspSaved = stream.ReadUint();
- cdgSaved = stream.ReadUint();
- for (int cid_idx = 1; cid_idx < cidcl; cid_idx++)
- {
- UInt32 dgid = stream.ReadUint();
- UInt32 cspidCur = stream.ReadUint();
- }
- break;
- case 0xf00b: // msofbtOPT
- UInt32 local_size = dgg_record_size;
- while (local_size > 0)
- {
- BIFF8_ShapeProp prop = new BIFF8_ShapeProp();
- UInt32 prop_size = prop.ReadProperty(stream);
- prop_list.Add(prop);
- local_size -= prop_size;
- }
- foreach (BIFF8_ShapeProp prop in prop_list)
- {
- prop.ReadPayload(stream);
- }
- break;
- case 0xf11e: // msofbtSplitMenuColors
- fillColor = stream.ReadUint();
- lineColor = stream.ReadUint();
- shadowColor = stream.ReadUint();
- threeDColor = stream.ReadUint();
- break;
- default:
- stream.SkipBytes((int)dgg_record_size);
- break;
- }
- total_record_size -= 8 + dgg_record_size;
- }
- return RecordSize;
- }
- internal void Write(StreamHelper stream)
- {
- StreamHelper helper_stream = new StreamHelper();
- this.mso_spid = 1026;
- this.cidcl = 2;
- this.cspSaved = 2;
- this.cdgSaved = (uint)this.Count;
- prop_list.Add(new BIFF8_ShapeProp(191, 0x00080008));
- prop_list.Add(new BIFF8_ShapeProp(385, 0x08000041));
- prop_list.Add(new BIFF8_ShapeProp(448, 0x08000040));
- helper_stream.WriteUshort(0x000f);
- helper_stream.WriteUshort(0xf000); // msofbtDggContainer
- long dgg_container_size_position = helper_stream.Position;
- helper_stream.WriteUint(0); // fix me
- helper_stream.WriteUshort(0x0000);
- helper_stream.WriteUshort(0xf006); // msofbtDgg
- uint dgg_record_size = 16 + (cidcl - 1) * 8;
- helper_stream.WriteUint(dgg_record_size); // dgg_record_size
- helper_stream.WriteUint(mso_spid);
- helper_stream.WriteUint(cidcl);
- helper_stream.WriteUint(cspSaved);
- helper_stream.WriteUint(cdgSaved);
- for (int cid_idx = 1; cid_idx < cidcl; cid_idx++)
- {
- UInt32 dgid = 1; // fix me
- UInt32 cspidCur = 2; // fix me
- helper_stream.WriteUint(dgid);
- helper_stream.WriteUint(cspidCur);
- }
- helper_stream.WriteUshort((ushort)(0x000f | (this.Count << 4)));
- helper_stream.WriteUshort(0xf001); // msofbtBstoreContainer
- long bstore_size_position = helper_stream.Position;
- helper_stream.WriteUint(0x0000);
- foreach (BIFF8_MSODrawingRecord record in this)
- {
- record.Write(helper_stream);
- }
- long current_stream_position = helper_stream.Position;
- helper_stream.Position = bstore_size_position;
- bstore_size_position = current_stream_position - bstore_size_position - 4;
- helper_stream.WriteUint((uint)bstore_size_position);
- helper_stream.Position = current_stream_position;
- helper_stream.WriteUshort(0x0033);
- helper_stream.WriteUshort(0xf00b); // msofbtOPT
- long opt_size_position = helper_stream.Position;
- helper_stream.WriteUint(0x0000);
- foreach (BIFF8_ShapeProp prop in prop_list) prop.WriteProperty(helper_stream);
- foreach (BIFF8_ShapeProp prop in prop_list) prop.WritePayload(helper_stream);
- // Fix options size
- long curr_position = helper_stream.Position;
- helper_stream.Position = opt_size_position;
- opt_size_position = curr_position - opt_size_position - sizeof(UInt32);
- helper_stream.WriteUint((ushort)opt_size_position);
- helper_stream.Position = curr_position;
- // skip SplitMenuColors
- helper_stream.WriteUshort(0x0040);
- helper_stream.WriteUshort(0xf11e); // msofbtSplitMenuColors
- helper_stream.WriteUint(16);
- helper_stream.WriteUint(fillColor);
- helper_stream.WriteUint(lineColor);
- helper_stream.WriteUint(shadowColor);
- helper_stream.WriteUint(threeDColor);
- long last_byte_position = helper_stream.Position;
- helper_stream.Position = dgg_container_size_position;
- dgg_container_size_position = last_byte_position - dgg_container_size_position - 4;
- helper_stream.WriteUint((uint)dgg_container_size_position);
- helper_stream.Position = 0;
- // Split huge temporary stream into records
- int iteration_trick = 0;
- int tail_size = (int)helper_stream.Length;
- ushort chunk_size;
- while (tail_size > 0)
- {
- ushort item_type = (ushort)((iteration_trick < 2) ? 0x00eb : 0x003c);
- stream.WriteUshort(item_type); // MSODRAWINGGROUP : CONTINUE
- chunk_size = (ushort)((tail_size <= 8224) ? tail_size : 8224);
- stream.WriteUshort(chunk_size);
- byte[] pictures = helper_stream.ReadBytes(chunk_size);
- stream.WriteBytes(pictures);
- tail_size -= chunk_size;
- iteration_trick++;
- }
- helper_stream.Dispose();
- helper_stream = null;
- }
- }
- }
|