source: trunk/src/opengl/glide/cvg/texus/quantize.c

Last change on this file was 6653, checked in by bird, 24 years ago

Added $Id:$ keyword.

File size: 22.6 KB
Line 
1/* $Id: quantize.c,v 1.2 2001-09-05 14:30:46 bird Exp $ */
2
3/*
4** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
5** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
6** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
7** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
8** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
9** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
10** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
11** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
12**
13** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
14** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
15** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
16** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
17** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
18** THE UNITED STATES.
19**
20** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
21**
22** $Revision: 1.2 $
23** $Date: 2001-09-05 14:30:46 $
24*/
25
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <math.h>
30
31#include "texusint.h"
32
33static int
34dithmat[4][4] = { 0, 8, 2, 10,
35 12, 4, 14, 6,
36 3, 11, 1, 9,
37 15, 7, 13, 5 };
38
39// for error diffusion.
40static int errR[MAX_TEXWIDTH], errG[MAX_TEXWIDTH], errB[MAX_TEXWIDTH];
41
42static int
43_txPixQuantize_RGB332( unsigned long argb, int x, int y, int w)
44{
45 return (
46 (((argb>>16) & 0xE0) |
47 ((argb>>11) & 0x1C) |
48 ((argb>> 6) & 0x03) ) );
49}
50
51static int
52_txPixQuantize_RGB332_D4x4( unsigned long argb, int x, int y, int w)
53{
54 int d = dithmat[y&3][x&3];
55 int n, t;
56
57 n = (int) (((argb >> 16) & 0xFF) * 0x70/255.0f + 0.5f) + d;
58 t = (n>>4)<<5;
59 n = (int) (((argb >> 8) & 0xFF) * 0x70/255.0f + 0.5f) + d;
60 t |= (n>>4)<<2;
61 n = (int) (((argb ) & 0xFF) * 0x30/255.0f + 0.5f) + d;
62 t |= (n>>4)<<0;
63 return t & 0xFF;
64}
65
66static int
67_txPixQuantize_RGB332_DErr( unsigned long argb, int x, int y, int w)
68{
69 static unsigned char a3[] = {0x00,0x24,0x49,0x6d,0x92,0xb6,0xdb,0xff};
70 static unsigned char a2[] = {0x00,0x55,0xaa,0xff};
71 static int qr, qg, qb; // quantized incoming values.
72 int ir, ig, ib; // incoming values.
73 int t;
74
75 ir = (argb >> 16) & 0xFF; // incoming pixel values.
76 ig = (argb >> 8) & 0xFF;
77 ib = (argb ) & 0xFF;
78
79 if (x == 0) qr = qg = qb = 0;
80
81 ir += errR[x] + qr;
82 ig += errG[x] + qg;
83 ib += errB[x] + qb;
84
85 qr = ir; // quantized pixel values.
86 qg = ig; // qR is error from pixel to left, errR is
87 qb = ib; // error from pixel to the top & top left.
88
89 if (qr < 0) qr = 0; if (qr > 255) qr = 255; // clamp.
90 if (qg < 0) qg = 0; if (qg > 255) qg = 255;
91 if (qb < 0) qb = 0; if (qb > 255) qb = 255;
92
93 // To RGB332.
94 qr = (int) (qr * 0x7ff/255.0f); qr >>= 8;
95 qg = (int) (qg * 0x7ff/255.0f); qg >>= 8;
96 qb = (int) (qb * 0x3ff/255.0f); qb >>= 8;
97
98 t = (qr << 5) | (qg << 2) | qb; // this is the value to be returned.
99
100 // Now dequantize the input, and compute & distribute the errors.
101 qr = a3[qr]; qr = ir - qr;
102 qg = a3[qg]; qg = ig - qg;
103 qb = a2[qb]; qb = ib - qb;
104
105 // 3/8 (=0.375) to the EAST, 3/8 to the SOUTH, 1/4 (0.25) to the SOUTH-EAST.
106 errR[x] = ((x == 0) ? 0 : errR[x]) + ((int) (qr * 0.375f));
107 errG[x] = ((x == 0) ? 0 : errG[x]) + ((int) (qg * 0.375f));
108 errB[x] = ((x == 0) ? 0 : errB[x]) + ((int) (qb * 0.375f));
109
110 errR[x+1] = (int) (qr * 0.250f);
111 errG[x+1] = (int) (qg * 0.250f);
112 errB[x+1] = (int) (qb * 0.250f);
113
114 qr = (int) (qr * 0.375f); // Carried to the pixel on the right.
115 qg = (int) (qg * 0.375f);
116 qb = (int) (qb * 0.375f);
117
118 return t & 0xFF;
119}
120
121/* YIQ422 done elsewhere */
122
123static int
124_txPixQuantize_A8( unsigned long argb, int x, int y, int w)
125{
126 return (argb >> 24);
127}
128
129static int
130_txPixQuantize_I8( unsigned long argb, int x, int y, int w)
131{
132 return (
133 ((int) (((argb >>16) & 0xFF) * .30F +
134 ((argb >> 8) & 0xFF) * .59F +
135 ((argb ) & 0xFF) * .11F + 0.5f )) & 0xFF);
136}
137
138static int
139_txPixQuantize_AI44( unsigned long argb, int x, int y, int w)
140{
141 return(
142 (int) (( ((argb>>16) & 0xFF) * .30F +
143 ((argb>> 8) & 0xFF) * .59F +
144 ((argb ) & 0xFF) * .11F + 0.5f ) * 0.0625f) |
145 (int) ((argb>>24) & 0xF0));
146}
147
148static int
149_txPixQuantize_AI44_D4x4( unsigned long argb, int x, int y, int w)
150{
151 int d = dithmat[y&3][x&3];
152 int n, t;
153
154 /* Don't dither alpha channel */
155 n = (int) ( ((argb>>16) & 0xFF) * .30F +
156 ((argb>> 8) & 0xFF) * .59F +
157 ((argb ) & 0xFF) * .11F + 0.5f);
158
159
160 n = (int) (n * 0xF0/255.0f + 0.5f) + d;
161 t = (n>>4);
162 t |= (int) ((argb>>24) & 0xF0);
163 return t & 0xFF;
164}
165
166static int
167_txPixQuantize_AI44_DErr( unsigned long argb, int x, int y, int w)
168{
169 int ii, t;
170 static int qi;
171
172 /* Don't dither alpha channel */
173 ii = (int) ( ((argb>>16) & 0xFF) * .30F +
174 ((argb>> 8) & 0xFF) * .59F +
175 ((argb ) & 0xFF) * .11F + 0.5f);
176
177
178 if (x == 0) qi = 0;
179 ii += errR[x] + qi;
180 qi = ii;
181 if (qi < 0) qi = 0; if (qi > 255) qi = 255; // clamp.
182 qi = (int) (qi * 0xfff/255.0f); qi >>= 8;
183
184 t = qi;
185 t |= (int) ((argb>>24) & 0xF0);
186
187
188 // Now dequantize the input, and compute & distribute the errors.
189 qi = (qi << 4) | qi;
190 qi = ii - qi;
191
192 // 3/8 (=0.375) to the EAST, 3/8 to the SOUTH, 1/4 (0.25) to the SOUTH-EAST.
193 errR[x] = ((x == 0) ? 0 : errR[x]) + ((int) (qi * 0.375f));
194 errR[x+1] = (int) (qi * 0.250f);
195 qi = (int) (qi * 0.375f); // Carried to the pixel on the right.
196
197 return t & 0xFF;
198}
199
200
201static int
202_txPixQuantize_ARGB8332 ( unsigned long argb, int x, int y, int w)
203{
204 return (
205 ((argb>>16) & 0xE0) |
206 ((argb>>11) & 0x1C) |
207 ((argb>> 6) & 0x03) |
208 ((argb>>16) & 0xFF00) );
209}
210
211
212static int
213_txPixQuantize_ARGB8332_D4x4( unsigned long argb, int x, int y, int w)
214{
215 int d = dithmat[y&3][x&3];
216 int n, t;
217
218 n = (int) (((argb >> 16) & 0xFF) * 0x70/255.0f + 0.5f) + d;
219 t = (n>>4)<<5;
220 n = (int) (((argb >> 8) & 0xFF) * 0x70/255.0f + 0.5f) + d;
221 t |= (n>>4)<<2;
222 n = (int) (((argb ) & 0xFF) * 0x30/255.0f + 0.5f) + d;
223 t |= (n>>4)<<0;
224 t |= ((argb >> 16) & 0xFF00);
225 return t & 0xFFFF;
226}
227
228static int
229_txPixQuantize_ARGB8332_DErr( unsigned long argb, int x, int y, int w)
230{
231 int t;
232
233 t = _txPixQuantize_RGB332_DErr(argb, x, y, w);
234 t |= ((argb >> 16) & 0xFF00);
235 return t & 0xFFFF;
236}
237
238/* AYIQ8422 done elsewhere */
239
240static int
241_txPixQuantize_RGB565( unsigned long argb, int x, int y, int w)
242{
243 return (
244 ((argb >> 8) & 0xF800) |
245 ((argb >> 5) & 0x07E0) |
246 ((argb >> 3) & 0x001F) );
247}
248
249static int
250_txPixQuantize_RGB565_D4x4 ( unsigned long argb, int x, int y, int w)
251{
252 int d = dithmat[y&3][x&3];
253 int n, t;
254
255 n = (int) (((argb >> 16) & 0xFF) * 0x1F0/255.0f + 0.5f) + d;
256 t = (n>>4)<<11;
257 n = (int) (((argb >> 8) & 0xFF) * 0x3F0/255.0f + 0.5f) + d;
258 t |= (n>>4)<<5;
259 n = (int) (((argb ) & 0xFF) * 0x1F0/255.0f + 0.5f) + d;
260 t |= (n>>4)<<0;
261 return t & 0xFFFF;
262}
263
264
265static int
266_txPixQuantize_RGB565_DErr ( unsigned long argb, int x, int y, int w)
267{
268 static int qr, qg, qb; // quantized incoming values.
269 int ir, ig, ib; // incoming values.
270 int t;
271
272 ir = (argb >> 16) & 0xFF; // incoming pixel values.
273 ig = (argb >> 8) & 0xFF;
274 ib = (argb ) & 0xFF;
275
276 if (x == 0) qr = qg = qb = 0;
277
278 ir += errR[x] + qr;
279 ig += errG[x] + qg;
280 ib += errB[x] + qb;
281
282 qr = ir; // quantized pixel values.
283 qg = ig; // qR is error from pixel to left, errR is
284 qb = ib; // error from pixel to the top & top left.
285
286 if (qr < 0) qr = 0; if (qr > 255) qr = 255; // clamp.
287 if (qg < 0) qg = 0; if (qg > 255) qg = 255;
288 if (qb < 0) qb = 0; if (qb > 255) qb = 255;
289
290 // To RGB565.
291 qr = (int) (qr * 0x1FFF/255.0f); qr >>= 8;
292 qg = (int) (qg * 0x3FFF/255.0f); qg >>= 8;
293 qb = (int) (qb * 0x1FFF/255.0f); qb >>= 8;
294
295 t = (qr << 11) | (qg << 5) | qb; // this is the value to be returned.
296
297 // Now dequantize the input, and compute & distribute the errors.
298 qr = (qr << 3) | (qr >> 2);
299 qg = (qg << 2) | (qg >> 4);
300 qb = (qb << 3) | (qb >> 2);
301 qr = ir - qr;
302 qg = ig - qg;
303 qb = ib - qb;
304
305 // 3/8 (=0.375) to the EAST, 3/8 to the SOUTH, 1/4 (0.25) to the SOUTH-EAST.
306 errR[x] = ((x == 0) ? 0 : errR[x]) + ((int) (qr * 0.375f));
307 errG[x] = ((x == 0) ? 0 : errG[x]) + ((int) (qg * 0.375f));
308 errB[x] = ((x == 0) ? 0 : errB[x]) + ((int) (qb * 0.375f));
309
310 errR[x+1] = (int) (qr * 0.250f);
311 errG[x+1] = (int) (qg * 0.250f);
312 errB[x+1] = (int) (qb * 0.250f);
313
314 qr = (int) (qr * 0.375f); // Carried to the pixel on the right.
315 qg = (int) (qg * 0.375f);
316 qb = (int) (qb * 0.375f);
317
318 return t & 0xFFFF;
319}
320
321static int
322_txPixQuantize_ARGB1555( unsigned long argb, int x, int y, int w)
323{
324 return (
325 ((argb >> 9) & 0x7C00) |
326 ((argb >> 6) & 0x03E0) |
327 ((argb >> 3) & 0x001F) |
328 ((argb >> 24) ? 0x8000 : 0) );
329}
330
331static int
332_txPixQuantize_ARGB1555_D4x4 ( unsigned long argb, int x, int y, int w)
333{
334 int d = dithmat[y&3][x&3];
335 int n, t;
336
337 n = (int) (((argb >> 16) & 0xFF) * 0x1F0/255.0f + 0.5f) + d;
338 t = (n>>4)<<10;
339 n = (int) (((argb >> 8) & 0xFF) * 0x1F0/255.0f + 0.5f) + d;
340 t |= (n>>4)<<5;
341 n = (int) (((argb ) & 0xFF) * 0x1F0/255.0f + 0.5f) + d;
342 t |= (n>>4)<<0;
343 t |= ((argb >> 24) ? 0x8000 : 0);
344 return t & 0xFFFF;
345}
346
347static int
348_txPixQuantize_ARGB1555_DErr ( unsigned long argb, int x, int y, int w)
349{
350 static int qr, qg, qb; // quantized incoming values.
351 int ir, ig, ib; // incoming values.
352 int t;
353
354 ir = (argb >> 16) & 0xFF; // incoming pixel values.
355 ig = (argb >> 8) & 0xFF;
356 ib = (argb ) & 0xFF;
357
358 if (x == 0) qr = qg = qb = 0;
359
360 ir += errR[x] + qr;
361 ig += errG[x] + qg;
362 ib += errB[x] + qb;
363
364 qr = ir; // quantized pixel values.
365 qg = ig; // qR is error from pixel to left, errR is
366 qb = ib; // error from pixel to the top & top left.
367
368 if (qr < 0) qr = 0; if (qr > 255) qr = 255; // clamp.
369 if (qg < 0) qg = 0; if (qg > 255) qg = 255;
370 if (qb < 0) qb = 0; if (qb > 255) qb = 255;
371
372 // To RGB565.
373 qr = (int) (qr * 0x1FFF/255.0f); qr >>= 8;
374 qg = (int) (qg * 0x1FFF/255.0f); qg >>= 8;
375 qb = (int) (qb * 0x1FFF/255.0f); qb >>= 8;
376
377 t = (qr << 10) | (qg << 5) | qb; // this is the value to be returned.
378 t |= ((argb >> 24) ? 0x8000 : 0);
379
380 // Now dequantize the input, and compute & distribute the errors.
381 qr = (qr << 3) | (qr >> 2);
382 qg = (qg << 3) | (qg >> 2);
383 qb = (qb << 3) | (qb >> 2);
384 qr = ir - qr;
385 qg = ig - qg;
386 qb = ib - qb;
387
388 // 3/8 (=0.375) to the EAST, 3/8 to the SOUTH, 1/4 (0.25) to the SOUTH-EAST.
389 errR[x] = ((x == 0) ? 0 : errR[x]) + ((int) (qr * 0.375f));
390 errG[x] = ((x == 0) ? 0 : errG[x]) + ((int) (qg * 0.375f));
391 errB[x] = ((x == 0) ? 0 : errB[x]) + ((int) (qb * 0.375f));
392
393 errR[x+1] = (int) (qr * 0.250f);
394 errG[x+1] = (int) (qg * 0.250f);
395 errB[x+1] = (int) (qb * 0.250f);
396
397 qr = (int) (qr * 0.375f); // Carried to the pixel on the right.
398 qg = (int) (qg * 0.375f);
399 qb = (int) (qb * 0.375f);
400
401 return t & 0xFFFF;
402}
403
404static int
405_txPixQuantize_ARGB4444 (unsigned long argb, int x, int y, int w)
406{
407 return (
408 ((argb >> 12) & 0x0F00) |
409 ((argb >> 8) & 0x00F0) |
410 ((argb >> 4) & 0x000F) |
411 ((argb >> 16) & 0xF000) );
412}
413
414static int
415_txPixQuantize_ARGB4444_D4x4 (unsigned long argb, int x, int y, int w)
416{
417 int d = dithmat[y&3][x&3];
418 int n, t;
419
420 n = (int) (((argb >> 16) & 0xFF) * 0xF0/255.0f + 0.5f) + d;
421 t = (n>>4)<<8;
422 n = (int) (((argb >> 8) & 0xFF) * 0xF0/255.0f + 0.5f) + d;
423 t |= (n>>4)<<4;
424 n = (int) (((argb ) & 0xFF) * 0xF0/255.0f + 0.5f) + d;
425 t |= (n>>4)<<0;
426 t |= (argb >> 16) & 0xF000;
427 return t & 0xFFFF;
428}
429
430static int
431_txPixQuantize_ARGB4444_DErr (unsigned long argb, int x, int y, int w)
432{
433 static int qr, qg, qb; // quantized incoming values.
434 int ir, ig, ib; // incoming values.
435 int t;
436
437 ir = (argb >> 16) & 0xFF; // incoming pixel values.
438 ig = (argb >> 8) & 0xFF;
439 ib = (argb ) & 0xFF;
440
441 if (x == 0) qr = qg = qb = 0;
442
443 ir += errR[x] + qr;
444 ig += errG[x] + qg;
445 ib += errB[x] + qb;
446
447 qr = ir; // quantized pixel values.
448 qg = ig; // qR is error from pixel to left, errR is
449 qb = ib; // error from pixel to the top & top left.
450
451 if (qr < 0) qr = 0; if (qr > 255) qr = 255; // clamp.
452 if (qg < 0) qg = 0; if (qg > 255) qg = 255;
453 if (qb < 0) qb = 0; if (qb > 255) qb = 255;
454
455 // To RGB565.
456 qr = (int) (qr * 0xFFF/255.0f); qr >>= 8;
457 qg = (int) (qg * 0xFFF/255.0f); qg >>= 8;
458 qb = (int) (qb * 0xFFF/255.0f); qb >>= 8;
459
460 t = (qr << 8) | (qg << 4) | qb; // this is the value to be returned.
461 t |= (argb >> 16) & 0xF000;
462
463 // Now dequantize the input, and compute & distribute the errors.
464 qr = (qr << 4) | (qr >> 0);
465 qg = (qg << 4) | (qg >> 0);
466 qb = (qb << 4) | (qb >> 0);
467 qr = ir - qr;
468 qg = ig - qg;
469 qb = ib - qb;
470
471 // 3/8 (=0.375) to the EAST, 3/8 to the SOUTH, 1/4 (0.25) to the SOUTH-EAST.
472 errR[x] = ((x == 0) ? 0 : errR[x]) + ((int) (qr * 0.375f));
473 errG[x] = ((x == 0) ? 0 : errG[x]) + ((int) (qg * 0.375f));
474 errB[x] = ((x == 0) ? 0 : errB[x]) + ((int) (qb * 0.375f));
475
476 errR[x+1] = (int) (qr * 0.250f);
477 errG[x+1] = (int) (qg * 0.250f);
478 errB[x+1] = (int) (qb * 0.250f);
479
480 qr = (int) (qr * 0.375f); // Carried to the pixel on the right.
481 qg = (int) (qg * 0.375f);
482 qb = (int) (qb * 0.375f);
483
484 return t & 0xFFFF;
485}
486
487static int
488_txPixQuantize_AI88( unsigned long argb, int x, int y, int w)
489{
490 return (
491 (((int) (((argb >>16) & 0xFF) * .30F +
492 ((argb >> 8) & 0xFF) * .59F +
493 ((argb ) & 0xFF) * .11F + 0.5f )) & 0xFF) |
494
495 ((argb >>16) & 0xFF00) );
496}
497
498
499static void
500_txImgQuantize(char *dst, char *src, int w, int h, FxU32 format, FxU32 dither)
501{
502 int (*quantizer)(unsigned long argb, int x, int y, int w);
503 int x, y;
504
505 dither &= TX_DITHER_MASK;
506
507 if (dither == TX_DITHER_ERR) { // Error diffusion, floyd-steinberg
508 int i;
509
510 // Clear error diffusion accumulators.
511 for (i=0; i<w; i++) errR[i] = errG[i] = errB[i] = 0;
512
513 switch(format) {
514 case GR_TEXFMT_RGB_332: quantizer = _txPixQuantize_RGB332_DErr;
515 break;
516 case GR_TEXFMT_A_8: quantizer = _txPixQuantize_A8;
517 break;
518 case GR_TEXFMT_I_8: quantizer = _txPixQuantize_I8;
519 break;
520 case GR_TEXFMT_AI_44: quantizer = _txPixQuantize_AI44_DErr;
521 break;
522 case GR_TEXFMT_ARGB_8332: quantizer = _txPixQuantize_ARGB8332_DErr;
523 break;
524 case GR_TEXFMT_RGB_565: quantizer = _txPixQuantize_RGB565_DErr;
525 break;
526 case GR_TEXFMT_ARGB_1555: quantizer = _txPixQuantize_ARGB1555_DErr;
527 break;
528 case GR_TEXFMT_ARGB_4444: quantizer = _txPixQuantize_ARGB4444_DErr;
529 break;
530 case GR_TEXFMT_AI_88: quantizer = _txPixQuantize_AI88;
531 break;
532
533 default: txPanic("Bad case in txQuantize()\n"); break;
534 }
535 }else if (dither == TX_DITHER_4x4) { // 4x4 ordered dithering.
536
537 switch(format) {
538 case GR_TEXFMT_RGB_332: quantizer = _txPixQuantize_RGB332_D4x4;
539 break;
540 case GR_TEXFMT_A_8: quantizer = _txPixQuantize_A8;
541 break;
542 case GR_TEXFMT_I_8: quantizer = _txPixQuantize_I8;
543 break;
544 case GR_TEXFMT_AI_44: quantizer = _txPixQuantize_AI44_D4x4;
545 break;
546
547 case GR_TEXFMT_ARGB_8332: quantizer = _txPixQuantize_ARGB8332_D4x4;
548 break;
549 case GR_TEXFMT_RGB_565: quantizer = _txPixQuantize_RGB565_D4x4;
550 break;
551 case GR_TEXFMT_ARGB_1555: quantizer = _txPixQuantize_ARGB1555_D4x4;
552 break;
553 case GR_TEXFMT_ARGB_4444: quantizer = _txPixQuantize_ARGB4444_D4x4;
554 break;
555 case GR_TEXFMT_AI_88: quantizer = _txPixQuantize_AI88;
556 break;
557
558 default: txPanic("Bad case in txQuantize()\n");
559 break;
560 }
561 } else { // No dithering.
562
563 switch(format) {
564 case GR_TEXFMT_RGB_332: quantizer = _txPixQuantize_RGB332;
565 break;
566 case GR_TEXFMT_A_8: quantizer = _txPixQuantize_A8;
567 break;
568 case GR_TEXFMT_I_8: quantizer = _txPixQuantize_I8;
569 break;
570 case GR_TEXFMT_AI_44: quantizer = _txPixQuantize_AI44;
571 break;
572
573 case GR_TEXFMT_ARGB_8332: quantizer = _txPixQuantize_ARGB8332;
574 break;
575 case GR_TEXFMT_RGB_565: quantizer = _txPixQuantize_RGB565;
576 break;
577 case GR_TEXFMT_ARGB_1555: quantizer = _txPixQuantize_ARGB1555;
578 break;
579 case GR_TEXFMT_ARGB_4444: quantizer = _txPixQuantize_ARGB4444;
580 break;
581 case GR_TEXFMT_AI_88: quantizer = _txPixQuantize_AI88;
582 break;
583
584 default: txPanic("Bad case in txQuantize()\n");
585 break;
586 }
587 }
588
589 if (format < GR_TEXFMT_16BIT) {
590 // 8 bit dst
591 for (y=0; y<h; y++) {
592 for (x=0; x<w; x++) {
593 *dst++ = (*quantizer)(*(unsigned long *)src, x, y, w);
594 src += 4;
595 }
596 }
597 } else {
598 // 16 bit dst.
599 unsigned short *dst16 = (unsigned short *) dst;
600
601 for (y=0; y<h; y++) {
602 for (x=0; x<w; x++) {
603 *dst16++ = (*quantizer)(*(unsigned long *)src, x, y, w);
604 src += 4;
605 }
606 }
607 }
608}
609
610/*
611 * Reduce an ARGB8888 image to 16bits or 8bits/pixel, possibly dithering
612 * the resulting image using either ordered 4x4 or error-diffusion dithering.
613 *
614 * For the special cases of YIQ image, you also get the choice of 2 different
615 * quality levels in each of the compression cases.
616 */
617void
618txMipQuantize(TxMip *pxMip, TxMip *txMip, int format, FxU32 dither, FxU32 compression)
619{
620 int i, w, h;
621
622 if( txVerbose )
623 {
624 printf("Quantizing: (to %s)", Format_Name[format]);
625 }
626 pxMip->format = format;
627 pxMip->width = txMip->width;
628 pxMip->height = txMip->height;
629
630 switch(format) {
631 // Special cases.
632 case GR_TEXFMT_YIQ_422:
633 case GR_TEXFMT_AYIQ_8422:
634 if( txVerbose )
635 printf(".\n");
636 txMipNcc(pxMip, txMip, format, dither, compression);
637 return;
638
639 case GR_TEXFMT_ARGB_8888:
640 // Copy source to destination, and be done.
641 if( txVerbose )
642 printf(".\n");
643 memcpy(pxMip->data[0], txMip->data[0], txMip->size);
644 return;
645
646 case GR_TEXFMT_P_8:
647 case GR_TEXFMT_AP_88:
648 if( txVerbose )
649 printf(".\n");
650 txMipPal256(pxMip, txMip, format, dither, compression);
651 return;
652
653 // Normal cases
654 case GR_TEXFMT_A_8:
655 case GR_TEXFMT_I_8:
656 case GR_TEXFMT_AI_44:
657 case GR_TEXFMT_RGB_332:
658 case GR_TEXFMT_RGB_565:
659 case GR_TEXFMT_ARGB_8332:
660 case GR_TEXFMT_ARGB_1555:
661 case GR_TEXFMT_ARGB_4444:
662 case GR_TEXFMT_AI_88:
663 break;
664
665 // Bad cases
666 default:
667 txPanic("Bad data format in Quantize\n");
668 return;
669
670 }
671
672 // We deal with rest of them here one mipmap level at a time.
673
674 w = txMip->width;
675 h = txMip->height;
676
677 for (i=0; i< pxMip->depth; i++) {
678 if( txVerbose )
679 printf(" %dx%d", w, h);
680
681 _txImgQuantize(pxMip->data[i], txMip->data[i], w, h, format, dither);
682 w >>= 1; if (w == 0) w = 1;
683 h >>= 1; if (h == 0) h = 1;
684 }
685 if( txVerbose )
686 printf(".\n");
687}
Note: See TracBrowser for help on using the repository browser.