MagickCore  6.9.10
Convert, Edit, Or Compose Bitmap Images
quantum-private.h
Go to the documentation of this file.
1 /*
2  Copyright 1999-2018 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  https://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/memory_.h"
22 #include "magick/cache.h"
23 #include "magick/image-private.h"
24 #include "magick/pixel-accessor.h"
25 
26 #if defined(__cplusplus) || defined(c_plusplus)
27 extern "C" {
28 #endif
29 
30 typedef struct _QuantumState
31 {
32  double
34 
35  unsigned int
37 
38  size_t
40 
41  const unsigned int
42  *mask;
43 } QuantumState;
44 
46 {
47  size_t
48  depth,
49  quantum;
50 
53 
54  double
55  minimum,
56  maximum,
57  scale;
58 
59  size_t
60  pad;
61 
63  min_is_white,
64  pack;
65 
68 
69  size_t
71 
73  **pixels;
74 
75  size_t
77 
80 
83 
86 
87  size_t
89 };
90 
91 extern MagickPrivate void
93 
94 static inline MagickSizeType GetQuantumRange(const size_t depth)
95 {
97  one;
98 
99  size_t
100  max_depth;
101 
102  if (depth == 0)
103  return(0);
104  one=1;
105  max_depth=8*sizeof(MagickSizeType);
106  return((MagickSizeType) ((one << (MagickMin(depth,max_depth)-1))+
107  ((one << (MagickMin(depth,max_depth)-1))-1)));
108 }
109 
110 static inline float HalfToSinglePrecision(const unsigned short half)
111 {
112 #define ExponentBias (127-15)
113 #define ExponentMask 0x7c00
114 #define ExponentShift 23
115 #define SignBitShift 31
116 #define SignificandShift 13
117 #define SignificandMask 0x00000400
118 
119  typedef union _SinglePrecision
120  {
121  unsigned int
122  fixed_point;
123 
124  float
125  single_precision;
126  } SinglePrecision;
127 
128  register unsigned int
129  exponent,
130  significand,
131  sign_bit;
132 
133  SinglePrecision
134  map;
135 
136  unsigned int
137  value;
138 
139  /*
140  The IEEE 754 standard specifies half precision as having:
141 
142  Sign bit: 1 bit
143  Exponent width: 5 bits
144  Significand precision: 11 (10 explicitly stored)
145  */
146  sign_bit=(unsigned int) ((half >> 15) & 0x00000001);
147  exponent=(unsigned int) ((half >> 10) & 0x0000001f);
148  significand=(unsigned int) (half & 0x000003ff);
149  if (exponent == 0)
150  {
151  if (significand == 0)
152  value=sign_bit << SignBitShift;
153  else
154  {
155  while ((significand & SignificandMask) == 0)
156  {
157  significand<<=1;
158  exponent--;
159  }
160  exponent++;
161  significand&=(~SignificandMask);
162  exponent+=ExponentBias;
163  value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
164  (significand << SignificandShift);
165  }
166  }
167  else
168  if (exponent == SignBitShift)
169  {
170  value=(sign_bit << SignBitShift) | 0x7f800000;
171  if (significand != 0)
172  value|=(significand << SignificandShift);
173  }
174  else
175  {
176  exponent+=ExponentBias;
177  significand<<=SignificandShift;
178  value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
179  significand;
180  }
181  map.fixed_point=value;
182  return(map.single_precision);
183 }
184 
185 static inline unsigned char *PopCharPixel(const unsigned char pixel,
186  unsigned char *pixels)
187 {
188  *pixels++=pixel;
189  return(pixels);
190 }
191 
192 static inline unsigned char *PopLongPixel(const EndianType endian,
193  const unsigned int pixel,unsigned char *pixels)
194 {
195  register unsigned int
196  quantum;
197 
198  quantum=(unsigned int) pixel;
199  if (endian == LSBEndian)
200  {
201  *pixels++=(unsigned char) (quantum);
202  *pixels++=(unsigned char) (quantum >> 8);
203  *pixels++=(unsigned char) (quantum >> 16);
204  *pixels++=(unsigned char) (quantum >> 24);
205  return(pixels);
206  }
207  *pixels++=(unsigned char) (quantum >> 24);
208  *pixels++=(unsigned char) (quantum >> 16);
209  *pixels++=(unsigned char) (quantum >> 8);
210  *pixels++=(unsigned char) (quantum);
211  return(pixels);
212 }
213 
214 static inline unsigned char *PopShortPixel(const EndianType endian,
215  const unsigned short pixel,unsigned char *pixels)
216 {
217  register unsigned int
218  quantum;
219 
220  quantum=pixel;
221  if (endian == LSBEndian)
222  {
223  *pixels++=(unsigned char) (quantum);
224  *pixels++=(unsigned char) (quantum >> 8);
225  return(pixels);
226  }
227  *pixels++=(unsigned char) (quantum >> 8);
228  *pixels++=(unsigned char) (quantum);
229  return(pixels);
230 }
231 
232 static inline const unsigned char *PushCharPixel(const unsigned char *pixels,
233  unsigned char *pixel)
234 {
235  *pixel=(*pixels++);
236  return(pixels);
237 }
238 
239 static inline const unsigned char *PushLongPixel(const EndianType endian,
240  const unsigned char *pixels,unsigned int *pixel)
241 {
242  register unsigned int
243  quantum;
244 
245  if (endian == LSBEndian)
246  {
247  quantum=((unsigned int) *pixels++);
248  quantum|=((unsigned int) *pixels++ << 8);
249  quantum|=((unsigned int) *pixels++ << 16);
250  quantum|=((unsigned int) *pixels++ << 24);
251  *pixel=quantum;
252  return(pixels);
253  }
254  quantum=((unsigned int) *pixels++ << 24);
255  quantum|=((unsigned int) *pixels++ << 16);
256  quantum|=((unsigned int) *pixels++ << 8);
257  quantum|=((unsigned int) *pixels++);
258  *pixel=quantum;
259  return(pixels);
260 }
261 
262 static inline const unsigned char *PushShortPixel(const EndianType endian,
263  const unsigned char *pixels,unsigned short *pixel)
264 {
265  register unsigned int
266  quantum;
267 
268  if (endian == LSBEndian)
269  {
270  quantum=(unsigned int) *pixels++;
271  quantum|=(unsigned int) (*pixels++ << 8);
272  *pixel=(unsigned short) (quantum & 0xffff);
273  return(pixels);
274  }
275  quantum=(unsigned int) (*pixels++ << 8);
276  quantum|=(unsigned int) *pixels++;
277  *pixel=(unsigned short) (quantum & 0xffff);
278  return(pixels);
279 }
280 
281 static inline Quantum ScaleAnyToQuantum(const QuantumAny quantum,
282  const QuantumAny range)
283 {
284  if (quantum > range)
285  return(QuantumRange);
286 #if !defined(MAGICKCORE_HDRI_SUPPORT)
287  return((Quantum) (((MagickRealType) QuantumRange*quantum)*
288  PerceptibleReciprocal((double) range)+0.5));
289 #else
290  return((Quantum) (((MagickRealType) QuantumRange*quantum)*
291  PerceptibleReciprocal((double) range)));
292 #endif
293 }
294 
295 static inline QuantumAny ScaleQuantumToAny(const Quantum quantum,
296  const QuantumAny range)
297 {
298  return((QuantumAny) (((MagickRealType) range*quantum)/QuantumRange+0.5));
299 }
300 
301 #if (MAGICKCORE_QUANTUM_DEPTH == 8)
302 static inline Quantum ScaleCharToQuantum(const unsigned char value)
303 {
304  return((Quantum) value);
305 }
306 
307 static inline Quantum ScaleLongToQuantum(const unsigned int value)
308 {
309 #if !defined(MAGICKCORE_HDRI_SUPPORT)
310  return((Quantum) ((value+8421504UL)/16843009UL));
311 #else
312  return((Quantum) (value/16843009.0));
313 #endif
314 }
315 
316 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
317 {
318  if (value <= 0.0)
319  return((Quantum) 0);
320  if (value >= MaxMap)
321  return(QuantumRange);
322 #if !defined(MAGICKCORE_HDRI_SUPPORT)
323  return((Quantum) (value+0.5));
324 #else
325  return((Quantum) value);
326 #endif
327 }
328 
329 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
330 {
331 #if !defined(MAGICKCORE_HDRI_SUPPORT)
332  return((unsigned int) (16843009UL*quantum));
333 #else
334  if (quantum <= 0.0)
335  return(0UL);
336  if ((16843009.0*quantum) >= 4294967295.0)
337  return(4294967295UL);
338  return((unsigned int) (16843009.0*quantum+0.5));
339 #endif
340 }
341 
342 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
343 {
344  if (quantum >= (Quantum) MaxMap)
345  return((unsigned int) MaxMap);
346 #if !defined(MAGICKCORE_HDRI_SUPPORT)
347  return((unsigned int) quantum);
348 #else
349  if (quantum < 0.0)
350  return(0UL);
351  return((unsigned int) (quantum+0.5));
352 #endif
353 }
354 
355 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
356 {
357 #if !defined(MAGICKCORE_HDRI_SUPPORT)
358  return((unsigned short) (257UL*quantum));
359 #else
360  if (quantum <= 0.0)
361  return(0);
362  if ((257.0*quantum) >= 65535.0)
363  return(65535);
364  return((unsigned short) (257.0*quantum+0.5));
365 #endif
366 }
367 
368 static inline Quantum ScaleShortToQuantum(const unsigned short value)
369 {
370 #if !defined(MAGICKCORE_HDRI_SUPPORT)
371  return((Quantum) ((value+128U)/257U));
372 #else
373  return((Quantum) (value/257.0));
374 #endif
375 }
376 #elif (MAGICKCORE_QUANTUM_DEPTH == 16)
377 static inline Quantum ScaleCharToQuantum(const unsigned char value)
378 {
379 #if !defined(MAGICKCORE_HDRI_SUPPORT)
380  return((Quantum) (257U*value));
381 #else
382  return((Quantum) (257.0*value));
383 #endif
384 }
385 
386 static inline Quantum ScaleLongToQuantum(const unsigned int value)
387 {
388 #if !defined(MAGICKCORE_HDRI_SUPPORT)
389  return((Quantum) ((value+MagickULLConstant(32768))/
390  MagickULLConstant(65537)));
391 #else
392  return((Quantum) (value/65537.0));
393 #endif
394 }
395 
396 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
397 {
398  if (value <= 0.0)
399  return((Quantum) 0);
400  if (value >= MaxMap)
401  return(QuantumRange);
402 #if !defined(MAGICKCORE_HDRI_SUPPORT)
403  return((Quantum) (value+0.5));
404 #else
405  return((Quantum) value);
406 #endif
407 }
408 
409 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
410 {
411 #if !defined(MAGICKCORE_HDRI_SUPPORT)
412  return((unsigned int) (65537UL*quantum));
413 #else
414  if (quantum <= 0.0)
415  return(0UL);
416  if ((65537.0*quantum) >= 4294967295.0)
417  return(4294967295U);
418  return((unsigned int) (65537.0*quantum+0.5));
419 #endif
420 }
421 
422 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
423 {
424  if (quantum >= (Quantum) MaxMap)
425  return((unsigned int) MaxMap);
426 #if !defined(MAGICKCORE_HDRI_SUPPORT)
427  return((unsigned int) quantum);
428 #else
429  if (quantum < 0.0)
430  return(0UL);
431  return((unsigned int) (quantum+0.5));
432 #endif
433 }
434 
435 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
436 {
437 #if !defined(MAGICKCORE_HDRI_SUPPORT)
438  return((unsigned short) quantum);
439 #else
440  if (quantum <= 0.0)
441  return(0);
442  if (quantum >= 65535.0)
443  return(65535);
444  return((unsigned short) (quantum+0.5));
445 #endif
446 }
447 
448 static inline Quantum ScaleShortToQuantum(const unsigned short value)
449 {
450  return((Quantum) value);
451 }
452 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
453 static inline Quantum ScaleCharToQuantum(const unsigned char value)
454 {
455 #if !defined(MAGICKCORE_HDRI_SUPPORT)
456  return((Quantum) (16843009UL*value));
457 #else
458  return((Quantum) (16843009.0*value));
459 #endif
460 }
461 
462 static inline Quantum ScaleLongToQuantum(const unsigned int value)
463 {
464  return((Quantum) value);
465 }
466 
467 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
468 {
469  if (value <= 0.0)
470  return((Quantum) 0);
471  if (value >= (Quantum) MaxMap)
472  return(QuantumRange);
473 #if !defined(MAGICKCORE_HDRI_SUPPORT)
474  return((Quantum) (65537.0*value+0.5));
475 #else
476  return((Quantum) (65537.0*value));
477 #endif
478 }
479 
480 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
481 {
482 #if !defined(MAGICKCORE_HDRI_SUPPORT)
483  return((unsigned int) quantum);
484 #else
485  if (quantum <= 0.0)
486  return(0);
487  if ((quantum) >= 4294967295.0)
488  return(4294967295);
489  return((unsigned int) (quantum+0.5));
490 #endif
491 }
492 
493 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
494 {
495  if (quantum < 0.0)
496  return(0UL);
497  if ((quantum/65537) >= (Quantum) MaxMap)
498  return((unsigned int) MaxMap);
499 #if !defined(MAGICKCORE_HDRI_SUPPORT)
500  return((unsigned int) ((quantum+MagickULLConstant(32768))/
501  MagickULLConstant(65537)));
502 #else
503  return((unsigned int) (quantum/65537.0+0.5));
504 #endif
505 }
506 
507 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
508 {
509 #if !defined(MAGICKCORE_HDRI_SUPPORT)
510  return((unsigned short) ((quantum+MagickULLConstant(32768))/
511  MagickULLConstant(65537)));
512 #else
513  if (quantum <= 0.0)
514  return(0);
515  if ((quantum/65537.0) >= 65535.0)
516  return(65535);
517  return((unsigned short) (quantum/65537.0+0.5));
518 #endif
519 }
520 
521 static inline Quantum ScaleShortToQuantum(const unsigned short value)
522 {
523 #if !defined(MAGICKCORE_HDRI_SUPPORT)
524  return((Quantum) (65537UL*value));
525 #else
526  return((Quantum) (65537.0*value));
527 #endif
528 }
529 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
530 static inline Quantum ScaleCharToQuantum(const unsigned char value)
531 {
532  return((Quantum) (72340172838076673.0*value));
533 }
534 
535 static inline Quantum ScaleLongToQuantum(const unsigned int value)
536 {
537  return((Quantum) (4294967297.0*value));
538 }
539 
540 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
541 {
542  if (value <= 0.0)
543  return((Quantum) 0);
544  if (value >= MaxMap)
545  return(QuantumRange);
546  return((Quantum) (281479271743489.0*value));
547 }
548 
549 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
550 {
551  return((unsigned int) (quantum/4294967297.0+0.5));
552 }
553 
554 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
555 {
556  if (quantum <= 0.0)
557  return(0UL);
558  if ((quantum/281479271743489.0) >= MaxMap)
559  return((unsigned int) MaxMap);
560  return((unsigned int) (quantum/281479271743489.0+0.5));
561 }
562 
563 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
564 {
565  if (quantum <= 0.0)
566  return(0);
567  if ((quantum/281479271743489.0) >= 65535.0)
568  return(65535);
569  return((unsigned short) (quantum/281479271743489.0+0.5));
570 }
571 
572 static inline Quantum ScaleShortToQuantum(const unsigned short value)
573 {
574  return((Quantum) (281479271743489.0*value));
575 }
576 #endif
577 
578 static inline unsigned short SinglePrecisionToHalf(const float value)
579 {
580  typedef union _SinglePrecision
581  {
582  unsigned int
583  fixed_point;
584 
585  float
586  single_precision;
587  } SinglePrecision;
588 
589  register int
590  exponent;
591 
592  register unsigned int
593  significand,
594  sign_bit;
595 
596  SinglePrecision
597  map;
598 
599  unsigned short
600  half;
601 
602  /*
603  The IEEE 754 standard specifies half precision as having:
604 
605  Sign bit: 1 bit
606  Exponent width: 5 bits
607  Significand precision: 11 (10 explicitly stored)
608  */
609  map.single_precision=value;
610  sign_bit=(map.fixed_point >> 16) & 0x00008000;
611  exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
612  significand=map.fixed_point & 0x007fffff;
613  if (exponent <= 0)
614  {
615  int
616  shift;
617 
618  if (exponent < -10)
619  return((unsigned short) sign_bit);
620  significand=significand | 0x00800000;
621  shift=(int) (14-exponent);
622  significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
623  ((significand >> shift) & 0x01)) >> shift);
624  return((unsigned short) (sign_bit | significand));
625  }
626  else
627  if (exponent == (0xff-ExponentBias))
628  {
629  if (significand == 0)
630  return((unsigned short) (sign_bit | ExponentMask));
631  else
632  {
633  significand>>=SignificandShift;
634  half=(unsigned short) (sign_bit | significand |
635  (significand == 0) | ExponentMask);
636  return(half);
637  }
638  }
639  significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
640  if ((significand & 0x00800000) != 0)
641  {
642  significand=0;
643  exponent++;
644  }
645  if (exponent > 30)
646  {
647  float
648  alpha;
649 
650  register int
651  i;
652 
653  /*
654  Float overflow.
655  */
656  alpha=1.0e10;
657  for (i=0; i < 10; i++)
658  alpha*=alpha;
659  return((unsigned short) (sign_bit | ExponentMask));
660  }
661  half=(unsigned short) (sign_bit | (exponent << 10) |
662  (significand >> SignificandShift));
663  return(half);
664 }
665 
666 #if defined(__cplusplus) || defined(c_plusplus)
667 }
668 #endif
669 
670 #endif
MagickDoubleType MagickRealType
Definition: magick-type.h:123
QuantumFormatType
Definition: quantum.h:44
QuantumFormatType format
Definition: quantum-private.h:52
static MagickSizeType GetQuantumRange(const size_t depth)
Definition: quantum-private.h:94
MemoryInfo ** pixels
Definition: quantum-private.h:73
#define ExponentMask
QuantumAlphaType alpha_type
Definition: quantum-private.h:67
size_t signature
Definition: quantum-private.h:88
#define MagickULLConstant(c)
Definition: magick-type.h:39
Definition: quantum.h:33
MagickPrivate void ResetQuantumState(QuantumInfo *)
Definition: quantum.c:578
#define SignBitShift
#define SignificandMask
QuantumState state
Definition: quantum-private.h:82
Definition: memory.c:131
EndianType
Definition: quantum.h:30
size_t quantum
Definition: quantum-private.h:48
EndianType endian
Definition: quantum-private.h:79
static const unsigned char * PushShortPixel(const EndianType endian, const unsigned char *pixels, unsigned short *pixel)
Definition: quantum-private.h:262
MagickBooleanType pack
Definition: quantum-private.h:63
static const unsigned char * PushCharPixel(const unsigned char *pixels, unsigned char *pixel)
Definition: quantum-private.h:232
MagickBooleanType
Definition: magick-type.h:189
static double PerceptibleReciprocal(const double x)
Definition: pixel-accessor.h:124
static Quantum ScaleAnyToQuantum(const QuantumAny quantum, const QuantumAny range)
Definition: quantum-private.h:281
static unsigned char * PopLongPixel(const EndianType endian, const unsigned int pixel, unsigned char *pixels)
Definition: quantum-private.h:192
unsigned int pixel
Definition: quantum-private.h:36
size_t MagickSizeType
Definition: magick-type.h:134
static const unsigned char * PushLongPixel(const EndianType endian, const unsigned char *pixels, unsigned int *pixel)
Definition: quantum-private.h:239
SemaphoreInfo * semaphore
Definition: quantum-private.h:85
#define SignificandShift
#define ExponentShift
#define MaxMap
Definition: magick-type.h:78
Definition: quantum-private.h:45
size_t pad
Definition: quantum-private.h:60
static float HalfToSinglePrecision(const unsigned short half)
Definition: quantum-private.h:110
size_t number_threads
Definition: quantum-private.h:70
double scale
Definition: quantum-private.h:55
const unsigned int * mask
Definition: quantum-private.h:42
unsigned short Quantum
Definition: magick-type.h:85
#define ExponentBias
size_t bits
Definition: quantum-private.h:39
size_t extent
Definition: quantum-private.h:76
static unsigned char * PopCharPixel(const unsigned char pixel, unsigned char *pixels)
Definition: quantum-private.h:185
static unsigned char * PopShortPixel(const EndianType endian, const unsigned short pixel, unsigned char *pixels)
Definition: quantum-private.h:214
#define MagickMin(x, y)
Definition: image-private.h:27
double inverse_scale
Definition: quantum-private.h:33
static unsigned short SinglePrecisionToHalf(const float value)
Definition: quantum-private.h:578
#define MagickPrivate
Definition: method-attribute.h:99
struct _QuantumState QuantumState
static QuantumAny ScaleQuantumToAny(const Quantum quantum, const QuantumAny range)
Definition: quantum-private.h:295
Definition: quantum-private.h:30
MagickSizeType QuantumAny
Definition: magick-type.h:148
QuantumAlphaType
Definition: quantum.h:37
Definition: semaphore.c:59
#define QuantumRange
Definition: magick-type.h:86