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
 * ordered.c --
3
 *
4
 *     This file contains C code to implement an ordered dither.
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 "proto.h"
31
#include "dither.h"
32
 
33
#define DITH_SIZE 16
34
 
35
 
36
/* Structures used to implement hybrid ordered dither/floyd-steinberg
37
   dither algorithm.
38
*/
39
 
40
static unsigned char *l_darrays[DITH_SIZE];
41
static unsigned char *cr_darrays[DITH_SIZE];
42
static unsigned char *cb_darrays[DITH_SIZE];
43
 
44
/*
45
 *--------------------------------------------------------------
46
 *
47
 *  InitOrderedDither--
48
 *
49
 *      Structures intialized for ordered dithering.
50
 *
51
 * Results:
52
 *      None.
53
 *
54
 * Side effects:
55
 *      None.
56
 *
57
 *--------------------------------------------------------------
58
 */
59
 
60
void
61
InitOrderedDither()
62
{
63
  int i, j, k, err_range, threshval;
64
  unsigned char *lmark, *cmark;
65
 
66
  for (i=0; i<DITH_SIZE; i++) {
67
    lmark = l_darrays[i] = (unsigned char *) malloc(256);
68
 
69
    for (j=0; j<lum_values[0]; j++) {
70
      *lmark++ = 0;
71
    }
72
 
73
    for (j=0; j<(LUM_RANGE-1); j++) {
74
      err_range = lum_values[j+1] - lum_values[j];
75
      threshval = ((i * err_range) / DITH_SIZE)+lum_values[j];
76
 
77
      for (k=lum_values[j]; k<lum_values[j+1]; k++) {
78
        if (k > threshval) {
79
          *lmark++ = ((j+1) * (CR_RANGE * CB_RANGE));
80
        }
81
        else {
82
          *lmark++ = (j * (CR_RANGE * CB_RANGE));
83
        }
84
      }
85
    }
86
 
87
    for (j=lum_values[LUM_RANGE-1]; j<256; j++) {
88
      *lmark++ = (LUM_RANGE-1)*(CR_RANGE * CB_RANGE);
89
    }
90
  }
91
 
92
  for (i=0; i<DITH_SIZE; i++) {
93
    cmark = cr_darrays[i] = (unsigned char *) malloc(256);
94
 
95
    for (j=0; j<cr_values[0]; j++) {
96
      *cmark++ = 0;
97
    }
98
 
99
    for (j=0; j<(CR_RANGE-1); j++) {
100
      err_range = cr_values[j+1] - cr_values[j];
101
      threshval = ((i * err_range) / DITH_SIZE)+cr_values[j];
102
 
103
      for (k=cr_values[j]; k<cr_values[j+1]; k++) {
104
        if (k > threshval) {
105
          *cmark++ = ((j+1) * CB_RANGE);
106
        }
107
        else {
108
          *cmark++ = (j * CB_RANGE);
109
        }
110
      }
111
    }
112
 
113
    for (j=cr_values[CR_RANGE-1]; j<256; j++) {
114
      *cmark++ = (CR_RANGE-1)*(CB_RANGE);
115
    }
116
  }
117
 
118
  for (i=0; i<DITH_SIZE; i++) {
119
    cmark = cb_darrays[i] = (unsigned char *) malloc(256);
120
 
121
    for (j=0; j<cb_values[0]; j++) {
122
      *cmark++ = 0;
123
    }
124
 
125
    for (j=0; j<(CB_RANGE-1); j++) {
126
      err_range = cb_values[j+1] - cb_values[j];
127
      threshval = ((i * err_range) / DITH_SIZE)+cb_values[j];
128
 
129
      for (k=cb_values[j]; k<cb_values[j+1]; k++) {
130
        if (k > threshval) {
131
          *cmark++ = j+1;
132
        }
133
        else {
134
          *cmark++ = j;
135
        }
136
      }
137
    }
138
 
139
    for (j=cb_values[CB_RANGE-1]; j<256; j++) {
140
      *cmark++ = CB_RANGE-1;
141
    }
142
  }
143
}
144
 
145
 
146
/*
147
 *--------------------------------------------------------------
148
 *
149
 * OrderedDitherImage --
150
 *
151
 *      Dithers an image using an ordered dither.
152
 *      Assumptions made:
153
 *        1) The color space is allocated y:cr:cb = 8:4:4
154
 *        2) The spatial resolution of y:cr:cb is 4:1:1
155
 *      The channels are dithered based on the standard
156
 *      ordered dither pattern for a 4x4 area.
157
 *
158
 * Results:
159
 *      None.
160
 *
161
 * Side effects:
162
 *      None.
163
 *
164
 *--------------------------------------------------------------
165
 */
166
void
167
OrderedDitherImage (lum, cr, cb, out, h, w)
168
    unsigned char *lum;
169
    unsigned char *cr;
170
    unsigned char *cb;
171
    unsigned char *out;
172
    int w, h;
173
{
174
  unsigned char *l, *r, *b, *o1, *o2;
175
  unsigned char *l2;
176
  unsigned char L, R, B;
177
  int i, j;
178
 
179
  l = lum;
180
  l2 = lum+w;
181
  r = cr;
182
  b = cb;
183
  o1 = out;
184
  o2 = out+w;
185
 
186
  for (i=0; i<h; i+=4) {
187
 
188
    for (j=0; j<w; j+=8) {
189
 
190
      R = r[0]; B = b[0];
191
 
192
      L = l[0];
193
      o1[0] = pixel[(l_darrays[0][L] + cr_darrays[0][R] + cb_darrays[0][B])];
194
      L = l[1];
195
      o1[1] = pixel[(l_darrays[8][L] + cr_darrays[8][R] + cb_darrays[8][B])];
196
      L = l2[0];
197
      o2[0] = pixel[(l_darrays[12][L] + cr_darrays[12][R] + cb_darrays[12][B])];
198
      L = l2[1];
199
      o2[1] = pixel[(l_darrays[4][L] + cr_darrays[4][R] + cb_darrays[4][B])];
200
 
201
      R = r[1]; B = b[1];
202
 
203
      L = l[2];
204
      o1[2] = pixel[(l_darrays[2][L] + cr_darrays[2][R] + cb_darrays[2][B])];
205
      L = l[3];
206
      o1[3] = pixel[(l_darrays[10][L] + cr_darrays[10][R] + cb_darrays[10][B])];
207
      L = l2[2];
208
      o2[2] = pixel[(l_darrays[14][L] + cr_darrays[14][R] + cb_darrays[14][B])];
209
      L = l2[3];
210
      o2[3] = pixel[(l_darrays[6][L] + cr_darrays[6][R] + cb_darrays[6][B])];
211
 
212
      R = r[2]; B = b[2];
213
 
214
      L = l[4];
215
      o1[4] = pixel[(l_darrays[0][L] + cr_darrays[0][R] + cb_darrays[0][B])];
216
      L = l[5];
217
      o1[5] = pixel[(l_darrays[8][L] + cr_darrays[8][R] + cb_darrays[8][B])];
218
      L = l2[4];
219
      o2[4] = pixel[(l_darrays[12][L] + cr_darrays[12][R] + cb_darrays[12][B])];
220
      L = l2[5];
221
      o2[5] = pixel[(l_darrays[4][L] + cr_darrays[4][R] + cb_darrays[4][B])];
222
 
223
      R = r[3]; B = b[3];
224
 
225
      L = l[6];
226
      o1[6] = pixel[(l_darrays[2][L] + cr_darrays[2][R] + cb_darrays[2][B])];
227
      L = l[7];
228
      o1[7] = pixel[(l_darrays[10][L] + cr_darrays[10][R] + cb_darrays[10][B])];
229
      L = l2[6];
230
      o2[6] = pixel[(l_darrays[14][L] + cr_darrays[14][R] + cb_darrays[14][B])];
231
      L = l2[7];
232
      o2[7] = pixel[(l_darrays[6][L] + cr_darrays[6][R] + cb_darrays[6][B])];
233
 
234
      l += 8;
235
      l2 += 8;
236
      r += 4;
237
      b += 4;
238
      o1 += 8;
239
      o2 += 8;
240
    }
241
 
242
    l += w;
243
        l2 += w;
244
    o1 += w;
245
        o2 += w;
246
 
247
    for (j=0; j<w; j+=8) {
248
 
249
      R = r[0]; B = b[0];
250
 
251
      L = l[0];
252
      o1[0] = pixel[(l_darrays[3][L] + cr_darrays[3][R] + cb_darrays[3][B])];
253
      L = l[1];
254
      o1[1] = pixel[(l_darrays[11][L] + cr_darrays[11][R] + cb_darrays[11][B])];
255
      L = l2[0];
256
      o2[0] = pixel[(l_darrays[15][L] + cr_darrays[15][R] + cb_darrays[15][B])];
257
      L = l2[1];
258
      o2[1] = pixel[(l_darrays[7][L] + cr_darrays[7][R] + cb_darrays[7][B])];
259
 
260
      R = r[1]; B = b[1];
261
 
262
      L = l[2];
263
      o1[2] = pixel[(l_darrays[1][L] + cr_darrays[1][R] + cb_darrays[1][B])];
264
      L = l[3];
265
      o1[3] = pixel[(l_darrays[9][L] + cr_darrays[9][R] + cb_darrays[9][B])];
266
      L = l2[2];
267
      o2[2] = pixel[(l_darrays[13][L] + cr_darrays[13][R] + cb_darrays[13][B])];
268
      L = l2[3];
269
      o2[3] = pixel[(l_darrays[5][L] + cr_darrays[5][R] + cb_darrays[5][B])];
270
 
271
      R = r[2]; B = b[2];
272
 
273
      L = l[4];
274
      o1[4] = pixel[(l_darrays[3][L] + cr_darrays[3][R] + cb_darrays[3][B])];
275
      L = l[5];
276
      o1[5] = pixel[(l_darrays[11][L] + cr_darrays[11][R] + cb_darrays[11][B])];
277
      L = l2[4];
278
      o2[4] = pixel[(l_darrays[15][L] + cr_darrays[15][R] + cb_darrays[15][B])];
279
      L = l2[5];
280
      o2[5] = pixel[(l_darrays[7][L] + cr_darrays[7][R] + cb_darrays[7][B])];
281
 
282
      R = r[3]; B = b[3];
283
 
284
      L = l[6];
285
      o1[6] = pixel[(l_darrays[1][L] + cr_darrays[1][R] + cb_darrays[1][B])];
286
      L = l[7];
287
      o1[7] = pixel[(l_darrays[9][L] + cr_darrays[9][R] + cb_darrays[9][B])];
288
      L = l2[6];
289
      o2[6] = pixel[(l_darrays[13][L] + cr_darrays[13][R] + cb_darrays[13][B])];
290
      L = l2[7];
291
      o2[7] = pixel[(l_darrays[5][L] + cr_darrays[5][R] + cb_darrays[5][B])];
292
 
293
      l += 8;
294
      l2 += 8;
295
      r += 4;
296
      b += 4;
297
      o1 += 8;
298
      o2 += 8;
299
    }
300
 
301
    l += w;
302
        l2 += w;
303
    o1 += w;
304
        o2 += w;
305
  }
306
}
307
 
308
 
309