summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: f00b5e7)
raw | patch | inline | side by side (parent: f00b5e7)
author | kiirala <kiirala@users.sourceforge.net> | |
Tue, 24 Jul 2007 12:48:54 +0000 (12:48 +0000) | ||
committer | kiirala <kiirala@users.sourceforge.net> | |
Tue, 24 Jul 2007 12:48:54 +0000 (12:48 +0000) |
src/display/nr-filter-utils.cpp | patch | blob | history | |
src/display/nr-filter-utils.h | patch | blob | history | |
src/display/pixblock-scaler.cpp | patch | blob | history |
index 85faadebcd86018873e67e6467735c6e274ab5ea..52c8ecc7d27dfef18cb898eb1cce24c465349b10 100644 (file)
namespace NR {
-int clamp(int val) {
+int clamp(int const val) {
if (val < 0) return 0;
if (val > 255) return 255;
return val;
}
-
+
+int clamp_alpha(int const val, int const alpha) {
+ if (val < 0) return 0;
+ if (val > alpha) return alpha;
+ return val;
+}
+
} //namespace NR
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
index b591b37cb759662d8f76e5cb3cedb5f8ad16e50e..5ac6fa5ab405711a58e2c2c84b10d3281b5c9d4c 100644 (file)
* \return 0 if the value is smaller than 0, 255 if it is greater 255, else v
* \param v the value to clamp
*/
-int clamp(int val);
+int clamp(int const val);
/**
* Macro to use the clamp function with double inputs and unsigned char output
*/
#define CLAMP_D_TO_U8(v) (unsigned char) clamp((int)round((v)))
+/**
+ * Clamps an integer to a value between 0 and alpha. Useful when handling
+ * images with premultiplied alpha, as setting some of RGB channels
+ * to a value bigger than alpha confuses the alpha blending in Inkscape
+ * \return 0 if val is negative, alpha if val is bigger than alpha, val otherwise
+ * \param val the value to clamp
+ * \param alpha the maximum value to clamp to
+ */
+int clamp_alpha(int const val, int const alpha);
+
} /* namespace NR */
#endif /* __NR_FILTER_UTILS_H__ */
index c5acaace0b3e5f4f033accc3ac7457715e031dcd..d65cfd4e0d78178a49c92289ac5f231df38635ad 100644 (file)
#include <cmath>
using std::floor;
+#include "display/nr-filter-utils.h"
#include "libnr/nr-pixblock.h"
namespace NR {
* Returns the interpolated value in 8-bit format, ready to be written
* to output buffer.
*/
-inline unsigned char samplex(const int a, const int b, const int c, const int d, const double len) {
+inline int samplex(const int a, const int b, const int c, const int d, const double len) {
double lenf = len - floor(len);
int sum = 0;
sum += (int)(a * (((-1.0 / 3.0) * lenf + 4.0 / 5.0) * lenf - 7.0 / 15.0) * lenf);
sum += (int)(b * (((lenf - 9.0 / 5.0) * lenf - 1.0 / 5.0) * lenf + 1.0));
sum += (int)(c * ((((1 - lenf) - 9.0 / 5.0) * (1 - lenf) - 1.0 / 5.0) * (1 - lenf) + 1.0));
sum += (int)(d * (((-1.0 / 3.0) * (1 - lenf) + 4.0 / 5.0) * (1 - lenf) - 7.0 / 15.0) * (1 - lenf));
- if (sum < 0) sum = 0;
- if (sum >= 256*256) sum = 255 * 256;
- return (unsigned char)(sum / 256);
+ //if (sum < 0) sum = 0;
+ //if (sum > 255 * 256) sum = 255 * 256;
+ return sum / 256;
}
/**
from_x);
_check_index(to, to_y * to->rs + to_x * 4, __LINE__);
- NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4] = result.r;
- NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 1] = result.g;
- NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 2] = result.b;
- NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 3] = result.a;
+
+ if (to->mode == NR_PIXBLOCK_MODE_R8G8B8A8P) {
+ /* Clamp the colour channels to range from 0 to result.a to
+ * make sure, we don't exceed 100% per colour channel with
+ * images that have premultiplied alpha */
+
+ result.a = clamp(result.a);
+
+ NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4] = clamp_alpha(result.r, result.a);
+ NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 1] = clamp_alpha(result.g, result.a);
+ NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 2] = clamp_alpha(result.b, result.a);
+ NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 3] = result.a;
+ } else {
+ NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4] = clamp(result.r);
+ NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 1] = clamp(result.g);
+ NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 2] = clamp(result.b);
+ NR_PIXBLOCK_PX(to)[to_y * to->rs + to_x * 4 + 3] = clamp(result.a);
+ }
}
}
}