Click here to Skip to main content
15,037,388 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
AnswerRe: How to fix the invalide pointer problem Pin
Saravanan Sundaresan24-Sep-16 19:55
professionalSaravanan Sundaresan24-Sep-16 19:55 
QuestionHow do you read / use this code? Pin
Vaclav_8-Sep-16 7:40
MemberVaclav_8-Sep-16 7:40 
AnswerRe: How do you read / use this code? Pin
NotPolitcallyCorrect8-Sep-16 7:58
MemberNotPolitcallyCorrect8-Sep-16 7:58 
GeneralRe: How do you read / use this code? Pin
Vaclav_8-Sep-16 10:16
MemberVaclav_8-Sep-16 10:16 
AnswerRe: How do you read / use this code? Pin
Bram van Kampen8-Sep-16 14:40
MemberBram van Kampen8-Sep-16 14:40 
AnswerRe: How do you read / use this code? Pin
leon de boer8-Sep-16 17:26
Memberleon de boer8-Sep-16 17:26 
GeneralSOLVED Re: How do you read / use this code? Pin
Vaclav_9-Sep-16 18:23
MemberVaclav_9-Sep-16 18:23 
QuestionReference CalculateRamp - How to derive entry arguments from the existing Gamma Ramp - My best solution Pin
Keith Davis3-Sep-16 6:28
MemberKeith Davis3-Sep-16 6:28 
In reference to the widely used CalculateRamp code:



public static void CalculateRamp(double level, double gamma, double brightness, double contrast)
{
    ramp.Red = new ushort[256];
    ramp.Green = new ushort[256];
    ramp.Blue = new ushort[256];

    gamma /= 10;
    brightness = 1 + (((brightness - 50) / 100) * 65535);
    contrast = 1 + ((contrast - 50) / 100);
    level = 1 + ((level - 50) / 100);

    for (int i = 0; i < 256; i++)
    {
        double value = i * 256;
        value = (Math.Pow(value / 65535, 1 / gamma) * 65535) + 0.5;
        value = ((((value / 65535) - 0.5) * contrast) + 0.5) * 65535;
        value = value += brightness;
        value *= level;
        ramp.Red[i] = ramp.Green[i] = ramp.Blue[i] = 
        (ushort)Math.Min((double)65535, Math.Max((double)0, value));
    }
    SetDeviceGammaRamp(GetDC(IntPtr.Zero), ref ramp);
} 


How would you calculate the input values (arguments) for this method directly from the existing Gamma Ramp? In other words, what would be the reverse method?

If I am going to provide these utilities to the user, I need to present them with their current settings prior to their making the adjustments.

I have tried for three days to come up with a solution, and must admit that this is beyond my capabilities.

Update Sept 8, 2016 - My best solution...

While I worked long and hard looking for a mathematical solution, I finally went back and played around with the iteration method.

A blunt force iteration that calculates each and every possible setting and then checks for a match will run for more than 20 minutes; which is unacceptable.

I found that I could take a single sample point in the middle of the array and quickly iterate through all possible settings to find a match for that one sample; and then perform all 256 of the calculations for the array to see if we had a complete match. This operation generally runs in less than a second.

But I realized that there was yet another problem. If the Gamma Ramp was not programmed using the CalculateRamp algorithm (such as factory setting) then it is unlikely that we will find an exact match for our settings; and our solution will fail.

So I devised a backup plan that uses four sample points from across the gamma ramp array; and then set up a "span" of acceptable values that would provide a close approximation for our settings. The criteria for "span" would broaden after each failure, and re-enter the search. This scenario will produce an approximation of the Gamma Ramp Settings usually within about three seconds. This is acceptable since my main program can perform this operation during the program startup sequence.

Here is my C++ solution...

//---------------------------------------------------------------------------
int __fastcall TForm1::Round( double flt ){
   int num = (int) flt;
   if( flt >= 0 ){
      if( flt - num >= .5 ){ num++;}
   }else{
      if( flt - num <= -.5 ){ num--;}
   }
   return( num );
}
//----------------------------------------------------------------------------
void __fastcall TForm1::GetGammaRampSettings(void){
   // level should be between 2 and 100
   // gamma should be between 2 and 50
   // brigntess should be between 0 and 100
   // contrast should be between 0 and 100

   double i,j,k,m;
   double gamma,bright,cntrst,level;
   double v1,v2,v3,v4;
   double c1,c2,c3,c4;
   double a1,a2,a3,a4,b1,b2,b3,b4; //for best estimate criteria
   int x1,x2,x3,x4,x5;
   int d,n;
   WORD span = 8;
   bool tog = false;

   TDateTime strt, end;

   WORD GammaArray[3][256]; //Gamma Ramp Array buffer
   WORD CompArray[256];     //Array buffer for comparison

   HDC GammaDC = GetDC( NULL );  //fetch the gamma ramp array
   GetDeviceGammaRamp( GammaDC, GammaArray );
   ReleaseDC( NULL, GammaDC );

   strt=Now();

   //Find two endpoints for the GammaArray
   for( x1 = 0; x1 < 256; x1++ ){
      if( GammaArray[0][x1] > 0 ){ break;}
   }

   for( x2 = 0; x2 < 256; x2++ ){
      if( GammaArray[0][x2] == 65535 ){ break;}
   }
   if( x2 == 256 ){ x2 = 255; }

   x5 = x1 + Round( (double)( x2 - x1 ) / 2.0 );

   Memo1->Lines->Add( "x1 = " + IntToStr( x1 )); //start
   Memo1->Lines->Add( "x2 = " + IntToStr( x2 )); //end
   Memo1->Lines->Add( "x5 = " + IntToStr( x5 )); //mid

   //neutral settings are as follows...
   //Bright = 50
   //Contrast = 50
   //Level = 50
   //Gamma = 10

   //The following code will look for an exact match to the settings
   //but it may fail if the gamma ramp was not programmed using the
   //original CalculateRamp code. ie: A factory setting, or other

   for(n=0;n<=40;){//gamma
      if( n < 9 ){         //gamma begins with a neutral setting of 10 and
         if( tog ){        //then increments high and low depending on tog
            i = ( 10 - n );
            tog = false; n++;
            if( i == 10 ){ continue;}
         }else{
            i = ( 10 + n );
            tog = true;
         }
      }else{
         i = ( 10 + n++ );
      }
      gamma = i / 10;
      v1 = ( pow( (double)(x5 * 256) / 65535, 1 / gamma) * 65535) + 0.5;
      for( j = 2; j < 101 ; j++ ){//level    //980,000 possible iterations
         level = 1 + ((j - 50) / 100);
         for( k = 0; k < 101; k++ ){//bright
            bright = 1 + (((k - 50) / 100) * 65535);
            for( m = 0; m < 101; m++ ){//contrast
               cntrst = 1 + ((m - 50) / 100);
               //Test only the mid-line value at first
               //To see if a complete comparison is warranted
               c1 = (((( v1 / 65535 ) - 0.5) * cntrst) + 0.5) * 65535;
               c1 = c1 += bright;
               c1 *= level;
               if( c1 > 65535){ c1 = 65535; }
               if( c1 < 0 ){ c1 = 0; }
		         if( (WORD) c1 == GammaArray[0][x5] ){
                  for( d = 0; d < 256; d++ ){
                     c1 = ( pow( (double)(d * 256) / 65535, 1 / gamma) * 65535) + 0.5;
                     c1 = ((( (c1 / 65535) - 0.5) * cntrst) + 0.5) * 65535;
                     c1 = c1 += bright;
                     c1 *= level;
                     if( c1 > 65535 ){ c1 = 65535;}
                     if( c1 < 0 ){ c1 = 0;}
                     CompArray[d] = (WORD) c1;
                  }
                  if(memcmp( &CompArray[0], &GammaArray[0][0], 2*256) == 0){
                     goto ENDIT;
                  }
               }
            }
         }
      }
   }

   //Since an exact match could not be found for the current
   //gamma ramp settings, we will broaden our criteria and
   //search for the best match for our gamma ramp settings.

   //Here our search is based on the start and end values,
   //plus two additional values that are 1/4 of the overall distance
   //above the start point; and 1/4 the distance below the end point.

   Memo1->Lines->Add("Values NOT Discovered!!!");
   Memo1->Lines->Add("Widening the Search....");

   x3 = x1 + Round( (double)( x2 - x1 ) / 4.0 );
   x4 = x1 + Round(( (double)( x2 - x1 ) / 4.0 )*3);

   Memo1->Lines->Add( "x1 = " + IntToStr( x1 )); //start
   Memo1->Lines->Add( "x2 = " + IntToStr( x2 )); //end
   Memo1->Lines->Add( "x3 = " + IntToStr( x3 )); // 1/4
   Memo1->Lines->Add( "x4 = " + IntToStr( x4 )); // 3/4

   BROADEN:

   a1 = GammaArray[0][x1]+span; //these are our high and low
   b1 = GammaArray[0][x1]-span; //values that the ramp values must
                                //fall within to be accepted
   a2 = GammaArray[0][x2]+span;
   b2 = GammaArray[0][x2]-span; //span begins at 8 and increments upwards
                                //with each loop, ever widening the
   a3 = GammaArray[0][x3]+span; //the search criteria
   b3 = GammaArray[0][x3]-span;

   a4 = GammaArray[0][x4]+span;
   b4 = GammaArray[0][x4]-span;

   tog=false;
   for(n=0;n<=40;){//gamma
      if( n < 9 ){         //gamma begins with a neutral setting of 10 and
         if( tog ){        //then increments high and low depending on tog
            i = ( 10 - n );
            tog = false; n++;
            if( i == 10 ){ continue;} //prevents two instances of i == 10
         }else{
            i = ( 10 + n );
            tog = true;
         }
      }else{
         i = ( 10 + n++ );
      }
      gamma = i / 10;
      v1 = ( pow( (double)(x1 * 256) / 65535, 1 / gamma) * 65535) + 0.5;
      v2 = ( pow( (double)(x2 * 256) / 65535, 1 / gamma) * 65535) + 0.5;
      v3 = ( pow( (double)(x3 * 256) / 65535, 1 / gamma) * 65535) + 0.5;
      v4 = ( pow( (double)(x4 * 256) / 65535, 1 / gamma) * 65535) + 0.5;
      for( j = 2; j < 101 ; j++ ){//level    //980,000 possible iterations
         level = 1 + ((j - 50) / 100);
         for( k = 0; k < 101; k++ ){//bright
            bright = 1 + (((k - 50) / 100) * 65535);
            for( m = 0; m < 101; m++ ){//contrast
               cntrst = 1 + ((m - 50) / 100);
               //Test the four sample values to see if the
               //results falls within our acceptance criteria.
               c1 = (((( v1 / 65535 ) - 0.5) * cntrst) + 0.5) * 65535;
               c1 = c1 += bright;
               c1 *= level;
               c2 = (((( v2 / 65535 ) - 0.5) * cntrst) + 0.5) * 65535;
               c2 = c2 += bright;
               c2 *= level;
               c3 = (((( v3 / 65535 ) - 0.5) * cntrst) + 0.5) * 65535;
               c3 = c3 += bright;
               c3 *= level;
               c4 = (((( v4 / 65535 ) - 0.5) * cntrst) + 0.5) * 65535;
               c4 = c4 += bright;
               c4 *= level;
		         if( c1 <= a1 && c1 >= b1 &&  c2 <= a2 && c2 >= b2 &&
                   c3 <= a3 && c3 >= b3 &&  c4 <= a4 && c4 >= b4 ){
                   Memo1->Lines->Add("Best Estimate +/- " + IntToStr( span ));
                   goto ENDIT;
               }
            }
         }
      }
   }

   if( span < 256){
      span *= 2;
      goto BROADEN;
   }else if( span <= 4096 ){ //set the maximum allowance for "span"
      span += 128;           //which is the basis for the allowable
      goto BROADEN;          //search criteria
   }

   //if we get to this point then we have utterly failed.
   Memo1->Lines->Add("Values STILL NOT Discovered.");
   Memo1->Lines->Add("GetGammaRampSettings Failed.");
   return;

   ENDIT:
   end=Now();
   Memo1->Lines->Add("Execution duration was "+
         FormatDateTime("nn:ss:zzz",end-strt));

   //Report on findings...
   Memo1->Lines->Add("Bright = " + IntToStr( (int) k ));
   Memo1->Lines->Add("Cntrst = " + IntToStr( (int) m ));
   Memo1->Lines->Add("Level = " + IntToStr( (int) j ));
   Memo1->Lines->Add("Gamma = " + IntToStr( (int) i ));

}
//---------------------------------------------------------------------------


modified 8-Sep-16 14:53pm.

QuestionRe: Reference CalculateRamp - How to derive entry arguments from the existing Gamma Ramp Pin
Richard MacCutchan3-Sep-16 6:36
mveRichard MacCutchan3-Sep-16 6:36 
AnswerRe: Reference CalculateRamp - How to derive entry arguments from the existing Gamma Ramp Pin
Keith Davis3-Sep-16 6:47
MemberKeith Davis3-Sep-16 6:47 
AnswerRe: Reference CalculateRamp - How to derive entry arguments from the existing Gamma Ramp Pin
Keith Davis3-Sep-16 7:11
MemberKeith Davis3-Sep-16 7:11 
AnswerRe: Reference CalculateRamp - How to derive entry arguments from the existing Gamma Ramp Pin
leon de boer4-Sep-16 3:54
Memberleon de boer4-Sep-16 3:54 
GeneralRe: Reference CalculateRamp - How to derive entry arguments from the existing Gamma Ramp Pin
Keith Davis4-Sep-16 9:10
MemberKeith Davis4-Sep-16 9:10 
GeneralRe: Reference CalculateRamp - How to derive entry arguments from the existing Gamma Ramp Pin
leon de boer4-Sep-16 22:36
Memberleon de boer4-Sep-16 22:36 
GeneralRe: Reference CalculateRamp - How to derive entry arguments from the existing Gamma Ramp Pin
Keith Davis5-Sep-16 4:38
MemberKeith Davis5-Sep-16 4:38 
GeneralRe: Reference CalculateRamp - How to derive entry arguments from the existing Gamma Ramp Pin
leon de boer5-Sep-16 6:06
Memberleon de boer5-Sep-16 6:06 
GeneralRe: Reference CalculateRamp - How to derive entry arguments from the existing Gamma Ramp Pin
Keith Davis5-Sep-16 8:23
MemberKeith Davis5-Sep-16 8:23 
GeneralRe: Reference CalculateRamp - How to derive entry arguments from the existing Gamma Ramp Pin
leon de boer5-Sep-16 18:55
Memberleon de boer5-Sep-16 18:55 
GeneralRe: Reference CalculateRamp - How to derive entry arguments from the existing Gamma Ramp Pin
Keith Davis5-Sep-16 19:55
MemberKeith Davis5-Sep-16 19:55 
GeneralRe: Reference CalculateRamp - How to derive entry arguments from the existing Gamma Ramp Pin
Keith Davis8-Sep-16 9:31
MemberKeith Davis8-Sep-16 9:31 
AnswerRe: Reference CalculateRamp - How to derive entry arguments from the existing Gamma Ramp - My Solution Pin
Keith Davis7-Sep-16 10:30
MemberKeith Davis7-Sep-16 10:30 
QuestionPrinter Control Pin
Bram van Kampen27-Aug-16 15:38
MemberBram van Kampen27-Aug-16 15:38 
QuestionRe: Printer Control Pin
Richard MacCutchan27-Aug-16 20:31
mveRichard MacCutchan27-Aug-16 20:31 
AnswerRe: Printer Control Pin
Bram van Kampen28-Aug-16 14:20
MemberBram van Kampen28-Aug-16 14:20 
GeneralRe: Printer Control Pin
Richard MacCutchan28-Aug-16 20:56
mveRichard MacCutchan28-Aug-16 20:56 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.