00001 #include "histogramengine.h"
00002 #include "../colors/plugincolors.h"
00003 #include "vframe.h"
00004
00005 #include <stdio.h>
00006 #include <string.h>
00007
00008 HistogramPackage::HistogramPackage()
00009 : LoadPackage()
00010 {
00011 start = end = 0;
00012 }
00013
00014
00015 HistogramUnit::HistogramUnit(HistogramEngine *server)
00016 : LoadClient(server)
00017 {
00018 for(int i = 0; i < 5; i++)
00019 accum[i] = new int64_t[HISTOGRAM_RANGE];
00020 }
00021
00022 HistogramUnit::~HistogramUnit()
00023 {
00024 for(int i = 0; i < 5; i++)
00025 delete [] accum[i];
00026 }
00027
00028 void HistogramUnit::process_package(LoadPackage *package)
00029 {
00030 HistogramPackage *pkg = (HistogramPackage*)package;
00031 HistogramEngine *server = (HistogramEngine*)get_server();
00032
00033
00034 #define HISTOGRAM_HEAD(type) \
00035 { \
00036 for(int i = pkg->start; i < pkg->end; i++) \
00037 { \
00038 type *row = (type*)data->get_rows()[i]; \
00039 for(int j = 0; j < w; j++) \
00040 {
00041
00042 #define HISTOGRAM_TAIL(components) \
00043 v = (r * 76 + g * 150 + b * 29) >> 8; \
00044 \
00045 \
00046 r += -(int)(HISTOGRAM_MIN * 0xffff); \
00047 g += -(int)(HISTOGRAM_MIN * 0xffff); \
00048 b += -(int)(HISTOGRAM_MIN * 0xffff); \
00049 v += -(int)(HISTOGRAM_MIN * 0xffff); \
00050 CLAMP(r, 0, HISTOGRAM_RANGE); \
00051 CLAMP(g, 0, HISTOGRAM_RANGE); \
00052 CLAMP(b, 0, HISTOGRAM_RANGE); \
00053 CLAMP(v, 0, HISTOGRAM_RANGE); \
00054 accum_r[r]++; \
00055 accum_g[g]++; \
00056 accum_b[b]++; \
00057 accum_v[v]++; \
00058 \
00059 row += components; \
00060 } \
00061 } \
00062 }
00063
00064
00065
00066 VFrame *data = server->data;
00067
00068 int w = data->get_w();
00069 int h = data->get_h();
00070 int64_t *accum_r = accum[HISTOGRAM_RED];
00071 int64_t *accum_g = accum[HISTOGRAM_GREEN];
00072 int64_t *accum_b = accum[HISTOGRAM_BLUE];
00073 int64_t *accum_a = accum[HISTOGRAM_ALPHA];
00074 int64_t *accum_v = accum[HISTOGRAM_VALUE];
00075 int r, g, b, a, y, u, v;
00076
00077 switch(data->get_color_model())
00078 {
00079 case BC_RGB888:
00080 HISTOGRAM_HEAD(unsigned char)
00081 r = (row[0] << 8) | row[0];
00082 g = (row[1] << 8) | row[1];
00083 b = (row[2] << 8) | row[2];
00084 HISTOGRAM_TAIL(3)
00085 break;
00086 case BC_RGB_FLOAT:
00087 HISTOGRAM_HEAD(float)
00088 r = (int)(row[0] * 0xffff);
00089 g = (int)(row[1] * 0xffff);
00090 b = (int)(row[2] * 0xffff);
00091 HISTOGRAM_TAIL(3)
00092 break;
00093 case BC_YUV888:
00094 HISTOGRAM_HEAD(unsigned char)
00095 y = (row[0] << 8) | row[0];
00096 u = (row[1] << 8) | row[1];
00097 v = (row[2] << 8) | row[2];
00098 server->yuv->yuv_to_rgb_16(r, g, b, y, u, v);
00099 HISTOGRAM_TAIL(3)
00100 break;
00101 case BC_RGBA8888:
00102 HISTOGRAM_HEAD(unsigned char)
00103 r = (row[0] << 8) | row[0];
00104 g = (row[1] << 8) | row[1];
00105 b = (row[2] << 8) | row[2];
00106 HISTOGRAM_TAIL(4)
00107 break;
00108 case BC_RGBA_FLOAT:
00109 HISTOGRAM_HEAD(float)
00110 r = (int)(row[0] * 0xffff);
00111 g = (int)(row[1] * 0xffff);
00112 b = (int)(row[2] * 0xffff);
00113 HISTOGRAM_TAIL(4)
00114 break;
00115 case BC_YUVA8888:
00116 HISTOGRAM_HEAD(unsigned char)
00117 y = (row[0] << 8) | row[0];
00118 u = (row[1] << 8) | row[1];
00119 v = (row[2] << 8) | row[2];
00120 server->yuv->yuv_to_rgb_16(r, g, b, y, u, v);
00121 HISTOGRAM_TAIL(4)
00122 break;
00123 case BC_RGB161616:
00124 HISTOGRAM_HEAD(uint16_t)
00125 r = row[0];
00126 g = row[1];
00127 b = row[2];
00128 HISTOGRAM_TAIL(3)
00129 break;
00130 case BC_YUV161616:
00131 HISTOGRAM_HEAD(uint16_t)
00132 y = row[0];
00133 u = row[1];
00134 v = row[2];
00135 server->yuv->yuv_to_rgb_16(r, g, b, y, u, v);
00136 HISTOGRAM_TAIL(3)
00137 break;
00138 case BC_RGBA16161616:
00139 HISTOGRAM_HEAD(uint16_t)
00140 r = row[0];
00141 g = row[1];
00142 b = row[2];
00143 HISTOGRAM_TAIL(3);
00144 break;
00145 case BC_YUVA16161616:
00146 HISTOGRAM_HEAD(uint16_t)
00147 y = row[0];
00148 u = row[1];
00149 v = row[2];
00150 server->yuv->yuv_to_rgb_16(r, g, b, y, u, v);
00151 HISTOGRAM_TAIL(4)
00152 break;
00153 }
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163 HistogramEngine::HistogramEngine(int total_clients, int total_packages)
00164 : LoadServer(total_clients, total_packages)
00165 {
00166 yuv = new YUV;
00167 data = 0;
00168 for(int i = 0; i < 5; i++)
00169 accum[i] = new int64_t[HISTOGRAM_RANGE];
00170 }
00171
00172 HistogramEngine::~HistogramEngine()
00173 {
00174 delete yuv;
00175 for(int i = 0; i < 5; i++)
00176 delete [] accum[i];
00177 }
00178
00179 void HistogramEngine::process_packages(VFrame *data)
00180 {
00181 this->data = data;
00182 LoadServer::process_packages();
00183 for(int i = 0; i < 5; i++)
00184 {
00185 bzero(accum[i], sizeof(int64_t) * HISTOGRAM_RANGE);
00186 }
00187
00188 for(int i = 0; i < get_total_clients(); i++)
00189 {
00190 HistogramUnit *unit = (HistogramUnit*)get_client(i);
00191 for(int k = 0; k < 5; k++)
00192 {
00193 for(int j = 0; j < HISTOGRAM_RANGE; j++)
00194 {
00195 accum[k][j] += unit->accum[k][j];
00196 }
00197 }
00198 }
00199
00200 }
00201
00202 void HistogramEngine::init_packages()
00203 {
00204 for(int i = 0; i < get_total_packages(); i++)
00205 {
00206 HistogramPackage *package = (HistogramPackage*)get_package(i);
00207 package->start = data->get_h() * i / get_total_packages();
00208 package->end = data->get_h() * (i + 1) / get_total_packages();
00209 }
00210
00211
00212 for(int i = 0; i < get_total_clients(); i++)
00213 {
00214 HistogramUnit *unit = (HistogramUnit*)get_client(i);
00215 for(int i = 0; i < 5; i++)
00216 bzero(unit->accum[i], sizeof(int64_t) * HISTOGRAM_RANGE);
00217 }
00218 }
00219
00220 LoadClient* HistogramEngine::new_client()
00221 {
00222 return (LoadClient*)new HistogramUnit(this);
00223 }
00224
00225 LoadPackage* HistogramEngine::new_package()
00226 {
00227 return (LoadPackage*)new HistogramPackage;
00228 }
00229