📄 bvccolorconverter.cpp
字号:
//! Blue unity LUT
static BYTE pLutB[LUT_LENGTH] = {0};
//! Indicates if the unitiy LUTs still have to be initializes
static bool AreLutsInitialized = false;
//! Initialize unitiy LUTs
static void InitializeLUTs()
{
for(int i=0; i<LUT_LENGTH; ++i)
{
pLutR[i] = BYTE( i );
pLutG[i] = BYTE( i );
pLutB[i] = BYTE( i );
}
AreLutsInitialized = true;
}
/*!
Conversion of Bayer raw pixel data to RGB using CDibPtrs. The source image bust be a top down bitmap.
The user has to specify the origin of the Bayer pattern. The resulting destination bitmap will be a bottom up bitmap.
If ptrDest is NULL or if the size of the referenced image does not fit ptrSource the
old image pointed to by ptrDest will be destroyed and a new fitting one created.
If ptrSource is NULL ptrDestinateion is destroyed and the function returns immediately.
*/
void CColorConverter::ConvertMono8ToRGB(
CDibPtr &ptrDest, //!< Smart pointer to the destinat韔n image.
const CDibPtr &ptrSource, //!< Smart pointer to the source image
PatternOrigin_t PatternOrigin //!< Indicates the Bayer pattern of the first line of ptrSource
)
{
// initialize static LUTs if necessary
if(!AreLutsInitialized)
InitializeLUTs();
// Call the more elaborate version of the function
CColorConverter::ConvertMono8ToRGB(ptrDest, ptrSource, PatternOrigin, pLutR, pLutG, pLutB);
}
/*!
Conversion of Bayer raw pixel data to RGB using CDibPtrs. The source image bust be a top down bitmap.
The user has to specify the origin of the Bayer pattern and to provide
lookup tables for the color channels (e.g. for white balance purposes).
The resulting destination bitmap will be a bottom up bitmap.
If ptrDest is NULL or if the size of the referenced image does not fit ptrSource the
old image pointed to by ptrDest will be destroyed and a new fitting one created.
If ptrSource is NULL ptrDestinateion is destroyed and the function returns immediately.
*/
void CColorConverter::ConvertMono8ToRGB(
CDibPtr &ptrDest, //!< Smart pointer to the destinat韔n image.
const CDibPtr &ptrSource, //!< Smart pointer to the source image
PatternOrigin_t PatternOrigin, //!< Indicates the Bayer pattern of the first line of ptrSource
const BYTE pLutR[LUT_LENGTH], //!< Look-up table for the red channel
const BYTE pLutG[LUT_LENGTH], //!< Look-up table for the green channel
const BYTE pLutB[LUT_LENGTH] //!< Look-up table for the blue channel
)
{
if(!ptrSource)
{
ptrDest.Release();
return;
}
// If necessary create a matching targe bitmap
if(
!ptrDest // Kein Target
|| ptrDest->GetSize() != ptrSource->GetSize() // size mismatch
|| ptrDest->GetBitsPerPixel() != 24 // color format mismatch
)
{
ptrDest.Create(
ptrSource->GetSize(), // same size as source
24, // 24 bit RGB
ptrSource->GetOrientation() == CDib::BottomUp ? CDib::TopDown : CDib::BottomUp, // the algorithm topples!
CDib::Color // Color
);
}
// Call raw function
CSize srcSize = ptrSource->GetSize();
CColorConverter::ConvertMono8ToRGB(
(BYTE*)ptrDest->GetPixels(),
(BYTE*)ptrSource->GetPixels(),
srcSize,
PatternOrigin,
pLutR,
pLutG,
pLutB
);
}
/*!
Conversion of Bayer raw pixel data to RGB. The source buffer must represent a top down Bayer coded image.
The user has to specify the origin of the Bayer pattern and to provide
lookup tables for the color channels (e.g. for white balance purposes).
The converted image will be a bottom up image.
*/
void CColorConverter::ConvertMono8ToRGB(
BYTE* pDest, //!< Pointer to which the RGB data will be written
const BYTE* pSource, //!< Pointer to the raw Bayer pixel data to be converted
const CSize& Size, //!< Size of image
PatternOrigin_t PatternOrigin, //!< PatternOrigin Spezifies wether the first pixel of the bayer raw data is a red, blue or green one
const BYTE pLutR[LUT_LENGTH], //!< Pointer to a lookup table for the green channel
const BYTE pLutG[LUT_LENGTH], //!< Pointer to a lookup table for the red channel
const BYTE pLutB[LUT_LENGTH] //!< Pointer to a lookup table for the blue channel
)
{
ConvertMono8ToRGB(pDest, pSource, Size, PatternOrigin, -Size.cx * 3, Size.cx, pLutR, pLutG, pLutB);
}
/*!
Conversion of Bayer raw pixel data to RGB. The source buffer must represent a top down Bayer coded image.
The user has to specify the origin of the Bayer pattern and to provide
lookup tables for the color channels (e.g. for white balance purposes). Different strides for the destination
buffer and source buffer can be specified (Stride is the distance,in bytes, between two memory addresses
that represent the beginning of one bitmap line and the beginning of the next bitmap line.)
For the destination buffer positive strides will result in top down images,
negative strides will result in bottom up images.
*/
void CColorConverter::ConvertMono8ToRGB(
BYTE* pDest, //!< Pointer to which the RGB data will be written
const BYTE* pSource, //!< Pointer to the raw Bayer pixel data to be converted
const CSize& Size, //!< Size of image
PatternOrigin_t PatternOrigin, //!< PatternOrigin Spezifies wether the first pixel of the bayer raw data is a red, blue or green one
int strideDest, //!< Stride for destination buffer (in bytes)
unsigned int strideSource //!< Stride for source buffer (in bytes)
)
{
// initialize static LUTs if necessary
if(!AreLutsInitialized)
InitializeLUTs();
ConvertMono8ToRGB(pDest, pSource, Size, PatternOrigin, strideDest, strideSource, pLutR, pLutG, pLutB);
}
/*!
Conversion of Bayer raw pixel data to RGB. The user has to specify the origin of the Bayer pattern and to provide
lookup tables for the color channels (e.g. for white balance purposes). Different strides for the destination
buffer and source buffer can be specified. Stride is the distance,in bytes, between two memory addresses
that represent the beginning of one bitmap line and the beginning of the next bitmap line. Negative strides
indicates bottom up images.
*/
void CColorConverter::ConvertMono8ToRGB(
BYTE* pDest, //!< Pointer to which the RGB data will be written
const BYTE* pSource, //!< Pointer to the raw Bayer pixel data to be converted
const CSize& Size, //!< Size of image
PatternOrigin_t PatternOrigin, //!< PatternOrigin Spezifies wether the first pixel of the bayer raw data is a red, blue or green one
int strideDest, //!< Stride for destination buffer (in bytes)
unsigned int strideSource, //!< Stride for source buffer (in bytes)
const BYTE pLutR[LUT_LENGTH], //!< Pointer to a lookup table for the green channel
const BYTE pLutG[LUT_LENGTH], //!< Pointer to a lookup table for the red channel
const BYTE pLutB[LUT_LENGTH] //!< Pointer to a lookup table for the blue channel
)
{
RGBTRIPLE* pRGB = (RGBTRIPLE*) pDest;
if ( strideDest < 0 )
pRGB = pRGB + (Size.cy - 1 ) * Size.cx;
switch ( PatternOrigin)
{
case poGB:
// Bayer Image starts with a GBGB row
ConvertMono8ToRGB( GBLineConverter::Convert, pRGB, pSource, Size, 0, strideDest, strideSource, pLutR, pLutG, pLutB);
ConvertMono8ToRGB( RGLineConverter::Convert, pRGB, pSource, Size, 1, strideDest, strideSource, pLutR, pLutG, pLutB);
break;
case poGR:
// Bayer Image starts with a GRGR row
ConvertMono8ToRGB( GRLineConverter::Convert, pRGB, pSource, Size, 0, strideDest, strideSource, pLutR, pLutG, pLutB);
ConvertMono8ToRGB( BGLineConverter::Convert, pRGB, pSource, Size, 1, strideDest, strideSource, pLutR, pLutG, pLutB);
break;
case poB:
// Bayer Image starts with a BGBG row
ConvertMono8ToRGB( BGLineConverter::Convert, pRGB, pSource, Size, 0, strideDest, strideSource, pLutR, pLutG, pLutB);
ConvertMono8ToRGB( GRLineConverter::Convert, pRGB, pSource, Size, 1, strideDest, strideSource, pLutR, pLutG, pLutB);
break;
case poR:
// Bayer Image starts with a RGRG row
ConvertMono8ToRGB( RGLineConverter::Convert, pRGB, pSource, Size, 0, strideDest, strideSource, pLutR, pLutG, pLutB);
ConvertMono8ToRGB( GBLineConverter::Convert, pRGB, pSource, Size, 1, strideDest, strideSource, pLutR, pLutG, pLutB);
}
// Treatment of the border: Erase the right most column and the last row of the destination image
static RGBTRIPLE zero = {0, 0, 0};
// set the right most column to zero
int i;
for ( i = 0; i < Size.cy; i++ )
{
pRGB[Size.cx - 1 + ( i * strideDest / 3 ) ] = zero;
}
// set the last row to zero
for ( i = 0; i < Size.cx; i ++ )
{
pRGB[ i + ( Size.cy - 1) * strideDest / 3 ] = zero;
}
}
#define REDPIXEL() \
pRGB->rgbtBlue = pLutB[*(pRaw + strideSource + 1)]; \
pRGB->rgbtGreen = pLutG[(BYTE) ( ( (int) *(pRaw +1) + (int) *(pRaw + strideSource) ) >> 1 )]; \
pRGB->rgbtRed = pLutR[*pRaw]; \
++pRaw; \
++pRGB;
#define BLUEPIXEL() \
pRGB->rgbtBlue = pLutB[*pRaw]; \
pRGB->rgbtGreen = pLutG[(BYTE) ( ( (int) *( pRaw + 1) + (int) *( pRaw + strideSource ) ) >> 1 )]; \
pRGB->rgbtRed = pLutR[*(pRaw + strideSource + 1)]; \
++pRaw; \
++pRGB;
#define GREENPIXEL_R() \
pRGB->rgbtBlue = pLutB[*(pRaw + strideSource )]; \
pRGB->rgbtGreen = pLutG[(BYTE) ( ( (int) *pRaw + (int) *(pRaw + strideSource + 1 ) ) >> 1 ) ]; \
pRGB->rgbtRed = pLutR[*(pRaw + 1)]; \
++pRaw; \
++pRGB;
#define GREENPIXEL_B() \
pRGB->rgbtBlue = pLutB[*(pRaw + 1)]; \
pRGB->rgbtGreen = pLutG[(BYTE) ( ( (int) *pRaw + (int) *(pRaw + strideSource + 1 ) ) >> 1 ) ]; \
pRGB->rgbtRed = pLutR[*(pRaw + strideSource )]; \
++pRaw; \
++pRGB;
void CColorConverter::GBLineConverter::Convert(const unsigned char*& pRaw, const BYTE* pRawEnd,
const BYTE pLutR[LUT_LENGTH], const BYTE pLutG[LUT_LENGTH], const BYTE pLutB[LUT_LENGTH],
const unsigned int strideSource, RGBTRIPLE*& pRGB )
{
while ( pRaw < pRawEnd )
{
GREENPIXEL_B();
BLUEPIXEL();
}
GREENPIXEL_B();
}
void CColorConverter::GRLineConverter::Convert(const BYTE*& pRaw, const BYTE* pRawEnd,
const BYTE pLutR[LUT_LENGTH], const BYTE pLutG[LUT_LENGTH], const BYTE pLutB[LUT_LENGTH],
const unsigned int strideSource, RGBTRIPLE*& pRGB )
{
while ( pRaw < pRawEnd )
{
GREENPIXEL_R();
REDPIXEL();
}
GREENPIXEL_R();
}
void CColorConverter::BGLineConverter::Convert(const BYTE*& pRaw, const BYTE* pRawEnd,
const BYTE pLutR[LUT_LENGTH], const BYTE pLutG[LUT_LENGTH], const BYTE pLutB[LUT_LENGTH],
const unsigned int strideSource, RGBTRIPLE*& pRGB )
{
while ( pRaw < pRawEnd )
{
BLUEPIXEL();
GREENPIXEL_B();
}
BLUEPIXEL();
}
void CColorConverter::RGLineConverter::Convert(const BYTE*& pRaw, const BYTE* pRawEnd,
const BYTE pLutR[LUT_LENGTH], const BYTE pLutG[LUT_LENGTH], const BYTE pLutB[LUT_LENGTH],
const unsigned int strideSource, RGBTRIPLE*& pRGB )
{
while ( pRaw < pRawEnd )
{
REDPIXEL();
GREENPIXEL_R();
}
REDPIXEL();
}
/* Converts every second lone into RGB. */
void CColorConverter::ConvertMono8ToRGB(
void (*Convert)(const BYTE*&, const BYTE*, const BYTE[], const BYTE[], const BYTE[], const unsigned, RGBTRIPLE*&),
RGBTRIPLE* pDest, const BYTE* pSource, const CSize& Size, unsigned int lineoffset,
int strideDest, unsigned int strideSource,
const BYTE pLutR[LUT_LENGTH], const BYTE pLutG[LUT_LENGTH], const BYTE pLutB[LUT_LENGTH])
{
const unsigned char* pLastLine = pSource + strideSource * ( Size.cy - 1);
const unsigned char* pRaw = pSource + lineoffset * strideSource;
RGBTRIPLE* pRGB = pDest + (int) lineoffset * strideDest / 3;
const unsigned char* pEnd;
while ( pRaw < pLastLine )
{
pEnd = pRaw + Size.cx - 2; // we skip the last column
Convert(pRaw, pEnd, pLutR, pLutG, pLutB, strideSource, pRGB );
pRaw += strideSource + 1;
pRGB += ( strideDest < 0 ? 3 : 1 ) * strideDest / 3 + 1 ;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -