diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | e2de64d6f1beb9e492daf5b886e19933c1fa41dd (patch) | |
tree | 9047cf9e6b5c43878d5bf82660adae77ceee097a /mpeglib/lib/util/render/dither/colorTableHighBit.cpp | |
download | tdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.tar.gz tdemultimedia-e2de64d6f1beb9e492daf5b886e19933c1fa41dd.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdemultimedia@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'mpeglib/lib/util/render/dither/colorTableHighBit.cpp')
-rw-r--r-- | mpeglib/lib/util/render/dither/colorTableHighBit.cpp | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/mpeglib/lib/util/render/dither/colorTableHighBit.cpp b/mpeglib/lib/util/render/dither/colorTableHighBit.cpp new file mode 100644 index 00000000..171f4e97 --- /dev/null +++ b/mpeglib/lib/util/render/dither/colorTableHighBit.cpp @@ -0,0 +1,248 @@ +/* + colorTables for 16,32 Bit depth + Copyright (C) 2000 Martin Vogt + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Library General Public License as published by + the Free Software Foundation. + + For more information look at the file COPYRIGHT in this package + + */ + + + +#include "colorTableHighBit.h" + +//#define INTERPOLATE + + +/* + * Erik Corry's multi-byte dither routines. + * + * The basic idea is that the Init generates all the necessary tables. + * The tables incorporate the information about the layout of pixels + * in the XImage, so that it should be able to cope with 15-bit, 16-bit + * 24-bit (non-packed) and 32-bit (10-11 bits per color!) screens. + * At present it cannot cope with 24-bit packed mode, since this involves + * getting down to byte level again. It is assumed that the bits for each + * color are contiguous in the longword. + * + * Writing to memory is done in shorts or ints. (Unfortunately, short is not + * very fast on Alpha, so there is room for improvement here). There is no + * dither time check for overflow - instead the tables have slack at + * each end. This is likely to be faster than an 'if' test as many modern + * architectures are really bad at ifs. Potentially, each '&&' causes a + * pipeline flush! + * + * There is no shifting and fixed point arithmetic, as I really doubt you + * can see the difference, and it costs. This may be just my bias, since I + * heard that Intel is really bad at shifting. + */ + + +/* + * How many 1 bits are there in the PIXVALword. + * Low performance, do not call often. + */ +static int number_of_bits_set(unsigned PIXVAL a) { + if(!a) return 0; + if(a & 1) return 1 + number_of_bits_set(a >> 1); + return(number_of_bits_set(a >> 1)); +} + + + +/* + * How many 0 bits are there at most significant end of PIXVALword. + * Low performance, do not call often. + */ +static int free_bits_at_top(unsigned PIXVAL a) { + /* assume char is 8 bits */ + if(!a) return sizeof(unsigned PIXVAL) * 8; + /* assume twos complement */ + if(((PIXVAL)a) < 0l) return 0; + return 1 + free_bits_at_top ( a << 1); +} + +/* + * How many 0 bits are there at least significant end of PIXVALword. + * Low performance, do not call often. + */ +static int free_bits_at_bottom(unsigned PIXVAL a) { + /* assume char is 8 bits */ + if(!a) return sizeof(unsigned PIXVAL) * 8; + if(((PIXVAL)a) & 1l) return 0; + return 1 + free_bits_at_bottom ( a >> 1); +} + + + +ColorTableHighBit::ColorTableHighBit(int bpp,unsigned int redMask, + unsigned int greenMask, + unsigned int blueMask) { + this->bpp=bpp; + this->redMask=redMask; + this->greenMask=greenMask; + this->blueMask=blueMask; + + colortab = new TABTYPE[5*256]; + + Cr_r_tab = &colortab[0*256]; + Cr_g_tab = &colortab[1*256]; + Cb_g_tab = &colortab[2*256]; + Cb_b_tab = &colortab[3*256]; + L_tab = &colortab[4*256]; + + rgb_2_pix = new PIXVAL [3*768]; + + r_2_pix_alloc = &rgb_2_pix[0*768]; + g_2_pix_alloc = &rgb_2_pix[1*768]; + b_2_pix_alloc = &rgb_2_pix[2*768]; + + initHighColor(bpp>=24,redMask,greenMask,blueMask); + +} + + +ColorTableHighBit::~ColorTableHighBit() { + delete colortab; + delete rgb_2_pix; +} + +/* + *-------------------------------------------------------------- + * + * InitColor16Dither -- + * + * 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 ColorTableHighBit::initHighColor(int thirty2,unsigned int redMask, + unsigned int greenMask, + unsigned int blueMask) { + + unsigned PIXVAL red_mask = redMask; + unsigned PIXVAL green_mask =greenMask; + unsigned PIXVAL blue_mask = blueMask; + + int CR, CB, i; + + + for (i=0; i<256; i++) { + L_tab[i] = i; + if (gammaCorrectFlag) { + L_tab[i] = (TABTYPE)GAMMA_CORRECTION(i); + } + + CB = CR = i; + + if (chromaCorrectFlag) { + CB -= 128; + CB = CHROMA_CORRECTION128(CB); + CR -= 128; + CR = CHROMA_CORRECTION128(CR); + } else { + CB -= 128; CR -= 128; + } +/* was + Cr_r_tab[i] = 1.596 * CR; + Cr_g_tab[i] = -0.813 * CR; + Cb_g_tab[i] = -0.391 * CB; + Cb_b_tab[i] = 2.018 * CB; + but they were just messed up. + Then was (_Video Deymstified_): + Cr_r_tab[i] = 1.366 * CR; + Cr_g_tab[i] = -0.700 * CR; + Cb_g_tab[i] = -0.334 * CB; + Cb_b_tab[i] = 1.732 * CB; + but really should be: + (from ITU-R BT.470-2 System B, G and SMPTE 170M ) +*/ + Cr_r_tab[i] = (TABTYPE) ( (0.419/0.299) * CR ); + Cr_g_tab[i] = (TABTYPE) ( -(0.299/0.419) * CR ); + Cb_g_tab[i] = (TABTYPE) ( -(0.114/0.331) * CB ); + Cb_b_tab[i] = (TABTYPE) ( (0.587/0.331) * CB ); + +/* + though you could argue for: + SMPTE 240M + Cr_r_tab[i] = (0.445/0.212) * CR; + Cr_g_tab[i] = -(0.212/0.445) * CR; + Cb_g_tab[i] = -(0.087/0.384) * CB; + Cb_b_tab[i] = (0.701/0.384) * CB; + FCC + Cr_r_tab[i] = (0.421/0.30) * CR; + Cr_g_tab[i] = -(0.30/0.421) * CR; + Cb_g_tab[i] = -(0.11/0.331) * CB; + Cb_b_tab[i] = (0.59/0.331) * CB; + ITU-R BT.709 + Cr_r_tab[i] = (0.454/0.2125) * CR; + Cr_g_tab[i] = -(0.2125/0.454) * CR; + Cb_g_tab[i] = -(0.0721/0.386) * CB; + Cb_b_tab[i] = (0.7154/0.386) * CB; +*/ + } + + /* + * Set up entries 0-255 in rgb-to-pixel value tables. + */ + for (i = 0; i < 256; i++) { + r_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(red_mask)); + r_2_pix_alloc[i + 256] <<= free_bits_at_bottom(red_mask); + g_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(green_mask)); + g_2_pix_alloc[i + 256] <<= free_bits_at_bottom(green_mask); + b_2_pix_alloc[i + 256] = i >> (8 - number_of_bits_set(blue_mask)); + b_2_pix_alloc[i + 256] <<= free_bits_at_bottom(blue_mask); + /* + * If we have 16-bit output depth, then we double the value + * in the top word. This means that we can write out both + * pixels in the pixel doubling mode with one op. It is + * harmless in the normal case as storing a 32-bit value + * through a short pointer will lose the top bits anyway. + * A similar optimisation for Alpha for 64 bit has been + * prepared for, but is not yet implemented. + */ + if(!thirty2) { + r_2_pix_alloc[i + 256] |= (r_2_pix_alloc[i + 256]) << 16; + g_2_pix_alloc[i + 256] |= (g_2_pix_alloc[i + 256]) << 16; + b_2_pix_alloc[i + 256] |= (b_2_pix_alloc[i + 256]) << 16; + + } +#ifdef SIXTYFOUR_BIT + if(thirty2) { + + r_2_pix_alloc[i + 256] |= (r_2_pix_alloc[i + 256]) << 32; + g_2_pix_alloc[i + 256] |= (g_2_pix_alloc[i + 256]) << 32; + b_2_pix_alloc[i + 256] |= (b_2_pix_alloc[i + 256]) << 32; + + } +#endif + } + + /* + * Spread out the values we have to the rest of the array so that + * we do not need to check for overflow. + */ + for (i = 0; i < 256; i++) { + r_2_pix_alloc[i] = r_2_pix_alloc[256]; + r_2_pix_alloc[i+ 512] = r_2_pix_alloc[511]; + g_2_pix_alloc[i] = g_2_pix_alloc[256]; + g_2_pix_alloc[i+ 512] = g_2_pix_alloc[511]; + b_2_pix_alloc[i] = b_2_pix_alloc[256]; + b_2_pix_alloc[i+ 512] = b_2_pix_alloc[511]; + } + + r_2_pix = r_2_pix_alloc + 256; + g_2_pix = g_2_pix_alloc + 256; + b_2_pix = b_2_pix_alloc + 256; +} |