Click here to Skip to main content
15,065,644 members
Home / Discussions / C / C++ / MFC
   

C / C++ / MFC

 
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 
Quote:
After unsuccessfully trying to solve for a mathematical solution for a week I had to try some other way to derive the Gamma Ramp Settings directly from the GetDeviceGammaRamp call.

One early attempt involved a simple iteration of all possible settings. This gave correct results, but it took more than 20 minutes to complete the operation. My application needs to be able to do this in under a second.

I finally found a better, more efficient way to perform the iterations, and it meets my requirements. It may be an imperfect solution; but a win is a win.

I shaved a little more time off of this operation by testing for a positive or a negative curve in the Gamma setting (or no curve at all = neutral setting 10). This saves a few iterations going in. To do this I created two additional functions: PtToPtRngBrg and GetPtFromPt.

If you like, you can skip these; and simply iterate through all possible Gamma settings (2 to 50). This would greatly simplify the code.

Here is my C++ solution...


C#
//---------------------------------------------------------------------------
#define DEG_RAD 0.017453292519943295769236907684886
//---------------------------------------------------------------------------
struct RngBrg{  //Struct for return values in the
   double rng;  //call to PtToPtRngBrg
   double brg;
};
//---------------------------------------------------------------------------
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,m4;
   double s1,s2,s3,s4;
   double gamma,bright,cntrst,level;
   double value;
   int d;
   int x1,x2,x3,x4;
   bool isFound=false;
   RngBrg rb; //Range and Bearing struct for distance and vector

   WORD GammaArray[3][256]; //Gamma Ramp Array buffer
   WORD CompArray[256];     //Array buffer for comparison
   double DArray[256];      //buffer used to hold gamma values

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

   //Calculate the Angle:

   //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){isFound=true; break;}
   }
   if( !isFound ){ x2--; }

   //normalize the gama ramp numbers
   //so that a distance and vector can be calculated
   s1 = ( (double) GammaArray[0][x1] + 1 ) / 256.0;
   s2 = ( (double) GammaArray[0][x2] + 1 ) / 256.0;

   //find the mid point array element from the line described above...
   x3 = x1 + ( ( x2 - x1 ) / 2 );
   s3 = ( (double) GammaArray[0][x3] + 1 ) / 256.0;

   Memo1->Lines->Add( "x1 = " + IntToStr(x1) + "  s1 = " + AnsiString(s1));
   Memo1->Lines->Add( "x2 = " + IntToStr(x2) + "  s2 = " + AnsiString(s2));
   Memo1->Lines->Add( "x3 = " + IntToStr(x3) + "  s3 = " + AnsiString(s3));

   //caculate the strait line between
   //the two endpoints discovered above
   PtToPtRngBrg( &rb, x1, s1, x2, s2 );

   //neutral settings are as follows...
   //Bright = 50
   //Contrast = 50
   //Level = 50
   //Gamma = 10
   //rng = 359.210244842766 and  brg = 45 with all neutral settings
   Memo1->Lines->Add( "rng = " + AnsiString( rb.rng ) +
                      "  brg = " + AnsiString( rb.brg ));

   //what would be the value of the midpoint
   //if it were a strait line (neutral gamma setting)?

   GetPtFromPt(x1, s1, rb.rng / 2.0, rb.brg, &m4, &s4);

   Memo1->Lines->Add("m4 = " + IntToStr( Round(m4) ) + "  s4=" + AnsiString(s4));
   Memo1->Lines->Add("s3 - s4 = " + AnsiString( s3-s4 ));

   x4 = Round(m4); //Rounding function call

   if(( s4 - s3 ) > 1 ){//we have a negative gamma curve (G<10)
      Memo1->Lines->Add("Negative Gamma Curve");
      for( i = 9; i > 1; i-- ){
         gamma=i/10;
         for( d = 0; d < 256; d++ ){
            DArray[d] = ( pow( (double)(d * 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
                  value = (((( DArray[x4] / 65535 ) - 0.5) * cntrst) + 0.5) * 65535;
                  value = value += bright;
                  value *= level;
                  if( value > 65535){ value = 65535; }
                  if( value < 0 ){ value = 0; }
		            if( (WORD) value == GammaArray[0][x4] ){
                     for( d = 0; d < 256; d++ ){
                        value = ((( (DArray[d] / 65535) - 0.5) * cntrst) + 0.5) * 65535;
                        value = value += bright;
                        value *= level;
                        if( value > 65535 ){ value = 65535;}
                        if( value < 0 ){ value = 0;}
                        CompArray[d] = (WORD) value;
                     }
                     if(memcmp( &CompArray[0], &GammaArray[0][0], 2*256) == 0){
                        goto ENDIT;
                     }
                  }
               }
            }
         }
      }
   }else if((s3-s4)>1){//we have a positive gamma curve(G>10)
      Memo1->Lines->Add("Positive Gamma Curve");
      for( i = 11; i < 51; i++ ){
         gamma=i/10;
         for( d = 0; d < 256; d++ ){
            DArray[d] = ( pow( (double)(d * 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
                  value = (((( DArray[x4] / 65535 ) - 0.5) * cntrst) + 0.5) * 65535;
                  value = value += bright;
                  value *= level;
                  if( value > 65535){ value = 65535; }
                  if( value < 0 ){ value = 0; }
		            if( (WORD) value == GammaArray[0][x4] ){
                     for( d = 0; d < 256; d++ ){
                        value = ((( (DArray[d] / 65535) - 0.5) * cntrst) + 0.5) * 65535;
                        value = value += bright;
                        value *= level;
                        if( value > 65535 ){ value = 65535;}
                        if( value < 0 ){ value = 0;}
                        CompArray[d] = (WORD) value;
                     }
                     if(memcmp( &CompArray[0], &GammaArray[0][0], 2*256) == 0){
                        goto ENDIT;
                     }
                  }
               }
            }
         }
      }

   }else{//no gamma curve (G=10)
      Memo1->Lines->Add("No Gamma Curve");
      i=10;
      gamma=1;  //same as 10 / 10
      for( d = 0; d < 256; d++ ){
         DArray[d] = ( pow( (double)(d * 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
               value = (((( DArray[x4] / 65535 ) - 0.5) * cntrst) + 0.5) * 65535;
               value = value += bright;
               value *= level;
               if( value > 65535){ value = 65535; }
               if( value < 0 ){ value = 0; }
		            if( (WORD) value == GammaArray[0][x4] ){
                  for( d = 0; d < 256; d++ ){
                     value = ((( (DArray[d] / 65535) - 0.5) * cntrst) + 0.5) * 65535;
                     value = value += bright;
                     value *= level;
                     if( value > 65535 ){ value = 65535;}
                     if( value < 0 ){ value = 0;}
                     CompArray[d] = (WORD)value;
                  }
                  if(memcmp( &CompArray[0], &GammaArray[0][0], 2*256) == 0){
                     goto ENDIT;
                  }
               }
            }
         }
      }
   }

   Memo1->Lines->Add("Values NOT Discovered - Checking All Values...");

   //if for any reason we did not find a match, reiterate through
   //all possible gamma settings...

   for(i=2;i<51;i++){
      gamma=i/10;
      for( d = 0; d < 256; d++ ){
         DArray[d] = ( pow( (double)(d * 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
               value = (((( DArray[x4] / 65535 ) - 0.5) * cntrst) + 0.5) * 65535;
               value = value += bright;
               value *= level;
               if( value > 65535){ value = 65535; }
               if( value < 0 ){ value = 0; }
		            if( (WORD) value == GammaArray[0][x4] ){
                  for( d = 0; d < 256; d++ ){
                     value = ((( (DArray[d] / 65535) - 0.5) * cntrst) + 0.5) * 65535;
                     value = value += bright;
                     value *= level;
                     if( value > 65535 ){ value = 65535;}
                     if( value < 0 ){ value = 0;}
                     CompArray[d] = (WORD) value;
                  }
                  if(memcmp( &CompArray[0], &GammaArray[0][0], 2*256) == 0){
                     goto ENDIT;
                  }
               }
            }
         }
      }
   }

   Memo1->Lines->Add("Values Still NOT Discovered!!!");
   Memo1->Lines->Add("Discovery Operation Failed.");
   return;

   ENDIT:

   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));
}
//---------------------------------------------------------------------------
short __fastcall TForm1::Round(double flt){
   short num=(short)flt;
   if(flt>=0){
      if(flt-num>=.5){num++;}
   }else{
      if(flt-num<=-.5){num--;}
   }
   return(num);
}
//----------------------------------------------------------------------------
bool __fastcall TForm1::PtToPtRngBrg(RngBrg *rb,double x1,double y1,double x2,double y2){//was PixToPixRngBrg
   rb->rng=0;rb->brg=0;
   //range is in pixels
   double diffx,diffy,dangle;
   if(x1>=x2){
      if(x1>=0&&x2<0){diffx=x1+fabs(x2);}else{diffx=x1-x2;}
   }else{
      if(x2>=0&&x1<0){diffx=x2+fabs(x1);}else{diffx=x2-x1;}
   }
   if(y1>=y2){
      if(y1>=0&&y2<0){diffy=y1+fabs(y2);}else{diffy=y1-y2;}
   }else{
      if(y2>=0&&y1<0){diffy=y2+fabs(y1);}else{diffy=y2-y1;}
   }

   if(diffx==0){
      rb->brg=0;rb->rng=y2-y1;
      return true;
   }
   if(diffy==0){
      rb->brg=90;rb->rng=x2-x1;
      return true;
   }
   dangle=atan(diffy/diffx);
   rb->rng=diffx/cos(dangle);//hyp
   dangle=dangle/DEG_RAD;
   rb->brg=90-dangle;
   return true;
}
//-----------------------------------------------------------------------
void __fastcall TForm1::GetPtFromPt(double x, double y,double rng,double brg,double *x2,double *y2){
   //Gets a pix(coord) from a pix (coord)
   //range is in absolute pixels
   if(brg>=360){brg-=360;}
   if(brg<0){brg+=360;}
   if(brg==360||brg==0){*x2=x;*y2=y+rng;return;}
   if(brg==270){*y2=y;*x2=x-rng;return;}
   if(brg==90){*y2=y;*x2=x+rng;return;}
   if(brg==180){*x2=x;*y2=y-rng;return;}

   if(brg<90){
      *x2=x+(rng*cos((90-brg)*DEG_RAD));
      *y2=y+(rng*sin((90-brg)*DEG_RAD));
      return;
   }
}
//---------------------------------------------------------------------------

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 
GeneralRe: Printer Control Pin
Jochen Arndt28-Aug-16 21:38
professionalJochen Arndt28-Aug-16 21:38 
GeneralRe: Printer Control Pin
Richard MacCutchan28-Aug-16 22:03
mveRichard MacCutchan28-Aug-16 22:03 
GeneralRe: Printer Control Pin
Jochen Arndt28-Aug-16 22:09
professionalJochen Arndt28-Aug-16 22:09 
GeneralRe: Printer Control Pin
Richard MacCutchan28-Aug-16 22:19
mveRichard MacCutchan28-Aug-16 22:19 
GeneralRe: Printer Control Pin
Bram van Kampen1-Sep-16 13:37
MemberBram van Kampen1-Sep-16 13:37 
GeneralRe: Printer Control Pin
Richard MacCutchan1-Sep-16 23:37
mveRichard MacCutchan1-Sep-16 23:37 
GeneralRe: Printer Control Pin
Bram van Kampen4-Sep-16 15:24
MemberBram van Kampen4-Sep-16 15:24 
GeneralRe: Printer Control Pin
Bram van Kampen4-Sep-16 15:30
MemberBram van Kampen4-Sep-16 15:30 
GeneralRe: Printer Control Pin
Richard MacCutchan4-Sep-16 21:39
mveRichard MacCutchan4-Sep-16 21:39 
GeneralRe: Printer Control Pin
Bram van Kampen6-Sep-16 16:03
MemberBram van Kampen6-Sep-16 16:03 
GeneralRe: Printer Control Pin
Richard MacCutchan6-Sep-16 21:35
mveRichard MacCutchan6-Sep-16 21:35 
GeneralRe: Printer Control Pin
Bram van Kampen8-Sep-16 14:18
MemberBram van Kampen8-Sep-16 14:18 
GeneralRe: Printer Control Pin
Richard MacCutchan8-Sep-16 22:37
mveRichard MacCutchan8-Sep-16 22:37 

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.