Some tweaks to the image translate code

This commit is contained in:
Steve Underwood 2013-05-16 02:28:20 +08:00
parent 97faaab42c
commit 37d109b107
5 changed files with 55 additions and 37 deletions

View File

@ -48,6 +48,7 @@
#include <math.h> #include <math.h>
#endif #endif
#include "floating_fudge.h" #include "floating_fudge.h"
#include <jpeglib.h>
#include <tiffio.h> #include <tiffio.h>
#include <assert.h> #include <assert.h>
@ -648,13 +649,21 @@ SPAN_DECLARE(int) image_translate_get_output_length(image_translate_state_t *s)
} }
/*- End of function --------------------------------------------------------*/ /*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) image_translate_set_row_read_handler(image_translate_state_t *s, t4_row_read_handler_t row_read_handler, void *row_read_user_data)
{
s->row_read_handler = row_read_handler;
s->row_read_user_data = row_read_user_data;
return 0;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_state_t *s, SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_state_t *s,
int input_format,
int input_width,
int input_length,
int output_format, int output_format,
int output_width, int output_width,
int output_length, int output_length,
int input_format,
int input_width,
int input_length,
t4_row_read_handler_t row_read_handler, t4_row_read_handler_t row_read_handler,
void *row_read_user_data) void *row_read_user_data)
{ {

View File

@ -66,29 +66,37 @@ SPAN_DECLARE(int) image_translate_get_output_width(image_translate_state_t *s);
\return The length of the output image, in pixel. */ \return The length of the output image, in pixel. */
SPAN_DECLARE(int) image_translate_get_output_length(image_translate_state_t *s); SPAN_DECLARE(int) image_translate_get_output_length(image_translate_state_t *s);
/*! \brief Set the row read callback routine for an image translation context.
\param s The image translation context.
\param row_read_handler A callback routine used to pull rows of pixels from the source image
into the translation process.
\param row_read_user_data An opaque pointer passed to read_row_handler
\return 0 for success, else -1. */
SPAN_DECLARE(int) image_translate_set_row_read_handler(image_translate_state_t *s, t4_row_read_handler_t row_read_handler, void *row_read_user_data);
/*! \brief Initialise an image translation context for rescaling and squashing a gray scale /*! \brief Initialise an image translation context for rescaling and squashing a gray scale
or colour image to a bi-level FAX type image. or colour image to a bi-level FAX type image.
\param s The image translation context. \param s The image translation context.
\param input_format x \param output_format The type of output image
\param input_width The width of the source image, in pixels.
\param input_length The length of the source image, in pixels.
\param output_format x
\param output_width The width of the output image, in pixels. If this is set <= 0 the image \param output_width The width of the output image, in pixels. If this is set <= 0 the image
will not be resized. will not be resized.
\param output_length The length of the output image, in pixels. If this is set to <= 0 the \param output_length The length of the output image, in pixels. If this is set to <= 0 the
output length will be derived automatically from the width, to maintain the geometry output length will be derived automatically from the width, to maintain the geometry
of the original image. of the original image.
\param input_format The type of source image
\param input_width The width of the source image, in pixels.
\param input_length The length of the source image, in pixels.
\param row_read_handler A callback routine used to pull rows of pixels from the source image \param row_read_handler A callback routine used to pull rows of pixels from the source image
into the translation process. into the translation process.
\param row_read_user_data An opaque point passed to read_row_handler \param row_read_user_data An opaque pointer passed to read_row_handler
\return A pointer to the context, or NULL if there was a problem. */ \return A pointer to the context, or NULL if there was a problem. */
SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_state_t *s, SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_state_t *s,
int input_format,
int input_width,
int input_length,
int output_format, int output_format,
int output_width, int output_width,
int output_length, int output_length,
int input_format,
int input_width,
int input_length,
t4_row_read_handler_t row_read_handler, t4_row_read_handler_t row_read_handler,
void *row_read_user_data); void *row_read_user_data);

View File

@ -34,6 +34,7 @@ extern "C"
#endif #endif
void set_illuminant_from_code(logging_state_t *logging, lab_params_t *s, const uint8_t code[4]); void set_illuminant_from_code(logging_state_t *logging, lab_params_t *s, const uint8_t code[4]);
void set_gamut_from_code(logging_state_t *logging, lab_params_t *s, const uint8_t code[12]); void set_gamut_from_code(logging_state_t *logging, lab_params_t *s, const uint8_t code[12]);
#if defined(__cplusplus) #if defined(__cplusplus)

View File

@ -834,7 +834,7 @@ static int read_tiff_image(t4_tx_state_t *s)
{ {
/* We need to dither this image down to pure black and white, possibly resizing it /* We need to dither this image down to pure black and white, possibly resizing it
along the way. */ along the way. */
if ((translator = image_translate_init(NULL, s->tiff.image_type, s->image_width, s->image_length, T4_IMAGE_TYPE_BILEVEL, 1728, -1, row_read, s)) == NULL) if ((translator = image_translate_init(NULL, T4_IMAGE_TYPE_BILEVEL, 1728, -1, s->tiff.image_type, s->image_width, s->image_length, row_read, s)) == NULL)
return -1; return -1;
s->image_width = image_translate_get_output_width(translator); s->image_width = image_translate_get_output_width(translator);
s->image_length = image_translate_get_output_length(translator); s->image_length = image_translate_get_output_length(translator);

View File

@ -433,27 +433,27 @@ static void translate_tests_gray16(void)
printf("Dithering from a 16 bit per sample gray scale to bi-level\n"); printf("Dithering from a 16 bit per sample gray scale to bi-level\n");
create_undithered_50_by_50(&im, (uint8_t *) image, 2); create_undithered_50_by_50(&im, (uint8_t *) image, 2);
s = image_translate_init(NULL, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im); s = image_translate_init(NULL, T4_IMAGE_TYPE_BILEVEL, -1, -1, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, row_read, &im);
get_bilevel_image(s, TRUE); get_bilevel_image(s, TRUE);
printf("Scrunching from a 16 bit per sample gray scale to 8 bit per sample gray scale\n"); printf("Scrunching from a 16 bit per sample gray scale to 8 bit per sample gray scale\n");
create_undithered_50_by_50(&im, (uint8_t *) image, 2); create_undithered_50_by_50(&im, (uint8_t *) image, 2);
s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, T4_IMAGE_TYPE_GRAY_8BIT, -1, -1, row_read, &im); s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_8BIT, -1, -1, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, row_read, &im);
get_gray8_image(s, TRUE); get_gray8_image(s, TRUE);
printf("Scrunching from a 16 bit per sample gray scale to 16 bit per sample gray scale\n"); printf("Scrunching from a 16 bit per sample gray scale to 16 bit per sample gray scale\n");
create_undithered_50_by_50(&im, (uint8_t *) image, 2); create_undithered_50_by_50(&im, (uint8_t *) image, 2);
s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, T4_IMAGE_TYPE_GRAY_12BIT, -1, -1, row_read, &im); s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_12BIT, -1, -1, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, row_read, &im);
get_gray16_image(s, TRUE); get_gray16_image(s, TRUE);
printf("Scrunching from a 16 bit per sample gray scale to 3x8 bit per sample colour\n"); printf("Scrunching from a 16 bit per sample gray scale to 3x8 bit per sample colour\n");
create_undithered_50_by_50(&im, (uint8_t *) image, 2); create_undithered_50_by_50(&im, (uint8_t *) image, 2);
s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, T4_IMAGE_TYPE_COLOUR_8BIT, -1, -1, row_read, &im); s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_8BIT, -1, -1, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, row_read, &im);
get_colour8_image(s, TRUE); get_colour8_image(s, TRUE);
printf("Scrunching from a 16 bit per sample gray scale to 3x16 bit per sample colour\n"); printf("Scrunching from a 16 bit per sample gray scale to 3x16 bit per sample colour\n");
create_undithered_50_by_50(&im, (uint8_t *) image, 2); create_undithered_50_by_50(&im, (uint8_t *) image, 2);
s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, T4_IMAGE_TYPE_COLOUR_12BIT, -1, -1, row_read, &im); s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, -1, -1, T4_IMAGE_TYPE_GRAY_12BIT, im.width, im.length, row_read, &im);
get_colour16_image(s, TRUE); get_colour16_image(s, TRUE);
image_translate_free(s); image_translate_free(s);
@ -468,27 +468,27 @@ static void translate_tests_gray8(void)
printf("Dithering from a 8 bit per sample gray scale to bi-level\n"); printf("Dithering from a 8 bit per sample gray scale to bi-level\n");
create_undithered_50_by_50(&im, image, 1); create_undithered_50_by_50(&im, image, 1);
s = image_translate_init(NULL, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im); s = image_translate_init(NULL, T4_IMAGE_TYPE_BILEVEL, -1, -1, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, row_read, &im);
get_bilevel_image(s, TRUE); get_bilevel_image(s, TRUE);
printf("Scrunching from a 8 bit per sample gray scale to 8 bit per sample gray scale\n"); printf("Scrunching from a 8 bit per sample gray scale to 8 bit per sample gray scale\n");
create_undithered_50_by_50(&im, image, 1); create_undithered_50_by_50(&im, image, 1);
s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, T4_IMAGE_TYPE_GRAY_8BIT, -1, -1, row_read, &im); s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_8BIT, -1, -1, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, row_read, &im);
get_gray8_image(s, TRUE); get_gray8_image(s, TRUE);
printf("Scrunching from a 8 bit per sample gray scale to 16 bit per sample gray scale\n"); printf("Scrunching from a 8 bit per sample gray scale to 16 bit per sample gray scale\n");
create_undithered_50_by_50(&im, image, 1); create_undithered_50_by_50(&im, image, 1);
s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, T4_IMAGE_TYPE_GRAY_12BIT, -1, -1, row_read, &im); s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_12BIT, -1, -1, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, row_read, &im);
get_gray16_image(s, TRUE); get_gray16_image(s, TRUE);
printf("Scrunching from a 8 bit per sample gray scale to 3x8 bit per sample colour\n"); printf("Scrunching from a 8 bit per sample gray scale to 3x8 bit per sample colour\n");
create_undithered_50_by_50(&im, image, 1); create_undithered_50_by_50(&im, image, 1);
s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, T4_IMAGE_TYPE_COLOUR_8BIT, -1, -1, row_read, &im); s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_8BIT, -1, -1, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, row_read, &im);
get_colour8_image(s, TRUE); get_colour8_image(s, TRUE);
printf("Scrunching from a 8 bit per sample gray scale to 3x16 bit per sample colour\n"); printf("Scrunching from a 8 bit per sample gray scale to 3x16 bit per sample colour\n");
create_undithered_50_by_50(&im, image, 1); create_undithered_50_by_50(&im, image, 1);
s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, T4_IMAGE_TYPE_COLOUR_12BIT, -1, -1, row_read, &im); s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, -1, -1, T4_IMAGE_TYPE_GRAY_8BIT, im.width, im.length, row_read, &im);
get_colour16_image(s, TRUE); get_colour16_image(s, TRUE);
image_translate_free(s); image_translate_free(s);
@ -503,27 +503,27 @@ static void translate_tests_colour16(void)
printf("Dithering from a 3x16 bit per sample colour to bi-level\n"); printf("Dithering from a 3x16 bit per sample colour to bi-level\n");
create_undithered_50_by_50(&im, (uint8_t *) image, 6); create_undithered_50_by_50(&im, (uint8_t *) image, 6);
s = image_translate_init(NULL, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im); s = image_translate_init(NULL, T4_IMAGE_TYPE_BILEVEL, -1, -1, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, row_read, &im);
get_bilevel_image(s, TRUE); get_bilevel_image(s, TRUE);
printf("Scrunching from a 3x16 bit per sample colour to 8 bit per sample gray scale\n"); printf("Scrunching from a 3x16 bit per sample colour to 8 bit per sample gray scale\n");
create_undithered_50_by_50(&im, (uint8_t *) image, 6); create_undithered_50_by_50(&im, (uint8_t *) image, 6);
s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, T4_IMAGE_TYPE_GRAY_8BIT, -1, -1, row_read, &im); s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_8BIT, -1, -1, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, row_read, &im);
get_gray8_image(s, TRUE); get_gray8_image(s, TRUE);
printf("Scrunching from a 3x16 bit per sample colour to 16 bit per sample gray scale\n"); printf("Scrunching from a 3x16 bit per sample colour to 16 bit per sample gray scale\n");
create_undithered_50_by_50(&im, (uint8_t *) image, 6); create_undithered_50_by_50(&im, (uint8_t *) image, 6);
s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, T4_IMAGE_TYPE_GRAY_12BIT, -1, -1, row_read, &im); s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_12BIT, -1, -1, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, row_read, &im);
get_gray16_image(s, TRUE); get_gray16_image(s, TRUE);
printf("Scrunching from a 3x16 bit per sample colour to 3x8 bit per sample colour\n"); printf("Scrunching from a 3x16 bit per sample colour to 3x8 bit per sample colour\n");
create_undithered_50_by_50(&im, (uint8_t *) image, 6); create_undithered_50_by_50(&im, (uint8_t *) image, 6);
s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, T4_IMAGE_TYPE_COLOUR_8BIT, -1, -1, row_read, &im); s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_8BIT, -1, -1, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, row_read, &im);
get_colour8_image(s, TRUE); get_colour8_image(s, TRUE);
printf("Scrunching from a 3x16 bit per sample colour to 3x16 bit per sample colour\n"); printf("Scrunching from a 3x16 bit per sample colour to 3x16 bit per sample colour\n");
create_undithered_50_by_50(&im, (uint8_t *) image, 6); create_undithered_50_by_50(&im, (uint8_t *) image, 6);
s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, T4_IMAGE_TYPE_COLOUR_12BIT, -1, -1, row_read, &im); s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, -1, -1, T4_IMAGE_TYPE_COLOUR_12BIT, im.width, im.length, row_read, &im);
get_colour16_image(s, TRUE); get_colour16_image(s, TRUE);
image_translate_free(s); image_translate_free(s);
@ -538,27 +538,27 @@ static void translate_tests_colour8(void)
printf("Dithering from a 3x8 bit per sample colour to bi-level\n"); printf("Dithering from a 3x8 bit per sample colour to bi-level\n");
create_undithered_50_by_50(&im, image, 3); create_undithered_50_by_50(&im, image, 3);
s = image_translate_init(NULL, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, -1, -1, row_read, &im); s = image_translate_init(NULL, T4_IMAGE_TYPE_BILEVEL, -1, -1, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, row_read, &im);
get_bilevel_image(s, TRUE); get_bilevel_image(s, TRUE);
printf("Scrunching from a 3x8 bit per sample colour to 8 bit per sample gray scale\n"); printf("Scrunching from a 3x8 bit per sample colour to 8 bit per sample gray scale\n");
create_undithered_50_by_50(&im, image, 3); create_undithered_50_by_50(&im, image, 3);
s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, T4_IMAGE_TYPE_GRAY_8BIT, -1, -1, row_read, &im); s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_8BIT, -1, -1, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, row_read, &im);
get_gray8_image(s, TRUE); get_gray8_image(s, TRUE);
printf("Scrunching from a 3x8 bit per sample colour to 16 bit per sample gray scale\n"); printf("Scrunching from a 3x8 bit per sample colour to 16 bit per sample gray scale\n");
create_undithered_50_by_50(&im, image, 3); create_undithered_50_by_50(&im, image, 3);
s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, T4_IMAGE_TYPE_GRAY_12BIT, -1, -1, row_read, &im); s = image_translate_init(s, T4_IMAGE_TYPE_GRAY_12BIT, -1, -1, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, row_read, &im);
get_gray16_image(s, TRUE); get_gray16_image(s, TRUE);
printf("Scrunching from a 3x8 bit per sample colour to 3x8 bit per sample colour\n"); printf("Scrunching from a 3x8 bit per sample colour to 3x8 bit per sample colour\n");
create_undithered_50_by_50(&im, image, 3); create_undithered_50_by_50(&im, image, 3);
s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, T4_IMAGE_TYPE_COLOUR_8BIT, -1, -1, row_read, &im); s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_8BIT, -1, -1, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, row_read, &im);
get_colour8_image(s, TRUE); get_colour8_image(s, TRUE);
printf("Scrunching from a 3x8 bit per sample colour to 3x16 bit per sample colour\n"); printf("Scrunching from a 3x8 bit per sample colour to 3x16 bit per sample colour\n");
create_undithered_50_by_50(&im, image, 3); create_undithered_50_by_50(&im, image, 3);
s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, T4_IMAGE_TYPE_COLOUR_12BIT, -1, -1, row_read, &im); s = image_translate_init(s, T4_IMAGE_TYPE_COLOUR_12BIT, -1, -1, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, row_read, &im);
get_colour16_image(s, TRUE); get_colour16_image(s, TRUE);
image_translate_free(s); image_translate_free(s);
@ -574,7 +574,7 @@ static void grow_tests_colour8(void)
printf("Image growth tests\n"); printf("Image growth tests\n");
create_undithered_50_by_50(&im, image, 3); create_undithered_50_by_50(&im, image, 3);
s = image_translate_init(NULL, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, T4_IMAGE_TYPE_BILEVEL, 200, -1, row_read, &im); s = image_translate_init(NULL, T4_IMAGE_TYPE_BILEVEL, 200, -1, T4_IMAGE_TYPE_COLOUR_8BIT, im.width, im.length, row_read, &im);
get_bilevel_image(s, FALSE); get_bilevel_image(s, FALSE);
image_translate_free(s); image_translate_free(s);
} }
@ -669,20 +669,20 @@ static void lenna_tests(int output_width, int output_length_scaling, const char
switch (output_length_scaling) switch (output_length_scaling)
{ {
case -2: case -2:
s = image_translate_init(NULL, T4_IMAGE_TYPE_COLOUR_8BIT, image_width, image_length, T4_IMAGE_TYPE_GRAY_8BIT, output_width, output_length, row_read, &im); s = image_translate_init(NULL, T4_IMAGE_TYPE_GRAY_8BIT, output_width, output_length, T4_IMAGE_TYPE_COLOUR_8BIT, image_width, image_length, row_read, &im);
output_width = image_translate_get_output_width(s); output_width = image_translate_get_output_width(s);
output_length = image_translate_get_output_length(s); output_length = image_translate_get_output_length(s);
s2 = image_translate_init(NULL, T4_IMAGE_TYPE_GRAY_8BIT, output_width, output_length, T4_IMAGE_TYPE_COLOUR_8BIT, -1, -1, row_read2, s); s2 = image_translate_init(NULL, T4_IMAGE_TYPE_COLOUR_8BIT, -1, -1, T4_IMAGE_TYPE_GRAY_8BIT, output_width, output_length, row_read2, s);
output_width = image_translate_get_output_width(s2); output_width = image_translate_get_output_width(s2);
output_length = image_translate_get_output_length(s2); output_length = image_translate_get_output_length(s2);
break; break;
case -1: case -1:
s = image_translate_init(NULL, T4_IMAGE_TYPE_COLOUR_8BIT, image_width, image_length, T4_IMAGE_TYPE_COLOUR_8BIT, output_width, output_length, row_read, &im); s = image_translate_init(NULL, T4_IMAGE_TYPE_COLOUR_8BIT, output_width, output_length, T4_IMAGE_TYPE_COLOUR_8BIT, image_width, image_length, row_read, &im);
output_width = image_translate_get_output_width(s); output_width = image_translate_get_output_width(s);
output_length = image_translate_get_output_length(s); output_length = image_translate_get_output_length(s);
break; break;
default: default:
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); s = image_translate_init(NULL, T4_IMAGE_TYPE_BILEVEL, output_width, output_length, T4_IMAGE_TYPE_COLOUR_8BIT, image_width, image_length, row_read, &im);
output_width = image_translate_get_output_width(s); output_width = image_translate_get_output_width(s);
output_length = image_translate_get_output_length(s); output_length = image_translate_get_output_length(s);
break; break;