Reading Bitmap file - c++

I try to read a bitmap file. This my program:
#include<iostream>
#include<fstream>
#include <string>
#include<windows.h>
using namespace std;
#pragma pack(1)
struct header
{
char header[2];
int32_t filesize;
int16_t reser;
int16_t reser1;
int32_t dataoffset;
};
struct infoheader
{
int32_t headersize;
int32_t width;
int32_t height;
int16_t plans;
int16_t bpp;
int32_t compression;
int32_t datasize;
int32_t re;
int32_t ve;
int32_t color;
int32_t importantcolor;
};
struct PIxel
{
unsigned char G;
unsigned char B;
unsigned char R;
};
int main()
{
header h;
infoheader info;
PIxel *p;
ifstream file("bmp2.bmp", ios::binary);
if (file.is_open())
{
cout << "true" << endl;
file.read((char*)&h, sizeof(h));
file.read((char*)&info, sizeof(info));
cout << info.width << " " << info.height << " " << h.filesize << " " << info.bpp << endl;
int pa = info.width % 4;
int size = info.width * info.height * (info.bpp / 3) + pa * info.height;
char* arr = new char[size];
file.read(arr, size);
char* temp = arr;
int sizep = info.height * info.width;
p = new PIxel[sizep];
for (int i = 0; i < info.height; i++)
{
for (int j = 0; j < info.width; j++)
{
p[i * info.height + j].B = *(temp++);
p[i * info.height + j].G = *(temp++);
p[i * info.height + j].R = *(temp++);
//p = p + 3;
}
p += pa;
}
HWND consoleWindow = GetConsoleWindow();
HDC hdc = GetDC(consoleWindow);
for (int i = 0; i < info.height; i++)
{
for (int j = 0; j < info.width; j++)
{
PIxel m = p[i * info.height + j];
SetPixel(hdc, i, j, RGB(m.R, m.G, m.B));
}
}
ReleaseDC(consoleWindow, hdc);
}
}
It works but the image on my console is not right...
Can you help me to fix it?

int size = info.width * info.height * (info.bpp / 3) + pa * info.height;
The above calculation for size is incorrect. Bits per pixel should be divided by 8. The indexing in the for loops is also wrong. It ends ups multiplying height x height.
Also SetPixel(... i, j ...) should be changed to SetPixel(... j, i ...) since i in your case, refers to the y-axis.
As mentioned in previous answer, the padding has to be fixed too.
Note that you can use LoadImage and other Windows GDI functions to open and draw bitmaps.
int size = (info.width * (info.bpp / 8) + pa) * info.height;
...
for(int i = info.height - 1; i >= 0; i--)
{
for(int j = 0; j < info.width; j++)
{
int index = i * (info.width) + j;
p[index].B = *(temp++);
p[index].G = *(temp++);
p[index].R = *(temp++);
}
temp += pa;
}
for(int i = 0; i < info.height; i++)
{
for(int j = 0; j < info.width; j++)
{
int index = i * (info.width) + j;
PIxel m = p[index];
SetPixel(hdc, j, i, RGB(m.R, m.G, m.B));
}
}

I believe you have your padding adjustment on the wrong pointer. The padding is present on the source image. You don't want it on the destination image. You are accounting for the padding with p += pa; you should instead replace this line with temp += pa to account for the padding of the source image.

Related

Assigning value to pointer with multithreading generates wrong result

void assign(short *inPtr, int ext[4], int sz[2])
{
for (int j = ext[2]; j < ext[3]; j++)
for (int i = ext[0]; i < ext[1]; i++)
{
inPtr[i + j * sz[1]] = 100;
}
}
int main(int, char **)
{
int size[2] = {16, 16};
short ptr[256];
std::vector<std::thread> pool;
int block = 2;
int row = size[0] / block;
int col = size[1] / block;
for (size_t j = 0; j < row; j++)
for (size_t i = 0; i < col; i++)
{
int ext[4] = {i * block, (i + 1) * block, j * block, (j + 1) * block};
pool.push_back(std::thread(assign, ptr, ext, size));
}
for (size_t i = 0; i < row * col; i++)
{
pool[i].join();
}
for (size_t i = 0; i < 256; i++)
{
std::cout << (double)ptr[i] << ", ";
}
std::cout << std::endl;
}
I'm trying to assign value to pointer ptr by using multithreading.
The code above is supposed to assign 100 to all element of ptr, however, there are many 0 in the output. Why does it happen and how to fix it ?

Pass an unsigned short pointer to a function that as reference for cropping an image

This program is crashing!, as a newbie can anyone say where is the memory getting corrupted here and what to do to fix this issue?
Here I am trying to extract an ROI from part of data and assigning it to original data back again.
Modified code below, here there is no issue and the 'newdata' will have cropped data from the original variable 'data'
#include "stdafx.h"
#include <iostream>
using namespace std;
void ExtractROI(unsigned short *image, int nRows, int nCols, unsigned short *imageROI)
{
int indexROI = 0;
for (int i = 0; i < nRows; i++)
{
for (int j = 0; j < nCols; j++)
{
imageROI[indexROI] = image[i * nCols + j];
indexROI++;
}
}
}
int main()
{
const int nRows = 12;
const int nCols = 12;
unsigned short *data = new unsigned short[nRows * nCols];
for (int i = 0; i < nRows; i++)
{
for (int j = 0; j < nCols; j++)
{
data[i * nCols + j] = i * nCols + j;
}
}
unsigned short *newdata = new unsigned short[2 * 2];
memset(newdata, 0, sizeof(unsigned short) * 2 * 2);
ExtractROI(data, 2, 2, newdata);
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
{
cout << "(" << i << "," << j << ")" << " = " << newdata[i * 2 + j] << endl;
}
}
delete[] data;
delete[] newdata;
char x;
cin >> x;
return 0;
}
/* Old code below*/
#include "stdafx.h"
#include <iostream>
using namespace std;
void ExtractROI(unsigned short *image, int nRows, int nCols, unsigned short *imageROI)
{
int indexROI = 0;
for (int i = 0; i < nRows; i++)
{
for (int j = 0; j < nCols; j++)
{
imageROI[indexROI] = image[i * nCols + j];
indexROI++;
}
}
}
int main()
{
const int nRows = 12;
const int nCols = 12;
unsigned short *data = new unsigned short[nRows * nCols];
for (int i = 0; i < nRows; i++)
{
for (int j = 0; j < nCols; j++)
{
data[i * nCols + j] = i * nCols + j;
}
}
unsigned short *newdata = new unsigned short[2 * 2];
memset(newdata, 0, sizeof(unsigned short) * 2 * 2);
ExtractROI(data, nRows, nCols, newdata);
data = newdata;
for (int i = 0; i < nRows; i++)
{
for (int j = 0; j < nCols; j++)
{
cout << "(" << i << "," << j << ")" << " = " << data[i * nCols + j] << endl;
}
}
/*delete[] data;
delete[] newdata;*/
char x;
cin >> x;
return 0;
}
Inside the loops in ExtractROI the variable indexROI will be increased a total of nRows * nCols times. Since you pass 12 for each, indexROI will at the end be 12 * 12 (or 144). This is quite a lot more than the 2 * 2 (or 4) elements allocated for imageROI.
Going out of bounds of allocated memory leads to undefined behavior.
After the call to ExtractROI you have the same problem in the loops there. As well as a memory leak (you lose what data is originally pointing to).

Can't access Unified Memory after i ran kernel function using it

so I am calling cudaMallocManaged for 2 functions in my code and it works fine for first function (backwardMask()) after i call it i can easily access my data from host, but my problem is with kernel function seriesLength() - because i am doing cudaMallocManaged on my indexmask and then (before calling seriesLength()) i can easily access/modify this indexmask on host , after i call seriesLength() it is modyfing my indexmask and also has no problem with accessing it, but after this function returns i am unable to read indexmask on host and am getting exception (status code 0xC0000022).
This is very weird error because I am doing it analogically to the first function(backwardMask()), which works correctly.
Any ideas/explainations will be highly appreciated.
Here is seriesLengths kernal function code:
__global__ void seriesLengths(int* scannedbw,int* indexmask,int* numOfSeries,int n){
int index = blockIdx.x * blockDim.x + threadIdx.x;
int stride = blockDim.x * gridDim.x;
for (int i = index; i < n;i+=stride)
{
if (i == (n - 1))
{
*numOfSeries = scannedbw[i];
indexmask[scannedbw[i]] = n;
}
if (i == 0)
{
indexmask[0] = 0;
}
else if (scannedbw[i] != scannedbw[i - 1])
{
indexmask[scannedbw[i] - 1] = i;
}
}
}
Code of kernel funct backwardMask:
__global__ void backwardMask(const char *in, int* bwMask,int n)
{
int index = blockIdx.x * blockDim.x + threadIdx.x;
int stride = blockDim.x * gridDim.x;
for (int i = index; i < n;i+=stride)
{
if (i == 0)
bwMask[i] = 1;
else
{
bwMask[i] = (in[i] != in[i - 1]);
}
}
}
Main function:
int main()
{
int N=1024;
srand(time(0));
char* t;
int* bwmask;
cudaMallocManaged(&t, N*sizeof(char));
cudaMallocManaged(&bwmask, N*sizeof(int));
for (int i = 0; i < N; i++)
{
if(i<300)
t[i] = 'a' + rand() % 2;
else
t[i] = 'a' + rand() % 20;
}
for (int j = 0; j < 60; j++)
std::cout << t[j];
std::cout << std::endl;
int blockSize = 256;
int numBlocks = (N + blockSize - 1) / blockSize;
backwardMask<<<numBlocks, blockSize >>>(t,bwmask , N);
cudaDeviceSynchronize();
for (int j = 0; j < 60; j++)
std::cout << bwmask[j];
std::cout << std::endl;
//now inclusive prefix sum for bwmask
int* scannedbwmask;
cudaMallocManaged(&scannedbwmask, N*sizeof(int));
thrust::inclusive_scan(bwmask, bwmask + N, scannedbwmask);
cudaDeviceSynchronize();
int numOfSeries;
//seriesLengths shows us lengths of each series by i-(i-1) and starting index of each series
int* indexmask;
cudaMallocManaged(&indexmask, (N+1)*sizeof(int));
seriesLengths<<<numBlocks, blockSize>>>(scannedbwmask, indexmask, &numOfSeries, N);
cudaDeviceSynchronize();
// accessing indexmask here gives us exception
std::cout << indexmask[3];
/*for (int j = 0; j < 60; j++)
std::cout << indexmask[j];
std::cout << std::endl;*/
std::cout << "numseries " << numOfSeries;
getch();
return 0;
}
Change numOfSeries to be pointer to int
int* numOfSeries;
then malloc memory for it:
cudaMallocManaged(&numOfSeries, sizeof(int));
and pass it like that:
seriesLengths<<<numBlocks, blockSize>>>(scannedbwmask, indexmask, numOfSeries, N);

How to take pixel coordinates from an image in c++ using specific conditions

I want to get (x,Y) co-ordinates from an image where the pixel value is not zero. I got the following error in this code:
error- bad access:
camera.cpp
void Camera ::write_uint8_image_1(uint8_image_t *image, int *output)
{
int index = 1;
for(uint32_t i = 0; i < image->h; i++)
{
for(uint32_t j = 0; j < image->w; j++)
{
if(image->data[i * image->w + j] != 0)
output[index++] = i;
output[index++] = j; /* error : bad access */
}
}
output[0] = index;
}
main.cpp
int output[800] = {0};
/*print output*/
C1.write_uint8_image_1(c.output_image, output);
for (int i = 1; i < output[0]; i++)
std::cout<< output[i] << " , ";

C++ memory leak, how to detect

I am using SSE to implement matrix multiplication, but I found there exists memory leak(see the picture below), the memory usage is increasing from 400M to 1G or more.
But, I free the memory in the code.
The following are codes
main.cpp
#include "sse_matrix.h"
#include <ctime>
int main(int argc, char* argv[])
{
vector<float> left(size, 0);
vector<float> right(size, 0);
vector<float> result(size, 0);
// initialize value
for (int i = 0; i < dim; i ++)
{
for (int j = 0; j < dim; j ++)
{
left[i*dim + j] = j;
right[i*dim + j] = j;
}
}
cout << "1. INFO: value initialized, starting matrix multiplication" << endl;
// calculate the result
clock_t my_time = clock();
SSE_Matrix_Multiply(&left, &right, &result);
cout << "2. INFO: SSE matrix multiplication result has got" << endl;
/*for (int i = 0; i < dim; i ++)
{
for (int j = 0; j < dim; j ++)
{
cout << result[i * dim + j] << " ";
}
cout << endl;
}*/
cout << "3. INFO: " << float(clock() - my_time)/1000.0 << endl;
system("pause");
return 0;
}
sse_matrix.h
#ifndef __SSE_MATRIX_H
#define __SSE_MATRIX_H
#include <vector>
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::vector;
//#define dim 8
//#define size (dim * dim)
const int dim = 4096;
const int size = dim * dim;
struct Matrix_Info
{
vector<float> * A;
int ax, ay;
vector<float> * B;
int bx, by;
vector<float> * C;
int cx, cy;
int m;
int n;
};
void Transpose_Matrix_SSE(float * matrix)
{
__m128 row1 = _mm_loadu_ps(&matrix[0*4]);
__m128 row2 = _mm_loadu_ps(&matrix[1*4]);
__m128 row3 = _mm_loadu_ps(&matrix[2*4]);
__m128 row4 = _mm_loadu_ps(&matrix[3*4]);
_MM_TRANSPOSE4_PS(row1, row2, row3, row4);
_mm_storeu_ps(&matrix[0*4], row1);
_mm_storeu_ps(&matrix[1*4], row2);
_mm_storeu_ps(&matrix[2*4], row3);
_mm_storeu_ps(&matrix[3*4], row4);
}
float * Shuffle_Matrix_Multiply(float * left, float * right)
{
__m128 _t1, _t2, _sum;
_sum = _mm_setzero_ps(); // set all value of _sum to zero
float * _result = new float[size];
float _res[4] = {0};
for (int i = 0; i < 4; i ++)
{
for (int j = 0; j < 4; j ++)
{
_t1 = _mm_loadu_ps(left + i * 4);
_t2 = _mm_loadu_ps(right + j * 4);
_sum = _mm_mul_ps(_t1, _t2);
_mm_storeu_ps(_res, _sum);
_result[i * 4 + j] = _res[0] + _res[1] + _res[2] + _res[3];
}
}
return _result;
}
float * SSE_4_Matrix(struct Matrix_Info * my_info)
{
int m = my_info->m;
int n = my_info->n;
int ax = my_info->ax;
int ay = my_info->ay;
int bx = my_info->bx;
int by = my_info->by;
//1. split Matrix A and Matrix B
float * _a = new float[16];
float * _b = new float[16];
for (int i = 0; i < m; i ++)
{
for (int j = 0; j < m; j ++)
{
_a[i*m + j] = (*my_info->A)[(i + ax) * n + j + ay];
_b[i*m + j] = (*my_info->B)[(i + bx) * n + j + by];
}
}
//2. transpose Matrix B
Transpose_Matrix_SSE(_b);
//3. calculate result and return a float pointer
return Shuffle_Matrix_Multiply(_a, _b);
}
int Matrix_Multiply(struct Matrix_Info * my_info)
{
int m = my_info->m;
int n = my_info->n;
int cx = my_info->cx;
int cy = my_info->cy;
for (int i = 0; i < m; i ++)
{
for (int j = 0; j < m; j ++)
{
float * temp = SSE_4_Matrix(my_info);
(*my_info->C)[(i + cx) * n + j + cy] += temp[i*m + j];
delete [] temp;
}
}
return 0;
}
void SSE_Matrix_Multiply(vector<float> * left, vector<float> * right, vector<float> * result)
{
struct Matrix_Info my_info;
my_info.A = left;
my_info.B = right;
my_info.C = result;
my_info.n = dim;
my_info.m = 4;
// Matrix A row:i, column:j
for (int i = 0; i < dim; i += 4)
{
for (int j = 0; j < dim; j += 4)
{
// Matrix B row:j column:k
for (int k = 0; k < dim; k += 4)
{
my_info.ax = i;
my_info.ay = j;
my_info.bx = j;
my_info.by = k;
my_info.cx = i;
my_info.cy = k;
Matrix_Multiply(&my_info);
}
}
}
}
#endif
And I guess maybe the memory leak is in Shuffle_Matrix_Multiply function in sse_matrix.h file. But, I am not sure, and now, the memory usage is increasing and my system will crash.
Hope someone can help to figure out and thanks in advance.
You never free the _a and _b allocated in SSE_4_Matrix.
You also allocate a lot dynamically just to throw it away a bit later. For example the _a and _b could be arrays of 16 floats in stack.
I would like to use a header file to help me to check memory leak. The header file as follows:
MemoryLeakChecker.hpp
#ifndef __MemoryLeakChecker_H__
#define __MemoryLeakChecker_H__
#include <crtdbg.h>
#include <cassert>
//for memory leak check
#ifdef _DEBUG
#define DEBUG_CLIENTBLOCK new(_CLIENT_BLOCK,__FILE__,__LINE__)
#else
#define DEBUG_CLIENTBLOCK
#endif
#define _CRTDBG_MAP_ALLOC
#ifdef _DEBUG
#define new DEBUG_CLIENTBLOCK
#endif
inline void checkMemoryLeak() {
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
int m_count = _CrtDumpMemoryLeaks();
assert(m_count == 0);
}
#endif
In my project, i will use MemoryLeakChecker.hpp in the file including main function as follows:
MemoryLeakTest.cpp
#include "MemoryLeakChecker.hpp"
int main() {
//_crtBreakAlloc = 148; //if you only know the memory leak block number is 148 after checking memory leak log, use this to locate the code causing memory leak.
//do some things
atexit(checkMemoryLeak); //check all leak after main() function called
return 0;
}
Run your program in debug mode in Visual Studio, you can get the memory leak log in output window after your program exited. Also, you can find the place where memory leaked in the memory leak log.