I am extremely new to manipulating bitmap data in C++, and I have a problem. I'm trying to follow this example from wikipedia. Here is the code I'm using:
#include <iostream>
#include <fstream>
#include <Windows.h>
using namespace std;
int main()
{
//fileheader
BITMAPFILEHEADER* bf = new BITMAPFILEHEADER;
bf->bfType = 66;
bf->bfSize = 70;
bf->bfOffBits = 54;
//infoheader
BITMAPINFOHEADER* bi = new BITMAPINFOHEADER;
bi->biSize = 40;
bi->biWidth = 2;
bi->biHeight = 2;
bi->biPlanes = 1;
bi->biBitCount = 24;
bi->biCompression = 0;
bi->biSizeImage = 16;
bi->biXPelsPerMeter = 2835;
bi->biYPelsPerMeter = 2835;
bi->biClrUsed = 0;
bi->biClrImportant = 0;
//image data
unsigned char* thedata = new unsigned char;
thedata[0] = 0;
thedata[1] = 0;
thedata[2] = 255;
thedata[3] = 255;
thedata[4] = 255;
thedata[5] = 255;
thedata[6] = 0;
thedata[7] = 0;
thedata[8] = 255;
thedata[9] = 0;
thedata[10] = 0;
thedata[11] = 0;
thedata[12] = 255;
thedata[13] = 0;
thedata[14] = 0;
thedata[15] = 0;
//dc
HDC dc = GetDC(NULL);
//bitmap info
BITMAPINFO* bmi = (BITMAPINFO*)bi;
//handle to bitmap
HBITMAP hbmp = CreateDIBitmap(dc, bi, CBM_INIT, thedata, bmi, DIB_RGB_COLORS);
//output to bmp....?
ofstream outFile;
outFile.open("outtestbmp.bmp");
outFile << hbmp;
outFile.close();
}
I've been searching Google for the past couple days trying to figure out how to get this done but I still can't seem to make it work.
This complies without errors, but the outtestbmp.bmp file in the end is unopenable. Are there any huge mistakes I'm making (probably dozens) that are preventing this from working? (I have high suspicions that using ofstream to output my bmp data is wrong).
EDIT: I've been told that setting bftype to 66 is wrong. What is the correct value?
Also, I've created a .bmp file of what the output should be. Here is the hex data for that bmp:
42 4D 46 00 00 00 00 00 00 00 36 00 00 00 28 00 00 00 02 00 00 00 02 00 00 00 01 00 18
00 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF
FF FF 00 00 FF 00 00 00 FF 00 00 00
and here is the data for my .bmp I'm outputting:
42 00 46 00 00 00 CD CD CD CD 36 00 00 00 28 00 00 00 02 00 00 00 02 00 00 00 01 00 18
00 00 00 00 00 10 00 00 00 13 0B 00 00 13 0B 00 00 00 00 00 00 00 00 00 00 00 00 FF FF
FF FF 00 00 FF 00 00 00 FF 00 00 00
bf->bfType == 66;
This is wrong on two counts. Firstly it's the wrong value (the magic value are the bytes 'BM' or 0x4d42 on a little-endian machine), and secondly it's not an assignment.
Then:
unsigned char* thedata = new unsigned char;
Only allocating 1 char?
And this:
outFile << hbmp;
Doesn't do what you think it does. You're just writing out a handle. You didn't need to create a bitmap, you just need to write out the data structures you've initialised (once you've made them correct).
And why are you new'ing everything? There's no need for this stuff to be dynamically allocated (and you're not delete'ing it either).
I would generally do it something like this (some code removed for brevity):
BITMAPFILEHEADER bf;
bf.bfType = 0x4d42;
bf.bfSize = 70;
bf.bfOffBits = 54;
//infoheader
BITMAPINFOHEADER bi;
bi.biSize = 40;
bi.biWidth = 2;
etc...
//image data
unsigned char* thedata = new unsigned char[16]; // Should really calculate this properly
thedata[0] = 0;
....
//output to bmp....?
ofstream outFile;
outFile.open("outtestbmp.bmp");
outFile.write((char *)&bf,sizeof(bf));
outFile.write((char *)&bi,sizeof(bi));
outFile.write((char *)thedata, 16);
outFile.close();
First you don't allocate enough memory for all your pixels, it should be something along the lines of
unsigned char* thedata = new unsigned char[numPixels * bytesPerPixel];
In your case, with a 2 by 2 picture and 24 bpp (bits per pixel), you should allocate 12 bytes.
Each pixel will correspond to three bytes in a row for their red, green and blue channel.
Note: I've never used Window's bitmap creation process but I worked with many libraries to manipulate images, including FreeImage, SDL and GD
HBITMAP is a handle to a bitmap not an actual bitmap. The real bitmap is stored in Kernel memory. You don't need to make any calls to the GDI if you are just writing the bitmap to a file. Even if it was an actual bitmap cout would need an operator overload to actually write the memory structure to a file since it isn't stored in memory the same it is on disk.
All you need to do is write the BITMAPFILEHEADER to a file, then write the BITMAPINFOHEADER to the file, and then write the data (if we are talking RGB, non-indexed).
Here is more info on how bitmaps are actually stored on disk.
Bitmap Storage (MSDN)
Reading a bitmap from a file is just same.
First, you need to allocate enough data for your pixels:
unsigned char* thedata = new unsigned char[2 * 2 * 3];
Then you need to use write and open the file as binary.
Instead of:
outFile.open("outtestbmp.bmp");
outFile << hbmp;
Something like:
outFile.open("outtestbmp.bmp", ios::binary||ios::out);
outfile.write(reinterpret_cast<char *>(bf), sizeof(BITMAPFILEHEADER));
outfile.write(reinterpret_cast<char *>(bi), sizeof(BITMAPINFOHEADER));
outfile.write(reinterpret_cast<char *>(thedata), 2 * 2 * 3);
outfile.close();
Related
BYTE* uMemory;
std::string data = "00 00 00 2D 01 00 B0 F9 1E 00"
data.erase(remove_if(data.begin(), data.end(), isspace), data.end());
int address = 0;
for (int i = 0; i < data.length(); i += 2)
{
std::string data_1 = data.substr(i, 2);
int num2 = std::stoi(data_1, 0, 16);
memcpy(&uMemory + address, &num2, 2);
address++;
}
I'm trying to copy this into memory (2E 01 00 00 00 2D 01 00 B0 F9 1E 00) for uMemory but I don't understand the logic of it.
No matter the amount of bytes I want it to copy it always ends up like this in memory:
00 00 00 00 00 00 00 00 00 01 00 00 2D 00 00 00 01 00 00 00 00 00 00 00 B0 00 00 00 F9 00 00 00 1E 00 00 00
Your immediate problem here is that uMemory is a pointer, and in the line
memcpy(&uMemory + address, &num2, 2);
you are forming a pointer to a pointer. &uMemory has type BYTE**, so when you do pointer arithmetic you're moving over one pointer-width each time, which is apparently 4 bytes on your platform judging by your output.
You're also clobbering a random section of memory of when you write here, likely the memory holding the data object itself (since that's what's declared immediately after the pointer.)
This was my solution. I would love some alternatives for better coding practices if possible.
std::atomic<BYTE> uMemory[256];
int address = 0;
std::vector<BYTE> array;
for (int i = 0; i < data.length(); i += 2)
{
std::string data_1 = data.substr(i, 2);
DWORD num2 = std::stoi(data_1, 0, 16);
array.push_back(num2);
}
std::copy(std::begin(array), std::end(array), std::begin(uMemory));
The only thing I'm not understanding is that I have to have std::atomic in order for the memory to not become random. Is there a different way of doing this?
I have a vector (which is just a wrapper over a char array) that is the input. The pkzip was created using c# sharpZipLib.
I stored the data into a file which I ran through a hex editor zip template that checked out. The input is good, it's not malformed. This all but the compressed data:
50 4B 03 04 14 00 00 00 08 00 51 B2 8B 4A B3 B6
6C B0 F6 18 00 00 40 07 01 00 07 00 00 00 2D 33
31 2F 31 32 38
<compressed data (6390 bytes)>
50 4B 01 02 14 00 14 00 00 00 08 00 51 B2 8B 4A
B3 B6 6C B0 F6 18 00 00 40 07 01 00 07 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 2D 33
31 2F 31 32 38 50 4B 05 06 00 00 00 00 01 00 01
00 35 00 00 00 1B 19 00 00 00 00
I have another vector which is to be the output. The inflated data will have about 67-68k, so I know it fits into the buffer.
For the life of me, I cannot get the minizip to inflate the former and store it into latter.
This is what I have so far:
#include "minizip\zlib.h"
#define ZLIB_WINAPI
std::vector<unsigned char> data;
/*...*/
std::vector<unsigned char> outBuffer(1024 * 1024);
z_stream stream;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
stream.opaque = Z_NULL;
stream.data_type = Z_BINARY;
stream.avail_in = data.size();
stream.avail_out = outBuffer.size();
stream.next_in = &data[0];
stream.next_out = &outBuffer[0];
int ret = inflateInit(&stream);
ret = inflate(&stream, 1);
ret = inflateEnd(&stream);
I used the debugger to step through the method and monitor the ret. inflate returned value -3 with message "incorrect header check".
This is a pkzip, which is a wrapper around zlib, but minizip should be a wrapper library around zlib that should support pkzip, shouldn't it be?
How do I have to modify this to work?
Since it starts with 50 4B 03 04 it is a PKZIP file, according to https://users.cs.jmu.edu/buchhofp/forensics/formats/pkzip.html
If these are zip files, then inflate is the wrong function. The zlib, gzip and zip formats are all different. You can read zip with zlib, if you use the right functions to do so. If you don't have the contrib, maybe download and rebuild zlib.
Here's some old code I have which works for zip files, using the zlib library. I might have moved some headers around, because the official zlib has them under zlib/contrib/minizip.
The arguments are filenames, so you'll have to modify it, or write your array to a file.
// #include <zlib/unzip.h>
#include <zlib/contrib/minizip/unzip.h>
/// return list of filenames in zip archive
std::list<std::string> GetZipFilenames(const char *szZipArchive){
std::list<std::string> results;
unzFile zip = unzOpen(szZipArchive);
if (zip){
unz_global_info info;
int rv = unzGetGlobalInfo(zip, &info);
if (UNZ_OK == unzGoToFirstFile(zip)){
do {
char szFilename[BUFSIZ];
if (UNZ_OK == unzGetCurrentFileInfo(zip, NULL, szFilename, sizeof(szFilename), NULL, 0, NULL, 0))
results.push_back(std::string(szFilename));
} while (UNZ_OK == unzGoToNextFile(zip));
}
}
return results;
}
/// extract the contents of szFilename inside szZipArchive
bool ExtractZipFileContents(const char *szZipArchive, const char *szFilename, std::string &contents){
bool result = false;
unzFile zip = unzOpen(szZipArchive);
if (zip){
if (UNZ_OK == unzLocateFile(zip, szFilename, 0)){
if (UNZ_OK == unzOpenCurrentFile(zip)){
char buffer[BUFSIZ];
size_t bytes;
while (0 < (bytes = unzReadCurrentFile(zip, buffer, sizeof(buffer)))){
contents += std::string(buffer, bytes);
}
unzCloseCurrentFile(zip);
result = (bytes == 0);
}
}
unzClose(zip);
}
return result;
}
If I understand the question correctly, you are trying to decompress the 6390 bytes of compressed data. That compressed data is a raw deflate stream, which has no zlib header or trailer. For that you would need to use inflateInit2(&stream, -MAX_WBITS) instead of inflateInit(&stream). The -MAX_WBITS requests decompression of raw deflate.
Zip-Utils
std::vector<unsigned char> inputBuffer;
std::vector<unsigned char> outBuffer(1024 * 1024);
HZIP hz = OpenZip(&inputBuffer[0], inputBuffer.capacity(), 0);
ZIPENTRY ze;
GetZipItem(hz, 0, &ze);
UnzipItem(hz, 0, &outBuffer[0], 1024 * 1024);
outBuffer.resize(ze.unc_size);
If inputBuffer contains a pkzip file, this snippet will unzip it and store contents in outBuffer.
That is all.
I would like to generate a BMP file from RGB values that I have stored already.
I'm programming on OS X so I can't use the predefined BMP headers.
I've tried doing the below but preview says that the file is corrupted.
void bitmap(Image * image) {
typedef struct /**** BMP file header structure ****/
{
unsigned short bfType; /* Magic number for file */
unsigned int bfSize; /* Size of file */
unsigned short bfReserved1; /* Reserved */
unsigned short bfReserved2; /* ... */
unsigned int bfOffBits; /* Offset to bitmap data */
} BITMAPFILEHEADER;
typedef struct /**** BMP file info structure ****/
{
unsigned int biSize; /* Size of info header */
int biWidth; /* Width of image */
int biHeight; /* Height of image */
unsigned short biPlanes; /* Number of color planes */
unsigned short biBitCount; /* Number of bits per pixel */
unsigned int biCompression; /* Type of compression to use */
unsigned int biSizeImage; /* Size of image data */
int biXPelsPerMeter; /* X pixels per meter */
int biYPelsPerMeter; /* Y pixels per meter */
unsigned int biClrUsed; /* Number of colors used */
unsigned int biClrImportant; /* Number of important colors */
} BITMAPINFOHEADER;
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
bfh.bfType = 0x4d42;
bfh.bfReserved1 = 0;
bfh.bfReserved2 = 0;
bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bfh.bfOffBits = 0x36;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = image->getWidth();
bih.biHeight = image->getHeight();
bih.biPlanes = 1;
bih.biBitCount = 24;
bih.biCompression = 0;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 0x0ec4;
bih.biYPelsPerMeter = 0x0ec4;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
FILE *file = fopen("a.bmp", "wb");
if (!file) {
cout << "File not found";
return;
}
fwrite(&bfh, 1, sizeof(bfh), file);
fwrite(&bih, 1, sizeof(bfh), file);
for (int x = 0; x < image->getWidth(); x++) {
for (int y = 0; y < image->getHeight(); y++) {
float r = image->getPixel(x, y).r;
float g = image->getPixel(x, y).g;
float b = image->getPixel(x, y).b;
fwrite(&r, 1, 1, file);
fwrite(&g, 1, 1, file);
fwrite(&b, 1, 1, file);
}
}
}
I'm not sure that I understand the structure correctly. I've tried reading about it but I must be missing something.
Here is the hex output of the file
42 4D 00 02 38 00 00 00 00 00 00 00 36 00 00 00 28 00 00 00 80 02 00 00 E0 01 00
00 01 00 18 00 00 00 00 00 00 00 00 00 C4 0E 00 00 C4 0E 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00
The question is good because it enlightens some pitfalls. Here are all issues in your code. By fixing them, everything works as expected:
Your bfSize field does not include the size of the bitmap
General: The BITMAPFILEHEADER becomes to large, since it begins with a 2 byte value followed by a 4 byte value. Padding rules say that this struct the first field will be 4 bytes instead of 2. Solution: Write the magic number separately by excluding it from BITMAPFILEHEADER:
unsigned short magic=0x4d42; //This field is _not_ included in `BITMAPFILEHEADER`
fwrite(&magic,1,sizeof(magic),file);
// Write the remaining part of the header (if you did not get an I/O error...)
This modification also implies that BITMAPFILEHEADER::bfSize is 2+sizeof(BITMAPFILEHADER) + sizeof(BITMAPINFOHEADER)+ biWidth*biHeight*3
You have also passed sizeof(bfh) for booth bfhand bih, so the complete BITMAPINFOHEADER is never written
The BMP file format requires that each scanline is DWORD-aligned so depending on the width, you may need to write zero bytes after each scanline
If you think the first scanline is up, your image is upside down, since your height is positive.
Bitmap files are stored row-wise, so you should loop over x-coordinates in the innermost loop
You have also write the wrong pixel values. You should write unsigned char instead of float. You write the correct size (1 byte), but it will not be the correct value:
unsigned char r = image->getPixel(x, y).r/255; //If 1.0f is white.
Also, bitmaps are BGR(A) and not RGB(A).
Assuming you have a nice width, a working example is
void bitmap()
{
typedef struct /**** BMP file header structure ****/
{
unsigned int bfSize; /* Size of file */
unsigned short bfReserved1; /* Reserved */
unsigned short bfReserved2; /* ... */
unsigned int bfOffBits; /* Offset to bitmap data */
} BITMAPFILEHEADER;
typedef struct /**** BMP file info structure ****/
{
unsigned int biSize; /* Size of info header */
int biWidth; /* Width of image */
int biHeight; /* Height of image */
unsigned short biPlanes; /* Number of color planes */
unsigned short biBitCount; /* Number of bits per pixel */
unsigned int biCompression; /* Type of compression to use */
unsigned int biSizeImage; /* Size of image data */
int biXPelsPerMeter; /* X pixels per meter */
int biYPelsPerMeter; /* Y pixels per meter */
unsigned int biClrUsed; /* Number of colors used */
unsigned int biClrImportant; /* Number of important colors */
} BITMAPINFOHEADER;
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
/* Magic number for file. It does not fit in the header structure due to alignment requirements, so put it outside */
unsigned short bfType=0x4d42;
bfh.bfReserved1 = 0;
bfh.bfReserved2 = 0;
bfh.bfSize = 2+sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+640*480*3;
bfh.bfOffBits = 0x36;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = 640;
bih.biHeight = 480;
bih.biPlanes = 1;
bih.biBitCount = 24;
bih.biCompression = 0;
bih.biSizeImage = 0;
bih.biXPelsPerMeter = 5000;
bih.biYPelsPerMeter = 5000;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
FILE *file = fopen("a.bmp", "wb");
if (!file)
{
printf("Could not write file\n");
return;
}
/*Write headers*/
fwrite(&bfType,1,sizeof(bfType),file);
fwrite(&bfh, 1, sizeof(bfh), file);
fwrite(&bih, 1, sizeof(bih), file);
/*Write bitmap*/
for (int y = bih.biHeight-1; y>=0; y--) /*Scanline loop backwards*/
{
for (int x = 0; x < bih.biWidth; x++) /*Column loop forwards*/
{
/*compute some pixel values*/
unsigned char r = 255*((float)x/bih.biWidth);
unsigned char g = 255*((float)y/bih.biHeight);
unsigned char b = 0;
fwrite(&b, 1, 1, file);
fwrite(&g, 1, 1, file);
fwrite(&r, 1, 1, file);
}
}
fclose(file);
}
user877329's Code worked for me. (Just some minor changes because im using C)
Note: Just pay attention, to the 'size' of the Variables, because it can be different, depending on which platform you Compile.
Hi I am reading in a binary file formatted in hex. It is an image file below is a short example of the first few lines of code using hd ... |more command on linux. The image is a binary graphic so the only pixel colours are either black or white. It is a 1024 by 1024 image however the size comes out to be 2097152 bytes
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000dfbf0 00 00 00 00 00 00 00 00 00 00 00 00 ff 00 ff 00 |................|
000dfc00 ff 00 ff 00 ff 00 00 00 00 00 00 00 00 00 00 00 |................|
000dfc10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
This is the code I am using to read it in found in another thread on SO
ifstream file (argv[1], ios::in | ios::binary | ios::ate);
ifstream::pos_type fileSize;
char* fileContents;
if(file.is_open())
{
fileSize = file.tellg();
fileContents = new char[fileSize];
file.seekg(0, ios::beg);
if(!file.read(fileContents, fileSize))
{
cout << "fail to read" << endl;
}
file.close();
cout << fileSize << endl;
The code works however when I run this for loop
for (i=0; i<2097152; i++)
printf("%hd",fileContents[i]);
The only thing printed out are zeros and no 1s. Why is this are my parameters in printf not correctly specifying the pixel size. I know for a fact that there are 1's in the image representing the white areas. Also how do i figure out how many bytes represent a pixel in this image.
Your printf() is wrong. %hd means short, while fileContents[i] is a char; on all modern systems I'm familiar with, this is a size mismatch. Use an array of short instead, since you have twice as many bytes as pixels.
Also, stop using printf() and use std::cout, avoiding all type mismatch problems.
Since 2097152/1024 is exactly 2048 which is in turn 2*1024, I would assume each pixel is 2 bytes.
The other problem is probably in the printf. I'm not sure what %hd is, I would use %02x myself and cast the data to int.
I have a file which first 64 bytes are:
0x00: 01 00 00 10 00 00 00 20 00 00 FF 03 00 00 00 10
0x10: 00 00 00 10 00 00 FF 03 00 00 00 10 00 00 FF 03
0x20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
When i'm reading the file (mode read and write) at position 26 for 4 bytes I get 0 and the next time (at position 30) i get correctly 4096.
The code is:
// read LastDirectoryBlockStartByte...
seekg(26);
char * pCUIBuffer = new char[4];
read(pCUIBuffer, 4);
const unsigned int x1 = gcount ();
const unsigned int LastDirectoryBlockStartByte = *(unsigned int *)pCUIBuffer;
// read LastDirectoryBlockNumberItems...
seekg(30);
read(pCUIBuffer, 4);
const unsigned int x2 = gcount ();
const unsigned int LastDirectoryBlockNumberItems = *(unsigned int *)pCUIBuffer;
With gcount() I checked the bytes are read - and this were correctly both times 4.
I have no idea to debug it.
---------- EDIT ----------
When I use the following code (with some dummy before) it reads correctly:
char * pCUIBuffer = new char[4];
seekg(26);
read(pCUIBuffer, 4);
const unsigned int x1 = gcount ();
seekg(26);
read(pCUIBuffer, 4);
const unsigned int x2 = gcount ();
const unsigned int LastDirectoryBlockStartByte = *(unsigned int *)pCUIBuffer;
// read LastDirectoryBlockNumberItems...
seekg(30);
read(pCUIBuffer, 4);
const unsigned int x3 = gcount ();
const unsigned int LastDirectoryBlockNumberItems = *(unsigned int *)pCUIBuffer;
The difficulty is that the code stands at the begining in a methode. And the "false readed value" has obviously nothing to do with the listed code. Maybe theres a trick with flush or sync (but both I tryed...) or somewhat else...
You are saying that pCUIBuffer contains a pointer:
*(unsigned int *)pCUIBuffer;
And then you go get whatever it's pointing at...in RAM. That could be anything.
Now I'm writing an answer, because my attempt to contact TonyK failes (I asked for writing an answer).
The perfect answer to my question was to enable exceptions by calling exceptions (eofbit | failbit | badbit).
Rumo