mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
taglib-sharp initial import (r553)
This commit is contained in:
2
taglib-sharp/examples/.gitignore
vendored
Normal file
2
taglib-sharp/examples/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
extractKey
|
||||
listData
|
||||
131
taglib-sharp/examples/BatchSet.cs
Normal file
131
taglib-sharp/examples/BatchSet.cs
Normal file
@@ -0,0 +1,131 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TagLib;
|
||||
|
||||
public class BatchSet
|
||||
{
|
||||
private enum Mode {
|
||||
Tag, Value, File
|
||||
}
|
||||
|
||||
public static void Main(string [] args)
|
||||
{
|
||||
if(args.Length < 3) {
|
||||
Console.Error.WriteLine ("USAGE: BatchSet.exe -tag value [-tag2 value ...] File1 [File2 ...]");
|
||||
return;
|
||||
}
|
||||
|
||||
Mode mode = Mode.Tag;
|
||||
List<string> files = new List<string> ();
|
||||
Dictionary<string,string> tags = new Dictionary<string,string> ();
|
||||
|
||||
string tag = null;
|
||||
|
||||
foreach (string str in args) {
|
||||
if (mode == Mode.Tag) {
|
||||
if (str [0] == '-') {
|
||||
if (str == "--") {
|
||||
mode = Mode.File;
|
||||
} else {
|
||||
tag = str.Substring (1);
|
||||
mode = Mode.Value;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
mode = Mode.File;
|
||||
}
|
||||
|
||||
if (mode == Mode.Value) {
|
||||
if (!tags.ContainsKey (tag))
|
||||
tags.Add (tag, str);
|
||||
mode = Mode.Tag;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mode == Mode.File)
|
||||
files.Add (str);
|
||||
}
|
||||
|
||||
foreach (string filename in files) {
|
||||
TagLib.File file = TagLib.File.Create (filename);
|
||||
if (file == null)
|
||||
continue;
|
||||
|
||||
Console.WriteLine ("Updating Tags For: " + filename);
|
||||
|
||||
foreach (string key in tags.Keys) {
|
||||
string value = tags [key];
|
||||
try {
|
||||
switch (key) {
|
||||
case "id3version":
|
||||
byte number = byte.Parse (value);
|
||||
if (number == 1) {
|
||||
file.RemoveTags (TagTypes.Id3v2);
|
||||
} else {
|
||||
TagLib.Id3v2.Tag v2 =
|
||||
file.GetTag (TagTypes.Id3v2, true)
|
||||
as TagLib.Id3v2.Tag;
|
||||
|
||||
if (v2 != null)
|
||||
v2.Version = number;
|
||||
}
|
||||
break;
|
||||
case "album":
|
||||
file.Tag.Album = value;
|
||||
break;
|
||||
case "artists":
|
||||
file.Tag.AlbumArtists = value.Split (new char [] {';'});
|
||||
break;
|
||||
case "comment":
|
||||
file.Tag.Comment = value;
|
||||
break;
|
||||
case "lyrics":
|
||||
file.Tag.Lyrics = value;
|
||||
break;
|
||||
case "composers":
|
||||
file.Tag.Composers = value.Split (new char [] {';'});
|
||||
break;
|
||||
case "disc":
|
||||
file.Tag.Disc = uint.Parse (value);
|
||||
break;
|
||||
case "disccount":
|
||||
file.Tag.DiscCount = uint.Parse (value);
|
||||
break;
|
||||
case "genres":
|
||||
file.Tag.Genres = value.Split (new char [] {';'});
|
||||
break;
|
||||
case "performers":
|
||||
file.Tag.Performers = value.Split (new char [] {';'});
|
||||
break;
|
||||
case "title":
|
||||
file.Tag.Title = value;
|
||||
break;
|
||||
case "track":
|
||||
file.Tag.Track = uint.Parse (value);
|
||||
break;
|
||||
case "trackcount":
|
||||
file.Tag.TrackCount = uint.Parse (value);
|
||||
break;
|
||||
case "year":
|
||||
file.Tag.Year = uint.Parse (value);
|
||||
break;
|
||||
case "pictures":
|
||||
List<Picture> pics = new List<Picture> ();
|
||||
if (!string.IsNullOrEmpty (value))
|
||||
foreach (string path in value.Split (new char [] {';'})) {
|
||||
pics.Add (new Picture (path));
|
||||
}
|
||||
file.Tag.Pictures = pics.ToArray ();
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Console.WriteLine ("Error setting tag " + key + ":");
|
||||
Console.WriteLine (e);
|
||||
}
|
||||
}
|
||||
|
||||
file.Save();
|
||||
}
|
||||
}
|
||||
}
|
||||
924
taglib-sharp/examples/GenerateTestFixture.cs
Normal file
924
taglib-sharp/examples/GenerateTestFixture.cs
Normal file
@@ -0,0 +1,924 @@
|
||||
//
|
||||
// This application parses a photo and compares the output to the output of exiv2.
|
||||
//
|
||||
// It can be used to make test fixtures. Manual validation is always required.
|
||||
//
|
||||
// You need the exiv2 app for this to work.
|
||||
//
|
||||
|
||||
using GLib;
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using TagLib;
|
||||
using TagLib.IFD;
|
||||
using TagLib.IFD.Tags;
|
||||
using TagLib.Xmp;
|
||||
|
||||
public class GenerateTestFixtureApp
|
||||
{
|
||||
private static MD5 md5 = MD5.Create ();
|
||||
|
||||
public static void Main (string [] args)
|
||||
{
|
||||
if(args.Length != 2) {
|
||||
Console.Error.WriteLine ("USAGE: mono GenerateTestFixture.exe NAME PATH");
|
||||
return;
|
||||
}
|
||||
|
||||
string name = args[0];
|
||||
string path = args[1];
|
||||
|
||||
EmitHeader (name, path);
|
||||
GenerateIFDFixture (name, path);
|
||||
GenerateXMPFixture (name, path);
|
||||
EmitFooter ();
|
||||
}
|
||||
|
||||
static Dictionary<string, int> sub_ifds = new Dictionary<string, int> ();
|
||||
static Dictionary<string, bool> sub_ifds_emitted = new Dictionary<string, bool> ();
|
||||
|
||||
static void GenerateIFDFixture (string name, string path)
|
||||
{
|
||||
// First run exiv2 on it.
|
||||
string output, err;
|
||||
int code;
|
||||
var result = GLib.Process.SpawnCommandLineSync (String.Format ("./listData e {0}", path), out output, out err, out code);
|
||||
if (!result) {
|
||||
Console.Error.WriteLine ("Invoking listData failed, are you running from the examples folder?");
|
||||
return;
|
||||
}
|
||||
|
||||
Write ("// ---------- Start of IFD tests ----------");
|
||||
|
||||
foreach (string line in output.Split ('\n')) {
|
||||
string[] parts = line.Split (new char[] {'\t'}, 5);
|
||||
if (parts.Length == 0 || line.Trim ().Equals (String.Empty) || parts.Length != 5)
|
||||
continue;
|
||||
string tag_label = parts[0];
|
||||
ushort tag = ushort.Parse (parts[1].Substring(2), System.Globalization.NumberStyles.HexNumber);
|
||||
string ifd = parts[2];
|
||||
string type = parts[3];
|
||||
uint length = uint.Parse (parts[4]);
|
||||
|
||||
if (ifd == "NikonSi02xx" || ifd == "NikonVr" || ifd == "NikonPc" || ifd == "NikonWt" || ifd == "NikonIi" || ifd == "NikonLd3") {
|
||||
continue; // Exiv2 makes these up.
|
||||
}
|
||||
|
||||
string val = ExtractKey (path, String.Format ("Exif.{0}.{1}", ifd, tag_label));
|
||||
|
||||
if (tag_label == "SubIFDs") {
|
||||
for (int i = 0; i < val.Split (' ').Length; i++) {
|
||||
var sub_ifd = String.Format ("SubImage{0}", sub_ifds.Count + 1);
|
||||
sub_ifds.Add (sub_ifd, sub_ifds.Count);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
EnsureIFD (ifd);
|
||||
|
||||
if (tag_label.Equals ("ExifTag"))
|
||||
type = "SubIFD";
|
||||
if (tag_label.Equals ("MakerNote")) {
|
||||
type = "MakerNote";
|
||||
val = String.Empty; // No need to echo.
|
||||
}
|
||||
if (tag_label.Equals ("InteroperabilityTag"))
|
||||
type = "SubIFD";
|
||||
if (tag_label.Equals ("GPSTag"))
|
||||
type = "SubIFD";
|
||||
if (tag_label.Equals ("JPEGInterchangeFormat"))
|
||||
type = "ThumbnailDataIFD";
|
||||
if (tag_label.Equals ("Preview") && ifd.Equals ("Nikon3"))
|
||||
type = "SubIFD";
|
||||
if (tag_label.Equals ("UserComment") && ifd.Equals ("Photo"))
|
||||
type = "UserComment";
|
||||
if (tag_label.Equals ("StripOffsets"))
|
||||
type = "StripOffsets";
|
||||
if (tag_label.Equals ("IPTCNAA"))
|
||||
type = "IPTCNAA";
|
||||
if (tag_label.Equals ("XMLPacket"))
|
||||
type = "XMLPacket";
|
||||
|
||||
if (ifd.Equals ("MakerNote"))
|
||||
continue; // Exiv2 makes these up.
|
||||
|
||||
Write ("// {1}.0x{0:X4} ({2}/{3}/{4}) \"{5}\"", tag, ifd, tag_label, type, length, length > 512 ? "(Value ommitted)" : val);
|
||||
|
||||
if (ifd.Equals ("Image")) {
|
||||
EmitTestIFDEntryOpen ("structure", 0, tag, ifd);
|
||||
} else if (ifd.Equals ("Thumbnail")) {
|
||||
EmitTestIFDEntryOpen ("structure", 1, tag, ifd);
|
||||
} else if (ifd.Equals ("Image2")) {
|
||||
EmitTestIFDEntryOpen ("structure", 2, tag, ifd);
|
||||
} else if (ifd.Equals ("Image3")) {
|
||||
EmitTestIFDEntryOpen ("structure", 3, tag, ifd);
|
||||
} else if (ifd.Equals ("Photo")) {
|
||||
EmitTestIFDEntryOpen ("exif_structure", 0, tag, ifd);
|
||||
} else if (IsPartOfMakernote (ifd)) {
|
||||
EmitTestIFDEntryOpen ("makernote_structure", 0, tag, ifd);
|
||||
} else if (ifd.Equals ("NikonPreview")) {
|
||||
EmitTestIFDEntryOpen ("nikonpreview_structure", 0, tag, ifd);
|
||||
} else if (ifd.Equals ("Iop")) {
|
||||
EmitTestIFDEntryOpen ("iop_structure", 0, tag, ifd);
|
||||
} else if (ifd.Equals ("GPSInfo")) {
|
||||
EmitTestIFDEntryOpen ("gps_structure", 0, tag, ifd);
|
||||
} else if (ifd.Equals ("CanonCs")) {
|
||||
EmitTestIFDEntryOpen ("makernote_structure", 0, (ushort) CanonMakerNoteEntryTag.CameraSettings, ifd);
|
||||
} else if (ifd.Equals ("CanonSi")) {
|
||||
EmitTestIFDEntryOpen ("makernote_structure", 0, (ushort) CanonMakerNoteEntryTag.ShotInfo, ifd);
|
||||
} else if (ifd.Equals ("CanonCf")) {
|
||||
EmitTestIFDEntryOpen ("makernote_structure", 0, (ushort) CanonMakerNoteEntryTag.CustomFunctions, ifd);
|
||||
} else if (ifd.Equals ("CanonPi")) {
|
||||
EmitTestIFDEntryOpen ("makernote_structure", 0, (ushort) CanonMakerNoteEntryTag.PictureInfo, ifd);
|
||||
} else if (ifd.Equals ("CanonFi")) {
|
||||
EmitTestIFDEntryOpen ("makernote_structure", 0, (ushort) 0x93, ifd);
|
||||
} else if (ifd.Equals ("PanasonicRaw")) {
|
||||
EmitTestIFDEntryOpen ("pana_structure", 0, tag, ifd);
|
||||
} else if (sub_ifds.ContainsKey (ifd)) {
|
||||
EmitTestIFDEntryOpen (String.Format ("{0}_structure", ifd), 0, tag, ifd);
|
||||
} else {
|
||||
throw new Exception (String.Format ("Unknown IFD: {0}", ifd));
|
||||
}
|
||||
|
||||
if (ifd.Equals ("CanonCs") || ifd.Equals ("CanonSi") || ifd.Equals ("CanonCf") || ifd.Equals ("CanonPi")) {
|
||||
// This are a made-up directory by exiv2
|
||||
EmitTestIFDIndexedShortEntry (tag, val);
|
||||
} else if (ifd.Equals ("CanonFi")) {
|
||||
// This are a made-up directory by exiv2
|
||||
// And the fist both entries are combined to a long by exiv2.
|
||||
if (tag == 0x0001) {
|
||||
string val1 = ((ushort) UInt32.Parse (val)).ToString ();
|
||||
string val2 = ((ushort) (UInt32.Parse (val) >> 16)).ToString ();
|
||||
EmitTestIFDIndexedShortEntry (tag, val1);
|
||||
EmitTestIFDIndexedShortEntry (tag + 1, val2);
|
||||
} else {
|
||||
EmitTestIFDIndexedShortEntry (tag, val);
|
||||
}
|
||||
} else if (type.Equals ("Ascii")) {
|
||||
EmitTestIFDStringEntry (val);
|
||||
} else if (type.Equals ("Short") && length == 1) {
|
||||
EmitTestIFDShortEntry (val);
|
||||
} else if (type.Equals ("Short") && length > 1) {
|
||||
EmitTestIFDShortArrayEntry (val);
|
||||
} else if (type.Equals ("SShort") && length == 1) {
|
||||
EmitTestIFDSShortEntry (val);
|
||||
} else if (type.Equals ("SShort") && length > 1) {
|
||||
EmitTestIFDSShortArrayEntry (val);
|
||||
} else if (type.Equals ("Rational") && length == 1) {
|
||||
EmitTestIFDRationalEntry (val);
|
||||
} else if (type.Equals ("Rational") && length > 1) {
|
||||
EmitTestIFDRationalArrayEntry (val);
|
||||
} else if (type.Equals ("SRational") && length == 1) {
|
||||
EmitTestIFDSRationalEntry (val);
|
||||
} else if (type.Equals ("SRational") && length > 1) {
|
||||
EmitTestIFDSRationalArrayEntry (val);
|
||||
} else if (type.Equals ("Long") && length == 1) {
|
||||
EmitTestIFDLongEntry (val);
|
||||
} else if (type.Equals ("Long") && length > 1) {
|
||||
EmitTestIFDLongArrayEntry (val);
|
||||
} else if (type.Equals ("SLong") && length == 1) {
|
||||
EmitTestIFDSLongEntry (val);
|
||||
} else if (type.Equals ("Byte") && length == 1) {
|
||||
EmitTestIFDByteEntry (val);
|
||||
} else if (type.Equals ("Byte") && length > 1) {
|
||||
EmitTestIFDByteArrayEntry (val);
|
||||
} else if (type.Equals ("SByte") && length == 1) {
|
||||
EmitTestIFDSByteEntry (val);
|
||||
} else if (type.Equals ("SubIFD")) {
|
||||
EmitTestIFDSubIFDEntry (val);
|
||||
} else if (type.Equals ("ThumbnailDataIFD")) {
|
||||
EmitTestIFDThumbnailDataIFDEntry (val);
|
||||
} else if (type.Equals ("MakerNote")) {
|
||||
EmitTestIFDMakerNoteIFDEntry (val);
|
||||
} else if (type.Equals ("UserComment")) {
|
||||
EmitTestIFDUserCommentIFDEntry (val);
|
||||
} else if (type.Equals ("Undefined")) {
|
||||
EmitTestIFDUndefinedEntry (val);
|
||||
} else if (type.Equals ("StripOffsets")) {
|
||||
EmitTestIFDStripOffsetsEntry (val);
|
||||
} else if (type.Equals ("IPTCNAA")) {
|
||||
EmitTestIFDIPTCNAAEntry (val);
|
||||
} else if (type.Equals ("XMLPacket")) {
|
||||
EmitTestIFDXMLPacketEntry (val);
|
||||
} else {
|
||||
throw new Exception ("Unknown type: " + type);
|
||||
}
|
||||
|
||||
EmitTestIFDEntryClose ();
|
||||
}
|
||||
|
||||
Write ();
|
||||
Write ("// ---------- End of IFD tests ----------");
|
||||
Write ();
|
||||
}
|
||||
|
||||
static Dictionary<string, string> xmp_prefixes = new Dictionary<string, string> ();
|
||||
|
||||
static void GenerateXMPFixture (string name, string path)
|
||||
{
|
||||
// First run exiv2 on it.
|
||||
string output, err;
|
||||
int code;
|
||||
var result = GLib.Process.SpawnCommandLineSync (String.Format ("./listData x {0}", path), out output, out err, out code);
|
||||
if (!result) {
|
||||
Console.Error.WriteLine ("Invoking exiv2 failed, do you have it installed?");
|
||||
return;
|
||||
}
|
||||
|
||||
if (output.Trim ().Equals (""))
|
||||
return;
|
||||
|
||||
Write ();
|
||||
Write ("// ---------- Start of XMP tests ----------");
|
||||
Write ();
|
||||
|
||||
Write ("XmpTag xmp = file.GetTag (TagTypes.XMP) as XmpTag;");
|
||||
|
||||
// Build prefix lookup dictionary.
|
||||
Type t = typeof(XmpTag);
|
||||
foreach (var member in t.GetMembers()) {
|
||||
if (!member.Name.EndsWith ("_NS"))
|
||||
continue;
|
||||
string val = (member as System.Reflection.FieldInfo).GetValue (null) as string;
|
||||
string prefix = XmpTag.NamespacePrefixes [val];
|
||||
xmp_prefixes [prefix] = member.Name;
|
||||
}
|
||||
|
||||
foreach (string line in output.Split ('\n')) {
|
||||
string[] parts = line.Split (new char[] {'\t'}, 3);
|
||||
if (parts.Length == 0 || line.Trim ().Equals (String.Empty))
|
||||
continue;
|
||||
string label = parts[0];
|
||||
string type = parts[1];
|
||||
uint length = uint.Parse (parts[2]);
|
||||
string val = ExtractKey (path, label).Trim ();
|
||||
|
||||
EmitXmpTest (label, type, length, val);
|
||||
}
|
||||
|
||||
Write ();
|
||||
Write ("// ---------- End of XMP tests ----------");
|
||||
Write ();
|
||||
}
|
||||
|
||||
static void EmitXmpTest (string label, string type, uint length, string val)
|
||||
{
|
||||
if (label.Equals ("Xmp.xmpMM.InstanceID"))
|
||||
return; // Continue this, exiv2 makes it up from the about attr
|
||||
if (label.Equals ("Xmp.tiff.Orientation"))
|
||||
return; // exiv2 destroys this value
|
||||
|
||||
var node_path = label.Split ('/');
|
||||
Write ("// {0} ({1}/{2}) \"{3}\"", label, type, length, val);
|
||||
Write ("{");
|
||||
Write ("var node = xmp.NodeTree;");
|
||||
|
||||
// Navigate to the correct node.
|
||||
foreach (var node in node_path) {
|
||||
var parts = node.Split ('.');
|
||||
var partscolon = node.Split (':');
|
||||
if (parts.Length == 3) {
|
||||
// Plain node
|
||||
int index = 0;
|
||||
string name = parts[2];
|
||||
if (parts[2].EndsWith("]")) {
|
||||
int index_start = parts[2].LastIndexOf ("[");
|
||||
string index_str = parts[2].Substring (index_start+1, parts[2].Length-index_start-2);
|
||||
index = int.Parse (index_str);
|
||||
name = parts[2].Substring (0, index_start);
|
||||
}
|
||||
string ns = GetXmpNs (parts[1]);
|
||||
Write ("node = node.GetChild ({0}, \"{1}\");", ns, name);
|
||||
Write ("Assert.IsNotNull (node);");
|
||||
|
||||
if (index > 0) {
|
||||
Write ("node = node.Children [{0}];", index - 1);
|
||||
Write ("Assert.IsNotNull (node);");
|
||||
}
|
||||
} else if (partscolon.Length == 2) {
|
||||
string ns = GetXmpNs (partscolon[0]);
|
||||
string name = partscolon[1];
|
||||
Write ("node = node.GetChild ({0}, \"{1}\");", ns, name);
|
||||
Write ("Assert.IsNotNull (node);");
|
||||
} else {
|
||||
throw new Exception ("Can't navigate to "+node);
|
||||
}
|
||||
}
|
||||
|
||||
if (length > 0 && type.Equals ("XmpText")) {
|
||||
Write ("Assert.AreEqual (\"{0}\", node.Value);", val);
|
||||
Write ("Assert.AreEqual (XmpNodeType.Simple, node.Type);");
|
||||
Write ("Assert.AreEqual (0, node.Children.Count);");
|
||||
} else if (type.Equals ("XmpBag") && length == 1) {
|
||||
Write ("Assert.AreEqual (XmpNodeType.Bag, node.Type);");
|
||||
Write ("Assert.AreEqual (\"\", node.Value);");
|
||||
Write ("Assert.AreEqual ({0}, node.Children.Count);", length);
|
||||
Write ("Assert.AreEqual (\"{0}\", node.Children [0].Value);", val);
|
||||
} else if (type.Equals ("LangAlt") && length == 1) {
|
||||
var langparts = val.Split (new char [] {' '}, 2);
|
||||
string lang = langparts[0].Substring (langparts[0].IndexOf ('"')+1, langparts [0].Length - langparts[0].IndexOf ('"')-2);
|
||||
Write ("Assert.AreEqual (\"{0}\", node.Children [0].GetQualifier (XmpTag.XML_NS, \"lang\").Value);", lang);
|
||||
Write ("Assert.AreEqual (\"{0}\", node.Children [0].Value);", langparts[1]);
|
||||
} else if (type.Equals ("XmpSeq") && length == 1) {
|
||||
Write ("Assert.AreEqual (XmpNodeType.Seq, node.Type);");
|
||||
Write ("Assert.AreEqual (\"\", node.Value);");
|
||||
Write ("Assert.AreEqual ({0}, node.Children.Count);", length);
|
||||
Write ("Assert.AreEqual (\"{0}\", node.Children [0].Value);", val);
|
||||
} else if (type.Equals ("XmpSeq") && length > 1) {
|
||||
string [] vals = val.Split (',');
|
||||
Write ("Assert.AreEqual (XmpNodeType.Seq, node.Type);");
|
||||
Write ("Assert.AreEqual (\"\", node.Value);");
|
||||
Write ("Assert.AreEqual ({0}, node.Children.Count);", length);
|
||||
var per_iter = vals.Length / length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
var builder = new List<string> ();
|
||||
for (int j = 0; j < per_iter; j++) {
|
||||
builder.Add (vals[per_iter*i + j].Trim ());
|
||||
}
|
||||
Write ("Assert.AreEqual (\"{0}\", node.Children [{1}].Value);", String.Join (", ", builder.ToArray ()), i);
|
||||
}
|
||||
} else if (type.Equals ("XmpBag") && length > 1) {
|
||||
string [] vals = val.Split (',');
|
||||
Write ("Assert.AreEqual (XmpNodeType.Bag, node.Type);");
|
||||
Write ("Assert.AreEqual (\"\", node.Value);");
|
||||
Write ("Assert.AreEqual ({0}, node.Children.Count);", length);
|
||||
Write ("var children_array = new System.Collections.Generic.List<string> ();");
|
||||
Write ("foreach (var child in node.Children)");
|
||||
Write ("{");
|
||||
Write ("children_array.Add (child.Value);");
|
||||
Write ("}");
|
||||
var per_iter = vals.Length / length;
|
||||
for (int i = 0; i < length; i++) {
|
||||
var builder = new List<string> ();
|
||||
for (int j = 0; j < per_iter; j++) {
|
||||
builder.Add (vals[per_iter*i + j].Trim ());
|
||||
}
|
||||
Write ("Assert.IsTrue (children_array.Contains (\"{0}\"));", String.Join (", ", builder.ToArray ()));
|
||||
}
|
||||
} else if (type.Equals ("XmpText") && length == 0 && val.StartsWith ("type=")) {
|
||||
if (val.Equals ("type=\"Bag\"")) {
|
||||
Write ("Assert.AreEqual (XmpNodeType.Bag, node.Type);");
|
||||
} else if (val.Equals ("type=\"Struct\"")) {
|
||||
// We disagree with exiv2 on the meaning of Struct. In Taglib#,
|
||||
// struct is meant to denote parseType=Resource types only, not
|
||||
// the shorthand equivalent. Also see XmpNode.RenderInto()
|
||||
//Write ("Assert.AreEqual (XmpNodeType.Struct, node.Type);");
|
||||
} else {
|
||||
throw new Exception ("Unknown type");
|
||||
}
|
||||
} else {
|
||||
throw new Exception (String.Format ("Can't test this (type: {0}, length: {1})", type, length));
|
||||
}
|
||||
Write ("}");
|
||||
}
|
||||
|
||||
static string ExtractKey (string file, string key)
|
||||
{
|
||||
string output, err;
|
||||
int code;
|
||||
var result = GLib.Process.SpawnCommandLineSync (String.Format ("./extractKey {0} {1}", file, key), out output, out err, out code);
|
||||
if (!result) {
|
||||
Console.Error.WriteLine ("Invoking extractKey failed, are you running from the examples folder?");
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
static string GetXmpNs (string prefix)
|
||||
{
|
||||
string result;
|
||||
if (prefix.Equals ("xmpBJ"))
|
||||
prefix = "xapBJ";
|
||||
if (prefix.Equals ("xmpMM"))
|
||||
prefix = "xapMM";
|
||||
if (prefix.Equals ("xmpRights"))
|
||||
prefix = "xapRights";
|
||||
if (prefix.Equals ("MicrosoftPhoto_1_")) // We correct this invalid namespace internally
|
||||
prefix = "MicrosoftPhoto";
|
||||
if (xmp_prefixes.TryGetValue (prefix, out result))
|
||||
return String.Format ("XmpTag.{0}", result);
|
||||
throw new Exception ("Unknown namespace prefix: "+prefix);
|
||||
}
|
||||
|
||||
static bool IsPartOfMakernote (string ifd) {
|
||||
return ifd.Equals ("MakerNote") ||
|
||||
ifd.Equals ("Canon") ||
|
||||
ifd.Equals ("Sony") ||
|
||||
ifd.Equals ("Nikon1") ||
|
||||
ifd.Equals ("Nikon2") ||
|
||||
ifd.Equals ("Nikon3") ||
|
||||
ifd.Equals ("Panasonic") ||
|
||||
ifd.Equals ("Olympus") ||
|
||||
ifd.Equals ("Pentax");
|
||||
}
|
||||
|
||||
static void EmitHeader (string name, string path)
|
||||
{
|
||||
int start = path.LastIndexOf ('/');
|
||||
string filename = path.Substring (start+1);
|
||||
Write ("// TODO: This file is automatically generated");
|
||||
Write ("// TODO: Further manual verification is needed");
|
||||
Write ();
|
||||
Write ("using System;");
|
||||
Write ("using NUnit.Framework;");
|
||||
Write ("using TagLib.IFD;");
|
||||
Write ("using TagLib.IFD.Entries;");
|
||||
Write ("using TagLib.IFD.Tags;");
|
||||
Write ("using TagLib.Xmp;");
|
||||
Write ("using TagLib.Tests.Images.Validators;");
|
||||
Write ();
|
||||
Write ("namespace TagLib.Tests.Images");
|
||||
Write ("{");
|
||||
Write ("[TestFixture]");
|
||||
Write ("public class {0}", name);
|
||||
Write ("{");
|
||||
Write ("[Test]");
|
||||
Write ("public void Test ()");
|
||||
Write ("{");
|
||||
Write ("ImageTest.Run (\"{0}\",", filename);
|
||||
level++;
|
||||
Write ("new {0}InvariantValidator (),", name);
|
||||
Write ("NoModificationValidator.Instance");
|
||||
level--;
|
||||
Write (");");
|
||||
Write ("}");
|
||||
Write ("}");
|
||||
Write ();
|
||||
Write ("public class {0}InvariantValidator : IMetadataInvariantValidator", name);
|
||||
Write ("{");
|
||||
Write ("public void ValidateMetadataInvariants (Image.File file)");
|
||||
Write ("{");
|
||||
Write ("Assert.IsNotNull (file);");
|
||||
}
|
||||
|
||||
static void EmitFooter ()
|
||||
{
|
||||
Write ("}"); // Method
|
||||
Write ("}"); // Class
|
||||
Write ("}"); // Namespace
|
||||
}
|
||||
|
||||
static bool is_panasonic_raw = false;
|
||||
|
||||
static bool structure_emitted = false;
|
||||
static bool exif_emitted = false;
|
||||
static bool makernote_emitted = false;
|
||||
static bool makernote_is_canon = false;
|
||||
static bool makernote_is_nikon1 = false;
|
||||
static bool makernote_is_nikon2 = false;
|
||||
static bool makernote_is_nikon3 = false;
|
||||
static bool makernote_is_panasonic = false;
|
||||
static bool nikonpreview_emitted = false;
|
||||
static bool iop_emitted = false;
|
||||
static bool gps_emitted = false;
|
||||
|
||||
static void EnsureIFD (string ifd) {
|
||||
if (ifd.Equals ("PanasonicRaw")) {
|
||||
if (is_panasonic_raw)
|
||||
return;
|
||||
|
||||
Write ();
|
||||
Write ("var tag = file.GetTag (TagTypes.TiffIFD) as IFDTag;");
|
||||
Write ("Assert.IsNotNull (tag, \"IFD tag not found\");");
|
||||
Write ();
|
||||
Write ("var pana_structure = tag.Structure;");
|
||||
Write ();
|
||||
Write ("var jpg_file = (file as TagLib.Tiff.Rw2.File).JpgFromRaw;");
|
||||
Write ("Assert.IsNotNull (tag, \"JpgFromRaw not found!\");");
|
||||
Write ("var jpg_tag = jpg_file.GetTag (TagTypes.TiffIFD) as IFDTag;");
|
||||
Write ("Assert.IsNotNull (tag, \"Jpg has no Exif tag!\");");
|
||||
Write ("var structure = jpg_tag.Structure;");
|
||||
|
||||
is_panasonic_raw = true;
|
||||
}
|
||||
|
||||
if (ifd.Equals ("Image") && !is_panasonic_raw) {
|
||||
if (structure_emitted)
|
||||
return;
|
||||
Write ();
|
||||
Write ("var tag = file.GetTag (TagTypes.TiffIFD) as IFDTag;");
|
||||
Write ("Assert.IsNotNull (tag, \"IFD tag not found\");");
|
||||
Write ();
|
||||
Write ("var structure = tag.Structure;");
|
||||
Write ();
|
||||
structure_emitted = true;
|
||||
}
|
||||
|
||||
if (ifd.Equals ("Photo")) {
|
||||
if (exif_emitted)
|
||||
return;
|
||||
EnsureIFD ("Image");
|
||||
Write ();
|
||||
Write ("var exif = structure.GetEntry (0, (ushort) IFDEntryTag.ExifIFD) as SubIFDEntry;");
|
||||
Write ("Assert.IsNotNull (exif, \"Exif tag not found\");");
|
||||
Write ("var exif_structure = exif.Structure;");
|
||||
Write ();
|
||||
exif_emitted = true;
|
||||
}
|
||||
|
||||
if (ifd.Equals ("MakerNote")) {
|
||||
if (makernote_emitted)
|
||||
return;
|
||||
EnsureIFD ("Photo");
|
||||
Write ();
|
||||
Write ("var makernote = exif_structure.GetEntry (0, (ushort) ExifEntryTag.MakerNote) as MakernoteIFDEntry;");
|
||||
Write ("Assert.IsNotNull (makernote, \"MakerNote tag not found\");");
|
||||
Write ("var makernote_structure = makernote.Structure;");
|
||||
Write ();
|
||||
makernote_emitted = true;
|
||||
}
|
||||
|
||||
if (ifd.Equals ("Canon") || ifd.Equals ("CanonCs") || ifd.Equals ("CanonSi")) {
|
||||
if (makernote_is_canon)
|
||||
return;
|
||||
EnsureIFD ("MakerNote");
|
||||
Write ();
|
||||
Write ("Assert.AreEqual (MakernoteType.Canon, makernote.MakernoteType);");
|
||||
Write ();
|
||||
makernote_is_canon = true;
|
||||
}
|
||||
|
||||
if (ifd.Equals ("Nikon1")) {
|
||||
if (makernote_is_nikon1)
|
||||
return;
|
||||
EnsureIFD ("MakerNote");
|
||||
Write ();
|
||||
Write ("Assert.AreEqual (MakernoteType.Nikon1, makernote.MakernoteType);");
|
||||
Write ();
|
||||
makernote_is_nikon1 = true;
|
||||
}
|
||||
|
||||
if (ifd.Equals ("Nikon2")) {
|
||||
if (makernote_is_nikon2)
|
||||
return;
|
||||
EnsureIFD ("MakerNote");
|
||||
Write ();
|
||||
Write ("Assert.AreEqual (MakernoteType.Nikon2, makernote.MakernoteType);");
|
||||
Write ();
|
||||
makernote_is_nikon2 = true;
|
||||
}
|
||||
|
||||
if (ifd.Equals ("Nikon3")) {
|
||||
if (makernote_is_nikon3)
|
||||
return;
|
||||
EnsureIFD ("MakerNote");
|
||||
Write ();
|
||||
Write ("Assert.AreEqual (MakernoteType.Nikon3, makernote.MakernoteType);");
|
||||
Write ();
|
||||
makernote_is_nikon3 = true;
|
||||
}
|
||||
|
||||
if (ifd.Equals ("NikonPreview")) {
|
||||
if (nikonpreview_emitted)
|
||||
return;
|
||||
EnsureIFD ("Nikon3");
|
||||
Write ();
|
||||
Write ("var nikonpreview = makernote_structure.GetEntry (0, (ushort) Nikon3MakerNoteEntryTag.Preview) as SubIFDEntry;");
|
||||
Write ("Assert.IsNotNull (nikonpreview, \"Nikon preview tag not found\");");
|
||||
Write ("var nikonpreview_structure = nikonpreview.Structure;");
|
||||
Write ();
|
||||
nikonpreview_emitted = true;
|
||||
}
|
||||
|
||||
if (ifd.Equals ("Panasonic")) {
|
||||
if (makernote_is_panasonic)
|
||||
return;
|
||||
EnsureIFD ("MakerNote");
|
||||
Write ();
|
||||
Write ("Assert.AreEqual (MakernoteType.Panasonic, makernote.MakernoteType);");
|
||||
Write ();
|
||||
makernote_is_panasonic = true;
|
||||
}
|
||||
|
||||
if (ifd.Equals ("Iop")) {
|
||||
if (iop_emitted)
|
||||
return;
|
||||
EnsureIFD ("Photo");
|
||||
Write ();
|
||||
Write ("var iop = exif_structure.GetEntry (0, (ushort) IFDEntryTag.InteroperabilityIFD) as SubIFDEntry;");
|
||||
Write ("Assert.IsNotNull (iop, \"Iop tag not found\");");
|
||||
Write ("var iop_structure = iop.Structure;");
|
||||
Write ();
|
||||
iop_emitted = true;
|
||||
}
|
||||
|
||||
if (ifd.Equals ("GPSInfo")) {
|
||||
if (gps_emitted)
|
||||
return;
|
||||
EnsureIFD ("Image");
|
||||
Write ();
|
||||
Write ("var gps = structure.GetEntry (0, (ushort) IFDEntryTag.GPSIFD) as SubIFDEntry;");
|
||||
Write ("Assert.IsNotNull (gps, \"GPS tag not found\");");
|
||||
Write ("var gps_structure = gps.Structure;");
|
||||
Write ();
|
||||
gps_emitted = true;
|
||||
}
|
||||
|
||||
if (sub_ifds.ContainsKey (ifd) && !sub_ifds_emitted.ContainsKey (ifd)) {
|
||||
Write ();
|
||||
Write ("var {0}_structure = (structure.GetEntry (0, (ushort) IFDEntryTag.SubIFDs) as SubIFDArrayEntry).Entries [{1}];", ifd, sub_ifds[ifd]);
|
||||
Write ("Assert.IsNotNull ({0}_structure, \"{0} structure not found\");", ifd);
|
||||
Write ();
|
||||
sub_ifds_emitted.Add (ifd, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void EmitTestIFDEntryOpen (string src, int ifd, ushort tag, string ifd_label)
|
||||
{
|
||||
Write ("{");
|
||||
Write (String.Format ("var entry = {0}.GetEntry ({1}, (ushort) {2});", src, ifd, StringifyEntryTag (ifd_label, tag)));
|
||||
Write (String.Format ("Assert.IsNotNull (entry, \"Entry 0x{0:X4} missing in IFD {1}\");", tag, ifd));
|
||||
}
|
||||
|
||||
static void EmitTestIFDEntryClose ()
|
||||
{
|
||||
Write ("}");
|
||||
}
|
||||
|
||||
static void EmitTestIFDStringEntry (string val)
|
||||
{
|
||||
Write ("Assert.IsNotNull (entry as StringIFDEntry, \"Entry is not a string!\");");
|
||||
Write ("Assert.AreEqual (\"{0}\", (entry as StringIFDEntry).Value{1});", val, val == String.Empty ? ".Trim ()" : "");
|
||||
}
|
||||
|
||||
static void EmitTestIFDShortEntry (string val)
|
||||
{
|
||||
Write ("Assert.IsNotNull (entry as ShortIFDEntry, \"Entry is not a short!\");");
|
||||
Write ("Assert.AreEqual ({0}, (entry as ShortIFDEntry).Value);", val);
|
||||
}
|
||||
|
||||
static void EmitTestIFDSShortEntry (string val)
|
||||
{
|
||||
Write ("Assert.IsNotNull (entry as SShortIFDEntry, \"Entry is not a signed short!\");");
|
||||
Write ("Assert.AreEqual ({0}, (entry as SShortIFDEntry).Value);", val);
|
||||
}
|
||||
|
||||
static void EmitTestIFDShortArrayEntry (string val)
|
||||
{
|
||||
val = String.Format ("new ushort [] {{ {0} }}", String.Join (", ", val.Split(' ')));
|
||||
Write ("Assert.IsNotNull (entry as ShortArrayIFDEntry, \"Entry is not a short array!\");");
|
||||
Write ("Assert.AreEqual ({0}, (entry as ShortArrayIFDEntry).Values);", val);
|
||||
}
|
||||
|
||||
static void EmitTestIFDSShortArrayEntry (string val)
|
||||
{
|
||||
val = String.Format ("new short [] {{ {0} }}", String.Join (", ", val.Split(' ')));
|
||||
Write ("Assert.IsNotNull (entry as SShortArrayIFDEntry, \"Entry is not a signed short array!\");");
|
||||
Write ("Assert.AreEqual ({0}, (entry as SShortArrayIFDEntry).Values);", val);
|
||||
}
|
||||
|
||||
static void EmitTestIFDRationalEntry (string val)
|
||||
{
|
||||
Write ("Assert.IsNotNull (entry as RationalIFDEntry, \"Entry is not a rational!\");");
|
||||
string[] parts = val.Split('/');
|
||||
Write ("Assert.AreEqual ({0}, (entry as RationalIFDEntry).Value.Numerator);", parts [0]);
|
||||
Write ("Assert.AreEqual ({0}, (entry as RationalIFDEntry).Value.Denominator);", parts [1]);
|
||||
}
|
||||
|
||||
static void EmitTestIFDRationalArrayEntry (string val)
|
||||
{
|
||||
var parts = val.Split(' ');
|
||||
Write ("Assert.IsNotNull (entry as RationalArrayIFDEntry, \"Entry is not a rational array!\");");
|
||||
Write ("var parts = (entry as RationalArrayIFDEntry).Values;");
|
||||
Write ("Assert.AreEqual ({0}, parts.Length);", parts.Length);
|
||||
for (int i = 0; i < parts.Length; i++) {
|
||||
var pieces = parts[i].Split('/');
|
||||
Write ("Assert.AreEqual ({0}, parts[{1}].Numerator);", pieces[0], i);
|
||||
Write ("Assert.AreEqual ({0}, parts[{1}].Denominator);", pieces[1], i);
|
||||
}
|
||||
}
|
||||
|
||||
static void EmitTestIFDSRationalEntry (string val)
|
||||
{
|
||||
Write ("Assert.IsNotNull (entry as SRationalIFDEntry, \"Entry is not a srational!\");");
|
||||
string[] parts = val.Split('/');
|
||||
Write ("Assert.AreEqual ({0}, (entry as SRationalIFDEntry).Value.Numerator);", parts [0]);
|
||||
Write ("Assert.AreEqual ({0}, (entry as SRationalIFDEntry).Value.Denominator);", parts [1]);
|
||||
}
|
||||
|
||||
static void EmitTestIFDSRationalArrayEntry (string val)
|
||||
{
|
||||
var parts = val.Split(' ');
|
||||
Write ("Assert.IsNotNull (entry as SRationalArrayIFDEntry, \"Entry is not a srational array!\");");
|
||||
Write ("var parts = (entry as SRationalArrayIFDEntry).Values;");
|
||||
Write ("Assert.AreEqual ({0}, parts.Length);", parts.Length);
|
||||
for (int i = 0; i < parts.Length; i++) {
|
||||
var pieces = parts[i].Split('/');
|
||||
Write ("Assert.AreEqual ({0}, parts[{1}].Numerator);", pieces[0], i);
|
||||
Write ("Assert.AreEqual ({0}, parts[{1}].Denominator);", pieces[1], i);
|
||||
}
|
||||
}
|
||||
|
||||
static void EmitTestIFDLongEntry (string val)
|
||||
{
|
||||
Write ("Assert.IsNotNull (entry as LongIFDEntry, \"Entry is not a long!\");");
|
||||
Write ("Assert.AreEqual ({0}, (entry as LongIFDEntry).Value);", val);
|
||||
}
|
||||
|
||||
static void EmitTestIFDLongArrayEntry (string val)
|
||||
{
|
||||
val = String.Format ("new long [] {{ {0} }}", String.Join (", ", val.Split(' ')));
|
||||
Write ("Assert.IsNotNull (entry as LongArrayIFDEntry, \"Entry is not a long array!\");");
|
||||
Write ("Assert.AreEqual ({0}, (entry as LongArrayIFDEntry).Values);", val);
|
||||
}
|
||||
|
||||
static void EmitTestIFDSLongEntry (string val)
|
||||
{
|
||||
Write ("Assert.IsNotNull (entry as SLongIFDEntry, \"Entry is not a signed long!\");");
|
||||
Write ("Assert.AreEqual ({0}, (entry as SLongIFDEntry).Value);", val);
|
||||
}
|
||||
|
||||
static void EmitTestIFDByteEntry (string val)
|
||||
{
|
||||
Write ("Assert.IsNotNull (entry as ByteIFDEntry, \"Entry is not a byte!\");");
|
||||
Write ("Assert.AreEqual ({0}, (entry as ByteIFDEntry).Value);", val);
|
||||
}
|
||||
|
||||
static void EmitTestIFDByteArrayEntry (string val)
|
||||
{
|
||||
EmitByteArrayComparison (val, "ByteVectorIFDEntry", "a byte array");
|
||||
}
|
||||
|
||||
static void EmitTestIFDSByteEntry (string val)
|
||||
{
|
||||
Write ("Assert.IsNotNull (entry as SByteIFDEntry, \"Entry is not a signed byte!\");");
|
||||
Write ("Assert.AreEqual ({0}, (entry as SByteIFDEntry).Value);", val);
|
||||
}
|
||||
|
||||
static void EmitTestIFDIPTCNAAEntry (string val)
|
||||
{
|
||||
Write ("Assert.IsNotNull (entry as ByteVectorIFDEntry, \"Entry is not a byte array!\");");
|
||||
}
|
||||
|
||||
static void EmitTestIFDXMLPacketEntry (string val)
|
||||
{
|
||||
Write ("Assert.IsNotNull (entry as ByteVectorIFDEntry, \"Entry is not a byte array!\");");
|
||||
}
|
||||
|
||||
static void EmitTestIFDUndefinedEntry (string val)
|
||||
{
|
||||
EmitByteArrayComparison (val, "UndefinedIFDEntry", "an undefined IFD entry");
|
||||
}
|
||||
|
||||
static void EmitByteArrayComparison (string val, string type, string type_desc)
|
||||
{
|
||||
Write ("Assert.IsNotNull (entry as {0}, \"Entry is not {1}!\");", type, type_desc);
|
||||
Write ("var parsed_bytes = (entry as {0}).Data.Data;", type);
|
||||
var parts = val.Trim ().Split(' ');
|
||||
if (parts.Length < 512) {
|
||||
Write ("var bytes = new byte [] {{ {0} }};", String.Join (", ", parts));
|
||||
Write ("Assert.AreEqual (bytes, parsed_bytes);");
|
||||
} else {
|
||||
// Starting with 512 byte items, we compare based on an MD5 hash, should be faster and reduces
|
||||
// the size of the test fixtures.
|
||||
byte [] data = new byte [parts.Length];
|
||||
for (int i = 0; i < parts.Length; i++) {
|
||||
data [i] = Byte.Parse (parts [i]);
|
||||
}
|
||||
var hash = md5.ComputeHash (data);
|
||||
|
||||
StringBuilder shash = new StringBuilder ();
|
||||
for (int i = 0; i < hash.Length; i++) {
|
||||
shash.Append (hash[i].ToString ("x2"));
|
||||
}
|
||||
|
||||
Write ("var parsed_hash = Utils.Md5Encode (parsed_bytes);");
|
||||
Write ("Assert.AreEqual (\"{0}\", parsed_hash);", shash.ToString ());
|
||||
Write ("Assert.AreEqual ({0}, parsed_bytes.Length);", parts.Length);
|
||||
}
|
||||
}
|
||||
|
||||
static void EmitTestIFDSubIFDEntry (string val)
|
||||
{
|
||||
Write ("Assert.IsNotNull (entry as SubIFDEntry, \"Entry is not a sub IFD!\");");
|
||||
}
|
||||
|
||||
static void EmitTestIFDThumbnailDataIFDEntry (string val)
|
||||
{
|
||||
Write ("Assert.IsNotNull (entry as ThumbnailDataIFDEntry, \"Entry is not a thumbnail IFD!\");");
|
||||
}
|
||||
|
||||
static void EmitTestIFDMakerNoteIFDEntry (string val)
|
||||
{
|
||||
Write ("Assert.IsNotNull (entry as MakernoteIFDEntry, \"Entry is not a makernote IFD!\");");
|
||||
}
|
||||
|
||||
static void EmitTestIFDUserCommentIFDEntry (string val)
|
||||
{
|
||||
Write ("Assert.IsNotNull (entry as UserCommentIFDEntry, \"Entry is not a user comment!\");");
|
||||
if (val.StartsWith ("charset=\"Ascii\""))
|
||||
val = val.Substring (15).Trim ();
|
||||
Write ("Assert.AreEqual (\"{0}\", (entry as UserCommentIFDEntry).Value.Trim ());", val);
|
||||
}
|
||||
|
||||
static void EmitTestIFDStripOffsetsEntry (string val)
|
||||
{
|
||||
// The offsets may change after writing. Therfore we cannot compare them directly.
|
||||
string offset_count = String.Format ("{0}", val.Split(' ').Length);
|
||||
//val = String.Format ("new long [] {{ {0} }}", String.Join (", ", val.Split(' ')));
|
||||
Write ("Assert.IsNotNull (entry as StripOffsetsIFDEntry, \"Entry is not a strip offsets entry!\");");
|
||||
//Write ("Assert.AreEqual ({0}, (entry as StripOffsetsIFDEntry).Values);", val);
|
||||
Write ("Assert.AreEqual ({0}, (entry as StripOffsetsIFDEntry).Values.Length);", offset_count);
|
||||
}
|
||||
|
||||
static void EmitTestIFDIndexedShortEntry (int index, string val)
|
||||
{
|
||||
Write ("Assert.IsNotNull (entry as ShortArrayIFDEntry, \"Entry is not a short array!\");");
|
||||
var parts = val.Trim ().Split (' ');
|
||||
Write ("Assert.IsTrue ({0} <= (entry as ShortArrayIFDEntry).Values.Length);", index + parts.Length);
|
||||
for (int i = 0; i < parts.Length; i++)
|
||||
Write ("Assert.AreEqual ({0}, (entry as ShortArrayIFDEntry).Values [{1}]);", parts [i], index + i);
|
||||
}
|
||||
|
||||
#region IFD tag names lookup
|
||||
|
||||
static Dictionary<string, Dictionary<ushort, string>> tag_names = null;
|
||||
|
||||
static string StringifyEntryTag (string src, ushort tag)
|
||||
{
|
||||
if (tag_names == null)
|
||||
BuildTagNamesTable ();
|
||||
Dictionary<ushort, string> table;
|
||||
string result;
|
||||
if (tag_names.TryGetValue (src, out table)) {
|
||||
if (table.TryGetValue (tag, out result))
|
||||
return result;
|
||||
}
|
||||
Write ("// TODO: Unknown IFD tag: {1} / 0x{0:X4}", tag, src);
|
||||
return String.Format ("0x{0:X4}", tag);
|
||||
}
|
||||
|
||||
static void BuildTagNamesTable ()
|
||||
{
|
||||
tag_names = new Dictionary<string, Dictionary<ushort, string>> ();
|
||||
|
||||
IndexTagType ("Image", typeof (IFDEntryTag), "IFDEntryTag");
|
||||
IndexTagType ("Image2", typeof (IFDEntryTag), "IFDEntryTag");
|
||||
IndexTagType ("Image3", typeof (IFDEntryTag), "IFDEntryTag");
|
||||
IndexTagType ("SubImage1", typeof (IFDEntryTag), "IFDEntryTag");
|
||||
IndexTagType ("SubImage2", typeof (IFDEntryTag), "IFDEntryTag");
|
||||
IndexTagType ("Thumbnail", typeof (IFDEntryTag), "IFDEntryTag"); // IFD1, for thumbnails
|
||||
IndexTagType ("Photo", typeof (IFDEntryTag), "IFDEntryTag");
|
||||
IndexTagType ("Photo", typeof (ExifEntryTag), "ExifEntryTag");
|
||||
IndexTagType ("Image", typeof (ExifEntryTag), "ExifEntryTag"); // Also put exif into Image, for DNG
|
||||
IndexTagType ("GPSInfo", typeof (GPSEntryTag), "GPSEntryTag");
|
||||
IndexTagType ("Iop", typeof (IOPEntryTag), "IOPEntryTag");
|
||||
IndexTagType ("Canon", typeof (CanonMakerNoteEntryTag), "CanonMakerNoteEntryTag");
|
||||
IndexTagType ("CanonCs", typeof (CanonMakerNoteEntryTag), "CanonMakerNoteEntryTag");
|
||||
IndexTagType ("CanonSi", typeof (CanonMakerNoteEntryTag), "CanonMakerNoteEntryTag");
|
||||
IndexTagType ("CanonCf", typeof (CanonMakerNoteEntryTag), "CanonMakerNoteEntryTag");
|
||||
IndexTagType ("CanonFi", typeof (CanonFileInfoEntryTag), "CanonFileInfoEntryTag");
|
||||
IndexTagType ("CanonFi", typeof (CanonMakerNoteEntryTag), "CanonMakerNoteEntryTag");
|
||||
IndexTagType ("CanonPi", typeof (CanonPictureInfoEntryTag), "CanonPictureInfoEntryTag");
|
||||
IndexTagType ("CanonPi", typeof (CanonMakerNoteEntryTag), "CanonMakerNoteEntryTag");
|
||||
IndexTagType ("Sony", typeof (SonyMakerNoteEntryTag), "SonyMakerNoteEntryTag");
|
||||
IndexTagType ("Olympus", typeof (OlympusMakerNoteEntryTag), "OlympusMakerNoteEntryTag");
|
||||
IndexTagType ("Pentax", typeof (PentaxMakerNoteEntryTag), "PentaxMakerNoteEntryTag");
|
||||
IndexTagType ("Nikon3", typeof (Nikon3MakerNoteEntryTag), "Nikon3MakerNoteEntryTag");
|
||||
IndexTagType ("NikonPreview", typeof (NikonPreviewMakerNoteEntryTag), "NikonPreviewMakerNoteEntryTag");
|
||||
IndexTagType ("Panasonic", typeof (PanasonicMakerNoteEntryTag), "PanasonicMakerNoteEntryTag");
|
||||
IndexTagType ("PanasonicRaw", typeof (IFDEntryTag), "IFDEntryTag");
|
||||
}
|
||||
|
||||
static void IndexTagType (string ifd, Type t, string typename)
|
||||
{
|
||||
if (!tag_names.ContainsKey (ifd))
|
||||
tag_names[ifd] = new Dictionary<ushort, string> ();
|
||||
foreach (string name in Enum.GetNames (t)) {
|
||||
ushort tag = (ushort) Enum.Parse (t, name);
|
||||
tag_names[ifd][tag] = String.Format ("{1}.{0}", name, typename);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Code emission
|
||||
|
||||
static int level = 0;
|
||||
|
||||
static void Write (string str, params object[] p)
|
||||
{
|
||||
Console.Write (new String ('\t', level));
|
||||
Console.WriteLine (str, p);
|
||||
}
|
||||
|
||||
static void Write ()
|
||||
{
|
||||
Console.WriteLine ();
|
||||
}
|
||||
|
||||
static void Write (string str)
|
||||
{
|
||||
if (str.Equals ("}"))
|
||||
level--;
|
||||
Console.Write (new String ('\t', level));
|
||||
Console.WriteLine (str);
|
||||
if (str.Equals ("{"))
|
||||
level++;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
13
taglib-sharp/examples/ListSupportedMimeTypes.cs
Normal file
13
taglib-sharp/examples/ListSupportedMimeTypes.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using TagLib;
|
||||
|
||||
public class ListSupportedMimeTypes
|
||||
{
|
||||
public static void Main()
|
||||
{
|
||||
foreach(string type in SupportedMimeType.AllMimeTypes) {
|
||||
Console.WriteLine(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
61
taglib-sharp/examples/Makefile.am
Normal file
61
taglib-sharp/examples/Makefile.am
Normal file
@@ -0,0 +1,61 @@
|
||||
READ_FROM_URI = ReadFromUri
|
||||
SET_PICTURES = SetPictures
|
||||
LIST_TYPES = ListSupportedMimeTypes
|
||||
BATCH_SET = BatchSet
|
||||
PARSE_PHOTO = ParsePhoto
|
||||
STRIP_IMAGE = StripImageData
|
||||
GENERATE_TEST_FIXTURE = GenerateTestFixture
|
||||
|
||||
REFERENCES = -r:taglib-sharp.dll
|
||||
EXAMPLES_BUILD = taglib-sharp.dll $(SET_PICTURES).exe $(LIST_TYPES).exe $(BATCH_SET).exe $(PARSE_PHOTO).exe $(STRIP_IMAGE).exe
|
||||
|
||||
if HAVE_GNOME_SHARP
|
||||
EXAMPLES_BUILD += $(READ_FROM_URI).exe
|
||||
if HAVE_EXIV2
|
||||
EXAMPLES_BUILD += $(GENERATE_TEST_FIXTURE).exe
|
||||
endif
|
||||
endif
|
||||
|
||||
all: $(EXAMPLES_BUILD)
|
||||
|
||||
taglib-sharp.dll:
|
||||
if [ ! -e $@ ]; then ln -s $(top_builddir)/src/taglib-sharp.dll $@; fi
|
||||
|
||||
if HAVE_GNOME_SHARP
|
||||
$(READ_FROM_URI).exe: $(READ_FROM_URI).cs
|
||||
$(MCS) -out:$@ -debug $(REFERENCES) $(GNOME_SHARP_LIBS) $<
|
||||
|
||||
if HAVE_EXIV2
|
||||
$(GENERATE_TEST_FIXTURE).exe: $(GENERATE_TEST_FIXTURE).cs listData extractKey
|
||||
$(MCS) -out:$@ -debug $(REFERENCES) $(GNOME_SHARP_LIBS) $<
|
||||
|
||||
listData: listData.cpp
|
||||
g++ -o $@ $(EXIV2_LIBS) $<
|
||||
|
||||
extractKey: extractKey.cpp
|
||||
g++ -o $@ $(EXIV2_LIBS) $<
|
||||
endif
|
||||
endif
|
||||
|
||||
$(SET_PICTURES).exe: $(SET_PICTURES).cs
|
||||
$(MCS) -out:$@ -debug $(REFERENCES) $<
|
||||
|
||||
$(LIST_TYPES).exe: $(LIST_TYPES).cs
|
||||
$(MCS) -out:$@ -debug $(REFERENCES) $<
|
||||
|
||||
$(BATCH_SET).exe: $(BATCH_SET).cs
|
||||
$(MCS) -out:$@ -debug $(REFERENCES) $<
|
||||
|
||||
$(PARSE_PHOTO).exe: $(PARSE_PHOTO).cs
|
||||
$(MCS) -out:$@ -debug $(REFERENCES) $<
|
||||
|
||||
$(STRIP_IMAGE).exe: $(STRIP_IMAGE).cs
|
||||
$(MCS) -out:$@ -debug $(REFERENCES) $<
|
||||
|
||||
EXTRA_DIST = $(READ_FROM_URI).cs $(SET_PICTURES).cs $(LIST_TYPES).cs $(BATCH_SET).cs $(PARSE_PHOTO).cs $(STRIP_IMAGE).cs $(GENERATE_TEST_FIXTURE).cs \
|
||||
$(srcdir)/covers/sample*
|
||||
|
||||
DISTCLEANFILES = *.pidb
|
||||
CLEANFILES = *.dll *.exe *.mdb
|
||||
MAINTAINERCLEANFILES = Makefile.in
|
||||
|
||||
82
taglib-sharp/examples/ParsePhoto.cs
Normal file
82
taglib-sharp/examples/ParsePhoto.cs
Normal file
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
|
||||
public class ParsePhotoApp
|
||||
{
|
||||
public static void Main (string [] args)
|
||||
{
|
||||
if(args.Length == 0) {
|
||||
Console.Error.WriteLine("USAGE: mono ParsePhoto.exe PATH [...]");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (string path in args)
|
||||
ParsePhoto (path);
|
||||
}
|
||||
|
||||
static void ParsePhoto (string path)
|
||||
{
|
||||
TagLib.File file = null;
|
||||
|
||||
try {
|
||||
file = TagLib.File.Create(path);
|
||||
} catch (TagLib.UnsupportedFormatException) {
|
||||
Console.WriteLine ("UNSUPPORTED FILE: " + path);
|
||||
Console.WriteLine (String.Empty);
|
||||
Console.WriteLine ("---------------------------------------");
|
||||
Console.WriteLine (String.Empty);
|
||||
return;
|
||||
}
|
||||
|
||||
var image = file as TagLib.Image.File;
|
||||
if (file == null) {
|
||||
Console.WriteLine ("NOT AN IMAGE FILE: " + path);
|
||||
Console.WriteLine (String.Empty);
|
||||
Console.WriteLine ("---------------------------------------");
|
||||
Console.WriteLine (String.Empty);
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine (String.Empty);
|
||||
Console.WriteLine (path);
|
||||
Console.WriteLine (String.Empty);
|
||||
|
||||
Console.WriteLine("Tags in object : " + image.TagTypes);
|
||||
Console.WriteLine (String.Empty);
|
||||
|
||||
Console.WriteLine("Comment : " + image.ImageTag.Comment);
|
||||
Console.Write("Keywords : ");
|
||||
foreach (var keyword in image.ImageTag.Keywords) {
|
||||
Console.Write (keyword + " ");
|
||||
}
|
||||
Console.WriteLine ();
|
||||
Console.WriteLine("Rating : " + image.ImageTag.Rating);
|
||||
Console.WriteLine("DateTime : " + image.ImageTag.DateTime);
|
||||
Console.WriteLine("Orientation : " + image.ImageTag.Orientation);
|
||||
Console.WriteLine("Software : " + image.ImageTag.Software);
|
||||
Console.WriteLine("ExposureTime : " + image.ImageTag.ExposureTime);
|
||||
Console.WriteLine("FNumber : " + image.ImageTag.FNumber);
|
||||
Console.WriteLine("ISOSpeedRatings : " + image.ImageTag.ISOSpeedRatings);
|
||||
Console.WriteLine("FocalLength : " + image.ImageTag.FocalLength);
|
||||
Console.WriteLine("FocalLength35mm : " + image.ImageTag.FocalLengthIn35mmFilm);
|
||||
Console.WriteLine("Make : " + image.ImageTag.Make);
|
||||
Console.WriteLine("Model : " + image.ImageTag.Model);
|
||||
|
||||
if (image.Properties != null) {
|
||||
Console.WriteLine("Width : " + image.Properties.PhotoWidth);
|
||||
Console.WriteLine("Height : " + image.Properties.PhotoHeight);
|
||||
Console.WriteLine("Type : " + image.Properties.Description);
|
||||
}
|
||||
|
||||
Console.WriteLine ();
|
||||
Console.WriteLine("Writable? : " + image.Writeable.ToString ());
|
||||
Console.WriteLine("Corrupt? : " + image.PossiblyCorrupt.ToString ());
|
||||
|
||||
if (image.PossiblyCorrupt) {
|
||||
foreach (string reason in image.CorruptionReasons) {
|
||||
Console.WriteLine (" * " + reason);
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine ("---------------------------------------");
|
||||
}
|
||||
}
|
||||
136
taglib-sharp/examples/ReadFromUri.boo
Normal file
136
taglib-sharp/examples/ReadFromUri.boo
Normal file
@@ -0,0 +1,136 @@
|
||||
import TagLib from "taglib-sharp.dll"
|
||||
import Gnome.Vfs from "gnome-vfs-sharp"
|
||||
import System
|
||||
import System.IO
|
||||
|
||||
def ReadFromUri(argv as (string)):
|
||||
|
||||
if len(argv) < 1:
|
||||
print "Usage: booi ReadFromUri.boo PATH [...]"
|
||||
return
|
||||
|
||||
Vfs.Initialize()
|
||||
|
||||
TagLib.File.SetFileAbstractionCreator(TagLib.File.FileAbstractionCreator(CreateFile))
|
||||
|
||||
start = DateTime.Now
|
||||
songs_read = 0
|
||||
|
||||
try:
|
||||
for path as string in argv:
|
||||
print path
|
||||
|
||||
file_info as System.IO.FileInfo = System.IO.FileInfo(path)
|
||||
uri as string = Gnome.Vfs.Uri.GetUriFromLocalPath (file_info.FullName)
|
||||
file as TagLib.File = null
|
||||
|
||||
try:
|
||||
file = TagLib.File.Create(uri)
|
||||
except UnsupportedFormatException:
|
||||
print "UNSUPPORTED FILE: ${path}"
|
||||
print string.Empty
|
||||
print "---------------------------------------"
|
||||
print string.Empty
|
||||
continue
|
||||
|
||||
print "Title: ${file.Tag.Title}"
|
||||
|
||||
if file.Tag.AlbumArtists is null:
|
||||
print "Artists:"
|
||||
else:
|
||||
print "Artists: ${string.Join ('\n ', file.Tag.AlbumArtists)}"
|
||||
|
||||
if file.Tag.Performers is null:
|
||||
print 'Performers:'
|
||||
else:
|
||||
print "Performers: ${string.Join ('\n ', file.Tag.Performers)}"
|
||||
|
||||
if file.Tag.Composers is null:
|
||||
print 'Composers:'
|
||||
else:
|
||||
print "Composers: ${string.Join ('\n ', file.Tag.Composers)}"
|
||||
|
||||
print "Album: ${file.Tag.Album}"
|
||||
print "Comment: ${file.Tag.Comment}"
|
||||
|
||||
if file.Tag.Genres is null:
|
||||
print 'Genres:'
|
||||
else:
|
||||
print "Genres: ${string.Join ('\n ', file.Tag.Genres)}"
|
||||
|
||||
print "Year: ${file.Tag.Year}"
|
||||
print "Track: ${file.Tag.Track}"
|
||||
print "TrackCount: ${file.Tag.TrackCount}"
|
||||
print "Disc: ${file.Tag.Disc}"
|
||||
print "DiscCount: ${file.Tag.DiscCount}"
|
||||
print "Lyrics:\n${file.Tag.Lyrics}"
|
||||
print string.Empty
|
||||
|
||||
print "Media Types: ${file.Properties.MediaTypes}"
|
||||
print string.Empty
|
||||
|
||||
for codec as ICodec in file.Properties.Codecs:
|
||||
|
||||
if codec.MediaTypes & MediaTypes.Audio:
|
||||
print "Audio Properties : ${(codec as IAudioCodec).Description}"
|
||||
print "Bitrate: ${(codec as IAudioCodec).AudioBitrate}"
|
||||
print "SampleRate: ${(codec as IAudioCodec).AudioSampleRate}"
|
||||
print "Channels: ${(codec as IAudioCodec).AudioChannels}"
|
||||
print string.Empty
|
||||
|
||||
if codec.MediaTypes & MediaTypes.Video:
|
||||
print "Video Properties : ${(codec as IVideoCodec).Description}"
|
||||
print "Width: ${(codec as IVideoCodec).VideoWidth}"
|
||||
print "Height: ${(codec as IVideoCodec).VideoHeight}"
|
||||
print string.Empty
|
||||
|
||||
if file.Properties.MediaTypes:
|
||||
print "Length: ${file.Properties.Duration}"
|
||||
print string.Empty
|
||||
|
||||
print "Embedded Pictures: ${file.Tag.Pictures.Length}"
|
||||
|
||||
for picture in file.Tag.Pictures:
|
||||
print picture.Description
|
||||
print " MimeType: ${picture.MimeType}"
|
||||
print " Size: ${picture.Data.Count}"
|
||||
print " Type: ${picture.Type}"
|
||||
|
||||
print ""
|
||||
print "---------------------------------------"
|
||||
print ""
|
||||
|
||||
songs_read = songs_read + 1
|
||||
|
||||
ensure:
|
||||
Vfs.Shutdown()
|
||||
|
||||
end as DateTime = DateTime.Now;
|
||||
|
||||
print "Total running time: ${end - start}"
|
||||
print "Total files read: ${songs_read}"
|
||||
print "Average time per file: ${TimeSpan ((end - start).Ticks / songs_read)}"
|
||||
|
||||
class VfsFileAbstraction(TagLib.File.IFileAbstraction):
|
||||
|
||||
_name as string
|
||||
|
||||
def constructor(file as string):
|
||||
_name = file
|
||||
|
||||
Name:
|
||||
get:
|
||||
return _name
|
||||
|
||||
ReadStream:
|
||||
get:
|
||||
return VfsStream(_name, FileMode.Open)
|
||||
|
||||
WriteStream:
|
||||
get:
|
||||
return VfsStream(_name, FileMode.Open)
|
||||
|
||||
def CreateFile(path):
|
||||
return VfsFileAbstraction(path)
|
||||
|
||||
ReadFromUri(argv)
|
||||
171
taglib-sharp/examples/ReadFromUri.cs
Normal file
171
taglib-sharp/examples/ReadFromUri.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
using System;
|
||||
using TagLib;
|
||||
using Gnome.Vfs;
|
||||
|
||||
public class ReadFromUri
|
||||
{
|
||||
public static void Write (string name, object value)
|
||||
{
|
||||
Console.WriteLine ("{0,20}: {1}",
|
||||
name, value == null ? "" : value
|
||||
);
|
||||
}
|
||||
|
||||
public static void Write (string name, string [] values)
|
||||
{
|
||||
Console.WriteLine ("{0,20}: {1}",
|
||||
name,
|
||||
values == null ? "" : String.Join ("\n ", values)
|
||||
);
|
||||
}
|
||||
|
||||
public static void Main(string [] args)
|
||||
{
|
||||
if(args.Length == 0) {
|
||||
Console.Error.WriteLine("USAGE: mono ReadFromUri.exe PATH [...]");
|
||||
return;
|
||||
}
|
||||
|
||||
Gnome.Vfs.Vfs.Initialize();
|
||||
|
||||
DateTime start = DateTime.Now;
|
||||
int songs_read = 0;
|
||||
try {
|
||||
foreach (string path in args)
|
||||
{
|
||||
string uri = path;
|
||||
Console.WriteLine (uri);
|
||||
TagLib.File file = null;
|
||||
|
||||
try {
|
||||
System.IO.FileInfo file_info = new System.IO.FileInfo(uri);
|
||||
uri = Gnome.Vfs.Uri.GetUriFromLocalPath (file_info.FullName);
|
||||
} catch {
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
file = TagLib.File.Create(new VfsFileAbstraction (uri));
|
||||
}
|
||||
catch (TagLib.UnsupportedFormatException)
|
||||
{
|
||||
Console.WriteLine ("UNSUPPORTED FILE: " + uri);
|
||||
Console.WriteLine (String.Empty);
|
||||
Console.WriteLine ("---------------------------------------");
|
||||
Console.WriteLine (String.Empty);
|
||||
continue;
|
||||
}
|
||||
|
||||
Console.WriteLine("Tags on disk: " + file.TagTypesOnDisk);
|
||||
Console.WriteLine("Tags in object: " + file.TagTypes);
|
||||
Console.WriteLine (String.Empty);
|
||||
|
||||
Write ("Grouping", file.Tag.Grouping);
|
||||
Write ("Title", file.Tag.Title);
|
||||
Write ("TitleSort", file.Tag.TitleSort);
|
||||
Write ("Album Artists", file.Tag.AlbumArtists);
|
||||
Write ("Album Artists Sort", file.Tag.AlbumArtistsSort);
|
||||
Write ("Performers", file.Tag.Performers);
|
||||
Write ("Performers Sort", file.Tag.PerformersSort);
|
||||
Write ("Composers", file.Tag.Composers);
|
||||
Write ("Composers Sort", file.Tag.ComposersSort);
|
||||
Write ("Conductor", file.Tag.Conductor);
|
||||
Write ("Album", file.Tag.Album);
|
||||
Write ("Album Sort", file.Tag.AlbumSort);
|
||||
Write ("Comment", file.Tag.Comment);
|
||||
Write ("Copyright", file.Tag.Copyright);
|
||||
Write ("Genres", file.Tag.Genres);
|
||||
Write ("BPM", file.Tag.BeatsPerMinute);
|
||||
Write ("Year", file.Tag.Year);
|
||||
Write ("Track", file.Tag.Track);
|
||||
Write ("TrackCount", file.Tag.TrackCount);
|
||||
Write ("Disc", file.Tag.Disc);
|
||||
Write ("DiscCount", file.Tag.DiscCount);
|
||||
|
||||
Console.WriteLine("Lyrics:\n" + file.Tag.Lyrics + "\n");
|
||||
|
||||
Console.WriteLine("Media Types: " + file.Properties.MediaTypes + "\n");
|
||||
|
||||
foreach (TagLib.ICodec codec in file.Properties.Codecs)
|
||||
{
|
||||
TagLib.IAudioCodec acodec = codec as TagLib.IAudioCodec;
|
||||
TagLib.IVideoCodec vcodec = codec as TagLib.IVideoCodec;
|
||||
|
||||
if (acodec != null && (acodec.MediaTypes & TagLib.MediaTypes.Audio) != TagLib.MediaTypes.None)
|
||||
{
|
||||
Console.WriteLine("Audio Properties : " + acodec.Description);
|
||||
Console.WriteLine("Bitrate: " + acodec.AudioBitrate);
|
||||
Console.WriteLine("SampleRate: " + acodec.AudioSampleRate);
|
||||
Console.WriteLine("Channels: " + acodec.AudioChannels + "\n");
|
||||
}
|
||||
|
||||
if (vcodec != null && (vcodec.MediaTypes & TagLib.MediaTypes.Video) != TagLib.MediaTypes.None)
|
||||
{
|
||||
Console.WriteLine("Video Properties : " + vcodec.Description);
|
||||
Console.WriteLine("Width: " + vcodec.VideoWidth);
|
||||
Console.WriteLine("Height: " + vcodec.VideoHeight + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (file.Properties.MediaTypes != TagLib.MediaTypes.None)
|
||||
Console.WriteLine("Length: " + file.Properties.Duration + "\n");
|
||||
|
||||
IPicture [] pictures = file.Tag.Pictures;
|
||||
|
||||
Console.WriteLine("Embedded Pictures: " + pictures.Length);
|
||||
|
||||
foreach(IPicture picture in pictures) {
|
||||
Console.WriteLine(picture.Description);
|
||||
Console.WriteLine(" MimeType: " + picture.MimeType);
|
||||
Console.WriteLine(" Size: " + picture.Data.Count);
|
||||
Console.WriteLine(" Type: " + picture.Type);
|
||||
}
|
||||
|
||||
Console.WriteLine (String.Empty);
|
||||
Console.WriteLine ("---------------------------------------");
|
||||
Console.WriteLine (String.Empty);
|
||||
|
||||
songs_read ++;
|
||||
}
|
||||
} finally {
|
||||
Gnome.Vfs.Vfs.Shutdown();
|
||||
}
|
||||
|
||||
DateTime end = DateTime.Now;
|
||||
|
||||
Console.WriteLine ("Total running time: " + (end - start));
|
||||
Console.WriteLine ("Total files read: " + songs_read);
|
||||
|
||||
if (songs_read > 0)
|
||||
{
|
||||
Console.WriteLine ("Average time per file: " + new TimeSpan ((end - start).Ticks / songs_read));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class VfsFileAbstraction : TagLib.File.IFileAbstraction
|
||||
{
|
||||
private string name;
|
||||
|
||||
public VfsFileAbstraction(string file)
|
||||
{
|
||||
name = file;
|
||||
}
|
||||
|
||||
public string Name {
|
||||
get { return name; }
|
||||
}
|
||||
|
||||
public System.IO.Stream ReadStream {
|
||||
get { return new VfsStream(Name, System.IO.FileMode.Open); }
|
||||
}
|
||||
|
||||
public System.IO.Stream WriteStream {
|
||||
get { return new VfsStream(Name, System.IO.FileMode.Open); }
|
||||
}
|
||||
|
||||
public void CloseStream (System.IO.Stream stream)
|
||||
{
|
||||
stream.Close ();
|
||||
}
|
||||
}
|
||||
55
taglib-sharp/examples/ReadFromUri.csproj
Normal file
55
taglib-sharp/examples/ReadFromUri.csproj
Normal file
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.21022</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{AB35577D-31CB-4848-AC41-13F00A5171A6}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>ReadFromUri</RootNamespace>
|
||||
<AssemblyName>ReadFromUri</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>.</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Commandlineparameters>../tests/samples/sample.ogg</Commandlineparameters>
|
||||
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
|
||||
<Execution>
|
||||
<Execution clr-version="Net_2_0" />
|
||||
</Execution>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>.</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Commandlineparameters>../tests/samples/sample_v2_only.mp3</Commandlineparameters>
|
||||
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
|
||||
<Execution>
|
||||
<Execution clr-version="Net_2_0" />
|
||||
</Execution>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ReadFromUri.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\src\taglib-sharp.csproj">
|
||||
<Project>{6B143A39-C7B2-4743-9917-92262C60E9A6}</Project>
|
||||
<Name>taglib-sharp</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="gnome-vfs-sharp, Version=2.8.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
28
taglib-sharp/examples/SetPictures.cs
Normal file
28
taglib-sharp/examples/SetPictures.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using TagLib;
|
||||
|
||||
public class SetPictures
|
||||
{
|
||||
public static void Main(string [] args)
|
||||
{
|
||||
if(args.Length < 2) {
|
||||
Console.Error.WriteLine("USAGE: mono SetPictures.exe AUDIO_PATH IMAGE_PATH_1[...IMAGE_PATH_N]");
|
||||
return;
|
||||
}
|
||||
|
||||
TagLib.File file = TagLib.File.Create(args[0]);
|
||||
Console.WriteLine("Current picture count: " + file.Tag.Pictures.Length);
|
||||
|
||||
Picture [] pictures = new Picture[args.Length - 1];
|
||||
|
||||
for(int i = 1; i < args.Length; i++) {
|
||||
Picture picture = new Picture(args[i]);
|
||||
pictures[i - 1] = picture;
|
||||
}
|
||||
|
||||
file.Tag.Pictures = pictures;
|
||||
file.Save();
|
||||
|
||||
Console.WriteLine("New picture count: " + file.Tag.Pictures.Length);
|
||||
}
|
||||
}
|
||||
52
taglib-sharp/examples/SetPictures.csproj
Normal file
52
taglib-sharp/examples/SetPictures.csproj
Normal file
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="3.5" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.21022</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{0C4645BE-7413-43FC-8856-1ECF1A790FF8}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>SetPictures</RootNamespace>
|
||||
<AssemblyName>SetPictures</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>.</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Commandlineparameters>../tests/samples/sample_v2_only.mp3 covers/sample_a.png covers/sample_b.jpg</Commandlineparameters>
|
||||
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
|
||||
<Execution>
|
||||
<Execution clr-version="Net_2_0" />
|
||||
</Execution>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>.</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Commandlineparameters>../tests/samples/sample_v2_only.mp3 covers/sample_a.png covers/sample_b.jpg</Commandlineparameters>
|
||||
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
|
||||
<Execution>
|
||||
<Execution clr-version="Net_2_0" />
|
||||
</Execution>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="SetPictures.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\src\taglib-sharp.csproj">
|
||||
<Project>{6B143A39-C7B2-4743-9917-92262C60E9A6}</Project>
|
||||
<Name>taglib-sharp</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
117
taglib-sharp/examples/StripImageData.cs
Normal file
117
taglib-sharp/examples/StripImageData.cs
Normal file
@@ -0,0 +1,117 @@
|
||||
|
||||
using System;
|
||||
using TagLib;
|
||||
|
||||
public class StripImageData
|
||||
{
|
||||
private static byte[] image_data = new byte[] {
|
||||
0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x01, 0x00,
|
||||
0x02, 0x11, 0x03, 0x11, 0x00, 0x3F, 0x00,
|
||||
0x8C, 0x80, 0x07, 0xFF, 0xD9
|
||||
};
|
||||
|
||||
public static void Main (string [] args)
|
||||
{
|
||||
if (args.Length != 1) {
|
||||
Console.Out.WriteLine ("usage: mono StripImageData.exe [jpegfile]");
|
||||
return;
|
||||
}
|
||||
|
||||
ImageFile file = new ImageFile (args [0]);
|
||||
|
||||
file.Mode = File.AccessMode.Write;
|
||||
|
||||
long greatest_segment_position = 0;
|
||||
long greatest_segment_length = 0;
|
||||
|
||||
// collect data segments
|
||||
while (true) {
|
||||
|
||||
long sos = file.Find (new byte [] {0xFF, 0xDA}, file.Tell);
|
||||
|
||||
if (sos == -1)
|
||||
break;
|
||||
|
||||
file.Seek (sos);
|
||||
|
||||
long segment_length = SkipDataSegment (file);
|
||||
|
||||
if (segment_length > greatest_segment_length) {
|
||||
greatest_segment_length = segment_length;
|
||||
greatest_segment_position = sos;
|
||||
}
|
||||
}
|
||||
|
||||
if (greatest_segment_length == 0)
|
||||
{
|
||||
Console.Out.WriteLine ("doesn't look like an jpeg file");
|
||||
return;
|
||||
}
|
||||
|
||||
System.Console.WriteLine ("Stripping data segment at {0}", greatest_segment_position);
|
||||
|
||||
file.RemoveBlock (greatest_segment_position, greatest_segment_length);
|
||||
file.Seek (greatest_segment_position);
|
||||
file.WriteBlock (image_data);
|
||||
file.Mode = File.AccessMode.Closed;
|
||||
}
|
||||
|
||||
private static long SkipDataSegment (ImageFile file)
|
||||
{
|
||||
long position = file.Tell;
|
||||
|
||||
// skip sos maker
|
||||
if (file.ReadBlock (2).ToUInt () != 0xFFDA)
|
||||
throw new Exception (String.Format ("Not a data segment at position: {0}", position));
|
||||
|
||||
while (true) {
|
||||
if (0xFF == (byte) file.ReadBlock (1)[0]) {
|
||||
byte maker = (byte) file.ReadBlock (1)[0];
|
||||
|
||||
if (maker != 0x00 && (maker <= 0xD0 || maker >= 0xD7))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
long length = file.Tell - position - 2;
|
||||
|
||||
System.Console.WriteLine ("Data segment of length {0} found at {1}", length, position);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
private class ImageFile : File {
|
||||
|
||||
// Hacky implementation to make use of some methods defined in TagLib.File
|
||||
|
||||
public ImageFile (string path)
|
||||
: base (new File.LocalFileAbstraction (path)) {}
|
||||
|
||||
public override Tag GetTag (TagLib.TagTypes type, bool create)
|
||||
{
|
||||
throw new System.NotImplementedException ();
|
||||
}
|
||||
|
||||
public override Properties Properties {
|
||||
get {
|
||||
throw new System.NotImplementedException ();
|
||||
}
|
||||
}
|
||||
|
||||
public override void RemoveTags (TagLib.TagTypes types)
|
||||
{
|
||||
throw new System.NotImplementedException ();
|
||||
}
|
||||
|
||||
public override void Save ()
|
||||
{
|
||||
throw new System.NotImplementedException ();
|
||||
}
|
||||
|
||||
public override Tag Tag {
|
||||
get {
|
||||
throw new System.NotImplementedException ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
taglib-sharp/examples/covers/sample_a.jpg
Normal file
BIN
taglib-sharp/examples/covers/sample_a.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
BIN
taglib-sharp/examples/covers/sample_a.png
Normal file
BIN
taglib-sharp/examples/covers/sample_a.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
taglib-sharp/examples/covers/sample_b.jpg
Normal file
BIN
taglib-sharp/examples/covers/sample_b.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
BIN
taglib-sharp/examples/covers/sample_b.png
Normal file
BIN
taglib-sharp/examples/covers/sample_b.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
BIN
taglib-sharp/examples/covers/sample_c.jpg
Normal file
BIN
taglib-sharp/examples/covers/sample_c.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
BIN
taglib-sharp/examples/covers/sample_c.png
Normal file
BIN
taglib-sharp/examples/covers/sample_c.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
41
taglib-sharp/examples/extractKey.cpp
Normal file
41
taglib-sharp/examples/extractKey.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#include <exiv2/image.hpp>
|
||||
#include <exiv2/exif.hpp>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cassert>
|
||||
|
||||
int main(int argc, char* const argv[])
|
||||
|
||||
try {
|
||||
if (argc != 3) {
|
||||
std::cout << "Usage: " << argv[0] << " file key\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(argv[1]);
|
||||
assert(image.get() != 0);
|
||||
image->readMetadata();
|
||||
|
||||
try {
|
||||
Exiv2::ExifData &exifData = image->exifData();
|
||||
const Exiv2::Value &value = exifData[argv[2]].value();
|
||||
std::cout << value;
|
||||
} catch (Exiv2::AnyError &e) {}
|
||||
|
||||
try {
|
||||
Exiv2::IptcData &iptcData = image->iptcData();
|
||||
const Exiv2::Value &value = iptcData[argv[2]].value();
|
||||
std::cout << value;
|
||||
} catch (Exiv2::AnyError &e) {}
|
||||
|
||||
try {
|
||||
Exiv2::XmpData &xmpData = image->xmpData();
|
||||
const Exiv2::Value &value = xmpData[argv[2]].value();
|
||||
std::cout << value;
|
||||
} catch (Exiv2::AnyError &e) {}
|
||||
|
||||
return 0;
|
||||
} catch (Exiv2::AnyError& e) {
|
||||
std::cout << "Caught Exiv2 exception '" << e << "'\n";
|
||||
return -1;
|
||||
}
|
||||
62
taglib-sharp/examples/listData.cpp
Normal file
62
taglib-sharp/examples/listData.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
#include <exiv2/image.hpp>
|
||||
#include <exiv2/exif.hpp>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cassert>
|
||||
|
||||
int main(int argc, char* const argv[])
|
||||
|
||||
try {
|
||||
if (argc != 3) {
|
||||
std::cout << "Usage: " << argv[0] << " mode file\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(argv[2]);
|
||||
assert(image.get() != 0);
|
||||
image->readMetadata();
|
||||
|
||||
if (argv[1][0] == 'e') {
|
||||
Exiv2::ExifData &exifData = image->exifData();
|
||||
if (!exifData.empty()) {
|
||||
Exiv2::ExifData::const_iterator exifEnd = exifData.end();
|
||||
for (Exiv2::ExifData::const_iterator i = exifData.begin(); i != exifEnd; ++i) {
|
||||
std::cout << i->tagName() << "\t"
|
||||
<< "0x" << std::setw(4) << std::setfill('0') << std::right
|
||||
<< std::hex << i->tag() << std::dec << "\t"
|
||||
<< i->groupName() << "\t"
|
||||
<< i->typeName() << "\t"
|
||||
<< i->count() << "\t"
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (argv[1][0] == 'i') {
|
||||
Exiv2::IptcData &iptcData = image->iptcData();
|
||||
if (!iptcData.empty()) {
|
||||
Exiv2::IptcData::const_iterator iptcEnd = iptcData.end();
|
||||
for (Exiv2::IptcData::const_iterator i = iptcData.begin(); i != iptcEnd; ++i) {
|
||||
std::cout << i->key() << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (argv[1][0] == 'x') {
|
||||
Exiv2::XmpData &xmpData = image->xmpData();
|
||||
if (!xmpData.empty()) {
|
||||
Exiv2::XmpData::const_iterator xmpEnd = xmpData.end();
|
||||
for (Exiv2::XmpData::const_iterator i = xmpData.begin(); i != xmpEnd; ++i) {
|
||||
std::cout << i->key() << "\t"
|
||||
<< i->typeName() << "\t"
|
||||
<< i->count() << "\t"
|
||||
<< "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
} catch (Exiv2::AnyError& e) {
|
||||
std::cout << "Caught Exiv2 exception '" << e << "'\n";
|
||||
return -1;
|
||||
}
|
||||
Reference in New Issue
Block a user