Skip to content

[CPP Library] Enhanced support. #171

@dorpxam

Description

@dorpxam

Hello, I would like to submit some modifications to you in order to optimize compatibility with the standard library and VS compilers.


Compiling under Visual Studio 2022 with and without LLVM/Clang.

There's a missing include for the files:

cpp/temperature/temperature_cache.h(105,8): error : no template named 'optional' in namespace 'std'
cpp/temperature/temperature_cache.h(106,8): error : no template named 'optional' in namespace 'std'
cpp/temperature/temperature_cache.h(107,8): error : no template named 'optional' in namespace 'std'
cpp/temperature/temperature_cache.h(108,8): error : no template named 'optional' in namespace 'std'

Solution:

#include <optional>


Here, it's the famous unix-style M_PI, not found in VS system:

cpp\dynamiccolor\material_dynamic_colors.cc(54,28): error : use of undeclared identifier 'M_PI'

Solution:

constexpr double M_PI = 3.141592653589793;

for WIN_32 defined system.


Compiling under Visual Studio 2022 only, no error with LLVM/Clang.

cpp\cam\viewing_conditions.h(49,60): error C4576
cpp\cam\hct_solver.cc(220,10): error C4576:
cpp\cam\hct_solver.cc(279,14): error C4576:
cpp\cam\hct_solver.cc(281,14): error C4576:
cpp\cam\hct_solver.cc(288,14): error C4576:
cpp\cam\hct_solver.cc(290,14): error C4576:
cpp\cam\hct_solver.cc(297,14): error C4576:
cpp\cam\hct_solver.cc(299,14): error C4576:
cpp\cam\hct_solver.cc(313,15): error C4576:
cpp\cam\hct_solver.cc(349,10): error C4576:
cpp\cam\hct_solver.cc(459,19): error C4576:
cpp\utils\utils.cc(175,10): error C4576

Where error C4576 = a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax

Solution:

remove traditional style cast before initializer list, the conversion is implicit.

After changes

Build successfully done under internal VS2022 and LLVM/Clang compilers.


About the Abseil Common Libraries dependency.

In 'utils.cc' and 'wsmeans.cc' there's dependencies over Abseil Common Libraries (C++).

A solution can be to make the Abseil library optional.


The HexFromArgb function:

In 'utils.cc' we have a include #include "absl/strings/str_cat.h" for the hexadecimal int string formatting. Just replace the include by :

#ifdef USE_ABSEIL_LIBRARY
#include "absl/strings/str_cat.h"
#else
#include <sstream>
#include <iomanip>
#endif

and modify the function with this one:

std::string HexFromArgb(Argb argb) 
{
#ifdef USE_ABSEIL_LIBRARY
    return absl::StrCat(absl::Hex(argb));
#else
    std::stringstream stream;
    stream << std::hex << argb;
    return stream.str();
#endif
}

The QuantizeWsmeans function:

In 'wsmeans.cc' we have a include #include "absl/container/flat_hash_map.h" for the better performance in the QuantizeWsmeans function. Just replace the include by :

#ifdef USE_ABSEIL_LIBRARY
#include "absl/container/flat_hash_map.h"
template <typename key, typename value>
using choiced_map = absl::flat_hash_map<key, value>;
#else
template <typename key, typename value>
using choiced_map = std::unordered_map<key, value>;
#endif

and modify the function with this one:

QuantizerResult QuantizeWsmeans(const std::vector<Argb>& input_pixels,
                                const std::vector<Argb>& starting_clusters,
                                uint16_t max_colors) {
  if (max_colors == 0 || input_pixels.empty()) {
    return QuantizerResult();
  }

  if (max_colors > 256) {
    // If colors is outside the range, just set it the max.
    max_colors = 256;
  }

  uint32_t pixel_count = input_pixels.size();
  choiced_map<Argb, int> pixel_to_count;
  std::vector<uint32_t> pixels;
  pixels.reserve(pixel_count);
  std::vector<Lab> points;
  points.reserve(pixel_count);
  for (Argb pixel : input_pixels) {
    // tested over 1000 runs with 128 colors, 12544 (112 x 112)
    // std::map 10.9 ms
    // std::unordered_map 10.2 ms
    // absl::btree_map 9.0 ms
    // absl::flat_hash_map 8.0 ms
    choiced_map<Argb, int>::iterator it = pixel_to_count.find(pixel);
    if (it != pixel_to_count.end()) {
      it->second++;

    } else {
      pixels.push_back(pixel);
      points.push_back(LabFromInt(pixel));
      pixel_to_count[pixel] = 1;
    }
  }

Conclusion

Thank you very much for this great library and the whole Material Design project.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions