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