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