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