Subversion Repositories shark

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/*
2
 * 2x2.c --
3
 *
4
 *      Procedures concerned with 2x2 dithering.
5
 *
6
 */
7
 
8
/*
9
 * Copyright (c) 1995 The Regents of the University of California.
10
 * All rights reserved.
11
 *
12
 * Permission to use, copy, modify, and distribute this software and its
13
 * documentation for any purpose, without fee, and without written agreement is
14
 * hereby granted, provided that the above copyright notice and the following
15
 * two paragraphs appear in all copies of this software.
16
 *
17
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
18
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
19
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
20
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21
 *
22
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
23
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
24
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
25
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
26
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
27
 */
28
 
29
#include "video.h"
30
#include "dither.h"
31
#include "proto.h"
32
#ifdef __STDC__
33
#include <stdlib.h>
34
#endif
35
 
36
#define RAND_ERR_RANGE 7
37
#define RAND_ERR_SUBVAL 3
38
 
39
#define NO_LRAND48
40
#define NO_RANDOM
41
 
42
/* Array containing actual pixel values for each possible 2x2 dither pattern. */
43
 
44
static unsigned char *dith_a;
45
 
46
/* Arrays mapping lum, cr, and cb values to portions of dither pattern code.
47
   The addtion of one value from each array yields a valid dither pattern
48
   code.
49
*/
50
 
51
static int lval_a[256+RAND_ERR_RANGE-1];
52
static int rval_a[256+RAND_ERR_RANGE-1];
53
static int bval_a[256+RAND_ERR_RANGE-1];
54
 
55
/* Range of possible dither patterns in each channel. */
56
 
57
#define L_DITH_RANGE (((LUM_RANGE-1)*4)+1)
58
#define CR_DITH_RANGE (((CR_RANGE-1)*4)+1)
59
#define CB_DITH_RANGE (((CB_RANGE-1)*4)+1)
60
 
61
/* Arrays of random error terms added to break up contours. */
62
 
63
static int *randval_a;
64
static int **randptr_a;
65
 
66
 
67
/*
68
 *--------------------------------------------------------------
69
 *
70
 *  Init2x2Dither--
71
 *
72
 *      Initializes structures used for 2x2 dithering.
73
 *
74
 * Results:
75
 *      None.
76
 *
77
 * Side effects:
78
 *      None.
79
 *
80
 *--------------------------------------------------------------
81
 */
82
 
83
void
84
Init2x2Dither()
85
{  
86
  unsigned char *dith_ca;
87
  int numcodes;
88
  int l_range, cr_range, cb_range;
89
  int p1, p2, p3, p4;
90
  int l_dith, cr_dith, cb_dith;
91
  int big_part, small_part;
92
  int i, j;
93
 
94
  l_range = L_DITH_RANGE;
95
  cr_range = CR_DITH_RANGE;
96
  cb_range = CB_DITH_RANGE;
97
 
98
  numcodes =  l_range * cr_range * cb_range;
99
 
100
  dith_a = (unsigned char *) malloc(numcodes*4);
101
 
102
  dith_ca =  dith_a;
103
 
104
  for (i=0; i<numcodes; i++) {
105
    l_dith = i  % l_range;
106
 
107
    big_part = l_dith / 4;
108
    small_part = l_dith % 4;
109
 
110
    p1 = big_part + ((small_part > 0) ? 1 : 0);
111
    p2 = big_part + ((small_part > 2) ? 1 : 0);
112
    p3 = big_part;
113
    p4 = big_part + ((small_part > 1) ? 1 : 0);
114
 
115
    p1 *= CR_RANGE * CB_RANGE;
116
    p2 *= CR_RANGE * CB_RANGE;
117
    p3 *= CR_RANGE * CB_RANGE;
118
    p4 *= CR_RANGE * CB_RANGE;
119
 
120
    cr_dith = (i/l_range) % cr_range;
121
 
122
    big_part = cr_dith / 4;
123
    small_part = cr_dith % 4;
124
 
125
    p1 += (big_part + ((small_part > 0) ? 1 : 0))*CB_RANGE;
126
    p2 += (big_part + ((small_part > 2) ? 1 : 0))*CB_RANGE;
127
    p3 += (big_part)*CB_RANGE;
128
    p4 += (big_part + ((small_part > 1) ? 1 : 0))*CB_RANGE;
129
 
130
    cb_dith = (i/(cr_range*l_range)) % cb_range;
131
 
132
    big_part = cb_dith / 4;
133
    small_part = cb_dith % 4;
134
 
135
    p1 += (big_part + ((small_part > 0) ? 1 : 0));
136
    p2 += (big_part + ((small_part > 2) ? 1 : 0));
137
    p3 += (big_part);
138
    p4 += (big_part + ((small_part > 1) ? 1 : 0));
139
 
140
    *dith_ca++ = p1;
141
    *dith_ca++ = p2;
142
    *dith_ca++ = p3;
143
    *dith_ca++ = p4;
144
  }
145
 
146
  for (i=RAND_ERR_SUBVAL; i<256+RAND_ERR_SUBVAL; i++) {
147
    j = i-RAND_ERR_SUBVAL;
148
    lval_a[i] = (j * L_DITH_RANGE)/256;
149
    rval_a[i] = (j * CR_DITH_RANGE)/256;
150
    bval_a[i] = (j * CB_DITH_RANGE)/256;
151
 
152
    bval_a[i] *= CR_DITH_RANGE * L_DITH_RANGE * 4;
153
    rval_a[i] *= L_DITH_RANGE * 4;
154
    lval_a[i] *= 4;
155
  }
156
 
157
  for (i=0; i<RAND_ERR_SUBVAL; i++) {
158
    lval_a[i] = lval_a[RAND_ERR_SUBVAL];
159
    rval_a[i] = rval_a[RAND_ERR_SUBVAL];
160
    bval_a[i] = bval_a[RAND_ERR_SUBVAL];
161
  }
162
 
163
   for(i=256+RAND_ERR_SUBVAL; i<256+RAND_ERR_RANGE-1; i++) {
164
     lval_a[i] = lval_a[255+RAND_ERR_SUBVAL];
165
     rval_a[i] = rval_a[255+RAND_ERR_SUBVAL];
166
     bval_a[i] = bval_a[255+RAND_ERR_SUBVAL];
167
   }
168
}
169
 
170
 
171
/*
172
 *--------------------------------------------------------------
173
 *
174
 * RandInit --
175
 *
176
 *      Initializes the random values used for 2x2 dithering.
177
 *
178
 * Results:
179
 *      randval_a filled with random values.
180
 *      randptr_a filled with random pointers to random value arrays.
181
 *
182
 * Side effects:
183
 *      None.
184
 *
185
 *--------------------------------------------------------------
186
 */
187
 
188
void RandInit(h, w)
189
     int h, w;
190
{
191
  int i;
192
 
193
  randval_a = (int *) malloc(w*5*sizeof(int));
194
  randptr_a = (int **) malloc(h*sizeof(int *));
195
 
196
#ifdef NO_LRAND48
197
  for (i=0; i<w*5; i++) {
198
#ifdef NO_RANDOM
199
#define random() rand()
200
#else
201
    long int random();
202
#endif
203
 
204
    randval_a[i] = random() % RAND_ERR_RANGE;
205
  }
206
 
207
  for (i=0; i<h; i++) {
208
#ifndef NO_RANDOM
209
    long int random();
210
#endif
211
 
212
    randptr_a[i] = randval_a + (random() % (w*2));
213
  }
214
#else /* NO_LRAND48 */
215
 
216
  for (i=0; i<w*5; i++) {
217
    long int lrand48();
218
 
219
    randval_a[i] = lrand48() % RAND_ERR_RANGE;
220
  }
221
 
222
  for (i=0; i<h; i++) {
223
    long int lrand48();
224
 
225
    randptr_a[i] = randval_a + (lrand48() % (w*2));
226
  }
227
#endif
228
 
229
}
230
 
231
 
232
/*
233
 *--------------------------------------------------------------
234
 *
235
 *  PostInit2x2Dither--
236
 *
237
 *      Remaps color numbers in dither patterns to actual pixel
238
 *      values allocated by the X server.
239
 *
240
 * Results:
241
 *      None.
242
 *
243
 * Side effects:
244
 *      None.
245
 *
246
 *--------------------------------------------------------------
247
 */
248
 
249
void
250
PostInit2x2Dither()
251
{
252
  unsigned char *dith_ca;
253
  int i;
254
 
255
  dith_ca = dith_a;
256
 
257
  for (i=0; i < (L_DITH_RANGE * CR_DITH_RANGE * CB_DITH_RANGE); i++) {
258
 
259
    *dith_ca = pixel[*dith_ca];
260
    dith_ca++;
261
    *dith_ca = pixel[*dith_ca];
262
    dith_ca++;
263
    *dith_ca = pixel[*dith_ca];
264
    dith_ca++;
265
    *dith_ca = pixel[*dith_ca];
266
    dith_ca++;
267
  }
268
}
269
 
270
 
271
/*
272
 *--------------------------------------------------------------
273
 *
274
 * Twox2DitherImage --
275
 *
276
 *      Dithers lum, cr, and cb channels togethor using predefined
277
 *      and computed 2x2 dither patterns. Each possible combination of
278
 *      lum, cr, and cb values combines to point to a particular dither
279
 *      pattern (2x2) which is used to represent the pixel. This assumes
280
 *      That the display plane is 4 times larger than the lumianance
281
 *      plane.
282
 *
283
 * Results:
284
 *      None.
285
 *
286
 * Side effects:
287
 *      None.
288
 *
289
 *--------------------------------------------------------------
290
 */
291
 
292
void
293
Twox2DitherImage(lum, cr, cb, out, h, w)
294
    unsigned char *lum;
295
    unsigned char *cr;
296
    unsigned char *cb;
297
    unsigned char *out;
298
    int w, h;
299
{
300
  int i, j;
301
  unsigned short *o1, *o2, *o3, *o4;
302
  unsigned char *l1, *l2, *base;
303
  unsigned char B, R;
304
  unsigned short *dith_ca;
305
  int big_adv = 3*w;
306
  int b_val, r_val, l_val;
307
  static int first = 1;
308
 
309
  if (first) {
310
    RandInit(h, w);
311
    first = 0;
312
  }
313
 
314
  o1 = (unsigned short *)out;
315
  o2 = (unsigned short *)(out+(2*w));
316
  o3 = (unsigned short *)(out+(4*w));
317
  o4 = (unsigned short *)(out+(6*w));
318
  l1 = lum;
319
  l2 = lum+w;
320
 
321
  for (i=0; i<h; i+=2) {
322
    for(j=0; j<w; j+= 4) {
323
 
324
      B = cb[0];
325
      b_val = bval_a[B];
326
      R = cr[0];
327
      r_val = rval_a[R];
328
      base = dith_a + b_val + r_val;
329
 
330
      l_val = lval_a[l1[0]];
331
      dith_ca = (unsigned short *)(base + l_val);
332
      o1[0] = dith_ca[0];
333
      o2[0] = dith_ca[1];
334
 
335
      l_val = lval_a[l1[1]];
336
      dith_ca = (unsigned short *)(base + l_val);
337
      o1[1] = dith_ca[0];
338
      o2[1] = dith_ca[1];
339
 
340
      l_val = lval_a[l2[0]];
341
      dith_ca = (unsigned short *)(base + l_val);
342
      o3[0] = dith_ca[0];
343
      o4[0] = dith_ca[1];
344
 
345
      l_val = lval_a[l2[1]];
346
      dith_ca = (unsigned short *)(base + l_val);
347
      o3[1] = dith_ca[0];
348
      o4[1] = dith_ca[1];
349
 
350
      B = cb[1];
351
      b_val = bval_a[B];
352
      R = cr[1];
353
      r_val = rval_a[R];
354
      base = dith_a + b_val + r_val;
355
 
356
      l_val = lval_a[l1[2]];
357
      dith_ca = (unsigned short *)(base + l_val);
358
      o1[2] = dith_ca[0];
359
      o2[2] = dith_ca[1];
360
 
361
      l_val = lval_a[l1[3]];
362
      dith_ca = (unsigned short *)(base + l_val);
363
      o1[3] = dith_ca[0];
364
      o2[3] = dith_ca[1];
365
 
366
      l_val = lval_a[l2[2]];
367
      dith_ca = (unsigned short *)(base + l_val);
368
      o3[2] = dith_ca[0];
369
      o4[2] = dith_ca[1];
370
 
371
      l_val = lval_a[l2[3]];
372
      dith_ca = (unsigned short *)(base + l_val);
373
      o3[3] = dith_ca[0];
374
      o4[3] = dith_ca[1];
375
 
376
      o1 += 4;
377
      o2 += 4;
378
      o3 += 4;
379
      o4 += 4;
380
      l1 += 4;
381
      l2 += 4;
382
      cb += 2;
383
      cr += 2;
384
    }    
385
 
386
    l1 += w;
387
    l2 += w;
388
    o1 += big_adv;
389
    o2 += big_adv;
390
    o3 += big_adv;
391
    o4 += big_adv;
392
  }
393
}