image.cc
Go to the documentation of this file.
00001 #include "cartographer/io/image.h"
00002 
00003 #include <memory>
00004 
00005 #include "cartographer/io/file_writer.h"
00006 #include "glog/logging.h"
00007 
00008 namespace cartographer {
00009 namespace io {
00010 namespace {
00011 
00012 uint32 Uint8ColorToCairo(const Uint8Color& color) {
00013   return static_cast<uint32>(255) << 24 | static_cast<uint32>(color[0]) << 16 |
00014          static_cast<uint32>(color[1]) << 8 | color[2];
00015 }
00016 
00017 Uint8Color CairoToUint8Color(uint32 color) {
00018   uint8 r = color >> 16;
00019   uint8 g = color >> 8;
00020   uint8 b = color;
00021   return {{r, g, b}};
00022 }
00023 
00024 cairo_status_t CairoWriteCallback(void* const closure,
00025                                   const unsigned char* data,
00026                                   const unsigned int length) {
00027   if (static_cast<FileWriter*>(closure)->Write(
00028           reinterpret_cast<const char*>(data), length)) {
00029     return CAIRO_STATUS_SUCCESS;
00030   }
00031   return CAIRO_STATUS_WRITE_ERROR;
00032 }
00033 
00034 void CheckStrideIsAsExpected(int width) {
00035   const int stride = cairo_format_stride_for_width(kCairoFormat, width);
00036   CHECK_EQ(stride, width * 4);
00037 }
00038 
00039 }  // namespace
00040 
00041 UniqueCairoSurfacePtr MakeUniqueCairoSurfacePtr(cairo_surface_t* surface) {
00042   return UniqueCairoSurfacePtr(surface, cairo_surface_destroy);
00043 }
00044 
00045 UniqueCairoPtr MakeUniqueCairoPtr(cairo_t* surface) {
00046   return UniqueCairoPtr(surface, cairo_destroy);
00047 }
00048 
00049 Image::Image(int width, int height)
00050     : width_(width), height_(height), pixels_(width * height, 0) {}
00051 
00052 Image::Image(UniqueCairoSurfacePtr surface)
00053     : width_(cairo_image_surface_get_width(surface.get())),
00054       height_(cairo_image_surface_get_height(surface.get())) {
00055   CHECK_EQ(cairo_image_surface_get_format(surface.get()), kCairoFormat);
00056   CheckStrideIsAsExpected(width_);
00057 
00058   const uint32* pixel_data =
00059       reinterpret_cast<uint32*>(cairo_image_surface_get_data(surface.get()));
00060   const int num_pixels = width_ * height_;
00061   pixels_.reserve(num_pixels);
00062   for (int i = 0; i < num_pixels; ++i) {
00063     pixels_.push_back(pixel_data[i]);
00064   }
00065 }
00066 
00067 void Image::Rotate90DegreesClockwise() {
00068   const auto old_pixels = pixels_;
00069   pixels_.clear();
00070   for (int x = 0; x < width_; ++x) {
00071     for (int y = height_ - 1; y >= 0; --y) {
00072       pixels_.push_back(old_pixels.at(y * width_ + x));
00073     }
00074   }
00075   std::swap(width_, height_);
00076 }
00077 
00078 void Image::WritePng(FileWriter* const file_writer) {
00079   // TODO(hrapp): cairo_image_surface_create_for_data does not take ownership of
00080   // the data until the surface is finalized. Once it is finalized though,
00081   // cairo_surface_write_to_png fails, complaining that the surface is already
00082   // finalized. This makes it pretty hard to pass back ownership of the image to
00083   // the caller.
00084   UniqueCairoSurfacePtr surface = GetCairoSurface();
00085   CHECK_EQ(cairo_surface_status(surface.get()), CAIRO_STATUS_SUCCESS);
00086   CHECK_EQ(cairo_surface_write_to_png_stream(surface.get(), &CairoWriteCallback,
00087                                              file_writer),
00088            CAIRO_STATUS_SUCCESS);
00089 }
00090 
00091 const Uint8Color Image::GetPixel(int x, int y) const {
00092   return CairoToUint8Color(pixels_[y * width_ + x]);
00093 }
00094 
00095 void Image::SetPixel(int x, int y, const Uint8Color& color) {
00096   pixels_[y * width_ + x] = Uint8ColorToCairo(color);
00097 }
00098 
00099 UniqueCairoSurfacePtr Image::GetCairoSurface() {
00100   return MakeUniqueCairoSurfacePtr(cairo_image_surface_create_for_data(
00101       reinterpret_cast<unsigned char*>(pixels_.data()), kCairoFormat, width_,
00102       height_, width_ * 4 /* stride */));
00103 }
00104 
00105 }  // namespace io
00106 }  // namespace cartographer


cartographer
Author(s): The Cartographer Authors
autogenerated on Thu May 9 2019 02:27:35