bool isXmpType(BasicIo& iIo, bool advance) { /* Check if the file starts with an optional XML declaration followed by either an XMP header (<?xpacket ... ?>) or an <x:xmpmeta> element. In addition, in order for empty XmpSidecar objects as created by Exiv2 to pass the test, just an XML header is also considered ok. */ const int32_t len = 80; byte buf[len]; iIo.read(buf, xmlHdrCnt + 1); if ( iIo.eof() && 0 == strncmp(reinterpret_cast<const char*>(buf), xmlHeader, xmlHdrCnt)) { return true; } if (iIo.error() || iIo.eof()) { return false; } iIo.read(buf + xmlHdrCnt + 1, len - xmlHdrCnt - 1); if (iIo.error() || iIo.eof()) { return false; } // Skip leading BOM int32_t start = 0; if (0 == strncmp(reinterpret_cast<const char*>(buf), "\xef\xbb\xbf", 3)) { start = 3; } bool rc = false; std::string head(reinterpret_cast<const char*>(buf + start), len - start); if (head.substr(0, 5) == "<?xml") { // Forward to the next tag for (unsigned i = 5; i < head.size(); ++i) { if (head[i] == '<') { head = head.substr(i); break; } } } if ( head.size() > 9 && ( head.substr(0, 9) == "<?xpacket" || head.substr(0, 10) == "<x:xmpmeta")) { rc = true; } if (!advance || !rc) { iIo.seek(-(len - start), BasicIo::cur); // Swallow the BOM } return rc; }
bool isTgaType(BasicIo& iIo, bool /*advance*/) { // not all TARGA files have a signature string, so first just try to match the file name extension std::string path = iIo.path(); if(path.rfind(".tga") != std::string::npos || path.rfind(".TGA") != std::string::npos) { return true; } byte buf[26]; long curPos = iIo.tell(); iIo.seek(-26, BasicIo::end); if (iIo.error() || iIo.eof()) { return false; } iIo.read(buf, sizeof(buf)); if (iIo.error()) { return false; } // some TARGA files, but not all, have a signature string at the end bool matched = (memcmp(buf + 8, "TRUEVISION-XFILE", 16) == 0); iIo.seek(curPos, BasicIo::beg); return matched; }
bool isXmpType(BasicIo& iIo, bool advance) { /* Make sure the file starts with and (optional) XML declaration, followed by an XMP header (<?xpacket ... ?>) or an <x:xmpmeta> element. That doesn't cover all cases, since also x:xmpmeta is optional, but let's wait and see. */ // Todo: Proper implementation const int32_t len = 10; byte buf[len]; iIo.read(buf, len); if (iIo.error() || iIo.eof()) { return false; } bool rc = false; const std::string head(reinterpret_cast<const char*>(buf), len); if ( head.substr(0, 5) == "<?xml" || head.substr(0, 9) == "<?xpacket" || head.substr(0, 10) == "<x:xmpmeta") { rc = true; } if (!advance || !rc) { iIo.seek(-len, BasicIo::cur); } return rc; }
bool isJpegType(BasicIo& iIo, bool advance) { bool result = true; byte tmpBuf[2]; iIo.read(tmpBuf, 2); if (iIo.error() || iIo.eof()) return false; if (0xff != tmpBuf[0] || JpegImage::soi_ != tmpBuf[1]) { result = false; } if (!advance || !result ) iIo.seek(-2, BasicIo::cur); return result; }
bool isMrwType(BasicIo& iIo, bool advance) { const int32_t len = 4; byte buf[len]; iIo.read(buf, len); if (iIo.error() || iIo.eof()) { return false; } int rc = memcmp(buf, "\0MRM", 4); if (!advance || rc != 0) { iIo.seek(-len, BasicIo::cur); } return rc == 0; }
bool isExvType(BasicIo& iIo, bool advance) { bool result = true; byte tmpBuf[7]; iIo.read(tmpBuf, 7); if (iIo.error() || iIo.eof()) return false; if ( 0xff != tmpBuf[0] || 0x01 != tmpBuf[1] || memcmp(tmpBuf + 2, ExvImage::exiv2Id_, 5) != 0) { result = false; } if (!advance || !result) iIo.seek(-7, BasicIo::cur); return result; }
bool isOrfType(BasicIo& iIo, bool advance) { const int32_t len = 8; byte buf[len]; iIo.read(buf, len); if (iIo.error() || iIo.eof()) { return false; } OrfHeader orfHeader; bool rc = orfHeader.read(buf, len); if (!advance || !rc) { iIo.seek(-len, BasicIo::cur); } return rc; }
bool isJp2Type(BasicIo& iIo, bool advance) { const int32_t len = 12; byte buf[len]; iIo.read(buf, len); if (iIo.error() || iIo.eof()) { return false; } bool matched = (memcmp(buf, Jp2Signature, len) == 0); if (!advance || !matched) { iIo.seek(-len, BasicIo::cur); } return matched; }
bool isPgfType(BasicIo& iIo, bool advance) { const int32_t len = 3; byte buf[len]; iIo.read(buf, len); if (iIo.error() || iIo.eof()) { return false; } int rc = memcmp(buf, pgfSignature, 3); if (!advance || rc != 0) { iIo.seek(-len, BasicIo::cur); } return rc == 0; }
bool isBmpType(BasicIo& iIo, bool advance) { const int32_t len = 2; const unsigned char BmpImageId[2] = { 'B', 'M' }; byte buf[len]; iIo.read(buf, len); if (iIo.error() || iIo.eof()) { return false; } bool matched = (memcmp(buf, BmpImageId, len) == 0); if (!advance || !matched) { iIo.seek(-len, BasicIo::cur); } return matched; }
bool isAsfType(BasicIo& iIo, bool advance) { const int32_t len = 16; byte buf[len]; iIo.read(buf, len); if (iIo.error() || iIo.eof()) { return false; } bool matched = isASFType(buf); if (!advance || !matched) { iIo.seek(0, BasicIo::beg); } return matched; }
bool isPsdType(BasicIo& iIo, bool advance) { const int32_t len = 6; const unsigned char PsdHeader[6] = { '8', 'B', 'P', 'S', 0, 1 }; byte buf[len]; iIo.read(buf, len); if (iIo.error() || iIo.eof()) { return false; } bool matched = (memcmp(buf, PsdHeader, len) == 0); if (!advance || !matched) { iIo.seek(-len, BasicIo::cur); } return matched; }
bool isCrwType(BasicIo& iIo, bool advance) { bool result = true; byte tmpBuf[14]; iIo.read(tmpBuf, 14); if (iIo.error() || iIo.eof()) { return false; } if (!( ('I' == tmpBuf[0] && 'I' == tmpBuf[1]) || ('M' == tmpBuf[0] && 'M' == tmpBuf[1]))) { result = false; } if ( true == result && std::memcmp(tmpBuf + 6, CiffHeader::signature_, 8) != 0) { result = false; } if (!advance || !result) iIo.seek(-14, BasicIo::cur); return result; }
bool isGifType(BasicIo& iIo, bool advance) { const int32_t len = 6; const unsigned char Gif87aId[8] = { 'G', 'I', 'F', '8', '7', 'a' }; const unsigned char Gif89aId[8] = { 'G', 'I', 'F', '8', '9', 'a' }; byte buf[len]; iIo.read(buf, len); if (iIo.error() || iIo.eof()) { return false; } bool matched = (memcmp(buf, Gif87aId, len) == 0) || (memcmp(buf, Gif89aId, len) == 0); if (!advance || !matched) { iIo.seek(-len, BasicIo::cur); } return matched; }