00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00141
00142
00143
00144
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
00640
00641
00642
00643
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
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