MagickCore  6.9.7
quantum-private.h
Go to the documentation of this file.
1 /*
2  Copyright 1999-2017 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 "magick/cache.h"
22 
23 #if defined(__cplusplus) || defined(c_plusplus)
24 extern "C" {
25 #endif
26 
27 typedef struct _QuantumState
28 {
29  double
31 
32  unsigned int
34 
35  size_t
37 
38  const unsigned int
39  *mask;
40 } QuantumState;
41 
43 {
44  size_t
45  depth,
46  quantum;
47 
50 
51  double
52  minimum,
53  maximum,
54  scale;
55 
56  size_t
57  pad;
58 
60  min_is_white,
61  pack;
62 
65 
66  size_t
68 
69  unsigned char
70  **pixels;
71 
72  size_t
74 
77 
80 
83 
84  size_t
86 };
87 
88 extern MagickPrivate void
90 
91 static inline MagickSizeType GetQuantumRange(const size_t depth)
92 {
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 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) (((MagickRealType) QuantumRange*quantum)/range+0.5));
278 #else
279  return((Quantum) (((MagickRealType) QuantumRange*quantum)/range));
280 #endif
281 }
282 
283 static inline QuantumAny ScaleQuantumToAny(const Quantum quantum,
284  const QuantumAny range)
285 {
286 #if !defined(MAGICKCORE_HDRI_SUPPORT)
287  return((QuantumAny) ((MagickRealType) range*quantum/QuantumRange));
288 #else
289  if (quantum <= 0.0)
290  return((QuantumAny) 0UL);
291  if (((MagickRealType) range*quantum/QuantumRange) >= 18446744073709551615.0)
292  return((QuantumAny) MagickULLConstant(18446744073709551615));
293  return((QuantumAny) ((MagickRealType) range*quantum/QuantumRange+0.5));
294 #endif
295 }
296 
297 #if (MAGICKCORE_QUANTUM_DEPTH == 8)
298 static inline Quantum ScaleCharToQuantum(const unsigned char value)
299 {
300  return((Quantum) value);
301 }
302 
303 static inline Quantum ScaleLongToQuantum(const unsigned int value)
304 {
305 #if !defined(MAGICKCORE_HDRI_SUPPORT)
306  return((Quantum) ((value+8421504UL)/16843009UL));
307 #else
308  return((Quantum) (value/16843009.0));
309 #endif
310 }
311 
312 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
313 {
314  if (value <= 0.0)
315  return((Quantum) 0);
316  if (value >= MaxMap)
317  return(QuantumRange);
318 #if !defined(MAGICKCORE_HDRI_SUPPORT)
319  return((Quantum) (value+0.5));
320 #else
321  return((Quantum) value);
322 #endif
323 }
324 
325 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
326 {
327 #if !defined(MAGICKCORE_HDRI_SUPPORT)
328  return((unsigned int) (16843009UL*quantum));
329 #else
330  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
331  return(0U);
332  if ((16843009.0*quantum) >= 4294967295.0)
333  return(4294967295UL);
334  return((unsigned int) (16843009.0*quantum+0.5));
335 #endif
336 }
337 
338 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
339 {
340  if (quantum >= (Quantum) MaxMap)
341  return((unsigned int) MaxMap);
342 #if !defined(MAGICKCORE_HDRI_SUPPORT)
343  return((unsigned int) quantum);
344 #else
345  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
346  return(0U);
347  return((unsigned int) (quantum+0.5));
348 #endif
349 }
350 
351 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
352 {
353 #if !defined(MAGICKCORE_HDRI_SUPPORT)
354  return((unsigned short) (257UL*quantum));
355 #else
356  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
357  return(0);
358  if ((257.0*quantum) >= 65535.0)
359  return(65535);
360  return((unsigned short) (257.0*quantum+0.5));
361 #endif
362 }
363 
364 static inline Quantum ScaleShortToQuantum(const unsigned short value)
365 {
366 #if !defined(MAGICKCORE_HDRI_SUPPORT)
367  return((Quantum) ((value+128U)/257U));
368 #else
369  return((Quantum) (value/257.0));
370 #endif
371 }
372 #elif (MAGICKCORE_QUANTUM_DEPTH == 16)
373 static inline Quantum ScaleCharToQuantum(const unsigned char value)
374 {
375 #if !defined(MAGICKCORE_HDRI_SUPPORT)
376  return((Quantum) (257U*value));
377 #else
378  return((Quantum) (257.0*value));
379 #endif
380 }
381 
382 static inline Quantum ScaleLongToQuantum(const unsigned int value)
383 {
384 #if !defined(MAGICKCORE_HDRI_SUPPORT)
385  return((Quantum) ((value+MagickULLConstant(32768))/
386  MagickULLConstant(65537)));
387 #else
388  return((Quantum) (value/65537.0));
389 #endif
390 }
391 
392 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
393 {
394  if (value <= 0.0)
395  return((Quantum) 0);
396  if (value >= MaxMap)
397  return(QuantumRange);
398 #if !defined(MAGICKCORE_HDRI_SUPPORT)
399  return((Quantum) (value+0.5));
400 #else
401  return((Quantum) value);
402 #endif
403 }
404 
405 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
406 {
407 #if !defined(MAGICKCORE_HDRI_SUPPORT)
408  return((unsigned int) (65537UL*quantum));
409 #else
410  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
411  return(0U);
412  if ((65537.0*quantum) >= 4294967295.0)
413  return(4294967295U);
414  return((unsigned int) (65537.0*quantum+0.5));
415 #endif
416 }
417 
418 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
419 {
420  if (quantum >= (Quantum) MaxMap)
421  return((unsigned int) MaxMap);
422 #if !defined(MAGICKCORE_HDRI_SUPPORT)
423  return((unsigned int) quantum);
424 #else
425  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
426  return(0U);
427  return((unsigned int) (quantum+0.5));
428 #endif
429 }
430 
431 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
432 {
433 #if !defined(MAGICKCORE_HDRI_SUPPORT)
434  return((unsigned short) quantum);
435 #else
436  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
437  return(0);
438  if (quantum >= 65535.0)
439  return(65535);
440  return((unsigned short) (quantum+0.5));
441 #endif
442 }
443 
444 static inline Quantum ScaleShortToQuantum(const unsigned short value)
445 {
446  return((Quantum) value);
447 }
448 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
449 static inline Quantum ScaleCharToQuantum(const unsigned char value)
450 {
451 #if !defined(MAGICKCORE_HDRI_SUPPORT)
452  return((Quantum) (16843009UL*value));
453 #else
454  return((Quantum) (16843009.0*value));
455 #endif
456 }
457 
458 static inline Quantum ScaleLongToQuantum(const unsigned int value)
459 {
460  return((Quantum) value);
461 }
462 
463 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
464 {
465  if (value <= 0.0)
466  return((Quantum) 0);
467  if (value >= (Quantum) MaxMap)
468  return(QuantumRange);
469 #if !defined(MAGICKCORE_HDRI_SUPPORT)
470  return((Quantum) (65537.0*value+0.5));
471 #else
472  return((Quantum) (65537.0*value));
473 #endif
474 }
475 
476 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
477 {
478 #if !defined(MAGICKCORE_HDRI_SUPPORT)
479  return((unsigned int) quantum);
480 #else
481  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
482  return(0U);
483  if ((quantum) >= 4294967295.0)
484  return(4294967295);
485  return((unsigned int) (quantum+0.5));
486 #endif
487 }
488 
489 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
490 {
491  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
492  return(0U);
493  if ((quantum/65537) >= (Quantum) MaxMap)
494  return((unsigned int) MaxMap);
495 #if !defined(MAGICKCORE_HDRI_SUPPORT)
496  return((unsigned int) ((quantum+MagickULLConstant(32768))/
497  MagickULLConstant(65537)));
498 #else
499  return((unsigned int) (quantum/65537.0+0.5));
500 #endif
501 }
502 
503 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
504 {
505 #if !defined(MAGICKCORE_HDRI_SUPPORT)
506  return((unsigned short) ((quantum+MagickULLConstant(32768))/
507  MagickULLConstant(65537)));
508 #else
509  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
510  return(0);
511  if ((quantum/65537.0) >= 65535.0)
512  return(65535);
513  return((unsigned short) (quantum/65537.0+0.5));
514 #endif
515 }
516 
517 static inline Quantum ScaleShortToQuantum(const unsigned short value)
518 {
519 #if !defined(MAGICKCORE_HDRI_SUPPORT)
520  return((Quantum) (65537UL*value));
521 #else
522  return((Quantum) (65537.0*value));
523 #endif
524 }
525 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
526 static inline Quantum ScaleCharToQuantum(const unsigned char value)
527 {
528  return((Quantum) (72340172838076673.0*value));
529 }
530 
531 static inline Quantum ScaleLongToQuantum(const unsigned int value)
532 {
533  return((Quantum) (4294967297.0*value));
534 }
535 
536 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
537 {
538  if (value <= 0.0)
539  return((Quantum) 0);
540  if (value >= MaxMap)
541  return(QuantumRange);
542  return((Quantum) (281479271743489.0*value));
543 }
544 
545 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
546 {
547  return((unsigned int) (quantum/4294967297.0+0.5));
548 }
549 
550 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
551 {
552  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
553  return(0U);
554  if ((quantum/281479271743489.0) >= MaxMap)
555  return((unsigned int) MaxMap);
556  return((unsigned int) (quantum/281479271743489.0+0.5));
557 }
558 
559 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
560 {
561  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
562  return(0);
563  if ((quantum/281479271743489.0) >= 65535.0)
564  return(65535);
565  return((unsigned short) (quantum/281479271743489.0+0.5));
566 }
567 
568 static inline Quantum ScaleShortToQuantum(const unsigned short value)
569 {
570  return((Quantum) (281479271743489.0*value));
571 }
572 #endif
573 
574 static inline unsigned short SinglePrecisionToHalf(const float value)
575 {
576  typedef union _SinglePrecision
577  {
578  unsigned int
579  fixed_point;
580 
581  float
582  single_precision;
583  } SinglePrecision;
584 
585  register int
586  exponent;
587 
588  register unsigned int
589  significand,
590  sign_bit;
591 
592  SinglePrecision
593  map;
594 
595  unsigned short
596  half;
597 
598  /*
599  The IEEE 754 standard specifies half precision as having:
600 
601  Sign bit: 1 bit
602  Exponent width: 5 bits
603  Significand precision: 11 (10 explicitly stored)
604  */
605  map.single_precision=value;
606  sign_bit=(map.fixed_point >> 16) & 0x00008000;
607  exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
608  significand=map.fixed_point & 0x007fffff;
609  if (exponent <= 0)
610  {
611  int
612  shift;
613 
614  if (exponent < -10)
615  return((unsigned short) sign_bit);
616  significand=significand | 0x00800000;
617  shift=(int) (14-exponent);
618  significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
619  ((significand >> shift) & 0x01)) >> shift);
620  return((unsigned short) (sign_bit | significand));
621  }
622  else
623  if (exponent == (0xff-ExponentBias))
624  {
625  if (significand == 0)
626  return((unsigned short) (sign_bit | ExponentMask));
627  else
628  {
629  significand>>=SignificandShift;
630  half=(unsigned short) (sign_bit | significand |
631  (significand == 0) | ExponentMask);
632  return(half);
633  }
634  }
635  significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
636  if ((significand & 0x00800000) != 0)
637  {
638  significand=0;
639  exponent++;
640  }
641  if (exponent > 30)
642  {
643  float
644  alpha;
645 
646  register int
647  i;
648 
649  /*
650  Float overflow.
651  */
652  alpha=1.0e10;
653  for (i=0; i < 10; i++)
654  alpha*=alpha;
655  return((unsigned short) (sign_bit | ExponentMask));
656  }
657  half=(unsigned short) (sign_bit | (exponent << 10) |
658  (significand >> SignificandShift));
659  return(half);
660 }
661 
662 #if defined(__cplusplus) || defined(c_plusplus)
663 }
664 #endif
665 
666 #endif
QuantumFormatType
Definition: quantum.h:45
QuantumFormatType format
Definition: quantum-private.h:49
static MagickSizeType GetQuantumRange(const size_t depth)
Definition: quantum-private.h:91
#define ExponentMask
QuantumAlphaType alpha_type
Definition: quantum-private.h:64
size_t signature
Definition: quantum-private.h:85
#define MagickULLConstant(c)
Definition: magick-type.h:40
unsigned char ** pixels
Definition: quantum-private.h:70
Definition: quantum.h:34
MagickPrivate void ResetQuantumState(QuantumInfo *)
Definition: quantum.c:574
#define SignBitShift
float MagickRealType
Definition: magick-type.h:80
#define SignificandMask
QuantumState state
Definition: quantum-private.h:79
EndianType
Definition: quantum.h:31
size_t quantum
Definition: quantum-private.h:45
EndianType endian
Definition: quantum-private.h:76
static const unsigned char * PushShortPixel(const EndianType endian, const unsigned char *pixels, unsigned short *pixel)
Definition: quantum-private.h:252
MagickBooleanType pack
Definition: quantum-private.h:60
static const unsigned char * PushCharPixel(const unsigned char *pixels, unsigned char *pixel)
Definition: quantum-private.h:222
MagickBooleanType
Definition: magick-type.h:215
static Quantum ScaleAnyToQuantum(const QuantumAny quantum, const QuantumAny range)
Definition: quantum-private.h:271
static unsigned char * PopLongPixel(const EndianType endian, const unsigned int pixel, unsigned char *pixels)
Definition: quantum-private.h:182
unsigned int pixel
Definition: quantum-private.h:33
size_t MagickSizeType
Definition: magick-type.h:160
static const unsigned char * PushLongPixel(const EndianType endian, const unsigned char *pixels, unsigned int *pixel)
Definition: quantum-private.h:229
SemaphoreInfo * semaphore
Definition: quantum-private.h:82
#define SignificandShift
#define ExponentShift
#define MaxMap
Definition: magick-type.h:74
Definition: quantum-private.h:42
size_t pad
Definition: quantum-private.h:57
#define IsNaN(a)
Definition: magick-type.h:227
static float HalfToSinglePrecision(const unsigned short half)
Definition: quantum-private.h:100
size_t number_threads
Definition: quantum-private.h:67
double scale
Definition: quantum-private.h:52
Definition: magick-type.h:217
const unsigned int * mask
Definition: quantum-private.h:39
unsigned short Quantum
Definition: magick-type.h:97
#define ExponentBias
size_t bits
Definition: quantum-private.h:36
size_t extent
Definition: quantum-private.h:73
static unsigned char * PopCharPixel(const unsigned char pixel, unsigned char *pixels)
Definition: quantum-private.h:175
static unsigned char * PopShortPixel(const EndianType endian, const unsigned short pixel, unsigned char *pixels)
Definition: quantum-private.h:204
double inverse_scale
Definition: quantum-private.h:30
static unsigned short SinglePrecisionToHalf(const float value)
Definition: quantum-private.h:574
#define MagickPrivate
Definition: method-attribute.h:99
struct _QuantumState QuantumState
static QuantumAny ScaleQuantumToAny(const Quantum quantum, const QuantumAny range)
Definition: quantum-private.h:283
Definition: quantum-private.h:27
MagickSizeType QuantumAny
Definition: magick-type.h:174
QuantumAlphaType
Definition: quantum.h:38
Definition: semaphore.c:58
#define QuantumRange
Definition: magick-type.h:98