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