blob: cd46e54ced9c859e9c019123a6edac45d7a8ca83 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
cristyfe676ee2013-11-18 13:03:38 +00002 Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization
cristy3ed852e2009-09-05 21:47:34 +00003 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
cristy6398ec72013-11-28 02:00:27 +000021#include "MagickCore/cache.h"
22
cristy3ed852e2009-09-05 21:47:34 +000023#if defined(__cplusplus) || defined(c_plusplus)
24extern "C" {
25#endif
26
cristy3ed852e2009-09-05 21:47:34 +000027typedef struct _QuantumState
28{
cristy3ed852e2009-09-05 21:47:34 +000029 double
cristy3ed852e2009-09-05 21:47:34 +000030 inverse_scale;
31
cristy4cb162a2010-05-30 03:04:47 +000032 unsigned int
cristy6b825f92010-06-04 02:01:10 +000033 pixel;
34
35 size_t
cristy3ed852e2009-09-05 21:47:34 +000036 bits;
37
cristy4cb162a2010-05-30 03:04:47 +000038 const unsigned int
cristy3ed852e2009-09-05 21:47:34 +000039 *mask;
40} QuantumState;
41
42struct _QuantumInfo
43{
cristybb503372010-05-27 20:51:26 +000044 size_t
cristy3ed852e2009-09-05 21:47:34 +000045 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
cristybb503372010-05-27 20:51:26 +000066 size_t
cristy3ed852e2009-09-05 21:47:34 +000067 number_threads;
68
69 unsigned char
70 **pixels;
71
72 size_t
73 extent;
74
cristy32c68432012-01-12 15:06:28 +000075 EndianType
76 endian;
77
78 QuantumState
79 state;
80
cristy3ed852e2009-09-05 21:47:34 +000081 SemaphoreInfo
82 *semaphore;
83
cristybb503372010-05-27 20:51:26 +000084 size_t
cristy3ed852e2009-09-05 21:47:34 +000085 signature;
86};
87
cristy79630222012-01-14 01:38:37 +000088extern MagickPrivate void
89 ResetQuantumState(QuantumInfo *);
90
cristybb503372010-05-27 20:51:26 +000091static inline MagickSizeType GetQuantumRange(const size_t depth)
cristy2a4d01c2010-01-10 21:14:51 +000092{
cristy4cb162a2010-05-30 03:04:47 +000093 MagickSizeType
94 one;
95
96 one=1;
97 return((MagickSizeType) ((one << (depth-1))+((one << (depth-1))-1)));
cristy2a4d01c2010-01-10 21:14:51 +000098}
99
100static inline float HalfToSinglePrecision(const unsigned short half)
cristy5ab5fc82010-01-05 20:52:48 +0000101{
cristy8a6a9802010-04-14 13:22:18 +0000102#define ExponentBias (127-15)
cristy24fb7dc2010-01-10 20:15:51 +0000103#define ExponentMask 0x7c00
104#define ExponentShift 23
cristybccb64f2010-01-10 21:16:36 +0000105#define SignBitShift 31
cristy24fb7dc2010-01-10 20:15:51 +0000106#define SignificandShift 13
107#define SignificandMask 0x00000400
cristy5ab5fc82010-01-05 20:52:48 +0000108
cristy24fb7dc2010-01-10 20:15:51 +0000109 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 /*
cristybccb64f2010-01-10 21:16:36 +0000130 The IEEE 754 standard specifies half precision as having:
cristy24fb7dc2010-01-10 20:15:51 +0000131
132 Sign bit: 1 bit
133 Exponent width: 5 bits
134 Significand precision: 11 (10 explicitly stored)
135 */
cristy2a4d01c2010-01-10 21:14:51 +0000136 sign_bit=(unsigned int) ((half >> 15) & 0x00000001);
137 exponent=(unsigned int) ((half >> 10) & 0x0000001f);
138 significand=(unsigned int) (half & 0x000003ff);
cristy24fb7dc2010-01-10 20:15:51 +0000139 if (exponent == 0)
140 {
cristy92caafa2010-05-10 12:56:29 +0000141 if (significand == 0)
cristy24fb7dc2010-01-10 20:15:51 +0000142 value=sign_bit << SignBitShift;
cristy92caafa2010-05-10 12:56:29 +0000143 else
144 {
cristy24fb7dc2010-01-10 20:15:51 +0000145 while ((significand & SignificandMask) == 0)
146 {
147 significand<<=1;
148 exponent--;
149 }
cristy92caafa2010-05-10 12:56:29 +0000150 exponent++;
cristy24fb7dc2010-01-10 20:15:51 +0000151 significand&=(~SignificandMask);
152 exponent+=ExponentBias;
153 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
154 (significand << SignificandShift);
cristy92caafa2010-05-10 12:56:29 +0000155 }
cristy24fb7dc2010-01-10 20:15:51 +0000156 }
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}
cristy5ab5fc82010-01-05 20:52:48 +0000174
cristy3ed852e2009-09-05 21:47:34 +0000175static 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,
cristy4cb162a2010-05-30 03:04:47 +0000183 const unsigned int pixel,unsigned char *pixels)
cristy3ed852e2009-09-05 21:47:34 +0000184{
185 register unsigned int
186 quantum;
187
188 quantum=(unsigned int) pixel;
cristy1715f792012-11-22 16:56:12 +0000189 if (endian == LSBEndian)
cristy3ed852e2009-09-05 21:47:34 +0000190 {
cristy3ed852e2009-09-05 21:47:34 +0000191 *pixels++=(unsigned char) (quantum);
cristy1715f792012-11-22 16:56:12 +0000192 *pixels++=(unsigned char) (quantum >> 8);
193 *pixels++=(unsigned char) (quantum >> 16);
194 *pixels++=(unsigned char) (quantum >> 24);
cristy3ed852e2009-09-05 21:47:34 +0000195 return(pixels);
196 }
cristy3ed852e2009-09-05 21:47:34 +0000197 *pixels++=(unsigned char) (quantum >> 24);
cristy1715f792012-11-22 16:56:12 +0000198 *pixels++=(unsigned char) (quantum >> 16);
199 *pixels++=(unsigned char) (quantum >> 8);
200 *pixels++=(unsigned char) (quantum);
cristy3ed852e2009-09-05 21:47:34 +0000201 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;
cristy1715f792012-11-22 16:56:12 +0000211 if (endian == LSBEndian)
cristy3ed852e2009-09-05 21:47:34 +0000212 {
cristy3ed852e2009-09-05 21:47:34 +0000213 *pixels++=(unsigned char) (quantum);
cristy1715f792012-11-22 16:56:12 +0000214 *pixels++=(unsigned char) (quantum >> 8);
cristy3ed852e2009-09-05 21:47:34 +0000215 return(pixels);
216 }
cristy3ed852e2009-09-05 21:47:34 +0000217 *pixels++=(unsigned char) (quantum >> 8);
cristy1715f792012-11-22 16:56:12 +0000218 *pixels++=(unsigned char) (quantum);
cristy3ed852e2009-09-05 21:47:34 +0000219 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,
cristy4cb162a2010-05-30 03:04:47 +0000230 const unsigned char *pixels,unsigned int *pixel)
cristy3ed852e2009-09-05 21:47:34 +0000231{
232 register unsigned int
233 quantum;
234
cristy1715f792012-11-22 16:56:12 +0000235 if (endian == LSBEndian)
cristy3ed852e2009-09-05 21:47:34 +0000236 {
cristy1715f792012-11-22 16:56:12 +0000237 quantum=(unsigned int) (*pixels++);
cristy3ed852e2009-09-05 21:47:34 +0000238 quantum|=(unsigned int) (*pixels++ << 8);
cristy1715f792012-11-22 16:56:12 +0000239 quantum|=(unsigned int) (*pixels++ << 16);
240 quantum|=(unsigned int) (*pixels++ << 24);
cristy70d7eae2012-11-17 19:40:21 +0000241 *pixel=(unsigned int) (quantum & 0xffffffff);
242 return(pixels);
cristy3ed852e2009-09-05 21:47:34 +0000243 }
cristy1715f792012-11-22 16:56:12 +0000244 quantum=(unsigned int) (*pixels++ << 24);
cristy70d7eae2012-11-17 19:40:21 +0000245 quantum|=(unsigned int) (*pixels++ << 16);
cristy1715f792012-11-22 16:56:12 +0000246 quantum|=(unsigned int) (*pixels++ << 8);
247 quantum|=(unsigned int) (*pixels++);
cristy4cb162a2010-05-30 03:04:47 +0000248 *pixel=(unsigned int) (quantum & 0xffffffff);
cristy3ed852e2009-09-05 21:47:34 +0000249 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
cristy1715f792012-11-22 16:56:12 +0000258 if (endian == LSBEndian)
cristy3ed852e2009-09-05 21:47:34 +0000259 {
cristy1715f792012-11-22 16:56:12 +0000260 quantum=(unsigned int) *pixels++;
261 quantum|=(unsigned int) (*pixels++ << 8);
cristy70d7eae2012-11-17 19:40:21 +0000262 *pixel=(unsigned short) (quantum & 0xffff);
263 return(pixels);
cristy3ed852e2009-09-05 21:47:34 +0000264 }
cristy1715f792012-11-22 16:56:12 +0000265 quantum=(unsigned int) (*pixels++ << 8);
266 quantum|=(unsigned int) *pixels++;
cristy3ed852e2009-09-05 21:47:34 +0000267 *pixel=(unsigned short) (quantum & 0xffff);
268 return(pixels);
269}
270
271static inline Quantum ScaleAnyToQuantum(const QuantumAny quantum,
272 const QuantumAny range)
273{
cristyb3963e62010-05-09 21:36:40 +0000274#if !defined(MAGICKCORE_HDRI_SUPPORT)
cristya19f1d72012-08-07 18:24:38 +0000275 return((Quantum) (((double) QuantumRange*quantum)/range+0.5));
cristyb3963e62010-05-09 21:36:40 +0000276#else
cristya19f1d72012-08-07 18:24:38 +0000277 return((Quantum) (((double) QuantumRange*quantum)/range));
cristyb3963e62010-05-09 21:36:40 +0000278#endif
cristy3ed852e2009-09-05 21:47:34 +0000279}
280
cristy3ed852e2009-09-05 21:47:34 +0000281static inline QuantumAny ScaleQuantumToAny(const Quantum quantum,
282 const QuantumAny range)
283{
cristya19f1d72012-08-07 18:24:38 +0000284 return((QuantumAny) (((double) range*quantum)/QuantumRange+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000285}
286
287#if (MAGICKCORE_QUANTUM_DEPTH == 8)
288static inline Quantum ScaleCharToQuantum(const unsigned char value)
289{
290 return((Quantum) value);
291}
292
cristy4cb162a2010-05-30 03:04:47 +0000293static inline Quantum ScaleLongToQuantum(const unsigned int value)
cristy3ed852e2009-09-05 21:47:34 +0000294{
295#if !defined(MAGICKCORE_HDRI_SUPPORT)
296 return((Quantum) ((value+8421504UL)/16843009UL));
297#else
298 return((Quantum) (value/16843009.0));
299#endif
300}
301
cristyb13e12a2012-01-06 21:48:27 +0000302static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
303{
304#if !defined(MAGICKCORE_HDRI_SUPPORT)
305 return((Quantum) ((value+MagickULLConstant(551911719039))/
306 MagickULLConstant(1103823438079)));
307#else
308 return((Quantum) (value/1103823438079.0));
309#endif
310}
311
cristybce4f4a2012-10-14 14:57:47 +0000312static inline Quantum ScaleMapToQuantum(const MagickRealType value)
cristy3ed852e2009-09-05 21:47:34 +0000313{
cristya45da3b2010-03-31 02:06:45 +0000314 if (value <= 0.0)
315 return((Quantum) 0);
cristya45da3b2010-03-31 02:06:45 +0000316 if (value >= MaxMap)
cristy6e963d82012-06-19 15:23:24 +0000317 return(QuantumRange);
cristydd2fd9f2010-05-10 01:43:37 +0000318#if !defined(MAGICKCORE_HDRI_SUPPORT)
319 return((Quantum) (value+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000320#else
cristydd2fd9f2010-05-10 01:43:37 +0000321 return((Quantum) value);
cristy3ed852e2009-09-05 21:47:34 +0000322#endif
323}
324
cristy4cb162a2010-05-30 03:04:47 +0000325static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
cristy3ed852e2009-09-05 21:47:34 +0000326{
327#if !defined(MAGICKCORE_HDRI_SUPPORT)
cristy4cb162a2010-05-30 03:04:47 +0000328 return((unsigned int) (16843009UL*quantum));
cristy3ed852e2009-09-05 21:47:34 +0000329#else
330 if (quantum <= 0.0)
331 return(0UL);
332 if ((16843009.0*quantum) >= 4294967295.0)
333 return(4294967295UL);
cristy4cb162a2010-05-30 03:04:47 +0000334 return((unsigned int) (16843009.0*quantum+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000335#endif
336}
337
cristyb13e12a2012-01-06 21:48:27 +0000338static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
339{
340#if !defined(MAGICKCORE_HDRI_SUPPORT)
341 return((MagickSizeType) (MagickULLConstant(551911719039)*quantum));
342#else
343 if (quantum <= 0.0)
344 return(0UL);
345 if ((551911719039.0*quantum) >= 18446744073709551615.0)
346 return(MagickULLConstant(18446744073709551615));
347 return((MagickSizeType) (1103823438079.0*quantum+0.5));
348#endif
349}
350
cristy4cb162a2010-05-30 03:04:47 +0000351static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
cristy3ed852e2009-09-05 21:47:34 +0000352{
353 if (quantum >= (Quantum) MaxMap)
cristy4cb162a2010-05-30 03:04:47 +0000354 return((unsigned int) MaxMap);
cristy3ed852e2009-09-05 21:47:34 +0000355#if !defined(MAGICKCORE_HDRI_SUPPORT)
cristy4cb162a2010-05-30 03:04:47 +0000356 return((unsigned int) quantum);
cristy3ed852e2009-09-05 21:47:34 +0000357#else
cristydd2fd9f2010-05-10 01:43:37 +0000358 if (quantum < 0.0)
359 return(0UL);
cristy4cb162a2010-05-30 03:04:47 +0000360 return((unsigned int) (quantum+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000361#endif
362}
363
364static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
365{
366#if !defined(MAGICKCORE_HDRI_SUPPORT)
367 return((unsigned short) (257UL*quantum));
368#else
369 if (quantum <= 0.0)
370 return(0);
cristycd817db2010-05-09 03:05:41 +0000371 if ((257.0*quantum) >= 65535.0)
cristy3ed852e2009-09-05 21:47:34 +0000372 return(65535);
cristycd817db2010-05-09 03:05:41 +0000373 return((unsigned short) (257.0*quantum+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000374#endif
375}
376
377static inline Quantum ScaleShortToQuantum(const unsigned short value)
378{
379#if !defined(MAGICKCORE_HDRI_SUPPORT)
cristye90d7402010-03-14 18:21:29 +0000380 return((Quantum) ((value+128U)/257U));
cristy3ed852e2009-09-05 21:47:34 +0000381#else
cristydd2fd9f2010-05-10 01:43:37 +0000382 return((Quantum) (value/257.0));
cristy3ed852e2009-09-05 21:47:34 +0000383#endif
384}
385#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
386static inline Quantum ScaleCharToQuantum(const unsigned char value)
387{
388#if !defined(MAGICKCORE_HDRI_SUPPORT)
cristye90d7402010-03-14 18:21:29 +0000389 return((Quantum) (257U*value));
cristy3ed852e2009-09-05 21:47:34 +0000390#else
cristydd2fd9f2010-05-10 01:43:37 +0000391 return((Quantum) (257.0*value));
cristy3ed852e2009-09-05 21:47:34 +0000392#endif
393}
394
cristy4cb162a2010-05-30 03:04:47 +0000395static inline Quantum ScaleLongToQuantum(const unsigned int value)
cristy3ed852e2009-09-05 21:47:34 +0000396{
397#if !defined(MAGICKCORE_HDRI_SUPPORT)
398 return((Quantum) ((value+MagickULLConstant(32768))/
399 MagickULLConstant(65537)));
400#else
cristydd2fd9f2010-05-10 01:43:37 +0000401 return((Quantum) (value/65537.0));
cristy3ed852e2009-09-05 21:47:34 +0000402#endif
403}
404
cristyb13e12a2012-01-06 21:48:27 +0000405static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
406{
407#if !defined(MAGICKCORE_HDRI_SUPPORT)
408 return((Quantum) ((value+MagickULLConstant(8421376))/
409 MagickULLConstant(16842752)));
410#else
411 return((Quantum) (value/16842752.0));
412#endif
413}
414
cristybce4f4a2012-10-14 14:57:47 +0000415static inline Quantum ScaleMapToQuantum(const MagickRealType value)
cristy3ed852e2009-09-05 21:47:34 +0000416{
cristya45da3b2010-03-31 02:06:45 +0000417 if (value <= 0.0)
418 return((Quantum) 0);
cristya45da3b2010-03-31 02:06:45 +0000419 if (value >= MaxMap)
cristy6e963d82012-06-19 15:23:24 +0000420 return(QuantumRange);
cristydd2fd9f2010-05-10 01:43:37 +0000421#if !defined(MAGICKCORE_HDRI_SUPPORT)
422 return((Quantum) (value+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000423#else
cristydd2fd9f2010-05-10 01:43:37 +0000424 return((Quantum) value);
cristy3ed852e2009-09-05 21:47:34 +0000425#endif
426}
427
cristy4cb162a2010-05-30 03:04:47 +0000428static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
cristy3ed852e2009-09-05 21:47:34 +0000429{
430#if !defined(MAGICKCORE_HDRI_SUPPORT)
cristy4cb162a2010-05-30 03:04:47 +0000431 return((unsigned int) (65537UL*quantum));
cristy3ed852e2009-09-05 21:47:34 +0000432#else
433 if (quantum <= 0.0)
434 return(0UL);
cristycd817db2010-05-09 03:05:41 +0000435 if ((65537.0*quantum) >= 4294967295.0)
cristy9f48ca62010-11-25 03:06:31 +0000436 return(4294967295U);
cristy4cb162a2010-05-30 03:04:47 +0000437 return((unsigned int) (65537.0*quantum+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000438#endif
439}
440
cristyb13e12a2012-01-06 21:48:27 +0000441static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
442{
443#if !defined(MAGICKCORE_HDRI_SUPPORT)
444 return((MagickSizeType) (MagickULLConstant(16842752)*quantum));
445#else
446 if (quantum <= 0.0)
447 return(0UL);
448 if ((65537.0*quantum) >= 18446744073709551615.0)
449 return(MagickULLConstant(18446744073709551615));
450 return((MagickSizeType) (16842752.0*quantum+0.5));
451#endif
452}
453
cristy4cb162a2010-05-30 03:04:47 +0000454static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
cristy3ed852e2009-09-05 21:47:34 +0000455{
456 if (quantum >= (Quantum) MaxMap)
cristy4cb162a2010-05-30 03:04:47 +0000457 return((unsigned int) MaxMap);
cristy3ed852e2009-09-05 21:47:34 +0000458#if !defined(MAGICKCORE_HDRI_SUPPORT)
cristy4cb162a2010-05-30 03:04:47 +0000459 return((unsigned int) quantum);
cristy3ed852e2009-09-05 21:47:34 +0000460#else
cristya8307572010-03-31 14:24:19 +0000461 if (quantum < 0.0)
462 return(0UL);
cristy4cb162a2010-05-30 03:04:47 +0000463 return((unsigned int) (quantum+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000464#endif
465}
466
467static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
468{
469#if !defined(MAGICKCORE_HDRI_SUPPORT)
470 return((unsigned short) quantum);
471#else
472 if (quantum <= 0.0)
473 return(0);
474 if (quantum >= 65535.0)
475 return(65535);
476 return((unsigned short) (quantum+0.5));
477#endif
478}
479
480static inline Quantum ScaleShortToQuantum(const unsigned short value)
481{
482 return((Quantum) value);
483}
484#elif (MAGICKCORE_QUANTUM_DEPTH == 32)
485static inline Quantum ScaleCharToQuantum(const unsigned char value)
486{
487#if !defined(MAGICKCORE_HDRI_SUPPORT)
488 return((Quantum) (16843009UL*value));
489#else
cristydd2fd9f2010-05-10 01:43:37 +0000490 return((Quantum) (16843009.0*value));
cristy3ed852e2009-09-05 21:47:34 +0000491#endif
492}
493
cristy4cb162a2010-05-30 03:04:47 +0000494static inline Quantum ScaleLongToQuantum(const unsigned int value)
cristy3ed852e2009-09-05 21:47:34 +0000495{
496 return((Quantum) value);
497}
498
cristyb13e12a2012-01-06 21:48:27 +0000499static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
500{
501 return((Quantum) value);
502}
503
cristybce4f4a2012-10-14 14:57:47 +0000504static inline Quantum ScaleMapToQuantum(const MagickRealType value)
cristy3ed852e2009-09-05 21:47:34 +0000505{
cristya45da3b2010-03-31 02:06:45 +0000506 if (value <= 0.0)
507 return((Quantum) 0);
cristydd2fd9f2010-05-10 01:43:37 +0000508 if (value >= (Quantum) MaxMap)
cristya45da3b2010-03-31 02:06:45 +0000509 return(QuantumRange);
cristydd2fd9f2010-05-10 01:43:37 +0000510#if !defined(MAGICKCORE_HDRI_SUPPORT)
511 return((Quantum) (65537.0*value+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000512#else
cristydd2fd9f2010-05-10 01:43:37 +0000513 return((Quantum) (65537.0*value));
cristy3ed852e2009-09-05 21:47:34 +0000514#endif
515}
516
cristy4cb162a2010-05-30 03:04:47 +0000517static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
cristy3ed852e2009-09-05 21:47:34 +0000518{
cristy0402ad32010-05-11 13:57:55 +0000519#if !defined(MAGICKCORE_HDRI_SUPPORT)
cristy4cb162a2010-05-30 03:04:47 +0000520 return((unsigned int) quantum);
cristy0402ad32010-05-11 13:57:55 +0000521#else
cristy4cb162a2010-05-30 03:04:47 +0000522 return((unsigned int) (quantum+0.5));
cristy0402ad32010-05-11 13:57:55 +0000523#endif
cristy3ed852e2009-09-05 21:47:34 +0000524}
525
cristyb13e12a2012-01-06 21:48:27 +0000526static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
527{
528#if !defined(MAGICKCORE_HDRI_SUPPORT)
529 return((MagickSizeType) quantum);
530#else
531 return((MagickSizeType) (quantum+0.5));
532#endif
533}
534
cristy4cb162a2010-05-30 03:04:47 +0000535static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
cristy3ed852e2009-09-05 21:47:34 +0000536{
cristya45da3b2010-03-31 02:06:45 +0000537 if (quantum < 0.0)
538 return(0UL);
cristydd2fd9f2010-05-10 01:43:37 +0000539 if ((quantum/65537) >= (Quantum) MaxMap)
cristy4cb162a2010-05-30 03:04:47 +0000540 return((unsigned int) MaxMap);
cristy3ed852e2009-09-05 21:47:34 +0000541#if !defined(MAGICKCORE_HDRI_SUPPORT)
cristy4cb162a2010-05-30 03:04:47 +0000542 return((unsigned int) ((quantum+MagickULLConstant(32768))/
cristy3ed852e2009-09-05 21:47:34 +0000543 MagickULLConstant(65537)));
544#else
cristy4cb162a2010-05-30 03:04:47 +0000545 return((unsigned int) (quantum/65537.0+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000546#endif
547}
548
549static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
550{
551#if !defined(MAGICKCORE_HDRI_SUPPORT)
552 return((unsigned short) ((quantum+MagickULLConstant(32768))/
553 MagickULLConstant(65537)));
554#else
555 if (quantum <= 0.0)
556 return(0);
cristycd817db2010-05-09 03:05:41 +0000557 if ((quantum/65537.0) >= 65535.0)
cristy3ed852e2009-09-05 21:47:34 +0000558 return(65535);
cristycd817db2010-05-09 03:05:41 +0000559 return((unsigned short) (quantum/65537.0+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000560#endif
561}
562
563static inline Quantum ScaleShortToQuantum(const unsigned short value)
564{
565#if !defined(MAGICKCORE_HDRI_SUPPORT)
566 return((Quantum) (65537UL*value));
567#else
cristy41f82a62010-05-10 13:05:18 +0000568 return((Quantum) (65537.0*value));
cristy3ed852e2009-09-05 21:47:34 +0000569#endif
570}
571#elif (MAGICKCORE_QUANTUM_DEPTH == 64)
572static inline Quantum ScaleCharToQuantum(const unsigned char value)
573{
cristydd2fd9f2010-05-10 01:43:37 +0000574 return((Quantum) (72340172838076673.0*value));
cristy3ed852e2009-09-05 21:47:34 +0000575}
576
cristy4cb162a2010-05-30 03:04:47 +0000577static inline Quantum ScaleLongToQuantum(const unsigned int value)
cristy3ed852e2009-09-05 21:47:34 +0000578{
cristyff2c0252010-05-11 14:00:48 +0000579 return((Quantum) (4294967297.0*value));
cristy3ed852e2009-09-05 21:47:34 +0000580}
581
cristyb13e12a2012-01-06 21:48:27 +0000582static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
583{
584 return((Quantum) (18446744073709551615.0*value));
585}
586
cristybce4f4a2012-10-14 14:57:47 +0000587static inline Quantum ScaleMapToQuantum(const MagickRealType value)
cristy3ed852e2009-09-05 21:47:34 +0000588{
cristya45da3b2010-03-31 02:06:45 +0000589 if (value <= 0.0)
590 return((Quantum) 0);
cristya45da3b2010-03-31 02:06:45 +0000591 if (value >= MaxMap)
592 return(QuantumRange);
cristydd2fd9f2010-05-10 01:43:37 +0000593 return((Quantum) (281479271743489.0*value));
cristy3ed852e2009-09-05 21:47:34 +0000594}
595
cristy4cb162a2010-05-30 03:04:47 +0000596static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
cristy3ed852e2009-09-05 21:47:34 +0000597{
cristy4cb162a2010-05-30 03:04:47 +0000598 return((unsigned int) (quantum/4294967297.0+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000599}
600
cristyb13e12a2012-01-06 21:48:27 +0000601static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
602{
603 return((MagickSizeType) (quantum/18446744073709551615.0+0.5));
604}
605
cristy4cb162a2010-05-30 03:04:47 +0000606static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
cristy3ed852e2009-09-05 21:47:34 +0000607{
cristy41f82a62010-05-10 13:05:18 +0000608 if (quantum <= 0.0)
cristydd2fd9f2010-05-10 01:43:37 +0000609 return(0UL);
cristy43513522010-05-11 13:46:36 +0000610 if ((quantum/281479271743489.0) >= MaxMap)
cristy4cb162a2010-05-30 03:04:47 +0000611 return((unsigned int) MaxMap);
612 return((unsigned int) (quantum/281479271743489.0+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000613}
614
615static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
616{
cristy5f54f2b2010-05-11 14:29:17 +0000617 if (quantum <= 0.0)
618 return(0);
cristyf4ad8d92010-05-12 17:58:41 +0000619 if ((quantum/281479271743489.0) >= 65535.0)
cristy5f54f2b2010-05-11 14:29:17 +0000620 return(65535);
cristy43513522010-05-11 13:46:36 +0000621 return((unsigned short) (quantum/281479271743489.0+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000622}
623
624static inline Quantum ScaleShortToQuantum(const unsigned short value)
625{
cristyb3963e62010-05-09 21:36:40 +0000626 return((Quantum) (281479271743489.0*value));
cristy3ed852e2009-09-05 21:47:34 +0000627}
628#endif
629
cristy2a4d01c2010-01-10 21:14:51 +0000630static inline unsigned short SinglePrecisionToHalf(const float value)
cristy24fb7dc2010-01-10 20:15:51 +0000631{
632 typedef union _SinglePrecision
633 {
634 unsigned int
635 fixed_point;
636
637 float
638 single_precision;
639 } SinglePrecision;
640
641 register int
642 exponent;
643
644 register unsigned int
645 significand,
646 sign_bit;
647
648 SinglePrecision
649 map;
650
651 unsigned short
cristy2a4d01c2010-01-10 21:14:51 +0000652 half;
cristy24fb7dc2010-01-10 20:15:51 +0000653
654 /*
cristybccb64f2010-01-10 21:16:36 +0000655 The IEEE 754 standard specifies half precision as having:
cristy24fb7dc2010-01-10 20:15:51 +0000656
657 Sign bit: 1 bit
658 Exponent width: 5 bits
659 Significand precision: 11 (10 explicitly stored)
660 */
661 map.single_precision=value;
662 sign_bit=(map.fixed_point >> 16) & 0x00008000;
663 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
664 significand=map.fixed_point & 0x007fffff;
665 if (exponent <= 0)
666 {
cristy4cb162a2010-05-30 03:04:47 +0000667 int
cristy24fb7dc2010-01-10 20:15:51 +0000668 shift;
669
670 if (exponent < -10)
671 return((unsigned short) sign_bit);
672 significand=significand | 0x00800000;
cristy4cb162a2010-05-30 03:04:47 +0000673 shift=(int) (14-exponent);
cristy24fb7dc2010-01-10 20:15:51 +0000674 significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
675 ((significand >> shift) & 0x01)) >> shift);
676 return((unsigned short) (sign_bit | significand));
677 }
678 else
679 if (exponent == (0xff-ExponentBias))
680 {
681 if (significand == 0)
682 return((unsigned short) (sign_bit | ExponentMask));
683 else
684 {
685 significand>>=SignificandShift;
cristy2a4d01c2010-01-10 21:14:51 +0000686 half=(unsigned short) (sign_bit | significand |
cristy24fb7dc2010-01-10 20:15:51 +0000687 (significand == 0) | ExponentMask);
cristy2a4d01c2010-01-10 21:14:51 +0000688 return(half);
cristy24fb7dc2010-01-10 20:15:51 +0000689 }
690 }
691 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
692 if ((significand & 0x00800000) != 0)
693 {
694 significand=0;
695 exponent++;
696 }
697 if (exponent > 30)
698 {
699 float
700 alpha;
701
cristy4cb162a2010-05-30 03:04:47 +0000702 register int
cristy24fb7dc2010-01-10 20:15:51 +0000703 i;
704
705 /*
706 Float overflow.
707 */
708 alpha=1.0e10;
709 for (i=0; i < 10; i++)
710 alpha*=alpha;
711 return((unsigned short) (sign_bit | ExponentMask));
712 }
cristy2a4d01c2010-01-10 21:14:51 +0000713 half=(unsigned short) (sign_bit | (exponent << 10) |
cristy24fb7dc2010-01-10 20:15:51 +0000714 (significand >> SignificandShift));
cristy2a4d01c2010-01-10 21:14:51 +0000715 return(half);
cristy24fb7dc2010-01-10 20:15:51 +0000716}
717
cristy3ed852e2009-09-05 21:47:34 +0000718#if defined(__cplusplus) || defined(c_plusplus)
719}
720#endif
721
722#endif