Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/*
2
 * ordered2.c --
3
 *
4
 *      This file contains C code to implement a faster ordered dither
5
 *      than the one found in ordered.c.  This dither is the default
6
 *      if no dither is specified.
7
 *
8
 */
9
 
10
/*  
11
 * Copyright (c) 1995 The Regents of the University of California.
12
 * All rights reserved.
13
 *
14
 * Permission to use, copy, modify, and distribute this software and its
15
 * documentation for any purpose, without fee, and without written agreement is
16
 * hereby granted, provided that the above copyright notice and the following
17
 * two paragraphs appear in all copies of this software.
18
 *
19
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
20
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
21
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
22
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
 *
24
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
25
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
26
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
27
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
28
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
29
 */
30
 
31
#include "video.h"
32
#include "proto.h"
33
#include "dither.h"
34
 
35
#define DITH_SIZE 16
36
 
37
 
38
/* Structures used to implement hybrid ordered dither/floyd-steinberg
39
   dither algorithm.
40
*/
41
 
42
static unsigned char ***ditherPtr[DITH_SIZE];
43
 
44
 
45
/*
46
 *--------------------------------------------------------------
47
 *
48
 *  InitOrderedDither--
49
 *
50
 *      Structures intialized for ordered dithering.
51
 *
52
 * Results:
53
 *      None.
54
 *
55
 * Side effects:
56
 *      None.
57
 *
58
 *--------------------------------------------------------------
59
 */
60
 
61
void
62
InitOrdered2Dither()
63
{
64
  unsigned char ****pos_2_cb;
65
  unsigned char ***cb_2_cr;
66
  unsigned char **cr_2_l;
67
  int cb_val, cb_rval, cr_val, cr_rval, l_val, l_rval;
68
  int i, j, pos;
69
  int err_range, threshval;
70
 
71
  pos_2_cb = (unsigned char ****) malloc (DITH_SIZE*sizeof(unsigned char ***));
72
  cb_2_cr = (unsigned char ***) malloc(CB_RANGE*sizeof(unsigned char **));
73
  cr_2_l = (unsigned char **) malloc(CR_RANGE*sizeof(unsigned char *));
74
 
75
  for (pos=0; pos<DITH_SIZE; pos++) {
76
 
77
    pos_2_cb[pos] = (unsigned char ***) malloc(256*(sizeof(unsigned char **)));
78
 
79
    for (j=0; j<CB_RANGE; j++) {
80
      cb_2_cr[j] = (unsigned char **) malloc(256*(sizeof(unsigned char *)));
81
    }
82
 
83
    for (cb_val=0; cb_val<cb_values[0]; cb_val++) {
84
      (pos_2_cb[pos])[cb_val] = cb_2_cr[0];
85
    }
86
 
87
    for (cb_rval=0; cb_rval<(CB_RANGE-1); cb_rval++) {
88
      err_range = cb_values[cb_rval+1] - cb_values[cb_rval];
89
      threshval = ((pos*err_range)/DITH_SIZE)+cb_values[cb_rval];
90
 
91
      for (cb_val=cb_values[cb_rval]; cb_val<cb_values[cb_rval+1]; cb_val++) {
92
        if (cb_val>threshval) (pos_2_cb[pos])[cb_val] = cb_2_cr[cb_rval+1];
93
        else (pos_2_cb[pos])[cb_val] = cb_2_cr[cb_rval];
94
      }
95
    }
96
 
97
    for (cb_val=cb_values[CB_RANGE-1]; cb_val<256; cb_val++) {
98
      (pos_2_cb[pos])[cb_val] = cb_2_cr[CB_RANGE-1];
99
    }
100
 
101
    for (cb_rval=0; cb_rval<CB_RANGE; cb_rval++) {
102
 
103
      for (j=0; j<CR_RANGE; j++) {
104
        cr_2_l[j] = (unsigned char *) malloc(256*(sizeof(unsigned char)));
105
      }
106
 
107
      for (cr_val=0; cr_val < cr_values[0]; cr_val++) {
108
        (cb_2_cr[cb_rval])[cr_val] = cr_2_l[0];
109
      }
110
 
111
      for (cr_rval=0; cr_rval<(CR_RANGE-1); cr_rval++) {
112
        err_range = cr_values[cr_rval+1] - cr_values[cr_rval];
113
        threshval = ((pos*err_range)/DITH_SIZE)+cr_values[cr_rval];
114
 
115
        for (cr_val=cr_values[cr_rval]; cr_val<cr_values[cr_rval+1]; cr_val++) {
116
          if (cr_val>threshval) (cb_2_cr[cb_rval])[cr_val] = cr_2_l[cr_rval+1];
117
          else (cb_2_cr[cb_rval])[cr_val] = cr_2_l[cr_rval];
118
        }
119
      }
120
 
121
      for (cr_val=cr_values[CR_RANGE-1]; cr_val<256; cr_val++) {
122
        (cb_2_cr[cb_rval])[cr_val] = cr_2_l[CR_RANGE-1];
123
      }
124
 
125
      for (cr_rval=0; cr_rval<CR_RANGE; cr_rval++) {
126
 
127
        for (l_val = 0; l_val < lum_values[0]; l_val++) {
128
          (cr_2_l[cr_rval])[l_val] = pixel[cb_rval+(cr_rval*CB_RANGE)+
129
                                            (0*CR_RANGE*CB_RANGE)];
130
        }
131
 
132
        for (l_rval=0; l_rval<(LUM_RANGE-1); l_rval++) {
133
          err_range = lum_values[l_rval+1] - lum_values[l_rval];
134
          threshval = ((pos*err_range) /DITH_SIZE) + lum_values[l_rval];
135
 
136
          for (l_val = lum_values[l_rval]; l_val < lum_values[l_rval+1]; l_val++) {
137
            if (l_val>threshval) (cr_2_l[cr_rval])[l_val] =
138
              pixel[cb_rval+(cr_rval*CB_RANGE)+((l_rval+1)*CR_RANGE*CB_RANGE)];
139
            else (cr_2_l[cr_rval])[l_val] =
140
              pixel[cb_rval+(cr_rval*CB_RANGE)+(l_rval*CR_RANGE*CB_RANGE)];
141
          }
142
        }
143
 
144
        for (l_val = lum_values[LUM_RANGE-1]; l_val < 256; l_val++) {
145
          (cr_2_l[cr_rval])[l_val] =
146
            pixel[cb_rval+(cr_rval*CB_RANGE)+((LUM_RANGE-1)*CR_RANGE*CB_RANGE)];
147
        }
148
      }
149
    }
150
  }
151
 
152
  for (i=0; i<DITH_SIZE; i++) {
153
    ditherPtr[i] = pos_2_cb[i];
154
  }
155
}
156
 
157
 
158
/*
159
 *--------------------------------------------------------------
160
 *
161
 * Ordered2DitherImage --
162
 *
163
 *      Dithers an image using an ordered dither.
164
 *      Assumptions made:
165
 *        1) The color space is allocated y:cr:cb = 8:4:4
166
 *        2) The spatial resolution of y:cr:cb is 4:1:1
167
 *      The channels are dithered based on the standard
168
 *      ordered dither pattern for a 4x4 area.
169
 *
170
 * Results:
171
 *      None.
172
 *
173
 * Side effects:
174
 *      None.
175
 *
176
 *--------------------------------------------------------------
177
 */
178
void
179
Ordered2DitherImage (lum, cr, cb, out, h, w)
180
    unsigned char *lum;
181
    unsigned char *cr;
182
    unsigned char *cb;
183
    unsigned char *out;
184
    int w, h;
185
{
186
  unsigned char *l, *r, *b, *o1, *o2;
187
  unsigned char *l2;
188
  unsigned char L, R, B;
189
  int i, j;
190
  unsigned char ***dp0 = ditherPtr[0];
191
  unsigned char ***dp2 = ditherPtr[2];
192
  unsigned char ***dp4 = ditherPtr[4];
193
  unsigned char ***dp6 = ditherPtr[6];
194
  unsigned char ***dp8 = ditherPtr[8];
195
  unsigned char ***dp10 = ditherPtr[10];
196
  unsigned char ***dp12 = ditherPtr[12];
197
  unsigned char ***dp14 = ditherPtr[14];
198
  unsigned char ***dp1 = ditherPtr[1];
199
  unsigned char ***dp3 = ditherPtr[3];
200
  unsigned char ***dp5 = ditherPtr[5];
201
  unsigned char ***dp7 = ditherPtr[7];
202
  unsigned char ***dp9 = ditherPtr[9];
203
  unsigned char ***dp11 = ditherPtr[11];
204
  unsigned char ***dp13 = ditherPtr[13];
205
  unsigned char ***dp15 = ditherPtr[15];
206
 
207
  l = lum;
208
  l2 = lum+w;
209
  r = cr;
210
  b = cb;
211
  o1 = out;
212
  o2 = out+w;
213
 
214
  for (i=0; i<h; i+=4) {
215
 
216
    for (j=0; j<w; j+=8) {
217
 
218
      R = r[0]; B = b[0];
219
 
220
      L = l[0];
221
      o1[0] = ((dp0[B])[R])[L];
222
      L = l[1];
223
      o1[1] = ((dp8[B])[R])[L];
224
      L = l2[0];
225
      o2[0] = ((dp12[B])[R])[L];
226
      L = l2[1];
227
      o2[1] = ((dp4[B])[R])[L];
228
 
229
      R = r[1]; B = b[1];
230
 
231
      L = l[2];
232
      o1[2] = ((dp2[B])[R])[L];
233
      L = l[3];
234
      o1[3] = ((dp10[B])[R])[L];
235
      L = l2[2];
236
      o2[2] = ((dp14[B])[R])[L];
237
      L = l2[3];
238
      o2[3] = ((dp6[B])[R])[L];
239
 
240
      R = r[2]; B = b[2];
241
 
242
      L = l[4];
243
      o1[4] = ((dp0[B])[R])[L];
244
      L = l[5];
245
      o1[5] = ((dp8[B])[R])[L];
246
      L = l2[4];
247
      o2[4] = ((dp12[B])[R])[L];
248
      L = l2[5];
249
      o2[5] = ((dp4[B])[R])[L];
250
 
251
      R = r[3]; B = b[3];
252
 
253
      L = l[6];
254
      o1[6] = ((dp2[B])[R])[L];
255
      L = l[7];
256
      o1[7] = ((dp10[B])[R])[L];
257
      L = l2[6];
258
      o2[6] = ((dp14[B])[R])[L];
259
      L = l2[7];
260
      o2[7] = ((dp6[B])[R])[L];
261
 
262
      l += 8;
263
      l2 += 8;
264
      r += 4;
265
      b += 4;
266
      o1 += 8;
267
      o2 += 8;
268
    }
269
 
270
    l += w;
271
        l2 += w;
272
    o1 += w;
273
        o2 += w;
274
 
275
    for (j=0; j<w; j+=8) {
276
 
277
      R = r[0]; B = b[0];
278
 
279
      L = l[0];
280
      o1[0] = ((dp3[B])[R])[L];
281
      L = l[1];
282
      o1[1] = ((dp11[B])[R])[L];
283
      L = l2[0];
284
      o2[0] = ((dp15[B])[R])[L];
285
      L = l2[1];
286
      o2[1] = ((dp7[B])[R])[L];
287
 
288
      R = r[1]; B = b[1];
289
 
290
      L = l[2];
291
      o1[2] = ((dp1[B])[R])[L];
292
      L = l[3];
293
      o1[3] = ((dp9[B])[R])[L];
294
      L = l2[2];
295
      o2[2] = ((dp13[B])[R])[L];
296
      L = l2[3];
297
      o2[3] = ((dp5[B])[R])[L];
298
 
299
      R = r[2]; B = b[2];
300
 
301
      L = l[4];
302
      o1[4] = ((dp3[B])[R])[L];
303
      L = l[5];
304
      o1[5] = ((dp11[B])[R])[L];
305
      L = l2[4];
306
      o2[4] = ((dp15[B])[R])[L];
307
      L = l2[5];
308
      o2[5] = ((dp7[B])[R])[L];
309
 
310
      R = r[3]; B = b[3];
311
 
312
      L = l[6];
313
      o1[6] = ((dp1[B])[R])[L];
314
      L = l[7];
315
      o1[7] = ((dp9[B])[R])[L];
316
      L = l2[6];
317
      o2[6] = ((dp13[B])[R])[L];
318
      L = l2[7];
319
      o2[7] = ((dp5[B])[R])[L];
320
 
321
      l += 8;
322
      l2 += 8;
323
      r += 4;
324
      b += 4;
325
      o1 += 8;
326
      o2 += 8;
327
    }
328
 
329
    l += w;
330
        l2 += w;
331
    o1 += w;
332
        o2 += w;
333
  }
334
}
335
 
336
 
337