blob: 37d22c73ce22e5a2d9ceb9e69fbfb3467a1bf3bb [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
Cristy7ce65e72015-12-12 18:03:16 -05002 Copyright 1999-2016 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{
Cristya1a36e72015-09-27 13:19:14 -0400232 register unsigned int
cristy3ed852e2009-09-05 21:47:34 +0000233 quantum;
234
cristy1715f792012-11-22 16:56:12 +0000235 if (endian == LSBEndian)
cristy3ed852e2009-09-05 21:47:34 +0000236 {
Cristya1a36e72015-09-27 13:19:14 -0400237 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;
cristy70d7eae2012-11-17 19:40:21 +0000242 return(pixels);
cristy3ed852e2009-09-05 21:47:34 +0000243 }
Cristya1a36e72015-09-27 13:19:14 -0400244 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;
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{
cristyda950bb2015-07-18 23:17:28 +0000274 if (quantum > range)
275 return(QuantumRange);
cristyb3963e62010-05-09 21:36:40 +0000276#if !defined(MAGICKCORE_HDRI_SUPPORT)
cristya19f1d72012-08-07 18:24:38 +0000277 return((Quantum) (((double) QuantumRange*quantum)/range+0.5));
cristyb3963e62010-05-09 21:36:40 +0000278#else
cristya19f1d72012-08-07 18:24:38 +0000279 return((Quantum) (((double) QuantumRange*quantum)/range));
cristyb3963e62010-05-09 21:36:40 +0000280#endif
cristy3ed852e2009-09-05 21:47:34 +0000281}
282
cristy3ed852e2009-09-05 21:47:34 +0000283static inline QuantumAny ScaleQuantumToAny(const Quantum quantum,
284 const QuantumAny range)
285{
cristya19f1d72012-08-07 18:24:38 +0000286 return((QuantumAny) (((double) range*quantum)/QuantumRange+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000287}
288
289#if (MAGICKCORE_QUANTUM_DEPTH == 8)
290static inline Quantum ScaleCharToQuantum(const unsigned char value)
291{
292 return((Quantum) value);
293}
294
cristy4cb162a2010-05-30 03:04:47 +0000295static inline Quantum ScaleLongToQuantum(const unsigned int value)
cristy3ed852e2009-09-05 21:47:34 +0000296{
297#if !defined(MAGICKCORE_HDRI_SUPPORT)
298 return((Quantum) ((value+8421504UL)/16843009UL));
299#else
300 return((Quantum) (value/16843009.0));
301#endif
302}
303
cristy8b8290b2014-05-26 12:55:32 +0000304static 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)
cristy3ed852e2009-09-05 21:47:34 +0000315{
cristya45da3b2010-03-31 02:06:45 +0000316 if (value <= 0.0)
317 return((Quantum) 0);
cristya45da3b2010-03-31 02:06:45 +0000318 if (value >= MaxMap)
cristy6e963d82012-06-19 15:23:24 +0000319 return(QuantumRange);
cristydd2fd9f2010-05-10 01:43:37 +0000320#if !defined(MAGICKCORE_HDRI_SUPPORT)
321 return((Quantum) (value+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000322#else
cristydd2fd9f2010-05-10 01:43:37 +0000323 return((Quantum) value);
cristy3ed852e2009-09-05 21:47:34 +0000324#endif
325}
326
cristy4cb162a2010-05-30 03:04:47 +0000327static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
cristy3ed852e2009-09-05 21:47:34 +0000328{
329#if !defined(MAGICKCORE_HDRI_SUPPORT)
cristy4cb162a2010-05-30 03:04:47 +0000330 return((unsigned int) (16843009UL*quantum));
cristy3ed852e2009-09-05 21:47:34 +0000331#else
332 if (quantum <= 0.0)
333 return(0UL);
334 if ((16843009.0*quantum) >= 4294967295.0)
335 return(4294967295UL);
cristy4cb162a2010-05-30 03:04:47 +0000336 return((unsigned int) (16843009.0*quantum+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000337#endif
338}
339
cristy8b8290b2014-05-26 12:55:32 +0000340static 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
cristy4cb162a2010-05-30 03:04:47 +0000353static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
cristy3ed852e2009-09-05 21:47:34 +0000354{
355 if (quantum >= (Quantum) MaxMap)
cristy4cb162a2010-05-30 03:04:47 +0000356 return((unsigned int) MaxMap);
cristy3ed852e2009-09-05 21:47:34 +0000357#if !defined(MAGICKCORE_HDRI_SUPPORT)
cristy4cb162a2010-05-30 03:04:47 +0000358 return((unsigned int) quantum);
cristy3ed852e2009-09-05 21:47:34 +0000359#else
cristydd2fd9f2010-05-10 01:43:37 +0000360 if (quantum < 0.0)
361 return(0UL);
cristy4cb162a2010-05-30 03:04:47 +0000362 return((unsigned int) (quantum+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000363#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);
cristycd817db2010-05-09 03:05:41 +0000373 if ((257.0*quantum) >= 65535.0)
cristy3ed852e2009-09-05 21:47:34 +0000374 return(65535);
cristycd817db2010-05-09 03:05:41 +0000375 return((unsigned short) (257.0*quantum+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000376#endif
377}
378
379static inline Quantum ScaleShortToQuantum(const unsigned short value)
380{
381#if !defined(MAGICKCORE_HDRI_SUPPORT)
cristye90d7402010-03-14 18:21:29 +0000382 return((Quantum) ((value+128U)/257U));
cristy3ed852e2009-09-05 21:47:34 +0000383#else
cristydd2fd9f2010-05-10 01:43:37 +0000384 return((Quantum) (value/257.0));
cristy3ed852e2009-09-05 21:47:34 +0000385#endif
386}
387#elif (MAGICKCORE_QUANTUM_DEPTH == 16)
388static inline Quantum ScaleCharToQuantum(const unsigned char value)
389{
390#if !defined(MAGICKCORE_HDRI_SUPPORT)
cristye90d7402010-03-14 18:21:29 +0000391 return((Quantum) (257U*value));
cristy3ed852e2009-09-05 21:47:34 +0000392#else
cristydd2fd9f2010-05-10 01:43:37 +0000393 return((Quantum) (257.0*value));
cristy3ed852e2009-09-05 21:47:34 +0000394#endif
395}
396
cristy4cb162a2010-05-30 03:04:47 +0000397static inline Quantum ScaleLongToQuantum(const unsigned int value)
cristy3ed852e2009-09-05 21:47:34 +0000398{
399#if !defined(MAGICKCORE_HDRI_SUPPORT)
400 return((Quantum) ((value+MagickULLConstant(32768))/
401 MagickULLConstant(65537)));
402#else
cristydd2fd9f2010-05-10 01:43:37 +0000403 return((Quantum) (value/65537.0));
cristy3ed852e2009-09-05 21:47:34 +0000404#endif
405}
406
cristy8b8290b2014-05-26 12:55:32 +0000407static 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)
cristy3ed852e2009-09-05 21:47:34 +0000418{
cristya45da3b2010-03-31 02:06:45 +0000419 if (value <= 0.0)
420 return((Quantum) 0);
cristya45da3b2010-03-31 02:06:45 +0000421 if (value >= MaxMap)
cristy6e963d82012-06-19 15:23:24 +0000422 return(QuantumRange);
cristydd2fd9f2010-05-10 01:43:37 +0000423#if !defined(MAGICKCORE_HDRI_SUPPORT)
424 return((Quantum) (value+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000425#else
cristydd2fd9f2010-05-10 01:43:37 +0000426 return((Quantum) value);
cristy3ed852e2009-09-05 21:47:34 +0000427#endif
428}
429
cristy4cb162a2010-05-30 03:04:47 +0000430static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
cristy3ed852e2009-09-05 21:47:34 +0000431{
432#if !defined(MAGICKCORE_HDRI_SUPPORT)
cristy4cb162a2010-05-30 03:04:47 +0000433 return((unsigned int) (65537UL*quantum));
cristy3ed852e2009-09-05 21:47:34 +0000434#else
435 if (quantum <= 0.0)
436 return(0UL);
cristycd817db2010-05-09 03:05:41 +0000437 if ((65537.0*quantum) >= 4294967295.0)
cristy9f48ca62010-11-25 03:06:31 +0000438 return(4294967295U);
cristy4cb162a2010-05-30 03:04:47 +0000439 return((unsigned int) (65537.0*quantum+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000440#endif
441}
442
cristy8b8290b2014-05-26 12:55:32 +0000443static 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
cristy4cb162a2010-05-30 03:04:47 +0000456static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
cristy3ed852e2009-09-05 21:47:34 +0000457{
458 if (quantum >= (Quantum) MaxMap)
cristy4cb162a2010-05-30 03:04:47 +0000459 return((unsigned int) MaxMap);
cristy3ed852e2009-09-05 21:47:34 +0000460#if !defined(MAGICKCORE_HDRI_SUPPORT)
cristy4cb162a2010-05-30 03:04:47 +0000461 return((unsigned int) quantum);
cristy3ed852e2009-09-05 21:47:34 +0000462#else
cristya8307572010-03-31 14:24:19 +0000463 if (quantum < 0.0)
464 return(0UL);
cristy4cb162a2010-05-30 03:04:47 +0000465 return((unsigned int) (quantum+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000466#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
cristydd2fd9f2010-05-10 01:43:37 +0000492 return((Quantum) (16843009.0*value));
cristy3ed852e2009-09-05 21:47:34 +0000493#endif
494}
495
cristy4cb162a2010-05-30 03:04:47 +0000496static inline Quantum ScaleLongToQuantum(const unsigned int value)
cristy3ed852e2009-09-05 21:47:34 +0000497{
498 return((Quantum) value);
499}
500
cristy8b8290b2014-05-26 12:55:32 +0000501static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
502{
503 return((Quantum) value);
504}
505
506static inline Quantum ScaleMapToQuantum(const MagickRealType value)
cristy3ed852e2009-09-05 21:47:34 +0000507{
cristya45da3b2010-03-31 02:06:45 +0000508 if (value <= 0.0)
509 return((Quantum) 0);
cristydd2fd9f2010-05-10 01:43:37 +0000510 if (value >= (Quantum) MaxMap)
cristya45da3b2010-03-31 02:06:45 +0000511 return(QuantumRange);
cristydd2fd9f2010-05-10 01:43:37 +0000512#if !defined(MAGICKCORE_HDRI_SUPPORT)
513 return((Quantum) (65537.0*value+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000514#else
cristydd2fd9f2010-05-10 01:43:37 +0000515 return((Quantum) (65537.0*value));
cristy3ed852e2009-09-05 21:47:34 +0000516#endif
517}
518
cristy4cb162a2010-05-30 03:04:47 +0000519static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
cristy3ed852e2009-09-05 21:47:34 +0000520{
cristy0402ad32010-05-11 13:57:55 +0000521#if !defined(MAGICKCORE_HDRI_SUPPORT)
cristy4cb162a2010-05-30 03:04:47 +0000522 return((unsigned int) quantum);
cristy0402ad32010-05-11 13:57:55 +0000523#else
cristyda97dba2014-05-24 22:59:47 +0000524 if (quantum <= 0.0)
525 return(0);
526 if ((quantum) >= 4294967295.0)
527 return(4294967295);
cristy4cb162a2010-05-30 03:04:47 +0000528 return((unsigned int) (quantum+0.5));
cristy0402ad32010-05-11 13:57:55 +0000529#endif
cristy3ed852e2009-09-05 21:47:34 +0000530}
531
cristy8b8290b2014-05-26 12:55:32 +0000532static 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
cristy4cb162a2010-05-30 03:04:47 +0000541static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
cristy3ed852e2009-09-05 21:47:34 +0000542{
cristya45da3b2010-03-31 02:06:45 +0000543 if (quantum < 0.0)
544 return(0UL);
cristydd2fd9f2010-05-10 01:43:37 +0000545 if ((quantum/65537) >= (Quantum) MaxMap)
cristy4cb162a2010-05-30 03:04:47 +0000546 return((unsigned int) MaxMap);
cristy3ed852e2009-09-05 21:47:34 +0000547#if !defined(MAGICKCORE_HDRI_SUPPORT)
cristy4cb162a2010-05-30 03:04:47 +0000548 return((unsigned int) ((quantum+MagickULLConstant(32768))/
cristy3ed852e2009-09-05 21:47:34 +0000549 MagickULLConstant(65537)));
550#else
cristy4cb162a2010-05-30 03:04:47 +0000551 return((unsigned int) (quantum/65537.0+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000552#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);
cristycd817db2010-05-09 03:05:41 +0000563 if ((quantum/65537.0) >= 65535.0)
cristy3ed852e2009-09-05 21:47:34 +0000564 return(65535);
cristycd817db2010-05-09 03:05:41 +0000565 return((unsigned short) (quantum/65537.0+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000566#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
cristy41f82a62010-05-10 13:05:18 +0000574 return((Quantum) (65537.0*value));
cristy3ed852e2009-09-05 21:47:34 +0000575#endif
576}
577#elif (MAGICKCORE_QUANTUM_DEPTH == 64)
578static inline Quantum ScaleCharToQuantum(const unsigned char value)
579{
cristydd2fd9f2010-05-10 01:43:37 +0000580 return((Quantum) (72340172838076673.0*value));
cristy3ed852e2009-09-05 21:47:34 +0000581}
582
cristy4cb162a2010-05-30 03:04:47 +0000583static inline Quantum ScaleLongToQuantum(const unsigned int value)
cristy3ed852e2009-09-05 21:47:34 +0000584{
cristyff2c0252010-05-11 14:00:48 +0000585 return((Quantum) (4294967297.0*value));
cristy3ed852e2009-09-05 21:47:34 +0000586}
587
cristy8b8290b2014-05-26 12:55:32 +0000588static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
589{
590 return((Quantum) (18446744073709551615.0*value));
591}
592
593static inline Quantum ScaleMapToQuantum(const MagickRealType value)
cristy3ed852e2009-09-05 21:47:34 +0000594{
cristya45da3b2010-03-31 02:06:45 +0000595 if (value <= 0.0)
596 return((Quantum) 0);
cristya45da3b2010-03-31 02:06:45 +0000597 if (value >= MaxMap)
598 return(QuantumRange);
cristydd2fd9f2010-05-10 01:43:37 +0000599 return((Quantum) (281479271743489.0*value));
cristy3ed852e2009-09-05 21:47:34 +0000600}
601
cristy4cb162a2010-05-30 03:04:47 +0000602static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
cristy3ed852e2009-09-05 21:47:34 +0000603{
cristy4cb162a2010-05-30 03:04:47 +0000604 return((unsigned int) (quantum/4294967297.0+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000605}
606
cristy8b8290b2014-05-26 12:55:32 +0000607static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
608{
609 return((MagickSizeType) (quantum/18446744073709551615.0+0.5));
610}
611
cristy4cb162a2010-05-30 03:04:47 +0000612static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
cristy3ed852e2009-09-05 21:47:34 +0000613{
cristy41f82a62010-05-10 13:05:18 +0000614 if (quantum <= 0.0)
cristydd2fd9f2010-05-10 01:43:37 +0000615 return(0UL);
cristy43513522010-05-11 13:46:36 +0000616 if ((quantum/281479271743489.0) >= MaxMap)
cristy4cb162a2010-05-30 03:04:47 +0000617 return((unsigned int) MaxMap);
618 return((unsigned int) (quantum/281479271743489.0+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000619}
620
621static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
622{
cristy5f54f2b2010-05-11 14:29:17 +0000623 if (quantum <= 0.0)
624 return(0);
cristyf4ad8d92010-05-12 17:58:41 +0000625 if ((quantum/281479271743489.0) >= 65535.0)
cristy5f54f2b2010-05-11 14:29:17 +0000626 return(65535);
cristy43513522010-05-11 13:46:36 +0000627 return((unsigned short) (quantum/281479271743489.0+0.5));
cristy3ed852e2009-09-05 21:47:34 +0000628}
629
630static inline Quantum ScaleShortToQuantum(const unsigned short value)
631{
cristyb3963e62010-05-09 21:36:40 +0000632 return((Quantum) (281479271743489.0*value));
cristy3ed852e2009-09-05 21:47:34 +0000633}
634#endif
635
cristy2a4d01c2010-01-10 21:14:51 +0000636static inline unsigned short SinglePrecisionToHalf(const float value)
cristy24fb7dc2010-01-10 20:15:51 +0000637{
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
cristy2a4d01c2010-01-10 21:14:51 +0000658 half;
cristy24fb7dc2010-01-10 20:15:51 +0000659
660 /*
cristybccb64f2010-01-10 21:16:36 +0000661 The IEEE 754 standard specifies half precision as having:
cristy24fb7dc2010-01-10 20:15:51 +0000662
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 {
cristy4cb162a2010-05-30 03:04:47 +0000673 int
cristy24fb7dc2010-01-10 20:15:51 +0000674 shift;
675
676 if (exponent < -10)
677 return((unsigned short) sign_bit);
678 significand=significand | 0x00800000;
cristy4cb162a2010-05-30 03:04:47 +0000679 shift=(int) (14-exponent);
cristy24fb7dc2010-01-10 20:15:51 +0000680 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;
cristy2a4d01c2010-01-10 21:14:51 +0000692 half=(unsigned short) (sign_bit | significand |
cristy24fb7dc2010-01-10 20:15:51 +0000693 (significand == 0) | ExponentMask);
cristy2a4d01c2010-01-10 21:14:51 +0000694 return(half);
cristy24fb7dc2010-01-10 20:15:51 +0000695 }
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
cristy4cb162a2010-05-30 03:04:47 +0000708 register int
cristy24fb7dc2010-01-10 20:15:51 +0000709 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 }
cristy2a4d01c2010-01-10 21:14:51 +0000719 half=(unsigned short) (sign_bit | (exponent << 10) |
cristy24fb7dc2010-01-10 20:15:51 +0000720 (significand >> SignificandShift));
cristy2a4d01c2010-01-10 21:14:51 +0000721 return(half);
cristy24fb7dc2010-01-10 20:15:51 +0000722}
723
cristy3ed852e2009-09-05 21:47:34 +0000724#if defined(__cplusplus) || defined(c_plusplus)
725}
726#endif
727
728#endif