inline R ConvertTo()

in IsometricPatternMatcher/Image.h [160:190]


  inline R ConvertTo() const {
    // Ensure for now that they are a powers of 2 (true for all current
    // use cases). This simplifies the arithmetic.
    static_assert(((R::Base::max_value + 1) & R::Base::max_value) == 0,
                  "Must be power of 2");
    static_assert(((max_value + 1) & max_value) == 0, "Must be power of 2");
    // Only support converting from higher bpp to lower bpp.
    // since we're doing integer division.
    static_assert(R::Base::max_value < max_value, "Can only reduce");

    // Sanity check
    static_assert((max_value + 1) % (R::Base::max_value + 1) == 0,
                  "Should be divisble");
    // It's not correct to divide by 4 for say going from 10bpp to 8bpp.
    // To be exact, we'd need to multiply by 255 / 1023
    // However, this should be sufficiently accurate.
    static constexpr int CONVERSION_FACTOR =
        (max_value + 1) / (R::Base::max_value + 1);

    R dest_image{this->w, this->h};
    for (size_t y = 0; y < this->h; ++y) {
      const BaseType* src_pixel_ptr = this->RowPtr(y);
      typename R::Base::BaseType* dest_pixel_ptr = dest_image.RowPtr(y);
      for (size_t x = 0; x < this->w; ++x) {
        *dest_pixel_ptr = *src_pixel_ptr / CONVERSION_FACTOR;
        ++src_pixel_ptr;
        ++dest_pixel_ptr;
      }
    }
    return dest_image;
  }