How to convert Halide::Buffer<unsigned char> to c++ array - c++

In lesson_02_input_image.cpp, I am trying to transpose Buffer<uint8_t> type data to a c++ array so that compare the time consumption between halide and c++. The code is like :
Halide::Buffer<uint8_t> input = load_image("images/rgb.png");
float *img = input.copy_to_device(halide_opencl_device_interface());
And the code got error:cannot convert ‘Halide::Buffer’ to ‘float*’ in initialization.It seems that input is Halide::Buffer type, how could I fix that?

Related

uint16_t array to string and back c++

I have a uint16_t array and I want to be able to convert it to a string and convert it back.
The goal is to save the array with this library and load it back into a variable.
What would be the best approach?
I tried to read the json key to the variable
uint16_t *program;
program = json["script"];
but it gives me this error:
no suitable conversion function from "nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, uint64_t, double, std::allocator, nlohmann::adl_serializer, std::vector<uint8_t, std::allocator<uint8_t>>>" to "uint16_t *" exists
That's why I thought that maybe I should convert it to another datatype with available conversion first.
Solved:
I used vector<uint16_t> instead of an uint16_t array, which had available conversion in the library.

Type conversion in open cv

I am trying to convert an uint32_t* into a format that could be accepted by a Mat object (from open cv). I do not need to display the data from the Mat, I am simply using the mat to transport and pack information.I know that opencv does not use uint32_t and as a workaround I used int. What I did is the following:
Mat package = Mat(width,height, CV_32SC4);
int *dst1 = package.data;
//code that works with the dst
//finally put it back in the package
package.data = dst1;
The above code gives me an error at the second line. (Cannot convert from 'int *' to 'uchar *')

using reinterpret_cast to convert char* to vector<byte>

I am using a library called botan for encryption. but the case here is not related with the library, it seems to be a issue in c++ or casting. using the library a 16 byte long vector is created as below.
SecureVector<byte> salt = rng.random_vec(16);
then it is converted to a string as,
std::string salt_string ((const char*)salt.begin() , salt.size());
using Qt i can just read the srting as,
ui->textEdit->append("Salt is : "+ QString::fromStdString(salt_string));
now I need to write this to a file and regenerate the vector at a later time.
It is written to a file as,
ofstream outfile ("salt.txt" , std::ios::binary);
outfile.write((const char*)salt.begin(), salt.size());
up to this point the code looks working great and the problem occurs when reading and regenerating the vector.
here is how i read the data to a char* array,
ifstream infile ("salt.txt" , std::ios::binary );
char* salt = new char[16];
infile.read(salt , 16 );
now I need to recreate the SecureVector<byte> as salt2 , I tried to do it using reinterpret_cast as below,
SecureVector<byte> salt2 = reinterpret_cast<byte> (salt);
which compiles without errors but returns a empty string when try to display as i displayed salt above. what am i doing wrong or how to do the conversion correctly. any help or advice will be highly appreciated.
reinterpret_cast doesn't magically convert one type to another, even if it appears to do so. Frankly, unless and until you understand what it does do, you should never use it.
To make a vector contain the bytes from an array, create the vector and then add the bytes to it. You can't do this using a cast.
SecureVector<byte> salt2(salt, salt + 16);
The problem here is your assignment:
SecureVector<byte> salt2 = reinterpret_cast<byte>(salt);
You are converting the char* into a byte (So a pointer is being converted to a byte (I assume you meant to convert it to a byte* (note the extra *) but that did not compile so you took off the * to see what would hapen)). What this does is undefined (if not a very bad idea). But You have a byte.
But it compiles because SecureVector<byte> has a constructor that takes a size_t as a parameter. A size_t is an integer as is a byte and thus the compiler generated an auto conversion and constructed you vector using the byte as a size.
What you actually want to do is use the constructor that takes a pointer to byte and a size. see: SecureVector.
SecureVector<byte> salt2(reinterpret_cast<byte*>(salt), 16);
It's ugly, but due to the type conversion you may have to just do a for loop here:
for(int i = 0; i < 16; ++i)
salt2.push_back(reinterpret_cast<byte>(salt[i]));
I don't think casting like that can work because a vector isn't laid out the same way an array is in memory, it has to contain other information like its size.

Writing uchar* data to file

I am using the OpenCV library, which has a class called Mat, representing a matrix, with data stored in an array at uchar* Mat::data. I want to write this data to a binary file using C++.
Here is my code:
cv::Mat m(3, 3, CV_8UC1); // This basically creates a 3-by-3 matrix
std::fstream fileOut("file.bin", std::ios::out | std::ios::binary);
fileOut.write((char*)m.data, 9); // This should write 9 bytes of data
And I am getting the error message:
invalid conversion from ‘uchar* {aka unsigned char*}’ to ‘std::basic_istream<char>::char_type* {aka char*}’
What should I do differently?
it's an illegal conversion in C++
use reinterpret_cast<const char*>(m.data)

C++ Variable Conversion

I need to pass one of my parameters to a write() function. It is asking for a type of 'const void*' I am a PHP guy and don't know C++ very well.
Here is my parameter:
const fmx::Text& distance = dataVect.AtAsText(3);
I don't know of any other way to pull in that field. I would love to just declare it const void* but I don't know how.
I guess just converting it would be easier than trying to pull it in the correct way??
The error message: cannot convert const fmx::Text to const void* for argument 2
write(fd, distance, 4);
I know this worked so can I just convert?
const void* s = "5000";
This is for a plugin in FileMaker so I don't really get c++ here.
Is there more anyone would need to help me solve this??
Thanks so much!
If fmx::Text was a pointer type, the compiler would automatically convert a reference to it into a void*. You need to use the address-of operator to give the function a pointer to work with:
write(fd, &distance, 4);
I don't really know filemaker, but this link shows that fmx::Text has a GetBytes function. You can then pass the pointer to the buffer filled with this function.
I'm assuming you actually want the text string.
I think you need to check the api for fmx::Text to get the string you want. Here is something I found to get the string out.
Looks like the type stores the data as UTF16, so you have to run a bit of code to get a string out, then pass it to your write function:
//a function to convert to a normal string
std::string getString(fmx::Text& Text)
{
char buffer[512] = {0}; //NOTE YOU HAVE A STRING SIZE LIMIT
// convert original text to ASCII text
outText.GetBytes( buffer, sizeof(buffer)-1, 0, Text.GetSize(), fmx::Text::kEncoding_Native );
return buffer;
}
Then call the function
std::string myString = getString(distance);
write(fd, myString.c_str(), myString.size());
Note I'm assuming a lot here...that you want a string in the current encoding, and not the raw UTF16 data from 'distance'. AND that GetBytes will not mangle the null characters in buffer....
You'll also need to include <string> in your c++ file.