void CAtmoGradients::SetActiveZone(int zone) { if(!m_ZoneRadios || (zone<0)) return; CAtmoZoneDefinition *azone = m_pConfig->getZoneDefinition( zone ); if(!azone) return; m_active_zone = zone; int *destWeight = new int[CAP_WIDTH * CAP_HEIGHT]; azone->UpdateWeighting(destWeight, m_pConfig->getLiveView_WidescreenMode(), m_edge_weight); BITMAP bmp; int byte = (CAP_WIDTH * 4); if(byte & 1) byte++; unsigned char *pixel_buffer = new unsigned char[byte * CAP_HEIGHT]; unsigned char *tmp = pixel_buffer; for(int y = 0; y < CAP_HEIGHT; y++) { tmp = pixel_buffer + y * byte; for(int x = 0; x < CAP_WIDTH; x++) { *tmp = 0; tmp++; // R *tmp = (unsigned char)destWeight[y * CAP_WIDTH + x]; tmp++; // G *tmp = 0; tmp++; // B *tmp = 0; tmp++; // A } } bmp.bmType = 0; bmp.bmBitsPixel = 32; bmp.bmHeight = CAP_HEIGHT; bmp.bmWidth = CAP_WIDTH; bmp.bmWidthBytes = byte; bmp.bmPlanes = 1; bmp.bmBits = pixel_buffer; if(m_current_gradient) { DeleteObject( m_current_gradient ); m_current_gradient = 0; } m_current_gradient = CreateBitmapIndirect(&bmp); DWORD error = GetLastError(); delete []destWeight; delete []pixel_buffer; }
ATMO_BOOL CAtmoGradients::HandleMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { ATMO_BOOL r = CBasicDialog::HandleMessage(hwnd, uMsg, wParam, lParam); HWND groupBox = getDlgItem( IDC_ZONE_GROUP ); CLanguage *Lng = new CLanguage; if((hwnd == groupBox) && (uMsg == WM_PAINT)) { HDC hdc = GetDC(hwnd); HDC memDC = CreateCompatibleDC(hdc); RECT r; GetClientRect( groupBox, &r ); int cx = (r.right - r.left) / 2; int cy = (r.bottom - r.top) / 2; HGDIOBJ oldObject = SelectObject( memDC, m_current_gradient ); DWORD error = GetLastError(); cx = cx - (CAP_WIDTH * 3) / 2; cy = cy - (CAP_HEIGHT * 3) / 2; StretchBlt( hdc, cx, cy, CAP_WIDTH*3, CAP_HEIGHT*3, memDC, 0, 0, CAP_WIDTH, CAP_HEIGHT, SRCCOPY ); error = GetLastError(); SelectObject( memDC, oldObject ); DeleteDC( memDC ); ReleaseDC(hwnd, hdc); } if((hwnd == groupBox) && (uMsg == WM_DROPFILES) && (m_active_zone>=0)) { char psz_filename[MAX_PATH]; char psz_filename_dest[MAX_PATH]; char msg[MAX_PATH+128]; DragQueryFile((HDROP)wParam, 0, psz_filename, sizeof(psz_filename)); int i; i = (int)strlen(psz_filename) - 1; while(i && psz_filename[i]!='.') i--; if(i>0) { if(!stricmp(&psz_filename[i],".bmp")) { CAtmoZoneDefinition *azone = m_pConfig->getZoneDefinition( m_active_zone ); if(azone) { sprintf(psz_filename_dest,"%s%s\\zone_%d.bmp", m_pDynData->getWorkDir(), m_pDynData->getAtmoConnection()->getDevicePath(), m_active_zone ); FILE *fp=fopen(psz_filename_dest,"r"); if(fp) { fclose(fp); sprintf( msg, Lng->sGradientsText[3] + "%s" + Lng->sGradientsText[4], psz_filename_dest); if(MessageBox(m_hDialog, msg ,Lng->sGradientsText[5],MB_ICONQUESTION | MB_YESNO) == IDNO) return(r); } switch(azone->LoadGradientFromBitmap( psz_filename )) { case ATMO_LOAD_GRADIENT_OK: SetActiveZone( m_active_zone ); InvalidateRect( groupBox, NULL, false); if(!CopyFile( psz_filename, psz_filename_dest, false)) { sprintf( msg, Lng->sGradientsText[3] + "%s" + Lng->sGradientsText[6], psz_filename_dest); MessageBox(m_hDialog, msg ,Lng->sGradientsText[7], MB_ICONERROR ); } else MessageBox(m_hDialog, Lng->sGradientsText[8],Lng->sGradientsText[9],MB_OK); break; case ATMO_LOAD_GRADIENT_FILENOTFOND: MessageBox(m_hDialog, Lng->sGradientsText[10],Lng->sGradientsText[7],MB_ICONERROR | MB_OK); break; case ATMO_LOAD_GRADIENT_FAILED_SIZE: MessageBox(m_hDialog, Lng->sGradientsText[11],Lng->sGradientsText[7],MB_ICONERROR | MB_OK); break; case ATMO_LOAD_GRADIENT_FAILED_HEADER: MessageBox(m_hDialog, Lng->sGradientsText[12],Lng->sGradientsText[7],MB_ICONERROR | MB_OK); break; case ATMO_LOAD_GRADIENT_FAILED_FORMAT: MessageBox(m_hDialog, Lng->sGradientsText[13],Lng->sGradientsText[7],MB_ICONERROR | MB_OK); break; } } return(r); } } MessageBox( m_hDialog, Lng->sGradientsText[14],Lng->sGradientsText[7],MB_ICONERROR | MB_OK); } return(r); }
void CAtmoDynData::ReloadZoneDefinitionBitmaps() { int i; // suchlogik fuer die Farbverlaufs Bitmaps ... // <WorkDir>\hardware\numchannels\zone..0..n.bmp // <WorkDir>\hardware\zone..0..n.bmp // <WorkDir>\zone..0..n.bmp // Automatik Berechnung... LockCriticalSection(); if(!m_pAtmoConnection || !m_pAtmoConfig) { UnLockCriticalSection(); return; } m_pAtmoConfig->UpdateZoneDefinitionCount(); CalculateDefaultZones(); char psz_filename[MAX_PATH]; CAtmoZoneDefinition *zoneDef; sprintf(psz_filename,"%s%s", m_WorkDir, m_pAtmoConnection->getDevicePath() ); CreateDirectory( psz_filename, NULL ); sprintf(psz_filename,"%s%s\\%dx%dx%d", m_WorkDir, m_pAtmoConnection->getDevicePath(), m_pAtmoConfig->getZonesTopCount(), m_pAtmoConfig->getZonesLRCount(), m_pAtmoConfig->getZonesBottomCount() ); CreateDirectory(psz_filename, NULL ); // try to load device depended zone definition bitmaps for(int zone=0; zone < m_pAtmoConfig->getZoneCount(); zone++) { zoneDef = m_pAtmoConfig->getZoneDefinition(zone); if(!zoneDef) continue; sprintf(psz_filename,"%s%s\\%dx%dx%d\\zone_%d.bmp", m_WorkDir, m_pAtmoConnection->getDevicePath(), m_pAtmoConfig->getZonesTopCount(), m_pAtmoConfig->getZonesLRCount(), m_pAtmoConfig->getZonesBottomCount(), zone ); i = zoneDef->LoadGradientFromBitmap( psz_filename ); if(i == ATMO_LOAD_GRADIENT_OK) continue; if((i == ATMO_LOAD_GRADIENT_FAILED_SIZE) || (i == ATMO_LOAD_GRADIENT_FAILED_HEADER)) MessageBox(0,psz_filename,"Failed to load, Check Format, Check Size.",MB_ICONERROR); sprintf(psz_filename,"%s%s\\zone_%d.bmp", m_WorkDir, m_pAtmoConnection->getDevicePath(), zone ); i = zoneDef->LoadGradientFromBitmap( psz_filename ); if(i == ATMO_LOAD_GRADIENT_OK) continue; if((i == ATMO_LOAD_GRADIENT_FAILED_SIZE) || (i == ATMO_LOAD_GRADIENT_FAILED_HEADER)) MessageBox(0,psz_filename,"Failed to load, Check Format, Check Size.",MB_ICONERROR); sprintf(psz_filename,"%szone_%d.bmp", m_WorkDir, zone ); i = zoneDef->LoadGradientFromBitmap( psz_filename ); if(i == ATMO_LOAD_GRADIENT_OK) continue; if((i == ATMO_LOAD_GRADIENT_FAILED_SIZE) || (i == ATMO_LOAD_GRADIENT_FAILED_HEADER)) MessageBox(0,psz_filename,"Failed to load, Check Format, Check Size.",MB_ICONERROR); } UnLockCriticalSection(); }
void CAtmoDynData::CalculateDefaultZones() { int i; int num_cols_top; int num_cols_bottom; int num_rows; CAtmoZoneDefinition *zoneDef; if(!m_pAtmoConfig) return; m_pAtmoConfig->UpdateZoneDefinitionCount(); num_cols_top = m_pAtmoConfig->getZonesTopCount(); num_cols_bottom = m_pAtmoConfig->getZonesBottomCount(); num_rows = m_pAtmoConfig->getZonesLRCount(); for(int zone=0; zone < m_pAtmoConfig->getZoneCount(); zone++) { zoneDef = m_pAtmoConfig->getZoneDefinition(zone); if(zoneDef) zoneDef->Fill(0); } // the zones will be counted starting from top left - in clockwise order around the display // the summary channel will be the last one (in the center) i = 0; // top zones from left to right for(int c=0;c<num_cols_top;c++) { zoneDef = m_pAtmoConfig->getZoneDefinition(i); i++; if(zoneDef) { int l = (c * CAP_WIDTH)/num_cols_top; int r = ((c+1) * CAP_WIDTH)/num_cols_top; zoneDef->FillGradientFromTop( ATMO_MAX( l - CAP_ZONE_OVERLAP, 0) , ATMO_MIN( r + CAP_ZONE_OVERLAP, CAP_WIDTH ) ); } } // right zones from top to bottom for(int r=0;r<num_rows;r++) { zoneDef = m_pAtmoConfig->getZoneDefinition(i); i++; if(zoneDef) { int t = (r * CAP_HEIGHT)/num_rows; int b = ((r+1) * CAP_HEIGHT)/num_rows; zoneDef->FillGradientFromRight( ATMO_MAX( t - CAP_ZONE_OVERLAP, 0) , ATMO_MIN( b + CAP_ZONE_OVERLAP, CAP_HEIGHT) ); } } // bottom zones from RIGHT to LEFT! for(int c=(num_cols_bottom-1);c>=0;c--) { zoneDef = m_pAtmoConfig->getZoneDefinition(i); i++; if(zoneDef) { int l = (c * CAP_WIDTH)/num_cols_bottom; int r = ((c+1) * CAP_WIDTH)/num_cols_bottom; zoneDef->FillGradientFromBottom( ATMO_MAX( l - CAP_ZONE_OVERLAP, 0 ), ATMO_MIN( r + CAP_ZONE_OVERLAP, CAP_WIDTH ) ); } } // left zones from bottom to top! for(int r=(num_rows-1);r>=0;r--) { zoneDef = m_pAtmoConfig->getZoneDefinition(i); i++; if(zoneDef) { int t = (r * CAP_HEIGHT)/num_rows; int b = ((r+1) * CAP_HEIGHT)/num_rows; zoneDef->FillGradientFromLeft( ATMO_MAX( t - CAP_ZONE_OVERLAP, 0 ), ATMO_MIN( b + CAP_ZONE_OVERLAP, CAP_HEIGHT ) ); } } if(m_pAtmoConfig->getZoneSummary()) { // and last the summary zone if requested! zoneDef = m_pAtmoConfig->getZoneDefinition(i++); if(zoneDef) zoneDef->Fill(255); } }
pColorPacket CAtmoColorCalculator::AnalyzeHSV(tHSVColor *HSV_Img) { int i; // counter int AtmoSetup_EdgeWeighting = m_pAtmoConfig->getLiveView_EdgeWeighting(); int AtmoSetup_WidescreenMode = m_pAtmoConfig->getLiveView_WidescreenMode(); int AtmoSetup_DarknessLimit = m_pAtmoConfig->getLiveView_DarknessLimit(); int AtmoSetup_BrightCorrect = m_pAtmoConfig->getLiveView_BrightCorrect(); int AtmoSetup_SatWinSize = m_pAtmoConfig->getLiveView_SatWinSize(); int AtmoSetup_NumZones = m_pAtmoConfig->getZoneCount(); tHSVColor *temp_Img; if(AtmoSetup_NumZones != m_LastNumZones) { delete[] m_Weight; delete[] m_hue_hist; delete[] m_windowed_hue_hist; delete[] m_most_used_hue_last; delete[] m_most_used_hue; delete[] m_sat_hist; delete[] m_windowed_sat_hist; delete[] m_most_used_sat; delete[] m_Zone_Weights; delete[] m_average_v; delete[] m_average_counter; m_Weight = new int[AtmoSetup_NumZones * IMAGE_SIZE]; m_Zone_Weights = new int*[AtmoSetup_NumZones]; for(int i = 0; i < AtmoSetup_NumZones; i++) m_Zone_Weights[i] = &m_Weight[i * IMAGE_SIZE]; m_hue_hist = new long int[(h_MAX+1) * AtmoSetup_NumZones]; m_windowed_hue_hist = new long int[(h_MAX+1) * AtmoSetup_NumZones]; m_most_used_hue_last = new int[AtmoSetup_NumZones]; m_most_used_hue = new int[AtmoSetup_NumZones]; memset( m_most_used_hue_last, 0, sizeof(int) * AtmoSetup_NumZones); m_sat_hist = new long int[(s_MAX+1) * AtmoSetup_NumZones]; m_windowed_sat_hist = new long int[(s_MAX+1) * AtmoSetup_NumZones]; m_most_used_sat = new int[AtmoSetup_NumZones]; m_average_v = new long int[AtmoSetup_NumZones]; m_average_counter = new int[AtmoSetup_NumZones]; m_LastNumZones = AtmoSetup_NumZones; } // calculate only if setup has changed if ((AtmoSetup_EdgeWeighting != m_LastEdgeWeighting) || (AtmoSetup_WidescreenMode != m_LastWidescreenMode) || (m_pAtmoConfig->getZonesTopCount() != m_LastLayout_TopCount) || (m_pAtmoConfig->getZonesBottomCount() != m_LastLayout_BottomCount) || (m_pAtmoConfig->getZonesLRCount() != m_LastLayout_LRCount) || (m_pAtmoConfig->m_UpdateEdgeWeightningFlag != 0) ) { for(i = 0 ;i < AtmoSetup_NumZones; i++) { CAtmoZoneDefinition *pZoneDef = m_pAtmoConfig->getZoneDefinition(i); if(pZoneDef) { pZoneDef->UpdateWeighting(m_Zone_Weights[i], AtmoSetup_WidescreenMode, AtmoSetup_EdgeWeighting); #ifdef _debug_zone_weight_ char filename[128]; sprintf(filename, "zone_%d_gradient_debug.bmp",i); pZoneDef->SaveZoneBitmap( filename ); sprintf(filename, "zone_%d_weight_%d_debug.bmp",i,AtmoSetup_EdgeWeighting); pZoneDef->SaveWeightBitmap(filename, m_Zone_Weights[i] ); #endif } } m_pAtmoConfig->m_UpdateEdgeWeightningFlag = 0; m_LastEdgeWeighting = AtmoSetup_EdgeWeighting; m_LastWidescreenMode = AtmoSetup_WidescreenMode; m_LastLayout_TopCount = m_pAtmoConfig->getZonesTopCount(); m_LastLayout_BottomCount = m_pAtmoConfig->getZonesBottomCount(); m_LastLayout_LRCount = m_pAtmoConfig->getZonesLRCount(); } AtmoSetup_DarknessLimit = AtmoSetup_DarknessLimit * 10; /***************************************************************************/ /* Hue */ /***************************************************************************/ /*----------------------------*/ /* hue histogram builtup */ /*----------------------------*/ // HSV histogram // long int hue_hist[CAP_MAX_NUM_ZONES][h_MAX+1]; // average brightness (value) // m_average_v m_average_counter // clean histogram --> calloc memset(m_hue_hist, 0, sizeof(long int) * (h_MAX+1) * AtmoSetup_NumZones); memset(m_average_v, 0, sizeof(long int) * AtmoSetup_NumZones); memset(m_average_counter, 0, sizeof(int) * AtmoSetup_NumZones); temp_Img = HSV_Img; i = 0; for (int row = 0; row < CAP_HEIGHT; row++) { for (int column = 0; column < CAP_WIDTH; column++) { // forget black bars: perform calculations only if pixel has some luminosity if ((*temp_Img).v > AtmoSetup_DarknessLimit) { // builtup histogram for the x Zones of the Display for (int zone = 0; zone < AtmoSetup_NumZones; zone++) { // Add weight to channel // Weight(zone, pixel_nummer) m_Weight[((zone) * (IMAGE_SIZE)) + (pixel_nummer)] // m_hue_hist[zone*(h_MAX+1) + HSV_Img[i].h] += m_Zone_Weights[zone][i] * HSV_Img[i].v; m_hue_hist[zone*(h_MAX+1) + (*temp_Img).h] += m_Zone_Weights[zone][i] * temp_Img->v; if(m_Zone_Weights[zone][i] > 0) { m_average_v[zone] += temp_Img->v; m_average_counter[zone]++; } } // calculate brightness average } temp_Img++; i++; } } /*----------------------------*/ /* hue histogram windowing */ /*----------------------------*/ // windowed HSV histogram // long int w_hue_hist[CAP_MAX_NUM_ZONES][h_MAX+1]; -> m_windowed_hue_hist // clean windowed histogram memset(m_windowed_hue_hist, 0, sizeof(long int) * (h_MAX+1) * AtmoSetup_NumZones); // steps in each direction; eg. 2 => -2 -1 0 1 2 windowing int hue_windowsize = m_pAtmoConfig->getLiveView_HueWinSize(); for (i = 0; i < h_MAX+1; i++) // walk through histogram [0;h_MAX] { // windowing from -hue_windowsize -> +hue_windowsize for (int mywin = -hue_windowsize; mywin < hue_windowsize+1; mywin++) { // addressed histogram candlestick int myidx = i + mywin; // handle beginning of windowing -> roll back if (myidx < 0) { myidx = myidx + h_MAX + 1; } // handle end of windowing -> roll forward if (myidx > h_MAX) { myidx = myidx - h_MAX - 1; } // Apply windowing to all x zones for (int zone = 0; zone < AtmoSetup_NumZones; zone++) { // apply lite triangular window design with gradient of 10% per discrete step m_windowed_hue_hist[(zone * (h_MAX+1)) + i] += m_hue_hist[(zone * (h_MAX+1)) + myidx] * ((hue_windowsize+1)-abs(mywin)); // apply window } } } /*--------------------------------------*/ /* analyze histogram for most used hue */ /*--------------------------------------*/ // index of last maximum // static int most_used_hue_last[CAP_MAX_NUM_ZONES] = {0, 0, 0, 0, 0}; --> m_most_used_hue_last // resulting hue for each channel //int most_used_hue[CAP_MAX_NUM_ZONES]; --> m_most_used_hue FindMostUsed(AtmoSetup_NumZones, m_most_used_hue, m_windowed_hue_hist); for (int zone = 0; zone < AtmoSetup_NumZones; zone++) { float percent = (float)m_windowed_hue_hist[zone * (h_MAX+1) + m_most_used_hue_last[zone]] / (float)m_windowed_hue_hist[zone * (h_MAX+1) + m_most_used_hue[zone]]; if (percent > 0.93f) // less than 7% difference? m_most_used_hue[zone] = m_most_used_hue_last[zone]; // use last index else m_most_used_hue_last[zone] = m_most_used_hue[zone]; } /* memset(m_most_used_hue, 0, sizeof(int) * AtmoSetup_NumZones); for (int zone = 0; zone < AtmoSetup_NumZones; zone++) { long int value = 0; for (i = 0; i < h_MAX+1; i++) // walk through histogram { long int tmp = m_windowed_hue_hist[ (zone * (h_MAX+1)) + i ]; if (tmp > value) // if new value bigger then old one { m_most_used_hue[zone] = i; // remember index value = tmp; // w_hue_hist[zone][i]; // and value } } float percent = (float)m_windowed_hue_hist[zone * (h_MAX+1) + m_most_used_hue_last[zone]] / (float)value; if (percent > 0.93f) // less than 7% difference? { m_most_used_hue[zone] = m_most_used_hue_last[zone]; // use last index } m_most_used_hue_last[zone] = m_most_used_hue[zone]; // save current index of most used hue } */ /***************************************************************************/ /* saturation */ /***************************************************************************/ // sat histogram // long int sat_hist[CAP_MAX_NUM_ZONES][s_MAX+1]; -> m_sat_hist // hue of the pixel we are working at int pixel_hue = 0; // clean histogram memset(m_sat_hist, 0, sizeof(long int) * (s_MAX+1) * AtmoSetup_NumZones); /*--------------------------------------*/ /* saturation histogram builtup */ /*--------------------------------------*/ i = 0; temp_Img = HSV_Img; for (int row = 0; row < CAP_HEIGHT; row++) { for (int column = 0; column < CAP_WIDTH; column++) { // forget black bars: perform calculations only if pixel has some luminosity if ((*temp_Img).v > AtmoSetup_DarknessLimit) { // find histogram position for pixel pixel_hue = (*temp_Img).h; // TODO: brightness calculation(if we require it some time) for (int zone = 0; zone < AtmoSetup_NumZones; zone++) { // only use pixel for histogram if hue is near most_used_hue if ((pixel_hue > m_most_used_hue[zone] - hue_windowsize) && (pixel_hue < m_most_used_hue[zone] + hue_windowsize)) { // build histogram // sat_hist[channel][HSV_Img[i].s] += Weight[i].channel[channel] * HSV_Img[i].v; m_sat_hist[zone * (s_MAX+1) + (*temp_Img).s ] += m_Zone_Weights[zone][i] * (*temp_Img).v; } } } i++; temp_Img++; } } /*--------------------------------------*/ /* saturation histogram windowing */ /*--------------------------------------*/ // windowed HSV histogram // long int w_sat_hist[CAP_MAX_NUM_ZONES][s_MAX+1]; --> m_windowed_sat_hist // clean windowed histogram memset(m_windowed_sat_hist, 0, sizeof(long int) * (s_MAX+1) * AtmoSetup_NumZones); // steps in each direction; eg. 2 => -2 -1 0 1 2 windowing int sat_windowsize = AtmoSetup_SatWinSize; // walk through histogram [0;h_MAX] for (i = 0; i < s_MAX + 1; i++) { // windowing from -hue_windowsize -> +hue_windowsize for (int mywin = -sat_windowsize; mywin < sat_windowsize+1; mywin++) { // addressed histogram candlestick int myidx = i + mywin; // handle beginning of windowing -> roll back if (myidx < 0) { myidx = myidx + s_MAX + 1; } // handle end of windowing -> roll forward if (myidx > h_MAX) { myidx = myidx - s_MAX - 1; } for (int zone = 0; zone < AtmoSetup_NumZones; zone++) { /* apply lite triangular window design with gradient of 10% per discrete step */ /* w_sat_hist[channel][i] += sat_hist[channel][myidx] * ((sat_windowsize+1)-abs(mywin)); // apply window */ m_windowed_sat_hist[zone * (s_MAX+1) + i] += m_sat_hist[zone* (h_MAX+1) + myidx] * ((sat_windowsize+1)-abs(mywin)); // apply window } } } /*--------------------------------------*/ /* analyze histogram for most used sat */ /*--------------------------------------*/ // resulting sat (most_used_hue) for each channel // int most_used_sat[CAP_MAX_NUM_ZONES];->m_most_used_sat FindMostUsed(AtmoSetup_NumZones, m_most_used_sat, m_windowed_sat_hist); /* memset(m_most_used_sat, 0, sizeof(int) * AtmoSetup_NumZones); for (int zone = 0; zone < AtmoSetup_NumZones; zone++) { int value = 0; // walk trough histogram for (i = 0; i < s_MAX+1; i++) { // if new value bigger then old one int tmp = m_windowed_sat_hist[zone * (s_MAX+1) + i]; // if (w_sat_hist[channel][i] > value) if (tmp > value) { // remember index m_most_used_sat[zone] = i; // and value value = tmp; } } } */ /*----------------------------------------------------------*/ /* calculate average brightness within HSV image */ /* uniform Brightness for all channels is calculated */ /*----------------------------------------------------------*/ /* code integrated into "hue histogram builtup" to save some looping time! int l_counter = 0; // average brightness (value) long int value_avg = 0; i = 0; for (int row = 0; row < CAP_HEIGHT; row++) { for (int column = 0; column < CAP_WIDTH; column++) { // find average value: only use bright pixels for luminance average if (HSV_Img[i].v > AtmoSetup_DarknessLimit) { // build brightness average value_avg += HSV_Img[i].v; l_counter++; } i++; } } // calculate brightness average if (l_counter > 0) { value_avg = value_avg / l_counter; } else { value_avg = AtmoSetup_DarknessLimit; } */ /*----------------------------*/ /* adjust and copy results */ /*----------------------------*/ tHSVColor hsv_pixel; // storage container for resulting RGB values pColorPacket output_colors; AllocColorPacket(output_colors, AtmoSetup_NumZones); // adjust brightness // int new_value = (int) ((float)value_avg * ((float)AtmoSetup_BrightCorrect / 100.0)); // if (new_value > 255) new_value = 255; // ensure brightness isn't set too high // hsv_pixel.v = (unsigned char)new_value; /* // calculate brightness average for(int zone = 0; zone < AtmoSetup_NumZones; zone++) { if(m_average_counter[zone] > 0) m_average_v[zone] = m_average_v[zone] / m_average_counter[zone] else m_average_v[zone] = AtmoSetup_DarknessLimit; } */ for (int zone = 0; zone < AtmoSetup_NumZones; zone++) { if(m_average_counter[zone] > 0) m_average_v[zone] = m_average_v[zone] / m_average_counter[zone]; else m_average_v[zone] = AtmoSetup_DarknessLimit; m_average_v[zone] = (int)((float)m_average_v[zone] * ((float)AtmoSetup_BrightCorrect / 100.0)); hsv_pixel.v = (unsigned char)ATMO_MAX(ATMO_MIN(m_average_v[zone],255),0); hsv_pixel.h = m_most_used_hue[zone]; hsv_pixel.s = m_most_used_sat[zone]; // convert back to rgb output_colors->zone[zone] = HSV2RGB(hsv_pixel); } return output_colors; }