⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vconvert.cxx

📁 pwlib源码库
💻 CXX
📖 第 1 页 / 共 4 页
字号:
  : PColourConverterRegistration(srcFmt,dstFmt){}PColourConverter * PSynonymColourRegistration::Create(unsigned w, unsigned h) const{  PINDEX tab = Find('\t');  return new PSynonymColour(Left(tab), Mid(tab+1), w, h);}BOOL PSynonymColour::Convert(const BYTE *srcFrameBuffer,                             BYTE *dstFrameBuffer,                             PINDEX * bytesReturned){  if ((srcFrameWidth != dstFrameWidth) || (srcFrameHeight != dstFrameHeight)) {    PTRACE(2,"PColCnv\tCannot do synonym colour conversion, source and destination frame size not equal.");    return FALSE;  }  if (verticalFlip) {    PINDEX rowSize = dstFrameBytes/srcFrameHeight;    if (rowSize*srcFrameHeight != dstFrameBytes) {      PTRACE(2,"PColCnv\tCannot do synonym colour conversion, frame does not have equal sized scan lines.");      return FALSE;    }    if (srcFrameBuffer != dstFrameBuffer) {      const BYTE * srcRowPtr = srcFrameBuffer;      BYTE * dstRowPtr = dstFrameBuffer + srcFrameHeight*rowSize;      for (unsigned y = 0; y < srcFrameHeight; y++) {        dstRowPtr -= rowSize;        memcpy(dstRowPtr, srcRowPtr, rowSize);        srcRowPtr += rowSize;      }    }    else {      BYTE * rowPtr1 = dstFrameBuffer;      BYTE * rowPtr2 = dstFrameBuffer + srcFrameHeight*rowSize;      PBYTEArray temp(rowSize);      for (unsigned y = 0; y < srcFrameHeight; y += 2) {        rowPtr2 -= rowSize;        memcpy(temp.GetPointer(), rowPtr1, rowSize);        memcpy(rowPtr1, rowPtr2, rowSize);        memcpy(rowPtr2, temp.GetPointer(), rowSize);        rowPtr1 += rowSize;      }    }  }  else {    if (srcFrameBuffer != dstFrameBuffer)      memcpy(dstFrameBuffer, srcFrameBuffer, dstFrameBytes);  }  if (bytesReturned != NULL)    *bytesReturned = dstFrameBytes;  return TRUE;}///////////////////////////////////////////////////////////////////////////////#define BLACK_Y 0#define BLACK_U 128#define BLACK_V 128#define greytoy(r, y) y=r#define greytoyuv(r, y, u, v) greytoy(r,y); u=BLACK_U; v=BLACK_Vvoid PStandardColourConverter::GreytoYUV420PSameSize(const BYTE * grey, BYTE * yuv) const{  const unsigned planeSize = srcFrameWidth*srcFrameHeight;  const unsigned halfWidth = srcFrameWidth >> 1;  // get pointers to the data  BYTE * yplane  = yuv;  BYTE * uplane  = yuv + planeSize;  BYTE * vplane  = yuv + planeSize + (planeSize >> 2);  const BYTE * greyIndex = grey;  for (unsigned y = 0; y < srcFrameHeight; y++) {    BYTE * yline  = yplane + (y * srcFrameWidth);    BYTE * uline  = uplane + ((y >> 1) * halfWidth);    BYTE * vline  = vplane + ((y >> 1) * halfWidth);    if (verticalFlip)      greyIndex = grey + srcFrameWidth*(srcFrameHeight-1-y);    for (unsigned x = 0; x < srcFrameWidth; x+=2) {      greytoy(*greyIndex, *yline);      greyIndex++;      yline++;      greytoyuv(*greyIndex, *yline, *uline, *vline);      greyIndex++;      yline++;      uline++;      vline++;    }  }}// Simple crop/pad version.  Image aligned to top-left// and cropped / padded with black borders as required.void PStandardColourConverter::GreytoYUV420PWithResize(const BYTE * grey,						       BYTE * yuv) const{  int planeSize = dstFrameWidth*dstFrameHeight;  const int halfWidth = dstFrameWidth >> 1;  unsigned min_width, min_height;  min_width  = (dstFrameWidth  < srcFrameWidth)  ? dstFrameWidth  : srcFrameWidth;  min_height = (dstFrameHeight < srcFrameHeight) ? dstFrameHeight : srcFrameHeight;  // get pointers to the data  BYTE * yplane  = yuv;  BYTE * uplane  = yuv + planeSize;  BYTE * vplane  = yuv + planeSize + (planeSize >> 2);  const BYTE * greyIndex = grey;  for (unsigned y = 0; y < min_height; y++)   {    BYTE * yline  = yplane + (y * dstFrameWidth);    BYTE * uline  = uplane + ((y >> 1) * halfWidth);    BYTE * vline  = vplane + ((y >> 1) * halfWidth);    if (verticalFlip)      greyIndex = grey + srcFrameWidth*(min_height-1-y);    for (unsigned x = 0; x < min_width; x+=2)     {      greytoy(*greyIndex, *yline);      greyIndex++;      yline++;      greytoyuv(*greyIndex, *yline, *uline, *vline);      greyIndex++;      yline++;      uline++;      vline++;    }    // Crop if source width > dest width    if (srcFrameWidth > dstFrameWidth)      greyIndex += srcFrameWidth - dstFrameWidth;    // Pad if dest width < source width    if (dstFrameWidth > srcFrameWidth) {      memset(yline, BLACK_Y, dstFrameWidth - srcFrameWidth);      memset(uline, BLACK_U, (dstFrameWidth - srcFrameWidth)>>1);      memset(vline, BLACK_V, (dstFrameWidth - srcFrameWidth)>>1);    }  }  // Pad if dest height > source height  if (dstFrameHeight > srcFrameHeight) {    BYTE * yline  = yplane + (srcFrameHeight * dstFrameWidth);    BYTE * uline  = uplane + ((srcFrameHeight >> 1) * halfWidth);    BYTE * vline  = vplane + ((srcFrameHeight >> 1) * halfWidth);    unsigned fill = (dstFrameHeight - srcFrameHeight) * dstFrameWidth;    memset(yline, BLACK_Y, fill);    memset(uline, BLACK_U, fill >> 2);    memset(vline, BLACK_V, fill >> 2);  }}BOOL PStandardColourConverter::GreytoYUV420P(const BYTE * grey,					     BYTE * yuv,					     PINDEX * bytesReturned) const{  if (grey == yuv)    return FALSE; // Cannot do in place conversion  if ((srcFrameWidth == dstFrameWidth) && (srcFrameHeight == dstFrameHeight))     GreytoYUV420PSameSize(grey, yuv);  else    GreytoYUV420PWithResize(grey, yuv);  if (bytesReturned != NULL)    *bytesReturned = dstFrameBytes;  return TRUE;}#define RGB2Y(r, g, b, y) \  y=(BYTE)(((int)257*(r)  +(int)504*(g) +(int)98*(b))/1000)#define RGB2YUV(r, g, b, y, cb, cr) \  RGB2Y(r, g, b, y); \  cb=(BYTE)((-148*(r)  -291*(g) +439*(b))/1000 + 128); \  cr=(BYTE)(( 439*(r)  -368*(g) - 71*(b))/1000 + 128)void PStandardColourConverter::RGBtoYUV420PSameSize(const BYTE * rgb,                                                    BYTE * yuv,                                                    unsigned rgbIncrement,						    unsigned redOffset,                                                    unsigned blueOffset) const{  const unsigned planeSize = srcFrameWidth*srcFrameHeight;  const unsigned halfWidth = srcFrameWidth >> 1;  // get pointers to the data  BYTE * yplane  = yuv;  BYTE * uplane  = yuv + planeSize;  BYTE * vplane  = yuv + planeSize + (planeSize >> 2);  const BYTE * rgbIndex = rgb;  for (unsigned y = 0; y < srcFrameHeight; y++) {    BYTE * yline  = yplane + (y * srcFrameWidth);    BYTE * uline  = uplane + ((y >> 1) * halfWidth);    BYTE * vline  = vplane + ((y >> 1) * halfWidth);    if (verticalFlip)      rgbIndex = rgb + (srcFrameWidth*(srcFrameHeight-1-y)*rgbIncrement);    for (unsigned x = 0; x < srcFrameWidth; x+=2) {      RGB2Y(rgbIndex[redOffset], rgbIndex[1], rgbIndex[blueOffset], *yline);      rgbIndex += rgbIncrement;      yline++;      RGB2YUV(rgbIndex[redOffset], rgbIndex[1], rgbIndex[blueOffset], *yline, *uline, *vline);      rgbIndex += rgbIncrement;      yline++;      uline++;      vline++;    }  }}// Simple crop/pad version.  Image aligned to top-left// and cropped / padded with black borders as required.void PStandardColourConverter::RGBtoYUV420PWithResize(const BYTE * rgb,                                                      BYTE * yuv,                                                      unsigned rgbIncrement,						      unsigned redOffset,                                                      unsigned blueOffset) const{  int planeSize = dstFrameWidth*dstFrameHeight;  const int halfWidth = dstFrameWidth >> 1;  unsigned min_width, min_height;  min_width  = (dstFrameWidth  < srcFrameWidth)  ? dstFrameWidth  : srcFrameWidth;  min_height = (dstFrameHeight < srcFrameHeight) ? dstFrameHeight : srcFrameHeight;  // get pointers to the data  BYTE * yplane  = yuv;  BYTE * uplane  = yuv + planeSize;  BYTE * vplane  = yuv + planeSize + (planeSize >> 2);  const BYTE * rgbIndex = rgb;  for (unsigned y = 0; y < min_height; y++)   {    BYTE * yline  = yplane + (y * dstFrameWidth);    BYTE * uline  = uplane + ((y >> 1) * halfWidth);    BYTE * vline  = vplane + ((y >> 1) * halfWidth);    if (verticalFlip)      rgbIndex = rgb + (srcFrameWidth*(min_height-1-y)*rgbIncrement);     for (unsigned x = 0; x < min_width; x+=2) {      RGB2Y(rgbIndex[redOffset], rgbIndex[1], rgbIndex[blueOffset], *yline);      rgbIndex += rgbIncrement;      yline++;      RGB2YUV(rgbIndex[redOffset], rgbIndex[1], rgbIndex[blueOffset], *yline, *uline, *vline);      rgbIndex += rgbIncrement;      yline++;      uline++;      vline++;    }    // Crop if source width > dest width    if (srcFrameWidth > dstFrameWidth)      rgbIndex += rgbIncrement * (srcFrameWidth - dstFrameWidth);    // Pad if dest width < source width    if (dstFrameWidth > srcFrameWidth) {      memset(yline, BLACK_Y, dstFrameWidth - srcFrameWidth);      memset(uline, BLACK_U, (dstFrameWidth - srcFrameWidth)>>1);      memset(vline, BLACK_V, (dstFrameWidth - srcFrameWidth)>>1);    }  }  // Pad if dest height > source height  if (dstFrameHeight > srcFrameHeight) {    BYTE * yline  = yplane + (srcFrameHeight * dstFrameWidth);    BYTE * uline  = uplane + ((srcFrameHeight >> 1) * halfWidth);    BYTE * vline  = vplane + ((srcFrameHeight >> 1) * halfWidth);    unsigned fill = (dstFrameHeight - srcFrameHeight) * dstFrameWidth;    memset(yline, BLACK_Y, fill);    memset(uline, BLACK_U, fill >> 2);    memset(vline, BLACK_V, fill >> 2);  }}BOOL PStandardColourConverter::RGBtoYUV420P(const BYTE * rgb,                                            BYTE * yuv,                                            PINDEX * bytesReturned,                                            unsigned rgbIncrement,					    unsigned redOffset,                                            unsigned blueOffset) const{  if (rgb == yuv)    return FALSE; // Cannot do in place conversion  if ((srcFrameWidth == dstFrameWidth) && (srcFrameHeight == dstFrameHeight))     RGBtoYUV420PSameSize(rgb, yuv, rgbIncrement, redOffset, blueOffset);  else    RGBtoYUV420PWithResize(rgb, yuv, rgbIncrement, redOffset, blueOffset);  if (bytesReturned != NULL)    *bytesReturned = dstFrameBytes;  return TRUE;}PSTANDARD_COLOUR_CONVERTER(Grey,YUV420P){  return GreytoYUV420P(srcFrameBuffer, dstFrameBuffer, bytesReturned);}PSTANDARD_COLOUR_CONVERTER(RGB24,YUV420P){  return RGBtoYUV420P(srcFrameBuffer, dstFrameBuffer, bytesReturned, 3,  0, 2);}PSTANDARD_COLOUR_CONVERTER(BGR24,YUV420P){  return RGBtoYUV420P(srcFrameBuffer, dstFrameBuffer, bytesReturned, 3,  2, 0);}PSTANDARD_COLOUR_CONVERTER(RGB32,YUV420P){  return RGBtoYUV420P(srcFrameBuffer, dstFrameBuffer, bytesReturned, 4, 0, 2);}PSTANDARD_COLOUR_CONVERTER(BGR32,YUV420P){  return RGBtoYUV420P(srcFrameBuffer, dstFrameBuffer, bytesReturned, 4, 2, 0);}// Consider a YUV422P image of 8x2 pixels.//// A plane of Y values    A B C D E F G H//                        I J K L M N O P//// A plane of U values    1 . 2 . 3 . 4 .//                        5 . 6 . 7 . 8 .//// A plane of V values    1 . 2 . 3 . 4 .//                        5 . 6 . 7 . 8 .// // YUV422 is stored as Y U Y V //   thus, a 4x4 image requires 32 bytes of storage.//// Image has two possible transformations.//        padded                 (src smaller than dst)      //        subsampled and padded  (src bigger than dst)  void PStandardColourConverter::ResizeYUV422(const BYTE * src, BYTE * dest) const{  DWORD *result = (DWORD *)dest;  DWORD black   = (DWORD)(BLACK_U<<24) + (BLACK_Y<<16) + (BLACK_U<<8) + BLACK_Y;  unsigned maxIndex    = dstFrameWidth*dstFrameHeight/2;  for (unsigned i = 0; i < maxIndex; i++)     *result++ = black;  if ( (dstFrameWidth*dstFrameHeight) > (srcFrameWidth*srcFrameHeight) ) {     //dest is bigger than the source. No subsampling.    //Place the src in the middle of the destination.    unsigned yOffset = dstFrameHeight - srcFrameHeight;    unsigned xOffset = dstFrameWidth - srcFrameWidth;    BYTE *s_ptr,*d_ptr;    d_ptr = (yOffset * dstFrameWidth) + xOffset + dest;    s_ptr = (BYTE *)src;    for (unsigned y = 0; y < srcFrameHeight; y++) {      memcpy(d_ptr,s_ptr, srcFrameWidth*2);      d_ptr += 2*dstFrameWidth;      s_ptr += 2*srcFrameWidth;    }  } else {      // source is bigger than the destination.    //    unsigned subSample  = 1 + (srcFrameHeight/dstFrameHeight) ;    unsigned yOffset    = dstFrameHeight - (srcFrameHeight/subSample);    unsigned xOffset    = dstFrameWidth - (srcFrameWidth/subSample);    unsigned subSample2 = subSample*2;    DWORD *s_ptr = (DWORD * )src;    DWORD *d_ptr = (DWORD *) dest + ((yOffset * dstFrameWidth) + xOffset)/4 ;    DWORD *sl_ptr, *dl_ptr;    for (unsigned y = 0; y < srcFrameHeight; y+= subSample) {      sl_ptr = s_ptr;      dl_ptr = d_ptr;      for (unsigned x = 0; x < srcFrameWidth; x+= subSample2) {	*dl_ptr++ = *sl_ptr;	sl_ptr += subSample;      }	      d_ptr += dstFrameWidth/2;      s_ptr += srcFrameWidth*subSample/2;    }  }}PSTANDARD_COLOUR_CONVERTER(YUV422,YUV422){  if (bytesReturned != NULL)    *bytesReturned = dstFrameBytes;    if (srcFrameBuffer == dstFrameBuffer)    return TRUE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -