34 #ifndef VP_IMAGE_LUT_H
35 #define VP_IMAGE_LUT_H
39 #if defined(VISP_HAVE_THREADS)
42 struct vpImageLut_Param_t
44 unsigned int m_start_index;
45 unsigned int m_end_index;
47 unsigned char m_lut[256];
48 unsigned char *m_bitmap;
50 vpImageLut_Param_t() : m_start_index(0), m_end_index(0), m_lut(), m_bitmap(nullptr) { }
52 vpImageLut_Param_t(
unsigned int start_index,
unsigned int end_index,
unsigned char *bitmap)
53 : m_start_index(start_index), m_end_index(end_index), m_lut(), m_bitmap(bitmap)
57 void performLutThread(vpImageLut_Param_t *imageLut_param)
59 unsigned int start_index = imageLut_param->m_start_index;
60 unsigned int end_index = imageLut_param->m_end_index;
62 unsigned char *bitmap = imageLut_param->m_bitmap;
64 unsigned char *ptrStart = bitmap + start_index;
65 unsigned char *ptrEnd = bitmap + end_index;
66 unsigned char *ptrCurrent = ptrStart;
68 if (end_index - start_index >= 8) {
70 for (; ptrCurrent <= ptrEnd - 8;) {
71 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
74 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
77 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
80 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
83 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
86 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
89 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
92 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
97 for (; ptrCurrent != ptrEnd; ++ptrCurrent) {
98 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent];
102 struct vpImageLutRGBa_Param_t
104 unsigned int m_start_index;
105 unsigned int m_end_index;
107 VISP_NAMESPACE_ADDRESSING
vpRGBa m_lut[256];
108 unsigned char *m_bitmap;
110 vpImageLutRGBa_Param_t() : m_start_index(0), m_end_index(0), m_lut(), m_bitmap(nullptr) { }
112 vpImageLutRGBa_Param_t(
unsigned int start_index,
unsigned int end_index,
unsigned char *bitmap)
113 : m_start_index(start_index), m_end_index(end_index), m_lut(), m_bitmap(bitmap)
117 void performLutRGBaThread(vpImageLutRGBa_Param_t *imageLut_param)
119 unsigned int start_index = imageLut_param->m_start_index;
120 unsigned int end_index = imageLut_param->m_end_index;
122 unsigned char *bitmap = imageLut_param->m_bitmap;
124 unsigned char *ptrStart = bitmap + start_index * 4;
125 unsigned char *ptrEnd = bitmap + end_index * 4;
126 unsigned char *ptrCurrent = ptrStart;
128 if (end_index - start_index >= 4 * 2) {
130 for (; ptrCurrent <= ptrEnd - 4 * 2;) {
131 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
133 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
135 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
137 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
140 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
142 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
144 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
146 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
151 while (ptrCurrent != ptrEnd) {
152 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].R;
155 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].G;
158 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].B;
161 *ptrCurrent = imageLut_param->m_lut[*ptrCurrent].A;
178 std::cerr <<
"Not implemented !" << std::endl;
194 unsigned char *ptrStart =
static_cast<unsigned char *
>(
bitmap);
195 unsigned char *ptrEnd = ptrStart + size;
196 unsigned char *ptrCurrent = ptrStart;
198 bool use_single_thread = ((nbThreads == 0) || (nbThreads == 1));
199 #if !defined(VISP_HAVE_THREADS)
200 use_single_thread =
true;
203 if ((!use_single_thread) && (
getSize() <= nbThreads)) {
204 use_single_thread =
true;
207 if (use_single_thread) {
210 while (ptrCurrent != ptrEnd) {
211 *ptrCurrent = lut[*ptrCurrent];
216 #if defined(VISP_HAVE_THREADS)
218 std::vector<std::thread *> threadpool;
219 std::vector<vpImageLut_Param_t *> imageLutParams;
221 unsigned int image_size =
getSize();
222 unsigned int step = image_size / nbThreads;
223 unsigned int last_step = image_size - step * (nbThreads - 1);
225 for (
unsigned int index = 0; index < nbThreads; ++index) {
226 unsigned int start_index = index * step;
227 unsigned int end_index = (index + 1) * step;
229 if (index == nbThreads - 1) {
230 end_index = start_index + last_step;
233 vpImageLut_Param_t *imageLut_param =
new vpImageLut_Param_t(start_index, end_index,
bitmap);
234 memcpy(imageLut_param->m_lut, lut, 256 *
sizeof(
unsigned char));
236 imageLutParams.push_back(imageLut_param);
239 std::thread *imageLut_thread =
new std::thread(&performLutThread, imageLut_param);
240 threadpool.push_back(imageLut_thread);
243 for (
size_t cpt = 0; cpt < threadpool.size(); ++cpt) {
245 threadpool[cpt]->join();
249 for (
size_t cpt = 0; cpt < threadpool.size(); ++cpt) {
250 delete threadpool[cpt];
253 for (
size_t cpt = 0; cpt < imageLutParams.size(); ++cpt) {
254 delete imageLutParams[cpt];
273 unsigned char *ptrStart =
reinterpret_cast<unsigned char *
>(
bitmap);
274 unsigned char *ptrEnd = ptrStart + (size * 4);
275 unsigned char *ptrCurrent = ptrStart;
277 bool use_single_thread = ((nbThreads == 0) || (nbThreads == 1));
278 #if !defined(VISP_HAVE_THREADS)
279 use_single_thread =
true;
282 if ((!use_single_thread) && (
getSize() <= nbThreads)) {
283 use_single_thread =
true;
286 if (use_single_thread) {
288 while (ptrCurrent != ptrEnd) {
289 *ptrCurrent = lut[*ptrCurrent].R;
292 *ptrCurrent = lut[*ptrCurrent].G;
295 *ptrCurrent = lut[*ptrCurrent].B;
298 *ptrCurrent = lut[*ptrCurrent].A;
303 #if defined(VISP_HAVE_THREADS)
305 std::vector<std::thread *> threadpool;
306 std::vector<vpImageLutRGBa_Param_t *> imageLutParams;
308 unsigned int image_size =
getSize();
309 unsigned int step = image_size / nbThreads;
310 unsigned int last_step = image_size - step * (nbThreads - 1);
312 for (
unsigned int index = 0; index < nbThreads; ++index) {
313 unsigned int start_index = index * step;
314 unsigned int end_index = (index + 1) * step;
316 if (index == nbThreads - 1) {
317 end_index = start_index + last_step;
320 vpImageLutRGBa_Param_t *imageLut_param =
new vpImageLutRGBa_Param_t(start_index, end_index, (
unsigned char *)
bitmap);
321 memcpy(
static_cast<void *
>(imageLut_param->m_lut), lut, 256 *
sizeof(
vpRGBa));
323 imageLutParams.push_back(imageLut_param);
326 std::thread *imageLut_thread =
new std::thread(&performLutRGBaThread, imageLut_param);
327 threadpool.push_back(imageLut_thread);
330 for (
size_t cpt = 0; cpt < threadpool.size(); ++cpt) {
332 threadpool[cpt]->join();
336 for (
size_t cpt = 0; cpt < threadpool.size(); ++cpt) {
337 delete threadpool[cpt];
340 for (
size_t cpt = 0; cpt < imageLutParams.size(); ++cpt) {
341 delete imageLutParams[cpt];
unsigned int getWidth() const
void performLut(const Type(&lut)[256], unsigned int nbThreads=1)
unsigned int getSize() const
Type * bitmap
points toward the bitmap
unsigned int getHeight() const