|
Because this is the C/C++/MFC forum. It is just a guess, anyway.
|
|
|
|
|
Okay so in C you will find references to libpng which was done for a computer book all over the internet, it is a platform-independent library that contains C functions for handling PNG images that is 20 years old. Technically the code is ANSI C (C89) which should run on most C compilers even those for micro-controllers.
It isn't bad and easily understandable. You will often find more up to date conversion of the original code
but it's more often you will run across the read implementation than the write.
The code to use the png library isn't hard as you will see
A simple libpng example program[^]
You download the png library from the pnglib homepage
libpng Home Page[^]
There are manuals and "howto" instructions and pages there.
In vino veritas
modified 19-Sep-16 13:29pm.
|
|
|
|
|
We are using the Carlos Antollini ado classes in our C/C++ program and when I try to close the database it hangs. The function never returns. I cannot figure out why. Anyone have any ideas?
m_pProjectDatabase declared as:
CADODatabase* m_pProjectDatabase;
if (m_pProjectDatabase != nullptr)
{
m_pProjectDatabase->Close();
}
This calls the ado2 function:
void CADODatabase::Close()
{
try
{
if(IsOpen())
{
if(m_doxCatalog.m_pCatalog != NULL)
{
_ConnectionPtr pConn = m_doxCatalog.m_pCatalog->GetActiveConnection();
pConn->Close();
}
}
}
catch(CString ex)
{
throw;
}
catch(_com_error &e)
{
dump_com_error(e);
}
catch(...)
{
throw (CString)"Unexplained Error in CADODatabase::Close";
}
}
and from there, nothing. Off into cyberspace never to be seen again.
|
|
|
|
|
Did you debug this CADODatabase::Close() code?
|
|
|
|
|
I have 2 vc 630 both of them the drink section is inop. I ran a motor count and it recognize the first 20 motors and not the drink section everything seem to be plugged in that I can see James
|
|
|
|
|
Sorry, we are software developers, primarily. We are not vending machine support people.
|
|
|
|
|
the muffler bearings need more walnut oil
|
|
|
|
|
I think some tickets to a seminar by Tony Robins sounds like just what your machines need.
|
|
|
|
|
Call machine support.
I think nothing can be done without physical access to the machines.
Patrice
“Everything should be made as simple as possible, but no simpler.” Albert Einstein
|
|
|
|
|
I receive an old project developing with COM and C++, this project throw much exception for the INVALID_POINTER,
I guess maybe the pointer is release, but then use this pointer.
Is there anyway to check where the memory leak and where the pointer is released?
|
|
|
|
|
Use the debugger .. you are a programmer!!!!!!!
When it breaks it will give you the pointer that is involved ... now look at all code that uses the pointer.
Also actually bother to look at any warning the compiler is spitting out.
The other thing you can have done is forgot to initialize the pointer and you are assuming it is zero.
pointer p;
pointer p = 0;
This can give the weird behaviour that in debug mode the code will work but in release mode it will crash. The reason is in debug mode the compiled code takes the time to zero all variables for you and so both codes act the same, in release mode it will not zero variables and "p" will be initialized at some garbage value.
You can generally pick this problem off by turning your warning level up to 4 on the compiler ... it will spit a warning ... "Possible use of uninitialized pointer"
In vino veritas
modified 9-Sep-16 1:12am.
|
|
|
|
|
Well, a memory leak is the opposite thing and happens when a pointer goes out of scope or is overwritten before the allocated memory was released.
What you have is a faulty lifcycle management. You can't release an object and then try to use it again. Your program must make sure that pointers are initialized before being used and also that those pointers are not forgotten or overwritten.
Begin with setting all pointers to NULL immediately after releasing the memory. This way you can at least check wether the pointer is NULL or contains a valid pointer before using it. To completely solve it, you should implement a better lifecycle management for your objects.
The language is JavaScript. that of Mordor, which I will not utter here
This is Javascript. If you put big wheels and a racing stripe on a golf cart, it's still a f***ing golf cart.
"I don't know, extraterrestrial?"
"You mean like from space?"
"No, from Canada."
If software development were a circus, we would all be the clowns.
|
|
|
|
|
Running with a memory leak detector can help?
|
|
|
|
|
According to the documentation included with this snippet I should be able to replace the placeholder function with my own.
I am not knowledgeable enough to decipher what exactly is the code trying to accomplish and how to replace it with real function.
A reference would also work, but since I have no idea what is this called I do not know what to Google for. Since this is not working code, code tags were not used.
Appreciate your help
Vaclav
/**
* SysTick hook
*
* This function is called from SysTick handler, before the default
* handler provided by Arduino.
*/
static int __false() {
// Return false
return 0;
}
int sysTickHook(void) __attribute__ ((weak, alias("__false")));
|
|
|
|
|
|
Yes, it is the last part of code implementing system timer ( ARM processor)
It is in what Arduino calls "core " code and I don';t really want to modify that code.
I just do not understand the syntax.
I read about GCC attributes, but it did not provide full answer.
What I am hoping for is some equivalent to function overload to replace the default function which does nothing and actually returns wrong value.
The return would be the easy part to fix.
|
|
|
|
|
Well
If this is found in a Cpp File,
it first of al defines a static Function, named 'false() returning an int.
Vaclav_Sal wrote: int sysTickHook(void) __attribute ((weak, alias("__false"))); Your Quoted Text has a Serious Bracket Imbalance, 'weak' and 'alias' are not CPP keywords.
I am not aware of any API called 'sysTickHook()' I think you are in the wrong forum.
Bram van Kampen
|
|
|
|
|
First lets give you what you are dealing with
Weak symbol - Wikipedia, the free encyclopedia[^]
The instructions you don't recognize are linker instructions to the compiler and will be absolutely required.
In the old days we used to have to compile units individually into ELF or OBJ files and then manually put them together, the syntax as they developed allow for automation of that process. Almost every C/C++ compiler on the market will have a way to pass instructions out to the linker and will be non standard but essential.
If you are trying to provide weak linking instructions on Visual Studio it is
__declspec(selectany)
Microsoft Visual Studio - selectany[^]
If you are trying to write portable code or ANSI compliant code you will need to refer to your special section in your compliance documentation on the use of linker instructions. I write ANSI compliant code for a number of companies and all they prefer to deal with them in different ways. Some insist you need it all in a specific implementation file and document, some will make you put it into a macro in an implementation file (with all other similar MACROS so they can easily look for conflicts).
Finally what the documentation is saying is you can provide the function
int sysTickHook(void){
}
That will be a timer tick function which is generally used to do things like update time etc. They just provide a dummy function which does nothing in case you don't need it there other code assumes you might and so they have a function call which must go somewhere.
In all normal O/S's linux, DOS, Windows they all have a kernel timertick which generally does a basic function like update the system time. They are allowing you to have the same.
In vino veritas
modified 9-Sep-16 0:59am.
|
|
|
|
|
I am not sure why all these tags , but I just want to let the forum know I found a reference.
Basically two "features" - attribute and weak / strong function declaration , in my case used by GCC.
Yet another neat way to extend K&R creation.
Thanks for all the help, I appreciate it.
<a href="http://www.valvers.com/programming/c/gcc-weak-function-attributes/">GCC Weak Function Attributes &#8211; Valvers</a>[<a href="http://www.valvers.com/programming/c/gcc-weak-function-attributes/" target="_blank" title="New Window">^</a>]
|
|
|
|
|
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){
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; int x1,x2,x3,x4,x5;
int d,n;
WORD span = 8;
bool tog = false;
TDateTime strt, end;
WORD GammaArray[3][256]; WORD CompArray[256];
HDC GammaDC = GetDC( NULL ); GetDeviceGammaRamp( GammaDC, GammaArray );
ReleaseDC( NULL, GammaDC );
strt=Now();
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 )); Memo1->Lines->Add( "x2 = " + IntToStr( x2 )); Memo1->Lines->Add( "x5 = " + IntToStr( x5 ));
for(n=0;n<=40;){ if( n < 9 ){ if( 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 = 1 + ((j - 50) / 100);
for( k = 0; k < 101; k++ ){ bright = 1 + (((k - 50) / 100) * 65535);
for( m = 0; m < 101; m++ ){ cntrst = 1 + ((m - 50) / 100);
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;
}
}
}
}
}
}
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 )); Memo1->Lines->Add( "x2 = " + IntToStr( x2 )); Memo1->Lines->Add( "x3 = " + IntToStr( x3 )); Memo1->Lines->Add( "x4 = " + IntToStr( x4 ));
BROADEN:
a1 = GammaArray[0][x1]+span; b1 = GammaArray[0][x1]-span; a2 = GammaArray[0][x2]+span;
b2 = GammaArray[0][x2]-span; a3 = GammaArray[0][x3]+span; b3 = GammaArray[0][x3]-span;
a4 = GammaArray[0][x4]+span;
b4 = GammaArray[0][x4]-span;
tog=false;
for(n=0;n<=40;){ if( n < 9 ){ if( 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)(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 = 1 + ((j - 50) / 100);
for( k = 0; k < 101; k++ ){ bright = 1 + (((k - 50) / 100) * 65535);
for( m = 0; m < 101; m++ ){ cntrst = 1 + ((m - 50) / 100);
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 ){ span += 128; goto BROADEN; }
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));
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.
|
|
|
|
|
Keith Davis wrote: the widely used CalculateRamp code Widely used by whom, and for what purpose? It also look like this is C# code not C++.
|
|
|
|
|
Yes this is C# code but I have found it on the Internet in C++ as well. The math is essentially the same either way.
This algorithm is used to adjust (or program) your graphic's card's gamma ramp with inputs for Brightness, Contrast, Level, and Gamma. It works well.
For test purposes I created a graph that plots the resulting gamma ramp. This helps me to visualize the changes made to the gamma ramp array; but I can't figure out how to work the problem from the existing gamma ramp array back to what would be the input arguments for Brightness, Contrast, Level, and Gamma.
It is simply beyond me.
|
|
|
|
|
Here is my C++ implementation of the algorythm:
void __fastcall TForm1::SetRamp(double level, double gamma, double bright, double cntrst){
HDC GammaDC=GetDC(NULL);
WORD GammaArray[3][256];
gamma /= 10;
bright = 1 + (((bright - 50) / 100) * 65535);
cntrst = 1 + ((cntrst - 50) / 100);
level = 1 + ((level - 50) / 100);
for(DWORD i=0;i<256;i++){
double value = i * 256;
value = (pow(value / 65535, 1 / gamma) * 65535) + 0.5;
value = ((((value / 65535) - 0.5) * cntrst) + 0.5) * 65535;
value = value += bright;
value *= level;
if(value>65535){value=65535;}
if(value<0){value=0;}
GammaArray[0][i]=GammaArray[1][i]=GammaArray[2][i]=(WORD)value;
}
if(!SetDeviceGammaRamp(GammaDC,GammaArray)){
Memo1->Lines->Add("SetDeviceGammaRamp Failed");
GraphIt(&GammaArray[0][0], false);
}else{
GraphIt(&GammaArray[0][0], true);
}
ReleaseDC(NULL,GammaDC);
}
|
|
|
|
|
All the gamma ramp or inv ramp does is stretch or compress the greyscale representation of the color range map.
So two simplest shapes you play with is exponential and 1-exponential graphs. A simple google of the two functions
will give you the formula and code for them. The above is an exponential hence the power function. Really you only
need the exponential form because 1-exp will give you the reverse code.
So if the above code works as you want 1 - (the exponential result) is the inverse it really is that simple as the
code result must be in the range between 0-1 you should be able to see why it inverts the graph. If you can't see
the logic google exp function and 1-exp function for the explaination.
In vino veritas
|
|
|
|
|
Hi Leon,
I understand what is going on with the Gamma Ramp. My question is really a math problem, and thus far the solution is beyond my skill level.
The algorithm previously posted works very well, and gives good control of the gamma ramp. What I don't understand concerning this algorithm is why my question has not been asked before. It seems that the first thing you would want to do is interpret the current settings from the gamma ramp array; and present the current settings to the user so that he can then begin to make adjustments by using the algorithm that I previously posted.
I'm trying to work the problem backwards from the GetDeviceGammaRamp function call to whatever input values would be required to create the current gamma ramp array: What will be the Brightness setting, what will be the Contrast setting, what will be the Level setting, and what will be the Gamma setting "going in".
The way that the input algorithm works is made ever more complex because "value" undergoes four or five operations before arriving at a final input value for each of the 256 members of the array. How to reverse this series of operations has me stumped.
Given any two of the three parts for any of these operations; it is possible to come up with the third part:
For example: any unknown part of 6=2*3 can be determine so long as any two parts are known ie: 3=6/2.
x=pow(y,z): y can be determined using y=pow(x,(1.0/z)); and z can be determined using log(x)/log(y).
The initial "value" is determined by it's place in the array, so this is known to us. Also know to us is the final value of "value" because we can extract it from the current gamma ramp array. So how would you work the problem backwards through each operation from the value of the gamma array [element] to determine each of the values for Brightness, Contrast, Level, and Gamma?
My graph visually demonstrates what is going on with the gamma ramp array. When Gamma is set to input value of 10, the curve is neutralized, and the graph presents a strait line.
When Brightness is lower than 50 the line moves in parallel from the 45 degree angle towards the lower right, and greater that 50 moves the line towards the upper left in parallel.
When Contrast is lower than 50, the graph line pivots clockwise about it's midpoint, and an input greater than 50 will pivot the line counterclockwise about its midpoint.
When Level is adjusted below 50 then the end of the graph line swings downwards while the starting point (0,0) remains stationary; and when Level is adjusted upwards the end of the graph line swings upwards while the starting point remains stationary.
When Gamma is adjusted to either side of 10; the graph line becomes a positive or negative curve.
All very interesting, but it doesn't provide me with any solutions to my problem.
At any rate, thanks for your interest and your input!
Best regards,
In Corona simul veritas
|
|
|
|
|