quantum-private.h

Go to the documentation of this file.
00001 /*
00002   Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization
00003   dedicated to making software imaging solutions freely available.
00004 
00005   You may not use this file except in compliance with the License.  You may
00006   obtain a copy of the License at
00007 
00008     https://imagemagick.org/script/license.php
00009 
00010   Unless required by applicable law or agreed to in writing, software
00011   distributed under the License is distributed on an "AS IS" BASIS,
00012   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013   See the License for the specific language governing permissions and
00014   limitations under the License.
00015 
00016   MagickCore quantum inline methods.
00017 */
00018 #ifndef MAGICKCORE_QUANTUM_PRIVATE_H
00019 #define MAGICKCORE_QUANTUM_PRIVATE_H
00020 
00021 #include "magick/memory_.h"
00022 #include "magick/cache.h"
00023 #include "magick/image-private.h"
00024 #include "magick/pixel-accessor.h"
00025 
00026 #if defined(__cplusplus) || defined(c_plusplus)
00027 extern "C" {
00028 #endif
00029 
00030 typedef struct _QuantumState
00031 {
00032   double
00033     inverse_scale;
00034 
00035   unsigned int
00036     pixel;
00037 
00038   size_t
00039     bits;
00040 
00041   const unsigned int
00042     *mask;
00043 } QuantumState;
00044 
00045 struct _QuantumInfo
00046 {
00047   size_t
00048     depth,
00049     quantum;
00050 
00051   QuantumFormatType
00052     format;
00053 
00054   double
00055     minimum,
00056     maximum,
00057     scale;
00058 
00059   size_t
00060     pad;
00061 
00062   MagickBooleanType
00063     min_is_white,
00064     pack;
00065 
00066   QuantumAlphaType
00067     alpha_type;
00068 
00069   size_t
00070     number_threads;
00071 
00072   MemoryInfo
00073     **pixels;
00074 
00075   size_t
00076     extent;
00077 
00078   EndianType
00079     endian;
00080 
00081   QuantumState
00082     state;
00083 
00084   SemaphoreInfo
00085     *semaphore;
00086 
00087   size_t
00088     signature;
00089 };
00090 
00091 extern MagickPrivate void
00092   ResetQuantumState(QuantumInfo *);
00093 
00094 static inline MagickSizeType GetQuantumRange(const size_t depth)
00095 {
00096   MagickSizeType
00097     one;
00098 
00099   size_t
00100     max_depth;
00101 
00102   if (depth == 0)
00103     return(0);
00104   one=1;
00105   max_depth=8*sizeof(MagickSizeType);
00106   return((MagickSizeType) ((one << (MagickMin(depth,max_depth)-1))+
00107     ((one << (MagickMin(depth,max_depth)-1))-1)));
00108 }
00109 
00110 static inline float HalfToSinglePrecision(const unsigned short half)
00111 {
00112 #define ExponentBias  (127-15)
00113 #define ExponentMask  0x7c00
00114 #define ExponentShift  23
00115 #define SignBitShift  31
00116 #define SignificandShift  13
00117 #define SignificandMask  0x00000400
00118 
00119   typedef union _SinglePrecision
00120   {
00121     unsigned int
00122       fixed_point;
00123 
00124     float
00125       single_precision;
00126   } SinglePrecision;
00127 
00128   register unsigned int
00129     exponent,
00130     significand,
00131     sign_bit;
00132 
00133   SinglePrecision
00134     map;
00135 
00136   unsigned int
00137     value;
00138 
00139   /*
00140     The IEEE 754 standard specifies half precision as having:
00141 
00142       Sign bit: 1 bit
00143       Exponent width: 5 bits
00144       Significand precision: 11 (10 explicitly stored)
00145   */
00146   sign_bit=(unsigned int) ((half >> 15) & 0x00000001);
00147   exponent=(unsigned int) ((half >> 10) & 0x0000001f);
00148   significand=(unsigned int) (half & 0x000003ff);
00149   if (exponent == 0)
00150     {
00151       if (significand == 0)
00152         value=sign_bit << SignBitShift;
00153       else
00154         {
00155           while ((significand & SignificandMask) == 0)
00156           {
00157             significand<<=1;
00158             exponent--;
00159           }
00160           exponent++;
00161           significand&=(~SignificandMask);
00162           exponent+=ExponentBias;
00163           value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
00164             (significand << SignificandShift);
00165         }
00166     }
00167   else
00168     if (exponent == SignBitShift)
00169       {
00170         value=(sign_bit << SignBitShift) | 0x7f800000;
00171         if (significand != 0)
00172           value|=(significand << SignificandShift);
00173       }
00174     else
00175       {
00176         exponent+=ExponentBias;
00177         significand<<=SignificandShift;
00178         value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
00179           significand;
00180       }
00181   map.fixed_point=value;
00182   return(map.single_precision);
00183 }
00184 
00185 static inline unsigned char *PopCharPixel(const unsigned char pixel,
00186   unsigned char *pixels)
00187 {
00188   *pixels++=pixel;
00189   return(pixels);
00190 }
00191 
00192 static inline unsigned char *PopLongPixel(const EndianType endian,
00193   const unsigned int pixel,unsigned char *pixels)
00194 {
00195   register unsigned int
00196     quantum;
00197 
00198   quantum=(unsigned int) pixel;
00199   if (endian == LSBEndian)
00200     {
00201       *pixels++=(unsigned char) (quantum);
00202       *pixels++=(unsigned char) (quantum >> 8);
00203       *pixels++=(unsigned char) (quantum >> 16);
00204       *pixels++=(unsigned char) (quantum >> 24);
00205       return(pixels);
00206     }
00207   *pixels++=(unsigned char) (quantum >> 24);
00208   *pixels++=(unsigned char) (quantum >> 16);
00209   *pixels++=(unsigned char) (quantum >> 8);
00210   *pixels++=(unsigned char) (quantum);
00211   return(pixels);
00212 }
00213 
00214 static inline unsigned char *PopShortPixel(const EndianType endian,
00215   const unsigned short pixel,unsigned char *pixels)
00216 {
00217   register unsigned int
00218     quantum;
00219 
00220   quantum=pixel;
00221   if (endian == LSBEndian)
00222     {
00223       *pixels++=(unsigned char) (quantum);
00224       *pixels++=(unsigned char) (quantum >> 8);
00225       return(pixels);
00226     }
00227   *pixels++=(unsigned char) (quantum >> 8);
00228   *pixels++=(unsigned char) (quantum);
00229   return(pixels);
00230 }
00231 
00232 static inline const unsigned char *PushCharPixel(const unsigned char *pixels,
00233   unsigned char *pixel)
00234 {
00235   *pixel=(*pixels++);
00236   return(pixels);
00237 }
00238 
00239 static inline const unsigned char *PushLongPixel(const EndianType endian,
00240   const unsigned char *pixels,unsigned int *pixel)
00241 {
00242   register unsigned int
00243     quantum;
00244 
00245   if (endian == LSBEndian)
00246     {
00247       quantum=((unsigned int) *pixels++);
00248       quantum|=((unsigned int) *pixels++ << 8);
00249       quantum|=((unsigned int) *pixels++ << 16);
00250       quantum|=((unsigned int) *pixels++ << 24);
00251       *pixel=quantum;
00252       return(pixels);
00253     }
00254   quantum=((unsigned int) *pixels++ << 24);
00255   quantum|=((unsigned int) *pixels++ << 16);
00256   quantum|=((unsigned int) *pixels++ << 8);
00257   quantum|=((unsigned int) *pixels++);
00258   *pixel=quantum;
00259   return(pixels);
00260 }
00261 
00262 static inline const unsigned char *PushShortPixel(const EndianType endian,
00263   const unsigned char *pixels,unsigned short *pixel)
00264 {
00265   register unsigned int
00266     quantum;
00267 
00268   if (endian == LSBEndian)
00269     {
00270       quantum=(unsigned int) *pixels++;
00271       quantum|=(unsigned int) (*pixels++ << 8);
00272       *pixel=(unsigned short) (quantum & 0xffff);
00273       return(pixels);
00274     }
00275   quantum=(unsigned int) (*pixels++ << 8);
00276   quantum|=(unsigned int) *pixels++;
00277   *pixel=(unsigned short) (quantum & 0xffff);
00278   return(pixels);
00279 }
00280 
00281 static inline const unsigned char *PushFloatPixel(const EndianType endian,
00282   const unsigned char *pixels,MagickFloatType *pixel)
00283 {
00284   union
00285   {
00286     unsigned int
00287       unsigned_value;
00288 
00289     MagickFloatType
00290       float_value;
00291   } quantum;
00292 
00293   if (endian == LSBEndian)
00294     {
00295       quantum.unsigned_value=((unsigned int) *pixels++);
00296       quantum.unsigned_value|=((unsigned int) *pixels++ << 8);
00297       quantum.unsigned_value|=((unsigned int) *pixels++ << 16);
00298       quantum.unsigned_value|=((unsigned int) *pixels++ << 24);
00299       *pixel=quantum.float_value;
00300       return(pixels);
00301     }
00302   quantum.unsigned_value=((unsigned int) *pixels++ << 24);
00303   quantum.unsigned_value|=((unsigned int) *pixels++ << 16);
00304   quantum.unsigned_value|=((unsigned int) *pixels++ << 8);
00305   quantum.unsigned_value|=((unsigned int) *pixels++);
00306   *pixel=quantum.float_value;
00307   return(pixels);
00308 }
00309 
00310 static inline Quantum ScaleAnyToQuantum(const QuantumAny quantum,
00311   const QuantumAny range)
00312 {
00313   if (quantum > range)
00314     return(QuantumRange);
00315 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00316   return((Quantum) (((MagickRealType) QuantumRange*quantum)*
00317     PerceptibleReciprocal((double) range)+0.5));
00318 #else
00319   return((Quantum) (((MagickRealType) QuantumRange*quantum)*
00320     PerceptibleReciprocal((double) range)));
00321 #endif
00322 }
00323 
00324 static inline QuantumAny ScaleQuantumToAny(const Quantum quantum,
00325   const QuantumAny range)
00326 {
00327 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00328   return((QuantumAny) ((MagickRealType) range*quantum/QuantumRange));
00329 #else
00330   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00331     return((QuantumAny) 0UL);
00332   if (((MagickRealType) range*quantum/QuantumRange) >= 18446744073709551615.0)
00333     return((QuantumAny) MagickULLConstant(18446744073709551615));
00334   return((QuantumAny) ((MagickRealType) range*quantum/QuantumRange+0.5));
00335 #endif
00336 }
00337 
00338 #if (MAGICKCORE_QUANTUM_DEPTH == 8)
00339 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00340 {
00341   return((Quantum) value);
00342 }
00343 
00344 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00345 {
00346 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00347   return((Quantum) ((value)/16843009UL));
00348 #else
00349   return((Quantum) (value/16843009.0));
00350 #endif
00351 }
00352 
00353 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00354 {
00355   if (value <= 0.0)
00356     return((Quantum) 0);
00357   if (value >= MaxMap)
00358     return(QuantumRange);
00359 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00360   return((Quantum) (value+0.5));
00361 #else
00362   return((Quantum) value);
00363 #endif
00364 }
00365 
00366 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00367 {
00368 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00369   return((unsigned int) (16843009UL*quantum));
00370 #else
00371   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00372     return(0U);
00373   if ((16843009.0*quantum) >= 4294967295.0)
00374     return(4294967295UL);
00375   return((unsigned int) (16843009.0*quantum+0.5));
00376 #endif
00377 }
00378 
00379 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00380 {
00381   if (quantum >= (Quantum) MaxMap)
00382     return((unsigned int) MaxMap);
00383 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00384   return((unsigned int) quantum);
00385 #else
00386   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00387     return(0U);
00388   return((unsigned int) (quantum+0.5));
00389 #endif
00390 }
00391 
00392 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00393 {
00394 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00395   return((unsigned short) (257UL*quantum));
00396 #else
00397   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00398     return(0);
00399   if ((257.0*quantum) >= 65535.0)
00400     return(65535);
00401   return((unsigned short) (257.0*quantum+0.5));
00402 #endif
00403 }
00404 
00405 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00406 {
00407 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00408   return((Quantum) ((value+128U)/257U));
00409 #else
00410   return((Quantum) (value/257.0));
00411 #endif
00412 }
00413 #elif (MAGICKCORE_QUANTUM_DEPTH == 16)
00414 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00415 {
00416 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00417   return((Quantum) (257U*value));
00418 #else
00419   return((Quantum) (257.0*value));
00420 #endif
00421 }
00422 
00423 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00424 {
00425 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00426   return((Quantum) ((value)/MagickULLConstant(65537)));
00427 #else
00428   return((Quantum) (value/65537.0));
00429 #endif
00430 }
00431 
00432 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00433 {
00434   if (value <= 0.0)
00435     return((Quantum) 0);
00436   if (value >= MaxMap)
00437     return(QuantumRange);
00438 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00439   return((Quantum) (value+0.5));
00440 #else
00441   return((Quantum) value);
00442 #endif
00443 }
00444 
00445 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00446 {
00447 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00448   return((unsigned int) (65537UL*quantum));
00449 #else
00450   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00451     return(0U);
00452   if ((65537.0*quantum) >= 4294967295.0)
00453     return(4294967295U);
00454   return((unsigned int) (65537.0*quantum+0.5));
00455 #endif
00456 }
00457 
00458 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00459 {
00460   if (quantum >= (Quantum) MaxMap)
00461     return((unsigned int) MaxMap);
00462 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00463   return((unsigned int) quantum);
00464 #else
00465   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00466     return(0U);
00467   return((unsigned int) (quantum+0.5));
00468 #endif
00469 }
00470 
00471 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00472 {
00473 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00474   return((unsigned short) quantum);
00475 #else
00476   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00477     return(0);
00478   if (quantum >= 65535.0)
00479     return(65535);
00480   return((unsigned short) (quantum+0.5));
00481 #endif
00482 }
00483 
00484 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00485 {
00486   return((Quantum) value);
00487 }
00488 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
00489 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00490 {
00491 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00492   return((Quantum) (16843009UL*value));
00493 #else
00494   return((Quantum) (16843009.0*value));
00495 #endif
00496 }
00497 
00498 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00499 {
00500   return((Quantum) value);
00501 }
00502 
00503 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00504 {
00505   if (value <= 0.0)
00506     return((Quantum) 0);
00507   if (value >= (Quantum) MaxMap)
00508     return(QuantumRange);
00509 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00510   return((Quantum) (65537.0*value+0.5));
00511 #else
00512   return((Quantum) (65537.0*value));
00513 #endif
00514 }
00515 
00516 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00517 {
00518 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00519   return((unsigned int) quantum);
00520 #else
00521   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00522     return(0U);
00523   if ((quantum) >= 4294967295.0)
00524     return(4294967295);
00525   return((unsigned int) (quantum+0.5));
00526 #endif
00527 }
00528 
00529 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00530 {
00531   if ((quantum/65537) >= (Quantum) MaxMap)
00532     return((unsigned int) MaxMap);
00533 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00534   return((unsigned int) ((quantum+MagickULLConstant(32768))/
00535     MagickULLConstant(65537)));
00536 #else
00537   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00538     return(0U);
00539   return((unsigned int) (quantum/65537.0+0.5));
00540 #endif
00541 }
00542 
00543 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00544 {
00545 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00546   return((unsigned short) ((quantum+MagickULLConstant(32768))/
00547     MagickULLConstant(65537)));
00548 #else
00549   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00550     return(0);
00551   if ((quantum/65537.0) >= 65535.0)
00552     return(65535);
00553   return((unsigned short) (quantum/65537.0+0.5));
00554 #endif
00555 }
00556 
00557 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00558 {
00559 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00560   return((Quantum) (65537UL*value));
00561 #else
00562   return((Quantum) (65537.0*value));
00563 #endif
00564 }
00565 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
00566 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00567 {
00568   return((Quantum) (72340172838076673.0*value));
00569 }
00570 
00571 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00572 {
00573   return((Quantum) (4294967297.0*value));
00574 }
00575 
00576 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00577 {
00578   if (value <= 0.0)
00579     return((Quantum) 0);
00580   if (value >= MaxMap)
00581     return(QuantumRange);
00582   return((Quantum) (281479271743489.0*value));
00583 }
00584 
00585 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00586 {
00587   return((unsigned int) (quantum/4294967297.0+0.5));
00588 }
00589 
00590 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00591 {
00592   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00593     return(0U);
00594   if ((quantum/281479271743489.0) >= MaxMap)
00595     return((unsigned int) MaxMap);
00596   return((unsigned int) (quantum/281479271743489.0+0.5));
00597 }
00598 
00599 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00600 {
00601   if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00602     return(0);
00603   if ((quantum/281479271743489.0) >= 65535.0)
00604     return(65535);
00605   return((unsigned short) (quantum/281479271743489.0+0.5));
00606 }
00607 
00608 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00609 {
00610   return((Quantum) (281479271743489.0*value));
00611 }
00612 #endif
00613 
00614 static inline unsigned short SinglePrecisionToHalf(const float value)
00615 {
00616   typedef union _SinglePrecision
00617   {
00618     unsigned int
00619       fixed_point;
00620 
00621     float
00622       single_precision;
00623   } SinglePrecision;
00624 
00625   register int
00626     exponent;
00627 
00628   register unsigned int
00629     significand,
00630     sign_bit;
00631 
00632   SinglePrecision
00633     map;
00634 
00635   unsigned short
00636     half;
00637 
00638   /*
00639     The IEEE 754 standard specifies half precision as having:
00640 
00641       Sign bit: 1 bit
00642       Exponent width: 5 bits
00643       Significand precision: 11 (10 explicitly stored)
00644   */
00645   map.single_precision=value;
00646   sign_bit=(map.fixed_point >> 16) & 0x00008000;
00647   exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
00648   significand=map.fixed_point & 0x007fffff;
00649   if (exponent <= 0)
00650     {
00651       int
00652         shift;
00653 
00654       if (exponent < -10)
00655         return((unsigned short) sign_bit);
00656       significand=significand | 0x00800000;
00657       shift=(int) (14-exponent);
00658       significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
00659         ((significand >> shift) & 0x01)) >> shift);
00660       return((unsigned short) (sign_bit | significand));
00661     }
00662   else
00663     if (exponent == (0xff-ExponentBias))
00664       {
00665         if (significand == 0)
00666           return((unsigned short) (sign_bit | ExponentMask));
00667         else
00668           {
00669             significand>>=SignificandShift;
00670             half=(unsigned short) (sign_bit | significand |
00671               (significand == 0) | ExponentMask);
00672             return(half);
00673           }
00674       }
00675   significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
00676   if ((significand & 0x00800000) != 0)
00677     {
00678       significand=0;
00679       exponent++;
00680     }
00681   if (exponent > 30)
00682     {
00683       float
00684         alpha;
00685 
00686       register int
00687         i;
00688 
00689       /*
00690         Float overflow.
00691       */
00692       alpha=1.0e10;
00693       for (i=0; i < 10; i++)
00694         alpha*=alpha;
00695       return((unsigned short) (sign_bit | ExponentMask));
00696     }
00697   half=(unsigned short) (sign_bit | (exponent << 10) |
00698     (significand >> SignificandShift));
00699   return(half);
00700 }
00701 
00702 #if defined(__cplusplus) || defined(c_plusplus)
00703 }
00704 #endif
00705 
00706 #endif

Generated on 31 Oct 2019 for MagickCore by  doxygen 1.6.1