예제 #1
0
파일: tgaimage.cpp 프로젝트: dtbinh/dviz
    bool isTgaType(BasicIo& iIo, bool /*advance*/)
    {
        // not all TARGA files have a signature string, so first just try to match the file name extension
        std::string path = iIo.path();
        if(path.rfind(".tga") != std::string::npos || path.rfind(".TGA") != std::string::npos)
        {
            return true;
        }

        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;
    }
예제 #2
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;

    }
예제 #3
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;
    }
 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;
 }
예제 #5
0
파일: xmpsidecar.cpp 프로젝트: obklar/exiv2
    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;

    }
예제 #6
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;
    }
예제 #7
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;
 }
예제 #8
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;
 }
예제 #9
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;
 }
예제 #10
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;
    }
예제 #11
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;
    }
예제 #12
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;
    }
예제 #13
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;
 }
예제 #14
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;
 }
예제 #15
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;
    }
예제 #16
0
파일: iotest.cpp 프로젝트: obklar/exiv2
int WriteReadSeek(BasicIo &io)
{
    byte buf[4096];
    const char tester1[] = "this is a little test of MemIo";
    const char tester2[] = "Appending this on the end";
    const char expect[] = "this is a little teAppending this on the end";
    const long insert = 19;
    const long len1 = (long)std::strlen(tester1) + 1;
    const long len2 = (long)std::strlen(tester2) + 1;

    if (io.open() != 0) {
        throw Error(9, io.path(), strError());
    }
    IoCloser closer(io);
    if (io.write((byte*)tester1, len1) != len1) {
        std::cerr << ": WRS initial write failed\n";
        return 2;
    }

    if (io.size() != len1) {
        std::cerr << ": WRS size is not " << len1 << "\n";
        return 2;
    }

    io.seek(-len1, BasicIo::cur);

    int c = EOF;
    std::memset(buf, -1, sizeof(buf));
    for (int i = 0; (c=io.getb()) != EOF; ++i) {
        buf[i] = (byte)c;
    }

    // Make sure we got the null back
    if(buf[len1-1] != 0) {
        std::cerr << ": WRS missing null terminator 1\n";
        return 3;
    }

    if (strcmp(tester1, (char*)buf) != 0 ) {
        std::cerr << ": WRS strings don't match 1\n";
        return 4;
    }

    io.seek(-2, BasicIo::end);
    if (io.getb() != 'o') {
        std::cerr << ": WRS bad getb o\n";
        return 5;
    }

    io.seek(-2, BasicIo::cur);
    if (io.getb() != 'I') {
        std::cerr << ": WRS bad getb I\n";
        return 6;
    }

    if (io.putb('O') != 'O') {
        std::cerr << ": WRS bad putb\n";
        return 7;
    }

    io.seek(-1, BasicIo::cur);
    if (io.getb() != 'O') {
        std::cerr << ": WRS bad getb O\n";
        return 8;
    }

    io.seek(insert, BasicIo::beg);
    if(io.write((byte*)tester2, len2) != len2) {
        std::cerr << ": WRS bad write 1\n";
        return 9;
    }

    // open should seek to beginning
    if (io.open() != 0)  {
        throw Error(9, io.path(), strError());
    }
    std::memset(buf, -1, sizeof(buf));
    if (io.read(buf, sizeof(buf)) != insert + len2) {
        std::cerr << ": WRS something went wrong\n";
        return 10;
    }

    // Make sure we got the null back
    if(buf[insert + len2 - 1] != 0) {
        std::cerr << ": WRS missing null terminator 2\n";
        return 11;
    }

    if (std::strcmp(expect, (char*)buf) != 0 ) {
        std::cerr << ": WRS strings don't match 2\n";
        return 12;
    }

    return 0;
}
예제 #17
0
    void PsdImage::doWriteMetadata(BasicIo& outIo)
    {
        if (!io_->isopen()) throw Error(20);
        if (!outIo.isopen()) throw Error(21);

#ifdef DEBUG
        std::cout << "Exiv2::PsdImage::doWriteMetadata: Writing PSD file " << io_->path() << "\n";
        std::cout << "Exiv2::PsdImage::doWriteMetadata: tmp file created " << outIo.path() << "\n";
#endif

        // Ensure that this is the correct image type
        if (!isPsdType(*io_, true)) {
            if (io_->error() || io_->eof()) throw Error(20);
            throw Error(22);
        }

        io_->seek(0, BasicIo::beg);    // rewind

        DataBuf lbuf(4096);
        byte buf[8];

        // Get Photoshop header from original file
        byte psd_head[26];
        if (io_->read(psd_head, 26) != 26) throw Error(3, "Photoshop");

        // Write Photoshop header data out to new PSD file
        if (outIo.write(psd_head, 26) != 26) throw Error(21);

        // Read colorDataLength from original PSD 
        if (io_->read(buf, 4) != 4) throw Error(3, "Photoshop");

        uint32_t colorDataLength = getULong(buf, bigEndian);

        // Write colorDataLength
        ul2Data(buf, colorDataLength, bigEndian);
        if (outIo.write(buf, 4) != 4) throw Error(21);
#ifdef DEBUG
        std::cerr << std::dec << "colorDataLength: " << colorDataLength << "\n";
#endif
        // Copy colorData
        uint32_t readTotal = 0;
        long toRead = 0;
        while (readTotal < colorDataLength) {
            toRead =   static_cast<long>(colorDataLength - readTotal) < lbuf.size_
                     ? colorDataLength - readTotal : lbuf.size_;
            if (io_->read(lbuf.pData_, toRead) != toRead) throw Error(3, "Photoshop");
            readTotal += toRead;
            if (outIo.write(lbuf.pData_, toRead) != toRead) throw Error(21);
        }
        if (outIo.error()) throw Error(21);

        uint32_t resLenOffset = io_->tell();  // remember for later update

        // Read length of all resource blocks from original PSD
        if (io_->read(buf, 4) != 4) throw Error(3, "Photoshop");

        uint32_t oldResLength = getULong(buf, bigEndian);
        uint32_t newResLength = 0;

        // Write oldResLength (will be updated later)
        ul2Data(buf, oldResLength, bigEndian);
        if (outIo.write(buf, 4) != 4) throw Error(21);

#ifdef DEBUG
        std::cerr << std::dec << "oldResLength: " << oldResLength << "\n";
#endif

        // Iterate over original resource blocks.
        // Replace or insert IPTC, EXIF and XMP
        // Original resource blocks assumed to be sorted ASC

        bool iptcDone = false;
        bool exifDone = false;
        bool xmpDone = false;
        while (oldResLength > 0) {
            if (io_->read(buf, 8) != 8) throw Error(3, "Photoshop");

            // read resource type and ID
            uint32_t resourceType = getULong(buf, bigEndian);

            if (resourceType != kPhotoshopResourceType) {
                break; // bad resource type
            }
            uint16_t resourceId = getUShort(buf + 4, bigEndian);
            uint32_t resourceNameLength = buf[6];
            uint32_t adjResourceNameLen = resourceNameLength & ~1;
            unsigned char resourceNameFirstChar = buf[7];

            // read rest of resource name, plus any padding
            DataBuf resName(256);
            if (   io_->read(resName.pData_, adjResourceNameLen)
                != static_cast<long>(adjResourceNameLen)) throw Error(3, "Photoshop");

            // read resource size (actual length w/o padding!)
            if (io_->read(buf, 4) != 4) throw Error(3, "Photoshop"); 

            uint32_t resourceSize = getULong(buf, bigEndian);
            uint32_t curOffset = io_->tell();

            // Write IPTC_NAA resource block
            if (   resourceId == kPhotoshopResourceID_IPTC_NAA
                || (resourceId > kPhotoshopResourceID_IPTC_NAA && iptcDone == false)) {
                newResLength += writeIptcData(iptcData_, outIo);
                resourceSize = (resourceSize + 1) & ~1;    // adjust for padding
                iptcDone = true;
            }

            // Write ExifInfo resource block
            else if (   resourceId == kPhotoshopResourceID_ExifInfo
                     || (resourceId > kPhotoshopResourceID_ExifInfo && exifDone == false)) {
                newResLength += writeExifData(exifData_, outIo);
                resourceSize = (resourceSize + 1) & ~1;    // adjust for padding
                exifDone = true;
            }

            // Write XMPpacket resource block
            else if (   resourceId == kPhotoshopResourceID_XMPPacket
                     || (resourceId > kPhotoshopResourceID_XMPPacket && xmpDone == false)) {
                newResLength += writeXmpData(xmpData_, outIo);
                resourceSize = (resourceSize + 1) & ~1;    // adjust for padding
                xmpDone = true;
            }

            // Copy all other resource blocks
            if (   resourceId != kPhotoshopResourceID_IPTC_NAA
                && resourceId != kPhotoshopResourceID_ExifInfo
                && resourceId != kPhotoshopResourceID_XMPPacket) {
#ifdef DEBUG
                std::cerr << std::hex << "copy : resourceId: " << resourceId << "\n";
                std::cerr << std::dec;
#endif
                // Copy resource block to new PSD file
                ul2Data(buf, kPhotoshopResourceType, bigEndian);
                if (outIo.write(buf, 4) != 4) throw Error(21);
                us2Data(buf, resourceId, bigEndian);
                if (outIo.write(buf, 2) != 2) throw Error(21);
                // Write resource name as Pascal string
                buf[0] = resourceNameLength & 0x000f;
                if (outIo.write(buf, 1) != 1) throw Error(21);
                buf[0] = resourceNameFirstChar;
                if (outIo.write(buf, 1) != 1) throw Error(21);
                if (   outIo.write(resName.pData_, adjResourceNameLen)
                    != static_cast<long>(adjResourceNameLen)) throw Error(21);
                ul2Data(buf, resourceSize, bigEndian);
                if (outIo.write(buf, 4) != 4) throw Error(21);

                readTotal = 0;
                toRead = 0;
                resourceSize = (resourceSize + 1) & ~1;        // pad to even
                while (readTotal < resourceSize) {
                    toRead =   static_cast<long>(resourceSize - readTotal) < lbuf.size_
                             ? resourceSize - readTotal : lbuf.size_;
                    if (io_->read(lbuf.pData_, toRead) != toRead) {
                        throw Error(3, "Photoshop");
                    }
                    readTotal += toRead;
                    if (outIo.write(lbuf.pData_, toRead) != toRead) throw Error(21);
                }
                if (outIo.error()) throw Error(21);
                newResLength += resourceSize + adjResourceNameLen + 12;
            }

            io_->seek(curOffset + resourceSize, BasicIo::beg);
            oldResLength -= (12 + adjResourceNameLen + resourceSize);
        }

        // Append IPTC_NAA resource block, if not yet written
        if (iptcDone == false) {
            newResLength += writeIptcData(iptcData_, outIo);
            iptcDone = true;
        }

        // Append ExifInfo resource block, if not yet written
        if (exifDone == false) {
            newResLength += writeExifData(exifData_, outIo);
            exifDone = true;
        }

        // Append XmpPacket resource block, if not yet written
        if (xmpDone == false) {
            newResLength += writeXmpData(xmpData_, outIo);
            xmpDone = true;
        }

        // Copy remaining data
        long readSize = 0;
        while ((readSize=io_->read(lbuf.pData_, lbuf.size_))) {
            if (outIo.write(lbuf.pData_, readSize) != readSize) throw Error(21);
        }
        if (outIo.error()) throw Error(21);

        // Update length of resources
#ifdef DEBUG
        std::cerr << "newResLength: " << newResLength << "\n";
#endif
        outIo.seek(resLenOffset, BasicIo::beg);
        ul2Data(buf, newResLength, bigEndian);
        if (outIo.write(buf, 4) != 4) throw Error(21);

    } // PsdImage::doWriteMetadata