void RafImage::readMetadata() { #ifdef DEBUG std::cerr << "Reading RAF file " << io_->path() << "\n"; #endif if (io_->open() != 0) throw Error(9, io_->path(), strError()); IoCloser closer(*io_); // Ensure that this is the correct image type if (!isRafType(*io_, false)) { if (io_->error() || io_->eof()) throw Error(14); throw Error(3, "RAF"); } byte const* pData = io_->mmap(); long size = io_->size(); if (size < 88 + 4) throw Error(14); // includes the test for -1 uint32_t const start = getULong(pData + 84, bigEndian) + 12; if (static_cast<uint32_t>(size) < start) throw Error(14); clearMetadata(); ByteOrder bo = TiffParser::decode(exifData_, iptcData_, xmpData_, pData + start, size - start); exifData_["Exif.Image2.JPEGInterchangeFormat"] = getULong(pData + 84, bigEndian); exifData_["Exif.Image2.JPEGInterchangeFormatLength"] = getULong(pData + 88, bigEndian); setByteOrder(bo); } // RafImage::readMetadata
void XmpSidecar::readMetadata() { #ifdef DEBUG std::cerr << "Reading XMP file " << io_->path() << "\n"; #endif if (io_->open() != 0) { throw Error(9, io_->path(), strError()); } IoCloser closer(*io_); // Ensure that this is the correct image type if (!isXmpType(*io_, false)) { if (io_->error() || io_->eof()) throw Error(14); throw Error(3, "XMP"); } // Read the XMP packet from the IO stream std::string xmpPacket; const long len = 64 * 1024; byte buf[len]; long l; while ((l = io_->read(buf, len)) > 0) { xmpPacket.append(reinterpret_cast<char*>(buf), l); } if (io_->error()) throw Error(14); clearMetadata(); xmpPacket_ = xmpPacket; if (xmpPacket_.size() > 0 && XmpParser::decode(xmpData_, xmpPacket_)) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to decode XMP metadata.\n"; #endif } copyXmpToIptc(xmpData_, iptcData_); copyXmpToExif(xmpData_, exifData_); } // XmpSidecar::readMetadata
void GifImage::readMetadata() { #ifdef DEBUG std::cerr << "Exiv2::GifImage::readMetadata: Reading GIF file " << io_->path() << "\n"; #endif if (io_->open() != 0) { throw Error(9, io_->path(), strError()); } IoCloser closer(*io_); // Ensure that this is the correct image type if (!isGifType(*io_, true)) { if (io_->error() || io_->eof()) throw Error(14); throw Error(3, "GIF"); } clearMetadata(); byte buf[4]; if (io_->read(buf, sizeof(buf)) == sizeof(buf)) { pixelWidth_ = getShort(buf, littleEndian); pixelHeight_ = getShort(buf + 2, littleEndian); } } // GifImage::readMetadata
void CrwImage::readMetadata() { #ifdef DEBUG std::cerr << "Reading CRW file " << io_->path() << "\n"; #endif if (io_->open() != 0) { throw Error(9, io_->path(), strError()); } IoCloser closer(*io_); // Ensure that this is the correct image type if (!isThisType(*io_, false)) { if (io_->error() || io_->eof()) throw Error(14); throw Error(33); } clearMetadata(); // Read the image into a memory buffer long imageSize = io_->size(); DataBuf image(imageSize); io_->read(image.pData_, imageSize); if (io_->error() || io_->eof()) throw Error(14); // Parse the image RawMetadata::AutoPtr parseTree(new CiffHeader); parseTree->read(image.pData_, image.size_, 0, invalidByteOrder); #ifdef DEBUG parseTree->print(std::cerr, invalidByteOrder); #endif parseTree->extract(*this, invalidByteOrder); } // CrwImage::readMetadata
void MrwImage::readMetadata() { #ifdef DEBUG std::cerr << "Reading MRW file " << io_->path() << "\n"; #endif if (io_->open() != 0) { throw Error(9, io_->path(), strError()); } IoCloser closer(*io_); // Ensure that this is the correct image type if (!isMrwType(*io_, false)) { if (io_->error() || io_->eof()) throw Error(14); throw Error(3, "MRW"); } clearMetadata(); // Find the TTW block and read it into a buffer uint32_t const len = 8; byte tmp[len]; io_->read(tmp, len); uint32_t pos = len; uint32_t const end = getULong(tmp + 4, bigEndian); pos += len; if (pos > end) throw Error(14); io_->read(tmp, len); if (io_->error() || io_->eof()) throw Error(14); while (memcmp(tmp + 1, "TTW", 3) != 0) { uint32_t const siz = getULong(tmp + 4, bigEndian); pos += siz; if (pos > end) throw Error(14); io_->seek(siz, BasicIo::cur); if (io_->error() || io_->eof()) throw Error(14); pos += len; if (pos > end) throw Error(14); io_->read(tmp, len); if (io_->error() || io_->eof()) throw Error(14); } DataBuf buf(getULong(tmp + 4, bigEndian)); io_->read(buf.pData_, buf.size_); if (io_->error() || io_->eof()) throw Error(14); ByteOrder bo = TiffParser::decode(exifData_, iptcData_, xmpData_, buf.pData_, buf.size_); setByteOrder(bo); } // MrwImage::readMetadata
void PgfImage::readMetadata() { #ifdef DEBUG std::cerr << "Exiv2::PgfImage::readMetadata: Reading PGF file " << io_->path() << "\n"; #endif if (io_->open() != 0) { throw Error(9, io_->path(), strError()); } IoCloser closer(*io_); // Ensure that this is the correct image type if (!isPgfType(*io_, true)) { if (io_->error() || io_->eof()) throw Error(14); throw Error(3, "PGF"); } clearMetadata(); readPgfMagicNumber(*io_); uint32_t headerSize = readPgfHeaderSize(*io_); readPgfHeaderStructure(*io_, &pixelWidth_, &pixelHeight_); // And now, the most interresting, the user data byte array where metadata are stored as small image. long size = 8 + headerSize - io_->tell(); #ifdef DEBUG std::cout << "Exiv2::PgfImage::readMetadata: Found Image data (" << size << " bytes)\n"; #endif if (size < 0) throw Error(20); if (size == 0) return; DataBuf imgData(size); std::memset(imgData.pData_, 0x0, imgData.size_); long bufRead = io_->read(imgData.pData_, imgData.size_); if (io_->error()) throw Error(14); if (bufRead != imgData.size_) throw Error(20); Image::AutoPtr image = Exiv2::ImageFactory::open(imgData.pData_, imgData.size_); image->readMetadata(); exifData() = image->exifData(); iptcData() = image->iptcData(); xmpData() = image->xmpData(); } // PgfImage::readMetadata
void TgaImage::readMetadata() { #ifdef DEBUG std::cerr << "Exiv2::TgaImage::readMetadata: Reading TARGA file " << io_->path() << "\n"; #endif if (io_->open() != 0) { throw Error(9, io_->path(), strError()); } IoCloser closer(*io_); // Ensure that this is the correct image type if (!isTgaType(*io_, false)) { if (io_->error() || io_->eof()) throw Error(14); throw Error(3, "TGA"); } clearMetadata(); /* The TARGA header goes as follows -- all numbers are in little-endian byte order: offset length name description ====== ======= ======================= =========== 0 1 byte ID length length of image ID (0 to 255) 1 1 byte color map type 0 = no color map; 1 = color map included 2 1 byte image type 0 = no image; 1 = uncompressed color-mapped; 2 = uncompressed true-color; 3 = uncompressed black-and-white; 9 = RLE-encoded color mapped; 10 = RLE-encoded true-color; 11 = RLE-encoded black-and-white 3 5 bytes color map specification 8 2 bytes x-origin of image 10 2 bytes y-origin of image 12 2 bytes image width 14 2 bytes image height 16 1 byte pixel depth 17 1 byte image descriptor */ byte buf[18]; if (io_->read(buf, sizeof(buf)) == sizeof(buf)) { pixelWidth_ = getShort(buf + 12, littleEndian); pixelHeight_ = getShort(buf + 14, littleEndian); } } // TgaImage::readMetadata
void BmpImage::readMetadata() { #ifdef DEBUG std::cerr << "Exiv2::BmpImage::readMetadata: Reading Windows bitmap file " << io_->path() << "\n"; #endif if (io_->open() != 0) { throw Error(9, io_->path(), strError()); } IoCloser closer(*io_); // Ensure that this is the correct image type if (!isBmpType(*io_, false)) { if (io_->error() || io_->eof()) throw Error(14); throw Error(3, "BMP"); } clearMetadata(); /* The Windows bitmap header goes as follows -- all numbers are in little-endian byte order: offset length name description ====== ======= ===================== ======= 0 2 bytes signature always 'BM' 2 4 bytes bitmap size 6 4 bytes reserved 10 4 bytes bitmap offset 14 4 bytes header size 18 4 bytes bitmap width 22 4 bytes bitmap height 26 2 bytes plane count 28 2 bytes depth 30 4 bytes compression 0 = none; 1 = RLE, 8 bits/pixel; 2 = RLE, 4 bits/pixel; 3 = bitfield; 4 = JPEG; 5 = PNG 34 4 bytes image size size of the raw bitmap data, in bytes 38 4 bytes horizontal resolution (in pixels per meter) 42 4 bytes vertical resolution (in pixels per meter) 46 4 bytes color count 50 4 bytes important colors number of "important" colors */ byte buf[54]; if (io_->read(buf, sizeof(buf)) == sizeof(buf)) { pixelWidth_ = getLong(buf + 18, littleEndian); pixelHeight_ = getLong(buf + 22, littleEndian); } } // BmpImage::readMetadata
void Cr2Image::readMetadata() { #ifdef DEBUG std::cerr << "Reading CR2 file " << io_->path() << "\n"; #endif if (io_->open() != 0) { throw Error(9, io_->path(), strError()); } IoCloser closer(*io_); // Ensure that this is the correct image type if (!isCr2Type(*io_, false)) { if (io_->error() || io_->eof()) throw Error(14); throw Error(3, "CR2"); } clearMetadata(); TiffParser::decode(this, io_->mmap(), io_->size(), TiffCreator::create, Cr2Decoder::findDecoder); } // Cr2Image::readMetadata
void XmpSidecar::readMetadata() { #ifdef DEBUG std::cerr << "Reading XMP file " << io_->path() << "\n"; #endif if (io_->open() != 0) { throw Error(9, io_->path(), strError()); } IoCloser closer(*io_); // Ensure that this is the correct image type if (!isXmpType(*io_, false)) { if (io_->error() || io_->eof()) throw Error(14); throw Error(3, "XMP"); } // Read the XMP packet from the IO stream std::string xmpPacket; const long len = 64 * 1024; byte buf[len]; long l; while ((l = io_->read(buf, len)) > 0) { xmpPacket.append(reinterpret_cast<char*>(buf), l); } if (io_->error()) throw Error(14); clearMetadata(); xmpPacket_ = xmpPacket; if (xmpPacket_.size() > 0 && XmpParser::decode(xmpData_, xmpPacket_)) { #ifndef SUPPRESS_WARNINGS EXV_WARNING << "Failed to decode XMP metadata.\n"; #endif } // #1112 - store dates to deal with loss of TZ information during conversions for (Exiv2::XmpData::const_iterator it = xmpData_.begin(); it != xmpData_.end(); ++it) { std::string key(it->key()); if ( key.find("Date") != std::string::npos ) { std::string value(it->value().toString()); dates_[key] = value; } } copyXmpToIptc(xmpData_, iptcData_); copyXmpToExif(xmpData_, exifData_); } // XmpSidecar::readMetadata
void RafImage::readMetadata() { #ifdef DEBUG std::cerr << "Reading RAF file " << io_->path() << "\n"; #endif if (io_->open() != 0) throw Error(9, io_->path(), strError()); IoCloser closer(*io_); // Ensure that this is the correct image type if (!isRafType(*io_, false)) { if (io_->error() || io_->eof()) throw Error(14); throw Error(3, "RAF"); } byte const* pData = io_->mmap(); long size = io_->size(); if (size < 84 + 4) throw Error(14); // includes the test for -1 uint32_t const start = getULong(pData + 84, bigEndian) + 12; if (static_cast<uint32_t>(size) < start) throw Error(14); clearMetadata(); TiffParser::decode(this, pData + start, size - start, TiffCreator::create, TiffDecoder::findDecoder); } // RafImage::readMetadata
void TiffImage::readMetadata() { #ifdef DEBUG std::cerr << "Reading TIFF file " << io_->path() << "\n"; #endif if (io_->open() != 0) { throw Error(9, io_->path(), strError()); } IoCloser closer(*io_); // Ensure that this is the correct image type if (!isThisType(*io_, false)) { if (io_->error() || io_->eof()) throw Error(14); throw Error(33); } clearMetadata(); // Read the image into a memory buffer long len = io_->size(); DataBuf buf(len); io_->read(buf.pData_, len); if (io_->error() || io_->eof()) throw Error(14); TiffParser::decode(this, buf.pData_, buf.size_, TiffCreator::create); } // TiffImage::readMetadata
long makeArchPack( const char* const confPath, \ bmdDatagram_t* const bmdDatagram_tParam, \ GenBuf_t* const bufor, \ transmission_t transmission, \ char** const archPackDir, \ char** const archPackFile ) { /* ---------------------------------------------- */ long longRet = 0; static int fileout = 0; static metadata_t* metadane = NULL; char* fileName = NULL; char* archPath = NULL; char* archPackPath = NULL; char* fileMetadata = NULL; char* stringTmp = NULL; char* fileCases = NULL; char** zip_list = NULL; long zip_list_size = 0; static Config_t archPackParams; long i = 0; char curr_dir[256] = {0}; /* ---------------------------------------------- */ if ( confPath == NULL ) { PRINT_ERROR("Nieprawidłowy pierwszy parametr. Error = %d\n", BMD_ERR_PARAM1); return BMD_ERR_PARAM1; } if ( bmdDatagram_tParam == NULL ) { PRINT_ERROR("Nieprawidłowy drugi parametr. Error = %d\n", BMD_ERR_PARAM2); return BMD_ERR_PARAM2; } if ( archPackDir == NULL ) { PRINT_ERROR("Nieprawidłowy czwarty parametr. Error = %d\n", BMD_ERR_PARAM4); return BMD_ERR_PARAM4; } if ( archPackFile == NULL ) { PRINT_ERROR("Nieprawidłowy piąty parametr. Error = %d\n", BMD_ERR_PARAM5); return BMD_ERR_PARAM5; } switch ( transmission ) { case startblk : { longRet = getArchPackConfiguration( confPath, &archPackParams ); if ( longRet != BMD_OK ) { PRINT_ERROR("Błąd odczytu konfiguracji paczki archiwalnej. Error = %d\n", BMD_ERR_OP_FAILED); return BMD_ERR_OP_FAILED; } longRet = composeMetadataStruct( &metadane, &archPackParams, bmdDatagram_tParam ); if ( longRet != BMD_OK ) { PRINT_ERROR("Błąd przy generowaniu pliku metadanych. Error = %d\n", BMD_ERR_OP_FAILED); return BMD_ERR_OP_FAILED; } longRet = openArchPackFile( &archPackParams, (char*)bmdDatagram_tParam->protocolDataFilename->buf, &fileout); if ( longRet != BMD_OK ) { PRINT_ERROR("Błąd tworzenia struktury paczki archiwalnej. Error = %d\n", BMD_ERR_OP_FAILED); return BMD_ERR_OP_FAILED; } asprintf( &fileName, "%s/%s_%d/metadane/%s", archPackParams.repository, \ archPackParams.tmp_dir, (int)getpid(), (char*)bmdDatagram_tParam->protocolDataFilename->buf ); longRet = composeXMLDocument( metadane, fileName ); if ( longRet != BMD_OK ) { PRINT_ERROR("Błąd błąd zapisu metadanych paczki archiwalnej. Error = %d\n", BMD_ERR_OP_FAILED); return BMD_ERR_OP_FAILED; } clearMetadata( &metadane ); longRet = addData2ArchpackFile(bufor, fileout); if ( longRet != BMD_OK ) { PRINT_ERROR("Błąd zapisu zawartości paczki archiwalnej. Error = %d\n", BMD_ERR_OP_FAILED); return BMD_ERR_OP_FAILED; } break; } case continueblk : { longRet = addData2ArchpackFile(bufor, fileout); if ( longRet != BMD_OK ) { PRINT_ERROR("Błąd zapisu zawartości paczki archiwalnej. Error = %d\n", BMD_ERR_OP_FAILED); return BMD_ERR_OP_FAILED; } break; } case stopblk : { longRet = addData2ArchpackFile(bufor, fileout); if ( longRet != BMD_OK ) { PRINT_ERROR("Błąd zapisu zawartości paczki archiwalnej. Error = %d\n", BMD_ERR_OP_FAILED); return BMD_ERR_OP_FAILED; } closeArchpackFile( &fileout ); asprintf( &archPath, "%s/%s_%d", archPackParams.repository, archPackParams.tmp_dir, (int)getpid()); if (getcwd(curr_dir,255)==NULL) { PRINT_ERROR("Błąd odczytu bieżącego katalogu. Error = %d\n", BMD_ERR_OP_FAILED); return BMD_ERR_OP_FAILED; } if ( chdir(archPath) != 0 ) { PRINT_ERROR("Błąd przy zmianie katalogu na tymczasowy. Error = %d\n", BMD_ERR_OP_FAILED); return BMD_ERR_OP_FAILED; } asprintf( &fileName, "dokumenty/%s",(char*)bmdDatagram_tParam->protocolDataFilename->buf ); asprintf( &fileMetadata, "metadane/%s.xml",(char*)bmdDatagram_tParam->protocolDataFilename->buf ); asprintf( &fileCases, "sprawy/" ); /* ---------------- pobrany plik ------------------ */ zip_list_size++; zip_list=(char **)realloc(zip_list,sizeof(char *)*zip_list_size); zip_list[zip_list_size-1]=(char*)malloc(strlen(fileName)+2); memset(zip_list[zip_list_size-1], 0, strlen(fileName)+1); memcpy(zip_list[zip_list_size-1], fileName, strlen(fileName)); /* ---------------- metadane ------------------ */ zip_list_size++; zip_list=(char **)realloc(zip_list,sizeof(char *)*zip_list_size); zip_list[zip_list_size-1]=(char*)malloc(strlen(fileMetadata)+2); memset(zip_list[zip_list_size-1], 0, strlen(fileMetadata)+1); memcpy(zip_list[zip_list_size-1], fileMetadata, strlen(fileMetadata)); zip_list_size++; zip_list=(char **)realloc(zip_list,sizeof(char *)*zip_list_size); zip_list[zip_list_size-1]=(char*)malloc(strlen(fileCases)+2); memset(zip_list[zip_list_size-1], 0, strlen(fileCases)+1); memcpy(zip_list[zip_list_size-1], fileCases, strlen(fileCases)); asprintf(&archPackPath, "%s/%s.zip", curr_dir, (char*)bmdDatagram_tParam->protocolDataFilename->buf); asprintf(archPackDir, "%s", curr_dir); asprintf(archPackFile, "%s.zip", (char*)bmdDatagram_tParam->protocolDataFilename->buf ); longRet = zipPackFile(zip_list, zip_list_size, archPackPath); /* porzadki */ unlink(fileName); free0(fileName); /* porzadki */ unlink(fileMetadata); free0(fileMetadata); /* porzadki */ asprintf( &stringTmp, "%s/dokumenty", archPath); rmdir(stringTmp); free0(stringTmp); /* porzadki */ asprintf(&stringTmp, "%s/metadane", archPath); rmdir(stringTmp); free0(stringTmp); /* porzadki */ asprintf(&stringTmp, "%s/sprawy", archPath); rmdir(stringTmp); free0(stringTmp); /* porzadki */ rmdir(archPath); for (i=0; i<zip_list_size; i++) { free0(zip_list[i]); } free0(zip_list); if ( chdir(curr_dir) != 0 ) { PRINT_ERROR("Błąd przy zmianie katalogu na tymczasowy. Error = %d\n", BMD_ERR_OP_FAILED); return BMD_ERR_OP_FAILED; } } } return BMD_OK; }
void JpegBase::readMetadata() { int rc = 0; // Todo: this should be the return value if (io_->open() != 0) throw Error(9, io_->path(), strError()); IoCloser closer(*io_); // Ensure that this is the correct image type if (!isThisType(*io_, true)) { if (io_->error() || io_->eof()) throw Error(14); throw Error(15); } clearMetadata(); int search = 5; const long bufMinSize = 36; long bufRead = 0; DataBuf buf(bufMinSize); Blob iptcBlob; bool foundPsData = false; bool foundExifData = false; // Read section marker int marker = advanceToMarker(); if (marker < 0) throw Error(15); while (marker != sos_ && marker != eoi_ && search > 0) { // Read size and signature (ok if this hits EOF) std::memset(buf.pData_, 0x0, buf.size_); bufRead = io_->read(buf.pData_, bufMinSize); if (io_->error()) throw Error(14); if (bufRead < 2) throw Error(15); uint16_t size = getUShort(buf.pData_, bigEndian); if (foundPsData && marker != app13_) { // For IPTC, decrement search only after all app13 segments are // loaded, assuming they all appear in sequence. But decode IPTC // data after the loop, in case an app13 is the last segment // before sos or eoi. foundPsData = false; if (--search == 0) break; } if ( !foundExifData && marker == app1_ && memcmp(buf.pData_ + 2, exifId_, 6) == 0) { if (size < 8) { rc = 1; break; } // Seek to beginning and read the Exif data io_->seek(8 - bufRead, BasicIo::cur); DataBuf rawExif(size - 8); io_->read(rawExif.pData_, rawExif.size_); if (io_->error() || io_->eof()) throw Error(14); ByteOrder bo = ExifParser::decode(exifData_, rawExif.pData_, rawExif.size_); setByteOrder(bo); if (rawExif.size_ > 0 && byteOrder() == invalidByteOrder) { #ifndef SUPPRESS_WARNINGS std::cerr << "Warning: Failed to decode Exif metadata.\n"; #endif exifData_.clear(); } --search; foundExifData = true; } else if (marker == app1_ && memcmp(buf.pData_ + 2, xmpId_, 29) == 0) { if (size < 31) { rc = 6; break; } // Seek to beginning and read the XMP packet io_->seek(31 - bufRead, BasicIo::cur); DataBuf xmpPacket(size - 31); io_->read(xmpPacket.pData_, xmpPacket.size_); if (io_->error() || io_->eof()) throw Error(14); xmpPacket_.assign(reinterpret_cast<char*>(xmpPacket.pData_), xmpPacket.size_); if (xmpPacket_.size() > 0 && XmpParser::decode(xmpData_, xmpPacket_)) { #ifndef SUPPRESS_WARNINGS std::cerr << "Warning: Failed to decode XMP metadata.\n"; #endif } --search; } else if ( marker == app13_ && memcmp(buf.pData_ + 2, Photoshop::ps3Id_, 14) == 0) { if (size < 16) { rc = 2; break; } // Read the rest of the APP13 segment io_->seek(16 - bufRead, BasicIo::cur); DataBuf psData(size - 16); io_->read(psData.pData_, psData.size_); if (io_->error() || io_->eof()) throw Error(14); const byte *record = 0; uint32_t sizeIptc = 0; uint32_t sizeHdr = 0; #ifdef DEBUG std::cerr << "Found app13 segment, size = " << size << "\n"; //hexdump(std::cerr, psData.pData_, psData.size_); #endif // Find actual IPTC data within the APP13 segment const byte* pEnd = psData.pData_ + psData.size_; const byte* pCur = psData.pData_; while ( pCur < pEnd && 0 == Photoshop::locateIptcIrb(pCur, static_cast<long>(pEnd - pCur), &record, &sizeHdr, &sizeIptc)) { if (sizeIptc) { #ifdef DEBUG std::cerr << "Found IPTC IRB, size = " << sizeIptc << "\n"; #endif append(iptcBlob, record + sizeHdr, sizeIptc); } pCur = record + sizeHdr + sizeIptc; pCur += (sizeIptc & 1); } foundPsData = true; } else if (marker == com_ && comment_.empty()) { if (size < 2) { rc = 3; break; } // JPEGs can have multiple comments, but for now only read // the first one (most jpegs only have one anyway). Comments // are simple single byte ISO-8859-1 strings. io_->seek(2 - bufRead, BasicIo::cur); DataBuf comment(size - 2); io_->read(comment.pData_, comment.size_); if (io_->error() || io_->eof()) throw Error(14); comment_.assign(reinterpret_cast<char*>(comment.pData_), comment.size_); while ( comment_.length() && comment_.at(comment_.length()-1) == '\0') { comment_.erase(comment_.length()-1); } --search; } else if ( pixelHeight_ == 0 && ( marker == sof0_ || marker == sof1_ || marker == sof2_ || marker == sof3_ || marker == sof5_ || marker == sof6_ || marker == sof7_ || marker == sof9_ || marker == sof10_ || marker == sof11_ || marker == sof13_ || marker == sof14_ || marker == sof15_)) { // We hit a SOFn (start-of-frame) marker if (size < 8) { rc = 7; break; } pixelHeight_ = getUShort(buf.pData_ + 3, bigEndian); pixelWidth_ = getUShort(buf.pData_ + 5, bigEndian); if (pixelHeight_ != 0) --search; // Skip the remainder of the segment io_->seek(size-bufRead, BasicIo::cur); } else { if (size < 2) { rc = 4; break; } // Skip the remainder of the unknown segment if (io_->seek(size - bufRead, BasicIo::cur)) throw Error(14); } // Read the beginning of the next segment marker = advanceToMarker(); if (marker < 0) { rc = 5; break; } } // while there are segments to process if ( iptcBlob.size() > 0 && IptcParser::decode(iptcData_, &iptcBlob[0], static_cast<uint32_t>(iptcBlob.size()))) { #ifndef SUPPRESS_WARNINGS std::cerr << "Warning: Failed to decode IPTC metadata.\n"; #endif iptcData_.clear(); } if (rc != 0) { #ifndef SUPPRESS_WARNINGS std::cerr << "Warning: JPEG format error, rc = " << rc << "\n"; #endif } } // JpegBase::readMetadata
void ExplorerPane::clear() { clearMetadata(); clearErrors(); clearSimulator(); }
void PsdImage::readMetadata() { #ifdef DEBUG std::cerr << "Exiv2::PsdImage::readMetadata: Reading Photoshop file " << io_->path() << "\n"; #endif if (io_->open() != 0) { throw Error(9, 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(14); throw Error(3, "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(3, "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(3, "Photoshop"); } // skip it uint32_t colorDataLength = getLong(buf, bigEndian); if (io_->seek(colorDataLength, BasicIo::cur)) { throw Error(3, "Photoshop"); } // after the color data section, comes a list of resource blocks, preceeded by the total byte size if (io_->read(buf, 4) != 4) { throw Error(3, "Photoshop"); } uint32_t resourcesLength = getLong(buf, bigEndian); while (resourcesLength > 0) { if (io_->read(buf, 8) != 8) { throw Error(3, "Photoshop"); } // read resource type and ID uint32_t resourceType = getLong(buf, bigEndian); uint16_t resourceId = getShort(buf + 4, bigEndian); if (resourceType != kPhotoshopResourceType) { break; // bad resource type } uint32_t resourceNameLength = buf[6] & ~1; // skip the resource name, plus any padding io_->seek(resourceNameLength, BasicIo::cur); // read resource size if (io_->read(buf, 4) != 4) { throw Error(3, "Photoshop"); } uint32_t resourceSize = getLong(buf, bigEndian); uint32_t curOffset = io_->tell(); processResourceBlock(resourceId, resourceSize); resourceSize = (resourceSize + 1) & ~1; // pad to even io_->seek(curOffset + resourceSize, BasicIo::beg); resourcesLength -= (12 + resourceNameLength + resourceSize); } } // PsdImage::readMetadata
void JpegBase::readMetadata() { int rc = 0; // Todo: this should be the return value if (io_->open() != 0) throw Error(9, io_->path(), strError()); IoCloser closer(*io_); // Ensure that this is the correct image type if (!isThisType(*io_, true)) { if (io_->error() || io_->eof()) throw Error(14); throw Error(15); } clearMetadata(); int search = 3; const long bufMinSize = 16; long bufRead = 0; DataBuf buf(bufMinSize); // Read section marker int marker = advanceToMarker(); if (marker < 0) throw Error(15); while (marker != sos_ && marker != eoi_ && search > 0) { // Read size and signature (ok if this hits EOF) bufRead = io_->read(buf.pData_, bufMinSize); if (io_->error()) throw Error(14); uint16_t size = getUShort(buf.pData_, bigEndian); if (marker == app1_ && memcmp(buf.pData_ + 2, exifId_, 6) == 0) { if (size < 8) { rc = 1; break; } // Seek to beginning and read the Exif data io_->seek(8-bufRead, BasicIo::cur); long sizeExifData = size - 8; DataBuf rawExif(sizeExifData); io_->read(rawExif.pData_, sizeExifData); if (io_->error() || io_->eof()) throw Error(14); if (exifData_.load(rawExif.pData_, sizeExifData)) { #ifndef SUPPRESS_WARNINGS std::cerr << "Warning: Failed to decode Exif metadata.\n"; #endif exifData_.clear(); } --search; } else if ( marker == app13_ && memcmp(buf.pData_ + 2, Photoshop::ps3Id_, 14) == 0) { if (size < 16) { rc = 2; break; } // Read the rest of the APP13 segment // needed if bufMinSize!=16: io_->seek(16-bufRead, BasicIo::cur); DataBuf psData(size - 16); io_->read(psData.pData_, psData.size_); if (io_->error() || io_->eof()) throw Error(14); const byte *record = 0; uint32_t sizeIptc = 0; uint32_t sizeHdr = 0; // Find actual Iptc data within the APP13 segment if (!Photoshop::locateIptcIrb(psData.pData_, psData.size_, &record, &sizeHdr, &sizeIptc)) { if (sizeIptc) { if (iptcData_.load(record + sizeHdr, sizeIptc)) { #ifndef SUPPRESS_WARNINGS std::cerr << "Warning: Failed to decode IPTC metadata.\n"; #endif iptcData_.clear(); } } } --search; } else if (marker == com_ && comment_.empty()) { if (size < 2) { rc = 3; break; } // Jpegs can have multiple comments, but for now only read // the first one (most jpegs only have one anyway). Comments // are simple single byte ISO-8859-1 strings. io_->seek(2-bufRead, BasicIo::cur); buf.alloc(size-2); io_->read(buf.pData_, size-2); if (io_->error() || io_->eof()) throw Error(14); comment_.assign(reinterpret_cast<char*>(buf.pData_), size-2); while ( comment_.length() && comment_.at(comment_.length()-1) == '\0') { comment_.erase(comment_.length()-1); } --search; } else { if (size < 2) { rc = 4; break; } // Skip the remainder of the unknown segment if (io_->seek(size-bufRead, BasicIo::cur)) throw Error(14); } // Read the beginning of the next segment marker = advanceToMarker(); if (marker < 0) { rc = 5; break; } } // while there are segments to process if (rc != 0) { #ifndef SUPPRESS_WARNINGS std::cerr << "Warning: JPEG format error, rc = " << rc << "\n"; #endif } } // JpegBase::readMetadata
patternMetadata::patternMetadata(int pdfWidth, int titleFontSize, int patternByFontSize, int photoByFontSize, QWidget* parent) : cancelAcceptDialogBase(parent), widgetLayout_(new QVBoxLayout), metadataBox_(new QGroupBox(tr("Pattern information (all fields are optional, all text will be centered in the pdf)"))), metadataLayout_(new QVBoxLayout), titleLabel_(new QLabel(tr("<u><b>Pattern title</b></u> (only the first line will be used):"))), titleEdit_(new fixedWidthTextEdit(pdfWidth, 1, this)), titleSettingsKey_("pattern_title"), titleFontSize_(titleFontSize), linesToKeep_(4), patternByLabel_(new QLabel(tr("<u><b>Pattern information</b></u> (only the first four lines will be used):"))), patternByEdit_(new fixedWidthTextEdit(pdfWidth, linesToKeep_, this)), patternBySettingsKey_("pattern_by"), patternByFontSize_(patternByFontSize), patternByLicenseLayout_(new QHBoxLayout), patternByLicenseButton_(new QPushButton(tr("Insert"))), patternByLicenses_(new QComboBox), photoByLabel_(new QLabel(tr("<u><b>Photo information</b></u> (only the first four lines will be used):"))), photoByEdit_(new fixedWidthTextEdit(pdfWidth, linesToKeep_, this)), photoBySettingsKey_("photo_by"), photoByFontSize_(photoByFontSize), photoByLicenseLayout_(new QHBoxLayout), photoByLicenseButton_(new QPushButton(tr("Insert"))), photoByLicenses_(new QComboBox), clearMetadataButton_(new QPushButton(tr("Clear all information"))), symbolSizeBox_(new QGroupBox(tr("Pdf symbol size"))), symbolSizeLayout_(new QVBoxLayout), symbolSizeTitleLayout_(new QHBoxLayout), symbolSizeTitle_(new QLabel("Set the pdf symbol size (from " + QString::number(MIN_SYMBOL_SIZE) + " to " + QString::number(MAX_SYMBOL_SIZE) + "): ")), symbolSizeSpinBox_(new QSpinBox), symbolSizeKey_("pdf_symbol_size"), symbolPreviewLayout_(new QHBoxLayout), symbolPreview_(new QLabel) { // TODO this won't quite be right since the textEdit has mystery margins const int inputFieldWidth = pdfWidth + ::scrollbarWidth(); const QFont applicationFont = QApplication::font(); #ifdef Q_OS_LINUX // Qt-linux bug (4.6.3) for QFontMetrics.lineSpacing()? const int linesFudge = 2; #else const int linesFudge = 1; #endif // title metadataLayout_->addWidget(titleLabel_); QFont titleFont = applicationFont; titleFont.setBold(true); titleFont.setPointSize(titleFontSize_); titleEdit_->setFont(titleFont); titleEdit_->setFixedWidth(inputFieldWidth); // TODO these fudges are probably not portable or lasting (then again, // what are the correct QT magic incantations to compute all of the // paddings, margins, frames, etc, and how often will they change?) const int lineHeightFudge = 8; const int comboBoxWidthFudge = 100; titleEdit_->setFixedHeight(linesFudge*QFontMetrics(titleFont).lineSpacing() + lineHeightFudge); metadataLayout_->addWidget(titleEdit_); metadataLayout_->addSpacing(20); // patternBy metadataLayout_->addWidget(patternByLabel_); QFont patternByFont = applicationFont; patternByFont.setPointSize(patternByFontSize_); patternByEdit_->setFont(patternByFont); patternByEdit_->setFixedWidth(inputFieldWidth); patternByEdit_-> setFixedHeight(linesFudge*linesToKeep_*QFontMetrics(patternByFont).lineSpacing() + lineHeightFudge); connect(patternByLicenseButton_, SIGNAL(clicked()), this, SLOT(insertPatternByLicense())); // unfortunately patternByLicenseButton_ doesn't know its width yet, // so we have to just approximate patternByLicenses_->setFixedWidth(inputFieldWidth - comboBoxWidthFudge); loadLicenses(patternByLicenses_, patternByFont, false); metadataLayout_->addWidget(patternByEdit_); patternByLicenseLayout_->addWidget(patternByLicenseButton_, 0, Qt::AlignLeft); patternByLicenseLayout_->addWidget(patternByLicenses_, 1, Qt::AlignLeft); metadataLayout_->addLayout(patternByLicenseLayout_); metadataLayout_->addSpacing(20); // photoBy metadataLayout_->addWidget(photoByLabel_); QFont photoByFont = applicationFont; photoByFont.setPointSize(photoByFontSize_); photoByEdit_->setFont(photoByFont); photoByEdit_->setFixedWidth(inputFieldWidth); photoByEdit_-> setFixedHeight(linesFudge*linesToKeep_*QFontMetrics(photoByFont).lineSpacing() + lineHeightFudge); connect(photoByLicenseButton_, SIGNAL(clicked()), this, SLOT(insertPhotoByLicense())); // unfortunately photobyLicenseButton_ doesn't know its width yet, // so we have to just approximate photoByLicenses_->setFixedWidth(inputFieldWidth - comboBoxWidthFudge); loadLicenses(photoByLicenses_, photoByFont, true); metadataLayout_->addWidget(photoByEdit_); photoByLicenseLayout_->addWidget(photoByLicenseButton_, 0, Qt::AlignLeft); photoByLicenseLayout_->addWidget(photoByLicenses_, 1, Qt::AlignLeft); metadataLayout_->addLayout(photoByLicenseLayout_); connect(clearMetadataButton_, SIGNAL(clicked()), this, SLOT(clearMetadata())); metadataLayout_->addWidget(clearMetadataButton_); metadataBox_->setLayout(metadataLayout_); widgetLayout_->addWidget(metadataBox_); setLayout(widgetLayout_); // load any saved fields const QSettings settings("cstitch", "cstitch"); loadSettings(settings, titleSettingsKey_, titleEdit_); loadSettings(settings, patternBySettingsKey_, patternByEdit_); loadSettings(settings, photoBySettingsKey_, photoByEdit_); constructSymbolPreview(settings); widgetLayout_->addWidget(cancelAcceptWidget()); titleEdit_->setFocus(); setWindowTitle(tr("Pattern information")); }