Example #1
0
    bool isXmpType(BasicIo& iIo, bool advance)
    {
        /*
          Make sure the file starts with and (optional) XML declaration,
          followed by an XMP header (<?xpacket ... ?>) or an <x:xmpmeta>
          element. That doesn't cover all cases, since also x:xmpmeta is
          optional, but let's wait and see.
         */

        // Todo: Proper implementation

        const int32_t len = 10;
        byte buf[len];
        iIo.read(buf, len);
        if (iIo.error() || iIo.eof()) {
            return false;
        }
        bool rc = false;
        const std::string head(reinterpret_cast<const char*>(buf), len);
        if (   head.substr(0, 5)  == "<?xml"
            || head.substr(0, 9)  == "<?xpacket"
            || head.substr(0, 10) == "<x:xmpmeta") {
            rc = true;
        }
        if (!advance || !rc) {
            iIo.seek(-len, BasicIo::cur);
        }
        return rc;

    }
Example #2
0
 void MemIo::transfer(BasicIo& src)
 {
     MemIo *memIo = dynamic_cast<MemIo*>(&src);
     if (memIo) {
         // Optimization if src is another instance of MemIo
         if (true == isMalloced_) {
             std::free(data_);
         }
         idx_ = 0;
         data_ = memIo->data_;
         size_ = memIo->size_;
         isMalloced_ = memIo->isMalloced_;
         memIo->idx_ = 0;
         memIo->data_ = 0;
         memIo->size_ = 0;
         memIo->isMalloced_ = false;
     }
     else {
         // Generic reopen to reset position to start
         if (src.open() != 0) {
             throw Error(9, src.path(), strError());
         }
         idx_ = 0;
         write(src);
         src.close();
     }
     if (error() || src.error()) throw Error(19, strError());
 }
Example #3
0
    DataBuf PgfImage::readPgfHeaderStructure(BasicIo& iIo, int& width, int& height)
    {
        DataBuf header(16);
        long bufRead = iIo.read(header.pData_, header.size_);
        if (iIo.error()) throw Error(14);
        if (bufRead != header.size_) throw Error(20);

        DataBuf work(8);  // don't disturb the binary data - doWriteMetadata reuses it
        memcpy (work.pData_,header.pData_,8);
        width   = byteSwap_(work,0,bSwap_);
        height  = byteSwap_(work,4,bSwap_);

        /* NOTE: properties not yet used
        byte nLevels  = buffer.pData_[8];
        byte quality  = buffer.pData_[9];
        byte bpp      = buffer.pData_[10];
        byte channels = buffer.pData_[11];
        */
        byte mode     = header.pData_[12];

        if (mode == 2)  // Indexed color image. We pass color table (256 * 3 bytes).
        {
            header.alloc(16 + 256*3);

            bufRead = iIo.read(&header.pData_[16], 256*3);
            if (iIo.error()) throw Error(14);
            if (bufRead != 256*3) throw Error(20);
        }

        return header;
    } // PgfImage::readPgfHeaderStructure
Example #4
0
    DataBuf PgfImage::readPgfHeaderStructure(BasicIo& iIo, int* width, int* height)
    {
        DataBuf header(16);
        long bufRead = iIo.read(header.pData_, header.size_);
        if (iIo.error()) throw Error(14);
        if (bufRead != header.size_) throw Error(20);

        memcpy(width,  &header.pData_[0], 4);      // TODO : check endianness.
        memcpy(height, &header.pData_[4], 4);      // TODO : check endianness.

        /* NOTE: properties not yet used
        byte nLevels  = buffer.pData_[8];
        byte quality  = buffer.pData_[9];
        byte bpp      = buffer.pData_[10];
        byte channels = buffer.pData_[11];
        */
        byte mode     = header.pData_[12];

        if (mode == 2)  // Indexed color image. We pass color table (256 * 3 bytes).
        {
            header.alloc(16 + 256*3);

            bufRead = iIo.read(&header.pData_[16], 256*3);
            if (iIo.error()) throw Error(14);
            if (bufRead != 256*3) throw Error(20);
        }

        return header;
    } // PgfImage::readPgfHeaderStructure
Example #5
0
 int JpegImage::writeHeader(BasicIo& outIo) const
 {
     // Jpeg header
     byte tmpBuf[2];
     tmpBuf[0] = 0xff;
     tmpBuf[1] = soi_;
     if (outIo.write(tmpBuf, 2) != 2) return 4;
     if (outIo.error()) return 4;
     return 0;
 }
Example #6
0
    bool isTgaType(BasicIo& iIo, bool /*advance*/)
    {
        // not all TARGA files have a signature string, so first just try to match the file name extension
#ifdef EXV_UNICODE_PATH
        std::wstring wpath = iIo.wpath();
        if(   wpath.rfind(EXV_WIDEN(".tga")) != std::wstring::npos
           || wpath.rfind(EXV_WIDEN(".TGA")) != std::wstring::npos) {
            return true;
        }
#else
        std::string path = iIo.path();
        if(   path.rfind(".tga") != std::string::npos
           || path.rfind(".TGA") != std::string::npos) {
            return true;
        }
#endif
        byte buf[26];
        long curPos = iIo.tell();
        iIo.seek(-26, BasicIo::end);
        if (iIo.error() || iIo.eof())
        {
            return false;
        }
        iIo.read(buf, sizeof(buf));
        if (iIo.error())
        {
            return false;
        }
        // some TARGA files, but not all, have a signature string at the end
        bool matched = (memcmp(buf + 8, "TRUEVISION-XFILE", 16) == 0);
        iIo.seek(curPos, BasicIo::beg);
        return matched;
    }
Example #7
0
    void FileIo::transfer(BasicIo& src)
    {
        const bool wasOpen = (fp_ != 0);
        const std::string lastMode(openMode_);

        FileIo *fileIo = dynamic_cast<FileIo*>(&src);
        if (fileIo) {
            // Optimization if src is another instance of FileIo
            fileIo->close();
            // Check if the file can be written to, if it already exists
            if (open("w+b") != 0) {
                // Remove the (temporary) file
                std::remove(fileIo->path_.c_str());
                throw Error(10, path_, "w+b", strError());
            }
            close();
            struct stat buf;
            if (::stat(path_.c_str(), &buf) == -1) {
                throw Error(2, path_, strError(), "stat");
            }
            // MSVCRT rename that does not overwrite existing files
            if (fileExists(path_) && std::remove(path_.c_str()) != 0) {
                throw Error(2, path_, strError(), "std::remove");
            }
            if (std::rename(fileIo->path_.c_str(), path_.c_str()) == -1) {
                throw Error(17, fileIo->path_, path_, strError());
            }
            std::remove(fileIo->path_.c_str());
            // Set original file permissions
            if (::chmod(path_.c_str(), buf.st_mode) == -1) {
                throw Error(2, fileIo->path_, strError(), "chmod");
            }
        }
        else {
            // Generic handling, reopen both to reset to start
            if (open("w+b") != 0) {
                throw Error(10, path_, "w+b", strError());
            }
            if (src.open() != 0) {
                throw Error(9, src.path(), strError());
            }
            write(src);
            src.close();
        }

        if (wasOpen) {
            if (open(lastMode) != 0) {
                throw Error(10, path_, lastMode, strError());
            }
        }
        else close();

        if (error() || src.error()) throw Error(18, path_, strError());
    }
Example #8
0
 int ExvImage::writeHeader(BasicIo& outIo) const
 {
     // Exv header
     byte tmpBuf[7];
     tmpBuf[0] = 0xff;
     tmpBuf[1] = 0x01;
     std::memcpy(tmpBuf + 2, exiv2Id_, 5);
     if (outIo.write(tmpBuf, 7) != 7) return 4;
     if (outIo.error()) return 4;
     return 0;
 }
Example #9
0
    bool isJpegType(BasicIo& iIo, bool advance)
    {
        bool result = true;
        byte tmpBuf[2];
        iIo.read(tmpBuf, 2);
        if (iIo.error() || iIo.eof()) return false;

        if (0xff != tmpBuf[0] || JpegImage::soi_ != tmpBuf[1]) {
            result = false;
        }
        if (!advance || !result ) iIo.seek(-2, BasicIo::cur);
        return result;
    }
Example #10
0
    bool isExvType(BasicIo& iIo, bool advance)
    {
        bool result = true;
        byte tmpBuf[7];
        iIo.read(tmpBuf, 7);
        if (iIo.error() || iIo.eof()) return false;

        if (   0xff != tmpBuf[0] || 0x01 != tmpBuf[1]
            || memcmp(tmpBuf + 2, ExvImage::exiv2Id_, 5) != 0) {
            result = false;
        }
        if (!advance || !result) iIo.seek(-7, BasicIo::cur);
        return result;
    }
 bool isMrwType(BasicIo& iIo, bool advance)
 {
     const int32_t len = 4;
     byte buf[len];
     iIo.read(buf, len);
     if (iIo.error() || iIo.eof()) {
         return false;
     }
     int rc = memcmp(buf, "\0MRM", 4);
     if (!advance || rc != 0) {
         iIo.seek(-len, BasicIo::cur);
     }
     return rc == 0;
 }
Example #12
0
    long MemIo::write(BasicIo& src)
    {
        if (static_cast<BasicIo*>(this) == &src) return 0;
        if (!src.isopen()) return 0;

        byte buf[4096];
        long readCount = 0;
        long writeTotal = 0;
        while ((readCount = src.read(buf, sizeof(buf)))) {
            write(buf, readCount);
            writeTotal += readCount;
        }

        return writeTotal;
    }
Example #13
0
    byte PgfImage::readPgfMagicNumber(BasicIo& iIo)
    {
        byte b = iIo.getb();
        if (iIo.error()) throw Error(14);

        if (b < 0x36)   // 0x36 = '6'.
        {
            // Not right Magick version.
#ifdef DEBUG
            std::cout << "Exiv2::PgfImage::readMetadata: wrong Magick number\n";
#endif
        }

        return b;
    } // PgfImage::readPgfMagicNumber
Example #14
0
 bool isOrfType(BasicIo& iIo, bool advance)
 {
     const int32_t len = 8;
     byte buf[len];
     iIo.read(buf, len);
     if (iIo.error() || iIo.eof()) {
         return false;
     }
     OrfHeader orfHeader;
     bool rc = orfHeader.read(buf, len);
     if (!advance || !rc) {
         iIo.seek(-len, BasicIo::cur);
     }
     return rc;
 }
Example #15
0
    uint32_t PgfImage::readPgfHeaderSize(BasicIo& iIo)
    {
        DataBuf buffer(4);
        long bufRead = iIo.read(buffer.pData_, buffer.size_);
        if (iIo.error()) throw Error(14);
        if (bufRead != buffer.size_) throw Error(20);

        int headerSize = (int) byteSwap_(buffer,0,bSwap_);
        if (headerSize <= 0 ) throw Error(22);

#ifdef DEBUG
        std::cout << "Exiv2::PgfImage: PGF header size : " << headerSize << " bytes\n";
#endif

        return headerSize;
    } // PgfImage::readPgfHeaderSize
Example #16
0
 bool isJp2Type(BasicIo& iIo, bool advance)
 {
     const int32_t len = 12;
     byte buf[len];
     iIo.read(buf, len);
     if (iIo.error() || iIo.eof())
     {
         return false;
     }
     bool matched = (memcmp(buf, Jp2Signature, len) == 0);
     if (!advance || !matched)
     {
         iIo.seek(-len, BasicIo::cur);
     }
     return matched;
 }
Example #17
0
    bool isPgfType(BasicIo& iIo, bool advance)
    {
        const int32_t len = 3;
        byte buf[len];
        iIo.read(buf, len);
        if (iIo.error() || iIo.eof())
        {
            return false;
        }
        int rc = memcmp(buf, pgfSignature, 3);
        if (!advance || rc != 0)
        {
            iIo.seek(-len, BasicIo::cur);
        }

        return rc == 0;
    }
Example #18
0
 bool isBmpType(BasicIo& iIo, bool advance)
 {
     const int32_t len = 2;
     const unsigned char BmpImageId[2] = { 'B', 'M' };
     byte buf[len];
     iIo.read(buf, len);
     if (iIo.error() || iIo.eof())
     {
         return false;
     }
     bool matched = (memcmp(buf, BmpImageId, len) == 0);
     if (!advance || !matched)
     {
         iIo.seek(-len, BasicIo::cur);
     }
     return matched;
 }
Example #19
0
    uint32_t PgfImage::readPgfHeaderSize(BasicIo& iIo)
    {
        DataBuf buffer(4);
        long bufRead = iIo.read(buffer.pData_, buffer.size_);
        if (iIo.error()) throw Error(14);
        if (bufRead != buffer.size_) throw Error(20);

        uint32_t headerSize = 0;
        memcpy (&headerSize, buffer.pData_, 4);      // TODO : check endianness.
        if (headerSize <= 0 ) throw Error(22);

#ifdef DEBUG
        std::cout << "Exiv2::PgfImage: PGF header size : " << headerSize << " bytes\n";
#endif

        return headerSize;
    } // PgfImage::readPgfHeaderSize
Example #20
0
    bool isAsfType(BasicIo& iIo, bool advance)
    {
        const int32_t len = 16;
        byte buf[len];
        iIo.read(buf, len);

        if (iIo.error() || iIo.eof()) {
            return false;
        }

        bool matched = isASFType(buf);
        if (!advance || !matched) {
            iIo.seek(0, BasicIo::beg);
        }

        return matched;
    }
Example #21
0
    bool isPsdType(BasicIo& iIo, bool advance)
    {
        const int32_t len = 6;
        const unsigned char PsdHeader[6] = { '8', 'B', 'P', 'S', 0, 1 };
        byte buf[len];
        iIo.read(buf, len);
        if (iIo.error() || iIo.eof())
        {
            return false;
        }
        bool matched = (memcmp(buf, PsdHeader, len) == 0);
        if (!advance || !matched)
        {
            iIo.seek(-len, BasicIo::cur);
        }

        return matched;
    }
Example #22
0
 bool isCrwType(BasicIo& iIo, bool advance)
 {
     bool result = true;
     byte tmpBuf[14];
     iIo.read(tmpBuf, 14);
     if (iIo.error() || iIo.eof()) {
         return false;
     }
     if (!(   ('I' == tmpBuf[0] && 'I' == tmpBuf[1])
           || ('M' == tmpBuf[0] && 'M' == tmpBuf[1]))) {
         result = false;
     }
     if (   true == result
         && std::memcmp(tmpBuf + 6, CiffHeader::signature_, 8) != 0) {
         result = false;
     }
     if (!advance || !result) iIo.seek(-14, BasicIo::cur);
     return result;
 }
Example #23
0
 bool isGifType(BasicIo& iIo, bool advance)
 {
     const int32_t len = 6;
     const unsigned char Gif87aId[8] = { 'G', 'I', 'F', '8', '7', 'a' };
     const unsigned char Gif89aId[8] = { 'G', 'I', 'F', '8', '9', 'a' };
     byte buf[len];
     iIo.read(buf, len);
     if (iIo.error() || iIo.eof())
     {
         return false;
     }
     bool matched =    (memcmp(buf, Gif87aId, len) == 0)
                    || (memcmp(buf, Gif89aId, len) == 0);
     if (!advance || !matched)
     {
         iIo.seek(-len, BasicIo::cur);
     }
     return matched;
 }
Example #24
0
int ImageFactory::getType(BasicIo& io)
{
    if (io.open() != 0) return ImageType::none;
    IoCloser closer(io);
    for (unsigned int i = 0; registry_[i].imageType_ != ImageType::none; ++i) {
        if (registry_[i].isThisType_(io, false)) {
            return registry_[i].imageType_;
        }
    }
    return ImageType::none;
} // ImageFactory::getType
Example #25
0
    bool isXmpType(BasicIo& iIo, bool advance)
    {
        /*
          Check if the file starts with an optional XML declaration followed by
          either an XMP header (<?xpacket ... ?>) or an <x:xmpmeta> element.

          In addition, in order for empty XmpSidecar objects as created by
          Exiv2 to pass the test, just an XML header is also considered ok.
         */
        const int32_t len = 80;
        byte buf[len];
        iIo.read(buf, xmlHdrCnt + 1);
        if (   iIo.eof()
            && 0 == strncmp(reinterpret_cast<const char*>(buf), xmlHeader, xmlHdrCnt)) {
            return true;
        }
        if (iIo.error() || iIo.eof()) {
            return false;
        }
        iIo.read(buf + xmlHdrCnt + 1, len - xmlHdrCnt - 1);
        if (iIo.error() || iIo.eof()) {
            return false;
        }
        // Skip leading BOM
        int32_t start = 0;
        if (0 == strncmp(reinterpret_cast<const char*>(buf), "\xef\xbb\xbf", 3)) {
            start = 3;
        }
        bool rc = false;
        std::string head(reinterpret_cast<const char*>(buf + start), len - start);
        if (head.substr(0, 5)  == "<?xml") {
            // Forward to the next tag
            for (unsigned i = 5; i < head.size(); ++i) {
                if (head[i] == '<') {
                    head = head.substr(i);
                    break;
                }
            }
        }
        if (   head.size() > 9
            && (   head.substr(0, 9)  == "<?xpacket"
                || head.substr(0, 10) == "<x:xmpmeta")) {
            rc = true;
        }
        if (!advance || !rc) {
            iIo.seek(-(len - start), BasicIo::cur); // Swallow the BOM
        }
        return rc;

    }
Example #26
0
    uint32_t PsdImage::writeIptcData(const IptcData& iptcData, BasicIo& out) const
    {
        uint32_t resLength = 0;
        byte buf[8];

        if (iptcData.count() > 0) {
            DataBuf rawIptc = IptcParser::encode(iptcData);
            if (rawIptc.size_ > 0) {
#ifdef DEBUG
                std::cerr << std::hex << "write: resourceId: " << kPhotoshopResourceID_IPTC_NAA << "\n";
                std::cerr << std::dec << "Writing IPTC_NAA: size: " << rawIptc.size_ << "\n";
#endif
                ul2Data(buf, kPhotoshopResourceType, bigEndian);
                if (out.write(buf, 4) != 4) throw Error(21);
                us2Data(buf, kPhotoshopResourceID_IPTC_NAA, bigEndian);
                if (out.write(buf, 2) != 2) throw Error(21);
                us2Data(buf, 0, bigEndian);                      // NULL resource name
                if (out.write(buf, 2) != 2) throw Error(21);
                ul2Data(buf, rawIptc.size_, bigEndian);
                if (out.write(buf, 4) != 4) throw Error(21);
                // Write encoded Iptc data
                if (out.write(rawIptc.pData_, rawIptc.size_) != rawIptc.size_) throw Error(21);
                resLength += rawIptc.size_ + 12;
                if (rawIptc.size_ & 1)    // even padding
                {
                    buf[0] = 0;
                    if (out.write(buf, 1) != 1) throw Error(21);
                    resLength++;
                }
            }
        }
        return resLength;
    } // PsdImage::writeIptcData
Example #27
0
    long FileIo::write(BasicIo& src)
    {
        assert(fp_ != 0);
        if (static_cast<BasicIo*>(this) == &src) return 0;
        if (!src.isopen()) return 0;
        if (switchMode(opWrite) != 0) return 0;

        byte buf[4096];
        long readCount = 0;
        long writeCount = 0;
        long writeTotal = 0;
        while ((readCount = src.read(buf, sizeof(buf)))) {
            writeTotal += writeCount = (long)std::fwrite(buf, 1, readCount, fp_);
            if (writeCount != readCount) {
                // try to reset back to where write stopped
                src.seek(writeCount-readCount, BasicIo::cur);
                break;
            }
        }

        return writeTotal;
    }
Example #28
0
 Image::Type ImageFactory::getType(BasicIo& io)
 {
     IoCloser closer(io);
     if (io.open() != 0) return Image::none;
     
     Image::Type type = Image::none;
     Registry::const_iterator b = registry_->begin();
     Registry::const_iterator e = registry_->end();
     for (Registry::const_iterator i = b; i != e; ++i)
     {
         if (i->second.isThisType(io, false)) {
             type = i->first;
             break;
         }
     }
     return type;
 } // ImageFactory::getType
Example #29
0
    uint32_t PsdImage::writeXmpData(const XmpData& xmpData, BasicIo& out) const
    {
        std::string xmpPacket;
        uint32_t resLength = 0;
        byte buf[8];

#ifdef DEBUG
        std::cerr << "writeXmpFromPacket(): " << writeXmpFromPacket() << "\n";
#endif
//        writeXmpFromPacket(true);
        if (writeXmpFromPacket() == false) {
            if (XmpParser::encode(xmpPacket, xmpData) > 1) {
#ifndef SUPPRESS_WARNINGS
                std::cerr << "Error: Failed to encode XMP metadata.\n";
#endif
            }
        }

        if (xmpPacket.size() > 0) {
#ifdef DEBUG
            std::cerr << std::hex << "write: resourceId: " << kPhotoshopResourceID_XMPPacket << "\n";
            std::cerr << std::dec << "Writing XMPPacket: size: " << xmpPacket.size() << "\n";
#endif
            ul2Data(buf, kPhotoshopResourceType, bigEndian);
            if (out.write(buf, 4) != 4) throw Error(21);
            us2Data(buf, kPhotoshopResourceID_XMPPacket, bigEndian);
            if (out.write(buf, 2) != 2) throw Error(21);
            us2Data(buf, 0, bigEndian);                      // NULL resource name
            if (out.write(buf, 2) != 2) throw Error(21);
            ul2Data(buf, xmpPacket.size(), bigEndian);
            if (out.write(buf, 4) != 4) throw Error(21);
            // Write XMPPacket
            if (out.write(reinterpret_cast<const byte*>(xmpPacket.data()), static_cast<long>(xmpPacket.size()))
                != static_cast<long>(xmpPacket.size())) throw Error(21);
            if (out.error()) throw Error(21);
            resLength += xmpPacket.size() + 12;
            if (xmpPacket.size() & 1)    // even padding
            {
                buf[0] = 0;
                if (out.write(buf, 1) != 1) throw Error(21);
                resLength++;
            }
        }
        return resLength;
    } // PsdImage::writeXmpData
Example #30
0
    uint32_t PsdImage::writeExifData(const ExifData& exifData, BasicIo& out)
    {
        uint32_t resLength = 0;
        byte buf[8];

        if (exifData.count() > 0) {
            Blob blob;
            ByteOrder bo = byteOrder();
            if (bo == invalidByteOrder) {
                bo = littleEndian;
                setByteOrder(bo);
            }
            ExifParser::encode(blob, bo, exifData);

            if (blob.size() > 0) {
#ifdef DEBUG
                std::cerr << std::hex << "write: resourceId: " << kPhotoshopResourceID_ExifInfo << "\n";
                std::cerr << std::dec << "Writing ExifInfo: size: " << blob.size() << "\n";
#endif
                ul2Data(buf, kPhotoshopResourceType, bigEndian);
                if (out.write(buf, 4) != 4) throw Error(21);
                us2Data(buf, kPhotoshopResourceID_ExifInfo, bigEndian);
                if (out.write(buf, 2) != 2) throw Error(21);
                us2Data(buf, 0, bigEndian);                      // NULL resource name
                if (out.write(buf, 2) != 2) throw Error(21);
                ul2Data(buf, blob.size(), bigEndian);
                if (out.write(buf, 4) != 4) throw Error(21);
                // Write encoded Exif data
                if (out.write(&blob[0], blob.size()) != static_cast<long>(blob.size())) throw Error(21);
                resLength += blob.size() + 12;
                if (blob.size() & 1)    // even padding
                {
                    buf[0] = 0;
                    if (out.write(buf, 1) != 1) throw Error(21);
                    resLength++;
                }
            }
        }
        return resLength;
    } // PsdImage::writeExifData