1/*
2  Copyright 1999-2016 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    http://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)
24extern "C" {
25#endif
26
27typedef 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
42struct _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
88extern MagickPrivate void
89  ResetQuantumState(QuantumInfo *);
90
91static 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
100static 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
175static inline unsigned char *PopCharPixel(const unsigned char pixel,
176  unsigned char *pixels)
177{
178  *pixels++=pixel;
179  return(pixels);
180}
181
182static 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
204static 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
222static inline const unsigned char *PushCharPixel(const unsigned char *pixels,
223  unsigned char *pixel)
224{
225  *pixel=(*pixels++);
226  return(pixels);
227}
228
229static 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
252static 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
271static inline Quantum ScaleAnyToQuantum(const QuantumAny quantum,
272  const QuantumAny range)
273{
274  if (quantum > range)
275    return(QuantumRange);
276#if !defined(MAGICKCORE_HDRI_SUPPORT)
277  return((Quantum) (((double) QuantumRange*quantum)/range+0.5));
278#else
279  return((Quantum) (((double) QuantumRange*quantum)/range));
280#endif
281}
282
283static inline QuantumAny ScaleQuantumToAny(const Quantum quantum,
284  const QuantumAny range)
285{
286  return((QuantumAny) (((double) range*quantum)/QuantumRange+0.5));
287}
288
289#if (MAGICKCORE_QUANTUM_DEPTH == 8)
290static inline Quantum ScaleCharToQuantum(const unsigned char value)
291{
292  return((Quantum) value);
293}
294
295static inline Quantum ScaleLongToQuantum(const unsigned int value)
296{
297#if !defined(MAGICKCORE_HDRI_SUPPORT)
298  return((Quantum) ((value+8421504UL)/16843009UL));
299#else
300  return((Quantum) (value/16843009.0));
301#endif
302}
303
304static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
305{
306#if !defined(MAGICKCORE_HDRI_SUPPORT)
307  return((Quantum) ((value+MagickULLConstant(551911719039))/
308    MagickULLConstant(1103823438079)));
309#else
310  return((Quantum) (value/1103823438079.0));
311#endif
312}
313
314static inline Quantum ScaleMapToQuantum(const MagickRealType value)
315{
316  if (value <= 0.0)
317    return((Quantum) 0);
318  if (value >= MaxMap)
319    return(QuantumRange);
320#if !defined(MAGICKCORE_HDRI_SUPPORT)
321  return((Quantum) (value+0.5));
322#else
323  return((Quantum) value);
324#endif
325}
326
327static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
328{
329#if !defined(MAGICKCORE_HDRI_SUPPORT)
330  return((unsigned int) (16843009UL*quantum));
331#else
332  if (quantum <= 0.0)
333    return(0UL);
334  if ((16843009.0*quantum) >= 4294967295.0)
335    return(4294967295UL);
336  return((unsigned int) (16843009.0*quantum+0.5));
337#endif
338}
339
340static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
341{
342#if !defined(MAGICKCORE_HDRI_SUPPORT)
343  return((MagickSizeType) (MagickULLConstant(551911719039)*quantum));
344#else
345  if (quantum <= 0.0)
346    return(0UL);
347  if ((551911719039.0*quantum) >= 18446744073709551615.0)
348    return(MagickULLConstant(18446744073709551615));
349  return((MagickSizeType) (1103823438079.0*quantum+0.5));
350#endif
351}
352
353static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
354{
355  if (quantum >= (Quantum) MaxMap)
356    return((unsigned int) MaxMap);
357#if !defined(MAGICKCORE_HDRI_SUPPORT)
358  return((unsigned int) quantum);
359#else
360  if (quantum < 0.0)
361    return(0UL);
362  return((unsigned int) (quantum+0.5));
363#endif
364}
365
366static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
367{
368#if !defined(MAGICKCORE_HDRI_SUPPORT)
369  return((unsigned short) (257UL*quantum));
370#else
371  if (quantum <= 0.0)
372    return(0);
373  if ((257.0*quantum) >= 65535.0)
374    return(65535);
375  return((unsigned short) (257.0*quantum+0.5));
376#endif
377}
378
379static inline Quantum ScaleShortToQuantum(const unsigned short value)
380{
381#if !defined(MAGICKCORE_HDRI_SUPPORT)
382  return((Quantum) ((value+128U)/257U));
383#else
384  return((Quantum) (value/257.0));
385#endif
386}
387#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
388static inline Quantum ScaleCharToQuantum(const unsigned char value)
389{
390#if !defined(MAGICKCORE_HDRI_SUPPORT)
391  return((Quantum) (257U*value));
392#else
393  return((Quantum) (257.0*value));
394#endif
395}
396
397static inline Quantum ScaleLongToQuantum(const unsigned int value)
398{
399#if !defined(MAGICKCORE_HDRI_SUPPORT)
400  return((Quantum) ((value+MagickULLConstant(32768))/
401    MagickULLConstant(65537)));
402#else
403  return((Quantum) (value/65537.0));
404#endif
405}
406
407static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
408{
409#if !defined(MAGICKCORE_HDRI_SUPPORT)
410  return((Quantum) ((value+MagickULLConstant(8421376))/
411    MagickULLConstant(16842752)));
412#else
413  return((Quantum) (value/16842752.0));
414#endif
415}
416
417static inline Quantum ScaleMapToQuantum(const MagickRealType value)
418{
419  if (value <= 0.0)
420    return((Quantum) 0);
421  if (value >= MaxMap)
422    return(QuantumRange);
423#if !defined(MAGICKCORE_HDRI_SUPPORT)
424  return((Quantum) (value+0.5));
425#else
426  return((Quantum) value);
427#endif
428}
429
430static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
431{
432#if !defined(MAGICKCORE_HDRI_SUPPORT)
433  return((unsigned int) (65537UL*quantum));
434#else
435  if (quantum <= 0.0)
436    return(0UL);
437  if ((65537.0*quantum) >= 4294967295.0)
438    return(4294967295U);
439  return((unsigned int) (65537.0*quantum+0.5));
440#endif
441}
442
443static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
444{
445#if !defined(MAGICKCORE_HDRI_SUPPORT)
446  return((MagickSizeType) (MagickULLConstant(16842752)*quantum));
447#else
448  if (quantum <= 0.0)
449    return(0UL);
450  if ((65537.0*quantum) >= 18446744073709551615.0)
451    return(MagickULLConstant(18446744073709551615));
452  return((MagickSizeType) (16842752.0*quantum+0.5));
453#endif
454}
455
456static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
457{
458  if (quantum >= (Quantum) MaxMap)
459    return((unsigned int) MaxMap);
460#if !defined(MAGICKCORE_HDRI_SUPPORT)
461  return((unsigned int) quantum);
462#else
463  if (quantum < 0.0)
464    return(0UL);
465  return((unsigned int) (quantum+0.5));
466#endif
467}
468
469static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
470{
471#if !defined(MAGICKCORE_HDRI_SUPPORT)
472  return((unsigned short) quantum);
473#else
474  if (quantum <= 0.0)
475    return(0);
476  if (quantum >= 65535.0)
477    return(65535);
478  return((unsigned short) (quantum+0.5));
479#endif
480}
481
482static inline Quantum ScaleShortToQuantum(const unsigned short value)
483{
484  return((Quantum) value);
485}
486#elif (MAGICKCORE_QUANTUM_DEPTH == 32)
487static inline Quantum ScaleCharToQuantum(const unsigned char value)
488{
489#if !defined(MAGICKCORE_HDRI_SUPPORT)
490  return((Quantum) (16843009UL*value));
491#else
492  return((Quantum) (16843009.0*value));
493#endif
494}
495
496static inline Quantum ScaleLongToQuantum(const unsigned int value)
497{
498  return((Quantum) value);
499}
500
501static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
502{
503  return((Quantum) value);
504}
505
506static inline Quantum ScaleMapToQuantum(const MagickRealType value)
507{
508  if (value <= 0.0)
509    return((Quantum) 0);
510  if (value >= (Quantum) MaxMap)
511    return(QuantumRange);
512#if !defined(MAGICKCORE_HDRI_SUPPORT)
513  return((Quantum) (65537.0*value+0.5));
514#else
515  return((Quantum) (65537.0*value));
516#endif
517}
518
519static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
520{
521#if !defined(MAGICKCORE_HDRI_SUPPORT)
522  return((unsigned int) quantum);
523#else
524  if (quantum <= 0.0)
525    return(0);
526  if ((quantum) >= 4294967295.0)
527    return(4294967295);
528  return((unsigned int) (quantum+0.5));
529#endif
530}
531
532static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
533{
534#if !defined(MAGICKCORE_HDRI_SUPPORT)
535  return((MagickSizeType) quantum);
536#else
537  return((MagickSizeType) (quantum+0.5));
538#endif
539}
540
541static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
542{
543  if (quantum < 0.0)
544    return(0UL);
545  if ((quantum/65537) >= (Quantum) MaxMap)
546    return((unsigned int) MaxMap);
547#if !defined(MAGICKCORE_HDRI_SUPPORT)
548  return((unsigned int) ((quantum+MagickULLConstant(32768))/
549    MagickULLConstant(65537)));
550#else
551  return((unsigned int) (quantum/65537.0+0.5));
552#endif
553}
554
555static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
556{
557#if !defined(MAGICKCORE_HDRI_SUPPORT)
558  return((unsigned short) ((quantum+MagickULLConstant(32768))/
559    MagickULLConstant(65537)));
560#else
561  if (quantum <= 0.0)
562    return(0);
563  if ((quantum/65537.0) >= 65535.0)
564    return(65535);
565  return((unsigned short) (quantum/65537.0+0.5));
566#endif
567}
568
569static inline Quantum ScaleShortToQuantum(const unsigned short value)
570{
571#if !defined(MAGICKCORE_HDRI_SUPPORT)
572  return((Quantum) (65537UL*value));
573#else
574  return((Quantum) (65537.0*value));
575#endif
576}
577#elif (MAGICKCORE_QUANTUM_DEPTH == 64)
578static inline Quantum ScaleCharToQuantum(const unsigned char value)
579{
580  return((Quantum) (72340172838076673.0*value));
581}
582
583static inline Quantum ScaleLongToQuantum(const unsigned int value)
584{
585  return((Quantum) (4294967297.0*value));
586}
587
588static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
589{
590  return((Quantum) (18446744073709551615.0*value));
591}
592
593static inline Quantum ScaleMapToQuantum(const MagickRealType value)
594{
595  if (value <= 0.0)
596    return((Quantum) 0);
597  if (value >= MaxMap)
598    return(QuantumRange);
599  return((Quantum) (281479271743489.0*value));
600}
601
602static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
603{
604  return((unsigned int) (quantum/4294967297.0+0.5));
605}
606
607static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
608{
609  return((MagickSizeType) (quantum/18446744073709551615.0+0.5));
610}
611
612static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
613{
614  if (quantum <= 0.0)
615    return(0UL);
616  if ((quantum/281479271743489.0) >= MaxMap)
617    return((unsigned int) MaxMap);
618  return((unsigned int) (quantum/281479271743489.0+0.5));
619}
620
621static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
622{
623  if (quantum <= 0.0)
624    return(0);
625  if ((quantum/281479271743489.0) >= 65535.0)
626    return(65535);
627  return((unsigned short) (quantum/281479271743489.0+0.5));
628}
629
630static inline Quantum ScaleShortToQuantum(const unsigned short value)
631{
632  return((Quantum) (281479271743489.0*value));
633}
634#endif
635
636static inline unsigned short SinglePrecisionToHalf(const float value)
637{
638  typedef union _SinglePrecision
639  {
640    unsigned int
641      fixed_point;
642
643    float
644      single_precision;
645  } SinglePrecision;
646
647  register int
648    exponent;
649
650  register unsigned int
651    significand,
652    sign_bit;
653
654  SinglePrecision
655    map;
656
657  unsigned short
658    half;
659
660  /*
661    The IEEE 754 standard specifies half precision as having:
662
663      Sign bit: 1 bit
664      Exponent width: 5 bits
665      Significand precision: 11 (10 explicitly stored)
666  */
667  map.single_precision=value;
668  sign_bit=(map.fixed_point >> 16) & 0x00008000;
669  exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
670  significand=map.fixed_point & 0x007fffff;
671  if (exponent <= 0)
672    {
673      int
674        shift;
675
676      if (exponent < -10)
677        return((unsigned short) sign_bit);
678      significand=significand | 0x00800000;
679      shift=(int) (14-exponent);
680      significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
681        ((significand >> shift) & 0x01)) >> shift);
682      return((unsigned short) (sign_bit | significand));
683    }
684  else
685    if (exponent == (0xff-ExponentBias))
686      {
687        if (significand == 0)
688          return((unsigned short) (sign_bit | ExponentMask));
689        else
690          {
691            significand>>=SignificandShift;
692            half=(unsigned short) (sign_bit | significand |
693              (significand == 0) | ExponentMask);
694            return(half);
695          }
696      }
697  significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
698  if ((significand & 0x00800000) != 0)
699    {
700      significand=0;
701      exponent++;
702    }
703  if (exponent > 30)
704    {
705      float
706        alpha;
707
708      register int
709        i;
710
711      /*
712        Float overflow.
713      */
714      alpha=1.0e10;
715      for (i=0; i < 10; i++)
716        alpha*=alpha;
717      return((unsigned short) (sign_bit | ExponentMask));
718    }
719  half=(unsigned short) (sign_bit | (exponent << 10) |
720    (significand >> SignificandShift));
721  return(half);
722}
723
724#if defined(__cplusplus) || defined(c_plusplus)
725}
726#endif
727
728#endif
729