Wednesday, May 30, 2007

What is the difference between 'delete' and 'delete[]'?

What is the difference between 'delete' and 'delete[]'?

Whenever you allocate memory with 'new[]', you have to free the memory using 'delete[]'. When you allocate memory with 'new', then use 'delete' without the brackets. You use 'new[]' to allocate an array of values (always starting at the index 0).

int *pi = new int; // allocates a single integer
int *pi_array = new int[10]; // allocates an array of 10 integers
delete pi;
pi = 0;
delete [] pi_array;
pi_array = 0;

'delete' frees the memory allocated to a single object,
while 'delete []' frees memory allocated to an array of objects, and
ensures the correct destructors are invoked


Sample program for testing the above concept:

We can use the static variable inside the non-static member function.


#include “string.h”
#include “conio.h”


class CMyClass
{
static int ObjectCount;
public:
CMyClass() ;
~CMyClass();
};

int CMyClass::ObjectCount = 0; //static member initialisation

CMyClass::CMyClass()
{
ObjectCount++;
printf("\n CMyClass constructor: Objects :%d",ObjectCount);
}

CMyClass::~CMyClass()
{
ObjectCount--;
printf("\n CMyClass destructor: Objects :%d",ObjectCount);

}


void DeletePtrTesting()
{
CMyClass* m_pClass;

m_pClass = new CMyClass[3];


if(m_pClass)
{
delete m_pClass;
}
}


void DeleteArrayTesting()
{
CMyClass* m_pClass;

m_pClass = new CMyClass[3];


if(m_pClass)
{
delete[] m_pClass;
}
}

int main(int argc, char* argv[])
{
//DeletePtrTesting();
DeleteArrayTesting();
getch();
return 0;
}


if we called the DeletePtrTesting() fn , it deletes the pointer alone

delete m_pClass;

Result :

CMyClass constructor: Objects :1
CMyClass constructor: Objects :2
CMyClass constructor: Objects :3
CMyClass destructor: Objects :2


Only one object is deleted from memory and 2 more objects are not deleted from memory.


But if we called the DeleteArrayTesting(), it deletes as follows

delete [] m_pClass;

and observe the output …

Result :

CMyClass constructor: Objects :1
CMyClass constructor: Objects :2
CMyClass constructor: Objects :3
CMyClass destructor: Objects :2
CMyClass destructor: Objects :1
CMyClass destructor: Objects :0


All the objects are deleted from memory. So whenever we create a pointer with new[], we have to delete the memory using delete[].

Usage:

Memory allocation Memory Deallocation
new delete
new[] delete[]

Directx transform built-in classes and interfaces list

http://msdn2.microsoft.com/en-us/library/aa752194.aspx


DirectX transform filter classes and interfaces list :
----------------------------------------------------------------------
Interfaces
CDXBaseARGBPtr
CDXBaseNTo1
CDXBaseSurface
CDXBnds
CDXMMXInfo
CDXScale
CDXTWorkInfoNTo1
CDXVec
DXBASESAMPLE
DXPMSAMPLE
DXSAMPLE
ICSSFilterDispatch
IDXARGBReadPtr
IDXARGBReadWritePtr
IDXARGBSurfaceInit
IDXBaseObject
IDXBasicImage
IDXDCLock
IDXDLUTBuilder
IDXEffect
IDXGradient
IDXLookupTable
IDXLUTBuilder
IDXRawSurface
IDXSurface
IDXSurfaceFactory
IDXSurfaceInit
IDXSurfaceModifier
IDXSurfacePick
IDXTaskManager
IDXTBindHost
IDXTConvolution
IDXTransform
IDXTransformFactory
IDXTScale
IDXTScaleOutput
IHTMLDXTransform
IObjectWithBehaviorSite

Necessity of copy constructors

Exception to Rule 25
Sometimes, it is desired to let objects in a class share a data area. In such a case, it is not necessary to define a copy constructor. Instead, it is necessary to make sure that this data area is not deallocated as long as there are pointers to it.
Exception to Rule 26
No exceptions.
Example 25: Definition of a "dangerous" class not having a copy constructor
#include

class String
{
public:
String(
const char* cp = ""); // Constructor
~String(); // Destructor
// ...
private:
char*
sp;
// ...
};

String::String(const char* cp) : sp( new char[strlen(cp)] ) // Constructor
{
strcpy(sp,cp);
}
String::~String() // Destructor
{
delete sp;
}

// "Dangerous" String class
void
main()
{
String w1;
String
w2 = w1;
// WARNING: IN A BITWISE COPY OF w1::sp,
// THE DESTRUCTOR FOR W1::SP WILL BE CALLED TWICE:
// FIRST, WHEN w1 IS DESTROYED; AGAIN, WHEN w2 IS DESTROYED.
}

Example 26: "Safe" class having copy constructor and default constructor
#include

class String
{
public:
String( const char* cp = ""); // Constructor
String( const String& sp ); // Copy constructor
~String(); // Destructor
// ...
private:
char* sp;
// ...
};

String::String( const char* cp ) : sp( new char[strlen(cp)] ) // Constructor
{
strcpy(sp,cp);
}

String::String( const String& stringA ) : sp( new char[strlen(stringA.sp)] )
{
strcpy(sp,stringA.sp);
}
String::~String() // Destructor
{
delete sp;
}

// "Safe" String class
void
main()
{
String w1;
String w2 = w1; // SAFE COPY: String::String( const String& ) CALLED.
}

Never specify public or protected member data in a class

Never specify public or protected member data in a class.
------------------------------------------------------------
The use of public variables is discouraged for the following reasons:

A public variable represents a violation of one of the basic principles of object-oriented programming, namely, encapsulation of data. For example, if there is a class of the type BankAccount, in which account_balance is a public variable, the value of this variable may be changed by any user of the class. However, if the variable has been declared private, its value may be changed only by the member functions of the class. [Not completely true. If a class has a member function which returns a reference to a data member, variables may be modified. This is avoided by following Rule 29.]
An arbitrary function in a program can change public data which may lead to errors that are difficult to locate.
If public data is avoided, its internal representation may be changed without users of the class having to modify their code. A principle of class design is to maintain the stability of the public interface of the class. The implementation of a class should not be a concern for its users.
The use of protected variables in a class are not recommended, since its variables become visible to its derived classes. The names of types or variables in a base class may then not be changed since the derived classes may depend on them. If a derived class, for some reason, must access data in its base class, one solution may be to make a special protected interface in the base class, containing functions which return private data. This solution would not imply any degradation of performance if the functions are defined inline.

The use of structs is also discouraged since these only contain public data. In interfaces with other languages (such as C), it may, however, be necessary to use structs.

Exception to Rule 22
In interfaces with other languages (such as C), it may be necessary to use structs having public data.
Example 22: The correct way to encapsulate data so that future changes are possible.
This shows why member functions should be used to access data (instead of using direct references). This usage provides long term advantages, since internal data in a class may be changed without having to modify interfaces and to re-write the code which uses them.

// Original class:

class Symbol {};
class OldSymbol : public Symbol {};

class Priority
{
public:
// returns pd
int priority();

// returns symbol
class Symbol* getSymbol() const;
// ...
private:
int pd;
OldSymbol symbol;
};


// Modified class:
// The programmer has chosen to change the private data from an int
// to an enum. A user of the class `Priority' does not have to change
// any code, since the enum return-value from the member function
// priority() is automatically converted to an int.

class Symbol {};
class NewSymbol : public Symbol {};
enum Priority { low, high, urgent };

class Priority
{
public:
// Interface intact through implicit cast, returns priority_data
Priority priority();

// Interface intact, object of new subclass to symbol returned
class Symbol* getSymbol() const;
// ...

private:
Priority priority_data; // New representation/name of internal data
NewSymbol symbol;
};

Tuesday, May 29, 2007

Never return a non-const reference to member data from a public function.

Never return a non-const reference to member data from a public function.
-----------------------------------------------------------------------------
class Account
{
public:
Account( int myMoney ) : moneyAmount( myMoney ) {};
const int& getSafeMoney() const { return moneyAmount; }

int& getRiskyMoney() const { return moneyAmount; } // No!
// ...
private:
int moneyAmount;
};

Account myAcc(10); // I'm a poor lonesome programmer a long way from home

myAcc.getSafeMoney() += 1000000; // Compilation error: assignment to constant

myAcc.getRiskyMoney()
+= 1000000; // myAcc::moneyAmount = 1000010 !!

Monday, May 28, 2007

How to use class member functions as callbacks?

C++ language: How to use class member functions as callbacks?

--------------------------------------------------------------------------------

Q: How to use class member functions as callbacks?

A: The problem is that every callback function has its own prototype, which determines the parameters that gets passed from the operating system to it.

In C++ every member function has a hidden parameter - the so-called 'this' pointer which will be automatically passed to the function. C++ is able to associate a function with a particular instance of an object by means of the 'this' pointer. Member functions access member variables through the 'this' pointer...


Code:

class foo
{
public:
void func() { integer_ = 0; }

private:
int integer_;
};
If you compile this code it will be compiled as


Code:

class foo
{
public:
void func(foo* this) { this->integer_ = 0; }

private:
int integer_;
};
The operating system does not call callback functions through objects therefore it cannot handle the automatically added 'this' pointer... To get a member functions working as a callback routine you need to tell the compiler explicitly not to expect a 'this' pointer. To avoid the automatic 'this' pointer you have two possibilities:

Non-member functions
Static member functions
Non-member functions are not part of a class and therefore do not have a 'this' pointer. Static member functions do not receive a 'this' pointer either...thus, if you want to use a member function as a callback routine you need to declare it as 'static'...

Mirror Filter

I completed the OpenCV Mirror class...

But it is not good to use OpenCV instead of it we can use the Gdi+ based rotation.

So I converted the OpenCV class developement to the Gdi+ class.

Gdi+ supports the PARGB format whereas openCV doesnt support this support.

Mirror Operations and its Gdi+ equaivalent RotateFlipType :
------------------------------------------------------------------

None - RotateNoneFlipNone
MirrorX - Rotate180FlipX
MirrorY - Rotate180FlipY
MirrorXY - RotateNoneFlipXY

Sunday, May 27, 2007

C++ keywords

C++ keywords
------------------------

DataTypes :
---------------------
1.bool
2.char
3.float
4.double
5.int
6.long
7.signed
8.short
9.unsigned

10.try
11.catch
12.throw




13 switch
14.case
15. break
16.default
17. continue

18.new
19.delete

20.private
21.protected
22.public

23.struct
24.class

25.const
26.const_cast
27.dynamic_cast
28.reinterpret_cast
29.static_cast

30.explicit
31.extern

32.friend
33.enum
34.inline
35.mutable
36.namespace
37.operator
38.register
39.return
40.sizeof
41.static
42.switch
43.template
44.this
45.typedef
46.typeid
47.typename
48.union
49.using
50.virtual
51.void
52.volatile
53.__wchar_t
54. wchar_t

String Sample application

#include "iostream"
#include "conio.h"
#include "string"
using namespace std;

void StringTest()
{
string str = "Hello World";

cout<
}


int main(int argc, char* argv[])
{
StringTest();

getch();
return 0;
}

Saturday, May 26, 2007

cpp tips-2

Access variable-argument lists.
-----------------------------------------


Required header file : "stdio.h" and "stdarg.h"

#include "stdarg.h"
int average( int first, ... );




int main( void )
{

/* Call with 3 integers (-1 is used as terminator). */
printf( "Average is: %d\n", average( 2, 3, 4, -1 ) );

/* Call with 4 integers. */
printf( "Average is: %d\n", average( 5, 7, 9, 11, -1 ) );

/* Call with just -1 terminator. */
printf( "Average is: %d\n", average( -1 ) );
}


int average( int first, ... )
{
int count = 0, sum = 0, i = first;
va_list marker;

va_start( marker, first ); /* Initialize variable arguments. */
while( i != -1 )
{
sum += i;
count++;
i = va_arg( marker, int);
}
va_end( marker ); /* Reset variable arguments. */
return( sum ? (sum / count) : 0 );
}


char array pointer :
-------------------------

Is it possible to use ?

void Display(char szText[100])
{
printf("%s",szText);
}

yes, the above code is working well.
we can display the unicode characters using wcout stream like cout stream.


Is there any class or stream available for logging information in C++?

yes ... clog stream can be used for logging purpose.


Is there any c++ function available for converting ANSI to unicode and unicode to ANSI conversion ?


yes...

wcstombs()-Convert sequence of wide characters to corresponding sequence of multibyte characters.
mbstowcs()- Convert sequence of multibyte characters to corresponding sequence of wide characters.



Is there any functions to convert the unicode characters to long or double like that ?...

yes, Required headers are or .

wcstol () - converts wchar* to long
wcstod() - converts wchar* to double
wcstoul() - converts wchar* to unsigned long

Cpp tips

To Be done :
--------------------

1.make use of namespaces in C++ ( C++ filter class developement ...)

To avoid the naming conflicts.

2.Use Exception handling mechanisms in ur C++ class



1.explicit keyword :
-----------------------

namespace ExplicitTesting
{
class Stack
{
int size;

public:

//explicit keyword restricts user to pass the value to the constructor

explicit Stack(int nCount)
{
size = nCount;
}

};
}


int main(int argc, char* argv[])
{
ExplicitTesting::Stack s(10) ;

// ExplicitTesting::Stack st; //Gives error


return 0;
}


2.namespace keyword :
------------------------------

we can use the namespace in two ways;

namespace Test
{
void print()
{
printf("\n Hello world...");
}
}


the client usage1 :
-------------------------

Test::print();

the client usage 2:
-----------------------
using namespace Test;

and call the print() fn


3.Exception :
-----------------

You can specify which set of exceptions a function might throw by writing an exception specification:

void f() throw(bad_alloc); //f() may only throw bad_alloc exceptions

You can specify that a function not throw an exception by declaring an empty set of exceptions:

void f() throw(); //f() does not throw

4. For boolean operations use bool data type in C++

5.Operators for Type Conversion in C++
--------------------------------------------------

1.static_cast<>
2.dynamic_cast<>
3.const_cast<>
4.reinterpret_cast<>

static_cast<> :

This operator converts a value logically. It can be considered a creation of a temporary object that is initialized by the value that gets converted.. For example:

example for static casting :
----------------------------------
float x;
...
cout << static_cast(x); // print x as int ...
f(static_cast("hello")); // call f() for string instead of char


double f(100.10);

printf("%d",static_cast(f));


double f(100.10); is equaivalent to the double f = 100.10;

Thursday, May 24, 2007

DirectX input surface may have different size output surface

Some Times the input surface may have different size output surface.

How can we make perfectly work with any type of Output ?

Solution :

1.Copy the input surface image to the the output surface image (with input surface image width and height alone)
2. Stretch the input surface image to the output surface image

Do the following steps for stretching :

1.Read data from input Surface
2.Perform operation on raw image data
3.Set the processed data to the input Surface.
4.Using IDXTScale resize the inputSurface image and copy it to the output surface.

Blurred image problem with Bitmap and Graphics pointers

DirectX Rotation filter problem


1.Clear all the bitmaps used, Then see whether any problem occurs.


I developed C++ class for rotation with bitmap and graphics as pointer objects. if I used this class,

I got the error in the video like TV dot points in an image. In DirectShow Rotation filter,

we are using bitmap and graphics objects locallly ( bitmap and graphics as normal objects).

So I developed the C++ class for rotation with Bitmap and graphics objects without pointers.

It gives us the quality output image. So I got a point in this view...

That is if we are using pointers the image is drawing over the existing image, So it looks like a dots image like in TV.


But this problem is not available if I am not using pointers for Bitmap and Graphics object.

So How I tackle the problem...

So I track the problem where it lies...


Solution :
-------------

1. I cleared the bitmap and graphics pointer objects contents. But it gives little bit quality to the image.

But not a full fledged quality output.


2. I changed the SetCompositingMode() of an Graphics object as SourceModeCopy


m_pGraphics->SetCompositingMode(CompositingModeSourceCopy);


then it gives the quality output video...



Here if we are using the bitmap and graphics as normal objects every time, it draws the image over the graphics object...

Every time the Bitmap and Graphics object is created So it doesnt make a dot points problem in an output image.

For Graphics and Bitmap pointer objects, I set the SetCompositingMode().

m_pGraphics->SetCompositingMode(CompositingModeSourceCopy);

Wednesday, May 23, 2007

Gdiplus Error in Win32 application

always comment #define WIN32_LEAN_AND_MEAN this macro while using Gdiplus in ur application.

Gdiplus Error in Win32 application

always comment #define WIN32_LEAN_AND_MEAN this macro while using Gdiplus in ur application.

Tuesday, May 22, 2007

How to use Gdi+ effects like Brightness, RedEye reduction

VOID Example_DrawImageRM(HDC hdc)
{
Graphics graphics(hdc);
graphics.SetPageUnit(UnitInch);
Image myImage(L"Photo.jpg");

REAL srcWidth = (REAL)myImage.GetWidth();
REAL srcHeight = (REAL)myImage.GetHeight();
RectF srcRect(0.0f, 0.0f, 1.0f, 1.0f);
Matrix myMatrix(2.0f, 0.2f, 0.3f, 1.0f, 3.0f, 2.0f);

BrightnessContrastParams briConParams;
briConParams.brightnessLevel = 0;
briConParams.contrastLevel = 30;
BrightnessContrast briCon;
briCon.SetParameters(&briConParams);

// Draw the image with increased contrast and transformed to
// fill a parallelogram.
graphics.DrawImage(&myImage, &srcRect, &myMatrix, &briCon, NULL, UnitInch);
}

Radio Buttons selection Problem

Tips Only for VC++ Developers
-----------------------------------------------

read this article with patience u may wonder the things about it...

I explained each and every steps ... So Dont mistake me....( u r all genius but I am so stupid to
rememeber the things...)

Follow the steps :
-----------------------
1.Open the Visual Studio 6.0
2.Select the "MFC AppWizard Exe" option
3. Give the project name
4.Select the "Dialog based application" and click the "Finish" button.
5.Next Click on "Resources" Tab in the Source code Browse window
6.Within Resources, click on Dialog and select the program's dialog

Do the following steps in Sequence :

7. Place the "Group Box" in the dialog we can call it as GroupBox1

8.Place two option buttons(Radio1,Radio2) within this GroupBox1

9. Place another "Group Box" in the dialog we can call it as GroupBox2

10.Place two option buttons(Radio3,Radio4) within this GroupBox2

11. run the application

12.Select the radio1 button in GroupBox1.

13.Next Select radio3 button in GroupBox2.Now the radio3 button is selected but the previous selection

radio1 button is deselected...

Am I right ?

Actually in a programming scenario,

the selection of radio button in one GroupBox must not affect the selection of radio button in another groupBox.

Here it is not like that...

So we have to do some thing different...



How can we make the selection of radio button in one GroupBox must not affect the selection of radio button in another groupBox ?

Solution :

Right click the Radio1 button's properties and select the "Group" check box .
Right click the radio3 button's properties and select the "Group" check box.

At conclusion :

make sure all the controls are placed in consecutive tab order.

(select the menu Layout-->Tab Order (Ctrl+D) )

For the 1st radio button, make sure the "Group" flag is set true (WS_GROUP, but you can do it in the resource editor.)
(select the "Group" check box of the first radio button).
Make sure the rest of the radio buttons have the "Group" flag set false.(unchecked status of "Group" check box of the first radio button).
The "Group" flag tells Windows that this control is the 1st control in a group.




( we may check it by opening the .rc file in a notepad )


Note :- But if u are selecting the "Group" check box of all the radio properties .
See the result.



PostScript :
I faced this problem during developement and finally got a solution for this problem... thanks for ur patience.Sorry for my bad tanglish..

Motion Detection using OpenCV

// MotionDetection.cpp : Defines the entry point for the console application.
//


// Contourold.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"

#include "iostream"
#include "stdlib.h"

// OpenCV includes.
#include "cv.h"
#include "highgui.h"
#pragma comment(lib,"cv.lib")
#pragma comment(lib,"cxcore.lib")
#pragma comment(lib,"highgui.lib")

using namespace std;

int main(int argc, char* argv[])
{

//Create a new window.
cvNamedWindow("My Window", CV_WINDOW_AUTOSIZE);

//Create a new movie capture object.
CvCapture *input;

//Assign the movie to capture.
//inputMovie = cvCaptureFromAVI("vinoth.avi");

char *fileName = "D:\\highway.avi";
//char *fileName = "D:\\Profile\\AVI\\cardriving.wmv";
input = cvCaptureFromFile(fileName);
if (!input)
{
cout << "Can't open file" << fileName < }


//Size of the image.
CvSize imgSize;
imgSize.width = 352;
imgSize.height = 240;

//Images to use in the program.
IplImage* greyImage = cvCreateImage( imgSize, IPL_DEPTH_8U, 1);
IplImage* colourImage;
IplImage* movingAverage = cvCreateImage( imgSize, IPL_DEPTH_32F, 3);
IplImage* difference;
IplImage* temp;
IplImage* motionHistory = cvCreateImage( imgSize, IPL_DEPTH_8U, 3);

//Rectangle to use to put around the people.
CvRect bndRect = cvRect(0,0,0,0);

//Points for the edges of the rectangle.
CvPoint pt1, pt2;

//Create a font object.
CvFont font;


//Create video to output to.
char* outFilename = argc==2 ? argv[1] : "D:\\outputMovie.avi";
CvVideoWriter* outputMovie = cvCreateVideoWriter(outFilename,
CV_FOURCC('F', 'L', 'V', 'I'), 29.97, cvSize(720, 576));

//Capture the movie frame by frame.
int prevX = 0;
int numPeople = 0;

//Buffer to save the number of people when converting the integer
//to a string.
char wow[65];

//The midpoint X position of the rectangle surrounding the moving objects.
int avgX = 0;

//Indicates whether this is the first time in the loop of frames.
bool first = true;

//Indicates the contour which was closest to the left boundary before the object
//entered the region between the buildings.
int closestToLeft = 0;
//Same as above, but for the right.
int closestToRight = 320;

//Keep processing frames...
for(;;)
{
//Get a frame from the input video.
colourImage = cvQueryFrame(input);

//If there are no more frames, jump out of the for.
if( !colourImage )
{
break;
}

//If this is the first time, initialize the images.
if(first)
{
difference = cvCloneImage(colourImage);
temp = cvCloneImage(colourImage);
cvConvertScale(colourImage, movingAverage, 1.0, 0.0);
first = false;
}
//else, make a running average of the motion.
else
{
cvRunningAvg(colourImage, movingAverage, 0.020, NULL);
}

//Convert the scale of the moving average.
cvConvertScale(movingAverage,temp, 1.0, 0.0);

//Minus the current frame from the moving average.
cvAbsDiff(colourImage,temp,difference);

//Convert the image to grayscale.
cvCvtColor(difference,greyImage,CV_RGB2GRAY);

//Convert the image to black and white.
cvThreshold(greyImage, greyImage, 70, 255, CV_THRESH_BINARY);

//Dilate and erode to get people blobs
cvDilate(greyImage, greyImage, 0, 18);
cvErode(greyImage, greyImage, 0, 10);

//Find the contours of the moving images in the frame.
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* contour = 0;
cvFindContours( greyImage, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );

//Process each moving contour in the current frame...
for( ; contour != 0; contour = contour->h_next )
{
//Get a bounding rectangle around the moving object.
bndRect = cvBoundingRect(contour, 0);

pt1.x = bndRect.x;
pt1.y = bndRect.y;
pt2.x = bndRect.x + bndRect.width;
pt2.y = bndRect.y + bndRect.height;

//Get an average X position of the moving contour.
avgX = (pt1.x + pt2.x) / 2;

//If the contour is within the edges of the building...
if(avgX > 90 && avgX < 250)
{
//If the the previous contour was within 2 of the left boundary...
if(closestToLeft >= 88 && closestToLeft <= 90)
{
//If the current X position is greater than the previous...
if(avgX > prevX)
{
//Increase the number of people.
numPeople++;

//Reset the closest object to the left indicator.
closestToLeft = 0;
}
}
//else if the previous contour was within 2 of the right boundary...
else if(closestToRight >= 250 && closestToRight <= 252)
{
//If the current X position is less than the previous...
if(avgX < prevX)
{
//Increase the number of people.
numPeople++;

//Reset the closest object to the right counter.
closestToRight = 320;
}
}

//Draw the bounding rectangle around the moving object.
cvRectangle(colourImage, pt1, pt2, CV_RGB(255,0,0), 1);
}

//If the current object is closer to the left boundary but still not across
//it, then change the closest to the left counter to this value.
if(avgX > closestToLeft && avgX <= 90)
{
closestToLeft = avgX;
}

//If the current object is closer to the right boundary but still not across
//it, then change the closest to the right counter to this value.
if(avgX < closestToRight && avgX >= 250)
{
closestToRight = avgX;
}

//Save the current X value to use as the previous in the next iteration.
prevX = avgX;
}


//Write the number of people counted at the top of the output frame.
cvInitFont(&font, CV_FONT_HERSHEY_SIMPLEX, 0.8, 0.8, 0, 2);
cvPutText(colourImage, _itoa(numPeople, wow, 10), cvPoint(60, 200), &font, cvScalar(0, 0, 300));

//Show the frame.
cvShowImage("My Window", colourImage);

//Wait for the user to see it.
cvWaitKey(10);

//Write the frame to the output movie.
cvWriteFrame(outputMovie, colourImage);
}

// Destroy the image, movies, and window.
cvReleaseImage(&temp);
cvReleaseImage(&difference);
cvReleaseImage(&greyImage);
cvReleaseImage(&movingAverage);
cvDestroyWindow("My Window");

cvReleaseCapture(&input);
cvReleaseVideoWriter(&outputMovie);


return 0;

}

Motion detection can be done through this program. this code contains the code for writing the motion detected video to the output file.

Here they hardcoded the values for detecting the people in the video.

we need to remove the code like AvgX,closestToLeft and closestToRight like these ...

it is an enough thing to use the draw the rectangle on all the moving objects.

How to use Memory DC with gdi+

Memory DC

Sample code...

HDC hSrcDC = GetDC(0);

HDC hMemDC = CreateCompatibleDC(hSrcDC);

Graphics graphics(hMemDC);

graphics.DrawLine(10,10,100,100);

BitBlt(hSrcDC,0,0,100,100,hMemDC,0,0,SRCCPY);

and then Do the bitBlt op to the source...

Friday, May 18, 2007

Codec

Codec

Codec stands for Coder/Decoder. Basically it is a piece of software or a driver that adds a support for certain video/audio format for your operating system. With codec, your system recognizes the format the codec is built for and allows you to play the audio/video file (=decode) or in some cases, to change another audio/video file into that format (=(en)code).

For example, when you install Windows to your home computer, Windows installs automatically bunch of most commonly used codec into the system, so you don't have to download them separately from their vendors. Despite that, there are some codecs that are widely used, but not installed automatically by Windows-- most notably DivX, MPEG-2 and in some cases (old Windows versions, like Win95) MPEG-1 codecs.

A listing of codecs follows:

Audio codecs

Non-compression formats

* AIFF - Audio Interchange File Format
* Resource Interchange File Format (RIFF)
o WAV - Microsoft "wave" format (format supports compression, but it is rarely
used)

Lossless data compression

* Apple Lossless
* Audio Lossless Coding (MPEG-4 ALS)
* Direct Stream Transfer (DST)
* Free Lossless Audio Codec (FLAC)
* LA (Lossless Audio)
* Lossless Predictive Audio Compression (LPAC)
* Lossless Transform Audio Compression (LTAC)
* Meridian Lossless Packing (MLP)
* Monkey's Audio (APE)
* OptimFROG
* RealAudio Loseless
* RKAU (RK Audio)
* Shorten (SHN)
* True Audio free lossless codec (TTA)
* WavPack
* Windows Media Audio 9 Lossless

Lossy data compression

* General (medium to high bit rate)
o A/52 or AC-3 AC-3 or Dolby Digital A/52
o ADPCM
o AAC Advanced Audio Coding (MPEG-2 and MPEG-4)
o ADX
o ARDOR (Adaptive Rate-Distortion Optimised sound codeR)
o ATRAC Adaptive TRansform Acoustic Coding (Used in MiniDisc devices)
o DTS (DTS Coherent Acoustics)
o FORtune[1]
o MP1 (MPEG audio layer-1)
o MP2 (MPEG audio
layer-2) Layer 2 audio codec (MPEG-1, MPEG-2 and non-ISO MPEG-2.5)
o MP3 (MPEG audio layer-3) Layer 3 audio codec (MPEG-1, MPEG-2 and non-ISO
MPEG-2.5)
o Musepack
o Ogg - container format (much like AVI) - best known as a Vorbis audio container (below).
o Perceptual Audio Coding
o TwinVQ
o Vorbis
o WMA (WindowsMedia Audio)

* Voice (low bit rate, optimized for speech)
o AMR
o AMBE
o CELP
o DSS
o EVRC
o G.711 (a-law and mu-law/u-law)
o G.722.1
o G.722
o G.723.1
o G.723 (Superceded by G.726)
o G.726 (ADPCM)
o G.728 (LD-CELP)
o G.729 (CS-ACELP)
o G.729a
o GSM
o HILN (MPEG-4 Parametric audio coding)
o iLBC
o IMBE
o QCELP
o SMV
o Speex, patent free
o VSELP



Text codecs

* Ogg Writ



Video codecs

AVI (Audio Video Interleave) is not a codec, rather it is a container format that many of these codec's can use.

Lossless data compression

* CorePNG
* H.264 High Profile supports lossless coding. Implemented by x264
* Huffyuv
* Lagarith
* LCL
* MSU Lossless Video Codec
* TSCC TechSmith Screen Capture Codec

Lossy data compression
* Audio Video Standard (AVS)
* Cinepak
* Dirac
* FORlive[2]
* H.261
* H.263
* H.263v2
* H.264, also known as MPEG-4 Advanced Video Coding (AVC)
o MainConcept
o Nero Digital
o QuickTime H.264
o Sorenson AVC Pro codec, Sorenson's new implementation
o Vanguard Software Solutions
o x264
* Indeo 3/4/5
* KVCD
* MJPEG
* MPEG-1 Video
* MPEG-2 Video
* MPEG-4 Advanced Simple Profile Video
o 3ivx
o DivX
o XviD
* MPEG-4 Advanced Video Coding is the same as H.264
* On2 Technologies VP3, VP6, VP7
* Pixlet
* RealVideo
* Tarkin
* Theora
* VC-1
* WindowsMedia Video
o ASF (Part of the Windows Media Series)
o WAX (Part of the Windows Media Series)

Download all the required codec in one pack only so that you can play any type of audio/video file on your pc. www.k-litecodecpack.com

GDI+ Display Text center in the Specified Rectangle _

Display the Text center in the specified rectangle :
-------------------------------------------------------------------------
we can convert this code into VC++ GDI+ code...
Rectangle rect1 = new Rectangle(10, 10, 130, 140);

// Create a StringFormat object with the each line of text, and the block
// of text centered on the page.
StringFormat stringFormat = new StringFormat();
stringFormat.Alignment = StringAlignment.Center;
stringFormat.LineAlignment = StringAlignment.Center;

// Draw the text and the surrounding rectangle.
e.Graphics.DrawString(text1, font1, Brushes.Blue, rect1, stringFormat);

Friday, May 11, 2007

Posterize Filter effect

works well for byte pixels :
-------------------------------------
#define rint(x) (floor((x)+0.5f))
unsigned char CPosterizeImp::PosterizePixel(unsigned char u_value, int iLevels )
{
double dblValue;

dblValue = (float)u_value/255.0;
dblValue = rint(dblValue * (iLevels - 1.0)) / (iLevels - 1.0);

return (unsigned char)(dblValue * 255.0);
}

Gdiplus code to load the bitmap on the specified HWND of the control

#include
using namespace Gdiplus;

ULONG_PTR gdiplusToken;
// Function LoadAnImage: accepts a file name and returns a HBITMAP.
// On error, it returns 0.
void InitGdiPlus()
{
GdiplusStartupInput gdiplusStartupInput;
gdiplusStartupInput.GdiplusVersion = 1;
// Initialize GDI+.
GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

}
void CloseGdiPlus()
{
GdiplusShutdown(gdiplusToken);
}
bool DLLDIR LoadImageOnCtrl(HWND hwnd,char* filename,char* szText)
{
WCHAR wcsFileName[MAX_PATH];
WCHAR wcsString[MAX_PATH];

RECT rect;



// Convert ANSI to WCHAR*

MultiByteToWideChar(0,0,filename,-1,wcsFileName,MAX_PATH);
MultiByteToWideChar(0,0,szText,-1,wcsString,MAX_PATH);


OutputDebugStringW(wcsFileName);
OutputDebugString("\n");
OutputDebugStringW(wcsString);



GetWindowRect(hwnd,&rect);
Gdiplus::Image* img = Gdiplus::Image::FromFile(wcsFileName);


if( img == NULL)
{
return false;
}

Graphics g(hwnd);
FontFamily fontFamily(L"Arial");
Font font(&fontFamily,8.0);
Gdiplus::PointF pointF(0, 0);
//graphics.DrawString(szPath, -1, &font, pointF, &solidBrush);
Gdiplus::SolidBrush solidBrush(Gdiplus::Color(255,0,0,0));

g.DrawImage(img,0,0,(rect.right - rect.left), (rect.bottom - rect.top));
g.DrawString(wcsString,-1,&font,pointF,&solidBrush);

return true;

}

Thursday, May 10, 2007

Only one Custom DirectX transform is working others are not working

I am implementing the sepia filter because RGB to Gray effect is already available in basic effects in DirectX transform.

Next I faced the problem in the DirectX transform filter.

I copied the Wipe transform filter and devleoped the simple DirectX transform filter. it works well.

I copied the same wipe transform filter and developed the Sepia transform filter and after the compilation, it is not working.

Even though this filter has differnt GUID in an .idl file, the first DirectX transform filter which is not working well after the compilation of the

second directX transform filter .

Solution :
The DirectX transform filter is not registered in the registry.

I just copied the DirectX transform filter.

It has ".rgs" files which is used to register the filter's Guid on the registry.

we must manually write this ".rgs" file. Depends upon the GUID of a transform filter, I changed the ".rgs" file.

Now it is working fine.

Color Progress control

Color progress bar control :
---------------------------------------------


After adding the progress bar control and add the "control" member variable to the progress bar as m_ColorProgressbar


No need for the OnCtlColor() fn.
Progress bar control supports color without OnCtlColor() fn.

class CAppDialog : public CDialog
{
public:
virtual void OnOK();
afx_msg void OnTimer(UINT nIDEvent);
};

BEGIN_MESSAGE_MAP()
ON_WM_TIMER()
END_MESSAGE_MAP()



#define PROG_TIMER 2011


void CAppDialog::OnOK()
{
m_ColorProgressbar.SetRange(0,100);
COLORREF m_BackColor = RGB(255,255,255); //white
COLORREF m_BarColor = RGB(255,140,0); //Orange
m_ColorProgressbar.SendMessage(PBM_SETBKCOLOR,0,m_BackColor);
m_ColorProgressbar.SendMessage(PBM_SETBARCOLOR,0,m_BarColor);
SetTimer(PROG_TIMER,100,NULL);
}

void CAppDialog::OnTimer(UINT nIDEvent)
{
if(nIDEvent == PROG_TIMER)
{
m_ColorProgressbar.StepIt();
}
CDialog::OnTimer(nIDEvent);
}

How do I draw a bitmap in the background of a dialog?

How do I draw a bitmap in the background of a dialog?
The trick is to override the OnEraseBkgnd handler. Here's one way of doing it:

BOOL CTestbed2Dlg::OnEraseBkgnd(CDC* pDC)
{
//if u load the bitmap in pDC using BitBlt() fn
}

change the color of an edit control

1. we can derive our own control from CEdit
2. we can change the color of an edit box using WM_CTLCOLOREDIT message


WM_CTLCOLOREDIT message code :
--------------------------------------------------------
I added the edit control to the Dialog box.

Next in the dlg.h header file, ( CDialog derived class)


I added the following code.


CEdit m_ColorEdit;

in the cpp file of the CDialog derived class add the following :

DDX_Control(pDX,IDC_EDIT1,m_ColorEdit);

(we added the member variable for the Edit control ...)


add this fn to the CDialog derived class.
afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);

and addthe message

ON_WM_CTLCOLOR() in the message map.

within OnOk() method,

I called the

HDC hdc = ::GetDC(m_ColorEdit.m_hWnd);

m_ColorEdit.SendMessage(WM_CTLCOLOREDIT, (WPARAM)hdc,
(LPARAM)m_ColorEdit.m_hWnd);


::ReleaseDC(m_ColorEdit.m_hWnd,editHdc);


within OnCtlColor() method add the following code :


HBRUSH CDialogAppDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

if( nCtlColor == CTLCOLOR_EDIT)
{

if(pWnd->GetDlgCtrlID() == IDC_EDIT1)
{
OutputDebugString("IDC_EDIT1 onCtlColor() fn");

hbr = CreateSolidBrush(RGB(255,140,0));
pDC->SetBkColor(RGB(255,140,0));
pDC->SetTextColor(RGB(255,255,255));
pDC->SetBkMode(OPAQUE);
}


}

we can do the same thing in Win32 as follows :

case WM_CTLCOLOREDIT :
HDC hdc = (HDC) wparam;
HWND hwnd = (HWND) lparam;
SetTextColor(hdc , RGB(255,255,255)); //Set the white as Text Color
SetBkColor(hdc,RGB(0,0,0)); //Set the black as background color
//return the background brush;

return bgBrush;
break;







Example for Someother things :

case WM_CTLCOLORDLG:
return (LONG)g_hbrBackground;
case WM_CTLCOLORSTATIC:
{
HDC hdcStatic = (HDC)wParam;
SetTextColor(hdcStatic, RGB(255, 255, 255));
SetBkMode(hdcStatic, TRANSPARENT);
return (LONG)g_hbrBackground;
}
break;



How can we dynamically create the brush with the specified color?

const COLORREF crefDarkGray = (RGB(128,128,128));


LOGBRUSH m_DGBrushStruct;
HBRUSH m_DGBrush;

m_DGBrushStruct.lbStyle = BS_SOLID;
m_DGBrushStruct.lbColor = crefDarkGray;
m_DGBrushStruct.lbHatch = 0;
m_DGBrush = ::CreateBrushIndirect (&m_DGBrushStruct);

within

case WM_CTLCOLOREDIT :
HDC hdc = (HDC) wparam;
HWND hwnd = (HWND) lparam;
SetTextColor(hdc , RGB(255,255,255)); //Set the white as Text Color
SetBkColor(hdc,RGB(0,0,0)); //Set the black as background color

//return the background brush;

return m_DGBrush;
break;



WM_CTLCOLOR Notification
The WM_CTLCOLOR message is used in 16-bit versions of Windows to change the color scheme of list boxes, the list boxes of combo boxes, button controls, edit controls, static controls, message boxes, and dialog boxes.

Note For information related to this message and 32-bit versions of Windows, see Remarks.



WM_CTLCOLOR
WPARAM wParam // Handle to a display context (DC).
LPARAM lParam; // Handle to a child window (control).

Return Value
If an application processes this message, it returns a handle to a brush. The system uses the brush to paint the background of the control.

Remarks
The WM_CTLCOLOR message has been replaced by more specific notifications in 32-bit versions of Windows. These replacements include the following:


WM_CTLCOLORBTN
WM_CTLCOLOREDIT
WM_CTLCOLORDLG
WM_CTLCOLORLISTBOX
WM_CTLCOLORSCROLLBAR
WM_CTLCOLORSTATIC

Some useful fns in DirectX transform

DetertmineBnds() to determine the output width and height.
DXBitBlt() fn used to copy the image.

Simple DirectX transform filter completed

I refered the AMGetErrorText() fn in DirectX transform filter.
To refer this function, we have to include
Quartz.lib and dshow.h files


00000000 8:58:52.593 AM [3244]
00000001 8:58:52.593 AM [3244] CDXTWipe::OnSetup() fn
00000002 8:58:52.593 AM [3244]
00000003 8:58:52.593 AM [3244] CDXTWipe::OnInitInstData() fn
00000004 8:58:52.593 AM [3244]
00000005 8:58:52.593 AM [3244] InputSurface(0)->GetDirectDrawSurface() failed
00000006 8:58:52.609 AM [3244] Unknown Error: 0x887a0001
00000007 8:58:52.609 AM [3244] Clip's mediatimes are invalid, or DibSeq too short, or a previous error caused this
00000008 8:58:52.609 AM [3244]

I added my filter as effect in Slomo.xtl file and put the debug string in my programme.

within my filter I get the DirectDraw surface from the IDXSurface interface.

if the filter is called by using XTLTest sample application (simply adding the filter's CLASSID in an Effect option).

The GetDirectDrawSurface() fn is failed with unknown error. so I has to change the program.

Instead of using DirectDrawSurface () directly use IDXARGBReadPtr interface to get the

surface data.


//One more thing we have to register all our filters in the registry under the category

// of CLSID_VIdeoEffects1category (for one input DirectX transform filter)

// and CLSID_VideoEffects2Category (for two input DirectX transform filter).


So I have to change it and use IDXARGBPtr for reading data from the IDXSurface.


Next to be Done :
--------------------------
1.Text overlay filter - use IDXARGBReadPtr interface.
2.Merge Filter

I found the reason for this error...
DXSurface does not have an underlying IDXSurface::GetDirectDrawSurface.
This is the case for some surfaces, such as procedural surfaces.
DirectX transform filter is made up of Procedural surfaces.



About the DC:
----------------------

IDXDCLock Interface

--------------------------------------------------------------------------------

The IDXDCLock interface is used to lock a surface and to obtain a device context (DC) that can be used with Microsoft® Windows® Graphics Device Interface (GDI) calls.

IDXDCLock Members

GetDC Retrieves the current DC.

Remarks

You can use IDXDCLock by calling the IDXSurface::LockSurface method and by specifying IID_IDXDCLock as the desired interface, or by calling the IDXSurface::LockSurfaceDC method. When the IDXDCLock interface is finally released, the underlying GDI DC is released.

IDXDCLock can be used by any transform that enables you to specify the desired output bounds.

Interface Information


I found out another way to get the DC of an IDXSurface interface :

IDXDCLock* pDCInputLock = NULL;
IDXDCLock* pDCOutputLock = NULL;
HDC hdcInput;
HDC hdcOutput;

OutputDebugString("\n CDXTWipe::WorkProc() fn");

InputSurface(0)->LockSurfaceDC(NULL,INFINITE,DXLOCKF_READ, &pDCInputLock);
OutputSurface()->LockSurfaceDC(NULL,INFINITE,DXLOCKF_READWRITE, &pDCOutputLock);

hdcInput = pDCInputLock->GetDC();
hdcOutput = pDCOutputLock->GetDC();

BitBlt(hdcOutput,0,0,m_OutputSize.cx,m_OutputSize.cy,hdcInput,0,0,SRCCOPY);
TextOut(hdcOutput,10,10,"sundar",6);

if(pDCInputLock)
{
pDCInputLock->Release();
pDCInputLock = NULL;
}
if(pDCOutputLock)
{
pDCOutputLock->Release();
pDCOutputLock = NULL;
}
return hr;


Next I used the LockSurfaceDC() fn of an IDXSurface it is also failed with error...

instead of adding text over it use RGB to Gray functionality using IDXARGBReadPtr interface.

IDXARGBReadPtr


To Be done :
--------------------
1.Add the Effect filter functionality to convert from RGB to Gray.
using IDXARGBReadWritePtr interface.




The following code simply copy the input surface to the output surface :
---------------------------------------------------------------------------------------------------

CDXDBnds srcBnds(InputSurface(),hr);

if(FAILED(hr))
{
OutputDebugString("\n failed in getting InputSurface()'s Bounds fn");
return E_FAIL;
}
CDXDBnds destBnds(OutputSurface(),hr);
if(FAILED(hr))
{
OutputDebugString("\n failed in getting OutputSurface()'s Bounds fn");
return E_FAIL;
}
hr = DXBitBlt(OutputSurface(),destBnds,InputSurface(),srcBnds,DXBOF_DO_OVER ,m_ulLockTimeOut);

return hr;


I tested the filter by simlply adding a color rectangle to my source image..

Thru XTL test it is now working...


For color rectangle, I did the following :
this will display the blue color rectangle in an image...
RECT rect;
rect.left = 0;
rect.top = 0;
rect.bottom = 50;
rect.right = 50;

hr = DXFillSurfaceRect(OutputSurface(),rect,0xff,FALSE,m_ulLockTimeOut);


I completed the testing of my filter with simple color rectangle effect and

added it with SlomoEffect.bat in XTLTest application.


So Next I will convert my Directshow baseclasses filters to Directx transform filters.

I Tested the filter with the graph.


How can we change the DirectXTransform filter's output size :

we can determine the output surface's bounds using CDXBaseNTo1::DetermineBnds() Method
if we override the base class method then we will get desired output.

we can build the merge filter in an easy manner in DirectX transform filter.


To Be done next :
--------------------------------
1. After lunch work with WMCSApp and Windows services application : - completed
2. Work with Merge filter -...
3.How can we pass two surfaces and create the output surface...

Thursday, May 03, 2007

3_May_2007

Done Today :

1.I tested the XTL play list sample in DirectShow Editing Services.
2.I added my effect in the play list But I got an error in it.

the error is as follows ;

Error 1411 (HRESULT 80070057)
Clsid of FX/Transition is not a DirectX Transform
Extra Info:{A5781BB9-E54B-11D1-9A72-0000F8756A10}

So next I have to put the debug string in all the CDXBaseNTo1 class member fns


I tested the XTL play list with the 1 in /1 out DirectX transform filters.
I added the XTL contents as follows :

XTL file contents :

I added the for the video in the source file speciified in

"





















"

DirectShow lacked the flexibility needed for nonlinear editing.

Enumerating the List of DirectX transform Effects in a system

I developed the sample application to enumerate the list of filters already available in a system.

I added tne strmiids.lib for this application.

CLSID_VideoEffects1Category - 1 input filters
CLSID_VideoEffects2Category - 2 input filters


The "Video Effects (1 input)" and "Video Effects (2 inputs)" categories contain video effects and transitions for DirectShow Editing Services.


we can search the following GUIDs in a registry.

it is in the following category
HKEY_CURRENT_USER->Software-> Microsoft ->ActiveSetup ->Active movie ->DevEnum->{CC7BFB42-F175-11D1-A392-00E0291F3959}(CLSID_VideoEffects1Category ->have the
list of filters available in a system.


#include "atlbase.h"
#include "dshow.h"
#include "conio.h"


EXTERN_GUID(CLSID_VideoEffects1Category, 0xcc7bfb42, 0xf175, 0x11d1, 0xa3, 0x92, 0x0, 0xe0, 0x29, 0x1f, 0x39, 0x59);
EXTERN_GUID(CLSID_VideoEffects2Category, 0xcc7bfb43, 0xf175, 0x11d1, 0xa3, 0x92, 0x0, 0xe0, 0x29, 0x1f, 0x39, 0x59);

/*
EXTERN_GUID(CLSID_VideoEffects1Category, 0xcc7bfb42, 0xf175, 0x11d1, 0xa3, 0x92, 0x0, 0xe0, 0x29, 0x1f, 0x39, 0x59);
EXTERN_GUID(CLSID_VideoEffects2Category, 0xcc7bfb43, 0xf175, 0x11d1, 0xa3, 0x92, 0x0, 0xe0, 0x29, 0x1f, 0x39, 0x59);
EXTERN_GUID(CLSID_AudioEffects1Category, 0xcc7bfb44, 0xf175, 0x11d1, 0xa3, 0x92, 0x0, 0xe0, 0x29, 0x1f, 0x39, 0x59);
EXTERN_GUID(CLSID_AudioEffects2Category, 0xcc7bfb45, 0xf175, 0x11d1, 0xa3, 0x92, 0x0, 0xe0, 0x29, 0x1f, 0x39, 0x59);

*/

// Enumerate all of the effects.
HRESULT EnumerateEffects(CLSID searchType)
{
// Once again, code stolen from the DX9 SDK.

// Create the System Device Enumerator.
ICreateDevEnum *pSysDevEnum = NULL;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL,
CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, (void **)&pSysDevEnum);
if (FAILED(hr))
{
return hr;
}

// Obtain a class enumerator for the effect category.
IEnumMoniker *pEnumCat = NULL;
hr = pSysDevEnum->CreateClassEnumerator(searchType, &pEnumCat, 0);

if (hr == S_OK)
{
// Enumerate the monikers.
IMoniker *pMoniker = NULL;
ULONG cFetched;
while (pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
{
// Bind the first moniker to an object.
IPropertyBag *pPropBag;
hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag,
(void **)&pPropBag);
if (SUCCEEDED(hr))
{
// To retrieve the filter's friendly name, do the following:
VARIANT varName;
VariantInit(&varName);
hr = pPropBag->Read(L"FriendlyName", &varName, 0);
if (SUCCEEDED(hr))
{
wprintf(L"Effect: %s\n", varName.bstrVal);
}
VariantClear(&varName);
pPropBag->Release();
}
pMoniker->Release();
}
pEnumCat->Release();
}
pSysDevEnum->Release();
return hr;
}

// A very simple program to list DES effects using DirectShow.
//
int main(int argc, char* argv[])
{

// Initialize the COM library.
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr))
{
// We'll send our error messages to the console.
printf("ERROR - Could not initialize COM library");
return hr;
}

// OK, so now we want to build the filter graph
// using an AudioCapture filter.
// But there are several to choose from,
// so we need to enumerate them, then pick one.
hr = EnumerateEffects(CLSID_VideoEffects1Category);

getch();
hr = EnumerateEffects(CLSID_VideoEffects2Category);
CoUninitialize();
getch();


return 0;
}

How to change the MIDL generated guid?

In an ATL project how we can change the class ID value of a particular class name ?

The class ID is defined in MIDL generated file like "wipe_i.c".But it is defn found

nowhere.

Solution :

we have to create the GUID using GUIDgen utility , copy and paste it in an ".idl" file

VC++ linker error

VC++ linker error :
----------------------------

LNK1181: cannot open input file 'C:\Program.obj'

Actually I linked the library file as follows ...


Project->Properties->Linker->Input option, I added the library file as follows

C:\Program Files\Microsoft Visual Studio\VC98\Lib\d3drm.lib.

But I got the error LNK1181: cannot open input file 'C:\Program.obj' .

The reason for this error is "Program Files" folder has blank in it...

ddraw.lib winmm.lib C:\program Files\Microsoft Visual Studio\VC98\Lib\d3drm.lib.

Blank is the separator between two libraries in an input option.

So the compiler consider it as

Program is one of the library. So in order to avoid this error I did the following :

Solution :
----------------

ddraw.lib winmm.lib "C:\Program Files\Microsoft Visual Studio\VC98\Lib\d3drm.lib"

if we specified the library file in a Double Quotation, From the starting quotation the compiler will search until the end quotation.

Wednesday, May 02, 2007

DirectX Transform Experiences

1.I tried the Flip() using the DirectX transform filter

Execute() method of a transform filter is failed..
Now I am working with this...


1.Identify whether it is possible to work with DirectX transform filter

Just copy the input surface image to the output surface image.


C:\Program Files \ IE6_LIB\
dtbase.h - these two files have the CDXBaseNTo1 class
dtbase.cpp

Any number of input image and only one output image...

Working WorkProc() fn
-----------------------------------

HRESULT CDXTWipe::WorkProc( const CDXTWorkInfoNTo1& WI, BOOL* pbContinue )
{
HRESULT hr = NOERROR;

HDC hdc1;
HDC hdc2;

OutputDebugString("\n CDXTWipe::WorkProc() fn");
hr = InputSurface(0)->GetDirectDrawSurface(IID_IDirectDrawSurface,(void**)&ppSurf);
if(ppSurf == NULL)
{
OutputDebugString("\n InputSurface(0)->GetDirectDrawSurface() failed");
return E_FAIL;
}
hr = OutputSurface()->GetDirectDrawSurface(IID_IDirectDrawSurface,(void**)&ppSurfOut);

if(ppSurfOut == NULL)
{
OutputDebugString("\n OutputSurface()->GetDirectDrawSurface() failed");
return E_FAIL;
}
// hr = ppSurfOut->Flip((LPDIRECTDRAWSURFACE)&ppSurf,DDFLIP_DONOTWAIT);



ppSurf->GetDC(&hdc1);
ppSurfOut->GetDC(&hdc2);
BitBlt(hdc2,0,0,300,300,hdc1,0,0,SRCCOPY);
TextOut(hdc2,10,10,"Sundar",6);
OutputDebugString("\n End of CDXTWipe::OnExecute() fn");

return hr;

}



we are deriving our DirectX transform filter from CDXBaseNTo1 class..


it takes n number of input images and produce only one output. IDXSurface interface wrapped the IDirectDrawSurface interface.


We can retrieve the input interface in a CDXBaseNTo1 class derived class as follows

IDirectDrawSurface* g_pSurfIn;
InputInterface(0) ->GetDirectDrawSurface(IID_IDirectDrawSurface,(void**)&g_pSurfIn);


we can retrieve the second surface interface (image) using

InputInterface(1)

OutputInterface() - used to retrieve output surface.


we can use DirectDraw or GDI mechanism to add effects to the filter....


we can query the DirectDrawSurface using the following from the IDXSurface interface.



IDirectDrawSurface* g_pSurfIn;
InputInterface(0) ->GetDirectDrawSurface(IID_IDirectDrawSurface,(void**)&g_pSurfIn);

Afterwards...

HDC hdc1;
g_pSurfIn->GetDC( &hdc1); //Get the Device context from the IDirectDrawSurface and next use the GDI functions to change the image



CDXBaseNTo1 class has Execute() fn...

Actually from the client application, we call this method for executing the transform..

this will in turn calls the


OnInitInstData()
WorkProc()
OnFreeInstData()

CDXBaseNTo1 also has the OnExecute() fn.

These three functions are virtual functions, So the derived class can change the behavior of the execution.

OnExecute() fn is not called. I wasted my time to focus on it...

But During execution, it is not called.

Execute()
{
OnInitInstData() - Init instance data
WorkProc() - This will contains the transformation code.For RGB to Gray filter
-RGB to Gray conversion is done here.

OnFreeInstData() - instance data to be released
}



How can we get the IDXSurface width and height ?


The CDXBnds template class is used to simplify construction and manipulation of the DXBNDS structure.


CDXDBnds InBounds(InputSurface(0), hr);
SIZE m_InputSize;


if (SUCCEEDED(hr))
{
InBounds.GetXYSize(m_InputSize);
}
m_InputSize has width and height of the inputSurface 0


we can identify whether the DirectDrawSurface can be flipped or not using the

GetFlipStatus() fn of the IDirectDrawSurface interface.


IDXSurface* g_pInSurfA;
IDXSurface* g_pInSurfB;




Error in IDXTransform:: Setup () fn:
------------------------------------------------------



Actually I developed the filter from the

CDXBaseNTo1 class.
In that filter

m_ulMaxInputs = 2; //These two are the members of CDXBaseNTo1 class
m_ulNumInRequired = 2;

while calling the IDXTransform interface method
Setup() fn used to pass the argument to the filter.

IUnknown* In[1];
IUnknown* Out[1];
In[0] = g_pInSurfA;
//In[1] = g_pInSurfB;
Out[0]= g_pOutSurf;
hr = g_pWipeTrans->Setup( In, 1, Out, 1, 0 );
//one input and one output


Even though I set it, the Setup() fn failed.

I changed the values as follows :

m_ulMaxInputs = 1;
m_ulNumInRequired = 1;


How can we do the DirectX transform filters :
Within DirectX transform filters we can do transform in the following ways :

1.GDI
2.GDI+
3.OpenCV
4.DirectDraw
5.Direct3D


How can we use t the the Device context from the IDXSurface ?
follow these three steps to use the device context from IDXSurface:

1.Get the DirectDraw Surface from the valid IDXSurface
2.Get the Device context from the DirectDraw Surface.
3.After processing release Device context using DirectDraw Surface.


Check this Process in the following Code :

IDirectDrawSurface* ppSurf, *ppSurfOut;
SIZE m_OutputSize;

HRESULT CDXTWipe::OnInitInstData( CDXTWorkInfoNTo1 &WorkInfo, ULONG &ulNumBandsToDo)
{
HRESULT hr = NOERROR;



//1. Get the DirectDraw Surface from the valid IDXSurface
hr = InputSurface(0)->GetDirectDrawSurface(IID_IDirectDrawSurface,(void**)&ppSurf);
if(ppSurf == NULL)
{
OutputDebugString("\n InputSurface(0)->GetDirectDrawSurface() failed");
return E_FAIL;
}
hr = OutputSurface()->GetDirectDrawSurface(IID_IDirectDrawSurface,(void**)&ppSurfOut);

if(ppSurfOut == NULL)
{
OutputDebugString("\n OutputSurface()->GetDirectDrawSurface() failed");
return E_FAIL;
}

CDXDBnds outBnds(OutputSurface(),hr); // To get the output surface's width and height

if(SUCCEEDED(hr))
{
outBnds.GetXYSize(m_OutputSize);
}

return hr;

}

HRESULT WorkProc()
{
HRESULT hr = S_OK;

//2.Get the Device Context from the DirectDrawSurface

ppSurf->GetDC(&hdcInput);
ppSurfOut->GetDC(&hdcOutput);

//Processing

BitBlt(hdcOutput,0,0,m_OutputSize.cx,m_OutputSize.cy,hdcInput,0,0,SRCCOPY);
TextOut(hdcOutput,10,10,"Sundar",6);

// 3.After processing release Device context using DirectDraw Surface.
//release DC
ppSurf->ReleaseDC(hdcInput);
ppSurfOut->ReleaseDC(hdcOutput);

return hr;

}

Tuesday, May 01, 2007

DirectX Transform Sample application

CoInitialize(NULL);
CoUnitialize();


IDXTransformFactory* g_pTransFact;
IDXSurfaceFactory* g_pSurfFact;
IDXTransform* g_pWipeTrans;

IDXSurface* g_pInSurfA;
IDXSurface* g_pInSurfB;
IDXEffect* g_pEffect;


BOOL ReadImageFile (IDXSurface **lplpDXSurf, PTSTR pstrFileName)
{
WCHAR pwcsBuffer[256] ;
HRESULT hr;
char szString[256];

#ifndef UNICODE
mbstowcs( pwcsBuffer, pstrFileName, strlen(pstrFileName)+1 );
#endif

// Load Input surfaces
hr = g_pSurfFact->LoadImage( pwcsBuffer, NULL, NULL,
&DDPF_PMARGB32, IID_IDXSurface, (void**)lplpDXSurf );

if (FAILED(hr))
{
wsprintf(szString, "Couldn't load image! hr=0x%08x", hr);
MessageBox(g_hDlg, szString, _T("Error Loading"), MB_ICONERROR );
}

return SUCCEEDED( hr );
}



//Create the transform factory

hr = CoCreateInstance( CLSID_DXTransformFactory,
NULL,
CLSCTX_INPROC,
IID_IDXTransformFactory,
(void**) &g_pTransFact );

_ASSERTE( g_pTransFact != NULL);


if(SUCCEEDED(hr))
{

//--- Get the surface factory interface
hr = g_pTransFact->QueryService( SID_SDXSurfaceFactory,
IID_IDXSurfaceFactory,
(void**) & g_pSurfFact
);

_ASSERTE ( g_pSurfFact != NULL);

}


//Create the Wipe transform and set it up...


if(SUCCEEDED(hr))
{
hr = g_pTransFact->CreateTransform( NULL,
0,
NULL,
0,
NULL,
NULL,
CLSID_DXTWipe,
IID_IDXTransform,
(void**)&g_pWipeTrans
);

_ASSERTE( g_pWipeTrans != NULL);


}

// Get the Effect interface. We'll use this to set
// execution properties for the effect (ie PercentComplete, Duration)

if( SUCCEEDED(hr))
{
hr = g_pWipeTrans ->QueryInterface( IID_IDXEffect,
(void**) &g_pEffect
);

_ASSERTE( g_pEffect != NULL);

}

int width = 400;
int height = 400;
CDXDBnds bnds;
bnds.SetXYSize( width, height);

hr = g_pSurfFact->CreateSurface( NULL,
NULL,
&DDPF_PMARGB32,
&bnds,
0,
NULL,
IID_IDXSurface,
(void**) g_pSurfFact );


ReadImageFile(g_pInSurf1,"test.png");
ReadImageFile(g_pInSurf2,"test2.png");



void HandlePlayForward()
{
float PercentComplete = 0;

do
{
g_pEffect->put_progress(PercentComplete);
PercentComplete = PercentComplete + 0.1f;
}
while( PercentComplete <= 1.0);


}