/src/mupdf/thirdparty/lcms2/src/extra_xform.h
Line | Count | Source |
1 | | // |
2 | | // Little cms |
3 | | |
4 | | // Chameleonic header file to instantiate different versions of the |
5 | | // transform routines. |
6 | | // |
7 | | // As a bare minimum the following must be defined on entry: |
8 | | // FUNCTION_NAME the name of the function |
9 | | // |
10 | | // In addition, a range of other symbols can be optionally defined on entry |
11 | | // to make the generated code more efficient. All these symbols (and |
12 | | // FUNCTION_NAME) will be automatically undefined at the end of the file so |
13 | | // that repeated #includes of this file are made simple. |
14 | | // |
15 | | // If caching is wanted, define CACHED. |
16 | | // |
17 | | // If the representation/calculations are to be done using floating point |
18 | | // define XFORM_FLOAT. In the absence of this it is assumed that the |
19 | | // calculations will be done in 16 bit with appropriate unpacking/repacking. |
20 | | // |
21 | | // If you know the number of input/output channels, define NUMINCHANNELS and |
22 | | // NUMOUTCHANNELS. |
23 | | // |
24 | | // If you know the number of bytes used for the packed version of input and/or |
25 | | // output, define INPACKEDSAMPLESIZE and OUTPACKEDSAMPLESIZE. |
26 | | // |
27 | | // If you do not know the number of channels and/or the sample size, but you |
28 | | // do know a maximum bound on the number of bytes used to represent the |
29 | | // unpacked samples, then operation with CACHE can be accelerated by defining |
30 | | // CMPBYTES to the number of bytes that should be compared to the cached result. |
31 | | // Usually that is calculated from NUMINCHANNELS and INPACKEDSAMPLESIZE, so |
32 | | // specifying it directly is only useful if either (or both) of those is not |
33 | | // known in advance. |
34 | | // |
35 | | // For Premultiplied Alpha modes, you must define PREMULT. We only support |
36 | | // premultiplied alpha where the alpha is the last 'extra' channel, and |
37 | | // where both source and destination are packed in the same way. |
38 | | // |
39 | | // If you know the code to be used to unpack (or pack, or both) data to/from |
40 | | // the simple 16 bit transform input/output format, then you can choose |
41 | | // to this directly by defining UNPACK/PACK macros as follows: |
42 | | // UNPACK(T,TO,FROM,SIZE,AL) (Opt) code to unpack input data (T = Transform |
43 | | // TO = buffer to unpack into, FROM = data, |
44 | | // SIZE = size of data, AL = Alpha) |
45 | | // PACK(T,FROM,TO,SIZE,AL) (Opt) code to pack transformed input data |
46 | | // (T = Transform, FROM = transformed data, |
47 | | // TO = output buffer to pack into, |
48 | | // SIZE = size of data, AL = Alpha) |
49 | | // |
50 | | // Ignore AL unless PREMULT is defined, in which case it will be in the packed |
51 | | // format. AL is guaranteed to be non-zero. |
52 | | // |
53 | | // If UNPACKINCLUDESPREALPHA is defined, then UNPACK should undo the |
54 | | // premultiplication by AL (i.e. divide by AL). Otherwise AL should be ignored |
55 | | // and this routine will do it for you. |
56 | | // |
57 | | // If PACKINCLUDESPREALPHA is defined, then PACK should apply AL (i.e. multiply |
58 | | // by AL). Otherwise AL should be ignored and this routine will do it for you. |
59 | | // |
60 | | // As an alternative to the above, if you know the function name that would |
61 | | // be called, supply that in UNPACKFN and PACKFN and inlining compilers |
62 | | // should hopefully do the hard work for you. |
63 | | // UNPACKFN (Opt) function to unpack input data |
64 | | // PACKFN (Opt) function to pack input data |
65 | | // |
66 | | // If the data happens to be in the correct input format anyway, we can skip |
67 | | // unpacking it entirely and just use it direct. |
68 | | // NO_UNPACK (Opt) if defined, transform direct from the input |
69 | | // data. |
70 | | // |
71 | | // UNPACK/PACK/UNPACKFN/PACKFN/NO_UNPACK are all expected to update their |
72 | | // TO pointer to point to the next pixels data. This means for cases where |
73 | | // we have extra bytes, they should skip the extra bytes too! |
74 | | // |
75 | | // If the data happens to be in the correct output format anyway, we can skip |
76 | | // packing it entirely and just transform it direct into the buffer. |
77 | | // NO_PACK (Opt) if defined, transform direct to the output |
78 | | // data. |
79 | | // COPY_MATCHED(FROM,TO)(Opt)if defined, copy output values from FROM to |
80 | | // TO. Used in the case CACHED case where the |
81 | | // cache matches and we have to copy forwards. |
82 | | // |
83 | | // GAMUTCHECK can be predefined if a gamut check needs to be done. |
84 | | // |
85 | | // If there are a known number of extra bytes to be dealt with, define EXTRABYTES |
86 | | // to that number (such as 0 for none). |
87 | | // If you want to provide your own code for copying from input to output, define |
88 | | // COPY_EXTRAS(TRANS,FROM,TO) to do so. |
89 | | // If none of these are defined, we call cmsHandleExtraChannels. |
90 | | |
91 | | #ifndef CMPBYTES |
92 | | #ifdef NUMINCHANNELS |
93 | | #ifdef XFORM_FLOAT |
94 | | #define CMPBYTES (NUMINCHANNELS*4) |
95 | | #else |
96 | | #define CMPBYTES (NUMINCHANNELS*2) |
97 | | #endif |
98 | | #endif |
99 | | #endif |
100 | | |
101 | | #ifdef CMPBYTES |
102 | | // Previously, we've attempted to do 'int' based checks here, but this falls |
103 | | // foul of some compilers with their strict pointer aliasing. We have the |
104 | | // choice of calling memcmp (which tests using chars, so is safe), or of |
105 | | // testing using the actual type. |
106 | | #ifdef XFORM_FLOAT |
107 | | #if CMPBYTES == 4 |
108 | | #define COMPARE(A,B) ((A)[0] != (B)[0]) |
109 | | #elif CMPBYTES == 8 |
110 | | #define COMPARE(A,B) (((A)[0] != (B)[0]) || ((A)[1] != (B)[1])) |
111 | | #elif CMPBYTES == 12 |
112 | | #define COMPARE(A,B) (((A)[0] != (B)[0]) || ((A)[1] != (B)[1]) || ((A)[2] != (B)[2])) |
113 | | #elif CMPBYTES == 16 |
114 | | #define COMPARE(A,B) (((A)[0] != (B)[0]) || ((A)[1] != (B)[1]) || ((A)[2] != (B)[2]) || ((A)[3] != (B)[3])) |
115 | | #endif |
116 | | #else |
117 | | #if CMPBYTES == 2 |
118 | 27 | #define COMPARE(A,B) ((A)[0] != (B)[0]) |
119 | | #elif CMPBYTES == 4 |
120 | 0 | #define COMPARE(A,B) (((A)[0] != (B)[0]) || ((A)[1] != (B)[1])) |
121 | | #elif CMPBYTES == 6 |
122 | 0 | #define COMPARE(A,B) (((A)[0] != (B)[0]) || ((A)[1] != (B)[1]) || ((A)[2] != (B)[2])) |
123 | | #elif CMPBYTES == 8 |
124 | 0 | #define COMPARE(A,B) (((A)[0] != (B)[0]) || ((A)[1] != (B)[1]) || ((A)[2] != (B)[2]) || ((A)[3] != (B)[3])) |
125 | | #endif |
126 | | #endif |
127 | | #else |
128 | | // Otherwise, set INBYTES to be the maximum size it could possibly be. |
129 | | #ifdef XFORM_FLOAT |
130 | | #define CMPBYTES (sizeof(cmsFloat32Number)*cmsMAXCHANNELS) |
131 | | #else |
132 | 0 | #define CMPBYTES (sizeof(cmsUInt16Number)*cmsMAXCHANNELS) |
133 | | #endif |
134 | | #endif |
135 | | |
136 | | #ifndef COMPARE |
137 | 0 | #define COMPARE(A,B) memcmp((A),(B), CMPBYTES) |
138 | | #endif |
139 | | |
140 | | #if defined(UNPACK) |
141 | | // Nothing to do, UNPACK is already defined |
142 | | #elif defined(NO_UNPACK) |
143 | | #define UNPACK(CTX,T,TO,FROM,STRIDE,AL) do { } while (0) |
144 | | #elif defined(UNPACKFN) |
145 | | #define UNPACK(CTX,T,TO,FROM,STRIDE,AL) \ |
146 | | do { (FROM) = UNPACKFN((CTX),(T),(TO),(FROM),(STRIDE),(AL)); } while (0) |
147 | | #elif defined(XFORM_FLOAT) |
148 | | #define UNPACK(CTX,T,TO,FROM,STRIDE,AL) \ |
149 | | do { (FROM) = (T)->FromInputFloat((CTX),(T),(TO),(FROM),(STRIDE)); } while (0) |
150 | | #else |
151 | | #define UNPACK(CTX,T,TO,FROM,STRIDE,AL) \ |
152 | 0 | do { (FROM) = (T)->FromInput((CTX),(T),(TO),(FROM),(STRIDE)); } while (0) |
153 | | #endif |
154 | | |
155 | | #if defined(PACK) |
156 | | // Nothing to do, PACK is already defined |
157 | | #elif defined(NO_PACK) |
158 | | #define PACK(CTX,T,FROM,TO,STRIDE,AL) \ |
159 | | do { (FROM) += (totaloutbytes/sizeof(XFORM_TYPE)); } while (0) |
160 | | #elif defined(PACKFN) |
161 | | #define PACK(CTX,T,FROM,TO,STRIDE,AL) \ |
162 | | do { (TO) = PACKFN((CTX),(T),(FROM),(TO),(STRIDE)); } while (0) |
163 | | #elif defined(XFORM_FLOAT) |
164 | | #define PACK(CTX,T,FROM,TO,STRIDE,AL) \ |
165 | | do { (TO) = (T)->ToOutputFloat((CTX),(T),(FROM),(TO),(STRIDE)); } while (0) |
166 | | #else |
167 | | #define PACK(CTX,T,FROM,TO,STRIDE,AL) \ |
168 | 0 | do { (TO) = (T)->ToOutput((CTX),(T),(FROM),(TO),(STRIDE)); } while (0) |
169 | | #endif |
170 | | |
171 | | #ifndef ZEROPACK |
172 | | /* The 'default' definition of ZEROPACK only works when |
173 | | * inpackedsamplesize == outpackedsamplesize. */ |
174 | 0 | #define ZEROPACK(CTX,T,TO,FROM) do { \ |
175 | 0 | memset((TO),0,numoutchannels*outpackedsamplesize);\ |
176 | 0 | if (numextras != 0) memcpy((TO)+numoutchannels*outpackedsamplesize,\ |
177 | 0 | (FROM)+numinchannels*inpackedsamplesize,\ |
178 | 0 | numextras*outpackedsamplesize);\ |
179 | 0 | (TO)+=(1+prealphaindexout)*outpackedsamplesize; } while (0) |
180 | | #endif |
181 | | |
182 | | #ifndef UNPRE |
183 | | #ifdef PREALPHA |
184 | | #else |
185 | | #define UNPRE(CTX,T,S,A) do {} while (0) |
186 | | #endif |
187 | | #endif |
188 | | |
189 | | #ifndef REPRE |
190 | | #ifdef PREALPHA |
191 | | #define REPRE(CTX,T,S,A) do { int i; for (i = 0; i < numoutchannels; i++) \ |
192 | | (S)[i] = mul65535((S)[i],A); } while (0) |
193 | | #else |
194 | | #define REPRE(CTX,T,S,A) do {} while (0) |
195 | | #endif |
196 | | #endif |
197 | | |
198 | | #ifndef XFORMVARS |
199 | | #define XFORMVARS(p) do { } while (0) |
200 | | #endif |
201 | | |
202 | | #if defined(NUMOUTCHANNELS) |
203 | | #ifdef XFORM_FLOAT |
204 | | #define OUTBYTES (sizeof(cmsFloat32Number)*NUMOUTCHANNELS) |
205 | | #else |
206 | | #define OUTBYTES (sizeof(cmsUInt16Number)*NUMOUTCHANNELS) |
207 | | #endif |
208 | | #endif |
209 | | |
210 | | #if defined(NO_PACK) && !defined(COPY_MATCHED) && defined(OUTBYTES) |
211 | | #if (defined(XFORM_FLOAT) && OUTBYTES == 4) || OUTBYTES == 2 |
212 | | #define COPY_MATCHED(FROM,TO) ((TO)[0] = (FROM)[0]) |
213 | | #elif (defined(XFORM_FLOAT) && OUTBYTES == 8) || OUTBYTES == 4 |
214 | | #define COPY_MATCHED(FROM,TO) ((TO)[0] = (FROM)[0],(TO)[1] = (FROM)[1]) |
215 | | #elif (defined(XFORM_FLOAT) && OUTBYTES == 12) || OUTBYTES == 6 |
216 | | #define COPY_MATCHED(FROM,TO) ((TO)[0] = (FROM)[0],(TO)[1] = (FROM)[1],(TO)[2] = (FROM)[2]) |
217 | | #elif (defined(XFORM_FLOAT) && OUTBYTES == 16) || OUTBYTES == 8 |
218 | | #define COPY_MATCHED(FROM,TO) ((TO)[0] = (FROM)[0],(TO)[1] = (FROM)[1],(TO)[2] = (FROM)[2],(TO)[3] = (FROM)[3]) |
219 | | #else |
220 | | #define COPY_MATCHED(FROM,TO) memcpy((TO),(FROM),(OUTBYTES)) |
221 | | #endif |
222 | | #endif |
223 | | |
224 | | #ifdef XFORM_FLOAT |
225 | | #define XFORM_TYPE cmsFloat32Number |
226 | | #else |
227 | 81 | #define XFORM_TYPE cmsUInt16Number |
228 | | #endif |
229 | | |
230 | | #ifndef COPY_EXTRAS |
231 | | #ifdef NUMEXTRAS |
232 | | #if NUMEXTRAS == 0 |
233 | 27 | #define COPY_EXTRAS(TRANS,FROM,TO) do { } while (0) |
234 | | #else |
235 | | #define COPY_EXTRAS(TRANS,FROM,TO) \ |
236 | 0 | do { memcpy((TO),(FROM),(NUMEXTRAS)*inpackedsamplesize); \ |
237 | 0 | (TO) += (NUMEXTRAS)*inpackedsamplesize; \ |
238 | 0 | (FROM) += (NUMEXTRAS)*inpackedsamplesize; \ |
239 | 0 | } while (0) |
240 | | #endif |
241 | | #else |
242 | | #define BULK_COPY_EXTRAS |
243 | 0 | #define COPY_EXTRAS(TRANS,FROM,TO) do { } while (0) |
244 | | #endif |
245 | | #endif |
246 | | |
247 | | static |
248 | | void FUNCTION_NAME(cmsContext ContextID, |
249 | | _cmsTRANSFORM* p, |
250 | | const void* in, |
251 | | void* out, |
252 | | cmsUInt32Number PixelsPerLine, |
253 | | cmsUInt32Number LineCount, |
254 | | const cmsStride* Stride) |
255 | 27 | { |
256 | 27 | _cmsTRANSFORMCORE *core = p->core; |
257 | 27 | #ifndef NO_UNPACK |
258 | | #ifdef XFORM_FLOAT |
259 | | cmsFloat32Number wIn[cmsMAXCHANNELS*2]; |
260 | | #else |
261 | 27 | cmsUInt16Number wIn[cmsMAXCHANNELS*2]; |
262 | 27 | #endif |
263 | 54 | #define wIn0 (&wIn[0]) |
264 | 54 | #define wIn1 (&wIn[cmsMAXCHANNELS]) |
265 | 27 | #endif |
266 | 27 | XFORM_TYPE *currIn; |
267 | | #ifdef CACHED |
268 | 27 | XFORM_TYPE *prevIn; |
269 | | #endif /* CACHED */ |
270 | | #ifdef NO_PACK |
271 | | XFORM_TYPE *wOut = (XFORM_TYPE *)out; |
272 | | XFORM_TYPE *prevOut = (XFORM_TYPE *)p->Cache.CacheOut; |
273 | | #else |
274 | 27 | XFORM_TYPE wOut[cmsMAXCHANNELS]; |
275 | 27 | #endif |
276 | | #if defined(PREALPHA) && !defined(PACKINCLUDESPREALPHA) |
277 | 0 | XFORM_TYPE wScaled[cmsMAXCHANNELS]; |
278 | | #endif |
279 | | #ifdef GAMUTCHECK |
280 | | _cmsPipelineEval16Fn evalGamut = core->GamutCheck->Eval16Fn; |
281 | | #endif /* GAMUTCHECK */ |
282 | | #ifdef XFORM_FLOAT |
283 | | _cmsPipelineEvalFloatFn eval = core->Lut->EvalFloatFn; |
284 | | const cmsPipeline *data = core->Lut; |
285 | | #else |
286 | 27 | _cmsPipelineEval16Fn eval = core->Lut->Eval16Fn; |
287 | 27 | void *data = core->Lut->Data; |
288 | 27 | #endif |
289 | 27 | cmsUInt32Number bppi = Stride->BytesPerPlaneIn; |
290 | 27 | cmsUInt32Number bppo = Stride->BytesPerPlaneOut; |
291 | | #ifdef NUMINCHANNELS |
292 | 27 | int numinchannels = NUMINCHANNELS; |
293 | | #else |
294 | 0 | int numinchannels = T_CHANNELS(p->InputFormat); |
295 | | #endif |
296 | | #ifdef NUMOUTCHANNELS |
297 | 27 | int numoutchannels = NUMOUTCHANNELS; |
298 | | #else |
299 | 0 | int numoutchannels = T_CHANNELS(p->OutputFormat); |
300 | | #endif |
301 | | #ifdef NUMEXTRAS |
302 | 27 | int numextras = NUMEXTRAS; |
303 | | #else |
304 | 0 | int numextras = T_EXTRA(p->InputFormat); |
305 | | #endif |
306 | | #ifdef INPACKEDSAMPLESIZE |
307 | 27 | int inpackedsamplesize = INPACKEDSAMPLESIZE; |
308 | | #else |
309 | 0 | int inpackedsamplesize = T_BYTES(p->InputFormat); |
310 | | #endif |
311 | | #ifdef OUTPACKEDSAMPLESIZE |
312 | 27 | int outpackedsamplesize = OUTPACKEDSAMPLESIZE; |
313 | | #else |
314 | 0 | int outpackedsamplesize = T_BYTES(p->OutputFormat); |
315 | | #endif |
316 | 27 | int prealphaindexin = numinchannels + numextras - 1; |
317 | 27 | int prealphaindexout = numoutchannels + numextras - 1; |
318 | 27 | int totalinbytes = (numinchannels + numextras)*inpackedsamplesize; |
319 | 27 | int totaloutbytes = (numoutchannels + numextras)*outpackedsamplesize; |
320 | | |
321 | | /* Silence some warnings */ |
322 | 27 | (void)bppi; |
323 | 27 | (void)bppo; |
324 | 27 | (void)prealphaindexin; |
325 | 27 | (void)numextras; |
326 | 27 | (void)prealphaindexout; |
327 | 27 | (void)inpackedsamplesize; |
328 | 27 | (void)outpackedsamplesize; |
329 | 27 | (void)totalinbytes; |
330 | 27 | (void)totaloutbytes; |
331 | | |
332 | | #ifdef BULK_COPY_EXTRAS |
333 | 0 | if (core->dwOriginalFlags & cmsFLAGS_COPY_ALPHA) |
334 | 0 | _cmsHandleExtraChannels(ContextID, p, in, out, PixelsPerLine, LineCount, Stride); |
335 | | #endif |
336 | | |
337 | 27 | if (PixelsPerLine == 0) |
338 | 0 | return; |
339 | | |
340 | | #ifdef NO_UNPACK |
341 | | prevIn = (XFORM_TYPE *)p->Cache.CacheIn; |
342 | | #else |
343 | | #ifdef CACHED |
344 | | // Empty buffers for quick memcmp |
345 | 27 | memset(wIn1, 0, sizeof(XFORM_TYPE) * cmsMAXCHANNELS); |
346 | | |
347 | | // Get copy of zero cache |
348 | 27 | memcpy(wIn0, p->Cache.CacheIn, sizeof(XFORM_TYPE) * cmsMAXCHANNELS); |
349 | 27 | memcpy(wOut, p->Cache.CacheOut, sizeof(XFORM_TYPE) * cmsMAXCHANNELS); |
350 | | |
351 | | // The caller guarantees us that the cache is always valid on entry; if |
352 | | // the representation is changed, the cache is reset. |
353 | 27 | prevIn = wIn0; |
354 | | #endif /* CACHED */ |
355 | 27 | currIn = wIn1; |
356 | 0 | #endif |
357 | |
|
358 | 54 | while (LineCount-- > 0) |
359 | 27 | { |
360 | 27 | cmsUInt32Number n = PixelsPerLine; |
361 | 27 | cmsUInt8Number* accum = (cmsUInt8Number*) in; |
362 | 27 | cmsUInt8Number* output = (cmsUInt8Number*) out; |
363 | | #ifdef NO_UNPACK |
364 | | currIn = (XFORM_TYPE *)accum; |
365 | | #endif |
366 | 54 | while (n-- > 0) { // prevIn == CacheIn, wOut = CacheOut |
367 | | #ifdef PREALPHA |
368 | | #ifdef XFORM_FLOAT |
369 | | cmsFloat32Number alpha = ((cmsFloat32Number *)accum)[prealphaindexin]; |
370 | | #else |
371 | 0 | cmsUInt32Number alpha = inpackedsamplesize == 2 ? |
372 | 0 | ((cmsUInt16Number *)accum)[prealphaindexin] : |
373 | 0 | (accum[prealphaindexin]); |
374 | | #endif |
375 | 0 | if (alpha == 0) { |
376 | 0 | ZEROPACK(ContextID,p,output,accum); |
377 | 0 | accum += inpackedsamplesize*(prealphaindexin+1); |
378 | 0 | } else { |
379 | 0 | #endif |
380 | 27 | UNPACK(ContextID,p,currIn,accum,bppi,alpha); |
381 | | #ifdef PREALPHA |
382 | | #ifndef UNPACKINCLUDESPREALPHA |
383 | | #ifdef XFORM_FLOAT |
384 | | { |
385 | | int i; |
386 | | cmsFloat32Number inva = 1.0f / alpha; |
387 | | for (i = 0; i < numinchannels; i++) |
388 | | currIn[i] *= inva; |
389 | | } |
390 | | #else |
391 | | { |
392 | | int i; |
393 | 0 | cmsUInt32Number al = inpackedsamplesize == 1 ? alpha*0x101 : alpha; |
394 | | cmsUInt32Number inva = 0xffff0000U / al; |
395 | 0 | for (i = 0; i < numinchannels; i++) |
396 | 0 | currIn[i] = ((currIn[i] * inva)>>16); |
397 | | } |
398 | | #endif |
399 | | #endif |
400 | | #endif |
401 | | #ifdef CACHED |
402 | 27 | if (COMPARE(currIn, prevIn)) |
403 | 0 | #endif /* CACHED */ |
404 | 0 | { |
405 | | #ifdef GAMUTCHECK |
406 | | #ifdef XFORM_FLOAT |
407 | | cmsFloat32Number OutOfGamut; |
408 | | |
409 | | // Evaluate gamut marker. |
410 | | cmsPipelineEvalFloat(currIn, &OutOfGamut, core->GamutCheck); |
411 | | |
412 | | // Is current color out of gamut? |
413 | | if (OutOfGamut > 0.0) |
414 | | // Certainly, out of gamut |
415 | | for (j=0; j < cmsMAXCHANNELS; j++) |
416 | | fOut[j] = -1.0; |
417 | | else |
418 | | #else |
419 | | cmsUInt16Number wOutOfGamut; |
420 | | |
421 | | evalGamut(ContextID, currIn, &wOutOfGamut, core->GamutCheck->Data); |
422 | 0 | if (wOutOfGamut >= 1) |
423 | | /* RJW: Could be faster? copy once to a local buffer? */ |
424 | 0 | cmsGetAlarmCodes(ContextID, wOut); |
425 | 0 | else |
426 | 0 | #endif /* FLOAT_XFORM */ |
427 | 0 | #endif /* GAMUTCHECK */ |
428 | 0 | eval(ContextID, currIn, wOut, data); |
429 | | #ifdef NO_UNPACK |
430 | | #ifdef CACHED |
431 | | prevIn = currIn; |
432 | | #endif |
433 | | currIn = (XFORM_TYPE *)(((char *)currIn) + totalinbytes); |
434 | | #else |
435 | | #ifdef CACHED |
436 | 0 | {XFORM_TYPE *tmp = currIn; currIn = prevIn; prevIn = tmp;} // SWAP |
437 | | #endif /* CACHED */ |
438 | 0 | #endif /* NO_UNPACK */ |
439 | 0 | } |
440 | | #ifdef NO_PACK |
441 | | else |
442 | | COPY_MATCHED(prevOut,wOut); |
443 | | prevOut = wOut; |
444 | | #endif |
445 | | #ifdef PREALPHA |
446 | | #ifndef PACKINCLUDESPREALPHA |
447 | | #ifdef XFORM_FLOAT |
448 | | { |
449 | | int i; |
450 | | for (i = 0; i < numoutchannels; i++) |
451 | | wScaled = wOut[i] * alpha; |
452 | | } |
453 | | #else |
454 | | { |
455 | | int i; |
456 | 0 | cmsUInt32Number al = inpackedsamplesize == 1 ? alpha*0x101 : alpha; |
457 | 0 | for (i = 0; i < numoutchannels; i++) |
458 | 0 | wScaled[i] = mul65535(wOut[i],al); |
459 | | } |
460 | | #endif |
461 | 0 | PACK(ContextID,p,wScaled,output,bppo,alpha); |
462 | | #else |
463 | 0 | PACK(ContextID,p,wOut,output,bppo,alpha); |
464 | | #endif |
465 | | #else |
466 | 27 | PACK(ContextID,p,wOut,output,bppo,alpha); |
467 | | #endif |
468 | 27 | COPY_EXTRAS(p,accum,output); |
469 | | #ifdef PREALPHA |
470 | | } |
471 | | #endif |
472 | 27 | } /* End x loop */ |
473 | 27 | in = (void *)((cmsUInt8Number *)in + Stride->BytesPerLineIn); |
474 | 27 | out = (void *)((cmsUInt8Number *)out + Stride->BytesPerLineOut); |
475 | 27 | } /* End y loop */ |
476 | | /* The following code is only safe if we know that a given transform is |
477 | | * called on one thread a time. */ |
478 | | #if 0 |
479 | | #ifdef CACHED |
480 | | #ifdef NO_UNPACK |
481 | | memcpy(p->Cache.CacheIn,prevIn, CMPBYTES); |
482 | | #else |
483 | | memcpy(p->Cache.CacheIn, prevIn, sizeof(XFORM_TYPE) * cmsMAXCHANNELS); |
484 | | #endif |
485 | | #ifdef NO_PACK |
486 | | COPY_MATCHED(prevOut,p->Cache.CacheOut); |
487 | | #else |
488 | | memcpy(p->Cache.CacheOut, wOut, sizeof(XFORM_TYPE) * cmsMAXCHANNELS); |
489 | | #endif /* NO_PACK */ |
490 | | #endif /* CACHED */ |
491 | | #endif |
492 | 0 | } Unexecuted instantiation: cmsxform.c:PrecalculatedXFORMGamutCheck_P Unexecuted instantiation: cmsxform.c:PrecalculatedXFORM_P Unexecuted instantiation: cmsxform.c:CachedXFORMGamutCheck_P Unexecuted instantiation: cmsxform.c:PrecalculatedXFORMGamutCheck Unexecuted instantiation: cmsxform.c:PrecalculatedXFORM Unexecuted instantiation: cmsxform.c:CachedXFORMGamutCheck Unexecuted instantiation: cmsxform.c:CachedXFORM1to1_P1 Unexecuted instantiation: cmsxform.c:CachedXFORM1x2to1x2_P2 Unexecuted instantiation: cmsxform.c:CachedXFORM1to3_P1 Unexecuted instantiation: cmsxform.c:CachedXFORM1x2to3x2_P2 Unexecuted instantiation: cmsxform.c:CachedXFORM1to4_P1 Unexecuted instantiation: cmsxform.c:CachedXFORM1x2to4x2_P2 Unexecuted instantiation: cmsxform.c:CachedXFORM3to1_P1 Unexecuted instantiation: cmsxform.c:CachedXFORM3x2to1x2_P2 Unexecuted instantiation: cmsxform.c:CachedXFORM3to3_P1 Unexecuted instantiation: cmsxform.c:CachedXFORM3x2to3x2_P2 Unexecuted instantiation: cmsxform.c:CachedXFORM3to4_P1 Unexecuted instantiation: cmsxform.c:CachedXFORM3x2to4x2_P2 Unexecuted instantiation: cmsxform.c:CachedXFORM4to1_P1 Unexecuted instantiation: cmsxform.c:CachedXFORM4x2to1x2_P2 Unexecuted instantiation: cmsxform.c:CachedXFORM4to3_P1 Unexecuted instantiation: cmsxform.c:CachedXFORM4x2to3x2_P2 Unexecuted instantiation: cmsxform.c:CachedXFORM4to4_P1 Unexecuted instantiation: cmsxform.c:CachedXFORM4x2to4x2_P2 Unexecuted instantiation: cmsxform.c:CachedXFORM1to1_1 Unexecuted instantiation: cmsxform.c:CachedXFORM1x2to1x2_2 Unexecuted instantiation: cmsxform.c:CachedXFORM1to3_1 Unexecuted instantiation: cmsxform.c:CachedXFORM1x2to3x2_2 Unexecuted instantiation: cmsxform.c:CachedXFORM1to4_1 Unexecuted instantiation: cmsxform.c:CachedXFORM1x2to4x2_2 Unexecuted instantiation: cmsxform.c:CachedXFORM3to1_1 Unexecuted instantiation: cmsxform.c:CachedXFORM3x2to1x2_2 Unexecuted instantiation: cmsxform.c:CachedXFORM3to3_1 Unexecuted instantiation: cmsxform.c:CachedXFORM3x2to3x2_2 Unexecuted instantiation: cmsxform.c:CachedXFORM3to4_1 Unexecuted instantiation: cmsxform.c:CachedXFORM3x2to4x2_2 Unexecuted instantiation: cmsxform.c:CachedXFORM4to1_1 Unexecuted instantiation: cmsxform.c:CachedXFORM4x2to1x2_2 Unexecuted instantiation: cmsxform.c:CachedXFORM4to3_1 Unexecuted instantiation: cmsxform.c:CachedXFORM4x2to3x2_2 Unexecuted instantiation: cmsxform.c:CachedXFORM4to4_1 Unexecuted instantiation: cmsxform.c:CachedXFORM4x2to4x2_2 Unexecuted instantiation: cmsxform.c:CachedXFORM_P1 Unexecuted instantiation: cmsxform.c:CachedXFORM_P2 Unexecuted instantiation: cmsxform.c:CachedXFORM Unexecuted instantiation: cmsxform.c:CachedXFORM1to1 Unexecuted instantiation: cmsxform.c:CachedXFORM1x2to1x2 Unexecuted instantiation: cmsxform.c:CachedXFORM1to3 cmsxform.c:CachedXFORM1x2to3x2 Line | Count | Source | 255 | 27 | { | 256 | 27 | _cmsTRANSFORMCORE *core = p->core; | 257 | 27 | #ifndef NO_UNPACK | 258 | | #ifdef XFORM_FLOAT | 259 | | cmsFloat32Number wIn[cmsMAXCHANNELS*2]; | 260 | | #else | 261 | 27 | cmsUInt16Number wIn[cmsMAXCHANNELS*2]; | 262 | 27 | #endif | 263 | 27 | #define wIn0 (&wIn[0]) | 264 | 27 | #define wIn1 (&wIn[cmsMAXCHANNELS]) | 265 | 27 | #endif | 266 | 27 | XFORM_TYPE *currIn; | 267 | 27 | #ifdef CACHED | 268 | 27 | XFORM_TYPE *prevIn; | 269 | 27 | #endif /* CACHED */ | 270 | | #ifdef NO_PACK | 271 | | XFORM_TYPE *wOut = (XFORM_TYPE *)out; | 272 | | XFORM_TYPE *prevOut = (XFORM_TYPE *)p->Cache.CacheOut; | 273 | | #else | 274 | 27 | XFORM_TYPE wOut[cmsMAXCHANNELS]; | 275 | 27 | #endif | 276 | | #if defined(PREALPHA) && !defined(PACKINCLUDESPREALPHA) | 277 | | XFORM_TYPE wScaled[cmsMAXCHANNELS]; | 278 | | #endif | 279 | | #ifdef GAMUTCHECK | 280 | | _cmsPipelineEval16Fn evalGamut = core->GamutCheck->Eval16Fn; | 281 | | #endif /* GAMUTCHECK */ | 282 | | #ifdef XFORM_FLOAT | 283 | | _cmsPipelineEvalFloatFn eval = core->Lut->EvalFloatFn; | 284 | | const cmsPipeline *data = core->Lut; | 285 | | #else | 286 | 27 | _cmsPipelineEval16Fn eval = core->Lut->Eval16Fn; | 287 | 27 | void *data = core->Lut->Data; | 288 | 27 | #endif | 289 | 27 | cmsUInt32Number bppi = Stride->BytesPerPlaneIn; | 290 | 27 | cmsUInt32Number bppo = Stride->BytesPerPlaneOut; | 291 | 27 | #ifdef NUMINCHANNELS | 292 | 27 | int numinchannels = NUMINCHANNELS; | 293 | | #else | 294 | | int numinchannels = T_CHANNELS(p->InputFormat); | 295 | | #endif | 296 | 27 | #ifdef NUMOUTCHANNELS | 297 | 27 | int numoutchannels = NUMOUTCHANNELS; | 298 | | #else | 299 | | int numoutchannels = T_CHANNELS(p->OutputFormat); | 300 | | #endif | 301 | 27 | #ifdef NUMEXTRAS | 302 | 27 | int numextras = NUMEXTRAS; | 303 | | #else | 304 | | int numextras = T_EXTRA(p->InputFormat); | 305 | | #endif | 306 | 27 | #ifdef INPACKEDSAMPLESIZE | 307 | 27 | int inpackedsamplesize = INPACKEDSAMPLESIZE; | 308 | | #else | 309 | | int inpackedsamplesize = T_BYTES(p->InputFormat); | 310 | | #endif | 311 | 27 | #ifdef OUTPACKEDSAMPLESIZE | 312 | 27 | int outpackedsamplesize = OUTPACKEDSAMPLESIZE; | 313 | | #else | 314 | | int outpackedsamplesize = T_BYTES(p->OutputFormat); | 315 | | #endif | 316 | 27 | int prealphaindexin = numinchannels + numextras - 1; | 317 | 27 | int prealphaindexout = numoutchannels + numextras - 1; | 318 | 27 | int totalinbytes = (numinchannels + numextras)*inpackedsamplesize; | 319 | 27 | int totaloutbytes = (numoutchannels + numextras)*outpackedsamplesize; | 320 | | | 321 | | /* Silence some warnings */ | 322 | 27 | (void)bppi; | 323 | 27 | (void)bppo; | 324 | 27 | (void)prealphaindexin; | 325 | 27 | (void)numextras; | 326 | 27 | (void)prealphaindexout; | 327 | 27 | (void)inpackedsamplesize; | 328 | 27 | (void)outpackedsamplesize; | 329 | 27 | (void)totalinbytes; | 330 | 27 | (void)totaloutbytes; | 331 | | | 332 | | #ifdef BULK_COPY_EXTRAS | 333 | | if (core->dwOriginalFlags & cmsFLAGS_COPY_ALPHA) | 334 | | _cmsHandleExtraChannels(ContextID, p, in, out, PixelsPerLine, LineCount, Stride); | 335 | | #endif | 336 | | | 337 | 27 | if (PixelsPerLine == 0) | 338 | 0 | return; | 339 | | | 340 | | #ifdef NO_UNPACK | 341 | | prevIn = (XFORM_TYPE *)p->Cache.CacheIn; | 342 | | #else | 343 | 27 | #ifdef CACHED | 344 | | // Empty buffers for quick memcmp | 345 | 27 | memset(wIn1, 0, sizeof(XFORM_TYPE) * cmsMAXCHANNELS); | 346 | | | 347 | | // Get copy of zero cache | 348 | 27 | memcpy(wIn0, p->Cache.CacheIn, sizeof(XFORM_TYPE) * cmsMAXCHANNELS); | 349 | 27 | memcpy(wOut, p->Cache.CacheOut, sizeof(XFORM_TYPE) * cmsMAXCHANNELS); | 350 | | | 351 | | // The caller guarantees us that the cache is always valid on entry; if | 352 | | // the representation is changed, the cache is reset. | 353 | 27 | prevIn = wIn0; | 354 | 27 | #endif /* CACHED */ | 355 | 27 | currIn = wIn1; | 356 | 27 | #endif | 357 | | | 358 | 54 | while (LineCount-- > 0) | 359 | 27 | { | 360 | 27 | cmsUInt32Number n = PixelsPerLine; | 361 | 27 | cmsUInt8Number* accum = (cmsUInt8Number*) in; | 362 | 27 | cmsUInt8Number* output = (cmsUInt8Number*) out; | 363 | | #ifdef NO_UNPACK | 364 | | currIn = (XFORM_TYPE *)accum; | 365 | | #endif | 366 | 54 | while (n-- > 0) { // prevIn == CacheIn, wOut = CacheOut | 367 | | #ifdef PREALPHA | 368 | | #ifdef XFORM_FLOAT | 369 | | cmsFloat32Number alpha = ((cmsFloat32Number *)accum)[prealphaindexin]; | 370 | | #else | 371 | | cmsUInt32Number alpha = inpackedsamplesize == 2 ? | 372 | | ((cmsUInt16Number *)accum)[prealphaindexin] : | 373 | | (accum[prealphaindexin]); | 374 | | #endif | 375 | | if (alpha == 0) { | 376 | | ZEROPACK(ContextID,p,output,accum); | 377 | | accum += inpackedsamplesize*(prealphaindexin+1); | 378 | | } else { | 379 | | #endif | 380 | 27 | UNPACK(ContextID,p,currIn,accum,bppi,alpha); | 381 | | #ifdef PREALPHA | 382 | | #ifndef UNPACKINCLUDESPREALPHA | 383 | | #ifdef XFORM_FLOAT | 384 | | { | 385 | | int i; | 386 | | cmsFloat32Number inva = 1.0f / alpha; | 387 | | for (i = 0; i < numinchannels; i++) | 388 | | currIn[i] *= inva; | 389 | | } | 390 | | #else | 391 | | { | 392 | | int i; | 393 | | cmsUInt32Number al = inpackedsamplesize == 1 ? alpha*0x101 : alpha; | 394 | | cmsUInt32Number inva = 0xffff0000U / al; | 395 | | for (i = 0; i < numinchannels; i++) | 396 | | currIn[i] = ((currIn[i] * inva)>>16); | 397 | | } | 398 | | #endif | 399 | | #endif | 400 | | #endif | 401 | 27 | #ifdef CACHED | 402 | 27 | if (COMPARE(currIn, prevIn)) | 403 | 0 | #endif /* CACHED */ | 404 | 0 | { | 405 | | #ifdef GAMUTCHECK | 406 | | #ifdef XFORM_FLOAT | 407 | | cmsFloat32Number OutOfGamut; | 408 | | | 409 | | // Evaluate gamut marker. | 410 | | cmsPipelineEvalFloat(currIn, &OutOfGamut, core->GamutCheck); | 411 | | | 412 | | // Is current color out of gamut? | 413 | | if (OutOfGamut > 0.0) | 414 | | // Certainly, out of gamut | 415 | | for (j=0; j < cmsMAXCHANNELS; j++) | 416 | | fOut[j] = -1.0; | 417 | | else | 418 | | #else | 419 | | cmsUInt16Number wOutOfGamut; | 420 | | | 421 | | evalGamut(ContextID, currIn, &wOutOfGamut, core->GamutCheck->Data); | 422 | | if (wOutOfGamut >= 1) | 423 | | /* RJW: Could be faster? copy once to a local buffer? */ | 424 | | cmsGetAlarmCodes(ContextID, wOut); | 425 | | else | 426 | | #endif /* FLOAT_XFORM */ | 427 | | #endif /* GAMUTCHECK */ | 428 | 0 | eval(ContextID, currIn, wOut, data); | 429 | | #ifdef NO_UNPACK | 430 | | #ifdef CACHED | 431 | | prevIn = currIn; | 432 | | #endif | 433 | | currIn = (XFORM_TYPE *)(((char *)currIn) + totalinbytes); | 434 | | #else | 435 | 0 | #ifdef CACHED | 436 | 0 | {XFORM_TYPE *tmp = currIn; currIn = prevIn; prevIn = tmp;} // SWAP | 437 | 0 | #endif /* CACHED */ | 438 | 0 | #endif /* NO_UNPACK */ | 439 | 0 | } | 440 | | #ifdef NO_PACK | 441 | | else | 442 | | COPY_MATCHED(prevOut,wOut); | 443 | | prevOut = wOut; | 444 | | #endif | 445 | | #ifdef PREALPHA | 446 | | #ifndef PACKINCLUDESPREALPHA | 447 | | #ifdef XFORM_FLOAT | 448 | | { | 449 | | int i; | 450 | | for (i = 0; i < numoutchannels; i++) | 451 | | wScaled = wOut[i] * alpha; | 452 | | } | 453 | | #else | 454 | | { | 455 | | int i; | 456 | | cmsUInt32Number al = inpackedsamplesize == 1 ? alpha*0x101 : alpha; | 457 | | for (i = 0; i < numoutchannels; i++) | 458 | | wScaled[i] = mul65535(wOut[i],al); | 459 | | } | 460 | | #endif | 461 | | PACK(ContextID,p,wScaled,output,bppo,alpha); | 462 | | #else | 463 | | PACK(ContextID,p,wOut,output,bppo,alpha); | 464 | | #endif | 465 | | #else | 466 | 27 | PACK(ContextID,p,wOut,output,bppo,alpha); | 467 | 27 | #endif | 468 | 27 | COPY_EXTRAS(p,accum,output); | 469 | | #ifdef PREALPHA | 470 | | } | 471 | | #endif | 472 | 27 | } /* End x loop */ | 473 | 27 | in = (void *)((cmsUInt8Number *)in + Stride->BytesPerLineIn); | 474 | 27 | out = (void *)((cmsUInt8Number *)out + Stride->BytesPerLineOut); | 475 | 27 | } /* End y loop */ | 476 | | /* The following code is only safe if we know that a given transform is | 477 | | * called on one thread a time. */ | 478 | | #if 0 | 479 | | #ifdef CACHED | 480 | | #ifdef NO_UNPACK | 481 | | memcpy(p->Cache.CacheIn,prevIn, CMPBYTES); | 482 | | #else | 483 | | memcpy(p->Cache.CacheIn, prevIn, sizeof(XFORM_TYPE) * cmsMAXCHANNELS); | 484 | | #endif | 485 | | #ifdef NO_PACK | 486 | | COPY_MATCHED(prevOut,p->Cache.CacheOut); | 487 | | #else | 488 | | memcpy(p->Cache.CacheOut, wOut, sizeof(XFORM_TYPE) * cmsMAXCHANNELS); | 489 | | #endif /* NO_PACK */ | 490 | | #endif /* CACHED */ | 491 | | #endif | 492 | 27 | } |
Unexecuted instantiation: cmsxform.c:CachedXFORM1to4 Unexecuted instantiation: cmsxform.c:CachedXFORM1x2to4x2 Unexecuted instantiation: cmsxform.c:CachedXFORM3to1 Unexecuted instantiation: cmsxform.c:CachedXFORM3x2to1x2 Unexecuted instantiation: cmsxform.c:CachedXFORM3to3 Unexecuted instantiation: cmsxform.c:CachedXFORM3x2to3x2 Unexecuted instantiation: cmsxform.c:CachedXFORM3to4 Unexecuted instantiation: cmsxform.c:CachedXFORM3x2to4x2 Unexecuted instantiation: cmsxform.c:CachedXFORM4to1 Unexecuted instantiation: cmsxform.c:CachedXFORM4x2to1x2 Unexecuted instantiation: cmsxform.c:CachedXFORM4to3 Unexecuted instantiation: cmsxform.c:CachedXFORM4x2to3x2 Unexecuted instantiation: cmsxform.c:CachedXFORM4to4 Unexecuted instantiation: cmsxform.c:CachedXFORM4x2to4x2 Unexecuted instantiation: cmsxform.c:CachedXFORM4 Unexecuted instantiation: cmsxform.c:CachedXFORM8 |
493 | | |
494 | | #undef wIn0 |
495 | | #undef wIn1 |
496 | | #undef XFORM_TYPE |
497 | | #undef XFORM_FLOAT |
498 | | |
499 | | #undef FUNCTION_NAME |
500 | | #undef COMPARE |
501 | | #undef CMPBYTES |
502 | | #undef OUTBYTES |
503 | | #undef UNPACK |
504 | | #undef NO_UNPACK |
505 | | #undef PACK |
506 | | #undef NO_PACK |
507 | | #undef UNPACKFN |
508 | | #undef PACKFN |
509 | | #undef GAMUTCHECK |
510 | | #undef CACHED |
511 | | #undef COPY_MATCHED |
512 | | #undef EXTRABYTES |
513 | | #undef COPY_EXTRAS |
514 | | #undef BULK_COPY_EXTRAS |
515 | | #undef PREALPHA |
516 | | #undef ZEROPACK |
517 | | #undef XFORMVARS |
518 | | #undef UNPRE |
519 | | #undef REPRE |
520 | | #undef INPACKEDSAMPLESIZE |
521 | | #undef OUTPACKEDSAMPLESIZE |
522 | | #undef NUMINCHANNELS |
523 | | #undef NUMOUTCHANNELS |
524 | | #undef NUMEXTRAS |