gint _lf_lens_name_compare (const lfLens *i1, const lfLens *i2) { int cmp = _lf_strcmp (i1->Maker, i2->Maker); if (cmp != 0) return cmp; return _lf_strcmp (i1->Model, i2->Model); }
gint _lf_camera_compare (gconstpointer a, gconstpointer b) { lfCamera *i1 = (lfCamera *)a; lfCamera *i2 = (lfCamera *)b; int cmp = _lf_strcmp (i1->Maker, i2->Maker); if (cmp != 0) return cmp; cmp = _lf_strcmp (i1->Model, i2->Model); if (cmp != 0) return cmp; return _lf_strcmp (i1->Variant, i2->Variant); }
gint _lf_mount_compare (gconstpointer a, gconstpointer b) { lfMount *i1 = (lfMount *)a; lfMount *i2 = (lfMount *)b; return _lf_strcmp (i1->Name, i2->Name); }
gint _lf_lens_compare (gconstpointer a, gconstpointer b) { lfLens *i1 = (lfLens *)a; lfLens *i2 = (lfLens *)b; int cmp = _lf_lens_name_compare (i1, i2); if (cmp != 0) return cmp; for (int i = 0; i1->Mounts [i] || i2->Mounts [i]; i++) { cmp = _lf_strcmp (i1->Mounts [i], i2->Mounts [i]); if (cmp != 0) return cmp; } cmp = _lf_lens_parameters_compare (i1, i2); if (cmp != 0) return cmp; cmp = int ((i1->CropFactor - i2->CropFactor) * 100); if (cmp != 0) return cmp; return int ((i1->AspectRatio - i2->AspectRatio) * 100); }
static void _lf_add_compat_mounts ( const lfDatabase *This, const lfLens *lens, GPtrArray *mounts, char *mount) { const lfMount *m = This->FindMount (mount); if (m && m->Compat) for (int i = 0; m->Compat [i]; i++) { mount = m->Compat [i]; int idx = _lf_ptr_array_find_sorted (mounts, mount, (GCompareFunc)_lf_strcmp); if (idx >= 0) continue; // mount already in the list // Check if the mount is not already in the main list bool already = false; for (int j = 0; lens->Mounts [j]; j++) if (!_lf_strcmp (mount, lens->Mounts [j])) { already = true; break; } if (!already) _lf_ptr_array_insert_sorted (mounts, mount, (GCompareFunc)_lf_strcmp); } }
static gint __find_camera_compare (gconstpointer a, gconstpointer b) { lfCamera *i1 = (lfCamera *)a; lfCamera *i2 = (lfCamera *)b; if (i1->Maker && i2->Maker) { int cmp = _lf_strcmp (i1->Maker, i2->Maker); if (cmp != 0) return cmp; } if (i1->Model && i2->Model) return _lf_strcmp (i1->Model, i2->Model); return 0; }
gint _lf_lens_compare (gconstpointer a, gconstpointer b) { int i; lfLens *i1 = (lfLens *)a; lfLens *i2 = (lfLens *)b; int cmp = _lf_strcmp (i1->Maker, i2->Maker); if (cmp != 0) return cmp; cmp = _lf_strcmp (i1->Model, i2->Model); if (cmp != 0) return cmp; for (i = 0; i1->Mounts [i] || i2->Mounts [i]; i++) { cmp = _lf_strcmp (i1->Mounts [i], i2->Mounts [i]); if (cmp != 0) return cmp; } cmp = int ((i1->MinFocal - i2->MinFocal) * 100); if (cmp != 0) return cmp; cmp = int ((i1->MaxFocal - i2->MaxFocal) * 100); if (cmp != 0) return cmp; cmp = int ((i1->MinAperture - i2->MinAperture) * 100); if (cmp != 0) return cmp; // MaxAperture is usually not given in database... // so it's a guessed value, often incorrect. //cmp = int ((i1->MaxAperture - i2->MaxAperture) * 100); //if (cmp != 0) // return cmp; return int ((i1->CropFactor - i2->CropFactor) * 100); }
gint _lf_lens_compare (gconstpointer a, gconstpointer b) { int i; lfLens *i1 = (lfLens *)a; lfLens *i2 = (lfLens *)b; int cmp = _lf_strcmp (i1->Maker, i2->Maker); if (cmp != 0) return cmp; cmp = _lf_strcmp (i1->Model, i2->Model); if (cmp != 0) return cmp; for (i = 0; i1->Mounts [i] || i2->Mounts [i]; i++) { cmp = _lf_strcmp (i1->Mounts [i], i2->Mounts [i]); if (cmp != 0) return cmp; } cmp = int ((i1->MinFocal - i2->MinFocal) * 100); if (cmp != 0) return cmp; cmp = int ((i1->MaxFocal - i2->MaxFocal) * 100); if (cmp != 0) return cmp; cmp = int ((i1->MinAperture - i2->MinAperture) * 100); if (cmp != 0) return cmp; cmp = int ((i1->MaxAperture - i2->MaxAperture) * 100); if (cmp != 0) return cmp; return int ((i1->CropFactor - i2->CropFactor) * 100); }
int _lf_lens_compare_score (const lfLens *pattern, const lfLens *match, lfFuzzyStrCmp *fuzzycmp, const char **compat_mounts) { int score = 0; // Compare numeric fields first since that's easy. if (pattern->Type != LF_UNKNOWN) if (pattern->Type != match->Type) return 0; if (pattern->CropFactor > 0.01 && pattern->CropFactor < match->CropFactor * 0.96) return 0; if (pattern->CropFactor >= match->CropFactor * 1.41) score += 2; else if (pattern->CropFactor >= match->CropFactor * 1.31) score += 4; else if (pattern->CropFactor >= match->CropFactor * 1.21) score += 6; else if (pattern->CropFactor >= match->CropFactor * 1.11) score += 8; else if (pattern->CropFactor >= match->CropFactor * 1.01) score += 10; else if (pattern->CropFactor >= match->CropFactor) score += 5; else if (pattern->CropFactor >= match->CropFactor * 0.96) score += 3; switch (_lf_compare_num (pattern->MinFocal, match->MinFocal)) { case -1: return 0; case +1: score += 10; break; } switch (_lf_compare_num (pattern->MaxFocal, match->MaxFocal)) { case -1: return 0; case +1: score += 10; break; } switch (_lf_compare_num (pattern->MinAperture, match->MinAperture)) { case -1: return 0; case +1: score += 10; break; } switch (_lf_compare_num (pattern->MaxAperture, match->MaxAperture)) { case -1: return 0; case +1: score += 10; break; } switch (_lf_compare_num (pattern->AspectRatio, match->AspectRatio)) { case -1: return 0; case +1: score += 10; break; } // Check the lens mount, if specified if (match->Mounts) { int old_score = score; if (compat_mounts && !compat_mounts [0]) compat_mounts = NULL; if (pattern->Mounts) { int nm = 0; for (int i = 0; pattern->Mounts [i]; i++) for (int j = 0; match->Mounts [j]; j++) if (!_lf_strcmp (pattern->Mounts [i], match->Mounts [j])) { nm++; break; } if (nm) { // Count number of mounts in the match lens int match_nm; for (match_nm = 0; match->Mounts [match_nm]; match_nm++) ; // Don't allow 0 score, make it at least 1 int _score = (nm * 20) / match_nm; if (!_score) _score = 1; score += _score; } } if (compat_mounts) { int nm = 0; for (int i = 0; compat_mounts [i]; i++) for (int j = 0; match->Mounts [j]; j++) if (!_lf_strcmp (compat_mounts [i], match->Mounts [j])) { nm++; break; } if (nm) { // Count number of compatible mounts in the match lens int match_nm; for (match_nm = 0; compat_mounts [match_nm]; match_nm++) ; // Don't allow 0 score, make it at least 1 int _score = (nm * 10) / match_nm; if (!_score) _score = 1; score += _score; } } // If there were no mount matches, fail the comparison if (old_score == score && (pattern->Mounts || compat_mounts)) return 0; } // If maker is specified, check it using our patented _lf_strcmp(tm) technology if (pattern->Maker && match->Maker) { if (_lf_mlstrcmp (pattern->Maker, match->Maker) != 0) return 0; // Bah! different maker. else score += 10; // Good doggy, here's a cookie } // And now the most complex part - compare models if (pattern->Model && match->Model) { int _score = fuzzycmp->Compare (match->Model); if (!_score) return 0; // Model does not match _score = (_score * 4) / 10; if (!_score) _score = 1; score += _score; } return score; }
static void _xml_text (GMarkupParseContext *context, const gchar *text, gsize text_len, gpointer user_data, GError **error) { lfParserData *pd = (lfParserData *)user_data; const gchar *ctx = g_markup_parse_context_get_element (context); while (*text && strchr (" \t\n\r", *text)) text++; if (!*text) goto leave; if (!strcmp (ctx, "name")) { if (pd->mount) pd->mount->SetName (text, pd->lang); else { bad_ctx: g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "Wrong context for element <%.*s>\n", int (text_len), text); goto leave; } } else if (!strcmp (ctx, "maker")) { if (pd->camera) pd->camera->SetMaker (text, pd->lang); else if (pd->lens) pd->lens->SetMaker (text, pd->lang); else goto bad_ctx; } else if (!strcmp (ctx, "model")) { if (pd->camera) pd->camera->SetModel (text, pd->lang); else if (pd->lens) pd->lens->SetModel (text, pd->lang); else goto bad_ctx; } else if (!strcmp (ctx, "variant")) { if (pd->camera) pd->camera->SetVariant (text, pd->lang); else goto bad_ctx; } else if (!strcmp (ctx, "mount")) { if (pd->camera) pd->camera->SetMount (text); else if (pd->lens) pd->lens->AddMount (text); else goto bad_ctx; } else if (!strcmp (ctx, "compat")) { if (pd->mount) pd->mount->AddCompat (text); else goto bad_ctx; } else if (!strcmp (ctx, "cropfactor")) { if (pd->camera) pd->camera->CropFactor = atof (text); else if (pd->lens) pd->lens->CropFactor = atof (text); else goto bad_ctx; } else if (!strcmp (ctx, "type")) { if (pd->lens) { if (!_lf_strcmp (text, "rectilinear")) pd->lens->Type = LF_RECTILINEAR; else if (!_lf_strcmp (text, "fisheye")) pd->lens->Type = LF_FISHEYE; else if (!_lf_strcmp (text, "panoramic")) pd->lens->Type = LF_PANORAMIC; else if (!_lf_strcmp (text, "equirectangular")) pd->lens->Type = LF_EQUIRECTANGULAR; else { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "Invalid lens type `%s' (%s/%s)\n", text, pd->camera ? pd->camera->Maker : "???", pd->camera ? pd->camera->Model : "???"); return; } } else goto bad_ctx; } leave: lf_free (pd->lang); pd->lang = NULL; }