diff --git a/source/app/ViewArea.cpp b/source/app/ViewArea.cpp index dbba02c..e787fe9 100644 --- a/source/app/ViewArea.cpp +++ b/source/app/ViewArea.cpp @@ -370,7 +370,7 @@ void ViewArea::paintEvent( QPaintEvent *event ) for( Int j = vr.y(); j <= vr.bottom(); j++ ) { QPoint pixelTopLeft( i, j ); - sPixelValue = m_pcCurrFrame->getPixelValue( pixelTopLeft, PlaYUVerFrame::COLOR_YUV ); + sPixelValue = m_pcCurrFrame->getPixelValue( pixelTopLeft.x(), pixelTopLeft.y(), PlaYUVerFrame::COLOR_YUV ); QRect pixelRect( viewToWindow( pixelTopLeft ), QSize( m_zoomFactor, m_zoomFactor ) ); if( sPixelValue.Luma < 128 ) diff --git a/source/app/plaYUVerApp.cpp b/source/app/plaYUVerApp.cpp index 615a2b1..6f24f98 100644 --- a/source/app/plaYUVerApp.cpp +++ b/source/app/plaYUVerApp.cpp @@ -908,7 +908,7 @@ Void plaYUVerApp::updatePixelValueStatusBar( const QPoint & pos, PlaYUVerFrame* if( ( posX < iWidth ) && ( posX >= 0 ) && ( posY < iHeight ) && ( posY >= 0 ) ) { - sPixelValue = curFrame->getPixelValue( pos, PlaYUVerFrame::COLOR_YUV ); + sPixelValue = curFrame->getPixelValue( pos.x(), pos.y(), PlaYUVerFrame::COLOR_YUV ); strPixel = QString( "Y: %1 U: %2 V: %3" ).arg( sPixelValue.Luma ).arg( sPixelValue.ChromaU ).arg( sPixelValue.ChromaV ); strStatus.append( strPixel ); statusBar()->showMessage( strStatus, 3000 ); diff --git a/source/lib/PlaYUVerFrame.cpp b/source/lib/PlaYUVerFrame.cpp index 5feccea..ba5722d 100644 --- a/source/lib/PlaYUVerFrame.cpp +++ b/source/lib/PlaYUVerFrame.cpp @@ -36,90 +36,15 @@ namespace plaYUVer { - - - -Void yuv420_init( UInt Width, UInt Height ) -{ - -} - -PlaYUVerFramePelFormat yuv420p = -{ - "YUV420p", - PlaYUVerFrame::COLOR_YUV, - 2, - 2, - yuv420_init, -}; - -PlaYUVerFramePelFormat yuv444p = -{ - "YUV444p", - PlaYUVerFrame::COLOR_YUV, - 1, - 1, - yuv420_init, -}; - -PlaYUVerFramePelFormat yuv422p = -{ - "YUV422p", - PlaYUVerFrame::COLOR_YUV, - 2, - 1, - yuv420_init, -}; - -PlaYUVerFramePelFormat yuv422 = -{ - "YUV422", - PlaYUVerFrame::COLOR_YUV, - 2, - 1, - yuv420_init, -}; - - -PlaYUVerFramePelFormat gray = -{ - "GRAY", - PlaYUVerFrame::COLOR_YUV, - 4, - 4, - yuv420_init, -}; - -PlaYUVerFramePelFormat rgb8 = -{ - "RGB8", - PlaYUVerFrame::COLOR_RGB, - 1, - 1, - yuv420_init, -}; - -PlaYUVerFramePelFormat PlaYUVerFramePelFormatsList[] = -{ - yuv420p, yuv444p, yuv422p, yuv422, gray, rgb8, -}; - QStringList PlaYUVerFrame::supportedPixelFormatList() { QStringList formats; - Int numberFormats = sizeof(PlaYUVerFramePelFormatsList)/sizeof(PlaYUVerFramePelFormat); - for(Int i=0; i max_bits_per_pel ) { return; } - m_pcPelFormat = &(PlaYUVerFramePelFormatsList[pel_format]); + m_pcPelFormat = &( g_PlaYUVerFramePelFormatsList[pel_format] ); m_bHasRGBPel = false; - - getMem3ImageComponents( &m_pppcInputPel, m_uiHeight, m_uiWidth, m_pcPelFormat->ratioChromaHeight, m_pcPelFormat->ratioChromaWidth ); - -// switch( m_iPixelFormat ) -// { -// case YUV420p: -// getMem3ImageComponents( &m_pppcInputPel, m_uiHeight, m_uiWidth, 2, 2 ); -// break; -// case YUV444p: -// getMem3ImageComponents( &m_pppcInputPel, m_uiHeight, m_uiWidth, 1, 1 ); -// break; -// case YUV422p: -// case YUYV422: -// getMem3ImageComponents( &m_pppcInputPel, m_uiHeight, m_uiWidth, 1, 2 ); -// break; -// case GRAY: -// getMem3ImageComponents( &m_pppcInputPel, m_uiHeight, m_uiWidth, 4, 4 ); -// break; -// case RGB8: -// getMem3ImageComponents( &m_pppcInputPel, m_uiHeight, m_uiWidth, 1, 1 ); -// break; -// default: -// m_pppcInputPel = NULL; -// break; -// } + if( m_pcPelFormat->colorSpace == COLOR_GRAY ) + { + getMem3ImageComponents( &m_pppcInputPel, m_uiHeight, m_uiWidth, 1, 1 ); + } + else + { + getMem3ImageComponents( &m_pppcInputPel, m_uiHeight, m_uiWidth, m_pcPelFormat->ratioChromaHeight, m_pcPelFormat->ratioChromaWidth ); + } getMem1D( &m_pcRGBPelInterlaced, m_uiHeight * m_uiWidth * 3 ); + openPixfc(); } -Void PlaYUVerFrame::openPixfc() +UInt64 PlaYUVerFrame::getBytesPerFrame() { -#ifdef USE_PIXFC - m_pcPixfc = NULL; - PixFcPixelFormat input_format = PixFcYUV420P; - PixFcFlag flags = (PixFcFlag)(PixFcFlag_Default + PixFcFlag_NNbResamplingOnly); - UInt input_row_size = m_uiWidth; - if (create_pixfc(&m_pcPixfc, input_format, PixFcRGB24, m_uiWidth, m_uiHeight, input_row_size, m_uiWidth * 3, flags ) != 0) - { - fprintf(stderr, "Error creating struct pixfc\n"); - m_pcPixfc = NULL; - return; - } -#endif + return getBytesPerFrame( m_uiWidth, m_uiHeight, m_iPixelFormat ); } -Void PlaYUVerFrame::closePixfc() +UInt64 PlaYUVerFrame::getBytesPerFrame( UInt uiWidth, UInt uiHeight, Int iPixelFormat ) { -#ifdef USE_PIXFC - if( m_pcPixfc ) - destroy_pixfc(m_pcPixfc); -#endif + PlaYUVerFramePelFormat* pcPelFormat = &( g_PlaYUVerFramePelFormatsList[iPixelFormat] ); + UInt64 numberBytes = uiWidth * uiHeight; + if( pcPelFormat->numberChannels > 1 ) + { + numberBytes += ( pcPelFormat->numberChannels - 1 ) * ( uiWidth * uiHeight ) / ( pcPelFormat->ratioChromaWidth * pcPelFormat->ratioChromaHeight ); + } + return numberBytes; } -Void PlaYUVerFrame::FrametoRGB8Pixfc() +UInt PlaYUVerFrame::getChromaWidth() const { -#ifdef USE_PIXFC - switch( m_iPixelFormat ) - { - case YUV420p: - m_pcPixfc->convert(m_pcPixfc, m_pppcInputPel, m_pcRGBPelInterlaced); - break; - case YUV422p: - break; - case YUV444p: - case YUYV422: - m_pcPixfc->convert(m_pcPixfc, m_pppcInputPel, m_pcRGBPelInterlaced); - break; - case GRAY: - break; - case RGB8: - break; - default: - // No action. - break; - } - m_bHasRGBPel = true; -#endif + return m_pcPelFormat->ratioChromaWidth > 0 ? m_uiWidth / m_pcPelFormat->ratioChromaWidth : 0; +} + +UInt PlaYUVerFrame::getChromaHeight() const +{ + return m_pcPelFormat->ratioChromaHeight > 0 ? m_uiHeight / m_pcPelFormat->ratioChromaHeight : 0; +} + +UInt PlaYUVerFrame::getChromaLength() const +{ + return getChromaWidth() * getChromaHeight(); } template @@ -279,6 +170,44 @@ Void rgbToYuv( T iR, T iG, T iB, T &iY, T &iU, T &iV ) iV = ( 1000 * ( iR - iY ) + 179456 ) / 1402; } + +Pixel PlaYUVerFrame::getPixelValue( Int xPos, Int yPos, Int eColorSpace ) +{ + Pixel PelValue = m_pcPelFormat->getPixelValue(m_pppcInputPel, xPos, yPos ); + ConvertPixel( PelValue, eColorSpace ); + return PelValue; +} + +Pixel PlaYUVerFrame::ConvertPixel( Pixel sInputPixel, Int eOutputSpace ) +{ + Int outA, outB, outC; + Pixel sOutputPixel = + { + COLOR_INVALID, + 0, + 0, + 0 }; + + if( sInputPixel.color_space == eOutputSpace ) + return sInputPixel; + + if( eOutputSpace == COLOR_RGB ) + { + yuvToRgb( sInputPixel.Luma, sInputPixel.ChromaU, sInputPixel.ChromaV, outA, outB, outC ); + sOutputPixel.ColorR = outA; + sOutputPixel.ColorG = outB; + sOutputPixel.ColorB = outC; + } + if( eOutputSpace == COLOR_YUV ) + { + rgbToYuv( sInputPixel.ColorR, sInputPixel.ColorG, sInputPixel.ColorB, outA, outB, outC ); + sOutputPixel.Luma = outA; + sOutputPixel.ChromaU = outB; + sOutputPixel.ChromaV = outC; + } + return sOutputPixel; +} + Void PlaYUVerFrame::FrametoRGB8() { if( m_bHasRGBPel ) @@ -571,176 +500,54 @@ Void PlaYUVerFrame::copyFrom( PlaYUVerFrame* input_frame, UInt xPos, UInt yPos ) } } -UInt64 PlaYUVerFrame::getBytesPerFrame() +Void PlaYUVerFrame::openPixfc() { - return getBytesPerFrame( m_uiWidth, m_uiHeight, m_iPixelFormat ); -} - -UInt64 PlaYUVerFrame::getBytesPerFrame( UInt uiWidth, UInt uiHeight, Int iPixelFormat ) -{ - switch( iPixelFormat ) +#ifdef USE_PIXFC + m_pcPixfc = NULL; + PixFcPixelFormat input_format = PixFcYUV420P; + PixFcFlag flags = (PixFcFlag)(PixFcFlag_Default + PixFcFlag_NNbResamplingOnly); + UInt input_row_size = m_uiWidth; + if (create_pixfc(&m_pcPixfc, input_format, PixFcRGB24, m_uiWidth, m_uiHeight, input_row_size, m_uiWidth * 3, flags ) != 0) { - case YUV420p: - return uiWidth * uiHeight * 1.5; - break; - case YUV444p: - return uiWidth * uiHeight * 3; - break; - case YUV422p: - case YUYV422: - return uiWidth * uiHeight * 2; - break; - case GRAY: - return uiWidth * uiHeight; - break; - case RGB8: - return uiWidth * uiHeight * 3; - break; - default: - return 0; + fprintf(stderr, "Error creating struct pixfc\n"); + m_pcPixfc = NULL; + return; } - return 0; +#endif } -UInt PlaYUVerFrame::getChromaWidth() const +Void PlaYUVerFrame::closePixfc() { +#ifdef USE_PIXFC + if( m_pcPixfc ) + destroy_pixfc(m_pcPixfc); +#endif +} + +Void PlaYUVerFrame::FrametoRGB8Pixfc() +{ +#ifdef USE_PIXFC switch( m_iPixelFormat ) { - case YUV420p: - return m_uiWidth / 2; + case YUV420p: + m_pcPixfc->convert(m_pcPixfc, m_pppcInputPel, m_pcRGBPelInterlaced); break; - case YUV444p: - case YUV422p: - case YUYV422: - case RGB8: - return m_uiWidth; + case YUV422p: break; - case GRAY: - return 0; + case YUV444p: + case YUYV422: + m_pcPixfc->convert(m_pcPixfc, m_pppcInputPel, m_pcRGBPelInterlaced); break; - default: - return 0; - } - return 0; -} - -UInt PlaYUVerFrame::getChromaHeight() const -{ - switch( m_iPixelFormat ) - { - case YUV420p: - case YUV422p: - case YUYV422: - return m_uiHeight / 2; + case GRAY: break; - case YUV444p: - case RGB8: - return m_uiHeight; - case GRAY: - return 0; + case RGB8: break; - default: - return 0; - } - return 0; -} - -UInt PlaYUVerFrame::getChromaLength() const -{ - switch( m_iPixelFormat ) - { - case YUV420p: - return m_uiWidth * m_uiHeight / 4; - break; - case YUV444p: - return m_uiWidth * m_uiHeight; - break; - case YUV422p: - case YUYV422: - return m_uiWidth * m_uiHeight / 2; - break; - case GRAY: - return 0; - break; - case RGB8: - return m_uiWidth * m_uiHeight; - break; - default: - return 0; - } - return 0; -} - -Pixel PlaYUVerFrame::getPixelValue( const QPoint &pos, Int color_space ) -{ - Pixel pixel_value; - switch( m_iPixelFormat ) - { - case YUV420p: - pixel_value.color_space = COLOR_YUV; - pixel_value.Luma = m_pppcInputPel[LUMA][pos.y()][pos.x()]; - pixel_value.ChromaU = m_pppcInputPel[CHROMA_U][pos.y() >> 1][pos.x() >> 1]; - pixel_value.ChromaV = m_pppcInputPel[CHROMA_V][pos.y() >> 1][pos.x() >> 1]; - break; - case YUV444p: - pixel_value.Luma = m_pppcInputPel[LUMA][pos.y()][pos.x()]; - pixel_value.ChromaU = m_pppcInputPel[CHROMA_U][pos.y()][pos.x()]; - pixel_value.ChromaV = m_pppcInputPel[CHROMA_V][pos.y()][pos.x()]; - break; - case YUV422p: - case YUYV422: - pixel_value.color_space = COLOR_YUV; - pixel_value.Luma = m_pppcInputPel[LUMA][pos.y()][pos.x()]; - pixel_value.ChromaU = m_pppcInputPel[CHROMA_U][pos.y()][pos.x() >> 1]; - pixel_value.ChromaV = m_pppcInputPel[CHROMA_V][pos.y()][pos.x() >> 1]; - break; - case GRAY: - pixel_value.color_space = COLOR_YUV; - pixel_value.Luma = m_pppcInputPel[LUMA][pos.y()][pos.x()]; - pixel_value.ChromaU = 0; - pixel_value.ChromaV = 0; - break; - case RGB8: - pixel_value.color_space = COLOR_RGB; - pixel_value.ColorR = m_pppcInputPel[COLOR_R][pos.y()][pos.x()]; - pixel_value.ColorG = m_pppcInputPel[COLOR_G][pos.y()][pos.x()]; - pixel_value.ColorB = m_pppcInputPel[COLOR_B][pos.y()][pos.x()]; - break; - default: + default: + // No action. break; } - ConvertPixel( pixel_value, color_space ); - return pixel_value; -} - -Pixel PlaYUVerFrame::ConvertPixel( Pixel sInputPixel, Int eOutputSpace ) -{ - Int outA, outB, outC; - Pixel sOutputPixel = - { - COLOR_INVALID, - 0, - 0, - 0 }; - - if( sInputPixel.color_space == eOutputSpace ) - return sInputPixel; - - if( eOutputSpace == COLOR_RGB ) - { - yuvToRgb( sInputPixel.Luma, sInputPixel.ChromaU, sInputPixel.ChromaV, outA, outB, outC ); - sOutputPixel.ColorR = outA; - sOutputPixel.ColorG = outB; - sOutputPixel.ColorB = outC; - } - if( eOutputSpace == COLOR_YUV ) - { - rgbToYuv( sInputPixel.ColorR, sInputPixel.ColorG, sInputPixel.ColorB, outA, outB, outC ); - sOutputPixel.Luma = outA; - sOutputPixel.ChromaU = outB; - sOutputPixel.ChromaV = outC; - } - return sOutputPixel; + m_bHasRGBPel = true; +#endif } #ifdef USE_OPENCV @@ -776,9 +583,7 @@ cv::Mat PlaYUVerFrame::getCvMat() } return opencvFrame; } -#endif -#ifdef USE_OPENCV Void PlaYUVerFrame::copyFrom( cv::Mat* opencvFrame ) { if( m_iPixelFormat == NO_FMT ) diff --git a/source/lib/PlaYUVerFrame.h b/source/lib/PlaYUVerFrame.h index 22c8e3f..51de341 100644 --- a/source/lib/PlaYUVerFrame.h +++ b/source/lib/PlaYUVerFrame.h @@ -47,11 +47,19 @@ typedef struct { const Char* name; Int colorSpace; + UInt numberChannels; Int ratioChromaWidth; Int ratioChromaHeight; - Void (*init)( UInt Width, UInt Height ); + Pixel (*getPixelValue) ( Pel ***Img, Int xPos, Int yPos ); + Void (*frameFromBuffer)( Pel *in, Pel*** out ); + Void (*bufferFromFrame)( Pel ***in, Pel* out ); + Void (*fillRGBbuffer)( Pel*** in, UChar* out ); } PlaYUVerFramePelFormat; +#define PLAYUVER_NUMBER_FORMATS 6 + +extern PlaYUVerFramePelFormat g_PlaYUVerFramePelFormatsList[PLAYUVER_NUMBER_FORMATS]; + class PlaYUVerFrame { public: @@ -129,7 +137,7 @@ public: return m_pppcInputPel; } - Pixel getPixelValue( const QPoint&, Int ); + Pixel getPixelValue( Int xPos, Int yPos, Int eColorSpace ); UChar* getQImageBuffer() const { diff --git a/source/lib/PlaYUVerFramePixelFormats.cpp b/source/lib/PlaYUVerFramePixelFormats.cpp new file mode 100644 index 0000000..a7790df --- /dev/null +++ b/source/lib/PlaYUVerFramePixelFormats.cpp @@ -0,0 +1,183 @@ +/* This file is a part of plaYUVer project + * Copyright (C) 2014 by Luis Lucas (luisfrlucas@gmail.com) + * Joao Carreira (jfmcarreira@gmail.com) + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** + * \file PlaYUVerFrame.cpp + * \brief Video Frame handling + */ + +#include "config.h" +#include +#include "LibMemory.h" +#include "PlaYUVerFrame.h" + +namespace plaYUVer +{ + +Void frameFromBuffer_yuv420p( Pel *in, Pel*** out ) +{ + +} +Void bufferFromFrame_yuv420p( Pel ***in, Pel* out ) +{ + +} +Void fillRGBbuffer_yuv420p( Pel*** in, UChar* out ) +{ + +} +Pixel getPixelValueYUV420p ( Pel ***Img, Int xPos, Int yPos ) +{ + Pixel pixel_value; + pixel_value.color_space = PlaYUVerFrame::COLOR_YUV; + pixel_value.Luma = Img[LUMA][yPos][xPos]; + pixel_value.ChromaU = Img[CHROMA_U][yPos >> 1][xPos >> 1]; + pixel_value.ChromaV = Img[CHROMA_V][yPos >> 1][xPos >> 1]; + return pixel_value; +} + +Pixel getPixelValueYUV444p ( Pel ***Img, Int xPos, Int yPos ) +{ + Pixel pixel_value; + pixel_value.color_space = PlaYUVerFrame::COLOR_YUV; + pixel_value.Luma = Img[LUMA][yPos][xPos]; + pixel_value.ChromaU = Img[CHROMA_U][yPos][xPos]; + pixel_value.ChromaV = Img[CHROMA_V][yPos][xPos]; + return pixel_value; +} + +Pixel getPixelValueYUV422 ( Pel ***Img, Int xPos, Int yPos ) +{ + Pixel pixel_value; + pixel_value.color_space = PlaYUVerFrame::COLOR_YUV; + pixel_value.Luma = Img[LUMA][yPos][xPos]; + pixel_value.ChromaU = Img[CHROMA_U][yPos][xPos >> 1]; + pixel_value.ChromaV = Img[CHROMA_V][yPos][xPos >> 1]; + return pixel_value; +} + +Pixel getPixelValueGray ( Pel ***Img, Int xPos, Int yPos ) +{ + Pixel pixel_value; + pixel_value.color_space = PlaYUVerFrame::COLOR_YUV; + pixel_value.Luma = Img[LUMA][yPos][xPos]; + pixel_value.ChromaU = 0; + pixel_value.ChromaV = 0; + return pixel_value; +} + +Pixel getPixelValueRGB8 ( Pel ***Img, Int xPos, Int yPos ) +{ + Pixel pixel_value; + pixel_value.color_space = PlaYUVerFrame::COLOR_RGB; + pixel_value.ColorR = Img[COLOR_R][yPos][xPos]; + pixel_value.ColorG = Img[COLOR_G][yPos][xPos]; + pixel_value.ColorB = Img[COLOR_B][yPos][xPos]; + return pixel_value; +} + +PlaYUVerFramePelFormat yuv420p = +{ + "YUV420p", + PlaYUVerFrame::COLOR_YUV, + 3, + 2, + 2, + getPixelValueYUV420p, + frameFromBuffer_yuv420p, + bufferFromFrame_yuv420p, + fillRGBbuffer_yuv420p, +}; + +PlaYUVerFramePelFormat yuv444p = +{ + "YUV444p", + PlaYUVerFrame::COLOR_YUV, + 3, + 1, + 1, + getPixelValueYUV444p, + frameFromBuffer_yuv420p, + bufferFromFrame_yuv420p, + fillRGBbuffer_yuv420p, +}; + +PlaYUVerFramePelFormat yuv422p = +{ + "YUV422p", + PlaYUVerFrame::COLOR_YUV, + 3, + 2, + 1, + getPixelValueYUV422, + frameFromBuffer_yuv420p, + bufferFromFrame_yuv420p, + fillRGBbuffer_yuv420p, +}; + +PlaYUVerFramePelFormat yuv422 = +{ + "YUV422", + PlaYUVerFrame::COLOR_YUV, + 3, + 2, + 1, + getPixelValueYUV422, + frameFromBuffer_yuv420p, + bufferFromFrame_yuv420p, + fillRGBbuffer_yuv420p, +}; + +PlaYUVerFramePelFormat gray = +{ + "GRAY", + PlaYUVerFrame::COLOR_GRAY, + 1, + 0, + 0, + getPixelValueGray, + frameFromBuffer_yuv420p, + bufferFromFrame_yuv420p, + fillRGBbuffer_yuv420p, +}; + +PlaYUVerFramePelFormat rgb8 = +{ + "RGB8", + PlaYUVerFrame::COLOR_RGB, + 3, + 1, + 1, + getPixelValueRGB8, + frameFromBuffer_yuv420p, + bufferFromFrame_yuv420p, + fillRGBbuffer_yuv420p, +}; + +extern PlaYUVerFramePelFormat g_PlaYUVerFramePelFormatsList[PLAYUVER_NUMBER_FORMATS] = +{ + yuv420p, + yuv444p, + yuv422p, + yuv422, + gray, + rgb8, +}; + +} // NAMESPACE