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