Proper check for rawzor libraries.
[rawtherapee-fixes.git] / rtgui / previewhandler.cc
blob421ebac9cabef5e37c9cf1cf78d047b35f591074
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 <previewhandler.h>
20 #include <gtkmm.h>
21 #include <rtengine.h>
23 using namespace rtengine;
24 using namespace rtengine::procparams;
26 PreviewHandler::PreviewHandler () : image(NULL) {
28 pih = new PreviewHandlerIdleHelper;
29 pih->phandler = this;
30 pih->destroyed = false;
31 pih->pending = 0;
34 PreviewHandler::~PreviewHandler () {
36 if (pih->pending)
37 pih->destroyed = true;
38 else
39 delete pih;
42 //----------------previewimagelistener functions--------------------
44 struct iaimgpar {
45 IImage8* image;
46 PreviewHandlerIdleHelper* pih;
47 double scale;
48 CropParams cp;
51 int iasetimage (void* data) {
53 gdk_threads_enter ();
55 iaimgpar* iap = (iaimgpar*)data;
56 PreviewHandlerIdleHelper* pih = iap->pih;
58 if (pih->destroyed) {
59 if (pih->pending == 1)
60 delete pih;
61 else
62 pih->pending--;
63 delete iap;
64 gdk_threads_leave ();
65 return 0;
68 if (pih->phandler->image) {
69 IImage8* temp = pih->phandler->image;
70 temp->getMutex().lock ();
71 pih->phandler->image = iap->image;
72 temp->getMutex().unlock ();
74 else
75 pih->phandler->image = iap->image;
76 pih->phandler->cropParams = iap->cp;
77 pih->phandler->previewScale = iap->scale;
78 pih->pending--;
79 delete iap;
81 gdk_threads_leave ();
83 return 0;
86 void PreviewHandler::setImage (rtengine::IImage8* i, double scale, rtengine::procparams::CropParams cp) {
88 pih->pending++;
90 iaimgpar* iap = new iaimgpar;
91 iap->image = i;
92 iap->pih = pih;
93 iap->scale = scale;
94 iap->cp = cp;
96 g_idle_add (iasetimage, iap);
99 int iadelimage (void* data) {
101 gdk_threads_enter ();
103 iaimgpar* iap = (iaimgpar*)data;
104 PreviewHandlerIdleHelper* pih = iap->pih;
106 if (pih->destroyed) {
107 if (pih->pending == 1)
108 delete pih;
109 else
110 pih->pending--;
111 delete iap;
112 gdk_threads_leave ();
113 return 0;
116 if (pih->phandler->image) {
117 IImage8* temp = pih->phandler->image;
118 temp->getMutex().lock ();
119 pih->phandler->image = NULL;
120 temp->getMutex().unlock ();
122 iap->image->free ();
123 pih->phandler->previewImgMutex.lock ();
124 pih->phandler->previewImg.clear ();
125 pih->phandler->previewImgMutex.unlock ();
127 pih->pending--;
128 delete iap;
130 gdk_threads_leave ();
132 return 0;
135 void PreviewHandler::delImage (IImage8* i) {
137 pih->pending++;
139 iaimgpar* iap = new iaimgpar;
140 iap->image = i;
141 iap->pih = pih;
143 g_idle_add (iadelimage, iap);
146 int imready (void* data) {
148 gdk_threads_enter ();
150 iaimgpar* iap = (iaimgpar*)data;
151 PreviewHandlerIdleHelper* pih = iap->pih;
153 if (pih->destroyed) {
154 if (pih->pending == 1)
155 delete pih;
156 else
157 pih->pending--;
158 delete iap;
159 gdk_threads_leave ();
160 return 0;
163 pih->phandler->previewImgMutex.lock ();
164 pih->phandler->previewImg = Gdk::Pixbuf::create_from_data (pih->phandler->image->getData(), Gdk::COLORSPACE_RGB, false, 8, pih->phandler->image->getWidth(), pih->phandler->image->getHeight(), 3*pih->phandler->image->getWidth());
165 pih->phandler->previewImgMutex.unlock ();
166 pih->phandler->cropParams = iap->cp;
167 pih->phandler->previewImageChanged ();
168 pih->pending--;
169 delete iap;
171 gdk_threads_leave ();
173 return 0;
176 void PreviewHandler::imageReady (CropParams cp) {
178 pih->pending++;
179 iaimgpar* iap = new iaimgpar;
180 iap->pih = pih;
181 iap->cp = cp;
182 g_idle_add (imready, iap);
185 Glib::RefPtr<Gdk::Pixbuf> PreviewHandler::getRoughImage (int x, int y, int w, int h, double zoom) {
187 Glib::RefPtr<Gdk::Pixbuf> resPixbuf;
188 previewImgMutex.lock ();
189 if (previewImg) {
190 double totalZoom = zoom*previewScale;
191 if (w>previewImg->get_width()*totalZoom)
192 w = image->getWidth()*totalZoom;
193 if (h>previewImg->get_height()*totalZoom)
194 h = image->getHeight()*totalZoom;
195 int ix = x*zoom;
196 int iy = y*zoom;
197 if (ix<0)
198 ix = 0;
199 if (iy<0)
200 iy = 0;
201 if ((ix+w)/totalZoom>previewImg->get_width())
202 ix = previewImg->get_width()*totalZoom - w;
203 if ((iy+h)/totalZoom>previewImg->get_height())
204 iy = previewImg->get_height()*totalZoom - h;
206 resPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, w, h);
207 previewImg->scale (resPixbuf, 0, 0, w, h, -ix, -iy, totalZoom, totalZoom, Gdk::INTERP_NEAREST);
209 previewImgMutex.unlock ();
210 return resPixbuf;
213 Glib::RefPtr<Gdk::Pixbuf> PreviewHandler::getRoughImage (int desiredW, int desiredH, double& zoom_) {
215 Glib::RefPtr<Gdk::Pixbuf> resPixbuf;
216 previewImgMutex.lock ();
217 if (previewImg) {
218 double zoom1 = (double)desiredW / previewImg->get_width();
219 double zoom2 = (double)desiredH / previewImg->get_height();
220 double zoom = zoom1<zoom2 ? zoom1 : zoom2;
222 resPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, image->getWidth()*zoom, image->getHeight()*zoom);
223 previewImg->scale (resPixbuf, 0, 0, previewImg->get_width()*zoom, previewImg->get_height()*zoom, 0, 0, zoom, zoom, Gdk::INTERP_NEAREST);
224 zoom_ = zoom / previewScale;
226 previewImgMutex.unlock ();
227 return resPixbuf;
230 void PreviewHandler::previewImageChanged () {
232 for (std::list<PreviewListener*>::iterator i=listeners.begin(); i!=listeners.end(); i++)
233 (*i)->previewImageChanged ();