This is MDAmethod.m in view mode; [Download] [Up]
/*
Ê¿¶ÑÇ»ÅÙ¶á»÷Ë¡
Mean Density Approximation Method
by Y.Kurosawa: "A Bilevel Display Technique for Gray Pictures Using
Mean Density Approximation", Trans. IPSJ, Vol.26, No.1, pp.153-160,
Jan. 1985 (in Japanese).
This routine uses modified MDA method coded by Takeshi Ogihara.
*/
#import "MDAmethod.h"
#import <stdlib.h>
#import <string.h>
@implementation MDAmethod
#define CUR_WEIGHT 10
static const unsigned char weight[3][5] = {
{0, 1, 2, 1, 0},
{1, 2, 5, 2, 1},
{2, 5, 0, 5, 2}
};
- init:(int)pixellevel width:(int)width
{
[super init];
if ((buffer = (unsigned char *)malloc(width * 3)) == NULL) {
[super init];
return nil;
}
lines[0] = buffer;
lines[1] = lines[0] + width;
lines[2] = lines[1] + width;
lnwidth = width;
return [self reset: pixellevel];
}
- reset:(int)pixellevel
{
int i, v;
float thresh, wadd;
first = 1;
thresh = 256.0 / (pixellevel - 1) + 0.1;
leftToRight = YES;
if (pixellevel == 2) {
for (i = 0; i < 128; i++) grad[i] = 0;
for ( ; i < 256; i++) grad[i] = 255;
threshold[0] = 0;
threshold[1] = 255;
}else {
wadd = thresh / 2.0;
for (i = 0; i < 256; i++) {
v = (int)((i + wadd) / thresh) * thresh;
if (v >= 255) break;
grad[i] = (v < 0) ? 0 : v;
}
for ( ; i < 256; i++) grad[i] = 255;
for (i = 0; i < 16; i++) {
if ((v = thresh * i) >= 255) {
threshold[i] = 255;
break;
}
threshold[i] = v;
}
}
return self;
}
- free
{
free((void *)buffer);
[super free];
return nil;
}
- (unsigned char *)buffer
{
return lines[2];
}
- (unsigned char *)getNewLine
{
int totalv, totalw;
int idx, i, j, w, low, high;
unsigned char *p;
if (first) {
memcpy(lines[0], lines[2], lnwidth);
memcpy(lines[1], lines[2], lnwidth);
first = 0;
}
idx = leftToRight ? 0 : (lnwidth - 1);
do {
if ((low = idx - 2) < 0) low = 0;
if ((high = idx + 2) >= lnwidth) high = lnwidth - 1;
totalv = 0;
totalw = 0;
for (i = 0; i < 3; i++)
for (j = low; j < high; j++) {
if ((w = weight[i][j + 2 - idx]) == 0)
continue;
totalw += w;
totalv += lines[i][j] * w;
}
/* (totalv + X * WEIGHT) / (totalw + WEIGHT) ~= val */
/* (totalv + X * WEIGHT) ~= val * (totalw + WEIGHT) */
/* X * WEIGHT ~= val * (totalw + WEIGHT) - totalv */
w = (lines[2][idx] * (totalw + CUR_WEIGHT) - totalv)
/ CUR_WEIGHT;
lines[2][idx] = (w > 255) ? 255 : ((w < 0) ? 0 : grad[w]);
}while (leftToRight ? (++idx < lnwidth) : (--idx >= 0));
p = lines[0];
lines[0] = lines[1];
lines[1] = lines[2];
lines[2] = p;
leftToRight = !leftToRight;
return lines[1];
}
- (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.