1 /*
2 delaboratory - color correction utility
3 Copyright (C) 2011 Jacek Poplawski
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "renderer.h"
20 #include "project.h"
21 #include "image.h"
22 #include "base_layer.h"
23 #include <iostream>
24 #include "layer_processor.h"
25 #include "str.h"
26 #include "logger.h"
27 #include "channel_manager.h"
28 #include "layer_stack.h"
29 #include "conversion_processor.h"
30 #include "canvas.h"
31
renderChannel(const deImage & image,int c,unsigned char * data,deChannelManager & channelManager,bool reversed)32 void renderChannel(const deImage& image, int c, unsigned char* data, deChannelManager& channelManager, bool reversed)
33 {
34 const deSize& s = image.getChannelSize();
35
36 const deValue* pixels = image.startRead(c);
37
38 if (!pixels)
39 {
40 logError("can't render channel - NULL pixels");
41 return;
42 }
43
44 int n = s.getN();
45 int i;
46 int pos = 0;
47 for (i = 0; i < n; i++)
48 {
49 deValue s = pixels[i];
50
51 if (reversed)
52 {
53 s = 1.0 - s;
54 }
55
56 unsigned char ss = 255 * s;
57
58 data[pos] = ss;
59 pos++;
60 data[pos] = ss;
61 pos++;
62 data[pos] = ss;
63 pos++;
64 }
65
66 image.finishRead(c);
67
68 }
69
deRenderer(deChannelManager & _channelManager)70 deRenderer::deRenderer(deChannelManager& _channelManager)
71 :size(0,0),
72 channelManager(_channelManager)
73 {
74 }
75
~deRenderer()76 deRenderer::~deRenderer()
77 {
78 }
79
prepareImage(const deViewManager & viewManager,deLayerProcessor & layerProcessor,deLayerStack & layerStack)80 bool deRenderer::prepareImage(const deViewManager& viewManager, deLayerProcessor& layerProcessor, deLayerStack& layerStack)
81 {
82 if (channelManager.isImageEmpty())
83 {
84 logError("image is empty");
85 return false;
86 }
87
88 mutex.lock();
89
90 int viewV = viewManager.getView();
91 int view = layerProcessor.getLastValidLayer();
92 if (view > viewV)
93 {
94 view = viewV;
95 }
96
97 if (view < 0)
98 {
99 logError("view < 0");
100 mutex.unlock();
101 return false;
102 }
103
104 const deBaseLayer* layer = layerStack.startReadLayer(view);
105
106 if (layer)
107 {
108 const deImage& layerImage = layer->getLayerImage();
109
110 if (viewManager.isSingleChannel())
111 {
112 bool reversed = false;
113 deColorSpace colorSpace = layerImage.getColorSpace();
114 if (colorSpace == deColorSpaceCMYK)
115 {
116 reversed = true;
117 }
118 renderChannel(layerImage, viewManager.getChannel(), getCurrentImageData(), channelManager, reversed);
119 renderedImage.clearError();
120 }
121 else
122 {
123 deConversionProcessor p;
124 if (!p.renderImageToRGBNew(layerImage, getCurrentImageData()))
125 {
126 logError("render image FAILED");
127 renderedImage.setError();
128 }
129 else
130 {
131 renderedImage.clearError();
132 }
133 }
134 }
135 else
136 {
137 logError("no layer in renderer");
138 }
139
140 layerStack.finishReadLayer(view);
141
142 mutex.unlock();
143
144 return true;
145 }
146
render(deCanvas & canvas)147 bool deRenderer::render(deCanvas& canvas)
148 {
149 mutex.lock();
150
151 bool result = renderedImage.render(canvas);
152
153 if (!result)
154 {
155 canvas.clear();
156 }
157
158 mutex.unlock();
159
160 return result;
161 }
162
getCurrentImageData()163 unsigned char* deRenderer::getCurrentImageData()
164 {
165 const deSize& s = channelManager.getChannelSizeFromChannelManager();
166 renderedImage.setSize(s);
167 return renderedImage.getCurrentImageData();
168 }
169