This is Dither.m in view mode; [Download] [Up]
#import "Dither.h" #import <stdlib.h> #import <string.h> @implementation Dither static const unsigned char ditherTable[4][4] = { { 0, 8, 2, 10}, { 12, 4, 14, 6}, { 3, 11, 1, 9}, { 15, 7, 13, 5} }; - init:(int)pixellevel width:(int)width { if ((buffer = (unsigned char *)malloc(width)) == NULL) { [super init]; return nil; } lnwidth = width; return [self reset: pixellevel]; } - reset:(int)pixellevel { int i, v, pv, cnt; float thresh, thstep; ylines = 0; thresh = 256.0 / (pixellevel - 1) + 0.1; thstep = (int)thresh / 17.0; threshold[cnt = 0] = pv = 0; for (i = 0, v = (int)thresh; i < 256; i++) { if (i >= v) { threshold[++cnt] = pv = v; v = (int)((cnt + 1) * thresh); if (v > 255) v = 255; } sect[i] = cnt; grad[i] = (int)((i - pv) / thstep); } threshold[++cnt] = 255; return self; } - free { free((void *)buffer); [super free]; return nil; } - (unsigned char *)buffer { return buffer; } - (unsigned char *)getNewLine { int x, cc, n; const unsigned char *yp; yp = ditherTable[ylines & 0x03]; for (x = 0; x < lnwidth; x++) { cc = buffer[x]; n = sect[cc]; if (yp[x & 3] < grad[cc]) ++n; buffer[x] = threshold[n]; } ylines++; return buffer; } - (const unsigned char *)threshold { return threshold; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.