/// <summary> /// Renders the current instance as a raw Flac picture. /// </summary> /// <returns> /// A <see cref="ByteVector" /> object containing the /// rendered version of the current instance. /// </returns> public ByteVector Render() { ByteVector data = new ByteVector(); data.Add(ByteVector.FromUInt((uint)Type)); ByteVector mime_data = ByteVector.FromString(MimeType, StringType.Latin1); data.Add(ByteVector.FromUInt((uint)mime_data.Count)); data.Add(mime_data); ByteVector decription_data = ByteVector.FromString( Description, StringType.UTF8); data.Add(ByteVector.FromUInt((uint) decription_data.Count)); data.Add(decription_data); data.Add(ByteVector.FromUInt((uint)Width)); data.Add(ByteVector.FromUInt((uint)Height)); data.Add(ByteVector.FromUInt((uint)ColorDepth)); data.Add(ByteVector.FromUInt((uint)IndexedColors)); data.Add(ByteVector.FromUInt((uint)Data.Count)); data.Add(Data); return(data); }
public ByteVector Render(bool addFramingBit) { ByteVector data = new ByteVector(); ByteVector vendor_data = ByteVector.FromString(vendor_id, StringType.UTF8); data.Add(ByteVector.FromUInt((uint)vendor_data.Count, false)); data.Add(vendor_data); data.Add(ByteVector.FromUInt(FieldCount, false)); foreach (KeyValuePair <string, string[]> entry in field_list) { foreach (string value in entry.Value) { ByteVector field_data = ByteVector.FromString(entry.Key, StringType.UTF8); field_data.Add((byte)'='); field_data.Add(ByteVector.FromString(value, StringType.UTF8)); data.Add(ByteVector.FromUInt((uint)field_data.Count, false)); data.Add(field_data); } } if (addFramingBit) { data.Add((byte)1); } return(data); }
private ByteVector Render(bool isHeader) { ByteVector v = new ByteVector(); v.Add(FileIdentifier); v.Add(ByteVector.FromUInt(2000, false)); v.Add(ByteVector.FromUInt(tag_size, false)); v.Add(ByteVector.FromUInt(item_count, false)); uint flags = 0; if ((Flags & FooterFlags.HeaderPresent) != 0) { flags |= (uint)FooterFlags.HeaderPresent; } if (isHeader) { flags |= (uint)FooterFlags.IsHeader; } else { flags &= (uint)~FooterFlags.IsHeader; } v.Add(ByteVector.FromUInt(flags, false)); v.Add(ByteVector.FromULong(0)); return(v); }
/// <summary> /// Adds the data of a single entry to <paramref name="entry_data"/>. /// </summary> /// <param name="entry_data"> /// A <see cref="ByteVector"/> to add the entry to. /// </param> /// <param name="tag"> /// A <see cref="System.UInt16"/> with the tag of the entry. /// </param> /// <param name="type"> /// A <see cref="System.UInt16"/> with the type of the entry. /// </param> /// <param name="count"> /// A <see cref="System.UInt32"/> with the data count of the entry, /// </param> /// <param name="offset"> /// A <see cref="System.UInt32"/> with the offset field of the entry. /// </param> protected void RenderEntry(ByteVector entry_data, ushort tag, ushort type, uint count, uint offset) { entry_data.Add(ByteVector.FromUShort(tag, is_bigendian)); entry_data.Add(ByteVector.FromUShort(type, is_bigendian)); entry_data.Add(ByteVector.FromUInt(count, is_bigendian)); entry_data.Add(ByteVector.FromUInt(offset, is_bigendian)); }
/// <summary> /// Creates a list of Chunks containing the PNG keywords /// </summary> /// <returns> /// A <see cref="ByteVector"/> with the list of chunks, or /// or <see langword="null" /> if no PNG Keywords are contained. /// </returns> private ByteVector RenderKeywordChunks() { // Check, if PngTag is contained PngTag png_tag = GetTag(TagTypes.Png, true) as PngTag; if (png_tag == null) { return(null); } ByteVector chunks = new ByteVector(); foreach (KeyValuePair <string, string> keyword in png_tag) { ByteVector data = new ByteVector(); data.Add(keyword.Key); data.Add("\0"); data.Add(keyword.Value); chunks.Add(ByteVector.FromUInt((uint)data.Count)); chunks.Add(tEXt_CHUNK_TYPE); chunks.Add(data); chunks.Add(ComputeCRC(tEXt_CHUNK_TYPE, data)); } return(chunks); }
public ByteVector Render(byte version) { ByteVector data = new ByteVector(); ByteVector id = ConvertId(frame_id, version, true); if (id == null) { throw new NotImplementedException(); } switch (version) { case 2: data.Add(id); data.Add(ByteVector.FromUInt(frame_size).Mid(1, 3)); return(data); case 3: ushort new_flags = (ushort)((((ushort)flags << 1) & 0xE000) | (((ushort)flags << 4) & 0x00C0) | (((ushort)flags >> 1) & 0x0020)); data.Add(id); data.Add(ByteVector.FromUInt(frame_size)); data.Add(ByteVector.FromUShort(new_flags)); return(data); case 4: data.Add(id); data.Add(SynchData.FromUInt(frame_size)); data.Add(ByteVector.FromUShort((ushort)flags)); return(data); default: throw new NotImplementedException("Unsupported tag version."); } }
/// <summary> /// Renderes the current instance as a raw Flac block header. /// </summary> /// <param name="isLastBlock"> /// A <see cref="bool" /> value specifying whether or not the /// header is the last header of the file. /// </param> /// <returns> /// A <see cref="ByteVector" /> object containing the /// rendered header. /// </returns> public ByteVector Render(bool isLastBlock) { ByteVector data = ByteVector.FromUInt(block_size); data [0] = (byte)(block_type + (isLastBlock ? 0x80 : 0)); return(data); }
/// <summary> /// Renders the header represented by the current instance. /// </summary> /// <returns> /// A <see cref="ByteVector" /> object containing the /// rendered version of the current instance. /// </returns> public ByteVector Render() { // Enlarge for size if necessary. if ((header_size == 8 || header_size == 24) && box_size > uint.MaxValue) { header_size += 8; box_size += 8; } // Add the box size and type to the output. ByteVector output = ByteVector.FromUInt( (header_size == 8 || header_size == 24) ? (uint)box_size : 1); output.Add(box_type); // If the box size is 16 or 32, we must have more a // large header to append. if (header_size == 16 || header_size == 32) { output.Add(ByteVector.FromULong(box_size)); } // The only reason for such a big size is an extended // type. Extend!!! if (header_size >= 24) { output.Add(extended_type); } return(output); }
/// <summary> /// Renderes the current instance as a raw Flac block header. /// </summary> /// <param name="isLastBlock"> /// A <see cref="bool" /> value specifying whether or not the /// header is the last header of the file. /// </param> /// <returns> /// A <see cref="ByteVector" /> object containing the /// rendered header. /// </returns> public ByteVector Render(bool isLastBlock) { var data = ByteVector.FromUInt(BlockSize); data[0] = (byte)(BlockType + (isLastBlock ? 0x80 : 0)); return(data); }
private ByteVector RenderExifSegment() { IFDTag exif = ImageTag.Exif; if (exif == null) { return(null); } uint first_ifd_offset = 8; var renderer = new IFDRenderer(true, exif.Structure, first_ifd_offset); ByteVector exif_data = renderer.Render(); uint segment_size = (uint)(first_ifd_offset + exif_data.Count + 2 + 6); if (segment_size > ushort.MaxValue) { throw new Exception("Exif Segment is too big to render"); } ByteVector data = new ByteVector(new byte[] { 0xFF, (byte)Marker.APP1 }); data.Add(ByteVector.FromUShort((ushort)segment_size)); data.Add("Exif\0\0"); data.Add(ByteVector.FromString("MM", StringType.Latin1)); data.Add(ByteVector.FromUShort(42)); data.Add(ByteVector.FromUInt(first_ifd_offset)); data.Add(exif_data); return(data); }
/// <summary> /// Creates a list of Chunks containing the PNG keywords /// </summary> /// <returns> /// A <see cref="ByteVector"/> with the list of chunks, or /// or <see langword="null" /> if no PNG Keywords are contained. /// </returns> ByteVector RenderKeywordChunks() { // Check, if PngTag is contained if (!(GetTag(TagTypes.Png, true) is PngTag png_tag)) { return(null); } var chunks = new ByteVector(); foreach (KeyValuePair <string, string> keyword in png_tag) { var data = new ByteVector { keyword.Key, "\0", keyword.Value }; chunks.Add(ByteVector.FromUInt((uint)data.Count)); chunks.Add(tEXt_CHUNK_TYPE); chunks.Add(data); chunks.Add(ComputeCRC(tEXt_CHUNK_TYPE, data)); } return(chunks); }
public override ByteVector Render(bool is_bigendian, uint offset, out ushort type, out uint count) { ByteVector data = new ByteVector(); ByteVector offset_data = new ByteVector(); uint data_offset = offset + (uint)(4 * Values.Length); for (int i = 0; i < Values.Length; i++) { uint new_offset = (uint)(data_offset + data.Count); file.Seek(Values[i], SeekOrigin.Begin); data.Add(file.ReadBlock((int)byte_counts[i])); Values[i] = new_offset; offset_data.Add(ByteVector.FromUInt(new_offset, is_bigendian)); } if (Values.Length > 1) { data.Insert(0, offset_data); } else { Values[0] = offset; } while (data.Count < 4) { data.Add(0x00); } type = (ushort)IFDEntryType.Long; count = (uint)Values.Length; return(data); }
/// <summary> /// Renders the current instance to a <see cref="ByteVector"/> /// </summary> /// <param name="is_bigendian"> /// A <see cref="System.Boolean"/> indicating the endianess for rendering. /// </param> /// <param name="offset"> /// A <see cref="System.UInt32"/> with the offset, the data is stored. /// </param> /// <param name="type"> /// A <see cref="System.UInt16"/> the ID of the type, which is rendered /// </param> /// <param name="count"> /// A <see cref="System.UInt32"/> with the count of the values which are /// rendered. /// </param> /// <returns> /// A <see cref="ByteVector"/> with the rendered data. /// </returns> public ByteVector Render(bool is_bigendian, uint offset, out ushort type, out uint count) { type = (ushort)IFDEntryType.Long; count = 1; return(ByteVector.FromUInt(Value, is_bigendian)); }
public void UInt() { Assert.AreEqual(UInt32.MaxValue, ByteVector.FromUInt(UInt32.MaxValue).ToUInt()); Assert.AreEqual(UInt32.MinValue, ByteVector.FromUInt(UInt32.MinValue).ToUInt()); Assert.AreEqual(0, ByteVector.FromUInt(0).ToUInt()); Assert.AreEqual(30292, ByteVector.FromUInt(30292).ToUInt()); }
protected override ByteVector Render(ByteVector topData) { ByteVector output = new ByteVector((byte)version); output.Add(ByteVector.FromUInt(flags).Mid(1, 3)); output.Add(topData); return(base.Render(output)); }
/// <summary> /// Renders the current instance as an APEv2 item. /// </summary> /// <returns> /// A <see cref="ByteVector" /> object containing the /// rendered version of the current instance. /// </returns> public ByteVector Render() { var flags = (uint)(ReadOnly ? 1 : 0) | ((uint)Type << 1); if (IsEmpty) { return(new ByteVector()); } ByteVector result = null; if (Type == ItemType.Binary) { if (text == null && data != null) { result = data; } } if (result == null && text != null) { result = new ByteVector(); for (var i = 0; i < text.Length; i++) { if (i != 0) { result.Add(0); } result.Add(ByteVector.FromString( text[i], StringType.UTF8)); } } // If no data is stored, don't write the item. if (result == null || result.Count == 0) { return(new ByteVector()); } var output = new ByteVector { ByteVector.FromUInt((uint)result.Count, false), ByteVector.FromUInt(flags, false), ByteVector.FromString(Key, StringType.UTF8), 0, result }; Size = output.Count; return(output); }
/// <summary> /// Renders the current instance, including its children, to /// a new <see cref="ByteVector" /> object, preceeding the /// contents with a specified block of data. /// </summary> /// <param name="topData"> /// A <see cref="ByteVector" /> object containing box /// specific header data to preceed the content. /// </param> /// <returns> /// A <see cref="ByteVector" /> object containing the /// rendered version of the current instance. /// </returns> protected override ByteVector Render(ByteVector topData) { var output = new ByteVector(version) { ByteVector.FromUInt(Flags).Mid(1, 3), topData }; return(base.Render(output)); }
public ByteVector Render(bool is_bigendian, uint offset, out ushort type, out uint count) { type = (ushort)IFDEntryType.Rational; count = 1; ByteVector data = new ByteVector(); data.Add(ByteVector.FromUInt(Value.Numerator, is_bigendian)); data.Add(ByteVector.FromUInt(Value.Denominator, is_bigendian)); return(data); }
/// <summary> /// Renders the IFD to an ByteVector where the offset of the IFD /// itself is <paramref name="ifd_offset"/> and all offsets /// contained in the IFD are adjusted accroding it. /// </summary> /// <param name="directory"> /// A <see cref="IFDDirectory"/> with the directory to render. /// </param> /// <param name="ifd_offset"> /// A <see cref="System.UInt32"/> with the offset of the IFD /// </param> /// <param name="last"> /// A <see cref="System.Boolean"/> which is true, if the IFD is /// the last one, i.e. the offset to the next IFD, which is /// stored inside the IFD, is 0. If the value is false, the /// offset to the next IFD is set that it starts directly after /// the current one. /// </param> /// <returns> /// A <see cref="ByteVector"/> with the rendered IFD. /// </returns> private ByteVector RenderIFD(IFDDirectory directory, uint ifd_offset, bool last) { if (directory.Count > (int)UInt16.MaxValue) { throw new Exception(String.Format("Directory has too much entries: {0}", directory.Count)); } // Remove empty SUB ifds. var tags = new List <ushort>(directory.Keys); foreach (var tag in tags) { var entry = directory[tag]; if (entry is SubIFDEntry && (entry as SubIFDEntry).ChildCount == 0) { directory.Remove(tag); } } ushort entry_count = (ushort)directory.Count; // ifd_offset + size of entry_count + entries + next ifd offset uint data_offset = ifd_offset + 2 + 12 * (uint)entry_count + 4; // store the entries itself ByteVector entry_data = new ByteVector(); // store the data referenced by the entries ByteVector offset_data = new ByteVector(); entry_data.Add(ByteVector.FromUShort(entry_count, is_bigendian)); foreach (IFDEntry entry in directory.Values) { RenderEntryData(entry, entry_data, offset_data, data_offset); } if (last) { entry_data.Add("\0\0\0\0"); } else { entry_data.Add(ByteVector.FromUInt((uint)(data_offset + offset_data.Count), is_bigendian)); } if (data_offset - ifd_offset != entry_data.Count) { throw new Exception(String.Format("Expected IFD data size was {0} but is {1}", data_offset - ifd_offset, entry_data.Count)); } entry_data.Add(offset_data); return(entry_data); }
/// <summary> /// Renders the current instance as an APEv2 item. /// </summary> /// <returns> /// A <see cref="ByteVector" /> object containing the /// rendered version of the current instance. /// </returns> public ByteVector Render() { uint flags = (uint)((ReadOnly) ? 1 : 0) | ((uint)Type << 1); if (IsEmpty) { return(new ByteVector()); } ByteVector result = null; if (type == ItemType.Binary) { if (text == null && data != null) { result = data; } } if (result == null && text != null) { result = new ByteVector(); for (int i = 0; i < text.Length; i++) { if (i != 0) { result.Add((byte)0); } result.Add(ByteVector.FromString( text [i], StringType.UTF8)); } } // If no data is stored, don't write the item. if (result == null || result.Count == 0) { return(new ByteVector()); } ByteVector output = new ByteVector(); output.Add(ByteVector.FromUInt((uint)result.Count, false)); output.Add(ByteVector.FromUInt(flags, false)); output.Add(ByteVector.FromString(key, StringType.UTF8)); output.Add((byte)0); output.Add(result); size_on_disk = output.Count; return(output); }
/// <summary> /// Renders the current instance to a <see cref="ByteVector"/> /// </summary> /// <param name="is_bigendian"> /// A <see cref="System.Boolean"/> indicating the endianess for rendering. /// </param> /// <param name="offset"> /// A <see cref="System.UInt32"/> with the offset, the data is stored. /// </param> /// <param name="type"> /// A <see cref="System.UInt16"/> the ID of the type, which is rendered /// </param> /// <param name="count"> /// A <see cref="System.UInt32"/> with the count of the values which are /// rendered. /// </param> /// <returns> /// A <see cref="ByteVector"/> with the rendered data. /// </returns> public override ByteVector Render(bool is_bigendian, uint offset, out ushort type, out uint count) { // The StripOffsets are an array of offsets, where the image data can be found. // We store the offsets and behind the offsets the image data is stored. Therfore, // the ByteVector data first collects the image data and the offsets itself are // collected by offset_data. Then both are concatenated. ByteVector data = new ByteVector(); ByteVector offset_data = new ByteVector(); // every offset needs 4 byte, we need to reserve the bytes. uint data_offset = offset + (uint)(4 * Values.Length); for (int i = 0; i < Values.Length; i++) { uint new_offset = (uint)(data_offset + data.Count); file.Seek(Values[i], SeekOrigin.Begin); data.Add(file.ReadBlock((int)byte_counts[i])); // update strip offset data to new offset Values[i] = new_offset; offset_data.Add(ByteVector.FromUInt(new_offset, is_bigendian)); } // If the StripOffsets only consists of one offset, this doesn't work, because this offset // should be stored inside the IFD as a value. But, because of the additional image data, // it is not stored there. We need to fix this, that the offset is adjusted correctly. // Therefore, the offset_data is only added if it contains more than one value. // Then, the offset is set correctly. (However, we need to ensure, that the image data // consists at least of 4 bytes, which is probably the case every time, but to be sure ...) // However, the strip offset in the array must also be adjusted, if the offset_data is ignored. if (Values.Length > 1) { data.Insert(0, offset_data); } else { Values[0] = offset; } while (data.Count < 4) { data.Add(0x00); } // the entry is a single long entry where the value is an offset to the data // the offset is automatically updated by the renderer. type = (ushort)IFDEntryType.Long; count = (uint)Values.Length; return(data); }
public override ByteVector Render(bool is_bigendian, uint offset, out ushort type, out uint count) { type = (ushort)IFDEntryType.Long; count = (uint)Values.Length; ByteVector data = new ByteVector(); foreach (uint value in Values) { data.Add(ByteVector.FromUInt(value, is_bigendian)); } return(data); }
public static void OverwriteSequenceNumbers(File file, long position, IDictionary <uint, int> shiftTable) { bool done = true; foreach (KeyValuePair <uint, int> pair in shiftTable) { if (pair.Value != 0) { done = false; break; } } if (done) { return; } while (position < file.Length) { PageHeader header = new PageHeader(file, position); int size = (int)(header.Size + header.DataSize); if (shiftTable.ContainsKey(header.StreamSerialNumber) && shiftTable [header.StreamSerialNumber] != 0) { file.Seek(position); ByteVector page_data = file.ReadBlock(size); ByteVector new_data = ByteVector.FromUInt( (uint)(header.PageSequenceNumber + shiftTable [header.StreamSerialNumber]), false); for (int i = 18; i < 22; i++) { page_data [i] = new_data [i - 18]; } for (int i = 22; i < 26; i++) { page_data [i] = 0; } new_data.Add(ByteVector.FromUInt( page_data.Checksum, false)); file.Seek(position + 18); file.WriteBlock(new_data); } position += size; } }
public virtual ByteVector Render(byte version) { if (version < 4) { Flags &= ~(FrameFlags.DataLengthIndicator | FrameFlags.Unsynchronisation); } if (version < 3) { Flags &= ~(FrameFlags.Compression | FrameFlags.Encryption | FrameFlags.FileAlterPreservation | FrameFlags.GroupingIdentity | FrameFlags.ReadOnly | FrameFlags.TagAlterPreservation); } ByteVector field_data = RenderFields(version); if (field_data.Count == 0) { return(new ByteVector()); } ByteVector front_data = new ByteVector(); if ((Flags & (FrameFlags.Compression | FrameFlags.DataLengthIndicator)) != 0) { front_data.Add(ByteVector.FromUInt((uint)field_data.Count)); } if ((Flags & FrameFlags.GroupingIdentity) != 0) { front_data.Add(group_id); } if ((Flags & FrameFlags.Encryption) != 0) { front_data.Add(encryption_id); } if ((Flags & FrameFlags.Compression) != 0) { throw new NotImplementedException("Compression not yet supported"); } if ((Flags & FrameFlags.Encryption) != 0) { throw new NotImplementedException("Encryption not yet supported"); } if ((Flags & FrameFlags.Unsynchronisation) != 0) { SynchData.UnsynchByteVector(field_data); } if (front_data.Count > 0) { field_data.Insert(0, front_data); } header.FrameSize = (uint)field_data.Count; ByteVector header_data = header.Render(version); header_data.Add(field_data); return(header_data); }
public override ByteVector Render(bool is_bigendian, uint offset, out ushort type, out uint count) { type = (ushort)IFDEntryType.Rational; count = (uint)Values.Length; ByteVector data = new ByteVector(); foreach (Rational rational in Values) { data.Add(ByteVector.FromUInt(rational.Numerator, is_bigendian)); data.Add(ByteVector.FromUInt(rational.Denominator, is_bigendian)); } return(data); }
/// <summary> /// Renders the current instance as a raw Xiph comment, /// optionally adding a framing bit. /// </summary> /// <param name="addFramingBit"> /// If <see langword="true" />, a framing bit will be added to /// the end of the content. /// </param> /// <returns> /// A <see cref="ByteVector"/> object containing the rendered /// version of the current instance. /// </returns> public ByteVector Render(bool addFramingBit) { ByteVector data = new ByteVector(); // Add the vendor ID length and the vendor ID. It's // important to use the length of the data(String::UTF8) // rather than the lenght of the the string since this // is UTF8 text and there may be more characters in the // data than in the UTF16 string. ByteVector vendor_data = ByteVector.FromString( vendor_id, StringType.UTF8); data.Add(ByteVector.FromUInt((uint)vendor_data.Count, false)); data.Add(vendor_data); // Add the number of fields. data.Add(ByteVector.FromUInt(FieldCount, false)); foreach (KeyValuePair <string, string[]> entry in field_list) { // And now iterate over the values of the // current list. foreach (string value in entry.Value) { ByteVector field_data = ByteVector.FromString( entry.Key, StringType.UTF8); field_data.Add((byte)'='); field_data.Add(ByteVector.FromString( value, StringType.UTF8)); data.Add(ByteVector.FromUInt((uint) field_data.Count, false)); data.Add(field_data); } } // Append the "framing bit". if (addFramingBit) { data.Add((byte)1); } return(data); }
public override void Save() { Mode = AccessMode.Write; try { ByteVector data = new ByteVector(); if (tag != null) { ByteVector tag_data = tag.Render(); if (tag_data.Count > 10) { if (tag_data.Count % 2 == 1) { tag_data.Add(0); } data.Add("ID3 "); data.Add(ByteVector.FromUInt((uint)tag_data.Count, true)); data.Add(tag_data); } } uint aiff_size; long tag_start, tag_end; Read(false, ReadStyle.None, out aiff_size, out tag_start, out tag_end); if (tag_start < 12 || tag_end < tag_start) { tag_start = tag_end = Length; } int length = (int)(tag_end - tag_start + 8); Insert(data, tag_start, length); if (data.Count - length != 0 && tag_start <= aiff_size) { if (tag == null) { length -= 16; } else { length -= 8; } Insert(ByteVector.FromUInt((uint)(aiff_size + data.Count - length), true), 4, 4); } TagTypesOnDisk = TagTypes; } finally { Mode = AccessMode.Closed; } }
public ByteVector Render() { ByteVector data = header.Render(); foreach (ByteVector v in packets) { data.Add(v); } ByteVector checksum = ByteVector.FromUInt(data.Checksum, false); for (int i = 0; i < 4; i++) { data[i + 22] = checksum[i]; } return(data); }
protected ByteVector RenderHeader(uint first_ifd_offset) { ByteVector data = new ByteVector(); if (IsBigEndian) { data.Add("MM"); } else { data.Add("II"); } data.Add(ByteVector.FromUShort(Magic, IsBigEndian)); data.Add(ByteVector.FromUInt(first_ifd_offset, IsBigEndian)); return(data); }
private static ByteVector ComputeCRC(params ByteVector[] datas) { uint crc = 0xFFFFFFFF; if (crc_table == null) { BuildCRCTable(); } foreach (var data in datas) { foreach (byte b in data) { crc = crc_table[(crc ^ b) & 0xFF] ^ (crc >> 8); } } return(ByteVector.FromUInt(crc ^ 0xFFFFFFFF)); }