📄 24bit.c
字号:
/* * This version of 24bit.c has been heavily modified by * Magnus Heldestat <Magnus.Heldestad@cs.umu.se> to optimize * for speed. Thanks, Magnus! *//* * 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. */#include <config.h>#include "video.h"#include "dither.h"#include "proto.h"#include <time.h>#include <malloc.h>#include "my_dmalloc.h"/* Optimization defines SAVE_L Save L between eacn pixel SAVE_CR Save CR and CB netween each y iter SAVE_ALL SAVE_L + SAVE_CR + Save last L for the first L POOR_Q1 Fast, but yields lower quality POOR_Q2 SAVE_ALL + Fast, but yields lower quality PRE_CALC Precalculates the YCrCb to RGB values (in InitColorDither) FLIP Flips the image in the correct way for lrectwrite (gl)*/#define SAVE_ALL /* SAVE_L and SAVE_CR automatically turned on */#define PRE_CALC#undef FLIP#undef POOR_Q1#undef POOR_Q2/* Benchmarking for the above defines for 20 * LiftOff.mpg (in secs) Hardware: Indy R4400 (150 MHz) with 64 meg memory running Irix 5.2 Compiler options: -kpicopt -O2 -mips2 Name User Sys Real Func only ==== ==== === ==== ========= unopt version: 108.941 1.055 1:50.98 50.59 ALL UNDEFINED: 106.254 1.098 1:50.12 38.99 SAVE_CR: 92.287 1.118 1:37.13 34.29 only PRE_CALC: 91.871 1.021 1:33.72 33.54 SAVE_L: 86.844 1.038 1:28.68 28.80 SAVE_ALL: 85.385 0.866 1:26.96 27.25 POOR_Q1: 76.498 0.905 1:18.04 18.41 POOR_Q2: 76.645 0.914 1:18.37 18.37 NOTE 1: the unopt version is the same as in mpeg_lib-1.1 NOTE 2: PRE_CALC is defined in all except ALL UNDEFINED NOTE 3: LiftOff is a Alias demo movie (see www.alias.com) As can be seen, the ColorDitherImage runs almost twice as fast with SAVE_ALL and PRE_CALC defined compared with the unopt version. *//* * 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 ALIGN(x,s) (((x & 0xff) == x) ? (x << s) : ((x < 0) ? 0 : (255 << s)))#define RR(x) (ALIGN(x, 0))#define GG(x) (ALIGN(x, (BITS)))#define BB(x) (ALIGN(x, (BITS*2)))/* Macro to convert a float to a fixed */#define FIX(x) ((int) ((x)*CONST_SCALE + 0.5))#define FIX2(x,v) (FIX(x) * (v - 128))/* Turn on SAVE_ALL if POOR_Q2 */#ifdef POOR_Q2#ifndef SAVE_ALL#define SAVE_ALL#endif#endif/* SAVE_ALL implies SAVE_L and SAVE_CR */#ifdef SAVE_ALL#ifndef SAVE_L#define SAVE_L#endif#ifndef SAVE_CR#define SAVE_CR#endif#endif/* If POOR_Q?, simplify the ALIGN define */#ifdef POOR_Q1#undef ALIGN#define ALIGN(x,s) (x << s)#endif#ifdef POOR_Q2#undef ALIGN#define ALIGN(x,s) (x << s)#endif#ifdef PRE_CALCstatic int *Cb_r_tab, *Cr_g_tab, *Cb_g_tab, *Cr_b_tab;#endif/* *-------------------------------------------------------------- * * 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. * *-------------------------------------------------------------- */voidInitColorDither(){#ifdef PRE_CALC int CR, CB, i; /* XXX leak alert! these are never free()'d... --GPW 1998/06/30 */ 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; Cb_r_tab[i] >>= BITS; Cr_g_tab[i] >>= BITS; Cb_g_tab[i] >>= BITS; Cr_b_tab[i] >>= BITS; }#endif}/* Space saving define */#define RR_GG_BB\ R = L + cb_r;\ G = L + cr_cb;\ B = L + cr_b;\ r = RR(R);\ g = GG(G);\ b = BB(B);/* *-------------------------------------------------------------- * * ColorDitherImage -- * * Converts image into 24 bit color. * * Results: * None. * * Side effects: * None. * *-------------------------------------------------------------- */voidColorDitherImage(lum, cr, cb, out, rows, cols) unsigned char *lum; unsigned char *cr; unsigned char *cb; unsigned char *out; int cols, rows;{ int L, CR, CB; unsigned int *row1, *row2; unsigned char *lum2; int x, y; unsigned int r, b, g; int cb_r, cr_b, cr_cb;#ifndef PRE_CALC int t1, t2;#endif#ifdef SAVE_L int rgb; int LL;#endif#ifdef SAVE_CR int ccr=-1, ccb=-1;#endif#ifdef FLIP row1 = (unsigned int *)out + cols * (rows - 1); row2 = row1 - cols;#else row1 = (unsigned int *)out; row2 = row1 + cols;#endif lum2 = lum + cols; for (y=0; y<rows; y+=2) { for (x=0; x<cols; x+=2) { int R, G, B; CR = *cr++; CB = *cb++;#ifdef SAVE_CR if(ccr != CR || ccb != CB) {#ifdef PRE_CALC cb_r = Cb_r_tab[CB]; cr_b = Cr_b_tab[CR]; cr_cb = Cr_g_tab[CR] + Cb_g_tab[CB];#else cb_r = FIX2(1.40200, CB); cr_b = FIX2(1.77200, CR); t1 = -FIX2(0.34414, CR); t2 = -FIX2(0.71414, CB); cb_r >>= BITS; cr_b >>= BITS; t1 >>= BITS; t2 >>= BITS; cr_cb = t1 + t2;#endif ccr = CR; ccb = CB;#ifdef SAVE_ALL LL = -1;#endif }#else#ifdef PRE_CALC cb_r = Cb_r_tab[CB]; cr_b = Cr_b_tab[CR]; cr_cb = Cr_g_tab[CR] + Cb_g_tab[CB];#else cb_r = FIX2(1.40200, CB); cr_b = FIX2(1.77200, CR); t1 = -FIX2(0.34414, CR); t2 = -FIX2(0.71414, CB); cb_r >>= BITS; cr_b >>= BITS; t1 >>= BITS; t2 >>= BITS; cr_cb = t1 + t2;#endif /* PRE_CALC */#endif /* SAVE_CR */#ifdef SAVE_L#ifdef SAVE_ALL L = *lum++; if(L != LL) { RR_GG_BB rgb = r | g | b; LL = L; } *row1++ = rgb;#else LL = L = *lum++; RR_GG_BB rgb = *row1++ = r | g | b;#endif#else L = *lum++; RR_GG_BB *row1++ = r | g | b;#endif L = *lum++;#ifdef SAVE_L if(L != LL) { RR_GG_BB rgb = r | g | b; LL = L; } *row1++ = rgb;#else RR_GG_BB *row1++ = r | g | b;#endif L = *lum2++;#ifdef SAVE_L if(L != LL) { RR_GG_BB rgb = r | g | b; LL = L; } *row2++ = rgb;#else RR_GG_BB *row2++ = r | g | b;#endif L = *lum2++;#ifdef SAVE_L if(L != LL) { RR_GG_BB rgb = r | g | b;#ifdef SAVE_ALL LL = L;#endif } *row2++ = rgb;#else RR_GG_BB *row2++ = r | g | b;#endif } lum += cols; lum2 += cols;#ifdef FLIP row1 -= 3 * cols; row2 -= 3 * cols;#else row1 += cols; row2 += cols;#endif }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -