organizing my files in C++ , ARGB to RGBA - c++

I'm trying to understand how the hpp, cpp, and main all work together. for this example I'm working on a code that coverts ARGB to RGBA and I'm confused on what to put in each file.
This is my code:
color.hpp
using namespace std;
#include <stdio.h>
#include <stdio.h>
#include <iostream>
#ifndef colors_hpp
#define colors_hpp
/* colors_hpp */
string getHex();
uint32_t fromArgb();
#endif
color.cpp
#include "colors.hpp"
#include <iostream>
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
template <typename T>
struct Color
{
public:
/* Works fine!!! */
Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a = 255)
{
buffer((r << 0) | (g << 8) | (b << 16) | (a << 24));
}
Color(const uint32_t argb)
{
buffer = fromArgb(argb);
}
inline uint32_t fromArgb(uint32_t argb)
{
return
// Source is in format: 0xAARRGGBB
((argb & 0x00FF0000) >> 16) | //____RR
((argb & 0x0000FF00)) | //_GG_
((argb & 0x000000FF) << 16) | //__BB_
((argb & 0xFF000000)); //AA____
// Return value is in format: 0xAABBGGRR
}
inline uint8_t getRed(void) const
{
return (buffer >> 0) & 0xFF;
}
inline uint8_t getGreen(void) const
{
return (buffer >> 8) & 0xFF;
}
inline uint8_t getBlue(void) const
{
return (buffer >> 16) & 0xFF;
}
inline uint8_t getAlpha(void) const
{
return (buffer >> 24) & 0xFF;
}
/* Works fine!!!*/
std::string getHex(void) const
{
std::string result = "#";
char colorBuffer[255] = {};
// Order is intentionally end to beginning
sprintf_s(colorBuffer, 255, "%.2X", getAlpha());
result.append(colorBuffer);
sprintf_s(colorBuffer, 255, "%.2X", getBlue());
result.append(colorBuffer);
sprintf_s(colorBuffer, 255, "%.2X", getGreen());
result.append(colorBuffer);
sprintf_s(colorBuffer, 255, "%.2X", getRed());
result.append(colorBuffer);
return result;
}
private:
uint32_t buffer;
};
main.cpp
int main(int argc, char**argv) {
fromArgb(255,255,0,0);
getHex();
}
I'm not able to understand where to use or call the struct or functions, and i'm really confused on what to put in hpp, cpp, and main files.

Some advice
Remove this template <typename T>
Move struct Color { ... }; to color.hpp (all of it, you can delete color.cpp, it is not needed).
Remove using namespace std; from color.hpp
Remove string getHex(); uint32_t fromArgb(); from color.hpp
change main to this
int main(int argc, char**argv) {
Color c;
c.fromArgb(255,255,0,0);
std::cout << c.getHex() << std::endl;
}
The main problem seems to be that you don't know how objects work. In order to use the fromArgb and getHex methods you need a Color object. So in my code I declared a Color object like this Color c; and then I used that colour object like this c.fromArgb(255,255,0,0); and this c.getHex(). How to use classes and objects is a more important topic than how to organise your code into headers and cpp files.
I haven't tested these changes. If there are any further problems you can't figure out then ask again.

Related

Why would elements in a union be unaligned

I've spent a couple hours trying to make sense of the results of a quick mockup I made for an application I am working on. Here is what I am trying to do. I have an incoming message, which among other things has a 512 bit field which can have multiple forms depending on its type and needs to be translated to usable data. The first type results in the 4 x 32-bit words originating from the little endian LSB
|31 0|
|-------------word1--------------|
|-------------word2--------------|
|-------------word3--------------|
|-------------word4--------------|
|-------------unused-------------|
...
|-------------unused-------------|
512
The second is significantly larger and has 4 x 128 bit words but still occupies the same overall space
|31 0|
|-------------word1--------------|
|----------word1 cont.-----------|
|----------word1 cont.-----------|
|----------word1 cont.-----------|
|-------------word2--------------|
|----------word2 cont.-----------|
|----------word2 cont.-----------|
|----------word2 cont.-----------|
|-------------word3--------------|
|----------word3 cont.-----------|
|----------word3 cont.-----------|
|----------word1 cont.-----------|
|-------------word4--------------|
|----------word4 cont.-----------|
|----------word4 cont.-----------|
|----------word4 cont.-----------|
I am attempting to make a class that processes this into 4 accessible void* fields, regardless of if they are type 1 and convertible to a unsigned integer or 128 bit of void data. Here is the code.
The first header is just common structures. I attempted to minimize bit shifting by using unions.
// Common.hpp
#ifndef COMMON_HPP
#define COMMON_HPP
#include <cstdint>
#include <cstddef>
enum WaveFormType
{
TYPE1,
TYPE2
};
enum CommandWordEnum
{
COMMAND1,
COMMAND2,
COMMAND3,
COMMAND4
};
// 384 + 32 + 32 + 32 + 32 = 512 bits
struct Type1CommandWord
{
uint32_t unused[12];
uint32_t word[4];
};
// 128 + 128 + 128 + 128 = 512 bits
struct Type2CommandWord
{
uint32_t word1[4];
uint32_t word2[4];
uint32_t word3[4];
uint32_t word4[4];
};
union CommandWordData
{
uint8_t buffer[64];
Type1CommandWord type1CommandWord;
Type2CommandWord type2CommandWord;
};
#endif /* COMMON_HPP */
The second class is a mockup of the incoming message. In reality it is a very large message, but at the moment, these fields are the ones I am concerned about.
// Message.hpp
#ifndef MESSAGE_HPP
#define MESSAGE_HPP
#include <cstdint>
#include "Common.hpp"
//Test Message
struct Message
{
uint8_t data[64];
WaveFormType waveFormType;
};
#endif /* MESSAGE_HPP */
The next class is the actual receiver class
// CommandReceiver.hpp
#ifndef COMMAND_RECEIVER_HPP
#define COMMAND_RECEIVER_HPP
#include "Common.hpp"
#include "Message.hpp"
#include <cstdlib>
class CommandReceiver
{
public:
CommandReceiver(Message &_message);
virtual ~CommandReceiver() = default;
WaveFormType getWaveFormType() const;
size_t getCommandWordSize() const;
void *getCommandWord(CommandWordEnum cmdWordEnum) const;
private:
CommandWordData commandWordData;
WaveFormType waveFormType;
};
#endif /* COMMAND_RECEIVER_HPP */
and the definition
// CommandReceiver.cpp
#include "CommandReceiver.hpp"
#include <string.h>
CommandReceiver::CommandReceiver(Message &_message)
: waveFormType(_message.waveFormType)
{
memset(
this->commandWordData.buffer,
0,
sizeof(commandWordData.buffer));
memcpy(
this->commandWordData.buffer,
&_message.data,
sizeof(this->commandWordData.buffer));
}
WaveFormType CommandReceiver::getWaveFormType() const
{
return waveFormType;
}
size_t CommandReceiver::getCommandWordSize() const
{
return((waveFormType == TYPE2)
? sizeof(this->commandWordData.type2CommandWord.word1)
: sizeof(this->commandWordData.type1CommandWord.word[1]));
}
void *CommandReceiver::getCommandWord(CommandWordEnum cmdWordEnum) const
{
void * cmdPtr = (void*)malloc(this->getCommandWordSize());
switch(cmdWordEnum)
{
case COMMAND1:
if(this->waveFormType == TYPE2)
{
memcpy(
cmdPtr,
this->commandWordData.type2CommandWord.word2,
this->getCommandWordSize());
}
else
{
memcpy(
cmdPtr,
&this->commandWordData.type1CommandWord.word[1],
this->getCommandWordSize());
}
break;
case COMMAND2:
if(this->waveFormType == TYPE2)
{
memcpy(
cmdPtr,
&this->commandWordData.type2CommandWord.word2,
this->getCommandWordSize());
}
else
{
memcpy(
cmdPtr,
&this->commandWordData.type1CommandWord.word[2],
this->getCommandWordSize());
}
break;
case COMMAND3:
if(this->waveFormType == TYPE2)
{
memcpy(
cmdPtr,
&this->commandWordData.type2CommandWord.word3,
this->getCommandWordSize());
}
else
{
memcpy(
cmdPtr,
&this->commandWordData.type1CommandWord.word[3],
this->getCommandWordSize());
}
break;
case COMMAND4:
if(this->waveFormType == TYPE2)
{
memcpy(
cmdPtr,
&this->commandWordData.type2CommandWord.word4,
this->getCommandWordSize());
}
else
{
memcpy(
cmdPtr,
&this->commandWordData.type1CommandWord.word[4],
this->getCommandWordSize());
}
break;
default:
// memcpy(
// cmdPtr,
// nullptr,
// this->getCommandWordSize());
break;
}
return cmdPtr;
}
finally the main file which I made a few simple tests.
What I am confused about is why a cannot get addresses to
align. See below.
#include "CommandReceiver.hpp"
#include <iostream>
#include <cstring>
#include <cassert>
//test
int main()
{
// Confirm substructures are the correct size
assert(sizeof(Type1CommandWord) == 512 / 8);
assert(sizeof(Type2CommandWord) == 512 / 8);
// Set up tests
Message msg;
memset(&msg.data, 0, sizeof(msg.data));
msg.data[60] = 0xDE;
msg.data[61] = 0xAD;
msg.data[62] = 0xC0;
msg.data[63] = 0xDE;
msg.waveFormType = TYPE1;
// Call the constructor
CommandReceiver cmdRec(msg);
// Confirm values copied in constructor match
assert(cmdRec.commandWordData.buffer[60] == 0xDE);
assert(cmdRec.commandWordData.buffer[61] == 0xAD);
assert(cmdRec.commandWordData.buffer[62] == 0xC0);
assert(cmdRec.commandWordData.buffer[63] == 0xDE);
std::cout << "0x"<< &cmdRec.commandWordData.buffer + 60 << "\n";
std::cout << "0x"<< &cmdRec.commandWordData.buffer + 61 << "\n";
std::cout << "0x"<< &cmdRec.commandWordData.type1CommandWord + (32 * 4) << "\n";
The bottom line is it is not working and the problem is fairly early on. I just cannot figure out why. Here is the output:
0x0x7ffc3139f2e8
0x0x7ffc3139f328
0x0x7ffc313a03e8
The first two fields should be adjacent characters of an unsigned char array. so I would expect them to be 1 byte off, not 744 bytes.
The third field should be equal to the first but instead it is 1100 bytes off. I'm obviously missing something big.
What am I missing? I'd also be interested in suggestions about better ways of doing this. However, the endpoints have to remain the same.
With pointer arithmetic, type of pointer does count:
int* p = /*..*/;
char* c = reinterpret_cast<char*>(p);
int n = /*..*/;
assert(reinterpret_cast<char*>(p + n) == c + n * sizeof(int));
// ^^^^^^^^^^^^^
So in your case
&cmdRec.commandWordData.type1CommandWord + (32 * 4)
"is"
reinterpret_cast<Type1CommandWord*>(
reinterpret_cast<const char*>(
&cmdRec.commandWordData.type1CommandWord
) + (32 * 4) * sizeof(Type1CommandWord)
)
and
&cmdRec.commandWordData.buffer + 60 is not &cmdRec.commandWordData.buffer[60] but
reinterpret_cast<uint8_t(*)[64]>(reinterpret_cast<char*>(&cmdRec.commandWordData.buffer) + 60 * sizeof(uint8_t[64]))

How do I create BMP files using c++?

I'm trying to create a class that saves BMP image given the pixels.
This is my .h:
#ifndef _IMAGE_SAVER_
#define _IMAGE_SAVER_
#include <vector>
#include <fstream>
#include <sstream>
#include <string>
#include <bitset>
//#define _DEBUG_
#ifdef _DEBUG_
#include <iostream>
#endif
#include <stdint.h>
typedef struct BMFileHeader {
uint16_t _bfType = 19778;
uint32_t _bfSize;
uint16_t _bfReserved1 = 0;
uint16_t _bfReserved2 = 0;
uint32_t _bfOffBits = 54;
} BMFileHeader;
typedef struct BMInfoHeader {
uint32_t _biSize = 40;
uint32_t _biWidth;
uint32_t _biHeight;
uint16_t _biPlanes = 1;
uint16_t _biBitCount = 24;
uint32_t _biCompression = 0;
uint32_t _biSizeImage = 0;
uint32_t _biXPelsPerMeter = 3780;
uint32_t _biYPelsPerMeter = 3780;
uint32_t _biClrUser = 0;
uint32_t _biClrImportant = 0;
} BMInfoHeader;
typedef struct RGBQuad {
uint8_t _blue;
uint8_t _green;
uint8_t _red;
} RGBQuad;
class ImageSaver
{
public:
ImageSaver() = delete;
ImageSaver(const uint32_t& height, const uint32_t& width, const std::vector<RGBQuad>& pixels) : _RGBQuad_Vector(pixels) {
this->_Info_Header._biHeight = height;
this->_Info_Header._biWidth = width;
};
void saveImage(const std::string& fileName);
protected:
void setFileSize();
void createImageFile(const std::string& fileName);
private:
BMFileHeader _File_Header;
BMInfoHeader _Info_Header;
std::vector<RGBQuad> _RGBQuad_Vector;
};
#endif
this is my .cpp:
#include "ImageSaver.h"
void ImageSaver::saveImage(const std::string& fileName)
{
this->setFileSize();
this->createImageFile(fileName);
}
void ImageSaver::setFileSize()
{
uint32_t height = this->_Info_Header._biHeight;
uint32_t width = this->_Info_Header._biWidth;
this->_File_Header._bfSize = 3 * (height * width) + 54;
}
void ImageSaver::createImageFile(const std::string& fileName)
{
std::ofstream imageFile(fileName + ".bmp", std::ios::binary);
imageFile.write((char*)&this->_File_Header, 14);
imageFile.write((char*)&this->_Info_Header, 40);
size_t numberOfPixels = this->_Info_Header._biHeight * this->_Info_Header._biWidth;
for (int i = 0; i < numberOfPixels; i++) {
imageFile.write((char*)&(this->_RGBQuad_Vector[i]), 3);
}
imageFile.close();
}
and this is my main.cpp:
#include "ImageSaver.h"
#include <vector>
#include <iostream>
int main() {
std::vector<RGBQuad> pixels;
for (unsigned i = 0; i < 512 * 512; i++) {
RGBQuad pixel;
pixel._blue = 0;
pixel._green = 255;
pixel._red = 255;
pixels.push_back(pixel);
}
ImageSaver im(512, 512, pixels);
im.saveImage("scene1");
std::cout << "ESTOP0" << std::endl;
return 0;
}
Whenever I try to create an image file, it says that that image file is corrupt, even though it seems to me that I've been following BMP format properly. I've analyzed raw binary data and data seems (to me) to be correct. GIMP can open the picture, but it gives a black 512x512 picture which is not what I'm going for here.
Certainly you miss #pragma pack. Wrap your structures with #pragma pack(push,1)/#pragma pack(pop)
When structures represent memory layout and should have no padding, even if having unaligned data, pack structures.
It is very helpful to have static_assert on expected sizeof value for such cases.
Additionally, when you pack them, the RGBQuad will become only 3 bytes. If you really want triple, suggest renaming it to triple. Otherwise add dummy or alpha byte to complete it to quad.

how can I save the color then .obj file , using PCL

pcl version 1.9.1
I read .txt file,and create PointXYZRGB ,set x、y、z and rgb,like this:
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/obj_io.h>
#include <pcl/PolygonMesh.h>
#include <pcl/point_cloud.h>
#include <pcl/io/vtk_lib_io.h>
#include <pcl/visualization/cloud_viewer.h>
using namespace std;
using namespace pcl;
int main()
{
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
std::string s;
while (cin >> s) {
ifstream input(s);
std::string line;
std::int32_t number = 0;
while (getline(input, line))
{
if (number % 10000 == 0) {
cout << "重置点数"<<number<<endl;
cloud->points.resize(number + 10100);
}
stringstream sstr(line);
string token;
int32_t tokennumber = 0;
while (getline(sstr, token, ','))
{
if (tokennumber == 0) {
cloud->points[number].x = atof(token.c_str());
}
else if (tokennumber == 1) {
cloud->points[number].y = atof(token.c_str());
}
else if (tokennumber == 2) {
cloud->points[number].z = atof(token.c_str());
}
else if (tokennumber == 3) {
int32_t num = std::stoi(token.substr(1), NULL, 16);
int32_t red = num >> 16 & 0xFF;
int32_t green = num >> 8 & 0xFF;
int32_t blue = num & 0xFF;
cloud->points[number].r = red;
cloud->points[number].g = green;
cloud->points[number].b = blue;
uint32_t rgb = (red << 16) | (green << 8) | (blue);
cloud->points[number].rgb = rgb;
}
tokennumber++;
}
number++;
}
pcl::PolygonMesh mesh;
pcl::toPCLPointCloud2(*cloud, mesh.cloud);
pcl::io::saveOBJFile("C:\\Users\\ASUS\\Desktop\\out_color2.obj", mesh);
cout << "文件保存完毕";`
but when I read the .obj file , use loadPolygonFileOBJ(),I find the PointXYZRGB doesn't have rgb,it lost color
#include <string>
#include <pcl/io/io.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/obj_io.h>
#include <pcl/PolygonMesh.h>
#include <pcl/point_cloud.h>
#include <pcl/io/vtk_lib_io.h>
#include <pcl/visualization/cloud_viewer.h>
using namespace pcl;
int main()
{
pcl::PolygonMesh mesh;
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>);
std::string s = "C:\\Users\\ASUS\\Desktop\\out_color2.obj";
pcl::io::loadPolygonFileOBJ(s, mesh);
pcl::fromPCLPointCloud2(mesh.cloud, *cloud);
for (int i = 0; i < cloud->points.size(); i++) {
PointXYZRGB point = cloud->points[i];
cout << point.z << point.x << point.y<<endl;
cout << point.r << point.g << point.b << endl;
}
boost::shared_ptr<visualization::PCLVisualizer> viewer(new visualization::PCLVisualizer("3D viewer"));
viewer->addPointCloud<PointXYZRGB>(cloud, "sample cloud");
viewer->setBackgroundColor(255, 255, 255);
while (!viewer->wasStopped()) {
viewer->spinOnce(100);
boost::this_thread::sleep(boost::posix_time::microseconds(1000));
}
}
return 0;
}
before saveOBJFile(),the viewer.showCloud() can display color
but when saveOBJFile() and loadPolygonFileOBJ() after , the color lost
Is that .obj file contain color?
Or something wrong?
so how can I save the color then .obj file
Generally .obj file is not suitable to hold colors. To use color in PCL, use ply file instead. Some other applications such as Meshlab on the other hand supports obj file with color.

How to create an image in c++ with an 2d rgb array?

Well I'm using a restAPI to get a 2d numpy rgb-array from python and I want to create and image from it using c++ .Do you have any idea how to do it? or Do you know a similar library of numpy fro c++?
Its pretty simple to create a bitmap (.bmp extensions).
You can either use a library, like this one:
https://github.com/ArashPartow/bitmap. A library with a narrow use case is usually pretty readable. The logic is all contained in a single hpp file in this case. Looking at it, its a little complex because it handles a ton of different cases.
Or you can just do it yourself. Look up how to write a binary bitmap header and use fstream to write it out to a file. You'll want to use the binary options when opening the file for writing ios::out | ios::binary. You can find the details of the bitmap header and file format here: https://en.wikipedia.org/wiki/BMP_file_format
By the way, Wikipedia has many decent references on binary file formats with bit-by-bit tables.
For an extremely naive implementation that does not handle a bunch of different formats, I've done this in the past.
BitmapFileHeader.h
#pragma once
#include <cstdint>
#pragma pack(push, 2)
struct BitmapFileHeader
{
char header[2]{'B', 'M'};
uint32_t fileSize;
uint32_t reserved{};
uint32_t dataOffset;
};
#pragma pack(pop)
BitmapInfoHeader.h
#pragma once
#include <cstdint>
#pragma pack(push, 2)
struct BitmapInfoHeader
{
uint32_t headerSize{ 40 };
uint32_t width{ 0 };
uint32_t height{ 0 };
uint16_t planes{ 1 };
uint16_t bitsPerPixel{ 24 };
uint32_t compression{ 0 };
uint32_t dataSize{ 0 };
uint32_t horizontalResolution{ 2400 };
uint32_t verticalResolution{ 2400 };
uint32_t colors{ 0 };
uint32_t importantColors{ 0 };
};
#pragma pack(pop)
Bitmap.h
#include <string>
#include <iostream>
#include <cstdint>
#include <memory>
#include <fstream>
#include "BitmapFileHeader.h"
#include "BitmapInfoHeader.h"
using namespace std;
class Bitmap
{
private:
int m_width{ 0 };
int m_height{ 0 };
unique_ptr<uint8_t[]> m_pixels{ nullptr };
public:
struct RBG {
uint8_t r;
uint8_t b;
uint8_t g;
};
Bitmap(int width, int height) : m_width(width),
m_height(height), m_pixels(new uint8_t[width * height * sizeof(RBG)]{}) {};
void setPixel(int, int, RBG);
void setDimensions(int, int);
int getSize();
bool write(string);
~Bitmap();
};
Bitmap.cpp
#include "stdafx.h"
#include "Bitmap.h"
using namespace std;
void Bitmap::setPixel(int x, int y, RBG color)
{
uint8_t *pixel = m_pixels.get();
pixel = pixel + ((y * sizeof(RBG)) * m_width) + (x * sizeof(RBG));
// little endian
pixel[0] = color.b;
pixel[1] = color.g;
pixel[2] = color.r;
}
void Bitmap::setDimensions(int w, int h)
{
m_width = w;
m_height = h;
}
int Bitmap::getSize()
{
return m_width * m_height * sizeof(RBG);
}
bool Bitmap::write(string filename)
{
BitmapFileHeader fileHeader;
BitmapInfoHeader infoHeader;
fileHeader.fileSize = sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader) + getSize();
fileHeader.dataOffset = sizeof(BitmapFileHeader) + sizeof(BitmapInfoHeader);
infoHeader.width = m_width;
infoHeader.height = m_height;
ofstream file;
file.open(filename, ios::out | ios::binary);
if (!file)
{
return false;
}
file.write(reinterpret_cast<char *>(&fileHeader), sizeof(fileHeader));
file.write(reinterpret_cast<char *>(&infoHeader), sizeof(infoHeader));
file.write(reinterpret_cast<char *>(m_pixels.get()), getSize());
file.close();
return true;
}
Bitmap::~Bitmap()
{
cout << "bitmap destroyed" << endl;
}

Boost::mpi sending array

Good Morning
I'm implementing a distributed image normalization algorithm an I'm using Boost::mpi with a class Pixel that contain the serialization code,
#ifndef PIXEL_H
#define PIXEL_H
#include <boost/mpi.hpp>
#include <boost/serialization/access.hpp>
class Pixel
{
private:
unsigned char m_red;
unsigned char m_green;
unsigned char m_blue;
friend class boost::serialization::access;
template <class Archive>
void serialize(Archive &ar, const unsigned int version) {
ar & m_red;
ar & m_green;
ar & m_blue;
}
public:
Pixel();
Pixel(unsigned char red,unsigned char green,unsigned char blue) : m_red(red), m_green(green), m_blue(blue) {};
virtual ~Pixel();
unsigned char getRed();
void setRed(unsigned char val);
unsigned char getGreen();
void setGreen(unsigned char val);
unsigned char getBlue();
void setBlue(unsigned char val);
void setColor (unsigned char red,unsigned char green,unsigned char blue);
};
The main.cpp is
#include <iostream>
#include <boost/mpi.hpp>
#include <vector>
#include "include/Pixel.h"
#include <cstdlib>
#include <ctime>
#define ALTEZZA 2
#define LARGHEZZA 2
namespace mpi=boost::mpi;
int main(int argc, char * argv[]) {
std::cout<<"Inizializzazione dell'ambiente MPI"<<std::endl;
mpi::environment env;
mpi::communicator world;
Pixel **vettore;
int i,j;
//Inizializzazione della matrice di test
if(world.rank() == 0){
std::cout<<"Inizializzazione matrice di test..."<<std::endl;
std::srand(std::time(0));
vettore = new Pixel *[ALTEZZA];
for (i = 0; i < ALTEZZA; i++) {
vettore[i] = new Pixel[LARGHEZZA];
}
for (i = 0; i < ALTEZZA; i++) {
for (j = 0; j < LARGHEZZA; j++) {
vettore[i][j].setColor(std::rand() % 256, std::rand() % 256, std::rand() % 256);
std::cout<<"Vettore["<<i<<"]["<<j<<"] = ("<<int(vettore[i][j].getRed())<<","<<int(vettore[i][j].getGreen())<<","<<int(vettore[i][j].getBlue())<<");"<<std::endl;
}
}
}
if (world.rank() == 0) {
std::cout<<"Invio matrice.."<<std::endl;
world.send(1, 0, vettore[0]);
}else {
Pixel *px;
world.recv(0, 0, px);
for (j = 0; j < LARGHEZZA; j++) {
std::cout<<int(px[j].getRed())<<" "<<int(px[j].getGreen())<<" "<<int(px[j].getBlue())<<std::endl;
}
}
return 0;
}
but when i run the program the cout on the receiving process print wrong value like this
Inizializzazione dell'ambiente MPI
Inizializzazione dell'ambiente MPI
Inizializzazione matrice di test...
Vettore[0][0] = (170,103,165);
Vettore[0][1] = (84,0,186);
Vettore[1][0] = (93,228,162);
Vettore[1][1] = (31,100,204);
Invio matrice..
170 103 165
217 1 0
I think that the problem is the 2d array because if I use std::vector i haven't this problem but I don't understand why.
I would imagine you have several problems (I can't test as I don't have a capable MPI installation..)
Firstly, your send() is wrong, currently you are triggering the overload:
template<typename T> void send(int, int, const T &) const;
But you are trying to send a raw array, I imagine the fix here has to be to pass the count, for example:
world.send(1, 0, vettore[0], 2); // 2 Pixels
Secondly, on the receiver side (this I'm not sure about), but I imagine you need to have a suitable array to read the data into.., for example:
Pixel px[LARGHEZZA];
world.recv(0, 0, px, 2);
I think this should fix your problems...