[Fingerforce-commits] [libfprint] 03/11: aeslib: improve frame-assembling routines

Didier Raboud odyx at moszumanska.debian.org
Sun Apr 12 09:42:01 UTC 2015


This is an automated email from the git hooks/post-receive script.

odyx pushed a commit to branch debian
in repository libfprint.

commit 061a457658f1b39fe04ceb3c104c46b19a13799f
Author: Vasily Khoruzhick <anarsoul at gmail.com>
Date:   Mon Dec 30 12:07:53 2013 +0300

    aeslib: improve frame-assembling routines
    
    Some scanners provide hardware assistance in frame assemling, i.e.
    horizontal and vertical offset to previous frame is provided. This
    commit improves code to utilise that assistance. Sensors without
    hardware assistance will use software algorithm, which was also
    improved to do search in horizontal direction.
---
 libfprint/aeslib.c          | 327 +++++++++++++++++++++++++++++++-------------
 libfprint/aeslib.h          |  13 +-
 libfprint/drivers/aes1610.c |  21 ++-
 libfprint/drivers/aes1660.c |   4 +-
 libfprint/drivers/aes2501.c |  22 ++-
 libfprint/drivers/aes2550.c |  17 ++-
 libfprint/drivers/aes2660.c |   3 +-
 libfprint/drivers/aes3k.c   |  16 ++-
 libfprint/drivers/aesx660.c |  23 ++--
 libfprint/drivers/aesx660.h |   3 +
 10 files changed, 320 insertions(+), 129 deletions(-)

diff --git a/libfprint/aeslib.c b/libfprint/aeslib.c
index 00ddfd9..8c0381a 100644
--- a/libfprint/aeslib.c
+++ b/libfprint/aeslib.c
@@ -158,127 +158,268 @@ void aes_write_regv(struct fp_img_dev *dev, const struct aes_regwrite *regs,
 	continue_write_regv(wdata);
 }
 
-void aes_assemble_image(unsigned char *input, size_t width, size_t height,
-	unsigned char *output)
+static inline unsigned char aes_get_pixel(struct aes_stripe *frame,
+					  unsigned int x,
+					  unsigned int y,
+					  unsigned int frame_width,
+					  unsigned int frame_height)
 {
-	size_t row, column;
+	unsigned char ret;
 
-	for (column = 0; column < width; column++) {
-		for (row = 0; row < height; row += 2) {
-			output[width * row + column] = (*input & 0x0f) * 17;
-			output[width * (row + 1) + column] = ((*input & 0xf0) >> 4) * 17;
-			input++;
-		}
-	}
+	ret = frame->data[x * (frame_height >> 1) + (y >> 1)];
+	ret = y % 2 ? ret >> 4 : ret & 0xf;
+	ret *= 17;
+
+	return ret;
 }
 
-/* find overlapping parts of  frames */
-static unsigned int find_overlap(unsigned char *first_frame,
-	unsigned char *second_frame, unsigned int *min_error,
-	unsigned int frame_width, unsigned int frame_height)
+static unsigned int calc_error(struct aes_stripe *first_frame,
+			       struct aes_stripe *second_frame,
+			       int dx,
+			       int dy,
+			       unsigned int frame_width,
+			       unsigned int frame_height)
 {
-	unsigned int dy;
-	unsigned int not_overlapped_height = 0;
-	/* 255 is highest brightness value for an 8bpp image */
-	*min_error = 255 * frame_width * frame_height;
-	for (dy = 0; dy < frame_height; dy++) {
-		/* Calculating difference (error) between parts of frames */
-		unsigned int i;
-		unsigned int error = 0;
-		for (i = 0; i < frame_width * (frame_height - dy); i++) {
-			/* Using ? operator to avoid abs function */
-			error += first_frame[i] > second_frame[i] ?
-					(first_frame[i] - second_frame[i]) :
-					(second_frame[i] - first_frame[i]);
-		}
+	unsigned int width, height;
+	unsigned int x1, y1, x2, y2, err, i, j;
+
+	width = frame_width - (dx > 0 ? dx : -dx);
+	height = frame_height - dy;
+
+	y1 = 0;
+	y2 = dy;
+	i = 0;
+	err = 0;
+	do {
+		x1 = dx < 0 ? 0 : dx;
+		x2 = dx < 0 ? -dx : 0;
+		j = 0;
+
+		do {
+			unsigned char v1, v2;
+
+
+			v1 = aes_get_pixel(first_frame, x1, y1, frame_width, frame_height);
+			v2 = aes_get_pixel(second_frame, x2, y2, frame_width, frame_height);
+			err += v1 > v2 ? v1 - v2 : v2 - v1;
+			j++;
+			x1++;
+			x2++;
+
+		} while (j < width);
+		i++;
+		y1++;
+		y2++;
+	} while (i < height);
+
+	/* Normalize error */
+	err *= (frame_height * frame_width);
+	err /= (height * width);
+
+	if (err == 0)
+		return INT_MAX;
+
+	return err;
+}
 
-		/* Normalize error */
-		error *= 15;
-		error /= i;
-		if (error < *min_error) {
-			*min_error = error;
-			not_overlapped_height = dy;
+/* This function is rather CPU-intensive. It's better to use hardware
+ * to detect movement direction when possible.
+ */
+static void find_overlap(struct aes_stripe *first_frame,
+			 struct aes_stripe *second_frame,
+			 unsigned int *min_error,
+			 unsigned int frame_width,
+			 unsigned int frame_height)
+{
+	int dx, dy;
+	unsigned int err;
+	*min_error = INT_MAX;
+
+	/* Seeking in horizontal and vertical dimensions,
+	 * for horizontal dimension we'll check only 8 pixels
+	 * in both directions. For vertical direction diff is
+	 * rarely less than 2, so start with it.
+	 */
+	for (dy = 2; dy < frame_height; dy++) {
+		for (dx = -8; dx < 8; dx++) {
+			err = calc_error(first_frame, second_frame,
+				dx, dy, frame_width, frame_height);
+			if (err < *min_error) {
+				*min_error = err;
+				second_frame->delta_x = -dx;
+				second_frame->delta_y = dy;
+			}
 		}
-		first_frame += frame_width;
 	}
-
-	return not_overlapped_height;
 }
 
-/* assemble a series of frames into a single image */
-static unsigned int assemble(GSList *list_entry, size_t num_stripes,
+unsigned int aes_calc_delta(GSList *stripes, size_t num_stripes,
 	unsigned int frame_width, unsigned int frame_height,
-	unsigned char *output, gboolean reverse, unsigned int *errors_sum)
+	gboolean reverse)
 {
-	uint8_t *assembled = output;
-	int frame;
-	uint32_t image_height = frame_height;
-	unsigned int min_error, frame_size = frame_width * frame_height;
-	*errors_sum = 0;
-
-	if (reverse)
-		output += (num_stripes - 1) * frame_size;
-	for (frame = 0; frame < num_stripes; frame++) {
-		aes_assemble_image(list_entry->data, frame_width, frame_height, output);
-
-		if (reverse)
-		    output -= frame_size;
+	GSList *list_entry = stripes;
+	GTimer *timer;
+	int frame = 1;
+	int height = 0;
+	struct aes_stripe *prev_stripe = list_entry->data;
+	unsigned int min_error;
+
+	list_entry = g_slist_next(list_entry);
+
+	timer = g_timer_new();
+	do {
+		struct aes_stripe *cur_stripe = list_entry->data;
+
+		if (reverse) {
+			find_overlap(prev_stripe, cur_stripe, &min_error,
+				frame_width, frame_height);
+			prev_stripe->delta_y = -prev_stripe->delta_y;
+			prev_stripe->delta_x = -prev_stripe->delta_x;
+		}
 		else
-		    output += frame_size;
+			find_overlap(cur_stripe, prev_stripe, &min_error,
+				frame_width, frame_height);
+
+		frame++;
+		height += prev_stripe->delta_y;
+		prev_stripe = cur_stripe;
 		list_entry = g_slist_next(list_entry);
+
+	} while (frame < num_stripes);
+
+	if (height < 0)
+		height = -height;
+	height += frame_height;
+	g_timer_stop(timer);
+	fp_dbg("calc delta completed in %f secs", g_timer_elapsed(timer, NULL));
+	g_timer_destroy(timer);
+
+	return height;
+}
+
+static inline void aes_blit_stripe(struct fp_img *img,
+				   struct aes_stripe *stripe,
+				   int x, int y, unsigned int frame_width,
+				   unsigned int frame_height)
+{
+	unsigned int ix, iy;
+	unsigned int fx, fy;
+	unsigned int width, height;
+
+	/* Find intersection */
+	if (x < 0) {
+		width = frame_width + x;
+		ix = 0;
+		fx = -x;
+	} else {
+		ix = x;
+		fx = 0;
+		width = frame_width;
 	}
+	if ((ix + width) > img->width)
+		width = img->width - ix;
 
-	/* Detecting where frames overlaped */
-	output = assembled;
-	for (frame = 1; frame < num_stripes; frame++) {
-		int not_overlapped;
-
-		output += frame_size;
-		not_overlapped = find_overlap(assembled, output, &min_error,
-			frame_width, frame_height);
-		*errors_sum += min_error;
-		image_height += not_overlapped;
-		assembled += frame_width * not_overlapped;
-		memcpy(assembled, output, frame_size);
+	if (y < 0) {
+		iy = 0;
+		fy = -y;
+		height = frame_height + y;
+	} else {
+		iy = y;
+		fy = 0;
+		height = frame_height;
+	}
+
+	if (fx > frame_width)
+		return;
+
+	if (fy > frame_height)
+		return;
+
+	if (ix > img->width)
+		return;
+
+	if (iy > img->height)
+		return;
+
+	if ((iy + height) > img->height)
+		height = img->height - iy;
+
+	for (; fy < height; fy++, iy++) {
+		if (x < 0) {
+			ix = 0;
+			fx = -x;
+		} else {
+			ix = x;
+			fx = 0;
+		}
+		for (; fx < width; fx++, ix++) {
+			img->data[ix + (iy * img->width)] = aes_get_pixel(stripe, fx, fy, frame_width, frame_height);
+		}
 	}
-	return image_height;
 }
 
 struct fp_img *aes_assemble(GSList *stripes, size_t stripes_len,
-	unsigned int frame_width, unsigned int frame_height)
+			    unsigned int frame_width, unsigned int frame_height, unsigned int img_width)
 {
-	size_t final_size;
+	GSList *stripe;
 	struct fp_img *img;
-	unsigned int frame_size = frame_width * frame_height;
-	unsigned int errors_sum, r_errors_sum;
+	int height = 0;
+	int i, y, x;
+	gboolean reverse = FALSE;
+	struct aes_stripe *aes_stripe;
 
 	BUG_ON(stripes_len == 0);
+	BUG_ON(img_width < frame_width);
 
-	/* create buffer big enough for max image */
-	img = fpi_img_new(stripes_len * frame_size);
+	/* Calculate height */
+	i = 0;
+	stripe = stripes;
 
-	img->flags = FP_IMG_COLORS_INVERTED;
-	img->height = assemble(stripes, stripes_len,
-		frame_width, frame_height,
-		img->data, FALSE, &errors_sum);
-	img->height = assemble(stripes, stripes_len,
-		frame_width, frame_height,
-		img->data, TRUE, &r_errors_sum);
-
-	if (r_errors_sum > errors_sum) {
-		img->height = assemble(stripes, stripes_len,
-			frame_width, frame_height,
-			img->data, FALSE, &errors_sum);
-		img->flags |= FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED;
-		fp_dbg("normal scan direction");
-	} else {
-		fp_dbg("reversed scan direction");
+	/* No offset for 1st image */
+	aes_stripe = stripe->data;
+	aes_stripe->delta_x = 0;
+	aes_stripe->delta_y = 0;
+	do {
+		aes_stripe = stripe->data;
+
+		height += aes_stripe->delta_y;
+		i++;
+		stripe = g_slist_next(stripe);
+	} while (i < stripes_len);
+
+	fp_dbg("height is %d", height);
+
+	if (height < 0) {
+		reverse = TRUE;
+		height = -height;
 	}
 
-	/* now that overlap has been removed, resize output image buffer */
-	final_size = img->height * frame_width;
-	img = fpi_img_resize(img, final_size);
-	img->width = frame_width;
+	/* For last frame */
+	height += frame_height;
+
+	/* Create buffer big enough for max image */
+	img = fpi_img_new(img_width * height);
+	img->flags = FP_IMG_COLORS_INVERTED;
+	img->width = img_width;
+	img->height = height;
+
+	/* Assemble stripes */
+	i = 0;
+	stripe = stripes;
+	y = reverse ? (height - frame_height) : 0;
+	x = (img_width - frame_width) / 2;
+
+	do {
+		aes_stripe = stripe->data;
+
+		y += aes_stripe->delta_y;
+		x += aes_stripe->delta_x;
+
+		aes_blit_stripe(img, aes_stripe, x, y, frame_width, frame_height);
+
+		stripe = g_slist_next(stripe);
+		i++;
+	} while (i < stripes_len);
 
 	return img;
 }
diff --git a/libfprint/aeslib.h b/libfprint/aeslib.h
index e366262..7721d11 100644
--- a/libfprint/aeslib.h
+++ b/libfprint/aeslib.h
@@ -27,17 +27,24 @@ struct aes_regwrite {
 	unsigned char value;
 };
 
+struct aes_stripe {
+	int delta_x;
+	int delta_y;
+	unsigned char data[0];
+};
+
 typedef void (*aes_write_regv_cb)(struct fp_img_dev *dev, int result,
 	void *user_data);
 
 void aes_write_regv(struct fp_img_dev *dev, const struct aes_regwrite *regs,
 	unsigned int num_regs, aes_write_regv_cb callback, void *user_data);
 
-void aes_assemble_image(unsigned char *input, size_t width, size_t height,
-	unsigned char *output);
+unsigned int aes_calc_delta(GSList *stripes, size_t stripes_len,
+	unsigned int frame_width, unsigned int frame_height,
+	gboolean reverse);
 
 struct fp_img *aes_assemble(GSList *stripes, size_t stripes_len,
-	unsigned int frame_width, unsigned int frame_height);
+	unsigned int frame_width, unsigned int frame_height, unsigned int img_width);
 
 #endif
 
diff --git a/libfprint/drivers/aes1610.c b/libfprint/drivers/aes1610.c
index 2e04c59..957d0f4 100644
--- a/libfprint/drivers/aes1610.c
+++ b/libfprint/drivers/aes1610.c
@@ -609,13 +609,24 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer)
 	/* stop capturing if MAX_FRAMES is reached */
 	if (aesdev->blanks_count > 10 || g_slist_length(aesdev->strips) >= MAX_FRAMES) {
 		struct fp_img *img;
+		unsigned int height, rev_height;
 
 		fp_dbg("sending stop capture.... blanks=%d  frames=%d", aesdev->blanks_count, g_slist_length(aesdev->strips));
 		/* send stop capture bits */
 		aes_write_regv(dev, capture_stop, G_N_ELEMENTS(capture_stop), stub_capture_stop_cb, NULL);
 		aesdev->strips = g_slist_reverse(aesdev->strips);
+		height = aes_calc_delta(aesdev->strips, aesdev->strips_len,
+			FRAME_WIDTH, FRAME_HEIGHT, FALSE);
+		rev_height = aes_calc_delta(aesdev->strips, aesdev->strips_len,
+			FRAME_WIDTH, FRAME_HEIGHT, TRUE);
+		fp_dbg("heights: %d rev: %d", height, rev_height);
+		if (rev_height < height) {
+			fp_dbg("Reversed direction");
+			height = aes_calc_delta(aesdev->strips, aesdev->strips_len,
+				FRAME_WIDTH, FRAME_HEIGHT, FALSE);
+		}
 		img = aes_assemble(aesdev->strips, aesdev->strips_len,
-			FRAME_WIDTH, FRAME_HEIGHT);
+			FRAME_WIDTH, FRAME_HEIGHT, FRAME_WIDTH + FRAME_WIDTH / 2);
 		g_slist_free_full(aesdev->strips, g_free);
 		aesdev->strips = NULL;
 		aesdev->strips_len = 0;
@@ -829,13 +840,9 @@ struct fp_img_driver aes1610_driver = {
 	},
 	.flags = 0,
 	.img_height = -1,
-	.img_width = 128,
+	.img_width = FRAME_WIDTH + FRAME_WIDTH / 2,
 
-	/* temporarily lowered until we sort out image processing code
-	 * binarized scan quality is good, minutiae detection is accurate,
-	 * it's just that we get fewer minutiae than other scanners (less scanning
-	 * area) */
-	.bz3_threshold = 10,
+	.bz3_threshold = 50,
 
 	.open = dev_init,
 	.close = dev_deinit,
diff --git a/libfprint/drivers/aes1660.c b/libfprint/drivers/aes1660.c
index d9ddc80..f931ba3 100644
--- a/libfprint/drivers/aes1660.c
+++ b/libfprint/drivers/aes1660.c
@@ -49,7 +49,6 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
 
 	dev->priv = aesdev = g_malloc0(sizeof(struct aesX660_dev));
 	aesdev->buffer = g_malloc0(AES1660_FRAME_SIZE + AESX660_HEADER_SIZE);
-	aesdev->h_scale_factor = SCALE_FACTOR;
 	aesdev->init_seqs[0] = aes1660_init_1;
 	aesdev->init_seqs_len[0] = array_n_elements(aes1660_init_1);
 	aesdev->init_seqs[1] = aes1660_init_2;
@@ -102,7 +101,8 @@ struct fp_img_driver aes1660_driver = {
 	},
 	.flags = 0,
 	.img_height = -1,
-	.img_width = FRAME_WIDTH * SCALE_FACTOR,
+	.img_width = FRAME_WIDTH + FRAME_WIDTH / 2,
+	.bz3_threshold = 70,
 
 	.open = dev_init,
 	.close = dev_deinit,
diff --git a/libfprint/drivers/aes2501.c b/libfprint/drivers/aes2501.c
index 75d19fc..264e2dc 100644
--- a/libfprint/drivers/aes2501.c
+++ b/libfprint/drivers/aes2501.c
@@ -481,10 +481,21 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer)
 		aesdev->no_finger_cnt++;
 		if (aesdev->no_finger_cnt == 3) {
 			struct fp_img *img;
+			unsigned int height, rev_height;
 
 			aesdev->strips = g_slist_reverse(aesdev->strips);
+			height = aes_calc_delta(aesdev->strips, aesdev->strips_len,
+				FRAME_WIDTH, FRAME_HEIGHT, FALSE);
+			rev_height = aes_calc_delta(aesdev->strips, aesdev->strips_len,
+				FRAME_WIDTH, FRAME_HEIGHT, TRUE);
+			fp_dbg("heights: %d rev: %d", height, rev_height);
+			if (rev_height < height) {
+				fp_dbg("Reversed direction");
+				height = aes_calc_delta(aesdev->strips, aesdev->strips_len,
+					FRAME_WIDTH, FRAME_HEIGHT, FALSE);
+			}
 			img = aes_assemble(aesdev->strips, aesdev->strips_len,
-				FRAME_WIDTH, FRAME_HEIGHT);
+				FRAME_WIDTH, FRAME_HEIGHT, FRAME_WIDTH + FRAME_WIDTH / 2);
 			g_slist_free_full(aesdev->strips, g_free);
 			aesdev->strips = NULL;
 			aesdev->strips_len = 0;
@@ -498,10 +509,13 @@ static void capture_read_strip_cb(struct libusb_transfer *transfer)
 	} else {
 		/* obtain next strip */
 		/* FIXME: would preallocating strip buffers be a decent optimization? */
-		stripdata = g_malloc(192 * 8);
+		struct aes_stripe *stripe = g_malloc(FRAME_WIDTH * FRAME_HEIGHT / 2 + sizeof(struct aes_stripe));
+		stripe->delta_x = 0;
+		stripe->delta_y = 0;
+		stripdata = stripe->data;
 		memcpy(stripdata, data + 1, 192*8);
 		aesdev->no_finger_cnt = 0;
-		aesdev->strips = g_slist_prepend(aesdev->strips, stripdata);
+		aesdev->strips = g_slist_prepend(aesdev->strips, stripe);
 		aesdev->strips_len++;
 
 		fpi_ssm_jump_to_state(ssm, CAPTURE_REQUEST_STRIP);
@@ -867,7 +881,7 @@ struct fp_img_driver aes2501_driver = {
 	},
 	.flags = 0,
 	.img_height = -1,
-	.img_width = 192,
+	.img_width = FRAME_WIDTH + FRAME_WIDTH / 2,
 
 	.open = dev_init,
 	.close = dev_deinit,
diff --git a/libfprint/drivers/aes2550.c b/libfprint/drivers/aes2550.c
index dcfbc82..29e59d1 100644
--- a/libfprint/drivers/aes2550.c
+++ b/libfprint/drivers/aes2550.c
@@ -204,6 +204,7 @@ static int process_strip_data(struct fpi_ssm *ssm, unsigned char *data)
 	unsigned char *stripdata;
 	struct fp_img_dev *dev = ssm->priv;
 	struct aes2550_dev *aesdev = dev->priv;
+	struct aes_stripe *stripe;
 	int len;
 
 	if (data[0] != AES2550_EDATA_MAGIC) {
@@ -214,11 +215,16 @@ static int process_strip_data(struct fpi_ssm *ssm, unsigned char *data)
 	if (len != (AES2550_STRIP_SIZE - 3)) {
 		fp_dbg("Bogus frame len: %.4x\n", len);
 	}
-	stripdata = g_malloc(FRAME_WIDTH * FRAME_HEIGHT / 2); /* 4 bits per pixel */
+	stripe = g_malloc(FRAME_WIDTH * FRAME_HEIGHT / 2 + sizeof(struct aes_stripe)); /* 4 bits per pixel */
+	stripe->delta_x = (int8_t)data[6];
+	stripe->delta_y = -(int8_t)data[7];
+	stripdata = stripe->data;
 	memcpy(stripdata, data + 33, FRAME_WIDTH * FRAME_HEIGHT / 2);
-	aesdev->strips = g_slist_prepend(aesdev->strips, stripdata);
+	aesdev->strips = g_slist_prepend(aesdev->strips, stripe);
 	aesdev->strips_len++;
 
+	fp_dbg("deltas: %dx%d", stripe->delta_x, stripe->delta_y);
+
 	return 0;
 }
 
@@ -242,12 +248,13 @@ static void capture_set_idle_reqs_cb(struct libusb_transfer *transfer)
 	struct aes2550_dev *aesdev = dev->priv;
 
 	if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
-		(transfer->length == transfer->actual_length)) {
+		(transfer->length == transfer->actual_length) &&
+		aesdev->strips_len) {
 		struct fp_img *img;
 
 		aesdev->strips = g_slist_reverse(aesdev->strips);
 		img = aes_assemble(aesdev->strips, aesdev->strips_len,
-			FRAME_WIDTH, FRAME_HEIGHT);
+			FRAME_WIDTH, FRAME_HEIGHT, FRAME_WIDTH + FRAME_WIDTH / 2);
 		g_slist_free_full(aesdev->strips, g_free);
 		aesdev->strips = NULL;
 		aesdev->strips_len = 0;
@@ -637,7 +644,7 @@ struct fp_img_driver aes2550_driver = {
 	},
 	.flags = 0,
 	.img_height = -1,
-	.img_width = 192,
+	.img_width = FRAME_WIDTH + FRAME_WIDTH / 2,
 
 	.open = dev_init,
 	.close = dev_deinit,
diff --git a/libfprint/drivers/aes2660.c b/libfprint/drivers/aes2660.c
index 4be7475..d7b6cef 100644
--- a/libfprint/drivers/aes2660.c
+++ b/libfprint/drivers/aes2660.c
@@ -49,7 +49,6 @@ static int dev_init(struct fp_img_dev *dev, unsigned long driver_data)
 	dev->priv = aesdev = g_malloc0(sizeof(struct aesX660_dev));
 	aesdev->buffer = g_malloc0(AES2660_FRAME_SIZE + AESX660_HEADER_SIZE);
 	/* No scaling for AES2660 */
-	aesdev->h_scale_factor = 1;
 	aesdev->init_seqs[0] = aes2660_init_1;
 	aesdev->init_seqs_len[0] = array_n_elements(aes2660_init_1);
 	aesdev->init_seqs[1] = aes2660_init_2;
@@ -103,7 +102,7 @@ struct fp_img_driver aes2660_driver = {
 	},
 	.flags = 0,
 	.img_height = -1,
-	.img_width = FRAME_WIDTH,
+	.img_width = FRAME_WIDTH + FRAME_WIDTH / 2,
 
 	.open = dev_init,
 	.close = dev_deinit,
diff --git a/libfprint/drivers/aes3k.c b/libfprint/drivers/aes3k.c
index fefba3c..ba96901 100644
--- a/libfprint/drivers/aes3k.c
+++ b/libfprint/drivers/aes3k.c
@@ -52,6 +52,20 @@
 
 static void do_capture(struct fp_img_dev *dev);
 
+static void aes3k_assemble_image(unsigned char *input, size_t width, size_t height,
+	unsigned char *output)
+{
+	size_t row, column;
+
+	for (column = 0; column < width; column++) {
+		for (row = 0; row < height; row += 2) {
+			output[width * row + column] = (*input & 0x0f) * 17;
+			output[width * (row + 1) + column] = ((*input & 0xf0) >> 4) * 17;
+			input++;
+		}
+	}
+}
+
 static void img_cb(struct libusb_transfer *transfer)
 {
 	struct fp_img_dev *dev = transfer->user_data;
@@ -80,7 +94,7 @@ static void img_cb(struct libusb_transfer *transfer)
 	for (i = 0; i < aesdev->frame_number; i++) {
 		fp_dbg("frame header byte %02x", *ptr);
 		ptr++;
-		aes_assemble_image(ptr, aesdev->frame_width, AES3K_FRAME_HEIGHT, tmp->data + (i * aesdev->frame_width * AES3K_FRAME_HEIGHT));
+		aes3k_assemble_image(ptr, aesdev->frame_width, AES3K_FRAME_HEIGHT, tmp->data + (i * aesdev->frame_width * AES3K_FRAME_HEIGHT));
 		ptr += aesdev->frame_size;
 	}
 
diff --git a/libfprint/drivers/aesx660.c b/libfprint/drivers/aesx660.c
index 6f35720..ec28a5b 100644
--- a/libfprint/drivers/aesx660.c
+++ b/libfprint/drivers/aesx660.c
@@ -273,19 +273,25 @@ enum capture_states {
 /* Returns number of processed bytes */
 static int process_stripe_data(struct fpi_ssm *ssm, unsigned char *data)
 {
+	struct aes_stripe *stripe;
 	unsigned char *stripdata;
 	struct fp_img_dev *dev = ssm->priv;
 	struct aesX660_dev *aesdev = dev->priv;
 
-	stripdata = g_malloc(aesdev->frame_width * FRAME_HEIGHT / 2); /* 4 bits per pixel */
+	stripe = g_malloc(aesdev->frame_width * FRAME_HEIGHT / 2 + sizeof(struct aes_stripe)); /* 4 bpp */
+	stripdata = stripe->data;
 
 	fp_dbg("Processing frame %.2x %.2x", data[AESX660_IMAGE_OK_OFFSET],
 		data[AESX660_LAST_FRAME_OFFSET]);
 
+	stripe->delta_x = (int8_t)data[AESX660_FRAME_DELTA_X_OFFSET];
+	stripe->delta_y = -(int8_t)data[AESX660_FRAME_DELTA_Y_OFFSET];
+	fp_dbg("Offset to previous frame: %d %d", stripe->delta_x, stripe->delta_y);
+
 	if (data[AESX660_IMAGE_OK_OFFSET] == AESX660_IMAGE_OK) {
 		memcpy(stripdata, data + AESX660_IMAGE_OFFSET, aesdev->frame_width * FRAME_HEIGHT / 2);
 
-		aesdev->strips = g_slist_prepend(aesdev->strips, stripdata);
+		aesdev->strips = g_slist_prepend(aesdev->strips, stripe);
 		aesdev->strips_len++;
 		return (data[AESX660_LAST_FRAME_OFFSET] & AESX660_LAST_FRAME_BIT);
 	} else {
@@ -302,22 +308,15 @@ static void capture_set_idle_cmd_cb(struct libusb_transfer *transfer)
 
 	if ((transfer->status == LIBUSB_TRANSFER_COMPLETED) &&
 		(transfer->length == transfer->actual_length)) {
-		struct fp_img *img, *tmp;
+		struct fp_img *img;
 
 		aesdev->strips = g_slist_reverse(aesdev->strips);
-		tmp = aes_assemble(aesdev->strips, aesdev->strips_len,
-			aesdev->frame_width, FRAME_HEIGHT);
+		img = aes_assemble(aesdev->strips, aesdev->strips_len,
+			aesdev->frame_width, FRAME_HEIGHT, aesdev->frame_width + aesdev->frame_width / 2);
 		g_slist_foreach(aesdev->strips, (GFunc) g_free, NULL);
 		g_slist_free(aesdev->strips);
 		aesdev->strips = NULL;
 		aesdev->strips_len = 0;
-		if (aesdev->h_scale_factor > 1) {
-			img = fpi_im_resize(tmp, aesdev->h_scale_factor, 1);
-			fp_img_free(tmp);
-		} else {
-			img = tmp;
-			tmp = NULL;
-		}
 		fpi_imgdev_image_captured(dev, img);
 		fpi_imgdev_report_finger_status(dev, FALSE);
 		fpi_ssm_mark_completed(ssm);
diff --git a/libfprint/drivers/aesx660.h b/libfprint/drivers/aesx660.h
index e354538..0510a43 100644
--- a/libfprint/drivers/aesx660.h
+++ b/libfprint/drivers/aesx660.h
@@ -35,6 +35,9 @@
 #define AESX660_LAST_FRAME_OFFSET 0x04
 #define AESX660_LAST_FRAME_BIT 0x01
 
+#define AESX660_FRAME_DELTA_X_OFFSET 16
+#define AESX660_FRAME_DELTA_Y_OFFSET 17
+
 #define AESX660_IMAGE_OFFSET 43
 #define AESX660_BULK_TRANSFER_SIZE 4096
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/fingerforce/libfprint.git



More information about the Fingerforce-commits mailing list