Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/*
2
 * Author:    Yoichiro Ueno (ueno@cs.titech.ac.jp)
3
 *
4
 * Copyright (C) 1991, 1992, Yoichiro Ueno.
5
 *
6
 * Permission to use, copy, modify, and distribute this software and
7
 * its documentation for any purpose is hereby granted by the Author without
8
 * fee, provided that the above copyright notice appear in all copies and
9
 * that both the copyright notice and this permission notice appear in
10
 * supporting documentation, and that the name of the Author not be used
11
 * in advertising or publicity pertaining to distribution of the software
12
 * without specific, written prior permission.  The Author makes no
13
 * representations about the suitability of this software for any purpose.
14
 * It is provided "as is" without express or implied warranty.
15
 *
16
 * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
20
 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21
 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22
 * PERFORMANCE OF THIS SOFTWARE.
23
 *
24
 */
25
 
26
#include <stddef.h>
27
#include "video.h"
28
#include "proto.h"
29
#include "dither.h"
30
 
31
 
32
 
33
/*
34
 *--------------------------------------------------------------
35
 *
36
 * MonoDitherImage --
37
 *
38
 *    Dithers image into monochrome.
39
 *    Dither algorithm is based on dither.c in xli.1.11.
40
 *
41
 * Results:
42
 *    None.
43
 *
44
 * Side effects:
45
 *    None.
46
 *
47
 *--------------------------------------------------------------
48
 */
49
#define MaxGrey        65280
50
#define Threshold    (MaxGrey/2)
51
#define MinGrey        0
52
 
53
#if LITTLE_ENDIAN_ARCHITECTURE
54
#    define SEED_BIT 0x01
55
#    define OPP_SEED_BIT 0x80
56
#    define SHIFT_SEED_BIT(b) (b <<= 1)
57
#    define OPP_SHIFT_SEED_BIT(b) (b >>= 1)
58
#else
59
#    define SEED_BIT 0x80
60
#    define OPP_SEED_BIT 0x01
61
#    define SHIFT_SEED_BIT(b) (b >>= 1)
62
#    define OPP_SHIFT_SEED_BIT(b) (b <<= 1)
63
#endif
64
 
65
static int    *curr = NULL;
66
static int    *next = NULL;
67
 
68
void
69
MonoDitherImage(lum, cr, cb, out, h, w)
70
    register unsigned char *lum;
71
    unsigned char *cr;
72
    unsigned char *cb;
73
    register unsigned char *out;
74
    int w, h;
75
{
76
  int bit_r2l;
77
  register unsigned int bit;
78
  register unsigned int data;
79
  int i;
80
  register int j;
81
  int *swap;
82
  register int out_err;
83
  register int next1;
84
  register int next2;
85
 
86
  if (curr == NULL) {
87
    curr = (int *)malloc((unsigned int) sizeof(int) * (w + 2));
88
    curr += 1;
89
  }
90
  if (next == NULL) {
91
    next = (int *)malloc((unsigned int) sizeof(int) * (w + 2));
92
    next += 1;
93
  }
94
 
95
  memset ((char *)curr, 0, (size_t)w * sizeof(*curr));
96
 
97
  bit_r2l = SEED_BIT << ((w - 1) & 7);
98
  for (i = 0; i < h; i ++) {
99
    if (i & 0x01) {                /* Right to Left */
100
      bit = bit_r2l;
101
      data = 0;
102
      out_err = curr[w-1];
103
      next1 = 0;
104
      next2 = 0;
105
      for (j=(w-1); j>=0; j--)
106
      {
107
        out_err = (out_err >> 4) + (lum[j] << 8);
108
        if (out_err > Threshold) {
109
          data |= bit;
110
          out_err -= MaxGrey;
111
        }
112
        else
113
          out_err -= MinGrey;
114
 
115
        next[j+1] = next1 +     (out_err * 3);
116
        next1     = next2 +     (out_err * 5);
117
        next2     =             (out_err * 1);
118
        out_err   = curr[j-1] + (out_err * 7);
119
 
120
        OPP_SHIFT_SEED_BIT(bit);
121
#if LITTLE_ENDIAN_ARCHITECTURE
122
        if (bit == 0) {
123
#else
124
        if (bit > 0x80) {
125
#endif
126
          out[j >> 3] = data;
127
          bit = OPP_SEED_BIT;
128
          data = 0;
129
        }
130
      }
131
      next[0] = next1;
132
    }
133
    else {                    /* Left to Right */
134
      bit = SEED_BIT;
135
      data = 0;
136
      out_err = curr[0];
137
      next1 = 0;
138
      next2 = 0;
139
      for (j=0; j<w; j++)
140
      {
141
        out_err = (out_err >> 4) + (lum[j] << 8);
142
        if (out_err > Threshold) {
143
          data |= bit;
144
          out_err = out_err - MaxGrey;
145
        }
146
        else
147
          out_err = out_err - MinGrey;
148
 
149
        next[j-1] = next1 +     (out_err * 3);
150
        next1     = next2 +     (out_err * 5);
151
        next2     =             (out_err * 1);
152
        out_err   = curr[j+1] + (out_err * 7);
153
 
154
        SHIFT_SEED_BIT(bit);
155
#if LITTLE_ENDIAN_ARCHITECTURE
156
        if (bit > 0x80) {
157
#else
158
        if (bit == 0) {
159
#endif
160
          out[j >> 3] = data;
161
          bit = SEED_BIT;
162
          data = 0;
163
        }
164
      }
165
      next[w-1] = next1;
166
    }
167
 
168
    lum += w;
169
    out += w >> 3;
170
    swap = curr;
171
    curr = next;
172
    next = swap;
173
  }
174
}
175
 
176
 
177
 
178
/*
179
 *--------------------------------------------------------------
180
 *
181
 * MonoThresholdImage --
182
 *
183
 *    convert image into monochrome with threshold.
184
 *
185
 * Results:
186
 *    None.
187
 *
188
 * Side effects:
189
 *    None.
190
 *
191
 *--------------------------------------------------------------
192
 */
193
void
194
MonoThresholdImage(lum, cr, cb, out, h, w)
195
    unsigned char *lum;
196
    unsigned char *cr;
197
    unsigned char *cb;
198
    unsigned char *out;
199
    int w, h;
200
{
201
  unsigned char bit;
202
  unsigned char data;
203
 
204
  bit = SEED_BIT;
205
  data = 0;
206
  for (w*=h; w>0; w--) {
207
    if(*lum++>128)
208
      data |= bit;
209
 
210
    SHIFT_SEED_BIT(bit);
211
    if(bit == 0) {
212
      *out ++ = data;
213
      bit = SEED_BIT;
214
      data = 0;
215
    }
216
  }
217
}