diff --git a/examples/img_capture.c b/examples/img_capture.c index 6edc191..1d88fdf 100644 --- a/examples/img_capture.c +++ b/examples/img_capture.c @@ -92,6 +92,13 @@ int main(void) goto out_close; } + fp_img_standardize(img); + r = fp_img_save_to_file(img, "finger_standardized.pgm"); + if (r) { + fprintf(stderr, "standardized img save failed, code %d\n", r); + goto out_close; + } + r = 0; out_close: fp_dev_close(dev); diff --git a/libfprint/drivers/uru4000.c b/libfprint/drivers/uru4000.c index 8a32497..56e5027 100644 --- a/libfprint/drivers/uru4000.c +++ b/libfprint/drivers/uru4000.c @@ -294,6 +294,7 @@ static int capture(struct fp_img_dev *dev, gboolean unconditional, img = fpi_img_resize(img, image_size); img->width = IMG_WIDTH; img->height = IMG_HEIGHT; + img->flags = FP_IMG_V_FLIPPED | FP_IMG_H_FLIPPED | FP_IMG_COLORS_INVERTED; *ret = img; return 0; diff --git a/libfprint/fp_internal.h b/libfprint/fp_internal.h index e8aeb2e..537b0d9 100644 --- a/libfprint/fp_internal.h +++ b/libfprint/fp_internal.h @@ -155,10 +155,16 @@ struct fp_print_data { struct fp_print_data *fpi_print_data_new(struct fp_dev *dev, size_t length); int fpi_print_data_compatible(struct fp_dev *dev, struct fp_print_data *data); +/* bit values for fp_img.flags */ +#define FP_IMG_V_FLIPPED (1<<0) +#define FP_IMG_H_FLIPPED (1<<1) +#define FP_IMG_COLORS_INVERTED (1<<2) + struct fp_img { int width; int height; size_t length; + uint16_t flags; unsigned char data[0]; }; diff --git a/libfprint/fprint.h b/libfprint/fprint.h index 128c011..541e976 100644 --- a/libfprint/fprint.h +++ b/libfprint/fprint.h @@ -97,6 +97,7 @@ int fp_img_get_height(struct fp_img *img); int fp_img_get_width(struct fp_img *img); unsigned char *fp_img_get_data(struct fp_img *img); int fp_img_save_to_file(struct fp_img *img, char *path); +void fp_img_standardize(struct fp_img *img); /* Library */ int fp_init(void); diff --git a/libfprint/img.c b/libfprint/img.c index 664bbea..38c492f 100644 --- a/libfprint/img.c +++ b/libfprint/img.c @@ -104,3 +104,63 @@ API_EXPORTED int fp_img_save_to_file(struct fp_img *img, char *path) return 0; } +static void vflip(struct fp_img *img) +{ + int width = img->width; + int data_len = img->width * img->height; + unsigned char rowbuf[width]; + int i; + + for (i = 0; i < img->height / 2; i++) { + int offset = i * width; + int swap_offset = data_len - (width * (i + 1)); + + /* copy top row into buffer */ + memcpy(rowbuf, img->data + offset, width); + + /* copy lower row over upper row */ + memcpy(img->data + offset, img->data + swap_offset, width); + + /* copy buffer over lower row */ + memcpy(img->data + swap_offset, rowbuf, width); + } +} + +static void hflip(struct fp_img *img) +{ + int width = img->width; + unsigned char rowbuf[width]; + int i, j; + + for (i = 0; i < img->height; i++) { + int offset = i * width; + + memcpy(rowbuf, img->data + offset, width); + for (j = 0; j < width; j++) + img->data[offset + j] = rowbuf[width - j - 1]; + } +} + +static void invert_colors(struct fp_img *img) +{ + int data_len = img->width * img->height; + int i; + for (i = 0; i < data_len; i++) + img->data[i] = 0xff - img->data[i]; +} + +API_EXPORTED void fp_img_standardize(struct fp_img *img) +{ + if (img->flags & FP_IMG_V_FLIPPED) { + vflip(img); + img->flags &= ~FP_IMG_V_FLIPPED; + } + if (img->flags & FP_IMG_H_FLIPPED) { + hflip(img); + img->flags &= ~FP_IMG_H_FLIPPED; + } + if (img->flags & FP_IMG_COLORS_INVERTED) { + invert_colors(img); + img->flags &= ~FP_IMG_COLORS_INVERTED; + } +}