Windows.h GDI - BITMAPINFO alloca indicates failure - winapi

I want to create an image from the desktop and set it to gray using BITMAPINFO, but it keeps showing me the warning, "Warning C6255 _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead".
I would appreciate any advice.
HBITMAP CreateGreyscaleBitmap(int cx, int cy)
{
BITMAPINFO* pbmi = (BITMAPINFO*)alloca(sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256);
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth = cx;
pbmi->bmiHeader.biHeight = cy;
pbmi->bmiHeader.biPlanes = 1;
pbmi->bmiHeader.biBitCount = 8;
pbmi->bmiHeader.biCompression = BI_RGB;
pbmi->bmiHeader.biSizeImage = 0;
pbmi->bmiHeader.biXPelsPerMeter = 14173;
pbmi->bmiHeader.biYPelsPerMeter = 14173;
pbmi->bmiHeader.biClrUsed = 0;
pbmi->bmiHeader.biClrImportant = 0;
for (int i = 0; i < 256; i++)
{
pbmi->bmiColors[i].rgbRed = i;
pbmi->bmiColors[i].rgbGreen = i;
pbmi->bmiColors[i].rgbBlue = i;
pbmi->bmiColors[i].rgbReserved = 0;
}
PVOID pv;
return CreateDIBSection(NULL, pbmi, DIB_RGB_COLORS, &pv, NULL, 0);
}

Related

How to use FF_CONSTANT for Force feedback for Linux?

I am not able to utilize FF_CONSTANT force effect. My try code is:
struct ff_effect joy_effect_, joy_effect_2;
if (iwantconstantforce)
{
joy_effect_.id = -1;
joy_effect_.type = FF_CONSTANT;
joy_effect_.direction = 0x0000; // down
joy_effect_.replay.length = 100;
joy_effect_.replay.delay = 0;
joy_effect_.trigger.button = 0;
joy_effect_.trigger.interval = 100;
joy_effect_.u.constant.level = 65535;
joy_effect_.u.constant.envelope.attack_length = joy_effect_.replay.length / 10;
joy_effect_.u.constant.envelope.fade_length = joy_effect_.replay.length / 10;
joy_effect_.u.constant.envelope.attack_level = joy_effect_.u.constant.level / 10;
joy_effect_.u.constant.envelope.fade_level = joy_effect_.u.constant.level / 10;
}
I am able to produce FF_SPRING and FF_DAMPER effects with following codes.
if (youwantdampereffect)
{
joy_effect_.id = -1;
joy_effect_.direction = 0; // down
joy_effect_.type = FF_DAMPER;
joy_effect_.replay.length = 20;
joy_effect_.replay.delay = 0;
joy_effect_.u.condition[0].right_saturation = 65535;
joy_effect_.u.condition[0].left_saturation = 65535;
joy_effect_.u.condition[0].right_coeff = 65535 / 2;
joy_effect_.u.condition[0].left_coeff = 65535 / 2;
joy_effect_.u.condition[0].deadband = 0;
joy_effect_.u.condition[0].center = 0;
int ret = ioctl(ff_fd_, EVIOCSFF, &joy_effect_); // upload the effect
}
if (youwantspringeffect)
{
joy_effect_2.id = -1;
joy_effect_2.direction = 0; // down
joy_effect_2.type = FF_SPRING;
joy_effect_2.replay.length = 20;
joy_effect_2.replay.delay = 0;
joy_effect_2.u.condition[0].right_saturation = 65535 / 2;
joy_effect_2.u.condition[0].left_saturation = 65535 / 2;
joy_effect_2.u.condition[0].right_coeff = 32767;
joy_effect_2.u.condition[0].left_coeff = 32767;
joy_effect_2.u.condition[0].deadband = 0;
joy_effect_2.u.condition[0].center = 0;
int ret = ioctl(ff_fd_, EVIOCSFF, &joy_effect_2); // upload the effect
}
I do not find any info about what is constant force effect feels like or when it makes sense to use it.
Can somebody brief its importance and usage?
Thanks :)

Access violation writing location 0x00000000 in middle of a for loop

I'm trying to use mnist dataset for neural networks but im getting a Access violation writing location 0x00000000
the code is
for (int i = 0; i < length; i++) {
innerarray = (int8_t*)malloc(width * height);
for (int j = 0; j < width * height; j++) {
int8_t value = 0;
innerarray[j] = value;
}
temparray[i] = innerarray;
}
for (int i = 0; i < length; i++) {
for (int j = 0; j < width * height; j++) {
int8_t grayscale;
rf.read((char*)&grayscale, 1);
temparray[i][j] = grayscale; //error happens here
}
}
variable values:
int length = 10000;
int width = 28;
int height = 28;
The weird thing is it only happen when i >= 2512. Also replacing grayscale with 0 doesn't work. I can hower set temparray[2512][0] to 0 before the last nested for loop.
Like this:
for (int i = 0; i < length; i++) {
innerarray = (int8_t*)malloc(width * height);
for (int j = 0; j < width * height; j++) {
int8_t value = 0;
innerarray[j] = value;
}
temparray[i] = innerarray;
}
temparray[2512][0] = 0; //works
for (int i = 0; i < length; i++) {
for (int j = 0; j < width * height; j++) {
int8_t grayscale;
rf.read((char*)&grayscale, 1);
temparray[i][j] = 0; //error still happens here
}
}
The full code is:
#include<iostream>
#include<fstream>
#include<cstdint>
#include<cstdlib>
#include<array>
using namespace std;
struct images {
int32_t height = 0;
int32_t width = 0;
int32_t magicnumber = 0;
int32_t numberofimages = 0;
int8_t** images[];
void setimages(int8_t** newimages) {
delete[] this->images;
int8_t** images = (int8_t**)malloc(numberofimages);
int8_t* innerarray;
for (int i = 0; i < numberofimages; i++) {
innerarray = (int8_t*)malloc(width * height);
images[i] = innerarray;
}
for (int i = 0; i < numberofimages; i++) {
for (int j = 0; j < width * height; j++) {
images[i][j] = newimages[i][j];
}
}
};
};
struct labels {
int32_t magicnumber = 0;
int32_t numberoflabels = 0;
int8_t labels[];
};
int32_t litleendiantobig(int32_t litle) {//reverse works as well
int32_t big = ((4278190080 & litle) >> 24) + ((255 & litle) << 24) + ((16711680 & litle) >> 8) + ((65280 & litle) << 8);
return big;
}
images loadimages(string filename, int32_t magicalnumber) {
ifstream rf(filename, ios::out | ios::binary);
if (!rf) {
cout << "Cannot open file! " << filename << endl;
exit(1);
}
int32_t magicnumberoffile;
rf.read((char*)&magicnumberoffile, 4);
magicnumberoffile = litleendiantobig(magicnumberoffile);
if (magicalnumber != magicnumberoffile) {
cout << "Wrong magic number!" << endl;
cout << "expected:" << magicalnumber << endl;
cout << "got:" << magicnumberoffile << endl;
exit(1);
}
images img;
int32_t length;
rf.read((char*)&length, 4);
length = litleendiantobig(length);
img.numberofimages = length;
int32_t width;
rf.read((char*)&width, 4);
width = litleendiantobig(width);
img.width = width;
int32_t height;
rf.read((char*)&height, 4);
height = litleendiantobig(height);
img.height = height;
int8_t** temparray = (int8_t**)malloc(length);
int8_t* innerarray;
for (int i = 0; i < length; i++) {
innerarray = (int8_t*)malloc(width * height);
for (int j = 0; j < width * height; j++) {
int8_t value = 0;
innerarray[j] = value;
}
temparray[i] = innerarray;
}
for (int i = 0; i < length; i++) {
for (int j = 0; j < width * height; j++) {
int8_t grayscale;
rf.read((char*)&grayscale, 1);
temparray[i][j] = grayscale; //error happens here
}
}
img.setimages(temparray);
rf.close();
return img;
}
int main() {
images testimages;
loadimages("t10k-images.bin", 2051);
cout << testimages.images;
return 0;
}
I don't now how to solve the problem and can't find it anywhere else. Thanks for helping me out.
Your using malloc has done you in.
int* array = (int*)malloc(width* height); // allocate width * height bytes.
array[i] = x; // Sets the [i] _integer_ of array to x.
// but you allocated space for BYTE size elemennts.
The correct way to allocate integers using malloc:
int* array = (int*)malloc(width* height * sizeof(int)); // allocate width * height ints
Either that or your original intent was to allocate 8 bit pixels. In that case, your pointers should be declared as unsigned char*.
In either case, when coding in C++, types are important, and using operator new to allocate your arrays would have saved you from these troubles.

Creating 24-bit BITMAP in Winapi

I'm using the following code in order to convert my ImageMagick image to 32-bit HBITMAP:
BITMAP bitmap;
std::memset(&bitmap, 0, sizeof(bitmap));
bitmap.bmType = 0;
bitmap.bmWidth = image->image()->columns;
bitmap.bmHeight = image->image()->rows;
bitmap.bmWidthBytes = 4 * bitmap.bmWidth;
bitmap.bmPlanes = 1;
bitmap.bmBitsPixel = 32;
bitmap.bmBits = NULL;
const size_t size = bitmap.bmWidthBytes * bitmap.bmHeight;
auto buffer = (HANDLE)GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, size);
RGBQUAD *bitmap_bits = (RGBQUAD *) GlobalLock((HGLOBAL) buffer);
register RGBQUAD *q = bitmap_bits;
for (size_t y = 0; y < image->image()->rows; y++)
{
register auto p = GetVirtualPixels(image->image(), 0, y, image->image()->columns, 1, exception);
if (!p) break;
for (size_t x = 0; x < image->image()->columns; x++)
{
q->rgbRed = ScaleQuantumToChar(GetPixelRed(image->image(), p));
q->rgbGreen = ScaleQuantumToChar(GetPixelGreen(image->image(), p));
q->rgbBlue = ScaleQuantumToChar(GetPixelBlue(image->image(), p));
q->rgbReserved = 0;
p += GetPixelChannels(image->image());
q++;
}
}
bitmap.bmBits = bitmap_bits;
HBITMAP hbmp = CreateBitmapIndirect(&bitmap);
It works well, but I'd like to save some memory by using images with lower depth. Unfortunately I'm not even able to make it work with 24-bit images. I modified my code to look like this:
BITMAP bitmap;
std::memset(&bitmap, 0, sizeof(bitmap));
bitmap.bmType = 0;
bitmap.bmWidth = image->image()->columns;
bitmap.bmHeight = image->image()->rows;
bitmap.bmWidthBytes = ((bitmap.bmWidth * 24 + 31) / 32) * 4;
bitmap.bmPlanes = 1;
bitmap.bmBitsPixel = 24;
bitmap.bmBits = NULL;
const size_t length = bitmap.bmWidthBytes * bitmap.bmHeight;
auto buffer = (HANDLE)GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, length);
RGBTRIPLE *bitmap_bits = (RGBTRIPLE *) GlobalLock((HGLOBAL) buffer);
register RGBTRIPLE *q = bitmap_bits;
for (size_t y = 0; y < image->image()->rows; y++)
{
register auto p = GetVirtualPixels(image->image(), 0, y, image->image()->columns, 1, exception);
if (!p) break;
for (size_t x = 0; x < image->image()->columns; x++)
{
q->rgbtRed = ScaleQuantumToChar(GetPixelRed(image->image(), p));
q->rgbtGreen = ScaleQuantumToChar(GetPixelGreen(image->image(), p));
q->rgbtBlue = ScaleQuantumToChar(GetPixelBlue(image->image(), p));
p += GetPixelChannels(image->image());
q++;
}
}
bitmap.bmBits = bitmap_bits;
HBITMAP hbmp = CreateBitmapIndirect(&bitmap);
But it seems that this code cannot produce valid bitmap. What am I doing wrong?
You are not taking the stride/alignment into account. Each row needs to be DWORD aligned.
Calculating Surface Stride
In an uncompressed bitmap, the stride is the number of bytes needed to go from the start of one row of pixels to the start of the next row. The image format defines a minimum stride for an image. In addition, the graphics hardware might require a larger stride for the surface that contains the image.
For uncompressed RGB formats, the minimum stride is always the image width in bytes, rounded up to the nearest DWORD. You can use the following formula to calculate the stride:
stride = ((((biWidth * biBitCount) + 31) & ~31) >> 3)
You need to fix the way you access the RGBTRIPLEs in the buffer.
Before the "x loop" you should do something like q = (RGBTRIPLE*) (((char*)bitmap_bits) + (y * bitmap.bmWidthBytes));
CreateBitmapIndirect creates a DDB which is perhaps not the best choice, create a DIB instead:
#define CalcStride(w, bpp) ( ((((w) * (bpp)) + 31) & ~31) >> 3 )
static void SetPixel24(UINT w, void*bits, UINT x, UINT y, COLORREF cr)
{
RGBTRIPLE*p = ((RGBTRIPLE*) ( ((char*)bits) + (y * CalcStride(w, 24)) )) + x;
p->rgbtRed = GetRValue(cr);
p->rgbtGreen = GetGValue(cr);
p->rgbtBlue = GetBValue(cr);
}
void Silly24BPPExample()
{
HWND hWnd = CreateWindowEx(WS_EX_APPWINDOW, WC_STATIC, 0, WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_OVERLAPPEDWINDOW|SS_BITMAP|SS_REALSIZECONTROL, 0, 0, 99, 99, 0, 0, 0, 0);
const INT w = 4, h = 4, bpp = 24;
BITMAPINFO bi;
ZeroMemory(&bi, sizeof(bi));
BITMAPINFOHEADER&bih = bi.bmiHeader;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = w, bih.biHeight = -h;
bih.biPlanes = 1, bih.biBitCount = bpp;
bih.biCompression = BI_RGB;
void*bits;
HBITMAP hBmp = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, &bits, NULL, 0);
for (UINT x = 0; x < w; ++x)
for (UINT y = 0; y < h; ++y)
SetPixel24(w, bits, x, y, RGB(255, 0, 0)); // All red
SetPixel24(w, bits, 0, 0, RGB(0, 0, 255)); // except one blue
SendMessage(hWnd, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM) hBmp);
for (MSG msg; IsWindow(hWnd) && GetMessage(&msg, 0, 0, 0); ) DispatchMessage(&msg);
// DeleteObject(...)
}

Fully Associative Cache implementation

I don't understand why my code for the fully associative cache doesn't match the trace files that I'm given.
The parameters are each cache line is 32 bytes and the total cache size is 16KB.
My implementations for set associative caches of 2,4,8,and 16 all work perfectly (using least recently used replacement policy). But for fully associative, which could also just be described as a set associative of 32, is VERY close to the trace file but not quite. Frankly, I don't know how to debug this one since there's a vast amount of steps (at least the way I did it)
Here's the relevant parts of my code (excuse the inefficiency)
//Fully Associative
int **fullyAssoc;
fullyAssoc = new int*[64]; //where fullyAssoc[0][index] is way 0, fullyAssoc[2][index] is way 1 etc..
int **LRU32;
LRU32 = new int*[32];
for (int i = 0; i < 64; ++i){ //Initialize all entries in fullyAssoc to 0
fullyAssoc[i] = new int[16 * CACHE_LINE / 32];
}
for (int i = 0; i < 16; i++){ //Initialize LRU array
LRU32[0][i] = 0;
LRU32[1][i] = 1;
LRU32[2][i] = 2;
LRU32[3][i] = 3;
LRU32[4][i] = 4;
LRU32[5][i] = 5;
LRU32[6][i] = 6;
LRU32[7][i] = 7;
LRU32[8][i] = 8;
LRU32[9][i] = 9;
LRU32[10][i] = 10;
LRU32[11][i] = 11;
LRU32[12][i] = 12;
LRU32[13][i] = 13;
LRU32[14][i] = 14;
LRU32[15][i] = 15;
LRU32[16][i] = 16;
LRU32[17][i] = 17;
LRU32[18][i] = 18;
LRU32[19][i] = 19;
LRU32[20][i] = 20;
LRU32[21][i] = 21;
LRU32[22][i] = 22;
LRU32[23][i] = 23;
LRU32[24][i] = 24;
LRU32[25][i] = 25;
LRU32[26][i] = 26;
LRU32[27][i] = 27;
LRU32[28][i] = 28;
LRU32[29][i] = 29;
LRU32[30][i] = 30;
LRU32[31][i] = 31;
}
int fullyAssocLRU = 0;
int memCount = 0;
while(getline(fileIn, line)){
stringstream s(line);
s >> instruction >> hex >> address;
int indexFull;
int tagFull;
unsigned long long address, addressFull;
address = address >> 5; //Byte offset
addressFull = address;
indexFull = addressFull % 16;
tagFull = addressFull >> 4;
if (assocCache(fullyAssoc, indexFull, 32, tagFull, LRU32) == 1){
fullyAssocLRU++;
}
}
void LRU_update(int **lru, int index, int way, int ways){
int temp = 0;
int temp2[ways];
int temp_index = 0;
int i = 0;
while(i < ways){
if (lru[i][index] == way/2){
temp = lru[i][index];
i++;
continue;
}
else{
temp2[temp_index] = lru[i][index];
temp_index++;
}
i++;
}
for (int j = 0; j < ways - 1; j++){
lru[j][index] = temp2[j];
}
lru[ways - 1][index] = temp;
}
bool assocCache(int **block, int index, int ways, int tag, int **lru){
bool retVal = false;
for(int i = 0; i < 2*ways; i = i + 2){
if (block[i][index] == 0){
block[i][index] = 1;
block[i+1][index] = tag;
LRU_update(lru, index, i, ways);
return retVal;
}
else{
if (block[i+1][index] == tag){
retVal = true;
LRU_update(lru, index, i, ways);
return retVal;
}
else{
continue;
}
}
}
int head = 2 * lru[0][index];
block[head][index] = 1;
block[head+1][index] = tag;
LRU_update(lru, index, head, ways);
return retVal;
}
The trace files is supposed to be:
837589,1122102; 932528,1122102; 972661,1122102; 1005547,1122102; //For direct mapped
993999,1122102; 999852,1122102; 999315,1122102; 1000092,1122102; //For set associative
1000500,1122102; //For fully associative (LRU)
My output is:
837589,1122102; 932528,1122102; 972661,1122102; 1005547,1122102;
939999,1122102; 999852,1122102; 999315,1122102; 1000092,1122102;
1000228,1122102;
As you can see, for the fully associative one, it's only 272 off the correct output. Why would it be off when switching from 16 ways to 32 ways?
Ah, I mistakenly though a fully associative cache for a 32 line size cache of 16KB cache size is 32 ways, when it's actually 512 ways.

CreateDIBSection + 16 bit system color

This code works perfect on 32 bit system color (Windows 7),
but it doesn't work on 16 bit color - menu bitmaps not transparent!!!:
...
HBITMAP rv = rgb(hsrc, 16);
...
HBITMAP rgb(HBITMAP hsrc, WORD wBitsPixel) {
HBITMAP hold = NULL;
HDC hdcsrc = NULL, hdc = NULL;
BITMAP bmp = {0};
HBITMAP dib = NULL;
UCHAR *dst = NULL, *src = NULL, *tmp = NULL;
UCHAR alpha;
int bpl;
ULONG x, y;
DWORD bmp_size = 0;
HANDLE hdib = NULL;
char *lpbitmap = NULL;
int rv = 0;
hdc = GetDC(m_hMainDlg);
hdcsrc = CreateCompatibleDC(hdc);
hold = (HBITMAP)SelectObject(hdcsrc, hsrc);
rv = GetObject(hsrc, sizeof(BITMAP), &bmp);
BITMAPINFOHEADER bi = {0};
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bmp.bmWidth;;
bi.biHeight = bmp.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitsPixel;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
bmp_size = ((bmp.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmp.bmHeight;
hdib = GlobalAlloc(GHND, bmp_size);
lpbitmap = (char *)GlobalLock(hdib);
/* Get bits of source bitmap. */
GetDIBits(hdcsrc, hsrc, 0, bmp.bmHeight, lpbitmap, (BITMAPINFO *)&bi, DIB_RGB_COLORS);
/* For destination bitmap */
BITMAPINFO bmi = {0};
bmi.bmiHeader.biSize = sizeof(BITMAPINFO);
bmi.bmiHeader.biWidth = bmp.bmWidth;
bmi.bmiHeader.biHeight = bmp.bmHeight;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = wBitsPixel;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter = 0;
bmi.bmiHeader.biYPelsPerMeter = 0;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
dib = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void **)&dst, NULL, 0);
bpl = 4 * bmp.bmWidth; /* bytes per line */
src = (UCHAR *)lpbitmap;
for (y = 0; y < bmp.bmHeight; y++, src += bpl) {
tmp = src;
for (x = 0; x < bmp.bmWidth; x++) {
alpha = tmp[3];
dst[0] = tmp[0] * alpha / 255;
dst[1] = tmp[1] * alpha / 255;
dst[2] = tmp[2] * alpha / 255;
dst[3] = alpha;
dst += 4;
tmp += 4;
}
}
// free resources
ReleaseDC(m_hMainDlg, hdc);
SelectObject(hdcsrc, hold);
DeleteDC(hdcsrc);
GlobalUnlock(hdib);
GlobalFree(hdib);
return dib;
}

Resources