private void ReadzTXtChunk(int data_length) { long position = Tell; ByteVector data = ReadChunkData(data_length); CheckCRC(zTXt_CHUNK_TYPE, data, ReadCRC()); int terminator_index; string keyword = ReadKeyword(data, 0, out terminator_index); if (terminator_index + 1 >= data_length) { throw new CorruptFileException("Compression Method byte expected"); } byte compression_method = data[terminator_index + 1]; ByteVector plain_data = Decompress(compression_method, data.Mid(terminator_index + 2)); if (plain_data == null) { return; } string value = plain_data.ToString(); PngTag png_tag = GetTag(TagTypes.Png, true) as PngTag; if (png_tag.GetKeyword(keyword) == null) { png_tag.SetKeyword(keyword, value); } AddMetadataBlock(position - 8, data_length + 8 + 4); }
/// <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); }
/// <summary> /// Reads an tEXt Chunk from file. The current position must be set /// to the start of the Chunk Data. Such a Chunk contains plain /// keywords. /// </summary> /// <param name="data_length"> /// A <see cref="System.Int32"/> with the length of the Chunk Data. /// </param> private void ReadtEXtChunk(int data_length) { long position = Tell; // tEXt Chunk // // N Bytes Keyword // 1 Byte Null Separator // N Bytes Txt // // Followed by 4 Bytes CRC data ByteVector data = ReadChunkData(data_length); CheckCRC(tEXt_CHUNK_TYPE, data, ReadCRC()); int keyword_terminator; string keyword = ReadKeyword(data, 0, out keyword_terminator); string value = data.Mid(keyword_terminator + 1).ToString(); PngTag png_tag = GetTag(TagTypes.Png, true) as PngTag; if (png_tag.GetKeyword(keyword) == null) { png_tag.SetKeyword(keyword, value); } AddMetadataBlock(position - 8, data_length + 8 + 4); }
/// <summary> /// Reads an zTXt Chunk from file. The current position must be set /// to the start of the Chunk Data. Such a Chunk contains compressed /// keywords. /// </summary> /// <param name="data_length"> /// A <see cref="System.Int32"/> with the length of the Chunk Data. /// </param> /// <remarks> /// The Chunk may also contain compressed Exif data which is written /// by other tools. But, since the PNG specification does not support /// Exif data, we ignore it here. /// </remarks> private void ReadzTXtChunk(int data_length) { long position = Tell; // zTXt Chunk // // N Bytes Keyword // 1 Byte Null Separator // 1 Byte Compression Method // N Bytes Txt // // Followed by 4 Bytes CRC data ByteVector data = ReadChunkData(data_length); CheckCRC(zTXt_CHUNK_TYPE, data, ReadCRC()); int terminator_index; string keyword = ReadKeyword(data, 0, out terminator_index); if (terminator_index + 1 >= data_length) { throw new CorruptFileException("Compression Method byte expected"); } byte compression_method = data [terminator_index + 1]; ByteVector plain_data = Decompress(compression_method, data.Mid(terminator_index + 2)); // ignore unknown compression methods if (plain_data == null) { return; } string value = plain_data.ToString(); RawProfile rawProfile = null; if (keyword.StartsWith("Raw profile type")) { rawProfile = ProcessRawProfile(value); value = rawProfile.ToString(); } // handle XMP, which has a fixed header if (keyword == "xmp" || rawProfile != null && string.Compare(rawProfile.Name, "xmp", StringComparison.InvariantCultureIgnoreCase) == 0) { ImageTag.AddTag(new XmpTag(string.Join("", rawProfile.Data.ToArray()), this)); } else { PngTag png_tag = GetTag(TagTypes.Png, true) as PngTag; if (png_tag.GetKeyword(keyword) == null) { png_tag.SetKeyword(keyword, value); } } AddMetadataBlock(position - 8, data_length + 8 + 4); }
private void ReadiTXtChunk(int data_length) { long position = Tell; ByteVector data = ReadChunkData(data_length); CheckCRC(iTXt_CHUNK_TYPE, data, ReadCRC()); if (data.StartsWith(XMP_CHUNK_HEADER)) { ImageTag.AddTag(new XmpTag(data.Mid(XMP_CHUNK_HEADER.Length).ToString(StringType.UTF8), this)); AddMetadataBlock(position - 8, data_length + 8 + 4); return; } int terminator_index; string keyword = ReadKeyword(data, 0, out terminator_index); if (terminator_index + 2 >= data_length) { throw new CorruptFileException("Compression Flag and Compression Method byte expected"); } byte compression_flag = data[terminator_index + 1]; byte compression_method = data[terminator_index + 2]; ByteVector txt_data = data.Mid(terminator_index + 1); if (compression_flag != 0x00) { txt_data = Decompress(compression_method, txt_data); if (txt_data == null) { return; } } string value = txt_data.ToString(); PngTag png_tag = GetTag(TagTypes.Png, true) as PngTag; if (png_tag.GetKeyword(keyword) == null) { png_tag.SetKeyword(keyword, value); } AddMetadataBlock(position - 8, data_length + 8 + 4); }
/// <summary> /// Gets a tag of a specified type from the current instance, /// optionally creating a new tag if possible. /// </summary> /// <param name="type"> /// A <see cref="TagLib.TagTypes" /> value indicating the /// type of tag to read. /// </param> /// <param name="create"> /// A <see cref="bool" /> value specifying whether or not to /// try and create the tag if one is not found. /// </param> /// <returns> /// A <see cref="Tag" /> object containing the tag that was /// found in or added to the current instance. If no /// matching tag was found and none was created, <see /// langword="null" /> is returned. /// </returns> public override TagLib.Tag GetTag (TagLib.TagTypes type, bool create) { foreach (Tag tag in ImageTag.AllTags) { if ((tag.TagTypes & type) == type) return tag; } if (!create || (type & ImageTag.AllowedTypes) == 0) return null; ImageTag new_tag = null; switch (type) { case TagTypes.JpegComment: new_tag = new JpegCommentTag (); break; case TagTypes.GifComment: new_tag = new GifCommentTag (); break; case TagTypes.Png: new_tag = new PngTag (); break; case TagTypes.TiffIFD: new_tag = new IFDTag (); break; case TagTypes.XMP: new_tag = new XmpTag (); break; } if (new_tag != null) { ImageTag.AddTag (new_tag); return new_tag; } throw new NotImplementedException (String.Format ("Adding tag of type {0} not supported!", type)); }
/// <summary> /// Reads an iTXt Chunk from file. The current position must be set /// to the start of the Chunk Data. Such a Chunk may contain XMP data /// or translated keywords. /// </summary> /// <param name="data_length"> /// A <see cref="System.Int32"/> with the length of the Chunk Data. /// </param> private void ReadiTXtChunk(int data_length) { long position = Tell; // iTXt Chunk // // N Bytes Keyword // 1 Byte Null Separator // 1 Byte Compression Flag (0 for uncompressed data) // 1 Byte Compression Method // N Bytes Language Tag // 1 Byte Null Separator // N Bytes Translated Keyword // 1 Byte Null Terminator // N Bytes Txt // // Followed by 4 Bytes CRC data ByteVector data = ReadChunkData(data_length); CheckCRC(iTXt_CHUNK_TYPE, data, ReadCRC()); // handle XMP, which has a fixed header if (data.StartsWith(XMP_CHUNK_HEADER)) { ImageTag.AddTag(new XmpTag(data.Mid(XMP_CHUNK_HEADER.Length).ToString(StringType.UTF8), this)); AddMetadataBlock(position - 8, data_length + 8 + 4); return; } int terminator_index; string keyword = ReadKeyword(data, 0, out terminator_index); if (terminator_index + 2 >= data_length) { throw new CorruptFileException("Compression Flag and Compression Method byte expected"); } byte compression_flag = data[terminator_index + 1]; byte compression_method = data[terminator_index + 2]; //string language = ReadTerminatedString (data, terminator_index + 3, out terminator_index); //string translated_keyword = ReadTerminatedString (data, terminator_index + 1, out terminator_index); ByteVector txt_data = data.Mid(terminator_index + 1); if (compression_flag != 0x00) { txt_data = Decompress(compression_method, txt_data); // ignore unknown compression methods if (txt_data == null) { return; } } string value = txt_data.ToString(); PngTag png_tag = GetTag(TagTypes.Png, true) as PngTag; if (png_tag.GetKeyword(keyword) == null) { png_tag.SetKeyword(keyword, value); } AddMetadataBlock(position - 8, data_length + 8 + 4); }