count++;
byte buf[count * MAX_ATTR_SIZE], *b = buf;
for (; a; a = a->same)
- b += base224_decode(buf, a->val, strlen(a->val));
+ b += base224_decode(b, a->val, strlen(a->val));
ASSERT(b != buf);
ioi->thumb_data = mp_alloc(pool, ioi->thumb_size = b - buf);
memcpy(ioi->thumb_data, buf, ioi->thumb_size);
put_image_obj_signature(struct odes *o, struct image_signature *sig)
{
/* signatures should be short enough to fit one attribute */
- ASSERT(MAX_ATTR_SIZE > BASE224_ENC_LENGTH(sizeof(struct image_vector) + 4 + sig->len * sizeof(struct image_region)));
- byte buf[MAX_ATTR_SIZE], *b = buf;
- memcpy(b, &sig->vec, sizeof(struct image_vector));
- b += sizeof(struct image_vector);
- *b++ = sig->len;
- *b++ = sig->df;
- *(u16 *)b++ = sig->dh;
- for (uns i = 0; i < sig->len; i++)
- {
- memcpy(b, sig->reg + i, sizeof(struct image_region));
- b += sizeof(struct image_region);
- }
- uns len = b - buf;
- byte b224[MAX_ATTR_SIZE];
- b224[base224_encode(b224, buf, len)] = 0;
- obj_set_attr(o, 'H', b224);
+ byte buf[MAX_ATTR_SIZE];
+ uns size = image_signature_size(sig->len);
+ ASSERT(MAX_ATTR_SIZE > BASE224_ENC_LENGTH(size));
+ buf[base224_encode(buf, (byte *)sig, size)] = 0;
+ obj_set_attr(o, 'H', buf);
+}
+
+uns
+get_image_obj_signature(struct image_signature *sig, struct odes *o)
+{
+ byte *a = obj_find_aval(o, 'H');
+ if (!a)
+ return 0;
+ UNUSED uns size = base224_decode((byte *)sig, a, strlen(a));
+ ASSERT(size == image_signature_size(sig->len));
+ return 1;
}
uns get_image_obj_thumb(struct image_obj_info *ioi, struct odes *o, struct mempool *pool);
struct image *read_image_obj_thumb(struct image_obj_info *ioi, struct fastbuf *fb, struct image_io *io, struct mempool *pool);
void put_image_obj_signature(struct odes *o, struct image_signature *sig);
+uns get_image_obj_signature(struct image_signature *sig, struct odes *o);
#endif
static double image_sig_inertia_scale[3] = { 3, 1, 0.3 };
-void
-bget_image_signature(struct fastbuf *fb, struct image_signature *sig)
-{
- breadb(fb, &sig->vec, sizeof(sig->vec));
- sig->len = bgetc(fb);
- breadb(fb, sig->reg, sig->len * sizeof(*sig->reg));
-}
-
-void
-bput_image_signature(struct fastbuf *fb, struct image_signature *sig)
-{
- bwrite(fb, &sig->vec, sizeof(sig->vec));
- bputc(fb, sig->len);
- bwrite(fb, sig->reg, sig->len * sizeof(*sig->reg));
-}
-
struct block {
u32 l, u, v; /* average Luv coefficients */
u32 lh, hl, hh; /* energies in Daubechies wavelet bands */
#define IMAGE_REG_H 3
#define IMAGE_REG_MAX 8
-/* K-dimensional feature vector */
+/* K-dimensional feature vector (6 bytes) */
struct image_vector {
byte f[IMAGE_VEC_F]; /* texture features */
} PACKED;
-/* Fetures for image regions */
+/* Fetures for image regions (16 bytes) */
struct image_region {
byte f[IMAGE_VEC_F]; /* texture features */
u16 h[IMAGE_REG_H]; /* shape features */
- byte wa; /* normalized area percentage */
- byte wb; /* normalized weight */
+ u16 wa; /* normalized area percentage */
+ u16 wb; /* normalized weight */
} PACKED;
-/* Image signature */
+/* Image signature (10 + len * 16 bytes) */
struct image_signature {
- struct image_vector vec; /* Combination of all regions... simple signature */
byte len; /* Number of regions */
byte df; /* average f dist */
u16 dh; /* average h dist */
+ struct image_vector vec; /* Combination of all regions... simple signature */
struct image_region reg[IMAGE_REG_MAX];/* Feature vector for every region */
-};
+} PACKED;
+
+static inline uns
+image_signature_size(uns len)
+{
+ return 4 + sizeof(struct image_vector) + len * sizeof(struct image_region);
+}
/* sig-dump.c */
/* sig-init.c */
-void bget_image_signature(struct fastbuf *fb, struct image_signature *sig);
-void bput_image_signature(struct fastbuf *fb, struct image_signature *sig);
int compute_image_signature(struct image_thread *thread, struct image_signature *sig, struct image *image);
/* sig-cmp.c */