home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / Graphics / ToyViewer-2.6a / src / ImageOpr.bproj / MDAmethod.m < prev    next >
Encoding:
Text File  |  1996-10-02  |  2.6 KB  |  131 lines

  1. /*
  2.     ˚¿¶±˙»¯ä¶Æ»ý¸¡
  3.  
  4.     Mean Density Approximation Method
  5.     by Y.Kurosawa: "A Bilevel Display Technique for Gray Pictures Using
  6.     Mean Density Approximation", Trans. IPSJ, Vol.26, No.1, pp.153-160,
  7.     Jan. 1985 (in Japanese).
  8.  
  9.     This routine uses modified MDA method coded by Takeshi Ogihara.
  10. */
  11. #import  "MDAmethod.h"
  12. #import  <stdlib.h>
  13. #import  <string.h>
  14.  
  15. @implementation MDAmethod
  16.  
  17. #define  CUR_WEIGHT    10
  18. static const unsigned char weight[3][5] = {
  19.     {0, 1, 2, 1, 0},
  20.     {1, 2, 5, 2, 1},
  21.     {2, 5, 0, 5, 2}
  22. };
  23.  
  24.  
  25. - init:(int)pixellevel width:(int)width
  26. {
  27.     [super init];
  28.     if ((buffer = (unsigned char *)malloc(width * 3)) == NULL) {
  29.         [super init];
  30.         return nil;
  31.     }
  32.     lines[0] = buffer;
  33.     lines[1] = lines[0] + width;
  34.     lines[2] = lines[1] + width;
  35.     lnwidth = width;
  36.     return [self reset: pixellevel];
  37. }
  38.  
  39. - reset:(int)pixellevel
  40. {
  41.     int i, v;
  42.     float thresh, wadd;
  43.  
  44.     first = 1;
  45.     thresh = 256.0 / (pixellevel - 1) + 0.1;
  46.     leftToRight = YES;
  47.     if (pixellevel == 2) {
  48.         for (i = 0; i < 128; i++) grad[i] = 0;
  49.         for ( ; i < 256; i++) grad[i] = 255;
  50.         threshold[0] = 0;
  51.         threshold[1] = 255;
  52.     }else {
  53.         wadd = thresh / 2.0;
  54.         for (i = 0; i < 256; i++) {
  55.             v = (int)((i + wadd) / thresh) * thresh;
  56.             if (v >= 255) break;
  57.             grad[i] = (v < 0) ? 0 : v;
  58.         }
  59.         for ( ; i < 256; i++) grad[i] = 255;
  60.         for (i = 0; i < 16; i++) {
  61.             if ((v = thresh * i) >= 255) {
  62.                 threshold[i] = 255;
  63.                 break;
  64.             }
  65.             threshold[i] = v;
  66.         }
  67.     }
  68.     return self;
  69. }
  70.  
  71. - free
  72. {
  73.     free((void *)buffer);
  74.     [super free];
  75.     return nil;
  76. }
  77.  
  78. - (unsigned char *)buffer
  79. {
  80.     return lines[2];
  81. }
  82.  
  83. - (unsigned char *)getNewLine
  84. {
  85.     int totalv, totalw;
  86.     int idx, i, j, w, low, high;
  87.     unsigned char *p;
  88.  
  89.     if (first) {
  90.         memcpy(lines[0], lines[2], lnwidth);
  91.         memcpy(lines[1], lines[2], lnwidth);
  92.         first = 0;
  93.     }
  94.     idx = leftToRight ? 0 : (lnwidth - 1);
  95.     do {
  96.         if ((low = idx - 2) < 0) low = 0;
  97.         if ((high = idx + 2) >= lnwidth) high = lnwidth - 1;
  98.         totalv = 0;
  99.         totalw = 0;
  100.         for (i = 0; i < 3; i++)
  101.             for (j = low; j < high; j++) {
  102.                 if ((w = weight[i][j + 2 - idx]) == 0)
  103.                     continue;
  104.                 totalw += w;
  105.                 totalv += lines[i][j] * w;
  106.             }
  107.     
  108.         /* (totalv + X * WEIGHT) / (totalw + WEIGHT) ~= val */
  109.         /* (totalv + X * WEIGHT) ~= val * (totalw + WEIGHT) */
  110.         /* X * WEIGHT ~= val * (totalw + WEIGHT) - totalv */
  111.         w = (lines[2][idx] * (totalw + CUR_WEIGHT) - totalv)
  112.             / CUR_WEIGHT;
  113.         lines[2][idx] = (w > 255) ? 255 : ((w < 0) ? 0 : grad[w]);
  114.     }while (leftToRight ? (++idx < lnwidth) : (--idx >= 0));
  115.  
  116.     p = lines[0];
  117.     lines[0] = lines[1];
  118.     lines[1] = lines[2];
  119.     lines[2] = p;
  120.     leftToRight = !leftToRight;
  121.  
  122.     return lines[1];
  123. }
  124.  
  125. - (const unsigned char *)threshold
  126. {
  127.     return threshold;
  128. }
  129.  
  130. @end
  131.