00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "yuv_viewer_gui.h"
00024
00025 #include <fvutils/color/colorspaces.h>
00026 #include <fvutils/draw/drawer.h>
00027
00028 #include <cmath>
00029 #include <cstring>
00030 #include <iomanip>
00031 #include <sstream>
00032
00033 #define M_2xPI (2*M_PI)
00034 using namespace fawkes;
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 YuvViewerGtkWindow::YuvViewerGtkWindow(BaseObjectType* cobject,
00047 const Glib::RefPtr<Gnome::Glade::Xml> ref_xml)
00048 : Gtk::Window(cobject)
00049 {
00050 ref_xml->get_widget("yuv_vp", __yuv_vp);
00051 ref_xml->get_widget("cur_vp", __cur_vp);
00052 ref_xml->get_widget("seg_vp", __seg_vp);
00053 ref_xml->get_widget("y_scale", __y_scale);
00054 ref_xml->get_widget("u_value", __u_value);
00055 ref_xml->get_widget("v_value", __v_value);
00056 ref_xml->get_widget("y_res", __y_res);
00057 ref_xml->get_widget("u_res", __u_res);
00058 ref_xml->get_widget("v_res", __v_res);
00059
00060 __yuv_widget = Gtk::manage(new ImageWidget(256, 256));
00061 __cur_widget = Gtk::manage(new ImageWidget( 60, 40));
00062 __seg_widget = Gtk::manage(new ImageWidget(256, 256));
00063
00064 __y_scale->signal_value_changed().connect(sigc::mem_fun(*this, &YuvViewerGtkWindow::on_y_value_changed));
00065 __y_res->signal_value_changed().connect(sigc::mem_fun(*this, &YuvViewerGtkWindow::on_y_res_changed));
00066 __u_res->signal_value_changed().connect(sigc::mem_fun(*this, &YuvViewerGtkWindow::on_uv_res_changed));
00067 __v_res->signal_value_changed().connect(sigc::mem_fun(*this, &YuvViewerGtkWindow::on_uv_res_changed));
00068
00069 __yuv_vp->signal_button_press_event().connect(sigc::mem_fun(*this, &YuvViewerGtkWindow::on_click_on_yuv));
00070 __yuv_vp->signal_motion_notify_event().connect(sigc::mem_fun(*this, &YuvViewerGtkWindow::on_mouse_over_yuv));
00071 __yuv_vp->add(*__yuv_widget);
00072 __cur_vp->add(*__cur_widget);
00073 __seg_vp->add(*__seg_widget);
00074
00075
00076 memset(__cur_buffer + 60 * 40, 128, 60 * 40);
00077 memset(__seg_buffer, 128, 256 * 256);
00078 on_y_value_changed();
00079 on_uv_res_changed();
00080 calc_seg();
00081 show_all_children();
00082 }
00083
00084
00085 YuvViewerGtkWindow::~YuvViewerGtkWindow()
00086 {
00087 }
00088
00089
00090
00091
00092
00093 bool
00094 YuvViewerGtkWindow::on_click_on_yuv(GdkEventButton *event)
00095 {
00096 GdkEventMotion mot;
00097 mot.x = event->x;
00098 mot.y = event->y;
00099 return on_mouse_over_yuv(&mot);
00100 }
00101
00102
00103
00104
00105
00106 bool
00107 YuvViewerGtkWindow::on_mouse_over_yuv(GdkEventMotion *event)
00108 {
00109 unsigned int u = std::max(0, std::min(255, (int)event->x));
00110 unsigned int v = 255 - std::max(0, std::min(255, (int)event->y));
00111
00112 __u_value->set_text(convert_float2str(u, 0));
00113 __v_value->set_text(convert_float2str(v, 0));
00114 memset(__cur_buffer + 60 * 40, u, 60 * 20);
00115 memset(__cur_buffer + 60 * 60, v, 60 * 20);
00116 __cur_widget->show(YUV422_PLANAR, __cur_buffer);
00117
00118 return true;
00119 }
00120
00121
00122 void
00123 YuvViewerGtkWindow::on_y_value_changed()
00124 {
00125 unsigned int y = round(__y_scale->get_value());
00126 memset(__yuv_buffer, y, 256 * 256);
00127 memset(__cur_buffer, y, 60 * 40);
00128
00129 Drawer d;
00130 d.set_buffer(__yuv_buffer, 256, 256);
00131 d.set_color(YUV_t::black());
00132 d.draw_line(127, 127, 0, 64);
00133 d.draw_line(127, 127, 64, 0);
00134
00135 d.draw_line(128, 127, 192, 0);
00136 d.draw_line(128, 127, 255, 64);
00137
00138 d.draw_line(128, 128, 192, 255);
00139 d.draw_line(128, 128, 255, 192);
00140
00141 d.draw_line(127, 128, 0, 192);
00142 d.draw_line(127, 128, 64, 255);
00143
00144 __yuv_widget->show(YUV422_PLANAR, __yuv_buffer);
00145 __cur_widget->show(YUV422_PLANAR, __cur_buffer);
00146 }
00147
00148
00149 void
00150 YuvViewerGtkWindow::on_y_res_changed()
00151 {
00152 unsigned int r = round(__y_res->get_value());
00153
00154 if (r == 0) {
00155 __y_scale->set_value(127);
00156 __y_scale->set_range(127, 128);
00157 }
00158 else {
00159 __y_scale->set_range(0, 255);
00160 __y_scale->set_increments(255.f / (pow(2, r) - 1), 0);
00161 }
00162 }
00163
00164 void
00165 YuvViewerGtkWindow::on_uv_res_changed()
00166 {
00167 unsigned char *yuv_u = __yuv_buffer + 256 * 256;
00168 unsigned char *yuv_v = yuv_u + 256 * 256 / 2;
00169 unsigned int u_div = 256 / (int)pow(2, __u_res->get_value());
00170 unsigned int v_div = 256 / (int)pow(2, __v_res->get_value());
00171
00172 for (unsigned int v = 0; v < 256; ++v) {
00173 memset((yuv_v + v * 128), ((255 - v) / v_div) * v_div, 128);
00174
00175 for (unsigned int u = 0; u < 128; ++u) {
00176 yuv_u[v * 128 + u] = (u * 2 / u_div) * u_div;
00177 }
00178 }
00179
00180 on_y_value_changed();
00181 }
00182
00183
00184
00185
00186
00187
00188
00189 Glib::ustring
00190 YuvViewerGtkWindow::convert_float2str(float f, unsigned int width)
00191 {
00192 #if GLIBMM_MAJOR_VERSION > 2 || ( GLIBMM_MAJOR_VERSION == 2 && GLIBMM_MINOR_VERSION >= 16 )
00193 return Glib::ustring::format(std::fixed, std::setprecision(width), f);
00194 #else
00195 std::ostringstream ss;
00196 ss << std::fixed << std::setprecision(width);
00197 ss << f;
00198
00199 return Glib::locale_to_utf8(ss.str());
00200 #endif
00201 }
00202
00203
00204 void
00205 YuvViewerGtkWindow::calc_seg()
00206 {
00207 YUV_t c;
00208 unsigned char *seg_u = __seg_buffer + 256 * 256;
00209 unsigned char *seg_v = seg_u + 256 * 256 / 2;
00210
00211 float a1 = atan2f(64, 128);
00212 float a2 = atan2f(128, 64);
00213 float a3 = atan2f(128, -64);
00214 float a4 = atan2f(64, -128);
00215 float a5 = atan2f(-64, -128) + M_2xPI;
00216 float a6 = atan2f(-128, -64) + M_2xPI;
00217 float a7 = atan2f(-128, 64) + M_2xPI;
00218 float a8 = atan2f(-64, 128) + M_2xPI;
00219
00220 for (int u = 0; u < 256; ++u) {
00221 float du = u - 128;
00222
00223 for (int v = 255; v >= 0; --v) {
00224 float dv = v - 128;
00225
00226 if (!du) {
00227 if (dv > 0) YUV_t::red();
00228 else c = YUV_t::gray();
00229 }
00230 else {
00231 float a = atan2f(dv, du);
00232 if (a < 0) a += M_2xPI;
00233
00234 if (a >= a1 && a < a2) c = YUV_t::magenta();
00235 else if (a >= a2 && a < a3) c = YUV_t::red();
00236 else if (a >= a3 && a < a4) c = YUV_t::orange();
00237 else if (a >= a4 && a < a5) c = YUV_t::yellow();
00238 else if (a >= a5 && a < a6) c = YUV_t::green();
00239 else if (a >= a6 && a < a7) c = YUV_t::gray();
00240 else if (a >= a7 && a < a8) c = YUV_t::cyan();
00241 else c = YUV_t::blue();
00242 }
00243
00244 unsigned int addr = ((255 - v) * 256 + u) / 2;
00245 seg_u[addr] = c.U;
00246 seg_v[addr] = c.V;
00247 }
00248 }
00249
00250 __seg_widget->show(YUV422_PLANAR, __seg_buffer);
00251 }