This is 12bit.c in view mode; [Download] [Up]
/*
* Copyright (c) 1992 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice and the following
* two paragraphs appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/*
hacked from 24bit.c by G. Arakaki. Specifically optimized for a
16bit color NeXTstation.
*/
#include "video.h"
#include "proto.h"
/*
* We'll define the "ConvertColor" macro here to do fixed point arithmetic
* that'll convert from YCrCb to RGB using:
* R = L + 1.40200*Cr;
* G = L - 0.34414*Cb - 0.71414*Cr
* B = L + 1.77200*Cb;
*
* We'll use fixed point by adding two extra bits after the decimal.
*/
#define BITS 8
#define ONE ((int) 1)
#define CONST_SCALE (ONE << BITS)
#define ROUND_FACTOR (ONE << (BITS-1))
/* Macro to convert integer to fixed. */
#define UP(x) (((int)(x)) << BITS)
/* Macro to convert fixed to integer (with rounding). */
#define DOWN(x) (((x) + ROUND_FACTOR) >> BITS)
/* Macro to convert a float to a fixed */
#define FIX(x) ((int) ((x)*CONST_SCALE + 0.5))
#define CLAMP(ll,x,ul) ( ((x)<(ll)) ?(ll):( ((x)>(ul)) ?(ul):(x)))
static int *Cb_r_tab, *Cr_g_tab, *Cb_g_tab, *Cr_b_tab;
static unsigned short YUV_to_RGB[64 * 32 * 32];
/*
*--------------------------------------------------------------
*
* InitColorDither --
*
* To get rid of the multiply and other conversions in color
* dither, we use a lookup table.
*
* Results:
* None.
*
* Side effects:
* The lookup tables are initialized.
*
*--------------------------------------------------------------
*/
void
InitColorDither()
{
int L, CR, CB;
int ll, rr, bb, i;
int cb_r;
int cr_g;
int cb_g;
int cr_b;
int R, G, B;
unsigned int r, b, g;
Cr_b_tab = (int *)malloc(256*sizeof(int));
Cr_g_tab = (int *)malloc(256*sizeof(int));
Cb_g_tab = (int *)malloc(256*sizeof(int));
Cb_r_tab = (int *)malloc(256*sizeof(int));
for (i=0; i<256; i++) {
CB = CR = i;
CB -= 128; CR -= 128;
Cb_r_tab[i] = FIX(1.40200) * CB;
Cr_g_tab[i] = -FIX(0.34414) * CR;
Cb_g_tab[i] = -FIX(0.71414) * CB;
Cr_b_tab[i] = FIX(1.77200) * CR;
}
for (ll = 0; ll < 64; ++ll) {
for (rr = 0; rr < 32; ++rr) {
for (bb = 0; bb < 32; ++bb) {
L = ll << 2;
CR = rr << 3;
CB = bb << 3;
cb_r = Cb_r_tab[CB];
cr_g = Cr_g_tab[CR];
cb_g = Cb_g_tab[CB];
cr_b = Cr_b_tab[CR];
L = UP(L);
R = L + cb_r;
G = L + cr_g + cb_g;
B = L + cr_b;
b = (CLAMP(0,B,UP(255)) & 0xf000) >> 8;
g = (CLAMP(0,G,UP(255)) & 0xf000) >> 4;
r = (CLAMP(0,R,UP(255)) & 0xf000);
YUV_to_RGB[ll << 10 | rr << 5 | bb] = r | g | b | 0x000f;
}
}
}
}
/*
*--------------------------------------------------------------
*
* ColorDitherImage --
*
* Converts image into 24 bit color.
*
* Results:
* None.
*
* Side effects:
* None.
*
*--------------------------------------------------------------
*/
void
ColorDitherImage(lum, cr, cb, out, rows, cols)
unsigned char *lum;
unsigned char *cr;
unsigned char *cb;
unsigned char *out;
int cols, rows;
{
register unsigned short *row1, *row2;
unsigned short *rowEnd, *blkEnd;
register unsigned char *lum2;
register int yuv;
row1 = (unsigned short *)out;
row2 = row1 + cols;
lum2 = lum + cols;
blkEnd = row1 + (rows * cols);
while (row1 < blkEnd) {
rowEnd = row1 + cols;
while (row1 < rowEnd) {
yuv = ((*lum++ & 0xfc) << 8) | ((*cr++ & 0xf8) << 2)
| (*cb++ >> 3);
*row1++ = YUV_to_RGB[yuv];
yuv = (yuv & 0x03ff) | ((*lum++ & 0xfc) << 8);
*row1++ = YUV_to_RGB[yuv];
/*
* Now, do second row.
*/
yuv = (yuv & 0x03ff) | ((*lum2++ & 0xfc) << 8);
*row2++ = YUV_to_RGB[yuv];
yuv = (yuv & 0x03ff) | ((*lum2++ & 0xfc) << 8);
*row2++ = YUV_to_RGB[yuv];
}
lum += cols;
lum2 += cols;
row1 += cols;
row2 += cols;
}
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.