template <class T, class BASE> byte * IteratedHashBase<T, BASE>::CreateUpdateSpace(size_t &size) { unsigned int blockSize = this->BlockSize(); unsigned int num = ModPowerOf2(m_countLo, blockSize); size = blockSize - num; return (byte *)DataBuf() + num; }
DataBuf Photoshop::setIptcIrb(const byte* pPsData, long 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::bimId_, 4); us2Data(tmpBuf + 4, iptc_, bigEndian); tmpBuf[6] = 0; tmpBuf[7] = 0; ul2Data(tmpBuf + 8, rawIptc.size_, bigEndian); append(psBlob, tmpBuf, 12); append(psBlob, rawIptc.pData_, 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, data is rounded to be even. const uint32_t sizeOldData = sizeHdr + sizeIptc + (sizeIptc & 1); // Note: Because of the rounding, sizeFront + sizeOldData can be // _greater_ than sizePsData by 1 (not just equal), if the original // data was not padded. if (static_cast<uint32_t>(sizePsData) > sizeFront + sizeOldData) { append(psBlob, record + sizeOldData, sizePsData - sizeFront - sizeOldData); } 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
DataBuf Value::dataArea() const { return DataBuf(0, 0); }
inline DataBuf ValueType<T>::dataArea() const { return DataBuf(pDataArea_, sizeDataArea_); }
DataBuf Rw2Header::write() const { // Todo: Implement me! return DataBuf(); }
DataBuf PreviewImage::copy() const { return DataBuf(pData_, size_); }
DataBuf PngChunk::readRawProfile(const DataBuf& text) { DataBuf info; register long i; register unsigned char *dp; const char *sp; unsigned int nibbles; long length; 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}; sp = (char*)text.pData_+1; // Look for newline while (*sp != '\n') sp++; // Look for length while (*sp == '\0' || *sp == ' ' || *sp == '\n') sp++; length = (long) atol(sp); while (*sp != ' ' && *sp != '\n') sp++; // Allocate space if (length == 0) { #ifdef DEBUG std::cerr << "Exiv2::PngChunk::readRawProfile: Unable To Copy Raw Profile: invalid profile length\n"; #endif return DataBuf(); } 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 dp = (unsigned char*)info.pData_; nibbles = length * 2; for (i = 0; i < (long) nibbles; i++) { 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++; } if (i%2 == 0) *dp = (unsigned char) (16*unhex[(int) *sp++]); else (*dp++) += unhex[(int) *sp++]; } return info; } // PngChunk::readRawProfile
DataBuf PngChunk::parsePngChunk(const byte* pData, long size, long& index, int keysize) { DataBuf arr; if(!strncmp((char*)PNG_CHUNK_TYPE(pData, index), "zTXt", 4)) { // Extract a deflate compressed Latin-1 text chunk #ifdef DEBUG std::cerr << "Exiv2::PngChunk::parsePngChunk: We found a zTXt field\n"; #endif // we get the compression method after the key const byte* compressionMethod = &PNG_CHUNK_DATA(pData, index, keysize+1); if ( *compressionMethod != 0x00 ) { // then it isn't zlib compressed and we are sunk #ifdef DEBUG std::cerr << "Exiv2::PngChunk::parsePngChunk: Non-standard zTXt compression method.\n"; #endif throw Error(14); } // compressed string after the compression technique spec const byte* compressedText = &PNG_CHUNK_DATA(pData, index, keysize+2); unsigned int compressedTextSize = getLong(&pData[index], bigEndian)-keysize-2; // security check, also considering overflow wraparound from the addition -- // we may endup with a /smaller/ index if we wrap all the way around long firstIndex = (long)(compressedText - pData); long onePastLastIndex = firstIndex + compressedTextSize; if ( onePastLastIndex > size || onePastLastIndex <= firstIndex) throw Error(14); zlibUncompress(compressedText, compressedTextSize, arr); } else if (!strncmp((char*)PNG_CHUNK_TYPE(pData, index), "tEXt", 4)) { // Extract a non-compressed Latin-1 text chunk #ifdef DEBUG std::cerr << "Exiv2::PngChunk::parsePngChunk: We found a tEXt field\n"; #endif // the text comes after the key, but isn't null terminated const byte* text = &PNG_CHUNK_DATA(pData, index, keysize+1); long textsize = getLong(&pData[index], bigEndian)-keysize-1; // security check, also considering overflow wraparound from the addition -- // we may endup with a /smaller/ index if we wrap all the way around long firstIndex = (long)(text - pData); long onePastLastIndex = firstIndex + textsize; if ( onePastLastIndex > size || onePastLastIndex <= firstIndex) throw Error(14); arr.alloc(textsize); arr = DataBuf(text, textsize); } else if(!strncmp((char*)PNG_CHUNK_TYPE(pData, index), "iTXt", 4)) { // Extract a deflate compressed or uncompressed UTF-8 text chunk // we get the compression flag after the key const byte* compressionFlag = &PNG_CHUNK_DATA(pData, index, keysize+1); // we get the compression method after the compression flag const byte* compressionMethod = &PNG_CHUNK_DATA(pData, index, keysize+1); // language description string after the compression technique spec const byte* languageText = &PNG_CHUNK_DATA(pData, index, keysize+1); unsigned int languageTextSize = getLong(&pData[index], bigEndian)-keysize-1; // translated keyword string after the language description const byte* translatedKeyText = &PNG_CHUNK_DATA(pData, index, keysize+1); unsigned int translatedKeyTextSize = getLong(&pData[index], bigEndian)-keysize-1; if ( *compressionFlag == 0x00 ) { // then it's an uncompressed iTXt chunk #ifdef DEBUG std::cerr << "Exiv2::PngChunk::parsePngChunk: We found an uncompressed iTXt field\n"; #endif // the text comes after the translated keyword, but isn't null terminated const byte* text = &PNG_CHUNK_DATA(pData, index, keysize+1); long textsize = getLong(&pData[index], bigEndian)-keysize-1; // security check, also considering overflow wraparound from the addition -- // we may endup with a /smaller/ index if we wrap all the way around long firstIndex = (long)(text - pData); long onePastLastIndex = firstIndex + textsize; if ( onePastLastIndex > size || onePastLastIndex <= firstIndex) throw Error(14); arr.alloc(textsize); arr = DataBuf(text, textsize); } else if ( *compressionMethod == 0x00 ) { // then it's a zlib compressed iTXt chunk #ifdef DEBUG std::cerr << "Exiv2::PngChunk::parsePngChunk: We found a zlib compressed iTXt field\n"; #endif // the compressed text comes after the translated keyword, but isn't null terminated const byte* compressedText = &PNG_CHUNK_DATA(pData, index, keysize+1); long compressedTextSize = getLong(&pData[index], bigEndian)-keysize-1; // security check, also considering overflow wraparound from the addition -- // we may endup with a /smaller/ index if we wrap all the way around long firstIndex = (long)(compressedText - pData); long onePastLastIndex = firstIndex + compressedTextSize; if ( onePastLastIndex > size || onePastLastIndex <= firstIndex) throw Error(14); zlibUncompress(compressedText, compressedTextSize, arr); } else { // then it isn't zlib compressed and we are sunk #ifdef DEBUG std::cerr << "Exiv2::PngChunk::parsePngChunk: Non-standard iTXt compression method.\n"; #endif throw Error(14); } } else { #ifdef DEBUG std::cerr << "Exiv2::PngChunk::parsePngChunk: We found a field, not expected though\n"; #endif throw Error(14); } return arr; } // PngChunk::parsePngChunk