[SCM] exiv2 packaging branch, master, updated. debian/0.25-3.1-3734-gdcbc29a

Maximiliano Curia maxy at moszumanska.debian.org
Thu Jul 13 17:42:27 UTC 2017


Gitweb-URL: http://git.debian.org/?p=pkg-kde/kde-extras/exiv2.git;a=commitdiff;h=3b13ab8

The following commit has been merged in the master branch:
commit 3b13ab8717c2597be3ee6ff2521d4290f7a632b4
Author: vog <vog at notjusthosting.com>
Date:   Fri Jun 24 17:33:17 2011 +0000

    #689: Make private implementation pf EpsImage really private
---
 src/epsimage.cpp | 769 ++++++++++++++++++++++++++++---------------------------
 src/epsimage.hpp |  25 --
 2 files changed, 395 insertions(+), 399 deletions(-)

diff --git a/src/epsimage.cpp b/src/epsimage.cpp
index a67e3b7..6698875 100644
--- a/src/epsimage.cpp
+++ b/src/epsimage.cpp
@@ -55,134 +55,352 @@ EXIV2_RCSID("@(#) $Id: epsimage.cpp $")
 #include <sstream>
 #include <string>
 
-// signature of DOS EPS
-static const std::string epsDosSignature = "\xc5\xd0\xd3\xc6";
-
-// first line of EPS
-static const std::string epsFirstLine[] = {
-    "%!PS-Adobe-3.0 EPSF-3.0",
-    "%!PS-Adobe-3.0 EPSF-3.0 ", // OpenOffice
-    "%!PS-Adobe-3.1 EPSF-3.0",  // Illustrator
-};
-
-// blank EPS file
-static const std::string epsBlank = "%!PS-Adobe-3.0 EPSF-3.0
"
-                                    "%%BoundingBox: 0 0 0 0
";
-
-// list of all valid XMP headers
-static const struct { std::string header; std::string charset; } xmpHeadersDef[] = {
-
-    // We do not enforce the trailing "?>" here, because the XMP specification
-    // permits additional attributes after begin="..." and id="...".
-
-    // normal headers
-    {"<?xpacket begin=\"\xef\xbb\xbf\" id=\"W5M0MpCehiHzreSzNTczkc9d\"", "UTF-8"},
-    {"<?xpacket begin=\"\xef\xbb\xbf\" id='W5M0MpCehiHzreSzNTczkc9d'",   "UTF-8"},
-    {"<?xpacket begin='\xef\xbb\xbf' id=\"W5M0MpCehiHzreSzNTczkc9d\"",   "UTF-8"},
-    {"<?xpacket begin='\xef\xbb\xbf' id='W5M0MpCehiHzreSzNTczkc9d'",     "UTF-8"},
-    {"<?xpacket begin=\"\xef\xbb\xbf\" id=\"W5M0MpCehiHzreSzNTczkc9d\"", "UTF-16BE"},
-    {"<?xpacket begin=\"\xef\xbb\xbf\" id='W5M0MpCehiHzreSzNTczkc9d'",   "UTF-16BE"},
-    {"<?xpacket begin='\xef\xbb\xbf' id=\"W5M0MpCehiHzreSzNTczkc9d\"",   "UTF-16BE"},
-    {"<?xpacket begin='\xef\xbb\xbf' id='W5M0MpCehiHzreSzNTczkc9d'",     "UTF-16BE"},
-    {"<?xpacket begin=\"\xef\xbb\xbf\" id=\"W5M0MpCehiHzreSzNTczkc9d\"", "UTF-16LE"},
-    {"<?xpacket begin=\"\xef\xbb\xbf\" id='W5M0MpCehiHzreSzNTczkc9d'",   "UTF-16LE"},
-    {"<?xpacket begin='\xef\xbb\xbf' id=\"W5M0MpCehiHzreSzNTczkc9d\"",   "UTF-16LE"},
-    {"<?xpacket begin='\xef\xbb\xbf' id='W5M0MpCehiHzreSzNTczkc9d'",     "UTF-16LE"},
-    {"<?xpacket begin=\"\xef\xbb\xbf\" id=\"W5M0MpCehiHzreSzNTczkc9d\"", "UTF-32BE"},
-    {"<?xpacket begin=\"\xef\xbb\xbf\" id='W5M0MpCehiHzreSzNTczkc9d'",   "UTF-32BE"},
-    {"<?xpacket begin='\xef\xbb\xbf' id=\"W5M0MpCehiHzreSzNTczkc9d\"",   "UTF-32BE"},
-    {"<?xpacket begin='\xef\xbb\xbf' id='W5M0MpCehiHzreSzNTczkc9d'",     "UTF-32BE"},
-    {"<?xpacket begin=\"\xef\xbb\xbf\" id=\"W5M0MpCehiHzreSzNTczkc9d\"", "UTF-32LE"},
-    {"<?xpacket begin=\"\xef\xbb\xbf\" id='W5M0MpCehiHzreSzNTczkc9d'",   "UTF-32LE"},
-    {"<?xpacket begin='\xef\xbb\xbf' id=\"W5M0MpCehiHzreSzNTczkc9d\"",   "UTF-32LE"},
-    {"<?xpacket begin='\xef\xbb\xbf' id='W5M0MpCehiHzreSzNTczkc9d'",     "UTF-32LE"},
-
-    // deprecated headers (empty begin attribute, UTF-8 only)
-    {"<?xpacket begin=\"\" id=\"W5M0MpCehiHzreSzNTczkc9d\"", "UTF-8"},
-    {"<?xpacket begin=\"\" id='W5M0MpCehiHzreSzNTczkc9d'",   "UTF-8"},
-    {"<?xpacket begin='' id=\"W5M0MpCehiHzreSzNTczkc9d\"",   "UTF-8"},
-    {"<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'",     "UTF-8"},
-};
-
-// list of all valid XMP trailers
-static const struct { std::string trailer; bool readOnly; } xmpTrailersDef[] = {
-
-    // We do not enforce the trailing "?>" here, because the XMP specification
-    // permits additional attributes after end="...".
-
-    {"<?xpacket end=\"r\"", true},
-    {"<?xpacket end='r'",   true},
-    {"<?xpacket end=\"w\"", false},
-    {"<?xpacket end='w'",   false},
-};
-
-// closing part of all valid XMP trailers
-static const std::string xmpTrailerEndDef = "?>";
-
 // *****************************************************************************
-// class member definitions
-namespace Exiv2
-{
-
-    EpsImage::EpsImage(BasicIo::AutoPtr io, bool create)
-            : Image(ImageType::eps, mdXmp, io)
+namespace {
+
+    using namespace Exiv2;
+
+    // signature of DOS EPS
+    static const std::string epsDosSignature = "\xc5\xd0\xd3\xc6";
+
+    // first line of EPS
+    static const std::string epsFirstLine[] = {
+        "%!PS-Adobe-3.0 EPSF-3.0",
+        "%!PS-Adobe-3.0 EPSF-3.0 ", // OpenOffice
+        "%!PS-Adobe-3.1 EPSF-3.0",  // Illustrator
+    };
+
+    // blank EPS file
+    static const std::string epsBlank = "%!PS-Adobe-3.0 EPSF-3.0
"
+                                        "%%BoundingBox: 0 0 0 0
";
+
+    // list of all valid XMP headers
+    static const struct { std::string header; std::string charset; } xmpHeadersDef[] = {
+
+        // We do not enforce the trailing "?>" here, because the XMP specification
+        // permits additional attributes after begin="..." and id="...".
+
+        // normal headers
+        {"<?xpacket begin=\"\xef\xbb\xbf\" id=\"W5M0MpCehiHzreSzNTczkc9d\"", "UTF-8"},
+        {"<?xpacket begin=\"\xef\xbb\xbf\" id='W5M0MpCehiHzreSzNTczkc9d'",   "UTF-8"},
+        {"<?xpacket begin='\xef\xbb\xbf' id=\"W5M0MpCehiHzreSzNTczkc9d\"",   "UTF-8"},
+        {"<?xpacket begin='\xef\xbb\xbf' id='W5M0MpCehiHzreSzNTczkc9d'",     "UTF-8"},
+        {"<?xpacket begin=\"\xef\xbb\xbf\" id=\"W5M0MpCehiHzreSzNTczkc9d\"", "UTF-16BE"},
+        {"<?xpacket begin=\"\xef\xbb\xbf\" id='W5M0MpCehiHzreSzNTczkc9d'",   "UTF-16BE"},
+        {"<?xpacket begin='\xef\xbb\xbf' id=\"W5M0MpCehiHzreSzNTczkc9d\"",   "UTF-16BE"},
+        {"<?xpacket begin='\xef\xbb\xbf' id='W5M0MpCehiHzreSzNTczkc9d'",     "UTF-16BE"},
+        {"<?xpacket begin=\"\xef\xbb\xbf\" id=\"W5M0MpCehiHzreSzNTczkc9d\"", "UTF-16LE"},
+        {"<?xpacket begin=\"\xef\xbb\xbf\" id='W5M0MpCehiHzreSzNTczkc9d'",   "UTF-16LE"},
+        {"<?xpacket begin='\xef\xbb\xbf' id=\"W5M0MpCehiHzreSzNTczkc9d\"",   "UTF-16LE"},
+        {"<?xpacket begin='\xef\xbb\xbf' id='W5M0MpCehiHzreSzNTczkc9d'",     "UTF-16LE"},
+        {"<?xpacket begin=\"\xef\xbb\xbf\" id=\"W5M0MpCehiHzreSzNTczkc9d\"", "UTF-32BE"},
+        {"<?xpacket begin=\"\xef\xbb\xbf\" id='W5M0MpCehiHzreSzNTczkc9d'",   "UTF-32BE"},
+        {"<?xpacket begin='\xef\xbb\xbf' id=\"W5M0MpCehiHzreSzNTczkc9d\"",   "UTF-32BE"},
+        {"<?xpacket begin='\xef\xbb\xbf' id='W5M0MpCehiHzreSzNTczkc9d'",     "UTF-32BE"},
+        {"<?xpacket begin=\"\xef\xbb\xbf\" id=\"W5M0MpCehiHzreSzNTczkc9d\"", "UTF-32LE"},
+        {"<?xpacket begin=\"\xef\xbb\xbf\" id='W5M0MpCehiHzreSzNTczkc9d'",   "UTF-32LE"},
+        {"<?xpacket begin='\xef\xbb\xbf' id=\"W5M0MpCehiHzreSzNTczkc9d\"",   "UTF-32LE"},
+        {"<?xpacket begin='\xef\xbb\xbf' id='W5M0MpCehiHzreSzNTczkc9d'",     "UTF-32LE"},
+
+        // deprecated headers (empty begin attribute, UTF-8 only)
+        {"<?xpacket begin=\"\" id=\"W5M0MpCehiHzreSzNTczkc9d\"", "UTF-8"},
+        {"<?xpacket begin=\"\" id='W5M0MpCehiHzreSzNTczkc9d'",   "UTF-8"},
+        {"<?xpacket begin='' id=\"W5M0MpCehiHzreSzNTczkc9d\"",   "UTF-8"},
+        {"<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'",     "UTF-8"},
+    };
+
+    // list of all valid XMP trailers
+    static const struct { std::string trailer; bool readOnly; } xmpTrailersDef[] = {
+
+        // We do not enforce the trailing "?>" here, because the XMP specification
+        // permits additional attributes after end="...".
+
+        {"<?xpacket end=\"r\"", true},
+        {"<?xpacket end='r'",   true},
+        {"<?xpacket end=\"w\"", false},
+        {"<?xpacket end='w'",   false},
+    };
+
+    // closing part of all valid XMP trailers
+    static const std::string xmpTrailerEndDef = "?>";
+
+    //! Write data into temp file, taking care of errors
+    static void writeTemp(BasicIo& tempIo, const char* data, size_t size)
     {
-        //LogMsg::setLevel(LogMsg::debug);
-        if (create) {
-            if (io_->open() == 0) {
-                #ifdef DEBUG
-                EXV_DEBUG << "Exiv2::EpsImage:: Creating blank EPS image
";
-                #endif
-                IoCloser closer(*io_);
-                if (io_->write(reinterpret_cast<const byte*>(epsBlank.data()), static_cast<long>(epsBlank.size())) != static_cast<long>(epsBlank.size())) {
-                    #ifndef SUPPRESS_WARNINGS
-                    EXV_WARNING << "Failed to write blank EPS image.
";
-                    #endif
-                    throw Error(21);
-                }
-            }
+        if (size == 0) return;
+        if (tempIo.write(reinterpret_cast<const byte*>(data), static_cast<long>(size)) != static_cast<long>(size)) {
+            #ifndef SUPPRESS_WARNINGS
+            EXV_WARNING << "Failed to write to temporary file.
";
+            #endif
+            throw Error(21);
         }
     }
 
-    std::string EpsImage::mimeType() const
+    //! Write data into temp file, taking care of errors
+    static void writeTemp(BasicIo& tempIo, const std::string &data)
     {
-        return "application/postscript";
+        writeTemp(tempIo, data.data(), data.size());
     }
 
-    void EpsImage::setComment(const std::string& /*comment*/)
+    //! Check whether a string has a certain beginning
+    static bool startsWith(const std::string& s, const std::string& start)
     {
-        throw Error(32, "Image comment", "EPS");
+        return s.size() >= start.size() && memcmp(s.data(), start.data(), start.size()) == 0;
     }
 
-    void EpsImage::readMetadata()
+    //! Check whether a string contains only white space characters
+    static bool onlyWhitespaces(const std::string& s)
     {
-        doReadWriteMetadata(/* write = */ false);
+        // According to the DSC 3.0 specification, 4.4 Parsing Rules,
+        // only spaces and tabs are considered to be white space characters.
+        return s.find_first_not_of(" 	") == std::string::npos;
     }
 
-    void EpsImage::writeMetadata()
+    //! Convert an integer of type size_t to a decimal string
+    static std::string toString(size_t size)
+    {
+        std::ostringstream stream;
+        stream << size;
+        return stream.str();
+    }
+
+    //! Read the next line of a buffer, allow for changing line ending style
+    static size_t readLine(std::string& line, const char* data, size_t startPos, size_t size)
+    {
+        line.clear();
+        size_t pos = startPos;
+        // step through line
+        while (pos < size && data[pos] != '
' && data[pos] != '
') {
+            line += data[pos];
+            pos++;
+        }
+        // skip line ending, if present
+        if (pos >= size) return pos;
+        pos++;
+        if (pos >= size) return pos;
+        if (data[pos - 1] == '
' && data[pos] == '
') pos++;
+        return pos;
+    }
+
+    //! Read the previous line of a buffer, allow for changing line ending style
+    static size_t readPrevLine(std::string& line, const char* data, size_t startPos, size_t size)
+    {
+        line.clear();
+        size_t pos = startPos;
+        if (pos > size) return pos;
+        // skip line ending of previous line, if present
+        if (pos <= 0) return pos;
+        if (data[pos - 1] == '
' || data[pos - 1] == '
') {
+            pos--;
+            if (pos <= 0) return pos;
+            if (data[pos - 1] == '
' && data[pos] == '
') {
+                pos--;
+                if (pos <= 0) return pos;
+            }
+        }
+        // step through previous line
+        while (pos >= 1 && data[pos - 1] != '
' && data[pos - 1] != '
') {
+            pos--;
+            line += data[pos];
+        }
+        std::reverse(line.begin(), line.end());
+        return pos;
+    }
+
+    //! Find an XMP block
+    static void findXmp(size_t& xmpPos, size_t& xmpSize, const char* data, size_t size, bool write)
     {
-        doReadWriteMetadata(/* write = */ true);
+        // prepare list of valid XMP headers
+        std::vector<std::pair<std::string, std::string> > xmpHeaders;
+        for (size_t i = 0; i < (sizeof xmpHeadersDef) / (sizeof *xmpHeadersDef); i++) {
+            const std::string &charset = xmpHeadersDef[i].charset;
+            std::string header(xmpHeadersDef[i].header);
+            if (!convertStringCharset(header, "UTF-8", charset.c_str())) {
+                throw Error(28, charset);
+            }
+            xmpHeaders.push_back(make_pair(header, charset));
+        }
+
+        // search for valid XMP header
+        xmpSize = 0;
+        for (xmpPos = 0; xmpPos < size; xmpPos++) {
+            if (data[xmpPos] != '\x00' && data[xmpPos] != '<') continue;
+            for (size_t i = 0; i < xmpHeaders.size(); i++) {
+                const std::string &header = xmpHeaders[i].first;
+                if (xmpPos + header.size() > size) continue;
+                if (memcmp(data + xmpPos, header.data(), header.size()) != 0) continue;
+                #ifdef DEBUG
+                EXV_DEBUG << "findXmp: Found XMP header at position: " << xmpPos << "
";
+                #endif
+
+                // prepare list of valid XMP trailers in the charset of the header
+                const std::string &charset = xmpHeaders[i].second;
+                std::vector<std::pair<std::string, bool> > xmpTrailers;
+                for (size_t j = 0; j < (sizeof xmpTrailersDef) / (sizeof *xmpTrailersDef); j++) {
+                    std::string trailer(xmpTrailersDef[j].trailer);
+                    if (!convertStringCharset(trailer, "UTF-8", charset.c_str())) {
+                        throw Error(28, charset);
+                    }
+                    xmpTrailers.push_back(make_pair(trailer, xmpTrailersDef[j].readOnly));
+                }
+                std::string xmpTrailerEnd(xmpTrailerEndDef);
+                if (!convertStringCharset(xmpTrailerEnd, "UTF-8", charset.c_str())) {
+                    throw Error(28, charset);
+                }
+
+                // search for valid XMP trailer
+                for (size_t trailerPos = xmpPos + header.size(); trailerPos < size; trailerPos++) {
+                    if (data[xmpPos] != '\x00' && data[xmpPos] != '<') continue;
+                    for (size_t j = 0; j < xmpTrailers.size(); j++) {
+                        const std::string &trailer = xmpTrailers[j].first;
+                        if (trailerPos + trailer.size() > size) continue;
+                        if (memcmp(data + trailerPos, trailer.data(), trailer.size()) != 0) continue;
+                        #ifdef DEBUG
+                        EXV_DEBUG << "findXmp: Found XMP trailer at position: " << trailerPos << "
";
+                        #endif
+
+                        const bool readOnly = xmpTrailers[j].second;
+                        if (readOnly) {
+                            #ifndef SUPPRESS_WARNINGS
+                            EXV_WARNING << "Unable to handle read-only XMP metadata yet. Please provide your"
+                                           " sample EPS file to the Exiv2 project: http://dev.exiv2.org/projects/exiv2
";
+                            #endif
+                            throw Error(write ? 21 : 14);
+                        }
+
+                        // search for end of XMP trailer
+                        for (size_t trailerEndPos = trailerPos + trailer.size(); trailerEndPos + xmpTrailerEnd.size() <= size; trailerEndPos++) {
+                            if (memcmp(data + trailerEndPos, xmpTrailerEnd.data(), xmpTrailerEnd.size()) == 0) {
+                                xmpSize = (trailerEndPos + xmpTrailerEnd.size()) - xmpPos;
+                                return;
+                            }
+                        }
+                        #ifndef SUPPRESS_WARNINGS
+                        EXV_WARNING << "Found XMP header but incomplete XMP trailer.
";
+                        #endif
+                        throw Error(write ? 21 : 14);
+                    }
+                }
+                #ifndef SUPPRESS_WARNINGS
+                EXV_WARNING << "Found XMP header but no XMP trailer.
";
+                #endif
+                throw Error(write ? 21 : 14);
+            }
+        }
     }
 
-    void EpsImage::doReadWriteMetadata(bool write)
+    //! Find removable XMP embeddings
+    static std::vector<std::pair<size_t, size_t> > findRemovableEmbeddings(const char* data, size_t posEof, size_t posEndPageSetup,
+                                                                           size_t xmpPos, size_t xmpSize, bool write)
     {
+        std::vector<std::pair<size_t, size_t> > removableEmbeddings;
+        std::string line;
+        size_t pos;
+
+        // check after XMP
+        pos = xmpPos + xmpSize;
+        pos = readLine(line, data, pos, posEof);
+        if (line != "") return removableEmbeddings;
+        #ifdef DEBUG
+        EXV_DEBUG << "findRemovableEmbeddings: Found empty line after XMP
";
+        #endif
+        pos = readLine(line, data, pos, posEof);
+        if (line != "%end_xml_packet") return removableEmbeddings;
+        #ifdef DEBUG
+        EXV_DEBUG << "findRemovableEmbeddings: Found %end_xml_packet
";
+        #endif
+        size_t posEmbeddingEnd = 0;
+        for (int i = 0; i < 32; i++) {
+            pos = readLine(line, data, pos, posEof);
+            if (line == "%end_xml_code") {
+                posEmbeddingEnd = pos;
+                break;
+            }
+        }
+        if (posEmbeddingEnd == 0) return removableEmbeddings;
+        #ifdef DEBUG
+        EXV_DEBUG << "findRemovableEmbeddings: Found %end_xml_code
";
+        #endif
+
+        // check before XMP
+        pos = xmpPos;
+        pos = readPrevLine(line, data, pos, posEof);
+        if (!startsWith(line, "%begin_xml_packet: ")) return removableEmbeddings;
+        #ifdef DEBUG
+        EXV_DEBUG << "findRemovableEmbeddings: Found %begin_xml_packet: ...
";
+        #endif
+        size_t posEmbeddingStart = posEof;
+        for (int i = 0; i < 32; i++) {
+            pos = readPrevLine(line, data, pos, posEof);
+            if (line == "%begin_xml_code") {
+                posEmbeddingStart = pos;
+                break;
+            }
+        }
+        if (posEmbeddingStart == posEof) return removableEmbeddings;
         #ifdef DEBUG
-        if (write) {
-            EXV_DEBUG << "Exiv2::EpsImage::doReadWriteMetadata: Writing EPS file " << io_->path() << "
";
+        EXV_DEBUG << "findRemovableEmbeddings: Found %begin_xml_code
";
+        #endif
+
+        // check at EOF
+        pos = posEof;
+        pos = readPrevLine(line, data, pos, posEof);
+        if (line == "[/EMC pdfmark") {
+            // Exiftool style
+            #ifdef DEBUG
+            EXV_DEBUG << "findRemovableEmbeddings: Found [/EMC pdfmark
";
+            #endif
+        } else if (line == "[/NamespacePop pdfmark") {
+            // Photoshop style
+            #ifdef DEBUG
+            EXV_DEBUG << "findRemovableEmbeddings: Found /NamespacePop pdfmark
";
+            #endif
+            pos = readPrevLine(line, data, pos, posEof);
+            if (line != "[{nextImage} 1 dict begin /Metadata {photoshop_metadata_stream} def currentdict end /PUT pdfmark") return removableEmbeddings;
+            #ifdef DEBUG
+            EXV_DEBUG << "findRemovableEmbeddings: Found /PUT pdfmark
";
+            #endif
         } else {
-            EXV_DEBUG << "Exiv2::EpsImage::doReadWriteMetadata: Reading EPS file " << io_->path() << "
";
+           return removableEmbeddings;
         }
+
+        // check whether another XMP metadata block would take precedence if this one was removed
+        {
+            size_t xmpPos, xmpSize;
+            findXmp(xmpPos, xmpSize, data, posEndPageSetup, write);
+            if (xmpSize != 0) {
+                #ifndef SUPPRESS_WARNINGS
+                EXV_WARNING << "Second XMP metadata block interferes at position: " << xmpPos << "
";
+                #endif
+                if (write) throw Error(21);
+            }
+        }
+
+        removableEmbeddings.push_back(std::make_pair(posEmbeddingStart, posEmbeddingEnd));
+        removableEmbeddings.push_back(std::make_pair(pos, posEof));
+        #ifdef DEBUG
+        const size_t n = removableEmbeddings.size();
+        EXV_DEBUG << "findRemovableEmbeddings: Recognized Photoshop-style XMP embedding at "
+                     "[" << removableEmbeddings[n-2].first << "," << removableEmbeddings[n-2].second << ")"
+                     " with trailer "
+                     "[" << removableEmbeddings[n-1].first << "," << removableEmbeddings[n-1].second << ")"
+                     "
";
         #endif
+        return removableEmbeddings;
+    }
 
+    //! Unified implementation of reading and writing EPS metadata
+    static void readWriteEpsMetadata(BasicIo& io, std::string& xmpPacket, bool write)
+    {
         // open input file
-        if (io_->open() != 0) {
-            throw Error(9, io_->path(), strError());
+        if (io.open() != 0) {
+            throw Error(9, io.path(), strError());
         }
-        IoCloser closer(*io_);
+        IoCloser closer(io);
 
         // read from input file via memory map
-        const char *data = reinterpret_cast<const char*>(io_->mmap());
-        const size_t size = io_->size();
+        const char *data = reinterpret_cast<const char*>(io.mmap());
+        const size_t size = io.size();
         size_t pos = 0;
         std::string line;
 
@@ -193,7 +411,7 @@ namespace Exiv2
         pos = readLine(line, data, firstLinePos, size);
         const std::string firstLine = line;
         #ifdef DEBUG
-        EXV_DEBUG << "Exiv2::EpsImage::doReadWriteMetadata: First line: " << firstLine << "
";
+        EXV_DEBUG << "readWriteEpsMetadata: First line: " << firstLine << "
";
         #endif
         bool matched = false;
         for (size_t i = 0; !matched && i < (sizeof epsFirstLine) / (sizeof *epsFirstLine); i++) {
@@ -213,13 +431,13 @@ namespace Exiv2
         const std::string lineEnding(data + firstLinePos + firstLine.size(), pos - (firstLinePos + firstLine.size()));
         #ifdef DEBUG
         if (lineEnding == "
") {
-            EXV_DEBUG << "Exiv2::EpsImage::doReadWriteMetadata: Line ending style: Unix (LF)
";
+            EXV_DEBUG << "readWriteEpsMetadata: Line ending style: Unix (LF)
";
         } else if (lineEnding == "
") {
-            EXV_DEBUG << "Exiv2::EpsImage::doReadWriteMetadata: Line ending style: Mac (CR)
";
+            EXV_DEBUG << "readWriteEpsMetadata: Line ending style: Mac (CR)
";
         } else if (lineEnding == "
") {
-            EXV_DEBUG << "Exiv2::EpsImage::doReadWriteMetadata: Line ending style: DOS (CR LF)
";
+            EXV_DEBUG << "readWriteEpsMetadata: Line ending style: DOS (CR LF)
";
         } else {
-            EXV_DEBUG << "Exiv2::EpsImage::doReadWriteMetadata: Line ending style: (unknown)
";
+            EXV_DEBUG << "readWriteEpsMetadata: Line ending style: (unknown)
";
         }
         #endif
 
@@ -246,7 +464,7 @@ namespace Exiv2
                 if (posEndComments == size) {
                     posEndComments = startPos;
                     #ifdef DEBUG
-                    EXV_DEBUG << "Exiv2::EpsImage::doReadWriteMetadata: Found implicit EndComments at position: " << startPos << "
";
+                    EXV_DEBUG << "readWriteEpsMetadata: Found implicit EndComments at position: " << startPos << "
";
                     #endif
                 }
             }
@@ -255,13 +473,13 @@ namespace Exiv2
                     posPage = startPos;
                     implicitPage = true;
                     #ifdef DEBUG
-                    EXV_DEBUG << "Exiv2::EpsImage::doReadWriteMetadata: Found implicit Page at position: " << startPos << "
";
+                    EXV_DEBUG << "readWriteEpsMetadata: Found implicit Page at position: " << startPos << "
";
                     #endif
                 }
                 if (posEndPageSetup == size && posPage != size && !inPageSetup) {
                     posEndPageSetup = startPos;
                     #ifdef DEBUG
-                    EXV_DEBUG << "Exiv2::EpsImage::doReadWriteMetadata: Found implicit EndPageSetup at position: " << startPos << "
";
+                    EXV_DEBUG << "readWriteEpsMetadata: Found implicit EndPageSetup at position: " << startPos << "
";
                     #endif
                 }
             }
@@ -269,7 +487,7 @@ namespace Exiv2
             if (line == "%%EOF" && posPageTrailer == size) {
                 posPageTrailer = startPos;
                 #ifdef DEBUG
-                EXV_DEBUG << "Exiv2::EpsImage::doReadWriteMetadata: Found implicit PageTrailer at position: " << startPos << "
";
+                EXV_DEBUG << "readWriteEpsMetadata: Found implicit PageTrailer at position: " << startPos << "
";
                 #endif
             }
             // explicit comments
@@ -349,7 +567,7 @@ namespace Exiv2
             }
             #ifdef DEBUG
             if (significantLine) {
-                EXV_DEBUG << "Exiv2::EpsImage::doReadWriteMetadata: Found significant line \"" << line << "\" at position: " << startPos << "
";
+                EXV_DEBUG << "readWriteEpsMetadata: Found significant line \"" << line << "\" at position: " << startPos << "
";
             }
             #endif
         }
@@ -392,12 +610,12 @@ namespace Exiv2
             readLine(line, data, posLineAfterXmp, size);
             if (line == "% &&end XMP packet marker&&" || line == "%  &&end XMP packet marker&&") {
                 #ifdef DEBUG
-                EXV_DEBUG << "Exiv2::EpsImage::doReadWriteMetadata: Recognized flexible XMP embedding
";
+                EXV_DEBUG << "readWriteEpsMetadata: Recognized flexible XMP embedding
";
                 #endif
                 const size_t posBeginXmlPacket = readPrevLine(line, data, xmpPos, size);
                 if (startsWith(line, "%begin_xml_packet:")) {
                     #ifdef DEBUG
-                    EXV_DEBUG << "Exiv2::EpsImage::doReadWriteMetadata: Found %begin_xml_packet before flexible XMP embedding
";
+                    EXV_DEBUG << "readWriteEpsMetadata: Found %begin_xml_packet before flexible XMP embedding
";
                     #endif
                     if (write) {
                         fixBeginXmlPacket = true;
@@ -422,28 +640,14 @@ namespace Exiv2
         }
 
         if (!write) {
-            // copy and decode XMP metadata
-            xmpPacket_.assign(data + xmpPos, xmpSize);
-            if (xmpPacket_.size() > 0 && XmpParser::decode(xmpData_, xmpPacket_) > 1) {
-                #ifndef SUPPRESS_WARNINGS
-                EXV_WARNING << "Failed to decode XMP metadata.
";
-                #endif
-                throw Error(14);
-            }
+            // copy
+            xmpPacket.assign(data + xmpPos, xmpSize);
         } else {
             const bool useExistingEmbedding = (xmpPos != size && removableEmbeddings.empty());
 
-            // encode XMP metadata if necessary
-            if (!writeXmpFromPacket() && XmpParser::encode(xmpPacket_, xmpData_) > 1) {
-                #ifndef SUPPRESS_WARNINGS
-                EXV_WARNING << "Failed to encode XMP metadata.
";
-                #endif
-                throw Error(21);
-            }
-
             // TODO: Add support for deleting XMP metadata. Note that this is not
             //       as simple as it may seem, and requires special attention!
-            if (xmpPacket_.size() == 0) {
+            if (xmpPacket.size() == 0) {
                 #ifndef SUPPRESS_WARNINGS
                 EXV_WARNING << "Deleting XMP metadata is currently not supported.
";
                 #endif
@@ -451,7 +655,7 @@ namespace Exiv2
             }
 
             // create temporary output file
-            BasicIo::AutoPtr tempIo(io_->temporary());
+            BasicIo::AutoPtr tempIo(io.temporary());
             assert (tempIo.get() != 0);
             if (!tempIo->isopen()) {
                 #ifndef SUPPRESS_WARNINGS
@@ -460,7 +664,7 @@ namespace Exiv2
                 throw Error(21);
             }
             #ifdef DEBUG
-            EXV_DEBUG << "Exiv2::EpsImage::doReadWriteMetadata: Created temporary file " << tempIo->path() << "
";
+            EXV_DEBUG << "readWriteEpsMetadata: Created temporary file " << tempIo->path() << "
";
             #endif
 
             // sort all positions
@@ -504,7 +708,7 @@ namespace Exiv2
                 if (pos == size && pos >= 1 && data[pos - 1] != '
' && data[pos - 1] != '
') {
                     writeTemp(*tempIo, lineEnding);
                     #ifdef DEBUG
-                    EXV_DEBUG << "Exiv2::EpsImage::doReadWriteMetadata: Added missing line ending of last line
";
+                    EXV_DEBUG << "readWriteEpsMetadata: Added missing line ending of last line
";
                     #endif
                 }
                 // update and complement DSC comments
@@ -566,9 +770,9 @@ namespace Exiv2
                     // insert XMP metadata into existing flexible embedding
                     if (pos == xmpPos) {
                         if (fixBeginXmlPacket) {
-                            writeTemp(*tempIo, "%begin_xml_packet: " + toString(xmpPacket_.size()) + lineEnding);
+                            writeTemp(*tempIo, "%begin_xml_packet: " + toString(xmpPacket.size()) + lineEnding);
                         }
-                        writeTemp(*tempIo, xmpPacket_.data(), xmpPacket_.size());
+                        writeTemp(*tempIo, xmpPacket.data(), xmpPacket.size());
                         skipPos += xmpSize;
                     }
                 } else {
@@ -598,9 +802,9 @@ namespace Exiv2
                         if (photoshop) {
                             writeTemp(*tempIo, "%Exiv2Notice: The following line is needed by Photoshop. "
                                                "Parameter must be exact size of XMP metadata." + lineEnding);
-                            writeTemp(*tempIo, "%begin_xml_packet: " + toString(xmpPacket_.size()) + lineEnding);
+                            writeTemp(*tempIo, "%begin_xml_packet: " + toString(xmpPacket.size()) + lineEnding);
                         }
-                        writeTemp(*tempIo, xmpPacket_.data(), xmpPacket_.size());
+                        writeTemp(*tempIo, xmpPacket.data(), xmpPacket.size());
                         writeTemp(*tempIo, lineEnding);
                         writeTemp(*tempIo, "% &&end XMP packet marker&&" + lineEnding);
                         writeTemp(*tempIo, "[/Document 1 dict begin" + lineEnding);
@@ -635,273 +839,90 @@ namespace Exiv2
             }
 
             // copy temporary file to real output file
-            io_->close();
-            io_->transfer(*tempIo);
-        }
-
-        #ifdef DEBUG
-        if (write) {
-            EXV_DEBUG << "Exiv2::EpsImage::doReadWriteMetadata: Finished writing EPS file " << io_->path() << "
";
-        } else {
-            EXV_DEBUG << "Exiv2::EpsImage::doReadWriteMetadata: Finished reading EPS file " << io_->path() << "
";
+            io.close();
+            io.transfer(*tempIo);
         }
-        #endif
     }
 
-    std::vector<std::pair<size_t, size_t> > EpsImage::findRemovableEmbeddings(const char* data, size_t posEof, size_t posEndPageSetup,
-                                                                              size_t xmpPos, size_t xmpSize, bool write)
-    {
-        std::vector<std::pair<size_t, size_t> > removableEmbeddings;
-        std::string line;
-        size_t pos;
-
-        // check after XMP
-        pos = xmpPos + xmpSize;
-        pos = readLine(line, data, pos, posEof);
-        if (line != "") return removableEmbeddings;
-        #ifdef DEBUG
-        EXV_DEBUG << "Exiv2::EpsImage::findRemovableEmbeddings: Found empty line after XMP
";
-        #endif
-        pos = readLine(line, data, pos, posEof);
-        if (line != "%end_xml_packet") return removableEmbeddings;
-        #ifdef DEBUG
-        EXV_DEBUG << "Exiv2::EpsImage::findRemovableEmbeddings: Found %end_xml_packet
";
-        #endif
-        size_t posEmbeddingEnd = 0;
-        for (int i = 0; i < 32; i++) {
-            pos = readLine(line, data, pos, posEof);
-            if (line == "%end_xml_code") {
-                posEmbeddingEnd = pos;
-                break;
-            }
-        }
-        if (posEmbeddingEnd == 0) return removableEmbeddings;
-        #ifdef DEBUG
-        EXV_DEBUG << "Exiv2::EpsImage::findRemovableEmbeddings: Found %end_xml_code
";
-        #endif
-
-        // check before XMP
-        pos = xmpPos;
-        pos = readPrevLine(line, data, pos, posEof);
-        if (!startsWith(line, "%begin_xml_packet: ")) return removableEmbeddings;
-        #ifdef DEBUG
-        EXV_DEBUG << "Exiv2::EpsImage::findRemovableEmbeddings: Found %begin_xml_packet: ...
";
-        #endif
-        size_t posEmbeddingStart = posEof;
-        for (int i = 0; i < 32; i++) {
-            pos = readPrevLine(line, data, pos, posEof);
-            if (line == "%begin_xml_code") {
-                posEmbeddingStart = pos;
-                break;
-            }
-        }
-        if (posEmbeddingStart == posEof) return removableEmbeddings;
-        #ifdef DEBUG
-        EXV_DEBUG << "Exiv2::EpsImage::findRemovableEmbeddings: Found %begin_xml_code
";
-        #endif
-
-        // check at EOF
-        pos = posEof;
-        pos = readPrevLine(line, data, pos, posEof);
-        if (line == "[/EMC pdfmark") {
-            // Exiftool style
-            #ifdef DEBUG
-            EXV_DEBUG << "Exiv2::EpsImage::findRemovableEmbeddings: Found [/EMC pdfmark
";
-            #endif
-        } else if (line == "[/NamespacePop pdfmark") {
-            // Photoshop style
-            #ifdef DEBUG
-            EXV_DEBUG << "Exiv2::EpsImage::findRemovableEmbeddings: Found /NamespacePop pdfmark
";
-            #endif
-            pos = readPrevLine(line, data, pos, posEof);
-            if (line != "[{nextImage} 1 dict begin /Metadata {photoshop_metadata_stream} def currentdict end /PUT pdfmark") return removableEmbeddings;
-            #ifdef DEBUG
-            EXV_DEBUG << "Exiv2::EpsImage::findRemovableEmbeddings: Found /PUT pdfmark
";
-            #endif
-        } else {
-           return removableEmbeddings;
-        }
-
-        // check whether another XMP metadata block would take precedence if this one was removed
-        {
-            size_t xmpPos, xmpSize;
-            findXmp(xmpPos, xmpSize, data, posEndPageSetup, write);
-            if (xmpSize != 0) {
-                #ifndef SUPPRESS_WARNINGS
-                EXV_WARNING << "Second XMP metadata block interferes at position: " << xmpPos << "
";
-                #endif
-                if (write) throw Error(21);
-            }
-        }
+} // namespace
 
-        removableEmbeddings.push_back(std::make_pair(posEmbeddingStart, posEmbeddingEnd));
-        removableEmbeddings.push_back(std::make_pair(pos, posEof));
-        #ifdef DEBUG
-        const size_t n = removableEmbeddings.size();
-        EXV_DEBUG << "Exiv2::EpsImage::findRemovableEmbeddings: Recognized Photoshop-style XMP embedding at "
-                     "[" << removableEmbeddings[n-2].first << "," << removableEmbeddings[n-2].second << ")"
-                     " with trailer "
-                     "[" << removableEmbeddings[n-1].first << "," << removableEmbeddings[n-1].second << ")"
-                     "
";
-        #endif
-        return removableEmbeddings;
-    }
+// *****************************************************************************
+// class member definitions
+namespace Exiv2
+{
 
-    void EpsImage::findXmp(size_t& xmpPos, size_t& xmpSize, const char* data, size_t size, bool write)
+    EpsImage::EpsImage(BasicIo::AutoPtr io, bool create)
+            : Image(ImageType::eps, mdXmp, io)
     {
-        // prepare list of valid XMP headers
-        std::vector<std::pair<std::string, std::string> > xmpHeaders;
-        for (size_t i = 0; i < (sizeof xmpHeadersDef) / (sizeof *xmpHeadersDef); i++) {
-            const std::string &charset = xmpHeadersDef[i].charset;
-            std::string header(xmpHeadersDef[i].header);
-            if (!convertStringCharset(header, "UTF-8", charset.c_str())) {
-                throw Error(28, charset);
-            }
-            xmpHeaders.push_back(make_pair(header, charset));
-        }
-
-        // search for valid XMP header
-        xmpSize = 0;
-        for (xmpPos = 0; xmpPos < size; xmpPos++) {
-            if (data[xmpPos] != '\x00' && data[xmpPos] != '<') continue;
-            for (size_t i = 0; i < xmpHeaders.size(); i++) {
-                const std::string &header = xmpHeaders[i].first;
-                if (xmpPos + header.size() > size) continue;
-                if (memcmp(data + xmpPos, header.data(), header.size()) != 0) continue;
+        //LogMsg::setLevel(LogMsg::debug);
+        if (create) {
+            if (io_->open() == 0) {
                 #ifdef DEBUG
-                EXV_DEBUG << "Exiv2::EpsImage::findXmp: Found XMP header at position: " << xmpPos << "
";
+                EXV_DEBUG << "Exiv2::EpsImage:: Creating blank EPS image
";
                 #endif
-
-                // prepare list of valid XMP trailers in the charset of the header
-                const std::string &charset = xmpHeaders[i].second;
-                std::vector<std::pair<std::string, bool> > xmpTrailers;
-                for (size_t j = 0; j < (sizeof xmpTrailersDef) / (sizeof *xmpTrailersDef); j++) {
-                    std::string trailer(xmpTrailersDef[j].trailer);
-                    if (!convertStringCharset(trailer, "UTF-8", charset.c_str())) {
-                        throw Error(28, charset);
-                    }
-                    xmpTrailers.push_back(make_pair(trailer, xmpTrailersDef[j].readOnly));
-                }
-                std::string xmpTrailerEnd(xmpTrailerEndDef);
-                if (!convertStringCharset(xmpTrailerEnd, "UTF-8", charset.c_str())) {
-                    throw Error(28, charset);
-                }
-
-                // search for valid XMP trailer
-                for (size_t trailerPos = xmpPos + header.size(); trailerPos < size; trailerPos++) {
-                    if (data[xmpPos] != '\x00' && data[xmpPos] != '<') continue;
-                    for (size_t j = 0; j < xmpTrailers.size(); j++) {
-                        const std::string &trailer = xmpTrailers[j].first;
-                        if (trailerPos + trailer.size() > size) continue;
-                        if (memcmp(data + trailerPos, trailer.data(), trailer.size()) != 0) continue;
-                        #ifdef DEBUG
-                        EXV_DEBUG << "Exiv2::EpsImage::findXmp: Found XMP trailer at position: " << trailerPos << "
";
-                        #endif
-
-                        const bool readOnly = xmpTrailers[j].second;
-                        if (readOnly) {
-                            #ifndef SUPPRESS_WARNINGS
-                            EXV_WARNING << "Unable to handle read-only XMP metadata yet. Please provide your"
-                                           " sample EPS file to the Exiv2 project: http://dev.exiv2.org/projects/exiv2
";
-                            #endif
-                            throw Error(write ? 21 : 14);
-                        }
-
-                        // search for end of XMP trailer
-                        for (size_t trailerEndPos = trailerPos + trailer.size(); trailerEndPos + xmpTrailerEnd.size() <= size; trailerEndPos++) {
-                            if (memcmp(data + trailerEndPos, xmpTrailerEnd.data(), xmpTrailerEnd.size()) == 0) {
-                                xmpSize = (trailerEndPos + xmpTrailerEnd.size()) - xmpPos;
-                                return;
-                            }
-                        }
-                        #ifndef SUPPRESS_WARNINGS
-                        EXV_WARNING << "Found XMP header but incomplete XMP trailer.
";
-                        #endif
-                        throw Error(write ? 21 : 14);
-                    }
+                IoCloser closer(*io_);
+                if (io_->write(reinterpret_cast<const byte*>(epsBlank.data()), static_cast<long>(epsBlank.size())) != static_cast<long>(epsBlank.size())) {
+                    #ifndef SUPPRESS_WARNINGS
+                    EXV_WARNING << "Failed to write blank EPS image.
";
+                    #endif
+                    throw Error(21);
                 }
-                #ifndef SUPPRESS_WARNINGS
-                EXV_WARNING << "Found XMP header but no XMP trailer.
";
-                #endif
-                throw Error(write ? 21 : 14);
             }
         }
     }
 
-    size_t EpsImage::readLine(std::string& line, const char* data, size_t startPos, size_t size)
+    std::string EpsImage::mimeType() const
     {
-        line.clear();
-        size_t pos = startPos;
-        // step through line
-        while (pos < size && data[pos] != '
' && data[pos] != '
') {
-            line += data[pos];
-            pos++;
-        }
-        // skip line ending, if present
-        if (pos >= size) return pos;
-        pos++;
-        if (pos >= size) return pos;
-        if (data[pos - 1] == '
' && data[pos] == '
') pos++;
-        return pos;
+        return "application/postscript";
     }
 
-    size_t EpsImage::readPrevLine(std::string& line, const char* data, size_t startPos, size_t size)
+    void EpsImage::setComment(const std::string& /*comment*/)
     {
-        line.clear();
-        size_t pos = startPos;
-        if (pos > size) return pos;
-        // skip line ending of previous line, if present
-        if (pos <= 0) return pos;
-        if (data[pos - 1] == '
' || data[pos - 1] == '
') {
-            pos--;
-            if (pos <= 0) return pos;
-            if (data[pos - 1] == '
' && data[pos] == '
') {
-                pos--;
-                if (pos <= 0) return pos;
-            }
-        }
-        // step through previous line
-        while (pos >= 1 && data[pos - 1] != '
' && data[pos - 1] != '
') {
-            pos--;
-            line += data[pos];
-        }
-        std::reverse(line.begin(), line.end());
-        return pos;
+        throw Error(32, "Image comment", "EPS");
     }
 
-    bool EpsImage::startsWith(const std::string& s, const std::string& start)
+    void EpsImage::readMetadata()
     {
-        return s.size() >= start.size() && memcmp(s.data(), start.data(), start.size()) == 0;
-    }
+        #ifdef DEBUG
+        EXV_DEBUG << "Exiv2::EpsImage::readMetadata: Reading EPS file " << io_->path() << "
";
+        #endif
 
-    bool EpsImage::onlyWhitespaces(const std::string& s)
-    {
-        // According to the DSC 3.0 specification, 4.4 Parsing Rules,
-        // only spaces and tabs are considered to be white space characters.
-        return s.find_first_not_of(" 	") == std::string::npos;
-    }
+        // read metadata
+        readWriteEpsMetadata(*io_, xmpPacket_, /* write = */ false);
 
-    std::string EpsImage::toString(size_t size)
-    {
-        std::ostringstream stream;
-        stream << size;
-        return stream.str();
+        // decode XMP metadata
+        if (xmpPacket_.size() > 0 && XmpParser::decode(xmpData_, xmpPacket_) > 1) {
+            #ifndef SUPPRESS_WARNINGS
+            EXV_WARNING << "Failed to decode XMP metadata.
";
+            #endif
+            throw Error(14);
+        }
+
+        #ifdef DEBUG
+        EXV_DEBUG << "Exiv2::EpsImage::readMetadata: Finished reading EPS file " << io_->path() << "
";
+        #endif
     }
 
-    void EpsImage::writeTemp(BasicIo& tempIo, const char* data, size_t size)
+    void EpsImage::writeMetadata()
     {
-        if (size == 0) return;
-        if (tempIo.write(reinterpret_cast<const byte*>(data), static_cast<long>(size)) != static_cast<long>(size)) {
+        #ifdef DEBUG
+        EXV_DEBUG << "Exiv2::EpsImage::writeMetadata: Writing EPS file " << io_->path() << "
";
+        #endif
+
+        // encode XMP metadata if necessary
+        if (!writeXmpFromPacket() && XmpParser::encode(xmpPacket_, xmpData_) > 1) {
             #ifndef SUPPRESS_WARNINGS
-            EXV_WARNING << "Failed to write to temporary file.
";
+            EXV_WARNING << "Failed to encode XMP metadata.
";
             #endif
             throw Error(21);
         }
-    }
 
-    void EpsImage::writeTemp(BasicIo& tempIo, const std::string &data)
-    {
-        writeTemp(tempIo, data.data(), data.size());
+        // write metadata
+        readWriteEpsMetadata(*io_, xmpPacket_, /* write = */ true);
+
+        #ifdef DEBUG
+        EXV_DEBUG << "Exiv2::EpsImage::writeMetadata: Finished writing EPS file " << io_->path() << "
";
+        #endif
     }
 
     // *************************************************************************
diff --git a/src/epsimage.hpp b/src/epsimage.hpp
index e82366e..b067387 100644
--- a/src/epsimage.hpp
+++ b/src/epsimage.hpp
@@ -105,31 +105,6 @@ namespace Exiv2
         EpsImage& operator=(const EpsImage& rhs);
         //@}
 
-        //! @name Internal implementation
-        //@{
-        //! Unified implementation of reading and writing metadata
-        EXV_DLLLOCAL void doReadWriteMetadata(bool write);
-        //! Find removable XMP embeddings
-        EXV_DLLLOCAL static std::vector<std::pair<size_t, size_t> > findRemovableEmbeddings(const char* data, size_t posEof, size_t posEndPageSetup,
-                                                                                            size_t xmpPos, size_t xmpSize, bool write);
-        //! Find an XMP block
-        EXV_DLLLOCAL static void findXmp(size_t& xmpPos, size_t& xmpSize, const char* data, size_t size, bool write);
-        //! Read the next line of a buffer, allow for changing line ending style
-        EXV_DLLLOCAL static size_t readLine(std::string& line, const char* data, size_t startPos, size_t size);
-        //! Read the previous line of a buffer, allow for changing line ending style
-        EXV_DLLLOCAL static size_t readPrevLine(std::string& line, const char* data, size_t startPos, size_t size);
-        //! Check whether a string has a certain beginning
-        EXV_DLLLOCAL static bool startsWith(const std::string& s, const std::string& start);
-        //! Check whether a string contains only white space characters
-        EXV_DLLLOCAL static bool onlyWhitespaces(const std::string& s);
-        //! Convert an integer of type size_t to a decimal string
-        EXV_DLLLOCAL static std::string toString(size_t size);
-        //! Write data into temp file, taking care of errors
-        EXV_DLLLOCAL static void writeTemp(BasicIo& tempIo, const char* data, size_t size);
-        //! Write data into temp file, taking care of errors
-        EXV_DLLLOCAL static void writeTemp(BasicIo& tempIo, const std::string &data);
-        //@}
-
     }; // class EpsImage
 
 // *****************************************************************************

-- 
exiv2 packaging



More information about the pkg-kde-commits mailing list