📄 dither.c
字号:
/* * ordered dither rotines * * stolen from The GIMP and trimmed for speed * */#include <stdlib.h>#include "dither.h"#define DITHER_LEVEL 8static long red_mult, green_mult;static long red_dither[256];static long green_dither[256];static long blue_dither[256];static long gray_dither[256];typedef unsigned long vector[DITHER_LEVEL];typedef vector matrix[DITHER_LEVEL];#if DITHER_LEVEL == 8#define DITHER_MASK 7static matrix DM ={ {0, 32, 8, 40, 2, 34, 10, 42}, {48, 16, 56, 24, 50, 18, 58, 26}, {12, 44, 4, 36, 14, 46, 6, 38}, {60, 28, 52, 20, 62, 30, 54, 22}, {3, 35, 11, 43, 1, 33, 9, 41}, {51, 19, 59, 27, 49, 17, 57, 25}, {15, 47, 7, 39, 13, 45, 5, 37}, {63, 31, 55, 23, 61, 29, 53, 21}};#endif#if DITHER_LEVEL == 4#define DITHER_MASK 3static matrix DM ={ {0, 8, 2, 10}, {12, 4, 14, 6}, {3, 11, 1, 9}, {15, 7, 13, 5}};#endifvoidinit_dither(int shades_r, int shades_g, int shades_b, int shades_gray){ int i, j; unsigned char low_shade, high_shade; unsigned short index; float red_colors_per_shade; float green_colors_per_shade; float blue_colors_per_shade; float gray_colors_per_shade; red_mult = shades_g * shades_b; green_mult = shades_b; red_colors_per_shade = 256.0 / (shades_r - 1); green_colors_per_shade = 256.0 / (shades_g - 1); blue_colors_per_shade = 256.0 / (shades_b - 1); gray_colors_per_shade = 256.0 / (shades_gray - 1); /* this avoids a shift when checking these values */ for (i = 0; i < DITHER_LEVEL; i++) for (j = 0; j < DITHER_LEVEL; j++) DM[i][j] *= 0x10000; /* setup arrays containing three bytes of information for red, green, & blue */ /* the arrays contain : * 1st byte: low end shade value * 2nd byte: high end shade value * 3rd & 4th bytes: ordered dither matrix index */ for (i = 0; i < 256; i++) { /* setup the red information */ { low_shade = (unsigned char) (i / red_colors_per_shade); high_shade = low_shade + 1; index = (unsigned short) (((i - low_shade * red_colors_per_shade) / red_colors_per_shade) * (DITHER_LEVEL * DITHER_LEVEL + 1)); low_shade *= red_mult; high_shade *= red_mult; red_dither[i] = (index << 16) + (high_shade << 8) + (low_shade); } /* setup the green information */ { low_shade = (unsigned char) (i / green_colors_per_shade); high_shade = low_shade + 1; index = (unsigned short) (((i - low_shade * green_colors_per_shade) / green_colors_per_shade) * (DITHER_LEVEL * DITHER_LEVEL + 1)); low_shade *= green_mult; high_shade *= green_mult; green_dither[i] = (index << 16) + (high_shade << 8) + (low_shade); } /* setup the blue information */ { low_shade = (unsigned char) (i / blue_colors_per_shade); high_shade = low_shade + 1; index = (unsigned short) (((i - low_shade * blue_colors_per_shade) / blue_colors_per_shade) * (DITHER_LEVEL * DITHER_LEVEL + 1)); blue_dither[i] = (index << 16) + (high_shade << 8) + (low_shade); } /* setup the gray information */ { low_shade = (unsigned char) (i / gray_colors_per_shade); high_shade = low_shade + 1; index = (unsigned short) (((i - low_shade * gray_colors_per_shade) / gray_colors_per_shade) * (DITHER_LEVEL * DITHER_LEVEL + 1)); gray_dither[i] = (index << 16) + (high_shade << 8) + (low_shade); } }}voiddither_line(unsigned char *src, unsigned char *dest, int y, int width){ register long a, b; long *ymod, xmod; ymod = DM[y & DITHER_MASK]; while (width--) { xmod = width & DITHER_MASK; b = red_dither[*(src++)]; if (ymod[xmod] < b) b >>= 8; a = green_dither[*(src++)]; if (ymod[xmod] < a) a >>= 8; b += a; a = blue_dither[*(src++)]; if (ymod[xmod] < a) a >>= 8; b += a; *(dest++) = b & 0xff; }}voiddither_line_gray(unsigned char *src, unsigned char *dest, int y, int width){ long *ymod, xmod; register long a; ymod = DM[y & DITHER_MASK]; while (width--) { xmod = width & DITHER_MASK; a = gray_dither[*(src++)]; if (ymod[xmod] < a) a >>= 8; *(dest++) = a & 0xff; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -