| 1 | /*
|
|---|
| 2 |
|
|---|
| 3 | gbmerr.c - Error diffusion Module
|
|---|
| 4 |
|
|---|
| 5 | */
|
|---|
| 6 |
|
|---|
| 7 | /*...sincludes:0:*/
|
|---|
| 8 | #include <stdio.h>
|
|---|
| 9 | #include <stddef.h>
|
|---|
| 10 | #include <stdlib.h>
|
|---|
| 11 | #include <string.h>
|
|---|
| 12 | #include "gbm.h"
|
|---|
| 13 |
|
|---|
| 14 | /*...vgbm\46\h:0:*/
|
|---|
| 15 | /*...e*/
|
|---|
| 16 | /*...svars:0:*/
|
|---|
| 17 | static BOOLEAN inited = FALSE;
|
|---|
| 18 |
|
|---|
| 19 | /*
|
|---|
| 20 | Tables used for quick saturated addition and subtraction.
|
|---|
| 21 | */
|
|---|
| 22 |
|
|---|
| 23 | static byte usat[256+256+256];
|
|---|
| 24 | #define U_SAT_ADD(a,b) usat[(a)+(b)+256]
|
|---|
| 25 |
|
|---|
| 26 | static short ssat[256+256+256+256];
|
|---|
| 27 | #define S_SAT_ADD(a,b) ssat[(a)+(b)+512]
|
|---|
| 28 |
|
|---|
| 29 | /*
|
|---|
| 30 | For 6Rx6Gx6B, 7Rx8Gx4B palettes etc.
|
|---|
| 31 | */
|
|---|
| 32 |
|
|---|
| 33 | static byte index4[0x100];
|
|---|
| 34 | static byte index6[0x100];
|
|---|
| 35 | static byte index7[0x100];
|
|---|
| 36 | static byte index8[0x100];
|
|---|
| 37 | static byte index16[0x100];
|
|---|
| 38 | static byte scale4[] = { 0, 85, 170, 255 };
|
|---|
| 39 | static byte scale6[] = { 0, 51, 102, 153, 204, 255 };
|
|---|
| 40 | static byte scale7[] = { 0, 43, 85, 128, 170, 213, 255 };
|
|---|
| 41 | static byte scale8[] = { 0, 36, 73, 109, 146, 182, 219, 255 };
|
|---|
| 42 | static byte scale16[] = { 0, 17, 34, 51, 68, 85, 102, 119, 136,
|
|---|
| 43 | 153, 170, 187, 204, 221, 238, 255 };
|
|---|
| 44 |
|
|---|
| 45 | static word randtab[0x100];
|
|---|
| 46 | static int randinx = 0;
|
|---|
| 47 | /*...e*/
|
|---|
| 48 | /*...sinit:0:*/
|
|---|
| 49 | /*
|
|---|
| 50 | This function initialises this module.
|
|---|
| 51 | It does this by preparing the quick saturated addition and subraction tables.
|
|---|
| 52 | */
|
|---|
| 53 |
|
|---|
| 54 | /*...snearest_inx:0:*/
|
|---|
| 55 | #ifndef abs
|
|---|
| 56 | #define abs(x) (((x)>=0)?(x):-(x))
|
|---|
| 57 | #endif
|
|---|
| 58 |
|
|---|
| 59 | static byte nearest_inx(byte value, const byte ab[], unsigned short cb)
|
|---|
| 60 | {
|
|---|
| 61 | byte b, inx, inx_min;
|
|---|
| 62 | short diff, diff_min;
|
|---|
| 63 |
|
|---|
| 64 | b = ab[0];
|
|---|
| 65 | diff_min = abs((short) value - (short) b);
|
|---|
| 66 | inx_min = 0;
|
|---|
| 67 | for ( inx = 1; (unsigned short) inx < cb; inx++ )
|
|---|
| 68 | {
|
|---|
| 69 | b = ab[inx];
|
|---|
| 70 | diff = abs((short) value - (short) b);
|
|---|
| 71 | if ( diff < diff_min )
|
|---|
| 72 | {
|
|---|
| 73 | diff_min = diff;
|
|---|
| 74 | inx_min = inx;
|
|---|
| 75 | }
|
|---|
| 76 | }
|
|---|
| 77 | return inx_min;
|
|---|
| 78 | }
|
|---|
| 79 | /*...e*/
|
|---|
| 80 |
|
|---|
| 81 | static void init(void)
|
|---|
| 82 | {
|
|---|
| 83 | int i;
|
|---|
| 84 |
|
|---|
| 85 | if ( inited )
|
|---|
| 86 | return;
|
|---|
| 87 |
|
|---|
| 88 | memset(usat, 0, 0x100);
|
|---|
| 89 | for ( i = 0; i < 0x100; i++ )
|
|---|
| 90 | usat[i + 0x100] = (byte) i;
|
|---|
| 91 | memset(usat + 0x200, 0xff, 0x100);
|
|---|
| 92 |
|
|---|
| 93 | for ( i = -0x200; i < -0x100; i++ )
|
|---|
| 94 | ssat[i + 0x200] = -0x100;
|
|---|
| 95 | for ( i = -0x100; i < 0x100; i++ )
|
|---|
| 96 | ssat[i + 0x200] = i;
|
|---|
| 97 | for ( i = 0x100; i < 0x200; i++ )
|
|---|
| 98 | ssat[i + 0x200] = 0xff;
|
|---|
| 99 |
|
|---|
| 100 | /* For 7 Red x 8 Green x 4 Blue palettes etc. */
|
|---|
| 101 |
|
|---|
| 102 | for ( i = 0; i < 0x100; i++ )
|
|---|
| 103 | {
|
|---|
| 104 | index4 [i] = nearest_inx((byte) i, scale4 , sizeof(scale4 ));
|
|---|
| 105 | index6 [i] = nearest_inx((byte) i, scale6 , sizeof(scale6 ));
|
|---|
| 106 | index7 [i] = nearest_inx((byte) i, scale7 , sizeof(scale7 ));
|
|---|
| 107 | index8 [i] = nearest_inx((byte) i, scale8 , sizeof(scale8 ));
|
|---|
| 108 | index16[i] = nearest_inx((byte) i, scale16, sizeof(scale16));
|
|---|
| 109 | }
|
|---|
| 110 |
|
|---|
| 111 | /* For faster random number calculation */
|
|---|
| 112 |
|
|---|
| 113 | for ( i = 0; i < 0x100; i++ )
|
|---|
| 114 | randtab [i] = (word) (rand() % (51*0x100));
|
|---|
| 115 |
|
|---|
| 116 | inited = TRUE;
|
|---|
| 117 | }
|
|---|
| 118 | /*...e*/
|
|---|
| 119 | /*...serrdiff:0:*/
|
|---|
| 120 | static BOOLEAN errdiff(
|
|---|
| 121 | const GBM *gbm, const byte *src, byte *dest,
|
|---|
| 122 | int dest_bpp,
|
|---|
| 123 | void (*errdiff_line)(byte *src, byte *dest, short *errs, int cx)
|
|---|
| 124 | )
|
|---|
| 125 | {
|
|---|
| 126 | int stride_src = ((gbm->w * 3 + 3) & ~3);
|
|---|
| 127 | int stride_dest = ((gbm->w * dest_bpp + 31) / 32) * 4;
|
|---|
| 128 | byte *buf;
|
|---|
| 129 | short *errs;
|
|---|
| 130 | int y;
|
|---|
| 131 |
|
|---|
| 132 | if ( (buf = malloc((size_t) stride_src + 3)) == NULL )
|
|---|
| 133 | return FALSE;
|
|---|
| 134 |
|
|---|
| 135 | if ( (errs = malloc((size_t) ((gbm->w + 1) * 3 * sizeof(short)))) == NULL )
|
|---|
| 136 | {
|
|---|
| 137 | free(buf);
|
|---|
| 138 | return FALSE;
|
|---|
| 139 | }
|
|---|
| 140 |
|
|---|
| 141 | memset(errs, 0, (gbm->w + 1) * 3 * sizeof(short));
|
|---|
| 142 |
|
|---|
| 143 | for ( y = 0; y < gbm->h; y++ )
|
|---|
| 144 | {
|
|---|
| 145 | memcpy(buf, src + y * stride_src, stride_src);
|
|---|
| 146 | (*errdiff_line)(buf, dest + y * stride_dest, errs, gbm->w);
|
|---|
| 147 | }
|
|---|
| 148 |
|
|---|
| 149 | free(buf);
|
|---|
| 150 | free(errs);
|
|---|
| 151 |
|
|---|
| 152 | return TRUE;
|
|---|
| 153 | }
|
|---|
| 154 | /*...e*/
|
|---|
| 155 |
|
|---|
| 156 | /*...sgbm_errdiff_line_24 \45\ error diffuse to fewer bits per pixel one line:0:*/
|
|---|
| 157 | /*
|
|---|
| 158 | This function takes a line of RGB data, a destination buffer and a buffer of
|
|---|
| 159 | error terms and performs one lines worth (a given # of pixels) of error
|
|---|
| 160 | diffusion.
|
|---|
| 161 | */
|
|---|
| 162 |
|
|---|
| 163 | void gbm_errdiff_line_24(byte *src, byte *dest, short *errs, int cx, byte rm, byte gm, byte bm)
|
|---|
| 164 | {
|
|---|
| 165 | int x, ptr = 0;
|
|---|
| 166 |
|
|---|
| 167 | init();
|
|---|
| 168 |
|
|---|
| 169 | /* Step 1: Add error terms to newly supplied line */
|
|---|
| 170 |
|
|---|
| 171 | for ( x = 0; x < cx * 3; x++ )
|
|---|
| 172 | src[x] = U_SAT_ADD((int) src[x], (int) errs[x]);
|
|---|
| 173 |
|
|---|
| 174 | /* Step 2: Zero out error terms */
|
|---|
| 175 |
|
|---|
| 176 | memset(errs, 0, cx * 3 * sizeof(errs[0]));
|
|---|
| 177 |
|
|---|
| 178 | /* Step 3: Go along data, finding nearest colour and propagating error */
|
|---|
| 179 |
|
|---|
| 180 | randinx = rand();
|
|---|
| 181 |
|
|---|
| 182 | for ( x = 0; x < cx; x++ )
|
|---|
| 183 | {
|
|---|
| 184 | byte b = *src++;
|
|---|
| 185 | byte g = *src++;
|
|---|
| 186 | byte r = *src++;
|
|---|
| 187 | byte bi = (b & bm);
|
|---|
| 188 | byte gi = (g & gm);
|
|---|
| 189 | byte ri = (r & rm);
|
|---|
| 190 | int be = b - (int) bi;
|
|---|
| 191 | int ge = g - (int) gi;
|
|---|
| 192 | int re = r - (int) ri;
|
|---|
| 193 | word rn = randtab[(byte) (randinx++)];
|
|---|
| 194 | int right = (rn >> 8);
|
|---|
| 195 | int down = ((rn & 0xff) % (63 - right));
|
|---|
| 196 | int be1 = ((be * right) >> 6);
|
|---|
| 197 | int ge1 = ((ge * right) >> 6);
|
|---|
| 198 | int re1 = ((re * right) >> 6);
|
|---|
| 199 | int be2 = ((be * down ) >> 6);
|
|---|
| 200 | int ge2 = ((ge * down ) >> 6);
|
|---|
| 201 | int re2 = ((re * down ) >> 6);
|
|---|
| 202 | int be3 = be - be1 - be2;
|
|---|
| 203 | int ge3 = ge - ge1 - ge2;
|
|---|
| 204 | int re3 = re - re1 - re2;
|
|---|
| 205 |
|
|---|
| 206 | *dest++ = bi;
|
|---|
| 207 | *dest++ = gi;
|
|---|
| 208 | *dest++ = ri;
|
|---|
| 209 |
|
|---|
| 210 | src[0] = U_SAT_ADD((int) src[0], be1);
|
|---|
| 211 | src[1] = U_SAT_ADD((int) src[1], ge1);
|
|---|
| 212 | src[2] = U_SAT_ADD((int) src[2], re1);
|
|---|
| 213 |
|
|---|
| 214 | errs[ptr ] = S_SAT_ADD((int) errs[ptr ], be2);
|
|---|
| 215 | errs[ptr + 1] = S_SAT_ADD((int) errs[ptr + 1], ge2);
|
|---|
| 216 | errs[ptr + 2] = S_SAT_ADD((int) errs[ptr + 2], re2);
|
|---|
| 217 |
|
|---|
| 218 | ptr += 3;
|
|---|
| 219 |
|
|---|
| 220 | errs[ptr ] = S_SAT_ADD((int) errs[ptr ], be3);
|
|---|
| 221 | errs[ptr + 1] = S_SAT_ADD((int) errs[ptr + 1], ge3);
|
|---|
| 222 | errs[ptr + 2] = S_SAT_ADD((int) errs[ptr + 2], re3);
|
|---|
| 223 | }
|
|---|
| 224 | }
|
|---|
| 225 | /*...e*/
|
|---|
| 226 | /*...sgbm_errdiff_24 \45\ error diffuse to fewer bits per pixel:0:*/
|
|---|
| 227 | BOOLEAN gbm_errdiff_24(const GBM *gbm, const byte *data24, byte *data24a, byte rm, byte gm, byte bm)
|
|---|
| 228 | {
|
|---|
| 229 | int stride = ((gbm->w * 3 + 3) & ~3);
|
|---|
| 230 | byte *buf;
|
|---|
| 231 | short *errs;
|
|---|
| 232 | int y;
|
|---|
| 233 |
|
|---|
| 234 | if ( (buf = malloc((size_t) (stride + 3))) == NULL )
|
|---|
| 235 | return FALSE;
|
|---|
| 236 |
|
|---|
| 237 | if ( (errs = malloc((size_t) ((gbm->w + 1) * 3 * sizeof(short)))) == NULL )
|
|---|
| 238 | {
|
|---|
| 239 | free(buf);
|
|---|
| 240 | return FALSE;
|
|---|
| 241 | }
|
|---|
| 242 |
|
|---|
| 243 | memset(errs, 0, (gbm->w + 1) * 3 * sizeof(short));
|
|---|
| 244 |
|
|---|
| 245 | for ( y = 0; y < gbm->h; y++ )
|
|---|
| 246 | {
|
|---|
| 247 | memcpy(buf, data24 + y * stride, stride);
|
|---|
| 248 | gbm_errdiff_line_24(buf, data24a + y * stride, errs, gbm->w, rm, gm, bm);
|
|---|
| 249 | }
|
|---|
| 250 |
|
|---|
| 251 | free(buf);
|
|---|
| 252 | free(errs);
|
|---|
| 253 |
|
|---|
| 254 | return TRUE;
|
|---|
| 255 | }
|
|---|
| 256 | /*...e*/
|
|---|
| 257 |
|
|---|
| 258 | /*...sgbm_errdiff_pal_6R6G6B \45\ return 6Rx6Gx6B palette:0:*/
|
|---|
| 259 | /*
|
|---|
| 260 | This function makes the palette for the 6 red x 6 green x 6 blue palette.
|
|---|
| 261 | 216 palette entrys used. Remaining 40 left blank.
|
|---|
| 262 | */
|
|---|
| 263 |
|
|---|
| 264 | void gbm_errdiff_pal_6R6G6B(GBMRGB *gbmrgb)
|
|---|
| 265 | {
|
|---|
| 266 | byte volatile r; /* C-Set/2 optimiser fix */
|
|---|
| 267 | byte volatile g;
|
|---|
| 268 | byte volatile b;
|
|---|
| 269 |
|
|---|
| 270 | init();
|
|---|
| 271 | memset(gbmrgb, 0x80, 0x100 * sizeof(GBMRGB));
|
|---|
| 272 | for ( r = 0; r < 6; r++ )
|
|---|
| 273 | for ( g = 0; g < 6; g++ )
|
|---|
| 274 | for ( b = 0; b < 6; b++ )
|
|---|
| 275 | {
|
|---|
| 276 | gbmrgb->r = scale6[r];
|
|---|
| 277 | gbmrgb->g = scale6[g];
|
|---|
| 278 | gbmrgb->b = scale6[b];
|
|---|
| 279 | gbmrgb++;
|
|---|
| 280 | }
|
|---|
| 281 | }
|
|---|
| 282 | /*...e*/
|
|---|
| 283 | /*...sgbm_errdiff_line_6R6G6B \45\ error diffuse to 6Rx6Gx6B one line:0:*/
|
|---|
| 284 | /*
|
|---|
| 285 | This function takes a line of RGB data, a destination buffer and a buffer of
|
|---|
| 286 | error terms and performs one lines worth (a given # of pixels) of error
|
|---|
| 287 | diffusion.
|
|---|
| 288 | */
|
|---|
| 289 |
|
|---|
| 290 | void gbm_errdiff_line_6R6G6B(byte *src, byte *dest, short *errs, int cx)
|
|---|
| 291 | {
|
|---|
| 292 | int x, ptr = 0;
|
|---|
| 293 |
|
|---|
| 294 | init();
|
|---|
| 295 |
|
|---|
| 296 | /* Step 1: Add error terms to newly supplied line */
|
|---|
| 297 |
|
|---|
| 298 | for ( x = 0; x < cx * 3; x++ )
|
|---|
| 299 | src[x] = U_SAT_ADD((int) src[x], (int) errs[x]);
|
|---|
| 300 |
|
|---|
| 301 | /* Step 2: Zero out error terms */
|
|---|
| 302 |
|
|---|
| 303 | memset(errs, 0, (cx + 1) * 3 * sizeof(errs[0]));
|
|---|
| 304 |
|
|---|
| 305 | /* Step 3: Go along data, finding nearest colour and propagating error */
|
|---|
| 306 |
|
|---|
| 307 | randinx = rand();
|
|---|
| 308 |
|
|---|
| 309 | for ( x = 0; x < cx; x++ )
|
|---|
| 310 | {
|
|---|
| 311 | byte b = *src++;
|
|---|
| 312 | byte g = *src++;
|
|---|
| 313 | byte r = *src++;
|
|---|
| 314 | byte bi = index6[b];
|
|---|
| 315 | byte gi = index6[g];
|
|---|
| 316 | byte ri = index6[r];
|
|---|
| 317 | int be = b - ((int) scale6[bi]);
|
|---|
| 318 | int ge = g - ((int) scale6[gi]);
|
|---|
| 319 | int re = r - ((int) scale6[ri]);
|
|---|
| 320 | word rn = randtab[(byte) (randinx++)];
|
|---|
| 321 | int right = (int) (rn >> 8);
|
|---|
| 322 | int down = (int) ((rn & 0xff) % (63 - right));
|
|---|
| 323 | int be1 = ((be * right) >> 6);
|
|---|
| 324 | int ge1 = ((ge * right) >> 6);
|
|---|
| 325 | int re1 = ((re * right) >> 6);
|
|---|
| 326 | int be2 = ((be * down ) >> 6);
|
|---|
| 327 | int ge2 = ((ge * down ) >> 6);
|
|---|
| 328 | int re2 = ((re * down ) >> 6);
|
|---|
| 329 | int be3 = be - be1 - be2;
|
|---|
| 330 | int ge3 = ge - ge1 - ge2;
|
|---|
| 331 | int re3 = re - re1 - re2;
|
|---|
| 332 |
|
|---|
| 333 | *dest++ = (byte) (6 * (6 * ri + gi) + bi);
|
|---|
| 334 |
|
|---|
| 335 | src[0] = U_SAT_ADD((int) src[0], be1);
|
|---|
| 336 | src[1] = U_SAT_ADD((int) src[1], ge1);
|
|---|
| 337 | src[2] = U_SAT_ADD((int) src[2], re1);
|
|---|
| 338 |
|
|---|
| 339 | errs[ptr ] = S_SAT_ADD((int) errs[ptr ], be2);
|
|---|
| 340 | errs[ptr + 1] = S_SAT_ADD((int) errs[ptr + 1], ge2);
|
|---|
| 341 | errs[ptr + 2] = S_SAT_ADD((int) errs[ptr + 2], re2);
|
|---|
| 342 |
|
|---|
| 343 | ptr += 3;
|
|---|
| 344 |
|
|---|
| 345 | errs[ptr ] = S_SAT_ADD((int) errs[ptr ], be3);
|
|---|
| 346 | errs[ptr + 1] = S_SAT_ADD((int) errs[ptr + 1], ge3);
|
|---|
| 347 | errs[ptr + 2] = S_SAT_ADD((int) errs[ptr + 2], re3);
|
|---|
| 348 | }
|
|---|
| 349 | }
|
|---|
| 350 | /*...e*/
|
|---|
| 351 | /*...sgbm_errdiff_6R6G6B \45\ error diffuse to 6Rx6Gx6B:0:*/
|
|---|
| 352 | BOOLEAN gbm_errdiff_6R6G6B(const GBM *gbm, const byte *data24, byte *data8)
|
|---|
| 353 | {
|
|---|
| 354 | return errdiff(gbm, data24, data8, 8, gbm_errdiff_line_6R6G6B);
|
|---|
| 355 | }
|
|---|
| 356 | /*...e*/
|
|---|
| 357 |
|
|---|
| 358 | /*...sgbm_errdiff_pal_7R8G4B \45\ return 7Rx8Gx4B palette:0:*/
|
|---|
| 359 | /*
|
|---|
| 360 | This function makes the palette for the 7 red x 8 green x 4 blue palette.
|
|---|
| 361 | 224 palette entrys used. Remaining 32 left blank.
|
|---|
| 362 | Colours calculated to match those used by 8514/A PM driver.
|
|---|
| 363 | */
|
|---|
| 364 |
|
|---|
| 365 | void gbm_errdiff_pal_7R8G4B(GBMRGB *gbmrgb)
|
|---|
| 366 | {
|
|---|
| 367 | byte volatile r; /* C-Set/2 optimiser fix */
|
|---|
| 368 | byte volatile g;
|
|---|
| 369 | byte volatile b;
|
|---|
| 370 |
|
|---|
| 371 | init();
|
|---|
| 372 |
|
|---|
| 373 | memset(gbmrgb, 0x80, 0x100 * sizeof(GBMRGB));
|
|---|
| 374 | for ( r = 0; r < 7; r++ )
|
|---|
| 375 | for ( g = 0; g < 8; g++ )
|
|---|
| 376 | for ( b = 0; b < 4; b++ )
|
|---|
| 377 | {
|
|---|
| 378 | gbmrgb->r = scale7[r];
|
|---|
| 379 | gbmrgb->g = scale8[g];
|
|---|
| 380 | gbmrgb->b = scale4[b];
|
|---|
| 381 | gbmrgb++;
|
|---|
| 382 | }
|
|---|
| 383 | }
|
|---|
| 384 | /*...e*/
|
|---|
| 385 | /*...sgbm_errdiff_line_7R8G4B \45\ error diffuse to 7Rx8Gx4B one line:0:*/
|
|---|
| 386 | /*
|
|---|
| 387 | This function takes a line of RGB data, a destination buffer and a buffer of
|
|---|
| 388 | error terms and performs one lines worth (a given # of pixels) of error
|
|---|
| 389 | diffusion.
|
|---|
| 390 | */
|
|---|
| 391 |
|
|---|
| 392 | void gbm_errdiff_line_7R8G4B(byte *src, byte *dest, short *errs, int cx)
|
|---|
| 393 | {
|
|---|
| 394 | int x, ptr = 0;
|
|---|
| 395 |
|
|---|
| 396 | init();
|
|---|
| 397 |
|
|---|
| 398 | /* Step 1: Add error terms to newly supplied line */
|
|---|
| 399 |
|
|---|
| 400 | for ( x = 0; x < cx * 3; x++ )
|
|---|
| 401 | src[x] = U_SAT_ADD((int) src[x], (int) errs[x]);
|
|---|
| 402 |
|
|---|
| 403 | /* Step 2: Zero out error terms */
|
|---|
| 404 |
|
|---|
| 405 | memset(errs, 0, (cx + 1) * 3 * sizeof(errs[0]));
|
|---|
| 406 |
|
|---|
| 407 | /* Step 3: Go along data, finding nearest colour and propagating error */
|
|---|
| 408 |
|
|---|
| 409 | randinx = rand();
|
|---|
| 410 |
|
|---|
| 411 | for ( x = 0; x < cx; x++ )
|
|---|
| 412 | {
|
|---|
| 413 | byte b = *src++;
|
|---|
| 414 | byte g = *src++;
|
|---|
| 415 | byte r = *src++;
|
|---|
| 416 | byte bi = index4[b];
|
|---|
| 417 | byte gi = index8[g];
|
|---|
| 418 | byte ri = index7[r];
|
|---|
| 419 | int be = b - ((int) scale4[bi]);
|
|---|
| 420 | int ge = g - ((int) scale8[gi]);
|
|---|
| 421 | int re = r - ((int) scale7[ri]);
|
|---|
| 422 | word rn = randtab[(byte) (randinx++)];
|
|---|
| 423 | int right = (rn >> 8);
|
|---|
| 424 | int down = ((rn & 0xff) % (63 - right));
|
|---|
| 425 | int be1 = ((be * right) >> 6);
|
|---|
| 426 | int ge1 = ((ge * right) >> 6);
|
|---|
| 427 | int re1 = ((re * right) >> 6);
|
|---|
| 428 | int be2 = ((be * down ) >> 6);
|
|---|
| 429 | int ge2 = ((ge * down ) >> 6);
|
|---|
| 430 | int re2 = ((re * down ) >> 6);
|
|---|
| 431 | int be3 = be - be1 - be2;
|
|---|
| 432 | int ge3 = ge - ge1 - ge2;
|
|---|
| 433 | int re3 = re - re1 - re2;
|
|---|
| 434 |
|
|---|
| 435 | *dest++ = (byte) (4 * (8 * ri + gi) + bi);
|
|---|
| 436 |
|
|---|
| 437 | src[0] = U_SAT_ADD((int) src[0], be1);
|
|---|
| 438 | src[1] = U_SAT_ADD((int) src[1], ge1);
|
|---|
| 439 | src[2] = U_SAT_ADD((int) src[2], re1);
|
|---|
| 440 |
|
|---|
| 441 | errs[ptr ] = S_SAT_ADD((int) errs[ptr ], be2);
|
|---|
| 442 | errs[ptr + 1] = S_SAT_ADD((int) errs[ptr + 1], ge2);
|
|---|
| 443 | errs[ptr + 2] = S_SAT_ADD((int) errs[ptr + 2], re2);
|
|---|
| 444 |
|
|---|
| 445 | ptr += 3;
|
|---|
| 446 |
|
|---|
| 447 | errs[ptr ] = S_SAT_ADD((int) errs[ptr ], be3);
|
|---|
| 448 | errs[ptr + 1] = S_SAT_ADD((int) errs[ptr + 1], ge3);
|
|---|
| 449 | errs[ptr + 2] = S_SAT_ADD((int) errs[ptr + 2], re3);
|
|---|
| 450 | }
|
|---|
| 451 | }
|
|---|
| 452 | /*...e*/
|
|---|
| 453 | /*...sgbm_errdiff_7R8G4B \45\ error diffuse to 7Rx8Gx4B:0:*/
|
|---|
| 454 | BOOLEAN gbm_errdiff_7R8G4B(const GBM *gbm, const byte *data24, byte *data8)
|
|---|
| 455 | {
|
|---|
| 456 | return errdiff(gbm, data24, data8, 8, gbm_errdiff_line_7R8G4B);
|
|---|
| 457 | }
|
|---|
| 458 | /*...e*/
|
|---|
| 459 |
|
|---|
| 460 | /*...sgbm_errdiff_pal_VGA \45\ return default VGA palette:0:*/
|
|---|
| 461 | /*
|
|---|
| 462 | This function makes the palette for the 16 colour VGA palette.
|
|---|
| 463 | */
|
|---|
| 464 |
|
|---|
| 465 | static GBMRGB gbmrgb_vga[] =
|
|---|
| 466 | {
|
|---|
| 467 | 0, 0, 0,
|
|---|
| 468 | 128, 0, 0,
|
|---|
| 469 | 0,128, 0,
|
|---|
| 470 | 128,128, 0,
|
|---|
| 471 | 0, 0,128,
|
|---|
| 472 | 128, 0,128,
|
|---|
| 473 | 0,128,128,
|
|---|
| 474 | 128,128,128,
|
|---|
| 475 | 204,204,204,
|
|---|
| 476 | 255, 0, 0,
|
|---|
| 477 | 0,255, 0,
|
|---|
| 478 | 255,255, 0,
|
|---|
| 479 | 0, 0,255,
|
|---|
| 480 | 255, 0,255,
|
|---|
| 481 | 0,255,255,
|
|---|
| 482 | 255,255,255,
|
|---|
| 483 | };
|
|---|
| 484 |
|
|---|
| 485 | void gbm_errdiff_pal_VGA(GBMRGB *gbmrgb)
|
|---|
| 486 | {
|
|---|
| 487 | init();
|
|---|
| 488 | memcpy((char *) gbmrgb, (char *) gbmrgb_vga, sizeof(gbmrgb_vga));
|
|---|
| 489 | }
|
|---|
| 490 | /*...e*/
|
|---|
| 491 | /*...sgbm_errdiff_line_VGA \45\ error diffuse to default VGA palette one line:0:*/
|
|---|
| 492 | /*
|
|---|
| 493 | This function takes a line of RGB data, a destination buffer and a buffer of
|
|---|
| 494 | error terms and performs one lines worth (a given # of pixels) of error
|
|---|
| 495 | diffusion.
|
|---|
| 496 | */
|
|---|
| 497 |
|
|---|
| 498 | /*...scalc_nearest:0:*/
|
|---|
| 499 | /*
|
|---|
| 500 | This function, when given am RGB colour, finds the VGA palette entry closest
|
|---|
| 501 | to it. We deliberately bias away from the two grey palette entries.
|
|---|
| 502 | */
|
|---|
| 503 |
|
|---|
| 504 | static byte calc_nearest(byte r, byte g, byte b)
|
|---|
| 505 | {
|
|---|
| 506 | long min_dist = 3L * 256L * 256L * 10L;
|
|---|
| 507 | byte bi, bi_min;
|
|---|
| 508 |
|
|---|
| 509 | for ( bi = 0; bi < 0x10; bi++ )
|
|---|
| 510 | {
|
|---|
| 511 | long b_dist = ((long) b - (long) gbmrgb_vga[bi].b);
|
|---|
| 512 | long g_dist = ((long) g - (long) gbmrgb_vga[bi].g);
|
|---|
| 513 | long r_dist = ((long) r - (long) gbmrgb_vga[bi].r);
|
|---|
| 514 | long dist = r_dist * r_dist + g_dist * g_dist + b_dist * b_dist;
|
|---|
| 515 |
|
|---|
| 516 | if ( bi == 7 || bi == 8 )
|
|---|
| 517 | /* Bias away from this colour */
|
|---|
| 518 | dist <<= 3;
|
|---|
| 519 |
|
|---|
| 520 | if ( dist < min_dist )
|
|---|
| 521 | {
|
|---|
| 522 | min_dist = dist;
|
|---|
| 523 | bi_min = bi;
|
|---|
| 524 | }
|
|---|
| 525 | }
|
|---|
| 526 | return bi_min;
|
|---|
| 527 | }
|
|---|
| 528 | /*...e*/
|
|---|
| 529 | /*...snearest_colour:0:*/
|
|---|
| 530 | /*
|
|---|
| 531 | This function finds the closest VGA palette colour to a given RGB value.
|
|---|
| 532 | It uses a lookup table to avoid performing distance calculations to the
|
|---|
| 533 | 16 palette entrys. The table is pre-calculated.
|
|---|
| 534 | */
|
|---|
| 535 |
|
|---|
| 536 | /*...squick lookup table:0:*/
|
|---|
| 537 | /*...v_gbmerr\46\c \45\ used to make quick_tab:0:*/
|
|---|
| 538 |
|
|---|
| 539 | static byte quick_tab[16][16][16] =
|
|---|
| 540 | {
|
|---|
| 541 | 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
|
|---|
| 542 | 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
|
|---|
| 543 | 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
|
|---|
| 544 | 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
|
|---|
| 545 | 255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
|
|---|
| 546 | 2,2,2,2,255,6,6,6,6,6,6,6,6,255,12,12,
|
|---|
| 547 | 2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,12,
|
|---|
| 548 | 2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
|
|---|
| 549 | 2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
|
|---|
| 550 | 2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,14,
|
|---|
| 551 | 2,2,2,2,255,6,6,6,6,6,6,6,6,255,14,14,
|
|---|
| 552 | 2,2,2,2,255,6,6,6,6,6,6,6,255,14,14,14,
|
|---|
| 553 | 10,10,10,10,255,6,6,6,6,6,6,255,14,14,14,14,
|
|---|
| 554 | 10,10,10,10,10,255,6,6,6,6,255,14,14,14,14,14,
|
|---|
| 555 | 10,10,10,10,10,10,255,6,6,255,14,14,14,14,14,14,
|
|---|
| 556 | 10,10,10,10,10,10,10,255,255,14,14,14,14,14,14,14,
|
|---|
| 557 | 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
|
|---|
| 558 | 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
|
|---|
| 559 | 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
|
|---|
| 560 | 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
|
|---|
| 561 | 255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
|
|---|
| 562 | 2,2,2,2,255,6,6,6,6,6,6,6,6,255,12,12,
|
|---|
| 563 | 2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,12,
|
|---|
| 564 | 2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
|
|---|
| 565 | 2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
|
|---|
| 566 | 2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,14,
|
|---|
| 567 | 2,2,2,2,255,6,6,6,6,6,6,6,6,255,14,14,
|
|---|
| 568 | 2,2,2,2,255,6,6,6,6,6,6,6,255,14,14,14,
|
|---|
| 569 | 10,10,10,10,255,6,6,6,6,6,6,255,14,14,14,14,
|
|---|
| 570 | 10,10,10,10,10,255,6,6,6,6,255,14,14,14,14,14,
|
|---|
| 571 | 10,10,10,10,10,10,255,6,6,255,14,14,14,14,14,14,
|
|---|
| 572 | 10,10,10,10,10,10,10,255,255,14,14,14,14,14,14,14,
|
|---|
| 573 | 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
|
|---|
| 574 | 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
|
|---|
| 575 | 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
|
|---|
| 576 | 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
|
|---|
| 577 | 255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
|
|---|
| 578 | 2,2,2,2,255,6,6,6,6,6,6,6,6,255,12,12,
|
|---|
| 579 | 2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,12,
|
|---|
| 580 | 2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
|
|---|
| 581 | 2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
|
|---|
| 582 | 2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,14,
|
|---|
| 583 | 2,2,2,2,255,6,6,6,6,6,6,6,6,255,14,14,
|
|---|
| 584 | 2,2,2,2,255,6,6,6,6,6,6,6,255,14,14,14,
|
|---|
| 585 | 10,10,10,10,255,6,6,6,6,6,6,255,14,14,14,14,
|
|---|
| 586 | 10,10,10,10,10,255,6,6,6,6,255,14,14,14,14,14,
|
|---|
| 587 | 10,10,10,10,10,10,255,6,6,255,14,14,14,14,14,14,
|
|---|
| 588 | 10,10,10,10,10,10,10,255,255,14,14,14,14,14,14,14,
|
|---|
| 589 | 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
|
|---|
| 590 | 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
|
|---|
| 591 | 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
|
|---|
| 592 | 0,0,0,0,255,4,4,4,4,4,4,4,12,12,12,12,
|
|---|
| 593 | 255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
|
|---|
| 594 | 2,2,2,2,255,6,6,6,6,6,6,6,6,255,12,12,
|
|---|
| 595 | 2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,12,
|
|---|
| 596 | 2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
|
|---|
| 597 | 2,2,2,2,255,6,6,6,6,6,6,6,6,6,6,255,
|
|---|
| 598 | 2,2,2,2,255,6,6,6,6,6,6,6,6,6,255,14,
|
|---|
| 599 | 2,2,2,2,255,6,6,6,6,6,6,6,6,255,14,14,
|
|---|
| 600 | 2,2,2,2,255,6,6,6,6,6,6,6,255,14,14,14,
|
|---|
| 601 | 10,10,10,10,255,6,6,6,6,6,6,255,14,14,14,14,
|
|---|
| 602 | 10,10,10,10,10,255,6,6,6,6,255,14,14,14,14,14,
|
|---|
| 603 | 10,10,10,10,10,10,255,6,6,255,14,14,14,14,14,14,
|
|---|
| 604 | 10,10,10,10,10,10,10,255,255,14,14,14,14,14,14,14,
|
|---|
| 605 | 255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
|
|---|
| 606 | 255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
|
|---|
| 607 | 255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
|
|---|
| 608 | 255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
|
|---|
| 609 | 255,255,255,255,255,255,255,255,255,255,255,255,255,12,12,12,
|
|---|
| 610 | 255,255,255,255,255,6,6,6,6,6,6,6,6,255,12,12,
|
|---|
| 611 | 255,255,255,255,255,6,6,6,6,6,6,6,6,6,255,12,
|
|---|
| 612 | 255,255,255,255,255,6,6,6,6,6,6,6,6,6,6,255,
|
|---|
| 613 | 255,255,255,255,255,6,6,6,6,6,6,6,6,6,6,255,
|
|---|
| 614 | 255,255,255,255,255,6,6,6,6,6,6,6,6,6,255,14,
|
|---|
| 615 | 255,255,255,255,255,6,6,6,6,6,6,6,6,255,14,14,
|
|---|
| 616 | 255,255,255,255,255,6,6,6,6,6,6,6,255,14,14,14,
|
|---|
| 617 | 255,255,255,255,255,6,6,6,6,6,6,255,14,14,14,14,
|
|---|
| 618 | 10,10,10,10,10,255,6,6,6,6,255,14,14,14,14,14,
|
|---|
| 619 | 10,10,10,10,10,10,255,6,6,255,14,14,14,14,14,14,
|
|---|
| 620 | 10,10,10,10,10,10,10,255,255,14,14,14,14,14,14,14,
|
|---|
| 621 | 1,1,1,1,255,5,5,5,5,5,5,5,5,255,12,12,
|
|---|
| 622 | 1,1,1,1,255,5,5,5,5,5,5,5,5,255,12,12,
|
|---|
| 623 | 1,1,1,1,255,5,5,5,5,5,5,5,5,255,12,12,
|
|---|
| 624 | 1,1,1,1,255,5,5,5,5,5,5,5,5,255,12,12,
|
|---|
| 625 | 255,255,255,255,255,5,5,5,5,5,5,5,5,255,12,12,
|
|---|
| 626 | 3,3,3,3,3,255,255,255,255,255,255,255,255,255,12,12,
|
|---|
| 627 | 3,3,3,3,3,255,6,6,6,6,6,6,6,6,255,12,
|
|---|
| 628 | 3,3,3,3,3,255,6,255,255,6,6,6,6,6,6,255,
|
|---|
| 629 | 3,3,3,3,3,255,6,255,255,6,6,6,6,6,6,255,
|
|---|
| 630 | 3,3,3,3,3,255,6,6,6,6,6,6,6,6,255,14,
|
|---|
| 631 | 3,3,3,3,3,255,6,6,6,6,6,6,6,255,14,14,
|
|---|
| 632 | 3,3,3,3,3,255,6,6,6,6,6,6,255,14,14,14,
|
|---|
| 633 | 3,3,3,3,3,255,6,6,6,6,6,255,14,14,14,14,
|
|---|
| 634 | 255,255,255,255,255,255,6,6,6,6,255,14,14,14,14,14,
|
|---|
| 635 | 10,10,10,10,10,10,255,6,6,255,14,14,14,14,14,14,
|
|---|
| 636 | 10,10,10,10,10,10,10,255,255,14,14,14,14,14,14,14,
|
|---|
| 637 | 1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,12,
|
|---|
| 638 | 1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,12,
|
|---|
| 639 | 1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,12,
|
|---|
| 640 | 1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,12,
|
|---|
| 641 | 255,255,255,255,255,5,5,5,5,5,5,5,5,5,255,12,
|
|---|
| 642 | 3,3,3,3,3,255,5,5,5,5,5,5,5,5,255,12,
|
|---|
| 643 | 3,3,3,3,3,3,255,255,255,255,255,255,255,255,255,12,
|
|---|
| 644 | 3,3,3,3,3,3,255,255,255,255,255,6,6,6,6,255,
|
|---|
| 645 | 3,3,3,3,3,3,255,255,255,255,255,6,6,6,6,255,
|
|---|
| 646 | 3,3,3,3,3,3,255,255,255,255,255,6,6,6,255,14,
|
|---|
| 647 | 3,3,3,3,3,3,255,255,255,255,6,6,6,255,14,14,
|
|---|
| 648 | 3,3,3,3,3,3,255,6,6,6,6,6,255,14,14,14,
|
|---|
| 649 | 3,3,3,3,3,3,255,6,6,6,6,255,14,14,14,14,
|
|---|
| 650 | 3,3,3,3,3,3,255,6,6,6,255,14,14,14,14,14,
|
|---|
| 651 | 255,255,255,255,255,255,255,6,6,255,14,14,14,14,14,14,
|
|---|
| 652 | 10,10,10,10,10,10,10,255,255,14,14,14,14,14,14,14,
|
|---|
| 653 | 1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
|
|---|
| 654 | 1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
|
|---|
| 655 | 1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
|
|---|
| 656 | 1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
|
|---|
| 657 | 255,255,255,255,255,5,5,5,5,5,5,5,5,5,5,255,
|
|---|
| 658 | 3,3,3,3,3,255,5,255,255,5,5,5,5,5,5,255,
|
|---|
| 659 | 3,3,3,3,3,3,255,255,255,255,255,5,5,5,5,255,
|
|---|
| 660 | 3,3,3,3,3,255,255,7,7,7,255,255,255,255,255,255,
|
|---|
| 661 | 3,3,3,3,3,255,255,7,7,7,255,6,6,6,6,255,
|
|---|
| 662 | 3,3,3,3,3,3,255,7,7,255,255,6,6,6,255,14,
|
|---|
| 663 | 3,3,3,3,3,3,255,255,255,255,255,6,6,255,14,14,
|
|---|
| 664 | 3,3,3,3,3,3,3,255,6,6,6,6,255,14,14,14,
|
|---|
| 665 | 3,3,3,3,3,3,3,255,6,6,6,255,14,14,14,14,
|
|---|
| 666 | 3,3,3,3,3,3,3,255,6,6,255,14,14,14,14,14,
|
|---|
| 667 | 3,3,3,3,3,3,3,255,6,255,14,14,14,14,14,14,
|
|---|
| 668 | 255,255,255,255,255,255,255,255,255,14,14,14,14,14,14,14,
|
|---|
| 669 | 1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
|
|---|
| 670 | 1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
|
|---|
| 671 | 1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
|
|---|
| 672 | 1,1,1,1,255,5,5,5,5,5,5,5,5,5,5,255,
|
|---|
| 673 | 255,255,255,255,255,5,5,5,5,5,5,5,5,5,5,255,
|
|---|
| 674 | 3,3,3,3,3,255,5,255,255,5,5,5,5,5,5,255,
|
|---|
| 675 | 3,3,3,3,3,3,255,255,255,255,255,5,5,5,5,255,
|
|---|
| 676 | 3,3,3,3,3,255,255,7,7,7,255,5,5,5,5,255,
|
|---|
| 677 | 3,3,3,3,3,255,255,7,7,7,255,255,255,255,255,255,
|
|---|
| 678 | 3,3,3,3,3,3,255,7,7,7,255,255,255,255,255,15,
|
|---|
| 679 | 3,3,3,3,3,3,255,255,255,255,255,255,255,255,15,15,
|
|---|
| 680 | 3,3,3,3,3,3,3,3,255,255,255,255,255,15,15,15,
|
|---|
| 681 | 3,3,3,3,3,3,3,3,255,255,255,255,15,15,15,15,
|
|---|
| 682 | 3,3,3,3,3,3,3,3,255,255,255,15,15,15,15,15,
|
|---|
| 683 | 3,3,3,3,3,3,3,3,255,255,15,15,15,15,15,15,
|
|---|
| 684 | 255,255,255,255,255,255,255,255,255,15,15,15,15,15,15,15,
|
|---|
| 685 | 1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,13,
|
|---|
| 686 | 1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,13,
|
|---|
| 687 | 1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,13,
|
|---|
| 688 | 1,1,1,1,255,5,5,5,5,5,5,5,5,5,255,13,
|
|---|
| 689 | 255,255,255,255,255,5,5,5,5,5,5,5,5,5,255,13,
|
|---|
| 690 | 3,3,3,3,3,255,5,5,5,5,5,5,5,5,255,13,
|
|---|
| 691 | 3,3,3,3,3,3,255,255,255,255,255,5,5,5,255,13,
|
|---|
| 692 | 3,3,3,3,3,3,255,7,7,255,255,5,5,5,255,13,
|
|---|
| 693 | 3,3,3,3,3,3,255,7,7,7,255,255,255,255,255,15,
|
|---|
| 694 | 3,3,3,3,3,3,255,255,7,7,255,255,255,15,15,15,
|
|---|
| 695 | 3,3,3,3,3,3,255,255,255,255,255,255,15,15,15,15,
|
|---|
| 696 | 3,3,3,3,3,3,3,3,255,255,255,15,15,15,15,15,
|
|---|
| 697 | 3,3,3,3,3,3,3,3,255,255,15,15,15,15,15,15,
|
|---|
| 698 | 3,3,3,3,3,3,3,3,255,15,15,15,15,15,15,15,
|
|---|
| 699 | 255,255,255,255,255,255,255,255,255,15,15,15,15,15,15,15,
|
|---|
| 700 | 11,11,11,11,11,11,11,11,15,15,15,15,15,15,15,15,
|
|---|
| 701 | 1,1,1,1,255,5,5,5,5,5,5,5,5,255,13,13,
|
|---|
| 702 | 1,1,1,1,255,5,5,5,5,5,5,5,5,255,13,13,
|
|---|
| 703 | 1,1,1,1,255,5,5,5,5,5,5,5,5,255,13,13,
|
|---|
| 704 | 1,1,1,1,255,5,5,5,5,5,5,5,5,255,13,13,
|
|---|
| 705 | 255,255,255,255,255,5,5,5,5,5,5,5,5,255,13,13,
|
|---|
| 706 | 3,3,3,3,3,255,5,5,5,5,5,5,5,255,13,13,
|
|---|
| 707 | 3,3,3,3,3,3,255,255,255,255,5,5,5,255,13,13,
|
|---|
| 708 | 3,3,3,3,3,3,255,255,255,255,255,5,5,255,13,13,
|
|---|
| 709 | 3,3,3,3,3,3,255,255,255,255,255,255,255,255,15,15,
|
|---|
| 710 | 3,3,3,3,3,3,255,255,255,255,255,255,15,15,15,15,
|
|---|
| 711 | 3,3,3,3,3,3,3,255,255,255,255,255,255,255,15,15,
|
|---|
| 712 | 3,3,3,3,3,3,3,3,255,255,255,255,255,255,255,15,
|
|---|
| 713 | 3,3,3,3,3,3,3,3,255,15,255,255,255,255,255,15,
|
|---|
| 714 | 255,255,255,255,255,255,255,255,255,15,255,255,255,255,15,15,
|
|---|
| 715 | 11,11,11,11,11,11,11,11,15,15,15,255,255,15,15,15,
|
|---|
| 716 | 11,11,11,11,11,11,11,11,15,15,15,15,15,15,15,15,
|
|---|
| 717 | 1,1,1,1,255,5,5,5,5,5,5,5,255,13,13,13,
|
|---|
| 718 | 1,1,1,1,255,5,5,5,5,5,5,5,255,13,13,13,
|
|---|
| 719 | 1,1,1,1,255,5,5,5,5,5,5,5,255,13,13,13,
|
|---|
| 720 | 1,1,1,1,255,5,5,5,5,5,5,5,255,13,13,13,
|
|---|
| 721 | 255,255,255,255,255,5,5,5,5,5,5,5,255,13,13,13,
|
|---|
| 722 | 3,3,3,3,3,255,5,5,5,5,5,5,255,13,13,13,
|
|---|
| 723 | 3,3,3,3,3,3,255,5,5,5,5,5,255,13,13,13,
|
|---|
| 724 | 3,3,3,3,3,3,3,255,5,5,5,5,255,13,13,13,
|
|---|
| 725 | 3,3,3,3,3,3,3,3,255,255,255,255,255,15,15,15,
|
|---|
| 726 | 3,3,3,3,3,3,3,3,255,255,255,15,15,15,15,15,
|
|---|
| 727 | 3,3,3,3,3,3,3,3,255,255,255,255,255,255,255,15,
|
|---|
| 728 | 3,3,3,3,3,3,3,3,255,15,255,255,8,255,255,15,
|
|---|
| 729 | 255,255,255,255,255,255,255,255,255,15,255,8,8,8,255,15,
|
|---|
| 730 | 11,11,11,11,11,11,11,11,15,15,255,255,8,255,255,15,
|
|---|
| 731 | 11,11,11,11,11,11,11,11,15,15,255,255,255,255,15,15,
|
|---|
| 732 | 11,11,11,11,11,11,11,11,15,15,15,15,15,15,15,15,
|
|---|
| 733 | 9,9,9,9,255,5,5,5,5,5,5,255,13,13,13,13,
|
|---|
| 734 | 9,9,9,9,255,5,5,5,5,5,5,255,13,13,13,13,
|
|---|
| 735 | 9,9,9,9,255,5,5,5,5,5,5,255,13,13,13,13,
|
|---|
| 736 | 9,9,9,9,255,5,5,5,5,5,5,255,13,13,13,13,
|
|---|
| 737 | 255,255,255,255,255,5,5,5,5,5,5,255,13,13,13,13,
|
|---|
| 738 | 3,3,3,3,3,255,5,5,5,5,5,255,13,13,13,13,
|
|---|
| 739 | 3,3,3,3,3,3,255,5,5,5,5,255,13,13,13,13,
|
|---|
| 740 | 3,3,3,3,3,3,3,255,5,5,5,255,13,13,13,13,
|
|---|
| 741 | 3,3,3,3,3,3,3,3,255,255,255,255,15,15,15,15,
|
|---|
| 742 | 3,3,3,3,3,3,3,3,255,255,15,15,15,15,15,15,
|
|---|
| 743 | 3,3,3,3,3,3,3,3,255,15,255,255,255,255,255,15,
|
|---|
| 744 | 255,255,255,255,255,255,255,255,255,15,255,8,8,8,255,15,
|
|---|
| 745 | 11,11,11,11,11,11,11,11,15,15,255,8,8,8,255,15,
|
|---|
| 746 | 11,11,11,11,11,11,11,11,15,15,255,8,8,255,255,15,
|
|---|
| 747 | 11,11,11,11,11,11,11,11,15,15,255,255,255,255,15,15,
|
|---|
| 748 | 11,11,11,11,11,11,11,11,15,15,15,15,15,15,15,15,
|
|---|
| 749 | 9,9,9,9,9,255,5,5,5,5,255,13,13,13,13,13,
|
|---|
| 750 | 9,9,9,9,9,255,5,5,5,5,255,13,13,13,13,13,
|
|---|
| 751 | 9,9,9,9,9,255,5,5,5,5,255,13,13,13,13,13,
|
|---|
| 752 | 9,9,9,9,9,255,5,5,5,5,255,13,13,13,13,13,
|
|---|
| 753 | 9,9,9,9,9,255,5,5,5,5,255,13,13,13,13,13,
|
|---|
| 754 | 255,255,255,255,255,255,5,5,5,5,255,13,13,13,13,13,
|
|---|
| 755 | 3,3,3,3,3,3,255,5,5,5,255,13,13,13,13,13,
|
|---|
| 756 | 3,3,3,3,3,3,3,255,5,5,255,13,13,13,13,13,
|
|---|
| 757 | 3,3,3,3,3,3,3,3,255,255,255,15,15,15,15,15,
|
|---|
| 758 | 3,3,3,3,3,3,3,3,255,15,15,15,15,15,15,15,
|
|---|
| 759 | 255,255,255,255,255,255,255,255,255,15,255,255,255,255,15,15,
|
|---|
| 760 | 11,11,11,11,11,11,11,11,15,15,255,255,8,255,255,15,
|
|---|
| 761 | 11,11,11,11,11,11,11,11,15,15,255,8,8,255,255,15,
|
|---|
| 762 | 11,11,11,11,11,11,11,11,15,15,255,255,255,255,255,15,
|
|---|
| 763 | 11,11,11,11,11,11,11,11,15,15,15,255,255,255,15,15,
|
|---|
| 764 | 11,11,11,11,11,11,11,11,15,15,15,15,15,15,15,15,
|
|---|
| 765 | 9,9,9,9,9,9,255,5,5,255,13,13,13,13,13,13,
|
|---|
| 766 | 9,9,9,9,9,9,255,5,5,255,13,13,13,13,13,13,
|
|---|
| 767 | 9,9,9,9,9,9,255,5,5,255,13,13,13,13,13,13,
|
|---|
| 768 | 9,9,9,9,9,9,255,5,5,255,13,13,13,13,13,13,
|
|---|
| 769 | 9,9,9,9,9,9,255,5,5,255,13,13,13,13,13,13,
|
|---|
| 770 | 9,9,9,9,9,9,255,5,5,255,13,13,13,13,13,13,
|
|---|
| 771 | 255,255,255,255,255,255,255,5,5,255,13,13,13,13,13,13,
|
|---|
| 772 | 3,3,3,3,3,3,3,255,5,255,13,13,13,13,13,13,
|
|---|
| 773 | 3,3,3,3,3,3,3,3,255,255,15,15,15,15,15,15,
|
|---|
| 774 | 255,255,255,255,255,255,255,255,255,15,15,15,15,15,15,15,
|
|---|
| 775 | 11,11,11,11,11,11,11,11,15,15,15,255,255,15,15,15,
|
|---|
| 776 | 11,11,11,11,11,11,11,11,15,15,255,255,255,255,15,15,
|
|---|
| 777 | 11,11,11,11,11,11,11,11,15,15,255,255,255,255,15,15,
|
|---|
| 778 | 11,11,11,11,11,11,11,11,15,15,15,255,255,255,15,15,
|
|---|
| 779 | 11,11,11,11,11,11,11,11,15,15,15,15,15,15,15,15,
|
|---|
| 780 | 11,11,11,11,11,11,11,11,15,15,15,15,15,15,15,15,
|
|---|
| 781 | 9,9,9,9,9,9,9,255,255,13,13,13,13,13,13,13,
|
|---|
| 782 | 9,9,9,9,9,9,9,255,255,13,13,13,13,13,13,13,
|
|---|
| 783 | 9,9,9,9,9,9,9,255,255,13,13,13,13,13,13,13,
|
|---|
| 784 | 9,9,9,9,9,9,9,255,255,13,13,13,13,13,13,13,
|
|---|
| 785 | 9,9,9,9,9,9,9,255,255,13,13,13,13,13,13,13,
|
|---|
| 786 | 9,9,9,9,9,9,9,255,255,13,13,13,13,13,13,13,
|
|---|
| 787 | 9,9,9,9,9,9,9,255,255,13,13,13,13,13,13,13,
|
|---|
| 788 | 255,255,255,255,255,255,255,255,255,13,13,13,13,13,13,13,
|
|---|
| 789 | 255,255,255,255,255,255,255,255,255,15,15,15,15,15,15,15,
|
|---|
| 790 | 11,11,11,11,11,11,11,11,15,15,15,15,15,15,15,15,
|
|---|
| 791 | 11,11,11,11,11,11,11,11,15,15,15,15,15,15,15,15,
|
|---|
| 792 | 11,11,11,11,11,11,11,11,15,15,15,15,15,15,15,15,
|
|---|
| 793 | 11,11,11,11,11,11,11,11,15,15,15,15,15,15,15,15,
|
|---|
| 794 | 11,11,11,11,11,11,11,11,15,15,15,15,15,15,15,15,
|
|---|
| 795 | 11,11,11,11,11,11,11,11,15,15,15,15,15,15,15,15,
|
|---|
| 796 | 11,11,11,11,11,11,11,11,15,15,15,15,15,15,15,15,
|
|---|
| 797 | };
|
|---|
| 798 | /*...e*/
|
|---|
| 799 |
|
|---|
| 800 | static byte nearest_colour(byte r, byte g, byte b)
|
|---|
| 801 | {
|
|---|
| 802 | byte i;
|
|---|
| 803 |
|
|---|
| 804 | if ( (i = quick_tab[r >> 4][g >> 4][b >> 4]) != (byte) 0xff )
|
|---|
| 805 | return i;
|
|---|
| 806 |
|
|---|
| 807 | return calc_nearest(r, g, b);
|
|---|
| 808 | }
|
|---|
| 809 | /*...e*/
|
|---|
| 810 |
|
|---|
| 811 | void gbm_errdiff_line_VGA(byte *src, byte *dest, short *errs, int cx)
|
|---|
| 812 | {
|
|---|
| 813 | BOOLEAN left = TRUE;
|
|---|
| 814 | int x, ptr = 0;
|
|---|
| 815 |
|
|---|
| 816 | init();
|
|---|
| 817 |
|
|---|
| 818 | /* Step 1: Add error terms to newly supplied line */
|
|---|
| 819 |
|
|---|
| 820 | for ( x = 0; x < cx * 3; x++ )
|
|---|
| 821 | src[x] = U_SAT_ADD((int) src[x], (int) errs[x]);
|
|---|
| 822 |
|
|---|
| 823 | /* Step 2: Zero out error terms */
|
|---|
| 824 |
|
|---|
| 825 | memset(errs, 0, (cx + 1) * 3 * sizeof(errs[0]));
|
|---|
| 826 |
|
|---|
| 827 | /* Step 3: Go along data, finding nearest colour and propagating error */
|
|---|
| 828 |
|
|---|
| 829 | randinx = rand();
|
|---|
| 830 |
|
|---|
| 831 | for ( x = 0; x < cx; x++ )
|
|---|
| 832 | {
|
|---|
| 833 | byte b = *src++;
|
|---|
| 834 | byte g = *src++;
|
|---|
| 835 | byte r = *src++;
|
|---|
| 836 | byte bi = nearest_colour(r, g, b);
|
|---|
| 837 | int be = (int) b - (int) gbmrgb_vga[bi].b;
|
|---|
| 838 | int ge = (int) g - (int) gbmrgb_vga[bi].g;
|
|---|
| 839 | int re = (int) r - (int) gbmrgb_vga[bi].r;
|
|---|
| 840 | word rn = randtab[(byte) (randinx++)];
|
|---|
| 841 | int right = (rn >> 8);
|
|---|
| 842 | int down = ((rn & 0xff) % (63 - right));
|
|---|
| 843 | int be1 = ((be * right) >> 6);
|
|---|
| 844 | int ge1 = ((ge * right) >> 6);
|
|---|
| 845 | int re1 = ((re * right) >> 6);
|
|---|
| 846 | int be2 = ((be * down ) >> 6);
|
|---|
| 847 | int ge2 = ((ge * down ) >> 6);
|
|---|
| 848 | int re2 = ((re * down ) >> 6);
|
|---|
| 849 | int be3 = be - be1 - be2;
|
|---|
| 850 | int ge3 = ge - ge1 - ge2;
|
|---|
| 851 | int re3 = re - re1 - re2;
|
|---|
| 852 |
|
|---|
| 853 | if ( left )
|
|---|
| 854 | *dest = (byte) (bi << 4);
|
|---|
| 855 | else
|
|---|
| 856 | *dest++ |= bi;
|
|---|
| 857 |
|
|---|
| 858 | left = !left;
|
|---|
| 859 |
|
|---|
| 860 | src[0] = U_SAT_ADD((int) src[0], be1);
|
|---|
| 861 | src[1] = U_SAT_ADD((int) src[1], ge1);
|
|---|
| 862 | src[2] = U_SAT_ADD((int) src[2], re1);
|
|---|
| 863 |
|
|---|
| 864 | errs[ptr ] = S_SAT_ADD((int) errs[ptr ], be2);
|
|---|
| 865 | errs[ptr + 1] = S_SAT_ADD((int) errs[ptr + 1], ge2);
|
|---|
| 866 | errs[ptr + 2] = S_SAT_ADD((int) errs[ptr + 2], re2);
|
|---|
| 867 |
|
|---|
| 868 | ptr += 3;
|
|---|
| 869 |
|
|---|
| 870 | errs[ptr ] = S_SAT_ADD((int) errs[ptr ], be3);
|
|---|
| 871 | errs[ptr + 1] = S_SAT_ADD((int) errs[ptr + 1], ge3);
|
|---|
| 872 | errs[ptr + 2] = S_SAT_ADD((int) errs[ptr + 2], re3);
|
|---|
| 873 | }
|
|---|
| 874 | }
|
|---|
| 875 | /*...e*/
|
|---|
| 876 | /*...sgbm_errdiff_VGA \45\ error diffuse to default VGA palette:0:*/
|
|---|
| 877 | BOOLEAN gbm_errdiff_VGA(const GBM *gbm, const byte *data24, byte *data4)
|
|---|
| 878 | {
|
|---|
| 879 | return errdiff(gbm, data24, data4, 4, gbm_errdiff_line_VGA);
|
|---|
| 880 | }
|
|---|
| 881 | /*...e*/
|
|---|
| 882 |
|
|---|
| 883 | /*...sgbm_errdiff_pal_8 \45\ return default 8 colour palette:0:*/
|
|---|
| 884 | /*
|
|---|
| 885 | This function makes the palette for the 16 colour 8 colour palette.
|
|---|
| 886 | */
|
|---|
| 887 |
|
|---|
| 888 | static GBMRGB gbmrgb_8[] =
|
|---|
| 889 | {
|
|---|
| 890 | 0, 0, 0,
|
|---|
| 891 | 0, 0,255,
|
|---|
| 892 | 0,255, 0,
|
|---|
| 893 | 0,255,255,
|
|---|
| 894 | 255, 0, 0,
|
|---|
| 895 | 255, 0,255,
|
|---|
| 896 | 255,255, 0,
|
|---|
| 897 | 255,255,255,
|
|---|
| 898 | 0, 0, 0,
|
|---|
| 899 | 0, 0, 0,
|
|---|
| 900 | 0, 0, 0,
|
|---|
| 901 | 0, 0, 0,
|
|---|
| 902 | 0, 0, 0,
|
|---|
| 903 | 0, 0, 0,
|
|---|
| 904 | 0, 0, 0,
|
|---|
| 905 | 0, 0, 0,
|
|---|
| 906 | };
|
|---|
| 907 |
|
|---|
| 908 | void gbm_errdiff_pal_8(GBMRGB *gbmrgb)
|
|---|
| 909 | {
|
|---|
| 910 | init();
|
|---|
| 911 | memcpy((char *) gbmrgb, (char *) gbmrgb_8, sizeof(gbmrgb_8));
|
|---|
| 912 | }
|
|---|
| 913 | /*...e*/
|
|---|
| 914 | /*...sgbm_errdiff_line_8 \45\ error diffuse to default 8 colour palette one line:0:*/
|
|---|
| 915 | /*
|
|---|
| 916 | This function takes a line of RGB data, a destination buffer and a buffer of
|
|---|
| 917 | error terms and performs one lines worth (a given # of pixels) of error
|
|---|
| 918 | diffusion.
|
|---|
| 919 | */
|
|---|
| 920 |
|
|---|
| 921 | void gbm_errdiff_line_8(byte *src, byte *dest, short *errs, int cx)
|
|---|
| 922 | {
|
|---|
| 923 | BOOLEAN left = TRUE;
|
|---|
| 924 | int x, ptr = 0;
|
|---|
| 925 |
|
|---|
| 926 | init();
|
|---|
| 927 |
|
|---|
| 928 | /* Step 1: Add error terms to newly supplied line */
|
|---|
| 929 |
|
|---|
| 930 | for ( x = 0; x < cx * 3; x++ )
|
|---|
| 931 | src[x] = U_SAT_ADD((int) src[x], (int) errs[x]);
|
|---|
| 932 |
|
|---|
| 933 | /* Step 2: Zero out error terms */
|
|---|
| 934 |
|
|---|
| 935 | memset(errs, 0, (cx + 1) * 3 * sizeof(errs[0]));
|
|---|
| 936 |
|
|---|
| 937 | /* Step 3: Go along data, finding nearest colour and propagating error */
|
|---|
| 938 |
|
|---|
| 939 | randinx = rand();
|
|---|
| 940 |
|
|---|
| 941 | for ( x = 0; x < cx; x++ )
|
|---|
| 942 | {
|
|---|
| 943 | byte b = *src++;
|
|---|
| 944 | byte g = *src++;
|
|---|
| 945 | byte r = *src++;
|
|---|
| 946 | byte bi = ((r&0x80U)>>5) | ((g&0x80U)>>6) | ((b&0x80U)>>7);
|
|---|
| 947 | int be = (int) b - (int) gbmrgb_8[bi].b;
|
|---|
| 948 | int ge = (int) g - (int) gbmrgb_8[bi].g;
|
|---|
| 949 | int re = (int) r - (int) gbmrgb_8[bi].r;
|
|---|
| 950 | word rn = randtab[(byte) (randinx++)];
|
|---|
| 951 | int right = (rn >> 8);
|
|---|
| 952 | int down = ((rn & 0xff) % (63 - right));
|
|---|
| 953 | int be1 = ((be * right) >> 6);
|
|---|
| 954 | int ge1 = ((ge * right) >> 6);
|
|---|
| 955 | int re1 = ((re * right) >> 6);
|
|---|
| 956 | int be2 = ((be * down ) >> 6);
|
|---|
| 957 | int ge2 = ((ge * down ) >> 6);
|
|---|
| 958 | int re2 = ((re * down ) >> 6);
|
|---|
| 959 | int be3 = be - be1 - be2;
|
|---|
| 960 | int ge3 = ge - ge1 - ge2;
|
|---|
| 961 | int re3 = re - re1 - re2;
|
|---|
| 962 |
|
|---|
| 963 | if ( left )
|
|---|
| 964 | *dest = (byte) (bi << 4);
|
|---|
| 965 | else
|
|---|
| 966 | *dest++ |= bi;
|
|---|
| 967 |
|
|---|
| 968 | left = !left;
|
|---|
| 969 |
|
|---|
| 970 | src[0] = U_SAT_ADD((int) src[0], be1);
|
|---|
| 971 | src[1] = U_SAT_ADD((int) src[1], ge1);
|
|---|
| 972 | src[2] = U_SAT_ADD((int) src[2], re1);
|
|---|
| 973 |
|
|---|
| 974 | errs[ptr ] = S_SAT_ADD((int) errs[ptr ], be2);
|
|---|
| 975 | errs[ptr + 1] = S_SAT_ADD((int) errs[ptr + 1], ge2);
|
|---|
| 976 | errs[ptr + 2] = S_SAT_ADD((int) errs[ptr + 2], re2);
|
|---|
| 977 |
|
|---|
| 978 | ptr += 3;
|
|---|
| 979 |
|
|---|
| 980 | errs[ptr ] = S_SAT_ADD((int) errs[ptr ], be3);
|
|---|
| 981 | errs[ptr + 1] = S_SAT_ADD((int) errs[ptr + 1], ge3);
|
|---|
| 982 | errs[ptr + 2] = S_SAT_ADD((int) errs[ptr + 2], re3);
|
|---|
| 983 | }
|
|---|
| 984 | }
|
|---|
| 985 | /*...e*/
|
|---|
| 986 | /*...sgbm_errdiff_8 \45\ error diffuse to default 8 colour palette:0:*/
|
|---|
| 987 | BOOLEAN gbm_errdiff_8(const GBM *gbm, const byte *data24, byte *data4)
|
|---|
| 988 | {
|
|---|
| 989 | return errdiff(gbm, data24, data4, 4, gbm_errdiff_line_8);
|
|---|
| 990 | }
|
|---|
| 991 | /*...e*/
|
|---|
| 992 |
|
|---|
| 993 | /*...sgbm_errdiff_pal_4G \45\ return 4 bit greyscale palette:0:*/
|
|---|
| 994 | /*
|
|---|
| 995 | This function makes the palette for the 16 colour VGA palette.
|
|---|
| 996 | */
|
|---|
| 997 |
|
|---|
| 998 | void gbm_errdiff_pal_4G(GBMRGB *gbmrgb)
|
|---|
| 999 | {
|
|---|
| 1000 | int i;
|
|---|
| 1001 |
|
|---|
| 1002 | init();
|
|---|
| 1003 | for ( i = 0; i < 0x10; i++ )
|
|---|
| 1004 | {
|
|---|
| 1005 | gbmrgb[i].r = scale16[i];
|
|---|
| 1006 | gbmrgb[i].g = scale16[i];
|
|---|
| 1007 | gbmrgb[i].b = scale16[i];
|
|---|
| 1008 | }
|
|---|
| 1009 | }
|
|---|
| 1010 | /*...e*/
|
|---|
| 1011 | /*...sgbm_errdiff_line_4G \45\ error diffuse to 4 bit greyscale palette one line:0:*/
|
|---|
| 1012 | /*
|
|---|
| 1013 | This function takes a line of RGB data, a destination buffer and a buffer of
|
|---|
| 1014 | error terms and performs one lines worth (a given # of pixels) of error
|
|---|
| 1015 | diffusion.
|
|---|
| 1016 | */
|
|---|
| 1017 |
|
|---|
| 1018 | void gbm_errdiff_line_4G(byte *src, byte *dest, short *errs, int cx)
|
|---|
| 1019 | {
|
|---|
| 1020 | BOOLEAN left = TRUE;
|
|---|
| 1021 | int x, ptr = 0;
|
|---|
| 1022 | byte *pb;
|
|---|
| 1023 |
|
|---|
| 1024 | init();
|
|---|
| 1025 |
|
|---|
| 1026 | /* Step 1: Add error terms to newly supplied line */
|
|---|
| 1027 |
|
|---|
| 1028 | for ( x = 0, pb = src; x < cx; x++ )
|
|---|
| 1029 | {
|
|---|
| 1030 | byte b = *pb++;
|
|---|
| 1031 | byte g = *pb++;
|
|---|
| 1032 | byte r = *pb++;
|
|---|
| 1033 |
|
|---|
| 1034 | src[x] = (byte) (((word) r * 77U + (word) g * 150U + (word) b * 29U) >> 8);
|
|---|
| 1035 | src[x] = U_SAT_ADD((int) src[x], (int) errs[x]);
|
|---|
| 1036 | }
|
|---|
| 1037 |
|
|---|
| 1038 | /* Step 2: Zero out error terms */
|
|---|
| 1039 |
|
|---|
| 1040 | memset(errs, 0, (cx + 1) * sizeof(errs[0]));
|
|---|
| 1041 |
|
|---|
| 1042 | /* Step 3: Go along data, finding nearest colour and propagating error */
|
|---|
| 1043 |
|
|---|
| 1044 | randinx = rand();
|
|---|
| 1045 |
|
|---|
| 1046 | for ( x = 0; x < cx; x++ )
|
|---|
| 1047 | {
|
|---|
| 1048 | byte grey = *src++;
|
|---|
| 1049 | byte inx = index16[grey];
|
|---|
| 1050 | int err = (int) grey - (int) scale16[inx];
|
|---|
| 1051 | word rn = randtab[(byte) (randinx++)];
|
|---|
| 1052 | int right = (rn >> 8);
|
|---|
| 1053 | int down = ((rn & 0xff) % (63 - right));
|
|---|
| 1054 | int err1 = ((err * right) >> 6);
|
|---|
| 1055 | int err2 = ((err * down ) >> 6);
|
|---|
| 1056 | int err3 = err - err1 - err2;
|
|---|
| 1057 |
|
|---|
| 1058 | if ( left )
|
|---|
| 1059 | *dest = (byte) (inx << 4);
|
|---|
| 1060 | else
|
|---|
| 1061 | *dest++ |= inx;
|
|---|
| 1062 |
|
|---|
| 1063 | left = !left;
|
|---|
| 1064 |
|
|---|
| 1065 | src[0] = U_SAT_ADD((int) src[0], err1);
|
|---|
| 1066 |
|
|---|
| 1067 | errs[ptr] = S_SAT_ADD((int) errs[ptr], err2);
|
|---|
| 1068 |
|
|---|
| 1069 | ptr++;
|
|---|
| 1070 |
|
|---|
| 1071 | errs[ptr] = S_SAT_ADD((int) errs[ptr], err3);
|
|---|
| 1072 | }
|
|---|
| 1073 | }
|
|---|
| 1074 | /*...e*/
|
|---|
| 1075 | /*...sgbm_errdiff_4G \45\ error diffuse to 4 bit greyscale palette:0:*/
|
|---|
| 1076 | BOOLEAN gbm_errdiff_4G(const GBM *gbm, const byte *data24, byte *data4)
|
|---|
| 1077 | {
|
|---|
| 1078 | return errdiff(gbm, data24, data4, 4, gbm_errdiff_line_4G);
|
|---|
| 1079 | }
|
|---|
| 1080 | /*...e*/
|
|---|
| 1081 |
|
|---|
| 1082 | /*...sgbm_errdiff_pal_BW \45\ return black and white palette:0:*/
|
|---|
| 1083 | /*
|
|---|
| 1084 | This function returns the b/w palette.
|
|---|
| 1085 | (We consider the image to be likely black on white,
|
|---|
| 1086 | hence the ordering of the palette entries).
|
|---|
| 1087 | */
|
|---|
| 1088 |
|
|---|
| 1089 | static GBMRGB gbmrgb_bw[] =
|
|---|
| 1090 | {
|
|---|
| 1091 | 255,255,255,
|
|---|
| 1092 | 0,0,0,
|
|---|
| 1093 | };
|
|---|
| 1094 |
|
|---|
| 1095 | void gbm_errdiff_pal_BW(GBMRGB *gbmrgb)
|
|---|
| 1096 | {
|
|---|
| 1097 | init();
|
|---|
| 1098 | memcpy((char *) gbmrgb, (char *) gbmrgb_bw, sizeof(gbmrgb_bw));
|
|---|
| 1099 | }
|
|---|
| 1100 | /*...e*/
|
|---|
| 1101 | /*...sgbm_errdiff_line_BW \45\ error diffuse to black and white one line:0:*/
|
|---|
| 1102 | /*
|
|---|
| 1103 | This function takes a line of RGB data, a destination buffer and a buffer of
|
|---|
| 1104 | error terms and performs one lines worth (a given # of pixels) of error
|
|---|
| 1105 | diffusion.
|
|---|
| 1106 | */
|
|---|
| 1107 |
|
|---|
| 1108 | void gbm_errdiff_line_BW(byte *src, byte *dest, short *errs, int cx)
|
|---|
| 1109 | {
|
|---|
| 1110 | int x, bit = 0, ptr = 0;
|
|---|
| 1111 | byte *pb;
|
|---|
| 1112 |
|
|---|
| 1113 | init();
|
|---|
| 1114 |
|
|---|
| 1115 | /* Step 1: Add error terms to newly supplied line */
|
|---|
| 1116 |
|
|---|
| 1117 | for ( x = 0, pb = src; x < cx; x++ )
|
|---|
| 1118 | {
|
|---|
| 1119 | byte b = *pb++;
|
|---|
| 1120 | byte g = *pb++;
|
|---|
| 1121 | byte r = *pb++;
|
|---|
| 1122 |
|
|---|
| 1123 | src[x] = (byte) (((word) r * 77U + (word) g * 150U + (word) b * 29U) >> 8);
|
|---|
| 1124 | src[x] = U_SAT_ADD((int) src[x], (int) errs[x]);
|
|---|
| 1125 | }
|
|---|
| 1126 |
|
|---|
| 1127 | /* Step 2: Zero out error terms */
|
|---|
| 1128 |
|
|---|
| 1129 | memset(errs, 0, (cx + 1) * sizeof(errs[0]));
|
|---|
| 1130 |
|
|---|
| 1131 | /* Step 3: Go along data, finding nearest colour and propagating error */
|
|---|
| 1132 |
|
|---|
| 1133 | memset(dest, 0, (unsigned) (cx + 7) >> 3);
|
|---|
| 1134 |
|
|---|
| 1135 | randinx = rand();
|
|---|
| 1136 |
|
|---|
| 1137 | for ( x = 0; x < cx; x++ )
|
|---|
| 1138 | {
|
|---|
| 1139 | byte grey = *src++;
|
|---|
| 1140 | byte inx = (byte) (grey < 0x80);
|
|---|
| 1141 | int err = (int) grey - (int) gbmrgb_bw[inx].b;
|
|---|
| 1142 | word rn = randtab[(byte) (randinx++)];
|
|---|
| 1143 | int right = (rn >> 8);
|
|---|
| 1144 | int down = ((rn & 0xff) % (63 - right));
|
|---|
| 1145 | int err1 = ((err * right) >> 6);
|
|---|
| 1146 | int err2 = ((err * down ) >> 6);
|
|---|
| 1147 | int err3 = err - err1 - err2;
|
|---|
| 1148 |
|
|---|
| 1149 | if ( inx )
|
|---|
| 1150 | *dest |= (0x80U >> bit);
|
|---|
| 1151 |
|
|---|
| 1152 | if ( ++bit == 8 )
|
|---|
| 1153 | {
|
|---|
| 1154 | bit = 0;
|
|---|
| 1155 | dest++;
|
|---|
| 1156 | }
|
|---|
| 1157 |
|
|---|
| 1158 | src[0] = U_SAT_ADD((int) src[0], err1);
|
|---|
| 1159 |
|
|---|
| 1160 | errs[ptr] = S_SAT_ADD((int) errs[ptr], err2);
|
|---|
| 1161 |
|
|---|
| 1162 | ptr++;
|
|---|
| 1163 |
|
|---|
| 1164 | errs[ptr] = S_SAT_ADD((int) errs[ptr], err3);
|
|---|
| 1165 | }
|
|---|
| 1166 | }
|
|---|
| 1167 | /*...e*/
|
|---|
| 1168 | /*...sgbm_errdiff_BW \45\ error diffuse to black and white:0:*/
|
|---|
| 1169 | BOOLEAN gbm_errdiff_BW(const GBM *gbm, const byte *data24, byte *data1)
|
|---|
| 1170 | {
|
|---|
| 1171 | return errdiff(gbm, data24, data1, 1, gbm_errdiff_line_BW);
|
|---|
| 1172 | }
|
|---|
| 1173 | /*...e*/
|
|---|