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