summaryrefslogtreecommitdiffstats
path: root/mpeglib/lib/util/render
diff options
context:
space:
mode:
Diffstat (limited to 'mpeglib/lib/util/render')
-rw-r--r--mpeglib/lib/util/render/Makefile.am59
-rw-r--r--mpeglib/lib/util/render/dither/Makefile.am40
-rw-r--r--mpeglib/lib/util/render/dither/colorTable8Bit.cpp147
-rw-r--r--mpeglib/lib/util/render/dither/colorTable8Bit.h57
-rw-r--r--mpeglib/lib/util/render/dither/colorTableHighBit.cpp248
-rw-r--r--mpeglib/lib/util/render/dither/colorTableHighBit.h73
-rw-r--r--mpeglib/lib/util/render/dither/dither16Bit.cpp300
-rw-r--r--mpeglib/lib/util/render/dither/dither16Bit.h55
-rw-r--r--mpeglib/lib/util/render/dither/dither32Bit.cpp253
-rw-r--r--mpeglib/lib/util/render/dither/dither32Bit.h55
-rw-r--r--mpeglib/lib/util/render/dither/dither32mmx.cpp272
-rw-r--r--mpeglib/lib/util/render/dither/dither8Bit.cpp306
-rw-r--r--mpeglib/lib/util/render/dither/dither8Bit.h63
-rw-r--r--mpeglib/lib/util/render/dither/ditherDef.h100
-rw-r--r--mpeglib/lib/util/render/dither/ditherMMX.h38
-rw-r--r--mpeglib/lib/util/render/dither/ditherRGB.cpp230
-rw-r--r--mpeglib/lib/util/render/dither/ditherRGB.h45
-rw-r--r--mpeglib/lib/util/render/dither/ditherRGB_flipped.cpp82
-rw-r--r--mpeglib/lib/util/render/dither/ditherRGB_flipped.h34
-rw-r--r--mpeglib/lib/util/render/dither/ditherWrapper.cpp246
-rw-r--r--mpeglib/lib/util/render/dither/ditherWrapper.h80
-rw-r--r--mpeglib/lib/util/render/dither/ditherer_mmx16.cpp256
-rw-r--r--mpeglib/lib/util/render/dither2YUV/Makefile.am22
-rw-r--r--mpeglib/lib/util/render/dither2YUV/README13
-rw-r--r--mpeglib/lib/util/render/dither2YUV/dither2YUV.cpp124
-rw-r--r--mpeglib/lib/util/render/dither2YUV/dither2YUV.h64
-rw-r--r--mpeglib/lib/util/render/dither2YUV/rgb2yuv16.cpp916
-rw-r--r--mpeglib/lib/util/render/dither2YUV/rgb2yuv16.h74
-rw-r--r--mpeglib/lib/util/render/dither2YUV/rgb2yuv32.cpp1143
-rw-r--r--mpeglib/lib/util/render/dither2YUV/rgb2yuv32.h93
-rw-r--r--mpeglib/lib/util/render/dither2YUV/rgb2yuvdefs.h74
-rw-r--r--mpeglib/lib/util/render/imageBase.cpp76
-rw-r--r--mpeglib/lib/util/render/imageBase.h140
-rw-r--r--mpeglib/lib/util/render/pictureArray.cpp101
-rw-r--r--mpeglib/lib/util/render/pictureArray.h76
-rw-r--r--mpeglib/lib/util/render/renderMachine.cpp205
-rw-r--r--mpeglib/lib/util/render/renderMachine.h90
-rw-r--r--mpeglib/lib/util/render/sdl/Makefile.am43
-rw-r--r--mpeglib/lib/util/render/sdl/imageDeskSDL.cpp110
-rw-r--r--mpeglib/lib/util/render/sdl/imageDeskSDL.h65
-rw-r--r--mpeglib/lib/util/render/sdl/sdlSurface.cpp219
-rw-r--r--mpeglib/lib/util/render/sdl/sdlSurface.h78
-rw-r--r--mpeglib/lib/util/render/surface.cpp117
-rw-r--r--mpeglib/lib/util/render/surface.h55
-rw-r--r--mpeglib/lib/util/render/x11/Makefile.am48
-rw-r--r--mpeglib/lib/util/render/x11/imageDGAFull.cpp289
-rw-r--r--mpeglib/lib/util/render/x11/imageDGAFull.h131
-rw-r--r--mpeglib/lib/util/render/x11/imageDeskX11.cpp439
-rw-r--r--mpeglib/lib/util/render/x11/imageDeskX11.h85
-rw-r--r--mpeglib/lib/util/render/x11/imageXVDesk.cpp405
-rw-r--r--mpeglib/lib/util/render/x11/imageXVDesk.h88
-rw-r--r--mpeglib/lib/util/render/x11/initDisplay.cpp255
-rw-r--r--mpeglib/lib/util/render/x11/initDisplay.h34
-rw-r--r--mpeglib/lib/util/render/x11/x11Surface.cpp389
-rw-r--r--mpeglib/lib/util/render/x11/x11Surface.h79
-rw-r--r--mpeglib/lib/util/render/x11/xinit.h99
-rw-r--r--mpeglib/lib/util/render/yuvPicture.cpp253
-rw-r--r--mpeglib/lib/util/render/yuvPicture.h110
58 files changed, 9641 insertions, 0 deletions
diff --git a/mpeglib/lib/util/render/Makefile.am b/mpeglib/lib/util/render/Makefile.am
new file mode 100644
index 00000000..24bc691f
--- /dev/null
+++ b/mpeglib/lib/util/render/Makefile.am
@@ -0,0 +1,59 @@
+# player - Makefile.am
+
+SUBDIRS = dither dither2YUV x11 sdl
+
+INCLUDES = $(all_includes)
+
+THIS_EXTRALIBS = dither/libdither.la \
+ dither2YUV/libdivxutil_dither.la \
+ x11/libutilx11.la
+
+
+noinst_LTLIBRARIES = libutilrender.la
+
+noinst_HEADERS = imageBase.h \
+ renderMachine.h surface.h
+
+
+kmpgincludedir = $(includedir)/$(THIS_LIB_NAME)/util/render
+
+kmpginclude_HEADERS = yuvPicture.h pictureArray.h
+
+
+libutilrender_la_SOURCES = yuvPicture.cpp imageBase.cpp \
+ renderMachine.cpp surface.cpp \
+ pictureArray.cpp
+
+libutilrender_la_LIBADD = $(THIS_EXTRALIBS)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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<LUM_RANGE; i++) {
+ lum_values[i] = ((i * 256) / (LUM_RANGE)) + (256/(LUM_RANGE*2));
+ L_tab[i] = lum_values[i];
+ if (gammaCorrectFlag) {
+ L_tab[i] = GAMMA_CORRECTION(L_tab[i]);
+ }
+
+ }
+
+
+ for (i=0; i<CR_RANGE; i++) {
+ register double tmp;
+ if (chromaCorrectFlag) {
+ tmp = ((i * 256) / (CR_RANGE)) + (256/(CR_RANGE*2));
+ Cr_r_tab[i]=(TABTYPE) ((0.419/0.299)*CHROMA_CORRECTION128D(tmp-128.0));
+ Cr_g_tab[i]=(TABTYPE) (-(0.299/0.419)*CHROMA_CORRECTION128D(tmp-128.0));
+ cr_values[i] = CHROMA_CORRECTION256(tmp);
+ } else {
+ tmp = ((i * 256) / (CR_RANGE)) + (256/(CR_RANGE*2));
+ Cr_r_tab[i] = (TABTYPE) ((0.419/0.299) * (tmp - 128.0));
+ Cr_g_tab[i] = (TABTYPE) (-(0.299/0.419) * (tmp - 128.0));
+ cr_values[i] = (int) tmp;
+ }
+ }
+
+
+ for (i=0; i<CB_RANGE; i++) {
+ register double tmp;
+ if (chromaCorrectFlag) {
+ tmp = ((i * 256) / (CB_RANGE)) + (256/(CB_RANGE*2));
+ Cb_g_tab[i]=(TABTYPE) (-(0.114/0.331)*CHROMA_CORRECTION128D(tmp-128.0));
+ Cb_b_tab[i]=(TABTYPE) ((0.587/0.331)*CHROMA_CORRECTION128D(tmp-128.0));
+ cb_values[i] = CHROMA_CORRECTION256(tmp);
+ } else {
+ tmp = ((i * 256) / (CB_RANGE)) + (256/(CB_RANGE*2));
+ Cb_g_tab[i] = (TABTYPE) (-(0.114/0.331) * (tmp - 128.0));
+ Cb_b_tab[i] = (TABTYPE) ((0.587/0.331) * (tmp - 128.0));
+ cb_values[i] = (int) tmp;
+ }
+ }
+}
+
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * ConvertColor --
+ *
+ * Given a l, cr, cb tuple, converts it to r,g,b.
+ *
+ * Results:
+ * r,g,b values returned in pointers passed as parameters.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void ColorTable8Bit::ConvertColor(unsigned int l, unsigned int cr,
+ unsigned int cb, unsigned char* r,
+ unsigned char* g, unsigned char* b) {
+
+ double fl, fr, fg, fb;
+
+ /*
+ * Old method w/o lookup table
+ *
+ * fl = 1.164*(((double) l)-16.0);
+ * fcr = ((double) cr) - 128.0;
+ * fcb = ((double) cb) - 128.0;
+ *
+ * fr = fl + (1.366 * fcr);
+ * fg = fl - (0.700 * fcr) - (0.334 * fcb);
+ * fb = fl + (1.732 * fcb);
+ */
+
+ fl = L_tab[l];
+
+ fr = fl + Cr_r_tab[cr];
+ fg = fl + Cr_g_tab[cr] + Cb_g_tab[cb];
+ fb = fl + Cb_b_tab[cb];
+
+ if (fr < 0.0) fr = 0.0;
+ else if (fr > 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<rows; y+=2) {
+ for (x=0; x<cols_2; x++) {
+ int R, G, B;
+
+ CR = *cr++;
+ CB = *cb++;
+ cr_r = Cr_r_tab[CR];
+ cr_g = Cr_g_tab[CR];
+ cb_g = Cb_g_tab[CB];
+ cb_b = Cb_b_tab[CB];
+
+ 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]);
+
+
+#ifdef INTERPOLATE
+ if(x != cols_2 - 1) {
+ CR = (CR + *cr) >> 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<rows; y+=2) {
+ for (x=0; x<cols_2; x++) {
+ int R, G, B;
+ int t;
+
+ CR = *cr++;
+ CB = *cb++;
+ cr_r = Cr_r_tab[CR];
+ cr_g = Cr_g_tab[CR];
+ cb_g = Cb_g_tab[CB];
+ cb_b = Cb_b_tab[CB];
+
+ 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++;
+
+ // INTERPOLATE
+ if(x != cols_2 - 1) {
+ CR = (CR + *cr) >> 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<rows; y+=2) {
+ for (x=0; x<cols_2; x++) {
+ int R, G, B;
+ PIXVAL t;
+
+ CR = *cr++;
+ CB = *cb++;
+ cr_r = Cr_r_tab[CR];
+ cr_g = Cr_g_tab[CR];
+ cb_g = Cb_g_tab[CB];
+ cb_b = Cb_b_tab[CB];
+
+ 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;
+
+ /* INTERPOLATE is now standard */
+ // INTERPOLATE
+ if(x != cols_2 - 1) {
+ CR = (CR + *cr) >> 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 <iostream>
+
+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:"<<MMX32_10w<<endl;
+ cout << "MMX32_80w:"<<MMX32_80w<<endl;
+ cout << "MMX32_Ubluecoeff:"<<MMX32_Ubluecoeff<<endl;
+ cout << "MMX32_Vredcoeff:"<<MMX32_Vredcoeff<<endl;
+ cout << "MMX32_Ugrncoeff:"<<MMX32_Ugrncoeff<<endl;
+ cout << "MMX32_Vgrncoeff:"<<MMX32_Vgrncoeff<<endl;
+ cout << "MMX32_Ycoeff:"<<MMX32_Ycoeff<<endl;
+ cout << "MMX32_00FFw:"<<MMX32_00FFw<<endl;
+ cout << "MMX32_FF00w:"<<MMX32_FF00w<<endl;
+}
+
+
+/**
+ This MMX assembler is my first assembler/MMX program ever.
+ Thus it maybe buggy.
+ Send patches to:
+ mvogt@rhrk.uni-kl.de
+
+ After it worked fine I have "obfuscated" the code a bit to have
+ more parallism in the MMX units. This means I moved
+ initilisation around and delayed other instruction.
+ Performance measurement did not show that this brought any advantage
+ but in theory it _should_ be faster this way.
+
+ The overall performanve gain to the C based dither was 30%-40%.
+ The MMX routine calculates 256bit=8RGB values in each cycle
+ (4 for row1 & 4 for row2)
+
+ The red/green/blue.. coefficents are taken from the mpeg_play
+ player. They look nice, but I dont know if you can have
+ better values, to avoid integer rounding errors.
+
+
+ IMPORTANT:
+ ==========
+
+ It is a requirement that the cr/cb/lum are 8 byte aligned and
+ the out are 16byte aligned or you will/may get segfaults
+
+*/
+
+void dither32_mmx(unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,
+ unsigned char* out,
+ int rows,
+ int cols,
+ int mod) {
+
+
+
+ unsigned int *row1;
+ unsigned int *row2;
+ row1 = (unsigned int *)out; // 32 bit target
+
+ unsigned char* end = lum +cols*rows; // Pointer to the end
+ int x=cols;
+ row2=row1+cols+mod; // start of second row
+ mod=4*cols+8*mod; // increment for row1 in byte
+
+ // buffer for asm function
+ int buf[6];
+ buf[0]=(int)(lum+cols); // lum2 pointer
+ buf[1]=(int)end;
+ buf[2]=x;
+ buf[3]=mod;
+ buf[4]=0; //tmp0;
+ buf[5]=cols;
+
+
+ __asm__ __volatile__ (
+ ".align 32\n"
+ "1:\n"
+
+ // create Cr (result in mm1)
+ "movd (%0), %%mm1\n" // 0 0 0 0 v3 v2 v1 v0
+ "pxor %%mm7,%%mm7\n" // 00 00 00 00 00 00 00 00
+ "movd (%2), %%mm2\n" // 0 0 0 0 l3 l2 l1 l0
+ "punpcklbw %%mm7,%%mm1\n" // 0 v3 0 v2 00 v1 00 v0
+ "punpckldq %%mm1,%%mm1\n" // 00 v1 00 v0 00 v1 00 v0
+ "psubw MMX32_80w,%%mm1\n" // mm1-128:r1 r1 r0 r0 r1 r1 r0 r0
+
+ // create Cr_g (result in mm0)
+ "movq %%mm1,%%mm0\n" // r1 r1 r0 r0 r1 r1 r0 r0
+ "pmullw MMX32_Vgrncoeff,%%mm0\n" // red*-46dec=0.7136*64
+ "pmullw MMX32_Vredcoeff,%%mm1\n" // red*89dec=1.4013*64
+ "psraw $6, %%mm0\n" // red=red/64
+ "psraw $6, %%mm1\n" // red=red/64
+
+
+ // create L1 L2 (result in mm2,mm4)
+ // L2=lum2
+ "movl %2,16%5\n" // store register in tmp0
+ "movl %5,%2\n" // lum2->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<DITH_SIZE; i++) {
+ delete cb_darrays[i];
+ delete l_darrays[i];
+ delete cr_darrays[i];
+ }
+}
+
+
+
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * InitOrderedDither--
+ *
+ * Structures initialized for ordered dithering.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+void Dither8Bit::initOrderedDither() {
+ int i, j, k, err_range, threshval;
+ unsigned char *lmark, *cmark;
+
+ for (i=0; i<DITH_SIZE; i++) {
+ lmark = l_darrays[i] = new unsigned char[256];
+ for (j=0; j<lum_values[0]; j++) {
+ *lmark++ = 0;
+ }
+ for (j=0; j<(LUM_RANGE-1); j++) {
+ err_range = lum_values[j+1] - lum_values[j];
+ threshval = ((i * err_range) / DITH_SIZE)+lum_values[j];
+
+ for (k=lum_values[j]; k<lum_values[j+1]; k++) {
+ if (k > 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<DITH_SIZE; i++) {
+ cmark = cr_darrays[i] = new unsigned char[256];
+
+ for (j=0; j<cr_values[0]; j++) {
+ *cmark++ = 0;
+ }
+
+ for (j=0; j<(CR_RANGE-1); j++) {
+ err_range = cr_values[j+1] - cr_values[j];
+ threshval = ((i * err_range) / DITH_SIZE)+cr_values[j];
+
+ for (k=cr_values[j]; k<cr_values[j+1]; k++) {
+ if (k > 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<DITH_SIZE; i++) {
+ cmark = cb_darrays[i] = new unsigned char[256];
+
+ for (j=0; j<cb_values[0]; j++) {
+ *cmark++ = 0;
+ }
+
+ for (j=0; j<(CB_RANGE-1); j++) {
+ err_range = cb_values[j+1] - cb_values[j];
+ threshval = ((i * err_range) / DITH_SIZE)+cb_values[j];
+
+ for (k=cb_values[j]; k<cb_values[j+1]; k++) {
+ if (k > 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<h; i+=4) {
+
+ for (j=0; j<w; j+=8) {
+
+ R = r[0]; B = b[0];
+
+ L = l[0];
+ o1[0] = pixel[(l_darrays[0][L] + cr_darrays[0][R] + cb_darrays[0][B])];
+ L = l[1];
+ o1[1] = pixel[(l_darrays[8][L] + cr_darrays[8][R] + cb_darrays[8][B])];
+ L = l2[0];
+ o2[0] = pixel[(l_darrays[12][L] + cr_darrays[12][R] + cb_darrays[12][B])];
+ L = l2[1];
+ o2[1] = pixel[(l_darrays[4][L] + cr_darrays[4][R] + cb_darrays[4][B])];
+
+ R = r[1]; B = b[1];
+
+ L = l[2];
+ o1[2] = pixel[(l_darrays[2][L] + cr_darrays[2][R] + cb_darrays[2][B])];
+ L = l[3];
+ o1[3] = pixel[(l_darrays[10][L] + cr_darrays[10][R] + cb_darrays[10][B])];
+ L = l2[2];
+ o2[2] = pixel[(l_darrays[14][L] + cr_darrays[14][R] + cb_darrays[14][B])];
+ L = l2[3];
+ o2[3] = pixel[(l_darrays[6][L] + cr_darrays[6][R] + cb_darrays[6][B])];
+
+ R = r[2]; B = b[2];
+
+ L = l[4];
+ o1[4] = pixel[(l_darrays[0][L] + cr_darrays[0][R] + cb_darrays[0][B])];
+ L = l[5];
+ o1[5] = pixel[(l_darrays[8][L] + cr_darrays[8][R] + cb_darrays[8][B])];
+ L = l2[4];
+ o2[4] = pixel[(l_darrays[12][L] + cr_darrays[12][R] + cb_darrays[12][B])];
+ L = l2[5];
+ o2[5] = pixel[(l_darrays[4][L] + cr_darrays[4][R] + cb_darrays[4][B])];
+
+ R = r[3]; B = b[3];
+
+ L = l[6];
+ o1[6] = pixel[(l_darrays[2][L] + cr_darrays[2][R] + cb_darrays[2][B])];
+ L = l[7];
+ o1[7] = pixel[(l_darrays[10][L] + cr_darrays[10][R] + cb_darrays[10][B])];
+ L = l2[6];
+ o2[6] = pixel[(l_darrays[14][L] + cr_darrays[14][R] + cb_darrays[14][B])];
+ L = l2[7];
+ o2[7] = pixel[(l_darrays[6][L] + cr_darrays[6][R] + cb_darrays[6][B])];
+
+ l += 8;
+ l2 += 8;
+ r += 4;
+ b += 4;
+ o1 += 8;
+ o2 += 8;
+ }
+
+ l += w;
+ l2 += w;
+ o1 += w;
+ o2 += w;
+
+ for (j=0; j<w; j+=8) {
+
+ R = r[0]; B = b[0];
+
+ L = l[0];
+ o1[0] = pixel[(l_darrays[3][L] + cr_darrays[3][R] + cb_darrays[3][B])];
+ L = l[1];
+ o1[1] = pixel[(l_darrays[11][L] + cr_darrays[11][R] + cb_darrays[11][B])];
+ L = l2[0];
+ o2[0] = pixel[(l_darrays[15][L] + cr_darrays[15][R] + cb_darrays[15][B])];
+ L = l2[1];
+ o2[1] = pixel[(l_darrays[7][L] + cr_darrays[7][R] + cb_darrays[7][B])];
+
+ R = r[1]; B = b[1];
+
+ L = l[2];
+ o1[2] = pixel[(l_darrays[1][L] + cr_darrays[1][R] + cb_darrays[1][B])];
+ L = l[3];
+ o1[3] = pixel[(l_darrays[9][L] + cr_darrays[9][R] + cb_darrays[9][B])];
+ L = l2[2];
+ o2[2] = pixel[(l_darrays[13][L] + cr_darrays[13][R] + cb_darrays[13][B])];
+ L = l2[3];
+ o2[3] = pixel[(l_darrays[5][L] + cr_darrays[5][R] + cb_darrays[5][B])];
+
+ R = r[2]; B = b[2];
+
+ L = l[4];
+ o1[4] = pixel[(l_darrays[3][L] + cr_darrays[3][R] + cb_darrays[3][B])];
+ L = l[5];
+ o1[5] = pixel[(l_darrays[11][L] + cr_darrays[11][R] + cb_darrays[11][B])];
+ L = l2[4];
+ o2[4] = pixel[(l_darrays[15][L] + cr_darrays[15][R] + cb_darrays[15][B])];
+ L = l2[5];
+ o2[5] = pixel[(l_darrays[7][L] + cr_darrays[7][R] + cb_darrays[7][B])];
+
+ R = r[3]; B = b[3];
+
+ L = l[6];
+ o1[6] = pixel[(l_darrays[1][L] + cr_darrays[1][R] + cb_darrays[1][B])];
+ L = l[7];
+ o1[7] = pixel[(l_darrays[9][L] + cr_darrays[9][R] + cb_darrays[9][B])];
+ L = l2[6];
+ o2[6] = pixel[(l_darrays[13][L] + cr_darrays[13][R] + cb_darrays[13][B])];
+ L = l2[7];
+ o2[7] = pixel[(l_darrays[5][L] + cr_darrays[5][R] + cb_darrays[5][B])];
+
+ l += 8;
+ l2 += 8;
+ r += 4;
+ b += 4;
+ o1 += 8;
+ o2 += 8;
+ }
+
+ l += w;
+ l2 += w;
+ o1 += w;
+ o2 += w;
+ }
+}
+
diff --git a/mpeglib/lib/util/render/dither/dither8Bit.h b/mpeglib/lib/util/render/dither/dither8Bit.h
new file mode 100644
index 00000000..7bdd4d8f
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/dither8Bit.h
@@ -0,0 +1,63 @@
+/*
+ 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
+
+ */
+
+
+
+#ifndef __DITHER_8BIT_H
+#define __DITHER_8BIT_H
+
+
+#include "colorTable8Bit.h"
+
+#define DITH_SIZE 16
+
+
+class Dither8Bit {
+
+ /* Structures used to implement hybrid ordered dither/floyd-steinberg
+ dither algorithm.
+ */
+
+ unsigned char *l_darrays[DITH_SIZE];
+ unsigned char *cr_darrays[DITH_SIZE];
+ unsigned char *cb_darrays[DITH_SIZE];
+
+ // private colormap
+ unsigned char pixel[256];
+
+ ColorTable8Bit* colorTable8Bit;
+
+ // Arrays holding quantized value ranged for lum, cr, and cb.
+ // (used for 8 Bit)
+
+ int* lum_values;
+ int* cr_values;
+ int* cb_values;
+
+
+ public:
+ Dither8Bit(unsigned char pixel[256]);
+ ~Dither8Bit();
+
+ void ditherImageOrdered (unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,
+ unsigned char* out,
+ int h,
+ int w);
+
+ private:
+ void initOrderedDither();
+};
+
+#endif
+
diff --git a/mpeglib/lib/util/render/dither/ditherDef.h b/mpeglib/lib/util/render/dither/ditherDef.h
new file mode 100644
index 00000000..2e8d7d0e
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/ditherDef.h
@@ -0,0 +1,100 @@
+/*
+ global definitions for dithering
+ 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 __DITHERDEF_H
+#define __DITHERDEF_H
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+extern "C" {
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+}
+
+
+#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 <math.h>
+
+
+
+/* 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 <iostream>
+
+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:"<<pixel
+ << " in DitherRGB_flipped::flipRGBImage"<<endl;
+ }
+ return byteDepth;
+
+}
+
+void DitherRGB::ditherRGBImage(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int offset) {
+ int byteDepth=getDepth(depth);
+ if (byteDepth == 0) {
+ return;
+ }
+
+
+ if (offset==0) {
+ int bytes=height*width*byteDepth;
+ memcpy(dest,src,bytes);
+ return;
+ }
+
+ int i;
+ int lineSize=width*byteDepth;
+
+ offset=offset*byteDepth+lineSize;
+
+ for (i=0;i<height;i++) {
+ memcpy(dest,src,lineSize);
+ src+=lineSize;
+ dest+=offset;
+ }
+
+
+}
+
+void DitherRGB::ditherRGBImage_x2(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int offset) {
+
+ int byteDepth=getDepth(depth);
+ if (byteDepth == 0) {
+ return;
+ }
+
+ switch(byteDepth) {
+ case 1:
+ ditherRGB1Byte_x2(dest,src,1,width, height,offset);
+ break;
+ case 2:
+ ditherRGB2Byte_x2(dest,src,2,width, height,offset);
+ break;
+ case 4:
+ ditherRGB4Byte_x2(dest,src,4,width, height,offset);
+ break;
+ default:
+ cout <<"ditherRGBImage_x2 byteDepth:"<<byteDepth
+ <<" not supported"<<endl;
+ }
+}
+
+
+void DitherRGB::ditherRGB1Byte_x2(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int offset) {
+
+ //
+ // dest destr
+ // destd destrd
+
+ int lineInc=2*width+offset;
+ unsigned char* destr=dest+1;
+ unsigned char* destd=dest+lineInc;
+ unsigned char* destrd=destd+1;
+
+ int row;
+ int col;
+ //
+ // We copy byte by byte this is slow, but works for
+ // all byteDepth
+ // this memcpy can be optimized with MMX very i) good ii) easily
+
+ for(row=0;row<height;row++) {
+ for(col=0;col<width;col++) {
+ *dest++=*src;
+ *destr++=*src;
+ *destd++=*src;
+ *destrd++=*src;
+ dest++;
+ destr++;
+ destd++;
+ destrd++;
+
+ src++;
+ }
+ dest+=lineInc;
+ destr+=lineInc;
+ destd+=lineInc;
+ destrd+=lineInc;
+ }
+}
+
+
+void DitherRGB::ditherRGB2Byte_x2(unsigned char* destination,
+ unsigned char* source,
+ int depth,int width,int height,int offset) {
+ //
+ // dest destr
+ // destd destrd
+
+ unsigned short int* src=(unsigned short int*) source;
+ unsigned short int* dest=(unsigned short int*) destination;
+
+ int lineInc=2*width+offset;
+ unsigned short int* destr=dest+1;
+ unsigned short int* destd=dest+lineInc;
+ unsigned short int* destrd=destd+1;
+
+ int row;
+ int col;
+ //
+ // We copy byte by byte this is slow, but works for
+ // all byteDepth
+ // this memcpy can be optimized with MMX very i) good ii) easily
+
+ for(row=0;row<height;row++) {
+ for(col=0;col<width;col++) {
+ *dest++=*src;
+ *destr++=*src;
+ *destd++=*src;
+ *destrd++=*src;
+ dest++;
+ destr++;
+ destd++;
+ destrd++;
+
+ src++;
+ }
+ dest+=lineInc;
+ destr+=lineInc;
+ destd+=lineInc;
+ destrd+=lineInc;
+ }
+}
+
+
+void DitherRGB::ditherRGB4Byte_x2(unsigned char* destination,
+ unsigned char* source,
+ int depth,int width,int height,int offset) {
+
+ //
+ // dest destr
+ // destd destrd
+
+ unsigned int* src=(unsigned int*) source;
+ unsigned int* dest=(unsigned int*) destination;
+
+ int lineInc=2*width+offset;
+ unsigned int* destr=dest+1;
+ unsigned int* destd=dest+lineInc;
+ unsigned int* destrd=destd+1;
+
+ int row;
+ int col;
+ //
+ // We copy byte by byte this is slow, but works for
+ // all byteDepth
+ // this memcpy can be optimized with MMX very i) good ii) easily
+
+ for(row=0;row<height;row++) {
+ for(col=0;col<width;col++) {
+ *dest++=*src;
+ *destr++=*src;
+ *destd++=*src;
+ *destrd++=*src;
+ dest++;
+ destr++;
+ destd++;
+ destrd++;
+
+ src++;
+ }
+ dest+=lineInc;
+ destr+=lineInc;
+ destd+=lineInc;
+ destrd+=lineInc;
+ }
+
+}
+
diff --git a/mpeglib/lib/util/render/dither/ditherRGB.h b/mpeglib/lib/util/render/dither/ditherRGB.h
new file mode 100644
index 00000000..6f24cd8c
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/ditherRGB.h
@@ -0,0 +1,45 @@
+/*
+ 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
+
+ */
+
+#ifndef __DITHERRGB_H
+#define __DITHERRGB_H
+
+#include "colorTableHighBit.h"
+
+class DitherRGB {
+
+ int flipSize;
+ unsigned char* flipSpace;
+
+ public:
+ DitherRGB();
+ ~DitherRGB();
+
+ // Note: this methods swaps the image
+ // itsself
+ void ditherRGBImage(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int offset);
+ void ditherRGBImage_x2(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int offset);
+ private:
+ int getDepth(int pixel);
+ // depth is here in byte!
+ void ditherRGB1Byte_x2(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int offset);
+ void ditherRGB2Byte_x2(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int offset);
+ void ditherRGB4Byte_x2(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int offset);
+
+};
+
+#endif
diff --git a/mpeglib/lib/util/render/dither/ditherRGB_flipped.cpp b/mpeglib/lib/util/render/dither/ditherRGB_flipped.cpp
new file mode 100644
index 00000000..ba177675
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/ditherRGB_flipped.cpp
@@ -0,0 +1,82 @@
+/*
+ flips RGB 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 "ditherRGB_flipped.h"
+
+#include <iostream>
+
+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:"<<depth
+ << " in DitherRGB_flipped::flipRGBImage"<<endl;
+ return;
+ }
+
+
+ int spaceNeeded=width*height*byteDepth;
+
+ if (spaceNeeded > flipSize) {
+ if (flipSpace != NULL) {
+ delete flipSpace;
+ }
+ cout << "flipSpace:"<<spaceNeeded<<endl;
+ flipSpace=new unsigned char[spaceNeeded+64];
+ flipSize=spaceNeeded;
+ }
+
+ int i;
+ int lineSize=width*byteDepth;
+ unsigned char* end=dest+lineSize*(height-1);
+
+ for (i=0;i<height;i++) {
+ memcpy(end,src,lineSize);
+ src+=lineSize;
+ end-=lineSize;
+ }
+
+}
+
+
diff --git a/mpeglib/lib/util/render/dither/ditherRGB_flipped.h b/mpeglib/lib/util/render/dither/ditherRGB_flipped.h
new file mode 100644
index 00000000..1d99f7f6
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/ditherRGB_flipped.h
@@ -0,0 +1,34 @@
+/*
+ flips RGB 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 __DITHERRGB_FLIPPED_H
+#define __DITHERRGB_FLIPPED_H
+
+#include "colorTableHighBit.h"
+
+class DitherRGB_flipped {
+
+ int flipSize;
+ unsigned char* flipSpace;
+
+ public:
+ DitherRGB_flipped();
+ ~DitherRGB_flipped();
+
+ // Note: this methods swaps the image
+ // itsself
+ void flipRGBImage(unsigned char* dest,unsigned char* src,
+ int depth,int width,int height,int offset);
+
+};
+
+#endif
diff --git a/mpeglib/lib/util/render/dither/ditherWrapper.cpp b/mpeglib/lib/util/render/dither/ditherWrapper.cpp
new file mode 100644
index 00000000..c6c37a79
--- /dev/null
+++ b/mpeglib/lib/util/render/dither/ditherWrapper.cpp
@@ -0,0 +1,246 @@
+/*
+ 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
+
+ */
+
+
+#include "ditherWrapper.h"
+
+#include <iostream>
+
+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:"<<inputType
+ << " in DitherWrapper::doDither"<<endl;
+}
+
+
+void DitherWrapper::doDitherRGB(YUVPicture* pic,int depth,int imageMode,
+ unsigned char* dest,int offset) {
+
+ int inputType=pic->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:"<<inputType<<" in DitherWrapper"<<endl;
+ exit(0);
+ }
+}
+
+
+void DitherWrapper::doDitherRGB_NORMAL(YUVPicture* pic,
+ int depth,int imageMode,
+ unsigned char* dest,int offset) {
+
+ int w=pic->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:"<<depth<<endl;
+ }
+
+}
+
+
+void DitherWrapper::doDither_x2(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: {
+ // 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 <stdlib.h>
+#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 <iostream>
+
+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"<<MMX16_0<<endl;
+ cout << "MMX16_10w:"<<MMX16_10w<<endl;
+ cout << "MMX16_80w:"<<MMX16_80w<<endl;
+ cout << "MMX16_Ublucoeff:"<<MMX16_Ublucoeff<<endl;
+ cout << "MMX16_Vredcoeff:"<<MMX16_Vredcoeff<<endl;
+ cout << "MMX16_Ugrncoeff:"<<MMX16_Ugrncoeff<<endl;
+ cout << "MMX16_Vgrncoeff:"<<MMX16_Vgrncoeff<<endl;
+ cout << "MMX16_Ycoeff:"<<MMX16_Ycoeff<<endl;
+ cout << "MMX16_redmask:"<<MMX16_redmask<<endl;
+ cout << "MMX16_grnmask:"<<MMX16_grnmask<<endl;
+ cout << "MMX16_00FFw:"<<MMX16_00FFw<<endl;
+}
+
+
+void ditherBlock(unsigned char *lum,
+ unsigned char *cr,
+ unsigned char *cb,
+ unsigned char *out,
+ int rows,
+ int cols,
+ int mod) {
+
+ unsigned short *row1;
+ unsigned short *row2;
+ row1 = (unsigned short* )out; // 16 bit target
+
+ unsigned char* end = lum +cols*rows; // Pointer to the end
+ int x=cols;
+ row2=row1+mod+cols; // start of second row
+ mod=2*cols+4*mod; // increment for row1 in byte
+
+ // buffer for asm function
+ int buf[6];
+ buf[0]=(int)(lum+cols); // lum2 pointer
+ buf[1]=(int)end;
+ buf[2]=x;
+ buf[3]=mod;
+ buf[4]=0; //tmp0;
+ buf[5]=cols;
+
+
+
+ __asm__ __volatile__(
+ ".align 32\n"
+ "1:\n"
+ "movd (%1), %%mm0\n" // 4 Cb 0 0 0 0 u3 u2 u1 u0
+ "pxor %%mm7, %%mm7\n"
+ "movd (%0), %%mm1\n" // 4 Cr 0 0 0 0 v3 v2 v1 v0
+ "punpcklbw %%mm7, %%mm0\n" // 4 W cb 0 u3 0 u2 0 u1 0 u0
+ "punpcklbw %%mm7, %%mm1\n" // 4 W cr 0 v3 0 v2 0 v1 0 v0
+ "psubw MMX16_80w, %%mm0\n"
+ "psubw MMX16_80w, %%mm1\n"
+ "movq %%mm0, %%mm2\n" // Cb 0 u3 0 u2 0 u1 0 u0
+ "movq %%mm1, %%mm3\n" // Cr
+ "pmullw MMX16_Ugrncoeff, %%mm2\n" // Cb2green 0 R3 0 R2 0 R1 0 R0
+ "movq (%2), %%mm6\n" // L1 l7 L6 L5 L4 L3 L2 L1 L0
+ "pmullw MMX16_Ublucoeff, %%mm0\n" // Cb2blue
+ "pand MMX16_00FFw, %%mm6\n" // L1 00 L6 00 L4 00 L2 00 L0
+ "pmullw MMX16_Vgrncoeff, %%mm3\n" // Cr2green
+ "movq (%2), %%mm7\n" // L2
+ "pmullw MMX16_Vredcoeff, %%mm1\n" // Cr2red
+ // "psubw MMX16_10w, %%mm6\n"
+ "psrlw $8, %%mm7\n" // L2 00 L7 00 L5 00 L3 00 L1
+ "pmullw MMX16_Ycoeff, %%mm6\n" // lum1
+ // "psubw MMX16_10w, %%mm7\n" // L2
+ "paddw %%mm3, %%mm2\n" // Cb2green + Cr2green == green
+ "pmullw MMX16_Ycoeff, %%mm7\n" // lum2
+
+ "movq %%mm6, %%mm4\n" // lum1
+ "paddw %%mm0, %%mm6\n" // lum1 +blue 00 B6 00 B4 00 B2 00 B0
+ "movq %%mm4, %%mm5\n" // lum1
+ "paddw %%mm1, %%mm4\n" // lum1 +red 00 R6 00 R4 00 R2 00 R0
+ "paddw %%mm2, %%mm5\n" // lum1 +green 00 G6 00 G4 00 G2 00 G0
+ "psraw $6, %%mm4\n" // R1 0 .. 64
+ "movq %%mm7, %%mm3\n" // lum2 00 L7 00 L5 00 L3 00 L1
+ "psraw $6, %%mm5\n" // G1 - .. +
+ "paddw %%mm0, %%mm7\n" // Lum2 +blue 00 B7 00 B5 00 B3 00 B1
+ "psraw $6, %%mm6\n" // B1 0 .. 64
+ "packuswb %%mm4, %%mm4\n" // R1 R1
+ "packuswb %%mm5, %%mm5\n" // G1 G1
+ "packuswb %%mm6, %%mm6\n" // B1 B1
+ "punpcklbw %%mm4, %%mm4\n"
+ "punpcklbw %%mm5, %%mm5\n"
+
+ "pand MMX16_redmask, %%mm4\n"
+ "psllw $3, %%mm5\n" // GREEN 1
+ "punpcklbw %%mm6, %%mm6\n"
+ "pand MMX16_grnmask, %%mm5\n"
+ "pand MMX16_redmask, %%mm6\n"
+ "por %%mm5, %%mm4\n" //
+ "psrlw $11, %%mm6\n" // BLUE 1
+ "movq %%mm3, %%mm5\n" // lum2
+ "paddw %%mm1, %%mm3\n" // lum2 +red 00 R7 00 R5 00 R3 00 R1
+ "paddw %%mm2, %%mm5\n" // lum2 +green 00 G7 00 G5 00 G3 00 G1
+ "psraw $6, %%mm3\n" // R2
+ "por %%mm6, %%mm4\n" // MM4
+ "psraw $6, %%mm5\n" // G2
+
+ "movl %2,16%5\n" // store register in tmp0
+ "movl %5,%2\n" // lum2->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
diff --git a/mpeglib/lib/util/render/dither2YUV/Makefile.am b/mpeglib/lib/util/render/dither2YUV/Makefile.am
new file mode 100644
index 00000000..374658a3
--- /dev/null
+++ b/mpeglib/lib/util/render/dither2YUV/Makefile.am
@@ -0,0 +1,22 @@
+# libdivxplugin - Makefile.am
+
+EXTRA_DIST = README
+
+INCLUDES = -I.. $(all_includes)
+
+
+noinst_LTLIBRARIES = libdivxutil_dither.la
+
+noinst_HEADERS = dither2YUV.h rgb2yuvdefs.h rgb2yuv16.h \
+ rgb2yuv32.h
+
+libdivxutil_dither_la_SOURCES = dither2YUV.cpp rgb2yuv16.cpp \
+ rgb2yuv32.cpp
+
+
+
+
+
+
+
+
diff --git a/mpeglib/lib/util/render/dither2YUV/README b/mpeglib/lib/util/render/dither2YUV/README
new file mode 100644
index 00000000..66246c13
--- /dev/null
+++ b/mpeglib/lib/util/render/dither2YUV/README
@@ -0,0 +1,13 @@
+
+
+* we have a Dither2Yuv base class. Currently this is not derived
+ from a basic ditherWrapper class because we don not have this
+ in mpeglib yet.
+ TODO: change in mpeglib DitherWrapper->Dither2RGB and
+ make DitherWrapper pure virtual and derive Dither2YUV
+ Dither2RGB from this class.
+
+* Note we do not support 8 Bit here, thus the constructor looks
+ dofferent.
+
+
diff --git a/mpeglib/lib/util/render/dither2YUV/dither2YUV.cpp b/mpeglib/lib/util/render/dither2YUV/dither2YUV.cpp
new file mode 100644
index 00000000..db4a3288
--- /dev/null
+++ b/mpeglib/lib/util/render/dither2YUV/dither2YUV.cpp
@@ -0,0 +1,124 @@
+/*
+ this class dithery RGB picture to yuv12
+ 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 "dither2YUV.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+Dither2YUV::Dither2YUV() {
+
+
+ lmmx=mm_support();
+
+}
+
+
+Dither2YUV::~Dither2YUV(){
+}
+
+
+
+
+
+
+void Dither2YUV::doDither(YUVPicture* pic,int depth,int ditherSize,
+ unsigned char* dest,int offset) {
+
+ int inputType=pic->getImageType();
+
+ switch(inputType) {
+ case PICTURE_RGB:
+ doDitherRGB_NORMAL(pic,depth,ditherSize,dest,offset);
+ break;
+ default:
+ std::cout << "unknown RGB type:"<<inputType<<" in Dither2YUV"<<std::endl;
+ exit(0);
+ }
+}
+
+
+void Dither2YUV::doDitherRGB_NORMAL(YUVPicture* rgbPic,
+ int depth,int ditherSize,
+ unsigned char* dest,int offset) {
+
+ switch (ditherSize) {
+ case _SIZE_NORMAL:
+ doDither2YUV_std(rgbPic,depth,dest,offset);
+ break;
+ case _SIZE_DOUBLE:
+ std::cout << "double not supported for RGB"<<std::endl;
+ break;
+ default:
+ std::cout << "unknown size:"<<ditherSize<<" in Dither2YUV"<<std::endl;
+ exit(0);
+ }
+}
+
+
+void Dither2YUV::doDither2YUV_std(YUVPicture* rgbPic,int depth,
+ unsigned char* dest,int offset){
+
+ int h=rgbPic->getHeight();
+ int w=rgbPic->getWidth();
+ int lumLength=w * h;
+ int colorLength=(w * h) / 4;
+
+ unsigned char* lum=dest;
+ unsigned char* cr=lum+lumLength;
+ unsigned char* cb=cr+colorLength;
+ unsigned char* rgbSource=rgbPic->getImagePtr();
+
+
+ switch (depth) {
+ case 8:
+ std::cout << "8 bit dither to yuv not supported"<<std::endl;
+ exit(0);
+ break;
+ case 16:
+ if (lmmx) {
+#ifdef INTEL
+ rgb2yuv16bit_mmx(rgbSource,lum,cr,cb,h,w);
+#endif
+ } else {
+ rgb2yuv16bit(rgbSource,lum,cr,cb,h,w);
+ }
+
+ break;
+ case 24:
+ if (lmmx) {
+#ifdef INTEL
+ rgb2yuv24bit_mmx(rgbSource,lum,cr,cb,h,w);
+#endif
+ } else {
+ rgb2yuv24bit(rgbSource,lum,cr,cb,h,w);
+ }
+ break;
+ case 32:
+ if (lmmx) {
+#ifdef INTEL
+ rgb2yuv32bit_mmx(rgbSource,lum,cr,cb,h,w);
+#endif
+ } else {
+ rgb2yuv32bit(rgbSource,lum,cr,cb,h,w);
+ }
+ break;
+ default:
+ std::cout << "cannot dither depth:"<<depth<<std::endl;
+ }
+
+}
+
+
diff --git a/mpeglib/lib/util/render/dither2YUV/dither2YUV.h b/mpeglib/lib/util/render/dither2YUV/dither2YUV.h
new file mode 100644
index 00000000..5ef26b2b
--- /dev/null
+++ b/mpeglib/lib/util/render/dither2YUV/dither2YUV.h
@@ -0,0 +1,64 @@
+/*
+ this class dithery RGB picture to yuv12
+ 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 __DITHER2YUV_H
+#define __DITHER2YUV_H
+
+
+#include "../../mmx/mmx.h"
+#include "../yuvPicture.h"
+
+
+#include <stdlib.h>
+#include "rgb2yuv16.h"
+#include "rgb2yuv32.h"
+
+#define _SIZE_NONE 0
+#define _SIZE_NORMAL 1
+#define _SIZE_DOUBLE 2
+
+
+/**
+ Wraps all calls to software ditherer and the different
+ resolutions,mmx enhancements, and doublesize ditherers.
+*/
+
+
+class Dither2YUV {
+
+ int lmmx;
+
+ int bpp;
+
+
+ public:
+ Dither2YUV();
+ ~Dither2YUV();
+
+ int getDitherSize();
+ void setDitherSize(int ditherSize);
+
+ void doDither(YUVPicture* pic,int depth,int ditherSize,
+ unsigned char* dest,int offset);
+
+
+ private:
+ void doDitherRGB_NORMAL(YUVPicture* pic,int depth,int ditherSize,
+ unsigned char* dest,int offset);
+
+ void doDither2YUV_std(YUVPicture* pic,int depth,
+ unsigned char* dest,int offset);
+
+};
+
+#endif
diff --git a/mpeglib/lib/util/render/dither2YUV/rgb2yuv16.cpp b/mpeglib/lib/util/render/dither2YUV/rgb2yuv16.cpp
new file mode 100644
index 00000000..e0d7fc86
--- /dev/null
+++ b/mpeglib/lib/util/render/dither2YUV/rgb2yuv16.cpp
@@ -0,0 +1,916 @@
+/***************************************************************************
+ rgb2yuv16.c - description
+ -------------------
+ begin : Tue Nov 2 2000
+ copyright : (C) 2000 by Christian Gerlach
+ email : cgerlach@rhrk.uni-kl.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "rgb2yuv16.h"
+#include <iostream>
+
+static unsigned short KEEPR[4] = { 63488, 63488, 63488, 63488 };
+unsigned short KEEPG[4] = { 2016, 2016, 2016, 2016 };
+unsigned short KEEPB[4] = { 31, 31, 31, 31 };
+
+short Y_RED[4] = { 307, 307, 307, 307 };
+short Y_GREEN[4] = { 302, 302, 302, 302 };
+short Y_BLUE[4] = { 117, 117, 117, 117 };
+
+short U_RED[4] = { -150, -150, -150, -150 };
+short U_GREEN[4] = { -147, -147, -147, -147 };
+short U_BLUE[4] = { 444, 444, 444, 444 };
+
+short V_RED[4] = { 632, 632, 632, 632 };
+short V_GREEN[4] = { -265, -265, -265, -265 };
+short V_BLUE[4] = { -102, -102, -102, -102 };
+
+
+// how to avoid these nasty compiler warinings?
+// heres one (maybe bad) method
+void dummyRGB2YUV16Bit() {
+
+ printf("%p\n",KEEPR);
+ printf("%p\n",KEEPG);
+ printf("%p\n",KEEPB);
+ printf("%p\n",Y_RED);
+ printf("%p\n",Y_GREEN);
+ printf("%p\n",Y_BLUE);
+ printf("%p\n",U_RED);
+ printf("%p\n",U_GREEN);
+ printf("%p\n",U_BLUE);
+ printf("%p\n",V_RED);
+ printf("%p\n",V_GREEN);
+ printf("%p\n",V_BLUE);
+}
+
+
+#ifndef INTEL
+void rgb2yuv16bit_mmx(unsigned char* ,unsigned char* ,unsigned char* ,
+ unsigned char* ,int , int ) {
+ std::cout << "RGB->YUV not compiled with INTEL" << std::endl;
+ exit(0);
+}
+
+void rgb2yuv16bit_mmx_fast(unsigned char* ,unsigned char* ,unsigned char* ,
+ unsigned char* ,int , int ) {
+ std::cout << "RGB->YUV not compiled with INTEL" << std::endl;
+ exit(0);
+}
+#endif
+
+
+void rgb2yuv16(unsigned char* rgbSource, unsigned char* dest)
+{
+ int rgb = *((unsigned short*) rgbSource++ );
+ int r = RED(rgb);
+ int g = GREEN(rgb);
+ int b = BLUE(rgb);
+
+ dest[0] = Y_RGB(r, g, b);
+ dest[1] = U_RGB(r, g, b);
+ dest[2] = V_RGB(r, g, b);
+}
+
+void rgb2yuv16bit(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width) {
+
+ int height2 = height / 2;
+ int width2 = width / 2;
+ int r, g, b, row, col, rgb;
+
+ for (row=0 ; row<height2 ; row++) {
+ for (col=0 ; col<width2 ; col++) {
+ rgb = *((unsigned short*) rgbSource++ );
+ r = RED(rgb);
+ g = GREEN(rgb);
+ b = BLUE(rgb);
+
+ *lum++ = Y_RGB(r, g, b);
+ *cr++ = U_RGB(r, g, b);
+ *cb++ = V_RGB(r, g, b);
+
+ rgb = *((unsigned short*) rgbSource++ );
+ r = RED(rgb);
+ g = GREEN(rgb);
+ b = BLUE(rgb);
+
+ *lum++ = Y_RGB(r, g, b);
+ }
+ for (col=0 ; col<width ; col++) {
+ rgb = *((unsigned short*) rgbSource++ );
+ r = RED(rgb);
+ g = GREEN(rgb);
+ b = BLUE(rgb);
+
+ *lum++ = Y_RGB(r, g, b);
+ }
+ }
+}
+
+
+#ifdef INTEL
+
+void rgb2yuv16bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width) {
+ int height2 = height / 2;
+ int width2 = width / 2;
+ int bytesPerLine = width * 2;
+
+ for (int row=0 ; row<height2 ; row++) {
+ rgb2yuv16bit_mmx422_row(rgbSource, lum, cr, cb, width);
+ rgbSource += bytesPerLine;
+ lum += width;
+ cr += width2;
+ cb += width2;
+
+ rgb2y16bit_mmx_row(rgbSource, lum, width);
+ rgbSource += bytesPerLine;
+ lum += width;
+ }
+}
+
+void rgb2yuv16bit_mmx_fast(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width) {
+
+ int height2 = height / 2;
+ int width2 = width / 2;
+ int bytesPerLine = width * 2;
+
+ for (int row=0 ; row<height2 ; row++) {
+ rgb2yuv16bit_mmx422_row_fast(rgbSource, lum, cr, cb, width);
+ rgbSource += bytesPerLine;
+ lum += width;
+ cr += width2;
+ cb += width2;
+
+ rgb2y16bit_mmx_row_fast(rgbSource, lum, width);
+ rgbSource += bytesPerLine;
+ lum += width;
+ }
+}
+
+void rgb2yuv16bit_mmx422_row(unsigned char* rgb,
+ unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel) {
+ unsigned int buf[17];
+
+ // 36%5 = TEMP0
+ // 44%5 = TEMPY
+ // 52%5 = TEMPU
+ // 60%5 = TEMPV
+
+ __asm__ __volatile__ (
+ "1:\n"
+
+ // unpack hicolor ( pixel 1 - 4)
+ "movq (%0), %%mm0\n"
+
+ "movq %%mm0, %%mm1\n"
+ "pand KEEPR, %%mm1\n"
+ "psrlq $8, %%mm1\n" // B3B2B1B0 -> mm1
+ "movq %%mm0, %%mm2\n"
+ "pand KEEPG, %%mm2\n"
+ "psrlq $3, %%mm2\n" // G3G2G1G0 -> mm2
+ "movq %%mm0, %%mm3\n"
+ "pand KEEPB, %%mm3\n"
+ "psllq $3, %%mm3\n" // G3G2G1G0 -> mm3
+
+ "movq %%mm2, %%mm0\n"
+ "punpcklbw %%mm1, %%mm2\n"
+ "punpckhbw %%mm1, %%mm0\n"
+
+ "pxor %%mm5, %%mm5\n"
+ "movq %%mm3, %%mm4\n"
+ "punpcklbw %%mm5, %%mm3\n"
+ "punpckhbw %%mm5, %%mm4\n"
+
+ "psllq $8, %%mm2\n"
+ "por %%mm2, %%mm3\n" // 0B1G1R10B0G0G0 -> mm3
+ "psllq $8, %%mm0\n"
+ "por %%mm0, %%mm4\n" // 0B3G3R30B2G2G2 -> mm4
+
+ "movq %%mm3, %5\n"
+ "movq %%mm4, 8%5\n"
+
+ // next 4 pixels ------------------------------
+
+ "movq 8(%0), %%mm0\n"
+
+ "movq %%mm0, %%mm1\n"
+ "pand KEEPR, %%mm1\n"
+ "psrlq $8, %%mm1\n" // B3B2B1B0 -> mm1
+ "movq %%mm0, %%mm2\n"
+ "pand KEEPG, %%mm2\n"
+ "psrlq $3, %%mm2\n" // G3G2G1G0 -> mm2
+ "movq %%mm0, %%mm3\n"
+ "pand KEEPB, %%mm3\n"
+ "psllq $3, %%mm3\n" // G3G2G1G0 -> mm3
+
+ "movq %%mm2, %%mm0\n"
+ "punpcklbw %%mm1, %%mm2\n"
+ "punpckhbw %%mm1, %%mm0\n"
+
+ "pxor %%mm5, %%mm5\n"
+ "movq %%mm3, %%mm4\n"
+ "punpcklbw %%mm5, %%mm3\n"
+ "punpckhbw %%mm5, %%mm4\n"
+
+ "psllq $8, %%mm2\n"
+ "por %%mm2, %%mm3\n" // 0B1G1R10B0G0G0 -> mm3
+ "psllq $8, %%mm0\n"
+ "por %%mm0, %%mm4\n" // 0B3G3R30B2G2G2 -> mm4
+
+ "movq %%mm3, 16%5\n"
+ "movq %%mm4, 24%5\n"
+
+ "add $16, %0\n"
+
+ // standard algorithm --------------------------------------------------
+
+ // pack rgb
+ // was: "movq (%0), %%mm1\n" // load G2R2B1G1R1B0G0R0
+ // ------------------------------
+ // (uses: mm0, mm1)
+ "movd 8%5, %%mm0\n"
+ "psllq $24, %%mm0\n"
+ "movd 4%5, %%mm1\n"
+ "por %%mm1, %%mm0\n"
+ "psllq $24, %%mm0\n"
+ "movd %5, %%mm1\n"
+ "por %%mm0, %%mm1\n"
+ // ------------------------------
+
+ "pxor %%mm6, %%mm6\n" // 0 -> mm6
+ "movq %%mm1, %%mm0\n" // G2R2B1G1R1B0G0R0 -> mm0
+ "psrlq $16, %%mm1\n" // 00G2R2B1G1R1B0 -> mm1
+ "punpcklbw ZEROSX, %%mm0\n" // R1B0G0R0 -> mm0
+ "movq %%mm1, %%mm7\n" // 00G2R2B1G1R1B0 -> mm7
+ "punpcklbw ZEROSX, %%mm1\n" // B1G1R1B0 -> mm1
+ "movq %%mm0, %%mm2\n" // R1B0G0R0 -> mm2
+ "pmaddwd YR0GRX, %%mm0\n" // yrR1,ygG0+yrR0 -> mm0
+
+ "movq %%mm1, %%mm3\n" // B1G1R1B0 -> mm3
+ "pmaddwd YBG0BX, %%mm1\n" // ybB1+ygG1,ybB0 -> mm1
+ "movq %%mm2, %%mm4\n" // R1B0G0R0 -> mm4
+ "pmaddwd UR0GRX, %%mm2\n" // urR1,ugG0+urR0 -> mm2
+ "movq %%mm3, %%mm5\n" // B1G1R1B0 -> mm5
+ "pmaddwd UBG0BX, %%mm3\n" // ubB1+ugG1,ubB0 -> mm3
+ "punpckhbw %%mm6, %%mm7\n" // 00G2R2 -> mm7
+ "pmaddwd VR0GRX, %%mm4\n" // vrR1,vgG0+vrR0 -> mm4
+ "paddd %%mm1, %%mm0\n" // Y1Y0 -> mm0
+
+ "pmaddwd VBG0BX, %%mm5\n" // vbB1+vgG1,vbB0 -> mm5
+
+ // pack rgb
+ // was: "movq 8(%0),%%mm1\n" // R5B4G4R4B3G3R3B2 -> mm1
+ // ------------------------------
+ // (uses: mm1, mm6)
+ "movd 20%5, %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 16%5, %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 12%5, %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ "psllq $8, %%mm1\n"
+ "movd 8%5, %%mm6\n"
+ "psrlq $16, %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ // ------------------------------
+
+ "paddd %%mm3, %%mm2\n" // U1U0 -> mm2
+
+ "movq %%mm1, %%mm6\n" // R5B4G4R4B3G3R3B2 -> mm6
+ "punpcklbw ZEROSX, %%mm1\n" // B3G3R3B2 -> mm1
+ "paddd %%mm5, %%mm4\n" // V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm1, %%mm5\n" // B3G3R3B2 -> mm5
+ "psllq $32, %%mm1\n" // R3B200 -> mm1
+
+ "paddd %%mm7, %%mm1\n" // R3B200+00G2R2=R3B2G2R2->mm1
+
+ "punpckhbw ZEROSX, %%mm6\n" // R5B4G4R3 -> mm6
+ "movq %%mm1, %%mm3\n" // R3B2G2R2 -> mm3
+
+ "pmaddwd YR0GRX, %%mm1\n" // yrR3,ygG2+yrR2 -> mm1
+ "movq %%mm5, %%mm7\n" // B3G3R3B2 -> mm7
+
+ "pmaddwd YBG0BX, %%mm5\n" // ybB3+ygG3,ybB2 -> mm5
+ "psrad $15, %%mm0\n" // 32-bit scaled Y1Y0 -> mm0
+
+ "movq %%mm6, 36%5\n" // R5B4G4R4 -> TEMP0
+ "movq %%mm3, %%mm6\n" // R3B2G2R2 -> mm6
+ "pmaddwd UR0GRX, %%mm6\n" // urR3,ugG2+urR2 -> mm6
+ "psrad $15, %%mm2\n" // 32-bit scaled U1U0 -> mm2
+
+ "paddd %%mm5, %%mm1\n" // Y3Y2 -> mm1
+ "movq %%mm7, %%mm5\n" // B3G3R3B2 -> mm5
+ "pmaddwd UBG0BX, %%mm7\n" // ubB3+ugG3,ubB2
+ "psrad $15, %%mm1\n" // 32-bit scaled Y3Y2 -> mm1
+
+ "pmaddwd VR0GRX, %%mm3\n" // vrR3,vgG2+vgR2
+ "packssdw %%mm1, %%mm0\n" // Y3Y2Y1Y0 -> mm0
+
+ "pmaddwd VBG0BX, %%mm5\n" // vbB3+vgG3,vbB2 -> mm5
+ "psrad $15, %%mm4\n" // 32-bit scaled V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "paddd %%mm7, %%mm6\n" // U3U2 -> mm6
+
+ // pack rgb
+ // was: "movq 16(%0), %%mm1\n" // B7G7R7B6G6R6B5G5 -> mm1
+ // ------------------------------
+ // (uses: mm1, mm7)
+ "movd 28%5, %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 24%5, %%mm7\n"
+ "por %%mm7, %%mm1\n"
+ "psllq $16, %%mm1\n"
+ "movd 20%5, %%mm7\n"
+ "psrlq $8, %%mm7\n"
+ "por %%mm7, %%mm1\n"
+ // ------------------------------
+
+ "movq %%mm1, %%mm7\n" // B7G7R7B6G6R6B5G5 -> mm1
+ "psrad $15, %%mm6\n" // 32-bit scaled U3U2 -> mm6
+
+ "paddd %%mm5, %%mm3\n" // V3V2 -> mm3
+ "psllq $16, %%mm7\n" // R7B6G6R6B5G500 -> mm7
+
+ "movq %%mm7, %%mm5\n" // R7B6G6R6B5G500 -> mm5
+ "psrad $15, %%mm3\n" // 32-bit scaled V3V2 -> mm3
+
+ "movq %%mm0, 44%5\n" // 32-bit scaled Y3Y2Y1Y0 -> TEMPY
+
+ "packssdw %%mm6, %%mm2\n" // 32-bit scaled U3U2U1U0 -> mm2
+
+ "movq 36%5, %%mm0\n" // R5B4G4R4 -> mm0
+
+ "punpcklbw ZEROSX, %%mm7\n" // B5G500 -> mm7
+ "movq %%mm0, %%mm6\n" // R5B4G4R4 -> mm6
+
+ "movq %%mm2, 52%5\n" // 32-bit scaled U3U2U1U0 -> TEMPU
+ "psrlq $32, %%mm0\n" // 00R5B4 -> mm0
+
+ "paddw %%mm0, %%mm7\n" // B5G5R5B4 -> mm7
+ "movq %%mm6, %%mm2\n" // B5B4G4R4 -> mm2
+
+ "pmaddwd YR0GRX, %%mm2\n" // yrR5,ygG4+yrR4 -> mm2
+ "movq %%mm7, %%mm0\n" // B5G5R5B4 -> mm0
+
+ "pmaddwd YBG0BX, %%mm7\n" // ybB5+ygG5,ybB4 -> mm7
+ "packssdw %%mm3, %%mm4\n" // 32-bit scaled V3V2V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm4, 60%5\n" // (V3V2V1V0)/256 -> mm4
+
+ "movq %%mm6, %%mm4\n" // B5B4G4R4 -> mm4
+
+ "pmaddwd UR0GRX, %%mm6\n" // urR5,ugG4+urR4
+ "movq %%mm0, %%mm3\n" // B5G5R5B4 -> mm0
+
+ "pmaddwd UBG0BX, %%mm0\n" // ubB5+ugG5,ubB4
+ "paddd %%mm7, %%mm2\n" // Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "pmaddwd VR0GRX, %%mm4\n" // vrR5,vgG4+vrR4 -> mm4
+ "pxor %%mm7, %%mm7\n" // 0 -> mm7
+
+ "pmaddwd VBG0BX, %%mm3\n" // vbB5+vgG5,vbB4 -> mm3
+ "punpckhbw %%mm7, %%mm1\n" // B7G7R7B6 -> mm1
+
+ "paddd %%mm6, %%mm0\n" // U5U4 -> mm0
+ "movq %%mm1, %%mm6\n" // B7G7R7B6 -> mm6
+
+ "pmaddwd YBG0BX, %%mm6\n" // ybB7+ygG7,ybB6 -> mm6
+ "punpckhbw %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "movq %%mm5, %%mm7\n" // R7B6G6R6 -> mm7
+ "paddd %%mm4, %%mm3\n" // V5V4 -> mm3
+
+ "pmaddwd YR0GRX, %%mm5\n" // yrR7,ygG6+yrR6 -> mm5
+ "movq %%mm1, %%mm4\n" // B7G7R7B6 -> mm4
+
+ "pmaddwd UBG0BX, %%mm4\n" // ubB7+ugG7,ubB6 -> mm4
+ "psrad $15, %%mm0\n" // 32-bit scaled U5U4 -> %%mm0
+
+ //----------------------------------------------------------------------
+
+ "paddd OFFSETWX, %%mm0\n" // add offset to U5U4 -> mm0
+ "psrad $15, %%mm2\n" // 32-bit scaled Y5Y4 -> mm2
+
+ "paddd %%mm5, %%mm6\n" // Y7Y6 -> mm6
+ "movq %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "pmaddwd UR0GRX, %%mm7\n" // urR7,ugG6+ugR6 -> mm7
+ "psrad $15, %%mm3\n" // 32-bit scaled V5V4 -> mm3
+
+ "pmaddwd VBG0BX, %%mm1\n" // vbB7+vgG7,vbB6 -> mm1
+ "psrad $15, %%mm6\n" // 32-bit scaled Y7Y6 -> mm6
+
+ "paddd OFFSETDX, %%mm4\n" // add offset to U7U6
+ "packssdw %%mm6, %%mm2\n" // Y7Y6Y5Y4 -> mm2
+
+ "pmaddwd VR0GRX, %%mm5\n" // vrR7,vgG6+vrR6 -> mm5
+ "paddd %%mm4, %%mm7\n" // U7U6 -> mm7
+
+ "psrad $15, %%mm7\n" // 32-bit scaled U7U6 -> mm7
+
+ //----------------------------------------------------------------------
+
+ "movq 44%5, %%mm6\n" // 32-bit scaled Y3Y2Y1Y0 -> mm6
+ "packssdw %%mm7, %%mm0\n" // 32-bit scaled U7U6U5U4 -> mm0
+
+ "movq 52%5, %%mm4\n" // 32-bit scaled U3U2U1U0 -> mm4
+ "packuswb %%mm2, %%mm6\n" // all 8 Y values -> mm6
+
+ "movq OFFSETBX, %%mm7\n" // 128,128,128,128 -> mm7
+ "paddd %%mm5, %%mm1\n" // V7V6 -> mm1
+
+ "paddw %%mm7, %%mm4\n" // add offset to U3U2U1U0/256
+ "psrad $15, %%mm1\n" // 32-bit scaled V7V6 -> mm1
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm6, (%1)\n" // store Y
+
+ "packuswb %%mm0, %%mm4\n" // all 8 U values -> mm4
+ "movq 60%5, %%mm5\n" // 32-bit scaled V3V2V1V0 -> mm5
+
+ "packssdw %%mm1, %%mm3\n" // V7V6V5V4 -> mm3
+ "paddw %%mm7, %%mm5\n" // add offset to V3V2V1V0
+ "paddw %%mm7, %%mm3\n" // add offset to V7V6V5V4
+
+ "packuswb %%mm3, %%mm5\n" // ALL 8 V values -> mm5
+
+ "movq CLEARX, %%mm2\n"
+ "pand %%mm2, %%mm4\n"
+ "pand %%mm2, %%mm5\n"
+
+ "packuswb %%mm5, %%mm4\n"
+
+ "movd %%mm4, (%2)\n"
+ "psrlq $32, %%mm4\n"
+ "movd %%mm4, (%3)\n"
+
+ "add $8, %1\n"
+ "add $4, %2\n"
+ "add $4, %3\n"
+
+ "sub $8, %4\n"
+ "jnz 1b\n"
+
+ "emms\n"
+
+ :
+ : "r" (rgb), "r" (lum), "r" (cr), "r" (cb),
+ "m" (pixel), "m" (buf[0])
+
+ );
+}
+
+void rgb2yuv16bit_mmx422_row_fast(unsigned char* rgb,
+ unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel)
+{
+ __asm__ __volatile__ (
+ "1:\n"
+
+ // unpack hicolor ( pixel 0 - 3)
+ "movq (%0), %%mm0\n"
+
+ "movq %%mm0, %%mm1\n"
+ "pand KEEPR, %%mm1\n"
+ "psrlq $11, %%mm1\n" // B3B2B1B0 -> mm1
+
+ "movq %%mm0, %%mm2\n"
+ "pand KEEPG, %%mm2\n"
+ "psrlq $5, %%mm2\n" // G3G2G1G0 -> mm2
+
+ "movq %%mm0, %%mm3\n"
+ "pand KEEPB, %%mm3\n" // R3R2R1R0 -> mm3
+
+ // unpack hicolor ( pixel 4 - 7)
+ "movq 8(%0), %%mm0\n"
+
+ "movq %%mm0, %%mm4\n"
+ "pand KEEPR, %%mm4\n"
+ "psrlq $11, %%mm4\n" // B7B6B5B4 -> mm4
+
+ "movq %%mm0, %%mm5\n"
+ "pand KEEPG, %%mm5\n"
+ "psrlq $5, %%mm5\n" // G7G6G5G4 -> mm5
+
+ "movq %%mm0, %%mm6\n"
+ "pand KEEPB, %%mm6\n" // R7R6R5R4 -> mm6
+
+ // calculate Y
+ "movq %%mm6, %%mm7\n"
+ "pmullw Y_RED, %%mm7\n"
+
+ "movq %%mm5, %%mm0\n"
+ "pmullw Y_GREEN, %%mm0\n"
+ "paddw %%mm0, %%mm7\n"
+
+ "movq %%mm4, %%mm0\n"
+ "pmullw Y_BLUE, %%mm0\n"
+ "paddw %%mm0, %%mm7\n"
+
+ "psrlw $7, %%mm7\n" // Y3Y2Y1Y0 -> mm7
+
+ "pxor %%mm0, %%mm0\n"
+ "packuswb %%mm0, %%mm7\n"
+ "movd %%mm7, 4(%1)\n" // Y3Y2Y1Y0 -> lum
+
+ // --------
+
+ "movq %%mm3, %%mm7\n"
+ "pmullw Y_RED, %%mm7\n"
+
+ "movq %%mm2, %%mm0\n"
+ "pmullw Y_GREEN, %%mm0\n"
+ "paddw %%mm0, %%mm7\n"
+
+ "movq %%mm1, %%mm0\n"
+ "pmullw Y_BLUE, %%mm0\n"
+ "paddw %%mm0, %%mm7\n"
+
+ "psrlw $7, %%mm7\n" // Y7Y6Y5Y4 -> mm7
+
+ "pxor %%mm0, %%mm0\n"
+ "packuswb %%mm0, %%mm7\n"
+ "movd %%mm7, (%1)\n" // Y7Y6Y5Y4 -> lum
+ "add $8, %1\n"
+
+ // pack RGB
+ "packuswb %%mm4, %%mm1\n"
+ "pand CLEARX, %%mm1\n" // B6B4B2B0 -> mm1
+ "packuswb %%mm5, %%mm2\n"
+ "pand CLEARX, %%mm2\n" // GRG4G2G0 -> mm2
+ "packuswb %%mm6, %%mm3\n"
+ "pand CLEARX, %%mm3\n" // R6R4R2R0 -> mm3
+
+ // calculate U
+ "movq %%mm3, %%mm7\n"
+ "pmullw U_RED, %%mm7\n"
+
+ "movq %%mm2, %%mm0\n"
+ "pmullw U_GREEN, %%mm0\n"
+ "paddw %%mm0, %%mm7\n"
+
+ "movq %%mm1, %%mm0\n"
+ "pmullw U_BLUE, %%mm0\n"
+ "paddw %%mm0, %%mm7\n"
+
+ "psrlw $7, %%mm7\n" // U3U2U1U0 -> mm7
+ "paddw OFFSETBX,%%mm7\n"
+ "pand CLEARX, %%mm7\n"
+
+ "pxor %%mm0, %%mm0\n"
+ "packuswb %%mm0, %%mm7\n"
+ "movd %%mm7, (%2)\n" // U3U2U1U0 -> lum
+ "add $4, %2\n"
+
+ // calculate V
+ "movq %%mm3, %%mm7\n"
+ "pmullw V_RED, %%mm7\n"
+
+ "movq %%mm2, %%mm0\n"
+ "pmullw V_GREEN, %%mm0\n"
+ "paddw %%mm0, %%mm7\n"
+
+ "movq %%mm1, %%mm0\n"
+ "pmullw V_BLUE, %%mm0\n"
+ "paddw %%mm0, %%mm7\n"
+
+ "psrlw $7, %%mm7\n" // V3V2V1V0 -> mm7
+ "paddw OFFSETBX,%%mm7\n"
+ "pand CLEARX, %%mm7\n"
+
+ "pxor %%mm0, %%mm0\n"
+ "packuswb %%mm0, %%mm7\n"
+ "movd %%mm7, (%3)\n" // V3V2V1V0 -> lum
+ "add $4, %3\n"
+
+ "add $16, %0\n"
+
+ "sub $8, %4\n"
+ "jnz 1b\n"
+
+ "emms\n"
+
+ :
+ : "r" (rgb), "r" (lum), "r" (cr), "r" (cb), "m" (pixel)
+
+ );
+}
+
+void rgb2y16bit_mmx_row(unsigned char* rgbSource,
+ unsigned char* lum, int pixel)
+{
+ unsigned int buf[16];
+
+ // 36%3 = TEMP0
+ // 44%3 = TEMPY
+
+ __asm__ __volatile__ (
+ "1:\n"
+
+ // unpack hicolor ( pixel 1 - 4)
+ "movq (%0), %%mm0\n"
+
+ "movq %%mm0, %%mm1\n"
+ "pand KEEPR, %%mm1\n"
+ "psrlq $8, %%mm1\n" // B3B2B1B0 -> mm1
+ "movq %%mm0, %%mm2\n"
+ "pand KEEPG, %%mm2\n"
+ "psrlq $3, %%mm2\n" // G3G2G1G0 -> mm2
+ "movq %%mm0, %%mm3\n"
+ "pand KEEPB, %%mm3\n"
+ "psllq $3, %%mm3\n" // G3G2G1G0 -> mm3
+
+ "movq %%mm2, %%mm0\n"
+ "punpcklbw %%mm1, %%mm2\n"
+ "punpckhbw %%mm1, %%mm0\n"
+
+ "pxor %%mm5, %%mm5\n"
+ "movq %%mm3, %%mm4\n"
+ "punpcklbw %%mm5, %%mm3\n"
+ "punpckhbw %%mm5, %%mm4\n"
+
+ "psllq $8, %%mm2\n"
+ "por %%mm2, %%mm3\n" // 0B1G1R10B0G0G0 -> mm3
+ "psllq $8, %%mm0\n"
+ "por %%mm0, %%mm4\n" // 0B3G3R30B2G2G2 -> mm4
+
+ "movq %%mm3, %3\n"
+ "movq %%mm4, 8%3\n"
+
+ // next 4 pixels ------------------------------
+
+ "movq 8(%0), %%mm0\n"
+
+ "movq %%mm0, %%mm1\n"
+ "pand KEEPR, %%mm1\n"
+ "psrlq $8, %%mm1\n" // B3B2B1B0 -> mm1
+ "movq %%mm0, %%mm2\n"
+ "pand KEEPG, %%mm2\n"
+ "psrlq $3, %%mm2\n" // G3G2G1G0 -> mm2
+ "movq %%mm0, %%mm3\n"
+ "pand KEEPB, %%mm3\n"
+ "psllq $3, %%mm3\n" // G3G2G1G0 -> mm3
+
+ "movq %%mm2, %%mm0\n"
+ "punpcklbw %%mm1, %%mm2\n"
+ "punpckhbw %%mm1, %%mm0\n"
+
+ "pxor %%mm5, %%mm5\n"
+ "movq %%mm3, %%mm4\n"
+ "punpcklbw %%mm5, %%mm3\n"
+ "punpckhbw %%mm5, %%mm4\n"
+
+ "psllq $8, %%mm2\n"
+ "por %%mm2, %%mm3\n" // 0B1G1R10B0G0G0 -> mm3
+ "psllq $8, %%mm0\n"
+ "por %%mm0, %%mm4\n" // 0B3G3R30B2G2G2 -> mm4
+
+ "movq %%mm3, 16%3\n"
+ "movq %%mm4, 24%3\n"
+
+ "add $16, %0\n"
+
+ // standard algorithm --------------------------------------------------
+
+ // pack rgb
+ // was: "movq (%0), %%mm1\n" // load G2R2B1G1R1B0G0R0
+ // ------------------------------
+ // (uses: mm0, mm1)
+ "movd 8%3, %%mm0\n"
+ "psllq $24, %%mm0\n"
+ "movd 4%3, %%mm1\n"
+ "por %%mm1, %%mm0\n"
+ "psllq $24, %%mm0\n"
+ "movd %3, %%mm1\n"
+ "por %%mm0, %%mm1\n"
+ // ------------------------------
+
+ "pxor %%mm6, %%mm6\n" // 0 -> mm6
+ "movq %%mm1, %%mm0\n" // G2R2B1G1R1B0G0R0 -> mm0
+ "psrlq $16, %%mm1\n" // 00G2R2B1G1R1B0 -> mm1
+ "punpcklbw ZEROSX, %%mm0\n" // R1B0G0R0 -> mm0
+ "movq %%mm1, %%mm7\n" // 00G2R2B1G1R1B0 -> mm7
+ "punpcklbw ZEROSX, %%mm1\n" // B1G1R1B0 -> mm1
+ "movq %%mm0, %%mm2\n" // R1B0G0R0 -> mm2
+ "pmaddwd YR0GRX, %%mm0\n" // yrR1,ygG0+yrR0 -> mm0
+ "movq %%mm1, %%mm3\n" // B1G1R1B0 -> mm3
+ "pmaddwd YBG0BX, %%mm1\n" // ybB1+ygG1,ybB0 -> mm1
+ "movq %%mm2, %%mm4\n" // R1B0G0R0 -> mm4
+ "movq %%mm3, %%mm5\n" // B1G1R1B0 -> mm5
+ "punpckhbw %%mm6, %%mm7\n" // 00G2R2 -> mm7
+ "paddd %%mm1, %%mm0\n" // Y1Y0 -> mm0
+
+ // pack rgb
+ // was: "movq 8(%0),%%mm1\n" // R5B4G4R4B3G3R3B2 -> mm1
+ // ------------------------------
+ // (uses: mm1, mm6)
+ "movd 20%3, %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 16%3, %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 12%3, %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ "psllq $8, %%mm1\n"
+ "movd 8%3, %%mm6\n"
+ "psrlq $16, %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ // ------------------------------
+
+ "movq %%mm1, %%mm6\n" // R5B4G4R4B3G3R3B2 -> mm6
+ "punpcklbw ZEROSX, %%mm1\n" // B3G3R3B2 -> mm1
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm1, %%mm5\n" // B3G3R3B2 -> mm5
+ "psllq $32, %%mm1\n" // R3B200 -> mm1
+
+ "paddd %%mm7, %%mm1\n" // R3B200+00G2R2=R3B2G2R2->mm1
+
+ "punpckhbw ZEROSX, %%mm6\n" // R5B4G4R3 -> mm6
+ "movq %%mm1, %%mm3\n" // R3B2G2R2 -> mm3
+
+ "pmaddwd YR0GRX, %%mm1\n" // yrR3,ygG2+yrR2 -> mm1
+ "movq %%mm5, %%mm7\n" // B3G3R3B2 -> mm7
+
+ "pmaddwd YBG0BX, %%mm5\n" // ybB3+ygG3,ybB2 -> mm5
+ "psrad $15, %%mm0\n" // 32-bit scaled Y1Y0 -> mm0
+
+ "movq %%mm6, 36%3\n" // R5B4G4R4 -> TEMP0
+ "movq %%mm3, %%mm6\n" // R3B2G2R2 -> mm6
+
+ "paddd %%mm5, %%mm1\n" // Y3Y2 -> mm1
+ "movq %%mm7, %%mm5\n" // B3G3R3B2 -> mm5
+ "psrad $15, %%mm1\n" // 32-bit scaled Y3Y2 -> mm1
+
+ "packssdw %%mm1, %%mm0\n" // Y3Y2Y1Y0 -> mm0
+
+ //----------------------------------------------------------------------
+
+ // pack rgb
+ // was: "movq 16(%0), %%mm1\n" // B7G7R7B6G6R6B5G5 -> mm1
+ // ------------------------------
+ // (uses: mm1, mm7)
+ "movd 28%3, %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 24%3, %%mm7\n"
+ "por %%mm7, %%mm1\n"
+ "psllq $16, %%mm1\n"
+ "movd 20%3, %%mm7\n"
+ "psrlq $8, %%mm7\n"
+ "por %%mm7, %%mm1\n"
+ // ------------------------------
+
+ "movq %%mm1, %%mm7\n" // B7G7R7B6G6R6B5G5 -> mm1
+
+ "psllq $16, %%mm7\n" // R7B6G6R6B5G500 -> mm7
+
+ "movq %%mm7, %%mm5\n" // R7B6G6R6B5G500 -> mm5
+
+ "movq %%mm0, 44%3\n" // 32-bit scaled Y3Y2Y1Y0 -> TEMPY
+
+ "movq 36%3, %%mm0\n" // R5B4G4R4 -> mm0
+
+ "punpcklbw ZEROSX, %%mm7\n" // B5G500 -> mm7
+ "movq %%mm0, %%mm6\n" // R5B4G4R4 -> mm6
+
+ "psrlq $32, %%mm0\n" // 00R5B4 -> mm0
+
+ "paddw %%mm0, %%mm7\n" // B5G5R5B4 -> mm7
+ "movq %%mm6, %%mm2\n" // B5B4G4R4 -> mm2
+
+ "pmaddwd YR0GRX, %%mm2\n" // yrR5,ygG4+yrR4 -> mm2
+
+ "pmaddwd YBG0BX, %%mm7\n" // ybB5+ygG5,ybB4 -> mm7
+
+ //----------------------------------------------------------------------
+ "paddd %%mm7, %%mm2\n" // Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "pxor %%mm7, %%mm7\n" // 0 -> mm7
+
+ "punpckhbw %%mm7, %%mm1\n" // B7G7R7B6 -> mm1
+
+ "movq %%mm1, %%mm6\n" // B7G7R7B6 -> mm6
+
+ "pmaddwd YBG0BX, %%mm6\n" // ybB7+ygG7,ybB6 -> mm6
+ "punpckhbw %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "pmaddwd YR0GRX, %%mm5\n" // yrR7,ygG6+yrR6 -> mm5
+
+ //----------------------------------------------------------------------
+
+ "psrad $15, %%mm2\n" // 32-bit scaled Y5Y4 -> mm2
+
+ "paddd %%mm5, %%mm6\n" // Y7Y6 -> mm6
+ "psrad $15, %%mm6\n" // 32-bit scaled Y7Y6 -> mm6
+
+ "packssdw %%mm6, %%mm2\n" // Y7Y6Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "movq 44%3, %%mm6\n" // 32-bit scaled Y3Y2Y1Y0 -> mm6
+ "packuswb %%mm2, %%mm6\n" // all 8 Y values -> mm6
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm6, (%1)\n" // store Y
+
+ "add $8, %1\n"
+
+ "sub $8, %2\n"
+ "jnz 1b\n"
+ "emms\n"
+
+ :
+ : "r" (rgbSource), "r" (lum), "m" (pixel), "m" (buf[0])
+
+ );
+}
+
+void rgb2y16bit_mmx_row_fast(unsigned char* rgb, unsigned char* lum, int pixel)
+{
+ __asm__ __volatile__ (
+ "1:\n"
+
+ // unpack hicolor ( pixel 1 - 4)
+ "movq (%0), %%mm0\n"
+
+ "movq %%mm0, %%mm1\n"
+ "pand KEEPR, %%mm1\n"
+ "psrlq $11, %%mm1\n" // B3B2B1B0 -> mm1
+
+ "movq %%mm0, %%mm2\n"
+ "pand KEEPG, %%mm2\n"
+ "psrlq $5, %%mm2\n" // G3G2G1G0 -> mm2
+ "movq %%mm0, %%mm3\n"
+ "pand KEEPB, %%mm3\n" // R3R2R1R0 -> mm3
+
+ // calculate Y
+ "movq %%mm3, %%mm4\n"
+ "pmullw Y_RED, %%mm4\n"
+
+ "movq %%mm2, %%mm5\n"
+ "pmullw Y_GREEN, %%mm5\n"
+ "paddw %%mm5, %%mm4\n"
+
+ "movq %%mm1, %%mm6\n"
+ "pmullw Y_BLUE, %%mm6\n"
+ "paddw %%mm6, %%mm4\n"
+
+ "psrlw $7, %%mm4\n" // Y3Y2Y1Y0 -> mm4
+
+ "pxor %%mm5, %%mm5\n"
+ "packuswb %%mm5, %%mm4\n"
+
+ "movd %%mm4, (%1)\n"
+ "add $4, %1\n"
+
+ "add $8, %0\n"
+
+ "sub $4, %2\n"
+ "jnz 1b\n"
+
+ "emms\n"
+
+ :
+ : "r" (rgb), "r" (lum), "m" (pixel)
+ );
+}
+
+
+#endif
+// INTEL
+
+
diff --git a/mpeglib/lib/util/render/dither2YUV/rgb2yuv16.h b/mpeglib/lib/util/render/dither2YUV/rgb2yuv16.h
new file mode 100644
index 00000000..7e4d6508
--- /dev/null
+++ b/mpeglib/lib/util/render/dither2YUV/rgb2yuv16.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ rgb2yuv16.h - description
+ -------------------
+ begin : Tue Nov 2 2000
+ copyright : (C) 2000 by Christian Gerlach
+ email : cgerlach@rhrk.uni-kl.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef __RGB2YUV16_H
+#define __RGB2YUV16_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "../yuvPicture.h"
+#include "rgb2yuvdefs.h"
+
+// slow C implementation
+void rgb2yuv16bit(unsigned char* rgbSource,
+ unsigned char* destLum,
+ unsigned char* destCr,
+ unsigned char* destCb,int height, int width);
+
+
+
+//
+// We compile with MMX if we are on INTEL arch
+// (this does not mean that we really support MMX,
+// this is a seperate/runtime check)
+//
+
+#ifdef INTEL
+
+void rgb2yuv16bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width);
+
+void rgb2yuv16bit_mmx_fast(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width);
+
+void rgb2yuv16bit_mmx422_row(unsigned char* rgb,
+ unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel);
+
+void rgb2y16bit_mmx_row(unsigned char* rgbSource,
+ unsigned char* lum, int pixel);
+
+void rgb2yuv16bit_mmx422_row_fast(unsigned char* rgb,
+ unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel);
+
+void rgb2y16bit_mmx_row_fast(unsigned char* rgb,
+ unsigned char* lum, int pixel);
+
+
+#endif
+// INTEL
+
+
+
+#endif
diff --git a/mpeglib/lib/util/render/dither2YUV/rgb2yuv32.cpp b/mpeglib/lib/util/render/dither2YUV/rgb2yuv32.cpp
new file mode 100644
index 00000000..3e246e25
--- /dev/null
+++ b/mpeglib/lib/util/render/dither2YUV/rgb2yuv32.cpp
@@ -0,0 +1,1143 @@
+/***************************************************************************
+ rgb2yuv32.cpp - description
+ -------------------
+ begin : Tue Nov 2 2000
+ copyright : (C) 2000 by Christian Gerlach
+ email : cgerlach@rhrk.uni-kl.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "rgb2yuv32.h"
+#include <iostream>
+
+void rgb2yuv32(unsigned char* rgb, unsigned char* dest)
+{
+ dest[0] = Y_RGB(rgb[0], rgb[1], rgb[2]);
+ dest[1] = U_RGB(rgb[0], rgb[1], rgb[2]);
+ dest[2] = V_RGB(rgb[0], rgb[1], rgb[2]);
+}
+
+void rgb2yuv24bit(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width) {
+ int width2 = width / 2;
+ int height2 = height / 2;
+ int r, g, b, row, col;
+
+ for (row=0 ; row<height2 ; row++) {
+ for (col=0 ; col<width2 ; col++) {
+ r = *rgbSource++;
+ g = *rgbSource++;
+ b = *rgbSource++;
+
+ *lum++ = Y_RGB(r, g, b);
+ *cr++ = U_RGB(r, g, b);
+ *cb++ = V_RGB(r, g, b);
+
+ r = *rgbSource++;
+ g = *rgbSource++;
+ b = *rgbSource++;
+
+ *lum++ = Y_RGB(r, g, b);
+ }
+ for (col=0 ; col<width ; col++) {
+ r = *rgbSource++;
+ g = *rgbSource++;
+ b = *rgbSource++;
+
+ *lum++ = Y_RGB(r, g, b);
+ }
+ }
+}
+
+void rgb2yuv32bit(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width) {
+
+ int width2 = width / 2;
+ int height2 = height / 2;
+ int r, g, b, row, col;
+
+ for (row=0 ; row<height2 ; row++) {
+ for (col=0 ; col<width2 ; col++) {
+ r = *rgbSource++;
+ g = *rgbSource++;
+ b = *rgbSource++;
+ rgbSource ++;
+
+ *lum++ = Y_RGB(r, g, b);
+ *cr++ = U_RGB(r, g, b);
+ *cb++ = V_RGB(r, g, b);
+
+ r = *rgbSource++;
+ g = *rgbSource++;
+ b = *rgbSource++;
+ rgbSource++;
+
+ *lum++ = Y_RGB(r, g, b);
+ }
+ for (col=0 ; col<width ; col++) {
+ r = *rgbSource++;
+ g = *rgbSource++;
+ b = *rgbSource++;
+ rgbSource ++;
+
+ *lum++ = Y_RGB(r, g, b);
+ }
+ }
+}
+
+#ifndef INTEL
+void rgb2yuv24bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width) {
+ std::cout << "RGB->YUV render not compiled for INTEL"<<std::endl;
+ exit(0);
+}
+
+void rgb2yuv32bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width) {
+ std::cout << "RGB->YUV render not compiled for INTEL"<<std::endl;
+ exit(0);
+}
+
+#endif
+
+#ifdef INTEL
+
+void rgb2yuv24bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width) {
+ int width2 = width / 2;
+ int height2 = height / 2;
+ int row;
+ int bytesPerLine = width * 3;
+
+ for (row=0 ; row<height2 ; row++) {
+ rgb2yuv24bit_mmx422_row(rgbSource, lum, cr, cb, width);
+ rgbSource += bytesPerLine;
+ lum += width;
+ cr += width2;
+ cb += width2;
+
+ rgb2y24bit_mmx_row(rgbSource, lum, width);
+ rgbSource += bytesPerLine;
+ lum += width;
+ }
+}
+
+void rgb2yuv32bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width) {
+
+
+ int width2 = width / 2;
+ int height2 = height / 2;
+ int bytesPerLine = width * 4;
+
+ for (int row=0 ; row<height2 ; row++) {
+ rgb2yuv32bit_mmx422_row(rgbSource, lum,cr, cb, width);
+ rgbSource += bytesPerLine;
+ lum += width;
+ cr += width2;
+ cb += width2;
+
+ rgb2y32bit_mmx_row(rgbSource, lum, width);
+ rgbSource += bytesPerLine;
+ lum += width;
+ }
+}
+
+void rgb2yuv24bit_mmx444_row(unsigned char* rgb, unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel)
+{
+ unsigned int buf[8];
+
+ // %5 = TEMP0
+ // 8%5 = TEMPY
+ // 16%5 = TEMPU
+ // 24%5 = TEMPV
+
+ __asm__ __volatile__ (
+ "1:\n"
+
+ "movq (%0), %%mm1\n" // load G2R2B1G1R1B0G0R0
+ "pxor %%mm6, %%mm6\n" // 0 -> mm6
+ "movq %%mm1, %%mm0\n" // G2R2B1G1R1B0G0R0 -> mm0
+ "psrlq $16, %%mm1\n" // 00G2R2B1G1R1B0 -> mm1
+ "punpcklbw ZEROSX, %%mm0\n" // R1B0G0R0 -> mm0
+ "movq %%mm1, %%mm7\n" // 00G2R2B1G1R1B0 -> mm7
+ "punpcklbw ZEROSX, %%mm1\n" // B1G1R1B0 -> mm1
+ "movq %%mm0, %%mm2\n" // R1B0G0R0 -> mm2
+ "pmaddwd YR0GRX, %%mm0\n" // yrR1,ygG0+yrR0 -> mm0
+ "movq %%mm1, %%mm3\n" // B1G1R1B0 -> mm3
+ "pmaddwd YBG0BX, %%mm1\n" // ybB1+ygG1,ybB0 -> mm1
+ "movq %%mm2, %%mm4\n" // R1B0G0R0 -> mm4
+ "pmaddwd UR0GRX, %%mm2\n" // urR1,ugG0+urR0 -> mm2
+ "movq %%mm3, %%mm5\n" // B1G1R1B0 -> mm5
+ "pmaddwd UBG0BX, %%mm3\n" // ubB1+ugG1,ubB0 -> mm3
+ "punpckhbw %%mm6, %%mm7\n" // 00G2R2 -> mm7
+ "pmaddwd VR0GRX, %%mm4\n" // vrR1,vgG0+vrR0 -> mm4
+ "paddd %%mm1, %%mm0\n" // Y1Y0 -> mm0
+
+ "pmaddwd VBG0BX, %%mm5\n" // vbB1+vgG1,vbB0 -> mm5
+
+ "movq 8(%0),%%mm1\n" // load G2R2B1G1R1B0G0R0
+ "paddd %%mm3, %%mm2\n" // U1U0 -> mm2
+
+ "movq %%mm1, %%mm6\n" // R5B4G4R4B3G3R3B2 -> mm6
+ "punpcklbw ZEROSX, %%mm1\n" // B3G3R3B2 -> mm1
+ "paddd %%mm5, %%mm4\n" // V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm1, %%mm5\n" // B3G3R3B2 -> mm5
+ "psllq $32, %%mm1\n" // R3B200 -> mm1
+
+ "paddd %%mm7, %%mm1\n" // R3B200+00G2R2=R3B2G2R2->mm1
+
+ "punpckhbw ZEROSX, %%mm6\n" // R5B4G4R3 -> mm6
+ "movq %%mm1, %%mm3\n" // R3B2G2R2 -> mm3
+
+ "pmaddwd YR0GRX, %%mm1\n" // yrR3,ygG2+yrR2 -> mm1
+ "movq %%mm5, %%mm7\n" // B3G3R3B2 -> mm7
+
+ "pmaddwd YBG0BX, %%mm5\n" // ybB3+ygG3,ybB2 -> mm5
+ "psrad $15, %%mm0\n" // 32-bit scaled Y1Y0 -> mm0
+
+ "movq %%mm6, %5\n" // R5B4G4R4 -> TEMP0
+ "movq %%mm3, %%mm6\n" // R3B2G2R2 -> mm6
+ "pmaddwd UR0GRX, %%mm6\n" // urR3,ugG2+urR2 -> mm6
+ "psrad $15, %%mm2\n" // 32-bit scaled U1U0 -> mm2
+
+ "paddd %%mm5, %%mm1\n" // Y3Y2 -> mm1
+ "movq %%mm7, %%mm5\n" // B3G3R3B2 -> mm5
+ "pmaddwd UBG0BX, %%mm7\n" // ubB3+ugG3,ubB2
+ "psrad $15, %%mm1\n" // 32-bit scaled Y3Y2 -> mm1
+
+ "pmaddwd VR0GRX, %%mm3\n" // vrR3,vgG2+vgR2
+ "packssdw %%mm1, %%mm0\n" // Y3Y2Y1Y0 -> mm0
+
+ "pmaddwd VBG0BX, %%mm5\n" // vbB3+vgG3,vbB2 -> mm5
+ "psrad $15, %%mm4\n" // 32-bit scaled V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq 16(%0), %%mm1\n" // B7G7R7B6G6R6B5G5 -> mm7
+ "paddd %%mm7, %%mm6\n" // U3U2 -> mm6
+
+ "movq %%mm1, %%mm7\n" // B7G7R7B6G6R6B5G5 -> mm1
+ "psrad $15, %%mm6\n" // 32-bit scaled U3U2 -> mm6
+
+ "paddd %%mm5, %%mm3\n" // V3V2 -> mm3
+ "psllq $16, %%mm7\n" // R7B6G6R6B5G500 -> mm7
+
+ "movq %%mm7, %%mm5\n" // R7B6G6R6B5G500 -> mm5
+ "psrad $15, %%mm3\n" // 32-bit scaled V3V2 -> mm3
+
+ "movq %%mm0, 8%5\n" // 32-bit scaled Y3Y2Y1Y0 -> TEMPY
+ "packssdw %%mm6, %%mm2\n" // 32-bit scaled U3U2U1U0 -> mm2
+
+ "movq %5, %%mm0\n" // R5B4G4R4 -> mm0
+
+ "punpcklbw ZEROSX, %%mm7\n" // B5G500 -> mm7
+ "movq %%mm0, %%mm6\n" // R5B4G4R4 -> mm6
+
+ "movq %%mm2, 16%5\n" // 32-bit scaled U3U2U1U0 -> TEMPU
+ "psrlq $32, %%mm0\n" // 00R5B4 -> mm0
+
+ "paddw %%mm0, %%mm7\n" // B5G5R5B4 -> mm7
+ "movq %%mm6, %%mm2\n" // B5B4G4R4 -> mm2
+
+ "pmaddwd YR0GRX, %%mm2\n" // yrR5,ygG4+yrR4 -> mm2
+ "movq %%mm7, %%mm0\n" // B5G5R5B4 -> mm0
+
+ "pmaddwd YBG0BX, %%mm7\n" // ybB5+ygG5,ybB4 -> mm7
+ "packssdw %%mm3, %%mm4\n" // 32-bit scaled V3V2V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm4, 24%5\n" // (V3V2V1V0)/256 -> mm4
+
+ "movq %%mm6, %%mm4\n" // B5B4G4R4 -> mm4
+
+ "pmaddwd UR0GRX, %%mm6\n" // urR5,ugG4+urR4
+ "movq %%mm0, %%mm3\n" // B5G5R5B4 -> mm0
+
+ "pmaddwd UBG0BX, %%mm0\n" // ubB5+ugG5,ubB4
+ "paddd %%mm7, %%mm2\n" // Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "pmaddwd VR0GRX, %%mm4\n" // vrR5,vgG4+vrR4 -> mm4
+ "pxor %%mm7, %%mm7\n" // 0 -> mm7
+
+ "pmaddwd VBG0BX, %%mm3\n" // vbB5+vgG5,vbB4 -> mm3
+ "punpckhbw %%mm7, %%mm1\n" // B7G7R7B6 -> mm1
+
+ "paddd %%mm6, %%mm0\n" // U5U4 -> mm0
+ "movq %%mm1, %%mm6\n" // B7G7R7B6 -> mm6
+
+ "pmaddwd YBG0BX, %%mm6\n" // ybB7+ygG7,ybB6 -> mm6
+ "punpckhbw %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "movq %%mm5, %%mm7\n" // R7B6G6R6 -> mm7
+ "paddd %%mm4, %%mm3\n" // V5V4 -> mm3
+
+ "pmaddwd YR0GRX, %%mm5\n" // yrR7,ygG6+yrR6 -> mm5
+ "movq %%mm1, %%mm4\n" // B7G7R7B6 -> mm4
+
+ "pmaddwd UBG0BX, %%mm4\n" // ubB7+ugG7,ubB6 -> mm4
+ "psrad $15, %%mm0\n" // 32-bit scaled U5U4 -> %%mm0
+
+ //----------------------------------------------------------------------
+
+ "paddd OFFSETWX, %%mm0\n" // add offset to U5U4 -> mm0
+ "psrad $15, %%mm2\n" // 32-bit scaled Y5Y4 -> mm2
+
+ "paddd %%mm5, %%mm6\n" // Y7Y6 -> mm6
+ "movq %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "pmaddwd UR0GRX, %%mm7\n" // urR7,ugG6+ugR6 -> mm7
+ "psrad $15, %%mm3\n" // 32-bit scaled V5V4 -> mm3
+
+ "pmaddwd VBG0BX, %%mm1\n" // vbB7+vgG7,vbB6 -> mm1
+ "psrad $15, %%mm6\n" // 32-bit scaled Y7Y6 -> mm6
+
+ "paddd OFFSETDX, %%mm4\n" // add offset to U7U6
+ "packssdw %%mm6, %%mm2\n" // Y7Y6Y5Y4 -> mm2
+
+ "pmaddwd VR0GRX, %%mm5\n" // vrR7,vgG6+vrR6 -> mm5
+ "paddd %%mm4, %%mm7\n" // U7U6 -> mm7
+
+ "psrad $15, %%mm7\n" // 32-bit scaled U7U6 -> mm7
+
+ //----------------------------------------------------------------------
+
+ "movq 8%5, %%mm6\n" // 32-bit scaled Y3Y2Y1Y0 -> mm6
+ "packssdw %%mm7, %%mm0\n" // 32-bit scaled U7U6U5U4 -> mm0
+
+ "movq 16%5, %%mm4\n" // 32-bit scaled U3U2U1U0 -> mm4
+ "packuswb %%mm2, %%mm6\n" // all 8 Y values -> mm6
+
+ "movq OFFSETBX, %%mm7\n" // 128,128,128,128 -> mm7
+ "paddd %%mm5, %%mm1\n" // V7V6 -> mm1
+
+ "paddw %%mm7, %%mm4\n" // add offset to U3U2U1U0/256
+ "psrad $15, %%mm1\n" // 32-bit scaled V7V6 -> mm1
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm6, (%1)\n" // store Y
+ "packuswb %%mm0, %%mm4\n" // all 8 U values -> mm4
+
+ "movq 24%5, %%mm5\n" // 32-bit scaled V3V2V1V0 -> mm5
+ "packssdw %%mm1, %%mm3\n" // V7V6V5V4 -> mm3
+ "paddw %%mm7, %%mm5\n" // add offset to V3V2V1V0
+ "paddw %%mm7, %%mm3\n" // add offset to V7V6V5V4
+
+ "movq %%mm4, (%2)\n" // store U
+ "packuswb %%mm3, %%mm5\n" // ALL 8 V values -> mm5
+
+ "movq %%mm5, (%3)\n" // store V
+
+ "sub $8, %4\n"
+ "jnz 1b\n"
+ "emms\n"
+
+ :
+ : "r" (rgb), "r" (lum), "r" (cr), "r" (cb), "m" (pixel), "m" (buf[0])
+ );
+}
+
+void rgb2yuv24bit_mmx422_row(unsigned char* rgb, unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel)
+{
+ unsigned int buf[8];
+
+ // %5 = TEMP0
+ // 8%5 = TEMPY
+ // 16%5 = TEMPU
+ // 24%5 = TEMPV
+
+ __asm__ __volatile__ (
+ "1:\n"
+
+ "movq (%0), %%mm1\n" // load G2R2B1G1R1B0G0R0
+ "pxor %%mm6, %%mm6\n" // 0 -> mm6
+ "movq %%mm1, %%mm0\n" // G2R2B1G1R1B0G0R0 -> mm0
+ "psrlq $16, %%mm1\n" // 00G2R2B1G1R1B0 -> mm1
+ "punpcklbw ZEROSX, %%mm0\n" // R1B0G0R0 -> mm0
+ "movq %%mm1, %%mm7\n" // 00G2R2B1G1R1B0 -> mm7
+ "punpcklbw ZEROSX, %%mm1\n" // B1G1R1B0 -> mm1
+ "movq %%mm0, %%mm2\n" // R1B0G0R0 -> mm2
+ "pmaddwd YR0GRX, %%mm0\n" // yrR1,ygG0+yrR0 -> mm0
+
+ "movq %%mm1, %%mm3\n" // B1G1R1B0 -> mm3
+ "pmaddwd YBG0BX, %%mm1\n" // ybB1+ygG1,ybB0 -> mm1
+ "movq %%mm2, %%mm4\n" // R1B0G0R0 -> mm4
+ "pmaddwd UR0GRX, %%mm2\n" // urR1,ugG0+urR0 -> mm2
+ "movq %%mm3, %%mm5\n" // B1G1R1B0 -> mm5
+ "pmaddwd UBG0BX, %%mm3\n" // ubB1+ugG1,ubB0 -> mm3
+ "punpckhbw %%mm6, %%mm7\n" // 00G2R2 -> mm7
+ "pmaddwd VR0GRX, %%mm4\n" // vrR1,vgG0+vrR0 -> mm4
+ "paddd %%mm1, %%mm0\n" // Y1Y0 -> mm0
+
+ "pmaddwd VBG0BX, %%mm5\n" // vbB1+vgG1,vbB0 -> mm5
+
+ "movq 8(%0),%%mm1\n" // load G2R2B1G1R1B0G0R0
+ "paddd %%mm3, %%mm2\n" // U1U0 -> mm2
+
+ "movq %%mm1, %%mm6\n" // R5B4G4R4B3G3R3B2 -> mm6
+ "punpcklbw ZEROSX, %%mm1\n" // B3G3R3B2 -> mm1
+ "paddd %%mm5, %%mm4\n" // V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm1, %%mm5\n" // B3G3R3B2 -> mm5
+ "psllq $32, %%mm1\n" // R3B200 -> mm1
+
+ "paddd %%mm7, %%mm1\n" // R3B200+00G2R2=R3B2G2R2->mm1
+
+ "punpckhbw ZEROSX, %%mm6\n" // R5B4G4R3 -> mm6
+ "movq %%mm1, %%mm3\n" // R3B2G2R2 -> mm3
+
+ "pmaddwd YR0GRX, %%mm1\n" // yrR3,ygG2+yrR2 -> mm1
+ "movq %%mm5, %%mm7\n" // B3G3R3B2 -> mm7
+
+ "pmaddwd YBG0BX, %%mm5\n" // ybB3+ygG3,ybB2 -> mm5
+ "psrad $15, %%mm0\n" // 32-bit scaled Y1Y0 -> mm0
+
+ "movq %%mm6, %5\n" // R5B4G4R4 -> TEMP0
+ "movq %%mm3, %%mm6\n" // R3B2G2R2 -> mm6
+ "pmaddwd UR0GRX, %%mm6\n" // urR3,ugG2+urR2 -> mm6
+ "psrad $15, %%mm2\n" // 32-bit scaled U1U0 -> mm2
+
+ "paddd %%mm5, %%mm1\n" // Y3Y2 -> mm1
+ "movq %%mm7, %%mm5\n" // B3G3R3B2 -> mm5
+ "pmaddwd UBG0BX, %%mm7\n" // ubB3+ugG3,ubB2
+ "psrad $15, %%mm1\n" // 32-bit scaled Y3Y2 -> mm1
+
+ "pmaddwd VR0GRX, %%mm3\n" // vrR3,vgG2+vgR2
+ "packssdw %%mm1, %%mm0\n" // Y3Y2Y1Y0 -> mm0
+
+ "pmaddwd VBG0BX, %%mm5\n" // vbB3+vgG3,vbB2 -> mm5
+ "psrad $15, %%mm4\n" // 32-bit scaled V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq 16(%0), %%mm1\n" // B7G7R7B6G6R6B5G5 -> mm7
+ "paddd %%mm7, %%mm6\n" // U3U2 -> mm6
+
+ "movq %%mm1, %%mm7\n" // B7G7R7B6G6R6B5G5 -> mm1
+ "psrad $15, %%mm6\n" // 32-bit scaled U3U2 -> mm6
+
+ "paddd %%mm5, %%mm3\n" // V3V2 -> mm3
+ "psllq $16, %%mm7\n" // R7B6G6R6B5G500 -> mm7
+
+ "movq %%mm7, %%mm5\n" // R7B6G6R6B5G500 -> mm5
+ "psrad $15, %%mm3\n" // 32-bit scaled V3V2 -> mm3
+
+ "movq %%mm0, 8%5\n" // 32-bit scaled Y3Y2Y1Y0 -> TEMPY
+ "packssdw %%mm6, %%mm2\n" // 32-bit scaled U3U2U1U0 -> mm2
+
+ "movq %5, %%mm0\n" // R5B4G4R4 -> mm0
+
+ "punpcklbw ZEROSX, %%mm7\n" // B5G500 -> mm7
+ "movq %%mm0, %%mm6\n" // R5B4G4R4 -> mm6
+
+ "movq %%mm2, 16%5\n" // 32-bit scaled U3U2U1U0 -> TEMPU
+ "psrlq $32, %%mm0\n" // 00R5B4 -> mm0
+
+ "paddw %%mm0, %%mm7\n" // B5G5R5B4 -> mm7
+ "movq %%mm6, %%mm2\n" // B5B4G4R4 -> mm2
+
+ "pmaddwd YR0GRX, %%mm2\n" // yrR5,ygG4+yrR4 -> mm2
+ "movq %%mm7, %%mm0\n" // B5G5R5B4 -> mm0
+
+ "pmaddwd YBG0BX, %%mm7\n" // ybB5+ygG5,ybB4 -> mm7
+ "packssdw %%mm3, %%mm4\n" // 32-bit scaled V3V2V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm4, 24%5\n" // (V3V2V1V0)/256 -> mm4
+
+ "movq %%mm6, %%mm4\n" // B5B4G4R4 -> mm4
+
+ "pmaddwd UR0GRX, %%mm6\n" // urR5,ugG4+urR4
+ "movq %%mm0, %%mm3\n" // B5G5R5B4 -> mm0
+
+ "pmaddwd UBG0BX, %%mm0\n" // ubB5+ugG5,ubB4
+ "paddd %%mm7, %%mm2\n" // Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "pmaddwd VR0GRX, %%mm4\n" // vrR5,vgG4+vrR4 -> mm4
+ "pxor %%mm7, %%mm7\n" // 0 -> mm7
+
+ "pmaddwd VBG0BX, %%mm3\n" // vbB5+vgG5,vbB4 -> mm3
+ "punpckhbw %%mm7, %%mm1\n" // B7G7R7B6 -> mm1
+
+ "paddd %%mm6, %%mm0\n" // U5U4 -> mm0
+ "movq %%mm1, %%mm6\n" // B7G7R7B6 -> mm6
+
+ "pmaddwd YBG0BX, %%mm6\n" // ybB7+ygG7,ybB6 -> mm6
+ "punpckhbw %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "movq %%mm5, %%mm7\n" // R7B6G6R6 -> mm7
+ "paddd %%mm4, %%mm3\n" // V5V4 -> mm3
+
+ "pmaddwd YR0GRX, %%mm5\n" // yrR7,ygG6+yrR6 -> mm5
+ "movq %%mm1, %%mm4\n" // B7G7R7B6 -> mm4
+
+ "pmaddwd UBG0BX, %%mm4\n" // ubB7+ugG7,ubB6 -> mm4
+ "psrad $15, %%mm0\n" // 32-bit scaled U5U4 -> %%mm0
+
+ //----------------------------------------------------------------------
+
+ "paddd OFFSETWX, %%mm0\n" // add offset to U5U4 -> mm0
+ "psrad $15, %%mm2\n" // 32-bit scaled Y5Y4 -> mm2
+
+ "paddd %%mm5, %%mm6\n" // Y7Y6 -> mm6
+ "movq %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "pmaddwd UR0GRX, %%mm7\n" // urR7,ugG6+ugR6 -> mm7
+ "psrad $15, %%mm3\n" // 32-bit scaled V5V4 -> mm3
+
+ "pmaddwd VBG0BX, %%mm1\n" // vbB7+vgG7,vbB6 -> mm1
+ "psrad $15, %%mm6\n" // 32-bit scaled Y7Y6 -> mm6
+
+ "paddd OFFSETDX, %%mm4\n" // add offset to U7U6
+ "packssdw %%mm6, %%mm2\n" // Y7Y6Y5Y4 -> mm2
+
+ "pmaddwd VR0GRX, %%mm5\n" // vrR7,vgG6+vrR6 -> mm5
+ "paddd %%mm4, %%mm7\n" // U7U6 -> mm7
+
+ "psrad $15, %%mm7\n" // 32-bit scaled U7U6 -> mm7
+
+ //----------------------------------------------------------------------
+
+ "movq 8%5, %%mm6\n" // 32-bit scaled Y3Y2Y1Y0 -> mm6
+ "packssdw %%mm7, %%mm0\n" // 32-bit scaled U7U6U5U4 -> mm0
+
+ "movq 16%5, %%mm4\n" // 32-bit scaled U3U2U1U0 -> mm4
+ "packuswb %%mm2, %%mm6\n" // all 8 Y values -> mm6
+
+ "movq OFFSETBX, %%mm7\n" // 128,128,128,128 -> mm7
+ "paddd %%mm5, %%mm1\n" // V7V6 -> mm1
+
+ "paddw %%mm7, %%mm4\n" // add offset to U3U2U1U0/256
+ "psrad $15, %%mm1\n" // 32-bit scaled V7V6 -> mm1
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm6, (%1)\n" // store Y
+ "packuswb %%mm0, %%mm4\n" // all 8 U values -> mm4
+
+ "movq 24%5, %%mm5\n" // 32-bit scaled V3V2V1V0 -> mm5
+ "packssdw %%mm1, %%mm3\n" // V7V6V5V4 -> mm3
+ "paddw %%mm7, %%mm5\n" // add offset to V3V2V1V0
+ "paddw %%mm7, %%mm3\n" // add offset to V7V6V5V4
+
+ "packuswb %%mm3, %%mm5\n" // ALL 8 V values -> mm5
+
+ // pack U and V
+ "movq CLEARX, %%mm2\n"
+ "pand %%mm2, %%mm4\n"
+ "pand %%mm2, %%mm5\n"
+
+ "packuswb %%mm5, %%mm4\n"
+
+ "movd %%mm4, (%2)\n"
+ "psrlq $32, %%mm4\n"
+ "movd %%mm4, (%3)\n"
+
+ "add $24, %0\n"
+ "add $8, %1\n"
+ "add $4, %2\n"
+ "add $4, %3\n"
+
+ "sub $8, %4\n"
+ "jnz 1b\n"
+ "emms\n"
+
+ :
+ : "r" (rgb), "r" (lum), "r" (cr), "r" (cb), "m" (pixel), "m" (buf[0])
+ );
+}
+
+void rgb2yuv32bit_mmx422_row(unsigned char* rgb, unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel)
+{
+ unsigned int buf[8];
+
+ // %5 = TEMP0
+ // 8%5 = TEMPY
+ // 16%5 = TEMPU
+ // 24%5 = TEMPV
+
+ __asm__ __volatile__ (
+ "1:\n"
+
+ // pack rgb
+ // was: "movq (%0), %%mm1\n" // load G2R2B1G1R1B0G0R0
+ // ------------------------------
+ // (uses: mm0, mm1)
+ "movd 8(%0), %%mm0\n"
+ "psllq $24, %%mm0\n"
+ "movd 4(%0), %%mm1\n"
+ "por %%mm1, %%mm0\n"
+ "psllq $24, %%mm0\n"
+ "movd (%0), %%mm1\n"
+ "por %%mm0, %%mm1\n"
+ // ------------------------------
+
+ "pxor %%mm6, %%mm6\n" // 0 -> mm6
+ "movq %%mm1, %%mm0\n" // G2R2B1G1R1B0G0R0 -> mm0
+ "psrlq $16, %%mm1\n" // 00G2R2B1G1R1B0 -> mm1
+ "punpcklbw ZEROSX, %%mm0\n" // R1B0G0R0 -> mm0
+ "movq %%mm1, %%mm7\n" // 00G2R2B1G1R1B0 -> mm7
+ "punpcklbw ZEROSX, %%mm1\n" // B1G1R1B0 -> mm1
+ "movq %%mm0, %%mm2\n" // R1B0G0R0 -> mm2
+ "pmaddwd YR0GRX, %%mm0\n" // yrR1,ygG0+yrR0 -> mm0
+
+ "movq %%mm1, %%mm3\n" // B1G1R1B0 -> mm3
+ "pmaddwd YBG0BX, %%mm1\n" // ybB1+ygG1,ybB0 -> mm1
+ "movq %%mm2, %%mm4\n" // R1B0G0R0 -> mm4
+ "pmaddwd UR0GRX, %%mm2\n" // urR1,ugG0+urR0 -> mm2
+ "movq %%mm3, %%mm5\n" // B1G1R1B0 -> mm5
+ "pmaddwd UBG0BX, %%mm3\n" // ubB1+ugG1,ubB0 -> mm3
+ "punpckhbw %%mm6, %%mm7\n" // 00G2R2 -> mm7
+ "pmaddwd VR0GRX, %%mm4\n" // vrR1,vgG0+vrR0 -> mm4
+ "paddd %%mm1, %%mm0\n" // Y1Y0 -> mm0
+
+ "pmaddwd VBG0BX, %%mm5\n" // vbB1+vgG1,vbB0 -> mm5
+
+ // pack rgb
+ // was: "movq 8(%0),%%mm1\n" // R5B4G4R4B3G3R3B2 -> mm1
+ // ------------------------------
+ // (uses: mm1, mm6)
+ "movd 20(%0), %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 16(%0), %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 12(%0), %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ "psllq $8, %%mm1\n"
+ "movd 8(%0), %%mm6\n"
+ "psrlq $16, %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ // ------------------------------
+
+ "paddd %%mm3, %%mm2\n" // U1U0 -> mm2
+
+ "movq %%mm1, %%mm6\n" // R5B4G4R4B3G3R3B2 -> mm6
+ "punpcklbw ZEROSX, %%mm1\n" // B3G3R3B2 -> mm1
+ "paddd %%mm5, %%mm4\n" // V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm1, %%mm5\n" // B3G3R3B2 -> mm5
+ "psllq $32, %%mm1\n" // R3B200 -> mm1
+
+ "paddd %%mm7, %%mm1\n" // R3B200+00G2R2=R3B2G2R2->mm1
+
+ "punpckhbw ZEROSX, %%mm6\n" // R5B4G4R3 -> mm6
+ "movq %%mm1, %%mm3\n" // R3B2G2R2 -> mm3
+
+ "pmaddwd YR0GRX, %%mm1\n" // yrR3,ygG2+yrR2 -> mm1
+ "movq %%mm5, %%mm7\n" // B3G3R3B2 -> mm7
+
+ "pmaddwd YBG0BX, %%mm5\n" // ybB3+ygG3,ybB2 -> mm5
+ "psrad $15, %%mm0\n" // 32-bit scaled Y1Y0 -> mm0
+
+ "movq %%mm6, %5\n" // R5B4G4R4 -> TEMP0
+ "movq %%mm3, %%mm6\n" // R3B2G2R2 -> mm6
+ "pmaddwd UR0GRX, %%mm6\n" // urR3,ugG2+urR2 -> mm6
+ "psrad $15, %%mm2\n" // 32-bit scaled U1U0 -> mm2
+
+ "paddd %%mm5, %%mm1\n" // Y3Y2 -> mm1
+ "movq %%mm7, %%mm5\n" // B3G3R3B2 -> mm5
+ "pmaddwd UBG0BX, %%mm7\n" // ubB3+ugG3,ubB2
+ "psrad $15, %%mm1\n" // 32-bit scaled Y3Y2 -> mm1
+
+ "pmaddwd VR0GRX, %%mm3\n" // vrR3,vgG2+vgR2
+ "packssdw %%mm1, %%mm0\n" // Y3Y2Y1Y0 -> mm0
+
+ "pmaddwd VBG0BX, %%mm5\n" // vbB3+vgG3,vbB2 -> mm5
+ "psrad $15, %%mm4\n" // 32-bit scaled V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "paddd %%mm7, %%mm6\n" // U3U2 -> mm6
+
+ // pack rgb
+ // was: "movq 16(%0), %%mm1\n" // B7G7R7B6G6R6B5G5 -> mm1
+ // ------------------------------
+ // (uses: mm1, mm7)
+ "movd 28(%0), %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 24(%0), %%mm7\n"
+ "por %%mm7, %%mm1\n"
+ "psllq $16, %%mm1\n"
+ "movd 20(%0), %%mm7\n"
+ "psrlq $8, %%mm7\n"
+ "por %%mm7, %%mm1\n"
+ // ------------------------------
+
+ "movq %%mm1, %%mm7\n" // B7G7R7B6G6R6B5G5 -> mm1
+ "psrad $15, %%mm6\n" // 32-bit scaled U3U2 -> mm6
+
+ "paddd %%mm5, %%mm3\n" // V3V2 -> mm3
+ "psllq $16, %%mm7\n" // R7B6G6R6B5G500 -> mm7
+
+ "movq %%mm7, %%mm5\n" // R7B6G6R6B5G500 -> mm5
+ "psrad $15, %%mm3\n" // 32-bit scaled V3V2 -> mm3
+
+ "movq %%mm0, 8%5\n" // 32-bit scaled Y3Y2Y1Y0 -> TEMPY
+
+ "packssdw %%mm6, %%mm2\n" // 32-bit scaled U3U2U1U0 -> mm2
+
+ "movq %5, %%mm0\n" // R5B4G4R4 -> mm0
+
+ "punpcklbw ZEROSX, %%mm7\n" // B5G500 -> mm7
+ "movq %%mm0, %%mm6\n" // R5B4G4R4 -> mm6
+
+ "movq %%mm2, 16%5\n" // 32-bit scaled U3U2U1U0 -> TEMPU
+ "psrlq $32, %%mm0\n" // 00R5B4 -> mm0
+
+ "paddw %%mm0, %%mm7\n" // B5G5R5B4 -> mm7
+ "movq %%mm6, %%mm2\n" // B5B4G4R4 -> mm2
+
+ "pmaddwd YR0GRX, %%mm2\n" // yrR5,ygG4+yrR4 -> mm2
+ "movq %%mm7, %%mm0\n" // B5G5R5B4 -> mm0
+
+ "pmaddwd YBG0BX, %%mm7\n" // ybB5+ygG5,ybB4 -> mm7
+ "packssdw %%mm3, %%mm4\n" // 32-bit scaled V3V2V1V0 -> mm4
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm4, 24%5\n" // (V3V2V1V0)/256 -> mm4
+
+ "movq %%mm6, %%mm4\n" // B5B4G4R4 -> mm4
+
+ "pmaddwd UR0GRX, %%mm6\n" // urR5,ugG4+urR4
+ "movq %%mm0, %%mm3\n" // B5G5R5B4 -> mm0
+
+ "pmaddwd UBG0BX, %%mm0\n" // ubB5+ugG5,ubB4
+ "paddd %%mm7, %%mm2\n" // Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "pmaddwd VR0GRX, %%mm4\n" // vrR5,vgG4+vrR4 -> mm4
+ "pxor %%mm7, %%mm7\n" // 0 -> mm7
+
+ "pmaddwd VBG0BX, %%mm3\n" // vbB5+vgG5,vbB4 -> mm3
+ "punpckhbw %%mm7, %%mm1\n" // B7G7R7B6 -> mm1
+
+ "paddd %%mm6, %%mm0\n" // U5U4 -> mm0
+ "movq %%mm1, %%mm6\n" // B7G7R7B6 -> mm6
+
+ "pmaddwd YBG0BX, %%mm6\n" // ybB7+ygG7,ybB6 -> mm6
+ "punpckhbw %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "movq %%mm5, %%mm7\n" // R7B6G6R6 -> mm7
+ "paddd %%mm4, %%mm3\n" // V5V4 -> mm3
+
+ "pmaddwd YR0GRX, %%mm5\n" // yrR7,ygG6+yrR6 -> mm5
+ "movq %%mm1, %%mm4\n" // B7G7R7B6 -> mm4
+
+ "pmaddwd UBG0BX, %%mm4\n" // ubB7+ugG7,ubB6 -> mm4
+ "psrad $15, %%mm0\n" // 32-bit scaled U5U4 -> %%mm0
+
+ //----------------------------------------------------------------------
+
+ "paddd OFFSETWX, %%mm0\n" // add offset to U5U4 -> mm0
+ "psrad $15, %%mm2\n" // 32-bit scaled Y5Y4 -> mm2
+
+ "paddd %%mm5, %%mm6\n" // Y7Y6 -> mm6
+ "movq %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "pmaddwd UR0GRX, %%mm7\n" // urR7,ugG6+ugR6 -> mm7
+ "psrad $15, %%mm3\n" // 32-bit scaled V5V4 -> mm3
+
+ "pmaddwd VBG0BX, %%mm1\n" // vbB7+vgG7,vbB6 -> mm1
+ "psrad $15, %%mm6\n" // 32-bit scaled Y7Y6 -> mm6
+
+ "paddd OFFSETDX, %%mm4\n" // add offset to U7U6
+ "packssdw %%mm6, %%mm2\n" // Y7Y6Y5Y4 -> mm2
+
+ "pmaddwd VR0GRX, %%mm5\n" // vrR7,vgG6+vrR6 -> mm5
+ "paddd %%mm4, %%mm7\n" // U7U6 -> mm7
+
+ "psrad $15, %%mm7\n" // 32-bit scaled U7U6 -> mm7
+
+ //----------------------------------------------------------------------
+
+ "movq 8%5, %%mm6\n" // 32-bit scaled Y3Y2Y1Y0 -> mm6
+ "packssdw %%mm7, %%mm0\n" // 32-bit scaled U7U6U5U4 -> mm0
+
+ "movq 16%5, %%mm4\n" // 32-bit scaled U3U2U1U0 -> mm4
+ "packuswb %%mm2, %%mm6\n" // all 8 Y values -> mm6
+
+ "movq OFFSETBX, %%mm7\n" // 128,128,128,128 -> mm7
+ "paddd %%mm5, %%mm1\n" // V7V6 -> mm1
+
+ "paddw %%mm7, %%mm4\n" // add offset to U3U2U1U0/256
+ "psrad $15, %%mm1\n" // 32-bit scaled V7V6 -> mm1
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm6, (%1)\n" // store Y
+
+ "packuswb %%mm0, %%mm4\n" // all 8 U values -> mm4
+ "movq 24%5, %%mm5\n" // 32-bit scaled V3V2V1V0 -> mm5
+
+ "packssdw %%mm1, %%mm3\n" // V7V6V5V4 -> mm3
+ "paddw %%mm7, %%mm5\n" // add offset to V3V2V1V0
+ "paddw %%mm7, %%mm3\n" // add offset to V7V6V5V4
+
+ "packuswb %%mm3, %%mm5\n" // ALL 8 V values -> mm5
+
+ "movq CLEARX, %%mm2\n"
+ "pand %%mm2, %%mm4\n"
+ "pand %%mm2, %%mm5\n"
+
+ "packuswb %%mm5, %%mm4\n"
+
+ "movd %%mm4, (%2)\n"
+ "psrlq $32, %%mm4\n"
+ "movd %%mm4, (%3)\n"
+
+ "add $32, %0\n"
+ "add $8, %1\n"
+ "add $4, %2\n"
+ "add $4, %3\n"
+
+ "sub $8, %4\n"
+ "jnz 1b\n"
+
+ "emms\n"
+
+ :
+ : "r" (rgb), "r" (lum), "r" (cr), "r" (cb), "m" (pixel), "m" (buf[0])
+
+ );
+}
+
+void rgb2y24bit_mmx_row(unsigned char* rgbSource, unsigned char* lum, int pixel)
+{
+ unsigned int buf[4];
+
+ // %3 = TEMP0
+ // 8%3 = TEMPY
+
+ __asm__ __volatile__ (
+ "1:\n"
+
+ "movq (%0), %%mm1\n" // load G2R2B1G1R1B0G0R0
+ "pxor %%mm6, %%mm6\n" // 0 -> mm6
+ "movq %%mm1, %%mm0\n" // G2R2B1G1R1B0G0R0 -> mm0
+ "psrlq $16, %%mm1\n" // 00G2R2B1G1R1B0 -> mm1
+ "punpcklbw ZEROSX, %%mm0\n" // R1B0G0R0 -> mm0
+ "movq %%mm1, %%mm7\n" // 00G2R2B1G1R1B0 -> mm7
+ "punpcklbw ZEROSX, %%mm1\n" // B1G1R1B0 -> mm1
+ "movq %%mm0, %%mm2\n" // R1B0G0R0 -> mm2
+ "pmaddwd YR0GRX, %%mm0\n" // yrR1,ygG0+yrR0 -> mm0
+ "movq %%mm1, %%mm3\n" // B1G1R1B0 -> mm3
+ "pmaddwd YBG0BX, %%mm1\n" // ybB1+ygG1,ybB0 -> mm1
+ "movq %%mm2, %%mm4\n" // R1B0G0R0 -> mm4
+ "movq %%mm3, %%mm5\n" // B1G1R1B0 -> mm5
+ "punpckhbw %%mm6, %%mm7\n" // 00G2R2 -> mm7
+ "paddd %%mm1, %%mm0\n" // Y1Y0 -> mm0
+
+ "movq 8(%0),%%mm1\n" // load G2R2B1G1R1B0G0R0
+
+ "movq %%mm1, %%mm6\n" // R5B4G4R4B3G3R3B2 -> mm6
+ "punpcklbw ZEROSX, %%mm1\n" // B3G3R3B2 -> mm1
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm1, %%mm5\n" // B3G3R3B2 -> mm5
+ "psllq $32, %%mm1\n" // R3B200 -> mm1
+
+ "paddd %%mm7, %%mm1\n" // R3B200+00G2R2=R3B2G2R2->mm1
+
+ "punpckhbw ZEROSX, %%mm6\n" // R5B4G4R3 -> mm6
+ "movq %%mm1, %%mm3\n" // R3B2G2R2 -> mm3
+
+ "pmaddwd YR0GRX, %%mm1\n" // yrR3,ygG2+yrR2 -> mm1
+ "movq %%mm5, %%mm7\n" // B3G3R3B2 -> mm7
+
+ "pmaddwd YBG0BX, %%mm5\n" // ybB3+ygG3,ybB2 -> mm5
+ "psrad $15, %%mm0\n" // 32-bit scaled Y1Y0 -> mm0
+
+ "movq %%mm6, %3\n" // R5B4G4R4 -> TEMP0
+ "movq %%mm3, %%mm6\n" // R3B2G2R2 -> mm6
+
+ "paddd %%mm5, %%mm1\n" // Y3Y2 -> mm1
+ "movq %%mm7, %%mm5\n" // B3G3R3B2 -> mm5
+ "psrad $15, %%mm1\n" // 32-bit scaled Y3Y2 -> mm1
+
+ "packssdw %%mm1, %%mm0\n" // Y3Y2Y1Y0 -> mm0
+
+ //----------------------------------------------------------------------
+
+ "movq 16(%0), %%mm1\n" // B7G7R7B6G6R6B5G5 -> mm7
+
+ "movq %%mm1, %%mm7\n" // B7G7R7B6G6R6B5G5 -> mm1
+
+ "psllq $16, %%mm7\n" // R7B6G6R6B5G500 -> mm7
+
+ "movq %%mm7, %%mm5\n" // R7B6G6R6B5G500 -> mm5
+
+ "movq %%mm0, 8%3\n" // 32-bit scaled Y3Y2Y1Y0 -> TEMPY
+
+ "movq %3, %%mm0\n" // R5B4G4R4 -> mm0
+
+ "punpcklbw ZEROSX, %%mm7\n" // B5G500 -> mm7
+ "movq %%mm0, %%mm6\n" // R5B4G4R4 -> mm6
+
+ "psrlq $32, %%mm0\n" // 00R5B4 -> mm0
+
+ "paddw %%mm0, %%mm7\n" // B5G5R5B4 -> mm7
+ "movq %%mm6, %%mm2\n" // B5B4G4R4 -> mm2
+
+ "pmaddwd YR0GRX, %%mm2\n" // yrR5,ygG4+yrR4 -> mm2
+
+ "pmaddwd YBG0BX, %%mm7\n" // ybB5+ygG5,ybB4 -> mm7
+
+ //----------------------------------------------------------------------
+ "paddd %%mm7, %%mm2\n" // Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "pxor %%mm7, %%mm7\n" // 0 -> mm7
+
+ "punpckhbw %%mm7, %%mm1\n" // B7G7R7B6 -> mm1
+
+ "movq %%mm1, %%mm6\n" // B7G7R7B6 -> mm6
+
+ "pmaddwd YBG0BX, %%mm6\n" // ybB7+ygG7,ybB6 -> mm6
+ "punpckhbw %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "pmaddwd YR0GRX, %%mm5\n" // yrR7,ygG6+yrR6 -> mm5
+
+ //----------------------------------------------------------------------
+
+ "psrad $15, %%mm2\n" // 32-bit scaled Y5Y4 -> mm2
+
+ "paddd %%mm5, %%mm6\n" // Y7Y6 -> mm6
+ "psrad $15, %%mm6\n" // 32-bit scaled Y7Y6 -> mm6
+
+ "packssdw %%mm6, %%mm2\n" // Y7Y6Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "movq 8%3, %%mm6\n" // 32-bit scaled Y3Y2Y1Y0 -> mm6
+ "packuswb %%mm2, %%mm6\n" // all 8 Y values -> mm6
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm6, (%1)\n" // store Y
+
+ "add $24, %0\n"
+ "add $8, %1\n"
+
+ "sub $8, %2\n"
+ "jnz 1b\n"
+ "emms\n"
+
+ :
+ : "r" (rgbSource), "r" (lum), "m" (pixel), "m" (buf[0])
+
+ );
+}
+
+void rgb2y32bit_mmx_row(unsigned char* rgbSource, unsigned char* lum, int pixel)
+{
+ unsigned int buf[4];
+
+ // %3 = TEMP0
+ // 8%3 = TEMPY
+
+ __asm__ __volatile__ (
+ "1:\n"
+
+ // pack rgb
+ // was: "movq (%0), %%mm1\n" // load G2R2B1G1R1B0G0R0
+ // ------------------------------
+ // (uses: mm0, mm1)
+ "movd 8(%0), %%mm0\n"
+ "psllq $24, %%mm0\n"
+ "movd 4(%0), %%mm1\n"
+ "por %%mm1, %%mm0\n"
+ "psllq $24, %%mm0\n"
+ "movd (%0), %%mm1\n"
+ "por %%mm0, %%mm1\n"
+ // ------------------------------
+
+ "pxor %%mm6, %%mm6\n" // 0 -> mm6
+ "movq %%mm1, %%mm0\n" // G2R2B1G1R1B0G0R0 -> mm0
+ "psrlq $16, %%mm1\n" // 00G2R2B1G1R1B0 -> mm1
+ "punpcklbw ZEROSX, %%mm0\n" // R1B0G0R0 -> mm0
+ "movq %%mm1, %%mm7\n" // 00G2R2B1G1R1B0 -> mm7
+ "punpcklbw ZEROSX, %%mm1\n" // B1G1R1B0 -> mm1
+ "movq %%mm0, %%mm2\n" // R1B0G0R0 -> mm2
+ "pmaddwd YR0GRX, %%mm0\n" // yrR1,ygG0+yrR0 -> mm0
+ "movq %%mm1, %%mm3\n" // B1G1R1B0 -> mm3
+ "pmaddwd YBG0BX, %%mm1\n" // ybB1+ygG1,ybB0 -> mm1
+ "movq %%mm2, %%mm4\n" // R1B0G0R0 -> mm4
+ "movq %%mm3, %%mm5\n" // B1G1R1B0 -> mm5
+ "punpckhbw %%mm6, %%mm7\n" // 00G2R2 -> mm7
+ "paddd %%mm1, %%mm0\n" // Y1Y0 -> mm0
+
+ // pack rgb
+ // was: "movq 8(%0),%%mm1\n" // R5B4G4R4B3G3R3B2 -> mm1
+ // ------------------------------
+ // (uses: mm1, mm6)
+ "movd 20(%0), %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 16(%0), %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 12(%0), %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ "psllq $8, %%mm1\n"
+ "movd 8(%0), %%mm6\n"
+ "psrlq $16, %%mm6\n"
+ "por %%mm6, %%mm1\n"
+ // ------------------------------
+
+ "movq %%mm1, %%mm6\n" // R5B4G4R4B3G3R3B2 -> mm6
+ "punpcklbw ZEROSX, %%mm1\n" // B3G3R3B2 -> mm1
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm1, %%mm5\n" // B3G3R3B2 -> mm5
+ "psllq $32, %%mm1\n" // R3B200 -> mm1
+
+ "paddd %%mm7, %%mm1\n" // R3B200+00G2R2=R3B2G2R2->mm1
+
+ "punpckhbw ZEROSX, %%mm6\n" // R5B4G4R3 -> mm6
+ "movq %%mm1, %%mm3\n" // R3B2G2R2 -> mm3
+
+ "pmaddwd YR0GRX, %%mm1\n" // yrR3,ygG2+yrR2 -> mm1
+ "movq %%mm5, %%mm7\n" // B3G3R3B2 -> mm7
+
+ "pmaddwd YBG0BX, %%mm5\n" // ybB3+ygG3,ybB2 -> mm5
+ "psrad $15, %%mm0\n" // 32-bit scaled Y1Y0 -> mm0
+
+ "movq %%mm6, %3\n" // R5B4G4R4 -> TEMP0
+ "movq %%mm3, %%mm6\n" // R3B2G2R2 -> mm6
+
+ "paddd %%mm5, %%mm1\n" // Y3Y2 -> mm1
+ "movq %%mm7, %%mm5\n" // B3G3R3B2 -> mm5
+ "psrad $15, %%mm1\n" // 32-bit scaled Y3Y2 -> mm1
+
+ "packssdw %%mm1, %%mm0\n" // Y3Y2Y1Y0 -> mm0
+
+ //----------------------------------------------------------------------
+
+ // pack rgb
+ // was: "movq 16(%0), %%mm1\n" // B7G7R7B6G6R6B5G5 -> mm1
+ // ------------------------------
+ // (uses: mm1, mm7)
+ "movd 28(%0), %%mm1\n"
+ "psllq $24, %%mm1\n"
+ "movd 24(%0), %%mm7\n"
+ "por %%mm7, %%mm1\n"
+ "psllq $16, %%mm1\n"
+ "movd 20(%0), %%mm7\n"
+ "psrlq $8, %%mm7\n"
+ "por %%mm7, %%mm1\n"
+ // ------------------------------
+
+ "movq %%mm1, %%mm7\n" // B7G7R7B6G6R6B5G5 -> mm1
+
+ "psllq $16, %%mm7\n" // R7B6G6R6B5G500 -> mm7
+
+ "movq %%mm7, %%mm5\n" // R7B6G6R6B5G500 -> mm5
+
+ "movq %%mm0, 8%3\n" // 32-bit scaled Y3Y2Y1Y0 -> TEMPY
+
+ "movq %3, %%mm0\n" // R5B4G4R4 -> mm0
+
+ "punpcklbw ZEROSX, %%mm7\n" // B5G500 -> mm7
+ "movq %%mm0, %%mm6\n" // R5B4G4R4 -> mm6
+
+ "psrlq $32, %%mm0\n" // 00R5B4 -> mm0
+
+ "paddw %%mm0, %%mm7\n" // B5G5R5B4 -> mm7
+ "movq %%mm6, %%mm2\n" // B5B4G4R4 -> mm2
+
+ "pmaddwd YR0GRX, %%mm2\n" // yrR5,ygG4+yrR4 -> mm2
+
+ "pmaddwd YBG0BX, %%mm7\n" // ybB5+ygG5,ybB4 -> mm7
+
+ //----------------------------------------------------------------------
+ "paddd %%mm7, %%mm2\n" // Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "pxor %%mm7, %%mm7\n" // 0 -> mm7
+
+ "punpckhbw %%mm7, %%mm1\n" // B7G7R7B6 -> mm1
+
+ "movq %%mm1, %%mm6\n" // B7G7R7B6 -> mm6
+
+ "pmaddwd YBG0BX, %%mm6\n" // ybB7+ygG7,ybB6 -> mm6
+ "punpckhbw %%mm7, %%mm5\n" // R7B6G6R6 -> mm5
+
+ "pmaddwd YR0GRX, %%mm5\n" // yrR7,ygG6+yrR6 -> mm5
+
+ //----------------------------------------------------------------------
+
+ "psrad $15, %%mm2\n" // 32-bit scaled Y5Y4 -> mm2
+
+ "paddd %%mm5, %%mm6\n" // Y7Y6 -> mm6
+ "psrad $15, %%mm6\n" // 32-bit scaled Y7Y6 -> mm6
+
+ "packssdw %%mm6, %%mm2\n" // Y7Y6Y5Y4 -> mm2
+
+ //----------------------------------------------------------------------
+
+ "movq 8%3, %%mm6\n" // 32-bit scaled Y3Y2Y1Y0 -> mm6
+ "packuswb %%mm2, %%mm6\n" // all 8 Y values -> mm6
+
+ //----------------------------------------------------------------------
+
+ "movq %%mm6, (%1)\n" // store Y
+
+ "add $32, %0\n"
+ "add $8, %1\n"
+
+ "sub $8, %2\n"
+ "jnz 1b\n"
+ "emms\n"
+
+ :
+ : "r" (rgbSource), "r" (lum), "r" (pixel), "m" (buf[0])
+
+ );
+}
+
+#endif
+// INTEL
+
diff --git a/mpeglib/lib/util/render/dither2YUV/rgb2yuv32.h b/mpeglib/lib/util/render/dither2YUV/rgb2yuv32.h
new file mode 100644
index 00000000..75fea27f
--- /dev/null
+++ b/mpeglib/lib/util/render/dither2YUV/rgb2yuv32.h
@@ -0,0 +1,93 @@
+/***************************************************************************
+ rgb2yuv32.h - description
+ -------------------
+ begin : Tue Nov 2 2000
+ copyright : (C) 2000 by Christian Gerlach
+ email : cgerlach@rhrk.uni-kl.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef _RGB2YUV32_H_
+#define _RGB2YUV32_H_
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "../yuvPicture.h"
+#include "rgb2yuvdefs.h"
+
+void rgb2yuv32(unsigned char* rgb, unsigned char* dest);
+
+// slow C rountines
+void rgb2yuv24bit(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width);
+
+void rgb2yuv32bit(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width);
+
+
+
+
+#ifndef INTEL
+void rgb2yuv24bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width);
+
+void rgb2yuv32bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width);
+#endif
+
+
+#ifdef INTEL
+
+void rgb2yuv24bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width);
+
+void rgb2yuv32bit_mmx(unsigned char* rgbSource,
+ unsigned char* lum,
+ unsigned char* cr,
+ unsigned char* cb,int height, int width);
+
+
+void rgb2yuv24bit_mmx444_row(unsigned char* rgb,
+ unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel);
+
+
+void rgb2yuv24bit_mmx422_row(unsigned char* rgb,
+ unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel);
+
+void rgb2yuv32bit_mmx422_row(unsigned char* rgb,
+ unsigned char* lum, unsigned char* cr,
+ unsigned char* cb, int pixel);
+
+void rgb2y24bit_mmx_row(unsigned char* rgbSource,
+ unsigned char* lum, int pixel);
+
+void rgb2y32bit_mmx_row(unsigned char* rgbSource,
+ unsigned char* lum, int pixel);
+
+#endif
+//INTEL
+
+
+#endif
diff --git a/mpeglib/lib/util/render/dither2YUV/rgb2yuvdefs.h b/mpeglib/lib/util/render/dither2YUV/rgb2yuvdefs.h
new file mode 100644
index 00000000..5c7ae574
--- /dev/null
+++ b/mpeglib/lib/util/render/dither2YUV/rgb2yuvdefs.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ rgb2yuvdefs.h - description
+ -------------------
+ begin : Tue Nov 2 2000
+ copyright : (C) 2000 by Christian Gerlach
+ email : cgerlach@rhrk.uni-kl.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#ifndef __RGB2YUVDEFS_H
+#define __RGB2YUVDEFS_H
+
+/* gcc 3.3.1 and later optimise the "not used" (only in asm code)
+ symbols away. So we need to mark them as used. */
+#if defined(__GNUC_PREREQ__) && !defined(__GNUC_PREREQ)
+#define __GNUC_PREREQ __GNUC_PREREQ__
+#endif
+#ifdef __GNUC_PREREQ
+#if __GNUC_PREREQ (3,1)
+# define __attribute_used__ __attribute__ ((__used__))
+#else
+# define __attribute_used__
+#endif
+#else
+# define __attribute_used__
+#endif
+
+// hicolor mode (16 bit) with r(5) g(6) b(5) bits (reverse order b, g, r)
+#define RED(rgb) (unsigned char) ((rgb) << 3)
+#define GREEN(rgb) (((rgb) & 0x7e0) >> 3)
+#define BLUE(rgb) (((rgb) & 0xf800) >> 8)
+
+#define YUV_SHIFT 15
+#define YUV_HALF (1<<(YUV_SHIFT-1))
+#define YUV_ONE (1<<YUV_SHIFT)
+#define Y_R ((int)( 0.299 * YUV_ONE ))
+#define Y_G ((int)( 0.587 * YUV_ONE ))
+#define Y_B ((int)( 0.114 * YUV_ONE ))
+#define U_R ((int)(-0.146 * YUV_ONE ))
+#define U_G ((int)(-0.288 * YUV_ONE ))
+#define U_B ((int)( 0.434 * YUV_ONE ))
+#define V_R ((int)( 0.617 * YUV_ONE ))
+#define V_G ((int)(-0.517 * YUV_ONE ))
+#define V_B ((int)(-0.100 * YUV_ONE ))
+
+#define Y_RGB(R,G,B) (( Y_R * (R) + Y_G * (G) + Y_B * (B)) >> YUV_SHIFT)
+#define U_RGB(R,G,B) ((( U_R * (R) + U_G * (G) + U_B * (B)) >> YUV_SHIFT) + 128)
+#define V_RGB(R,G,B) ((( V_R * (R) + V_G * (G) + V_B * (B)) >> YUV_SHIFT) + 128)
+
+static unsigned char __attribute_used__ CLEARX[8] = { 255, 0, 255, 0, 255, 0, 255, 0 };
+static short __attribute_used__ ZEROSX[4] = { 0, 0, 0, 0 };
+
+static short __attribute_used__ OFFSETDX[4] = { 0, 64, 0, 64 };
+static short __attribute_used__ OFFSETWX[4] = { 128, 0, 128, 0 };
+static short __attribute_used__ OFFSETBX[4] = { 128, 128, 128, 128 };
+
+static short __attribute_used__ YR0GRX[4] = { Y_R, Y_G, 0, Y_R };
+static short __attribute_used__ YBG0BX[4] = { Y_B, 0, Y_G, Y_B };
+
+static short __attribute_used__ UR0GRX[4] = { U_R, U_G, 0, U_R };
+static short __attribute_used__ UBG0BX[4] = { U_B, 0, U_G, U_B };
+
+static short __attribute_used__ VR0GRX[4] = { V_R, V_G, 0, V_R };
+static short __attribute_used__ VBG0BX[4] = { V_B, 0, V_G, V_B };
+
+#endif
diff --git a/mpeglib/lib/util/render/imageBase.cpp b/mpeglib/lib/util/render/imageBase.cpp
new file mode 100644
index 00000000..040486ea
--- /dev/null
+++ b/mpeglib/lib/util/render/imageBase.cpp
@@ -0,0 +1,76 @@
+/*
+ base clase for X11 images (stores important parameters and dither pic)
+ 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 "imageBase.h"
+
+#include <iostream>
+
+using namespace std;
+
+ImageBase::ImageBase() {
+ identifier = NULL;
+}
+
+
+ImageBase::~ImageBase() {
+ if (identifier != NULL)
+ delete [] identifier;
+}
+
+void ImageBase::init(XWindow* xWindow, YUVPicture*)
+{
+ cout << "direct virtual call: ImageBase::init "<<endl;
+}
+
+int ImageBase::support() {
+ cout << "direct virtual call: ImageBase::support "<<endl;
+ return false;
+}
+
+int ImageBase::openImage(int) {
+ cout << "direct virtual call: ImageBase::openImage "<<endl;
+ return false;
+}
+
+
+int ImageBase::closeImage(){
+ cout << "direct virtual call: ImageBase::closeImage "<<endl;
+ return false;
+}
+
+void ImageBase::ditherImage(YUVPicture*) {
+ cout << "direct virtual call: ImageBase::ditherImage "<<endl;
+}
+
+
+void ImageBase::putImage() {
+ cout << "direct virtual call: ImageBase::putImage "<<endl;
+}
+
+void ImageBase::putImage(int ,int ) {
+ cout << "direct virtual call: ImageBase::putImage(w,h) "<<endl;
+}
+
+void ImageBase::setIdentifier(const char *id)
+{
+ if (identifier != NULL)
+ delete [] identifier;
+
+ identifier = new char [strlen(id) + 1];
+ strcpy(identifier, id);
+}
+
+char *ImageBase::getIdentifier()
+{
+ return identifier;
+}
diff --git a/mpeglib/lib/util/render/imageBase.h b/mpeglib/lib/util/render/imageBase.h
new file mode 100644
index 00000000..e1f7ae8c
--- /dev/null
+++ b/mpeglib/lib/util/render/imageBase.h
@@ -0,0 +1,140 @@
+/*
+ base clase for X11 images (stores important parameters and dither pic)
+ 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 __IMAGEBASE_H
+#define __IMAGEBASE_H
+
+
+#include <stdio.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include "yuvPicture.h"
+#include "dither/ditherWrapper.h"
+
+
+
+#define _IMAGE_NONE 0
+#define _IMAGE_DESK 1
+#define _IMAGE_FULL 2
+#define _IMAGE_DOUBLE 4
+#define _IMAGE_RESIZE 8
+#define _IMAGE_DISABLED 16
+
+
+#define HAS_DESK(image) ((((image)->supportedModes) & _IMAGE_DESK) > 0)
+#define HAS_FULL(image) ((((image)->supportedModes) & _IMAGE_FULL) > 0)
+#define HAS_DOUBLE(image) ((((image)->supportedModes) & _IMAGE_DOUBLE) > 0)
+#define HAS_RESIZE(image) ((((image)->supportedModes) & _IMAGE_RESIZE) > 0)
+#define IS_DISABLED(image) ((((image)->supportedModes) & _IMAGE_DISABLED) > 0)
+
+#define IS_DESK(mode) (((mode) & _IMAGE_DESK) > 0)
+#define IS_FULL(mode) (((mode) & _IMAGE_FULL) > 0)
+#define IS_DOUBLE(mode) (((mode) & _IMAGE_DOUBLE) > 0)
+#define IS_RESIZEABLE(mode) (((mode) & _IMAGE_RESIZE) > 0)
+
+
+/**
+ This class creates from a given X11 Window a special image to
+ display.
+ An image has some characteristics, like startadress, width height,
+ if each row has a terminating modifier etc...
+
+ The image is resposible for the conversion from the yuv
+ format to the destination.
+
+ It is initialized with the constructed x11Window.
+ During a mode-switch (which is handled by x11window) the following
+ sequence is called:
+
+ support() ->true/false if this image type is supported
+ (switching to it is allowed)
+
+ openImage() called once when we switch to this
+ image type
+
+ ditherImage(..) for the conversion from yuv->rgb
+ obviously called for every image
+ putImage(..) time for display it
+
+ closeImage() called once, when we leave this image type
+
+
+ This sequence is necessary, because the user likey to switch
+ form desktop display to dga fullscreen.
+
+ The following image classes seems to be useful:
+
+ imageDeskX11 : standard ximage, maybe with shared mem support
+ full software rendering
+ imageDeskXV : image with hardware yuv->rgb rendering
+
+ imageDGAFull : dga 2.0 full software rendering (needs root)
+ imageXVFull : fullscreen hardware yuv->rgb rendering
+
+ The hierarchy is as follows:
+
+ (desk mode)
+ imageStdX11 : fallback, should work everywhere
+ imageStdXV : if supported imageStdX11 is disabled
+
+ (fullscreen mode)
+ imageDGAFull :
+ imageXVFull :
+
+ The supported switches between the modes are
+
+
+ desktop <-> fullscreen mode.
+
+
+*/
+
+
+class XWindow;
+
+class ImageBase {
+ private:
+ char *identifier;
+
+ public:
+ unsigned int supportedModes;
+
+ public:
+ ImageBase();
+ virtual ~ImageBase();
+
+ virtual void init(XWindow* xWindow, YUVPicture* pic = NULL);
+
+ virtual int support();
+
+ virtual int openImage(int imageMode);
+ virtual int closeImage();
+
+ virtual void ditherImage(YUVPicture* pic);
+ virtual void putImage();
+ virtual void putImage(int w,int h);
+
+ virtual int active() { return true; }
+
+ void setIdentifier(const char *id);
+ char *getIdentifier();
+
+};
+
+#endif
+
diff --git a/mpeglib/lib/util/render/pictureArray.cpp b/mpeglib/lib/util/render/pictureArray.cpp
new file mode 100644
index 00000000..71381ea0
--- /dev/null
+++ b/mpeglib/lib/util/render/pictureArray.cpp
@@ -0,0 +1,101 @@
+/*
+ nice try of an X11 output plugin
+ 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
+
+ */
+
+
+#include "pictureArray.h"
+
+
+
+PictureArray::PictureArray(int width, int height) {
+ int i;
+ pictureCallback=NULL;
+ imageType=PICTURE_NO_TYPE;
+
+ for (i=0;i<_PICTURE_ARRAY_SIZE;i++) {
+ pictureArray[i]=new YUVPicture(width,height);
+ imageType=pictureArray[i]->getImageType();
+ }
+
+ /* Find a pict image structure in ring buffer not currently locked. */
+ /* Set current pict image structure to the one just found in ring. */
+
+ current=pictureArray[0];
+ past=pictureArray[1];
+ future=pictureArray[2];
+
+ picPerSec=0.0;
+ this->width=width;
+ this->height=height;
+
+}
+
+
+PictureArray::~PictureArray() {
+ int i;
+ for (i=0;i<_PICTURE_ARRAY_SIZE;i++) {
+ if (pictureArray[i] != NULL) {
+ delete pictureArray[i];
+ pictureArray[i]=NULL;
+ }
+
+ }
+}
+
+
+
+
+
+void PictureArray::setPicturePerSecond(double val) {
+ picPerSec=val;
+}
+
+
+double PictureArray::getPicturePerSecond() {
+ return picPerSec;
+}
+
+
+
+
+void PictureArray::forward() {
+ /* Update past and future references if needed. */
+
+ YUVPicture* tmp=past;
+
+ past = future;
+ future = current;
+ current = tmp;
+
+
+}
+
+
+
+
+YUVPicture* PictureArray::getYUVPictureCallback() {
+ return pictureCallback;
+}
+
+
+void PictureArray::setYUVPictureCallback(YUVPicture* pic) {
+ this->pictureCallback=pic;
+}
+
+
+void PictureArray::setImageType(int imageType) {
+ int i;
+ this->imageType=imageType;
+ for (i=0;i<_PICTURE_ARRAY_SIZE;i++) {
+ pictureArray[i]->setImageType(imageType);
+ }
+}
+
diff --git a/mpeglib/lib/util/render/pictureArray.h b/mpeglib/lib/util/render/pictureArray.h
new file mode 100644
index 00000000..6a7e731c
--- /dev/null
+++ b/mpeglib/lib/util/render/pictureArray.h
@@ -0,0 +1,76 @@
+/*
+ nice try of an X11 output plugin
+ 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 __VIDEOOUTPUTX11_H
+#define __VIDEOOUTPUTX11_H
+
+
+#include "yuvPicture.h"
+#include <stdlib.h>
+
+#define _PICTURE_ARRAY_SIZE 5
+
+class PictureArray {
+
+ class YUVPicture* pictureArray[_PICTURE_ARRAY_SIZE];
+
+ class YUVPicture* past; /* Past predictive frame. */
+ class YUVPicture* future; /* Future predictive frame. */
+ class YUVPicture* current; /* Current frame. */
+
+ double picPerSec;
+ int width;
+ int height;
+
+ int imageType;
+
+ public:
+ PictureArray(int width, int height);
+ ~PictureArray();
+
+ inline YUVPicture* getPast() {return past;}
+ inline YUVPicture* getFuture() {return future;}
+ inline YUVPicture* getCurrent() {return current;}
+
+
+ inline void setPast(YUVPicture* pic) {past=pic;}
+ inline void setFuture(YUVPicture* pic) {future=pic;}
+ inline void setCurrent(YUVPicture* pic) {current=pic;}
+ inline int getWidth() { return width; }
+ inline int getWidth_Half() { return width/2; }
+
+ // attention with these!
+ // these are shares pointer
+ // only call after mpegVidRsrc and then set them back to NULL
+ YUVPicture* getYUVPictureCallback();
+ void setYUVPictureCallback(YUVPicture* pic);
+
+
+ void forward();
+
+ void setPicturePerSecond(double val);
+ double getPicturePerSecond();
+
+ // use these to swap the yuv Mode
+ inline int getImageType() { return imageType; }
+ void setImageType(int mode);
+
+
+ private:
+ YUVPicture* pictureCallback;
+
+
+};
+#endif
+
diff --git a/mpeglib/lib/util/render/renderMachine.cpp b/mpeglib/lib/util/render/renderMachine.cpp
new file mode 100644
index 00000000..c6327930
--- /dev/null
+++ b/mpeglib/lib/util/render/renderMachine.cpp
@@ -0,0 +1,205 @@
+ /*
+ puts the yuv images onto a surface
+ 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 "renderMachine.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+RenderMachine::RenderMachine() {
+
+#ifndef SDL_WRAPPER
+ surface=new X11Surface();
+#endif
+#ifdef SDL_WRAPPER
+ surface=new SDLSurface();
+#endif
+
+
+ pictureArray=NULL;
+
+ startTime=new TimeStamp();
+ endTime=new TimeStamp();
+
+ initialMode = _IMAGE_DESK;
+}
+
+
+RenderMachine::~RenderMachine() {
+
+
+ closeWindow();
+ delete surface;
+
+ delete startTime;
+ delete endTime;
+
+}
+
+
+
+
+
+
+void RenderMachine::waitRestTime() {
+ endTime->gettimeofday();
+ startTime->minus(endTime,endTime);
+ endTime->waitForIt();
+
+}
+
+int RenderMachine::x11WindowId()
+{
+ return surface->x11WindowId();
+}
+
+
+int RenderMachine::openWindow(int width,
+ int height,const char *title) {
+if (surface->open(width,height,title)) {
+ pictureArray=new PictureArray(width, height);
+
+ return switchToMode(initialMode);
+ }
+ return false;
+}
+
+
+void RenderMachine::closeWindow() {
+
+ if (surface->isOpen()==false) {
+ return;
+ }
+ if (pictureArray != NULL) {
+ delete pictureArray;
+ pictureArray=NULL;
+ }
+ surface->close();
+}
+
+/**
+ important method. This is our only way to switch from
+ fullscreen back to the desktop screen.
+ This method is called if the video end (normal or by user request)
+ We dont have a callback, thus after the image stops, we would
+ never get events.
+*/
+void RenderMachine::flushWindow() {
+
+ // we always switch back to desk mode.
+ if (IS_FULL(surface->getImageMode())) {
+ switchToMode(surface->getImageMode() ^ _IMAGE_DESK ^ _IMAGE_FULL);
+ }
+
+
+}
+
+
+
+
+void RenderMachine::putImage(YUVPicture* pic,
+ TimeStamp* waitTime,
+ TimeStamp* ) {
+ if (pic == NULL) {
+ cout << "pic is null"<<endl;
+ return;
+ }
+ startTime->gettimeofday();
+ startTime->addOffset(waitTime);
+
+ // need dither?
+ surface->dither(pic);
+
+ int nextMode;
+ if (surface->checkEvent(&nextMode) == true) {
+ switchToMode(nextMode);
+ }
+ surface->putImage(pic);
+ waitRestTime();
+}
+
+
+int RenderMachine::switchToMode(int mode) {
+ if (surface->getImageMode() != mode) {
+ surface->closeImage();
+ if (mode != _IMAGE_NONE) {
+ surface->openImage(mode);
+ }
+
+ else {
+ cout << "no imageMode, no open, that's life"<<endl;
+ return false;
+ }
+ }
+ return true;
+}
+
+
+
+PictureArray* RenderMachine::lockPictureArray() {
+ return pictureArray;
+}
+
+
+void RenderMachine::unlockPictureArray(PictureArray* pictureArray) {
+
+ // chance to switch mode
+
+
+ // put picture out
+ if (surface->getImageMode() != _IMAGE_NONE) {
+ YUVPicture* pic=pictureArray->getYUVPictureCallback();
+ if (pic != NULL) {
+ TimeStamp* waitTime=pic->getWaitTime();
+ TimeStamp* earlyTime=pic->getEarlyTime();
+ putImage(pic,waitTime,earlyTime);
+ }
+ } else {
+ cout << "no mode selected"<<endl;
+ }
+}
+
+
+void RenderMachine::config(const char* key,
+ const char* value,void* user_data) {
+ if (strcmp(key,"getDepth")==0) {
+ int* val=(int*)user_data;
+ *val=surface->getDepth();
+ }
+ if (surface != NULL) {
+ int mode = surface->getImageMode();
+ if (strcmp(key,"toggleFullscreen")==0) {
+ if (surface->findImage(mode ^ _IMAGE_FULL) != NULL) {
+ if (surface->isOpen())
+ switchToMode(mode ^ _IMAGE_FULL);
+ else
+ initialMode = _IMAGE_FULL;
+ }
+ }
+ if (strcmp(key,"toggleDouble")==0) {
+ if (surface->findImage(mode ^ _IMAGE_DOUBLE) != NULL) {
+ if (surface->isOpen())
+ switchToMode(mode ^ _IMAGE_DOUBLE);
+ else
+ initialMode = _IMAGE_DOUBLE;
+ }
+ }
+ }
+
+ surface->config(key,value,user_data);
+}
+
+
+
diff --git a/mpeglib/lib/util/render/renderMachine.h b/mpeglib/lib/util/render/renderMachine.h
new file mode 100644
index 00000000..728a6740
--- /dev/null
+++ b/mpeglib/lib/util/render/renderMachine.h
@@ -0,0 +1,90 @@
+/*
+ puts the yuv images onto a surface
+ 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 __RENDERMACHINE_H
+#define __RENDERMACHINE_H
+
+
+
+
+/**
+ RenderMachine. We still have the problem, because of performance,
+ that we cannot have a yuv picture format in the decoder
+ and one in the output to x11. they must be shared.
+ XV support then directly works on them and SDL images
+ can be exported to the decoder as well.
+
+ Another point is : mode switch. User want desktop->fullscreen switch.
+ Due to the threaded nature, we must have a single synchronization
+ point, when we know that the decoder currently does _not_ decode
+ so that we can switch the imaged and free the memory.
+
+ Some points are currently unclear, for example how to handle
+ applications, which want to redirect the image into their own
+ buffers, but hey, there are that many classes and layers
+ I really think it should be doable somehow
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef SDL_WRAPPER
+#include "x11/x11Surface.h"
+#endif
+
+#ifdef SDL_WRAPPER
+#include "sdl/sdlSurface.h"
+#endif
+
+#include "pictureArray.h"
+#include "../abstract/abs_thread.h"
+
+class RenderMachine {
+
+
+ Surface* surface;
+ PictureArray* pictureArray;
+
+
+ TimeStamp* startTime;
+ TimeStamp* endTime;
+
+ int initialMode;
+
+ public:
+ RenderMachine();
+ ~RenderMachine();
+
+ int openWindow(int width, int height,const char *title);
+ int x11WindowId();
+ void closeWindow();
+ void flushWindow();
+
+
+ PictureArray* lockPictureArray();
+ void unlockPictureArray(PictureArray* pictureArray);
+
+ void config(const char* key, const char* value,void* user_data);
+
+ private:
+ void waitRestTime();
+ void putImage(YUVPicture* pic,TimeStamp* waitTime,TimeStamp* earlyTime);
+
+ int switchToMode(int mode);
+
+};
+#endif
diff --git a/mpeglib/lib/util/render/sdl/Makefile.am b/mpeglib/lib/util/render/sdl/Makefile.am
new file mode 100644
index 00000000..1a4b85eb
--- /dev/null
+++ b/mpeglib/lib/util/render/sdl/Makefile.am
@@ -0,0 +1,43 @@
+# player - Makefile.am
+
+INCLUDES = $(all_includes)
+
+
+noinst_LTLIBRARIES = libutilsdl.la
+
+noinst_HEADERS = imageDeskSDL.h sdlSurface.h
+
+libutilsdl_la_SOURCES = imageDeskSDL.cpp sdlSurface.cpp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mpeglib/lib/util/render/sdl/imageDeskSDL.cpp b/mpeglib/lib/util/render/sdl/imageDeskSDL.cpp
new file mode 100644
index 00000000..b1ff9a7c
--- /dev/null
+++ b/mpeglib/lib/util/render/sdl/imageDeskSDL.cpp
@@ -0,0 +1,110 @@
+/*
+ SDL surface output
+ 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 "imageDeskSDL.h"
+
+#ifdef SDL_WRAPPER
+
+
+ImageDeskSDL::ImageDeskSDL() {
+
+ this->surface=NULL;
+ this->rect=NULL;
+ imageMode=_IMAGE_NONE;
+ lSupport=true;
+ image=NULL;
+}
+
+
+ImageDeskSDL::~ImageDeskSDL() {
+ closeImage();
+ cout << "SDL destry needed"<<endl;
+}
+
+
+
+int ImageDeskSDL::support() {
+ return lSupport;
+}
+
+
+void ImageDeskSDL::init(XWindow* xWindow, YUVPicture* pic) {
+ cout << "ImageDeskSDL::init"<<endl;
+ this->surface=(SDL_Surface*)xWindow;
+ this->rect=(SDL_Rect*)pic;
+}
+
+int ImageDeskSDL::openImage(int imageMode) {
+ int w=rect->w;
+ int h=rect->h;
+ this->imageMode=imageMode;
+ /* Create a YV12 image (Y + V + U) */
+ cout << "CreateYUVOverlay -s"<<imageMode<<" w:"<<w<<" h:"<<h<<endl;
+ image = SDL_CreateYUVOverlay(w,h,
+ SDL_YV12_OVERLAY,
+ surface);
+ if (image == NULL) {
+ cout << "error creating image"<<endl;
+ exit(0);
+ }
+ cout << "CreateYUVOverlay -e"<<endl;
+ return true;
+}
+
+
+int ImageDeskSDL::closeImage() {
+ if (image != NULL) {
+ cout << "FreeYUVOverlay -s"<<endl;
+ SDL_FreeYUVOverlay(image);
+ // otherwise test of NULL will fail
+ image = NULL;
+ cout << "FreeYUVOverlay -e"<<endl;
+ }
+ return true;
+}
+
+
+
+void ImageDeskSDL::ditherImage(YUVPicture* pic) {
+
+ int w=pic->getWidth();
+ int h=pic->getHeight();
+ int size=w*h+(w*h)/2;
+ SDL_LockYUVOverlay(image);
+ memcpy(*((char**)image->pixels),pic->getLuminancePtr(),size);
+ SDL_UnlockYUVOverlay(image);
+
+}
+
+
+void ImageDeskSDL::putImage(int w, int h) {
+ SDL_Rect dest;
+ dest.x=0;
+ dest.y=0;
+ dest.w=rect->w;
+ dest.h=rect->h;
+ if (imageMode & _IMAGE_RESIZE) {
+ dest.w = w;
+ dest.h = h;
+ }
+
+ if (imageMode & _IMAGE_DOUBLE) {
+ dest.w*=2;
+ dest.h*=2;
+ }
+ SDL_DisplayYUVOverlay(image,&dest);
+
+}
+
+#endif
+
diff --git a/mpeglib/lib/util/render/sdl/imageDeskSDL.h b/mpeglib/lib/util/render/sdl/imageDeskSDL.h
new file mode 100644
index 00000000..1bccb94a
--- /dev/null
+++ b/mpeglib/lib/util/render/sdl/imageDeskSDL.h
@@ -0,0 +1,65 @@
+/*
+ SDL surface output
+ 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 __IMAGEDESKSDL_H
+#define __IMAGEDESKSDL_H
+
+#include "../imageBase.h"
+
+
+
+#ifndef SDL_WRAPPER
+ class ImageDeskSDL : public ImageBase {
+ };
+#endif
+
+#ifdef SDL_WRAPPER
+
+#if defined WIN32
+#include <SDL.h>
+#include <SDL_video.h>
+#else
+#include <SDL/SDL.h>
+#include <SDL/SDL_video.h>
+#endif
+
+class ImageDeskSDL : public ImageBase {
+
+ int lSupport;
+ SDL_Overlay *image;
+
+ SDL_Surface* surface;
+ SDL_Rect* rect;
+ int imageMode;
+
+ public:
+ ImageDeskSDL();
+ ~ImageDeskSDL();
+
+ int support();
+ void init(XWindow* xWindow, YUVPicture* pic=NULL);
+
+
+ int openImage(int imageMode);
+ int closeImage();
+
+ void ditherImage(YUVPicture* pic);
+
+ void putImage(int w, int h);
+
+
+
+};
+#endif
+
+#endif
diff --git a/mpeglib/lib/util/render/sdl/sdlSurface.cpp b/mpeglib/lib/util/render/sdl/sdlSurface.cpp
new file mode 100644
index 00000000..86ef41bb
--- /dev/null
+++ b/mpeglib/lib/util/render/sdl/sdlSurface.cpp
@@ -0,0 +1,219 @@
+/*
+ surface wrapper for SDL
+ 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 "sdlSurface.h"
+
+
+#ifdef SDL_WRAPPER
+
+
+SDLSurface::SDLSurface() {
+ surface=NULL;
+ lOpen=false;
+ imageMode=_IMAGE_NONE;
+ lSDLInit=false;
+ imageDeskSDL=new ImageDeskSDL();
+}
+
+
+SDLSurface::~SDLSurface() {
+ close();
+ if (imageCurrent != NULL) {
+ imageCurrent->closeImage();
+ delete imageCurrent;
+ // otherwise test of NULL will fail
+ imageCurrent = NULL;
+ }
+}
+
+
+int SDLSurface::isOpen() {
+ return lOpen;
+}
+
+int SDLSurface::getImageMode() {
+ return imageMode;
+}
+
+int SDLSurface::open(int width, int height,const char *title,bool border) {
+ cout << "SDL openImage:"<<title<<endl;
+
+ sdlinit();
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.w = width;
+ rect.h = height;
+
+ return true;
+}
+
+
+int SDLSurface::close() {
+ if (isOpen()==false) {
+ cout << "WindowOut::closeWindow already closed"<<endl;
+ return true;
+ }
+ if(surface) {
+ SDL_FreeSurface(surface);
+ surface = NULL;
+ }
+
+ lOpen=false;
+ return true;
+}
+
+
+int SDLSurface::getHeight() {
+ return rect.h;
+}
+
+
+int SDLSurface::getWidth() {
+ return rect.w;
+}
+
+
+int SDLSurface::getDepth() {
+ return video_bpp;
+}
+
+int SDLSurface::putImage(YUVPicture* ) {
+ return true;
+}
+
+
+int SDLSurface::openImage(int imageMode, YUVPicture* pic) {
+ if (this->imageMode != _IMAGE_NONE) {
+ cout << "bad open error X11Surface::openImage"<<endl;
+ exit(0);
+ }
+ cout << "************* openImage SDL"<<imageMode<<endl;
+ this->imageMode=imageMode;
+ imageCurrent=NULL;
+ int w=getWidth();
+ int h=getHeight();
+ if(imageMode & _IMAGE_RESIZE) {
+ w=resize_rect.w;
+ h=resize_rect.h;
+ }
+
+ if (imageMode & _IMAGE_DOUBLE) {
+ w=rect.w*2;
+ h=rect.h*2;
+ }
+
+ if (imageMode & _IMAGE_DESK) {
+ if (imageDeskSDL->support()) {
+ imageCurrent=imageDeskSDL;
+ int video_flags = SDL_SWSURFACE;
+ video_flags |= SDL_ASYNCBLIT;
+ video_flags |= SDL_RESIZABLE;
+ if(surface)
+ SDL_FreeSurface(surface);
+ surface = SDL_SetVideoMode(w, h, video_bpp, video_flags);
+
+ }
+ }
+ if (imageMode & _IMAGE_FULL) {
+ if (imageDeskSDL->support()) {
+ imageCurrent=imageDeskSDL;
+ int video_flags = SDL_FULLSCREEN;
+ video_flags |= SDL_ASYNCBLIT;
+ video_flags |= SDL_HWSURFACE;
+ if(surface)
+ SDL_FreeSurface(surface);
+ surface = SDL_SetVideoMode(w, h, video_bpp, video_flags);
+ }
+ }
+ if (imageCurrent != NULL) {
+ cout << "surface:"<<surface<<endl;
+ imageCurrent->init((XWindow*)surface,(YUVPicture*)&rect);
+ imageCurrent->openImage(imageMode);
+ }
+ return (imageCurrent != NULL);
+}
+
+
+int SDLSurface::closeImage() {
+ this->imageMode = _IMAGE_NONE;
+ if (imageCurrent != NULL) {
+ imageCurrent->closeImage();
+ }
+ imageCurrent=NULL;
+ return true;
+}
+
+int SDLSurface::checkEvent(int* newMode) {
+ int back=false;
+ SDL_Event event;
+ SDL_PollEvent(&event);
+ switch (event.type) {
+ case SDL_MOUSEBUTTONDOWN: {
+ int button=event.button.button;
+ if (button == 1) {
+ *newMode = imageMode ^ _IMAGE_DOUBLE;
+ back=true;
+ }
+ if (button == 3) {
+ *newMode = imageMode ^ _IMAGE_DESK ^ _IMAGE_FULL;
+ back=true;
+ }
+ break;
+ }
+ case SDL_VIDEORESIZE : {
+ resize_rect.w = event.resize.w;
+ resize_rect.h = event.resize.h;
+ *newMode = imageMode | _IMAGE_RESIZE;
+ back = true;
+ break;
+ }
+
+ }
+ return back;
+}
+
+int SDLSurface::dither(YUVPicture* pic) {
+ if (imageCurrent != NULL) {
+ imageCurrent->ditherImage(pic);
+ if(imageMode & _IMAGE_RESIZE) {
+ imageCurrent->putImage(resize_rect.w, resize_rect.h);
+ } else {
+ imageCurrent->putImage(rect.w, rect.h);
+ }
+ }
+ return true;
+}
+
+void SDLSurface::sdlinit() {
+ if (lSDLInit == false) {
+ if (SDL_Init(SDL_INIT_VIDEO) < 0 ) {
+ fprintf(stderr, "Warning: Couldn't init SDL video: %s\n",
+ SDL_GetError());
+ fprintf(stderr, "Will ignore video stream\n");
+ exit(0);
+ }
+ atexit(SDL_Quit);
+ cout << "****************** SDL VIDEO System **********"<<endl;
+ /* Get the "native" video mode */
+ video_info=SDL_GetVideoInfo();
+ video_bpp=video_info->vfmt->BitsPerPixel;
+ imageMode=_IMAGE_NONE;
+
+ imageCurrent=NULL;
+ }
+ lSDLInit=true;
+}
+
+#endif
diff --git a/mpeglib/lib/util/render/sdl/sdlSurface.h b/mpeglib/lib/util/render/sdl/sdlSurface.h
new file mode 100644
index 00000000..aca5f293
--- /dev/null
+++ b/mpeglib/lib/util/render/sdl/sdlSurface.h
@@ -0,0 +1,78 @@
+/*
+ surface wrapper for SDL
+ 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 __SDLSURFACE_H
+#define __SDLSURFACE_H
+
+
+#include "../surface.h"
+#include "imageDeskSDL.h"
+
+
+
+#ifndef SDL_WRAPPER
+ class SDLSurface : public Surface {
+ };
+#endif
+
+#ifdef SDL_WRAPPER
+#if defined WIN32
+#include <SDL.h>
+#include <SDL_video.h>
+#else
+#include <SDL/SDL.h>
+#include <SDL/SDL_video.h>
+#endif
+
+
+class SDLSurface : public Surface {
+
+ int lOpen;
+ int imageMode;
+ int lSDLInit;
+ int video_bpp;
+ SDL_Surface* surface;
+ SDL_Rect rect;
+ SDL_Rect resize_rect;
+ const SDL_VideoInfo *video_info;
+
+ ImageBase* imageCurrent;
+
+ ImageDeskSDL* imageDeskSDL;
+
+ public:
+ SDLSurface();
+ ~SDLSurface();
+
+ int isOpen();
+ int open(int width, int height,const char *title, bool border=false);
+ int close();
+ int getHeight();
+ int getWidth();
+ int getDepth();
+ int getImageMode();
+ int checkEvent(int* mode);
+
+ int openImage(int imageMode, YUVPicture* pic = NULL);
+ int closeImage();
+ int dither(YUVPicture* pic);
+ int putImage(YUVPicture* pic);
+
+
+ private:
+ void sdlinit();
+};
+#endif
+
+#endif
diff --git a/mpeglib/lib/util/render/surface.cpp b/mpeglib/lib/util/render/surface.cpp
new file mode 100644
index 00000000..12a15410
--- /dev/null
+++ b/mpeglib/lib/util/render/surface.cpp
@@ -0,0 +1,117 @@
+/*
+ surface base class
+ 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 "surface.h"
+
+#include <iostream>
+
+using namespace std;
+
+Surface::Surface() {
+}
+
+
+Surface::~Surface() {
+}
+
+
+int Surface::isOpen() {
+ cout << "direct virtual call Surface::isOpen "<<endl;
+ return false;
+}
+
+
+int Surface::open(int width, int height,const char *title, bool border) {
+ cout << "direct virtual call Surface::open "<<endl;
+ cout << "width:"<<width<<" height:"<<height
+ << " title:"<<title<<endl;
+ return false;
+}
+
+
+int Surface::close() {
+ cout << "direct virtual call Surface::close "<<endl;
+ return true;
+}
+
+
+int Surface::getHeight() {
+ cout << "direct virtual call Surface::getHeight "<<endl;
+ return 0;
+}
+
+
+int Surface::getWidth() {
+ cout << "direct virtual call Surface::getWidth "<<endl;
+ return 0;
+}
+
+
+int Surface::getDepth() {
+ cout << "direct virtual call Surface::getDepth "<<endl;
+ return 0;
+}
+
+int Surface::getImageMode() {
+ cout << "direct virtual call Surface::getImageMode "<<endl;
+ return 0;
+}
+
+int Surface::x11WindowId() {
+ cout << "direct virtual call Surface::x11WindowId " << endl;
+ return -1;
+}
+
+ImageBase *Surface::findImage(int)
+{
+ cout << "direct virtual call: Surface::findImage "<<endl;
+ return NULL;
+}
+
+int Surface::openImage(int mode, YUVPicture*) {
+ cout << "direct virtual call Surface::openImage "<<endl;
+ cout << "imageMode:"<<mode<<endl;
+ return false;
+}
+
+
+int Surface::closeImage() {
+ cout << "direct virtual call Surface::closeImage "<<endl;
+ return true;
+}
+
+
+int Surface::dither(YUVPicture* pic) {
+ cout << "direct virtual call Surface::dither "<<endl;
+ pic->print("Surface::dither");
+ return false;
+}
+
+
+int Surface::putImage(YUVPicture* pic) {
+ cout << "direct virtual call Surface::putImage "<<endl;
+ pic->print("Surface::putImage");
+ return false;
+}
+
+int Surface::checkEvent(int*) {
+ cout << "direct virtual call Surface::checkEvent "<<endl;
+ return false;
+}
+
+void Surface::config(const char* ,
+ const char* ,void* ) {
+ cout << "direct virtual call Surface::config"<<endl;
+}
+
diff --git a/mpeglib/lib/util/render/surface.h b/mpeglib/lib/util/render/surface.h
new file mode 100644
index 00000000..84de996a
--- /dev/null
+++ b/mpeglib/lib/util/render/surface.h
@@ -0,0 +1,55 @@
+/*
+ surface base class
+ 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 __SURFACE_H
+#define __SURFACE_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "yuvPicture.h"
+
+class ImageBase;
+
+class Surface {
+
+ public:
+ Surface();
+ virtual ~Surface();
+
+ virtual int isOpen();
+ virtual int open(int width, int height,const char *title, bool border=false);
+ virtual int close();
+ virtual int getHeight();
+ virtual int getWidth();
+ virtual int getDepth();
+ virtual int getImageMode();
+ virtual int x11WindowId();
+
+ virtual ImageBase *findImage(int imageMode);
+
+ virtual int openImage(int mode, YUVPicture* pic = NULL);
+ virtual int closeImage();
+ virtual int dither(YUVPicture* pic);
+ virtual int putImage(YUVPicture* pic);
+
+ virtual int checkEvent(int* mode);
+
+ // config surface
+ virtual void config(const char* key,
+ const char* value,void* user_data);
+
+
+};
+#endif
diff --git a/mpeglib/lib/util/render/x11/Makefile.am b/mpeglib/lib/util/render/x11/Makefile.am
new file mode 100644
index 00000000..97ab0d67
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/Makefile.am
@@ -0,0 +1,48 @@
+# player - Makefile.am
+
+INCLUDES = $(all_includes)
+
+
+noinst_LTLIBRARIES = libutilx11.la
+
+
+noinst_HEADERS = initDisplay.h \
+ imageDeskX11.h imageDGAFull.h \
+ imageXVDesk.h x11Surface.h xinit.h
+
+libutilx11_la_SOURCES = initDisplay.cpp \
+ imageDeskX11.cpp \
+ imageDGAFull.cpp imageXVDesk.cpp \
+ x11Surface.cpp
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mpeglib/lib/util/render/x11/imageDGAFull.cpp b/mpeglib/lib/util/render/x11/imageDGAFull.cpp
new file mode 100644
index 00000000..6e07b658
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/imageDGAFull.cpp
@@ -0,0 +1,289 @@
+/*
+ xfree 4.0 dga fullscreen mode
+ Copyright (C) 2000 Martin Vogt, Christian Gerlach
+
+ 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 "imageDGAFull.h"
+
+#include <iostream>
+
+using namespace std;
+
+ImageDGAFull::ImageDGAFull() {
+
+ m_iMode = -1;
+ m_bIsActive = false;
+ lSupport=false;
+ m_pxWindow = NULL;
+ m_iImageMode = _IMAGE_NONE;
+ ditherWrapper=NULL;
+ supportedModes = _IMAGE_NONE;
+ setIdentifier("DGA");
+}
+
+
+ImageDGAFull::~ImageDGAFull() {
+ if (ditherWrapper != NULL) {
+ delete ditherWrapper;
+ }
+}
+
+void ImageDGAFull::init(XWindow *xWindow, YUVPicture*)
+{
+ int uid;
+
+ m_pxWindow = xWindow;
+ if (ditherWrapper == NULL) {
+ ditherWrapper=new DitherWrapper(xWindow->depth,
+ xWindow->redMask,
+ xWindow->greenMask,
+ xWindow->blueMask,
+ xWindow->pixel);
+ }
+
+#ifndef X11_DGA2
+ return;
+#endif
+
+#ifdef X11_DGA2
+ m_pDGAModes=NULL;
+ m_iNumberModes = 0;
+
+ m_iVideoWidth = xWindow->width;
+ m_iVideoHeight = xWindow->height;
+ uid=getuid();
+ if (uid != 0) {
+ //cout << "you are :"<<uid<<" and not root(0). DGA 2.0 needs root"<<endl;
+ return;
+ }
+
+ if ((m_pDisplay =xWindow->display)==NULL ) {
+ fprintf( stderr, " cannot connect to X server %s\n", XDisplayName(NULL));
+ return;
+ }
+
+ m_iScreen = DefaultScreen(xWindow->display);
+
+
+ if (!XF86DGAQueryVersion(xWindow->display,
+ &m_iMajorVersion, &m_iMinorVersion)) {
+ fprintf(stderr, "Unable to query video extension version\n");
+ return ;
+ }
+ printf("DGA version %d.%d detected!\n", m_iMajorVersion, m_iMinorVersion);
+
+ // Fail if the extension version in the server is too old
+ if (m_iMajorVersion < DGA_MINMAJOR ||
+ (m_iMajorVersion == DGA_MINMAJOR && m_iMinorVersion < DGA_MINMINOR)) {
+ fprintf(stderr, "Xserver is running an old XFree86-DGA version"
+ " (%d.%d)\n", m_iMajorVersion, m_iMinorVersion);
+ fprintf(stderr, "Minimum required version is %d.%d\n",
+ DGA_MINMAJOR, DGA_MINMINOR);
+ return ;
+ }
+
+ if (!XF86DGAQueryExtension(m_pDisplay, &m_iEventBase, &m_iErrorBase)) {
+ fprintf(stderr, "Unable to query video extension information\n");
+ return ;
+ }
+ printf("Event base %d\n", m_iEventBase);
+ printf("Error base %d\n", m_iErrorBase);
+
+ lSupport=true;
+ supportedModes = _IMAGE_FULL;
+#endif
+}
+
+int ImageDGAFull::support() {
+ return lSupport;
+}
+
+
+int ImageDGAFull::openImage(int mode) {
+#ifdef X11_DGA2
+ int width, bank, ram;
+ m_bAllowZoom = IS_DOUBLE(mode);
+ m_iImageMode = mode;
+
+ /* Open access to the framebuffer */
+ if ( ! XDGAOpenFramebuffer(m_pDisplay,m_iScreen) ) {
+ return(false);
+ }
+
+ findMode(m_pxWindow->width, m_pxWindow->height, m_pxWindow->depth);
+ m_pDevice = XDGASetMode(m_pDisplay, m_iScreen, m_pDGAModes[m_iMode].num);
+
+
+ XDGASelectInput(m_pDisplay, m_iScreen,
+ KeyPressMask | ButtonPressMask | PointerMotionMask);
+
+ XF86DGAGetVideo(m_pDisplay,m_iScreen,&m_pAddr,&width,&bank,&ram);
+
+
+ if(bank < (ram * 1024)) {
+ XF86DGASetVidPage(m_pxWindow->display,
+ DefaultScreen(m_pxWindow->display), 0);
+ }
+
+ XF86DGASetViewPort(m_pxWindow->display,
+ DefaultScreen(m_pxWindow->display),0,0);
+
+
+ printf("Offset:%8x\n",m_iOffsetScreen);
+ m_pStartAddr = m_pAddr + m_iOffsetScreen;
+ m_iOffsetLine = (m_iBytesPerLine - m_iBytesPerRow) / m_iBytesPerPixel;
+ cout << "LineOffset: " << m_iOffsetLine << endl;
+
+ // Clear the screen
+ memset(m_pAddr, 0, m_iBytesPerLine * m_iScreenHeight);
+ /* char *pos = m_pStartAddr;
+ int end = (m_bZoom) ? 2*m_iVideoHeight : m_iVideoHeight;
+ for (int line=0 ; line<end ; line++) {
+ memset(pos, 80, m_iBytesPerRow);
+ pos += m_iBytesPerRow + m_iOffsetLine * m_iBytesPerPixel;
+ }
+ sleep(2);*/
+
+ m_bIsActive = true;
+#endif
+ return true;
+}
+
+
+int ImageDGAFull::closeImage() {
+#ifdef X11_DGA2
+ m_bIsActive = false;
+ stop();
+
+ // delete resources
+ if (m_pDGAModes != NULL) {
+ delete m_pDGAModes;
+ m_pDGAModes=NULL;
+ }
+#endif
+ return true;
+}
+
+
+unsigned char* ImageDGAFull::address() {
+ return (unsigned char*) m_pStartAddr;
+}
+
+
+int ImageDGAFull::offset() {
+ return m_iOffsetLine;
+}
+
+
+void ImageDGAFull::ditherImage(YUVPicture* pic) {
+
+ int useMode = (m_bZoom) ? m_iImageMode : m_iImageMode & (!_IMAGE_DOUBLE);
+
+ ditherWrapper->doDither(pic,m_pxWindow->depth,useMode,
+ address(),offset());
+}
+
+
+void ImageDGAFull::putImage() {
+
+ if (event())
+ closeImage();
+}
+
+
+int ImageDGAFull::findMode(int width, int height, int bpp) {
+#ifdef X11_DGA2
+ int minBorder = INT_MAX;
+ int yBorder=0;
+ int border;
+
+ // TODO: also check the y-axis
+
+ m_iMode = -1;
+ m_iNumberModes = 0;
+ m_pDGAModes = XDGAQueryModes(m_pDisplay, m_iScreen, &m_iNumberModes);
+ printf("Number modes: %d\n", m_iNumberModes);
+
+ for (int count=0 ; count<m_iNumberModes ; count++) {
+
+
+ if (m_pDGAModes[count].depth != bpp)
+ continue;
+
+ printf("Mode: %d %dx%d \t bpp %d\n",
+ count,
+ m_pDGAModes[count].viewportWidth,
+ m_pDGAModes[count].viewportHeight,
+ m_pDGAModes[count].bitsPerPixel);
+
+ // test normal video
+ border = m_pDGAModes[count].viewportWidth - width;
+ if ((border >= 0) && (border < minBorder)) {
+ minBorder = border;
+ m_iMode = count;
+ m_bZoom = false;
+ yBorder = m_pDGAModes[count].viewportHeight - height;
+ }
+
+ // test zoomed video
+ if (m_bAllowZoom) {
+ border = m_pDGAModes[count].viewportWidth - 2 * width;
+ if ((border >= 0) && (border < minBorder)) {
+ minBorder = border;
+ m_iMode = count;
+ m_bZoom = true;
+ yBorder = m_pDGAModes[count].viewportHeight-2*height;
+ }
+ }
+ }
+
+ if (m_iMode != -1) {
+ m_iScreenWidth = m_pDGAModes[m_iMode].viewportWidth;
+ m_iScreenHeight = m_pDGAModes[m_iMode].viewportHeight;
+
+ m_iBytesPerPixel = m_pDGAModes[m_iMode].bitsPerPixel / 8;
+ m_iBytesPerLine = m_pDGAModes[m_iMode].bytesPerScanline;
+ m_iBytesPerRow = width * m_iBytesPerPixel;
+ if (m_bZoom) {
+ m_iBytesPerRow += m_iBytesPerRow;
+ }
+
+ m_iOffsetScreen = minBorder * (m_iBytesPerPixel / 2) +
+ (yBorder / 2) * m_iBytesPerLine;
+ }
+
+ cout << "Best Mode: " << m_iMode << endl;
+ cout << "Border Size: " << minBorder / 2 << endl;
+ cout << "Zoom: " << m_bZoom << endl;
+ cout << "Bytes per Line: " << m_iBytesPerLine << endl;
+ cout << "Bytes per Row: " << m_iBytesPerRow << endl;
+ cout << "Bytes per Pixel:" << m_iBytesPerPixel << endl;
+ cout << "Total offset: " << m_iOffsetScreen << endl;
+#endif
+ return (m_iMode != -1);
+}
+
+
+
+int ImageDGAFull::event() {
+ XEvent event;
+ return XCheckTypedEvent(m_pDisplay, ButtonPress + m_iEventBase, &event);
+}
+
+void ImageDGAFull::stop() {
+#ifdef X11_DGA2
+ m_bIsActive = false;
+ XF86DGADirectVideo(m_pDisplay, m_iScreen, 0);
+
+ XUngrabPointer(m_pDisplay, CurrentTime);
+ XUngrabKeyboard(m_pDisplay, CurrentTime);
+#endif
+}
diff --git a/mpeglib/lib/util/render/x11/imageDGAFull.h b/mpeglib/lib/util/render/x11/imageDGAFull.h
new file mode 100644
index 00000000..ddb8f493
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/imageDGAFull.h
@@ -0,0 +1,131 @@
+/*
+ xfree 4.0 dga fullscreen mode
+ Copyright (C) 2000 Martin Vogt, Christian Gerlach
+
+ 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 __IMAGEDGAFULL_H
+#define __IMAGEDGAFULL_H
+#include "xinit.h"
+
+#include "../imageBase.h"
+
+
+
+#include <stdio.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/types.h>
+
+
+
+
+#define DGA_MINMAJOR 2
+#define DGA_MINMINOR 0
+
+
+
+
+/**
+
+ Displays and renders X11 images in software with the help
+ of the ditherWrapper class. It switches to xfree 4.0 dga 2.0
+ and needs root priviliges for that
+
+*/
+
+
+class ImageDGAFull : public ImageBase {
+
+
+ XWindow* m_pxWindow;
+
+ // DGA status
+ int m_iMajorVersion;
+ int m_iMinorVersion;
+ int m_iEventBase;
+ int m_iErrorBase;
+
+ int m_iScreen;
+
+ Display *m_pDisplay;
+
+ int m_iNumberModes;
+
+#ifdef X11_DGA2
+ XDGAMode *m_pDGAModes;
+ XDGADevice *m_pDevice;
+#endif
+
+ int m_iScreenWidth;
+ int m_iScreenHeight;
+
+ char *m_pAddr; // Base address of the screen
+
+ // DGA parameter
+ int m_iVideoWidth;
+ int m_iVideoHeight;
+
+ int m_iBytesPerLine;
+ int m_iBytesPerRow; // Size of one image line
+ int m_iBytesPerPixel;
+ int m_iOffsetScreen;
+ int m_iOffsetLine;
+ char *m_pStartAddr; // Start address for a centered image
+
+ int m_iImageMode;
+ int m_iMode;
+ bool m_bZoom;
+ bool m_bAllowZoom;
+
+ bool m_bIsActive;
+
+ int lSupport;
+ DitherWrapper* ditherWrapper;
+
+
+ public:
+ ImageDGAFull();
+ ~ImageDGAFull();
+
+ void init(XWindow *xWindow, YUVPicture* pic = NULL);
+
+ int support();
+
+ int openImage(int mode);
+ int closeImage();
+
+ void ditherImage(YUVPicture* pic);
+ void putImage();
+
+ int active() { return m_bIsActive; }
+
+ private:
+
+ // Tries to find a fullscreen-mode which matches the resolution best
+ int findMode(int width, int height, int bpp);
+
+ // Returns TRUE if an event is waiting
+ int event();
+
+ // Returns the start address of the upper left corner of the video frame
+ unsigned char *address();
+
+ // Number of bytes from the end of a row to the beginning of next one
+ int offset();
+
+ // Disables DGA-View (performs a mode-switch if neccesary)
+ void stop();
+
+
+
+};
+
+#endif
diff --git a/mpeglib/lib/util/render/x11/imageDeskX11.cpp b/mpeglib/lib/util/render/x11/imageDeskX11.cpp
new file mode 100644
index 00000000..9607d749
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/imageDeskX11.cpp
@@ -0,0 +1,439 @@
+/*
+ standard and shared mem X11 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 "imageDeskX11.h"
+
+#include <iostream>
+
+using namespace std;
+
+static int lXerror;
+
+static int dummy(Display* , XErrorEvent*) {
+ lXerror=true;
+ return true;
+}
+
+
+
+ImageDeskX11::ImageDeskX11() {
+ lSupport=true;
+ supportedModes = _IMAGE_DESK | _IMAGE_DOUBLE | _IMAGE_FULL;
+ setIdentifier("Standard X11");
+ xWindow = NULL;
+ ditherWrapper=NULL;
+#ifdef X11_XVIDMODE
+ iOldMode = -1;
+ vm_modelines = NULL;
+#endif
+}
+
+
+ImageDeskX11::~ImageDeskX11() {
+ destroyImage();
+ if (ditherWrapper != NULL) {
+ delete ditherWrapper;
+ }
+}
+
+
+void ImageDeskX11::init(XWindow* xWindow, YUVPicture*)
+{
+ videoaccesstype=VIDEO_XI_NONE;
+ this->xWindow=xWindow;
+ virtualscreen=NULL;
+ ximage=NULL;
+ imageMode=_IMAGE_NONE;
+ if (ditherWrapper == NULL) {
+ ditherWrapper=new DitherWrapper(xWindow->depth,
+ xWindow->redMask,
+ xWindow->greenMask,
+ xWindow->blueMask,
+ xWindow->pixel);
+ }
+
+#ifdef X11_SHARED_MEM
+ shmseginfo=NULL;
+#endif
+}
+
+int ImageDeskX11::support() {
+ return lSupport;
+}
+
+
+int ImageDeskX11::openImage(int mode) {
+
+ if (xWindow == NULL) {
+ cout << "ImageDeskX11::openImage - call init before open!" << endl;
+ return false;
+ }
+
+ closeImage();
+ imageMode = mode;
+ int err;
+
+ if ((err=createImage(VIDEO_XI_SHMSTD,imageMode)) != ERR_XI_OK) {
+ printf("\nX initialisation error:\n *** %s\n",ERR_XI_STR[err]);
+ printf("check ipcs and delete resources with ipcrm\n");
+ if ((err=createImage(VIDEO_XI_STANDARD,imageMode)) != ERR_XI_OK) {
+ printf("\nX initialisation error:\n *** %s\n",ERR_XI_STR[err]);
+ videoaccesstype=VIDEO_XI_NONE;
+ } else {
+ lSupport=true;
+ }
+ } else {
+ lSupport=true;
+ }
+ switch(videoaccesstype) {
+ case VIDEO_XI_STANDARD:
+ //printf(" # using conventional Xlib calls.\n\n");
+ break;
+ case VIDEO_XI_SHMSTD:
+ //printf(" # Using Xlib shared memory extension %d.%d\n\n",
+ //XShmMajor,XShmMinor);
+ break;
+ default:
+ cout << "could not create image->no video output possible"<<endl;
+
+ }
+
+ iOffsetX = iOffsetY = 0;
+ int w = xWindow->width;
+ int h = xWindow->height;
+ if (IS_FULL(imageMode)) {
+ switchMode(xWindow->width, xWindow->height, IS_DOUBLE(imageMode));
+ iOffsetX = (iWidth - w) / 2;
+ iOffsetY = (iHeight - h) / 2;
+ if (bZoom) {
+ iOffsetX -= w / 2;
+ iOffsetY -= h / 2;
+ }
+ XResizeWindow(xWindow->display, xWindow->window, iWidth, iHeight);
+ } else if (IS_DOUBLE(imageMode)) {
+ XResizeWindow(xWindow->display, xWindow->window,
+ xWindow->width * 2, xWindow->height * 2);
+ }
+
+ if (lSupport==true) {
+ return true;
+ }
+ return false;
+}
+
+
+int ImageDeskX11::closeImage() {
+ destroyImage();
+
+#ifdef X11_XVIDMODE
+ if (iOldMode != -1) {
+ cout << "switch back to original videomode" << endl;
+ XF86VidModeSwitchToMode(xWindow->display,XDefaultScreen(xWindow->display),
+ vm_modelines[iOldMode]);
+ XFlush(xWindow->display);
+ iOldMode=-1;
+ }
+#endif
+
+ return true;
+}
+
+
+void ImageDeskX11::ditherImage(YUVPicture* pic) {
+ if (xWindow == NULL) {
+ cout << "ImageDeskX11::ditherImage - you have to call init first!" << endl;
+ return;
+ }
+
+ ditherWrapper->doDither(pic,xWindow->depth,imageMode,
+ virtualscreen,0);
+}
+
+
+void ImageDeskX11::putImage(){
+ if (xWindow == NULL) {
+ cout << "ImageDeskX11::putImage - you have to call init first!" << endl;
+ return;
+ }
+
+
+ int height=xWindow->height;
+ int width=xWindow->width;
+
+ if (imageMode & _IMAGE_DOUBLE) {
+ height=2*height;
+ width=2*width;
+ }
+
+#ifdef X11_SHARED_MEM
+ switch(videoaccesstype) {
+ case VIDEO_XI_SHMSTD:
+ XShmPutImage(xWindow->display,xWindow->window,
+ xWindow->gc,ximage,
+ 0, 0, iOffsetX, iOffsetY, width, height, False);
+ XSync(xWindow->display,false); /* true not needed, done by XPending */
+ break;
+
+
+ case VIDEO_XI_STANDARD:
+#endif
+ XPutImage(xWindow->display,xWindow->window,
+ xWindow->gc, ximage,
+ 0, 0, iOffsetX, iOffsetY, width, height);
+ XSync(xWindow->display,false); /* true not needed, done by XPending */
+#ifdef X11_SHARED_MEM
+ break;
+ }
+#endif
+}
+
+
+
+int ImageDeskX11::createImage(int createType,int mode) {
+
+ if (xWindow == NULL) {
+ cout << "ImageDeskX11::createImage - you have to call init first!" << endl;
+ return false;
+ }
+
+ videoaccesstype=VIDEO_XI_NONE;
+
+#ifdef X11_SHARED_MEM
+ if(XShmQueryVersion(xWindow->display,&XShmMajor,&XShmMinor,&XShmPixmaps)) {
+ if (XShmPixmaps==True) {
+ if (createType & VIDEO_XI_SHMSTD) {
+ videoaccesstype=VIDEO_XI_SHMSTD;
+ }
+ }
+ } else {
+ if (createType & VIDEO_XI_SHMSTD) {
+ return ERR_XI_NOSHAREDMEMORY;
+ }
+ }
+#endif
+ if (videoaccesstype == VIDEO_XI_NONE) {
+ videoaccesstype=createType;
+ }
+
+ switch(videoaccesstype)
+ {
+#ifdef X11_SHARED_MEM
+
+
+ case VIDEO_XI_SHMSTD:
+
+ lXerror=false;
+ XSetErrorHandler(dummy);
+
+ shmseginfo=(XShmSegmentInfo *)malloc(sizeof(XShmSegmentInfo));
+ if(!shmseginfo)
+ return ERR_XI_SHMALLOC;
+
+ memset(shmseginfo,0, sizeof(XShmSegmentInfo));
+
+ if (imageMode & _IMAGE_DOUBLE) {
+ ximage=XShmCreateImage(xWindow->display,xWindow->visual,
+ xWindow->depth,
+ ZPixmap,NULL,shmseginfo,2*xWindow->width,
+ 2*xWindow->height);
+ } else {
+ ximage=XShmCreateImage(xWindow->display,xWindow->visual,
+ xWindow->depth,
+ ZPixmap,NULL,shmseginfo,xWindow->width,
+ xWindow->height);
+ }
+
+ if(!ximage)
+ return ERR_XI_SHMXIMAGE;
+
+ shmseginfo->shmid=shmget(IPC_PRIVATE,
+ ximage->bytes_per_line*
+ ximage->height,IPC_CREAT|0777);
+
+ if(shmseginfo->shmid<0)
+ return ERR_XI_SHMSEGINFO;
+
+ shmseginfo->shmaddr=(char*)shmat(shmseginfo->shmid,NULL,0);
+ ximage->data=shmseginfo->shmaddr;
+ virtualscreen=(unsigned char *)ximage->data;
+
+ if(!virtualscreen)
+ return ERR_XI_SHMVIRTALLOC;
+
+ shmseginfo->readOnly=False;
+
+ XShmAttach(xWindow->display,shmseginfo);
+ XSync(xWindow->display, False);
+ XSetErrorHandler(NULL);
+ XFlush(xWindow->display);
+ if (lXerror) {
+ cout << "ERR_XI_SHMATTACH -2"<<endl;
+ return ERR_XI_SHMATTACH;
+ }
+
+ break;
+#endif
+
+ case VIDEO_XI_STANDARD:
+ if (mode & _IMAGE_DOUBLE) {
+ virtualscreen=(unsigned char *)
+ malloc(xWindow->screensize*sizeof(char)*4);
+
+ if(virtualscreen==NULL)
+ return ERR_XI_VIRTALLOC;
+
+ ximage=XCreateImage(xWindow->display,xWindow->visual,
+ xWindow->depth,ZPixmap,
+ 0,(char*)virtualscreen,
+ 2*xWindow->width,2*xWindow->height,
+ 32,2*xWindow->width*xWindow->pixelsize);
+ } else {
+ virtualscreen=(unsigned char *)
+ malloc(xWindow->screensize*sizeof(char));
+
+ if(virtualscreen==NULL)
+ return ERR_XI_VIRTALLOC;
+
+ ximage=XCreateImage(xWindow->display,xWindow->visual,
+ xWindow->depth,ZPixmap,
+ 0,(char*)virtualscreen,
+ xWindow->width,xWindow->height,
+ 32,xWindow->width*xWindow->pixelsize);
+ }
+
+ if(!ximage)
+ return ERR_XI_XIMAGE;
+ break;
+
+ default:
+ return ERR_XI_FAILURE;
+
+ }
+
+ if ( (videoaccesstype == VIDEO_XI_STANDARD) ||
+ (videoaccesstype == VIDEO_XI_SHMSTD) ) {
+#ifndef WORDS_BIGENDIAN
+ ximage->byte_order = LSBFirst;
+ ximage->bitmap_bit_order = LSBFirst;
+#else
+ ximage->byte_order = MSBFirst;
+ ximage->bitmap_bit_order = MSBFirst;
+#endif
+
+ }
+ return ERR_XI_OK;
+}
+
+
+
+int ImageDeskX11::destroyImage() {
+ if(xWindow && xWindow->display && xWindow->window) {
+ switch(videoaccesstype) {
+#ifdef X11_SHARED_MEM
+ case VIDEO_XI_SHMSTD:
+ if (shmseginfo) {
+ XShmDetach(xWindow->display,shmseginfo);
+ if(ximage) {
+ XDestroyImage(ximage);
+ ximage=NULL;
+ }
+ if(shmseginfo->shmaddr) {
+ shmdt(shmseginfo->shmaddr);
+ shmseginfo->shmaddr=NULL;
+ }
+ if(shmseginfo->shmid>=0)
+ shmctl(shmseginfo->shmid,IPC_RMID,NULL);
+
+ free(shmseginfo);
+ }
+ shmseginfo=NULL;
+ break;
+
+#endif
+ case VIDEO_XI_STANDARD:
+ if(ximage) {
+ XDestroyImage(ximage);
+ ximage=NULL;
+ /*
+ XDestroyImage function calls frees both the image structure
+ and the data pointed to by the image structure.
+ */
+ virtualscreen=NULL;
+ }
+ break;
+
+ default:
+ // cout << "no open window to close"<<endl;
+ break;
+ }
+ }
+ videoaccesstype=VIDEO_XI_NONE;
+ imageMode=_IMAGE_NONE;
+ return true;
+}
+
+
+bool ImageDeskX11::switchMode(int width, int , bool zoom)
+{
+ iWidth = xWindow->screenptr->width;
+ iHeight = xWindow->screenptr->height;
+
+#ifdef X11_XVIDMODE
+ iOldMode = -1;
+ int vm_count,i;
+
+ cout << "Find best matching videomode ..." << endl;
+
+ if (!XF86VidModeGetAllModeLines(xWindow->display,XDefaultScreen(xWindow->display),
+ &vm_count,&vm_modelines)) {
+ return false;
+ }
+
+ int bestMode = -1;
+ int border, minBorder = INT_MAX;
+
+ for (i = 0; i < vm_count; i++) {
+ printf("mode %d: %dx%d\n",i, vm_modelines[i]->hdisplay,vm_modelines[i]->vdisplay);
+
+ if (xWindow->screenptr->width == vm_modelines[i]->hdisplay)
+ iOldMode = i;
+
+ border = vm_modelines[i]->hdisplay - width;
+ if ((border > 0) && (border < minBorder)) {
+ bestMode = i;
+ minBorder = border;
+ bZoom = false;
+ }
+ if (zoom) {
+ border = vm_modelines[i]->hdisplay - 2 * width;
+ if ((border > 0) && (border < minBorder)) {
+ bestMode = i;
+ minBorder = border;
+ bZoom = true;
+ }
+ }
+ }
+ cout << "best mode: " << bestMode << endl;
+
+ iWidth = vm_modelines[bestMode]->hdisplay;
+ iHeight = vm_modelines[bestMode]->vdisplay;
+
+ if (XF86VidModeSwitchToMode(xWindow->display,XDefaultScreen(xWindow->display),
+ vm_modelines[bestMode])) {
+ XF86VidModeSetViewPort(xWindow->display,XDefaultScreen(xWindow->display), 0, 0);
+ XFlush(xWindow->display);
+ return true;
+ }
+#endif
+ return false;
+}
diff --git a/mpeglib/lib/util/render/x11/imageDeskX11.h b/mpeglib/lib/util/render/x11/imageDeskX11.h
new file mode 100644
index 00000000..efbd4e90
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/imageDeskX11.h
@@ -0,0 +1,85 @@
+/*
+ standard and shared mem X11 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 __IMAGEDESKX11_H
+#define __IMAGEDESKX11_H
+#include <limits.h>
+#include "xinit.h"
+
+#include "../imageBase.h"
+
+#define VIDEO_XI_NONE 0x00 /* No access defined */
+#define VIDEO_XI_STANDARD 0x01 /* Use standard Xlib calls */
+#define VIDEO_XI_SHMSTD 0X02 /* Use Xlib shared memory extension */
+
+/**
+
+ Displays and renders X11 images in software with the help
+ of the ditherWrapper class.
+*/
+
+
+class ImageDeskX11 : public ImageBase {
+
+#ifdef X11_SHARED_MEM
+ XShmSegmentInfo *shmseginfo;
+#endif
+
+ unsigned char *virtualscreen;
+ int videoaccesstype;
+ XImage *ximage;
+ int lSupport;
+
+ int XShmMajor,XShmMinor;
+ Bool XShmPixmaps;
+
+ XWindow* xWindow;
+ int imageMode;
+ DitherWrapper* ditherWrapper;
+
+ int iOffsetX;
+ int iOffsetY;
+ int iWidth;
+ int iHeight;
+
+#ifdef X11_XVIDMODE
+ XF86VidModeModeInfo **vm_modelines;
+
+ int iOldMode;
+#endif
+
+ bool bZoom;
+
+ public:
+ ImageDeskX11();
+ ~ImageDeskX11();
+
+ void init(XWindow* xWindow, YUVPicture* pic = NULL);
+
+ int support();
+
+ int openImage(int ditherSize);
+ int closeImage();
+
+ void ditherImage(YUVPicture* pic);
+ void putImage();
+
+ private:
+ int createImage(int createType,int size);
+ int destroyImage();
+
+ bool switchMode(int width, int height, bool zoom);
+
+};
+
+#endif
diff --git a/mpeglib/lib/util/render/x11/imageXVDesk.cpp b/mpeglib/lib/util/render/x11/imageXVDesk.cpp
new file mode 100644
index 00000000..e087ba40
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/imageXVDesk.cpp
@@ -0,0 +1,405 @@
+/*
+ xfree 4.0 XV extension desk mode
+ 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 "imageXVDesk.h"
+
+#include <iostream>
+
+using namespace std;
+
+ImageXVDesk::ImageXVDesk() {
+
+ lSupport=false;
+
+ ditherWrapper=NULL;
+ supportedModes = _IMAGE_NONE;
+ setIdentifier("XV");
+
+ xWindow = NULL;
+
+#ifdef X11_XV
+ keepRatio = false;
+
+#endif
+}
+
+
+ImageXVDesk::~ImageXVDesk() {
+ if (ditherWrapper != NULL) {
+ delete ditherWrapper;
+ }
+ freeImage();
+}
+
+void ImageXVDesk::init(XWindow* xWindow, YUVPicture*)
+{
+#ifdef X11_XV
+ this->xWindow=xWindow;
+
+ xv_port=-1;
+ shmem_flag = 0;
+ yuv_image=NULL;
+ yuv_shminfo.shmaddr=NULL;
+ yuv_shminfo.shmid=-1;
+
+ if (XShmQueryExtension(xWindow->display)) shmem_flag = 1;
+ if (!shmem_flag) {
+ printf("no shmem available.\n");
+ return;
+ }
+
+
+ if (haveXVSupport(xWindow)==true) {
+ supportedModes = _IMAGE_DESK | _IMAGE_DOUBLE | _IMAGE_FULL | _IMAGE_RESIZE;
+ lSupport=true;
+ } else {
+ return;
+ }
+
+ if (ditherWrapper == NULL) {
+ ditherWrapper=new Dither2YUV();
+ }
+ imageID = -1;
+#endif
+}
+
+int ImageXVDesk::support() {
+ return lSupport;
+}
+
+int ImageXVDesk::openImage(int imageMode) {
+
+
+ if (imageMode & _IMAGE_FULL) {
+ XResizeWindow(xWindow->display, xWindow->window,
+ xWindow->screenptr->width, xWindow->screenptr->height);
+ setKeepRatio(true);
+ } else if (imageMode & _IMAGE_DOUBLE) {
+ XResizeWindow(xWindow->display, xWindow->window,
+ xWindow->width * 2, xWindow->height * 2);
+ setKeepRatio(false);
+ } else {
+ setKeepRatio(false);
+ }
+
+ return true;
+}
+
+
+int ImageXVDesk::closeImage() {
+ freeImage();
+ return true;
+}
+
+void ImageXVDesk::ditherImage(YUVPicture* pic) {
+
+#ifdef X11_XV
+ int x_return;
+ int y_return;
+ int height, dy;
+ unsigned int border_width_return;
+ unsigned int depth_return;
+ unsigned int _w;
+ unsigned int _h;
+ Window _dw;
+
+ if (xWindow == NULL) {
+ cout << "ImageXVDesk::ditherImage - you have to call before dithering an image!" << endl;
+ return;
+ }
+
+ // check for not supported formats and if possible convert them
+ int inputType=pic->getImageType();
+ if (inputType == PICTURE_RGB_FLIPPED) {
+ cout << "xv for flipped rgb not implemented"<<endl;
+ return;
+ }
+
+ // create xv image
+ int id;
+ if (imageID != pic->getImageType()) {
+ imageID = pic->getImageType();
+ switch (imageID) {
+ case PICTURE_YUVMODE_CR_CB:
+ case PICTURE_YUVMODE_CB_CR:
+ case PICTURE_RGB:
+ id = GUID_YUV12_PLANAR;
+ break;
+ case PICTURE_YUVMODE_YUY2:
+ id = GUID_YUY2_PACKED;
+ break;
+ case PICTURE_YUVMODE_UYVY:
+ id = GUID_UYVY_PACKED;
+ break;
+ default:
+ cout << "unknown type for yuv image!" << endl;
+ return;
+ }
+ freeImage();
+
+ createImage(id);
+ }
+
+ XGetGeometry(xWindow->display,(Drawable)xWindow->window,
+ &_dw, &x_return, &y_return, &_w, &_h,
+ &border_width_return, &depth_return);
+
+ // now dither the image
+
+ // we (currently) cannot create yuvPicture _in_
+ // the shared segment here we copy it
+
+ unsigned char* image=pic->getImagePtr();
+ if (inputType == PICTURE_RGB) {
+ ditherWrapper->doDither(pic,
+ DefaultDepth(xWindow->display,xWindow->screennum),
+ _SIZE_NORMAL, (unsigned char*) yuv_image->data, 0);
+ } else {
+ memcpy(yuv_image->data,image,pic->getImageSize());
+ }
+
+ if (keepRatio) {
+ height = (_w * yuv_image->height) / yuv_image->width;
+ dy = (((int) _h) - height + 1) / 2;
+ XvShmPutImage(xWindow->display, xv_port,xWindow->window,
+ xWindow->gc, yuv_image,
+ 0, 0, yuv_image->width, yuv_image->height,
+ 0, dy, _w, height, False);
+ if (dy > 0) {
+ XFillRectangle(xWindow->display, xWindow->window,xWindow->gc,
+ 0, 0, _w, dy);
+ XFillRectangle(xWindow->display, xWindow->window,xWindow->gc,
+ 0, height+dy-1, _w, dy+1);
+ }
+ } else {
+ XvShmPutImage(xWindow->display, xv_port,xWindow->window,
+ xWindow->gc, yuv_image,
+ 0, 0, yuv_image->width, yuv_image->height,
+ 0, 0, _w, _h, False);
+ }
+#endif
+}
+
+
+void ImageXVDesk::putImage() {
+
+ //XFlush(xWindow->display);
+ XSync(xWindow->display, false);
+}
+
+void ImageXVDesk::setKeepRatio(bool enable)
+{
+#ifdef X11_XV
+ keepRatio = enable;
+#endif
+}
+
+
+int ImageXVDesk::haveXVSupport(XWindow* xWindow) {
+#ifdef X11_XV
+ int ret;
+ unsigned int p_version=0;
+ unsigned int p_release=0;
+ unsigned int p_request_base=0;
+ unsigned int p_event_base=0;
+ unsigned int p_error_base=0;
+
+ unsigned int p_num_adaptors=0;
+
+ /**------------------------------- XV ------------------------------------*/
+
+ /** query and print Xvideo properties */
+
+ ret = XvQueryExtension(xWindow->display,
+ &p_version, &p_release, &p_request_base,
+ &p_event_base, &p_error_base);
+ if (ret != Success) {
+ if (ret == XvBadExtension) {
+ printf("XvBadExtension returned at XvQueryExtension.\n");
+ } else if (ret == XvBadAlloc) {
+ printf("XvBadAlloc returned at XvQueryExtension.\n");
+ } else {
+ printf("other error happened at XvQueryExtension.\n");
+ }
+ return false;
+ }
+ /*
+ printf("========================================\n");
+ printf("XvQueryExtension returned the following:\n");
+ printf("p_version : %u\n", p_version);
+ printf("p_release : %u\n", p_release);
+ printf("p_request_base : %u\n", p_request_base);
+ printf("p_event_base : %u\n", p_event_base);
+ printf("p_error_base : %u\n", p_error_base);
+ printf("========================================\n");
+ */
+
+ ret = XvQueryAdaptors(xWindow->display, DefaultRootWindow(xWindow->display),
+ &p_num_adaptors, &ai);
+
+ if (ret != Success) {
+ if (ret == XvBadExtension) {
+ printf("XvBadExtension returned at XvQueryExtension.\n");
+ } else if (ret == XvBadAlloc) {
+ printf("XvBadAlloc returned at XvQueryExtension.\n");
+ } else {
+ printf("other error happaned at XvQueryAdaptors.\n");
+ }
+ return false;
+ }
+ /*
+ printf("=======================================\n");
+ printf("XvQueryAdaptors returned the following:\n");
+ printf("%d adaptors available.\n", p_num_adaptors);
+ */
+ if (p_num_adaptors == 0) {
+ //cout << "no adaptors found. XV not possible"<<endl;
+ return false;
+ }
+
+ unsigned int i;
+ unsigned int j;
+
+ for (i = 0; i < p_num_adaptors; i++) {
+ /*
+ printf(" name: %s\n"
+ " type: %s%s%s%s%s\n"
+ " ports: %ld\n"
+ " first port: %ld\n",
+ ai[i].name,
+ (ai[i].type & XvInputMask) ? "input | " : "",
+ (ai[i].type & XvOutputMask) ? "output | " : "",
+ (ai[i].type & XvVideoMask) ? "video | " : "",
+ (ai[i].type & XvStillMask) ? "still | " : "",
+ (ai[i].type & XvImageMask) ? "image | " : "",
+ ai[i].num_ports,
+ ai[i].base_id);
+ */
+ xv_port = ai[i].base_id;
+
+ //printf("adaptor %d ; format list:\n", i);
+ for (j = 0; j < ai[i].num_formats; j++) {
+ /*
+ printf(" depth=%d, visual=%ld\n",
+ ai[i].formats[j].depth,
+ ai[i].formats[j].visual_id);
+ */
+ }
+ unsigned int p;
+ unsigned int encodings;
+ int attributes;
+ int formats;
+
+ for (p = ai[i].base_id; p < ai[i].base_id+ai[i].num_ports; p++) {
+
+ //printf(" encoding list for port %d\n", p);
+ if (XvQueryEncodings(xWindow->display, p, &encodings, &ei) != Success) {
+ //printf("XvQueryEncodings failed.\n");
+ continue;
+ }
+ for (j = 0; j < encodings; j++) {
+ /*
+ printf(" id=%ld, name=%s, size=%ldx%ld, numerator=%d, denominator=%d\n",
+ ei[j].encoding_id, ei[j].name, ei[j].width, ei[j].height,
+ ei[j].rate.numerator, ei[j].rate.denominator);
+ */
+ }
+ XvFreeEncodingInfo(ei);
+ int k;
+ //printf(" attribute list for port %d\n", p);
+ at = XvQueryPortAttributes(xWindow->display, p, &attributes);
+ for (k = 0; k < attributes; k++) {
+ /*
+ printf(" name: %s\n"
+ " flags: %s%s\n"
+ " min_color: %i\n"
+ " max_color: %i\n",
+ at[k].name,
+ (at[k].flags & XvGettable) ? " get" : "",
+ (at[k].flags & XvSettable) ? " set" : "",
+ at[k].min_value, at[k].max_value);
+ */
+ }
+ if (at)
+ XFree(at);
+
+ //printf(" image format list for port %d\n", p);
+ fo = XvListImageFormats(xWindow->display, p, &formats);
+ for (k = 0; k < formats; k++) {
+ /*
+ printf(" 0x%x (%4.4s) %s\n",
+ fo[k].id,
+ (char *)&fo[k].id,
+ (fo[k].format == XvPacked) ? "packed" : "planar");
+ */
+ }
+ if (fo)
+ XFree(fo);
+ }
+ printf("\n");
+ }
+ if (p_num_adaptors > 0)
+ XvFreeAdaptorInfo(ai);
+ if (xv_port == -1) {
+ return false;
+ }
+#endif
+ return true;
+
+}
+
+
+void ImageXVDesk::freeImage() {
+#ifdef X11_XV
+ if (xWindow == NULL) {
+ return;
+ }
+ if (yuv_shminfo.shmid >=0) {
+ XShmDetach(xWindow->display,&yuv_shminfo);
+ if(yuv_shminfo.shmaddr) {
+ shmdt(yuv_shminfo.shmaddr);
+ XFree(yuv_image);
+ yuv_shminfo.shmaddr=NULL;
+ }
+ XSync(xWindow->display, False);
+ yuv_shminfo.shmid=-1;
+ }
+#endif
+}
+
+
+void ImageXVDesk::createImage(int id) {
+#ifdef X11_XV
+ if (xWindow == NULL) {
+ cout << "ImageXVDesk::freeImage - you have to call init before creating an image!" << endl;
+ return;
+ }
+
+ yuv_image = XvShmCreateImage(xWindow->display, xv_port,
+ id, 0,
+ xWindow->width,
+ xWindow->height, &yuv_shminfo);
+
+ yuv_shminfo.shmid = shmget(IPC_PRIVATE,
+ yuv_image->data_size, IPC_CREAT | 0777);
+ yuv_shminfo.shmaddr = yuv_image->data =
+ (char*)shmat(yuv_shminfo.shmid, 0, 0);
+ yuv_shminfo.readOnly = False;
+
+ if (!XShmAttach(xWindow->display, &yuv_shminfo)) {
+ printf("XShmAttach failed !\n");
+ lSupport=false;
+ return;
+ }
+ shmctl(yuv_shminfo.shmid, IPC_RMID, 0);
+#endif
+}
diff --git a/mpeglib/lib/util/render/x11/imageXVDesk.h b/mpeglib/lib/util/render/x11/imageXVDesk.h
new file mode 100644
index 00000000..44124428
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/imageXVDesk.h
@@ -0,0 +1,88 @@
+/*
+ xfree 4.0 XV extension desk mode
+ 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 __IMAGEXVDESK_H
+#define __IMAGEXVDESK_H
+
+#include "xinit.h"
+
+#include "../imageBase.h"
+#include "../dither2YUV/dither2YUV.h"
+
+#include <stdio.h>
+
+#if !defined(__NetBSD__)
+#include <semaphore.h>
+#endif
+
+//#undef X11_XV
+
+#define GUID_YUV12_PLANAR 0x32315659
+#define GUID_I420_PLANAR 0x30323449
+#define GUID_YUY2_PACKED 0x32595559
+#define GUID_UYVY_PACKED 0x59565955
+
+/**
+ The XV extension dither yuv images in hardware and allows
+ scaling of images.
+ But its currently not supported by many drivers.
+
+*/
+
+
+class ImageXVDesk : public ImageBase {
+
+#ifdef X11_XV
+ XvAdaptorInfo *ai;
+ XvEncodingInfo *ei;
+ XvAttribute *at;
+ XvImageFormatValues *fo;
+
+ XvImage *yuv_image;
+ bool keepRatio;
+
+ int xv_port;
+ int imageID;
+
+ int shmem_flag;
+ XShmSegmentInfo yuv_shminfo;
+#endif
+ Dither2YUV* ditherWrapper;
+
+ int lSupport;
+ XWindow* xWindow;
+
+ public:
+ ImageXVDesk();
+ ~ImageXVDesk();
+
+ void init(XWindow* xWindow, YUVPicture* pic = NULL);
+
+ int support();
+
+ int openImage(int imageMode);
+ int closeImage();
+
+ void ditherImage(YUVPicture* pic);
+ void putImage();
+
+ void setKeepRatio(bool enable);
+
+ private:
+ int haveXVSupport(XWindow* xWindow);
+ void freeImage();
+ void createImage(int id);
+
+};
+
+#endif
diff --git a/mpeglib/lib/util/render/x11/initDisplay.cpp b/mpeglib/lib/util/render/x11/initDisplay.cpp
new file mode 100644
index 00000000..d0029eb6
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/initDisplay.cpp
@@ -0,0 +1,255 @@
+/*
+ here are the different initialisation routines for different displays
+ 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
+
+ */
+
+
+
+#include "initDisplay.h"
+
+#include <iostream>
+
+using namespace std;
+
+
+
+static unsigned long wpixel[256];
+
+
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * InitColorDisplay --
+ *
+ * Initialized display for full color output.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+void initColorDisplay(XWindow* xwindow) {
+ XWindowAttributes winattr;
+
+
+ XGetWindowAttributes(xwindow->display, xwindow->window, &winattr);
+
+ xwindow->redMask = winattr.visual->red_mask;
+ xwindow->greenMask = winattr.visual->green_mask;
+ xwindow->blueMask = winattr.visual->blue_mask;
+}
+
+
+
+
+
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * FindFullColorVisual
+ *
+ * Returns a pointer to a full color bit visual on the display
+ *
+ * Results:
+ * See above.
+ *
+ * Side effects:
+ * Unknown.
+ *
+ *--------------------------------------------------------------
+ */
+Visual* FindFullColorVisual (Display* dpy,int* depth) {
+ XVisualInfo vinfo;
+ XVisualInfo *vinfo_ret;
+ int numitems, maxdepth;
+
+#if defined(__cplusplus) || defined(c_plusplus)
+ vinfo.c_class = TrueColor;
+#else
+ vinfo.class = TrueColor;
+#endif
+
+ vinfo_ret = XGetVisualInfo(dpy, VisualClassMask, &vinfo, &numitems);
+
+ if (numitems == 0) return NULL;
+
+ maxdepth = 0;
+ while(numitems > 0) {
+ if (vinfo_ret[numitems-1].depth > maxdepth) {
+ maxdepth = vinfo_ret[numitems-1 ].depth;
+ }
+ numitems--;
+ }
+ XFree((void *) vinfo_ret);
+
+ if (maxdepth < 16) return NULL;
+
+ if (XMatchVisualInfo(dpy, DefaultScreen(dpy), maxdepth,
+ TrueColor, &vinfo)) {
+ *depth = maxdepth;
+ return vinfo.visual;
+ }
+
+ return NULL;
+}
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * CreateFullColorWindow
+ *
+ * Creates a window capable of handling 32 bit color.
+ *
+ * Results:
+ * See above.
+ *
+ * Side effects:
+ * Unknown.
+ *
+ *--------------------------------------------------------------
+ */
+void CreateFullColorWindow (XWindow* xwindow) {
+ int depth;
+ Visual *visual;
+ XSetWindowAttributes xswa;
+ unsigned long mask;
+ unsigned int c_class;
+ int screen;
+ Display *dpy=xwindow->display;
+ /*
+ int x = xinfo->hints.x,
+ y = xinfo->hints.y;
+ unsigned int w = xinfo->hints.width,
+ h = xinfo->hints.height;
+ */
+ screen = XDefaultScreen(dpy);
+ c_class = InputOutput; /* Could be InputOnly */
+ if (xwindow->visual == NULL) {
+ xwindow->visual = visual = FindFullColorVisual (dpy, &depth);
+ xwindow->depth = depth;
+ } else {
+ visual=xwindow->visual;
+ depth=xwindow->depth;
+ }
+
+ if (visual == NULL) {
+ cout << "visual is null"<<endl;
+ return;
+ }
+ mask = CWBackPixel | CWColormap | CWBorderPixel;
+ if (xwindow->colormap==0) {
+ xswa.colormap = XCreateColormap(dpy,
+ XRootWindow(dpy, screen),
+ visual, AllocNone);
+ } else xswa.colormap = xwindow->colormap;
+ xswa.background_pixel = BlackPixel(dpy, DefaultScreen(dpy));
+ xswa.border_pixel = WhitePixel(dpy, DefaultScreen(dpy));
+ XSetWindowColormap(xwindow->display,xwindow->window,xwindow->colormap);
+
+
+ /*
+ xwindow->window = XCreateWindow(dpy, RootWindow(dpy, screen), x, y, w, h,
+ (unsigned int) 1, depth, c_class,
+ visual, mask, &xswa);
+ */
+}
+
+
+
+
+
+
+
+/*
+ *--------------------------------------------------------------
+ *
+ * InitSimpleDisplay --
+ *
+ * Initialized display, sets up colormap, etc. Use for 8 Bit color
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *--------------------------------------------------------------
+ */
+
+void initSimpleDisplay(XWindow* xwindow) {
+ int ncolors = LUM_RANGE*CB_RANGE*CR_RANGE;
+ XColor xcolor;
+ int i, lum_num, cr_num, cb_num;
+ unsigned char r, g, b;
+ Colormap dcmap;
+ Display *display;
+ ColorTable8Bit colorTable8Bit;
+
+ display = xwindow->display;
+
+
+ xwindow->colormap = XDefaultColormap(display, DefaultScreen(display));
+ dcmap = xwindow->colormap;
+
+ xcolor.flags = DoRed | DoGreen | DoBlue;
+
+
+ //if (xinfo->owncmFlag) goto create_map;
+
+retry_alloc_colors:
+ for (i=0; i<ncolors; i++) {
+
+ lum_num = (i / (CR_RANGE*CB_RANGE))%LUM_RANGE;
+ cr_num = (i / CB_RANGE)%CR_RANGE;
+ cb_num = i % CB_RANGE;
+
+ colorTable8Bit.ConvertColor(lum_num, cr_num, cb_num, &r, &g, &b);
+
+ xcolor.red = r * 256;
+ xcolor.green = g * 256;
+ xcolor.blue = b * 256;
+
+ if ((XAllocColor(display,xwindow->colormap , &xcolor) == 0
+ && xwindow->colormap == dcmap)) {
+ int j;
+ unsigned long tmp_pixel;
+ XWindowAttributes xwa;
+
+ // Free colors.
+ for (j = 0; j < i; j ++) {
+ tmp_pixel = wpixel[j];
+ XFreeColors(display,xwindow->colormap , &tmp_pixel, 1, 0);
+ }
+
+
+ //create_map:
+ XGetWindowAttributes(display, xwindow->window, &xwa);
+ xwindow->colormap = XCreateColormap(display, xwindow->window,
+ xwa.visual, AllocNone);
+ XSetWindowColormap(display, xwindow->window,xwindow->colormap );
+
+ goto retry_alloc_colors;
+ }
+ xwindow->pixel[i]=xcolor.pixel;
+ wpixel[i] = xcolor.pixel;
+ }
+
+}
+
+
diff --git a/mpeglib/lib/util/render/x11/initDisplay.h b/mpeglib/lib/util/render/x11/initDisplay.h
new file mode 100644
index 00000000..62841f19
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/initDisplay.h
@@ -0,0 +1,34 @@
+/*
+ here are the different initialisation routines for different displays
+ 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 __INITDISPLAY_H
+#define __INITDISPLAY_H
+
+#include "math.h"
+#include "xinit.h"
+#include "../dither/colorTable8Bit.h"
+
+
+
+extern void initColorDisplay(XWindow* xwindow);
+extern void initSimpleDisplay(XWindow* xwindow);
+
+// helper functions
+Visual *FindFullColorVisual (Display *dpy ,int *depth);
+void CreateFullColorWindow (XWindow* xwindow);
+
+
+
+#endif
diff --git a/mpeglib/lib/util/render/x11/x11Surface.cpp b/mpeglib/lib/util/render/x11/x11Surface.cpp
new file mode 100644
index 00000000..d7b8f052
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/x11Surface.cpp
@@ -0,0 +1,389 @@
+/*
+ surface wrapper for X11 Window
+ 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 "x11Surface.h"
+
+#include <iostream>
+
+using namespace std;
+
+const char *ERR_XI_STR[] = {
+ "X initialisation OK!",
+ "No Shared Memory available",
+ "cannot open Display",
+ "bad color depth",
+ "can't create Window",
+ "can't alloc memory for virtual screen",
+ "cannot create XImage",
+ "can't alloc memory for Shared memory segment info",
+ "cannot create Shared Memory XImage",
+ "Shared memory segment info error",
+ "Shared memory virtual screen allocation failed",
+ "cannot attach Shared Memory segment to display"
+};
+
+
+#ifndef KDE_USE_FINAL
+static int dummy(Display* , XErrorEvent*) {
+ cout << "received x11 error!"<<endl;
+ return true;
+}
+#endif
+
+X11Surface::X11Surface() {
+ xWindow=(XWindow *)malloc(sizeof(XWindow));
+ xWindow->lOpen=false;
+ xWindow->x = xWindow->y = 0;
+ xWindow->window = 0;
+ m_windowIdAvailable = false;
+
+ imageMode=_IMAGE_NONE;
+
+ imageCurrent=NULL;
+ xWindow->lOpen=false;
+
+
+ xWindow->display=XOpenDisplay(NULL);
+ if (xWindow->display)
+ XFlush(xWindow->display);
+ xWindow->redMask=0;
+ xWindow->greenMask=0;
+ xWindow->blueMask=0;
+ lXVAllow=true;
+
+ images=0;
+ imageList = new ImageBase* [4];
+ imageList[images++] = new ImageXVDesk();
+ imageList[images++] = new ImageDGAFull();
+ imageList[images++] = new ImageDeskX11();
+ imageList[images] = NULL;
+}
+
+
+X11Surface::~X11Surface() {
+ close();
+ if (xWindow->display)
+ XCloseDisplay(xWindow->display);
+ free(xWindow);
+
+ for (int count=0 ; count<images ; count++) {
+ if (imageList[count] != NULL)
+ delete imageList[count];
+ }
+ delete [] imageList;
+}
+
+
+int X11Surface::getHeight() {
+ return xWindow->height;
+}
+
+
+int X11Surface::getWidth() {
+ return xWindow->width;
+}
+
+int X11Surface::isOpen() {
+ return xWindow->lOpen;
+}
+
+int X11Surface::x11WindowId() {
+ if(m_windowIdAvailable)
+ return xWindow->window;
+ else
+ return -1;
+}
+
+int X11Surface::open(int width, int height,const char *title, bool border) {
+
+ close();
+ xWindow->width=width;
+ xWindow->height=height;
+
+ if(!xWindow->display) {
+ printf("\nX initialisation error:\n *** %s\n",ERR_XI_STR[ERR_XI_DISPLAY]);
+ printf("check ipcs and delete resources with ipcrm\n");
+ exit(0);
+ }
+
+ xWindow->screennum=DefaultScreen(xWindow->display);
+ xWindow->screenptr=DefaultScreenOfDisplay(xWindow->display);
+ xWindow->visual=DefaultVisualOfScreen(xWindow->screenptr);
+ xWindow->depth=DefaultDepth(xWindow->display,xWindow->screennum);
+
+ switch(xWindow->depth) {
+ case 8:
+ xWindow->pixelsize=1;
+ break;
+ case 16:
+ xWindow->pixelsize=2;
+ break;
+ case 24:
+ xWindow->pixelsize=4;
+ break;
+ case 32:
+ xWindow->pixelsize=4;
+ break;
+ default:
+ cout << "unknown pixelsize for depth:"<<xWindow->depth<<endl;
+ exit(0);
+ }
+
+ XColor background, ignored;
+ XAllocNamedColor (xWindow->display,
+ DefaultColormap (xWindow->display, xWindow->screennum),
+ "black", &background, &ignored);
+
+ XSetWindowAttributes attributes;
+ attributes.background_pixel=background.pixel;
+ attributes.backing_store=NotUseful;
+ attributes.override_redirect=True;
+
+ xWindow->window=XCreateWindow(xWindow->display,
+ RootWindowOfScreen(xWindow->screenptr),
+ 0,0,
+ xWindow->width,
+ xWindow->height,0,
+ xWindow->depth,
+ InputOutput, xWindow->visual,
+ (border) ? CWBackingStore : CWBackPixel|CWOverrideRedirect,
+ &attributes);
+
+ m_windowIdAvailable = true;
+ if(!xWindow->window) {
+ printf("\nX initialisation error:\n *** %s\n",ERR_XI_STR[ERR_XI_WINDOW]);
+ printf("check ipcs and delete resources with ipcrm\n");
+ return false;
+ }
+
+ WM_DELETE_WINDOW = XInternAtom(xWindow->display, "WM_DELETE_WINDOW", False);
+ XSetWMProtocols(xWindow->display, xWindow->window, &WM_DELETE_WINDOW, 1);
+
+ XSetErrorHandler(dummy);
+
+ XStoreName(xWindow->display,xWindow->window,title);
+ XSelectInput(xWindow->display,xWindow->window,
+ ExposureMask|KeyPressMask|KeyReleaseMask|ButtonPressMask);
+ xWindow->gc=XCreateGC(xWindow->display,xWindow->window,0,NULL);
+ XMapRaised(xWindow->display,xWindow->window);
+
+ if (xWindow->depth >= 16) {
+ initColorDisplay(xWindow);
+
+ } else {
+ // depth is <= 8
+ // allocate memory for dithertables
+ // gets the rgb masks
+ initColorDisplay(xWindow);
+ // create 8 bit dithertables
+ // create private colormap
+ initSimpleDisplay(xWindow);
+
+ }
+
+ xWindow->palette=NULL;
+ xWindow->screensize=xWindow->height*xWindow->width*xWindow->pixelsize;
+ xWindow->lOpen=true;
+
+ for (int count=0 ; count<images ; count++) {
+ if (imageList[count] != NULL)
+ imageList[count]->init(xWindow);
+ }
+
+ return true;
+}
+
+
+int X11Surface::close() {
+ if (isOpen()==false) {
+ return true;
+ }
+ closeImage();
+
+ XFreeGC(xWindow->display,xWindow->gc);
+ XDestroyWindow(xWindow->display,xWindow->window);
+
+ xWindow->lOpen=false;
+
+
+ return true;
+}
+
+ImageBase *X11Surface::findImage(int mode) {
+ for (int count=0 ; count<images ; count++) {
+ if ((imageList[count] == NULL) || (IS_DISABLED(imageList[count])))
+ continue;
+
+ if (imageList[count]->supportedModes & mode)
+ return imageList[count];
+ }
+ return NULL;
+}
+
+ImageBase **X11Surface::getModes() {
+ return imageList;
+}
+
+void X11Surface::setModes(ImageBase **modes) {
+ imageList = modes;
+}
+
+int X11Surface::openImage(int mode, YUVPicture*) {
+ if (imageMode != _IMAGE_NONE) {
+ cout << "bad open error X11Surface::openImage"<<endl;
+ return false;
+ }
+ if (mode == _IMAGE_NONE) {
+ cout << "X11Surface::openImage - no valid mode specified"<<endl;
+ return false;
+ }
+
+ ImageBase *newImage=findImage(mode);
+
+ if (newImage == NULL) {
+ cout << " X11Surface::openImage - no matching image found"<<endl;
+ imageMode=_IMAGE_NONE;
+ } else {
+ /*
+ printf("Best image found: %s\n", newImage->getIdentifier());
+ printf("\tsupported modes: desk=%d, double=%d, full=%d, resize=%d\n",
+ HAS_DESK(newImage),
+ HAS_DOUBLE(newImage),
+ HAS_FULL(newImage),
+ HAS_RESIZE(newImage));
+ */
+
+ open(xWindow->width, xWindow->height, "mpeglib", !(mode & _IMAGE_FULL));
+ newImage->openImage(mode);
+ if (!IS_FULL(mode)) {
+ XMoveWindow(xWindow->display, xWindow->window,
+ xWindow->x, xWindow->y);
+
+ XSizeHints hints;
+ hints.flags = PMaxSize;
+ if (HAS_RESIZE(newImage)) {
+ hints.max_width = INT_MAX;
+ hints.max_height = INT_MAX;
+ } else {
+ hints.max_width = xWindow->width;
+ hints.max_height = xWindow->height;
+ }
+ XSetWMNormalHints(xWindow->display, xWindow->window, &hints);
+ }
+
+ imageMode=mode;
+ }
+ imageCurrent = newImage;
+ XSync(xWindow->display,true);
+ return (imageCurrent != NULL);
+}
+
+
+int X11Surface::closeImage() {
+
+ if ((imageMode == _IMAGE_NONE) || (!xWindow->lOpen))
+ return false;
+
+ ImageBase *old = imageCurrent;
+ imageCurrent=NULL;
+
+ XWindowAttributes attr;
+ Window junkwin;
+
+ if (!IS_FULL(imageMode)) {
+ if (!XGetWindowAttributes(xWindow->display, xWindow->window, &attr))
+ cout << "Can't get window attributes." << endl;
+
+ XTranslateCoordinates (xWindow->display, xWindow->window, attr.root,
+ -attr.border_width,
+ -attr.border_width,
+ &xWindow->x, &xWindow->y, &junkwin);
+ }
+
+ imageMode=_IMAGE_NONE;
+ old->closeImage();
+
+ return true;
+}
+
+
+int X11Surface::dither(YUVPicture* pic) {
+ if (imageCurrent != NULL) {
+ imageCurrent->ditherImage(pic);
+ }
+ return true;
+}
+
+
+int X11Surface::putImage(YUVPicture* ) {
+ if (imageCurrent != NULL) {
+ imageCurrent->putImage();
+ }
+ return true;
+}
+
+
+int X11Surface::getDepth() {
+ return xWindow->depth;
+}
+
+int X11Surface::getImageMode() {
+ return imageMode;
+}
+
+int X11Surface::checkEvent(int* newMode) {
+ XEvent event;
+
+ if (isOpen()==false)
+ return false;
+
+ // check if we forward the call to the FULLSCREEN mode
+ if (!imageCurrent->active()) {
+ if (IS_FULL(imageMode)) {
+ *newMode=imageMode ^ _IMAGE_FULL;
+ return true;
+ }
+ }
+
+ // normal X11 images use the X11 event queue
+ if (XCheckTypedWindowEvent(xWindow->display,
+ xWindow->window,ButtonPress,&event)) {
+ if (event.xbutton.button == Button1) {
+ if (findImage(_IMAGE_DOUBLE) != NULL)
+ *newMode = imageMode ^ _IMAGE_DOUBLE;
+ } else if (event.xbutton.button == Button3) {
+ if (findImage(_IMAGE_FULL) != NULL)
+ *newMode = imageMode ^ _IMAGE_DESK ^ _IMAGE_FULL;
+ }
+ return true;
+ }
+ // now check if there are unneeded events in the queue,
+ // then delete them
+ int eventCnt=XPending(xWindow->display);
+ if (eventCnt > 10) {
+ XSync(xWindow->display,true);
+ }
+ return false;
+
+
+}
+
+
+
+void X11Surface::config(const char* key,
+ const char* value, void* ) {
+ if (strcmp(key,"xvAllow")==0) {
+ lXVAllow=atoi(value);
+ }
+}
+
diff --git a/mpeglib/lib/util/render/x11/x11Surface.h b/mpeglib/lib/util/render/x11/x11Surface.h
new file mode 100644
index 00000000..54a6582d
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/x11Surface.h
@@ -0,0 +1,79 @@
+/*
+ surface wrapper for X11 Window
+ 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 __X11SURFACE_H
+#define __X11SURFACE_H
+
+#include <limits.h>
+#include "xinit.h"
+#include "../surface.h"
+#include "initDisplay.h"
+#include "../dither/ditherWrapper.h"
+#include "imageDeskX11.h"
+#include "imageDGAFull.h"
+#include "imageXVDesk.h"
+
+
+
+class X11Surface : public Surface {
+
+ int lOpen;
+ int imageMode;
+
+ XWindow* xWindow;
+
+ ImageBase** imageList;
+ int images;
+
+ ImageBase* imageCurrent;
+
+ Atom WM_DELETE_WINDOW;
+ Atom WM_RESIZE_WINDOW;
+ int lXVAllow;
+
+ public:
+ X11Surface();
+ ~X11Surface();
+
+ int isOpen();
+ int open(int width, int height,const char *title, bool border = false);
+ int close();
+ int getHeight();
+ int getWidth();
+ int getDepth();
+ int getImageMode();
+ int x11WindowId();
+
+ ImageBase *findImage(int mode);
+
+ // these functions grant access to the supported images. be careful when changing
+ // entries, because these are no copies. they are the original values!
+ ImageBase **getModes();
+ void setModes(ImageBase **modes);
+
+ int openImage(int mode, YUVPicture* pic = NULL);
+ int closeImage();
+ int dither(YUVPicture* pic);
+ int putImage(YUVPicture* pic);
+
+ int checkEvent(int* mode);
+
+ void config(const char* key,
+ const char* value,void* user_data);
+
+
+ private:
+ int initX11();
+ bool m_windowIdAvailable;
+};
+#endif
diff --git a/mpeglib/lib/util/render/x11/xinit.h b/mpeglib/lib/util/render/x11/xinit.h
new file mode 100644
index 00000000..c42c290f
--- /dev/null
+++ b/mpeglib/lib/util/render/x11/xinit.h
@@ -0,0 +1,99 @@
+
+#ifndef __XINIT_H__
+#define __XINIT_H__
+
+#define __USE_X_SHAREDMEMORY__
+
+#include <pthread.h>
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include <X11/Xatom.h>
+
+
+
+#ifdef X11_SHARED_MEM
+#include <X11/extensions/XShm.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif
+
+
+#ifdef X11_XV
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/XShm.h>
+#endif
+
+#ifdef X11_XVIDMODE
+#include <X11/extensions/xf86vmode.h>
+#endif
+
+#ifdef X11_DGA2
+#include <X11/extensions/xf86dga.h>
+#endif
+
+#define ERR_XI_FAILURE 0xFF
+#define ERR_XI_OK 0x00
+#define ERR_XI_NOSHAREDMEMORY 0x01
+#define ERR_XI_DISPLAY 0x02
+#define ERR_XI_BADDEPTH 0x03
+#define ERR_XI_WINDOW 0x04
+#define ERR_XI_VIRTALLOC 0x05
+#define ERR_XI_XIMAGE 0x06
+#define ERR_XI_SHMALLOC 0x07
+#define ERR_XI_SHMXIMAGE 0x08
+#define ERR_XI_SHMSEGINFO 0x09
+#define ERR_XI_SHMVIRTALLOC 0x0A
+#define ERR_XI_SHMATTACH 0x0B
+
+
+
+
+#define PIXEL unsigned long
+
+extern const char *ERR_XI_STR[];
+
+struct XWindow {
+
+ Display *display;
+ Window window;
+ Screen *screenptr;
+ int screennum;
+ Visual *visual;
+ GC gc;
+
+ Colormap colormap;
+ PIXEL *palette;
+ int colorcells;
+
+ int x;
+ int y;
+ int width;
+ int height;
+ int depth;
+ int pixelsize;
+ int screensize;
+ int lOpen;
+
+ // colorMask
+ unsigned int redMask;
+ unsigned int greenMask;
+ unsigned int blueMask;
+
+ // colortable for 8 bit colormap
+ // (created with interference by the XServer)
+ unsigned char pixel[256];
+
+};
+
+
+#endif /* __XINIT_H__ */
diff --git a/mpeglib/lib/util/render/yuvPicture.cpp b/mpeglib/lib/util/render/yuvPicture.cpp
new file mode 100644
index 00000000..e79d3bde
--- /dev/null
+++ b/mpeglib/lib/util/render/yuvPicture.cpp
@@ -0,0 +1,253 @@
+/*
+ describes a picture in yuv format
+ 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 "yuvPicture.h"
+
+#include <iostream>
+
+using namespace std;
+
+static int instanceCnt=0;
+
+YUVPicture::YUVPicture(int width,int height) {
+ this->width=width;
+ this->height=height;
+
+ instance=instanceCnt;
+ instanceCnt++;
+ imagePtr=NULL;
+
+ setImageType(PICTURE_YUVMODE_CR_CB);
+
+
+ startTimeStamp=new TimeStamp();
+ waitTime=new TimeStamp();
+ earlyTime=new TimeStamp();
+ mpegType=-1;
+
+}
+
+
+YUVPicture::~YUVPicture() {
+ delete imagePtr;
+ delete earlyTime;
+ delete startTimeStamp;
+ delete waitTime;
+}
+
+
+
+int YUVPicture::getHeight() {
+ return height;
+}
+
+
+int YUVPicture::getWidth() {
+ return width;
+}
+
+
+
+int YUVPicture::getLumLength() {
+ return lumLength;
+}
+
+
+int YUVPicture::getColorLength() {
+ return colorLength;
+}
+
+int YUVPicture::getImageSize() {
+ return imageSize;
+}
+
+
+
+
+
+
+
+void YUVPicture::print(const char* title) {
+ cout << title <<":";
+ printf(" instance:%d ",instance);
+ printf(" width:%d ",width);
+ printf(" height:%d ",height);
+ cout <<" picPerSec:"<<picPerSec;
+ switch(mpegType) {
+ case 1:
+ printf("I_FRAME ");
+ break;
+ case 2:
+ printf("P_FRAME ");
+ break;
+ case 3:
+ printf("B_FRAME ");
+ break;
+ case 4:
+ printf("D_FRAME ");
+ break;
+ default:
+ printf("<unknown> ");
+ }
+ printf("\n");
+
+
+}
+
+
+void YUVPicture::setPicturePerSecond(float val) {
+ this->picPerSec=val;
+}
+
+
+float YUVPicture::getPicturePerSecond() {
+ return picPerSec;
+}
+
+
+void YUVPicture::setStartTimeStamp(TimeStamp* aStamp) {
+ aStamp->copyTo(startTimeStamp);
+}
+
+
+TimeStamp* YUVPicture::getStartTimeStamp() {
+ return startTimeStamp;
+}
+
+void YUVPicture::setWaitTime(TimeStamp* aStamp) {
+ aStamp->copyTo(waitTime);
+}
+
+
+TimeStamp* YUVPicture::getWaitTime() {
+ return waitTime;
+}
+
+void YUVPicture::setEarlyTime(TimeStamp* earlyTime) {
+ this->earlyTime=earlyTime;
+}
+
+
+TimeStamp* YUVPicture::getEarlyTime() {
+ return earlyTime;
+}
+
+
+
+void YUVPicture::setMpegPictureType(int type) {
+ this->mpegType=type;
+}
+
+
+int YUVPicture::getMpegPictureType() {
+ return mpegType;
+}
+
+
+void YUVPicture::setImageType(int imageType) {
+
+
+ //
+ // Reset everything
+ //
+
+ if (imagePtr != NULL) {
+ delete [] imagePtr;
+ imagePtr=NULL;
+ }
+ this->imageType=imageType;
+
+ lumLength=0;
+ colorLength=0;
+ Cr_mode=NULL;
+ Cb_mode=NULL;
+ luminance_mode=NULL;
+
+
+ //
+ // YUV Images
+ //
+ if ( (imageType == PICTURE_YUVMODE_CR_CB) ||
+ (imageType == PICTURE_YUVMODE_CB_CR) ) {
+
+
+ lumLength=width * height;
+ colorLength=width * height / 4;
+ imageSize=lumLength+colorLength+colorLength;
+
+ // the 64 is some "security" space
+ imagePtr=new unsigned char[imageSize+64];
+
+ if (imagePtr == NULL) {
+ cout << "cannot create image"<<endl;
+ exit(0);
+ }
+
+ // now caculate pointers to start addresses of lum/Cr/Cb blocks
+ // we need the yuvPtr for direct dither in hardware
+ // this should save a memcpy
+
+ luminance = imagePtr;
+ Cr = imagePtr+lumLength;
+ Cb = imagePtr+lumLength+colorLength;
+
+
+ if ( (luminance == NULL) ||
+ (Cr == NULL) ||
+ (Cb == NULL) ) {
+ cout << "allocation luminance/Cr/Cb error"<<endl;
+ exit(0);
+ }
+
+ switch(imageType) {
+ case PICTURE_YUVMODE_CR_CB:
+ Cr_mode=Cr;
+ Cb_mode=Cb;
+ luminance_mode=imagePtr;
+ break;
+ case PICTURE_YUVMODE_CB_CR:
+ Cr_mode=Cb;
+ Cb_mode=Cr;
+ luminance_mode=imagePtr;
+ break;
+ default:
+ cout << "unknown yuv mode:"<<imageType<<endl;
+ }
+ }
+ else if ( (imageType == PICTURE_YUVMODE_YUY2) ||
+ (imageType == PICTURE_YUVMODE_UYVY) ) {
+ // these yuv-modes are packed
+
+ imageSize=width * height * 2;
+
+ // the 64 is some "security" space
+ imagePtr=new unsigned char[imageSize+64];
+
+ if (imagePtr == NULL) {
+ cout << "cannot create image"<<endl;
+ exit(0);
+ }
+ }
+
+ //
+ // RGB Imcdages
+ //
+
+ if ( (imageType == PICTURE_RGB) ||
+ (imageType == PICTURE_RGB_FLIPPED) ){
+ imageSize=width*height*4;
+ imagePtr=new unsigned char[imageSize];
+ }
+ memset(imagePtr,0,imageSize);
+}
diff --git a/mpeglib/lib/util/render/yuvPicture.h b/mpeglib/lib/util/render/yuvPicture.h
new file mode 100644
index 00000000..1995b473
--- /dev/null
+++ b/mpeglib/lib/util/render/yuvPicture.h
@@ -0,0 +1,110 @@
+/*
+ describes a picture in yuv format
+ 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 __YUVPICTURE_H
+#define __YUVPICTURE_H
+
+
+extern "C" {
+#include <stdio.h>
+#include <string.h>
+}
+
+#include "../timeStamp.h"
+
+#define PICTURE_NO_TYPE -1
+
+#define PICTURE_YUVMODE_CR_CB 1
+#define PICTURE_YUVMODE_CB_CR 2
+#define PICTURE_RGB 3
+#define PICTURE_RGB_FLIPPED 4
+#define PICTURE_YUVMODE_YUY2 5
+#define PICTURE_YUVMODE_UYVY 6
+
+class YUVPicture {
+
+ unsigned char* imagePtr; /* Pointer to complete yuv image */
+
+ unsigned char* luminance; /* Luminance plane. */
+ unsigned char* Cr; /* Cr plane. */
+ unsigned char* Cb; /* Cb plane. */
+
+
+ int width;
+ int height;
+
+ float picPerSec;
+ int lumLength;
+ int colorLength;
+ int imageSize;
+
+ TimeStamp* startTimeStamp;
+ TimeStamp* waitTime;
+ TimeStamp* earlyTime;
+
+ int mpegType;
+ int instance;
+ int imageType;
+
+ unsigned char* image_mode; /* start Pointer to complete image */
+ unsigned char* luminance_mode; /* Luminace plane. */
+ unsigned char* Cr_mode; /* Cr plane. */
+ unsigned char* Cb_mode; /* Cb plane. */
+
+ public:
+ YUVPicture(int width,int height);
+ ~YUVPicture();
+
+ //
+ // For YUV Images
+ //
+ inline unsigned char* getLuminancePtr() {return luminance_mode;}
+ inline unsigned char* getCrPtr() {return Cr_mode;}
+ inline unsigned char* getCbPtr() {return Cb_mode;}
+
+ // general
+ inline unsigned char* getImagePtr() {return imagePtr;}
+
+ // use these to swap the image Types
+ inline int getImageType() { return imageType; }
+ void setImageType(int mode);
+
+
+ int getHeight();
+ int getWidth();
+
+ int getLumLength();
+ int getColorLength();
+ int getImageSize();
+
+ void setPicturePerSecond(float val);
+ float getPicturePerSecond();
+
+
+ void setStartTimeStamp(TimeStamp* timeStamp);
+ TimeStamp* getStartTimeStamp();
+
+ void setWaitTime(TimeStamp* waitTime);
+ TimeStamp* getWaitTime();
+
+ void setEarlyTime(TimeStamp* earlyTime);
+ TimeStamp* getEarlyTime();
+
+ void setMpegPictureType(int type);
+ int getMpegPictureType();
+
+
+ void print(const char* title);
+};
+#endif