ftp.nice.ch/pub/next/graphics/movie/mpeg.2.0.s.tar.gz#/mpeg_next/12bit.c

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.