|
I think struct is creatin a problem.
try doing it by using union inside a struct.
i think it will work.
tHeStRat
|
|
|
|
|
WalderMort wrote: This is what I currently have, but it's size is still 1 byte even though only 4 bits are being used.
I believe the minimum size of your structure is the size of the base type, in this case BYTE.
|
|
|
|
|
|
Funny you say that, I was just playing around with the bitfields and found my solution. Though I'm not sure of how portable it may be.
struct block
{
union
{
struct Upper
{
BYTE Pack : 4;
BYTE State : 3;
BYTE Repaint : 1;
};
struct Lower
{
BYTE State : 3;
BYTE Repaint : 1;
};
BYTE Total;
} U;
};
Waldermort
|
|
|
|
|
Original struct
<br />
struct aablock<br />
{<br />
BYTE Flag : 1; <br />
BYTE State : 3;<br />
};<br />
Original array of size 512
<br />
MAXSIZE = 512<br />
aablock aa[MAXSIZE];<br />
Modified Struct
<br />
struct bbblock<br />
{<br />
BYTE FlagOdd : 1; <br />
BYTE StateOdd : 3;<br />
BYTE FlagEven : 1; <br />
BYTE StateEven : 3;<br />
};<br />
<br />
try to suffle the elements if size of this struct > sizeof(BYTE)<br />
if you are having an array of size say 512 then you may declare array with half of that size.
Each element will store 2 elements of original struct
<br />
bbblock bb[MAXSIZE/2];<br />
<br />
j = -1;<br />
for(i = 0; i < MAXSIZE/2; ++i)<br />
{<br />
j++
bb[i].FlagEven = aa[j].Flag;<br />
bb[i].StateEven = aa[j].State;<br />
j++;
bb[i].FlagOdd = aa[j].Flag;<br />
bb[i].StateOdd = aa[j].State;<br />
}<br />
|
|
|
|
|
Good Ans....
But i have some confusion.
In That code what is the meaning of This
BYTE Flag : 1;
Line.
How we can use one bit from that Byte?
i got the error on that each line..
Please solve my doubt.
hiren Thakkar
|
|
|
|
|
If you read the other answers, you'll see someone refers to bitfields. That's the important clue - you can look that up in your c++ book, as the full answer is too long for me to bother typing here!
Iain.
|
|
|
|
|
Hi,
We are getting ready to start developing a new windows application interface for our research application. The current version was written in MFC (Dialog box version) where there is a main dialog box which covers the whole screen and then several small dialog boxes are defined in it each one performing certain action and currently everything runs in serialized fashion. With this application we are getting closed loop frequencies of not more than 3Hz. For the next generation application we are intending to improve this atleast to 15Hz by implementing multi threading environment.
Here is how the program flow goes in current application.. you capture an image (at certain exposure settings, the longer the exposure time, the more delay you have in capturing the image) and is shown on one of the dialog boxes (say dailog1), do some analysis on that image and comeup with some data that should be shows in graphical format on the image in dialog1 and then using the same data and doing some more calculations you have to draw some graphics on three more dialog boxes and then compute the resultant data that is to be fed to the system and update another graphical dialog box to reflect the final result. At the end update some parameters(values) on the main dialog box.
Before you capture next image for next iteration, you should be done by sending the new values calculated in previous iteration. Currently, this goes one after the other (including graphic dialog boxes update). As far as I can see, updating these graphic dialog boxes is taking lots of time compared to actual data computation.
I am looking forward for some better ideas on implementing this to higher speeds.
thanks in advance.
|
|
|
|
|
Pavan Berkeley wrote: updating these graphic dialog boxes is taking lots of time compared to actual data computation
Screen drawing on modern PCs should be pretty fast.
Are you sure the bottleneck isn't somewhere else?
What exposure time is typical?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
I think I am sure... but anyway here are the timings that I measured while running the closed loop..
Camera function started 40:48:961.054
Camera function done 40:49:4.228 >> ~43msec (for capturing the image at 20msec exposure time, subtracting the background)
Calculations done 40:49:17.848 (entire calculations are done by this point ~13msec)
Updated displays 40:49:259.003 (entire displays are updated by this point ~242msec)
one iteration completed
Here are the timings that I recorded from the current application. From the above, we cant get rid of 20msec delay from camera (which sometimes changes to even more, but 20msec is the min). This comes out to be 3.37Hz which is very slow comparatively.
PKNT
|
|
|
|
|
Focusing on the display updates, then, what kind of (and how many) operations
are you doing?
Drawing bitmaps? Graphs? Using GDI? GDI+?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
The way its implemented currently is just using SetPixel, so its GDI. This is done for 5 dialog windows (including drawing over camera image) after each iteration of calculation. Among these 5 dilaog boxes, two graphical dialog boxes are being updated in the main dialog box file.
PKNT
|
|
|
|
|
Kiran Satish wrote: ...just using SetPixel...
ouch!
I don't know the format of the data you need to display, but I bet you can
shave 100-200 ms off your display time.
If the data is in a bitmap form (rows and columns of pixels) then I would start
with using a DIBSection(). This gives you a DIB that you can select into a
device context AND you have a pointer to the pixel bits. You can directly
set pixels in memory, probably way faster than SetPixel().
The DIBSection can remain selected into a memory DC.
Then you can blt the entire bitmap to the screen in one shot.
What format is the pixel data in? Dimensions, bits-per-pixel, etc.??
Does this sound like something you can benefit from?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Yeh, sure DIBSection will be definitely faster than drawing pixel by pixel. But the problem is I am not sure how to convert the data that I use into usable format for this function. I will do some research and some testing to see if I can somehow change or redefine the data to go in this way. Anyway here is how the function is implemented for repainting one of the dialog boxes..
void ResImageDlg::color_AllBoxes(CWnd *ResDisp)<br />
{<br />
double resval;<br />
int i,j,x,y;<br />
RECT ResRect;<br />
COLORREF color;<br />
<br />
CDC *ResCDC = ResDisp->GetDC();<br />
for(i=0; i < GRID; i++)
{<br />
for(j=0; j < GRID; j++)<br />
{<br />
if( (j == 0 || j == (GRID-1)) && (i == 0 || i == (GRID-1)) )<br />
;
else<br />
{<br />
resval = (parent->calcfile)->FetchResData(i,j); <br />
ResRect.left = X_OFFSET + (i*(RES_BOX_SIZE+BOX_GAP));<br />
ResRect.right = ResRect.left + RES_BOX_SIZE;<br />
ResRect.top = Y_OFFSET + (j*(RES_BOX_SIZE+BOX_GAP));<br />
ResRect.bottom = ResRect.top + RES_BOX_SIZE;<br />
color = check_ColorLimits(resval); <br />
for(x=ResRect.left; x < ResRect.right; x++)<br />
for(y=ResRect.top; y < ResRect.bottom; y++)<br />
ResCDC->SetPixelV(x,y,color);<br />
}<br />
}<br />
}<br />
ResDisp->ReleaseDC(ResCDC);<br />
}
The actual data is nothing but some real numbers between 0 and 2.0; two other dialog boxes are also drawn in the same fashion, but since they are 8bit graphic type, the data is scaled to be in between 0 and 255 and uses SetPixelV to draw that pixel.
Hope I am not confusing...
PKNT
|
|
|
|
|
I can't read your code for the loops - can you modify your post so
HTML tags are ignored?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
what about the SetPixel loop?
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Heh cool, thanks
You can optimize this alot.
Move any code that calculates rects, positions, etc. to a more appropriate
place - the place where it changes (e.g. WM_SIZE). Usually that stuff stays the
same between draws so there's no reason to recalculate it every time you draw.
Same goes for any variables that don't change or don't change often.
Change the SetPixel loop to write directly to the pixel memory of a DIBSection.
SetPixel has to calculate the width of the destination bitmap(DC) in bytes and
calculate the offset in the destination pixel memory every time you call it.
In your own loop, most of this can be calculated once and you can increment your
way through the pixel data.
I'm still not clear on your data format...how do the 8-bit values relate to an RGB color?
Is it grayscale?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Mark Salsbery wrote: I'm still not clear on your data format...how do the 8-bit values relate to an RGB color?
Is it grayscale?
Yes, among 5 graphic dialog boxes two are grayscale while other 3 are color. The loop that I have shown you above is of a color graphic dialog box. Even for grayscale values, they use the same 8bit value (that they calculate according to the data value) for all three channels of RGB.
PKNT
|
|
|
|
|
The grayscale will be way faster if you stop using SetPixel().
And what about the color....is that 8-bit too? If so, how do you map 8-bit to RGB?
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
For color values, its not 8 bits. RGB value is calculated using the following function.
<br />
double mid = get_MidVal();
double max = get_MaxVal() - mid;<br />
double min = get_MinVal() - mid;<br />
val -= mid;
int blueval=0;<br />
int redval=(int)(MID_RGB_VALUE + ((val/max)*MID_RGB_VALUE));<br />
int greenval=(int)(MID_RGB_VALUE - ((val/max)*MID_RGB_VALUE));<br />
if ((val <= min)||(val >= max)) <br />
{redval=255;blueval=255;greenval=0;}<br />
<br />
return RGB(redval,greenval,blueval);
then that RGB value is used to color all the pixels in that particular box of the loop in earlier post.
PKNT
|
|
|
|
|
Well that's cool....you have RGB covered for two data types. What did you need SetPixelV for then?
SetPixelV would be your slowest API call.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Honestly, I donnno why they used it. Its written like 4 years ago by two people and they are not here now .
Will see wht I can do to modify this using DIBSection. I haven't used it in any of my applications till now, so have to do some research/reading on it and also the way to implement in my case.
thanks for all your help, I really appreciate it.
PKNT
|
|
|
|
|
Kiran Satish wrote: so have to do some research/reading on it and also the way to implement in my case.
Hopefully this will help a bit...
<code>
LONG DIBSecWidth = ...;
LONG DIBSecHeight = ...;
LONG BitsPerPixel = 24;
LONG Stride = ((DIBSecWidth * BitsPerPixel + 31L) & (~31L)) / 8L;
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(BITMAPINFO));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = DIBSecWidth;
bmi.bmiHeader.biHeight = DIBSecHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = (WORD)BitsPerPixel;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = Stride * abs(DIBSecHeight);
BYTE *pDIBSectionBits;
HBITMAP hbm = ::CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void**)&pDIBSectionBits, NULL, 0);
<code>
int x = ...;
int y = ...;
RGBTRIPLE *pPixel = (RGBTRIPLE *)(pDIBSectionBits + ((y * Stride) + (x * sizeof(RGBTRIPLE))));
<code>
pPixel[0].rgbtBlue = 0;
pPixel[0].rgbtGreen = 0;
pPixel[0].rgbtRed = 0;
<code>
RECT rect;
rect.left = 10;
rect.top = 10;
rect.right = 20;
rect.bottom = 20;
RGBTRIPLE *pCurRowPixel = (RGBTRIPLE *)(pDIBSectionBits + ((rect.top * Stride) + (rect.left * sizeof(RGBTRIPLE))));
for (int y = 0; y < rect.bottom - rect.top; ++y)
{
for (int x = 0; x < rect.right - rect.left; ++x)
{
pCurRowPixel[x].rgbtBlue = 0;
pCurRowPixel[x].rgbtGreen = 0;
pCurRowPixel[x].rgbtRed = 0;
}
pCurRowPixel = (RGBTRIPLE *)((BYTE*)pCurRowPixel + Stride);
}
You can probably optimize that stuff even further for specific implementations
but that generic code should be much faster than a SetPixel loop
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Thanks for the info, will help me in understanding it more easily. Just done with matlab, will start going thru this now.
PKNT
|
|
|
|
|
I found very little help on DIBSection while found many examples on using CBitmap class. Anyway I started off routine of my application where I color boxes in a window.
My window (with 12x12 grid) is 513x513 and the grid's horizontal and vertical offset is 20 (this would be the width of the border of the grid) and box width (each box in the grid) is 15 and box gap is 2(this would be the width of grid lines inside). These are constants and they stay the same all the time.
So while creating this window object I have to do the following--
LONG DIBSecWidth = 513;
LONG DIBSecHeight = 513;
LONG BitsPerPixel = 24;
CDC *ResCDC = ResDisp->GetDC();/*ResDisp is handle of this window and ResCDC need not be changed while redrawing so I dont need to call it everytime I call the above routine.*/
LONG Stride = ((DIBSecWidth * BitsPerPixel + 31L) & (~31L)) / 8L; /**I didnt understand this step, how can I calculate this in my case*/
BITMAPINFO bmi;
memset(&bmi, 0, sizeof(BITMAPINFO));
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = DIBSecWidth;
bmi.bmiHeader.biHeight = DIBSecHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = (WORD)BitsPerPixel;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = Stride * abs(DIBSecHeight);
BYTE *pDIBSectionBits;
HBITMAP hbm = ::CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void**)&pDIBSectionBits, NULL, 0);/**I have to replace first argument NULL with my ResCDC */
From then I couldnt understand how I can find pixel address for each pixel in my application while considering box sizes and gap.
Now I have to color each box with some color, so is there any way to fill each box in memory with that same color rather going in two for loops, like using fillrect etc?? This way I can eliminate the inner two for loops in my code.
thanks,
PKNT
|
|
|
|