From e2de64d6f1beb9e492daf5b886e19933c1fa41dd Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: 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 --- mpeglib/lib/util/render/dither/Makefile.am | 40 +++ mpeglib/lib/util/render/dither/colorTable8Bit.cpp | 147 ++++++++++ mpeglib/lib/util/render/dither/colorTable8Bit.h | 57 ++++ .../lib/util/render/dither/colorTableHighBit.cpp | 248 +++++++++++++++++ mpeglib/lib/util/render/dither/colorTableHighBit.h | 73 +++++ mpeglib/lib/util/render/dither/dither16Bit.cpp | 300 ++++++++++++++++++++ mpeglib/lib/util/render/dither/dither16Bit.h | 55 ++++ mpeglib/lib/util/render/dither/dither32Bit.cpp | 253 +++++++++++++++++ mpeglib/lib/util/render/dither/dither32Bit.h | 55 ++++ mpeglib/lib/util/render/dither/dither32mmx.cpp | 272 ++++++++++++++++++ mpeglib/lib/util/render/dither/dither8Bit.cpp | 306 +++++++++++++++++++++ mpeglib/lib/util/render/dither/dither8Bit.h | 63 +++++ mpeglib/lib/util/render/dither/ditherDef.h | 100 +++++++ mpeglib/lib/util/render/dither/ditherMMX.h | 38 +++ mpeglib/lib/util/render/dither/ditherRGB.cpp | 230 ++++++++++++++++ mpeglib/lib/util/render/dither/ditherRGB.h | 45 +++ .../lib/util/render/dither/ditherRGB_flipped.cpp | 82 ++++++ mpeglib/lib/util/render/dither/ditherRGB_flipped.h | 34 +++ mpeglib/lib/util/render/dither/ditherWrapper.cpp | 246 +++++++++++++++++ mpeglib/lib/util/render/dither/ditherWrapper.h | 80 ++++++ mpeglib/lib/util/render/dither/ditherer_mmx16.cpp | 256 +++++++++++++++++ 21 files changed, 2980 insertions(+) create mode 100644 mpeglib/lib/util/render/dither/Makefile.am create mode 100644 mpeglib/lib/util/render/dither/colorTable8Bit.cpp create mode 100644 mpeglib/lib/util/render/dither/colorTable8Bit.h create mode 100644 mpeglib/lib/util/render/dither/colorTableHighBit.cpp create mode 100644 mpeglib/lib/util/render/dither/colorTableHighBit.h create mode 100644 mpeglib/lib/util/render/dither/dither16Bit.cpp create mode 100644 mpeglib/lib/util/render/dither/dither16Bit.h create mode 100644 mpeglib/lib/util/render/dither/dither32Bit.cpp create mode 100644 mpeglib/lib/util/render/dither/dither32Bit.h create mode 100644 mpeglib/lib/util/render/dither/dither32mmx.cpp create mode 100644 mpeglib/lib/util/render/dither/dither8Bit.cpp create mode 100644 mpeglib/lib/util/render/dither/dither8Bit.h create mode 100644 mpeglib/lib/util/render/dither/ditherDef.h create mode 100644 mpeglib/lib/util/render/dither/ditherMMX.h create mode 100644 mpeglib/lib/util/render/dither/ditherRGB.cpp create mode 100644 mpeglib/lib/util/render/dither/ditherRGB.h create mode 100644 mpeglib/lib/util/render/dither/ditherRGB_flipped.cpp create mode 100644 mpeglib/lib/util/render/dither/ditherRGB_flipped.h create mode 100644 mpeglib/lib/util/render/dither/ditherWrapper.cpp create mode 100644 mpeglib/lib/util/render/dither/ditherWrapper.h create mode 100644 mpeglib/lib/util/render/dither/ditherer_mmx16.cpp (limited to 'mpeglib/lib/util/render/dither') diff --git a/mpeglib/lib/util/render/dither/Makefile.am b/mpeglib/lib/util/render/dither/Makefile.am new file mode 100644 index 00000000..166d5ca3 --- /dev/null +++ b/mpeglib/lib/util/render/dither/Makefile.am @@ -0,0 +1,40 @@ +# liboutplugin - Makefile.am + +INCLUDES = $(all_includes) + +EXTRA_DIST = ditherDef.h ditherMMX.h \ + ditherer_mmx16.cpp dither32mmx.cpp + +noinst_LTLIBRARIES = libdither.la + +noinst_HEADERS = ditherWrapper.h \ + dither8Bit.h colorTable8Bit.h \ + colorTableHighBit.h dither16Bit.h \ + dither32Bit.h ditherRGB_flipped.h \ + ditherRGB.h + +libdither_la_SOURCES = ditherWrapper.cpp \ + dither8Bit.cpp \ + colorTable8Bit.cpp colorTableHighBit.cpp \ + dither16Bit.cpp dither32Bit.cpp \ + ditherRGB_flipped.cpp ditherRGB.cpp \ + ditherer_mmx16.cpp dither32mmx.cpp + + + + + + + + + + + + + + + + + + + diff --git a/mpeglib/lib/util/render/dither/colorTable8Bit.cpp b/mpeglib/lib/util/render/dither/colorTable8Bit.cpp new file mode 100644 index 00000000..57c533de --- /dev/null +++ b/mpeglib/lib/util/render/dither/colorTable8Bit.cpp @@ -0,0 +1,147 @@ +/* + colorTables for 8 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 "colorTable8Bit.h" + + +ColorTable8Bit::ColorTable8Bit() { + + lum_values = new int[LUM_RANGE]; + cr_values = new int[CR_RANGE]; + cb_values = new int[CB_RANGE]; + + + /* We can exploit cache by allocating contiguous blocks */ + + 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]; + + init8BitColor(); +} + + +ColorTable8Bit::~ColorTable8Bit() { + delete lum_values; + delete cr_values; + delete cb_values; + delete colortab; +} + + +void ColorTable8Bit::init8BitColor() { + int i; + + + + for (i=0; i 255.0) fr = 255.0; + + if (fg < 0.0) fg = 0.0; + else if (fg > 255.0) fg = 255.0; + + if (fb < 0.0) fb = 0.0; + else if (fb > 255.0) fb = 255.0; + + *r = (unsigned char) fr; + *g = (unsigned char) fg; + *b = (unsigned char) fb; + +} diff --git a/mpeglib/lib/util/render/dither/colorTable8Bit.h b/mpeglib/lib/util/render/dither/colorTable8Bit.h new file mode 100644 index 00000000..6d873d1d --- /dev/null +++ b/mpeglib/lib/util/render/dither/colorTable8Bit.h @@ -0,0 +1,57 @@ +/* + colorTables for 8 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 + + */ + + +#ifndef __COLORTABLE8BIT_H +#define __COLORTABLE8BIT_H + +#include "ditherDef.h" + + +class ColorTable8Bit { + + // Arrays holding quantized value ranged for lum, cr, and cb. + // (used for 8 Bit) + + int* lum_values; + int* cr_values; + int* cb_values; + + + + + TABTYPE *L_tab; + TABTYPE *Cr_r_tab; + TABTYPE *Cr_g_tab; + TABTYPE *Cb_g_tab; + TABTYPE *Cb_b_tab; + TABTYPE *colortab; + + + public: + ColorTable8Bit(); + ~ColorTable8Bit(); + + inline int* getLumValues() { return lum_values; } + inline int* getCrValues() { return cr_values; } + inline int* getCbValues() { return cb_values; } + + void ConvertColor(unsigned int l, unsigned int cr, unsigned int cb, + unsigned char* r, unsigned char* g, unsigned char* b); + + + private: + void init8BitColor(); + + +}; +#endif 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; +} diff --git a/mpeglib/lib/util/render/dither/colorTableHighBit.h b/mpeglib/lib/util/render/dither/colorTableHighBit.h new file mode 100644 index 00000000..9945414d --- /dev/null +++ b/mpeglib/lib/util/render/dither/colorTableHighBit.h @@ -0,0 +1,73 @@ +/* + 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 + + */ + + +#ifndef __COLORTABLEHIGHBIT_H +#define __COLORTABLEHIGHBIT_H + +#include "ditherDef.h" + + + + +class ColorTableHighBit { + + TABTYPE *L_tab; + TABTYPE *Cr_r_tab; + TABTYPE *Cr_g_tab; + TABTYPE *Cb_g_tab; + TABTYPE *Cb_b_tab; + TABTYPE *colortab; + + + PIXVAL *r_2_pix; + PIXVAL *g_2_pix; + PIXVAL *b_2_pix; + PIXVAL *rgb_2_pix; + + PIXVAL *r_2_pix_alloc; + PIXVAL *g_2_pix_alloc; + PIXVAL *b_2_pix_alloc; + + + + // init stuff + int bpp; + // colorMask + unsigned int redMask; + unsigned int greenMask; + unsigned int blueMask; + + public: + ColorTableHighBit(int bpp,unsigned int redMask, + unsigned int greenMask,unsigned int blueMask); + ~ColorTableHighBit(); + + inline TABTYPE* getL_tab() { return L_tab ; } + inline TABTYPE* getCr_r_tab() { return Cr_r_tab ; } + inline TABTYPE* getCr_g_tab() { return Cr_g_tab ; } + inline TABTYPE* getCb_g_tab() { return Cb_g_tab ; } + inline TABTYPE* getCb_b_tab() { return Cb_b_tab ; } + + + inline PIXVAL* getr_2_pix() { return r_2_pix ; } + inline PIXVAL* getg_2_pix() { return g_2_pix ; } + inline PIXVAL* getb_2_pix() { return b_2_pix ; } + + + + private: + void initHighColor(int thirty2,unsigned int redMask, + unsigned int greenMask,unsigned int blueMask); + +}; +#endif diff --git a/mpeglib/lib/util/render/dither/dither16Bit.cpp b/mpeglib/lib/util/render/dither/dither16Bit.cpp new file mode 100644 index 00000000..0a843ee9 --- /dev/null +++ b/mpeglib/lib/util/render/dither/dither16Bit.cpp @@ -0,0 +1,300 @@ +/* + dither 16 bit depth yuv images + 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 "dither16Bit.h" + + +Dither16Bit::Dither16Bit(unsigned int redMask, + unsigned int greenMask,unsigned int blueMask) { + + + colorTableHighBit=new ColorTableHighBit(16,redMask,greenMask,blueMask); + L_tab=colorTableHighBit->getL_tab(); + Cr_r_tab=colorTableHighBit->getCr_r_tab(); + Cr_g_tab=colorTableHighBit->getCr_g_tab(); + Cb_g_tab=colorTableHighBit->getCb_g_tab(); + Cb_b_tab=colorTableHighBit->getCb_b_tab(); + + r_2_pix=colorTableHighBit->getr_2_pix(); + g_2_pix=colorTableHighBit->getg_2_pix(); + b_2_pix=colorTableHighBit->getb_2_pix(); + +} + + +Dither16Bit::~Dither16Bit() { + delete colorTableHighBit; +} + + +/* + *-------------------------------------------------------------- + * + * Color16DitherImage -- + * + * Converts image into 16 bit color. + * + * Results: + * None. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +void Dither16Bit::ditherImageColor16(unsigned char* lum, + unsigned char* cr, + unsigned char* cb, + unsigned char* out, + int rows, + int cols, + int offset) { + + int L, CR, CB; + unsigned short *row1, *row2; + unsigned char *lum2; + int x, y; + int cr_r; + int cr_g; + int cb_g; + int cb_b; + int cols_2 = cols/2; + + row1 = (unsigned short *)out; + row2=row1+cols_2+cols_2+offset; // start of second row + + offset=2*offset+cols_2+cols_2; + + lum2 = lum + cols_2 + cols_2; + + + for (y=0; y> 1; + CB = (CB + *cb) >> 1; + cr_r = Cr_r_tab[CR]; + cr_g = Cr_g_tab[CR]; + cb_g = Cb_g_tab[CB]; + cb_b = Cb_b_tab[CB]; + } +#endif + + L = L_tab[(int) *lum++]; + + R = L + cr_r; + G = L + cr_g + cb_g; + B = L + cb_b; + + *row1++ = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); + + /* + * Now, do second row. + */ +#ifdef INTERPOLATE + if(y != rows - 2) { + CR = (CR + *(cr + cols_2 - 1)) >> 1; + CB = (CB + *(cb + cols_2 - 1)) >> 1; + cr_r = Cr_r_tab[CR]; + cr_g = Cr_g_tab[CR]; + cb_g = Cb_g_tab[CB]; + cb_b = Cb_b_tab[CB]; + } +#endif + + L = L_tab[(int) *lum2++]; + R = L + cr_r; + G = L + cr_g + cb_g; + B = L + cb_b; + + *row2++ = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); + + L = L_tab[(int) *lum2++]; + R = L + cr_r; + G = L + cr_g + cb_g; + B = L + cb_b; + + *row2++ = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); + } + /* + * These values are at the start of the next line, (due + * to the ++'s above),but they need to be at the start + * of the line after that. + */ + lum += cols_2 + cols_2; + lum2 += cols_2 + cols_2; + row1 += offset; + row2 += offset; + } +} + + +/* + * Erik Corry's pixel doubling routines for 15/16/24/32 bit screens. + */ + + +/* + *-------------------------------------------------------------- + * + * Twox2Color16DitherImage -- + * + * Converts image into 16 bit color at double size. + * + * Results: + * None. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +/* + * In this function I make use of a nasty trick. The tables have the lower + * 16 bits replicated in the upper 16. This means I can write ints and get + * the horisontal doubling for free (almost). + */ + +void Dither16Bit::ditherImageTwox2Color16(unsigned char* lum, + unsigned char* cr, + unsigned char* cb, + unsigned char* out, + int rows, + int cols, + int mod) { + int L, CR, CB; + unsigned int *row1 = (unsigned int *)out; + unsigned int *row2 = row1 + cols + mod/2; + unsigned int *row3 = row2 + cols + mod/2; + unsigned int *row4 = row3 + cols + mod/2; + unsigned char *lum2; + int x, y; + int cr_r; + int cr_g; + int cb_g; + int cb_b; + int cols_2 = cols/2; + + lum2 = lum + cols_2 + cols_2; + for (y=0; y> 1; + CB = (CB + *cb) >> 1; + cr_r = Cr_r_tab[CR]; + cr_g = Cr_g_tab[CR]; + cb_g = Cb_g_tab[CB]; + cb_b = Cb_b_tab[CB]; + } + // end + + L = L_tab[(int) *lum++]; + + R = L + cr_r; + G = L + cr_g + cb_g; + B = L + cb_b; + + t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); + row1[0] = t; + row1++; + row2[0] = t; + row2++; + + /* + * Now, do second row. + */ + // INTERPOLATE + if(y != rows - 2) { + CR = (CR + *(cr + cols_2 - 1)) >> 1; + CB = (CB + *(cb + cols_2 - 1)) >> 1; + cr_r = Cr_r_tab[CR]; + cr_g = Cr_g_tab[CR]; + cb_g = Cb_g_tab[CB]; + cb_b = Cb_b_tab[CB]; + } + // end + + L = L_tab[(int) *lum2++]; + R = L + cr_r; + G = L + cr_g + cb_g; + B = L + cb_b; + + t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); + row3[0] = t; + row3++; + row4[0] = t; + row4++; + + L = L_tab[(int) *lum2++]; + R = L + cr_r; + G = L + cr_g + cb_g; + B = L + cb_b; + + t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); + row3[0] = t; + row3++; + row4[0] = t; + row4++; + } + lum += cols_2 + cols_2; + lum2 += cols_2 + cols_2; + row1 += 6 * cols_2 + 2*mod; + row3 += 6 * cols_2 + 2*mod; + row2 += 6 * cols_2 + 2*mod; + row4 += 6 * cols_2 + 2*mod; + } +} diff --git a/mpeglib/lib/util/render/dither/dither16Bit.h b/mpeglib/lib/util/render/dither/dither16Bit.h new file mode 100644 index 00000000..2e47c01c --- /dev/null +++ b/mpeglib/lib/util/render/dither/dither16Bit.h @@ -0,0 +1,55 @@ +/* + dither 16 bit depth yuv images + 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 + + */ + +#ifndef __DITHER16Bit_H +#define __DITHER16Bit_H + +#include "colorTableHighBit.h" + +class Dither16Bit { + + ColorTableHighBit* colorTableHighBit; + + TABTYPE *L_tab; + TABTYPE *Cr_r_tab; + TABTYPE *Cr_g_tab; + TABTYPE *Cb_g_tab; + TABTYPE *Cb_b_tab; + + PIXVAL *r_2_pix; + PIXVAL *g_2_pix; + PIXVAL *b_2_pix; + + public: + Dither16Bit(unsigned int redMask, + unsigned int greenMask,unsigned int blueMask); + ~Dither16Bit(); + + void ditherImageColor16(unsigned char* lum, + unsigned char* cr, + unsigned char* cb, + unsigned char* out, + int rows, + int cols, + int offset); + + void ditherImageTwox2Color16(unsigned char* lum, + unsigned char* cr, + unsigned char* cb, + unsigned char* out, + int rows, + int cols, + int mod); + +}; + +#endif diff --git a/mpeglib/lib/util/render/dither/dither32Bit.cpp b/mpeglib/lib/util/render/dither/dither32Bit.cpp new file mode 100644 index 00000000..61a1d2dc --- /dev/null +++ b/mpeglib/lib/util/render/dither/dither32Bit.cpp @@ -0,0 +1,253 @@ +/* + dither 32 bit depth yuv images + 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 "dither32Bit.h" + + +#define doRow(row,Lum) *row++=(local_r_2_pix[Lum] | \ + local_g_2_pix[Lum] | local_b_2_pix[Lum]) + + +Dither32Bit::Dither32Bit(unsigned int redMask, + unsigned int greenMask,unsigned int blueMask) { + + + colorTableHighBit=new ColorTableHighBit(32,redMask,greenMask,blueMask); + L_tab=colorTableHighBit->getL_tab(); + Cr_r_tab=colorTableHighBit->getCr_r_tab(); + Cr_g_tab=colorTableHighBit->getCr_g_tab(); + Cb_g_tab=colorTableHighBit->getCb_g_tab(); + Cb_b_tab=colorTableHighBit->getCb_b_tab(); + + r_2_pix=colorTableHighBit->getr_2_pix(); + g_2_pix=colorTableHighBit->getg_2_pix(); + b_2_pix=colorTableHighBit->getb_2_pix(); + +} + + +Dither32Bit::~Dither32Bit() { + delete colorTableHighBit; +} + + +void Dither32Bit::ditherImageColor32(unsigned char* lum, + unsigned char* cr, + unsigned char* cb, + unsigned char* out, + int rows, + int cols, + int mod) { + + int L; + int n; + int rowWork; + int colWork; + + unsigned int *row1, *row2; + unsigned char *lum2; + PIXVAL* local_r_2_pix; + PIXVAL* local_g_2_pix; + PIXVAL* local_b_2_pix; + + row1 = (unsigned int *)out; + + row2 = row1+cols+mod; + lum2 = lum+cols; + + // because the width/height are a multiply of a macroblocksize + // cols/rows always are even + colWork=cols>>1; + rowWork=rows>>1; + mod=cols+2*mod; + + while(rowWork--) { + n=colWork; + while(n--) { + + local_r_2_pix=r_2_pix+Cr_r_tab[*cr]; + local_g_2_pix=g_2_pix+Cr_g_tab[*cr++] + Cb_g_tab[*cb]; + local_b_2_pix=b_2_pix+Cb_b_tab[*cb++]; + + L = L_tab[*lum++]; + doRow(row1,L); + + L = L_tab[*lum++]; + doRow(row1,L); + + L = L_tab [*lum2++]; + doRow(row2,L); + + L = L_tab [*lum2++]; + doRow(row2,L); + + + } + row2 += mod; + lum += cols; + lum2 += cols; + row1 += mod; + + } + +} + +/* + *-------------------------------------------------------------- + * + * Twox2Color32 -- + * + * Converts image into 24/32 bit color. + * + * Results: + * None. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +void Dither32Bit::ditherImageTwox2Color32(unsigned char* lum, + unsigned char* cr, + unsigned char* cb, + unsigned char* out, + int rows, + int cols, + int mod) { + int L, CR, CB; + unsigned PIXVAL *row1 = (unsigned PIXVAL *)out; + unsigned PIXVAL *row2 = row1 + cols * ONE_TWO + mod; + unsigned PIXVAL *row3 = row2 + cols * ONE_TWO + mod; + unsigned PIXVAL *row4 = row3 + cols * ONE_TWO + mod; + unsigned char *lum2; + int x, y; + int cr_r; + int cr_g; + int cb_g; + int cb_b; + int cols_2 = cols/2; + int loffset = ONE_TWO * 6 *cols_2 + 4*mod ; + + lum2 = lum + cols_2 + cols_2; + for (y=0; y> 1; + CB = (CB + *cb) >> 1; + cr_r = Cr_r_tab[CR]; + cr_g = Cr_g_tab[CR]; + cb_g = Cb_g_tab[CB]; + cb_b = Cb_b_tab[CB]; + } + // end + /* end INTERPOLATE */ + + L = L_tab[ (int) *lum++]; + + R = L + cr_r; + G = L + cr_g + cb_g; + B = L + cb_b; + + t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); + row1[0] = t; + row2[0] = t; +#ifndef SIXTYFOUR_BIT + row1[1] = t; + row2[1] = t; +#endif + row1 += ONE_TWO; + row2 += ONE_TWO; + + /* + * Now, do second row. + */ + /* INTERPOLATE is now standard */ + // INTERPOLATE + if(y != rows - 2) { + CR = (unsigned int) (CR + *(cr + cols_2 - 1)) >> 1; + CB = (unsigned int) (CB + *(cb + cols_2 - 1)) >> 1; + cr_r = Cr_r_tab[CR]; + cr_g = Cr_g_tab[CR]; + cb_g = Cb_g_tab[CB]; + cb_b = Cb_b_tab[CB]; + } + // end + /* endif */ + L = L_tab[ (int) *lum2++]; + R = L + cr_r; + G = L + cr_g + cb_g; + B = L + cb_b; + + t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); + row3[0] = t; + row4[0] = t; +#ifndef SIXTYFOUR_BIT + row3[1] = t; + row4[1] = t; +#endif + row3 += ONE_TWO; + row4 += ONE_TWO; + + L = L_tab[(int) *lum2++]; + R = L + cr_r; + G = L + cr_g + cb_g; + B = L + cb_b; + + t = (r_2_pix[R] | g_2_pix[G] | b_2_pix[B]); + row3[0] = t; + row4[0] = t; +#ifndef SIXTYFOUR_BIT + row3[1] = t; + row4[1] = t; +#endif + row3 += ONE_TWO; + row4 += ONE_TWO; + } + lum += cols_2 + cols_2; + lum2 += cols_2 + cols_2; + + row1 += loffset; + row3 += loffset; + row2 += loffset; + row4 += loffset; + } +} diff --git a/mpeglib/lib/util/render/dither/dither32Bit.h b/mpeglib/lib/util/render/dither/dither32Bit.h new file mode 100644 index 00000000..440d021a --- /dev/null +++ b/mpeglib/lib/util/render/dither/dither32Bit.h @@ -0,0 +1,55 @@ +/* + dither 32 bit depth yuv images + 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 + + */ + +#ifndef __DITHER32Bit_H +#define __DITHER32Bit_H + +#include "colorTableHighBit.h" + +class Dither32Bit { + + ColorTableHighBit* colorTableHighBit; + + TABTYPE *L_tab; + TABTYPE *Cr_r_tab; + TABTYPE *Cr_g_tab; + TABTYPE *Cb_g_tab; + TABTYPE *Cb_b_tab; + + PIXVAL *r_2_pix; + PIXVAL *g_2_pix; + PIXVAL *b_2_pix; + + public: + Dither32Bit(unsigned int redMask, + unsigned int greenMask,unsigned int blueMask); + ~Dither32Bit(); + + void ditherImageColor32(unsigned char* lum, + unsigned char* cr, + unsigned char* cb, + unsigned char* out, + int rows, + int cols, + int offset); + + void ditherImageTwox2Color32(unsigned char* lum, + unsigned char* cr, + unsigned char* cb, + unsigned char* out, + int rows, + int cols, + int mod); + +}; + +#endif diff --git a/mpeglib/lib/util/render/dither/dither32mmx.cpp b/mpeglib/lib/util/render/dither/dither32mmx.cpp new file mode 100644 index 00000000..b5fa4807 --- /dev/null +++ b/mpeglib/lib/util/render/dither/dither32mmx.cpp @@ -0,0 +1,272 @@ +/* + MMX ditherer for 32 bit displays + 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 "ditherMMX.h" + +#include + +using namespace std; + + +#ifndef INTEL + void dither32_mmx(unsigned char* lum, + unsigned char* cr, + unsigned char* cb, + unsigned char* out, + int rows, + int cols, + int mod) { + printf("urgs! dither32_mmx \n"); + printf("never should happen!\n"); + exit(0); +} + +#else + + +static unsigned long MMX32_80w[] = {0x00800080, 0x00800080}; +static unsigned long MMX32_10w[] = {0x00100010, 0x00100010}; +static unsigned long MMX32_00FFw[] = {0x00ff00ff, 0x00ff00ff}; +static unsigned long MMX32_FF00w[] = {0xff00ff00, 0xff00ff00}; +static unsigned short MMX32_Ycoeff[] = {0x4a, 0x4a, 0x4a, 0x4a}; +static unsigned short MMX32_Vredcoeff[] = {0x59, 0x59, 0x59, 0x59}; +static unsigned short MMX32_Ubluecoeff[] = {0x72, 0x72, 0x72, 0x72}; +static unsigned short MMX32_Ugrncoeff[] = {0xffea,0xffea,0xffea,0xffea}; +static unsigned short MMX32_Vgrncoeff[] = {0xffd2,0xffd2,0xffd2,0xffd2}; + +void dummy_dithermmx32() { + cout << "MMX32_10w:"<register + "movd (%2),%%mm3\n" // 0 0 0 0 L3 L2 L1 L0 + "movl 16%5,%2\n" // tmp0->register + "punpckldq %%mm3,%%mm2\n" // L3 L2 L1 L0 l3 l2 l1 l0 + "movq %%mm2,%%mm4\n" // L3 L2 L1 L0 l3 l2 l1 l0 + "pand MMX32_FF00w, %%mm2\n" // L3 0 L1 0 l3 0 l1 0 + "pand MMX32_00FFw, %%mm4\n" // 0 L2 0 L0 0 l2 0 l0 + "psrlw $8,%%mm2\n" // 0 L3 0 L1 0 l3 0 l1 + + + + // create R (result in mm6) + "movq %%mm2,%%mm5\n" // 0 L3 0 L1 0 l3 0 l1 + "movq %%mm4,%%mm6\n" // 0 L2 0 L0 0 l2 0 l0 + "paddsw %%mm1, %%mm5\n" // lum1+red:x R3 x R1 x r3 x r1 + "paddsw %%mm1, %%mm6\n" // lum1+red:x R2 x R0 x r2 x r0 + "packuswb %%mm5,%%mm5\n" // R3 R1 r3 r1 R3 R1 r3 r1 + "packuswb %%mm6,%%mm6\n" // R2 R0 r2 r0 R2 R0 r2 r0 + "pxor %%mm7,%%mm7\n" // 00 00 00 00 00 00 00 00 + "punpcklbw %%mm5,%%mm6\n" // R3 R2 R1 R0 r3 r2 r1 r0 + + + // create Cb (result in mm1) + "movd (%1), %%mm1\n" // 0 0 0 0 u3 u2 u1 u0 + "punpcklbw %%mm7,%%mm1\n" // 0 u3 0 u2 00 u1 00 u0 + "punpckldq %%mm1,%%mm1\n" // 00 u1 00 u0 00 u1 00 u0 + "psubw MMX32_80w,%%mm1\n" // mm1-128:u1 u1 u0 u0 u1 u1 u0 u0 + // create Cb_g (result in mm5) + "movq %%mm1,%%mm5\n" // u1 u1 u0 u0 u1 u1 u0 u0 + "pmullw MMX32_Ugrncoeff,%%mm5\n" // blue*-109dec=1.7129*64 + "pmullw MMX32_Ubluecoeff,%%mm1\n" // blue*114dec=1.78125*64 + "psraw $6, %%mm5\n" // blue=red/64 + "psraw $6, %%mm1\n" // blue=blue/64 + + + // create G (result in mm7) + "movq %%mm2,%%mm3\n" // 0 L3 0 L1 0 l3 0 l1 + "movq %%mm4,%%mm7\n" // 0 L2 0 L0 0 l2 0 l1 + "paddsw %%mm5, %%mm3\n" // lum1+Cb_g:x G3t x G1t x g3t x g1t + "paddsw %%mm5, %%mm7\n" // lum1+Cb_g:x G2t x G0t x g2t x g0t + "paddsw %%mm0, %%mm3\n" // lum1+Cr_g:x G3 x G1 x g3 x g1 + "paddsw %%mm0, %%mm7\n" // lum1+blue:x G2 x G0 x g2 x g0 + "packuswb %%mm3,%%mm3\n" // G3 G1 g3 g1 G3 G1 g3 g1 + "packuswb %%mm7,%%mm7\n" // G2 G0 g2 g0 G2 G0 g2 g0 + "punpcklbw %%mm3,%%mm7\n" // G3 G2 G1 G0 g3 g2 g1 g0 + + + // create B (result in mm5) + "movq %%mm2,%%mm3\n" // 0 L3 0 L1 0 l3 0 l1 + "movq %%mm4,%%mm5\n" // 0 L2 0 L0 0 l2 0 l1 + "paddsw %%mm1, %%mm3\n" // lum1+blue:x B3 x B1 x b3 x b1 + "paddsw %%mm1, %%mm5\n" // lum1+blue:x B2 x B0 x b2 x b0 + "packuswb %%mm3,%%mm3\n" // B3 B1 b3 b1 B3 B1 b3 b1 + "packuswb %%mm5,%%mm5\n" // B2 B0 b2 b0 B2 B0 b2 b0 + "punpcklbw %%mm3,%%mm5\n" // B3 B2 B1 B0 b3 b2 b1 b0 + + + // fill destination row1 (needed are mm6=Rr,mm7=Gg,mm5=Bb) + + "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 + "pxor %%mm4,%%mm4\n" // 0 0 0 0 0 0 0 0 + "movq %%mm6,%%mm1\n" // R3 R2 R1 R0 r3 r2 r1 r0 + "movq %%mm5,%%mm3\n" // B3 B2 B1 B0 b3 b2 b1 b0 + // process lower lum + "punpcklbw %%mm4,%%mm1\n" // 0 r3 0 r2 0 r1 0 r0 + "punpcklbw %%mm4,%%mm3\n" // 0 b3 0 b2 0 b1 0 b0 + "movq %%mm1,%%mm2\n" // 0 r3 0 r2 0 r1 0 r0 + "movq %%mm3,%%mm0\n" // 0 b3 0 b2 0 b1 0 b0 + "punpcklwd %%mm1,%%mm3\n" // 0 r1 0 b1 0 r0 0 b0 + "punpckhwd %%mm2,%%mm0\n" // 0 r3 0 b3 0 r2 0 b2 + + "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 + "movq %%mm7,%%mm1\n" // G3 G2 G1 G0 g3 g2 g1 g0 + "punpcklbw %%mm1,%%mm2\n" // g3 0 g2 0 g1 0 g0 0 + "punpcklwd %%mm4,%%mm2\n" // 0 0 g1 0 0 0 g0 0 + "por %%mm3, %%mm2\n" // 0 r1 g1 b1 0 r0 g0 b0 + "movq %%mm2,(%3)\n" // wrote out ! row1 + + "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 + "punpcklbw %%mm1,%%mm4\n" // g3 0 g2 0 g1 0 g0 0 + "punpckhwd %%mm2,%%mm4\n" // 0 0 g3 0 0 0 g2 0 + "por %%mm0, %%mm4\n" // 0 r3 g3 b3 0 r2 g2 b2 + "movq %%mm4,8(%3)\n" // wrote out ! row1 + + // fill destination row2 (needed are mm6=Rr,mm7=Gg,mm5=Bb) + // this can be done "destructive" + "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 + "punpckhbw %%mm2,%%mm6\n" // 0 R3 0 R2 0 R1 0 R0 + "punpckhbw %%mm1,%%mm5\n" // G3 B3 G2 B2 G1 B1 G0 B0 + "movq %%mm5,%%mm1\n" // G3 B3 G2 B2 G1 B1 G0 B0 + "punpcklwd %%mm6,%%mm1\n" // 0 R1 G1 B1 0 R0 G0 B0 + "movq %%mm1,(%4)\n" // wrote out ! row2 + "punpckhwd %%mm6,%%mm5\n" // 0 R3 G3 B3 0 R2 G2 B2 + "movq %%mm5,8(%4)\n" // wrote out ! row2 + + "addl $4,%2\n" // lum+4 + "addl $4,%5\n" // lum2+4 + "leal 16(%3),%3\n" // row1+16 + "leal 16(%4),%4\n" // row2+16 + "addl $2, %0\n" // cr+2 + "addl $2, %1\n" // cb+2 + + "subl $4,8%5\n" // x+4 x is buf[2] + "cmpl $0,8%5\n" + + "jne 1b\n" + "addl 20%5, %2\n" // lum += cols + "movl %2,16%5\n" // store register in tmp0 + "movl 20%5,%2\n" // cols->register + + "addl %2, %5\n" // lum2 += cols + "addl 12%5, %3\n" // row1+= mod is buf[0] + "addl 12%5, %4\n" // row2+= mod is buf[0] + + "movl %2, 8%5\n" // x=cols + "movl 16%5,%2\n" // store tmp0 in register + + "cmpl 4%5, %2\n" // buf[1] is end + "jl 1b\n" + "emms\n" + : + : "r" (cr), "r"(cb),"r"(lum), + "r"(row1),"r"(row2),"m"(buf[0]) + ); + + + +} + + +#endif diff --git a/mpeglib/lib/util/render/dither/dither8Bit.cpp b/mpeglib/lib/util/render/dither/dither8Bit.cpp new file mode 100644 index 00000000..4f85d3fb --- /dev/null +++ b/mpeglib/lib/util/render/dither/dither8Bit.cpp @@ -0,0 +1,306 @@ +/* + dither 8 bit depth yuv images + 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 "dither8Bit.h" + + +Dither8Bit::Dither8Bit(unsigned char pixel[256]) { + + int i; + for(i=0;i<256;i++) { + this->pixel[i]=pixel[i]; + } + colorTable8Bit=new ColorTable8Bit(); + + lum_values = colorTable8Bit->getLumValues(); + cr_values = colorTable8Bit->getCrValues(); + cb_values = colorTable8Bit->getCbValues(); + + + + initOrderedDither(); + +} + + +Dither8Bit::~Dither8Bit() { + int i; + for (i=0; i threshval) { + *lmark++ = ((j+1) * (CR_RANGE * CB_RANGE)); + } + else { + *lmark++ = (j * (CR_RANGE * CB_RANGE)); + } + } + } + for (j=lum_values[LUM_RANGE-1]; j<256; j++) { + *lmark++ = (LUM_RANGE-1)*(CR_RANGE * CB_RANGE); + } + } + for (i=0; i threshval) { + *cmark++ = ((j+1) * CB_RANGE); + } + else { + *cmark++ = (j * CB_RANGE); + } + } + } + + for (j=cr_values[CR_RANGE-1]; j<256; j++) { + *cmark++ = (CR_RANGE-1)*(CB_RANGE); + } + } + + for (i=0; i threshval) { + *cmark++ = j+1; + } + else { + *cmark++ = j; + } + } + } + + for (j=cb_values[CB_RANGE-1]; j<256; j++) { + *cmark++ = CB_RANGE-1; + } + } +} + + + +/* + *-------------------------------------------------------------- + * + * OrderedDitherImage -- + * + * Dithers an image using an ordered dither. + * Assumptions made: + * 1) The color space is allocated y:cr:cb = 8:4:4 + * 2) The spatial resolution of y:cr:cb is 4:1:1 + * The channels are dithered based on the standard + * ordered dither pattern for a 4x4 area. + * + * Results: + * None. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + +void Dither8Bit::ditherImageOrdered (unsigned char* lum, + unsigned char* cr, + unsigned char* cb, + unsigned char* out, + int h, + int w) { + unsigned char *l, *r, *b, *o1, *o2; + unsigned char *l2; + unsigned char L, R, B; + int i, j; + + l = lum; + l2 = lum+w; + r = cr; + b = cb; + o1 = out; + o2 = out+w; + + + for (i=0; i +#include +#include +} + + +#ifdef __GNUC__ +#if (__GNUC__ < 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ < 91 ) ) +#ifndef _AIX +#warning "inline code disabled! (buggy egcs version)" +#undef __NO_MATH_INLINES +#define __NO_MATH_INLINES 1 +#endif +#endif +#endif +#include + + + +/* Gamma correction stuff */ +extern int gammaCorrectFlag; +extern double gammaCorrect; + +/* Chroma correction stuff */ +extern int chromaCorrectFlag; +extern double chromaCorrect; + + +#define CB_BASE 1 +#define CR_BASE (CB_BASE*CB_RANGE) +#define LUM_BASE (CR_BASE*CR_RANGE) + +#define TABTYPE short + +#ifdef SIXTYFOUR_BIT +#define PIXVAL long +#else +#define PIXVAL int +#endif + +#ifdef SIXTYFOUR_BIT +#define ONE_TWO 1 +#else +#define ONE_TWO 2 +#endif + + + +#define Min(x,y) (((x) < (y)) ? (x) : (y)) +#define Max(x,y) (((x) > (y)) ? (x) : (y)) + +#define CHROMA_CORRECTION128(x) ((x) >= 0 \ + ? Min(127, (int)(((x) * chromaCorrect))) \ + : Max(-128, (int)(((x) * chromaCorrect)))) +#define CHROMA_CORRECTION256D(x) ((x) >= 128 \ + ? 128.0 + Min(127.0, (((x)-128.0) * chromaCorrect)) \ + : 128.0 - Min(128.0, (((128.0-(x))* chromaCorrect)))) + + + +#define GAMMA_CORRECTION(x) ((int)(pow((x) / 255.0, 1.0/gammaCorrect)* 255.0)) + +#define CHROMA_CORRECTION128D(x) ((x) >= 0 \ + ? Min(127.0, ((x) * chromaCorrect)) \ + : Max(-128.0, ((x) * chromaCorrect))) + +#define CHROMA_CORRECTION256(x) ((x) >= 128 \ + ? 128 + Min(127, (int)(((x)-128.0) * chromaCorrect)) \ + : 128 - Min(128, (int)((128.0-(x)) * chromaCorrect))) + +// Range values for lum, cr, cb. +#define LUM_RANGE 8 +#define CR_RANGE 4 +#define CB_RANGE 4 + + +#endif diff --git a/mpeglib/lib/util/render/dither/ditherMMX.h b/mpeglib/lib/util/render/dither/ditherMMX.h new file mode 100644 index 00000000..2f08b689 --- /dev/null +++ b/mpeglib/lib/util/render/dither/ditherMMX.h @@ -0,0 +1,38 @@ +/* + mmx ditherer + 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 + + */ + + +#ifndef __DITHERMMX_H +#define __DITHERMMX_H + +#include "ditherDef.h" + + +// The mmx dither routine come from NIST +// NIST is an mpeg2/dvd player +// more: http://home.germany.net/100-5083/ +extern void ditherBlock(unsigned char *lum, + unsigned char *cr, + unsigned char *cb, + unsigned char *out, + int rows, int cols, int mod); + +extern void dither32_mmx(unsigned char* lum, + unsigned char* cr, + unsigned char* cb, + unsigned char* out, + int rows, + int cols, + int mod); + + +#endif diff --git a/mpeglib/lib/util/render/dither/ditherRGB.cpp b/mpeglib/lib/util/render/dither/ditherRGB.cpp new file mode 100644 index 00000000..1bcdb2ff --- /dev/null +++ b/mpeglib/lib/util/render/dither/ditherRGB.cpp @@ -0,0 +1,230 @@ +/* + copys RGB images to a destination + 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 "ditherRGB.h" + +#include + +using namespace std; + +DitherRGB::DitherRGB() { +} + + +DitherRGB::~DitherRGB() { +} + + +int DitherRGB::getDepth(int pixel) { + int byteDepth=0; + + switch(pixel) { + case 8: + byteDepth=1; + break; + case 15: + case 16: + byteDepth=2; + break; + case 24: + case 32: + byteDepth=4; + break; + default: + cout << "unknown byteDepth:"< + +using namespace std; + + +DitherRGB_flipped::DitherRGB_flipped() { + flipSpace=NULL; + flipSize=0; +} + +DitherRGB_flipped::~DitherRGB_flipped() { + if (flipSpace != NULL) { + delete flipSpace; + } +} + + + + +void DitherRGB_flipped::flipRGBImage(unsigned char* dest,unsigned char* src, + int depth,int width,int height,int ) { + + int byteDepth; + + switch(depth) { + case 8: + byteDepth=1; + break; + case 15: + case 16: + byteDepth=2; + break; + case 24: + case 32: + byteDepth=4; + break; + default: + cout << "unknown byteDepth:"< flipSize) { + if (flipSpace != NULL) { + delete flipSpace; + } + cout << "flipSpace:"< + +using namespace std; + + +/* + Flag for gamma correction + Makes images brighter/darker. + It's in the source but not activated (for now) +*/ +int gammaCorrectFlag = 0; +double gammaCorrect = 1.0; + +/* + Flag for chroma correction. + reduce the color intensity.. + It's in the source but not activated (for now) +*/ +int chromaCorrectFlag = 0; +double chromaCorrect = 1.0; + + + +DitherWrapper::DitherWrapper(int bpp,unsigned int redMask, + unsigned int greenMask,unsigned int blueMask, + unsigned char pixel[256]) { + + this->bpp=bpp; + this->redMask=redMask; + this->greenMask=greenMask; + this->blueMask=blueMask; + + + dither8Bit=new Dither8Bit(pixel); + dither16Bit=new Dither16Bit(redMask,greenMask,blueMask); + dither32Bit=new Dither32Bit(redMask,greenMask,blueMask); + ditherRGB_flipped=new DitherRGB_flipped(); + ditherRGB=new DitherRGB(); + + +#ifdef INTEL + lmmx=mm_support(); +#else + lmmx=false; +#endif + + +} + + +DitherWrapper::~DitherWrapper(){ + delete dither16Bit; + delete dither8Bit; + delete dither32Bit; + delete ditherRGB_flipped; + delete ditherRGB; +} + + + + + +void DitherWrapper::doDither(YUVPicture* pic,int depth,int imageMode, + unsigned char* dest,int offset) { + + + // + // according to the input imageType and the output area + // handle different dither methods + // + + int inputType=pic->getImageType(); + + if ( (inputType == PICTURE_YUVMODE_CR_CB) || + (inputType == PICTURE_YUVMODE_CB_CR) ) { + doDitherYUV(pic,depth,imageMode,dest,offset); + return; + } + + if ( (inputType == PICTURE_RGB) || + (inputType == PICTURE_RGB_FLIPPED) ){ + doDitherRGB(pic,depth,imageMode,dest,offset); + return; + } + + cout << "unknown inputType:"<getImageType(); + + switch(inputType) { + case PICTURE_RGB: + doDitherRGB_NORMAL(pic,depth,imageMode,dest,offset); + break; + case PICTURE_RGB_FLIPPED: + doDitherRGB_FLIPPED(pic,depth,imageMode,dest,offset); + break; + default: + cout << "unknown RGB type:"<getWidth(); + int h=pic->getHeight(); + + unsigned char* src=pic->getImagePtr(); + + if (imageMode & _IMAGE_DOUBLE) { + ditherRGB->ditherRGBImage_x2(dest,src,depth,w,h,offset); + } else { + ditherRGB->ditherRGBImage(dest,src,depth,w,h,offset); + } +} + +void DitherWrapper::doDitherRGB_FLIPPED(YUVPicture* pic, + int depth,int imageMode, + unsigned char* dest,int offset) { + + int w=pic->getWidth(); + int h=pic->getHeight(); + + unsigned char* src=pic->getImagePtr(); + + ditherRGB_flipped->flipRGBImage(dest,src,depth,w,h,offset); +} + + + +void DitherWrapper::doDitherYUV(YUVPicture* pic,int depth,int imageMode, + unsigned char* dest,int offset) { + + if (imageMode & _IMAGE_DOUBLE) { + doDither_x2(pic,depth,dest,offset); + } else { + doDither_std(pic,depth,dest,offset); + } +} + + +void DitherWrapper::doDither_std(YUVPicture* pic,int depth, + unsigned char* dest,int offset){ + + int h=pic->getHeight(); + int w=pic->getWidth(); + unsigned char* lum=pic->getLuminancePtr(); + unsigned char* cr=pic->getCrPtr(); + unsigned char* cb=pic->getCbPtr(); + + + switch (depth) { + case 8: + dither8Bit->ditherImageOrdered(lum, cr, cb,dest , h, w); + break; + case 16: + if (lmmx) { + ditherBlock(lum,cr,cb,dest,h,w,offset); + } else { + dither16Bit->ditherImageColor16(lum,cr,cb,dest,h,w,offset); + } + + break; + case 24: + case 32: + if (lmmx) { + dither32_mmx(lum, cr, cb,dest ,h,w,offset); + } else { + dither32Bit->ditherImageColor32(lum, cr, cb,dest ,h,w,offset); + } + + + break; + default: + cout << "cannot dither depth:"<getHeight(); + int w=pic->getWidth(); + unsigned char* lum=pic->getLuminancePtr(); + unsigned char* cr=pic->getCrPtr(); + unsigned char* cb=pic->getCbPtr(); + + + switch (depth) { + case 8: { + // we do dither with the 8Bit std YUV ditherer to RGB + // and then we do the double part with the + // RGB ditherer. Its obviously much slower but at + // least it works. To not allocate memory twice + // we are a bit tricky. We know that the image + // has space for doubls size. We but the not double size + // image at the bottom of the dest. Maybe that + // the last line gets overwritten + int memPos=3*h*w; + dither8Bit->ditherImageOrdered(lum, cr, cb,dest+memPos, h, w); + unsigned char* src=dest+memPos; + ditherRGB->ditherRGBImage_x2(dest,src,depth,w,h,0); + break; + } + case 16: + dither16Bit->ditherImageTwox2Color16(lum,cr,cb,dest,h,w,offset); + break; + case 24: + case 32: + if (lmmx) { + //dither32x2_mmx(lum, cr, cb,dest ,h,w,offset); + dither32Bit->ditherImageTwox2Color32(lum,cr,cb,dest,h,w,offset); + } else { + dither32Bit->ditherImageTwox2Color32(lum,cr,cb,dest,h,w,offset); + } + break; + default: + cout << "cannot dither depth:" << depth << endl; + } +} diff --git a/mpeglib/lib/util/render/dither/ditherWrapper.h b/mpeglib/lib/util/render/dither/ditherWrapper.h new file mode 100644 index 00000000..b01abff8 --- /dev/null +++ b/mpeglib/lib/util/render/dither/ditherWrapper.h @@ -0,0 +1,80 @@ +/* + wrapper for X11 Window + Copyright (C) 1999 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 + + */ + + +#ifndef __DITHERWRAPPER_H +#define __DITHERWRAPPER_H + + +#include "../../mmx/mmx.h" + +#include "../yuvPicture.h" +#include "../imageBase.h" +#include +#include "ditherMMX.h" +#include "dither8Bit.h" +#include "dither16Bit.h" +#include "dither32Bit.h" +#include "ditherRGB_flipped.h" +#include "ditherRGB.h" + + +/** + Wraps all calls to software ditherer and the different + resolutions,mmx enhancements, and doublesize ditherers. +*/ + + +class DitherWrapper { + + int lmmx; + + int bpp; + // colorMask + unsigned int redMask; + unsigned int greenMask; + unsigned int blueMask; + + Dither8Bit* dither8Bit; + Dither16Bit* dither16Bit; + Dither32Bit* dither32Bit; + DitherRGB_flipped* ditherRGB_flipped; + DitherRGB* ditherRGB; + + public: + DitherWrapper(int bpp,unsigned int redMask, + unsigned int greenMask,unsigned int blueMask, + unsigned char pixel[256]); + ~DitherWrapper(); + +/* int getDitherSize(); */ +/* void setDitherSize(int ditherMode); */ + + void doDither(YUVPicture* pic,int depth,int imageMode, + unsigned char* dest,int offset); + + + private: + void doDitherYUV(YUVPicture* pic,int depth,int imageMode, + unsigned char* dest,int offset); + void doDitherRGB(YUVPicture* pic,int depth,int imageMode, + unsigned char* dest,int offset); + void doDitherRGB_NORMAL(YUVPicture* pic,int depth,int imageMode, + unsigned char* dest,int offset); + void doDitherRGB_FLIPPED(YUVPicture* pic,int depth,int imageMode, + unsigned char* dest,int offset); + + void doDither_std(YUVPicture* pic,int depth,unsigned char* dest,int offset); + void doDither_x2(YUVPicture* pic,int depth,unsigned char* dest,int offset); +}; + +#endif diff --git a/mpeglib/lib/util/render/dither/ditherer_mmx16.cpp b/mpeglib/lib/util/render/dither/ditherer_mmx16.cpp new file mode 100644 index 00000000..757f0676 --- /dev/null +++ b/mpeglib/lib/util/render/dither/ditherer_mmx16.cpp @@ -0,0 +1,256 @@ + +#include "ditherMMX.h" + +#include + +using namespace std; + +#ifndef INTEL +// nothing +void ditherBlock(unsigned char *lum, unsigned char *cr, unsigned char *cb, + unsigned char *out, + int cols, int rows, int screen_width) { + printf("call to ditherBlock. this should never happen\n"); + printf("check mmx detection routine.\n"); + exit(0); +} +#else + + +static long long MMX16_0 = 0L; +static unsigned long MMX16_10w[] = {0x00100010, 0x00100010}; +static unsigned long MMX16_80w[] = {0x00800080, 0x00800080}; +static unsigned long MMX16_00FFw[] = {0x00ff00ff, 0x00ff00ff}; +static unsigned short MMX16_Ublucoeff[] = {0x81, 0x81, 0x81, 0x81}; +static unsigned short MMX16_Vredcoeff[] = {0x66, 0x66, 0x66, 0x66}; +static unsigned short MMX16_Ugrncoeff[] = {0xffe8, 0xffe8, 0xffe8, 0xffe8}; +static unsigned short MMX16_Vgrncoeff[] = {0xffcd, 0xffcd, 0xffcd, 0xffcd}; +static unsigned short MMX16_Ycoeff[] = {0x4a, 0x4a, 0x4a, 0x4a}; +static unsigned short MMX16_redmask[] = {0xf800, 0xf800, 0xf800, 0xf800}; +static unsigned short MMX16_grnmask[] = {0x7e0, 0x7e0, 0x7e0, 0x7e0}; + +void dummy_dithermmx16() { + cout << "MMX16_0"<register + "movq (%2),%%mm6\n" // 0 0 0 0 L3 L2 L1 L0 (load lum2) + + + //"movq (%2, %5), %%mm6\n" // L3 load lum2 + "psraw $6, %%mm7\n" + "packuswb %%mm3, %%mm3\n" + "packuswb %%mm5, %%mm5\n" + "packuswb %%mm7, %%mm7\n" + "pand MMX16_00FFw, %%mm6\n" // L3 + "punpcklbw %%mm3, %%mm3\n" + // "psubw MMX16_10w, %%mm6\n" // L3 + "punpcklbw %%mm5, %%mm5\n" + "pmullw MMX16_Ycoeff, %%mm6\n" // lum3 + "punpcklbw %%mm7, %%mm7\n" + "psllw $3, %%mm5\n" // GREEN 2 + "pand MMX16_redmask, %%mm7\n" + "pand MMX16_redmask, %%mm3\n" + "psrlw $11, %%mm7\n" // BLUE 2 + "pand MMX16_grnmask, %%mm5\n" + "por %%mm7, %%mm3\n" + + "movq (%2), %%mm7\n" // L4 load lum2 + "movl 16%5,%2\n" // tmp0->register + + "por %%mm5, %%mm3\n" // + "psrlw $8, %%mm7\n" // L4 + "movq %%mm4, %%mm5\n" + // "psubw MMX16_10w, %%mm7\n" // L4 + "punpcklwd %%mm3, %%mm4\n" + "pmullw MMX16_Ycoeff, %%mm7\n" // lum4 + "punpckhwd %%mm3, %%mm5\n" + + "movq %%mm4, (%3)\n" // write row1 + "movq %%mm5, 8(%3)\n" // write row1 + + "movq %%mm6, %%mm4\n" // Lum3 + "paddw %%mm0, %%mm6\n" // Lum3 +blue + + "movq %%mm4, %%mm5\n" // Lum3 + "paddw %%mm1, %%mm4\n" // Lum3 +red + "paddw %%mm2, %%mm5\n" // Lum3 +green + "psraw $6, %%mm4\n" + "movq %%mm7, %%mm3\n" // Lum4 + "psraw $6, %%mm5\n" + "paddw %%mm0, %%mm7\n" // Lum4 +blue + "psraw $6, %%mm6\n" // Lum3 +blue + "movq %%mm3, %%mm0\n" // Lum4 + "packuswb %%mm4, %%mm4\n" + "paddw %%mm1, %%mm3\n" // Lum4 +red + "packuswb %%mm5, %%mm5\n" + "paddw %%mm2, %%mm0\n" // Lum4 +green + "packuswb %%mm6, %%mm6\n" + "punpcklbw %%mm4, %%mm4\n" + "punpcklbw %%mm5, %%mm5\n" + "punpcklbw %%mm6, %%mm6\n" + "psllw $3, %%mm5\n" // GREEN 3 + "pand MMX16_redmask, %%mm4\n" + "psraw $6, %%mm3\n" // psr 6 + "psraw $6, %%mm0\n" + "pand MMX16_redmask, %%mm6\n" // BLUE + "pand MMX16_grnmask, %%mm5\n" + "psrlw $11, %%mm6\n" // BLUE 3 + "por %%mm5, %%mm4\n" + "psraw $6, %%mm7\n" + "por %%mm6, %%mm4\n" + "packuswb %%mm3, %%mm3\n" + "packuswb %%mm0, %%mm0\n" + "packuswb %%mm7, %%mm7\n" + "punpcklbw %%mm3, %%mm3\n" + "punpcklbw %%mm0, %%mm0\n" + "punpcklbw %%mm7, %%mm7\n" + "pand MMX16_redmask, %%mm3\n" + "pand MMX16_redmask, %%mm7\n" // BLUE + "psllw $3, %%mm0\n" // GREEN 4 + "psrlw $11, %%mm7\n" + "pand MMX16_grnmask, %%mm0\n" + "por %%mm7, %%mm3\n" + "por %%mm0, %%mm3\n" + + "movq %%mm4, %%mm5\n" + + "punpcklwd %%mm3, %%mm4\n" + "punpckhwd %%mm3, %%mm5\n" + + "movq %%mm4, (%4)\n" + "movq %%mm5, 8(%4)\n" + + "subl $8, 8%5\n" // x-=8 + "addl $8, %5\n" // lum2+8 + "addl $8, %2\n" + "addl $4, %0\n" + "addl $4, %1\n" + "cmpl $0, 8%5\n" + "leal 16(%3), %3\n" + "leal 16(%4), %4\n" // row2+16 + + + "jne 1b\n" + "addl 20%5, %2\n" // lum += cols + + "movl %2,16%5\n" // store register in tmp0 + "movl 20%5,%2\n" // cols->register + + "addl %2, %5\n" // lum2 += cols + "addl 12%5, %3\n" // row1+= mod + "addl 12%5, %4\n" // row2+= mod + "movl %2, 8%5\n" // x=cols + "movl 16%5,%2\n" // store tmp0 in register + + "cmpl 4%5, %2\n" + "jl 1b\n" + + : + :"r" (cr), "r"(cb),"r"(lum), + "r"(row1),"r"(row2),"m"(buf[0]) + + ); + __asm__ ( + "emms\n" + ); + + } + +#endif -- cgit v1.2.3