Project

General

Profile

RE: Extracting UTF8 metadata ยป try2.cpp

Access user comment in various ways and convert it to UTF-8 - Andreas Huggel, 21 Oct 2009 13:43

 
1
#include "image.hpp"
2
#include "exif.hpp"
3
#include <iostream>
4
#include <cassert>
5
#include <string>
6
#include "futils.hpp"
7
#include <iconv.h>
8

    
9
std::string printUcs2(const std::string& value);
10

    
11
int main(int argc, char* const argv[])
12
{
13
    if (argc != 2) {
14
        std::cout << "Usage: " << argv[0] << " file\n";
15
        return 1;
16
    }
17

    
18
    Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(argv[1]);
19
    assert(image.get() != 0);
20
    image->readMetadata();
21

    
22
    Exiv2::ExifData &exifData = image->exifData();
23

    
24
    Exiv2::ExifData::const_iterator md = exifData.findKey(
25
        Exiv2::ExifKey("Exif.Photo.UserComment"));
26
    if (md == exifData.end()) {
27
        std::cout << "No Exif comment found in the image.\n";
28
    }
29
    else {
30
        std::string val = md->toString();
31
        std::string::size_type start = val.find(' ');
32
        if (start != std::string::npos) {
33
            val = val.substr(start + 1);
34
        }
35
        std::cout << "md->toString()\n"
36
                  << "--------------\n"
37
                  << "size = " << val.size() << "\n"
38
                  << printUcs2(val) << "\n\n";
39

    
40
        val = md->print(&exifData);
41
        std::cout << "md->print(&exifData)\n"
42
                  << "--------------------\n"
43
                  << "size = " << val.size() << "\n"
44
                  << printUcs2(val) << "\n\n";
45

    
46
        const Exiv2::CommentValue& cv = dynamic_cast<const Exiv2::CommentValue&>(md->value());
47
        val = cv.comment();
48
        std::cout << "Exiv2::CommentValue::comment()\n"
49
                  << "------------------------------\n"
50
                  << "size = " << val.size() << "\n"
51
                  << printUcs2(val) << "\n\n";
52
    }
53
    return 0;
54
}
55

    
56
std::string printUcs2(const std::string& value)
57
{
58
    bool go = true;
59
    iconv_t cd = (iconv_t)(-1);
60
    cd = iconv_open("UTF-8", "UCS-2BE");
61
    if (cd == (iconv_t)(-1)) {
62
        std::cerr << "iconv_open: " << Exiv2::strError() << "\n";
63
        go = false;
64
    }
65
    std::string ret;
66
    if (go) {
67
        Exiv2::DataBuf ob(value.size() * 2);
68
        char* outptr = reinterpret_cast<char*>(ob.pData_);
69
        const char* outbuf = outptr;
70
        size_t outbytesleft = ob.size_;
71
        EXV_ICONV_CONST char* inbuf = const_cast<EXV_ICONV_CONST char*>(value.data());
72
        size_t inbytesleft = value.size();
73

    
74
        std::cerr << std::dec << "inbytesleft = " << inbytesleft << ", "
75
                  << "outbytesleft = " << outbytesleft << "\n";
76

    
77
        size_t rc = iconv(cd,
78
                          &inbuf,
79
                          &inbytesleft,
80
                          &outptr,
81
                          &outbytesleft);
82
        if (rc == size_t(-1)) {
83
            std::cerr << "iconv: "
84
                      << Exiv2::strError()
85
                      << " inbytesleft = " << inbytesleft << "\n";
86
            go = false;
87
        }
88
        if (go) {
89
            if (outptr > outbuf && *(outptr-1) == '\0') outptr--;
90
            ret = std::string(outbuf, outptr-outbuf);
91
        }
92
    }
93
    if (cd != (iconv_t)(-1)) {
94
        iconv_close(cd);
95
    }
96
    return ret;
97
} // printUcs2
    (1-1/1)