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 (quantum < 0)
287  return((QuantumAny) 0);
288  return((QuantumAny) (((MagickRealType) range*quantum)/QuantumRange+0.5));
289 }
290 
291 #if (MAGICKCORE_QUANTUM_DEPTH == 8)
292 static inline Quantum ScaleCharToQuantum(const unsigned char value)
293 {
294  return((Quantum) value);
295 }
296 
297 static inline Quantum ScaleLongToQuantum(const unsigned int value)
298 {
299 #if !defined(MAGICKCORE_HDRI_SUPPORT)
300  return((Quantum) ((value+8421504UL)/16843009UL));
301 #else
302  return((Quantum) (value/16843009.0));
303 #endif
304 }
305 
306 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
307 {
308  if (value <= 0.0)
309  return((Quantum) 0);
310  if (value >= MaxMap)
311  return(QuantumRange);
312 #if !defined(MAGICKCORE_HDRI_SUPPORT)
313  return((Quantum) (value+0.5));
314 #else
315  return((Quantum) value);
316 #endif
317 }
318 
319 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
320 {
321 #if !defined(MAGICKCORE_HDRI_SUPPORT)
322  return((unsigned int) (16843009UL*quantum));
323 #else
324  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
325  return(0U);
326  if ((16843009.0*quantum) >= 4294967295.0)
327  return(4294967295UL);
328  return((unsigned int) (16843009.0*quantum+0.5));
329 #endif
330 }
331 
332 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
333 {
334  if (quantum >= (Quantum) MaxMap)
335  return((unsigned int) MaxMap);
336 #if !defined(MAGICKCORE_HDRI_SUPPORT)
337  return((unsigned int) quantum);
338 #else
339  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
340  return(0U);
341  return((unsigned int) (quantum+0.5));
342 #endif
343 }
344 
345 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
346 {
347 #if !defined(MAGICKCORE_HDRI_SUPPORT)
348  return((unsigned short) (257UL*quantum));
349 #else
350  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
351  return(0);
352  if ((257.0*quantum) >= 65535.0)
353  return(65535);
354  return((unsigned short) (257.0*quantum+0.5));
355 #endif
356 }
357 
358 static inline Quantum ScaleShortToQuantum(const unsigned short value)
359 {
360 #if !defined(MAGICKCORE_HDRI_SUPPORT)
361  return((Quantum) ((value+128U)/257U));
362 #else
363  return((Quantum) (value/257.0));
364 #endif
365 }
366 #elif (MAGICKCORE_QUANTUM_DEPTH == 16)
367 static inline Quantum ScaleCharToQuantum(const unsigned char value)
368 {
369 #if !defined(MAGICKCORE_HDRI_SUPPORT)
370  return((Quantum) (257U*value));
371 #else
372  return((Quantum) (257.0*value));
373 #endif
374 }
375 
376 static inline Quantum ScaleLongToQuantum(const unsigned int value)
377 {
378 #if !defined(MAGICKCORE_HDRI_SUPPORT)
379  return((Quantum) ((value+MagickULLConstant(32768))/
380  MagickULLConstant(65537)));
381 #else
382  return((Quantum) (value/65537.0));
383 #endif
384 }
385 
386 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
387 {
388  if (value <= 0.0)
389  return((Quantum) 0);
390  if (value >= MaxMap)
391  return(QuantumRange);
392 #if !defined(MAGICKCORE_HDRI_SUPPORT)
393  return((Quantum) (value+0.5));
394 #else
395  return((Quantum) value);
396 #endif
397 }
398 
399 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
400 {
401 #if !defined(MAGICKCORE_HDRI_SUPPORT)
402  return((unsigned int) (65537UL*quantum));
403 #else
404  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
405  return(0U);
406  if ((65537.0*quantum) >= 4294967295.0)
407  return(4294967295U);
408  return((unsigned int) (65537.0*quantum+0.5));
409 #endif
410 }
411 
412 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
413 {
414  if (quantum >= (Quantum) MaxMap)
415  return((unsigned int) MaxMap);
416 #if !defined(MAGICKCORE_HDRI_SUPPORT)
417  return((unsigned int) quantum);
418 #else
419  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
420  return(0U);
421  return((unsigned int) (quantum+0.5));
422 #endif
423 }
424 
425 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
426 {
427 #if !defined(MAGICKCORE_HDRI_SUPPORT)
428  return((unsigned short) quantum);
429 #else
430  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
431  return(0);
432  if (quantum >= 65535.0)
433  return(65535);
434  return((unsigned short) (quantum+0.5));
435 #endif
436 }
437 
438 static inline Quantum ScaleShortToQuantum(const unsigned short value)
439 {
440  return((Quantum) value);
441 }
442 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
443 static inline Quantum ScaleCharToQuantum(const unsigned char value)
444 {
445 #if !defined(MAGICKCORE_HDRI_SUPPORT)
446  return((Quantum) (16843009UL*value));
447 #else
448  return((Quantum) (16843009.0*value));
449 #endif
450 }
451 
452 static inline Quantum ScaleLongToQuantum(const unsigned int value)
453 {
454  return((Quantum) value);
455 }
456 
457 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
458 {
459  if (value <= 0.0)
460  return((Quantum) 0);
461  if (value >= (Quantum) MaxMap)
462  return(QuantumRange);
463 #if !defined(MAGICKCORE_HDRI_SUPPORT)
464  return((Quantum) (65537.0*value+0.5));
465 #else
466  return((Quantum) (65537.0*value));
467 #endif
468 }
469 
470 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
471 {
472 #if !defined(MAGICKCORE_HDRI_SUPPORT)
473  return((unsigned int) quantum);
474 #else
475  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
476  return(0U);
477  if ((quantum) >= 4294967295.0)
478  return(4294967295);
479  return((unsigned int) (quantum+0.5));
480 #endif
481 }
482 
483 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
484 {
485  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
486  return(0U);
487  if ((quantum/65537) >= (Quantum) MaxMap)
488  return((unsigned int) MaxMap);
489 #if !defined(MAGICKCORE_HDRI_SUPPORT)
490  return((unsigned int) ((quantum+MagickULLConstant(32768))/
491  MagickULLConstant(65537)));
492 #else
493  return((unsigned int) (quantum/65537.0+0.5));
494 #endif
495 }
496 
497 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
498 {
499 #if !defined(MAGICKCORE_HDRI_SUPPORT)
500  return((unsigned short) ((quantum+MagickULLConstant(32768))/
501  MagickULLConstant(65537)));
502 #else
503  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
504  return(0);
505  if ((quantum/65537.0) >= 65535.0)
506  return(65535);
507  return((unsigned short) (quantum/65537.0+0.5));
508 #endif
509 }
510 
511 static inline Quantum ScaleShortToQuantum(const unsigned short value)
512 {
513 #if !defined(MAGICKCORE_HDRI_SUPPORT)
514  return((Quantum) (65537UL*value));
515 #else
516  return((Quantum) (65537.0*value));
517 #endif
518 }
519 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
520 static inline Quantum ScaleCharToQuantum(const unsigned char value)
521 {
522  return((Quantum) (72340172838076673.0*value));
523 }
524 
525 static inline Quantum ScaleLongToQuantum(const unsigned int value)
526 {
527  return((Quantum) (4294967297.0*value));
528 }
529 
530 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
531 {
532  if (value <= 0.0)
533  return((Quantum) 0);
534  if (value >= MaxMap)
535  return(QuantumRange);
536  return((Quantum) (281479271743489.0*value));
537 }
538 
539 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
540 {
541  return((unsigned int) (quantum/4294967297.0+0.5));
542 }
543 
544 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
545 {
546  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
547  return(0U);
548  if ((quantum/281479271743489.0) >= MaxMap)
549  return((unsigned int) MaxMap);
550  return((unsigned int) (quantum/281479271743489.0+0.5));
551 }
552 
553 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
554 {
555  if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
556  return(0);
557  if ((quantum/281479271743489.0) >= 65535.0)
558  return(65535);
559  return((unsigned short) (quantum/281479271743489.0+0.5));
560 }
561 
562 static inline Quantum ScaleShortToQuantum(const unsigned short value)
563 {
564  return((Quantum) (281479271743489.0*value));
565 }
566 #endif
567 
568 static inline unsigned short SinglePrecisionToHalf(const float value)
569 {
570  typedef union _SinglePrecision
571  {
572  unsigned int
573  fixed_point;
574 
575  float
576  single_precision;
577  } SinglePrecision;
578 
579  register int
580  exponent;
581 
582  register unsigned int
583  significand,
584  sign_bit;
585 
586  SinglePrecision
587  map;
588 
589  unsigned short
590  half;
591 
592  /*
593  The IEEE 754 standard specifies half precision as having:
594 
595  Sign bit: 1 bit
596  Exponent width: 5 bits
597  Significand precision: 11 (10 explicitly stored)
598  */
599  map.single_precision=value;
600  sign_bit=(map.fixed_point >> 16) & 0x00008000;
601  exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
602  significand=map.fixed_point & 0x007fffff;
603  if (exponent <= 0)
604  {
605  int
606  shift;
607 
608  if (exponent < -10)
609  return((unsigned short) sign_bit);
610  significand=significand | 0x00800000;
611  shift=(int) (14-exponent);
612  significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
613  ((significand >> shift) & 0x01)) >> shift);
614  return((unsigned short) (sign_bit | significand));
615  }
616  else
617  if (exponent == (0xff-ExponentBias))
618  {
619  if (significand == 0)
620  return((unsigned short) (sign_bit | ExponentMask));
621  else
622  {
623  significand>>=SignificandShift;
624  half=(unsigned short) (sign_bit | significand |
625  (significand == 0) | ExponentMask);
626  return(half);
627  }
628  }
629  significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
630  if ((significand & 0x00800000) != 0)
631  {
632  significand=0;
633  exponent++;
634  }
635  if (exponent > 30)
636  {
637  float
638  alpha;
639 
640  register int
641  i;
642 
643  /*
644  Float overflow.
645  */
646  alpha=1.0e10;
647  for (i=0; i < 10; i++)
648  alpha*=alpha;
649  return((unsigned short) (sign_bit | ExponentMask));
650  }
651  half=(unsigned short) (sign_bit | (exponent << 10) |
652  (significand >> SignificandShift));
653  return(half);
654 }
655 
656 #if defined(__cplusplus) || defined(c_plusplus)
657 }
658 #endif
659 
660 #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:568
#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