1 /*
2 * imagesource_ncolour_preview.cpp
3 *
4 * Renders an RGB preview of a DeviceN Image
5 * Supports random access
6 *
7 * Copyright (c) 2008 by Alastair M. Robinson
8 * Distributed under the terms of the GNU General Public License -
9 * see the file named "COPYING" for more details.
10 *
11 */
12
13 #include <iostream>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <math.h>
17
18 #include "../support/util.h"
19
20 #include "imagesource_devicen_preview.h"
21
22 using namespace std;
23
24
ISDeviceN_Colorant_Preview()25 ISDeviceN_Colorant_Preview::ISDeviceN_Colorant_Preview()
26 : red(0), green(0), blue(0), longname(NULL), alias(0)
27 {
28 }
29
30
ISDeviceN_Colorant_Preview(const char * longname,int red,int green,int blue,char alias)31 ISDeviceN_Colorant_Preview::ISDeviceN_Colorant_Preview(const char *longname,int red, int green, int blue, char alias)
32 : red(EIGHTTOIS(red)),green(EIGHTTOIS(green)),blue(EIGHTTOIS(blue)),longname(NULL),alias(alias)
33 {
34 if(longname)
35 this->longname=strdup(longname);
36 }
37
38
ISDeviceN_Colorant_Preview(const char * longname)39 ISDeviceN_Colorant_Preview::ISDeviceN_Colorant_Preview(const char *longname)
40 : red(EIGHTTOIS(red)),green(EIGHTTOIS(green)),blue(EIGHTTOIS(blue)),longname(NULL),alias(alias)
41 {
42 if(StrcasecmpIgnoreSpaces(longname,"Cyan")==0)
43 {
44 red=EIGHTTOIS(0); green=EIGHTTOIS(190); blue=EIGHTTOIS(255); alias='C';
45 }
46 else if(StrcasecmpIgnoreSpaces(longname,"Magenta")==0)
47 {
48 red=EIGHTTOIS(255); green=EIGHTTOIS(0); blue=EIGHTTOIS(190); alias='M';
49 }
50 else if(StrcasecmpIgnoreSpaces(longname,"Vivid Magenta")==0)
51 {
52 red=EIGHTTOIS(255); green=EIGHTTOIS(0); blue=EIGHTTOIS(190); alias='M';
53 }
54 else if(StrcasecmpIgnoreSpaces(longname,"Yellow")==0)
55 {
56 red=EIGHTTOIS(255); green=EIGHTTOIS(255); blue=EIGHTTOIS(0); alias='Y';
57 }
58 else if(StrcasecmpIgnoreSpaces(longname,"Black")==0)
59 {
60 red=EIGHTTOIS(0); green=EIGHTTOIS(0); blue=EIGHTTOIS(0); alias='K';
61 }
62 else if(StrcasecmpIgnoreSpaces(longname,"Photo Black")==0)
63 {
64 red=EIGHTTOIS(0); green=EIGHTTOIS(0); blue=EIGHTTOIS(0); alias='K';
65 }
66 else if(StrcasecmpIgnoreSpaces(longname,"Matte Black")==0)
67 {
68 red=EIGHTTOIS(0); green=EIGHTTOIS(0); blue=EIGHTTOIS(0); alias='T';
69 }
70 else if(StrcasecmpIgnoreSpaces(longname,"Light Cyan")==0)
71 {
72 red=EIGHTTOIS(127); green=EIGHTTOIS(220); blue=EIGHTTOIS(255); alias='c';
73 }
74 else if(StrcasecmpIgnoreSpaces(longname,"Light Magenta")==0)
75 {
76 red=EIGHTTOIS(255); green=EIGHTTOIS(127); blue=EIGHTTOIS(220); alias='m';
77 }
78 else if(StrcasecmpIgnoreSpaces(longname,"Vivid Light Magenta")==0)
79 {
80 red=EIGHTTOIS(255); green=EIGHTTOIS(127); blue=EIGHTTOIS(220); alias='m';
81 }
82 else if(StrcasecmpIgnoreSpaces(longname,"Light Black")==0)
83 {
84 red=EIGHTTOIS(127); green=EIGHTTOIS(127); blue=EIGHTTOIS(127); alias='k';
85 }
86 else if(StrcasecmpIgnoreSpaces(longname,"Red")==0)
87 {
88 red=EIGHTTOIS(255); green=EIGHTTOIS(0); blue=EIGHTTOIS(0); alias='R';
89 }
90 else if(StrcasecmpIgnoreSpaces(longname,"Blue")==0)
91 {
92 red=EIGHTTOIS(0); green=EIGHTTOIS(0); blue=EIGHTTOIS(255); alias='B';
93 }
94 else
95 throw "Unknown colorant";
96 if(longname)
97 this->longname=strdup(longname);
98 }
99
100
ISDeviceN_Colorant_Preview(const ISDeviceN_Colorant_Preview & other)101 ISDeviceN_Colorant_Preview::ISDeviceN_Colorant_Preview(const ISDeviceN_Colorant_Preview &other)
102 : red(other.red), green(other.green), blue(other.blue), longname(NULL), alias(other.alias)
103 {
104 if(other.longname)
105 longname=strdup(other.longname);
106 }
107
108
~ISDeviceN_Colorant_Preview()109 ISDeviceN_Colorant_Preview::~ISDeviceN_Colorant_Preview()
110 {
111 if(longname)
112 free(longname);
113 }
114
115
operator =(const ISDeviceN_Colorant_Preview & other)116 ISDeviceN_Colorant_Preview &ISDeviceN_Colorant_Preview::operator=(const ISDeviceN_Colorant_Preview &other)
117 {
118 if(longname)
119 free(longname);
120 if(other.longname)
121 longname=strdup(other.longname);
122 red=other.red;
123 green=other.green;
124 blue=other.blue;
125 alias=other.alias;
126 return(*this);
127 }
128
129 //////////////////////////////////////////////////////////////////////////////
130
131 class ISDeviceNPreview_Colorant
132 {
133 public:
134 ISDataType red,green,blue;
135 };
136
137 //////////////////////////////////////////////////////////////////////////////
138
139
~ImageSource_DeviceN_Preview()140 ImageSource_DeviceN_Preview::~ImageSource_DeviceN_Preview()
141 {
142 if(source)
143 delete source;
144
145 if(colorants)
146 delete[] colorants;
147 }
148
149
GetRow(int row)150 ISDataType *ImageSource_DeviceN_Preview::GetRow(int row)
151 {
152 if(row==currentrow)
153 return(rowbuffer);
154
155 ISDataType *srcdata=source->GetRow(row);
156
157 switch(type)
158 {
159 case IS_TYPE_RGBA:
160 for(int x=0;x<width;++x)
161 {
162 unsigned int red=IS_SAMPLEMAX,green=IS_SAMPLEMAX,blue=IS_SAMPLEMAX;
163 for(int s=0;s<source->samplesperpixel-1;++s)
164 {
165 unsigned int t=srcdata[x*source->samplesperpixel+s];
166 unsigned int tr=IS_SAMPLEMAX-((IS_SAMPLEMAX-colorants[s].red)*t)/IS_SAMPLEMAX;
167 unsigned int tg=IS_SAMPLEMAX-((IS_SAMPLEMAX-colorants[s].green)*t)/IS_SAMPLEMAX;
168 unsigned int tb=IS_SAMPLEMAX-((IS_SAMPLEMAX-colorants[s].blue)*t)/IS_SAMPLEMAX;
169 if(tr<red) red=tr;
170 if(tg<green) green=tg;
171 if(tb<blue) blue=tb;
172 }
173 rowbuffer[x*samplesperpixel]=red;
174 rowbuffer[x*samplesperpixel+1]=green;
175 rowbuffer[x*samplesperpixel+2]=blue;
176 rowbuffer[x*samplesperpixel+3]=srcdata[x*source->samplesperpixel+source->samplesperpixel-1];
177 }
178 break;
179 case IS_TYPE_RGB:
180 for(int x=0;x<width;++x)
181 {
182 unsigned int red=IS_SAMPLEMAX,green=IS_SAMPLEMAX,blue=IS_SAMPLEMAX;
183 for(int s=0;s<source->samplesperpixel;++s)
184 {
185 unsigned int t=srcdata[x*source->samplesperpixel+s];
186 unsigned int tr=IS_SAMPLEMAX-((IS_SAMPLEMAX-colorants[s].red)*t)/IS_SAMPLEMAX;
187 unsigned int tg=IS_SAMPLEMAX-((IS_SAMPLEMAX-colorants[s].green)*t)/IS_SAMPLEMAX;
188 unsigned int tb=IS_SAMPLEMAX-((IS_SAMPLEMAX-colorants[s].blue)*t)/IS_SAMPLEMAX;
189 if(tr<red) red=tr;
190 if(tg<green) green=tg;
191 if(tb<blue) blue=tb;
192 }
193 rowbuffer[x*samplesperpixel]=red;
194 rowbuffer[x*samplesperpixel+1]=green;
195 rowbuffer[x*samplesperpixel+2]=blue;
196 }
197 break;
198 default:
199 throw "DeviceN Preview currently only supports RGB output";
200 break;
201 }
202
203 currentrow=row;
204
205 return(rowbuffer);
206 }
207
208
ImageSource_DeviceN_Preview(struct ImageSource * source,DeviceNColorantList * cols,int firstcolorant)209 ImageSource_DeviceN_Preview::ImageSource_DeviceN_Preview(struct ImageSource *source,DeviceNColorantList *cols,int firstcolorant)
210 : ImageSource(source), source(source), colorants(NULL)
211 {
212 int sourcespp=source->samplesperpixel;
213 if(HAS_ALPHA(type))
214 {
215 type=IS_TYPE_RGBA;
216 samplesperpixel=4;
217 --sourcespp;
218 }
219 else
220 {
221 type=IS_TYPE_RGB;
222 samplesperpixel=3;
223 }
224 int c=cols->GetColorantCount();
225 if((c-firstcolorant)<sourcespp)
226 throw "ISDeviceN: Not enough colorants provided!";
227 colorants=new ISDeviceNPreview_Colorant[c];
228 for(int i=0;i<(c-firstcolorant);++i)
229 {
230 DeviceNColorant *col=(*cols)[i+firstcolorant];
231 colorants[i].red=EIGHTTOIS(col->red);
232 colorants[i].green=EIGHTTOIS(col->green);
233 colorants[i].blue=EIGHTTOIS(col->blue);
234 }
235 MakeRowBuffer();
236 }
237
238