воскресенье, 8 августа 2010 г.
Похолодало
Сегодня был один из самых прохладных дней за все лето. Днем мой градусник показывал всего +45 на солнце (обычно все +50), а вечером температура упала до +33. На улице можно было дышать и даже гулять.
среда, 4 августа 2010 г.
First results of test - mp3 (id3v2)
./Rammstein - Mann gegen Mann.mp3
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#comment
"[Xakep Online] ";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentCreated
"2005";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentSize
"7096320";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#isPartOf
"";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#lastModified
"1230225080";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#mimeType
"audio/mpeg",
"audio/mpeg";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#title
"Mann gegen Mann";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#url
"./Rammstein - Mann gegen Mann.mp3";
http://www.semanticdesktop.org/ontologies/2007/03/22/nco#creator
"Rammstein";
http://www.semanticdesktop.org/ontologies/2007/03/22/nco#publisher
":nwlrb";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#averageBitrate
"128000";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#channels
"2";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#codec
"MP3";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#fileName
"Rammstein - Mann gegen Mann.mp3";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#sampleRate
"44100";
http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#genre
"Rock";
http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#musicAlbum
":bmqbh";
http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#trackNumber
"2";
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Audio",
"http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#MusicPiece",
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject".
:bmqbh
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#title
"Rosenrot";
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
"http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#MusicAlbum".
:nwlrb
http://www.semanticdesktop.org/ontologies/2007/03/22/nco#fullname
"LAME 3.90.3+mod";
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
"http://www.semanticdesktop.org/ontologies/2007/03/22/nco#Contact".
Generated Mp3EndAnalyzer by Translator:
./Rammstein - Mann gegen Mann.mp3
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentSize
"7096320";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#isPartOf
"";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#lastModified
"1230225080";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#mimeType
"audio/mpeg",
"audio/mpeg";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#title
"Mann gegen Mann";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#url
"./Rammstein - Mann gegen Mann.mp3";
http://www.semanticdesktop.org/ontologies/2007/03/22/nco#publisher
":cdarz";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#fileName
"Rammstein - Mann gegen Mann.mp3";
http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#composer
":hiddq";
http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#genre
"(17)";
http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#lyricist
":owkky";
http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#musicAlbum
":nwlrb";
http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#performer
":bmqbh";
http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#trackNumber
"2";
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
"http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#musicPiece",
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Audio",
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject".
:bmqbh
http://www.semanticdesktop.org/ontologies/2007/03/22/nco#fullname
"Rammstein";
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
"http://www.semanticdesktop.org/ontologies/2007/03/22/nco#contact".
:cdarz
http://www.semanticdesktop.org/ontologies/2007/03/22/nco#fullname
"LAME 3.90.3+mod";
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
"http://www.semanticdesktop.org/ontologies/2007/03/22/nco#contact".
:hiddq
http://www.semanticdesktop.org/ontologies/2007/03/22/nco#fullname
"Rammstein";
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
"http://www.semanticdesktop.org/ontologies/2007/03/22/nco#contact".
:nwlrb
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#title
"Rosenrot";
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
"http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#MusicAlbum".
:owkky
http://www.semanticdesktop.org/ontologies/2007/03/22/nco#fullname
"";
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
"http://www.semanticdesktop.org/ontologies/2007/03/22/nco#contact".
Extractor test:
myvector stores 9 numbers.
Name=Publisher Value = LAME 3.90.3+mod
Name=Title Value = Mann gegen Mann
Name=Publisher Value = Po-X
Name=Genre Value = (17)
Name=Album Value = Rosenrot
Name=Performer Value = Rammstein
Name=Track_number Value = 2
Name=Composer Value = Rammstein
Name=Performer Value = Rammstein
TFL input file:
Format mp3;
Metadata: id3v2, id3v1;
if(id3v2)
{
Created = "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentCreated";
Subject = "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#subject";
Title = "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#title";
Description = "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#description";
Comment = "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#comment";
Artist = "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#creator";
Album = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#musicAlbum";
Genre = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#genre";
Composer = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#composer";
Performer = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#performer";
Liricist = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#lyricist";
Publisher = "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#publisher";
Language = "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#landuage";
Copyright = "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#copyright";
Track_number = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#trackNumber";
Duration = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#duration";
Bitrate = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#averageBitrate";
Samplerate = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#sampleRate";
Codec = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#codec";
Channels = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#channels";
&type = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
&fullname = "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#fullname";
&titleProperty = "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#title";
&albumTrackCount = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#albumTrackCount";
&discNumber = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#setNumber";
&discCount = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#setCount";
&musicClass = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#musicPiece";
&audioClass = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Audio";
&albumClass = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#MusicAlbum";
&contactClass = "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#contact";
Uri a, a1, a2, a3, a4;
T: a1 - type - contactClass;
T: a1 - fullname - Performer;
T: a2 - type - contactClass;
T: a2 - fullname - Publisher;
T: a - titleProperty - Album;
T: a - type - albumClass;
T: a3 - type - contactClass;
T: a3 - fullname - Liricist;
T: a4 - type - contactClass;
T: a4 - fullname - Composer;
D: type - musicClass;
D: type - audioClass;
}
TL input file:
Binary id3v2;
ByteOrder=MSB;
BitOrder=MSB;
StartMetadataKey ID3(offset=0, size=3);
checkKey(ID3)="ID3";
MetadataKey HeaderFlag(start, offset=5, size=1);
MetadataKey ID3_size(start, offset=6, size=4);
MetadataSize=getNumber(ID3_size);
if (getBit(HeaderFlag, 6)==1)
{
MetadataKey ExHeaderSize(start, offset=10, size=4);
MetadataKey FirstFrameID(start, offset=getNumber(ExHeaderSize)+10, size=4);
MetadataSize-=(10+getNumber(ExHeaderSize));
}
else
MetadataKey FirstFrameID(start, offset=10, size=4);
key=FirstFrameID;
while(MetadataSize>0)
{
MetadataKey sizeOfTag(key, offset=0, size=4);
if(getByte(key, 0)==0x00)
{
break;
}
else {
TagSize=getNumber(sizeOfTag);
if((getValue(key)=="TALB" || getValue(key)=="TOAL") && TagSize>1)
{
MetadataKey encoding(key, offset=6, size=1);
SetTag Album(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
if(getValue(key)=="TCOM" && (TagSize>1))
{
MetadataKey encoding(key, offset=6, size=1);
setTag Composer(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
if((getValue(key)=="TYAR" || getValue(key)=="TDRL" || getValue(key)=="TDAT" || getValue(key)=="TDRC") && TagSize>1)
{
MetadataKey encoding(key, offset=6, size=1);
setTag Created(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
if(getValue(key)=="TRCK" && TagSize>1)
{
MetadataKey encoding(key, offset=6, size=1);
setTag Track_number(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
if(getValue(key)=="TIT2" && TagSize>1)
{
MetadataKey encoding(key, offset=6, size=1);
setTag Title(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
if(getValue(key)=="TIT1" && TagSize>1)
{
MetadataKey encoding(key, offset=6, size=1);
setTag Subject(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
if(getValue(key)=="TIT3" && TagSize>1)
{
MetadataKey encoding(key, offset=6, size=1);
setTag Description(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
if((getValue(key)=="TPE1" || getValue(key)=="TPE2" || getValue(key)=="TPE3" || getValue(key)=="TPE4")&& TagSize>1)
{
MetadataKey encoding(key, offset=6, size=1);
setTag Performer(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
if((getValue(key)=="TPUB" || getValue(key)=="TENC")&& TagSize>1)
{
MetadataKey encoding(key, offset=6, size=1);
setTag Publisher(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
if(getValue(key)=="TEXT" && TagSize>1)
{
MetadataKey encoding(key, offset=6, size=1);
setTag Liricist(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
if(getValue(key)=="TCON" && TagSize>1)
{
MetadataKey encoding(key, offset=6, size=1);
setTag Genre(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
if(getValue(key)=="TLAN" && TagSize>1)
{
MetadataKey encoding(key, offset=6, size=1);
setTag Language(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
if(getValue(key)=="TCOP" && TagSize>1)
{
MetadataKey encoding(key, offset=6, size=1);
setTag Copyright(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
if(getValue(key)=="TLEN" && TagSize>1)
{
MetadataKey encoding(key, offset=6, size=1);
setTag Duration(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
MetadataSize-=(10+getNumber(sizeOfTag));
shift(key, 6+getNumber(sizeOfTag));
}
}
First results of test - png
./2.png
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentSize
"145620";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#isPartOf
"";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#lastModified
"1278429356";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#mimeType
"image/png",
"image/png";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#url
"./2.png";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#colorDepth
"32";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#fileName
"2.png";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height
"415";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#interlaceMode
"None";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width
"800";
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#RasterImage",
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject".
Generated PngEndAnalyzer by Translator:
./2.png
http://freedesktop.org/standards/xesam/1.0/core#compressionAlgorithm
"6";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentSize
"145620";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#isPartOf
"";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#lastModified
"1278429356";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#mimeType
"image/png",
"image/png";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#url
"./2.png";
http://www.semanticdesktop.org/ontologies/2007/03/22/nco#creator
":nwlrb";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#colorDepth
"32";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#fileName
"2.png";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height
"415";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#interlaceMode
"0";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width
"800";
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#RasterImage",
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject".
:nwlrb
http://www.semanticdesktop.org/ontologies/2007/03/22/nco#fullname
"";
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
"http://www.semanticdesktop.org/ontologies/2007/03/22/nco#Contact".
Extractor test:
myvector stores 7 numbers.
Name=Width Value = 800
Name=Height Value = 415
Name=Color_type Value = 8
Name=Compression_method Value = 6
Name=ColorDept Value = 32
Name=Filter_method Value = 0
Name=Interlace_method Value = 0
TFL input file:
Format Png;
Metadata: PngChunk;
if(PngChunk)
{
Width = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width";
Height = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height";
ColorDepth= "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#colorDepth";
Compression_method = "http://freedesktop.org/standards/xesam/1.0/core#compressionAlgorithm";
Interlace_method = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#interlaceMode";
Title="http://www.semanticdesktop.org/ontologies/2007/01/19/nie#title";
Author="http://www.semanticdesktop.org/ontologies/2007/03/22/nco#creator";
Description="http://www.semanticdesktop.org/ontologies/2007/01/19/nie#description";
Copyright="http://www.semanticdesktop.org/ontologies/2007/01/19/nie#copyright";
Creation_time="http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentCreated";
Software="http://www.semanticdesktop.org/ontologies/2007/01/19/nie#generator";
Dislaimer="http://www.semanticdesktop.org/ontologies/2007/01/19/nie#disclaimer";
Warning="http://www.semanticdesktop.org/ontologies/2007/01/19/nie#comment";
Source="http://www.semanticdesktop.org/ontologies/2007/05/10/nexif#model";
Comment="http://www.semanticdesktop.org/ontologies/2007/01/19/nie#comment";
&type="http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
&fullname="http://www.semanticdesktop.org/ontologies/2007/03/22/nco#fullname";
&contactClass= "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#Contact";
&rasterImage = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#RasterImage";
Uri a;
T: a - type - contactClass;
T: a - fullname - Author;
D: type - rasterImage;
}
TL input file:
Binary PngChunk;
ByteOrder=MSB;
BitOrder=MSB;
StartMetadataKey MagicHex(offset=0, size=8);
checkKey(MagicHex)=0x89504e470d0a1a0a;
MetadataKey length(MagicHex, offset=0, size=4);
MetadataKey chunkname(length, offset=0, size=4);
MetadataKey data(chunkname, offset=0, size=getNumber(length));
MetadataKey crc(data, offset=0, size=4);
while(getValue(chunkname)!="IEND")
{
if(getValue(chunkname)=="IHDR")
{
MetadataKey width(chunkname, offset=0, size=4);
SetTag Width(getNumber(width));
MetadataKey height(width, offset=0, size=4);
SetTag Height(getNumber(height));
MetadataKey ColorType(height, offset=0, size=1);
SetTag Color_type(getNumber(ColorType));
MetadataKey Compression(ColorType, offset=0, size=1);
SetTag Compression_method(getNumber(Compression));
if(getNumber(Compression)==2)
{
n=3*getNumber(ColorType);
SetTag ColorDepth(n);
}
if(getNumber(Compression)==4)
{
n=2*getNumber(ColorType);
SetTag ColorDepth(n);
}
if(getNumber(Compression)==6)
{
n=4*getNumber(ColorType);
SetTag ColorDepth(n);
}
MetadataKey Filter(Compression, offset=0, size=1);
SetTag Filter_method(getNumber(Filter));
MetadataKey Interlace(Filter, offset=0, size=1);
SetTag Interlace_method(getNumber(Interlace));
}
if(getValue(chunkname)=="tEXt")
{
keyword=getStringByLink(chunkname,offset=0);
n=getLength(keyword);
datatext=getStringByLink(chunkname,offset=n+1);
if(keyword=="Title") SetTag Title(datatext);
if(keyword=="Author") SetTag Author(datatext);
if(keyword=="Description") SetTag Description(datatext);
if(keyword=="Copyright") SetTag Copyright(datatext);
if(keyword=="Creation Time") SetTag Creation_time(datatext);
if(keyword=="Software") SetTag Software(datatext);
if(keyword=="Disclaimer") SetTag Disclaimer(datatext);
if(keyword=="Warning") SetTag Warning(datatext);
if(keyword=="Source") SetTag Source(datatext);
if(keyword=="Comment") SetTag Comment(datatext);
}
oldlength=getNumber(length);
shift(length, 8+oldlength);
newlength=getNumber(length);
shift(chunkname, 8+oldlength);
shift(data, 12);
shift(crc, 8+newlength);
}
вторник, 3 августа 2010 г.
First results of test - bmp
./test.bmp
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentSize
"921654";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#isPartOf
"";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#lastModified
"1280740186";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#mimeType
"image/bmp",
"image/bmp";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#url
"./test.bmp";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#colorDepth
"24";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#fileName
"test.bmp";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height
"480";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width
"640";
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#RasterImage",
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject".
Generated bmpEndAnalyzer by Translator:
./test.bmp
http://freedesktop.org/standards/xesam/1.0/core#formatSubtype
"Windows Bitmap";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentSize
"921654";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#isPartOf
"";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#lastModified
"1280740186";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#mimeType
"image/bmp",
"image/bmp";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#url
"./test.bmp";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#colorDepth
"24";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#fileName
"test.bmp";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height
"480";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width
"640";
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#RasterImage",
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject".
TFL input file:
Format Bmp;
Metadata: BmpInfoHeader;
if(BmpInfoHeader)
{
Type = "http://freedesktop.org/standards/xesam/1.0/core#formatSubtype";
Compression = "http://freedesktop.org/standards/xesam/1.0/core#compressionAlgorithm";
Width = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width";
Height = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height";
Color = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#colorDepth";
&rdftype = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
&rasterImage = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#RasterImage";
D: rdftype - rasterImage;
}
TL input file:
Binary BmpInfoHeader;
StartMetadataKey BM(offset=0, size=2);
checkKey(BM)="BM";
if(getString(BM)=="BM") SetTag Type("Windows Bitmap");
MetadataKey Width(start, offset=18, size=4);
SetTag Width(getNumber(Width));
MetadataKey Height(Width, offset=0, size=4);
SetTag Height(getNumber(Height));
MetadataKey BitCount(Height, offset=2, size=2);
SetTag Color(getNumber(BitCount));
MetadataKey Compression(BitCount, offset=0, size=4);
if(getNumber(Compression)==0) setTag Campression("None");
if(getNumber(Compression)==1) setTag Campression("RLE 8bit/pixel");
if(getNumber(Compression)==2) setTag Campression("RLE 4bit/pixel");
if(getNumber(Compression)==3) setTag Campression("Bit fields");
воскресенье, 1 августа 2010 г.
И даже работает...
Старый парсер выдает это для Png:
./test.png
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentSize
"49237";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#isPartOf
"";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#lastModified
"1280592673";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#mimeType
"image/png",
"image/png";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#url
"./test.png";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#colorDepth
"8";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#fileName
"test.png";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height
"450";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#interlaceMode
"None";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width
"600";
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#RasterImage",
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject".
Новый это:
./test.png
http://freedesktop.org/standards/xesam/1.0/core#compressionAlgorithm
"3";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentSize
"49237";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#isPartOf
"";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#lastModified
"1280592673";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#mimeType
"image/png",
"image/png";
http://www.semanticdesktop.org/ontologies/2007/01/19/nie#url
"./test.png";
http://www.semanticdesktop.org/ontologies/2007/03/22/nco#creator
":nwlrb";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#colorDepth
"8";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#fileName
"test.png";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height
"450";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#interlaceMode
"0";
http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width
"600";
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
"http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#FileDataObject".
:nwlrb
http://www.semanticdesktop.org/ontologies/2007/03/22/nco#fullname
"";
http://www.w3.org/1999/02/22-rdf-syntax-ns#type
"http://www.semanticdesktop.org/ontologies/2007/03/22/nco#Contact".
Не в десятку, но это уже минус входного файла — нужно сесть и все по-человечески доделать. Есть еще недоделки(большие и не очень) и баги, но тут два позитивных момента 1) я о них знаю 2) по ходу все можно доделать/исправить — не смертельно. Ура, начинаем тесты!!!!
четверг, 29 июля 2010 г.
TFL examples - mp3
Metadata: id3v2, id3v1;
if(id3v2)
{
created = "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#contentCreated";
subject = "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#subject";
title = "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#title";
description = "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#description";
comment = "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#comment";
artist = "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#creator";
album = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#musicAlbum";
genre = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#genre";
composer = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#composer";
performer = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#performer";
liricist = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#lyricist";
publisher = "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#publisher";
language = "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#landuage";
copyright = "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#copyright";
trackNumber = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#trackNumber";
duration = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#duration";
bitrate = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#averageBitrate";
samplerate = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#sampleRate";
codec = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#codec";
channels = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#channels";
&type = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
&fullname = "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#fullname";
&titleProperty = "http://www.semanticdesktop.org/ontologies/2007/01/19/nie#title";
&albumTrackCount = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#albumTrackCount";
&discNumber = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#setNumber";
&discCount = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#setCount";
&musicClass = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#musicPiece";
&audioClass = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Audio";
&albumClass = "http://www.semanticdesktop.org/ontologies/2009/02/19/nmm#MusicAlbum";
&contactClass = "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#contact";
Uri a, a1, a2, a3, a4, a5;
T: a1 - type - contactClass;
T: a1 - fullname - performer;
T: a2 - type - contactClass;
T: a2 - fullname - publisher;
T: a - titleProperty - album;
T: a - type - albumClass;
T: a3 - type - contactClass;
T: a3 - fullname - liricist;
T: a4 - type - contactClass;
T: a4 - fullname - composer;
T: a5- albumTrackCount - trackNumber;
}
среда, 14 июля 2010 г.
The first results
The goal of project it is a creating of parsers generator for Strigi. Input of generator it is two file. First – describing of metadata format, second – mapping (it is shows how is related tags of metadata and ontology). I separated it for two reasons: 1) one format can has two or more type of metadata (different version of metadata format or new universal formal like xmp) 2) testing grammar really simpler when it is separated.
My first step it is developing of a language for describing metadata format and language for describing the mapping. I created language base on png, exif, id3, vorbis comment and xmp (last 2 a little bit). The language for metadata it is Tag language (TL – short name) and it is contain main item MetadataKey. This is example for png (file pngchunk.txt)
/* key word Binary means that description starts and MetadataKey is defined by offset and size. I planned to expand the language for finding tag by key word and if it necessary it will start by Text key word.
PngChung it name and prefix for future class of extractor */
1 Binary PngChunk;
2
/* ByteOrder и BitOrder it is order a byte and bit. If it is not defined it will LSB.*/
3 ByteOrder=MSB;
4 BitOrder=MSB;
5
/*StartMetadataKey – it is the first key that define type of metadata. Offset for this key from beginning of file. */
6 StartMetadataKey IHDR(offset=12, size=4);
/* Checking value of key. It is required for StartMetadataKey and can to check a string or a hex value.*/
7 checkKey(IHDR)="IHDR";
8
/*MetadataKey –region that contains tag. It can defined by base key (or key word “start”), offset and size. If first parameter is “start” then offset for key from beginning of file. If first parameter is another MetadataKey the offset for key from end base key. */
9 MetadataKey width(IHDR, offset=0, size=4);
/* Creating tag with name “Widht” and with number value that is saved by MetadataKey. Currently I can get only string and int32 types. But I will expand it for double and int64 in future. */
10 SetTag Width(getNumber(width));
11
12 MetadataKey height(width, offset=0, size=4);
13 SetTag Height(getNumber(height));
14
15 MetadataKey ColorType(height, offset=0, size=1);
16 SetTag Color_type(getNumber(ColorType));
17
18 MetadataKey Compression(ColorType, offset=0, size=1);
19 SetTag Compression_method(getNumber(Compression));
20
21 MetadataKey Filter(Compression, offset=0, size=1);
22 SetTag Filter_method(getNumber(Filter));
23
24 MetadataKey Interlace(Filter, offset=0, size=1);
25 SetTag Interlace_method(getNumber(Interlace));
Additional functions:
getNumberByLink(key, offset, size) or getNumberByLink(offset, size) – get number by offset and size. If key is not defined offset from beginning of file.
getStringByLink(key, offset, size), getStringByLink( offset, size), getStringByLink(key, offset), getStringByLink( offset) – get string by offset. If key is not defined offset from beginning of file. If size is not defined it get all until symbol end of string or end of file.
getValueByLink(key, offset, size), getValueByLink(offset, size) – get data without type conversion. 9never used but exist).
All this function it is short variant of MetadataKey + getValue (getString, getNumber)
Functions:
shift(key,n) – moved key on n steps .
getBit(key,n) – get bit number n inside key.
getByte(key, n) – get byte number n inside key.
(You can fine examples of using these functions in files id3tag.txt и exif.txt)
And of course I implemented loop (currently only wile) and if- else
Language for mapping I called – Tiny Format language or shot TFL. For png example (file png_triplex.txt):
/* Format it is key word. After this key word follow prefix for EndAnalyzer class.*/
1 Format Png;
2
/* Metadata – key word defined list of name of formats metadata . Png has only one type of metadata – it PngChunk*/
3 Metadata: PngChunk;
4
5
/* It checking StartMetadataKey. If it is true then triplex creates according to mapping inside this if .*/
6 if(PngChunk)
7 {
/* The name of tag here has to be same name of tag that was been created by setTag function in file pngchunk.txt */
8 With = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width";
9 Height = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height";
10 Color_type= "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#colorDepth";
11 Compression_method = "http://freedesktop.org/standards/xesam/1.0/core#compressionAlgorithm";
12 Interlace_method = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#interlaceMode";
13
14 }
Second step it is writing of translator for TFL and TL languages. Each translator contains scanner, parser and generator of c++ code. For developing of scanner and parser I used coco/r generator. It doesn’t have tool for testing and debug grammar (like AntlrWorks for antlr) but it has more clear documentation. The result of working of the TL translator it is class extractor which extracts tag and saves it in vector of Tag.
/*files PngChunkextractor.h и PngChunkextractor.cpp after working TL translator*/
1 #ifndef PngChunkExtractor_H_
2 #define PngChunkExtractor_H_
3 #include "MetadataKey.h"
4 #include "Tag.h"
5 #include "MetadataFunc.h"
6 #include
7 #include
8
9
10 class PngChunkExtractor {
11 public:
12 PngChunkExtractor(std::ifstream _is) {is=_is;}
13 std::vector
14 bool toCheck();
15 private:
16 std::ifstream is;
17 };
18 #endif
The result of working of the TFL translator it is class inheritance from StreamEndAnalyzer class.
/* files Pngendanalyzer.h и Pngendanalyzer.cpp after working of TFL translator */
1 #include "Pngendanalyzer.h"
2 #include
3
4
5 void PngEndAnalyzerFactory::registerFields(FieldRegister& reg) {
6 RF["PngChunk_Color_typeField"]=reg.registerField("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#colorDepth");
7 addField("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#colorDepth");
8 RF["PngChunk_Compression_methodField"]=reg.registerField("http://freedesktop.org/standards/xesam/1.0/core#compressionAlgorithm");
9 addField("http://freedesktop.org/standards/xesam/1.0/core#compressionAlgorithm");
10 RF["PngChunk_HeightField"]=reg.registerField("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height");
11 addField("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height");
12 RF["PngChunk_Interlace_methodField"]=reg.registerField("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#interlaceMode");
13 addField("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#interlaceMode");
14 RF["PngChunk_WithField"]=reg.registerField("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width");
15 addField("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width");
16 }
17
18
19 signed char PngEndAnalyzer::analyze(AnalysisResult& as, InputStream* in) {
20 int flag=-1;
21 PngChunkExtractor PngChunk(InputStream* in);
22 if(PngChunk.toCheck()){
23 std::vector
24 flag=0;
25 for(int i=0; i
34 case 2: as.addValue(factory->getField(name), t.getString()); break;
35 }
36 name.clear();
37 }
38 return flag;
39 }
Next steps:
1. To rewrite the MetadataKey for working with InputStream (I think I have done it, but didn’t test well)
2. To add opportunity in TL language to get double type.
3. To add in TFL triplex creating.
4. To add the message about declaration error, encoding and another things that I missed.
Link:
http://gitorious.org/strigi/strigi-grammar/trees/master/Translator
вторник, 13 июля 2010 г.
Экватор - Первые итоги
Экватор - Первые итоги
Итак, цель проекта - написать генератор парсеров для Strigi. Т.е. на вход подается описание формата метаданных и описание того как соотносятся теги и свойства онтологий, а на выходе получался бы парсер который бы извлекал теги и создавал бы триплексы. С чего я начала:
1. С чтения документации форматов метаданных (т.е. только ту часть которая описывает метаданные). Пока осилила только png, exif(jpg), id3(mp3), немного Vorbis comment (flac) и xmp. После этого увлекательного чтения нужно было придумать свой язык для описания метаданных. Вот это как раз было самым сложным этапом работы и прежде чем прейди к какому-то жизнеспособному решению я сделала штуки 3 неудачных попытки. Язык я назвала Tag language или сокращенно TL–оригинально :) И ключевым элементом в нем стал MetadataKey. На примере png (файл pngtag.txt):
/* Ключевое слово Binary означает старт + обозначает способ задания MetadataKey по смещения и размеру (планируется что дальше я расширю язык для извлечения тегов по ключевому слову, тогда для такого формата описание будет начинаться с ключевого слова Text). PngChunk – имя нашего описания, а так же префикс для будущего класса.*/
1 Binary PngChunk;
2
/* ByteOrder и BitOrder порядок байтов и битов. Если эти константы не заданы, то по умолчанию они будут равны LSB.*/
3 ByteOrder=MSB;
4 BitOrder=MSB;
5
/*StartMetadataKey – это самый первый тег который определяет что те самые метаданные. offset для этого ключа задается всегда от начала файла. */
6 StartMetadataKey IHDR(offset=12, size=4);
/*Проверка значения ключа. Для StartMetadataKey –обязательна и может проверять значение строки (как указано ниже) или hex.*/
7 checkKey(IHDR)="IHDR";
8
/*MetadataKey –область в которой хранятся нужные нам данные. Задается тремя параметрами:
другой MetadataKey или ключевой слово start, означающее начало файла. Этот параметр указывает точку относительно которой будет считаться смещение. В случае если указан MetadataKey – это конец ключа
offset - смещение
size – размер ключа*/
9 MetadataKey width(IHDR, offset=0, size=4);
/*Создаем тег с именем Widht с целочисленным значением, которое храниться в MetadataKey*/
10 SetTag Width(getNumber(width));
11
12 MetadataKey height(width, offset=0, size=4);
13 SetTag Height(getNumber(height));
14
15 MetadataKey ColorType(height, offset=0, size=1);
16 SetTag Color_type(getNumber(ColorType));
17
18 MetadataKey Compression(ColorType, offset=0, size=1);
19 SetTag Compression_method(getNumber(Compression));
20
21 MetadataKey Filter(Compression, offset=0, size=1);
22 SetTag Filter_method(getNumber(Filter));
23
24 MetadataKey Interlace(Filter, offset=0, size=1);- 25 SetTag Interlace_method(getNumber(Interlace));
Еще есть функции getNumberByLink(key, offset, size) или getNumberByLink(offset, size) – берет целое число по смещению и размеру. Если key не задан, то смещение считается от начала файла.
getStringByLink(key, offset, size), getStringByLink( offset, size), getStringByLink(key, offset), getStringByLink( offset) – берет строку по смещению. Если key не задан, то считает смещение от начала файла. Если size не задан, то берет все пока не встретит знак конца строки или не дойдет до конца файла.
getValueByLink(key, offset, size), getValueByLink(offset, size) –берет значение без приведения к типу. (пока нигде не используется). Все эти функции короткая запись MetadataKey + getValue
Функция shift(key,n) – сдвигает ключ key на n позиций.
getBit(key,n) – берет n-ый бит в ключе key.
getByte(key, n) – берет n-ый байт в ключе key.
Примеры использования в файлах id3tag.txt и exif.txt
Так же есть цикл (пока только while) и условия(if - else).
Язык для описания соответствия между тегами и онтологией я назвала Tiny Format Language – TFL. Опять же для png (файл png_triplex.txt):
- /* Format ключевое слово, после которого идет префикс для имени класса - парсера*/
1 Format Png;
2
/* Metadata – ключевое слово, за которым следует список описаний метаданных. У png только один «вид» метаданных, а у jpg например может быть xmp или exif */
3 Metadata: PngChunk;
4
5
/*Эта проверка означает, что если мы нашли StartMetadataKey и он прошел проверку, то мы сопоставляем тери и свойства в онтологиях.*/
6 if(PngChunk)
7 {
/* Имя тега в этом описании должно соответствовать имени тега заданным при помощи функции setTag в файле pngtag.txt */
8 With = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width";
9 Height = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height";
10 Color_type= "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#colorDepth";
11 Compression_method = "http://freedesktop.org/standards/xesam/1.0/core#compressionAlgorithm";
12 Interlace_method = "http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#interlaceMode";
13 - 14 }
2. Далее для этих двух языков нужно было написать трансляторы. Каждый транслятор состоит из сканера, парсера и генератора кода. Для создания сканера и парсера я воспользовалась генератором coco/r. Вообще то сначала я планировала работать с antlr, уж очень у них удобная среда разработки и тестирования грамматики AntlrWork. Но отношения с этим инструментом не сложились, вернее не сложились отношения с его документацией, и я решила реализовывать транслятор при помощи coco.
Вот что получается для png:
- /*файлы PngChunkextractor.h и PngChunkextractor.cpp результат работы TL транслятора*/
1 #ifndef PngChunkExtractor_H_
2 #define PngChunkExtractor_H_
3 #include "MetadataKey.h"
4 #include "Tag.h"
5 #include "MetadataFunc.h"
6 #include
7 #include
8
9
10 class PngChunkExtractor {
11 public:
12 PngChunkExtractor(std::ifstream _is) {is=_is;}
13 std::vectortoExtract();
14 bool toCheck();
15 private:
16 std::ifstream is;
17 };
18 #endif
/* файлы Pngendanalyzer.h и Pngendanalyzer.cpp – результат работы TFL - транслятора */
1 #include "Pngendanalyzer.h"
2 #include
3
4
5 void PngEndAnalyzerFactory::registerFields(FieldRegister& reg) {
6 RF["PngChunk_Color_typeField"]=reg.registerField("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#colorDepth");
7 addField("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#colorDepth");
8 RF["PngChunk_Compression_methodField"]=reg.registerField("http://freedesktop.org/standards/xesam/1.0/core#compressionAlgorithm");
9 addField("http://freedesktop.org/standards/xesam/1.0/core#compressionAlgorithm");
10 RF["PngChunk_HeightField"]=reg.registerField("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height");
11 addField("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#height");
12 RF["PngChunk_Interlace_methodField"]=reg.registerField("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#interlaceMode");
13 addField("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#interlaceMode");
14 RF["PngChunk_WithField"]=reg.registerField("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width");
15 addField("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#width");
16 }
17
18
19 signed char PngEndAnalyzer::analyze(AnalysisResult& as, InputStream* in) {
20 int flag=-1;
21 PngChunkExtractor PngChunk(InputStream* in);
22 if(PngChunk.toCheck()){
23 std::vectortag_v=PngChunk.toExtract();
24 flag=0;
25 for(int i=0; igetField(name), t.getNumber()); break;
34 case 2: as.addValue(factory->getField(name), t.getString()); break;
35 }
36 name.clear();
37 }
38 return flag; - 39 }
Что дальше:
1. Подправить классы для работы с потоками Strigi (кажется почти доделала)
2. Добавить в TL возможность брать значения типа double
3. Добавить в TFL возможность создавать триплексы
4. Дописать вывод ошибок декларирования переменных, работу с кодировкой и прочие нюансы, которые я упустила.
5. Доделать пример с exif, png, id3, которые бы иллюстрировали все возможности языка.
Ссылка на исходники:
http://gitorious.org/strigi/strigi-grammar/trees/master/Translator
четверг, 1 июля 2010 г.
Translator
(It haven't been finished yet.)
Binary Exif;
ByteOrder=LSB;
BitOrder=MSB;
StartMetadataKey APP1_Markeer(offset=2, size=2);
checkKey(APP1_Markeer)=0xFFE1;
MetadataKey APP1(start, offset=2, size=10);
MetadataKey IFD_Offset(APP1, offset=4, size=4);
MetadataKey CountOfTag(APP1, offset=getNumber(IFD_Offset), size=2);
MetadataKey FirstTagID(CountOfTag, offset=0, size=2);
TagID=FirstTagID;
count=getNumber(CountOfTag);
while(count>0)
{
MetadataKey Type(TagID, offset=0, size=2);
MetadataKey ValueOffset(TagID, offset=6, size=4);
if(getValue(TagID)==0x010E)
{
if(getValue(Type)==2) {SetTag Image_description(getStringByLink(APP1, offset=getNumber(ValueOffset)));}
if(getValue(Type)==5) {SetTag Image_description(getStringByLink(TagID, offset=getNumber(ValueOffset), size=8));}
if(getValue(Type)==1 || (getValue(Type)==3) || (getValue(Type)==4)) {SetTag Image_description(getString(ValueOffset));}
}
if(getValue(TagID)==0x010F)
{
if(getValue(Type)==2) {SetTag Make(getStringByLink(APP1, offset=getNumber(ValueOffset)));}
if(getValue(Type)==5) {SetTag Make(getStringByLink(TagID, offset=getNumber(ValueOffset), size=8));}
if(getValue(Type)==1 || (getValue(Type)==3) || (getValue(Type)==4)) {SetTag Make(getString(ValueOffset));}
}
if(getValue(TagID)==0x0110)
{
if(getValue(Type)==2) {SetTag Model(getStringByLink(APP1, offset=getNumber(ValueOffset)));}
if(getValue(Type)==5) {SetTag Model(getStringByLink(TagID, offset=getNumber(ValueOffset), size=8));}
if(getValue(Type)==1 || (getValue(Type)==3) || (getValue(Type)==4)) {SetTag Model(getString(ValueOffset));}
}
if(getValue(TagID)==0x0112)
{
if(getValue(Type)==2) {SetTag Orientation(getStringByLink(APP1, offset=getNumber(ValueOffset)));}
if(getValue(Type)==5) {SetTag Orientation(getNumberByLink(TagID, offset=getNumber(ValueOffset), size=8));}
if(getValue(Type)==1 || (getValue(Type)==3) || (getValue(Type)==4)) {SetTag Orientation(getNumber(ValueOffset));}
}
if(getValue(TagID)==0x011A)
{
if(getValue(Type)==2) {SetTag XResolution(getStringByLink(APP1, offset=getNumber(ValueOffset)));}
if(getValue(Type)==5) {SetTag XResolution(getNumberByLink(TagID, offset=getNumber(ValueOffset), size=8));}
if(getValue(Type)==1 || (getValue(Type)==3) || (getValue(Type)==4)) {SetTag XResolution(getNumber(ValueOffset));}
}
if(getValue(TagID)==0x011B)
{
if(getValue(Type)==2) {SetTag YResolution(getStringByLink(APP1, offset=getNumber(ValueOffset)));}
if(getValue(Type)==5) {SetTag YResolution(getNumberByLink(TagID, offset=getNumber(ValueOffset), size=8));}
if(getValue(Type)==1 || (getValue(Type)==3) || (getValue(Type)==4)) {SetTag YResolution(getNumber(ValueOffset));}
}
if(getValue(TagID)==0x0132)
{
if(getValue(Type)==2) {SetTag DateTime(getStringByLink(APP1, offset=getNumber(ValueOffset)));}
if(getValue(Type)==5) {SetTag DateTime(getStringByLink(TagID, offset=getNumber(ValueOffset), size=8));}
if(getValue(Type)==1 || (getValue(Type)==3) || (getValue(Type)==4)) {SetTag DateTime(getString(ValueOffset));}
}
count-=1;
shift(TagID,10);
}
Is generated parser
#include "MetadataKey.h"
#include "Tag.h"
#include "MetadataFunc.h"
#include
#include
int main(){
std::ifstream is;
int DefaultByteOrder=ByteOrderLSB;
int DefaultBitOrder=BitOrderMSB;
MetadataKey APP1;
MetadataKey CountOfTag;
MetadataKey FirstTagID;
MetadataKey IFD_Offset;
MetadataKey TagID;
MetadataKey Type;
MetadataKey ValueOffset;
int count;
std::vector
is.open ("test.mp3", std::ifstream::in | std::ifstream::binary);
if (is.good()) {
MetadataKey APP1_Markeer(is);
APP1_Markeer.setOffset(2);
APP1_Markeer.setSize(2);
if(!checkKey(APP1_Markeer,0xFFE1)) return -1;
APP1.setStream(is);
APP1.setOffset(2);
APP1.setSize(10);
IFD_Offset.setStream(is);
IFD_Offset.setBaseKey(APP1);
IFD_Offset.setOffset(4);
IFD_Offset.setSize(4);
CountOfTag.setStream(is);
CountOfTag.setBaseKey(APP1);
CountOfTag.setOffset(IFD_Offset.getNumber(DefaultByteOrder));
CountOfTag.setSize(2);
FirstTagID.setStream(is);
FirstTagID.setBaseKey(CountOfTag);
FirstTagID.setOffset(0);
FirstTagID.setSize(2);
TagID=FirstTagID;
count=CountOfTag.getNumber(DefaultByteOrder);
while(count>0){
Type.setStream(is);
Type.setBaseKey(TagID);
Type.setOffset(0);
Type.setSize(2);
ValueOffset.setStream(is);
ValueOffset.setBaseKey(TagID);
ValueOffset.setOffset(6);
ValueOffset.setSize(4);
if(TagID.getValue()==0x010E){
if(Type.getValue()==2){
Tag t0;
t0.setName("Image_description" );
t0.setValue(getCString(APP1,ValueOffset.getNumber(DefaultByteOrder)));
TagArray.push_back(t0);
}
if(Type.getValue()==5){
Tag t1;
t1.setName("Image_description" );
t1.setValue(getStringByLink(TagID,ValueOffset.getNumber(DefaultByteOrder),8));
TagArray.push_back(t1);
}
if(Type.getValue()==1||(Type.getValue()==3)||(Type.getValue()==4)){
Tag t2;
t2.setName("Image_description" );
t2.setValue(ValueOffset.getString());
TagArray.push_back(t2);
}
}
if(TagID.getValue()==0x010F){
if(Type.getValue()==2){
Tag t3;
t3.setName("Make" );
t3.setValue(getCString(APP1,ValueOffset.getNumber(DefaultByteOrder)));
TagArray.push_back(t3);
}
if(Type.getValue()==5){
Tag t4;
t4.setName("Make" );
t4.setValue(getStringByLink(TagID,ValueOffset.getNumber(DefaultByteOrder),8));
TagArray.push_back(t4);
}
if(Type.getValue()==1||(Type.getValue()==3)||(Type.getValue()==4)){
Tag t5;
t5.setName("Make" );
t5.setValue(ValueOffset.getString());
TagArray.push_back(t5);
}
}
if(TagID.getValue()==0x0110){
if(Type.getValue()==2){
Tag t6;
t6.setName("Model" );
t6.setValue(getCString(APP1,ValueOffset.getNumber(DefaultByteOrder)));
TagArray.push_back(t6);
}
if(Type.getValue()==5){
Tag t7;
t7.setName("Model" );
t7.setValue(getStringByLink(TagID,ValueOffset.getNumber(DefaultByteOrder),8));
TagArray.push_back(t7);
}
if(Type.getValue()==1||(Type.getValue()==3)||(Type.getValue()==4)){
Tag t8;
t8.setName("Model" );
t8.setValue(ValueOffset.getString());
TagArray.push_back(t8);
}
}
if(TagID.getValue()==0x0112){
if(Type.getValue()==2){
Tag t9;
t9.setName("Orientation" );
t9.setValue(getCString(APP1,ValueOffset.getNumber(DefaultByteOrder)));
TagArray.push_back(t9);
}
if(Type.getValue()==5){
Tag t10;
t10.setName("Orientation" );
t10.setValue(getNumberByLink(DefaultByteOrder, TagID,ValueOffset.getNumber(DefaultByteOrder),8));
TagArray.push_back(t10);
}
if(Type.getValue()==1||(Type.getValue()==3)||(Type.getValue()==4)){
Tag t11;
t11.setName("Orientation" );
t11.setValue(ValueOffset.getNumber(DefaultByteOrder));
TagArray.push_back(t11);
}
}
if(TagID.getValue()==0x011A){
if(Type.getValue()==2){
Tag t12;
t12.setName("XResolution" );
t12.setValue(getCString(APP1,ValueOffset.getNumber(DefaultByteOrder)));
TagArray.push_back(t12);
}
if(Type.getValue()==5){
Tag t13;
t13.setName("XResolution" );
t13.setValue(getNumberByLink(DefaultByteOrder, TagID,ValueOffset.getNumber(DefaultByteOrder),8));
TagArray.push_back(t13);
}
if(Type.getValue()==1||(Type.getValue()==3)||(Type.getValue()==4)){
Tag t14;
t14.setName("XResolution" );
t14.setValue(ValueOffset.getNumber(DefaultByteOrder));
TagArray.push_back(t14);
}
}
if(TagID.getValue()==0x011B){
if(Type.getValue()==2){
Tag t15;
t15.setName("YResolution" );
t15.setValue(getCString(APP1,ValueOffset.getNumber(DefaultByteOrder)));
TagArray.push_back(t15);
}
if(Type.getValue()==5){
Tag t16;
t16.setName("YResolution" );
t16.setValue(getNumberByLink(DefaultByteOrder, TagID,ValueOffset.getNumber(DefaultByteOrder),8));
TagArray.push_back(t16);
}
if(Type.getValue()==1||(Type.getValue()==3)||(Type.getValue()==4)){
Tag t17;
t17.setName("YResolution" );
t17.setValue(ValueOffset.getNumber(DefaultByteOrder));
TagArray.push_back(t17);
}
}
if(TagID.getValue()==0x0132){
if(Type.getValue()==2){
Tag t18;
t18.setName("DateTime" );
t18.setValue(getCString(APP1,ValueOffset.getNumber(DefaultByteOrder)));
TagArray.push_back(t18);
}
if(Type.getValue()==5){
Tag t19;
t19.setName("DateTime" );
t19.setValue(getStringByLink(TagID,ValueOffset.getNumber(DefaultByteOrder),8));
TagArray.push_back(t19);
}
if(Type.getValue()==1||(Type.getValue()==3)||(Type.getValue()==4)){
Tag t20;
t20.setName("DateTime" );
t20.setValue(ValueOffset.getString());
TagArray.push_back(t20);
}
}
count-=1;
TagID.setOffset(10+TagID.getSize());
}
}
return 0;
}
среда, 30 июня 2010 г.
Translator
Description of png file
Binary PNG;
ByteOrder=MSB;
BitOrder=MSB;
StartMetadataKey IHDR(offset=12, size=4);
checkKey(IHDR)="IHDR";
MetadataKey width(IHDR, offset=0, size=4);
SetTag Width(getNumber(width));
MetadataKey height(width, offset=0, size=4);
SetTag Height(getNumber(height));
MetadataKey ColorType(height, offset=0, size=1);
SetTag Color_type(getNumber(ColorType));
MetadataKey Compression(ColorType, offset=0, size=1);
SetTag Compression_method(getNumber(Compression));
MetadataKey Filter(Compression, offset=0, size=1);
SetTag Filter_method(getNumber(Filter));
MetadataKey Interlace(Filter, offset=0, size=1);
SetTag Interlace_method(getNumber(Interlace));
Is generated parser
#include "MetadataKey.h"
#include "Tag.h"
#include "MetadataFunc.h"
#include
#include
int main(){
std::ifstream is;
int DefaultByteOrder=ByteOrderMSB;
int DefaultBitOrder=BitOrderMSB;
MetadataKey ColorType;
MetadataKey Compression;
MetadataKey Filter;
MetadataKey Interlace;
MetadataKey height;
MetadataKey width;
std::vector
is.open ("test.png", std::ifstream::in | std::ifstream::binary);
if (is.good()) {
MetadataKey IHDR(is);
IHDR.setOffset(12);
IHDR.setSize(4);
if(!checkKey(IHDR,"IHDR")) return -1;
width.setStream(is);
width.setBaseKey(IHDR);
width.setOffset(0);
width.setSize(4);
Tag t0;
t0.setName("Width" );
t0.setValue(width.getNumber(DefaultByteOrder));
TagArray.push_back(t0);
height.setStream(is);
height.setBaseKey(width);
height.setOffset(0);
height.setSize(4);
Tag t1;
t1.setName("Height" );
t1.setValue(height.getNumber(DefaultByteOrder));
TagArray.push_back(t1);
ColorType.setStream(is);
ColorType.setBaseKey(height);
ColorType.setOffset(0);
ColorType.setSize(1);
Tag t2;
t2.setName("Color_type" );
t2.setValue(ColorType.getNumber(DefaultByteOrder));
TagArray.push_back(t2);
Compression.setStream(is);
Compression.setBaseKey(ColorType);
Compression.setOffset(0);
Compression.setSize(1);
Tag t3;
t3.setName("Compression_method" );
t3.setValue(Compression.getNumber(DefaultByteOrder));
TagArray.push_back(t3);
Filter.setStream(is);
Filter.setBaseKey(Compression);
Filter.setOffset(0);
Filter.setSize(1);
Tag t4;
t4.setName("Filter_method" );
t4.setValue(Filter.getNumber(DefaultByteOrder));
TagArray.push_back(t4);
Interlace.setStream(is);
Interlace.setBaseKey(Filter);
Interlace.setOffset(0);
Interlace.setSize(1);
Tag t5;
t5.setName("Interlace_method" );
t5.setValue(Interlace.getNumber(DefaultByteOrder));
TagArray.push_back(t5);
}
return 0;
}
понедельник, 28 июня 2010 г.
Translator
Description of mp3 file
Binary ID3;
ByteOrder=MSB;
BitOrder=MSB;
StartMetadataKey ID3(offset=0, size=3);
checkKey(ID3)="ID3";
MetadataKey HeaderFlag(start, offset=5, size=1);
MetadataKey ID3_size(start, offset=6, size=4);
MetadataSize=getNumber(ID3_size);
if (getBit(HeaderFlag, 6)==1)
{
MetadataKey ExHeaderSize(start, offset=10, size=4);
MetadataKey FirstFrameID(start, offset=getNumber(ExHeaderSize)+10, size=4);
MetadataSize-=(10+getNumber(ExHeaderSize));
}
else
MetadataKey FirstFrameID(start, offset=10, size=4);
key=FirstFrameID;
while(MetadataSize>0)
{
MetadataKey sizeOfTag(key, offset=0, size=4);
if(getByte(key, 0)==0x00)
{
break;
}
else {
TagSize=getNumber(sizeOfTag);
if(getValue(key)=="TALB" && (TagSize>1))
{
MetadataKey encoding(key, offset=6, size=1);
SetTag Album(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
if(getValue(key)=="TCOM" && (TagSize>1))
{
MetadataKey encoding(key, offset=6, size=1);
setTag Composer(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
if(getValue(key)=="TDAT" && (TagSize>1))
{
MetadataKey encoding(key, offset=6, size=1);
setTag Date(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
if(getValue(key)=="TRCK" && (TagSize>1))
{
MetadataKey encoding(key, offset=6, size=1);
setTag Track_number(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
if(getValue(key)=="TIT2" && (TagSize>1))
{
MetadataKey encoding(key, offset=6, size=1);
setTag Title(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
if(getValue(key)=="TENC" && (TagSize>1))
{
MetadataKey encoding(key, offset=6, size=1);
setTag Encoded_by(getStringByLink(encoding, offset=0, size=getNumber(sizeOfTag)-1));
}
MetadataSize-=(10+getNumber(sizeOfTag));
shift(key, 10+getNumber(sizeOfTag));
}
}
Is generated parser
#include "MetadataKey.h"
#include "Tag.h"
#include "MetadataFunc.h"
#include
#include
int main(){
std::ifstream is;
int DefaultByteOrder=ByteOrderMSB;
int DefaultBitOrder=BitOrderMSB;
MetadataKey ExHeaderSize;
MetadataKey FirstFrameID;
MetadataKey HeaderFlag;
MetadataKey ID3_size;
int MetadataSize;
int TagSize;
MetadataKey encoding;
MetadataKey key;
MetadataKey sizeOfTag;
std::vector
is.open ("test.mp3", std::ifstream::in | std::ifstream::binary);
if (is.good()) {
MetadataKey ID3(is);
ID3.setOffset(0);
ID3.setSize(3);
if(!checkKey(ID3,"ID3")) return -1;
HeaderFlag.setStream(is);
HeaderFlag.setOffset(5);
HeaderFlag.setSize(1);
ID3_size.setStream(is);
ID3_size.setOffset(6);
ID3_size.setSize(4);
MetadataSize=ID3_size.getNumber(DefaultByteOrder);
if(HeaderFlag.getBit(6, DefaultBitOrder)==1){
ExHeaderSize.setStream(is);
ExHeaderSize.setOffset(10);
ExHeaderSize.setSize(4);
FirstFrameID.setStream(is);
FirstFrameID.setOffset(ExHeaderSize.getNumber(DefaultByteOrder)+10);
FirstFrameID.setSize(4);
MetadataSize-=(10+ExHeaderSize.getNumber(DefaultByteOrder));
}
else{
FirstFrameID.setStream(is);
FirstFrameID.setOffset(10);
FirstFrameID.setSize(4);
}
key=FirstFrameID;
while(MetadataSize>0){
sizeOfTag.setStream(is);
sizeOfTag.setBaseKey(key);
sizeOfTag.setOffset(0);
sizeOfTag.setSize(4);
if(key.getByte(0)==0x00){
break;}
else{
{
TagSize=sizeOfTag.getNumber(DefaultByteOrder);
if(key.getValue()=="TALB"&&(TagSize>1)){
encoding.setStream(is);
encoding.setBaseKey(key);
encoding.setOffset(6);
encoding.setSize(1);
Tag t0;
t0.setName("Album" );
t0.setValue(getStringByLink(encoding,0,sizeOfTag.getNumber(DefaultByteOrder)-1));
TagArray.push_back(t0);
}
if(key.getValue()=="TCOM"&&(TagSize>1)){
encoding.setStream(is);
encoding.setBaseKey(key);
encoding.setOffset(6);
encoding.setSize(1);
Tag t1;
t1.setName("Composer" );
t1.setValue(getStringByLink(encoding,0,sizeOfTag.getNumber(DefaultByteOrder)-1));
TagArray.push_back(t1);
}
if(key.getValue()=="TDAT"&&(TagSize>1)){
encoding.setStream(is);
encoding.setBaseKey(key);
encoding.setOffset(6);
encoding.setSize(1);
Tag t2;
t2.setName("Date" );
t2.setValue(getStringByLink(encoding,0,sizeOfTag.getNumber(DefaultByteOrder)-1));
TagArray.push_back(t2);
}
if(key.getValue()=="TRCK"&&(TagSize>1)){
encoding.setStream(is);
encoding.setBaseKey(key);
encoding.setOffset(6);
encoding.setSize(1);
Tag t3;
t3.setName("Track_number" );
t3.setValue(getStringByLink(encoding,0,sizeOfTag.getNumber(DefaultByteOrder)-1));
TagArray.push_back(t3);
}
if(key.getValue()=="TIT2"&&(TagSize>1)){
encoding.setStream(is);
encoding.setBaseKey(key);
encoding.setOffset(6);
encoding.setSize(1);
Tag t4;
t4.setName("Title" );
t4.setValue(getStringByLink(encoding,0,sizeOfTag.getNumber(DefaultByteOrder)-1));
TagArray.push_back(t4);
}
if(key.getValue()=="TENC"&&(TagSize>1)){
encoding.setStream(is);
encoding.setBaseKey(key);
encoding.setOffset(6);
encoding.setSize(1);
Tag t5;
t5.setName("Encoded_by" );
t5.setValue(getStringByLink(encoding,0,sizeOfTag.getNumber(DefaultByteOrder)-1));
TagArray.push_back(t5);
}
MetadataSize-=(10+sizeOfTag.getNumber(DefaultByteOrder));
key.setOffset(10+sizeOfTag.getNumber(DefaultByteOrder)+key.getSize());
}
}
}
}
return 0;
}
пятница, 18 июня 2010 г.
ID3 and Exif
ID3
/*
Section Name( Length=0, Offset=0,
BeginMarker=0, EndMarker=0 )
Offset= A // Абсолютное смещение
Offset= +A // Смещение вперед
Offset= -A // Смещение назад
-------------------------------------------------
Read ( Length=0, Offset=0,
BeginMarker=0, EndMarker=0 )
*/
Section ID3_Header( Offset=0, BeginMarker="ID3" )
{
Version = Read(1);
Revision = Read(1);
Flags = Read(1);
ID3Size = Read(4);
if (Flags[6])
{
Section ID3_ExtHeader()
{
ExtSize = Read(4);
ExtFlags = Read(2);
SizeOfPadding = Read(4);
}
Skip(ExtSize);
ID3Size -= (10+ExtSize);
}
}
Section Frames(Size=ID3Size)
{
for()
{
Section Frame_Header(Size=10)
{
Frame_ID = Read(4);
Frame_Size = Read(4);
Status = Read(1);
Enc = Read(1);
}
Switch (Frame_ID)
{
case "UFID": Frame_UFID(Frame_Size);
case "TIT2": Frame_TIT2(Frame_Size);
default: Skip(Frame_Size);
}
}
}
function ReadID3String(Enc)
{
if (Enc==0x01) return ReadUnicodeString();
else return ReadString();
}
//Unique file identifier
function Frame_UFID(Frame_Size)
{
Section (Size=Frame_Size)
{
Owner_Identifier = ReadString();
Identifier = Read( Frame_Size-SizeOf(Owner_Identifier) );
}
}
//The 'Title/Songname/Content description' frame is the actual name of the piece (e.g. "Adagio", "Hurricane Donna").
function Frame_TIT2(Frame_Size)
{
Section (Size=Frame_Size)
{
Text_Enc = Read(1);
Title2 = ReadID3String(Text_Enc);
}
}
Exif
/*
Section Name( Length=0, Offset=0,
BeginMarker=0, EndMarker=0 )
Offset= A // Абсолютное смещение
Offset= +A // Смещение вперед
Offset= -A // Смещение назад
-------------------------------------------------
Read ( Length=0, Offset=0,
BeginMarker=0, EndMarker=0 )
*/
Section APP1( Offset=0x02, BeginMarker=0xFFE1 )
{
// APP1Length = Read(Length=2);
APP1Length = Read(2);
Identifier = Read(5);
}
Section APP1_Body(Offset=+1, Size=APP1Length-8)
{
ByteOrder = Read(2);
IFD0_Offset = Read(4, Offset=4);
Section IFD0(Offset=IFD0_Offset)
{
NumberOfInteroperability = Read(2);
for(NumberOfInteroperability)
{
FillParam( Read(Param) );
}
NextIFDOffset = Read(2);
}
Section ExifIFD(Offset=ExifIFDPointer)
{
}
}
--------------------------------------------------------
structure Param
{
Tag(2),
Type(2),
Count(4),
ValueOrOffset(4)
}
function GetValue(Param)
{
Switch(Param.Type)
{
case 0x0200: return ReadString(Offset=Param.ValueOrOffset);
case 0x0500: return Read(8, Offset=Param.ValueOrOffset);
case 0x0300: return Param.ValueOrOffset;
case 0x0400: return Param.ValueOrOffset;
}
}
function FillParam(Param)
{
switch (Param.Tag)
{
case 0x0E01: ImageDescription = GetValue(Param);
case 0x0F01: Make = GetValue(Param);
case 0x1001: Model = GetValue(Param);
case 0x1201: Orientation = GetValue(Param);
case 0x1A01: XResolution = GetValue(Param);
case 0x1B01: YResolution = GetValue(Param);
case 0x2801: ResolutionUnit = GetValue(Param);
case 0x3201: DateTime = GetValue(Param);
case 0x1302: YCbCrPositioning = GetValue(Param);
case 0x9882: CopyRight = GetValue(Param);
case 0x6987: ExifIFDPointer = GetValue(Param);
}
}
четверг, 10 июня 2010 г.
ID3
Binary ID3;
StartMetadataKey ID3(offset=0, size=3);
If(getValue(ID3)!=”ID3”) exit;
MetadataKye HeaderFlag(start, offset=3, size=1);
MeatdataKey ID3_size(start, offset=6, size=4);
MetadataSize=getValue(ID3_size);
If(getValue(HeaderFlag)[6])
{
MetadataKey ExHeaderSize(start, offset=10, size=4);
MetadataKey FirstFrameID(ExHeaderSize, offset=getValue(ExHeaderSize)+10, size=4);
MetadataSize -=(10+getValue(ExHeaderSize));
}
Else
MetadataKey FirstFrameID(start, offset=10, size=4);
Key=FirstFrameID;
While(MetadataSize>0)
{
MetadataKey size(key, offset=4, size=4);
If(getValue(key)==”TALB”)
{
MetadataKey encoding(key, offset=10, size=1);
SetTag Album(getVakue(encoding) , getValueByLink(encoding, offset=1, size=getValue(size)-1));
}
If(getValue(key)==”TCOM”)
{
MetadataKey encoding(key, offset=10, size=1);
SetTag Composer(getVakue(encoding) , getValueByLink(encoding, offset=1, size=getValue(size)-1));
}
If(getValue(key)==”TDAT”)
{
MetadataKey encoding(key, offset=10, size=1);
SetTag Date(getVakue(encoding) , getValueByLink(encoding, offset=1, size=getValue(size)-1));
}
MetadataSize -=(10+getValue(size));
MetadataKey newKey(key, offset=10+geValue(size), size=4);
Key=newKey;
}
Exif
Binary Exif;
StartMetadataKey APP1_Marker(offset=2, size=2);
If(getValue(APP1_Marker)!=0xFFE1) exit;
MetadataKey Length(APP1_Marker, offset=2, size=2);
MetadataKey APP1(APP1_Marker, offset=10, size=getValue(Length));
MetadataKey IFD_Offset(APP1, offset=4, size=4);
MetadataKey CountOfTag(APP1, offset-getValue(IDF_Offset), size=2);
MetadataKey FirstTagID(CountOfTag, offset=2, size=2);
MetadataKey TagID=FirstTagID;
count=getValue(CountOgTag));
While(coun>0)
{
MetadataKey Type(TagID, offset=2, size=2);
MetadataKey ValueOffset(TagID, offset=8, size=4);
If(getValue(TagID)==0x0E01)
{
If(getValue(Type)==0x200) SetTag ImageDescription(0x01, getValueByLink(TagID,offset=getValue(ValueOffset), key=00));
If(getValue(Type)==0x500) SetTag ImageDescription(0x01, getValueByLink(TagID,offset=getValue(ValueOffset), size=8));
if(tag.Type==0x0100 || tag.Type==0x0300 || tag.Type==0x0400)SetTag ImageDescription(0x01, getValue(ValueOffset));
}
If(getValue(TagID)==0x0F01)
{
If(getValue(Type)==0x200) SetTag Make (0x01, getValueByLink(TagID,offset=getValue(ValueOffset), key=00));
If(getValue(Type)==0x500) SetTag Make(0x01, getValueByLink(TagID,offset=getValue(ValueOffset), size=8));
if(tag.Type==0x0100 || tag.Type==0x0300 || tag.Type==0x0400)SetTag Make (0x01, getValue(ValueOffset));
}
If(getValue(TagID)==0x1001)
{
If(getValue(Type)==0x200) SetTag Model(0x01, getValueByLink(TagID,offset=getValue(ValueOffset), key=00));
If(getValue(Type)==0x500) SetTag Model(0x01, getValueByLink(TagID,offset=getValue(ValueOffset), size=8));
if(tag.Type==0x0100 || tag.Type==0x0300 || tag.Type==0x0400)SetTag Model(0x01, getValue(ValueOffset));
}
If(getValue(TagID)==0x1201)
{
If(getValue(Type)==0x200) SetTag Orientation(0x01, getValueByLink(TagID,offset=getValue(ValueOffset), key=00));
If(getValue(Type)==0x500) SetTag Orientation0x01, getValueByLink(TagID,offset=getValue(ValueOffset), size=8));
if(tag.Type==0x0100 || tag.Type==0x0300 || tag.Type==0x0400)SetTag Orientation(0x01, getValue(ValueOffset));
}
If(getValue(TagID)==0x1A01)
{
If(getValue(Type)==0x200) SetTag XResolution(0x01, getValueByLink(TagID,offset=getValue(ValueOffset), key=00));
If(getValue(Type)==0x500) SetTag XResolution (0x01, getValueByLink(TagID,offset=getValue(ValueOffset), size=8));
if(tag.Type==0x0100 || tag.Type==0x0300 || tag.Type==0x0400)SetTag XResolution (0x01, getValue(ValueOffset));
}
If(getValue(TagID)==0x1B01)
{
If(getValue(Type)==0x200) SetTag YResolution(0x01, getValueByLink(TagID,offset=getValue(ValueOffset), key=00));
If(getValue(Type)==0x500) SetTag YResolution (0x01, getValueByLink(TagID,offset=getValue(ValueOffset), size=8));
if(tag.Type==0x0100 || tag.Type==0x0300 || tag.Type==0x0400)SetTag YResolution (0x01, getValue(ValueOffset));
}
If(getValue(TagID)==0x3201)
{
If(getValue(Type)==0x200) SetTag DateTime(0x01, getValueByLink(TagID,offset=getValue(ValueOffset), key=00));
If(getValue(Type)==0x500) SetTag DateTime (0x01, getValueByLink(TagID,offset=getValue(ValueOffset), size=8));
if(tag.Type==0x0100 || tag.Type==0x0300 || tag.Type==0x0400)SetTag DateTime(0x01, getValue(ValueOffset));
}
count-=1;
Metadatakey newTagID(TagID, offset=12, size=2);
TagID=newTadIG;
}