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