merged hv7 mod
[goodguy/history.git] / cinelerra-5.1 / plugins / threshold / histogramengine.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "histogramengine.h"
23 #include "bccolors.h"
24 #include "vframe.h"
25
26 #include <stdio.h>
27 #include <string.h>
28
29 HistogramPackage::HistogramPackage()
30  : LoadPackage()
31 {
32         start = end = 0;
33 }
34
35
36 HistogramUnit::HistogramUnit(HistogramEngine *server)
37  : LoadClient(server)
38 {
39         for(int i = 0; i < 5; i++)
40                 accum[i] = new int64_t[HISTOGRAM_RANGE];
41 }
42
43 HistogramUnit::~HistogramUnit()
44 {
45         for(int i = 0; i < 5; i++)
46                 delete [] accum[i];
47 }
48
49 void HistogramUnit::process_package(LoadPackage *package)
50 {
51         HistogramPackage *pkg = (HistogramPackage*)package;
52         HistogramEngine *server = (HistogramEngine*)get_server();
53
54
55 #define HISTOGRAM_HEAD(type) \
56 { \
57         for(int i = pkg->start; i < pkg->end; i++) \
58         { \
59                 type *row = (type*)data->get_rows()[i]; \
60                 for(int j = 0; j < w; j++) \
61                 {
62
63 #define HISTOGRAM_TAIL(components) \
64                         v = (r * 76 + g * 150 + b * 29) >> 8; \
65 /*                      v = MAX(r, g); */ \
66 /*                      v = MAX(v, b); */ \
67                         r += -(int)(HISTOGRAM_MIN * 0xffff); \
68                         g += -(int)(HISTOGRAM_MIN * 0xffff); \
69                         b += -(int)(HISTOGRAM_MIN * 0xffff); \
70                         v += -(int)(HISTOGRAM_MIN * 0xffff); \
71                         CLAMP(r, 0, HISTOGRAM_RANGE); \
72                         CLAMP(g, 0, HISTOGRAM_RANGE); \
73                         CLAMP(b, 0, HISTOGRAM_RANGE); \
74                         CLAMP(v, 0, HISTOGRAM_RANGE); \
75                         accum_r[r]++; \
76                         accum_g[g]++; \
77                         accum_b[b]++; \
78                         accum_v[v]++; \
79 /*                      if(components == 4) accum_a[row[3]]++; */ \
80                         row += components; \
81                 } \
82         } \
83 }
84
85
86
87         VFrame *data = server->data;
88
89         int w = data->get_w();
90         //int h = data->get_h();
91         int64_t *accum_r = accum[HISTOGRAM_RED];
92         int64_t *accum_g = accum[HISTOGRAM_GREEN];
93         int64_t *accum_b = accum[HISTOGRAM_BLUE];
94         //int64_t *accum_a = accum[HISTOGRAM_ALPHA];
95         int64_t *accum_v = accum[HISTOGRAM_VALUE];
96         int r, g, b, y, u, v; // ,a;
97
98         switch(data->get_color_model())
99         {
100                 case BC_RGB888:
101                         HISTOGRAM_HEAD(unsigned char)
102                         r = (row[0] << 8) | row[0];
103                         g = (row[1] << 8) | row[1];
104                         b = (row[2] << 8) | row[2];
105                         HISTOGRAM_TAIL(3)
106                         break;
107                 case BC_RGB_FLOAT:
108                         HISTOGRAM_HEAD(float)
109                         r = (int)(row[0] * 0xffff);
110                         g = (int)(row[1] * 0xffff);
111                         b = (int)(row[2] * 0xffff);
112                         HISTOGRAM_TAIL(3)
113                         break;
114                 case BC_YUV888:
115                         HISTOGRAM_HEAD(unsigned char)
116                         y = (row[0] << 8) | row[0];
117                         u = (row[1] << 8) | row[1];
118                         v = (row[2] << 8) | row[2];
119                         server->yuv->yuv_to_rgb_16(r, g, b, y, u, v);
120                         HISTOGRAM_TAIL(3)
121                         break;
122                 case BC_RGBA8888:
123                         HISTOGRAM_HEAD(unsigned char)
124                         r = (row[0] << 8) | row[0];
125                         g = (row[1] << 8) | row[1];
126                         b = (row[2] << 8) | row[2];
127                         HISTOGRAM_TAIL(4)
128                         break;
129                 case BC_RGBA_FLOAT:
130                         HISTOGRAM_HEAD(float)
131                         r = (int)(row[0] * 0xffff);
132                         g = (int)(row[1] * 0xffff);
133                         b = (int)(row[2] * 0xffff);
134                         HISTOGRAM_TAIL(4)
135                         break;
136                 case BC_YUVA8888:
137                         HISTOGRAM_HEAD(unsigned char)
138                         y = (row[0] << 8) | row[0];
139                         u = (row[1] << 8) | row[1];
140                         v = (row[2] << 8) | row[2];
141                         server->yuv->yuv_to_rgb_16(r, g, b, y, u, v);
142                         HISTOGRAM_TAIL(4)
143                         break;
144                 case BC_RGB161616:
145                         HISTOGRAM_HEAD(uint16_t)
146                         r = row[0];
147                         g = row[1];
148                         b = row[2];
149                         HISTOGRAM_TAIL(3)
150                         break;
151                 case BC_YUV161616:
152                         HISTOGRAM_HEAD(uint16_t)
153                         y = row[0];
154                         u = row[1];
155                         v = row[2];
156                         server->yuv->yuv_to_rgb_16(r, g, b, y, u, v);
157                         HISTOGRAM_TAIL(3)
158                         break;
159                 case BC_RGBA16161616:
160                         HISTOGRAM_HEAD(uint16_t)
161                         r = row[0];
162                         g = row[1];
163                         b = row[2];
164                         HISTOGRAM_TAIL(3);
165                         break;
166                 case BC_YUVA16161616:
167                         HISTOGRAM_HEAD(uint16_t)
168                         y = row[0];
169                         u = row[1];
170                         v = row[2];
171                         server->yuv->yuv_to_rgb_16(r, g, b, y, u, v);
172                         HISTOGRAM_TAIL(4)
173                         break;
174         }
175 }
176
177
178
179
180
181
182
183
184 HistogramEngine::HistogramEngine(int total_clients, int total_packages)
185  : LoadServer(total_clients, total_packages)
186 {
187         yuv = new YUV;
188         data = 0;
189         for(int i = 0; i < 5; i++)
190                 accum[i] = new int64_t[HISTOGRAM_RANGE];
191 }
192
193 HistogramEngine::~HistogramEngine()
194 {
195         delete yuv;
196         for(int i = 0; i < 5; i++)
197                 delete [] accum[i];
198 }
199
200 void HistogramEngine::process_packages(VFrame *data)
201 {
202         this->data = data;
203         LoadServer::process_packages();
204         for(int i = 0; i < 5; i++)
205         {
206                 bzero(accum[i], sizeof(int64_t) * HISTOGRAM_RANGE);
207         }
208
209         for(int i = 0; i < get_total_clients(); i++)
210         {
211                 HistogramUnit *unit = (HistogramUnit*)get_client(i);
212                 for(int k = 0; k < 5; k++)
213                 {
214                         for(int j = 0; j < HISTOGRAM_RANGE; j++)
215                         {
216                                 accum[k][j] += unit->accum[k][j];
217                         }
218                 }
219         }
220
221 }
222
223 void HistogramEngine::init_packages()
224 {
225         for(int i = 0; i < get_total_packages(); i++)
226         {
227                 HistogramPackage *package = (HistogramPackage*)get_package(i);
228                 package->start = data->get_h() * i / get_total_packages();
229                 package->end = data->get_h() * (i + 1) / get_total_packages();
230         }
231
232 // Initialize clients here in case some don't get run.
233         for(int i = 0; i < get_total_clients(); i++)
234         {
235                 HistogramUnit *unit = (HistogramUnit*)get_client(i);
236                 for(int i = 0; i < 5; i++)
237                         bzero(unit->accum[i], sizeof(int64_t) * HISTOGRAM_RANGE);
238         }
239 }
240
241 LoadClient* HistogramEngine::new_client()
242 {
243         return (LoadClient*)new HistogramUnit(this);
244 }
245
246 LoadPackage* HistogramEngine::new_package()
247 {
248         return (LoadPackage*)new HistogramPackage;
249 }
250