/** \if INCLUDE_IN_HTML_ONLY \fn void GenerateFixedPointVersion(void) \brief The function calculate Hardware output to be programmed from contrast applied matrix \details: The function convert floating values into fixed point format \param void \return void \callgraph \callergraph \ingroup RgbToYuvCoder \endif */ void GenerateFixedPointVersion(void) { float_t fpScaled; uint8_t u8_TargetCount, u8_SourceCount = 0; #if ENABLE_YUVCODER_TRACES OstTraceInt0(TRACE_DEBUG, "<yuvcoder> >> GenerateFixedPointVersion\n"); #endif // copy correct parts of 6 item array into 9 element array for (u8_TargetCount = 0; u8_TargetCount < 9; u8_TargetCount++) { #if ENABLE_YUVCODER_TRACES OstTraceInt2(TRACE_DEBUG, "<yuvcoder> f_OutputMatrixView[%u] = %f\n", u8_SourceCount, f_OutputMatrixView[u8_SourceCount]); #endif // f_OutputMatrixView has only 6 elements so output matrix column 3 is invalid if (!(2 == u8_TargetCount || 5 == u8_TargetCount || 8 == u8_TargetCount)) { // round and convert to int16 every array element fpScaled = F_MATRIX_SCALER * f_OutputMatrixView[u8_SourceCount++]; ptrs16_RgbToYuvMatrix[u8_TargetCount] = GetRounded(fpScaled); #if ENABLE_YUVCODER_TRACES OstTraceInt3(TRACE_DEBUG, "<yuvcoder> fpScaled = %f, ptrs16_RgbToYuvMatrix[%u] = %+d\n", fpScaled, u8_TargetCount, ptrs16_RgbToYuvMatrix[u8_TargetCount]); #endif } } #if ENABLE_YUVCODER_TRACES OstTraceInt0(TRACE_DEBUG, "<yuvcoder> << GenerateFixedPointVersion\n"); #endif return; }
//----------------------------------------------------------------------- // Print status bar //----------------------------------------------------------------------- void CWeightManager::PrintInfo (int bar_cycle) { CSubsystem *VSI = mveh->GetSVSI(); time = globals->bar_timer; double dT = globals->dST; double alt = mveh->GetAltitude(); double agl = mveh->GetAltitudeAGL(); double spd = mveh->GetIAS(); double vsi = (VSI)?(VSI->GaugeBusFT01()):(0); double cap = mveh->GetMagneticDirection(); double pit = mveh->GetPitch(); vsi = GetRounded(vsi); int fps = (dT > 0.00001)?(double(1) / dT): 0; _snprintf (buf,255, "Alt= %-5.0lf AGL= %-5.0lf Speed= %-2.0lf VSI= %-5.0lf CAP= %-3.0lf PITCH=%.2lf FPS= %03d", alt, agl, spd, vsi, cap, pit, fps); globals->fui->DrawNoticeToUser (buf, 1); return; }
/** \if INCLUDE_IN_HTML_ONLY \fn void YCbCrToRgb(float_t f_Contrast,float_t f_Saturation) \brief Used to convert fpOutputMatrix[][] to Rgb format by multiplying it by the inverse of the stock rgbToYuv. This will result in the identity matrix if contrast = saturation = 100%. \details \param f_Contrast: Contrast value in floating point \param f_Saturation: Saturation value in floating point \return void \callgraph \callergraph \ingroup RgbToYuvCoder \endif */ void YCbCrToRgb( float_t f_Contrast, float_t f_Saturation) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ float_t f_CommonFactor; float_t f_OnDiagonalByCol[3]; float_t f_OffDiagonalByCol[3]; float_t f_OutputExcursion; float_t f_Tmp; int16_t s16_OffsetIntegerOffDiagonalsByCol[3]; int16_t s16_OffsetIntegerExcursions[3]; int16_t s16_OffsetIntegerOnDiagonal[3]; int16_t s16_Element; uint8_t u8_Col, u8_Row; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #if ENABLE_YUVCODER_TRACES OstTraceInt0(TRACE_DEBUG, "<yuvcoder> >> YCbCrToRgb\n"); #endif s16_OffsetIntegerOnDiagonal[0] = s16_OffsetIntegerOnDiagonal[1] = s16_OffsetIntegerOnDiagonal[2] = 0; for (u8_Col = 0; u8_Col < 3; ++u8_Col) { // double dCommonFactor = dContrast * (1-dSaturation) * Luma.m_adElements[iCol]; f_CommonFactor = f_Contrast * (1 - f_Saturation) * ptr_YuvStockMatrix[u8_Col]; // adOffDiagonalByCol[iCol] = dCommonFactor; f_OffDiagonalByCol[u8_Col] = f_CommonFactor; // adOnDiagonal[iCol] = dCommonFactor + dContrast * dSaturation; f_OnDiagonalByCol[u8_Col] = f_CommonFactor + f_Contrast * f_Saturation; } // we can now determine the expected row midpoints // (or rather the excursions = midpoint * 2)... // as the f_Excursion is the same for each row we just do one calculation. // f_OutputExcursion = f_OnDiagonalByCol[0] + f_OffDiagonalByCol[1] + f_OffDiagonalByCol[2]; // f_OutputExcursion = f_OnDiagonalByCol[0] + f_OffDiagonalByCol[1] + f_OffDiagonalByCol[2]; // we now loop through each col/row generating reduced precision versions // of the off-diagonal elements and the excursions (by scaling according // to the desired precision then a rounding cast to integer)... // for (u8_Col = 0; u8_Col < 3; u8_Col++) { //s16_OffsetIntegerOffDiagonalsByCol[i] = iGetRounded( MatrixScaler * adOffDiagonalByCol[i] ); f_Tmp = F_MATRIX_SCALER * f_OffDiagonalByCol[u8_Col]; s16_OffsetIntegerOffDiagonalsByCol[u8_Col] = GetRounded(f_Tmp); //s16_OffsetIntegerExcursions[i] = iGetRounded( m_dMatrixScaler * adOutputExcursions[i] ) f_Tmp = F_MATRIX_SCALER * f_OutputExcursion; s16_OffsetIntegerExcursions[u8_Col] = GetRounded(f_Tmp); } // loop through each row generating reduced precision on-diagonal // elements that satisfy the desired reduced precision excursions... for (u8_Row = 0; u8_Row < 3; u8_Row++) { for (u8_Col = 0; u8_Col < 3; u8_Col++) { s16_OffsetIntegerOnDiagonal[u8_Row] += (u8_Row == u8_Col) ? s16_OffsetIntegerExcursions[u8_Col] : -s16_OffsetIntegerOffDiagonalsByCol[u8_Col]; } } // using the observed mirror image about the diagonal for // the op rgb matrix create the matrix. for (u8_Row = 0; u8_Row < 3; u8_Row++) { for (u8_Col = 0; u8_Col < 3; u8_Col++) { s16_Element = (u8_Row == u8_Col) ? s16_OffsetIntegerOnDiagonal[u8_Col] : s16_OffsetIntegerOffDiagonalsByCol[u8_Col]; ptrs16_RgbToYuvMatrix[(u8_Row * 3) + u8_Col] = s16_Element; } } #if ENABLE_YUVCODER_TRACES OstTraceInt0(TRACE_DEBUG, "<yuvcoder> << YCbCrToRgb\n"); #endif return; }
/** \if INCLUDE_IN_HTML_ONLY \fn void FinaliseYCbCrMatrix(float_t f_Contrast, float_t f_Saturation) \brief The function calculate last element of each row by subtracting sum of first two element from ideal sum. \details: \param f_Contrast: Contrast value in floating point \param f_Saturation: Saturation value in floating point \return void \callgraph \callergraph \ingroup RgbToYuvCoder \endif */ void FinaliseYCbCrMatrix( float_t f_Contrast, float_t f_Saturation) { float_t f_OutputExcursionDividedByInputExcursion; float_t f_Scaler; float_t f_RowSumLuma; int16_t s16_IdealLastElement; int16_t s16_IdealRowSums[3]; int16_t s16_RowSum; uint8_t u8_Element; uint8_t u8_Row; #if ENABLE_YUVCODER_TRACES uint32_t count = 0; OstTraceInt2(TRACE_DEBUG, "<yuvcoder> >> FinaliseYCbCrMatrix : v = %f, f_Saturation = %f\n", f_Contrast, f_Saturation); #endif s16_IdealRowSums[0] = s16_IdealRowSums[1] = s16_IdealRowSums[2] = 0; // Convert Martix in floating point to Fixed point format GenerateFixedPointVersion(); // double dOutputExcursionDividedByInputExcursion = dDesiredLumaExcursion / dInputMax; // <Hem> We are assuming that excursion for luma and chroma will be same. Is it a good asumption ? f_OutputExcursionDividedByInputExcursion = (float_t) (ptr_PipeRgbToYUVSignalRange->u16_LumaExcursion) / RGBTOYUVCODER_MAX_INPUT_FROM_PIPE; // all calculations are in Fixed point format, so multiply by Matrix scaler // double dScaler = MatrixScaler * ((double)m_iContrast/100.0); f_Scaler = F_MATRIX_SCALER * f_Contrast; // double dRowSum = dOutputExcursionDividedByInputExcursion * dScaler; f_RowSumLuma = f_OutputExcursionDividedByInputExcursion * f_Scaler; // updating only element 0 as in YCbCr matrix, only Row[0] sum has finite value // Row[1] and Row[2] sum are always zero as they are difference signals s16_IdealRowSums[0] = GetRounded(f_RowSumLuma); for (u8_Row = 0; u8_Row < 3; u8_Row++) { s16_RowSum = 0; // the ideal 'last' element is simply the ideal row sum // minus the other two elements... // s16_IdealLastElement = s16_IdealRowSums[u8_Row]; for (u8_Element = 0; u8_Element < 2; ++u8_Element) { s16_RowSum += ptrs16_RgbToYuvMatrix[(u8_Row * 3) + u8_Element]; } ptrs16_RgbToYuvMatrix[(u8_Row * 3) + 2] = s16_IdealRowSums[u8_Row] - s16_RowSum; #if ENABLE_YUVCODER_TRACES OstTraceInt3(TRACE_DEBUG,"<yuvcoder> s16_RowSum = %+d, s16_IdealRowSums[%d] = %+d\n", s16_RowSum, u8_Row, s16_IdealRowSums[u8_Row]); OstTraceInt2(TRACE_DEBUG,"<yuvcoder> ptrs16_RgbToYuvMatrix[%d] = %+d\n", (u8_Row * 3) + 2, ptrs16_RgbToYuvMatrix[(u8_Row * 3) + 2]); #endif } #if ENABLE_YUVCODER_TRACES OstTraceInt1(TRACE_DEBUG, "<yuvcoder> f_OutputExcursionDividedByInputExcursion = %f\n", f_OutputExcursionDividedByInputExcursion); for (count =0; count <3; count++) { OstTraceInt1(TRACE_DEBUG, "<yuvcoder> s16_IdealRowSums[count] = %u\n", s16_IdealRowSums[count]); } for (count =0; count <9; count++) { OstTraceInt2(TRACE_DEBUG, "<yuvcoder> ptrs16_RgbToYuvMatrix[%u] = %d",count, ptrs16_RgbToYuvMatrix[count]); } OstTraceInt0(TRACE_DEBUG, "<yuvcoder> << FinaliseYCbCrMatrix\n"); #endif return; }