diff --git a/libs/spandsp/src/image_translate.c b/libs/spandsp/src/image_translate.c index 785997def5..54037990fc 100644 --- a/libs/spandsp/src/image_translate.c +++ b/libs/spandsp/src/image_translate.c @@ -2,8 +2,9 @@ * SpanDSP - a series of DSP components for telephony * * image_translate.c - Image translation routines for reworking colour - * and gray scale images to be bi-level images of an - * appropriate size to be FAX compatible. + * and gray scale images to be colour, gray scale or + * bi-level images of an appropriate size to be FAX + * compatible. * * Written by Steve Underwood * @@ -80,69 +81,237 @@ #include "spandsp/private/t4_rx.h" #include "spandsp/private/t4_tx.h" -static int image_colour16_to_gray8_row(uint8_t mono[], uint16_t colour[], int pixels) +static int image_colour16_to_colour8_row(uint8_t colour8[], uint16_t colour16[], int pixels) +{ + int i; + + for (i = 0; i < 3*pixels; i++) + colour8[i] = colour16[i] >> 8; + return pixels; +} +/*- End of function --------------------------------------------------------*/ + +static int image_colour16_to_gray16_row(uint16_t gray16[], uint16_t colour16[], int pixels) { int i; uint32_t gray; for (i = 0; i < pixels; i++) { - gray = colour[3*i]*19595 + colour[3*i + 1]*38469 + colour[3*i + 2]*7472; - mono[i] = saturateu8(gray >> 24); + gray = colour16[3*i]*19595 + colour16[3*i + 1]*38469 + colour16[3*i + 2]*7472; + gray16[i] = saturateu16(gray >> 16); } return pixels; } /*- End of function --------------------------------------------------------*/ -static int image_colour8_to_gray8_row(uint8_t mono[], uint8_t colour[], int pixels) +static int image_colour16_to_gray8_row(uint8_t gray8[], uint16_t colour16[], int pixels) { int i; uint32_t gray; for (i = 0; i < pixels; i++) { - gray = colour[3*i]*19595 + colour[3*i + 1]*38469 + colour[3*i + 2]*7472; - mono[i] = saturateu8(gray >> 16); + gray = colour16[3*i]*19595 + colour16[3*i + 1]*38469 + colour16[3*i + 2]*7472; + gray8[i] = saturateu8(gray >> 24); } return pixels; } /*- End of function --------------------------------------------------------*/ -static int image_gray16_to_gray8_row(uint8_t mono[], uint16_t gray[], int pixels) +static int image_colour8_to_gray16_row(uint16_t gray16[], uint8_t colour8[], int pixels) { int i; + uint32_t gray; for (i = 0; i < pixels; i++) - mono[i] = gray[i] >> 8; + { + gray = colour8[3*i]*19595 + colour8[3*i + 1]*38469 + colour8[3*i + 2]*7472; + gray16[i] = saturateu16(gray >> 8); + } return pixels; } /*- End of function --------------------------------------------------------*/ -static int get_and_scrunch_row(image_translate_state_t *s, uint8_t buf[], size_t len) +static int image_colour8_to_gray8_row(uint8_t gray8[], uint8_t colour8[], int pixels) { - int row_len; + int i; + uint32_t gray; - row_len = (*s->row_read_handler)(s->row_read_user_data, buf, s->input_width*s->bytes_per_pixel); - if (row_len != s->input_width*s->bytes_per_pixel) + for (i = 0; i < pixels; i++) + { + gray = colour8[3*i]*19595 + colour8[3*i + 1]*38469 + colour8[3*i + 2]*7472; + gray8[i] = saturateu8(gray >> 16); + } + return pixels; +} +/*- End of function --------------------------------------------------------*/ + +static int image_colour8_to_colour16_row(uint16_t colour16[], uint8_t colour8[], int pixels) +{ + int i; + + for (i = 3*pixels - 1; i >= 0; i--) + colour16[i] = colour8[i] << 8; + return pixels; +} +/*- End of function --------------------------------------------------------*/ + +static int image_gray16_to_colour16_row(uint16_t colour16[], uint16_t gray16[], int pixels) +{ + int i; + + for (i = pixels - 1; i >= 0; i--) + { + /* TODO: need to balance the colours */ + colour16[3*i] = gray16[i]; + colour16[3*i + 1] = gray16[i]; + colour16[3*i + 2] = gray16[i]; + } + return pixels; +} +/*- End of function --------------------------------------------------------*/ + +static int image_gray16_to_colour8_row(uint8_t colour8[], uint16_t gray16[], int pixels) +{ + int i; + + for (i = pixels - 1; i >= 0; i--) + { + /* TODO: need to balance the colours */ + colour8[3*i] = gray16[i] >> 8; + colour8[3*i + 1] = gray16[i] >> 8; + colour8[3*i + 2] = gray16[i] >> 8; + } + return pixels; +} +/*- End of function --------------------------------------------------------*/ + +static int image_gray16_to_gray8_row(uint8_t gray8[], uint16_t gray16[], int pixels) +{ + int i; + + for (i = 0; i < pixels; i++) + gray8[i] = gray16[i] >> 8; + return pixels; +} +/*- End of function --------------------------------------------------------*/ + +static int image_gray8_to_colour16_row(uint16_t colour16[], uint8_t gray8[], int pixels) +{ + int i; + + for (i = pixels - 1; i >= 0; i--) + { + /* TODO: need to balance the colours */ + colour16[3*i] = gray8[i] << 8; + colour16[3*i + 1] = gray8[i] << 8; + colour16[3*i + 2] = gray8[i] << 8; + } + return pixels; +} +/*- End of function --------------------------------------------------------*/ + +static int image_gray8_to_colour8_row(uint8_t colour8[], uint8_t gray8[], int pixels) +{ + int i; + + for (i = pixels - 1; i >= 0; i--) + { + /* TODO: need to balance the colours */ + colour8[3*i] = gray8[i]; + colour8[3*i + 1] = gray8[i]; + colour8[3*i + 2] = gray8[i]; + } + return pixels; +} +/*- End of function --------------------------------------------------------*/ + +static int image_gray8_to_gray16_row(uint16_t gray16[], uint8_t gray8[], int pixels) +{ + int i; + + for (i = pixels - 1; i >= 0; i--) + gray16[i] = gray8[i] << 8; + return pixels; +} +/*- End of function --------------------------------------------------------*/ + +static int get_and_scrunch_row(image_translate_state_t *s, uint8_t buf[]) +{ + int input_row_len; + + input_row_len = (*s->row_read_handler)(s->row_read_user_data, buf, s->input_width*s->input_bytes_per_pixel); + if (input_row_len != s->input_width*s->input_bytes_per_pixel) return 0; - /* Scrunch colour down to gray, and scrunch 16 bit pixels down to 8 bit pixels */ + /* Scrunch colour down to gray, vice versa. Scrunch 16 bit pixels down to 8 bit pixels, or vice versa. */ switch (s->input_format) { case T4_IMAGE_TYPE_GRAY_12BIT: - image_gray16_to_gray8_row(buf, (uint16_t *) buf, s->input_width); + switch (s->output_format) + { + case T4_IMAGE_TYPE_BILEVEL: + case T4_IMAGE_TYPE_GRAY_8BIT: + image_gray16_to_gray8_row(buf, (uint16_t *) buf, s->input_width); + break; + case T4_IMAGE_TYPE_COLOUR_12BIT: + image_gray16_to_colour16_row((uint16_t *) buf, (uint16_t *) buf, s->input_width); + break; + case T4_IMAGE_TYPE_COLOUR_8BIT: + image_gray16_to_colour8_row(buf, (uint16_t *) buf, s->input_width); + break; + } + break; + case T4_IMAGE_TYPE_GRAY_8BIT: + switch (s->output_format) + { + case T4_IMAGE_TYPE_GRAY_12BIT: + image_gray8_to_gray16_row((uint16_t *) buf, buf, s->input_width); + break; + case T4_IMAGE_TYPE_COLOUR_12BIT: + image_gray8_to_colour16_row((uint16_t *) buf, buf, s->input_width); + break; + case T4_IMAGE_TYPE_COLOUR_8BIT: + image_gray8_to_colour8_row(buf, buf, s->input_width); + break; + } break; case T4_IMAGE_TYPE_COLOUR_12BIT: - image_colour16_to_gray8_row(buf, (uint16_t *) buf, s->input_width); + switch (s->output_format) + { + case T4_IMAGE_TYPE_GRAY_12BIT: + image_colour16_to_gray16_row((uint16_t *) buf, (uint16_t *) buf, s->input_width); + break; + case T4_IMAGE_TYPE_BILEVEL: + case T4_IMAGE_TYPE_GRAY_8BIT: + image_colour16_to_gray8_row(buf, (uint16_t *) buf, s->input_width); + break; + case T4_IMAGE_TYPE_COLOUR_8BIT: + image_colour16_to_colour8_row(buf, (uint16_t *) buf, s->input_width); + break; + } break; case T4_IMAGE_TYPE_COLOUR_8BIT: - image_colour8_to_gray8_row(buf, buf, s->input_width); + switch (s->output_format) + { + case T4_IMAGE_TYPE_GRAY_12BIT: + image_colour8_to_gray16_row((uint16_t *) buf, buf, s->input_width); + break; + case T4_IMAGE_TYPE_BILEVEL: + case T4_IMAGE_TYPE_GRAY_8BIT: + image_colour8_to_gray8_row(buf, buf, s->input_width); + break; + case T4_IMAGE_TYPE_COLOUR_12BIT: + image_colour8_to_colour16_row((uint16_t *) buf, buf, s->input_width); + break; + } break; } - return row_len; + return s->output_width; } /*- End of function --------------------------------------------------------*/ -static int image_resize_row(image_translate_state_t *s, uint8_t buf[], size_t len) +static int image_resize_row(image_translate_state_t *s, uint8_t buf[]) { int i; int output_width; @@ -184,8 +353,8 @@ static int image_resize_row(image_translate_state_t *s, uint8_t buf[], size_t le s->raw_output_row = -1; break; } - row_len = get_and_scrunch_row(s, s->raw_pixel_row[0], s->input_width*s->bytes_per_pixel); - if (row_len != s->input_width*s->bytes_per_pixel) + row_len = get_and_scrunch_row(s, s->raw_pixel_row[0]); + if (row_len != s->output_width) { s->raw_output_row = -1; return 0; @@ -221,7 +390,7 @@ static int image_resize_row(image_translate_state_t *s, uint8_t buf[], size_t le #endif if (++s->raw_output_row >= s->output_length) s->raw_output_row = -1; - return len; + return s->output_width; } /*- End of function --------------------------------------------------------*/ @@ -335,6 +504,7 @@ SPAN_DECLARE(int) image_translate_row(image_translate_state_t *s, uint8_t buf[], - At the last row we dither and output, without getting an extra row in. */ for (i = (y == 0) ? 0 : 1; i < 2; i++) { + /* Swap the row buffers */ p = s->pixel_row[0]; s->pixel_row[0] = s->pixel_row[1]; s->pixel_row[1] = p; @@ -344,17 +514,24 @@ SPAN_DECLARE(int) image_translate_row(image_translate_state_t *s, uint8_t buf[], will fail, with the end of image condition (i.e. returning zero length) */ if (s->resize) { - if (image_resize_row(s, s->pixel_row[1], s->output_width*s->bytes_per_pixel) != s->output_width*s->bytes_per_pixel) + if (image_resize_row(s, s->pixel_row[1]) != s->output_width) s->output_row = -1; } else { - if (get_and_scrunch_row(s, s->pixel_row[1], s->output_width*s->bytes_per_pixel) != s->output_width*s->bytes_per_pixel) + if (get_and_scrunch_row(s, s->pixel_row[1]) != s->output_width) s->output_row = -1; } } if (s->output_format == T4_IMAGE_TYPE_BILEVEL) + { i = floyd_steinberg_dither_row(s, buf, y); + } + else + { + i = s->output_width*s->output_bytes_per_pixel; + memcpy(buf, s->pixel_row[1], i); + } return i; } /*- End of function --------------------------------------------------------*/ @@ -413,19 +590,38 @@ SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_sta switch (s->input_format) { case T4_IMAGE_TYPE_GRAY_8BIT: - s->bytes_per_pixel = 1; + s->input_bytes_per_pixel = 1; break; case T4_IMAGE_TYPE_GRAY_12BIT: - s->bytes_per_pixel = 2; + s->input_bytes_per_pixel = 2; break; case T4_IMAGE_TYPE_COLOUR_8BIT: - s->bytes_per_pixel = 3; + s->input_bytes_per_pixel = 3; break; case T4_IMAGE_TYPE_COLOUR_12BIT: - s->bytes_per_pixel = 6; + s->input_bytes_per_pixel = 6; break; default: - s->bytes_per_pixel = 1; + s->input_bytes_per_pixel = 1; + break; + } + + switch (s->output_format) + { + case T4_IMAGE_TYPE_GRAY_8BIT: + s->output_bytes_per_pixel = 1; + break; + case T4_IMAGE_TYPE_GRAY_12BIT: + s->output_bytes_per_pixel = 2; + break; + case T4_IMAGE_TYPE_COLOUR_8BIT: + s->output_bytes_per_pixel = 3; + break; + case T4_IMAGE_TYPE_COLOUR_12BIT: + s->output_bytes_per_pixel = 6; + break; + default: + s->output_bytes_per_pixel = 1; break; } @@ -434,9 +630,9 @@ SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_sta { for (i = 0; i < 2; i++) { - if ((s->raw_pixel_row[i] = (uint8_t *) malloc(s->input_width*s->bytes_per_pixel)) == NULL) + if ((s->raw_pixel_row[i] = (uint8_t *) malloc(s->input_width*s->input_bytes_per_pixel)) == NULL) return NULL; - memset(s->raw_pixel_row[i], 0, s->input_width*s->bytes_per_pixel); + memset(s->raw_pixel_row[i], 0, s->input_width*s->input_bytes_per_pixel); if ((s->pixel_row[i] = (uint8_t *) malloc(s->output_width*sizeof(uint8_t))) == NULL) return NULL; memset(s->pixel_row[i], 0, s->output_width*sizeof(uint8_t)); @@ -446,9 +642,9 @@ SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_sta { for (i = 0; i < 2; i++) { - if ((s->pixel_row[i] = (uint8_t *) malloc(s->output_width*s->bytes_per_pixel)) == NULL) + if ((s->pixel_row[i] = (uint8_t *) malloc(s->output_width*s->input_bytes_per_pixel)) == NULL) return NULL; - memset(s->pixel_row[i], 0, s->output_width*s->bytes_per_pixel); + memset(s->pixel_row[i], 0, s->output_width*s->input_bytes_per_pixel); } } diff --git a/libs/spandsp/src/spandsp/image_translate.h b/libs/spandsp/src/spandsp/image_translate.h index 31f13d2845..7f91c2db0a 100644 --- a/libs/spandsp/src/spandsp/image_translate.h +++ b/libs/spandsp/src/spandsp/image_translate.h @@ -2,8 +2,9 @@ * SpanDSP - a series of DSP components for telephony * * image_translate.h - Image translation routines for reworking colour - * and gray scale images to be bi-level images of an - * appropriate size to be FAX compatible. + * and gray scale images to be colour, gray scale or + * bi-level images of an appropriate size to be FAX + * compatible. * * Written by Steve Underwood * diff --git a/libs/spandsp/src/spandsp/private/image_translate.h b/libs/spandsp/src/spandsp/private/image_translate.h index e473a0f644..02a13506df 100644 --- a/libs/spandsp/src/spandsp/private/image_translate.h +++ b/libs/spandsp/src/spandsp/private/image_translate.h @@ -1,7 +1,7 @@ /* * SpanDSP - a series of DSP components for telephony * - * private/image_translate.c - Image translation routines for reworking colour + * private/image_translate.h - Image translation routines for reworking colour * and gray scale images to be bi-level images of an * appropriate size to be FAX compatible. * @@ -33,11 +33,12 @@ struct image_translate_state_s int input_format; int input_width; int input_length; + int input_bytes_per_pixel; int output_format; int output_width; int output_length; + int output_bytes_per_pixel; int resize; - int bytes_per_pixel; int raw_input_row; int raw_output_row; int output_row; diff --git a/libs/spandsp/tests/image_translate_tests.c b/libs/spandsp/tests/image_translate_tests.c index b57fe3965b..b1930c12a3 100644 --- a/libs/spandsp/tests/image_translate_tests.c +++ b/libs/spandsp/tests/image_translate_tests.c @@ -159,7 +159,7 @@ static int row_read(void *user_data, uint8_t buf[], size_t len) } /*- End of function --------------------------------------------------------*/ -static void get_flattened_image(image_translate_state_t *s, int compare) +static void get_bilevel_image(image_translate_state_t *s, int compare) { int i; int len; @@ -191,12 +191,147 @@ static void get_flattened_image(image_translate_state_t *s, int compare) } /*- End of function --------------------------------------------------------*/ +static void get_gray8_image(image_translate_state_t *s, int compare) +{ + int i; + int j; + int len; + uint8_t row_buf[5000]; + + for (i = 0; i < s->output_length; i++) + { + if ((len = image_translate_row(s, row_buf, s->output_width)) != s->output_width) + { + printf("Image finished early - %d %d\n", len, s->output_width); + exit(2); + } + if (compare) + { + for (j = 0; j < 50; j++) + { + if (row_buf[j] != j*1200/256) + { + printf("Image mismatch - %d - %d\n", j, row_buf[3*j]); + exit(2); + } + } + } + } + if ((len = image_translate_row(s, row_buf, s->output_width)) != 0) + { + printf("Image finished late - %d %d\n", len, s->output_width); + exit(2); + } +} +/*- End of function --------------------------------------------------------*/ + +static void get_gray16_image(image_translate_state_t *s, int compare) +{ + int i; + int j; + int len; + uint16_t row_buf[5000]; + + for (i = 0; i < s->output_length; i++) + { + if ((len = image_translate_row(s, (uint8_t *) row_buf, 2*s->output_width)) != 2*s->output_width) + { + printf("Image finished early - %d %d\n", len, 2*s->output_width); + exit(2); + } + if (compare) + { + for (j = 0; j < 50; j++) + { + if (row_buf[j] != j*1200) + { + printf("Image mismatch - %d - %d\n", j, row_buf[j]); + exit(2); + } + } + } + } + if ((len = image_translate_row(s, (uint8_t *) row_buf, 2*s->output_width)) != 0) + { + printf("Image finished late - %d %d\n", len, 2*s->output_width); + exit(2); + } +} +/*- End of function --------------------------------------------------------*/ + +static void get_colour8_image(image_translate_state_t *s, int compare) +{ + int i; + int j; + int len; + uint8_t row_buf[5000]; + + for (i = 0; i < s->output_length; i++) + { + if ((len = image_translate_row(s, row_buf, 3*s->output_width)) != 3*s->output_width) + { + printf("Image finished early - %d %d\n", len, 3*s->output_width); + exit(2); + } + if (compare) + { + for (j = 0; j < 50; j++) + { + if (row_buf[3*j + 0] != j*1200/256 || row_buf[3*j + 1] != j*1200/256 || row_buf[3*j + 2] != j*1200/256) + { + printf("Image mismatch - %d - %d %d %d\n", j, row_buf[3*j + 0], row_buf[3*j + 1], row_buf[3*j + 2]); + exit(2); + } + } + } + } + if ((len = image_translate_row(s, row_buf, 2*s->output_width)) != 0) + { + printf("Image finished late - %d %d\n", len, 3*s->output_width); + exit(2); + } +} +/*- End of function --------------------------------------------------------*/ + +static void get_colour16_image(image_translate_state_t *s, int compare) +{ + int i; + int j; + int len; + uint16_t row_buf[5000]; + + for (i = 0; i < s->output_length; i++) + { + if ((len = image_translate_row(s, (uint8_t *) row_buf, 6*s->output_width)) != 6*s->output_width) + { + printf("Image finished early - %d %d\n", len, 6*s->output_width); + exit(2); + } + if (compare) + { + for (j = 0; j < 50; j++) + { + if (row_buf[3*j + 0] != j*1200 || row_buf[3*j + 1] != j*1200 || row_buf[3*j + 2] != j*1200) + { + printf("Image mismatch - %d - %d %d %d\n", j, row_buf[3*j + 0], row_buf[3*j + 1], row_buf[3*j + 2]); + exit(2); + } + } + } + } + if ((len = image_translate_row(s, (uint8_t *) row_buf, 6*s->output_width)) != 0) + { + printf("Image finished late - %d %d\n", len, 6*s->output_width); + exit(2); + } +} +/*- End of function --------------------------------------------------------*/ + static void dither_tests_gray16(void) { int i; int j; - image_translate_state_t bw; - image_translate_state_t *s = &bw; + image_translate_state_t *s; uint16_t image[50*50]; image_descriptor_t im; @@ -213,8 +348,9 @@ static void dither_tests_gray16(void) image[i*im.width + j] = j*1200; } - s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im); - get_flattened_image(s, TRUE); + s = image_translate_init(NULL, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im); + get_bilevel_image(s, TRUE); + image_translate_free(s); } /*- End of function --------------------------------------------------------*/ @@ -222,8 +358,7 @@ static void dither_tests_gray8(void) { int i; int j; - image_translate_state_t bw; - image_translate_state_t *s = &bw; + image_translate_state_t *s; uint8_t image[50*50]; image_descriptor_t im; @@ -239,8 +374,10 @@ static void dither_tests_gray8(void) for (j = 0; j < im.width; j++) image[i*im.width + j] = j*1200/256; } - s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im); - get_flattened_image(s, TRUE); + + s = image_translate_init(NULL, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im); + get_bilevel_image(s, TRUE); + image_translate_free(s); } /*- End of function --------------------------------------------------------*/ @@ -248,8 +385,7 @@ static void dither_tests_colour16(void) { int i; int j; - image_translate_state_t bw; - image_translate_state_t *s = &bw; + image_translate_state_t *s; uint16_t image[50*50*3]; image_descriptor_t im; @@ -264,13 +400,96 @@ static void dither_tests_colour16(void) { for (j = 0; j < im.width; j++) { - image[i*3*im.width + 3*j + 0] = j*1200; - image[i*3*im.width + 3*j + 1] = j*1200; - image[i*3*im.width + 3*j + 2] = j*1200; + image[i*3*im.width + 3*j + 0] = j*1200 + i; + image[i*3*im.width + 3*j + 1] = j*1200 + i; + image[i*3*im.width + 3*j + 2] = j*1200 + i; } } - s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im); - get_flattened_image(s, TRUE); + + s = image_translate_init(NULL, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im); + get_bilevel_image(s, TRUE); + + printf("Scrunching from a 3x16 bit per sample colour to 8 bit per sample gray scale\n"); + im.image = (const uint8_t *) image; + im.width = 50; + im.length = 50; + im.bytes_per_pixel = 6; + im.current_row = 0; + + for (i = 0; i < im.length; i++) + { + for (j = 0; j < im.width; j++) + { + image[i*3*im.width + 3*j + 0] = j*1200 + i; + image[i*3*im.width + 3*j + 1] = j*1200 + i; + image[i*3*im.width + 3*j + 2] = j*1200 + i; + } + } + + s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, T4_IMAGE_TYPE_GRAY_8BIT, -1, -1, row_read, &im); + get_gray8_image(s, TRUE); + + printf("Scrunching from a 3x16 bit per sample colour to 16 bit per sample gray scale\n"); + im.image = (const uint8_t *) image; + im.width = 50; + im.length = 50; + im.bytes_per_pixel = 6; + im.current_row = 0; + + for (i = 0; i < im.length; i++) + { + for (j = 0; j < im.width; j++) + { + image[i*3*im.width + 3*j + 0] = j*1200 + i; + image[i*3*im.width + 3*j + 1] = j*1200 + i; + image[i*3*im.width + 3*j + 2] = j*1200 + i; + } + } + + s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, T4_IMAGE_TYPE_GRAY_12BIT, -1, -1, row_read, &im); + get_gray16_image(s, TRUE); + + printf("Scrunching from a 3x16 bit per sample colour to 3x8 bit per sample colour\n"); + im.image = (const uint8_t *) image; + im.width = 50; + im.length = 50; + im.bytes_per_pixel = 6; + im.current_row = 0; + + for (i = 0; i < im.length; i++) + { + for (j = 0; j < im.width; j++) + { + image[i*3*im.width + 3*j + 0] = j*1200 + i; + image[i*3*im.width + 3*j + 1] = j*1200 + i; + image[i*3*im.width + 3*j + 2] = j*1200 + i; + } + } + + s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, T4_IMAGE_TYPE_COLOUR_8BIT, -1, -1, row_read, &im); + get_colour8_image(s, TRUE); + + printf("Scrunching from a 3x16 bit per sample colour to 3x16 bit per sample colour\n"); + im.image = (const uint8_t *) image; + im.width = 50; + im.length = 50; + im.bytes_per_pixel = 6; + im.current_row = 0; + + for (i = 0; i < im.length; i++) + { + for (j = 0; j < im.width; j++) + { + image[i*3*im.width + 3*j + 0] = j*1200 + i; + image[i*3*im.width + 3*j + 1] = j*1200 + i; + image[i*3*im.width + 3*j + 2] = j*1200 + i; + } + } + + s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, T4_IMAGE_TYPE_COLOUR_12BIT, -1, -1, row_read, &im); + get_colour16_image(s, TRUE); + + image_translate_free(s); } /*- End of function --------------------------------------------------------*/ @@ -278,8 +497,7 @@ static void dither_tests_colour8(void) { int i; int j; - image_translate_state_t bw; - image_translate_state_t *s = &bw; + image_translate_state_t *s; uint8_t image[50*50*3]; image_descriptor_t im; @@ -294,14 +512,15 @@ static void dither_tests_colour8(void) { for (j = 0; j < im.width; j++) { - image[i*3*im.width + 3*j + 0] = j*1200/256; - image[i*3*im.width + 3*j + 1] = j*1200/256; - image[i*3*im.width + 3*j + 2] = j*1200/256; + image[i*3*im.width + 3*j + 0] = j*1200/256 + i; + image[i*3*im.width + 3*j + 1] = j*1200/256 + i; + image[i*3*im.width + 3*j + 2] = j*1200/256 + i; } } - s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im); - get_flattened_image(s, TRUE); + s = image_translate_init(NULL, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im); + get_bilevel_image(s, TRUE); + image_translate_free(s); } /*- End of function --------------------------------------------------------*/ @@ -309,8 +528,7 @@ static void grow_tests_colour8(void) { int i; int j; - image_translate_state_t resize; - image_translate_state_t *s1 = &resize; + image_translate_state_t *s; uint8_t image[50*50*3]; image_descriptor_t im; @@ -325,15 +543,15 @@ static void grow_tests_colour8(void) { for (j = 0; j < im.width; j++) { - image[i*3*im.width + 3*j + 0] = j*1200/256; - image[i*3*im.width + 3*j + 1] = j*1200/256; - image[i*3*im.width + 3*j + 2] = j*1200/256; + image[i*3*im.width + 3*j + 0] = j*1200/256 + i; + image[i*3*im.width + 3*j + 1] = j*1200/256 + i; + image[i*3*im.width + 3*j + 2] = j*1200/256 + i; } } - s1 = image_translate_init(s1, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, 200, -1, row_read, &im); - - get_flattened_image(s1, FALSE); + s = image_translate_init(NULL, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, 200, -1, row_read, &im); + get_bilevel_image(s, FALSE); + image_translate_free(s); } /*- End of function --------------------------------------------------------*/ @@ -352,8 +570,7 @@ static void lenna_tests(int output_width, int output_length_scaling, const char int16_t samples_per_pixel; int i; int n; - image_translate_state_t bw; - image_translate_state_t *s = &bw; + image_translate_state_t *s; image_descriptor_t im; float x_resolution; float y_resolution; @@ -375,7 +592,7 @@ static void lenna_tests(int output_width, int output_length_scaling, const char y_resolution = 200.0; TIFFGetField(in_file, TIFFTAG_YRESOLUTION, &y_resolution); res_unit = RESUNIT_INCH; - TIFFSetField(in_file, TIFFTAG_RESOLUTIONUNIT, &res_unit); + TIFFGetField(in_file, TIFFTAG_RESOLUTIONUNIT, &res_unit); bits_per_sample = 0; TIFFGetField(in_file, TIFFTAG_BITSPERSAMPLE, &bits_per_sample); samples_per_pixel = 0; @@ -409,7 +626,7 @@ static void lenna_tests(int output_width, int output_length_scaling, const char im.current_row = 0; im.bytes_per_pixel = samples_per_pixel; - s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_8BIT, image_width, image_length, T4_IMAGE_TYPE_BILEVEL, output_width, output_length, row_read, &im); + s = image_translate_init(NULL, T4_IMAGE_TYPE_COLOUR_8BIT, image_width, image_length, T4_IMAGE_TYPE_BILEVEL, output_width, output_length, row_read, &im); output_width = image_translate_get_output_width(s); output_length = image_translate_get_output_length(s); @@ -445,6 +662,7 @@ static void lenna_tests(int output_width, int output_length_scaling, const char TIFFWriteEncodedStrip(out_file, 0, image2, output_width*output_length/8); TIFFWriteDirectory(out_file); TIFFClose(out_file); + image_translate_free(s); } /*- End of function --------------------------------------------------------*/