aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamie Tittle <tigital@users.sourceforge.net>2005-04-11 16:21:05 +0000
committerJamie Tittle <tigital@users.sourceforge.net>2005-04-11 16:21:05 +0000
commitf198fa87788161da7d491787cfabccc0cb63b0df (patch)
treed7f86fa0f7d60cbed4c32e39165200a8a85fcf6e
parent0376bb6218ca67e7d57b00af5c85610e6b7d4c90 (diff)
added colorspace message which allows us to select the destination colorspace (YUV, RGB/BGR, RGBA/BGRA); now uses GemPixUtils color conversions to centralize the code
svn path=/trunk/externals/gem2pdp/; revision=2710
-rw-r--r--pdp2gem.cpp308
-rw-r--r--pdp2gem.h19
2 files changed, 275 insertions, 52 deletions
diff --git a/pdp2gem.cpp b/pdp2gem.cpp
index 2fba0c8..78ec856 100644
--- a/pdp2gem.cpp
+++ b/pdp2gem.cpp
@@ -3,7 +3,8 @@
*
* Holds the contents of a PDP packet and introduce it in the GEM rendering chain
*
- * Copyright (c) 2003 Yves Degoyon
+ * Copyright (c) 2003-2005 Yves Degoyon
+ * Copyright (c) 2004-2005 James Tittle
*
*/
@@ -11,19 +12,56 @@
#include "pdp2gem.h"
#include "yuv.h"
-CPPEXTERN_NEW(pdp2gem)
+CPPEXTERN_NEW_WITH_ONE_ARG(pdp2gem, t_symbol *, A_DEFSYM)
-pdp2gem :: pdp2gem(void)
+pdp2gem :: pdp2gem(t_symbol *colorspace)
{
+ csMess(colorspace->s_name);
+
// initialize the pix block data
m_pixBlock.image.data = NULL;
m_pixBlock.image.xsize = 0;
m_pixBlock.image.ysize = 0;
+
+ if ( m_colorspace == GL_RGB ){
m_pixBlock.image.csize = 3;
m_pixBlock.image.format = GL_RGB;
m_pixBlock.image.type = GL_UNSIGNED_BYTE;
- m_format = GL_RGB;
- m_csize = 3;
+ m_format = GL_RGB;
+ m_csize = 3;
+ }else if ( m_colorspace == GL_YUV422_GEM ){
+ m_pixBlock.image.csize = 2;
+ m_pixBlock.image.format = GL_YCBCR_422_GEM;
+#ifdef __APPLE__
+ m_pixBlock.image.type = GL_UNSIGNED_SHORT_8_8_REV_APPLE;
+#else
+ m_pixBlock.image.type = GL_UNSIGNED_BYTE;
+#endif
+ m_format = GL_YUV422_GEM;
+ m_csize = 2;
+ }else if ( m_colorspace == GL_RGBA || m_colorspace == GL_BGRA_EXT){
+ m_pixBlock.image.csize = 4;
+ m_csize = 4;
+#ifdef __APPLE__
+ m_pixBlock.image.format = GL_BGRA_EXT;
+ m_format = GL_BGRA_EXT;
+#else
+ m_pixBlock.image.format = GL_RGBA;
+ m_format = GL_RGBA;
+#endif
+ m_pixBlock.image.type = GL_UNSIGNED_BYTE;
+ post("pdp2gem: RGBA conversion not yet implemented");
+ }else if ( m_colorspace == GL_LUMINANCE ){
+ post("pdp2gem: Gray conversion not yet implemented");
+ m_pixBlock.image.csize = 1;
+ m_pixBlock.image.format = GL_LUMINANCE;
+ m_pixBlock.image.type = GL_UNSIGNED_BYTE;
+ m_format = GL_RGB;
+ m_csize = 1;
+ }else{
+ post("pdp2gem: needs to know what colorspace to import to: YUV, RGB, RGBA, or Gray");
+ }
+
m_data = NULL;
m_packet0 = -1;
m_xsize = 0;
@@ -41,7 +79,6 @@ pdp2gem :: pdp2gem(void)
{
post("pdp2gem : created mutex");
}
-
}
pdp2gem :: ~pdp2gem()
@@ -54,6 +91,7 @@ pdp2gem :: ~pdp2gem()
}
deleteBuffer();
+ colorspace = NULL;
}
void pdp2gem :: deleteBuffer()
@@ -88,17 +126,17 @@ void pdp2gem :: createBuffer()
post("pdp2gem : created buffer %dx%d", m_xsize, m_ysize );
}
-void pdp2gem :: pdpMess(t_symbol *action, t_int pcktno)
+void pdp2gem :: pdpMess(t_symbol *action, int pcktno)
{
t_int psize;
- short int *pY, *pU, *pV;
+ short int *pY, *pY2, *pU, *pV;
unsigned char r,g,b;
- unsigned char y,u,v;
+ unsigned char y,y2,u,v;
t_int cpt, px, py;
if (action == gensym("register_ro"))
{
- m_dropped = pdp_packet_copy_ro_or_drop(&m_packet0, pcktno);
+ m_dropped = pdp_packet_copy_ro_or_drop((int*)&m_packet0, pcktno);
}
// post("pdp2gem : got pdp packet #%d : dropped : %d", pcktno, m_dropped );
@@ -108,16 +146,18 @@ void pdp2gem :: pdpMess(t_symbol *action, t_int pcktno)
{
if ( PDP_IMAGE == m_header->type )
{
- if (pdp_packet_header(m_packet0)->info.image.encoding == PDP_IMAGE_YV12)
- {
- if ( ( m_xsize != (int)m_header->info.image.width ) ||
- ( m_ysize != (int)m_header->info.image.height ) )
- {
- m_xsize = m_header->info.image.width;
- m_ysize = m_header->info.image.height;
- createBuffer();
- }
- m_pdpdata = (short int *)pdp_packet_data(m_packet0);
+ if (pdp_packet_header(m_packet0)->info.image.encoding == PDP_IMAGE_YV12
+ && (m_colorspace == GL_RGB || m_colorspace == GL_BGR_EXT) )
+ {
+ if ( ( m_xsize != (int)m_header->info.image.width ) ||
+ ( m_ysize != (int)m_header->info.image.height ) )
+ {
+ m_xsize = m_header->info.image.width;
+ m_ysize = m_header->info.image.height;
+ createBuffer();
+ }
+ m_pdpdata = (short int *)pdp_packet_data(m_packet0);
+#if 0
psize = m_xsize*m_ysize;
pY = m_pdpdata;
pV = m_pdpdata+psize;
@@ -135,31 +175,142 @@ void pdp2gem :: pdpMess(t_symbol *action, t_int pcktno)
y = *(pY)>>7;
v = (*(pV)>>8)+128;
u = (*(pU)>>8)+128;
- m_data[cpt++] = yuv_YUVtoR( y, u, v );
- m_data[cpt++] = yuv_YUVtoG( y, u, v );
- m_data[cpt] = yuv_YUVtoB( y, u, v );
- pY++;
- if ( (px%2==0) && (py%2==0) )
- {
- pV++; pU++;
- }
- }
- }
-
- // unlock mutex
- pthread_mutex_unlock(m_mutex);
-
- // free PDP packet
- pdp_packet_mark_unused(m_packet0);
- m_packet0 = -1;
- }
- else
- {
- post("pdp2gem : unsupported image type", m_header->info.image.encoding );
- }
- }
- }
+#ifdef __APPLE__
+ m_data[cpt++] = yuv_YUVtoB( y, u, v );
+ m_data[cpt++] = yuv_YUVtoG( y, u, v );
+ m_data[cpt] = yuv_YUVtoR( y, u, v );
+#else
+ m_data[cpt++] = yuv_YUVtoR( y, u, v );
+ m_data[cpt++] = yuv_YUVtoG( y, u, v );
+ m_data[cpt] = yuv_YUVtoB( y, u, v );
+#endif
+ pY++;
+ if ( (px%2==0) && (py%2==0) )
+ {
+ pV++; pU++;
+ }
+ }
+ }
+#else
+ m_pixBlock.image.fromYV12(m_pdpdata);
+#endif
+ // unlock mutex
+ pthread_mutex_unlock(m_mutex);
+
+ // free PDP packet
+ pdp_packet_mark_unused(m_packet0);
+ m_packet0 = -1;
+ } else if (pdp_packet_header(m_packet0)->info.image.encoding == PDP_IMAGE_YV12
+ && (m_colorspace == GL_RGBA || m_colorspace == GL_BGRA_EXT) )
+ {
+ if ( ( m_xsize != (int)m_header->info.image.width ) ||
+ ( m_ysize != (int)m_header->info.image.height ) )
+ {
+ m_xsize = m_header->info.image.width;
+ m_ysize = m_header->info.image.height;
+ createBuffer();
+ }
+ m_pdpdata = (short int *)pdp_packet_data(m_packet0);
+#if 0
+ psize = m_xsize*m_ysize;
+ pY = m_pdpdata;
+ pV = m_pdpdata+psize;
+ pU = m_pdpdata+psize+(psize>>2);
+
+ // lock mutex
+ pthread_mutex_lock(m_mutex);
+
+ // copy image data
+ for ( py=0; py<m_ysize; py++)
+ {
+ for ( px=0; px<m_xsize; px++)
+ {
+ cpt=((m_ysize-py)*m_xsize+px)*4;
+ y = *(pY)>>7;
+ v = (*(pV)>>8)+128;
+ u = (*(pU)>>8)+128;
+ m_data[cpt++] = yuv_YUVtoR( y, u, v );
+ m_data[cpt++] = yuv_YUVtoG( y, u, v );
+ m_data[cpt] = yuv_YUVtoB( y, u, v );
+ pY++;
+ if ( (px%2==0) && (py%2==0) )
+ {
+ pV++; pU++;
+ }
+ }
+ }
+#else
+ m_pixBlock.image.fromYV12(m_pdpdata);
+#endif
+ // unlock mutex
+ pthread_mutex_unlock(m_mutex);
+
+ // free PDP packet
+ pdp_packet_mark_unused(m_packet0);
+ m_packet0 = -1;
+ } else if (pdp_packet_header(m_packet0)->info.image.encoding == PDP_IMAGE_YV12
+ && m_colorspace == GL_YCBCR_422_GEM)
+ {
+ if ( ( m_xsize != (int)m_header->info.image.width ) ||
+ ( m_ysize != (int)m_header->info.image.height ) )
+ {
+ m_xsize = m_header->info.image.width;
+ m_ysize = m_header->info.image.height;
+ createBuffer();
+ }
+ m_pdpdata = (short int *)pdp_packet_data(m_packet0);
+#if 0
+ psize = m_xsize*m_ysize;
+ pY = m_pdpdata;
+ pY2= m_pdpdata+m_xsize;
+ pV = m_pdpdata+psize;
+ pU = m_pdpdata+psize+(psize>>2);
+ unsigned char *pixels1 = m_data;
+ unsigned char *pixels2 = m_data + m_xsize * 2;
+ short *py1 = pY;
+ short *py2 = pY+m_xsize; // plane_1 is luma
+ short *pu = pU;
+ short *pv = pV;
+ int row = m_ysize>>1;
+ int cols = m_xsize>>1;
+ unsigned char u,v;
+ // lock mutex
+ pthread_mutex_lock(m_mutex);
+
+ // copy image data
+ while(row--){
+ int col=cols;
+ while(col--){
+ u=((*pu++)>>8)+128; v=((*pv++)>>8)+128;
+ *pixels1++=u;
+ *pixels1++=(*py1++)>>7;
+ *pixels1++=v;
+ *pixels1++=(*py1++)>>7;
+ *pixels2++=u;
+ *pixels2++=(*py2++)>>7;
+ *pixels2++=v;
+ *pixels2++=(*py2++)>>7;
+ }
+ pixels1+= m_xsize*m_csize; pixels2+= m_xsize*m_csize;
+ py1+=m_xsize*1; py2+=m_xsize*1;
+ }
+ #else
+ m_pixBlock.image.fromYV12(m_pdpdata);
+ #endif
+ // unlock mutex
+ pthread_mutex_unlock(m_mutex);
+
+ // free PDP packet
+ pdp_packet_mark_unused(m_packet0);
+ m_packet0 = -1;
+ }
+ else
+ {
+ post("pdp2gem : unsupported image type %i", m_header->info.image.encoding );
+ }
+ }
+ }
}
void pdp2gem :: startRendering()
@@ -187,16 +338,77 @@ void pdp2gem :: postrender(GemState *state)
pthread_mutex_unlock(m_mutex);
}
+/////////////////////////////////////////////////////////
+// colorspaceMess
+//
+/////////////////////////////////////////////////////////
+void pdp2gem :: csMess(char* format)
+{
+ if (!strcmp(format, "YUV")){
+ m_colorspace = GL_YCBCR_422_GEM;
+ post("pdp2gem: colorspace is YUV %d",m_colorspace);
+ m_csize = 2;
+ m_format = GL_YUV422_GEM;
+#ifdef __APPLE__
+ m_pixBlock.image.type = GL_UNSIGNED_SHORT_8_8_REV_APPLE;
+#else
+ m_pixBlock.image.type = GL_UNSIGNED_BYTE;
+#endif
+ createBuffer();
+ return;
+ } else
+
+ if (!strcmp(format, "RGB")){
+ m_colorspace = GL_RGB;
+ post("pdp2gem: colorspace is GL_RGB %d",m_colorspace);
+ m_csize = 3;
+ m_pixBlock.image.type = GL_UNSIGNED_BYTE;
+#ifdef __APPLE__
+ m_format = GL_BGR_EXT;
+#else
+ m_format = GL_RGB;
+#endif
+ createBuffer();
+ return;
+ } else
+
+ if (!strcmp(format, "RGBA")){
+ m_colorspace = GL_RGBA;
+ post("pdp2gem: colorspace is GL_RGBA %d",m_colorspace);
+ m_csize = 4;
+#ifdef __APPLE__
+ m_format = GL_BGRA_EXT; m_pixBlock.image.format = GL_UNSIGNED_INT_8_8_8_8_REV;
+#else
+ m_format = GL_RGBA; m_pixBlock.image.format = GL_UNSIGNED_BYTE;
+#endif
+ createBuffer();
+ return;
+ } else {
+
+ post("pdp2gem: colorspace is unknown %d",m_colorspace);
+ post("pdp2gem: using default colorspace: YUV");
+ m_csize = 2;
+ m_colorspace = GL_YCBCR_422_GEM;
+ createBuffer();
+ }
+}
+
void pdp2gem :: obj_setupCallback(t_class *classPtr)
{
- post( "pdp2gem : a bridge between PDP/PiDiP and GEM v"GEM2PDP_VERSION" (ydegoyon@free.fr)" );
- class_addmethod(classPtr, (t_method)&pdp2gem::pdpCallback, gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL);
+ post( "pdp2gem : a bridge between PDP/PiDiP and GEM v"GEM2PDP_VERSION" (ydegoyon@free.fr & tigital@mac.com)" );
+ class_addmethod(classPtr, (t_method)&pdp2gem::pdpCallback,
+ gensym("pdp"), A_SYMBOL, A_DEFFLOAT, A_NULL);
+ class_addmethod(classPtr, (t_method)&pdp2gem::csMessCallback,
+ gensym("colorspace"), A_DEFSYMBOL, A_NULL);
class_sethelpsymbol( classPtr, gensym("pdp2gem.pd") );
}
void pdp2gem :: pdpCallback(void *data, t_symbol *action, t_floatarg fpcktno)
{
- // post("pdp2gem : callback : action : %s : no : %f", action->s_name, fpcktno );
+ //post("pdp2gem : callback : action : %s : no : %f\n", action->s_name, fpcktno );
GetMyClass(data)->pdpMess(action, (int)fpcktno);
}
-
+void pdp2gem :: csMessCallback (void *data, t_symbol *colorspace)
+{
+ GetMyClass(data)->csMess((char*)colorspace->s_name);
+}
diff --git a/pdp2gem.h b/pdp2gem.h
index 90969d0..84841b7 100644
--- a/pdp2gem.h
+++ b/pdp2gem.h
@@ -3,7 +3,8 @@
*
* Holds the contents of a PDP packet and introduce it in the GEM rendering chain
*
- * Copyright (c) 2003 Yves Degoyon
+ * Copyright (c) 2003-2005 Yves Degoyon
+ * Copyright (c) 2004-2005 James Tittle
*
*/
@@ -30,7 +31,7 @@ class GEM_EXTERN pdp2gem : public GemBase
CPPEXTERN_HEADER(pdp2gem, GemBase)
public:
- pdp2gem(void);
+ pdp2gem(t_symbol *colorspace);
protected:
virtual ~pdp2gem(void);
@@ -40,8 +41,14 @@ class GEM_EXTERN pdp2gem : public GemBase
virtual void postrender(GemState *state);
virtual void startRendering(void);
virtual void stopRendering(void) {}
- static void pdpCallback(void *data, t_symbol *action, t_floatarg fpcktno);
- void pdpMess(t_symbol *action, t_int fpcktno);
+ void pdpMess(t_symbol *action, int fpcktno);
+
+ //////////
+ // colorspace-message
+ virtual void csMess(char* format);
+
+ t_symbol *colorspace;
+ int m_colorspace;
unsigned char *m_data;
pixBlock m_pixBlock;
@@ -56,6 +63,10 @@ class GEM_EXTERN pdp2gem : public GemBase
t_int m_dropped;
t_pdp *m_header;
short int *m_pdpdata;
+
+ private:
+ static void pdpCallback(void *data, t_symbol *action, t_floatarg fpcktno);
+ static void csMessCallback(void *data, t_symbol *colorspace);
};
#endif // for header file