Read/Write file metadata using C/C++ - c++

Searched through net, could't find a way to read/write file metadata using C or C++, however, there are tools available for this, and also there are API's in C# and Java to do this. But I want to do it from scratch in C or C++.
For example, read/write image metadata.
Have found out that there are three formats in which metadata is written to files. EXIF, IPTC and XMP.
Thanks.

Why would you want to do it from scratch?
Anyway, you need documentation and you may also want to look at an existing library for helps, expecially if you have no experience in the field.
Have you tried Exiv ?
Exiv2 is a C++ library and a command
line utility to manage image metadata.
It provides fast and easy read and
write access to the Exif, IPTC and XMP
metadata of images in various formats.
Exiv2 is available as free software
and with a commercial license, and is
used in many projects.

There are different solutions. One is to define a structure (but make sure the field alignements are correct), then read the data, and use the structure to access the fields. Trivial example:
struct header {
uint32_t len;
unsigned char type;
char name[16];
};
struct header hdr;
read(fd,&hdr,sizeof(hdr));
... access your fields using the structure ...
The topic is a bit more complex than this ;) But since you did not specified much more I think this still can help a bit.

Related

How to embed resources into a single executable?

If you've ever used the tool Game Maker, it's a bit like that. I want to be able to take all my sounds, images, and everything else of the like and embed them into a single C++ executable. Game Maker would have a built-in editor, and would have the images embedded into the .gmk file, and when you'd open it it would read the images, and display them in the game. I'm thinking he had the images saved not as images, but as pure data stored in the .gmk file and interpreted by the editor or by some interpreter written into the .exe. How would I go about making something similar?
The windows resource system works like this, so if you make a WinAPI or MFC application, you can use this. Also, Qt provides the same functionality, but in a platform independent way. They just write the files in raw binary format into a byte array in a normal C++ file, so they get compiled as data into the exe. Then they provide functions for accessing these data blocks like normal files, although I don't know how they really work. Probably a special implementation of their file class which just accesses those byte array variables.
For images only, a very simple approach is to use the XPM format.
This format is a valid C/C++ header, so you can include it directly into a C++ source file and use it directly.
The main issue with this approach is that XPM is not a compressed format, so uses a lot of storage.
In consequence, in practice I only seen this used for icons and small graphical objects, but in principle you could do more.
The other cool thing about XPM is that it's human readable - again great for designing small and simple icons.
To generalize this idea to other formats, what you could do is to create a compile chain that:
Encodes the target file as ASCII (Uuencode or such)
Turns that into a single named C String in a source file.
Create a header just declaring the name
Define a function recovering the binary form from the string
For the Windows OS I have a solution if you are willing to use another tool and possibly framework. Try the "peresembed" tool. It embeds files into PE image sections so you can have all your images, sounds and configuration files in just one EXE file. Supports compression too, although you do need a ZIP in-memory reading framework then. Can even embed files into the PE resource tree based on their relative file paths.
Example usage:
peresembed -file content.txt _export_to_resolve input.exe output.exe
In your C++ file you have:
struct embedded_data
{
void *dataloc;
size_t datasize;
};
extern "C" __declspec(dllexport) const volatile embedded_data _export_to_resolve = { 0 };
Get peresembed from: https://osdn.net/projects/pefrm-units/releases/70746
Showcase video: https://www.youtube.com/watch?v=1uYdjiZc5XI

Methods of storing application data/settings without the registry?

I need some methods of storing and getting data from a file (in WIN32 api c++ application, not MFC or .NET)
e.g. saving the x, y, width and height of the window when you close it, and loading the data when you open the window.
I have tried .ini files, with the functions -- WritePrivateProfileString and ReadPrivateProfileString/Int, but on MSDN it says
"This function is provided only for compatibility with 16-bit Windows-based applications. Applications should store initialization information in the registry."
and when i tried on my Windows7 64bit machine to read a ini file, i got blue screen! (in debug mode with visual studio) O.O
I notice that most other application use XML to store data, but I don't have a clue how to read/write xml data in c++, are there any libraries or windows functions which will allow me to use xml data?
Any other suggestions would be good too, thanks.
There is nothing wrong with .ini files, the only problem with them is where to write them. CIniFile from CodeProject is good enough class. Ini file should be placed in %APPDATA%/<Name Of Your Application> (or %LOCALAPPDATA%\<Same Name Here>, as described below).
EDIT: If we are talking about Windows family of operating systems from Windows 2000 onward then function SHGetFolderPath is portable way to retrieve user specific folder where application configuration files should be stored. To store data in romaing folder use CSIDL_APPDATA with SHGetFolderPath. To store data to local folder use CSIDL_LOCAL_APPDATA.
The difference between local and roaming folder is in the nature of the data to be stored. If data is too large or machine specific then store it in local folder. Your data (coordinates and size of the window) are local in nature (on other machine you may have different resolution), so you should actually use CSIDL_LOCAL_APPDATA.
Windows Vista and later have extended function SHGetKnownFolderPath with its own set of constants, but if you seek compatibility stick to the former SHGetFolderPath.
TinyXML is a popular and simple XML parser for C++.
Apart from that, you can really use any format you want to store your settings, though it's considered good practice to keep settings in text format so that they can be hand-edited if necessary.
It's fairly simple to write your own functions for reading/writing a file in INI or similar format. The format is entirely up to you, as long as it's easily comprehensible to humans. Some possibilities are:
; Comment
# Comment
Key = Value (standard INI format)
Key Value
Key: Value
You could use Boost.PropertyTree for this.
Property trees are versatile data
structures, but are particularly
suited for holding configuration data.
The tree provides its own,
tree-specific interface, and each node
is also an STL-compatible Sequence for
its child nodes.
It supports serialization, and so is well-suited to managing and persisting changeable configuration data. There is an example here on how to load and save using the XML data format that this library supports.
The library uses RapidXML internally but hides the parsing and encoding details, which would save you some implementation time (XML libraries all have their idiosyncracies), while still allowing you to use XML as the data representation on disk.
libxml2. I have seen quite a lot places where it is used. Easy to use and loads of examples to get you started and not a vast library as such. And in C, take it wherever you want.
pugixml is another good (and well documented) XML parser library. And If you like portability XML is a better option.
While INI files may not be the best format, I think you can safely ignore the warning MSDN puts on WritePrivateProfileString and ReadPrivateProfileString.
Those two functions are NEVER going away. It would break THOUSANDS of applications.
That warning has been there for years and I suspect was added when the registry was all the rage and someone naively thought it would one day completely replace INI files.
I might be wrong but it would be very unlike Microsoft to break so many existing apps like this for no good reasons. (Not that they do not occasionally break backwards compatibility, but this would cause huge problems for zero benefit.)
Ohhh My GOD? Have you ever thought of stright-forward solution rather then thinking of Super-Duper-all-can-do framework way?
Sorry...
You want to store two numbers between restarts???
Save: Open a file, write these two numbers, close the file:
std::ifstream out(file_name);
out << x << ' ' << y;
out.close();
Load: Open a file, read these two numbers, close the file:
std::ifstream in(file_name);
if(!in) return error...
in >> x >> y;
if(!in) return error...
in.close();
Libconfig is the best solution in C++ as far as I have tried.
Works multi platform with minimum coding.
You must try that!
I like the TinyXML solution suggested.
But for Windows, I like .ini even more.
So I'll suggest the inih library, free and open source on GitHub here. Very simple and easy to use - 1 header file library iirc.

C++ file container (e.g. zip) for easy access

I have a lot of small files I need to ship with an application I build and I want to put this files into an archive to make copying and redistributing more easy.
I also really like the idea of having them all in one place so I need to compare the md5 of one file only in case something goes wrong.
I'm thinking about a class which can load the archive and return a list of files within the archive and load a file into memory if I need to access it.
I already searched the Internet for different methods of achieving what I want and found out about zlib and the lzma sdk.
Both didn't really appeal to me because I don't really found out how portable zlib is and I didn't like the lzma sdk as it is just to much and I don't want to blow up the application because of this problem. Another downside with zlib is that I don't have the C/C++ experience (I'm really new to C++) to get everything explained in the manual.
I also have to add that this is a time critical problem. I though some time about implementing a simple format like tar in a way I can easy access the files within my application but I just didn't find the time to do that yet.
So what I'm searching for is a library that allows me to access the files within an archive. I'd be glad if anybody could point me in the right direction here.
Thanks in advance,
Robin.
Edit: I need the archive to be accessed under linux and windows. Sorry I didn't mention that in the beginning.
For zipping, I've always been partial to ZipUtils, which makes the process easy and is built on top of the zlib and info-zip libraries.
The answer depends on whether you plan to modify the archive via code after the archive is initially built.
If you don't need to modify it, you can use TAR - it's a handy and simple format. If you want compression, you can implement tar.gz reader or find some library that does this (I believe there are some available, including open-source ones).
If your application needs random access to the data or it needs to modify the archive, then regular TAR or ZIP archives are not good. Virtual file system such as our SolFS or CodeBase file system will fit much better: virtual file systems are suited for frequent modifications of the storage, while archives target mainly write-once-read-many usage scenarios.
zlib is highly portable and very widely used. if you can't make sense of the C++ interface, there are alternatives for many other languages - see 'Related External Links' here.
Take another look before you search for something different.
If you're using Qt or Windows you can also pack data into the executable's resource area. You would only have to distribute the executable file using this technique. There's a well defined API already written and tested to access that data.
The zlib API is the way to go. Simple and portable. Lookat unzip.h header for APIs that access archive files. It is in C and very easy.
If the files are small, you can dump them into string literals (search for bin2h utility) and include in your project. Then change the code that read the files. If all files are currently read using ifstream class, simply changing it to istringstream class and recompile the code.
Try using Quazip - it's quite simple to use. You can use it as a stream from which you read the compressed file on the fly.

Reading from compressed archives

I want to place all my programs content in a compressed archive file as its starting to get quite large. I know theres a few libraries around like zlib but i dont know how to make them do what I want to do:
Be able to load textures/models etc from the file, curretly im using d3dx methods such as D3DXCreateTextureFromFileEx. I dont really want to have to write my own image loaders for the diffrent formats I want, so I need some way to be compatible with these d3d methods. I know they have a way to load from an in-memory file, would it be suitable to extract the file into memory somehow then load that?
Be able to use c++ streams with files in the compressed archive eg:
std::zipstream file("data.zip:sounds/beep.wav", std::ios::in | std::ios::binary);
I'd recommend looking at open source games (quake3 for example). Some of them are packing resources and have working implementations of "virtual file system", as Vilx noted. You might get some ideas.
There is an article entitled Programming a Virtual File System archived on flipcode that should provide what you need. If you have questions specific to that article, many former flipcode members now frequent the forums at DevMaster.net.
There are ready made libraries for this sort of thing. I'm afraid I don't know any names, but I suggest to google on the keywords "virtual file system".

VCL alternative to IStorage

To preface I am using Borland C++ and the VCL.
I need some sort of structured storage object which can be saved to disk as a single file and can contain multiple named blobs of binary data which I can programatically enumerate, access and manipulate.
The IStorage interface seems to be close what I want but I would prefer a VCL style solution as converting TStream's (VCL) to IStream's among other things gets awkward and their must be a simpler solution using the VCL stuff allready available, like a TIniFile but for binary data.
I don't want to use XML as the binary data blobs are very large and when correctly encoded for use in XML it's completely inneficient.
Thanks in advance for all suggestions.
A zip file is de facto a standard container, and it seems you can get a TStream interface to them: http://www.tek-tips.com/faqs.cfm?fid=6734
SolFS (Solid File System) from Eldos.
http://www.eldos.com/solfs/
Very reliable, but might not be the cheapest solution ($372 for one developer).
I went for ZipForge by ComponentAce. It's fast, is being actively developed/supported and has the perfect interface to support what I want.
Thanks for everybodys other suggestions.
If you don't want to store huge file(it has 2GB limit), GPStructuredStorage might be handy.
It's a open source structured storage library written in pure delphi, still maintained and seems to be worked with D2010.