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

📄 vconvert.cxx

📁 pwlib源码库
💻 CXX
📖 第 1 页 / 共 4 页
字号:
  if ((srcFrameWidth == dstFrameWidth) && (srcFrameHeight == dstFrameHeight))     memcpy(dstFrameBuffer,srcFrameBuffer,srcFrameWidth*srcFrameHeight*2);  else    ResizeYUV422(srcFrameBuffer, dstFrameBuffer);  return TRUE;}///No resize here.//Colour format change only, YUV422 is turned into YUV420P.static void Yuv422ToYuv420P(unsigned dstFrameWidth, unsigned dstFrameHeight,                             const BYTE * srcFrame, BYTE * dstFrame){  unsigned  a,b;  BYTE *u,*v;  const BYTE * s =  srcFrame;  BYTE * y =  dstFrame;  u = y + (dstFrameWidth * dstFrameHeight);  v = u + (dstFrameWidth * dstFrameHeight / 4);  for (a = 0; a < dstFrameHeight; a+=2) {    for (b = 0; b < dstFrameWidth; b+=2) {      *(y++) = *(s++);      *(u++) = *(s++);      *(y++) = *(s++);      *(v++) = *(s++);    }    for (b = 0; b < dstFrameWidth; b+=2) {      *(y++) = *(s++);      s++;      *(y++) = *(s++);      s++;    }  }}PSTANDARD_COLOUR_CONVERTER(YUV422,YUV420P){  if (srcFrameBuffer == dstFrameBuffer)    return FALSE;  if ((srcFrameWidth==dstFrameWidth) && (srcFrameHeight==dstFrameHeight))    Yuv422ToYuv420P(srcFrameWidth, srcFrameHeight, srcFrameBuffer, dstFrameBuffer);  else {    //do a resize.  then convert to yuv420p.    BYTE * intermed = intermediateFrameStore.GetPointer(dstFrameWidth*dstFrameHeight*2);    ResizeYUV422(srcFrameBuffer, intermed);    Yuv422ToYuv420P(dstFrameWidth, dstFrameHeight, intermed, dstFrameBuffer);  }  if (bytesReturned != NULL)    *bytesReturned = dstFrameBytes;  return TRUE;}#define LIMIT(x) (unsigned char) (((x > 0xffffff) ? 0xff0000 : ((x <= 0xffff) ? 0 : x & 0xff0000)) >> 16)static inline int clip(int a, int limit) {  return a<limit?a:limit;}BOOL PStandardColourConverter::SBGGR8toYUV420P(const BYTE * src,					       BYTE * dst,					       PINDEX * bytesReturned) const{#define USE_SBGGR8_NATIVE 1 // set to 0 to use the double conversion algorithm (Bayer->RGB->YUV420P)  #if USE_SBGGR8_NATIVE  // kernels for Y conversion, normalised by 2^16  const int kR[]={1802,9667,1802,9667,19661,9667,1802,9667,1802};   const int kG1[]={7733,9830,7733,3604,7733,3604,7733,9830,7733};  const int kG2[]={7733,3604,7733,9830,7733,9830,7733,3604,7733};  const int kB[]={4915,9667,4915,9667,7209,9667,4915,9667,4915};  //  const int kID[]={0,0,0,0,65536,0,0,0,0}; identity kernel, use to test  int B, G, G1, G2, R;  const int stride = srcFrameWidth;  unsigned const int hSize =srcFrameHeight/2;  unsigned const int vSize =srcFrameWidth/2;  unsigned const int lastRow=srcFrameHeight-1;  unsigned const int lastCol=srcFrameWidth-1;  unsigned int i,j;  const BYTE *sBayer = src;  //	Y = round( 0.256788 * R + 0.504129 * G + 0.097906 * B) +  16;  //  Y = round( 0.30 * R + 0.59 * G + 0.11 * B ) use this!  //	U = round(-0.148223 * R - 0.290993 * G + 0.439216 * B) + 128;  //	V = round( 0.439216 * R - 0.367788 * G - 0.071427 * B) + 128;  // Compute U and V planes using EXACT values, reading 2x2 pixels at a time  BYTE *dU = dst+srcFrameHeight*srcFrameWidth;  BYTE *dV = dU+hSize*vSize;  for (i=0; i<hSize; i++) {          for (j=0; j<vSize; j++) {      B=sBayer[0];      G1=sBayer[1];      G2=sBayer[stride];      R=sBayer[stride+1];      G=G1+G2;      *dU = (BYTE)( ( (-19428 * R -19071*G +57569 * B) >> 17) + 128 );      *dV = (BYTE)( ( ( 57569 * R -24103*G -9362 * B) >> 17) + 128 );      sBayer+=2;      dU++;      dV++;    }    sBayer+=stride; // skip odd lines  }  // Compute Y plane  BYTE *dY = dst;  sBayer=src;  const int * k; // kernel pointer  int dxLeft, dxRight; // precalculated offsets, needed for first and last column  const BYTE *sBayerTop, *sBayerBottom;  for (i=0; i<srcFrameHeight; i++) {    // Pointer to previous row, to the next if we are on the first one    sBayerTop=sBayer+(i?(-stride):stride);    // Pointer to next row, to the previous one if we are on the last    sBayerBottom=sBayer+((i<lastRow)?stride:(-stride));    // offset to previous column, to the next if we are on the first col    dxLeft=1;    for (j=0; j<srcFrameWidth; j++) {      // offset to next column, to previous if we are on the last one      dxRight=j<lastCol?1:(-1);      // find the proper kernel according to the current pixel color      if ( (i ^ j) & 1)  k=(j&1)?kG1:kG2; // green 1 or green 2      else if (!(i & 1))  k=kB; // blue      else /* if (!(j & 1)) */ k=kR; // red            // apply the proper kernel to this pixel and surrounding ones      *dY= (BYTE)(clip( (k[0])*(int)sBayerTop[dxLeft]+			(k[1])*(int)(*sBayerTop)+			(k[2])*(int)sBayerTop[dxRight]+			(k[3])*(int)sBayer[dxLeft]+			(k[4])*(int)(*sBayer)+			(k[5])*(int)sBayer[dxRight]+			(k[6])*(int)sBayerBottom[dxLeft]+			(k[7])*(int)(*sBayerBottom)+			(k[8])*(int)sBayerBottom[dxRight], (1<<24)) >> 16);      dY++;      sBayer++;      sBayerTop++;      sBayerBottom++;      dxLeft=-1;    }  }  if (bytesReturned)    *bytesReturned = srcFrameHeight*srcFrameWidth+2*hSize*vSize;  return true;#else //USE_SBGGR8_NATIVE  // shortest but less efficient (one malloc per conversion!)  BYTE * tempDest=(BYTE*)malloc(3*srcFrameWidth*srcFrameHeight);  SBGGR8toRGB(src, tempDest, NULL);  BOOL r = RGBtoYUV420P(tempDest, dst, bytesReturned, 3, 2, 0);  free(tempDest);  return r;#endif //USE_SBGGR8_NATIVE}BOOL PStandardColourConverter::SBGGR8toRGB(const BYTE * src,                                           BYTE       * dst,                                           PINDEX     * bytesReturned) const{  if (src == dst || verticalFlip)    return FALSE;  long int i;  const BYTE *rawpt;  BYTE *scanpt;  long int size;  rawpt = src;  scanpt = dst;  long int WIDTH = srcFrameWidth, HEIGHT = srcFrameHeight;  size = WIDTH*HEIGHT;  for ( i = 0; i < size; i++ ) {    if ( (i/WIDTH) % 2 == 0 ) {      if ( (i % 2) == 0 ) {        /* B */        if ( (i > WIDTH) && ((i % WIDTH) > 0) ) {          *scanpt++ = (BYTE) ((*(rawpt-WIDTH-1)+*(rawpt-WIDTH+1)+ *(rawpt+WIDTH-1)+*(rawpt+WIDTH+1))/4);	/* R */          *scanpt++ = (BYTE) ((*(rawpt-1)+*(rawpt+1)+ *(rawpt+WIDTH)+*(rawpt-WIDTH))/4);	/* G */          *scanpt++ = *rawpt;					/* B */        } else {          /* first line or left column */          *scanpt++ = *(rawpt+WIDTH+1);		/* R */          *scanpt++ = (BYTE) ((*(rawpt+1)+*(rawpt+WIDTH))/2);	/* G */          *scanpt++ = *rawpt;				/* B */        }      } else {        /* (B)G */        if ( (i > WIDTH) && ((i % WIDTH) < (WIDTH-1)) ) {          *scanpt++ = (BYTE) ((*(rawpt+WIDTH)+*(rawpt-WIDTH))/2);	/* R */          *scanpt++ = *rawpt;					/* G */          *scanpt++ = (BYTE) ((*(rawpt-1)+*(rawpt+1))/2);		/* B */        } else {          /* first line or right column */          *scanpt++ = *(rawpt+WIDTH);	/* R */          *scanpt++ = *rawpt;		/* G */          *scanpt++ = *(rawpt-1);	/* B */        }      }    } else {      if ( (i % 2) == 0 ) {        /* G(R) */        if ( (i < (WIDTH*(HEIGHT-1))) && ((i % WIDTH) > 0) ) {          *scanpt++ = (BYTE) ((*(rawpt-1)+*(rawpt+1))/2);		/* R */          *scanpt++ = *rawpt;					/* G */          *scanpt++ = (BYTE) ((*(rawpt+WIDTH)+*(rawpt-WIDTH))/2);	/* B */        } else {          /* bottom line or left column */          *scanpt++ = *(rawpt+1);		/* R */          *scanpt++ = *rawpt;			/* G */          *scanpt++ = *(rawpt-WIDTH);		/* B */        }      } else {        /* R */        if ( i < (WIDTH*(HEIGHT-1)) && ((i % WIDTH) < (WIDTH-1)) ) {          *scanpt++ = *rawpt;					/* R */          *scanpt++ = (BYTE) ((*(rawpt-1)+*(rawpt+1)+*(rawpt-WIDTH)+*(rawpt+WIDTH))/4);	/* G */          *scanpt++ = (BYTE) ((*(rawpt-WIDTH-1)+*(rawpt-WIDTH+1)+*(rawpt+WIDTH-1)+*(rawpt+WIDTH+1))/4);	/* B */        } else {          /* bottom line or right column */          *scanpt++ = *rawpt;				/* R */          *scanpt++ = (BYTE) ((*(rawpt-1)+*(rawpt-WIDTH))/2);	/* G */          *scanpt++ = *(rawpt-WIDTH-1);		/* B */        }      }    }    rawpt++;  }  if (bytesReturned)    *bytesReturned = scanpt - dst;  return TRUE;}BOOL PStandardColourConverter::YUV420PtoRGB(const BYTE * srcFrameBuffer,                                            BYTE * dstFrameBuffer,                                            PINDEX * bytesReturned,                                            unsigned rgbIncrement,                                            unsigned redOffset,                                            unsigned blueOffset) const{  if (srcFrameBuffer == dstFrameBuffer)    return FALSE;  BYTE          *dstImageFrame;  unsigned int   nbytes    = srcFrameWidth*srcFrameHeight;  const BYTE    *yplane    = srcFrameBuffer;           		// 1 byte Y (luminance) for each pixel  const BYTE    *uplane    = yplane+nbytes;              	// 1 byte U for a block of 4 pixels  const BYTE    *vplane    = uplane+(nbytes >> 2);       	// 1 byte V for a block of 4 pixels  unsigned int   pixpos[4] = {0, 1, srcFrameWidth, srcFrameWidth + 1};  unsigned int   originalPixpos[4] = {0, 1, srcFrameWidth, srcFrameWidth + 1};  unsigned int   x, y, p;  long     int   yvalue;  long     int   l, r, g, b;  if (verticalFlip) {    dstImageFrame = dstFrameBuffer + ((srcFrameHeight - 2) * srcFrameWidth * rgbIncrement);    pixpos[0] = srcFrameWidth;    pixpos[1] = srcFrameWidth +1;    pixpos[2] = 0;    pixpos[3] = 1;  }  else    dstImageFrame = dstFrameBuffer;  for (y = 0; y < srcFrameHeight; y += 2)  {    for (x = 0; x < srcFrameWidth; x += 2)    {      // The RGB value without luminance      long cb = *uplane-128;      long cr = *vplane-128;      long rd = 104635*cr;			// 		  106986*cr      long gd = -25690*cb-53294*cr;		// -26261*cb  +   -54496*cr       long bd = 132278*cb;			// 135221*cb      // Add luminance to each of the 4 pixels      for (p = 0; p < 4; p++)      {        yvalue = *(yplane + originalPixpos[p])-16;        if (yvalue < 0) yvalue = 0;        l = 76310*yvalue;        r = l+rd;        g = l+gd;        b = l+bd;        BYTE * rgpPtr = dstImageFrame + rgbIncrement*pixpos[p];        rgpPtr[redOffset ] = LIMIT(r);        rgpPtr[1         ] = LIMIT(g);        rgpPtr[blueOffset] = LIMIT(b);        if (rgbIncrement == 4)          rgpPtr[3] = 0;      }      yplane += 2;      dstImageFrame += rgbIncrement*2;      uplane++;      vplane++;    }     yplane += srcFrameWidth;    if (verticalFlip)      dstImageFrame -= 3*rgbIncrement*srcFrameWidth;    else      dstImageFrame += rgbIncrement*srcFrameWidth;    }  if (bytesReturned != NULL)    *bytesReturned = dstFrameBytes;  return TRUE;}PSTANDARD_COLOUR_CONVERTER(SBGGR8,RGB24){  return SBGGR8toRGB(srcFrameBuffer, dstFrameBuffer, bytesReturned);}PSTANDARD_COLOUR_CONVERTER(SBGGR8,YUV420P){  return SBGGR8toYUV420P(srcFrameBuffer, dstFrameBuffer, bytesReturned);}PSTANDARD_COLOUR_CONVERTER(YUV420P,RGB24){  return YUV420PtoRGB(srcFrameBuffer, dstFrameBuffer, bytesReturned, 3, 0, 2);}PSTANDARD_COLOUR_CONVERTER(YUV420P,BGR24){  return YUV420PtoRGB(srcFrameBuffer, dstFrameBuffer, bytesReturned, 3, 2, 0);}PSTANDARD_COLOUR_CONVERTER(YUV420P,RGB32){  return YUV420PtoRGB(srcFrameBuffer, dstFrameBuffer, bytesReturned, 4, 0, 2);}PSTANDARD_COLOUR_CONVERTER(YUV420P,BGR32){  return YUV420PtoRGB(srcFrameBuffer, dstFrameBuffer, bytesReturned, 4, 2, 0);}static void SwapRedAndBlueRow(const BYTE * srcRowPtr,                              BYTE * dstRowPtr,                              unsigned width,                              unsigned srcIncrement,                              unsigned dstIncrement){  for (unsigned x = 0; x < width; x++) {    BYTE temp = srcRowPtr[0]; // Do it this way in case src and dst are same buffer    dstRowPtr[0] = srcRowPtr[2];    dstRowPtr[1] = srcRowPtr[1];    dstRowPtr[2] = temp;    srcRowPtr += srcIncrement;    dstRowPtr += dstIncrement;  }}BOOL PStandardColourConverter::SwapRedAndBlue(const BYTE * srcFrameBuffer,                                              BYTE * dstFrameBuffer,                                              PINDEX * bytesReturned,                                              unsigned srcIncrement,                                              unsigned dstIncrement) const{  if ((dstFrameWidth != srcFrameWidth) || (dstFrameHeight != srcFrameHeight))    return FALSE;  unsigned srcRowSize = srcFrameBytes/srcFrameHeight;  const BYTE * srcRowPtr = srcFrameBuffer;  unsigned dstRowSize = dstFrameBytes/dstFrameHeight;  BYTE * dstRowPtr = dstFrameBuffer;  if (verticalFlip) {    dstRowPtr += dstFrameHeight*dstRowSize;    if (srcFrameBuffer == dstFrameBuffer) {      PBYTEArray tempRow(PMAX(srcRowSize, dstRowSize));      unsigned halfHeight = (srcFrameHeight+1)/2;      for (unsigned y = 0; y < halfHeight; y++) {        dstRowPtr -= dstRowSize;        SwapRedAndBlueRow(dstRowPtr, tempRow.GetPointer(), dstFrameWidth, srcIncrement, dstIncrement);        SwapRedAndBlueRow(srcRowPtr, dstRowPtr, srcFrameWidth, srcIncrement, dstIncrement);        memcpy((BYTE *)srcRowPtr, tempRow, srcRowSize);        srcRowPtr += srcRowSize;      }    }    else {      for (unsigned y = 0; y < srcFrameHeight; y++) {        dstRowPtr -= dstRowSize;        SwapRedAndBlueRow(srcRowPtr, dstRowPtr, srcFrameWidth, srcIncrement, dstIncrement);        srcRowPtr += srcRowSize;      }    }  }  else {    for (unsigned y = 0; y < srcFrameHeight; y++) {

⌨️ 快捷键说明

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