ref: a5ed0292b110606df51f607427cdd17f86f10f04
parent: 05e36767b0d3dcf64e9a37bbd0a2cc93771dfbfd
author: ISSOtm <[email protected]>
date: Fri May 20 14:27:54 EDT 2022
Reject colors with ambiguous alpha channel
--- a/include/gfx/rgba.hpp
+++ b/include/gfx/rgba.hpp
@@ -9,6 +9,7 @@
#ifndef RGBDS_GFX_RGBA_HPP
#define RGBDS_GFX_RGBA_HPP
+#include <cstdint>
#include <stdint.h>
struct Rgba {
@@ -50,12 +51,10 @@
*/
static constexpr uint16_t transparent = 0b1'00000'00000'00000;
- /**
- * All alpha values strictly below this will be considered transparent
- */
- static constexpr uint8_t opacity_threshold = 0xF0; // TODO: adjust this
- // TODO: also a transparency threshold, and error out on "middle" values
- bool isTransparent() const { return alpha < opacity_threshold; }
+ static constexpr uint8_t transparency_threshold = 0x10;
+ bool isTransparent() const { return alpha < transparency_threshold; }
+ static constexpr uint8_t opacity_threshold = 0xF0;
+ bool isOpaque() const { return alpha >= opacity_threshold; }
/**
* Computes the equivalent CGB color, respects the color curve depending on options
*/
--- a/src/gfx/process.cpp
+++ b/src/gfx/process.cpp
@@ -323,10 +323,22 @@
// assigned, and conflicts always occur between that and another color.
// For the same reason, we don't need to worry about order, either.
std::vector<std::tuple<uint32_t, uint32_t>> conflicts;
+ // Holds colors whose alpha value is ambiguous
+ std::vector<uint32_t> indeterminates;
// Assign a color to the given position, and register it in the image palette as well
- auto assignColor = [this, &conflicts](png_uint_32 x, png_uint_32 y, Rgba &&color) {
- if (Rgba const *other = colors.registerColor(color); other) {
+ auto assignColor = [this, &conflicts, &indeterminates](png_uint_32 x, png_uint_32 y,
+ Rgba &&color) {
+ if (!color.isTransparent() && !color.isOpaque()) {
+ uint32_t css = color.toCSS();
+ if (std::find(indeterminates.begin(), indeterminates.end(), css)
+ == indeterminates.end()) {
+ error(
+ "Color #%08x is neither transparent (alpha < %u) nor opaque (alpha >= %u)",
+ css, Rgba::transparency_threshold, Rgba::opacity_threshold);
+ indeterminates.push_back(css);
+ }
+ } else if (Rgba const *other = colors.registerColor(color); other) {
std::tuple conflicting{color.toCSS(), other->toCSS()};
// Do not report combinations twice
if (std::find(conflicts.begin(), conflicts.end(), conflicting) == conflicts.end()) {
--- a/src/gfx/rgba.cpp
+++ b/src/gfx/rgba.cpp
@@ -33,6 +33,7 @@
if (isTransparent()) {
return transparent;
}
+ assert(isOpaque());
uint8_t r = red, g = green, b = blue;
if (options.useColorCurve) {