1 /*
2   Copyright 1999-2021 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_H
19 #define MAGICKCORE_QUANTUM_H
20 
21 #include <float.h>
22 #include "MagickCore/image.h"
23 #include "MagickCore/semaphore.h"
24 
25 #if defined(__cplusplus) || defined(c_plusplus)
26 extern "C" {
27 #endif
28 
29 typedef enum
30 {
31   UndefinedEndian,
32   LSBEndian,
33   MSBEndian
34 } EndianType;
35 
36 typedef enum
37 {
38   UndefinedQuantumAlpha,
39   AssociatedQuantumAlpha,
40   DisassociatedQuantumAlpha
41 } QuantumAlphaType;
42 
43 typedef enum
44 {
45   UndefinedQuantumFormat,
46   FloatingPointQuantumFormat,
47   SignedQuantumFormat,
48   UnsignedQuantumFormat
49 } QuantumFormatType;
50 
51 typedef enum
52 {
53   UndefinedQuantum,
54   AlphaQuantum,
55   BGRAQuantum,
56   BGROQuantum,
57   BGRQuantum,
58   BlackQuantum,
59   BlueQuantum,
60   CbYCrAQuantum,
61   CbYCrQuantum,
62   CbYCrYQuantum,
63   CMYKAQuantum,
64   CMYKOQuantum,
65   CMYKQuantum,
66   CyanQuantum,
67   GrayAlphaQuantum,
68   GrayQuantum,
69   GreenQuantum,
70   IndexAlphaQuantum,
71   IndexQuantum,
72   MagentaQuantum,
73   OpacityQuantum,
74   RedQuantum,
75   RGBAQuantum,
76   RGBOQuantum,
77   RGBPadQuantum,
78   RGBQuantum,
79   YellowQuantum
80 } QuantumType;
81 
82 typedef struct _QuantumInfo
83   QuantumInfo;
84 
ClampToQuantum(const MagickRealType quantum)85 static inline Quantum ClampToQuantum(const MagickRealType quantum)
86 {
87 #if defined(MAGICKCORE_HDRI_SUPPORT)
88   return((Quantum) quantum);
89 #else
90   if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
91     return((Quantum) 0);
92   if (quantum >= (MagickRealType) QuantumRange)
93     return(QuantumRange);
94   return((Quantum) (quantum+0.5));
95 #endif
96 }
97 
98 #if (MAGICKCORE_QUANTUM_DEPTH == 8)
ScaleQuantumToChar(const Quantum quantum)99 static inline unsigned char ScaleQuantumToChar(const Quantum quantum)
100 {
101 #if !defined(MAGICKCORE_HDRI_SUPPORT)
102   return((unsigned char) quantum);
103 #else
104   if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
105     return(0);
106   if (quantum >= 255.0)
107     return(255);
108   return((unsigned char) (quantum+0.5));
109 #endif
110 }
111 #elif (MAGICKCORE_QUANTUM_DEPTH == 16)
ScaleQuantumToChar(const Quantum quantum)112 static inline unsigned char ScaleQuantumToChar(const Quantum quantum)
113 {
114 #if !defined(MAGICKCORE_HDRI_SUPPORT)
115   return((unsigned char) (((quantum+128UL)-((quantum+128UL) >> 8)) >> 8));
116 #else
117   if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
118     return(0);
119   if ((quantum/257.0) >= 255.0)
120     return(255);
121   return((unsigned char) (quantum/257.0+0.5));
122 #endif
123 }
124 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
ScaleQuantumToChar(const Quantum quantum)125 static inline unsigned char ScaleQuantumToChar(const Quantum quantum)
126 {
127 #if !defined(MAGICKCORE_HDRI_SUPPORT)
128   return((unsigned char) ((quantum+MagickULLConstant(8421504))/
129     MagickULLConstant(16843009)));
130 #else
131   if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
132     return(0);
133   if ((quantum/16843009.0) >= 255.0)
134     return(255);
135   return((unsigned char) (quantum/16843009.0+0.5));
136 #endif
137 }
138 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
ScaleQuantumToChar(const Quantum quantum)139 static inline unsigned char ScaleQuantumToChar(const Quantum quantum)
140 {
141 #if !defined(MAGICKCORE_HDRI_SUPPORT)
142   return((unsigned char) (quantum/72340172838076673.0+0.5));
143 #else
144   if ((IsNaN(quantum) != 0) || (quantum <= 0.0))
145     return(0);
146   if ((quantum/72340172838076673.0) >= 255.0)
147     return(255);
148   return((unsigned char) (quantum/72340172838076673.0+0.5));
149 #endif
150 }
151 #endif
152 
153 extern MagickExport EndianType
154   GetQuantumEndian(const QuantumInfo *);
155 
156 extern MagickExport MagickBooleanType
157   SetQuantumDepth(const Image *,QuantumInfo *,const size_t),
158   SetQuantumEndian(const Image *,QuantumInfo *,const EndianType),
159   SetQuantumFormat(const Image *,QuantumInfo *,const QuantumFormatType),
160   SetQuantumPad(const Image *,QuantumInfo *,const size_t);
161 
162 extern MagickExport QuantumFormatType
163   GetQuantumFormat(const QuantumInfo *);
164 
165 extern MagickExport QuantumInfo
166   *AcquireQuantumInfo(const ImageInfo *,Image *),
167   *DestroyQuantumInfo(QuantumInfo *);
168 
169 extern MagickExport QuantumType
170   GetQuantumType(Image *,ExceptionInfo *);
171 
172 extern MagickExport size_t
173   ExportQuantumPixels(const Image *,CacheView *,QuantumInfo *,const QuantumType,
174     unsigned char *magick_restrict,ExceptionInfo *),
175   GetQuantumExtent(const Image *,const QuantumInfo *,const QuantumType),
176   ImportQuantumPixels(const Image *,CacheView *,QuantumInfo *,const QuantumType,
177     const unsigned char *magick_restrict,ExceptionInfo *);
178 
179 extern MagickExport unsigned char
180   *GetQuantumPixels(const QuantumInfo *);
181 
182 extern MagickExport void
183   GetQuantumInfo(const ImageInfo *,QuantumInfo *),
184   SetQuantumAlphaType(QuantumInfo *,const QuantumAlphaType),
185   SetQuantumImageType(Image *,const QuantumType),
186   SetQuantumMinIsWhite(QuantumInfo *,const MagickBooleanType),
187   SetQuantumPack(QuantumInfo *,const MagickBooleanType),
188   SetQuantumQuantum(QuantumInfo *,const size_t),
189   SetQuantumScale(QuantumInfo *,const double);
190 
191 #if defined(__cplusplus) || defined(c_plusplus)
192 }
193 #endif
194 
195 #endif
196