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 "video.h"
27 #include "proto.h"
28 #include "dither.h"
29
30
31
32 /*
33 *--------------------------------------------------------------
34 *
35 * MonoDitherImage --
36 *
37 * Dithers image into monochrome.
38 * Dither algorithm is based on dither.c in xli.1.11.
39 *
40 * Results:
41 * None.
42 *
43 * Side effects:
44 * None.
45 *
46 *--------------------------------------------------------------
47 */
48 #define MaxGrey 65280
49 #define Threshold (MaxGrey/2)
50 #define MinGrey 0
51
52 #if LITTLE_ENDIAN_ARCHITECTURE
53 # define SEED_BIT 0x01
54 # define OPP_SEED_BIT 0x80
55 # define SHIFT_SEED_BIT(b) (b <<= 1)
56 # define OPP_SHIFT_SEED_BIT(b) (b >>= 1)
57 #else
58 # define SEED_BIT 0x80
59 # define OPP_SEED_BIT 0x01
60 # define SHIFT_SEED_BIT(b) (b >>= 1)
61 # define OPP_SHIFT_SEED_BIT(b) (b <<= 1)
62 #endif
63
64 static int *curr = NULL;
65 static int *next = NULL;
66
67 void
MonoDitherImage(lum,cr,cb,out,h,w)68 MonoDitherImage(lum, cr, cb, out, h, w)
69 register unsigned char *lum;
70 unsigned char *cr;
71 unsigned char *cb;
72 register unsigned char *out;
73 int w, h;
74 {
75 int bit_r2l;
76 register unsigned int bit;
77 register unsigned int data;
78 int i;
79 register int j;
80 int *swap;
81 register int out_err;
82 register int next1;
83 register int next2;
84
85 if (curr == NULL) {
86 curr = (int *)malloc((unsigned int) sizeof(int) * (w + 2));
87 curr += 1;
88 }
89 if (next == NULL) {
90 next = (int *)malloc((unsigned int) sizeof(int) * (w + 2));
91 next += 1;
92 }
93
94 memset ((char *)curr, 0, (size_t)w * sizeof(*curr));
95
96 bit_r2l = SEED_BIT << (w - 1 & 7);
97 for (i = 0; i < h; i ++) {
98 if (i & 0x01) { /* Right to Left */
99 bit = bit_r2l;
100 data = 0;
101 out_err = curr[w-1];
102 next1 = 0;
103 next2 = 0;
104 for (j=(w-1); j>=0; j--)
105 {
106 out_err = (out_err >> 4) + (lum[j] << 8);
107 if (out_err > Threshold) {
108 data |= bit;
109 out_err -= MaxGrey;
110 }
111 else
112 out_err -= MinGrey;
113
114 next[j+1] = next1 + (out_err * 3);
115 next1 = next2 + (out_err * 5);
116 next2 = (out_err * 1);
117 out_err = curr[j-1] + (out_err * 7);
118
119 OPP_SHIFT_SEED_BIT(bit);
120 #if LITTLE_ENDIAN_ARCHITECTURE
121 if (bit == 0) {
122 #else
123 if (bit > 0x80) {
124 #endif
125 out[j >> 3] = data;
126 bit = OPP_SEED_BIT;
127 data = 0;
128 }
129 }
130 next[0] = next1;
131 }
132 else { /* Left to Right */
133 bit = SEED_BIT;
134 data = 0;
135 out_err = curr[0];
136 next1 = 0;
137 next2 = 0;
138 for (j=0; j<w; j++)
139 {
140 out_err = (out_err >> 4) + (lum[j] << 8);
141 if (out_err > Threshold) {
142 data |= bit;
143 out_err = out_err - MaxGrey;
144 }
145 else
146 out_err = out_err - MinGrey;
147
148 next[j-1] = next1 + (out_err * 3);
149 next1 = next2 + (out_err * 5);
150 next2 = (out_err * 1);
151 out_err = curr[j+1] + (out_err * 7);
152
153 SHIFT_SEED_BIT(bit);
154 #if LITTLE_ENDIAN_ARCHITECTURE
155 if (bit > 0x80) {
156 #else
157 if (bit == 0) {
158 #endif
159 out[j >> 3] = data;
160 bit = SEED_BIT;
161 data = 0;
162 }
163 }
164 next[w-1] = next1;
165 }
166
167 lum += w;
168 out += w >> 3;
169 swap = curr;
170 curr = next;
171 next = swap;
172 }
173 }
174
175
176
177 /*
178 *--------------------------------------------------------------
179 *
180 * MonoThresholdImage --
181 *
182 * convert image into monochrome with threshold.
183 *
184 * Results:
185 * None.
186 *
187 * Side effects:
188 * None.
189 *
190 *--------------------------------------------------------------
191 */
192 void
MonoThresholdImage(lum,cr,cb,out,h,w)193 MonoThresholdImage(lum, cr, cb, out, h, w)
194 unsigned char *lum;
195 unsigned char *cr;
196 unsigned char *cb;
197 unsigned char *out;
198 int w, h;
199 {
200 unsigned char bit;
201 unsigned char data;
202
203 bit = SEED_BIT;
204 data = 0;
205 for (w*=h; w>0; w--) {
206 if(*lum++>128)
207 data |= bit;
208
209 SHIFT_SEED_BIT(bit);
210 if(bit == 0) {
211 *out ++ = data;
212 bit = SEED_BIT;
213 data = 0;
214 }
215 }
216 }
217