Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | pj | 1 | /* |
2 | * Copyright (c) 1995 The Regents of the University of California. |
||
3 | * All rights reserved. |
||
4 | * |
||
5 | * Permission to use, copy, modify, and distribute this software and its |
||
6 | * documentation for any purpose, without fee, and without written agreement is |
||
7 | * hereby granted, provided that the above copyright notice and the following |
||
8 | * two paragraphs appear in all copies of this software. |
||
9 | * |
||
10 | * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR |
||
11 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT |
||
12 | * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF |
||
13 | * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
14 | * |
||
15 | * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, |
||
16 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY |
||
17 | * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
||
18 | * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO |
||
19 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
||
20 | */ |
||
21 | |||
22 | /* |
||
23 | * Copyright (c) 1995 Erik Corry |
||
24 | * All rights reserved. |
||
25 | * |
||
26 | * Permission to use, copy, modify, and distribute this software and its |
||
27 | * documentation for any purpose, without fee, and without written agreement is |
||
28 | * hereby granted, provided that the above copyright notice and the following |
||
29 | * two paragraphs appear in all copies of this software. |
||
30 | * |
||
31 | * IN NO EVENT SHALL ERIK CORRY BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, |
||
32 | * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF |
||
33 | * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ERIK CORRY HAS BEEN ADVISED |
||
34 | * OF THE POSSIBILITY OF SUCH DAMAGE. |
||
35 | * |
||
36 | * ERIK CORRY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT |
||
37 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
||
38 | * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" |
||
39 | * BASIS, AND ERIK CORRY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, |
||
40 | * UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
||
41 | */ |
||
42 | |||
43 | /* |
||
44 | * Portions of this software Copyright (c) 1995 Brown University. |
||
45 | * All rights reserved. |
||
46 | * |
||
47 | * Permission to use, copy, modify, and distribute this software and its |
||
48 | * documentation for any purpose, without fee, and without written agreement |
||
49 | * is hereby granted, provided that the above copyright notice and the |
||
50 | * following two paragraphs appear in all copies of this software. |
||
51 | * |
||
52 | * IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR |
||
53 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT |
||
54 | * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN |
||
55 | * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
56 | * |
||
57 | * BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT |
||
58 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
||
59 | * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" |
||
60 | * BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, |
||
61 | * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
||
62 | */ |
||
63 | |||
64 | #include "video.h" |
||
65 | #include "dither.h" |
||
66 | #include "proto.h" |
||
67 | #include <math.h> |
||
68 | |||
69 | /* |
||
70 | Changes to make the code reentrant: |
||
71 | None |
||
72 | Additional changes: |
||
73 | do not define INTERPOLATE, add #ifdef INTERPOLATE |
||
74 | -lsh@cs.brown.edu (Loring Holden) |
||
75 | */ |
||
76 | /* #define INTERPOLATE */ |
||
77 | |||
78 | /* |
||
79 | * Erik Corry's multi-byte dither routines. |
||
80 | * |
||
81 | * The basic idea is that the Init generates all the necessary tables. |
||
82 | * The tables incorporate the information about the layout of pixels |
||
83 | * in the XImage, so that it should be able to cope with 15-bit, 16-bit |
||
84 | * 24-bit (non-packed) and 32-bit (10-11 bits per color!) screens. |
||
85 | * At present it cannot cope with 24-bit packed mode, since this involves |
||
86 | * getting down to byte level again. It is assumed that the bits for each |
||
87 | * color are contiguous in the longword. |
||
88 | * |
||
89 | * Writing to memory is done in shorts or ints. (Unfortunately, short is not |
||
90 | * very fast on Alpha, so there is room for improvement here). There is no |
||
91 | * dither time check for overflow - instead the tables have slack at |
||
92 | * each end. This is likely to be faster than an 'if' test as many modern |
||
93 | * architectures are really bad at ifs. Potentially, each '&&' causes a |
||
94 | * pipeline flush! |
||
95 | * |
||
96 | * There is no shifting and fixed point arithmetic, as I really doubt you |
||
97 | * can see the difference, and it costs. This may be just my bias, since I |
||
98 | * heard that Intel is really bad at shifting. |
||
99 | */ |
||
100 | |||
101 | /* |
||
102 | * How many 1 bits are there in the longword. |
||
103 | * Low performance, do not call often. |
||
104 | */ |
||
105 | static int |
||
106 | number_of_bits_set(a) |
||
107 | unsigned long a; |
||
108 | { |
||
109 | if(!a) return 0; |
||
110 | if(a & 1) return 1 + number_of_bits_set(a >> 1); |
||
111 | return(number_of_bits_set(a >> 1)); |
||
112 | } |
||
113 | |||
114 | /* |
||
115 | * Shift the 0s in the least significant end out of the longword. |
||
116 | * Low performance, do not call often. |
||
117 | */ |
||
118 | static unsigned long |
||
119 | shifted_down(a) |
||
120 | unsigned long a; |
||
121 | { |
||
122 | if(!a) return 0; |
||
123 | if(a & 1) return a; |
||
124 | return a >> 1; |
||
125 | } |
||
126 | |||
127 | /* |
||
128 | * How many 0 bits are there at most significant end of longword. |
||
129 | * Low performance, do not call often. |
||
130 | */ |
||
131 | static int |
||
132 | free_bits_at_top(a) |
||
133 | unsigned long a; |
||
134 | { |
||
135 | /* assume char is 8 bits */ |
||
136 | if(!a) return sizeof(unsigned long) * 8; |
||
137 | /* assume twos complement */ |
||
138 | if(((long)a) < 0l) return 0; |
||
139 | return 1 + free_bits_at_top ( a << 1); |
||
140 | } |
||
141 | |||
142 | /* |
||
143 | * How many 0 bits are there at least significant end of longword. |
||
144 | * Low performance, do not call often. |
||
145 | */ |
||
146 | static int |
||
147 | free_bits_at_bottom(a) |
||
148 | unsigned long a; |
||
149 | { |
||
150 | /* assume char is 8 bits */ |
||
151 | if(!a) return sizeof(unsigned long) * 8; |
||
152 | if(((long)a) & 1l) return 0; |
||
153 | return 1 + free_bits_at_bottom ( a >> 1); |
||
154 | } |
||
155 | |||
156 | static int *L_tab=NULL, *Cr_r_tab=NULL, *Cr_g_tab=NULL, *Cb_g_tab=NULL, |
||
157 | *Cb_b_tab=NULL; |
||
158 | |||
159 | /* |
||
160 | * We define tables that convert a color value between -256 and 512 |
||
161 | * into the R, G and B parts of the pixel. The normal range is 0-255. |
||
162 | */ |
||
163 | |||
164 | static long *r_2_pix=NULL; |
||
165 | static long *g_2_pix=NULL; |
||
166 | static long *b_2_pix=NULL; |
||
167 | static long *r_2_pix_alloc=NULL; |
||
168 | static long *g_2_pix_alloc=NULL; |
||
169 | static long *b_2_pix_alloc=NULL; |
||
170 | |||
171 | |||
172 | /* |
||
173 | *-------------------------------------------------------------- |
||
174 | * |
||
175 | * InitColor16Dither -- |
||
176 | * |
||
177 | * To get rid of the multiply and other conversions in color |
||
178 | * dither, we use a lookup table. |
||
179 | * |
||
180 | * Results: |
||
181 | * None. |
||
182 | * |
||
183 | * Side effects: |
||
184 | * The lookup tables are initialized. |
||
185 | * |
||
186 | *-------------------------------------------------------------- |
||
187 | */ |
||
188 | |||
189 | void |
||
190 | InitColorDither(thirty2) |
||
191 | int thirty2; |
||
192 | { |
||
193 | /* |
||
194 | * misuse of the wpixel array for the pixel masks. Note that this |
||
195 | * implies that the window is created before this routine is called |
||
196 | */ |
||
197 | unsigned long red_mask = wpixel[0]; |
||
198 | unsigned long green_mask = wpixel[1]; |
||
199 | unsigned long blue_mask = wpixel[2]; |
||
200 | |||
201 | int L, CR, CB, i; |
||
202 | |||
203 | if (L_tab==NULL) |
||
204 | L_tab = (int *)malloc(256*sizeof(int)); |
||
205 | if (Cr_r_tab==NULL) |
||
206 | Cr_r_tab = (int *)malloc(256*sizeof(int)); |
||
207 | if (Cr_g_tab==NULL) |
||
208 | Cr_g_tab = (int *)malloc(256*sizeof(int)); |
||
209 | if (Cb_g_tab==NULL) |
||
210 | Cb_g_tab = (int *)malloc(256*sizeof(int)); |
||
211 | if (Cb_b_tab==NULL) |
||
212 | Cb_b_tab = (int *)malloc(256*sizeof(int)); |
||
213 | |||
214 | if (r_2_pix_alloc==NULL) |
||
215 | r_2_pix_alloc = (long *)malloc(768*sizeof(long)); |
||
216 | if (g_2_pix_alloc==NULL) |
||
217 | g_2_pix_alloc = (long *)malloc(768*sizeof(long)); |
||
218 | if (b_2_pix_alloc==NULL) |
||
219 | b_2_pix_alloc = (long *)malloc(768*sizeof(long)); |
||
220 | |||
221 | if (L_tab == NULL || |
||
222 | Cr_r_tab == NULL || |
||
223 | Cr_g_tab == NULL || |
||
224 | Cb_g_tab == NULL || |
||
225 | Cb_b_tab == NULL || |
||
226 | r_2_pix_alloc == NULL || |
||
227 | g_2_pix_alloc == NULL || |
||
228 | b_2_pix_alloc == NULL) { |
||
229 | fprintf(stderr, "Could not get enough memory in InitColorDither\n"); |
||
230 | exit(1); |
||
231 | } |
||
232 | |||
233 | for (i=0; i<256; i++) { |
||
234 | L_tab[i] = i; |
||
235 | if (gammaCorrectFlag) { |
||
236 | L_tab[i] = GAMMA_CORRECTION(i); |
||
237 | } |
||
238 | |||
239 | CB = CR = i; |
||
240 | |||
241 | if (chromaCorrectFlag) { |
||
242 | CB -= 128; |
||
243 | CB = CHROMA_CORRECTION128(CB); |
||
244 | CR -= 128; |
||
245 | CR = CHROMA_CORRECTION128(CR); |
||
246 | } else { |
||
247 | CB -= 128; CR -= 128; |
||
248 | } |
||
249 | /* was |
||
250 | Cr_r_tab[i] = 1.596 * CR; |
||
251 | Cr_g_tab[i] = -0.813 * CR; |
||
252 | Cb_g_tab[i] = -0.391 * CB; |
||
253 | Cb_b_tab[i] = 2.018 * CB; |
||
254 | but they were just messed up. |
||
255 | Then was (_Video Deymstified_): |
||
256 | Cr_r_tab[i] = 1.366 * CR; |
||
257 | Cr_g_tab[i] = -0.700 * CR; |
||
258 | Cb_g_tab[i] = -0.334 * CB; |
||
259 | Cb_b_tab[i] = 1.732 * CB; |
||
260 | but really should be: |
||
261 | (from ITU-R BT.470-2 System B, G and SMPTE 170M ) |
||
262 | */ |
||
263 | Cr_r_tab[i] = (0.419/0.299) * CR; |
||
264 | Cr_g_tab[i] = -(0.299/0.419) * CR; |
||
265 | Cb_g_tab[i] = -(0.114/0.331) * CB; |
||
266 | Cb_b_tab[i] = (0.587/0.331) * CB; |
||
267 | |||
268 | /* |
||
269 | though you could argue for: |
||
270 | SMPTE 240M |
||
271 | Cr_r_tab[i] = (0.445/0.212) * CR; |
||
272 | Cr_g_tab[i] = -(0.212/0.445) * CR; |
||
273 | Cb_g_tab[i] = -(0.087/0.384) * CB; |
||
274 | Cb_b_tab[i] = (0.701/0.384) * CB; |
||
275 | FCC |
||
276 | Cr_r_tab[i] = (0.421/0.30) * CR; |
||
277 | Cr_g_tab[i] = -(0.30/0.421) * CR; |
||
278 | Cb_g_tab[i] = -(0.11/0.331) * CB; |
||
279 | Cb_b_tab[i] = (0.59/0.331) * CB; |
||
280 | ITU-R BT.709 |
||
281 | Cr_r_tab[i] = (0.454/0.2125) * CR; |
||
282 | Cr_g_tab[i] = -(0.2125/0.454) * CR; |
||
283 | Cb_g_tab[i] = -(0.0721/0.386) * CB; |
||
284 | Cb_b_tab[i] = (0.7154/0.386) * CB; |
||
285 | */ |
||
286 | } |
||
287 | |||
288 | /* |
||
289 | * Set up entries 0-255 in rgb-to-pixel value tables. |
||
290 | */ |
||
291 | for (i = 0; i < 256; i++) { |
||
292 | r_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(red_mask)); |
||
293 | r_2_pix_alloc[i + 256] <<= free_bits_at_bottom(red_mask); |
||
294 | g_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(green_mask)); |
||
295 | g_2_pix_alloc[i + 256] <<= free_bits_at_bottom(green_mask); |
||
296 | b_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(blue_mask)); |
||
297 | b_2_pix_alloc[i + 256] <<= free_bits_at_bottom(blue_mask); |
||
298 | /* |
||
299 | * If we have 16-bit output depth, then we double the value |
||
300 | * in the top word. This means that we can write out both |
||
301 | * pixels in the pixel doubling mode with one op. It is |
||
302 | * harmless in the normal case as storing a 32-bit value |
||
303 | * through a short pointer will lose the top bits anyway. |
||
304 | * A similar optimisation for Alpha for 64 bit has been |
||
305 | * prepared for, but is not yet implemented. |
||
306 | */ |
||
307 | if(!thirty2) { |
||
308 | |||
309 | r_2_pix_alloc[i + 256] |= (r_2_pix_alloc[i + 256]) << 16; |
||
310 | g_2_pix_alloc[i + 256] |= (g_2_pix_alloc[i + 256]) << 16; |
||
311 | b_2_pix_alloc[i + 256] |= (b_2_pix_alloc[i + 256]) << 16; |
||
312 | |||
313 | } |
||
314 | #ifdef SIXTYFOUR_BIT |
||
315 | if(thirty2) { |
||
316 | |||
317 | r_2_pix_alloc[i + 256] |= (r_2_pix_alloc[i + 256]) << 32; |
||
318 | g_2_pix_alloc[i + 256] |= (g_2_pix_alloc[i + 256]) << 32; |
||
319 | b_2_pix_alloc[i + 256] |= (b_2_pix_alloc[i + 256]) << 32; |
||
320 | |||
321 | } |
||
322 | #endif |
||
323 | } |
||
324 | |||
325 | /* |
||
326 | * Spread out the values we have to the rest of the array so that |
||
327 | * we do not need to check for overflow. |
||
328 | */ |
||
329 | for (i = 0; i < 256; i++) { |
||
330 | r_2_pix_alloc[i] = r_2_pix_alloc[256]; |
||
331 | r_2_pix_alloc[i+ 512] = r_2_pix_alloc[511]; |
||
332 | g_2_pix_alloc[i] = g_2_pix_alloc[256]; |
||
333 | g_2_pix_alloc[i+ 512] = g_2_pix_alloc[511]; |
||
334 | b_2_pix_alloc[i] = b_2_pix_alloc[256]; |
||
335 | b_2_pix_alloc[i+ 512] = b_2_pix_alloc[511]; |
||
336 | } |
||
337 | |||
338 | r_2_pix = r_2_pix_alloc + 256; |
||
339 | g_2_pix = g_2_pix_alloc + 256; |
||
340 | b_2_pix = b_2_pix_alloc + 256; |
||
341 | |||
342 | } |
||
343 | |||
344 | |||
345 | /* |
||
346 | *-------------------------------------------------------------- |
||
347 | * |
||
348 | * Color16DitherImage -- |
||
349 | * |
||
350 | * Converts image into 16 bit color. |
||
351 | * |
||
352 | * Results: |
||
353 | * None. |
||
354 | * |
||
355 | * Side effects: |
||
356 | * None. |
||
357 | * |
||
358 | *-------------------------------------------------------------- |
||
359 | */ |
||
360 | |||
361 | void |
||
362 | Color16DitherImage(lum, cr, cb, out, rows, cols) |
||
363 | unsigned char *lum; |
||
364 | unsigned char *cr; |
||
365 | unsigned char *cb; |
||
366 | unsigned char *out; |
||
367 | int cols, rows; |
||
368 | |||
369 | { |
||
370 | int L, CR, CB; |
||
371 | unsigned short *row1, *row2; |
||
372 | unsigned char *lum2; |
||
373 | int x, y; |
||
374 | unsigned int r, b, g; |
||
375 | int cr_r; |
||
376 | int cr_g; |
||
377 | int cb_g; |
||
378 | int cb_b; |
||
379 | int cols_2 = cols/2; |
||
380 | |||
381 | row1 = (unsigned short *)out; |
||
382 | row2 = row1 + cols_2 + cols_2; |
||
383 | lum2 = lum + cols_2 + cols_2; |
||
384 | |||
385 | for (y=0; y<rows; y+=2) { |
||
386 | for (x=0; x<cols_2; x++) { |
||
387 | int R, G, B; |
||
388 | |||
389 | CR = *cr++; |
||
390 | CB = *cb++; |
||
391 | cr_r = Cr_r_tab[CR]; |
||
392 | cr_g = Cr_g_tab[CR]; |
||
393 | cb_g = Cb_g_tab[CB]; |
||
394 | cb_b = Cb_b_tab[CB]; |
||
395 | |||
396 | L = L_tab[(int) *lum++]; |
||
397 | |||
398 | R = L + cr_r; |
||
399 | G = L + cr_g + cb_g; |
||
400 | B = L + cb_b; |
||
401 | |||
402 | *row1++ = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); |
||
403 | |||
404 | #ifdef INTERPOLATE |
||
405 | if(x != cols_2 - 1) { |
||
406 | CR = (CR + *cr) >> 1; |
||
407 | CB = (CB + *cb) >> 1; |
||
408 | cr_r = Cr_r_tab[CR]; |
||
409 | cr_g = Cr_g_tab[CR]; |
||
410 | cb_g = Cb_g_tab[CB]; |
||
411 | cb_b = Cb_b_tab[CB]; |
||
412 | } |
||
413 | #endif |
||
414 | |||
415 | L = L_tab[(int) *lum++]; |
||
416 | |||
417 | R = L + cr_r; |
||
418 | G = L + cr_g + cb_g; |
||
419 | B = L + cb_b; |
||
420 | |||
421 | *row1++ = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); |
||
422 | |||
423 | /* |
||
424 | * Now, do second row. |
||
425 | */ |
||
426 | #ifdef INTERPOLATE |
||
427 | if(y != rows - 2) { |
||
428 | CR = (CR + *(cr + cols_2 - 1)) >> 1; |
||
429 | CB = (CB + *(cb + cols_2 - 1)) >> 1; |
||
430 | cr_r = Cr_r_tab[CR]; |
||
431 | cr_g = Cr_g_tab[CR]; |
||
432 | cb_g = Cb_g_tab[CB]; |
||
433 | cb_b = Cb_b_tab[CB]; |
||
434 | } |
||
435 | #endif |
||
436 | |||
437 | L = L_tab[(int) *lum2++]; |
||
438 | R = L + cr_r; |
||
439 | G = L + cr_g + cb_g; |
||
440 | B = L + cb_b; |
||
441 | |||
442 | *row2++ = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); |
||
443 | |||
444 | L = L_tab[(int) *lum2++]; |
||
445 | R = L + cr_r; |
||
446 | G = L + cr_g + cb_g; |
||
447 | B = L + cb_b; |
||
448 | |||
449 | *row2++ = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); |
||
450 | } |
||
451 | /* |
||
452 | * These values are at the start of the next line, (due |
||
453 | * to the ++'s above),but they need to be at the start |
||
454 | * of the line after that. |
||
455 | */ |
||
456 | lum += cols_2 + cols_2; |
||
457 | lum2 += cols_2 + cols_2; |
||
458 | row1 += cols_2 + cols_2; |
||
459 | row2 += cols_2 + cols_2; |
||
460 | } |
||
461 | } |
||
462 | |||
463 | |||
464 | |||
465 | |||
466 | /* |
||
467 | *-------------------------------------------------------------- |
||
468 | * |
||
469 | * Color32DitherImage -- |
||
470 | * |
||
471 | * Converts image into 32 bit color (or 24-bit non-packed). |
||
472 | * |
||
473 | * Results: |
||
474 | * None. |
||
475 | * |
||
476 | * Side effects: |
||
477 | * None. |
||
478 | * |
||
479 | *-------------------------------------------------------------- |
||
480 | */ |
||
481 | |||
482 | /* |
||
483 | * This is a copysoft version of the function above with ints instead |
||
484 | * of shorts to cause a 4-byte pixel size |
||
485 | */ |
||
486 | |||
487 | void |
||
488 | Color32DitherImage(lum, cr, cb, out, rows, cols) |
||
489 | unsigned char *lum; |
||
490 | unsigned char *cr; |
||
491 | unsigned char *cb; |
||
492 | unsigned char *out; |
||
493 | int cols, rows; |
||
494 | |||
495 | { |
||
496 | int L, CR, CB; |
||
497 | unsigned int *row1, *row2; |
||
498 | unsigned char *lum2; |
||
499 | int x, y; |
||
500 | unsigned int r, b, g; |
||
501 | int cr_r; |
||
502 | int cr_g; |
||
503 | int cb_g; |
||
504 | int cb_b; |
||
505 | int cols_2 = cols / 2; |
||
506 | |||
507 | row1 = (unsigned int *)out; |
||
508 | row2 = row1 + cols_2 + cols_2; |
||
509 | lum2 = lum + cols_2 + cols_2; |
||
510 | for (y=0; y<rows; y+=2) { |
||
511 | for (x=0; x<cols_2; x++) { |
||
512 | int R, G, B; |
||
513 | |||
514 | CR = *cr++; |
||
515 | CB = *cb++; |
||
516 | cr_r = Cr_r_tab[CR]; |
||
517 | cr_g = Cr_g_tab[CR]; |
||
518 | cb_g = Cb_g_tab[CB]; |
||
519 | cb_b = Cb_b_tab[CB]; |
||
520 | |||
521 | L = L_tab[(int) *lum++]; |
||
522 | |||
523 | R = L + cr_r; |
||
524 | G = L + cr_g + cb_g; |
||
525 | B = L + cb_b; |
||
526 | |||
527 | *row1++ = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); |
||
528 | |||
529 | #ifdef INTERPOLATE |
||
530 | if(x != cols_2 - 1) { |
||
531 | CR = (CR + *cr) >> 1; |
||
532 | CB = (CB + *cb) >> 1; |
||
533 | cr_r = Cr_r_tab[CR]; |
||
534 | cr_g = Cr_g_tab[CR]; |
||
535 | cb_g = Cb_g_tab[CB]; |
||
536 | cb_b = Cb_b_tab[CB]; |
||
537 | } |
||
538 | #endif |
||
539 | |||
540 | L = L_tab[(int) *lum++]; |
||
541 | |||
542 | R = L + cr_r; |
||
543 | G = L + cr_g + cb_g; |
||
544 | B = L + cb_b; |
||
545 | |||
546 | *row1++ = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); |
||
547 | |||
548 | /* |
||
549 | * Now, do second row. |
||
550 | */ |
||
551 | |||
552 | #ifdef INTERPOLATE |
||
553 | if(y != rows - 2) { |
||
554 | CR = (CR + *(cr + cols_2 - 1)) >> 1; |
||
555 | CB = (CB + *(cb + cols_2 - 1)) >> 1; |
||
556 | cr_r = Cr_r_tab[CR]; |
||
557 | cr_g = Cr_g_tab[CR]; |
||
558 | cb_g = Cb_g_tab[CB]; |
||
559 | cb_b = Cb_b_tab[CB]; |
||
560 | } |
||
561 | #endif |
||
562 | |||
563 | L = L_tab [(int) *lum2++]; |
||
564 | R = L + cr_r; |
||
565 | G = L + cr_g + cb_g; |
||
566 | B = L + cb_b; |
||
567 | |||
568 | *row2++ = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); |
||
569 | |||
570 | L = L_tab [(int) *lum2++]; |
||
571 | R = L + cr_r; |
||
572 | G = L + cr_g + cb_g; |
||
573 | B = L + cb_b; |
||
574 | |||
575 | *row2++ = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); |
||
576 | } |
||
577 | lum += cols_2 + cols_2; |
||
578 | lum2 += cols_2 + cols_2; |
||
579 | row1 += cols_2 + cols_2; |
||
580 | row2 += cols_2 + cols_2; |
||
581 | } |
||
582 | } |
||
583 | |||
584 | /* |
||
585 | * Erik Corry's pixel doubling routines for 15/16/24/32 bit screens. |
||
586 | */ |
||
587 | |||
588 | |||
589 | |||
590 | /* |
||
591 | *-------------------------------------------------------------- |
||
592 | * |
||
593 | * Twox2Color16DitherImage -- |
||
594 | * |
||
595 | * Converts image into 16 bit color at double size. |
||
596 | * |
||
597 | * Results: |
||
598 | * None. |
||
599 | * |
||
600 | * Side effects: |
||
601 | * None. |
||
602 | * |
||
603 | *-------------------------------------------------------------- |
||
604 | */ |
||
605 | |||
606 | /* |
||
607 | * In this function I make use of a nasty trick. The tables have the lower |
||
608 | * 16 bits replicated in the upper 16. This means I can write ints and get |
||
609 | * the horisontal doubling for free (almost). |
||
610 | */ |
||
611 | |||
612 | void |
||
613 | Twox2Color16DitherImage(lum, cr, cb, out, rows, cols) |
||
614 | unsigned char *lum; |
||
615 | unsigned char *cr; |
||
616 | unsigned char *cb; |
||
617 | unsigned char *out; |
||
618 | int cols, rows; |
||
619 | |||
620 | { |
||
621 | int L, CR, CB; |
||
622 | unsigned int *row1 = (unsigned int *)out; |
||
623 | unsigned int *row2 = row1 + cols; |
||
624 | unsigned int *row3 = row2 + cols; |
||
625 | unsigned int *row4 = row3 + cols; |
||
626 | unsigned char *lum2; |
||
627 | int x, y; |
||
628 | unsigned int r, b, g; |
||
629 | int cr_r; |
||
630 | int cr_g; |
||
631 | int cb_g; |
||
632 | int cb_b; |
||
633 | int cols_2 = cols/2; |
||
634 | |||
635 | lum2 = lum + cols_2 + cols_2; |
||
636 | for (y=0; y<rows; y+=2) { |
||
637 | for (x=0; x<cols_2; x++) { |
||
638 | int R, G, B; |
||
639 | int t; |
||
640 | |||
641 | CR = *cr++; |
||
642 | CB = *cb++; |
||
643 | cr_r = Cr_r_tab[CR]; |
||
644 | cr_g = Cr_g_tab[CR]; |
||
645 | cb_g = Cb_g_tab[CB]; |
||
646 | cb_b = Cb_b_tab[CB]; |
||
647 | |||
648 | L = L_tab[(int) *lum++]; |
||
649 | |||
650 | R = L + cr_r; |
||
651 | G = L + cr_g + cb_g; |
||
652 | B = L + cb_b; |
||
653 | |||
654 | t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); |
||
655 | row1[0] = t; |
||
656 | row1++; |
||
657 | row2[0] = t; |
||
658 | row2++; |
||
659 | |||
660 | #ifdef INTERPOLATE |
||
661 | if(x != cols_2 - 1) { |
||
662 | CR = (CR + *cr) >> 1; |
||
663 | CB = (CB + *cb) >> 1; |
||
664 | cr_r = Cr_r_tab[CR]; |
||
665 | cr_g = Cr_g_tab[CR]; |
||
666 | cb_g = Cb_g_tab[CB]; |
||
667 | cb_b = Cb_b_tab[CB]; |
||
668 | } |
||
669 | #endif |
||
670 | L = L_tab[(int) *lum++]; |
||
671 | |||
672 | R = L + cr_r; |
||
673 | G = L + cr_g + cb_g; |
||
674 | B = L + cb_b; |
||
675 | |||
676 | t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); |
||
677 | row1[0] = t; |
||
678 | row1++; |
||
679 | row2[0] = t; |
||
680 | row2++; |
||
681 | |||
682 | /* |
||
683 | * Now, do second row. |
||
684 | */ |
||
685 | #ifdef INTERPOLATE |
||
686 | if(y != rows - 2) { |
||
687 | CR = (CR + *(cr + cols_2 - 1)) >> 1; |
||
688 | CB = (CB + *(cb + cols_2 - 1)) >> 1; |
||
689 | cr_r = Cr_r_tab[CR]; |
||
690 | cr_g = Cr_g_tab[CR]; |
||
691 | cb_g = Cb_g_tab[CB]; |
||
692 | cb_b = Cb_b_tab[CB]; |
||
693 | } |
||
694 | #endif |
||
695 | L = L_tab[(int) *lum2++]; |
||
696 | R = L + cr_r; |
||
697 | G = L + cr_g + cb_g; |
||
698 | B = L + cb_b; |
||
699 | |||
700 | t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); |
||
701 | row3[0] = t; |
||
702 | row3++; |
||
703 | row4[0] = t; |
||
704 | row4++; |
||
705 | |||
706 | L = L_tab[(int) *lum2++]; |
||
707 | R = L + cr_r; |
||
708 | G = L + cr_g + cb_g; |
||
709 | B = L + cb_b; |
||
710 | |||
711 | t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); |
||
712 | row3[0] = t; |
||
713 | row3++; |
||
714 | row4[0] = t; |
||
715 | row4++; |
||
716 | } |
||
717 | lum += cols_2 + cols_2; |
||
718 | lum2 += cols_2 + cols_2; |
||
719 | row1 += 6 * cols_2; |
||
720 | row3 += 6 * cols_2; |
||
721 | row2 += 6 * cols_2; |
||
722 | row4 += 6 * cols_2; |
||
723 | } |
||
724 | } |
||
725 | |||
726 | |||
727 | |||
728 | |||
729 | /* |
||
730 | *-------------------------------------------------------------- |
||
731 | * |
||
732 | * Twox2Color32 -- |
||
733 | * |
||
734 | * Converts image into 24/32 bit color. |
||
735 | * |
||
736 | * Results: |
||
737 | * None. |
||
738 | * |
||
739 | * Side effects: |
||
740 | * None. |
||
741 | * |
||
742 | *-------------------------------------------------------------- |
||
743 | */ |
||
744 | |||
745 | #ifdef SIXTYFOUR_BIT |
||
746 | #define ONE_TWO 1 |
||
747 | #else |
||
748 | #define ONE_TWO 2 |
||
749 | #endif |
||
750 | |||
751 | void |
||
752 | Twox2Color32DitherImage(lum, cr, cb, out, rows, cols) |
||
753 | unsigned char *lum; |
||
754 | unsigned char *cr; |
||
755 | unsigned char *cb; |
||
756 | unsigned char *out; |
||
757 | int cols, rows; |
||
758 | |||
759 | { |
||
760 | int L, CR, CB; |
||
761 | unsigned long *row1 = (unsigned long *)out; |
||
762 | unsigned long *row2 = row1 + cols * ONE_TWO; |
||
763 | unsigned long *row3 = row2 + cols * ONE_TWO; |
||
764 | unsigned long *row4 = row3 + cols * ONE_TWO; |
||
765 | unsigned char *lum2; |
||
766 | int x, y; |
||
767 | unsigned int r, b, g; |
||
768 | int cr_r; |
||
769 | int cr_g; |
||
770 | int cb_g; |
||
771 | int cb_b; |
||
772 | int cols_2 = cols/2; |
||
773 | |||
774 | lum2 = lum + cols_2 + cols_2; |
||
775 | for (y=0; y<rows; y+=2) { |
||
776 | for (x=0; x<cols_2; x++) { |
||
777 | int R, G, B; |
||
778 | long t; |
||
779 | |||
780 | CR = *cr++; |
||
781 | CB = *cb++; |
||
782 | cr_r = Cr_r_tab[CR]; |
||
783 | cr_g = Cr_g_tab[CR]; |
||
784 | cb_g = Cb_g_tab[CB]; |
||
785 | cb_b = Cb_b_tab[CB]; |
||
786 | |||
787 | L = L_tab[ (int) *lum++]; |
||
788 | |||
789 | R = L + cr_r; |
||
790 | G = L + cr_g + cb_g; |
||
791 | B = L + cb_b; |
||
792 | |||
793 | t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); |
||
794 | row1[0] = t; |
||
795 | row2[0] = t; |
||
796 | #ifndef SIXTYFOUR_BIT |
||
797 | row1[1] = t; |
||
798 | row2[1] = t; |
||
799 | #endif |
||
800 | row1 += ONE_TWO; |
||
801 | row2 += ONE_TWO; |
||
802 | |||
803 | /* INTERPOLATE is now standard */ |
||
804 | #ifdef INTERPOLATE |
||
805 | if(x != cols_2 - 1) { |
||
806 | CR = (CR + *cr) >> 1; |
||
807 | CB = (CB + *cb) >> 1; |
||
808 | cr_r = Cr_r_tab[CR]; |
||
809 | cr_g = Cr_g_tab[CR]; |
||
810 | cb_g = Cb_g_tab[CB]; |
||
811 | cb_b = Cb_b_tab[CB]; |
||
812 | } |
||
813 | #endif |
||
814 | /* end INTERPOLATE */ |
||
815 | L = L_tab[ (int) *lum++]; |
||
816 | |||
817 | R = L + cr_r; |
||
818 | G = L + cr_g + cb_g; |
||
819 | B = L + cb_b; |
||
820 | |||
821 | t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); |
||
822 | row1[0] = t; |
||
823 | row2[0] = t; |
||
824 | #ifndef SIXTYFOUR_BIT |
||
825 | row1[1] = t; |
||
826 | row2[1] = t; |
||
827 | #endif |
||
828 | row1 += ONE_TWO; |
||
829 | row2 += ONE_TWO; |
||
830 | |||
831 | /* |
||
832 | * Now, do second row. |
||
833 | */ |
||
834 | /* INTERPOLATE is now standard */ |
||
835 | #ifdef INTERPOLATE |
||
836 | if(y != rows - 2) { |
||
837 | CR = (unsigned int) (CR + *(cr + cols_2 - 1)) >> 1; |
||
838 | CB = (unsigned int) (CB + *(cb + cols_2 - 1)) >> 1; |
||
839 | cr_r = Cr_r_tab[CR]; |
||
840 | cr_g = Cr_g_tab[CR]; |
||
841 | cb_g = Cb_g_tab[CB]; |
||
842 | cb_b = Cb_b_tab[CB]; |
||
843 | } |
||
844 | #endif |
||
845 | /* endif */ |
||
846 | L = L_tab[ (int) *lum2++]; |
||
847 | R = L + cr_r; |
||
848 | G = L + cr_g + cb_g; |
||
849 | B = L + cb_b; |
||
850 | |||
851 | t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); |
||
852 | row3[0] = t; |
||
853 | row4[0] = t; |
||
854 | #ifndef SIXTYFOUR_BIT |
||
855 | row3[1] = t; |
||
856 | row4[1] = t; |
||
857 | #endif |
||
858 | row3 += ONE_TWO; |
||
859 | row4 += ONE_TWO; |
||
860 | |||
861 | L = L_tab[(int) *lum2++]; |
||
862 | R = L + cr_r; |
||
863 | G = L + cr_g + cb_g; |
||
864 | B = L + cb_b; |
||
865 | |||
866 | t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); |
||
867 | row3[0] = t; |
||
868 | row4[0] = t; |
||
869 | #ifndef SIXTYFOUR_BIT |
||
870 | row3[1] = t; |
||
871 | row4[1] = t; |
||
872 | #endif |
||
873 | row3 += ONE_TWO; |
||
874 | row4 += ONE_TWO; |
||
875 | } |
||
876 | lum += cols_2 + cols_2; |
||
877 | lum2 += cols_2 + cols_2; |
||
878 | |||
879 | row1 += ONE_TWO * 6 *cols_2; |
||
880 | row3 += ONE_TWO * 6 *cols_2; |
||
881 | row2 += ONE_TWO * 6 *cols_2; |
||
882 | row4 += ONE_TWO * 6 *cols_2; |
||
883 | } |
||
884 | } |
||
885 |