Skip to content

Commit

Permalink
Allow searching images by IQDB hash.
Browse files Browse the repository at this point in the history
Allow clients to pass a `hash` param to search by IQDB hash. This way
clients can search for hashes they've generated themselves, instead of
having to send full images to IQDB.
  • Loading branch information
evazion committed Jun 11, 2021
1 parent 8b733fe commit ba1a1d2
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 5 deletions.
1 change: 1 addition & 0 deletions include/iqdb/haar_signature.h
Expand Up @@ -15,6 +15,7 @@ struct HaarSignature {

HaarSignature() {};
explicit HaarSignature(lumin_t avglf, signature_t sig);
static HaarSignature from_hash(const std::string hash);
static HaarSignature from_file_content(const std::string blob);

std::string to_string() const;
Expand Down
23 changes: 23 additions & 0 deletions src/haar_signature.cpp
Expand Up @@ -18,6 +18,29 @@ HaarSignature::HaarSignature(lumin_t avglf_, signature_t sig_) {
std::sort(&sig[2][0], &sig[2][NUM_COEFS]);
}

HaarSignature HaarSignature::from_hash(const std::string hash) {
if (hash.size() != 5 + 2*sizeof(HaarSignature)) {
throw param_error("Invalid hash (hash=" + hash + ")");
}

HaarSignature haar;
const char* p = hash.c_str() + 5; // skip "iqdb_" prefix

for (double& avglf : haar.avglf) {
sscanf(p, "%16lx", reinterpret_cast<uint64_t*>(&avglf));
p += 2 * sizeof(uint64_t);
}

for (int c = 0; c < 3; c++) {
for (int16_t& coef : haar.sig[c]) {
sscanf(p, "%4hx", &coef);
p += 2 * sizeof(int16_t);
}
}

return haar;
}

HaarSignature HaarSignature::from_file_content(const std::string blob) {
HaarSignature signature;
std::vector<unsigned char> rchan(NUM_PIXELS * NUM_PIXELS);
Expand Down
16 changes: 11 additions & 5 deletions src/server.cpp
Expand Up @@ -104,16 +104,22 @@ void http_server(const std::string host, const int port, const std::string datab
std::shared_lock lock(mutex_);

int limit = 10;
sim_vector matches;
json data;

if (!request.has_file("file"))
throw imgdb::param_error("`POST /query` requires a `file` param");

if (request.has_param("limit"))
limit = stoi(request.get_param_value("limit"));

const auto &file = request.get_file_value("file");
const auto matches = memory_db->queryFromBlob(file.content, limit);
if (request.has_param("hash")) {
const auto hash = request.get_param_value("hash");
HaarSignature haar = HaarSignature::from_hash(hash);
matches = memory_db->queryFromSignature(haar, limit);
} else if (request.has_file("file")) {
const auto &file = request.get_file_value("file");
matches = memory_db->queryFromBlob(file.content, limit);
} else {
throw param_error("`POST /query` requires a `file` or `hash` param");
}

for (const auto &match : matches) {
auto image = memory_db->getImage(match.id);
Expand Down

0 comments on commit ba1a1d2

Please sign in to comment.