Writing array into bitmap c++ - c++

I have trouble with writing array into a bitmap again, so basically I read data from .bmp file where I get data of pixels and I want to make B and R = 0 so here it is my code:
int row_padded = ( Picture.biWidth*3 + 3) & (~3);
unsigned char* data = new unsigned char [row_padded];
unsigned char tmp;
for(int i = 0; i < Picture.biHeight; i++)
{
fread(data, sizeof(unsigned char), row_padded, plik);
for(int j = 0; j < Picture.biWidth*3; j += 3)
{
data[j] = 0;
data[j+2] = 0;
}
}
Now when I have my B and R = 0 I want to save it again to the same file, so I am using:
for(int j = 0; j< Picture.biHeight; j++)
{
fwrite(data,1,Picture.biWidth, f);
}
but nothing works.

fwrite(data,1,Picture.biWidth, f) must be fwrite(data,1,row_padded, f) no ? else only the first third of the bytes are written
note : by definition sizeof(unsigned char) is 1

Related

RC4 Not generating the proper scrambled state array

I have the follow code below to generate a scrambled state array, however, it does not seem to be generating the properly randomized state array for the key (51323).
unsigned char* generateStateArray(unsigned long key) {
unsigned char s[256];
//Load the state array from 1-255
for (int i = 0; i < 256; i++) {
s[i] = i;
}
//Get the binary representation of the key
unsigned long n = key;
int binary[64];
for (int i = 0; i < 64; i++) {
binary[i] = 0;
std::cout << binary[i];
}
std::cout << std::endl;
for (int i = 0; n > 0; i++) {
binary[i] = n % 2;
n /= 2;
}
//Randomize the entries
int j = 0;
for (int i = 0; i < 256; i++) {
j = (j + binary[i % 64] + s[i]) & 255;
char c = s[i];
s[i] = s[j];
s[j] = c;
}
}
The output for S should look like:
But it gives me this output:
Any idea what I'm doing wrong and how I can fix it?

Double free or corruption (!prev) error in my c++ destructor

I have a program that does operations on a vector, not altering them but just reading once and then writing out what is required based on what is given. My program runs but I get this error at the end;
*** Error in './volimage: double free or corruption (!prev): 0x00000000123c10 ***
I have googled, and it seems the problem is with my destructor, but I can't for the life of me find or solve it.
This is the destructor:
VolImage::~VolImage()
{
std::cout << "Destructor" << std::endl;
//deconstructing the vector of slices
int i, j, k;
for (i = 0; i<size; i++)
{
for (j = 0; j<height; j++)
{
delete[] slices[i][j];
}
delete[] slices[i];
}
slices.clear();
}
The vector was populated using the following:
std::vector<unsigned char**> slices; // data for each slice, in order
//populating vector
int i, j, k;
unsigned char ** rows = new unsigned char*[height];
for (i = 0; i < size; i++)
{
for (j = 0; j < height; j++)
{
unsigned char* cols = new unsigned char[width];
string num = "%d" + j;
fileName = baseName + num + ".raw";
myFile.open(fileName);
for (k = 0; k < width; k++)
{
unsigned char x;
myFile >> x;
cols[k] = x;
}
myFile.close();
rows[i] = cols;
}
slices.push_back(rows);
}
Thanks, a hasty reply would be appreciated as i need to submit this soon
You allocated the buffer for storing pointers to pointers only once. You have to allocate ones for each rows.
Also note that the line string num = "%d" + j; has a big chance to cause out-of-range access because "%d" + j is equivalent to &"%d"[j] and only 0 <= j < 3 is allowed.
One more thing: rows[i] = cols; should be rows[j] = cols; as #dasblinkenlight says.
Try this:
//populating vector
int i, j, k;
for (i = 0; i < size; i++)
{
unsigned char ** rows = new unsigned char*[height]; // move this line
for (j = 0; j < height; j++)
{
unsigned char* cols = new unsigned char[width];
std::stringstream ss;
string num;
ss << j;
ss >> num; // convert the integer stored in j to string
fileName = baseName + num + ".raw";
myFile.open(fileName);
for (k = 0; k < width; k++)
{
unsigned char x;
myFile >> x;
cols[k] = x;
}
myFile.close();
rows[j] = cols;
}
slices.push_back(rows);
}
Add #include <sstream> to your code if it doesn't exists to use std::stringstream.
This is not a direct answer, I agree with #MikeCAT's answer. I want to add to the comment posted under the soln : (I dont have enough rep to post a comment directly).
Please see here for why sizeof(slices) returns 24.
How about something like : (width * height * sizeof(slices[0][0][0]) ) * size, provided that slices[0][0][0] exists.

Array of pointers to every n-th element of bigger unsigned char array

I have a huge array of unsigned chars (called main_data) containing some data, which is being refreshed once in a while. I would like to create an array (called plot_data) of pointers to every n-th element of main_data. The idea is to upload new data to main_data from external source and to have reduced plot_data automatically available for my plot. Here is my closest try (it is written in Managed C++, VC++ 2010, WinForms project):
int mainDataSize = 64;
int plotDataSize = 8;
unsigned char* main_data = new unsigned char[mainDataSize];
for (int i = 0; i < mainDataSize; i++) {
main_data[i] = 2 * (i % 32);
}
unsigned char* plot_data = new unsigned char[plotDataSize];
for (int i = 0; i < plotDataSize; i++) {
int idx = (int)(mainDataSize / plotDataSize * i);
plot_data[i] = main_data[idx];
}
printf("Original data:\n");
for (int i = 0; i < mainDataSize; i++) {
printf("%d ", main_data[i]);
}
printf("\n\nData for plot:\n");
for (int i = 0; i < plotDataSize; i++) {
printf("%d ", plot_data[i]);
}
Then, after modification of main_data, I would expect that printing array of pointers would give me modified values. Here is the code for modification and printing:
for (int i = 0; i < mainDataSize; i++) {
main_data[i] = i;
}
printf("\n\nChange made - Main data:\n");
for (int i = 0; i < mainDataSize; i++) {
printf("%d ", main_data[i]);
}
printf("\n\nChange made - Plot data:\n");
for (int i = 0; i < plotDataSize; i++) {
printf("%d ", plot_data[i]);
}
I have been trying to fix this for few hours and it seems I don't get something, which should be relatively simple. Please, help me to understand my mistake.
I would like to create an array (called plot_data) of pointers
The code you posted does not create an array of pointers. It creates a dynamic array of unsigned char's.
If you want to create an array of pointers:
unsigned char** plot_data = new unsigned char*[plotDataSize];
Then in the loop:
plot_data[i] = main_data + idx;
Note this is bad code because there are memory leaks everywhere
I also recommend you use std::vector, as your code will leak memory if the proper calls to delete[] are not done.
#include <vector>
//...
std::vector<unsigned char> main_data(mainDataSize);
//...
std::vector<unsigned char*> plot_data(plotDataSize);
The leaks are now gone.
You are creating an array of chars, not an array of char *'s. You need to change your code to use an array of pointers:
int main()
{
int mainDataSize = 64;
int plotDataSize = 8;
unsigned char ** main_data = new unsigned char * [mainDataSize];
for (int i = 0; i < mainDataSize; i++) {
main_data[i] = new unsigned char(2 * (i % 32));
}
unsigned char ** plot_data = new unsigned char * [plotDataSize];
for (int i = 0; i < plotDataSize; i++) {
int idx = (int)(mainDataSize / plotDataSize * i);
plot_data[i] = main_data[idx];
}
printf("Original data:\n");
for (int i = 0; i < mainDataSize; i++) {
printf("%d ", *main_data[i]);
}
printf("\n\nData for plot:\n");
for (int i = 0; i < plotDataSize; i++) {
printf("%d ", *plot_data[i]);
}
for (int i = 0; i < mainDataSize; i++) {
*main_data[i] = i;
}
printf("\n\nChange made - Main data:\n");
for (int i = 0; i < mainDataSize; i++) {
printf("%d ", *main_data[i]);
}
printf("\n\nChange made - Plot data:\n");
for (int i = 0; i < plotDataSize; i++) {
printf("%d ", *plot_data[i]);
}
for (int i = 0; i < mainDataSize; i++) {
delete main_data[i];
}
delete[] main_data;
delete[] plot_data;
return 0;
}

Counting Sort confusion. Not sorting array (c++)

I was researching counting sort and decided to try an algorithm i found online. Though, it doesn't seem to actually sort my array.
void countSort2(int arr[], int n, int exp)
{
int *output = new int[n]; // output array
int i, count[10] = {0};
// Store count of occurrences in count[]
for (i = 0; i < n; i++)
count[ (arr[i]/exp)%10 ]++;
// Change count[i] so that count[i] now contains actual position of
// this digit in output[]
for (i = 1; i < 10; i++)
count[i] += count[i - 1];
// Build the output array
for (i = n - 1; i >= 0; i--)
{
output[count[ (arr[i]/exp)%10 ] - 1] = arr[i];
count[ (arr[i]/exp)%10 ]--;
}
// Copy the output array to arr[], so that arr[] now
// contains sorted numbers according to curent digit
for (i = 0; i < n; i++)
arr[i] = output[i];
}
int main()
{
int b[10] = {4,3,2,1,6,7,8,9,7,6};
countSort2(b,10,10);
int i = 0;
while(i<10)
{
cout<<b[i]<<endl;
i++;
}
When the array is printed out, I get: "4,3,2,1,6,7,8,9,7,6". Am I calling the function wrong?
This is how you call the method [1]..
10 is the number of elements...
int main()
{
int b[10] = {14,23,22,11,66,67,58,49,17,16};
countSort2(b,10,1);
countSort2(b,10,10);
int i = 0;
while(i<10)
{
cout<<b[i]<<endl;
i++;
}
return 0;
}
This is a radix sort that sorts an array by a decimal digit. The sort is done from least significant digit to most significant digit. This means a series of calls with exp = 1, 10, 100, 1000, 10000, ... .
Here is an example of a radix sort that sorts an array of 64 bit unsigned integers by the bytes in the integers, from least significant to most significant. In this example, the temporary array is passed as a parameter to RadixSort():
typedef unsigned __int64 UI64;
typedef unsigned __int64 * PUI64;
PUI64 RadixSort(PUI64 pData, PUI64 pTemp, size_t count)
{
size_t mIndex[8][256] = {0}; // index matrix
PUI64 pDst, pSrc, pTmp;
size_t i,j,m,n;
UI64 u;
for(i = 0; i < count; i++){ // generate histograms
u = pData[i];
for(j = 0; j < 8; j++){
mIndex[j][(size_t)(u & 0xff)]++;
u >>= 8;
}
}
for(j = 0; j < 8; j++){ // convert to indices
n = 0;
for(i = 0; i < 256; i++){
m = mIndex[j][i];
mIndex[j][i] = n;
n += m;
}
}
pDst = pTemp; // radix sort
pSrc = pData;
for(j = 0; j < 8; j++){
for(i = 0; i < count; i++){
u = pSrc[i];
m = (size_t)(u >> (j<<3)) & 0xff;
pDst[mIndex[j][m]++] = u;
}
pTmp = pSrc;
pSrc = pDst;
pDst = pTmp;
}
return(pSrc);
}

Printing to a STL(stereolithography) file in binary mode

I am trying to print to a stl file and can't print correctly.
There are lot of samples for Hex format printing in C++ but no sample program for binary format. My program is as follow. What is wrong with my program?
string name = "Create by stlwrite.m ";
name = name + currentDateTime();
pFile.setf(ios::left);
pFile.width(sizeof(unsigned char)*80);
//header
pFile << name;
unsigned int size = faces.rows;
//size
pFile.write((char*)&size,sizeof(size));
int height = 25;
unsigned short ** data= new unsigned short *[height];
for(int i = 0; i < height; i++)
{
data[i] = new unsigned short[142000];
}
for(int j = 0; j < 142000; j++)
{
int i = 0;
//for one facets
for(int k = 0; k < (*facets[j]).cols; k++)
{
for(int l = 0; l < (*facets[j]).rows; l++)
{
float f = (*facets[j]).at<float>(l,k);
data[i][j] = *reinterpret_cast<unsigned int *>(&f);
data[i+1][j] = *reinterpret_cast<unsigned int *>(&f)>>16;
i = i + 2;
}
}
//then for the last row
data[height-1][j] = (unsigned short)0;
}
for (int i = 0; i < height; i++)
for (int j = 0; j < faces.rows; j++)
pFile.write ((char*)&data[i][j], sizeof(unsigned short) );
pFile.close();
EDIT1: I follow the idea of Matlab stlwrite.mat program.link
This is the C code to print in binary mode.
The calling function is:
stl_write_binary(X, Y, path)
Where X is 3xM Vertices matrix and Y is 3xN faces matrix. Both are in OpenCV's Mat structure.
Path is the path to store the STL file you can modify it according to your requirement.
The whole code is:
int stl_write_binary(Mat &vertemp, Mat &faces, PathToFolders &path)
{
Mat vertices(vertemp.cols,vertemp.rows,vertemp.type());
vertices = vertemp.t();
cv::Mat** facets = new cv::Mat*[faces.rows];
for(int i = 0; i < faces.rows; i++)
{
facets[i] = new cv::Mat(3,4,CV_32F);
for(int j = 0; j < 3; j++)
{
vertices(Range::all(),Range(faces.at<int>(i,j),faces.at<int>(i,j)+1)).convertTo((*(facets[i]))(Range::all(),Range(j+1,j+2)), CV_32F);
}
}
//Compute their normals
Mat V1(3,faces.rows,CV_32F);
Mat V2(3,faces.rows,CV_32F);
for(int i = 0; i < faces.rows; i++)
{
V1(Range::all(),Range(i,i+1)) = ((*(facets[i]))(Range::all(),Range(2,3))) - ((*(facets[i]))(Range::all(),Range(1,2)));
V2(Range::all(),Range(i,i+1)) = ((*(facets[i]))(Range::all(),Range(3,4))) - ((*(facets[i]))(Range::all(),Range(1,2)));
}
Mat V3(3,faces.rows,CV_32F);
Mat V4(3,faces.rows,CV_32F);
Mat V5(3,faces.rows,CV_32F);
Mat V6(3,faces.rows,CV_32F);
V1(Range(1,2),Range::all()).copyTo(V3(Range(0,1),Range::all()));
V1(Range(2,3),Range::all()).copyTo(V3(Range(1,2),Range::all()));
V1(Range(0,1),Range::all()).copyTo(V3(Range(2,3),Range::all()));
V2(Range(2,3),Range::all()).copyTo(V4(Range(0,1),Range::all()));
V2(Range(0,1),Range::all()).copyTo(V4(Range(1,2),Range::all()));
V2(Range(1,2),Range::all()).copyTo(V4(Range(2,3),Range::all()));
V2(Range(1,2),Range::all()).copyTo(V5(Range(0,1),Range::all()));
V2(Range(2,3),Range::all()).copyTo(V5(Range(1,2),Range::all()));
V2(Range(0,1),Range::all()).copyTo(V5(Range(2,3),Range::all()));
V1(Range(2,3),Range::all()).copyTo(V6(Range(0,1),Range::all()));
V1(Range(0,1),Range::all()).copyTo(V6(Range(1,2),Range::all()));
V1(Range(1,2),Range::all()).copyTo(V6(Range(2,3),Range::all()));
Mat normals(3,faces.rows,CV_32F);
normals = V3.mul(V4) - V5.mul(V6);
V1.release();
V2.release();
V3.release();
V4.release();
V5.release();
V6.release();
Mat normalsqu(3,faces.rows,CV_32F);
Mat normalsqu_colm_summed(1,faces.rows,CV_32F);
normalsqu = normals.mul(normals);
cv::reduce(normalsqu, normalsqu_colm_summed, 0, CV_REDUCE_SUM, CV_32F);
cv::sqrt(normalsqu_colm_summed,normalsqu_colm_summed);//check mem leak
normalsqu.release();
normalsqu_colm_summed = 1/normalsqu_colm_summed;
for(int i = 0; i < faces.rows; i++)
{
normals(Range::all(),Range(i,i+1)) = normals(Range::all(),Range(i,i+1)) * normalsqu_colm_summed.at<float>(i);
}
normalsqu_colm_summed.release();
for(int i = 0; i < faces.rows; i++)
{
normals(Range::all(),Range(i,i+1)).copyTo(((*(facets[i]))(Range::all(),Range(0,1))));
}
normals.release();
//write to stl file
//get file paths
std::vector<std::string> masktoken;
split(path.pathtoimages, '/', masktoken);
path.pathtoSTL = path.pathtoSTL+masktoken[0];
for(int i = 1; i < masktoken.size()-1; i++)
{
path.pathtoSTL = path.pathtoSTL+"/"+masktoken[i];
}
path.pathtoSTL = path.pathtoSTL+"/"+"mesh.stl";
cout<<"Saving file to "<<path.pathtoSTL<<endl;
const char * c = path.pathtoSTL.c_str();
ofstream pFile;
pFile.open (c, ios::out | ios::binary);
if (pFile.is_open())
{
string name = "Create by stlwrite.m ";
name = name + currentDateTime();
pFile.setf(ios::left);
pFile.width(sizeof(unsigned char)*80);
//header
pFile << name;
unsigned int size = faces.rows;
//size
pFile.write((char*)&size,sizeof(size));
int height = (*facets[0]).rows * (*facets[0]).cols * 2 + 1;
unsigned short ** data= new unsigned short *[height];
for(int i = 0; i < height; i++)
{
data[i] = new unsigned short[faces.rows];
}
for(int j = 0; j < faces.rows; j++)
{
int i = 0;
//for one facets
for(int k = 0; k < (*facets[j]).cols; k++)
{
for(int l = 0; l < (*facets[j]).rows; l++)
{
float f = (*facets[j]).at<float>(l,k);
data[i][j] = *reinterpret_cast<unsigned int *>(&f);
data[i+1][j] = *reinterpret_cast<unsigned int *>(&f)>>16;
i = i + 2;
}
}
//then for the last row
data[height-1][j] = (unsigned short)0;
}
for (int i = 0; i < faces.rows; i++)
for (int j = 0; j < height; j++)
pFile.write ((char*)&data[j][i], sizeof(unsigned short) );
pFile.close();
//fclose (pFile);
//delete table
for(int i = 0; i < height; i++)
{
delete[] data[i];
}
delete[] data;
}else{
cout<<"stlwrite:cannotWriteFile"<<" "<<"Unable to write to"<<" "<<path.pathtoSTL<<endl;
}
for(int i = 0; i < faces.rows; i++)
{
(*facets[i]).release();
}
delete[] facets;
return 1;
}