Proper check for rawzor libraries.
[rawtherapee-fixes.git] / rtgui / thumbimageupdater.cc
blob2dfaf066c65982238cc22de9778d968f2cfff608
1 /*
2 * This file is part of RawTherapee.
4 * Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
6 * RawTherapee 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 3 of the License, or
9 * (at your option) any later version.
11 * RawTherapee 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.
16 * You should have received a copy of the GNU General Public License
17 * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
19 #include <thumbimageupdater.h>
20 #include <gtkmm.h>
22 ThumbImageUpdater thumbImageUpdater;
24 ThumbImageUpdater::ThumbImageUpdater ()
25 : tostop(false), stopped(true), qMutex(NULL), startMutex(NULL) {
29 void ThumbImageUpdater::add (Thumbnail* t, const rtengine::procparams::ProcParams& params, int height, bool* priority, ThumbImageUpdateListener* l) {
31 if (!qMutex)
32 qMutex = new Glib::Mutex ();
33 if (!startMutex)
34 startMutex = new Glib::Mutex ();
36 qMutex->lock ();
37 // look up if an older version is in the queue
38 std::list<Job>::iterator i;
39 for (i=jqueue.begin(); i!=jqueue.end(); i++)
40 if (i->thumbnail==t && i->listener==l) {
41 i->pparams = params;
42 i->height = height;
43 i->priority = priority;
44 break;
46 // not found, create and append new job
47 if (i==jqueue.end ()) {
48 Job j;
49 j.thumbnail = t;
50 j.pparams = params;
51 j.height = height;
52 j.listener = l;
53 j.priority = priority;
54 jqueue.push_back (j);
56 qMutex->unlock ();
59 void ThumbImageUpdater::process () {
61 if (stopped) {
62 #undef THREAD_PRIORITY_NORMAL
63 stopped = false;
64 thread = Glib::Thread::create(sigc::mem_fun(*this, &ThumbImageUpdater::process_), (unsigned long int)0, true, true, Glib::THREAD_PRIORITY_NORMAL);
68 void ThumbImageUpdater::process_ () {
70 stopped = false;
71 tostop = false;
73 #define threadNum 4 // IF LCMS GETS THREAD SAFETY WE CAN ENABLE MORE THREADS
74 Glib::Thread **threadPool = new Glib::Thread* [threadNum];
76 while (!tostop && !jqueue.empty ()) {
78 qMutex->lock ();
79 int threads = 0;
80 for (; threads<threadNum && !jqueue.empty (); threads++) {
81 // find first entry having update priority, if any
82 std::list<Job>::iterator i;
83 for (i=jqueue.begin (); i!=jqueue.end(); i++)
84 if (*(i->priority))
85 break;
86 if (i==jqueue.end())
87 i = jqueue.begin();
88 Job current = *i;
89 jqueue.erase (i);
90 if (current.listener)
91 threadPool[threads] = Glib::Thread::create(sigc::bind(sigc::mem_fun(*this, &ThumbImageUpdater::processJob), current), 0, true, true, Glib::THREAD_PRIORITY_NORMAL);
92 else
93 threadPool[threads] = NULL;
95 qMutex->unlock ();
97 for (int j=0; j<threads; j++)
98 if (threadPool[j])
99 threadPool[j]->join ();
101 stopped = true;
104 void ThumbImageUpdater::processJob (Job current) {
106 if (current.listener) {
107 double scale = 1.0;
108 rtengine::IImage8* img = current.thumbnail->processThumbImage (current.pparams, current.height, scale);
109 if (img)
110 current.listener->updateImage (img, scale, current.pparams.crop);
115 void ThumbImageUpdater::stop () {
117 if (stopped) {
118 tostop = true;
119 return; }
121 gdk_threads_leave();
122 tostop = true;
123 Glib::Thread::self()->yield();
124 if (!stopped)
125 thread->join ();
126 gdk_threads_enter();
129 void ThumbImageUpdater::removeJobs () {
131 if (!qMutex)
132 return;
134 qMutex->lock ();
135 while (!jqueue.empty())
136 jqueue.pop_front ();
137 qMutex->unlock ();
140 void ThumbImageUpdater::removeJobs (ThumbImageUpdateListener* listener) {
142 if (!qMutex)
143 return;
145 qMutex->lock ();
146 bool ready = false;
147 while (!ready) {
148 ready = true;
149 std::list<Job>::iterator i;
150 for (i=jqueue.begin(); i!=jqueue.end(); i++)
151 if (i->listener == listener) {
152 jqueue.erase (i);
153 ready = false;
154 break;
157 qMutex->unlock ();
160 void ThumbImageUpdater::terminate () {
162 stop ();
163 removeJobs ();