MagickCore 6.9.13
Loading...
Searching...
No Matches
quantum-private.h
1/*
2 Copyright 1999 ImageMagick Studio LLC, a non-profit organization
3 dedicated to making software imaging solutions freely available.
4
5 You may not use this file except in compliance with the License. You may
6 obtain a copy of the License at
7
8 https://imagemagick.org/script/license.php
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15
16 MagickCore quantum inline methods.
17*/
18#ifndef MAGICKCORE_QUANTUM_PRIVATE_H
19#define MAGICKCORE_QUANTUM_PRIVATE_H
20
21#include "magick/memory_.h"
22#include "magick/cache.h"
23#include "magick/image-private.h"
24#include "magick/pixel-accessor.h"
25#include "magick/statistic-private.h"
26
27#if defined(__cplusplus) || defined(c_plusplus)
28extern "C" {
29#endif
30
31typedef struct _QuantumState
32{
33 double
34 inverse_scale;
35
36 unsigned int
37 pixel;
38
39 size_t
40 bits;
41
42 const unsigned int
43 *mask;
44} QuantumState;
45
47{
48 size_t
49 depth,
50 quantum;
51
52 QuantumFormatType
53 format;
54
55 double
56 minimum,
57 maximum,
58 scale;
59
60 size_t
61 pad;
62
63 MagickBooleanType
64 min_is_white,
65 pack;
66
67 QuantumAlphaType
68 alpha_type;
69
70 size_t
71 number_threads;
72
73 MemoryInfo
74 **pixels;
75
76 size_t
77 extent;
78
79 EndianType
80 endian;
81
82 QuantumState
83 state;
84
86 *semaphore;
87
88 size_t
89 signature;
90};
91
92extern MagickPrivate void
93 ResetQuantumState(QuantumInfo *);
94
95static inline MagickSizeType GetQuantumRange(const size_t depth)
96{
97 MagickSizeType
98 one;
99
100 size_t
101 max_depth;
102
103 if (depth == 0)
104 return(0);
105 one=1;
106 max_depth=8*sizeof(MagickSizeType);
107 return((MagickSizeType) ((one << (MagickMin(depth,max_depth)-1))+
108 ((one << (MagickMin(depth,max_depth)-1))-1)));
109}
110
111static inline float HalfToSinglePrecision(const unsigned short half)
112{
113#define ExponentBias (127-15)
114#define ExponentMask (0x7c00U)
115#define ExponentShift 23
116#define SignBitShift 31
117#define SignificandShift 13
118#define SignificandMask (0x00000400U)
119
120 typedef union _SinglePrecision
121 {
122 unsigned int
123 fixed_point;
124
125 float
126 single_precision;
127 } SinglePrecision;
128
129 unsigned int
130 exponent,
131 significand,
132 sign_bit;
133
134 SinglePrecision
135 map;
136
137 unsigned int
138 value;
139
140 /*
141 The IEEE 754 standard specifies half precision as having:
142
143 Sign bit: 1 bit
144 Exponent width: 5 bits
145 Significand precision: 11 (10 explicitly stored)
146 */
147 sign_bit=(unsigned int) ((half >> 15) & 0x00000001);
148 exponent=(unsigned int) ((half >> 10) & 0x0000001f);
149 significand=(unsigned int) (half & 0x000003ff);
150 if (exponent == 0)
151 {
152 if (significand == 0)
153 value=sign_bit << SignBitShift;
154 else
155 {
156 while ((significand & SignificandMask) == 0)
157 {
158 significand<<=1;
159 exponent--;
160 }
161 exponent++;
162 significand&=(~SignificandMask);
163 exponent+=ExponentBias;
164 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
165 (significand << SignificandShift);
166 }
167 }
168 else
169 if (exponent == SignBitShift)
170 {
171 value=(sign_bit << SignBitShift) | 0x7f800000;
172 if (significand != 0)
173 value|=(significand << SignificandShift);
174 }
175 else
176 {
177 exponent+=ExponentBias;
178 significand<<=SignificandShift;
179 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
180 significand;
181 }
182 map.fixed_point=value;
183 return(map.single_precision);
184}
185
186static inline unsigned char *PopCharPixel(const unsigned char pixel,
187 unsigned char *magick_restrict pixels)
188{
189 *pixels++=pixel;
190 return(pixels);
191}
192
193static inline unsigned char *PopLongPixel(const EndianType endian,
194 const unsigned int pixel,unsigned char *magick_restrict pixels)
195{
196 unsigned int
197 quantum;
198
199 quantum=(unsigned int) pixel;
200 if (endian == LSBEndian)
201 {
202 *pixels++=(unsigned char) (quantum);
203 *pixels++=(unsigned char) (quantum >> 8);
204 *pixels++=(unsigned char) (quantum >> 16);
205 *pixels++=(unsigned char) (quantum >> 24);
206 return(pixels);
207 }
208 *pixels++=(unsigned char) (quantum >> 24);
209 *pixels++=(unsigned char) (quantum >> 16);
210 *pixels++=(unsigned char) (quantum >> 8);
211 *pixels++=(unsigned char) (quantum);
212 return(pixels);
213}
214
215static inline unsigned char *PopShortPixel(const EndianType endian,
216 const unsigned short pixel,unsigned char *magick_restrict pixels)
217{
218 unsigned int
219 quantum;
220
221 quantum=pixel;
222 if (endian == LSBEndian)
223 {
224 *pixels++=(unsigned char) (quantum);
225 *pixels++=(unsigned char) (quantum >> 8);
226 return(pixels);
227 }
228 *pixels++=(unsigned char) (quantum >> 8);
229 *pixels++=(unsigned char) (quantum);
230 return(pixels);
231}
232
233static inline const unsigned char *PushCharPixel(
234 const unsigned char *magick_restrict pixels,
235 unsigned char *magick_restrict pixel)
236{
237 *pixel=(*pixels++);
238 return(pixels);
239}
240
241static inline const unsigned char *PushLongPixel(const EndianType endian,
242 const unsigned char *magick_restrict pixels,
243 unsigned int *magick_restrict pixel)
244{
245 unsigned int
246 quantum;
247
248 if (endian == LSBEndian)
249 {
250 quantum=((unsigned int) *pixels++);
251 quantum|=((unsigned int) *pixels++ << 8);
252 quantum|=((unsigned int) *pixels++ << 16);
253 quantum|=((unsigned int) *pixels++ << 24);
254 *pixel=quantum;
255 return(pixels);
256 }
257 quantum=((unsigned int) *pixels++ << 24);
258 quantum|=((unsigned int) *pixels++ << 16);
259 quantum|=((unsigned int) *pixels++ << 8);
260 quantum|=((unsigned int) *pixels++);
261 *pixel=quantum;
262 return(pixels);
263}
264
265static inline const unsigned char *PushShortPixel(const EndianType endian,
266 const unsigned char *magick_restrict pixels,
267 unsigned short *magick_restrict pixel)
268{
269 unsigned int
270 quantum;
271
272 if (endian == LSBEndian)
273 {
274 quantum=(unsigned int) *pixels++;
275 quantum|=(unsigned int) (*pixels++ << 8);
276 *pixel=(unsigned short) (quantum & 0xffff);
277 return(pixels);
278 }
279 quantum=(unsigned int) (*pixels++ << 8);
280 quantum|=(unsigned int) *pixels++;
281 *pixel=(unsigned short) (quantum & 0xffff);
282 return(pixels);
283}
284
285static inline const unsigned char *PushFloatPixel(const EndianType endian,
286 const unsigned char *magick_restrict pixels,
287 MagickFloatType *magick_restrict pixel)
288{
289 union
290 {
291 unsigned int
292 unsigned_value;
293
294 MagickFloatType
295 float_value;
296 } quantum;
297
298 if (endian == LSBEndian)
299 {
300 quantum.unsigned_value=((unsigned int) *pixels++);
301 quantum.unsigned_value|=((unsigned int) *pixels++ << 8);
302 quantum.unsigned_value|=((unsigned int) *pixels++ << 16);
303 quantum.unsigned_value|=((unsigned int) *pixels++ << 24);
304 *pixel=quantum.float_value;
305 return(pixels);
306 }
307 quantum.unsigned_value=((unsigned int) *pixels++ << 24);
308 quantum.unsigned_value|=((unsigned int) *pixels++ << 16);
309 quantum.unsigned_value|=((unsigned int) *pixels++ << 8);
310 quantum.unsigned_value|=((unsigned int) *pixels++);
311 *pixel=quantum.float_value;
312 return(pixels);
313}
314
315static inline Quantum ScaleAnyToQuantum(const QuantumAny quantum,
316 const QuantumAny range)
317{
318 if (quantum > range)
319 return(QuantumRange);
320#if !defined(MAGICKCORE_HDRI_SUPPORT)
321 return((Quantum) ((double) QuantumRange*(quantum*
322 MagickSafeReciprocal((double) range))+0.5));
323#else
324 return((Quantum) ((double) QuantumRange*(quantum*
325 MagickSafeReciprocal((double) range))));
326#endif
327}
328
329static inline QuantumAny ScaleQuantumToAny(const Quantum quantum,
330 const QuantumAny range)
331{
332#if !defined(MAGICKCORE_HDRI_SUPPORT)
333 return((QuantumAny) ((MagickRealType) range*quantum/QuantumRange));
334#else
335 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
336 return((QuantumAny) 0UL);
337 if ((range*(MagickRealType) quantum/(MagickRealType) QuantumRange) >= 18446744073709551615.0)
338 return((QuantumAny) MagickULLConstant(18446744073709551615));
339 return((QuantumAny) (range*(MagickRealType) quantum/(MagickRealType) QuantumRange+0.5));
340#endif
341}
342
343#if (MAGICKCORE_QUANTUM_DEPTH == 8)
344static inline Quantum ScaleCharToQuantum(const unsigned char value)
345{
346 return((Quantum) value);
347}
348
349static inline Quantum ScaleLongToQuantum(const unsigned int value)
350{
351#if !defined(MAGICKCORE_HDRI_SUPPORT)
352 return((Quantum) ((value)/16843009UL));
353#else
354 return((Quantum) (value/16843009.0));
355#endif
356}
357
358static inline Quantum ScaleMapToQuantum(const MagickRealType value)
359{
360 if (value <= 0.0)
361 return((Quantum) 0);
362 if (value >= MaxMap)
363 return(QuantumRange);
364#if !defined(MAGICKCORE_HDRI_SUPPORT)
365 return((Quantum) (value+0.5));
366#else
367 return((Quantum) value);
368#endif
369}
370
371static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
372{
373#if !defined(MAGICKCORE_HDRI_SUPPORT)
374 return((unsigned int) (16843009UL*quantum));
375#else
376 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
377 return(0U);
378 if ((16843009.0*quantum) >= 4294967295.0)
379 return(4294967295UL);
380 return((unsigned int) (16843009.0*quantum+0.5));
381#endif
382}
383
384static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
385{
386 if (quantum >= (Quantum) MaxMap)
387 return((unsigned int) MaxMap);
388#if !defined(MAGICKCORE_HDRI_SUPPORT)
389 return((unsigned int) quantum);
390#else
391 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
392 return(0U);
393 return((unsigned int) (quantum+0.5));
394#endif
395}
396
397static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
398{
399#if !defined(MAGICKCORE_HDRI_SUPPORT)
400 return((unsigned short) (257UL*quantum));
401#else
402 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
403 return(0);
404 if ((257.0*quantum) >= 65535.0)
405 return(65535);
406 return((unsigned short) (257.0*quantum+0.5));
407#endif
408}
409
410static inline Quantum ScaleShortToQuantum(const unsigned short value)
411{
412#if !defined(MAGICKCORE_HDRI_SUPPORT)
413 return((Quantum) ((value+128U)/257U));
414#else
415 return((Quantum) (value/257.0));
416#endif
417}
418#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
419static inline Quantum ScaleCharToQuantum(const unsigned char value)
420{
421#if !defined(MAGICKCORE_HDRI_SUPPORT)
422 return((Quantum) (257U*value));
423#else
424 return((Quantum) (257.0*value));
425#endif
426}
427
428static inline Quantum ScaleLongToQuantum(const unsigned int value)
429{
430#if !defined(MAGICKCORE_HDRI_SUPPORT)
431 return((Quantum) ((value)/MagickULLConstant(65537)));
432#else
433 return((Quantum) (value/65537.0));
434#endif
435}
436
437static inline Quantum ScaleMapToQuantum(const MagickRealType value)
438{
439 if (value <= 0.0)
440 return((Quantum) 0);
441 if (value >= MaxMap)
442 return(QuantumRange);
443#if !defined(MAGICKCORE_HDRI_SUPPORT)
444 return((Quantum) (value+0.5));
445#else
446 return((Quantum) value);
447#endif
448}
449
450static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
451{
452#if !defined(MAGICKCORE_HDRI_SUPPORT)
453 return((unsigned int) (65537UL*quantum));
454#else
455 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
456 return(0U);
457 if ((65537.0f*quantum) >= 4294967295.0f)
458 return(4294967295U);
459 return((unsigned int) (65537.0f*quantum+0.5f));
460#endif
461}
462
463static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
464{
465 if (quantum >= (Quantum) MaxMap)
466 return((unsigned int) MaxMap);
467#if !defined(MAGICKCORE_HDRI_SUPPORT)
468 return((unsigned int) quantum);
469#else
470 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
471 return(0U);
472 return((unsigned int) (quantum+0.5f));
473#endif
474}
475
476static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
477{
478#if !defined(MAGICKCORE_HDRI_SUPPORT)
479 return((unsigned short) quantum);
480#else
481 if ((IsNaN(quantum) != 0) || (quantum <= 0.0f))
482 return(0);
483 if (quantum >= 65535.0f)
484 return(65535);
485 return((unsigned short) (quantum+0.5f));
486#endif
487}
488
489static inline Quantum ScaleShortToQuantum(const unsigned short value)
490{
491 return((Quantum) value);
492}
493#elif (MAGICKCORE_QUANTUM_DEPTH == 32)
494static inline Quantum ScaleCharToQuantum(const unsigned char value)
495{
496#if !defined(MAGICKCORE_HDRI_SUPPORT)
497 return((Quantum) (16843009UL*value));
498#else
499 return((Quantum) (16843009.0*value));
500#endif
501}
502
503static inline Quantum ScaleLongToQuantum(const unsigned int value)
504{
505 return((Quantum) value);
506}
507
508static inline Quantum ScaleMapToQuantum(const MagickRealType value)
509{
510 if (value <= 0.0)
511 return((Quantum) 0);
512 if (value >= (Quantum) MaxMap)
513 return(QuantumRange);
514#if !defined(MAGICKCORE_HDRI_SUPPORT)
515 return((Quantum) (65537.0f*value+0.5f));
516#else
517 return((Quantum) (65537.0f*value));
518#endif
519}
520
521static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
522{
523#if !defined(MAGICKCORE_HDRI_SUPPORT)
524 return((unsigned int) quantum);
525#else
526 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
527 return(0U);
528 if ((quantum) >= 4294967295.0)
529 return(4294967295);
530 return((unsigned int) (quantum+0.5));
531#endif
532}
533
534static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
535{
536 if ((quantum/65537) >= (Quantum) MaxMap)
537 return((unsigned int) MaxMap);
538#if !defined(MAGICKCORE_HDRI_SUPPORT)
539 return((unsigned int) ((quantum+MagickULLConstant(32768))/
540 MagickULLConstant(65537)));
541#else
542 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
543 return(0U);
544 return((unsigned int) (quantum/65537.0+0.5));
545#endif
546}
547
548static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
549{
550#if !defined(MAGICKCORE_HDRI_SUPPORT)
551 return((unsigned short) ((quantum+MagickULLConstant(32768))/
552 MagickULLConstant(65537)));
553#else
554 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
555 return(0);
556 if ((quantum/65537.0) >= 65535.0)
557 return(65535);
558 return((unsigned short) (quantum/65537.0+0.5));
559#endif
560}
561
562static inline Quantum ScaleShortToQuantum(const unsigned short value)
563{
564#if !defined(MAGICKCORE_HDRI_SUPPORT)
565 return((Quantum) (65537UL*value));
566#else
567 return((Quantum) (65537.0*value));
568#endif
569}
570#elif (MAGICKCORE_QUANTUM_DEPTH == 64)
571static inline Quantum ScaleCharToQuantum(const unsigned char value)
572{
573 return((Quantum) (72340172838076673.0*value));
574}
575
576static inline Quantum ScaleLongToQuantum(const unsigned int value)
577{
578 return((Quantum) (4294967297.0*value));
579}
580
581static inline Quantum ScaleMapToQuantum(const MagickRealType value)
582{
583 if (value <= 0.0)
584 return((Quantum) 0);
585 if (value >= MaxMap)
586 return(QuantumRange);
587 return((Quantum) (281479271743489.0*value));
588}
589
590static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
591{
592 return((unsigned int) (quantum/4294967297.0+0.5));
593}
594
595static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
596{
597 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
598 return(0U);
599 if ((quantum/281479271743489.0) >= MaxMap)
600 return((unsigned int) MaxMap);
601 return((unsigned int) (quantum/281479271743489.0+0.5));
602}
603
604static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
605{
606 if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
607 return(0);
608 if ((quantum/281479271743489.0) >= 65535.0)
609 return(65535);
610 return((unsigned short) (quantum/281479271743489.0+0.5));
611}
612
613static inline Quantum ScaleShortToQuantum(const unsigned short value)
614{
615 return((Quantum) (281479271743489.0*value));
616}
617#endif
618
619static inline unsigned short SinglePrecisionToHalf(const float value)
620{
621 typedef union _SinglePrecision
622 {
623 unsigned int
624 fixed_point;
625
626 float
627 single_precision;
628 } SinglePrecision;
629
630 int
631 exponent;
632
633 unsigned int
634 significand,
635 sign_bit;
636
637 SinglePrecision
638 map;
639
640 unsigned short
641 half;
642
643 /*
644 The IEEE 754 standard specifies half precision as having:
645
646 Sign bit: 1 bit
647 Exponent width: 5 bits
648 Significand precision: 11 (10 explicitly stored)
649 */
650 map.single_precision=value;
651 sign_bit=(map.fixed_point >> 16) & 0x00008000;
652 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
653 significand=map.fixed_point & 0x007fffff;
654 if (exponent <= 0)
655 {
656 int
657 shift;
658
659 if (exponent < -10)
660 return((unsigned short) sign_bit);
661 significand=significand | 0x00800000;
662 shift=(int) (14-exponent);
663 significand=(unsigned int) ((significand+((1U << (shift-1))-1)+
664 ((significand >> shift) & 0x01)) >> shift);
665 return((unsigned short) (sign_bit | significand));
666 }
667 else
668 if (exponent == (0xff-ExponentBias))
669 {
670 if (significand == 0)
671 return((unsigned short) (sign_bit | ExponentMask));
672 else
673 {
674 significand>>=SignificandShift;
675 half=(unsigned short) (sign_bit | significand |
676 (significand == 0) | ExponentMask);
677 return(half);
678 }
679 }
680 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
681 if ((significand & 0x00800000) != 0)
682 {
683 significand=0;
684 exponent++;
685 }
686 if (exponent > 30)
687 {
688 float
689 alpha;
690
691 int
692 i;
693
694 /*
695 Float overflow.
696 */
697 alpha=1.0e10;
698 for (i=0; i < 10; i++)
699 alpha*=alpha;
700 return((unsigned short) (sign_bit | ExponentMask));
701 }
702 half=(unsigned short) (sign_bit | ((unsigned int) exponent << 10) |
703 (significand >> SignificandShift));
704 return(half);
705}
706
707#if defined(__cplusplus) || defined(c_plusplus)
708}
709#endif
710
711#endif