diff options
author | Roger Leigh <rleigh@debian.org> | 2008-10-26 16:11:05 +0000 |
---|---|---|
committer | Roger Leigh <rleigh@debian.org> | 2008-10-26 16:11:05 +0000 |
commit | 3b59bb0a607ec27ea60f07d1cd5d1bbb4483c832 (patch) | |
tree | c119edaa8374e7b6387de7aa7d65b143732af5db /src/main/print-dither-matrices.c | |
parent | eb5718390731a9746c556317e641320b671f2091 (diff) |
Imported Upstream version 4.2.7
Diffstat (limited to 'src/main/print-dither-matrices.c')
-rw-r--r-- | src/main/print-dither-matrices.c | 241 |
1 files changed, 238 insertions, 3 deletions
diff --git a/src/main/print-dither-matrices.c b/src/main/print-dither-matrices.c index 92ef667..531d1f1 100644 --- a/src/main/print-dither-matrices.c +++ b/src/main/print-dither-matrices.c @@ -1,5 +1,5 @@ /* - * "$Id: print-dither-matrices.c,v 1.4 2001/09/08 17:13:48 rleigh Exp $" + * "$Id: print-dither-matrices.c,v 1.4.4.1 2002/05/03 01:30:28 rlk Exp $" * * Print plug-in driver utility functions for the GIMP. * @@ -27,8 +27,12 @@ #ifdef HAVE_CONFIG_H #include <config.h> #endif -#include <gimp-print/gimp-print.h> -#include "gimp-print-internal.h" +#include "print-dither.h" +#include <math.h> + +#ifdef __GNUC__ +#define inline __inline__ +#endif static const unsigned short mat_1_1[] = { @@ -59,3 +63,234 @@ const stp_dither_matrix_short_t stp_4_1_matrix = { 509, 131, 2, 1, mat_4_1 }; + +static inline int +calc_ordered_point(unsigned x, unsigned y, int steps, int multiplier, + int size, const unsigned *map) +{ + int i, j; + unsigned retval = 0; + int divisor = 1; + int div1; + for (i = 0; i < steps; i++) + { + int xa = (x / divisor) % size; + int ya = (y / divisor) % size; + unsigned base; + base = map[ya + (xa * size)]; + div1 = 1; + for (j = i; j < steps - 1; j++) + div1 *= size * size; + retval += base * div1; + divisor *= size; + } + return retval * multiplier; +} + +static int +is_po2(size_t i) +{ + if (i == 0) + return 0; + return (((i & (i - 1)) == 0) ? 1 : 0); +} + +void +stp_init_iterated_matrix(dither_matrix_t *mat, size_t size, size_t exp, + const unsigned *array) +{ + int i; + int x, y; + mat->base = size; + mat->exp = exp; + mat->x_size = 1; + for (i = 0; i < exp; i++) + mat->x_size *= mat->base; + mat->y_size = mat->x_size; + mat->total_size = mat->x_size * mat->y_size; + mat->matrix = stp_malloc(sizeof(unsigned) * mat->x_size * mat->y_size); + for (x = 0; x < mat->x_size; x++) + for (y = 0; y < mat->y_size; y++) + { + mat->matrix[x + y * mat->x_size] = + calc_ordered_point(x, y, mat->exp, 1, mat->base, array); + mat->matrix[x + y * mat->x_size] = + (double) mat->matrix[x + y * mat->x_size] * 65536.0 / + (double) (mat->x_size * mat->y_size); + } + mat->last_x = mat->last_x_mod = 0; + mat->last_y = mat->last_y_mod = 0; + mat->index = 0; + mat->i_own = 1; + if (is_po2(mat->x_size)) + mat->fast_mask = mat->x_size - 1; + else + mat->fast_mask = 0; +} + +#define MATRIX_POINT(m, x, y, x_size, y_size) \ + ((m)[(((x) + (x_size)) % (x_size)) + ((x_size) * (((y) + (y_size)) % (y_size)))]) + +void +stp_shear_matrix(dither_matrix_t *mat, int x_shear, int y_shear) +{ + int i; + int j; + int *tmp = stp_malloc(mat->x_size * mat->y_size * sizeof(int)); + for (i = 0; i < mat->x_size; i++) + for (j = 0; j < mat->y_size; j++) + MATRIX_POINT(tmp, i, j, mat->x_size, mat->y_size) = + MATRIX_POINT(mat->matrix, i, j * (x_shear + 1), mat->x_size, + mat->y_size); + for (i = 0; i < mat->x_size; i++) + for (j = 0; j < mat->y_size; j++) + MATRIX_POINT(mat->matrix, i, j, mat->x_size, mat->y_size) = + MATRIX_POINT(tmp, i * (y_shear + 1), j, mat->x_size, mat->y_size); + stp_free(tmp); +} + +void +stp_init_matrix(dither_matrix_t *mat, int x_size, int y_size, + const unsigned int *array, int transpose, int prescaled) +{ + int x, y; + mat->base = x_size; + mat->exp = 1; + mat->x_size = x_size; + mat->y_size = y_size; + mat->total_size = mat->x_size * mat->y_size; + mat->matrix = stp_malloc(sizeof(unsigned) * mat->x_size * mat->y_size); + for (x = 0; x < mat->x_size; x++) + for (y = 0; y < mat->y_size; y++) + { + if (transpose) + mat->matrix[x + y * mat->x_size] = array[y + x * mat->y_size]; + else + mat->matrix[x + y * mat->x_size] = array[x + y * mat->x_size]; + if (!prescaled) + mat->matrix[x + y * mat->x_size] = + (double) mat->matrix[x + y * mat->x_size] * 65536.0 / + (double) (mat->x_size * mat->y_size); + } + mat->last_x = mat->last_x_mod = 0; + mat->last_y = mat->last_y_mod = 0; + mat->index = 0; + mat->i_own = 1; + if (is_po2(mat->x_size)) + mat->fast_mask = mat->x_size - 1; + else + mat->fast_mask = 0; +} + +void +stp_init_matrix_short(dither_matrix_t *mat, int x_size, int y_size, + const unsigned short *array, int transpose, + int prescaled) +{ + int x, y; + mat->base = x_size; + mat->exp = 1; + mat->x_size = x_size; + mat->y_size = y_size; + mat->total_size = mat->x_size * mat->y_size; + mat->matrix = stp_malloc(sizeof(unsigned) * mat->x_size * mat->y_size); + for (x = 0; x < mat->x_size; x++) + for (y = 0; y < mat->y_size; y++) + { + if (transpose) + mat->matrix[x + y * mat->x_size] = array[y + x * mat->y_size]; + else + mat->matrix[x + y * mat->x_size] = array[x + y * mat->x_size]; + if (!prescaled) + mat->matrix[x + y * mat->x_size] = + (double) mat->matrix[x + y * mat->x_size] * 65536.0 / + (double) (mat->x_size * mat->y_size); + } + mat->last_x = mat->last_x_mod = 0; + mat->last_y = mat->last_y_mod = 0; + mat->index = 0; + mat->i_own = 1; + if (is_po2(mat->x_size)) + mat->fast_mask = mat->x_size - 1; + else + mat->fast_mask = 0; +} + +void +stp_destroy_matrix(dither_matrix_t *mat) +{ + if (mat->i_own && mat->matrix) + stp_free(mat->matrix); + mat->matrix = NULL; + mat->base = 0; + mat->exp = 0; + mat->x_size = 0; + mat->y_size = 0; + mat->total_size = 0; + mat->i_own = 0; +} + +void +stp_clone_matrix(const dither_matrix_t *src, dither_matrix_t *dest, + int x_offset, int y_offset) +{ + dest->base = src->base; + dest->exp = src->exp; + dest->x_size = src->x_size; + dest->y_size = src->y_size; + dest->total_size = src->total_size; + dest->matrix = src->matrix; + dest->x_offset = x_offset; + dest->y_offset = y_offset; + dest->last_x = 0; + dest->last_x_mod = dest->x_offset % dest->x_size; + dest->last_y = 0; + dest->last_y_mod = dest->x_size * (dest->y_offset % dest->y_size); + dest->index = dest->last_x_mod + dest->last_y_mod; + dest->fast_mask = src->fast_mask; + dest->i_own = 0; +} + +void +stp_copy_matrix(const dither_matrix_t *src, dither_matrix_t *dest) +{ + int x; + dest->base = src->base; + dest->exp = src->exp; + dest->x_size = src->x_size; + dest->y_size = src->y_size; + dest->total_size = src->total_size; + dest->matrix = stp_malloc(sizeof(unsigned) * dest->x_size * dest->y_size); + for (x = 0; x < dest->x_size * dest->y_size; x++) + dest->matrix[x] = src->matrix[x]; + dest->x_offset = 0; + dest->y_offset = 0; + dest->last_x = 0; + dest->last_x_mod = 0; + dest->last_y = 0; + dest->last_y_mod = 0; + dest->index = 0; + dest->fast_mask = src->fast_mask; + dest->i_own = 1; +} + +void +stp_exponential_scale_matrix(dither_matrix_t *mat, double exponent) +{ + int i; + int mat_size = mat->x_size * mat->y_size; + for (i = 0; i < mat_size; i++) + { + double dd = mat->matrix[i] / 65535.0; + dd = pow(dd, exponent); + mat->matrix[i] = 65535 * dd; + } +} + +void +stp_matrix_set_row(dither_matrix_t *mat, int y) +{ + mat->last_y = y; + mat->last_y_mod = mat->x_size * ((y + mat->y_offset) % mat->y_size); + mat->index = mat->last_x_mod + mat->last_y_mod; +} |