summaryrefslogtreecommitdiff
path: root/libfprint
diff options
context:
space:
mode:
Diffstat (limited to 'libfprint')
-rw-r--r--libfprint/aeslib.c327
-rw-r--r--libfprint/aeslib.h13
-rw-r--r--libfprint/drivers/aes1610.c21
-rw-r--r--libfprint/drivers/aes1660.c4
-rw-r--r--libfprint/drivers/aes2501.c22
-rw-r--r--libfprint/drivers/aes2550.c17
-rw-r--r--libfprint/drivers/aes2660.c3
-rw-r--r--libfprint/drivers/aes3k.c16
-rw-r--r--libfprint/drivers/aesx660.c23
-rw-r--r--libfprint/drivers/aesx660.h3
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