Create CBitmap object from memory - windows

I have a memory block which is merely binary data read from a .jpeg file. How can i create a CBitmap object from it?

There's no API or standard library function that deals with JPEGs. However, you may use GDI+ routuines to read the JPEG data and translate it to a bitmap, around which you would construct a CBitmap object.

Related

How to overwrite portions of a DriverKit OSData internal buffer?

The documentation of OSData says that "...You can add bytes to them and overwrite portions of the byte array.". I can see a method to append bytes, but I don't understand how I am able to overwrite a portion of the buffer.
Another option would be to use IONewZero to allocate a number of elements of the type I need. I my case I just need this for ints.
Example:
T* dataBuffer = IONewZero(T, SIZE);
And then deallocate with:
IOSafeDeleteNULL(dataBuffer_, T, SIZE);
What are the advantages of using an OSData object compared to the solution with IONewZero / IOSafeDeleteNULL?
I think the documentation might just be copy-pasted from the kernel variant of OSData. I've seen that in a bunch of places, especially USBDriverKit.
OSData is mostly useful for dealing with plist-like data structures (i.e. setting and getting properties on service objects) in conjunction with the other OSTypes: OSArray, OSDictionary, OSNumber, etc. It's also used for in-band (<= 4096 byte) "struct" arguments of user client external methods.
The only use I can see outside of those scenarios is when you absolutely have to reference-count a blob of data. But it's certainly not a particularly convenient or efficient container for data-in-progress. If you subsequently need to send the data to a device or map it to user space, IOBufferMemoryDescriptor is probably a better choice (and also reference counted) though it's even more heavyweight.

Looping and bitmaps: How do I dispose of emgu image(Of bgr, byte) when looping?

How do you dispose of bitmaps and images when in a for...next loop?
Particularly image(of bgr, byte) images.
The "image(of bgr, byte)" images are from the emgu library.
The Dispose() command works fine when you dispose of a single bitmap or image.
But when you are looping through multiple images, Outofmemory errors occur.
Even when applying the using ... end using commands, memory issues occur.
For example, this will throw memory errors for me:
Dim pic As Bitmap = New Bitmap(270, 100)
For i = 0 to 100
Dim CleanImage As New Image(Of Bgr, Byte)(pic)
'this command comes from the emgu library - tesseract
OCRz.Recognize(CleanImage)
CleanImage.Dispose()
Next
As will:
Dim pic As Bitmap = New Bitmap(270, 100)
For i = 0 to 100
Using CleanImage As New Image(Of Bgr, Byte)(pic)
OCRz.Recognize(CleanImage)
End Using
Next
I've tried GC.Collect(). This didn't work.
How do I properly rid the program of these annoying bitmaps and images?
I'm desperate for a solution.
The emgu wiki states the following:
Automatic Garbage Collection The Image class
automatically take care of the memory management and garbage
collection.
Once the garbage collector decided that there is no more reference to
the Image object, it will call the Disposed method,
which release the unmanaged IplImage structure.
The time of when garbage collector decides to dispose the image is not
guaranteed. When working with large image, it is recommend to call the
Dispose() method to explicitly release the object. Alternatively, use
the using keyword in C# to limit the scope of the image
using (Image<Gray, Single> image = new Image<Gray, Single>(1000, 800))
{
... //do something here in the image
} //The image will be disposed here and memory freed
This is exactly what I am doing. Yet, I receive this OutOfMemory exception. What is going on?

Optimized screen capture directly from device context

I've managed to get a buffer pointer from a Bitmap object as follows:
hDesktopWnd=GetDesktopWindow();
hDesktopDC=GetDC(hDesktopWnd);
// Get Screen Dimensions
int nWidth=GetSystemMetrics(SM_CXSCREEN);
int nHeight=GetSystemMetrics(SM_CYSCREEN);
CImage objCImg;
objCImg.Create( nWidth, nHeight, 24, BI_RGB);
HDC hdcMemDC = objCImg.GetDC();
if(!BitBlt(hdcMemDC,0,0,nWidth, nHeight,hDesktopDC, 0,0,SRCCOPY))
{
printf("Error during Bitblt");
}
unsigned char* pData = (unsigned char*)objCImg.GetBits();
I can modify the image using this pData.
I am trying to optimize screen capture timing, but even though this operation contains only one BitBlt, still this operation is taking 94ms on my PC. While
// Get the Desktop windows handle and device context
hDesktopWnd=GetDesktopWindow();
hDesktopDC=GetDC(hDesktopWnd);
// Get the handle to the existing DC and create a bitmap file object
HDC hBmpFileDC=CreateCompatibleDC(hDesktopDC);
HBITMAP hBmpFileBitmap=CreateCompatibleBitmap(hDesktopDC,nWidth,nHeight);
// Assign the object in Memory DC to the bitmap and perform a bitblt
SelectObject(hBmpFileDC,hBmpFileBitmap);
BitBlt(hBmpFileDC,0,0,nWidth,nHeight,hDesktopDC,0,0,SRCCOPY|CAPTUREBLT);
pBuf=malloc(bmpInfo.bmiHeader.biSizeImage); // Size of Image
GetDIBits(hdc,hBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf,&bmpInfo,DIB_RGB_COLORS);
This operation has one BitBlt and one Memory Copy operation in GetDIBits still this total operation is taking 46 ms on my PC.
Can someone please clarify this discrepancy in the two BitBlt operation and why the bitblt is taking more time when the DC is not derived as a compatible DC (CreateCompatibleDC) in the first case because as per my understanding BitBlt is almost similar to a memcpy operation.
Inturn I would also like to ask is there any way to access the image buffer pointer directly from the hdc.
which means can get buffer pointer to the image directly from the HDC
hDesktopWnd=GetDesktopWindow();
hDesktopDC=GetDC(hDesktopWnd);
// Now derive buffer from this **hDesktopDC**
I've also asked the same question before: Unable to access buffer data
Also, can someone pls comment if windows allows such type of data handling?

Create HANDLE to BITMAP

Is there any way to create HANDLE (specifically HBITMAP) to existing in memory BITMAP struct without using Device Contex(DC)?

API to get the graphics or video memory

I want to get the adpater RAM or graphics RAM which you can see in Display settings or Device manager using API. I am in C++ application.
I have tried seraching on net and as per my RnD I have come to conclusion that we can get the graphics memory info from
1. DirectX SDK structure called DXGI_ADAPTER_DESC. But what if I dont want to use DirectX API.
2. Win32_videocontroller : But this class does not always give you adapterRAM info if availability of video controller is offline. I have checked it on vista.
Is there any other way to get the graphics RAM?
There is NO way to directly get graphics RAM on windows, windows prevents you doing this as it maintains control over what is displayed.
You CAN, however, create a DirectX device. Get the back buffer surface and then lock it. After locking you can fill it with whatever you want and then unlock and call present. This is slow, though, as you have to copy the video memory back across the bus into main memory. Some cards also use "swizzled" formats that it has to un-swizzle as it copies. This adds further time to doing it and some cards will even ban you from doing it.
In general you want to avoid directly accessing the video card and letting windows/DirectX do the drawing for you. Under D3D1x Im' pretty sure you can do it via an IDXGIOutput though. It really is something to try and avoid though ...
You can write to a linear array via standard win32 (This example assumes C) but its quite involved.
First you need the linear array.
unsigned int* pBits = malloc( width * height );
Then you need to create a bitmap and select it to the DC.
HBITMAP hBitmap = ::CreateBitmap( width, height, 1, 32, NULL );
SelectObject( hDC, (HGDIOBJ)hBitmap );
You can then fill the pBits array as you please. When you've finished you can then set the bitmap's bits.
::SetBitmapBits( hBitmap, width * height * 4, (void*)pBits )
When you've finished using your bitmap don't forget to delete it (Using DeleteObject) AND free your linear array!
Edit: There is only one way to reliably get the video ram and that is to go through the DX Diag interfaces. Have a look at IDxDiagProvider and IDxDiagContainer in the DX SDK.
Win32_videocontroller is your best course to get the amount of gfx memory. That's how its done in Doom3 source.
You say "..availability of video controller is offline. I have checked it on vista." Under what circumstances would the video controller be offline?
Incidentally, you can find the Doom3 source here. The function you're looking for is called Sys_GetVideoRam and it's in a file called win_shared.cpp, although if you do a solution wide search it'll turn it up for you.
User mode threads cannot access memory regions and I/O mapped from hardware devices, including the framebuffer. Anyway, what you would want to do that? Suppose the case you can access the framebuffer directly: now you must handle a LOT of possible pixel formats in the framebuffer. You can assume a 32-bit RGBA or ARGB organization. There is the possibility of 15/16/24-bit displays (RGBA555, RGBA5551, RGBA4444, RGBA565, RGBA888...). That's if you don't want to also support the video-surface formats (overlays) such as YUV-based.
So let the display driver and/or the subjacent APIs to do that effort.
If you want to write to a display surface (which not equals exactly to framebuffer memory, altough it's conceptually almost the same) there are a lot of options. DX, Win32, or you may try the SDL library (libsdl).

Resources