Commit message: Change BasicIO read/write methods to use size_t
CVE: CVE-2019-13504
Vulnerability description: There is an out-of-bounds read in Exiv2::MrwImage::readMetadata in mrwimage.cpp in Exiv2 through 0.27.2.

Project: exiv2
File: actions.cpp

    int Insert::insertXmpPacket(const std::string& path, const Exiv2::DataBuf& xmpBlob, bool usePacket) const
    {
        std::string xmpPacket;
        for (size_t i = 0; i < xmpBlob.size_; i++) {
            xmpPacket += static_cast<char>(xmpBlob.pData_[i]);
        }
        Exiv2::Image::UniquePtr image = Exiv2::ImageFactory::open(path);
        image->readMetadata();
        image->clearXmpData();
        image->setXmpPacket(xmpPacket);
        image->writeXmpFromPacket(usePacket);
        image->writeMetadata();

        return 0;
    }

Project: exiv2
File: jp2image.cpp

    void Jp2Image::setComment(const std::string& /*comment*/)
    {
        // Todo: implement me!
        throw(Error(kerInvalidSettingForImage, "Image comment", "JP2"));
    } // Jp2Image::setComment

Project: exiv2
File: jpgimage.cpp

    std::string ExvImage::mimeType() const
    {
        return "image/x-exv";
    }

Project: exiv2
File: basicio.cpp

    int RemoteIo::open()
    {
        close(); // reset the IO position
        bigBlock_ = nullptr;
        if (p_->isMalloced_ == false) {
            long length = p_->getFileLength();
            if (length < 0) { // unable to get the length of remote file, get the whole file content.
                std::string data;
                p_->getDataByRange(-1, -1, data);
                p_->size_ = data.length();
                size_t nBlocks = (p_->size_ + p_->blockSize_ - 1) / p_->blockSize_;
                p_->blocksMap_  = new BlockMap[nBlocks];
                p_->isMalloced_ = true;
                byte* source = (byte*)data.c_str();
                size_t remain = p_->size_, iBlock = 0, totalRead = 0;
                while (remain) {
                    size_t allow = EXV_MIN(remain, p_->blockSize_);
                    p_->blocksMap_[iBlock].populate(&source[totalRead], allow);
                    remain -= allow;
                    totalRead += allow;
                    iBlock++;
                }
            } else if (length == 0) { // file is empty
                throw Error(kerErrorMessage, "the file length is 0");
            } else {
                p_->size_ = (size_t) length;
                size_t nBlocks = (p_->size_ + p_->blockSize_ - 1) / p_->blockSize_;
                p_->blocksMap_  = new BlockMap[nBlocks];
                p_->isMalloced_ = true;
            }
        }
        return 0; // means OK
    }

Project: exiv2
File: types.cpp

    Rational floatToRationalCast(float f)
    {
#if defined(_MSC_VER) && _MSC_VER < 1800
        if (!_finite(f)) {
#else
        if (!std::isfinite(f)) {
#endif
            return Rational(f > 0 ? 1 : -1, 0);
        }
        // Beware: primitive conversion algorithm
        int32_t den = 1000000;
        const long f_as_long = static_cast<long>(f);
        if (Safe::abs(f_as_long) > 2147) {
            den = 10000;
        }
        if (Safe::abs(f_as_long) > 214748) {
            den = 100;
        }
        if (Safe::abs(f_as_long) > 21474836) {
            den = 1;
        }
        const float rnd = f >= 0 ? 0.5f : -0.5f;
        const int32_t nom = static_cast<int32_t>(f * den + rnd);
        const int32_t g = gcd(nom, den);

        return Rational(nom / g, den / g);
    }

}                                       // namespace Exiv2

Project: exiv2
File: value.cpp

    StringValueBase::StringValueBase(TypeId typeId, const std::string& buf)
        : Value(typeId)
    {
        read(buf);
    }

Project: exiv2
File: xmp.cpp

    Xmpdatum& Xmpdatum::operator=(const Value& value)
    {
        setValue(&value);
        return *this;
    }

Project: exiv2
File: basicio.cpp

    int FileIo::Impl::switchMode(OpMode opMode)
    {
        if (fp_ == nullptr)
            return 1;
        if (opMode_ == opMode)
            return 0;
        OpMode oldOpMode = opMode_;
        opMode_ = opMode;

        bool reopen = true;
        switch (opMode) {
            case opRead:
                // Flush if current mode allows reading, else reopen (in mode "r+b"
                // as in this case we know that we can write to the file)
                if (openMode_[0] == 'r' || openMode_[1] == '+')
                    reopen = false;
                break;
            case opWrite:
                // Flush if current mode allows writing, else reopen
                if (openMode_[0] != 'r' || openMode_[1] == '+')
                    reopen = false;
                break;
            case opSeek:
                reopen = false;
                break;
        }

        if (!reopen) {
            // Do not do anything when switching _from_ opSeek mode; we
            // flush when switching _to_ opSeek.
            if (oldOpMode == opSeek)
                return 0;

            // Flush. On msvcrt fflush does not do the job
            std::fseek(fp_, 0, SEEK_CUR);
            return 0;
        }

        // Reopen the file
        long offset = std::ftell(fp_);
        if (offset == -1)
            return -1;
        // 'Manual' open("r+b") to avoid munmap()
        std::fclose(fp_);
        openMode_ = "r+b";
        opMode_ = opSeek;
#ifdef EXV_UNICODE_PATH
        if (wpMode_ == wpUnicode) {
            fp_ = ::_wfopen(wpath_.c_str(), s2ws(openMode_).c_str());
        } else
#endif
        {
            fp_ = std::fopen(path_.c_str(), openMode_.c_str());
        }
        if (fp_ == nullptr)
            return 1;
        return std::fseek(fp_, offset, SEEK_SET);
    }  // FileIo::Impl::switchMode

Project: exiv2
File: image.cpp

    Image::~Image()
    {
    }

Project: exiv2
File: jpgimage.cpp

    int Photoshop::locatePreviewIrb(const byte*     pPsData,
                                    size_t sizePsData,
                                    const byte**    record,
                                    uint32_t *const sizeHdr,
                                    uint32_t *const sizeData)
    {
        return locateIrb(pPsData, sizePsData, preview_, record, sizeHdr, sizeData);
    }

Project: exiv2
File: psdimage.cpp

    void PsdImage::writeMetadata()
    {
        if (io_->open() != 0) {
            throw Error(kerDataSourceOpenFailed, io_->path(), strError());
        }
        IoCloser closer(*io_);
        BasicIo::UniquePtr tempIo(new MemIo);
        assert (tempIo.get() != 0);

        doWriteMetadata(*tempIo);  // may throw
        io_->close();
        io_->transfer(*tempIo);  // may throw

    }  // PsdImage::writeMetadata

Project: exiv2
File: actions.cpp

    Erase* Erase::clone_() const
    {
        return new Erase(*this);
    }

Project: exiv2
File: tiffcomposite_int.cpp

    void TiffBinaryArray::doEncode(TiffEncoder& encoder, const Exifdatum* datum)
    {
        encoder.encodeBinaryArray(this, datum);
    } // TiffBinaryArray::doEncode

Project: exiv2
File: tiffcomposite_int.cpp

    void TiffEntryBase::setValue(Value::UniquePtr value)
    {
        if (value.get() == 0) return;
        tiffType_ = toTiffType(value->typeId());
        count_ = value->count();
        delete pValue_;
        pValue_ = value.release();
    } // TiffEntryBase::setValue

Project: exiv2
File: tiffimage.cpp

    bool isTiffType(BasicIo& iIo, bool advance)
    {
        const int32_t len = 8;
        byte buf[len];
        iIo.read(buf, len);
        if (iIo.error() || iIo.eof()) {
            return false;
        }
        TiffHeader tiffHeader;
        bool rc = tiffHeader.read(buf, len);
        if (!advance || !rc) {
            iIo.seek(-len, BasicIo::cur);
        }
        return rc;
    }

Project: exiv2
File: jpgimage.cpp

    bool Photoshop::isIrb(const byte* pPsData,
                          long        sizePsData)
    {
        if (sizePsData < 4) return false;
        for (size_t i = 0; i < (sizeof irbId_) / (sizeof *irbId_); i++) {
            assert(strlen(irbId_[i]) == 4);
            if (memcmp(pPsData, irbId_[i], 4) == 0) return true;
        }
        return false;
    }

Project: exiv2
File: actions.cpp

    int metacopy(const std::string& source, const std::string& tgt, Exiv2::ImageType targetType, bool preserve)
    {
#ifdef DEBUG
        std::cerr << "actions.cpp::metacopy"
                  << " source = " << source << " target = " << tgt << std::endl;
#endif

        // read the source metadata
        int rc = -1;
        if (!Exiv2::fileExists(source, true)) {
            std::cerr << source << ": " << _("Failed to open the file\n");
            return rc;
        }

        bool bStdin = source == "-";
        bool bStdout = tgt == "-";

        Exiv2::DataBuf stdIn;
        if (bStdin)
            Params::instance().getStdin(stdIn);
        Exiv2::BasicIo::UniquePtr ioStdin = Exiv2::BasicIo::UniquePtr(new Exiv2::MemIo(stdIn.pData_, stdIn.size_));

        Exiv2::Image::UniquePtr sourceImage =
            bStdin ? Exiv2::ImageFactory::open(std::move(ioStdin)) : Exiv2::ImageFactory::open(source);
        sourceImage->readMetadata();

        // Apply any modification commands to the source image on-the-fly
        Action::Modify::applyCommands(sourceImage.get());

        // Open or create the target file
        std::string target(bStdout ? temporaryPath() : tgt);

        Exiv2::Image::UniquePtr targetImage;
        if (Exiv2::fileExists(target)) {
            targetImage = Exiv2::ImageFactory::open(target);
            targetImage->readMetadata();
        } else {
            targetImage = Exiv2::ImageFactory::create(targetType, target);
            assert(targetImage.get() != 0);
        }

        // Copy each type of metadata
        if (Params::instance().target_ & Params::ctExif && !sourceImage->exifData().empty()) {
            if (Params::instance().verbose_) {
                std::cout << _("Writing Exif data from") << " " << source << " " << _("to") << " " << target
                          << std::endl;
            }
            if (preserve) {
                for (auto i = sourceImage->exifData().begin(); i != sourceImage->exifData().end(); ++i) {
                    targetImage->exifData()[i->key()] = i->value();
                }
            } else {
                targetImage->setExifData(sourceImage->exifData());
            }
        }
        if (Params::instance().target_ & Params::ctIptc && !sourceImage->iptcData().empty()) {
            if (Params::instance().verbose_) {
                std::cout << _("Writing IPTC data from") << " " << source << " " << _("to") << " " << target
                          << std::endl;
            }
            if (preserve) {
                for (auto i = sourceImage->iptcData().begin(); i != sourceImage->iptcData().end(); ++i) {
                    targetImage->iptcData()[i->key()] = i->value();
                }
            } else {
                targetImage->setIptcData(sourceImage->iptcData());
            }
        }
        if (Params::instance().target_ & (Params::ctXmp | Params::ctXmpRaw) && !sourceImage->xmpData().empty()) {
            if (Params::instance().verbose_) {
                std::cout << _("Writing XMP data from") << " " << source << " " << _("to") << " " << target
                          << std::endl;
            }

            // #1148 use Raw XMP packet if there are no XMP modification commands
            int tRawSidecar = Params::ctXmpSidecar | Params::ctXmpRaw;  // option -eXX
            // printTarget("in metacopy",Params::instance().target_,true);
            if (Params::instance().modifyCmds_.size() == 0 &&
                (Params::instance().target_ & tRawSidecar) == tRawSidecar) {
                // std::cout << "short cut" << std::endl;
                // http://www.cplusplus.com/doc/tutorial/files/
                std::ofstream os;
                os.open(target.c_str());
                sourceImage->printStructure(os, Exiv2::kpsXMP);
                os.close();
                rc = 0;
            } else if (preserve) {
                for (auto i = sourceImage->xmpData().begin(); i != sourceImage->xmpData().end(); ++i) {
                    targetImage->xmpData()[i->key()] = i->value();
                }
            } else {
                // std::cout << "long cut" << std::endl;
                targetImage->setXmpData(sourceImage->xmpData());
            }
        }
        if (Params::instance().target_ & Params::ctComment && !sourceImage->comment().empty()) {
            if (Params::instance().verbose_) {
                std::cout << _("Writing JPEG comment from") << " " << source << " " << _("to") << " " << tgt
                          << std::endl;
            }
            targetImage->setComment(sourceImage->comment());
        }
        if (rc < 0)
            try {
                targetImage->writeMetadata();
                rc = 0;
            } catch (const Exiv2::AnyError& e) {
                std::cerr << tgt << ": " << _("Could not write metadata to file") << ": " << e << "\n";
                rc = 1;
            }

        // if we used a temporary target, copy it to stdout
        if (rc == 0 && bStdout) {
            FILE* f = ::fopen(target.c_str(), "rb");
            _setmode(_fileno(stdout), O_BINARY);

            if (f) {
                char buffer[8 * 1024];
                size_t n = 1;
                while (!feof(f) && n > 0) {
                    n = fread(buffer, 1, sizeof buffer, f);
                    fwrite(buffer, 1, n, stdout);
                }
                fclose(f);
            }
        }

        // delete temporary target
        if (bStdout)
            std::remove(target.c_str());

        return rc;
    }

Project: exiv2
File: exif.cpp

    Exifdatum::Exifdatum(const ExifKey& key, const Value* pValue)
        : key_(key.clone())
    {
        if (pValue) value_ = pValue->clone();
    }

Project: exiv2
File: image.cpp

    void Image::printIFDStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStructureOption option,uint32_t start,bool bSwap,char c,int depth)
    {
        depth++;
        bool bFirst  = true  ;

        // buffer
        const size_t dirSize = 32;
        DataBuf  dir(dirSize);
        bool bPrint = option == kpsBasic || option == kpsRecursive;

        do {
            // Read top of directory
            const int seekSuccess = !io.seek(start,BasicIo::beg);
            const size_t bytesRead = io.read(dir.pData_, 2);
            if (!seekSuccess || bytesRead == 0) {
                throw Error(kerCorruptedMetadata);
            }
            uint16_t   dirLength = byteSwap2(dir,0,bSwap);

            bool tooBig = dirLength > 500;
            if ( tooBig ) {
                out << Internal::indent(depth) << "dirLength = " << dirLength << std::endl;
                throw Error(kerTiffDirectoryTooLarge);
            }

            if ( bFirst && bPrint ) {
                out << Internal::indent(depth) << Internal::stringFormat("STRUCTURE OF TIFF FILE (%c%c): ",c,c) << io.path() << std::endl;
            }

            // Read the dictionary
            for ( int i = 0 ; i < dirLength ; i ++ ) {
                if ( bFirst && bPrint ) {
                    out << Internal::indent(depth)
                        << " address |    tag                              |     "
                        << " type |    count |    offset | value\n";
                }
                bFirst = false;

                io.read(dir.pData_, 12);
                uint16_t tag    = byteSwap2(dir,0,bSwap);
                uint16_t type   = byteSwap2(dir,2,bSwap);
                uint32_t count  = byteSwap4(dir,4,bSwap);
                uint32_t offset = byteSwap4(dir,8,bSwap);

                // Break for unknown tag types else we may segfault.
                if ( !typeValid(type) ) {
                    std::cerr << "invalid type value detected in Image::printIFDStructure:  " << type << std::endl;
                    start = 0; // break from do loop
                    throw Error(kerInvalidTypeValue);
                }

                std::string sp  = "" ; // output spacer

                //prepare to print the value
                uint32_t kount  = isPrintXMP(tag,option) ? count // haul in all the data
                                : isPrintICC(tag,option) ? count // ditto
                                : isStringType(type)     ? (count > 32 ? 32 : count) // restrict long arrays
                                : count > 5              ? 5
                                : count
                                ;
                uint32_t pad    = isStringType(type) ? 1 : 0;
                uint32_t size   = isStringType(type) ? 1
                                : is2ByteType(type)  ? 2
                                : is4ByteType(type)  ? 4
                                : is8ByteType(type)  ? 8
                                : 1
                                ;

                // if ( offset > io.size() ) offset = 0; // Denial of service?

                // #55 and #56 memory allocation crash test/data/POC8
                long long allocate = (long long) size*count + pad+20;
                if ( allocate > (long long) io.size() ) {
                    throw Error(kerInvalidMalloc);
                }
                DataBuf  buf((long)allocate);  // allocate a buffer
                std::memset(buf.pData_, 0, buf.size_);
                std::memcpy(buf.pData_,dir.pData_+8,4);  // copy dir[8:11] into buffer (short strings)
                const bool bOffsetIsPointer = count*size > 4;

                if ( bOffsetIsPointer ) {         // read into buffer
                    size_t   restore = io.tell();  // save
                    io.seek(offset,BasicIo::beg);  // position
                    io.read(buf.pData_,count*size);// read
                    io.seek(restore,BasicIo::beg); // restore
                }

                if ( bPrint ) {
                    const uint32_t address = start + 2 + i*12 ;
                    const std::string offsetString = bOffsetIsPointer?
                        Internal::stringFormat("%10u", offset):
                        "";

                    out << Internal::indent(depth)
                    << Internal::stringFormat("%8u | %#06x %-28s |%10s |%9u |%10s | "
                                              ,address,tag,tagName(tag).c_str(),typeName(type),count,offsetString.c_str());
                    if ( isShortType(type) ){
                        for ( size_t k = 0 ; k < kount ; k++ ) {
                            out << sp << byteSwap2(buf,k*size,bSwap);
                            sp = " ";
                        }
                    } else if ( isLongType(type) ){
                        for ( size_t k = 0 ; k < kount ; k++ ) {
                            out << sp << byteSwap4(buf,k*size,bSwap);
                            sp = " ";
                        }

                    } else if ( isRationalType(type) ){
                        for ( size_t k = 0 ; k < kount ; k++ ) {
                            uint32_t a = byteSwap4(buf,k*size+0,bSwap);
                            uint32_t b = byteSwap4(buf,k*size+4,bSwap);
                            out << sp << a << "/" << b;
                            sp = " ";
                        }
                    } else if ( isStringType(type) ) {
                        out << sp << Internal::binaryToString(makeSlice(buf, 0, kount));
                    }

                    sp = kount == count ? "" : " ...";
                    out << sp << std::endl;

                    if ( option == kpsRecursive && (tag == 0x8769 /* ExifTag */ || tag == 0x014a/*SubIFDs*/  || type == tiffIfd) ) {
                        for ( size_t k = 0 ; k < count ; k++ ) {
                            size_t   restore = io.tell();
                            uint32_t offset2 = byteSwap4(buf,k*size,bSwap);
                            printIFDStructure(io,out,option,offset2,bSwap,c,depth);
                            io.seek(restore,BasicIo::beg);
                        }
                    } else if ( option == kpsRecursive && tag == 0x83bb /* IPTCNAA */ ) {

                        if (static_cast<size_t>(Safe::add(count, offset)) > io.size()) {
                            throw Error(kerCorruptedMetadata);
                        }

                        const size_t restore = io.tell();
                        io.seek(offset, BasicIo::beg);  // position
                        std::vector<byte> bytes(count) ;  // allocate memory
                        // TODO: once we have C++11 use bytes.data()
                        const size_t read_bytes = io.read(&bytes[0], count);
                        io.seek(restore, BasicIo::beg);
                        // TODO: once we have C++11 use bytes.data()
                        IptcData::printStructure(out, makeSliceUntil(&bytes[0], read_bytes), depth);

                    }  else if ( option == kpsRecursive && tag == 0x927c /* MakerNote */ && count > 10) {
                        size_t   restore = io.tell();  // save

                        uint32_t jump= 10           ;
                        byte     bytes[20]          ;
                        const char* chars = (const char*) &bytes[0] ;
                        io.seek(offset,BasicIo::beg);  // position
                        io.read(bytes,jump    )     ;  // read
                        bytes[jump]=0               ;
                        if ( ::strcmp("Nikon",chars) == 0 ) {
                            // tag is an embedded tiff
                            byte* bytes2=new byte[count-jump] ;  // allocate memory
                            io.read(bytes2,count-jump)        ;  // read
                            MemIo memIo(bytes2,count-jump)    ;  // create a file
                            printTiffStructure(memIo,out,option,depth);
                            delete[] bytes2                   ;  // free
                        } else {
                            // tag is an IFD
                            io.seek(0,BasicIo::beg);  // position
                            printIFDStructure(io,out,option,offset,bSwap,c,depth);
                        }

                        io.seek(restore,BasicIo::beg); // restore
                    }
                }

                if ( isPrintXMP(tag,option) ) {
                    buf.pData_[count]=0;
                    out << (char*) buf.pData_;
                }
                if ( isPrintICC(tag,option) ) {
                    out.write((const char*)buf.pData_,count);
                }
            }
            if ( start ) {
                io.read(dir.pData_, 4);
                start = tooBig ? 0 : byteSwap4(dir,0,bSwap);
            }
        } while (start) ;

        if ( bPrint ) {
            out << Internal::indent(depth) << "END " << io.path() << std::endl;
        }
        out.flush();
        depth--;
    }

Project: exiv2
File: xmp.cpp

    std::ostream& Xmpdatum::write(std::ostream& os, const ExifData*) const
    {
        return XmpProperties::printProperty(os, key(), value());
    }

Project: exiv2
File: crwimage.cpp

    Image::UniquePtr newCrwInstance(BasicIo::UniquePtr io, bool create)
    {
        Image::UniquePtr image(new CrwImage(std::move(io), create));
        if (!image->good()) {
            image.reset();
        }
        return image;
    }

Project: exiv2
File: types.cpp

    EXV_WARN_UNUSED_RESULT std::pair<byte*, long> DataBuf::release()
    {
        std::pair<byte*, long> p = std::make_pair(pData_, (long)size_);
        pData_ = 0;
        size_ = 0;
        return p;
    }

Project: exiv2
File: image.cpp

    int Image::pixelWidth() const
    {
        return pixelWidth_;
    }

Project: exiv2
File: makernote_int.cpp

        std::string readExiv2Config(const std::string& section,const std::string& value,const std::string& def)
        {
            std::string result = def;
            Exiv2::INIReader reader(Exiv2::Internal::getExiv2ConfigPath());

            if (reader.ParseError() == 0) {
                result = reader.Get(section,value,def);
            }
            return result;
        }

Project: exiv2
File: pngchunk_int.cpp

        DataBuf PngChunk::readRawProfile(const DataBuf& text, bool iTXt)
        {
            DataBuf info;
            unsigned char unhex[103] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7,  8,  9,  0,  0,  0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0,  0,  0,  0,  0, 0, 0,
                                        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, 13, 14, 15};
            if (text.size_ == 0) {
                return DataBuf();
            }

            if (iTXt) {
                info.alloc(text.size_);
                ::memcpy(info.pData_, text.pData_, text.size_);
                return info;
            }

            const char* sp = (char*)text.pData_ + 1;            // current byte (space pointer)
            const char* eot = (char*)text.pData_ + text.size_;  // end of text

            if (sp >= eot) {
                return DataBuf();
            }

            // Look for newline
            while (*sp != '\n') {
                sp++;
                if (sp == eot) {
                    return DataBuf();
                }
            }
            sp++;  // step over '\n'
            if (sp == eot) {
                return DataBuf();
            }

            // Look for length
            while (*sp == '\0' || *sp == ' ' || *sp == '\n') {
                sp++;
                if (sp == eot) {
                    return DataBuf();
                }
            }

            // Parse the length.
            long length = 0;
            while ('0' <= *sp && *sp <= '9') {
                // Compute the new length using unsigned long, so that we can
                // check for overflow.
                const unsigned long newlength = (10 * static_cast<unsigned long>(length)) + (*sp - '0');
                if (newlength > static_cast<unsigned long>(std::numeric_limits<long>::max())) {
                    return DataBuf(); // Integer overflow.
                }
                length = static_cast<long>(newlength);
                sp++;
                if (sp == eot ) {
                    return DataBuf();
                }
            }
            sp++;  // step over '\n'
            if (sp == eot) {
                return DataBuf();
            }

            enforce(length <= (eot - sp)/2, Exiv2::kerCorruptedMetadata);

            // Allocate space
            if (length == 0) {
#ifdef DEBUG
                std::cerr << "Exiv2::PngChunk::readRawProfile: Unable To Copy Raw Profile: invalid profile length\n";
#endif
            }
            info.alloc(length);
            if (info.size_ != length) {
#ifdef DEBUG
                std::cerr << "Exiv2::PngChunk::readRawProfile: Unable To Copy Raw Profile: cannot allocate memory\n";
#endif
                return DataBuf();
            }

            // Copy profile, skipping white space and column 1 "=" signs

            unsigned char* dp = (unsigned char*)info.pData_;  // decode pointer
            unsigned int nibbles = length * 2;

            for (long i = 0; i < (long)nibbles; i++) {
                enforce(sp < eot, Exiv2::kerCorruptedMetadata);
                while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f') {
                    if (*sp == '\0') {
#ifdef DEBUG
                        std::cerr << "Exiv2::PngChunk::readRawProfile: Unable To Copy Raw Profile: ran out of data\n";
#endif
                        return DataBuf();
                    }

                    sp++;
                    enforce(sp < eot, Exiv2::kerCorruptedMetadata);
                }

                if (i%2 == 0)
                    *dp = (unsigned char) (16*unhex[(int) *sp++]);
                else
                    (*dp++) += unhex[(int) *sp++];
            }

            return info;

        }  // PngChunk::readRawProfile

Project: exiv2
File: actions.cpp

    int Print::printMetadata(const Exiv2::Image* image)
    {
        bool ret = false;
        bool noExif = false;
        if (Params::instance().printTags_ & Exiv2::mdExif) {
            const Exiv2::ExifData& exifData = image->exifData();
            for (auto md = exifData.begin(); md != exifData.end(); ++md) {
                ret |= printMetadatum(*md, image);
            }
            if (exifData.empty())
                noExif = true;
        }

        bool noIptc = false;
        if (Params::instance().printTags_ & Exiv2::mdIptc) {
            const Exiv2::IptcData& iptcData = image->iptcData();
            for (auto md = iptcData.begin(); md != iptcData.end(); ++md) {
                ret |= printMetadatum(*md, image);
            }
            if (iptcData.empty())
                noIptc = true;
        }

        bool noXmp = false;
        if (Params::instance().printTags_ & Exiv2::mdXmp) {
            const Exiv2::XmpData& xmpData = image->xmpData();
            for (auto md = xmpData.begin(); md != xmpData.end(); ++md) {
                ret |= printMetadatum(*md, image);
            }
            if (xmpData.empty())
                noXmp = true;
        }

        // With -v, inform about the absence of any (requested) type of metadata
        if (Params::instance().verbose_) {
            if (noExif)
                std::cerr << path_ << ": " << _("No Exif data found in the file\n");
            if (noIptc)
                std::cerr << path_ << ": " << _("No IPTC data found in the file\n");
            if (noXmp)
                std::cerr << path_ << ": " << _("No XMP data found in the file\n");
        }

        // With -g or -K, return -3 if no matching tags were found
        int rc = 0;
        if ((!Params::instance().greps_.empty() || !Params::instance().keys_.empty()) && !ret)
            rc = 1;

        return rc;
    }

Project: exiv2
File: types.cpp

    long parseLong(const std::string& s, bool& ok)
    {
        long ret = stringTo<long>(s, ok);
        if (ok) return ret;

        float f = stringTo<float>(s, ok);
        if (ok) return static_cast<long>(f);

        Rational r = stringTo<Rational>(s, ok);
        if (ok) {
            if (r.second == 0) {
                ok = false;
                return 0;
            }
            return static_cast<long>(static_cast<float>(r.first) / r.second);
        }

        bool b = stringTo<bool>(s, ok);
        if (ok) return b ? 1 : 0;

        // everything failed, return from stringTo<long> is probably the best fit
        return ret;
    }

Project: exiv2
File: makernote_int.cpp

    uint32_t SigmaMnHeader::ifdOffset() const
    {
        return start_;
    }

Project: exiv2
File: tiffcomposite_int.cpp

    void TiffDataEntry::doAccept(TiffVisitor& visitor)
    {
        visitor.visitDataEntry(this);
    } // TiffDataEntry::doAccept

Project: exiv2
File: value.cpp

    long XmpTextValue::count() const
    {
        return size();
    }

Project: exiv2
File: jpgimage.cpp

    void JpegBase::doWriteMetadata(BasicIo& outIo)
    {
        if (!io_->isopen())
            throw Error(kerInputDataReadFailed);
        if (!outIo.isopen())
            throw Error(kerImageWriteFailed);

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

        const long bufMinSize = 36;
        size_t bufRead = 0;
        DataBuf buf(bufMinSize);
        const long seek = io_->tell();
        int count = 0;
        int search = 0;
        int insertPos = 0;
        int comPos = 0;
        int skipApp1Exif = -1;
        int skipApp1Xmp = -1;
        bool foundCompletePsData = false;
        bool foundIccData = false;
        std::vector<int> skipApp13Ps3;
        std::vector<int> skipApp2Icc;
        int skipCom = -1;
        Blob psBlob;
        DataBuf rawExif;
        xmpData().usePacket(writeXmpFromPacket());

        // Write image header
        if (writeHeader(outIo))
            throw Error(kerImageWriteFailed);

        // Read section marker
        int marker = advanceToMarker();
        if (marker < 0)
            throw Error(kerNoImageInInputData);

        // First find segments of interest. Normally app0 is first and we want
        // to insert after it. But if app0 comes after com, app1 and app13 then
        // don't bother.
        while (marker != sos_ && marker != eoi_ && search < 6) {
            // Read size and signature (ok if this hits EOF)
            bufRead = io_->read(buf.pData_, bufMinSize);
            if (io_->error())
                throw Error(kerInputDataReadFailed);
            uint16_t size = getUShort(buf.pData_, bigEndian);

            if (marker == app0_) {
                if (size < 2)
                    throw Error(kerNoImageInInputData);
                insertPos = count + 1;
                if (io_->seek(size - bufRead, BasicIo::cur))
                    throw Error(kerNoImageInInputData);
            } else if (skipApp1Exif == -1 && marker == app1_ && memcmp(buf.pData_ + 2, exifId_, 6) == 0) {
                if (size < 8)
                    throw Error(kerNoImageInInputData);
                skipApp1Exif = count;
                ++search;
                // Seek to beginning and read the current Exif data
                io_->seek(8 - bufRead, BasicIo::cur);
                rawExif.alloc(size - 8);
                io_->read(rawExif.pData_, rawExif.size_);
                if (io_->error() || io_->eof())
                    throw Error(kerNoImageInInputData);
            } else if (skipApp1Xmp == -1 && marker == app1_ && memcmp(buf.pData_ + 2, xmpId_, 29) == 0) {
                if (size < 31)
                    throw Error(kerNoImageInInputData);
                skipApp1Xmp = count;
                ++search;
                if (io_->seek(size - bufRead, BasicIo::cur))
                    throw Error(kerNoImageInInputData);
            } else if (marker == app2_ && memcmp(buf.pData_ + 2, iccId_, 11) == 0) {
                if (size < 31)
                    throw Error(kerNoImageInInputData);
                skipApp2Icc.push_back(count);
                if (!foundIccData) {
                    ++search;
                    foundIccData = true;
                }
                if (io_->seek(size - bufRead, BasicIo::cur))
                    throw Error(kerNoImageInInputData);
            } else if (!foundCompletePsData && marker == app13_ && memcmp(buf.pData_ + 2, Photoshop::ps3Id_, 14) == 0) {
#ifdef DEBUG
                std::cerr << "Found APP13 Photoshop PS3 segment\n";
#endif
                if (size < 16)
                    throw Error(kerNoImageInInputData);
                skipApp13Ps3.push_back(count);
                io_->seek(16 - bufRead, BasicIo::cur);
                // Load PS data now to allow reinsertion at any point
                DataBuf psData(size - 16);
                io_->read(psData.pData_, size - 16);
                if (io_->error() || io_->eof())
                    throw Error(kerInputDataReadFailed);
                // Append to psBlob
                append(psBlob, psData.pData_, (uint32_t)psData.size_);
                // Check whether psBlob is complete
                if (psBlob.size() > 0 && Photoshop::valid(&psBlob[0], (long)psBlob.size())) {
                    foundCompletePsData = true;
                }
            } else if (marker == com_ && skipCom == -1) {
                if (size < 2)
                    throw Error(kerNoImageInInputData);
                // Jpegs can have multiple comments, but for now only handle
                // the first one (most jpegs only have one anyway).
                skipCom = count;
                ++search;
                if (io_->seek(size - bufRead, BasicIo::cur))
                    throw Error(kerNoImageInInputData);
            } else {
                if (size < 2)
                    throw Error(kerNoImageInInputData);
                if (io_->seek(size - bufRead, BasicIo::cur))
                    throw Error(kerNoImageInInputData);
            }
            // As in jpeg-6b/wrjpgcom.c:
            // We will insert the new comment marker just before SOFn.
            // This (a) causes the new comment to appear after, rather than before,
            // existing comments; and (b) ensures that comments come after any JFIF
            // or JFXX markers, as required by the JFIF specification.
            if (comPos == 0 && inRange2(marker, sof0_, sof3_, sof5_, sof15_)) {
                comPos = count;
                ++search;
            }
            marker = advanceToMarker();
            if (marker < 0)
                throw Error(kerNoImageInInputData);
            ++count;
        }

        if (!foundCompletePsData && psBlob.size() > 0)
            throw Error(kerNoImageInInputData);
        search += (int)skipApp13Ps3.size() + (int)skipApp2Icc.size();

        if (comPos == 0) {
            if (marker == eoi_)
                comPos = count;
            else
                comPos = insertPos;
            ++search;
        }
        if (exifData_.count() > 0)
            ++search;
        if (writeXmpFromPacket() == false && xmpData_.count() > 0)
            ++search;
        if (writeXmpFromPacket() == true && xmpPacket_.size() > 0)
            ++search;
        if (foundCompletePsData || iptcData_.count() > 0)
            ++search;
        if (!comment_.empty())
            ++search;

        io_->seek(seek, BasicIo::beg);
        count = 0;
        marker = advanceToMarker();
        if (marker < 0)
            throw Error(kerNoImageInInputData);

        // To simplify this a bit, new segments are inserts at either the start
        // or right after app0. This is standard in most jpegs, but has the
        // potential to change segment ordering (which is allowed).
        // Segments are erased if there is no assigned metadata.
        while (marker != sos_ && search > 0) {
            // Read size and signature (ok if this hits EOF)
            bufRead = io_->read(buf.pData_, bufMinSize);
            if (io_->error())
                throw Error(kerInputDataReadFailed);
            // Careful, this can be a meaningless number for empty
            // images with only an eoi_ marker
            uint16_t size = getUShort(buf.pData_, bigEndian);

            if (insertPos == count) {
                byte tmpBuf[64];
                // Write Exif data first so that - if there is no app0 - we
                // create "Exif images" according to the Exif standard.
                if (exifData_.count() > 0) {
                    Blob blob;
                    ByteOrder bo = byteOrder();
                    if (bo == invalidByteOrder) {
                        bo = littleEndian;
                        setByteOrder(bo);
                    }
                    WriteMethod wm = ExifParser::encode(blob, rawExif.pData_, (uint32_t)rawExif.size_, bo, exifData_);
                    const byte* pExifData = rawExif.pData_;
                    size_t exifSize = rawExif.size_;
                    if (wm == wmIntrusive) {
                        pExifData = blob.size() > 0 ? &blob[0] : 0;
                        exifSize = blob.size();
                    }
                    if (exifSize > 0) {
                        // Write APP1 marker, size of APP1 field, Exif id and Exif data
                        tmpBuf[0] = 0xff;
                        tmpBuf[1] = app1_;

                        if (exifSize + 8 > 0xffff)
                            throw Error(kerTooLargeJpegSegment, "Exif");
                        us2Data(tmpBuf + 2, static_cast<uint16_t>(exifSize + 8), bigEndian);
                        std::memcpy(tmpBuf + 4, exifId_, 6);
                        if (outIo.write(tmpBuf, 10) != 10)
                            throw Error(kerImageWriteFailed);

                        // Write new Exif data buffer
                        if (outIo.write(pExifData, exifSize) != static_cast<long>(exifSize))
                            throw Error(kerImageWriteFailed);
                        if (outIo.error())
                            throw Error(kerImageWriteFailed);
                        --search;
                    }
                }
                if (writeXmpFromPacket() == false) {
                    if (XmpParser::encode(xmpPacket_, xmpData_,
                                          XmpParser::useCompactFormat | XmpParser::omitAllFormatting) > 1) {
#ifndef SUPPRESS_WARNINGS
                        EXV_ERROR << "Failed to encode XMP metadata.\n";
#endif
                    }
                }
                if (xmpPacket_.size() > 0) {
                    // Write APP1 marker, size of APP1 field, XMP id and XMP packet
                    tmpBuf[0] = 0xff;
                    tmpBuf[1] = app1_;

                    if (xmpPacket_.size() + 31 > 0xffff)
                        throw Error(kerTooLargeJpegSegment, "XMP");
                    us2Data(tmpBuf + 2, static_cast<uint16_t>(xmpPacket_.size() + 31), bigEndian);
                    std::memcpy(tmpBuf + 4, xmpId_, 29);
                    if (outIo.write(tmpBuf, 33) != 33)
                        throw Error(kerImageWriteFailed);

                    // Write new XMP packet
                    if (outIo.write(reinterpret_cast<const byte*>(xmpPacket_.data()),
                                    xmpPacket_.size()) != xmpPacket_.size())
                        throw Error(kerImageWriteFailed);
                    if (outIo.error())
                        throw Error(kerImageWriteFailed);
                    --search;
                }

                if (iccProfileDefined()) {
                    // Write APP2 marker, size of APP2 field, and IccProfile
                    // See comments in readMetadata() about the ICC embedding specification
                    tmpBuf[0] = 0xff;
                    tmpBuf[1] = app2_;

                    size_t chunk_size = 256 * 256 - 40;  // leave bytes for marker, header and padding
                    size_t profileSize = (int)iccProfile_.size_;
                    size_t chunks = 1 + (profileSize - 1) / chunk_size;
                    if (iccProfile_.size_ > 256 * chunk_size)
                        throw Error(kerTooLargeJpegSegment, "IccProfile");
                    for (size_t chunk = 0; chunk < chunks; chunk++) {
                        size_t bytes = profileSize > chunk_size ? chunk_size : profileSize;  // bytes to write
                        profileSize -= bytes;

                        // write JPEG marker (2 bytes)
                        if (outIo.write(tmpBuf, 2) != 2)
                            throw Error(kerImageWriteFailed);  // JPEG Marker
                        // write length (2 bytes).  length includes the 2 bytes for the length
                        us2Data(tmpBuf + 2, (uint16_t)(2 + 14 + bytes), bigEndian);
                        if (outIo.write(tmpBuf + 2, 2) != 2)
                            throw Error(kerImageWriteFailed);  // JPEG Length

                        // write the ICC_PROFILE header (14 bytes)
                        char pad[2];
                        pad[0] = static_cast<char>(chunk + 1);
                        pad[1] = static_cast<char>(chunks);
                        outIo.write((const byte*)iccId_, 12);
                        outIo.write((const byte*)pad, 2);
                        if (outIo.write(iccProfile_.pData_ + (chunk * chunk_size), bytes) != bytes)
                            throw Error(kerImageWriteFailed);
                        if (outIo.error())
                            throw Error(kerImageWriteFailed);
                    }
                    --search;
                }

                if (foundCompletePsData || iptcData_.count() > 0) {
                    // Set the new IPTC IRB, keeps existing IRBs but removes the
                    // IPTC block if there is no new IPTC data to write
                    DataBuf newPsData =
                        Photoshop::setIptcIrb(psBlob.size() > 0 ? &psBlob[0] : 0, (long)psBlob.size(), iptcData_);
                    const long maxChunkSize = 0xffff - 16;
                    const byte* chunkStart = newPsData.pData_;
                    const byte* chunkEnd = chunkStart + newPsData.size_;
                    while (chunkStart < chunkEnd) {
                        // Determine size of next chunk
                        size_t chunkSize = static_cast<long>(chunkEnd - chunkStart);
                        if (chunkSize > maxChunkSize) {
                            chunkSize = maxChunkSize;
                            // Don't break at a valid IRB boundary
                            const long writtenSize = static_cast<long>(chunkStart - newPsData.pData_);
                            if (Photoshop::valid(newPsData.pData_, writtenSize + chunkSize)) {
                                // Since an IRB has minimum size 12,
                                // (chunkSize - 8) can't be also a IRB boundary
                                chunkSize -= 8;
                            }
                        }

                        // Write APP13 marker, chunk size, and ps3Id
                        tmpBuf[0] = 0xff;
                        tmpBuf[1] = app13_;
                        us2Data(tmpBuf + 2, static_cast<uint16_t>(chunkSize + 16), bigEndian);
                        std::memcpy(tmpBuf + 4, Photoshop::ps3Id_, 14);
                        if (outIo.write(tmpBuf, 18) != 18)
                            throw Error(kerImageWriteFailed);
                        if (outIo.error())
                            throw Error(kerImageWriteFailed);

                        // Write next chunk of the Photoshop IRB data buffer
                        if (outIo.write(chunkStart, chunkSize) != chunkSize)
                            throw Error(kerImageWriteFailed);
                        if (outIo.error())
                            throw Error(kerImageWriteFailed);

                        chunkStart += chunkSize;
                    }
                    --search;
                }
            }
            if (comPos == count) {
                if (!comment_.empty()) {
                    byte tmpBuf[4];
                    // Write COM marker, size of comment, and string
                    tmpBuf[0] = 0xff;
                    tmpBuf[1] = com_;

                    if (comment_.length() + 3 > 0xffff)
                        throw Error(kerTooLargeJpegSegment, "JPEG comment");
                    us2Data(tmpBuf + 2, static_cast<uint16_t>(comment_.length() + 3), bigEndian);

                    if (outIo.write(tmpBuf, 4) != 4)
                        throw Error(kerImageWriteFailed);
                    if (outIo.write((byte*)comment_.data(), (long)comment_.length()) != comment_.length())
                        throw Error(kerImageWriteFailed);
                    if (outIo.putb(0) == EOF)
                        throw Error(kerImageWriteFailed);
                    if (outIo.error())
                        throw Error(kerImageWriteFailed);
                    --search;
                }
                --search;
            }
            if (marker == eoi_) {
                break;
            } else if (skipApp1Exif == count || skipApp1Xmp == count ||
                       std::find(skipApp13Ps3.begin(), skipApp13Ps3.end(), count) != skipApp13Ps3.end() ||
                       std::find(skipApp2Icc.begin(), skipApp2Icc.end(), count) != skipApp2Icc.end() ||
                       skipCom == count) {
                --search;
                io_->seek(size - bufRead, BasicIo::cur);
            } else {
                if (size < 2)
                    throw Error(kerNoImageInInputData);
                buf.alloc(size + 2);
                io_->seek(-(int64_t)bufRead - 2, BasicIo::cur);
                io_->read(buf.pData_, size + 2);
                if (io_->error() || io_->eof())
                    throw Error(kerInputDataReadFailed);
                if (outIo.write(buf.pData_, size + 2) != size + 2)
                    throw Error(kerImageWriteFailed);
                if (outIo.error())
                    throw Error(kerImageWriteFailed);
            }

            // Next marker
            marker = advanceToMarker();
            if (marker < 0)
                throw Error(kerNoImageInInputData);
            ++count;
        }

        // Populate the fake data, only make sense for remoteio, httpio and sshio.
        // it avoids allocating memory for parts of the file that contain image-date.
        io_->populateFakeData();

        // Copy rest of the Io
        io_->seek(-2, BasicIo::cur);
        buf.alloc(4096);
        size_t readSize = 0;
        while ((readSize = io_->read(buf.pData_, buf.size_))) {
            if (outIo.write(buf.pData_, readSize) != readSize)
                throw Error(kerImageWriteFailed);
        }
        if (outIo.error())
            throw Error(kerImageWriteFailed);

    }  // JpegBase::doWriteMetadata

Project: exiv2
File: actions.cpp

    void Modify::delMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd)
    {
        if (Params::instance().verbose_) {
            std::cout << _("Del") << " " << modifyCmd.key_ << std::endl;
        }

        Exiv2::ExifData& exifData = pImage->exifData();
        Exiv2::IptcData& iptcData = pImage->iptcData();
        Exiv2::XmpData& xmpData = pImage->xmpData();
        if (modifyCmd.metadataId_ == exif) {
            Exiv2::ExifData::iterator pos;
            Exiv2::ExifKey exifKey = Exiv2::ExifKey(modifyCmd.key_);
            while ((pos = exifData.findKey(exifKey)) != exifData.end()) {
                exifData.erase(pos);
            }
        }
        if (modifyCmd.metadataId_ == iptc) {
            Exiv2::IptcData::iterator pos;
            Exiv2::IptcKey iptcKey = Exiv2::IptcKey(modifyCmd.key_);
            while ((pos = iptcData.findKey(iptcKey)) != iptcData.end()) {
                iptcData.erase(pos);
            }
        }
        if (modifyCmd.metadataId_ == xmp) {
            Exiv2::XmpData::iterator pos;
            Exiv2::XmpKey xmpKey = Exiv2::XmpKey(modifyCmd.key_);
            if ((pos = xmpData.findKey(xmpKey)) != xmpData.end()) {
                xmpData.eraseFamily(pos);
            }
        }
    }

Project: exiv2
File: xmp.cpp

    int XmpData::add(const XmpKey& key, const Value* value)
    {
        return add(Xmpdatum(key, value));
    }

Project: exiv2
File: tiffvisitor_int.cpp

    void TiffDecoder::getObjData(byte const*& pData,
                                 long& size,
                                 uint16_t tag,
                                 IfdId group,
                                 const TiffEntryBase* object)
    {
        if (object && object->tag() == tag && object->group() == group) {
            pData = object->pData();
            size = object->size();
            return;
        }
        TiffFinder finder(tag, group);
        pRoot_->accept(finder);
        TiffEntryBase const* te = dynamic_cast<TiffEntryBase*>(finder.result());
        if (te) {
            pData = te->pData();
            size = te->size();
            return;
        }
    }

Project: exiv2
File: tiffcomposite_int.cpp

    TiffComponent* TiffComponent::doAddChild(UniquePtr /*tiffComponent*/)
    {
        return 0;
    } // TiffComponent::doAddChild

Project: exiv2
File: psdimage.cpp

    void PsdImage::doWriteMetadata(BasicIo& outIo)
    {
        if (!io_->isopen())
            throw Error(kerInputDataReadFailed);
        if (!outIo.isopen())
            throw Error(kerImageWriteFailed);

#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(kerInputDataReadFailed);
            throw Error(kerNoImageInInputData);
        }

        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(kerNotAnImage, "Photoshop");

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

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

        uint32_t colorDataLength = getULong(buf, bigEndian);

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

        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(kerNotAnImage, "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(kerImageWriteFailed);

#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(kerNotAnImage, "Photoshop");

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

            if (!Photoshop::isIrb(buf, 4)) {
                throw Error(kerNotAnImage, "Photoshop");  // 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(kerNotAnImage, "Photoshop");

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

            uint32_t resourceSize = getULong(buf, bigEndian);
            uint32_t pResourceSize = (resourceSize + 1) & ~1;  // padded resource size
            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);
                iptcDone = true;
            }

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

            // Write XMPpacket resource block
            else if ((resourceId == kPhotoshopResourceID_XMPPacket || resourceId > kPhotoshopResourceID_XMPPacket) &&
                     xmpDone == false) {
                newResLength += writeXmpData(xmpData_, outIo);
                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 : resourceType: " << resourceType << "\n";
                std::cerr << std::hex << "copy : resourceId: " << resourceId << "\n";
                std::cerr << std::dec;
#endif
                // Copy resource block to new PSD file
                ul2Data(buf, resourceType, bigEndian);
                if (outIo.write(buf, 4) != 4)
                    throw Error(kerImageWriteFailed);
                us2Data(buf, resourceId, bigEndian);
                if (outIo.write(buf, 2) != 2)
                    throw Error(kerImageWriteFailed);
                // Write resource name as Pascal string
                buf[0] = resourceNameLength & 0x00ff;
                if (outIo.write(buf, 1) != 1)
                    throw Error(kerImageWriteFailed);
                buf[0] = resourceNameFirstChar;
                if (outIo.write(buf, 1) != 1)
                    throw Error(kerImageWriteFailed);
                if (outIo.write(resName.pData_, adjResourceNameLen) != static_cast<long>(adjResourceNameLen))
                    throw Error(kerImageWriteFailed);
                ul2Data(buf, resourceSize, bigEndian);
                if (outIo.write(buf, 4) != 4)
                    throw Error(kerImageWriteFailed);

                readTotal = 0;
                toRead = 0;
                while (readTotal < pResourceSize) {
                    toRead = static_cast<long>(pResourceSize - readTotal) < lbuf.size_
                                 ? static_cast<long>(pResourceSize - readTotal)
                                 : lbuf.size_;
                    if (io_->read(lbuf.pData_, toRead) != toRead) {
                        throw Error(kerNotAnImage, "Photoshop");
                    }
                    readTotal += toRead;
                    if (outIo.write(lbuf.pData_, toRead) != toRead)
                        throw Error(kerImageWriteFailed);
                }
                if (outIo.error())
                    throw Error(kerImageWriteFailed);
                newResLength += pResourceSize + adjResourceNameLen + 12;
            }

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

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

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

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

        // Populate the fake data, only make sense for remoteio, httpio and sshio.
        // it avoids allocating memory for parts of the file that contain image-date.
        io_->populateFakeData();

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

            // 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(kerImageWriteFailed);

    }  // PsdImage::doWriteMetadata

Project: exiv2
File: tiffcomposite_int.cpp

    uint32_t TiffSubIfd::doSizeImage() const
    {
        uint32_t len = 0;
        for (Ifds::const_iterator i = ifds_.begin(); i != ifds_.end(); ++i) {
            len += (*i)->sizeImage();
        }
        return len;
    } // TiffSubIfd::doSizeImage

Project: exiv2
File: value.cpp

    long DateValue::count() const
    {
        return size();
    }

Project: exiv2
File: value.cpp

    const char* CommentValue::CharsetInfo::code(CharsetId charsetId)
    {
        return charsetTable_[ charsetId < lastCharsetId ? charsetId : undefined ].code_;
    }

Project: exiv2
File: makernote_int.cpp

    size_t FujiMnHeader::size() const
    {
        return header_.size_;
    }

Project: exiv2
File: tiffvisitor_int.cpp

    void TiffFinder::visitBinaryElement(TiffBinaryElement* object)
    {
        findObject(object);
    }

Project: exiv2
File: tiffcomposite_int.cpp

    bool TiffIfdMakernote::readHeader(const byte* pData,
                                      uint32_t    size,
                                      ByteOrder   byteOrder)
    {
        if (!pHeader_) return true;
        return pHeader_->read(pData, size, byteOrder);
    }

Project: exiv2
File: tiffcomposite_int.cpp

    TiffBinaryArray* TiffBinaryArray::doClone() const
    {
        return new TiffBinaryArray(*this);
    }

Project: exiv2
File: iptc.cpp

    Iptcdatum::Iptcdatum(const IptcKey& key,
                         const Value* pValue)
        : key_(key.clone())
    {
        if (pValue) value_ = pValue->clone();
    }

Project: exiv2
File: tiffvisitor_int.cpp

    void TiffReader::setOrigState()
    {
        pState_ = &origState_;
    }

Project: exiv2
File: tiffvisitor_int.cpp

    void TiffDecoder::visitBinaryElement(TiffBinaryElement* object)
    {
        decodeTiffEntry(object);
    }

Project: exiv2
File: value.cpp

    int Value::setDataArea(const byte* /*buf*/, long /*len*/)
    {
        return -1;
    }

Project: exiv2
File: webpimage.cpp

    void WebPImage::readMetadata()
    {
        if (io_->open() != 0) throw Error(kerDataSourceOpenFailed, io_->path(), strError());
        IoCloser closer(*io_);
        // Ensure that this is the correct image type
        if (!isWebPType(*io_, true)) {
            if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
            throw Error(kerNotAJpeg);
        }
        clearMetadata();

        byte data[12];
        DataBuf chunkId(5);
        chunkId.pData_[4] = '\0' ;

        io_->readOrThrow(data, WEBP_TAG_SIZE * 3);

        const uint32_t filesize_u32 =
            Safe::add(Exiv2::getULong(data + WEBP_TAG_SIZE, littleEndian), 8U);
        enforce(filesize_u32 <= io_->size(), Exiv2::kerCorruptedMetadata);

        // Check that `filesize_u32` is safe to cast to `long`. The `#if`
        // is needed because this check is redundant on platforms where
        // `long` is 64 bits.  On those platforms, it causes the build to
        // fail due to a compiler warning in clang.
#if LONG_MAX < UINT_MAX
        enforce(filesize_u32 <= static_cast<size_t>(std::numeric_limits<long>::max()),
                Exiv2::kerCorruptedMetadata);
#endif

        WebPImage::decodeChunks(static_cast<long>(filesize_u32));

    } // WebPImage::readMetadata

Project: exiv2
File: makernote_int.cpp

    bool Olympus2MnHeader::read(const byte* pData,
                                uint32_t size,
                                ByteOrder /*byteOrder*/)
    {
        if (!pData || size < sizeOfSignature()) return false;
        header_.alloc(sizeOfSignature());
        std::memcpy(header_.pData_, pData, header_.size_);
        if (   static_cast<uint32_t>(header_.size_) < sizeOfSignature()
            || 0 != memcmp(header_.pData_, signature_, 10)) {
            return false;
        }
        return true;
    } // Olympus2MnHeader::read

Project: exiv2
File: image.cpp

    const std::string& Image::xmpPacket() const
    {
        return xmpPacket_;
    }

Project: exiv2
File: image.cpp

    void append(Blob& blob, const byte* buf, uint32_t len)
    {
        if (len != 0) {
            assert(buf != 0);
            Blob::size_type size = blob.size();
            if (blob.capacity() - size < len) {
                blob.reserve(size + 65536);
            }
            blob.resize(size + len);
            std::memcpy(&blob[size], buf, len);
        }
    }

Project: exiv2
File: webpimage.cpp

    WebPImage::WebPImage(BasicIo::UniquePtr io)
    : Image(ImageType::webp, mdNone, std::move(io))
    {
    } // WebPImage::WebPImage

Project: exiv2
File: webpimage.cpp

    void WebPImage::inject_VP8X(BasicIo& iIo, bool has_xmp,
                                bool has_exif, bool has_alpha,
                                bool has_icc, int width, int height) {
        byte size[4]  = { 0x0A, 0x00, 0x00, 0x00 };
        byte data[10] = { 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00 };
        iIo.write((const byte*)WEBP_CHUNK_HEADER_VP8X, WEBP_TAG_SIZE);
        iIo.write(size, WEBP_TAG_SIZE);

        if (has_alpha) {
            data[0] |= WEBP_VP8X_ALPHA_BIT;
        }

        if (has_icc) {
            data[0] |= WEBP_VP8X_ICC_BIT;
        }

        if (has_xmp) {
            data[0] |= WEBP_VP8X_XMP_BIT;
        }

        if (has_exif) {
            data[0] |= WEBP_VP8X_EXIF_BIT;
        }

        /* set width - stored in 24bits*/
        int w = width - 1;
        data[4] = w & 0xFF;
        data[5] = (w >> 8) & 0xFF;
        data[6] = (w >> 16) & 0xFF;

        /* set height - stored in 24bits */
        int h = height - 1;
        data[7] = h & 0xFF;
        data[8] = (h >> 8) & 0xFF;
        data[9] = (h >> 16) & 0xFF;

        iIo.write(data, 10);

        /* Handle inject an icc profile right after VP8X chunk */
        if (has_icc) {
            byte size_buff[WEBP_TAG_SIZE];
            ul2Data(size_buff, (uint32_t)iccProfile_.size_, littleEndian);
            if (iIo.write((const byte*)WEBP_CHUNK_HEADER_VP8X, WEBP_TAG_SIZE) != WEBP_TAG_SIZE)
                throw Error(kerImageWriteFailed);
            if (iIo.write(size_buff, WEBP_TAG_SIZE) != WEBP_TAG_SIZE)
                throw Error(kerImageWriteFailed);
            if (iIo.write(iccProfile_.pData_, iccProfile_.size_) != iccProfile_.size_)
                throw Error(kerImageWriteFailed);
            if (iIo.tell() % 2) {
                if (iIo.write(&WEBP_PAD_ODD, 1) != 1) throw Error(kerImageWriteFailed);
            }

            has_icc = false;
        }
    }

Project: exiv2
File: xmp.cpp

    void XmpData::sortByKey()
    {
        std::sort(xmpMetadata_.begin(), xmpMetadata_.end(), cmpMetadataByKey);
    }

Project: exiv2
File: tiffvisitor_int.cpp

    int TiffReader::nextIdx(IfdId group)
    {
        return ++idxSeq_[group];
    }

Project: exiv2
File: iptc.cpp

    int IptcData::add(const Iptcdatum& iptcDatum)
    {
        if (!IptcDataSets::dataSetRepeatable(
               iptcDatum.tag(), iptcDatum.record()) &&
               findId(iptcDatum.tag(), iptcDatum.record()) != end()) {
             return 6;
        }
        // allow duplicates
        iptcMetadata_.push_back(iptcDatum);
        return 0;
    }

Project: exiv2
File: tiffcomposite_int.cpp

    void TiffImageEntry::doAccept(TiffVisitor& visitor)
    {
        visitor.visitImageEntry(this);
    } // TiffImageEntry::doAccept

Project: exiv2
File: tiffcomposite_int.cpp

    TiffSizeEntry::~TiffSizeEntry()
    {
    }

Project: exiv2
File: tiffcomposite_int.cpp

    void TiffIfdMakernote::doAccept(TiffVisitor& visitor)
    {
        if (visitor.go(TiffVisitor::geTraverse)) visitor.visitIfdMakernote(this);
        if (visitor.go(TiffVisitor::geKnownMakernote)) ifd_.accept(visitor);
        if (   visitor.go(TiffVisitor::geKnownMakernote)
            && visitor.go(TiffVisitor::geTraverse)) visitor.visitIfdMakernoteEnd(this);
    }

Project: exiv2
File: value.cpp

    TimeValue::TimeValue()
        : Value(time)
    {
    }

Project: exiv2
File: convert.cpp

    std::string Converter::computeExifDigest(bool)
    {
        return std::string("");
    }

Project: exiv2
File: preview.cpp

    DataBuf LoaderXmpJpeg::getData() const
    {
        if (!valid()) return DataBuf();
        return DataBuf(preview_.pData_, preview_.size_);
    }

Project: exiv2
File: tiffcomposite_int.cpp

    TiffBinaryElement::~TiffBinaryElement()
    {
    }

Project: exiv2
File: xmp.cpp

    float Xmpdatum::toFloat(long n) const
    {
        return p_->value_.get() == 0 ? -1 : p_->value_->toFloat(n);
    }

Project: exiv2
File: makernote_int.cpp

    uint32_t PentaxDngMnHeader::baseOffset(uint32_t mnOffset) const
    {
        return mnOffset;
    }

Project: exiv2
File: tiffvisitor_int.cpp

    void TiffEncoder::visitMnEntry(TiffMnEntry* object)
    {
        // Test is required here as well as in the callback encoder function
        if (!object->mn_) {
            encodeTiffComponent(object);
        }
        else if (del_) {
            // The makernote is made up of decoded tags, delete binary tag
            ExifKey key(object->tag(), groupName(object->group()));
            ExifData::iterator pos = exifData_.findKey(key);
            if (pos != exifData_.end()) exifData_.erase(pos);
        }
    }

Project: exiv2
File: image.cpp

    uint16_t Image::byteSwap2(const DataBuf& buf,size_t offset,bool bSwap) const
    {
        uint16_t v;
        char*    p = (char*) &v;
        p[0] = buf.pData_[offset];
        p[1] = buf.pData_[offset+1];
        return Image::byteSwap(v,bSwap);
    }

Project: exiv2
File: makernote_int.cpp

    TiffComponent* newNikonMn(uint16_t    tag,
                              IfdId       group,
                              IfdId       /*mnGroup*/,
                              const byte* pData,
                              uint32_t    size,
                              ByteOrder   /*byteOrder*/)
    {
        // If there is no "Nikon" string it must be Nikon1 format
        if (size < 6 ||    std::string(reinterpret_cast<const char*>(pData), 6)
                        != std::string("Nikon\0", 6)) {
            // Require at least an IFD with 1 entry
            if (size < 18) return 0;
            return newIfdMn2(tag, group, nikon1Id);
        }
        // If the "Nikon" string is not followed by a TIFF header, we assume
        // Nikon2 format
        TiffHeader tiffHeader;
        if (   size < 18
            || !tiffHeader.read(pData + 10, size - 10)
            || tiffHeader.tag() != 0x002a) {
            // Require at least the header and an IFD with 1 entry
            if (size < Nikon2MnHeader::sizeOfSignature() + 18) return 0;
            return newNikon2Mn2(tag, group, nikon2Id);
        }
        // Else we have a Nikon3 makernote
        // Require at least the header and an IFD with 1 entry
        if (size < Nikon3MnHeader::sizeOfSignature() + 18) return 0;
        return newNikon3Mn2(tag, group, nikon3Id);
    }

Project: exiv2
File: value.cpp

    long StringValueBase::toLong(long n) const
    {
        ok_ = true;
        return value_[n];
    }

Project: exiv2
File: preview.cpp

    Loader::Loader(PreviewId id, const Image &image)
        : id_(id), image_(image),
          width_(0), height_(0),
          size_(0),
          valid_(false)
    {
    }

Project: exiv2
File: image.cpp

    Image::UniquePtr ImageFactory::open(BasicIo::UniquePtr io)
    {
        if (io->open() != 0) {
            throw Error(kerDataSourceOpenFailed, io->path(), strError());
        }
        for (unsigned int i = 0; registry[i].imageType_ != ImageType::none; ++i) {
            if (registry[i].isThisType_(*io, false)) {
                return registry[i].newInstance_(std::move(io), false);
            }
        }
        return Image::UniquePtr();
    }

Project: exiv2
File: tiffcomposite_int.cpp

    TiffComponent* TiffComponent::addChild(TiffComponent::UniquePtr tiffComponent)
    {
        return doAddChild(std::move(tiffComponent));
    } // TiffComponent::addChild

Project: exiv2
File: tiffimage.cpp

    EncoderFct TiffMapping::findEncoder(
        const std::string& make,
              uint32_t     extendedTag,
              IfdId        group
    )
    {
        EncoderFct encoderFct = 0;
        const TiffMappingInfo* td = find(tiffMappingInfo_,
                                         TiffMappingInfo::Key(make, extendedTag, group));
        if (td) {
            // Returns 0 if no special encoder function is found
            encoderFct = td->encoderFct_;
        }
        return encoderFct;
    }

Project: exiv2
File: makernote_int.cpp

    TiffComponent* newSigmaMn(uint16_t    tag,
                              IfdId       group,
                              IfdId       mnGroup,
                              const byte* /*pData*/,
                              uint32_t    size,
                              ByteOrder   /*byteOrder*/)
    {
        // Require at least the header and an IFD with 1 entry
        if (size < SigmaMnHeader::sizeOfSignature() + 18) return 0;
        return newSigmaMn2(tag, group, mnGroup);
    }

Project: exiv2
File: crwimage_int.cpp

    void CiffDirectory::doAddComponent(UniquePtr component)
    {
        components_.push_back(component.release());
    }

Project: exiv2
File: tiffvisitor_int.cpp

    void TiffCopier::visitImageEntry(TiffImageEntry* object)
    {
        copyObject(object);
    }

Project: exiv2
File: crwimage_int.cpp

    void CiffComponent::doPrint(std::ostream&      os,
                                ByteOrder          byteOrder,
                                const std::string& prefix) const
    {
        os << prefix
           << _("tag") << " = 0x" << std::setw(4) << std::setfill('0')
           << std::hex << std::right << tagId()
           << ", " << _("dir") << " = 0x" << std::setw(4) << std::setfill('0')
           << std::hex << std::right << dir()
           << ", " << _("type") << " = " << TypeInfo::typeName(typeId())
           << ", " << _("size") << " = " << std::dec << size_
           << ", " << _("offset") << " = " << offset_ << "\n";

        Value::UniquePtr value;
        if (typeId() != directory) {
            value = Value::create(typeId());
            value->read(pData_, size_, byteOrder);
            if (value->size() < 100) {
                os << prefix << *value << "\n";
            }
        }
    } // CiffComponent::doPrint

Project: exiv2
File: preview.cpp

    long PreviewImage::writeFile(const std::wstring& wpath) const
    {
        std::wstring name = wpath + wextension();
        // Todo: Creating a DataBuf here unnecessarily copies the memory
        DataBuf buf(pData_, size_);
        return Exiv2::writeFile(buf, name);
    }

Project: exiv2
File: crwimage_int.cpp

    void CrwMap::decodeBasic(const CiffComponent& ciffComponent,
                             const CrwMapping*    pCrwMapping,
                                   Image&         image,
                                   ByteOrder      byteOrder)
    {
        assert(pCrwMapping != 0);
        // create a key and value pair
        ExifKey key(pCrwMapping->tag_, Internal::groupName(pCrwMapping->ifdId_));
        Value::UniquePtr value;
        if (ciffComponent.typeId() != directory) {
            value = Value::create(ciffComponent.typeId());
            uint32_t size = 0;
            if (pCrwMapping->size_ != 0) {
                // size in the mapping table overrides all
                size = pCrwMapping->size_;
            }
            else if (ciffComponent.typeId() == asciiString) {
                // determine size from the data, by looking for the first 0
                uint32_t i = 0;
                for (;    i < ciffComponent.size()
                       && ciffComponent.pData()[i] != '\0'; ++i) {
                    // empty
                }
                size = ++i;
            }
            else {
                // by default, use the size from the directory entry
                size = ciffComponent.size();
            }
            value->read(ciffComponent.pData(), size, byteOrder);
        }
        // Add metadatum to exif data
        image.exifData().add(key, value.get());
    } // CrwMap::decodeBasic

Project: exiv2
File: xmp.cpp

    size_t Xmpdatum::count() const
    {
        return p_->value_.get() == 0 ? 0 : p_->value_->count();
    }

Project: exiv2
File: exif.cpp

    Value::UniquePtr Exifdatum::getValue() const
    {
        return value_.get() == 0 ? nullptr : value_->clone();
    }

Project: exiv2
File: tiffcomposite_int.cpp

    uint32_t TiffIfdMakernote::ifdOffset() const
    {
        if (!pHeader_) return 0;
        return pHeader_->ifdOffset();
    }

Project: exiv2
File: tiffcomposite_int.cpp

    TiffIfdMakernote* TiffIfdMakernote::doClone() const
    {
        assert(false); // Not implemented
        return 0;
    }

Project: exiv2
File: xmp.cpp

    Xmpdatum::Impl::Impl(const XmpKey& key, const Value* pValue)
        : key_(key.clone())
    {
        if (pValue) value_ = pValue->clone();
    }

Project: exiv2
File: preview.cpp

    LoaderNative::LoaderNative(PreviewId id, const Image &image, int parIdx)
        : Loader(id, image)
    {
        if (!(0 <= parIdx && static_cast<size_t>(parIdx) < image.nativePreviews().size())) return;
        nativePreview_ = image.nativePreviews()[parIdx];
        width_ = nativePreview_.width_;
        height_ = nativePreview_.height_;
        valid_ = true;
        if (nativePreview_.filter_ == "") {
            size_ = nativePreview_.size_;
        } else {
            size_ = getData().size_;
        }
    }

Project: exiv2
File: exif.cpp

    long ExifThumbC::writeFile(const std::wstring& wpath) const
    {
        Thumbnail::UniquePtr thumbnail = Thumbnail::create(exifData_);
        if (thumbnail.get() == 0) return 0;
        std::wstring name = wpath + thumbnail->wextension();
        DataBuf buf(thumbnail->copy(exifData_));
        if (buf.size_ == 0) return 0;
        return Exiv2::writeFile(buf, name);
    }

Project: exiv2
File: tiffvisitor_int.cpp

    TiffVisitor::TiffVisitor()
    {
        for (int i = 0; i < events_; ++i) {
            go_[i] = true;
        }
    }

Project: exiv2
File: makernote_int.cpp

    size_t SamsungMnHeader::size() const
    {
        return 0;
    }

Project: exiv2
File: tiffcomposite_int.cpp

    uint32_t TiffIfdMakernote::doSizeImage() const
    {
        return ifd_.sizeImage();
    } // TiffIfdMakernote::doSizeImage

Project: exiv2
File: exif.cpp

    std::string Exifdatum::groupName() const
    {
        return key_.get() == 0 ? "" : key_->groupName();
    }

Project: exiv2
File: value.cpp

    XmpArrayValue::XmpArrayValue(TypeId typeId)
        : XmpValue(typeId)
    {
        setXmpArrayType(xmpArrayType(typeId));
    }

Project: exiv2
File: convert.cpp

    void Converter::cnvExifComment(const char* from, const char* to)
    {
        Exiv2::ExifData::iterator pos = exifData_->findKey(ExifKey(from));
        if (pos == exifData_->end()) return;
        if (!prepareXmpTarget(to)) return;
        const CommentValue* cv = dynamic_cast<const CommentValue*>(&pos->value());
        if (cv == 0) {
#ifndef SUPPRESS_WARNINGS
            EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
#endif
            return;
        }
        // Todo: Convert to UTF-8 if necessary
        (*xmpData_)[to] = cv->comment();
        if (erase_) exifData_->erase(pos);
    }

Project: exiv2
File: actions.cpp

    int Modify::addMetadatum(Exiv2::Image* pImage, const ModifyCmd& modifyCmd)
    {
        if (Params::instance().verbose_) {
            std::cout << _("Add") << " " << modifyCmd.key_ << " \"" << modifyCmd.value_ << "\" ("
                      << Exiv2::TypeInfo::typeName(modifyCmd.typeId_) << ")" << std::endl;
        }
        Exiv2::ExifData& exifData = pImage->exifData();
        Exiv2::IptcData& iptcData = pImage->iptcData();
        Exiv2::XmpData& xmpData = pImage->xmpData();
        Exiv2::Value::UniquePtr value = Exiv2::Value::create(modifyCmd.typeId_);
        int rc = value->read(modifyCmd.value_);
        if (0 == rc) {
            if (modifyCmd.metadataId_ == exif) {
                exifData.add(Exiv2::ExifKey(modifyCmd.key_), value.get());
            }
            if (modifyCmd.metadataId_ == iptc) {
                iptcData.add(Exiv2::IptcKey(modifyCmd.key_), value.get());
            }
            if (modifyCmd.metadataId_ == xmp) {
                xmpData.add(Exiv2::XmpKey(modifyCmd.key_), value.get());
            }
        } else {
            std::cerr << _("Warning") << ": " << modifyCmd.key_ << ": " << _("Failed to read") << " "
                      << Exiv2::TypeInfo::typeName(value->typeId()) << " " << _("value") << " \"" << modifyCmd.value_
                      << "\"\n";
        }
        return rc;
    }

Project: exiv2
File: tiffcomposite_int.cpp

    TiffDirectory* TiffDirectory::doClone() const
    {
        return new TiffDirectory(*this);
    }

Project: exiv2
File: tiffvisitor_int.cpp

    void TiffCopier::visitEntry(TiffEntry* object)
    {
        copyObject(object);
    }

Project: exiv2
File: value.cpp

    float StringValueBase::toFloat(long n) const
    {
        ok_ = true;
        return value_[n];
    }

Project: exiv2
File: tiffcomposite_int.cpp

    TiffComponent* TiffComponent::doAddPath(uint16_t  /*tag*/,
                                            TiffPath& /*tiffPath*/,
                                            TiffComponent* const /*pRoot*/,
                                            TiffComponent::UniquePtr /*object*/)
    {
        return this;
    } // TiffComponent::doAddPath

Project: exiv2
File: tiffvisitor_int.cpp

    void TiffVisitor::visitDirectoryNext(TiffDirectory* /*object*/)
    {
    }

Project: exiv2
File: tiffcomposite_int.cpp

    uint32_t TiffDataEntry::doWrite(IoWrapper& ioWrapper,
                                    ByteOrder byteOrder,
                                    int32_t   offset,
                                    uint32_t  /*valueIdx*/,
                                    uint32_t  dataIdx,
                                    uint32_t& /*imageIdx*/)
    {
        if (!pValue() || pValue()->count() == 0) return 0;

        DataBuf buf(pValue()->size());
        uint32_t idx = 0;
        const long prevOffset = pValue()->toLong(0);
        for (uint32_t i = 0; i < count(); ++i) {
            const long newDataIdx =   pValue()->toLong(i) - prevOffset
                                    + static_cast<long>(dataIdx);
            idx += writeOffset(buf.pData_ + idx,
                               offset + newDataIdx,
                               tiffType(),
                               byteOrder);
        }
        ioWrapper.write(buf.pData_, buf.size_);
        return (uint32_t)buf.size_;
    } // TiffDataEntry::doWrite

Project: exiv2
File: tiffcomposite_int.cpp

    void TiffImageEntry::doEncode(TiffEncoder& encoder, const Exifdatum* datum)
    {
        encoder.encodeImageEntry(this, datum);
    } // TiffImageEntry::doEncode

Project: exiv2
File: makernote_int.cpp

    constexpr uint32_t PentaxMnHeader::sizeOfSignature()
    {
        return sizeof(signature_);
    }

Project: exiv2
File: crwimage.cpp

    void CrwParser::decode(CrwImage* pCrwImage, const byte* pData, uint32_t size)
    {
        assert(pCrwImage != 0);
        assert(pData != 0);

        // Parse the image, starting with a CIFF header component
        CiffHeader::UniquePtr head(new CiffHeader);
        head->read(pData, size);
#ifdef DEBUG
        head->print(std::cerr);
#endif
        head->decode(*pCrwImage);

        // a hack to get absolute offset of preview image inside CRW structure
        CiffComponent* preview = head->findComponent(0x2007, 0x0000);
        if (preview) {
            (pCrwImage->exifData())["Exif.Image2.JPEGInterchangeFormat"] = uint32_t(preview->pData() - pData);
            (pCrwImage->exifData())["Exif.Image2.JPEGInterchangeFormatLength"] = preview->size();
        }
    } // CrwParser::decode

Project: exiv2
File: value.cpp

    long DataValue::size() const
    {
        return static_cast<long>(value_.size());
    }

Project: exiv2
File: actions.cpp

    Modify* Modify::clone_() const
    {
        return new Modify(*this);
    }

Project: exiv2
File: makernote_int.cpp

    size_t Nikon3MnHeader::write(IoWrapper& ioWrapper, ByteOrder byteOrder) const
    {
        assert(buf_.size_ >= 10);

        ioWrapper.write(buf_.pData_, 10);
        // Todo: This removes any gap between the header and
        // makernote IFD. The gap should be copied too.
        TiffHeader th(byteOrder);
        DataBuf buf = th.write();
        ioWrapper.write(buf.pData_, buf.size_);
        return 10 + buf.size_;
    } // Nikon3MnHeader::write

Project: exiv2
File: value.cpp

    long XmpArrayValue::toLong(long n) const
    {
        return parseLong(value_[n], ok_);
    }

Project: exiv2
File: actions.cpp

    Extract* Extract::clone_() const
    {
        return new Extract(*this);
    }

Project: exiv2
File: tiffvisitor_int.cpp

    void TiffDecoder::decodeTiffEntry(const TiffEntryBase* object)
    {
        assert(object != 0);

        // Don't decode the entry if value is not set
        if (!object->pValue()) return;

        const DecoderFct decoderFct = findDecoderFct_(make_,
                                                      object->tag(),
                                                      object->group());
        // skip decoding if decoderFct == 0
        if (decoderFct) {
            EXV_CALL_MEMBER_FN(*this, decoderFct)(object);
        }
    } // TiffDecoder::decodeTiffEntry

Project: exiv2
File: xmp.cpp

    std::string Xmpdatum::groupName() const
    {
        return p_->key_.get() == 0 ? "" : p_->key_->groupName();
    }

Project: exiv2
File: tiffcomposite_int.cpp

    uint32_t TiffSubIfd::doSizeData() const
    {
        uint32_t len = 0;
        for (Ifds::const_iterator i = ifds_.begin(); i != ifds_.end(); ++i) {
            len += (*i)->size();
        }
        return len;
    } // TiffSubIfd::doSizeData

Project: exiv2
File: value.cpp

    long DateValue::copy(byte* buf, ByteOrder /*byteOrder*/) const
    {
        // sprintf wants to add the null terminator, so use oversized buffer
        char temp[9];

        int wrote = sprintf(temp, "%04d%02d%02d", date_.year, date_.month, date_.day);
        assert(wrote == 8);
        std::memcpy(buf, temp, wrote);
        return wrote;
    }

Project: exiv2
File: rafimage.cpp

    void RafImage::printStructure(std::ostream& out, PrintStructureOption option, int depth) {
        if (io_->open() != 0) {
            throw Error(kerDataSourceOpenFailed, io_->path(), strError());
        }
        // Ensure this is the correct image type
        if (!isRafType(*io_, true)) {
            if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
            throw Error(kerNotAnImage, "RAF");
        }
        const bool bPrint = option==kpsBasic || option==kpsRecursive;
        if ( bPrint ) {
            io_->seek(0,BasicIo::beg); // rewind

            {
                out << Internal::indent(depth)
                    << "STRUCTURE OF RAF FILE: "
                    << io().path()
                    << std::endl;
                out << Internal::indent(depth)
                    << Internal::stringFormat("    Length |   Offset | Payload")
                    << std::endl;
            }

            byte magicdata [17];
            io_->read(magicdata, 16);
            magicdata[16] = 0;
            {
                out << Internal::indent(depth)
                    << Internal::stringFormat("  %8u | %8u | ", 16, 0)
                    << "Magic number : "
                    << std::string((char*)&magicdata)
                    << std::endl;
            }

            byte data1 [5];
            io_->read(data1, 4);
            data1[4] = 0;
            {
                out << Internal::indent(depth)
                    << Internal::stringFormat("  %8u | %8u | ", 4, 16)
                    << "data 1 : "
                    << std::string((char*)&data1)
                    << std::endl;
            }

            byte data2 [9];
            io_->read(data2, 8);
            data2[8] = 0;
            {
                out << Internal::indent(depth)
                    << Internal::stringFormat("  %8u | %8u | ", 8, 20)
                    << "data 2 : "
                    << std::string((char*)&data2)
                    << std::endl;
            }

            byte camdata [33];
            io_->read(camdata, 32);
            camdata[32] = 0;
            {
                out << Internal::indent(depth)
                    << Internal::stringFormat("  %8u | %8u | ", 32, 28)
                    << "camera : "
                    << std::string((char*)&camdata)
                    << std::endl;
            }

            byte dir_version [5];
            io_->read(dir_version, 4);
            dir_version[4] = 0;
            {
                out << Internal::indent(depth)
                    << Internal::stringFormat("  %8u | %8u | ", 4, 60)
                    << "dir version : "
                    << std::string((char*)&dir_version)
                    << std::endl;
            }

            byte unknown [20];
            io_->read(unknown, 20);

            byte jpg_img_offset [4];
            io_->read(jpg_img_offset, 4);
            byte jpg_img_length [4];
            io_->read(jpg_img_length, 4);
            long jpg_img_off = Exiv2::getULong((const byte *) jpg_img_offset, bigEndian);
            long jpg_img_len = Exiv2::getULong((const byte *) jpg_img_length, bigEndian);
            std::stringstream j_off;
            std::stringstream j_len;
            j_off << jpg_img_off;
            j_len << jpg_img_len;
            {
                out << Internal::indent(depth)
                    << Internal::stringFormat("  %8u | %8u | ", 4, 84)
                    << "JPEG Image Offset : "
                    << j_off.str()
                    << std::endl;
                out << Internal::indent(depth)
                    << Internal::stringFormat("  %8u | %8u | ", 4, 88)
                    << "JPEG Image Length : "
                    << j_len.str()
                    << std::endl;
            }

            byte cfa_header_offset [4];
            io_->read(cfa_header_offset, 4);
            byte cfa_header_length [4];
            io_->read(cfa_header_length, 4);
            long cfa_hdr_off = Exiv2::getULong((const byte *) cfa_header_offset, bigEndian);
            long cfa_hdr_len = Exiv2::getULong((const byte *) cfa_header_length, bigEndian);
            std::stringstream ch_off;
            std::stringstream ch_len;
            ch_off << cfa_hdr_off;
            ch_len << cfa_hdr_len;
            {
                out << Internal::indent(depth)
                    << Internal::stringFormat("  %8u | %8u | ", 4, 92)
                    << "CFA Header Offset : "
                    << ch_off.str()
                    << std::endl;
                out << Internal::indent(depth)
                    << Internal::stringFormat("  %8u | %8u | ", 4, 96)
                    << "CFA Header Length : "
                    << ch_len.str()
                    << std::endl;
            }

            byte cfa_offset [4];
            io_->read(cfa_offset, 4);
            byte cfa_length [4];
            io_->read(cfa_length, 4);
            long cfa_off = Exiv2::getULong((const byte *) cfa_offset, bigEndian);
            long cfa_len = Exiv2::getULong((const byte *) cfa_length, bigEndian);
            std::stringstream c_off;
            std::stringstream c_len;
            c_off << cfa_off;
            c_len << cfa_len;
            {
                out << Internal::indent(depth)
                    << Internal::stringFormat("  %8u | %8u | ", 4, 100)
                    << "CFA Offset : "
                    << c_off.str()
                    << std::endl;
                out << Internal::indent(depth)
                    << Internal::stringFormat("  %8u | %8u | ", 4, 104)
                    << "CFA Length : "
                    << c_len.str()
                    << std::endl;
            }

            io_->seek(jpg_img_off, BasicIo::beg); // rewind
            DataBuf payload(16); // header is different from chunks
            io_->read(payload.pData_, payload.size_);
            {
                out << Internal::indent(depth)
                    << Internal::stringFormat("  %8u | %8u | ", jpg_img_len, jpg_img_off)
                    << "jpg image / exif : "
                    << Internal::binaryToString(makeSlice(payload, 0, payload.size_))
                    << std::endl;
            }

            io_->seek(cfa_hdr_off, BasicIo::beg); // rewind
            io_->read(payload.pData_, payload.size_);
            {
                out << Internal::indent(depth)
                    << Internal::stringFormat("  %8u | %8u | ", cfa_hdr_len, cfa_hdr_off)
                    << "CFA Header: "
                    << Internal::binaryToString(makeSlice(payload, 0, payload.size_))
                    << std::endl;
            }

            io_->seek(cfa_off, BasicIo::beg); // rewind
            io_->read(payload.pData_, payload.size_);
            {
                out << Internal::indent(depth)
                    << Internal::stringFormat("  %8u | %8u | ", cfa_len, cfa_off)
                    << "CFA : "
                    << Internal::binaryToString(makeSlice(payload, 0, payload.size_))
                    << std::endl;
            }
        }
    } // RafImage::printStructure

Project: exiv2
File: tiffvisitor_int.cpp

    void TiffEncoder::visitDirectory(TiffDirectory* /*object*/)
    {
        // Nothing to do
    }

Project: exiv2
File: tiffcomposite_int.cpp

    uint32_t TiffDirectory::doWriteData(IoWrapper& ioWrapper,
                                        ByteOrder byteOrder,
                                        int32_t   offset,
                                        uint32_t  dataIdx,
                                        uint32_t& imageIdx) const
    {
        uint32_t len = 0;
        for (Components::const_iterator i = components_.begin(); i != components_.end(); ++i) {
            len += (*i)->writeData(ioWrapper, byteOrder, offset, dataIdx + len, imageIdx);
        }
        return len;
    } // TiffDirectory::doWriteData

Project: exiv2
File: tiffimage_int.cpp

    bool isTiffImageTag(uint16_t tag, IfdId group)
    {
        //! List of TIFF image tags
        static const TiffImgTagStruct tiffImageTags[] = {
            { 0x00fe, ifd0Id }, // Exif.Image.NewSubfileType
            { 0x00ff, ifd0Id }, // Exif.Image.SubfileType
            { 0x0100, ifd0Id }, // Exif.Image.ImageWidth
            { 0x0101, ifd0Id }, // Exif.Image.ImageLength
            { 0x0102, ifd0Id }, // Exif.Image.BitsPerSample
            { 0x0103, ifd0Id }, // Exif.Image.Compression
            { 0x0106, ifd0Id }, // Exif.Image.PhotometricInterpretation
            { 0x010a, ifd0Id }, // Exif.Image.FillOrder
            { 0x0111, ifd0Id }, // Exif.Image.StripOffsets
            { 0x0115, ifd0Id }, // Exif.Image.SamplesPerPixel
            { 0x0116, ifd0Id }, // Exif.Image.RowsPerStrip
            { 0x0117, ifd0Id }, // Exif.Image.StripByteCounts
            { 0x011a, ifd0Id }, // Exif.Image.XResolution
            { 0x011b, ifd0Id }, // Exif.Image.YResolution
            { 0x011c, ifd0Id }, // Exif.Image.PlanarConfiguration
            { 0x0122, ifd0Id }, // Exif.Image.GrayResponseUnit
            { 0x0123, ifd0Id }, // Exif.Image.GrayResponseCurve
            { 0x0124, ifd0Id }, // Exif.Image.T4Options
            { 0x0125, ifd0Id }, // Exif.Image.T6Options
            { 0x0128, ifd0Id }, // Exif.Image.ResolutionUnit
            { 0x0129, ifd0Id }, // Exif.Image.PageNumber
            { 0x012d, ifd0Id }, // Exif.Image.TransferFunction
            { 0x013d, ifd0Id }, // Exif.Image.Predictor
            { 0x013e, ifd0Id }, // Exif.Image.WhitePoint
            { 0x013f, ifd0Id }, // Exif.Image.PrimaryChromaticities
            { 0x0140, ifd0Id }, // Exif.Image.ColorMap
            { 0x0141, ifd0Id }, // Exif.Image.HalftoneHints
            { 0x0142, ifd0Id }, // Exif.Image.TileWidth
            { 0x0143, ifd0Id }, // Exif.Image.TileLength
            { 0x0144, ifd0Id }, // Exif.Image.TileOffsets
            { 0x0145, ifd0Id }, // Exif.Image.TileByteCounts
            { 0x014c, ifd0Id }, // Exif.Image.InkSet
            { 0x014d, ifd0Id }, // Exif.Image.InkNames
            { 0x014e, ifd0Id }, // Exif.Image.NumberOfInks
            { 0x0150, ifd0Id }, // Exif.Image.DotRange
            { 0x0151, ifd0Id }, // Exif.Image.TargetPrinter
            { 0x0152, ifd0Id }, // Exif.Image.ExtraSamples
            { 0x0153, ifd0Id }, // Exif.Image.SampleFormat
            { 0x0154, ifd0Id }, // Exif.Image.SMinSampleValue
            { 0x0155, ifd0Id }, // Exif.Image.SMaxSampleValue
            { 0x0156, ifd0Id }, // Exif.Image.TransferRange
            { 0x0157, ifd0Id }, // Exif.Image.ClipPath
            { 0x0158, ifd0Id }, // Exif.Image.XClipPathUnits
            { 0x0159, ifd0Id }, // Exif.Image.YClipPathUnits
            { 0x015a, ifd0Id }, // Exif.Image.Indexed
            { 0x015b, ifd0Id }, // Exif.Image.JPEGTables
            { 0x0200, ifd0Id }, // Exif.Image.JPEGProc
            { 0x0201, ifd0Id }, // Exif.Image.JPEGInterchangeFormat
            { 0x0202, ifd0Id }, // Exif.Image.JPEGInterchangeFormatLength
            { 0x0203, ifd0Id }, // Exif.Image.JPEGRestartInterval
            { 0x0205, ifd0Id }, // Exif.Image.JPEGLosslessPredictors
            { 0x0206, ifd0Id }, // Exif.Image.JPEGPointTransforms
            { 0x0207, ifd0Id }, // Exif.Image.JPEGQTables
            { 0x0208, ifd0Id }, // Exif.Image.JPEGDCTables
            { 0x0209, ifd0Id }, // Exif.Image.JPEGACTables
            { 0x0211, ifd0Id }, // Exif.Image.YCbCrCoefficients
            { 0x0212, ifd0Id }, // Exif.Image.YCbCrSubSampling
            { 0x0213, ifd0Id }, // Exif.Image.YCbCrPositioning
            { 0x0214, ifd0Id }, // Exif.Image.ReferenceBlackWhite
            { 0x828d, ifd0Id }, // Exif.Image.CFARepeatPatternDim
            { 0x828e, ifd0Id }, // Exif.Image.CFAPattern
        //  { 0x8773, ifd0Id }, // Exif.Image.InterColorProfile
            { 0x8824, ifd0Id }, // Exif.Image.SpectralSensitivity
            { 0x8828, ifd0Id }, // Exif.Image.OECF
            { 0x9102, ifd0Id }, // Exif.Image.CompressedBitsPerPixel
            { 0x9217, ifd0Id }, // Exif.Image.SensingMethod
        };

        // If tag, group is one of the image tags listed above -> bingo!
        if (find(tiffImageTags, TiffImgTagStruct::Key(tag, group))) {
#ifdef DEBUG
            ExifKey key(tag, groupName(group));
            std::cerr << "Image tag: " << key << " (3)\n";
#endif
            return true;
        }
#ifdef DEBUG
        std::cerr << "Not an image tag: " << tag << " (4)\n";
#endif
        return false;
    }

Project: exiv2
File: tiffcomposite_int.cpp

    void TiffEntry::doAccept(TiffVisitor& visitor)
    {
        visitor.visitEntry(this);
    } // TiffEntry::doAccept

Project: exiv2
File: webpimage.cpp

    void WebPImage::doWriteMetadata(BasicIo& outIo)
    {
        if (!io_->isopen()) throw Error(kerInputDataReadFailed);
        if (!outIo.isopen()) throw Error(kerImageWriteFailed);

#ifdef DEBUG
        std::cout << "Writing metadata" << std::endl;
#endif

        byte    data   [WEBP_TAG_SIZE*3];
        DataBuf chunkId(WEBP_TAG_SIZE+1);
        chunkId.pData_ [WEBP_TAG_SIZE] = '\0';

        io_->read(data, WEBP_TAG_SIZE * 3);
        uint64_t filesize = Exiv2::getULong(data + WEBP_TAG_SIZE, littleEndian);

        /* Set up header */
        if (outIo.write(data, WEBP_TAG_SIZE * 3) != WEBP_TAG_SIZE * 3)
            throw Error(kerImageWriteFailed);

        /* Parse Chunks */
        bool has_size  = false;
        bool has_xmp   = false;
        bool has_exif  = false;
        bool has_vp8x  = false;
        bool has_alpha = false;
        bool has_icc   = iccProfileDefined();

        int width      = 0;
        int height     = 0;

        byte       size_buff[WEBP_TAG_SIZE];
        Blob       blob;

        if (exifData_.count() > 0) {
            ExifParser::encode(blob, littleEndian, exifData_);
            if (blob.size() > 0) {
                has_exif = true;
            }
        }

        if (xmpData_.count() > 0 && !writeXmpFromPacket()) {
            XmpParser::encode(xmpPacket_, xmpData_,
                              XmpParser::useCompactFormat |
                              XmpParser::omitAllFormatting);
        }
        has_xmp = xmpPacket_.size() > 0;
        std::string xmp(xmpPacket_);

        /* Verify for a VP8X Chunk First before writing in
         case we have any exif or xmp data, also check
         for any chunks with alpha frame/layer set */
        while ( !io_->eof() && (uint64_t) io_->tell() < filesize) {
            io_->read(chunkId.pData_, WEBP_TAG_SIZE);
            io_->read(size_buff, WEBP_TAG_SIZE);
            long size = Exiv2::getULong(size_buff, littleEndian);
            DataBuf payload(size);
            io_->read(payload.pData_, payload.size_);
            byte c;
            if ( payload.size_ % 2 ) io_->read(&c,1);

            /* Chunk with information about features
             used in the file. */
            if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8X) && !has_vp8x) {
                has_vp8x = true;
            }
            if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8X) && !has_size) {
                has_size = true;
                byte size_buf[WEBP_TAG_SIZE];

                // Fetch width - stored in 24bits
                memcpy(&size_buf, &payload.pData_[4], 3);
                size_buf[3] = 0;
                width = Exiv2::getULong(size_buf, littleEndian) + 1;

                // Fetch height - stored in 24bits
                memcpy(&size_buf, &payload.pData_[7], 3);
                size_buf[3] = 0;
                height = Exiv2::getULong(size_buf, littleEndian) + 1;
            }

            /* Chunk with with animation control data. */
#ifdef __CHECK_FOR_ALPHA__  // Maybe in the future
            if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_ANIM) && !has_alpha) {
                has_alpha = true;
            }
#endif

            /* Chunk with with lossy image data. */
#ifdef __CHECK_FOR_ALPHA__ // Maybe in the future
            if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8) && !has_alpha) {
                has_alpha = true;
            }
#endif
            if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8) && !has_size) {
                has_size = true;
                byte size_buf[2];

                /* Refer to this https://tools.ietf.org/html/rfc6386
                   for height and width reference for VP8 chunks */

                // Fetch width - stored in 16bits
                memcpy(&size_buf, &payload.pData_[6], 2);
                width = Exiv2::getUShort(size_buf, littleEndian) & 0x3fff;

                // Fetch height - stored in 16bits
                memcpy(&size_buf, &payload.pData_[8], 2);
                height = Exiv2::getUShort(size_buf, littleEndian) & 0x3fff;
            }

            /* Chunk with with lossless image data. */
            if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8L) && !has_alpha) {
                if ((payload.pData_[4] & WEBP_VP8X_ALPHA_BIT) == WEBP_VP8X_ALPHA_BIT) {
                    has_alpha = true;
                }
            }
            if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8L) && !has_size) {
                has_size = true;
                byte size_buf_w[2];
                byte size_buf_h[3];

                /* For VP8L chunks width & height are stored in 28 bits
                   of a 32 bit field requires bitshifting to get actual
                   sizes. Width and height are split even into 14 bits
                   each. Refer to this https://goo.gl/bpgMJf */

                // Fetch width - 14 bits wide
                memcpy(&size_buf_w, &payload.pData_[1], 2);
                size_buf_w[1] &= 0x3F;
                width = Exiv2::getUShort(size_buf_w, littleEndian) + 1;

                // Fetch height - 14 bits wide
                memcpy(&size_buf_h, &payload.pData_[2], 3);
                size_buf_h[0] =
                  ((size_buf_h[0] >> 6) & 0x3) |
                    ((size_buf_h[1] & 0x3F) << 0x2);
                size_buf_h[1] =
                  ((size_buf_h[1] >> 6) & 0x3) |
                    ((size_buf_h[2] & 0xF) << 0x2);
                height = Exiv2::getUShort(size_buf_h, littleEndian) + 1;
            }

            /* Chunk with animation frame. */
            if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_ANMF) && !has_alpha) {
                if ((payload.pData_[5] & 0x2) == 0x2) {
                    has_alpha = true;
                }
            }
            if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_ANMF) && !has_size) {
                has_size = true;
                byte size_buf[WEBP_TAG_SIZE];

                // Fetch width - stored in 24bits
                memcpy(&size_buf, &payload.pData_[6], 3);
                size_buf[3] = 0;
                width = Exiv2::getULong(size_buf, littleEndian) + 1;

                // Fetch height - stored in 24bits
                memcpy(&size_buf, &payload.pData_[9], 3);
                size_buf[3] = 0;
                height = Exiv2::getULong(size_buf, littleEndian) + 1;
            }

            /* Chunk with alpha data. */
            if (equalsWebPTag(chunkId, "ALPH") && !has_alpha) {
                has_alpha = true;
            }
        }

        /* Inject a VP8X chunk if one isn't available. */
        if (!has_vp8x) {
            inject_VP8X(outIo, has_xmp, has_exif, has_alpha,
                        has_icc, width, height);
        }

        io_->seek(12, BasicIo::beg);
        while ( !io_->eof() && (uint64_t) io_->tell() < filesize) {
            io_->read(chunkId.pData_, 4);
            io_->read(size_buff, 4);

            long size = Exiv2::getULong(size_buff, littleEndian);

            DataBuf payload(size);
            io_->read(payload.pData_, size);
            if ( io_->tell() % 2 ) io_->seek(+1,BasicIo::cur); // skip pad

            if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8X)) {
                if (has_icc){
                    payload.pData_[0] |= WEBP_VP8X_ICC_BIT;
                } else {
                    payload.pData_[0] &= ~WEBP_VP8X_ICC_BIT;
                }

                if (has_xmp){
                    payload.pData_[0] |= WEBP_VP8X_XMP_BIT;
                } else {
                    payload.pData_[0] &= ~WEBP_VP8X_XMP_BIT;
                }

                if (has_exif) {
                    payload.pData_[0] |= WEBP_VP8X_EXIF_BIT;
                } else {
                    payload.pData_[0] &= ~WEBP_VP8X_EXIF_BIT;
                }

                if (outIo.write(chunkId.pData_, WEBP_TAG_SIZE) != WEBP_TAG_SIZE)
                    throw Error(kerImageWriteFailed);
                if (outIo.write(size_buff, WEBP_TAG_SIZE) != WEBP_TAG_SIZE)
                    throw Error(kerImageWriteFailed);
                if (outIo.write(payload.pData_, payload.size_) != payload.size_)
                    throw Error(kerImageWriteFailed);
                if (outIo.tell() % 2) {
                    if (outIo.write(&WEBP_PAD_ODD, 1) != 1) throw Error(kerImageWriteFailed);
                }

                if (has_icc) {
                    if (outIo.write((const byte*)WEBP_CHUNK_HEADER_ICCP, WEBP_TAG_SIZE) != WEBP_TAG_SIZE) throw Error(kerImageWriteFailed);
                    ul2Data(data, (uint32_t) iccProfile_.size_, littleEndian);
                    if (outIo.write(data, WEBP_TAG_SIZE) != WEBP_TAG_SIZE) throw Error(kerImageWriteFailed);
                    if (outIo.write(iccProfile_.pData_, iccProfile_.size_) != iccProfile_.size_) {
                        throw Error(kerImageWriteFailed);
                    }
                    has_icc = false;
                }
            } else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_ICCP)) {
                // Skip it altogether handle it prior to here :)
            } else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_EXIF)) {
                // Skip and add new data afterwards
            } else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_XMP)) {
                // Skip and add new data afterwards
            } else {
                if (outIo.write(chunkId.pData_, WEBP_TAG_SIZE) != WEBP_TAG_SIZE)
                    throw Error(kerImageWriteFailed);
                if (outIo.write(size_buff, WEBP_TAG_SIZE) != WEBP_TAG_SIZE)
                    throw Error(kerImageWriteFailed);
                if (outIo.write(payload.pData_, payload.size_) != payload.size_)
                    throw Error(kerImageWriteFailed);
            }

            // Encoder required to pad odd sized data with a null byte
            if (outIo.tell() % 2) {
                if (outIo.write(&WEBP_PAD_ODD, 1) != 1) throw Error(kerImageWriteFailed);
            }
        }

        if (has_exif) {
            if (outIo.write((const byte*)WEBP_CHUNK_HEADER_EXIF, WEBP_TAG_SIZE) != WEBP_TAG_SIZE) throw Error(kerImageWriteFailed);
            us2Data(data, (uint16_t) blob.size()+8, bigEndian);
            ul2Data(data, (uint32_t) blob.size(), littleEndian);
            if (outIo.write(data, WEBP_TAG_SIZE) != WEBP_TAG_SIZE) throw Error(kerImageWriteFailed);
            if (outIo.write((const byte*)&blob[0], blob.size()) != blob.size())
            {
                throw Error(kerImageWriteFailed);
            }
            if (outIo.tell() % 2) {
                if (outIo.write(&WEBP_PAD_ODD, 1) != 1) throw Error(kerImageWriteFailed);
            }
        }

        if (has_xmp) {
            if (outIo.write((const byte*)WEBP_CHUNK_HEADER_XMP, WEBP_TAG_SIZE) != WEBP_TAG_SIZE) throw Error(kerImageWriteFailed);
            ul2Data(data, (uint32_t) xmpPacket().size(), littleEndian);
            if (outIo.write(data, WEBP_TAG_SIZE) != WEBP_TAG_SIZE) throw Error(kerImageWriteFailed);
            if (outIo.write((const byte*)xmp.data(), xmp.size()) != xmp.size()) {
                throw Error(kerImageWriteFailed);
            }
            if (outIo.tell() % 2) {
                if (outIo.write(&WEBP_PAD_ODD, 1) != 1) throw Error(kerImageWriteFailed);
            }
        }

        // Fix File Size Payload Data
        outIo.seek(0, BasicIo::beg);
        filesize = outIo.size() - 8;
        outIo.seek(4, BasicIo::beg);
        ul2Data(data, (uint32_t) filesize, littleEndian);
        if (outIo.write(data, WEBP_TAG_SIZE) != WEBP_TAG_SIZE) throw Error(kerImageWriteFailed);

    } // WebPImage::writeMetadata

Project: exiv2
File: convert.cpp

    bool swapBytes(std::string& str)
    {
        // Naive byte-swapping, I'm sure this can be done more efficiently
        if (str.size() & 1) {
#ifdef DEBUG
            EXV_DEBUG << "swapBytes: Size " << str.size() << " of input string is not even.\n";
#endif
            return false;
        }
        for (unsigned int i = 0; i < str.size() / 2; ++i) {
            char t = str[2 * i];
            str[2 * i] = str[2 * i + 1];
            str[2 * i + 1] = t;
        }
        return true;
    }

Project: exiv2
File: preview.cpp

    PreviewProperties LoaderNative::getProperties() const
    {
        PreviewProperties prop = Loader::getProperties();
        prop.mimeType_ = nativePreview_.mimeType_;
        if (nativePreview_.mimeType_ == "image/jpeg") {
            prop.extension_ = ".jpg";
        } else if (nativePreview_.mimeType_ == "image/tiff") {
            prop.extension_ = ".tif";
        } else if (nativePreview_.mimeType_ == "image/x-wmf") {
            prop.extension_ = ".wmf";
        } else if (nativePreview_.mimeType_ == "image/x-portable-anymap") {
            prop.extension_ = ".pnm";
        } else {
#ifndef SUPPRESS_WARNINGS
            EXV_WARNING << "Unknown native preview format: " << nativePreview_.mimeType_ << "\n";
#endif
            prop.extension_ = ".dat";
        }
#ifdef EXV_UNICODE_PATH
        prop.wextension_ = s2ws(prop.extension_);
#endif
        return prop;
    }

Project: exiv2
File: basicio.cpp

    size_t FileIo::write(const byte* data, size_t wcount)
    {
        assert(p_->fp_ != 0);
        if (p_->switchMode(Impl::opWrite) != 0) return 0;
        return (long)std::fwrite(data, 1, wcount, p_->fp_);
    }

Project: exiv2
File: exif.cpp

    int Exifdatum::idx() const
    {
        return key_.get() == 0 ? 0 : key_->idx();
    }

Project: exiv2
File: image.cpp

    bool Image::is4ByteType(uint16_t type)
    {
        return isLongType(type)
            || type == Exiv2::tiffFloat
            || type == Exiv2::tiffIfd
            ;
    }

Project: exiv2
File: bigtiffimage.cpp

            ByteOrder byteOrder() const
            {
                assert(isValid());
                return byteOrder_;
            }

Project: exiv2
File: xmp.cpp

    Xmpdatum::Impl& Xmpdatum::Impl::operator=(const Impl& rhs)
    {
        if (this == &rhs) return *this;
        key_.reset();
        if (rhs.key_.get() != 0) key_ = rhs.key_->clone(); // deep copy
        value_.reset();
        if (rhs.value_.get() != 0) value_ = rhs.value_->clone(); // deep copy
        return *this;
    }

Project: exiv2
File: tiffcomposite_int.cpp

    TiffComponent* TiffDirectory::doAddChild(TiffComponent::UniquePtr tiffComponent)
    {
        TiffComponent* tc = tiffComponent.release();
        components_.push_back(tc);
        return tc;
    } // TiffDirectory::doAddChild

Project: exiv2
File: preview.cpp

    PreviewPropertiesList PreviewManager::getPreviewProperties() const
    {
        PreviewPropertiesList list;
        // go through the loader table and store all successfully created loaders in the list
        for (PreviewId id = 0; id < Loader::getNumLoaders(); ++id) {
            Loader::UniquePtr loader = Loader::create(id, image_);
            if (loader.get() && loader->readDimensions()) {
                PreviewProperties props = loader->getProperties();
                DataBuf buf             = loader->getData(); // #16 getPreviewImage()
                props.size_             = (uint32_t)buf.size_;         //     update the size
                list.push_back(props) ;
            }
        }
        std::sort(list.begin(), list.end(), cmpPreviewProperties);
        return list;
    }

Project: exiv2
File: exif.cpp

    Rational Exifdatum::toRational(long n) const
    {
        return value_.get() == 0 ? Rational(-1, 1) : value_->toRational(n);
    }

Project: exiv2
File: iptc.cpp

    std::string Iptcdatum::tagLabel() const
    {
        return key_.get() == 0 ? "" : key_->tagLabel();
    }

Project: exiv2
File: makernote_int.cpp

    Casio2MnHeader::Casio2MnHeader(): start_(0)
    {
        read(signature_, sizeOfSignature(), invalidByteOrder );
    }

Project: exiv2
File: preview.cpp

    DataBuf makePnm(uint32_t width, uint32_t height, const DataBuf &rgb)
    {
        const size_t expectedSize = static_cast<size_t>(width * height * 3);
        if (rgb.size_ != expectedSize) {
#ifndef SUPPRESS_WARNINGS
            EXV_WARNING << "Invalid size of preview data. Expected " << expectedSize << " bytes, got " << rgb.size_ << " bytes.\n";
#endif
            return DataBuf();
        }

        const std::string header = "P6\n" + toString(width) + " " + toString(height) + "\n255\n";
        const byte *headerBytes = reinterpret_cast<const byte*>(header.data());

        DataBuf dest(static_cast<long>(header.size() + rgb.size_));
        std::copy(headerBytes, headerBytes + header.size(), dest.pData_);
        std::copy(rgb.pData_, rgb.pData_ + rgb.size_, dest.pData_ + header.size());
        return dest;
    }

Project: exiv2
File: exif.cpp

    Exifdatum& Exifdatum::operator=(const Value& value)
    {
        setValue(&value);
        return *this;
    }

Project: exiv2
File: value.cpp

    long StringValueBase::copy(byte* buf, ByteOrder /*byteOrder*/) const
    {
        if (value_.size() == 0) return 0;
        // byteOrder not needed
        assert(buf != 0);
        return static_cast<long>(
            value_.copy(reinterpret_cast<char*>(buf), value_.size())
            );
    }

Project: exiv2
File: convert.cpp

    void Converter::cnvXmpDate(const char* from, const char* to)
    {
        Exiv2::XmpData::iterator pos = xmpData_->findKey(XmpKey(from));
        if (pos == xmpData_->end()) return;
        if (!prepareExifTarget(to)) return;
#ifdef EXV_HAVE_XMP_TOOLKIT
        std::string value = pos->toString();
        if (!pos->value().ok()) {
#ifndef SUPPRESS_WARNINGS
            EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
#endif
            return;
        }
        XMP_DateTime datetime;
        try {
            SXMPUtils::ConvertToDate(value, &datetime);
        }
#ifndef SUPPRESS_WARNINGS
        catch (const XMP_Error& e) {
            EXV_WARNING << "Failed to convert " << from << " to " << to << " (" << e.GetErrMsg() << ")\n";
            return;
        }
#else
        catch (const XMP_Error&) {
            return;
        }
#endif // SUPPRESS_WARNINGS
        char buf[30];
        if (std::string(to) != "Exif.GPSInfo.GPSTimeStamp") {

            SXMPUtils::ConvertToLocalTime(&datetime);

            snprintf(buf, sizeof(buf), "%4d:%02d:%02d %02d:%02d:%02d",
                     static_cast<int>(datetime.year),
                     static_cast<int>(datetime.month),
                     static_cast<int>(datetime.day),
                     static_cast<int>(datetime.hour),
                     static_cast<int>(datetime.minute),
                     static_cast<int>(datetime.second));
            buf[sizeof(buf) - 1] = 0;
            (*exifData_)[to] = buf;

            if (datetime.nanoSecond) {
                const char* subsecTag = 0;
                if (std::string(to) == "Exif.Image.DateTime") {
                    subsecTag = "Exif.Photo.SubSecTime";
                }
                else if (std::string(to) == "Exif.Photo.DateTimeOriginal") {
                    subsecTag = "Exif.Photo.SubSecTimeOriginal";
                }
                else if (std::string(to) == "Exif.Photo.DateTimeDigitized") {
                    subsecTag = "Exif.Photo.SubSecTimeDigitized";
                }
                if (subsecTag) {
                    prepareExifTarget(subsecTag, true);
                    (*exifData_)[subsecTag] = toString(datetime.nanoSecond);
                }
            }
        }
        else { // "Exif.GPSInfo.GPSTimeStamp"

            // Ignore the time zone, assuming the time is in UTC as it should be

            URational rhour(datetime.hour, 1);
            URational rmin(datetime.minute, 1);
            URational rsec(datetime.second, 1);
            if (datetime.nanoSecond != 0) {
                if (datetime.second != 0) {
                    // Add the seconds to rmin so that the ns fit into rsec
                    rmin.second = 60;
                    rmin.first *= 60;
                    rmin.first += datetime.second;
                }
                rsec.second = 1000000000;
                rsec.first = datetime.nanoSecond;
            }

            std::ostringstream array;
            array << rhour << " " << rmin << " " << rsec;
            (*exifData_)[to] = array.str();

            prepareExifTarget("Exif.GPSInfo.GPSDateStamp", true);
            snprintf(buf, sizeof(buf), "%4d:%02d:%02d",
                    static_cast<int>(datetime.year),
                    static_cast<int>(datetime.month),
                    static_cast<int>(datetime.day));
            buf[sizeof(buf) - 1] = 0;
            (*exifData_)["Exif.GPSInfo.GPSDateStamp"] = buf;
        }

        if (erase_) xmpData_->erase(pos);
#else
# ifndef SUPPRESS_WARNINGS
        EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
# endif
#endif // !EXV_HAVE_XMP_TOOLKIT
    }

Project: exiv2
File: value.cpp

    int XmpTextValue::read(const std::string& buf)
    {
        // support a type=Alt,Bag,Seq,Struct indicator
        std::string b = buf;
        std::string type;
        if (buf.length() > 5 && buf.substr(0, 5) == "type=") {
            std::string::size_type pos = buf.find_first_of(' ');
            type = buf.substr(5, pos-5);
            // Strip quotes (so you can also specify the type without quotes)
            if (type[0] == '"') type = type.substr(1);
            if (type[type.length()-1] == '"') type = type.substr(0, type.length()-1);
            b.clear();
            if (pos != std::string::npos) b = buf.substr(pos+1);
        }
        if (!type.empty()) {
            if (type == "Alt") {
                setXmpArrayType(XmpValue::xaAlt);
            }
            else if (type == "Bag") {
                setXmpArrayType(XmpValue::xaBag);
            }
            else if (type == "Seq") {
                setXmpArrayType(XmpValue::xaSeq);
            }
            else if (type == "Struct") {
                setXmpStruct();
            }
            else {
                throw Error(kerInvalidXmpText, type);
            }
        }
        value_ = b;
        return 0;
    }

Project: exiv2
File: basicio.cpp

    void MemIo::Impl::reserve(size_t wcount)
    {
        const size_t need = wcount + idx_;
        size_t blockSize =     32*1024;   // 32768           `
        const size_t maxBlockSize = 4*1024*1024;

        if (!isMalloced_) {
            // Minimum size for 1st block
            size_t size  = EXV_MAX(blockSize * (1 + need / blockSize), size_);
            byte* data = (byte*)std::malloc(size);
            if (  data == nullptr ) {
                throw Error(kerMallocFailed);
            }
            if (data_ != nullptr) {
                std::memcpy(data, data_, size_);
            }
            data_ = data;
            sizeAlloced_ = size;
            isMalloced_ = true;
        }

        if (need > size_) {
            if (need > sizeAlloced_) {
                blockSize = 2*sizeAlloced_ ;
                if ( blockSize > maxBlockSize ) blockSize = maxBlockSize ;
                // Allocate in blocks
                size_t want      = blockSize * (1 + need / blockSize );
                data_ = (byte*)std::realloc(data_, want);
                if ( data_ == nullptr ) {
                    throw Error(kerMallocFailed);
                }
                sizeAlloced_ = want;
                isMalloced_ = true;
            }
            size_ = need;
        }
    }

Project: exiv2
File: tiffcomposite_int.cpp

    void TiffEntryBase::setData(byte* pData, int32_t size)
    {
        if (isMalloced_) {
            delete[] pData_;
        }
        pData_ = pData;
        size_  = size;
        if (pData_ == 0) size_ = 0;
    }

Project: exiv2
File: value.cpp

    int AsciiValue::read(const std::string& buf)
    {
        value_ = buf;
        if (value_.size() > 0 && value_[value_.size()-1] != '\0') value_ += '\0';
        return 0;
    }

Project: exiv2
File: value.cpp

    const DateValue::Date& DateValue::getDate() const
    {
        return date_;
    }

Project: exiv2
File: tiffvisitor_int.cpp

    void TiffReader::setMnState(const TiffRwState* state)
    {
        if (state != 0) {
            // invalidByteOrder indicates 'no change'
            if (state->byteOrder() == invalidByteOrder) {
                mnState_ = TiffRwState(origState_.byteOrder(), state->baseOffset());
            }
            else {
                mnState_ = *state;
            }
        }
        pState_ = &mnState_;
    }

Project: exiv2
File: convert.cpp

    void Converter::cnvExifArray(const char* from, const char* to)
    {
        Exiv2::ExifData::iterator pos = exifData_->findKey(ExifKey(from));
        if (pos == exifData_->end()) return;
        if (!prepareXmpTarget(to)) return;
        for (int i = 0; i < pos->count(); ++i) {
            std::string value = pos->toString(i);
            if (!pos->value().ok()) {
#ifndef SUPPRESS_WARNINGS
                EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
#endif
                return;
            }
            (*xmpData_)[to] = value;
        }
        if (erase_) exifData_->erase(pos);
    }

Project: exiv2
File: value.cpp

    float TimeValue::toFloat(long n) const
    {
        return static_cast<float>(toLong(n));
    }

Project: exiv2
File: crwimage.cpp

    void CrwImage::setIptcData(const IptcData& /*iptcData*/)
    {
        // not supported
        throw(Error(kerInvalidSettingForImage, "IPTC metadata", "CRW"));
    }

Project: exiv2
File: iptc.cpp

    IptcData::iterator IptcData::findId(uint16_t dataset, uint16_t record)
    {
        return std::find_if(iptcMetadata_.begin(), iptcMetadata_.end(),
                            FindIptcdatum(dataset, record));
    }

Project: exiv2
File: image.cpp

    void Image::clearComment()
    {
        comment_.erase();
    }

Project: exiv2
File: basicio.cpp

    size_t CurlIo::write(BasicIo& src)
    {
        if (p_->protocol_ == pHttp || p_->protocol_ == pHttps) {
            return RemoteIo::write(src);
        } else {
            throw Error(kerErrorMessage, "doesnt support write for this protocol.");
        }
    }

Project: exiv2
File: tiffcomposite_int.cpp

    bool TiffBinaryArray::initialize(IfdId group)
    {
        if (arrayCfg_ != 0) return true; // Not a complex array or already initialized

        for (int idx = 0; idx < setSize_; ++idx) {
            if (arraySet_[idx].cfg_.group_ == group) {
                arrayCfg_ = &arraySet_[idx].cfg_;
                arrayDef_ = arraySet_[idx].def_;
                defSize_  = arraySet_[idx].defSize_;
                return true;
            }
        }
        return false;
    }

Project: exiv2
File: tiffcomposite_int.cpp

    int TiffComponent::idx() const
    {
        return 0;
    }

Project: exiv2
File: value.cpp

    XmpValue::XmpValue(TypeId typeId)
        : Value(typeId),
          xmpArrayType_(xaNone),
          xmpStruct_(xsNone)
    {
    }

Project: exiv2
File: basicio.cpp

    size_t RemoteIo::read(byte* buf, size_t rcount)
    {
        assert(p_->isMalloced_);
        if (p_->eof_) return 0;
        p_->totalRead_ += (uint32_t)rcount;

        size_t allow     = EXV_MIN(rcount, (long)( p_->size_ - p_->idx_));
        size_t lowBlock  =  p_->idx_         /p_->blockSize_;
        size_t highBlock = (p_->idx_ + allow)/p_->blockSize_;

        // connect to the remote machine & populate the blocks just in time.
        p_->populateBlocks(lowBlock, highBlock);
        byte* fakeData = (byte*) std::calloc(p_->blockSize_, sizeof(byte));
        if (!fakeData) {
            throw Error(kerErrorMessage, "Unable to allocate data");
        }

        size_t iBlock = lowBlock;
        size_t startPos = p_->idx_ - lowBlock*p_->blockSize_;
        size_t totalRead = 0;
        do {
            byte* data = p_->blocksMap_[iBlock++].getData();
            if (data == nullptr) data = fakeData;
            size_t blockR = EXV_MIN(allow, p_->blockSize_ - startPos);
            std::memcpy(&buf[totalRead], &data[startPos], blockR);
            totalRead += blockR;
            startPos = 0;
            allow -= blockR;
        } while(allow);

        if (fakeData) std::free(fakeData);

        p_->idx_ += (long) totalRead;
        p_->eof_ = (p_->idx_ == (long) p_->size_);

        return (long) totalRead;
    }

Project: exiv2
File: convert.cpp

    void Converter::cnvExifValue(const char* from, const char* to)
    {
        Exiv2::ExifData::iterator pos = exifData_->findKey(ExifKey(from));
        if (pos == exifData_->end()) return;
        std::string value = pos->toString();
        if (!pos->value().ok()) {
#ifndef SUPPRESS_WARNINGS
            EXV_WARNING << "Failed to convert " << from << " to " << to << "\n";
#endif
            return;
        }
        if (!prepareXmpTarget(to)) return;
        (*xmpData_)[to] = value;
        if (erase_) exifData_->erase(pos);
    }

Project: exiv2
File: jpgimage.cpp

    DataBuf Photoshop::setIptcIrb(const byte* pPsData, size_t sizePsData, const IptcData& iptcData)
    {
        if (sizePsData > 0) assert(pPsData);
#ifdef DEBUG
        std::cerr << "IRB block at the beginning of Photoshop::setIptcIrb\n";
        if (sizePsData == 0) std::cerr << "  None.\n";
        else hexdump(std::cerr, pPsData, sizePsData);
#endif
        const byte* record    = pPsData;
        uint32_t    sizeIptc  = 0;
        uint32_t    sizeHdr   = 0;
        DataBuf rc;
        // Safe to call with zero psData.size_
        if (0 > Photoshop::locateIptcIrb(pPsData, sizePsData, &record, &sizeHdr, &sizeIptc)) {
            return rc;
        }
        Blob psBlob;
        const uint32_t sizeFront = static_cast<uint32_t>(record - pPsData);
        // Write data before old record.
        if (sizePsData > 0 && sizeFront > 0) {
            append(psBlob, pPsData, sizeFront);
        }
        // Write new iptc record if we have it
        DataBuf rawIptc = IptcParser::encode(iptcData);
        if (rawIptc.size_ > 0) {
            byte tmpBuf[12];
            std::memcpy(tmpBuf, Photoshop::irbId_[0], 4);
            us2Data(tmpBuf + 4, iptc_, bigEndian);
            tmpBuf[6] = 0;
            tmpBuf[7] = 0;
            ul2Data(tmpBuf + 8, (uint32_t)rawIptc.size_, bigEndian);
            append(psBlob, tmpBuf, 12);
            append(psBlob, rawIptc.pData_, (uint32_t)rawIptc.size_);
            // Data is padded to be even (but not included in size)
            if (rawIptc.size_ & 1) psBlob.push_back(0x00);
        }
        // Write existing stuff after record,
        // skip the current and all remaining IPTC blocks
        long pos = sizeFront;
        while (0 == Photoshop::locateIptcIrb(pPsData + pos, sizePsData - pos, &record, &sizeHdr, &sizeIptc)) {
            const long newPos = static_cast<long>(record - pPsData);
            // Copy data up to the IPTC IRB
            if (newPos > pos) {
                append(psBlob, pPsData + pos, newPos - pos);
            }
            // Skip the IPTC IRB
            pos = newPos + sizeHdr + sizeIptc + (sizeIptc & 1);
        }
        if (pos < sizePsData) {
            append(psBlob, pPsData + pos, (uint32_t)(sizePsData - pos));
        }
        // Data is rounded to be even
        if (psBlob.size() > 0) rc = DataBuf(&psBlob[0], static_cast<long>(psBlob.size()));
#ifdef DEBUG
        std::cerr << "IRB block at the end of Photoshop::setIptcIrb\n";
        if (rc.size_ == 0) std::cerr << "  None.\n";
        else hexdump(std::cerr, rc.pData_, rc.size_);
#endif
        return rc;

    } // Photoshop::setIptcIrb

Project: exiv2
File: actions.cpp

    int Modify::applyCommands(Exiv2::Image* pImage)
    {
        if (!Params::instance().jpegComment_.empty()) {
            if (Params::instance().verbose_) {
                std::cout << _("Setting JPEG comment") << " '" << Params::instance().jpegComment_ << "'" << std::endl;
            }
            pImage->setComment(Params::instance().jpegComment_);
        }

        // loop through command table and apply each command
        ModifyCmds& modifyCmds = Params::instance().modifyCmds_;
        int rc = 0;
        int ret = 0;
        for (auto i = modifyCmds.cbegin(); i != modifyCmds.cend(); ++i) {
            switch (i->cmdId_) {
                case add:
                    ret = addMetadatum(pImage, *i);
                    if (rc == 0)
                        rc = ret;
                    break;
                case set:
                    ret = setMetadatum(pImage, *i);
                    if (rc == 0)
                        rc = ret;
                    break;
                case del:
                    delMetadatum(pImage, *i);
                    break;
                case reg:
                    regNamespace(*i);
                    break;
                case invalidCmdId:
                    assert(invalidCmdId == i->cmdId_);
                    break;
            }
        }
        return rc;
    }

Project: exiv2
File: exif.cpp

    const wchar_t* ExifThumbC::wextension() const
    {
        Thumbnail::UniquePtr thumbnail = Thumbnail::create(exifData_);
        if (thumbnail.get() == 0) return EXV_WIDEN("");
        return thumbnail->wextension();
    }

Project: exiv2
File: preview.cpp

    LoaderExifDataJpeg::LoaderExifDataJpeg(PreviewId id, const Image &image, int parIdx)
        : Loader(id, image),
          dataKey_(param_[parIdx].dataKey_)
    {
        ExifData::const_iterator pos = image_.exifData().findKey(dataKey_);
        if (pos != image_.exifData().end()) {
            size_ = pos->sizeDataArea(); // indirect data
            if (size_ == 0 && pos->typeId() == undefined)
                size_ = pos->size(); // direct data
        }

        if (size_ == 0) return;

        valid_ = true;
    }

Project: exiv2
File: tiffcomposite_int.cpp

    uint32_t TiffDirectory::doCount() const
    {
        return static_cast<uint32_t>(components_.size());
    }

Project: exiv2
File: xmp.cpp

    void printNode(const std::string& ,
                   const std::string& ,
                   const std::string& ,
                   const XMP_OptionBits& )
    {}

Project: exiv2
File: tiffcomposite_int.cpp

    void TiffIfdMakernote::setByteOrder(ByteOrder byteOrder)
    {
        if (pHeader_) pHeader_->setByteOrder(byteOrder);
    }

Project: exiv2
File: makernote_int.cpp

    void MnHeader::setByteOrder(ByteOrder /*byteOrder*/)
    {
    }

Project: exiv2
File: tiffvisitor_int.cpp

    void TiffEncoder::encodeTiffComponent(
              TiffEntryBase* object,
        const Exifdatum*     datum
    )
    {
        assert(object != 0);

        ExifData::iterator pos = exifData_.end();
        const Exifdatum* ed = datum;
        if (ed == 0) {
            // Non-intrusive writing: find matching tag
            ExifKey key(object->tag(), groupName(object->group()));
            pos = exifData_.findKey(key);
            if (pos != exifData_.end()) {
                ed = &(*pos);
                if (object->idx() != pos->idx()) {
                    // Try to find exact match (in case of duplicate tags)
                    ExifData::iterator pos2 =
                        std::find_if(exifData_.begin(), exifData_.end(),
                                     FindExifdatum2(object->group(), object->idx()));
                    if (pos2 != exifData_.end() && pos2->key() == key.key()) {
                        ed = &(*pos2);
                        pos = pos2; // make sure we delete the correct tag below
                    }
                }
            }
            else {
                setDirty();
#ifdef DEBUG
                std::cerr << "DELETING          " << key << ", idx = " << object->idx() << "\n";
#endif
            }
        }
        else {
            // For intrusive writing, the index is used to preserve the order of
            // duplicate tags
            object->idx_ = ed->idx();
        }
        // Skip encoding image tags of existing TIFF image - they were copied earlier -
        // but encode image tags of new images (creation)
        if (ed && !isImageTag(object->tag(), object->group())) {
            const EncoderFct fct = findEncoderFct_(make_, object->tag(), object->group());
            if (fct) {
                // If an encoding function is registered for the tag, use it
                EXV_CALL_MEMBER_FN(*this, fct)(object, ed);
            }
            else {
                // Else use the encode function at the object (results in a double-dispatch
                // to the appropriate encoding function of the encoder.
                object->encode(*this, ed);
            }
        }
        if (del_ && pos != exifData_.end()) {
            exifData_.erase(pos);
        }
#ifdef DEBUG
        std::cerr << "\n";
#endif
    } // TiffEncoder::encodeTiffComponent

Project: exiv2
File: value.cpp

    long TimeValue::copy(byte* buf, ByteOrder /*byteOrder*/) const
    {
        char temp[12];
        char plusMinus = '+';
        if (time_.tzHour < 0 || time_.tzMinute < 0)
            plusMinus = '-';

        const int wrote = snprintf(temp, sizeof(temp), // 11 bytes are written + \0
                   "%02d%02d%02d%1c%02d%02d",
                   time_.hour, time_.minute, time_.second,
                   plusMinus, abs(time_.tzHour), abs(time_.tzMinute));

        enforce(wrote == 11, Exiv2::kerUnsupportedTimeFormat);
        std::memcpy(buf, temp, wrote);
        return wrote;
    }

Project: exiv2
File: convert.cpp

    bool utf8ToUcs2le(std::string& str)
    {
        return mb2wc(CP_UTF8, str);
    }

Project: exiv2
File: bigtiffimage.cpp

            Header(const ByteOrder& order, int v, int size, uint64_t offset):
                byteOrder_(order),
                version_(v),
                data_size_(size),
                dir_offset_(offset)
            {

            }

Project: exiv2
File: tiffimage.cpp

    void OffsetWriter::setOrigin(OffsetId id, uint32_t origin, ByteOrder byteOrder)
    {
        offsetList_[id] = OffsetData(origin, byteOrder);
    }

Project: exiv2
File: xmp.cpp

    static XMP_Status nsDumper
    ( void*           refCon
    , XMP_StringPtr   buffer
    , XMP_StringLen   bufferSize
    ) {
        XMP_Status result = 0 ;
        std::string out(buffer,bufferSize);

        // remove blanks
        // http://stackoverflow.com/questions/83439/remove-spaces-from-stdstring-in-c
        std::string::iterator end_pos = std::remove(out.begin(), out.end(), ' ');
        out.erase(end_pos, out.end());

        bool bURI = out.find("http://") != std::string::npos   ;
        bool bNS  = out.find(':') != std::string::npos && !bURI;

        // pop trailing ':' on a namespace
        if ( bNS ) {
        std::size_t length = out.length();
            if ( out[length-1] == ':' ) out = out.substr(0,length-1);
        }

        if ( bURI || bNS ) {
            std::map<std::string,std::string>* p = (std::map<std::string,std::string>*) refCon;
            std::map<std::string,std::string>& m = *p;

            std::string b("");
            if ( bNS ) {  // store the NS in dict[""]
                m[b]=out;
            } else if ( m.find(b) != m.end() ) {  // store dict[uri] = dict[""]
                m[m[b]]=out;
                m.erase(b);
            }
        }
        return result;
    }

Project: exiv2
File: types.cpp

    DataBuf::~DataBuf()
    { delete[] pData_; }

Project: exiv2
File: types.cpp

        bool operator==(const std::string& name) const
        {
            return 0 == strcmp(name_, name.c_str());
        }

Project: exiv2
File: types.cpp

    DataBuf &DataBuf::operator=(DataBufRef rhs) { reset(rhs.p); return *this; }

Project: exiv2
File: xmp.cpp

    XMP_OptionBits xmpArrayOptionBits(Exiv2::XmpValue::XmpArrayType xat)
    {
        XMP_OptionBits var(0);
        switch (xat) {
        case Exiv2::XmpValue::xaNone:
            break;
        case Exiv2::XmpValue::xaAlt:
            XMP_SetOption(var, kXMP_PropValueIsArray);
            XMP_SetOption(var, kXMP_PropArrayIsAlternate);
            break;
        case Exiv2::XmpValue::xaSeq:
            XMP_SetOption(var, kXMP_PropValueIsArray);
            XMP_SetOption(var, kXMP_PropArrayIsOrdered);
            break;
        case Exiv2::XmpValue::xaBag:
            XMP_SetOption(var, kXMP_PropValueIsArray);
            break;
        }
        return var;
    }

Project: exiv2
File: iptc.cpp

    IptcData::const_iterator IptcData::findKey(const IptcKey& key) const
    {
        return std::find_if(iptcMetadata_.begin(), iptcMetadata_.end(),
                            FindIptcdatum(key.tag(), key.record()));
    }

Project: exiv2
File: tiffimage.cpp

        bool operator==(int compression) const { return compression_ == compression; }

Project: exiv2
File: image.cpp

    uint64_t Image::byteSwap(uint64_t value,bool bSwap) const
    {
        uint64_t result = 0;
        byte* source_value = reinterpret_cast<byte *>(&value);
        byte* destination_value = reinterpret_cast<byte *>(&result);

        for (int i = 0; i < 8; i++)
            destination_value[i] = source_value[8 - i - 1];

        return bSwap ? result : value;
    }

Project: exiv2
File: tiffvisitor_int.cpp

    void TiffVisitor::visitBinaryArrayEnd(TiffBinaryArray* /*object*/)
    {
    }

Project: exiv2
File: xmp.cpp

    Xmpdatum::Xmpdatum(const XmpKey& key, const Value* pValue)
        : p_(new Impl(key, pValue))
    {
    }

Project: exiv2
File: crwimage_int.cpp

    CiffComponent* CiffComponent::doAdd(CrwDirs& /*crwDirs*/, uint16_t /*crwTagId*/)
    {
        return 0;
    }

Project: exiv2
File: convert.cpp

    bool Converter::prepareXmpTarget(const char* to, bool force)
    {
        Exiv2::XmpData::iterator pos = xmpData_->findKey(XmpKey(to));
        if (pos == xmpData_->end()) return true;
        if (!overwrite_ && !force) return false;
        xmpData_->erase(pos);
        return true;
    }

Project: exiv2
File: makernote_int.cpp

    uint32_t Nikon3MnHeader::ifdOffset() const
    {
        return start_;
    }

Project: exiv2
File: tiffcomposite_int.cpp

    void TiffSubIfd::doAccept(TiffVisitor& visitor)
    {
        visitor.visitSubIfd(this);
        for (Ifds::iterator i = ifds_.begin();
             visitor.go(TiffVisitor::geTraverse) && i != ifds_.end(); ++i) {
            (*i)->accept(visitor);
        }
    } // TiffSubIfd::doAccept

Project: exiv2
File: convert.cpp

    void Converter::cnvExifGPSVersion(const char* from, const char* to)
    {
        Exiv2::ExifData::iterator pos = exifData_->findKey(ExifKey(from));
        if (pos == exifData_->end()) return;
        if (!prepareXmpTarget(to)) return;
        std::ostringstream value;
        for (int i = 0; i < pos->count(); ++i) {
            if (i > 0) value << '.';
            value << pos->toLong(i);
        }
        (*xmpData_)[to] = value.str();
        if (erase_) exifData_->erase(pos);
    }

Project: exiv2
File: tiffcomposite_int.cpp

    uint32_t TiffDataEntry::doWriteData(IoWrapper& ioWrapper,
                                        ByteOrder /*byteOrder*/,
                                        int32_t   /*offset*/,
                                        uint32_t  /*dataIdx*/,
                                        uint32_t& /*imageIdx*/) const
    {
        if (!pValue()) return 0;

        DataBuf buf = pValue()->dataArea();
        ioWrapper.write(buf.pData_, buf.size_);
        // Align data to word boundary
        uint32_t align = (buf.size_ & 1);
        if (align) ioWrapper.putb(0x0);

        return (uint32_t)buf.size_ + align;
    } // TiffDataEntry::doWriteData

Project: exiv2
File: makernote_int.cpp

    size_t Olympus2MnHeader::size() const
    {
        return header_.size_;
    }

Project: exiv2
File: convert.cpp

    bool asciiToUtf8(std::string& /*str*/)
    {
        // nothing to do
        return true;
    }

Project: exiv2
File: mrwimage.cpp

    void MrwImage::writeMetadata()
    {
        // Todo: implement me!
        throw(Error(kerWritingImageFormatUnsupported, "MRW"));
    } // MrwImage::writeMetadata

Project: exiv2
File: image.cpp

    Image::UniquePtr ImageFactory::open(const std::wstring& wpath, bool useCurl)
    {
        Image::UniquePtr image = open(ImageFactory::createIo(wpath, useCurl)); // may throw
        if (image.get() == 0) throw WError(kerFileContainsUnknownImageType, wpath);
        return image;
    }

Project: exiv2
File: preview.cpp

    uint32_t PreviewImage::height() const
    {
        return properties_.height_;
    }

Project: exiv2
File: makernote_int.cpp

    TiffComponent* newIfdMn2(uint16_t tag,
                             IfdId    group,
                             IfdId    mnGroup)
    {
        return new TiffIfdMakernote(tag, group, mnGroup, 0);
    }

Project: exiv2
File: tiffvisitor_int.cpp

    void TiffVisitor::visitIfdMakernoteEnd(TiffIfdMakernote* /*object*/)
    {
    }

Project: exiv2
File: iptc.cpp

    void IptcData::sortByTag()
    {
        std::sort(iptcMetadata_.begin(), iptcMetadata_.end(), cmpMetadataByTag);
    }

Project: exiv2
File: makernote_int.cpp

    Nikon3MnHeader::~Nikon3MnHeader()
    {
    }

Project: exiv2
File: tiffcomposite_int.cpp

    uint32_t TiffBinaryArray::doWrite(IoWrapper& ioWrapper,
                                      ByteOrder byteOrder,
                                      int32_t   offset,
                                      uint32_t  valueIdx,
                                      uint32_t  dataIdx,
                                      uint32_t& imageIdx)
    {
        if (cfg() == 0 || !decoded()) return TiffEntryBase::doWrite(ioWrapper,
                                                                    byteOrder,
                                                                    offset,
                                                                    valueIdx,
                                                                    dataIdx,
                                                                    imageIdx);
        if (cfg()->byteOrder_ != invalidByteOrder) byteOrder = cfg()->byteOrder_;
        // Tags must be sorted in ascending order
        std::sort(elements_.begin(), elements_.end(), cmpTagLt);
        uint32_t idx = 0;
        MemIo mio;
        IoWrapper mioWrapper(mio, 0, 0, 0);
        // Some array entries need to have the size in the first element
        if (cfg()->hasSize_) {
            byte buf[4];
            long elSize = TypeInfo::typeSize(toTypeId(cfg()->elTiffType_, 0, cfg()->group_));
            switch (elSize) {
            case 2:
                idx += us2Data(buf, size(), byteOrder);
                break;
            case 4:
                idx += ul2Data(buf, size(), byteOrder);
                break;
            default:
                assert(false);
            }
            mioWrapper.write(buf, elSize);
        }
        // write all tags of the array (Todo: assumes that there are no duplicates, need check)
        for (Components::const_iterator i = elements_.begin(); i != elements_.end(); ++i) {
            // Skip the manufactured tag, if it exists
            if (cfg()->hasSize_ && (*i)->tag() == 0) continue;
            uint32_t newIdx = (*i)->tag() * cfg()->tagStep();
            idx += fillGap(mioWrapper, idx, newIdx);
            idx += (*i)->write(mioWrapper, byteOrder, offset + newIdx, valueIdx, dataIdx, imageIdx);
        }
        if (cfg()->hasFillers_ && def()) {
            const ArrayDef* lastDef = def() + defSize() - 1;
            uint16_t lastTag = static_cast<uint16_t>(lastDef->idx_ / cfg()->tagStep());
            idx += fillGap(mioWrapper, idx, lastDef->idx_ + lastDef->size(lastTag, cfg()->group_));
        }
        DataBuf buf;
        if (cfg()->cryptFct_) {
            buf = cfg()->cryptFct_(tag(), mio.mmap(), static_cast<uint32_t>(mio.size()), pRoot_);
        }
        if (buf.size_ > 0) {
            ioWrapper.write(buf.pData_, buf.size_);
        }
        else {
            ioWrapper.write(mio.mmap(), static_cast<uint32_t>(mio.size()));
        }

        return idx;
    } // TiffBinaryArray::doWrite

Project: exiv2
File: tiffvisitor_int.cpp

    void TiffEncoder::encodeDataEntry(TiffDataEntry* object, const Exifdatum* datum)
    {
        encodeOffsetEntry(object, datum);

        if (!dirty_ && writeMethod() == wmNonIntrusive) {
            assert(object);
            assert(object->pValue());
            if (  object->sizeDataArea_
                < static_cast<uint32_t>(object->pValue()->sizeDataArea())) {
#ifdef DEBUG
                ExifKey key(object->tag(), groupName(object->group()));
                std::cerr << "DATAAREA GREW     " << key << "\n";
#endif
                setDirty();
            }
            else {
                // Write the new dataarea, fill with 0x0
#ifdef DEBUG
                ExifKey key(object->tag(), groupName(object->group()));
                std::cerr << "Writing data area for " << key << "\n";
#endif
                DataBuf buf = object->pValue()->dataArea();
                memcpy(object->pDataArea_, buf.pData_, buf.size_);
                if (object->sizeDataArea_ > static_cast<uint32_t>(buf.size_)) {
                    memset(object->pDataArea_ + buf.size_,
                           0x0, object->sizeDataArea_ - buf.size_);
                }
            }
        }

    } // TiffEncoder::encodeDataEntry

Project: exiv2
File: value.cpp

    Value& Value::operator=(const Value& rhs)
    {
        if (this == &rhs) return *this;
        type_ = rhs.type_;
        ok_ = rhs.ok_;
        return *this;
    }

Project: exiv2
File: jp2image.cpp

    static void lf(std::ostream& out,bool& bLF)
    {
        if ( bLF ) {
            out << std::endl;
            out.flush();
            bLF = false ;
        }
    }

Project: exiv2
File: actions.cpp

    int Extract::run(const std::string& path)
    {
        try {
            path_ = path;
            int rc = 0;

            bool bStdout = Params::instance().target_ & Params::ctStdInOut ? true : false;
            if (bStdout) {
                _setmode(_fileno(stdout), _O_BINARY);
            }

            if (Params::instance().target_ & Params::ctThumb) {
                rc = writeThumbnail();
            }
            if (!rc && Params::instance().target_ & Params::ctPreview) {
                rc = writePreviews();
            }
            if (!rc && Params::instance().target_ & Params::ctXmpSidecar) {
                std::string xmpPath = bStdout ? "-" : newFilePath(path_, ".xmp");
                if (dontOverwrite(xmpPath))
                    return 0;
                rc = metacopy(path_, xmpPath, Exiv2::ImageType::xmp, false);
            }
            if (!rc && Params::instance().target_ & Params::ctIccProfile) {
                std::string iccPath = bStdout ? "-" : newFilePath(path_, ".icc");
                rc = writeIccProfile(iccPath);
            }
            if (!rc && !(Params::instance().target_ & Params::ctXmpSidecar) &&
                !(Params::instance().target_ & Params::ctThumb) && !(Params::instance().target_ & Params::ctPreview) &&
                !(Params::instance().target_ & Params::ctIccProfile)) {
                std::string exvPath = bStdout ? "-" : newFilePath(path_, ".exv");
                if (dontOverwrite(exvPath))
                    return 0;
                rc = metacopy(path_, exvPath, Exiv2::ImageType::exv, false);
            }
            return rc;
        } catch (const Exiv2::AnyError& e) {
            std::cerr << "Exiv2 exception in extract action for file " << path << ":\n" << e << "\n";
            return 1;
        }
    }

Project: exiv2
File: pngchunk_int.cpp

        std::string PngChunk::makeAsciiTxtChunk(const std::string& keyword, const std::string& text, bool compress)
        {
            // Chunk structure: length (4 bytes) + chunk type + chunk data + CRC (4 bytes)
            // Length is the size of the chunk data
            // CRC is calculated on chunk type + chunk data

            // Compressed text chunk using zlib.
            // Chunk data format : keyword + 0x00 + compression method (0x00) + compressed text

            // Not Compressed text chunk.
            // Chunk data format : keyword + 0x00 + text

            // Build chunk data, determine chunk type
            std::string chunkData = keyword + '\0';
            std::string chunkType;
            if (compress) {
                chunkData += '\0' + zlibCompress(text);
                chunkType = "zTXt";
            } else {
                chunkData += text;
                chunkType = "tEXt";
            }
            // Determine length of the chunk data
            byte length[4];
            ul2Data(length, static_cast<uint32_t>(chunkData.size()), bigEndian);
            // Calculate CRC on chunk type and chunk data
            std::string crcData = chunkType + chunkData;
            uLong tmp = crc32(0L, Z_NULL, 0);
            tmp = crc32(tmp, (const Bytef*)crcData.data(), static_cast<uInt>(crcData.size()));
            byte crc[4];
            ul2Data(crc, tmp, bigEndian);
            // Assemble the chunk
            return std::string((const char*)length, 4) + chunkType + chunkData + std::string((const char*)crc, 4);

        }  // PngChunk::makeAsciiTxtChunk

Project: exiv2
File: xmp.cpp

    int XmpParser::encode(      std::string& /*xmpPacket*/,
                          const XmpData&     xmpData,
                                uint16_t     /*formatFlags*/,
                                uint32_t     /*padding*/)
    {
        if (!xmpData.empty()) {
#ifndef SUPPRESS_WARNINGS
            EXV_WARNING << "XMP toolkit support not compiled in.\n";
#endif
        }
        return 1;
    } // XmpParser::encode

Project: exiv2
File: convert.cpp

    void Converter::cnvNone(const char*, const char*)
    {
        return;
    }

Project: exiv2
File: jp2image.cpp

    std::string Jp2Image::mimeType() const
    {
        return "image/jp2";
    }

Project: exiv2
File: basicio.cpp

    SshIo::SshImpl::SshImpl(const std::wstring& wurl, size_t blockSize):Impl(wurl, blockSize)
    {
        std::string url;
        url.assign(wurl.begin(), wurl.end());
        path_ = url;

        hostInfo_ = Exiv2::Uri::Parse(url);
        Exiv2::Uri::Decode(hostInfo_);

        // remove / at the beginning of the path
        if (hostInfo_.Path[0] == '/') {
            hostInfo_.Path = hostInfo_.Path.substr(1);
        }
        ssh_ = new SSH(hostInfo_.Host, hostInfo_.Username, hostInfo_.Password, hostInfo_.Port);

        if (protocol_ == pSftp) {
            ssh_->getFileSftp(hostInfo_.Path, fileHandler_);
            if (fileHandler_ == nullptr) throw Error(kerErrorMessage, "Unable to open the file");
        } else {
            fileHandler_ = nullptr;
        }
    }

Project: exiv2
File: tiffvisitor_int.cpp

    void TiffDecoder::visitBinaryArray(TiffBinaryArray* object)
    {
        if (object->cfg() == 0 || !object->decoded()) {
            decodeTiffEntry(object);
        }
    }

Project: exiv2
File: value.cpp

    int StringValueBase::read(const byte* buf, size_t len, ByteOrder /*byteOrder*/)
    {
        // byteOrder not needed
        if (buf) value_ = std::string(reinterpret_cast<const char*>(buf), len);
        return 0;
    }

Project: exiv2
File: makernote_int.cpp

    bool TiffMnRegistry::operator==(const std::string& key) const
    {
        std::string make(make_);
        if (key.size() > 0 && key[0] == '-') return false;
        return make == key.substr(0, make.length());
    }

Project: exiv2
File: actions.cpp

    int dontOverwrite(const std::string& path)
    {
        if (path == "-")
            return 0;

        if (!Params::instance().force_ && Exiv2::fileExists(path)) {
            std::cout << Params::instance().progname() << ": " << _("Overwrite") << " `" << path << "'? ";
            std::string s;
            std::cin >> s;
            if (s[0] != 'y' && s[0] != 'Y')
                return 1;
        }
        return 0;
    }

Project: exiv2
File: tiffvisitor_int.cpp

    void TiffCopier::visitSizeEntry(TiffSizeEntry* object)
    {
        copyObject(object);
    }

Project: exiv2
File: rafimage.cpp

    bool isRafType(BasicIo& iIo, bool advance)
    {
        const int32_t len = 8;
        byte buf[len];
        iIo.read(buf, len);
        if (iIo.error() || iIo.eof()) {
            return false;
        }
        int rc = memcmp(buf, "FUJIFILM", 8);
        if (!advance || rc != 0) {
            iIo.seek(-len, BasicIo::cur);
        }
        return rc == 0;
    }

Project: exiv2
File: tiffimage.cpp

    void TiffHeaderBase::setOffset(uint32_t offset)
    {
        offset_ = offset;
    }

Project: exiv2
File: image.cpp

    void Image::clearXmpPacket()
    {
        xmpPacket_.clear();
        writeXmpFromPacket(true);
    }

Project: exiv2
File: tiffcomposite_int.cpp

    TiffSubIfd* TiffSubIfd::doClone() const
    {
        return new TiffSubIfd(*this);
    }

Project: exiv2
File: tiffcomposite_int.cpp

    TiffComponent* TiffBinaryArray::doAddPath(uint16_t tag,
                                              TiffPath& tiffPath,
                                              TiffComponent* const pRoot,
                                              TiffComponent::UniquePtr object)
    {
        pRoot_ = pRoot;
        if (tiffPath.size() == 1) {
            // An unknown complex binary array has no children and acts like a standard TIFF entry
            return this;
        }
        tiffPath.pop();
        const TiffPathItem tpi = tiffPath.top();
        // Initialize the binary array (if it is a complex array)
        initialize(tpi.group());
        TiffComponent* tc = 0;
        // Todo: Duplicates are not allowed!
        // To allow duplicate entries, we only check if the new component already
        // exists if there is still at least one composite tag on the stack
        if (tiffPath.size() > 1) {
            for (Components::iterator i = elements_.begin(); i != elements_.end(); ++i) {
                if ((*i)->tag() == tpi.tag() && (*i)->group() == tpi.group()) {
                    tc = *i;
                    break;
                }
            }
        }
        if (tc == 0) {
            TiffComponent::UniquePtr atc;
            if (tiffPath.size() == 1 && object.get() != 0) {
                atc = std::move(object);
            }
            else {
                atc = TiffCreator::create(tpi.extendedTag(), tpi.group());
            }
            assert(atc.get() != 0);
            assert(tpi.extendedTag() != Tag::next);
            tc = addChild(std::move(atc));
            setCount(static_cast<uint32_t>(elements_.size()));
        }
        return tc->addPath(tag, tiffPath, pRoot, std::move(object));
    } // TiffBinaryArray::doAddPath

Project: exiv2
File: makernote_int.cpp

    uint32_t OlympusMnHeader::ifdOffset() const
    {
        return sizeOfSignature();
    }

Project: exiv2
File: actions.cpp

    void Print::printLabel(const std::string& label) const
    {
        std::cout << std::setfill(' ') << std::left;
        if (Params::instance().files_.size() > 1) {
            std::cout << std::setw(20) << path_ << " ";
        }
        std::cout << std::make_pair(label, align_) << ": ";
    }

Project: exiv2
File: tiffcomposite_int.cpp

    void TiffEntryBase::setData(DataBuf buf)
    {
        std::pair<byte*, long> p = buf.release();
        setData(p.first, p.second);
        isMalloced_ = true;
    }

Project: exiv2
File: makernote_int.cpp

    uint32_t Nikon3MnHeader::baseOffset(uint32_t mnOffset) const
    {
        return mnOffset + 10;
    }

Project: exiv2
File: preview.cpp

    bool LoaderXmpJpeg::readDimensions()
    {
        return valid();
    }

Project: exiv2
File: iptc.cpp

    std::string Iptcdatum::groupName() const
    {
        return key_.get() == 0 ? "" : key_->groupName();
    }

Project: exiv2
File: xmp.cpp

        ~AutoLock()
        {
            if (xmpLockFct_) xmpLockFct_(pLockData_, false);
        }

Project: exiv2
File: tiffcomposite_int.cpp

    uint32_t TiffIfdMakernote::mnOffset() const
    {
        return mnOffset_;
    }

Project: exiv2
File: mrwimage.cpp

    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;
    }

Project: exiv2
File: iptc.cpp

    Rational Iptcdatum::toRational(long n) const
    {
        return value_.get() == 0 ? Rational(-1, 1) : value_->toRational(n);
    }

Project: exiv2
File: value.cpp

    long DataValue::copy(byte* buf, ByteOrder /*byteOrder*/) const
    {
        // byteOrder not needed
        return static_cast<long>(
            std::copy(value_.begin(), value_.end(), buf) - buf
            );
    }

Project: exiv2
File: rafimage.cpp

    int RafImage::pixelWidth() const
    {
        Exiv2::ExifData::const_iterator widthIter = exifData_.findKey(Exiv2::ExifKey("Exif.Photo.PixelXDimension"));
        if (widthIter != exifData_.end() && widthIter->count() > 0) {
            return widthIter->toLong();
        }
        return 0;
    }

Project: exiv2
File: makernote_int.cpp

    void Nikon3MnHeader::setByteOrder(ByteOrder byteOrder)
    {
        byteOrder_ = byteOrder;
    }

Project: exiv2
File: types.cpp

    std::ostream& operator<<(std::ostream& os, const URational& r)
    {
        return os << r.first << "/" << r.second;
    }

Project: exiv2
File: value.cpp

    StringValue::StringValue(const std::string& buf)
        : StringValueBase(string, buf)
    {
    }

Project: exiv2
File: tiffcomposite_int.cpp

    uint32_t TiffEntryBase::doWriteData(IoWrapper&/*ioWrapper*/,
                                        ByteOrder /*byteOrder*/,
                                        int32_t   /*offset*/,
                                        uint32_t  /*dataIdx*/,
                                        uint32_t& /*imageIdx*/) const
    {
        return 0;
    } // TiffEntryBase::doWriteData

Project: exiv2
File: basicio.cpp

    size_t RemoteIo::write(BasicIo& src)
    {
        assert(p_->isMalloced_);
        if (!src.isopen()) return 0;

        /*
         * The idea is to compare the file content, find the different bytes and submit them to the remote machine.
         * To simplify it, it:
         *      + goes from the left, find the first different position -> $left
         *      + goes from the right, find the first different position -> $right
         * The different bytes are [$left-$right] part.
         */
        size_t left       = 0;
        size_t right      = 0;
        size_t blockIndex = 0;
        size_t i          = 0;
        size_t readCount  = 0;
        size_t blockSize  = 0;
        byte*  buf        = (byte*) std::malloc(p_->blockSize_);
        size_t nBlocks    = (p_->size_ + p_->blockSize_ - 1) / p_->blockSize_;

        // find $left
        src.seek(0, BasicIo::beg);
        bool findDiff = false;
        while (blockIndex < nBlocks && !src.eof() && !findDiff) {
            blockSize = p_->blocksMap_[blockIndex].getSize();
            bool isFakeData = p_->blocksMap_[blockIndex].isKnown(); // fake data
            readCount = (size_t) src.read(buf, (long) blockSize);
            byte* blockData = p_->blocksMap_[blockIndex].getData();
            for (i = 0; (i < readCount) && (i < blockSize) && !findDiff; i++) {
                if ((!isFakeData && buf[i] != blockData[i]) || (isFakeData && buf[i] != 0)) {
                    findDiff = true;
                } else {
                    left++;
                }
            }
            blockIndex++;
        }

        // find $right
        findDiff    = false;
        blockIndex  = nBlocks - 1;
        blockSize   = p_->blocksMap_[blockIndex].getSize();
        while ((blockIndex + 1 > 0) && right < src.size() && !findDiff) {
            if(src.seek(-1 * (blockSize + right), BasicIo::end)) {
                findDiff = true;
            } else {
                bool isFakeData = p_->blocksMap_[blockIndex].isKnown(); // fake data
                readCount = src.read(buf, (long) blockSize);
                byte* blockData = p_->blocksMap_[blockIndex].getData();
                for (i = 0; (i < readCount) && (i < blockSize) && !findDiff; i++) {
                    if ((!isFakeData && buf[readCount - i - 1] != blockData[blockSize - i - 1]) || (isFakeData && buf[readCount - i - 1] != 0)) {
                        findDiff = true;
                    } else {
                        right++;
                    }
                }
            }
            blockIndex--;
            blockSize = (long)p_->blocksMap_[blockIndex].getSize();
        }

        // free buf
        if (buf) std::free(buf);

        // submit to the remote machine.
        long dataSize = (long) (src.size() - left - right);
        if (dataSize > 0) {
            byte* data = (byte*) std::malloc(dataSize);
            src.seek(left, BasicIo::beg);
            src.read(data, dataSize);
            p_->writeRemote(data, (size_t)dataSize, (long)left, (long) (p_->size_ - right));
            if (data) std::free(data);
        }
        return (long) src.size();
    }

Project: exiv2
File: xmp.cpp

    int XmpParser::encode(      std::string& xmpPacket,
                          const XmpData&     xmpData,
                                uint16_t     formatFlags,
                                uint32_t     padding)
    { try {
        if (xmpData.empty()) {
            xmpPacket.clear();
            return 0;
        }

        if (!initialize()) {
#ifndef SUPPRESS_WARNINGS
            EXV_ERROR << "XMP toolkit initialization failed.\n";
#endif
            return 2;
        }
        // Register custom namespaces with XMP-SDK
        for (XmpProperties::NsRegistry::iterator i = XmpProperties::nsRegistry_.begin();
             i != XmpProperties::nsRegistry_.end(); ++i) {
#ifdef DEBUG
            std::cerr << "Registering " << i->second.prefix_ << " : " << i->first << "\n";
#endif
            registerNs(i->first, i->second.prefix_);
        }
        SXMPMeta meta;
        for (XmpData::const_iterator i = xmpData.begin(); i != xmpData.end(); ++i) {
            const std::string ns = XmpProperties::ns(i->groupName());
            XMP_OptionBits options = 0;

            if (i->typeId() == langAlt) {

                // Encode Lang Alt property
                const LangAltValue* la = dynamic_cast<const LangAltValue*>(&i->value());
                if (la == 0) throw Error(kerEncodeLangAltPropertyFailed, i->key());

                int idx = 1;
                for ( LangAltValue::ValueType::const_iterator k = la->value_.begin()
                    ; k != la->value_.end()
                    ; ++k
                ) {
                    if ( k->second.size() ) { // remove lang specs with no value
                        printNode(ns, i->tagName(), k->second, 0);
                        meta.AppendArrayItem(ns.c_str(), i->tagName().c_str(), kXMP_PropArrayIsAlternate, k->second.c_str());
                        const std::string item = i->tagName() + "[" + toString(idx++) + "]";
                        meta.SetQualifier(ns.c_str(), item.c_str(), kXMP_NS_XML, "lang", k->first.c_str());
                    }
                }
                continue;
            }

            // Todo: Xmpdatum should have an XmpValue, not a Value
            const XmpValue* val = dynamic_cast<const XmpValue*>(&i->value());
            if (val == 0) throw Error(kerInvalidKeyXmpValue, i->key(), i->typeName());
            options =   xmpArrayOptionBits(val->xmpArrayType())
                      | xmpArrayOptionBits(val->xmpStruct());
            if (   i->typeId() == xmpBag
                || i->typeId() == xmpSeq
                || i->typeId() == xmpAlt) {
                printNode(ns, i->tagName(), "", options);
                meta.SetProperty(ns.c_str(), i->tagName().c_str(), 0, options);
                for (int idx = 0; idx < i->count(); ++idx) {
                    const std::string item = i->tagName() + "[" + toString(idx + 1) + "]";
                    printNode(ns, item, i->toString(idx), 0);
                    meta.SetProperty(ns.c_str(), item.c_str(), i->toString(idx).c_str());
                }
                continue;
            }
            if (i->typeId() == xmpText) {
                if (i->count() == 0) {
                    printNode(ns, i->tagName(), "", options);
                    meta.SetProperty(ns.c_str(), i->tagName().c_str(), 0, options);
                }
                else {
                    printNode(ns, i->tagName(), i->toString(0), options);
                    meta.SetProperty(ns.c_str(), i->tagName().c_str(), i->toString(0).c_str(), options);
                }
                continue;
            }
            // Don't let any Xmpdatum go by unnoticed
            throw Error(kerUnhandledXmpdatum, i->tagName(), i->typeName());
        }
        std::string tmpPacket;
        meta.SerializeToBuffer(&tmpPacket, xmpFormatOptionBits(static_cast<XmpFormatFlags>(formatFlags)), padding); // throws
        xmpPacket = tmpPacket;

        return 0;
    }
#ifndef SUPPRESS_WARNINGS
    catch (const XMP_Error& e) {
        EXV_ERROR << Error(kerXMPToolkitError, e.GetID(), e.GetErrMsg()) << "\n";
        return 3;
    }
#else
    catch (const XMP_Error&) {
        return 3;
    }
#endif // SUPPRESS_WARNINGS
    } // XmpParser::decode

Project: exiv2
File: preview.cpp

    PreviewProperties LoaderExifJpeg::getProperties() const
    {
        PreviewProperties prop = Loader::getProperties();
        prop.mimeType_ = "image/jpeg";
        prop.extension_ = ".jpg";
#ifdef EXV_UNICODE_PATH
        prop.wextension_ = EXV_WIDEN(".jpg");
#endif
        return prop;
    }

Project: exiv2
File: makernote_int.cpp

    SigmaMnHeader::~SigmaMnHeader()
    {
    }

Project: exiv2
File: tiffcomposite_int.cpp

    ByteOrder TiffIfdMakernote::byteOrder() const
    {
        assert(imageByteOrder_ != invalidByteOrder);
        if (!pHeader_ || pHeader_->byteOrder() == invalidByteOrder) {
            return imageByteOrder_;
        }
        return pHeader_->byteOrder();
    }

Project: exiv2
File: xmp.cpp

    XmpData::iterator XmpData::end()
    {
        return xmpMetadata_.end();
    }

Project: exiv2
File: actions.cpp

    FixIso* FixIso::clone_() const
    {
        return new FixIso(*this);
    }

Project: exiv2
File: preview.cpp

    Loader::UniquePtr Loader::create(PreviewId id, const Image &image)
    {
        if (id < 0 || id >= Loader::getNumLoaders())
            return UniquePtr();

        if (loaderList_[id].imageMimeType_ &&
            std::string(loaderList_[id].imageMimeType_) != image.mimeType())
            return UniquePtr();

        UniquePtr loader = loaderList_[id].create_(id, image, loaderList_[id].parIdx_);

        if (loader.get() && !loader->valid()) loader.reset();
        return loader;
    }

Project: exiv2
File: value.cpp

    long DataValue::count() const
    {
        return size();
    }

Project: exiv2
File: makernote_int.cpp

        bool operator==(const Key& key) const
        {
            return    key.tag_ == tag_
                   && 0 == strncmp(key.ver_, ver_, strlen(ver_))
                   && (size_ == 0 || key.size_ == size_);
        }

Project: exiv2
File: jp2image.cpp

    Jp2Image::Jp2Image(BasicIo::UniquePtr io, bool create)
            : Image(ImageType::jp2, mdExif | mdIptc | mdXmp, std::move(io))
    {
        if (create)
        {
            if (io_->open() == 0)
            {
#ifdef DEBUG
                std::cerr << "Exiv2::Jp2Image:: Creating JPEG2000 image to memory" << std::endl;
#endif
                IoCloser closer(*io_);
                if (io_->write(Jp2Blank, sizeof(Jp2Blank)) != sizeof(Jp2Blank))
                {
#ifdef DEBUG
                    std::cerr << "Exiv2::Jp2Image:: Failed to create JPEG2000 image on memory" << std::endl;
#endif
                }
            }
        }
    } // Jp2Image::Jp2Image

Project: exiv2
File: tiffimage.cpp

    uint32_t TiffHeaderBase::size() const
    {
        return size_;
    }

Project: exiv2
File: makernote_int.cpp

    constexpr uint32_t Nikon3MnHeader::sizeOfSignature()
    {
        return sizeof(signature_);
    }

Project: exiv2
File: crwimage_int.cpp

    DataLocId CiffComponent::dataLocation(uint16_t tag)
    {
        switch (tag & 0xc000) {
        case 0x0000: return valueData;
        case 0x4000: return directoryData;
        default: throw Error(kerCorruptedMetadata);
        }
    } // CiffComponent::dataLocation

Project: exiv2
File: crwimage.cpp

    CrwImage::CrwImage(BasicIo::UniquePtr io, bool /*create*/)
        : Image(ImageType::crw, mdExif | mdComment, std::move(io))
    {
    } // CrwImage::CrwImage

Project: exiv2
File: tiffcomposite_int.cpp

    TiffBinaryArray::TiffBinaryArray(const TiffBinaryArray& rhs)
        : TiffEntryBase(rhs),
          cfgSelFct_(rhs.cfgSelFct_),
          arraySet_(rhs.arraySet_),
          arrayCfg_(rhs.arrayCfg_),
          arrayDef_(rhs.arrayDef_),
          defSize_(rhs.defSize_),
          setSize_(rhs.setSize_),
          origData_(rhs.origData_),
          origSize_(rhs.origSize_),
          pRoot_(rhs.pRoot_),
          decoded_(false)
    {
    }

Project: exiv2
File: crwimage_int.cpp

    void CiffDirectory::readDirectory(const byte* pData,
                                      uint32_t    size,
                                      ByteOrder   byteOrder)
    {
        if (size < 4)
            throw Error(kerCorruptedMetadata);
        uint32_t o = getULong(pData + size - 4, byteOrder);
        if ( o > size-2 )
            throw Error(kerCorruptedMetadata);
        uint16_t count = getUShort(pData + o, byteOrder);
#ifdef DEBUG
        std::cout << "Directory at offset " << std::dec << o
                  <<", " << count << " entries \n";
#endif
        o += 2;
        if ( static_cast<uint32_t>(count) * 10 > size-o )
            throw Error(kerCorruptedMetadata);

        for (uint16_t i = 0; i < count; ++i) {
            uint16_t tag = getUShort(pData + o, byteOrder);
            CiffComponent::UniquePtr m;
            switch (CiffComponent::typeId(tag)) {
            case directory: m = CiffComponent::UniquePtr(new CiffDirectory); break;
            default: m = CiffComponent::UniquePtr(new CiffEntry); break;
            }
            m->setDir(this->tag());
            m->read(pData, size, o, byteOrder);
            add(std::move(m));
            o += 10;
        }
    }  // CiffDirectory::readDirectory

Project: exiv2
File: image.cpp

    void Image::clearExifData()
    {
        exifData_.clear();
    }

Project: exiv2
File: tiffcomposite_int.cpp

    uint32_t TiffDirectory::doSize() const
    {
        uint32_t compCount = count();
        // Size of the directory, without values and additional data
        uint32_t len = 2 + 12 * compCount + (hasNext_ ? 4 : 0);
        // Size of IFD values and data
        for (Components::const_iterator i = components_.begin(); i != components_.end(); ++i) {
            uint32_t sv = (*i)->size();
            if (sv > 4) {
                sv += sv & 1;               // Align value to word boundary
                len += sv;
            }
            uint32_t sd = (*i)->sizeData();
            sd += sd & 1;                   // Align data to word boundary
            len += sd;
        }
        // Size of next-IFD, if any
        uint32_t sizeNext = 0;
        if (pNext_) {
            sizeNext = pNext_->size();
            len += sizeNext;
        }
        // Reset size of IFD if it has no entries and no or empty next IFD.
        if (compCount == 0 && sizeNext == 0) len = 0;
        return len;
    } // TiffDirectory::doSize

Project: exiv2
File: image.cpp

    bool Image::iccProfileDefined() const { return iccProfile_.size_?true:false;}

Project: exiv2
File: value.cpp

    std::ostream& XmpTextValue::write(std::ostream& os) const
    {
        bool del = false;
        if (xmpArrayType() != XmpValue::xaNone) {
            switch (xmpArrayType()) {
            case XmpValue::xaAlt: os << "type=\"Alt\""; break;
            case XmpValue::xaBag: os << "type=\"Bag\""; break;
            case XmpValue::xaSeq: os << "type=\"Seq\""; break;
            case XmpValue::xaNone: break; // just to suppress the warning
            }
            del = true;
        }
        else if (xmpStruct() != XmpValue::xsNone) {
            switch (xmpStruct()) {
            case XmpValue::xsStruct: os << "type=\"Struct\""; break;
            case XmpValue::xsNone: break; // just to suppress the warning
            }
            del = true;
        }
        if (del && !value_.empty()) os << " ";
        return os << value_;
    }

Project: exiv2
File: exif.cpp

    size_t Exifdatum::count() const
    {
        return value_.get() == 0 ? 0 : value_->count();
    }

Project: exiv2
File: exif.cpp

    std::string Exifdatum::toString(long n) const
    {
        return value_.get() == 0 ? "" : value_->toString(n);
    }

Project: exiv2
File: exif.cpp

    const char* TiffThumbnail::extension() const
    {
        return ".tif";
    }

Project: exiv2
File: types.cpp

    Slice<byte*> makeSlice(DataBuf& buf, size_t begin, size_t end)
    {
        checkDataBufBounds(buf, end);
        return Slice<byte*>(buf.pData_, begin, end);
    }

Project: exiv2
File: basicio.cpp

    size_t MemIo::write(const byte* data, size_t wcount)
    {
        p_->reserve(wcount);
        assert(p_->isMalloced_);
        if (data != nullptr) {
            std::memcpy(&p_->data_[p_->idx_], data, wcount);
        }
        p_->idx_ += wcount;
        return wcount;
    }

Project: exiv2
File: tiffcomposite_int.cpp

    uint32_t TiffBinaryArray::doCount() const
    {
        if (cfg() == 0 || !decoded()) return TiffEntryBase::doCount();

        if (elements_.empty()) return 0;

        TypeId typeId = toTypeId(tiffType(), tag(), group());
        long typeSize = TypeInfo::typeSize(typeId);
        if (0 == typeSize) {
#ifndef SUPPRESS_WARNINGS
            EXV_WARNING << "Directory " << groupName(group())
                        << ", entry 0x" << std::setw(4)
                        << std::setfill('0') << std::hex << tag()
                        << " has unknown Exif (TIFF) type " << std::dec << tiffType()
                        << "; setting type size 1.\n";
#endif
            typeSize = 1;
        }

        return static_cast<uint32_t>(static_cast<double>(size()) / typeSize + 0.5);
    }

Project: exiv2
File: types.cpp

    long r2Data(byte* buf, Rational l, ByteOrder byteOrder)
    {
        long o = l2Data(buf, l.first, byteOrder);
        o += l2Data(buf+o, l.second, byteOrder);
        return o;
    }

Project: exiv2
File: preview.cpp

    DataBuf decodeHex(const byte *src, long srcSize)
    {
        // create decoding table
        byte invalid = 16;
        byte decodeHexTable[256];
        for (long i = 0; i < 256; i++) decodeHexTable[i] = invalid;
        for (byte i = 0; i < 10; i++) decodeHexTable[static_cast<byte>('0') + i] = i;
        for (byte i = 0; i < 6; i++) decodeHexTable[static_cast<byte>('A') + i] = i + 10;
        for (byte i = 0; i < 6; i++) decodeHexTable[static_cast<byte>('a') + i] = i + 10;

        // calculate dest size
        long validSrcSize = 0;
        for (long srcPos = 0; srcPos < srcSize; srcPos++) {
            if (decodeHexTable[src[srcPos]] != invalid) validSrcSize++;
        }
        const long destSize = validSrcSize / 2;

        // allocate dest buffer
        DataBuf dest(destSize);

        // decode
        for (long srcPos = 0, destPos = 0; destPos < destSize; destPos++) {
            byte buffer = 0;
            for (int bufferPos = 1; bufferPos >= 0 && srcPos < srcSize; srcPos++) {
                byte srcValue = decodeHexTable[src[srcPos]];
                if (srcValue == invalid) continue;
                buffer |= srcValue << (bufferPos * 4);
                bufferPos--;
            }
            dest.pData_[destPos] = buffer;
        }
        return dest;
    }

Project: exiv2
File: image.cpp

    const IptcData& Image::iptcData() const
    {
        return iptcData_;
    }

Project: exiv2
File: value.cpp

    DataValue* DataValue::clone_() const
    {
        return new DataValue(*this);
    }

Project: exiv2
File: tiffimage_int.cpp

    TiffComponent::UniquePtr TiffCreator::create(uint32_t extendedTag,
                                               IfdId    group)
    {
        TiffComponent::UniquePtr tc;
        uint16_t tag = static_cast<uint16_t>(extendedTag & 0xffff);
        const TiffGroupStruct* ts = find(tiffGroupStruct_,
                                         TiffGroupStruct::Key(extendedTag, group));
        if (ts && ts->newTiffCompFct_) {
            tc = ts->newTiffCompFct_(tag, group);
        }
#ifdef DEBUG
        else {
            if (!ts) {
                std::cerr << "Warning: No TIFF structure entry found for ";
            }
            else {
                std::cerr << "Warning: No TIFF component creator found for ";
            }
            std::cerr << "extended tag 0x" << std::setw(4) << std::setfill('0')
                      << std::hex << std::right << extendedTag
                      << ", group " << groupName(group) << "\n";
        }
#endif
        return tc;
    } // TiffCreator::create

Project: exiv2
File: basicio.cpp

    size_t CurlIo::write(const byte* data, size_t wcount)
    {
        if (p_->protocol_ == pHttp || p_->protocol_ == pHttps) {
            return RemoteIo::write(data, wcount);
        } else {
            throw Error(kerErrorMessage, "doesnt support write for this protocol.");
        }
    }

Project: exiv2
File: makernote_int.cpp

    Nikon3MnHeader::Nikon3MnHeader()
    {
        buf_.alloc(sizeOfSignature());
        std::memcpy(buf_.pData_, signature_, buf_.size_);
        byteOrder_ = invalidByteOrder;
        start_ = sizeOfSignature();
    }

Project: exiv2
File: makernote_int.cpp

    int nikonSelector(uint16_t tag, const byte* pData, uint32_t size, TiffComponent* const /*pRoot*/)
    {
        if (size < 4) return -1;
        const NikonArrayIdx* aix = find(nikonArrayIdx, NikonArrayIdx::Key(tag, reinterpret_cast<const char*>(pData), size));
        return aix == 0 ? -1 : aix->idx_;
    }

Project: exiv2
File: makernote_int.cpp

            Key(uint16_t tag, const char* ver, uint32_t size) : tag_(tag), ver_(ver), size_(size) {}

Project: exiv2
File: psdimage.cpp

    void PsdImage::readMetadata()
    {
#ifdef DEBUG
        std::cerr << "Exiv2::PsdImage::readMetadata: Reading Photoshop file " << io_->path() << "\n";
#endif
        if (io_->open() != 0) {
            throw Error(kerDataSourceOpenFailed, io_->path(), strError());
        }
        IoCloser closer(*io_);
        // Ensure that this is the correct image type
        if (!isPsdType(*io_, false)) {
            if (io_->error() || io_->eof())
                throw Error(kerFailedToReadImageData);
            throw Error(kerNotAnImage, "Photoshop");
        }
        clearMetadata();

        /*
          The Photoshop header goes as follows -- all numbers are in big-endian byte order:

          offset  length   name       description
          ======  =======  =========  =========
           0      4 bytes  signature  always '8BPS'
           4      2 bytes  version    always equal to 1
           6      6 bytes  reserved   must be zero
          12      2 bytes  channels   number of channels in the image, including alpha channels (1 to 24)
          14      4 bytes  rows       the height of the image in pixels
          18      4 bytes  columns    the width of the image in pixels
          22      2 bytes  depth      the number of bits per channel
          24      2 bytes  mode       the color mode of the file; Supported values are: Bitmap=0; Grayscale=1;
          Indexed=2; RGB=3; CMYK=4; Multichannel=7; Duotone=8; Lab=9
        */
        byte buf[26];
        if (io_->read(buf, 26) != 26) {
            throw Error(kerNotAnImage, "Photoshop");
        }
        pixelWidth_ = getLong(buf + 18, bigEndian);
        pixelHeight_ = getLong(buf + 14, bigEndian);

        // immediately following the image header is the color mode data section,
        // the first four bytes of which specify the byte size of the whole section
        if (io_->read(buf, 4) != 4) {
            throw Error(kerNotAnImage, "Photoshop");
        }

        // skip it
        uint32_t colorDataLength = getULong(buf, bigEndian);
        if (io_->seek(colorDataLength, BasicIo::cur)) {
            throw Error(kerNotAnImage, "Photoshop");
        }

        // after the color data section, comes a list of resource blocks, preceded by the total byte size
        if (io_->read(buf, 4) != 4) {
            throw Error(kerNotAnImage, "Photoshop");
        }
        uint32_t resourcesLength = getULong(buf, bigEndian);
        enforce(resourcesLength < io_->size(), Exiv2::kerCorruptedMetadata);

        while (resourcesLength > 0)
        {
            enforce(resourcesLength >= 8, Exiv2::kerCorruptedMetadata);
            resourcesLength -= 8;
            if (io_->read(buf, 8) != 8) {
                throw Error(kerNotAnImage, "Photoshop");
            }

            if (!Photoshop::isIrb(buf, 4)) {
                break;  // bad resource type
            }
            uint16_t resourceId = getUShort(buf + 4, bigEndian);
            uint32_t resourceNameLength = buf[6] & ~1;

            // skip the resource name, plus any padding
            enforce(resourceNameLength <= resourcesLength, Exiv2::kerCorruptedMetadata);
            resourcesLength -= resourceNameLength;
            io_->seek(resourceNameLength, BasicIo::cur);

            // read resource size
            enforce(resourcesLength >= 4, Exiv2::kerCorruptedMetadata);
            resourcesLength -= 4;
            if (io_->read(buf, 4) != 4) {
                throw Error(kerNotAnImage, "Photoshop");
            }
            uint32_t resourceSize = getULong(buf, bigEndian);
            uint32_t curOffset = io_->tell();

#ifdef DEBUG
            std::cerr << std::hex << "resourceId: " << resourceId << std::dec << " length: " << resourceSize << std::hex
                      << "\n";
#endif

            enforce(resourceSize <= resourcesLength, Exiv2::kerCorruptedMetadata);
            readResourceBlock(resourceId, resourceSize);
            resourceSize = (resourceSize + 1) & ~1;        // pad to even
            enforce(resourceSize <= resourcesLength, Exiv2::kerCorruptedMetadata);
            resourcesLength -= resourceSize;
            io_->seek(curOffset + resourceSize, BasicIo::beg);
        }

    }  // PsdImage::readMetadata

Project: exiv2
File: value.cpp

    XmpArrayValue* XmpArrayValue::clone_() const
    {
        return new XmpArrayValue(*this);
    }

Project: exiv2
File: exif.cpp

    void ExifThumb::setJpegThumbnail(
        const std::wstring& wpath,
              URational     xres,
              URational     yres,
              uint16_t      unit
    )
    {
        DataBuf thumb = readFile(wpath); // may throw
        setJpegThumbnail(thumb.pData_, thumb.size_, xres, yres, unit);
    }

Project: exiv2
File: webpimage.cpp

    Image::UniquePtr newWebPInstance(BasicIo::UniquePtr io, bool /*create*/)
    {
        Image::UniquePtr image(new WebPImage(std::move(io)));
        if (!image->good()) {
            image.reset();
        }
        return image;
    }

Project: exiv2
File: image.cpp

    bool Image::isLongType(uint16_t type) {
         return type == Exiv2::unsignedLong
             || type == Exiv2::signedLong
             ;
    }