Skip to content

Commit

Permalink
Use unsigned chars for image rendering
Browse files Browse the repository at this point in the history
This ensures that the rendered bitmaps don't come out weirdly on
platforms where chars are singed by default.
  • Loading branch information
stephenswat committed Nov 20, 2024
1 parent 4cb1f81 commit f96c7a7
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 46 deletions.
56 changes: 28 additions & 28 deletions examples/common/bitmap/bitmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* the necessary headers to turn it into a bitmap image.
*/
void render_bitmap(
char * img, unsigned int w, unsigned int h, std::string fname
unsigned char * img, unsigned int w, unsigned int h, std::string fname
)
{
/*
Expand Down Expand Up @@ -51,7 +51,7 @@ void render_bitmap(
* This is the definition of the BMP header... It's rather esoteric, but it
* is necessary.
*/
char header[54] = {
unsigned char header[54] = {
/*
* Bytes [0:1]: The BMP magic numbers.
*/
Expand All @@ -60,10 +60,10 @@ void render_bitmap(
/*
* Bytes [2:5]: The total size of this file.
*/
static_cast<char>(filesize),
static_cast<char>(filesize >> 8),
static_cast<char>(filesize >> 16),
static_cast<char>(filesize >> 24),
static_cast<unsigned char>(filesize),
static_cast<unsigned char>(filesize >> 8),
static_cast<unsigned char>(filesize >> 16),
static_cast<unsigned char>(filesize >> 24),
/*
* Bytes [6:9]: Reserved bytes which nobody uses.
*/
Expand All @@ -74,10 +74,10 @@ void render_bitmap(
/*
* Bytes [10:13]: The starting position of the image segment.
*/
static_cast<char>(offset),
static_cast<char>(offset >> 8),
static_cast<char>(offset >> 16),
static_cast<char>(offset >> 24),
static_cast<unsigned char>(offset),
static_cast<unsigned char>(offset >> 8),
static_cast<unsigned char>(offset >> 16),
static_cast<unsigned char>(offset >> 24),
/*
* Bytes [14:17]: This identifies the size of the DIB header, which in
* this case identifies it as BITMAPINFOHEADER.
Expand All @@ -89,17 +89,17 @@ void render_bitmap(
/*
* Bytes [18:21]: The width of the image.
*/
static_cast<char>(w),
static_cast<char>(w >> 8),
static_cast<char>(w >> 16),
static_cast<char>(w >> 24),
static_cast<unsigned char>(w),
static_cast<unsigned char>(w >> 8),
static_cast<unsigned char>(w >> 16),
static_cast<unsigned char>(w >> 24),
/*
* Bytes [22:25]: The height of the image.
*/
static_cast<char>(h),
static_cast<char>(h >> 8),
static_cast<char>(h >> 16),
static_cast<char>(h >> 24),
static_cast<unsigned char>(h),
static_cast<unsigned char>(h >> 8),
static_cast<unsigned char>(h >> 16),
static_cast<unsigned char>(h >> 24),
/*
* Bytes [26:27]: The number of color planes, which is always 1.
*/
Expand Down Expand Up @@ -145,12 +145,12 @@ void render_bitmap(
* Bitmap rows must be padded to multiples of 4, so we will keep these
* padding zeros handy for when we need to do that.
*/
char padding[3] = {0, 0, 0};
unsigned char padding[3] = {0, 0, 0};

/*
* Start off by writing the 54 byte header to the file.
*/
bmp.write(header, 54);
bmp.write(reinterpret_cast<char *>(header), 54);

/*
* Here we compute the colour palette. Each byte identifies one of 256
Expand Down Expand Up @@ -189,14 +189,14 @@ void render_bitmap(
* For each of the 256 colours, write the output RGB colour to the file
* in four bytes.
*/
char cmap[4] = {
static_cast<char>((rp + q) * 255),
static_cast<char>((gp + q) * 255),
static_cast<char>((bp + q) * 255),
unsigned char cmap[4] = {
static_cast<unsigned char>((rp + q) * 255),
static_cast<unsigned char>((gp + q) * 255),
static_cast<unsigned char>((bp + q) * 255),
0,
};

bmp.write(cmap, 4);
bmp.write(reinterpret_cast<char *>(cmap), 4);
}

/*
Expand All @@ -208,14 +208,14 @@ void render_bitmap(
/*
* Retrieve the magnitude from the image, and write it.
*/
char r = img[h * x + y];
bmp.write(&r, 1);
unsigned char r = img[h * x + y];
bmp.write(reinterpret_cast<char *>(&r), 1);
}

/*
* If necessary, write the appropriate padding to the file.
*/
bmp.write(padding, (4 - (w % 4)) % 4);
bmp.write(reinterpret_cast<char *>(padding), (4 - (w % 4)) % 4);
}

bmp.close();
Expand Down
2 changes: 1 addition & 1 deletion examples/common/bitmap/bitmap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@
#include <string>

void render_bitmap(
char * img, unsigned int w, unsigned int h, std::string fname
unsigned char * img, unsigned int w, unsigned int h, std::string fname
);
6 changes: 3 additions & 3 deletions examples/cpu/render_image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,16 @@ int main(int argc, char ** argv)

covfie::utility::nd_size<2> im_size = f.backend().get_configuration();

std::unique_ptr<char[]> img =
std::make_unique<char[]>(im_size[1] * im_size[0]);
std::unique_ptr<unsigned char[]> img =
std::make_unique<unsigned char[]>(im_size[1] * im_size[0]);

BOOST_LOG_TRIVIAL(info) << "Rendering vector field to image...";

for (std::size_t x = 0; x < im_size[1]; ++x) {
for (std::size_t y = 0; y < im_size[0]; ++y) {
field_t::view_t::output_t p = fv.at(x, y);

img[im_size[1] * y + x] = static_cast<char>(std::lround(
img[im_size[1] * y + x] = static_cast<unsigned char>(std::lround(
255.f *
std::min(
std::sqrt(p[0] * p[0] + p[1] * p[1] + p[2] * p[2]), 1.0f
Expand Down
4 changes: 2 additions & 2 deletions examples/cpu/render_slice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ int main(int argc, char ** argv)

BOOST_LOG_TRIVIAL(info) << "Allocating memory for output image...";

std::unique_ptr<char[]> img = std::make_unique<char[]>(
std::unique_ptr<unsigned char[]> img = std::make_unique<unsigned char[]>(
vm["width"].as<unsigned int>() * vm["height"].as<unsigned int>()
);

Expand Down Expand Up @@ -156,7 +156,7 @@ int main(int argc, char ** argv)
}

img[vm["height"].as<unsigned int>() * x + y] =
static_cast<char>(std::lround(
static_cast<unsigned char>(std::lround(
255.f * std::min(
std::sqrt(
std::pow(p[0] / 0.000299792458f, 2.f) +
Expand Down
14 changes: 8 additions & 6 deletions examples/cuda/render_slice.cu
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ void parse_opts(
template <typename field_t>
__global__ void render(
typename field_t::view_t vf,
char * out,
unsigned char * out,
unsigned int width,
unsigned int height,
float z
Expand All @@ -95,7 +95,7 @@ __global__ void render(

typename field_t::output_t p =
vf.at(fx * 20000.f - 10000.f, fy * 20000.f - 10000.f, z);
out[height * x + y] = static_cast<char>(std::lround(
out[height * x + y] = static_cast<unsigned char>(std::lround(
255.f * std::min(
std::sqrt(
std::pow(p[0] / 0.000299792458f, 2.f) +
Expand Down Expand Up @@ -138,10 +138,11 @@ int main(int argc, char ** argv)

BOOST_LOG_TRIVIAL(info) << "Allocating device memory for output image...";

char * img_device;
unsigned char * img_device;

cudaErrorCheck(cudaMalloc(
reinterpret_cast<void **>(&img_device), width * height * sizeof(char)
reinterpret_cast<void **>(&img_device),
width * height * sizeof(unsigned char)
));

BOOST_LOG_TRIVIAL(info) << "Rendering magnetic field strength to image...";
Expand Down Expand Up @@ -172,14 +173,15 @@ int main(int argc, char ** argv)

BOOST_LOG_TRIVIAL(info) << "Allocating host memory for output image...";

std::unique_ptr<char[]> img_host = std::make_unique<char[]>(width * height);
std::unique_ptr<unsigned char[]> img_host =
std::make_unique<unsigned char[]>(width * height);

BOOST_LOG_TRIVIAL(info) << "Copying image from device to host...";

cudaErrorCheck(cudaMemcpy(
img_host.get(),
img_device,
width * height * sizeof(char),
width * height * sizeof(unsigned char),
cudaMemcpyDeviceToHost
));

Expand Down
14 changes: 8 additions & 6 deletions examples/cuda/render_slice_texture.cu
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ void parse_opts(
template <typename field_t>
__global__ void render(
typename field_t::view_t vf,
char * out,
unsigned char * out,
unsigned int width,
unsigned int height,
float z
Expand All @@ -96,7 +96,7 @@ __global__ void render(

typename field_t::output_t p =
vf.at(fx * 20000.f - 10000.f, fy * 20000.f - 10000.f, z);
out[height * x + y] = static_cast<char>(std::lround(
out[height * x + y] = static_cast<unsigned char>(std::lround(
255.f * std::min(
std::sqrt(
std::pow(p[0] / 0.000299792458f, 2.f) +
Expand Down Expand Up @@ -141,10 +141,11 @@ int main(int argc, char ** argv)

BOOST_LOG_TRIVIAL(info) << "Allocating device memory for output image...";

char * img_device;
unsigned char * img_device;

cudaErrorCheck(cudaMalloc(
reinterpret_cast<void **>(&img_device), width * height * sizeof(char)
reinterpret_cast<void **>(&img_device),
width * height * sizeof(unsigned char)
));

BOOST_LOG_TRIVIAL(info) << "Rendering magnetic field strength to image...";
Expand Down Expand Up @@ -175,14 +176,15 @@ int main(int argc, char ** argv)

BOOST_LOG_TRIVIAL(info) << "Allocating host memory for output image...";

std::unique_ptr<char[]> img_host = std::make_unique<char[]>(width * height);
std::unique_ptr<unsigned char[]> img_host =
std::make_unique<unsigned char[]>(width * height);

BOOST_LOG_TRIVIAL(info) << "Copying image from device to host...";

cudaErrorCheck(cudaMemcpy(
img_host.get(),
img_device,
width * height * sizeof(char),
width * height * sizeof(unsigned char),
cudaMemcpyDeviceToHost
));

Expand Down

0 comments on commit f96c7a7

Please sign in to comment.