Commit c5387bca authored by Davis King's avatar Davis King

Changed code around a little to avoid problems in gcc when used with mingw. One of the

problems was that assign_pixel() would sometimes give the wrong output when optimizations
were enabled.  This seems to be a bug in mingw's gcc and these code changes avoid triggering
it.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%403812
parent b6f6ab72
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "../gui_widgets.h" #include "../gui_widgets.h"
#include "../unicode.h" #include "../unicode.h"
#include "../smart_pointers_thread_safe.h" #include "../smart_pointers_thread_safe.h"
#include "../uintn.h"
#include <map> #include <map>
...@@ -34,12 +35,7 @@ namespace nativefont ...@@ -34,12 +35,7 @@ namespace nativefont
namespace font_renderer namespace font_renderer
{ {
#if defined(WIN32) && !defined(__MINGW32__) typedef dlib::uint8 byte;
typedef BYTE uint8_t;
typedef WORD uint16_t;
typedef DWORD uint32_t;
#endif
typedef uint8_t byte;
#ifdef WIN32 #ifdef WIN32
...@@ -62,7 +58,7 @@ namespace nativefont ...@@ -62,7 +58,7 @@ namespace nativefont
typedef char type_t; typedef char type_t;
}; };
template <> struct size2inner_trait<2>{ template <> struct size2inner_trait<2>{
typedef uint16_t type_t; typedef dlib::uint16 type_t;
}; };
template <> struct size2inner_trait<4>{ template <> struct size2inner_trait<4>{
typedef dlib::unichar type_t; typedef dlib::unichar type_t;
......
...@@ -432,146 +432,107 @@ namespace dlib ...@@ -432,146 +432,107 @@ namespace dlib
namespace assign_pixel_helpers namespace assign_pixel_helpers
{ {
enum
{
grayscale = 1,
rgb,
hsi,
rgb_alpha
};
template <
typename P1,
typename P2,
int p1_type = static_switch<
pixel_traits<P1>::grayscale,
pixel_traits<P1>::rgb,
pixel_traits<P1>::hsi,
pixel_traits<P1>::rgb_alpha >::value,
int p2_type = static_switch<
pixel_traits<P2>::grayscale,
pixel_traits<P2>::rgb,
pixel_traits<P2>::hsi,
pixel_traits<P2>::rgb_alpha >::value
>
struct helper;
// ----------------------------- // -----------------------------
// all the same kind // all the same kind
template < typename P > template < typename P >
struct helper<P,P,grayscale,grayscale> typename enable_if_c<pixel_traits<P>::grayscale>::type
{ assign(P& dest, const P& src)
static void assign(P& dest, const P& src) {
{ dest = src;
dest = src; }
}
};
template < typename P1, typename P2 > template < typename P1, typename P2 >
struct helper<P1,P2,grayscale,grayscale> typename enable_if_c<pixel_traits<P1>::grayscale && pixel_traits<P2>::grayscale>::type
{ assign(P1& dest, const P2& src)
static void assign(P1& dest, const P2& src) {
{ if (src <= pixel_traits<P1>::max())
if (src <= pixel_traits<P1>::max()) dest = static_cast<P1>(src);
dest = static_cast<P1>(src); else
else dest = static_cast<P1>(pixel_traits<P1>::max());
dest = static_cast<P1>(pixel_traits<P1>::max()); }
}
};
template < typename P1, typename P2 > template < typename P1, typename P2 >
struct helper<P1,P2,rgb,rgb> typename enable_if_c<pixel_traits<P1>::rgb && pixel_traits<P2>::rgb>::type
{ assign(P1& dest, const P2& src)
static void assign(P1& dest, const P2& src) {
{ dest.red = src.red;
dest.red = src.red; dest.green = src.green;
dest.green = src.green; dest.blue = src.blue;
dest.blue = src.blue; }
}
};
template < typename P1, typename P2 > template < typename P1, typename P2 >
struct helper<P1,P2,rgb_alpha,rgb_alpha> typename enable_if_c<pixel_traits<P1>::rgb_alpha && pixel_traits<P2>::rgb_alpha>::type
{ assign(P1& dest, const P2& src)
static void assign(P1& dest, const P2& src) {
{ dest.red = src.red;
dest.red = src.red; dest.green = src.green;
dest.green = src.green; dest.blue = src.blue;
dest.blue = src.blue; dest.alpha = src.alpha;
dest.alpha = src.alpha; }
}
};
template < typename P1, typename P2 > template < typename P1, typename P2 >
struct helper<P1,P2,hsi,hsi> typename enable_if_c<pixel_traits<P1>::hsi && pixel_traits<P2>::hsi>::type
{ assign(P1& dest, const P2& src)
static void assign(P1& dest, const P2& src) {
{ dest.h = src.h;
dest.h = src.h; dest.s = src.s;
dest.s = src.s; dest.i = src.i;
dest.i = src.i; }
}
};
// ----------------------------- // -----------------------------
// dest is a grayscale // dest is a grayscale
template < typename P1, typename P2 > template < typename P1, typename P2 >
struct helper<P1,P2,grayscale,rgb> typename enable_if_c<pixel_traits<P1>::grayscale && pixel_traits<P2>::rgb>::type
{ assign(P1& dest, const P2& src)
static void assign(P1& dest, const P2& src) {
{ dest = static_cast<P1>((static_cast<unsigned int>(src.red) +
dest = static_cast<P1>((static_cast<unsigned int>(src.red) + static_cast<unsigned int>(src.green) +
static_cast<unsigned int>(src.green) + static_cast<unsigned int>(src.blue))/3);
static_cast<unsigned int>(src.blue))/3); }
}
};
template < typename P1, typename P2 > template < typename P1, typename P2 >
struct helper<P1,P2,grayscale,rgb_alpha> typename enable_if_c<pixel_traits<P1>::grayscale && pixel_traits<P2>::rgb_alpha>::type
{ assign(P1& dest, const P2& src)
static void assign(P1& dest, const P2& src) {
{
const unsigned char avg = static_cast<unsigned char>((static_cast<unsigned int>(src.red) + const unsigned char avg = static_cast<unsigned char>((static_cast<unsigned int>(src.red) +
static_cast<unsigned int>(src.green) + static_cast<unsigned int>(src.green) +
static_cast<unsigned int>(src.blue))/3); static_cast<unsigned int>(src.blue))/3);
if (src.alpha == 255) if (src.alpha == 255)
{ {
dest = avg; dest = avg;
} }
else else
{ {
// perform this assignment using fixed point arithmetic: // perform this assignment using fixed point arithmetic:
// dest = src*(alpha/255) + src*(1 - alpha/255); // dest = src*(alpha/255) + src*(1 - alpha/255);
// dest = src*(alpha/255) + dest*1 - dest*(alpha/255); // dest = src*(alpha/255) + dest*1 - dest*(alpha/255);
// dest = dest*1 + src*(alpha/255) - dest*(alpha/255); // dest = dest*1 + src*(alpha/255) - dest*(alpha/255);
// dest = dest*1 + (src - dest)*(alpha/255); // dest = dest*1 + (src - dest)*(alpha/255);
// dest += (src - dest)*(alpha/255); // dest += (src - dest)*(alpha/255);
unsigned int temp = avg; unsigned int temp = avg;
temp -= dest; temp -= dest;
temp *= src.alpha; temp *= src.alpha;
temp >>= 8; temp >>= 8;
dest += static_cast<unsigned char>(temp&0xFF); dest += static_cast<unsigned char>(temp&0xFF);
} }
} }
};
template < typename P1, typename P2 > template < typename P1, typename P2 >
struct helper<P1,P2,grayscale,hsi> typename enable_if_c<pixel_traits<P1>::grayscale && pixel_traits<P2>::hsi>::type
{ assign(P1& dest, const P2& src)
static void assign(P1& dest, const P2& src) {
{ dest = static_cast<P1>(src.i);
dest = static_cast<P1>(src.i); }
}
};
// ----------------------------- // -----------------------------
...@@ -676,225 +637,202 @@ namespace dlib ...@@ -676,225 +637,202 @@ namespace dlib
// dest is a color rgb_pixel // dest is a color rgb_pixel
template < typename P1 > template < typename P1 >
struct helper<P1,unsigned char,rgb,grayscale> typename enable_if_c<pixel_traits<P1>::rgb>::type
{ assign(P1& dest, const unsigned char& src)
static void assign(P1& dest, const unsigned char& src) {
{ dest.red = src;
dest.red = src; dest.green = src;
dest.green = src; dest.blue = src;
dest.blue = src; }
}
};
template < typename P1, typename P2 > template < typename P1, typename P2 >
struct helper<P1,P2,rgb,grayscale> typename enable_if_c<pixel_traits<P1>::rgb && pixel_traits<P2>::grayscale>::type
{ assign(P1& dest, const P2& src)
static void assign(P1& dest, const P2& src) {
{ unsigned char p;
unsigned char p; if (src <= 255)
if (src <= 255) p = static_cast<unsigned char>(src);
p = static_cast<unsigned char>(src); else
else p = 255;
p = 255;
dest.red = p;
dest.red = p; dest.green = p;
dest.green = p; dest.blue = p;
dest.blue = p; }
}
};
template < typename P1, typename P2 > template < typename P1, typename P2 >
struct helper<P1,P2,rgb,rgb_alpha> typename enable_if_c<pixel_traits<P1>::rgb && pixel_traits<P2>::rgb_alpha>::type
{ assign(P1& dest, const P2& src)
static void assign(P1& dest, const P2& src) {
{ if (src.alpha == 255)
if (src.alpha == 255) {
{ dest.red = src.red;
dest.red = src.red; dest.green = src.green;
dest.green = src.green; dest.blue = src.blue;
dest.blue = src.blue; }
} else
else {
{ // perform this assignment using fixed point arithmetic:
// perform this assignment using fixed point arithmetic: // dest = src*(alpha/255) + src*(1 - alpha/255);
// dest = src*(alpha/255) + src*(1 - alpha/255); // dest = src*(alpha/255) + dest*1 - dest*(alpha/255);
// dest = src*(alpha/255) + dest*1 - dest*(alpha/255); // dest = dest*1 + src*(alpha/255) - dest*(alpha/255);
// dest = dest*1 + src*(alpha/255) - dest*(alpha/255); // dest = dest*1 + (src - dest)*(alpha/255);
// dest = dest*1 + (src - dest)*(alpha/255); // dest += (src - dest)*(alpha/255);
// dest += (src - dest)*(alpha/255);
unsigned int temp_r = src.red;
unsigned int temp_r = src.red; unsigned int temp_g = src.green;
unsigned int temp_g = src.green; unsigned int temp_b = src.blue;
unsigned int temp_b = src.blue;
temp_r -= dest.red;
temp_r -= dest.red; temp_g -= dest.green;
temp_g -= dest.green; temp_b -= dest.blue;
temp_b -= dest.blue;
temp_r *= src.alpha;
temp_r *= src.alpha; temp_g *= src.alpha;
temp_g *= src.alpha; temp_b *= src.alpha;
temp_b *= src.alpha;
temp_r >>= 8;
temp_r >>= 8; temp_g >>= 8;
temp_g >>= 8; temp_b >>= 8;
temp_b >>= 8;
dest.red += static_cast<unsigned char>(temp_r&0xFF);
dest.red += static_cast<unsigned char>(temp_r&0xFF); dest.green += static_cast<unsigned char>(temp_g&0xFF);
dest.green += static_cast<unsigned char>(temp_g&0xFF); dest.blue += static_cast<unsigned char>(temp_b&0xFF);
dest.blue += static_cast<unsigned char>(temp_b&0xFF); }
} }
}
};
template < typename P1, typename P2 > template < typename P1, typename P2 >
struct helper<P1,P2,rgb,hsi> typename enable_if_c<pixel_traits<P1>::rgb && pixel_traits<P2>::hsi>::type
{ assign(P1& dest, const P2& src)
static void assign(P1& dest, const P2& src) {
{ COLOUR c;
COLOUR c; HSL h;
HSL h; h.h = src.h;
h.h = src.h; h.h = h.h/255.0*360;
h.h = h.h/255.0*360; h.s = src.s/255.0;
h.s = src.s/255.0; h.l = src.i/255.0;
h.l = src.i/255.0; c = HSL2RGB(h);
c = HSL2RGB(h);
dest.red = static_cast<unsigned char>(c.r*255.0);
dest.red = static_cast<unsigned char>(c.r*255.0); dest.green = static_cast<unsigned char>(c.g*255.0);
dest.green = static_cast<unsigned char>(c.g*255.0); dest.blue = static_cast<unsigned char>(c.b*255.0);
dest.blue = static_cast<unsigned char>(c.b*255.0); }
}
};
// ----------------------------- // -----------------------------
// dest is a color rgb_alpha_pixel // dest is a color rgb_alpha_pixel
template < typename P1 > template < typename P1 >
struct helper<P1,unsigned char,rgb_alpha,grayscale> typename enable_if_c<pixel_traits<P1>::rgb_alpha>::type
{ assign(P1& dest, const unsigned char& src)
static void assign(P1& dest, const unsigned char& src) {
{ dest.red = src;
dest.red = src; dest.green = src;
dest.green = src; dest.blue = src;
dest.blue = src; dest.alpha = 255;
dest.alpha = 255; }
}
};
template < typename P1, typename P2 > template < typename P1, typename P2 >
struct helper<P1,P2,rgb_alpha,grayscale> typename enable_if_c<pixel_traits<P1>::rgb_alpha && pixel_traits<P2>::grayscale>::type
{ assign(P1& dest, const P2& src)
static void assign(P1& dest, const P2& src) {
{ unsigned char p;
unsigned char p; if (src <= 255)
if (src <= 255) p = static_cast<unsigned char>(src);
p = static_cast<unsigned char>(src); else
else p = 255;
p = 255;
dest.red = p;
dest.red = p; dest.green = p;
dest.green = p; dest.blue = p;
dest.blue = p; dest.alpha = 255;
dest.alpha = 255; }
}
};
template < typename P1, typename P2 > template < typename P1, typename P2 >
struct helper<P1,P2,rgb_alpha,rgb> typename enable_if_c<pixel_traits<P1>::rgb_alpha && pixel_traits<P2>::rgb>::type
{ assign(P1& dest, const P2& src)
static void assign(P1& dest, const P2& src) {
{ dest.red = src.red;
dest.red = src.red; dest.green = src.green;
dest.green = src.green; dest.blue = src.blue;
dest.blue = src.blue; dest.alpha = 255;
dest.alpha = 255; }
}
};
template < typename P1, typename P2 > template < typename P1, typename P2 >
struct helper<P1,P2,rgb_alpha,hsi> typename enable_if_c<pixel_traits<P1>::rgb_alpha && pixel_traits<P2>::hsi>::type
{ assign(P1& dest, const P2& src)
static void assign(P1& dest, const P2& src) {
{ COLOUR c;
COLOUR c; HSL h;
HSL h; h.h = src.h;
h.h = src.h; h.h = h.h/255.0*360;
h.h = h.h/255.0*360; h.s = src.s/255.0;
h.s = src.s/255.0; h.l = src.i/255.0;
h.l = src.i/255.0; c = HSL2RGB(h);
c = HSL2RGB(h);
dest.red = static_cast<unsigned char>(c.r*255.0);
dest.red = static_cast<unsigned char>(c.r*255.0); dest.green = static_cast<unsigned char>(c.g*255.0);
dest.green = static_cast<unsigned char>(c.g*255.0); dest.blue = static_cast<unsigned char>(c.b*255.0);
dest.blue = static_cast<unsigned char>(c.b*255.0); dest.alpha = 255;
dest.alpha = 255; }
}
};
// ----------------------------- // -----------------------------
// dest is an hsi pixel // dest is an hsi pixel
template < typename P1> template < typename P1>
struct helper<P1,unsigned char,hsi,grayscale> typename enable_if_c<pixel_traits<P1>::hsi>::type
{ assign(P1& dest, const unsigned char& src)
static void assign(P1& dest, const unsigned char& src) {
{ dest.h = 0;
dest.h = 0; dest.s = 0;
dest.s = 0; dest.i = src;
dest.i = src; }
}
};
template < typename P1, typename P2 > template < typename P1, typename P2 >
struct helper<P1,P2,hsi,grayscale> typename enable_if_c<pixel_traits<P1>::hsi && pixel_traits<P2>::grayscale>::type
{ assign(P1& dest, const P2& src)
static void assign(P1& dest, const P2& src) {
{ dest.h = 0;
dest.h = 0; dest.s = 0;
dest.s = 0; if (src <= 255)
if (src <= 255) dest.i = static_cast<unsigned char>(src);
dest.i = static_cast<unsigned char>(src); else
else dest.i = 255;
dest.i = 255; }
}
};
template < typename P1, typename P2 > template < typename P1, typename P2 >
struct helper<P1,P2,hsi,rgb_alpha> typename enable_if_c<pixel_traits<P1>::hsi && pixel_traits<P2>::rgb>::type
{ assign(P1& dest, const P2& src)
static void assign(P1& dest, const P2& src) {
{ COLOUR c1;
rgb_pixel temp; HSL c2;
// convert target hsi pixel to rgb c1.r = src.red/255.0;
helper<rgb_pixel,P1>::assign(temp,dest); c1.g = src.green/255.0;
c1.b = src.blue/255.0;
// now assign the rgb_alpha value to our temp rgb pixel c2 = RGB2HSL(c1);
helper<rgb_pixel,P2>::assign(temp,src);
dest.h = static_cast<unsigned char>(c2.h/360.0*255.0);
// now we can just go assign the new rgb value to the dest.s = static_cast<unsigned char>(c2.s*255.0);
// hsi pixel dest.i = static_cast<unsigned char>(c2.l*255.0);
helper<P1,rgb_pixel>::assign(dest,temp); }
}
};
template < typename P1, typename P2 > template < typename P1, typename P2 >
struct helper<P1,P2,hsi,rgb> typename enable_if_c<pixel_traits<P1>::hsi && pixel_traits<P2>::rgb_alpha>::type
{ assign(P1& dest, const P2& src)
static void assign(P1& dest, const P2& src) {
{ rgb_pixel temp;
COLOUR c1; // convert target hsi pixel to rgb
HSL c2; assign(temp,dest);
c1.r = src.red/255.0;
c1.g = src.green/255.0; // now assign the rgb_alpha value to our temp rgb pixel
c1.b = src.blue/255.0; assign(temp,src);
c2 = RGB2HSL(c1);
// now we can just go assign the new rgb value to the
dest.h = static_cast<unsigned char>(c2.h/360.0*255.0); // hsi pixel
dest.s = static_cast<unsigned char>(c2.s*255.0); assign(dest,temp);
dest.i = static_cast<unsigned char>(c2.l*255.0); }
}
};
} }
// ----------------------------- // -----------------------------
...@@ -903,7 +841,7 @@ namespace dlib ...@@ -903,7 +841,7 @@ namespace dlib
inline void assign_pixel ( inline void assign_pixel (
P1& dest, P1& dest,
const P2& src const P2& src
) { assign_pixel_helpers::helper<P1,P2>::assign(dest,src); } ) { assign_pixel_helpers::assign(dest,src); }
template < typename P1> template < typename P1>
inline void assign_pixel ( inline void assign_pixel (
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment