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 *magick_restrict 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 *magick_restrict 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 *magick_restrict 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(
00233 const unsigned char *magick_restrict pixels,
00234 unsigned char *magick_restrict pixel)
00235 {
00236 *pixel=(*pixels++);
00237 return(pixels);
00238 }
00239
00240 static inline const unsigned char *PushLongPixel(const EndianType endian,
00241 const unsigned char *magick_restrict pixels,
00242 unsigned int *magick_restrict pixel)
00243 {
00244 register unsigned int
00245 quantum;
00246
00247 if (endian == LSBEndian)
00248 {
00249 quantum=((unsigned int) *pixels++);
00250 quantum|=((unsigned int) *pixels++ << 8);
00251 quantum|=((unsigned int) *pixels++ << 16);
00252 quantum|=((unsigned int) *pixels++ << 24);
00253 *pixel=quantum;
00254 return(pixels);
00255 }
00256 quantum=((unsigned int) *pixels++ << 24);
00257 quantum|=((unsigned int) *pixels++ << 16);
00258 quantum|=((unsigned int) *pixels++ << 8);
00259 quantum|=((unsigned int) *pixels++);
00260 *pixel=quantum;
00261 return(pixels);
00262 }
00263
00264 static inline const unsigned char *PushShortPixel(const EndianType endian,
00265 const unsigned char *magick_restrict pixels,
00266 unsigned short *magick_restrict pixel)
00267 {
00268 register unsigned int
00269 quantum;
00270
00271 if (endian == LSBEndian)
00272 {
00273 quantum=(unsigned int) *pixels++;
00274 quantum|=(unsigned int) (*pixels++ << 8);
00275 *pixel=(unsigned short) (quantum & 0xffff);
00276 return(pixels);
00277 }
00278 quantum=(unsigned int) (*pixels++ << 8);
00279 quantum|=(unsigned int) *pixels++;
00280 *pixel=(unsigned short) (quantum & 0xffff);
00281 return(pixels);
00282 }
00283
00284 static inline const unsigned char *PushFloatPixel(const EndianType endian,
00285 const unsigned char *magick_restrict pixels,
00286 MagickFloatType *magick_restrict pixel)
00287 {
00288 union
00289 {
00290 unsigned int
00291 unsigned_value;
00292
00293 MagickFloatType
00294 float_value;
00295 } quantum;
00296
00297 if (endian == LSBEndian)
00298 {
00299 quantum.unsigned_value=((unsigned int) *pixels++);
00300 quantum.unsigned_value|=((unsigned int) *pixels++ << 8);
00301 quantum.unsigned_value|=((unsigned int) *pixels++ << 16);
00302 quantum.unsigned_value|=((unsigned int) *pixels++ << 24);
00303 *pixel=quantum.float_value;
00304 return(pixels);
00305 }
00306 quantum.unsigned_value=((unsigned int) *pixels++ << 24);
00307 quantum.unsigned_value|=((unsigned int) *pixels++ << 16);
00308 quantum.unsigned_value|=((unsigned int) *pixels++ << 8);
00309 quantum.unsigned_value|=((unsigned int) *pixels++);
00310 *pixel=quantum.float_value;
00311 return(pixels);
00312 }
00313
00314 static inline Quantum ScaleAnyToQuantum(const QuantumAny quantum,
00315 const QuantumAny range)
00316 {
00317 if (quantum > range)
00318 return(QuantumRange);
00319 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00320 return((Quantum) ((double) QuantumRange*(quantum*
00321 PerceptibleReciprocal((double) range))+0.5));
00322 #else
00323 return((Quantum) ((double) QuantumRange*(quantum*
00324 PerceptibleReciprocal((double) range))));
00325 #endif
00326 }
00327
00328 static inline QuantumAny ScaleQuantumToAny(const Quantum quantum,
00329 const QuantumAny range)
00330 {
00331 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00332 return((QuantumAny) ((MagickRealType) range*quantum/QuantumRange));
00333 #else
00334 if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00335 return((QuantumAny) 0UL);
00336 if (((MagickRealType) range*quantum/QuantumRange) >= 18446744073709551615.0)
00337 return((QuantumAny) MagickULLConstant(18446744073709551615));
00338 return((QuantumAny) ((MagickRealType) range*quantum/QuantumRange+0.5));
00339 #endif
00340 }
00341
00342 #if (MAGICKCORE_QUANTUM_DEPTH == 8)
00343 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00344 {
00345 return((Quantum) value);
00346 }
00347
00348 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00349 {
00350 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00351 return((Quantum) ((value)/16843009UL));
00352 #else
00353 return((Quantum) (value/16843009.0));
00354 #endif
00355 }
00356
00357 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00358 {
00359 if (value <= 0.0)
00360 return((Quantum) 0);
00361 if (value >= MaxMap)
00362 return(QuantumRange);
00363 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00364 return((Quantum) (value+0.5));
00365 #else
00366 return((Quantum) value);
00367 #endif
00368 }
00369
00370 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00371 {
00372 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00373 return((unsigned int) (16843009UL*quantum));
00374 #else
00375 if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00376 return(0U);
00377 if ((16843009.0*quantum) >= 4294967295.0)
00378 return(4294967295UL);
00379 return((unsigned int) (16843009.0*quantum+0.5));
00380 #endif
00381 }
00382
00383 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00384 {
00385 if (quantum >= (Quantum) MaxMap)
00386 return((unsigned int) MaxMap);
00387 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00388 return((unsigned int) quantum);
00389 #else
00390 if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00391 return(0U);
00392 return((unsigned int) (quantum+0.5));
00393 #endif
00394 }
00395
00396 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00397 {
00398 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00399 return((unsigned short) (257UL*quantum));
00400 #else
00401 if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00402 return(0);
00403 if ((257.0*quantum) >= 65535.0)
00404 return(65535);
00405 return((unsigned short) (257.0*quantum+0.5));
00406 #endif
00407 }
00408
00409 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00410 {
00411 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00412 return((Quantum) ((value+128U)/257U));
00413 #else
00414 return((Quantum) (value/257.0));
00415 #endif
00416 }
00417 #elif (MAGICKCORE_QUANTUM_DEPTH == 16)
00418 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00419 {
00420 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00421 return((Quantum) (257U*value));
00422 #else
00423 return((Quantum) (257.0*value));
00424 #endif
00425 }
00426
00427 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00428 {
00429 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00430 return((Quantum) ((value)/MagickULLConstant(65537)));
00431 #else
00432 return((Quantum) (value/65537.0));
00433 #endif
00434 }
00435
00436 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00437 {
00438 if (value <= 0.0)
00439 return((Quantum) 0);
00440 if (value >= MaxMap)
00441 return(QuantumRange);
00442 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00443 return((Quantum) (value+0.5));
00444 #else
00445 return((Quantum) value);
00446 #endif
00447 }
00448
00449 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00450 {
00451 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00452 return((unsigned int) (65537UL*quantum));
00453 #else
00454 if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00455 return(0U);
00456 if ((65537.0*quantum) >= 4294967295.0)
00457 return(4294967295U);
00458 return((unsigned int) (65537.0*quantum+0.5));
00459 #endif
00460 }
00461
00462 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00463 {
00464 if (quantum >= (Quantum) MaxMap)
00465 return((unsigned int) MaxMap);
00466 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00467 return((unsigned int) quantum);
00468 #else
00469 if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00470 return(0U);
00471 return((unsigned int) (quantum+0.5));
00472 #endif
00473 }
00474
00475 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00476 {
00477 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00478 return((unsigned short) quantum);
00479 #else
00480 if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00481 return(0);
00482 if (quantum >= 65535.0)
00483 return(65535);
00484 return((unsigned short) (quantum+0.5));
00485 #endif
00486 }
00487
00488 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00489 {
00490 return((Quantum) value);
00491 }
00492 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
00493 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00494 {
00495 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00496 return((Quantum) (16843009UL*value));
00497 #else
00498 return((Quantum) (16843009.0*value));
00499 #endif
00500 }
00501
00502 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00503 {
00504 return((Quantum) value);
00505 }
00506
00507 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00508 {
00509 if (value <= 0.0)
00510 return((Quantum) 0);
00511 if (value >= (Quantum) MaxMap)
00512 return(QuantumRange);
00513 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00514 return((Quantum) (65537.0*value+0.5));
00515 #else
00516 return((Quantum) (65537.0*value));
00517 #endif
00518 }
00519
00520 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00521 {
00522 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00523 return((unsigned int) quantum);
00524 #else
00525 if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00526 return(0U);
00527 if ((quantum) >= 4294967295.0)
00528 return(4294967295);
00529 return((unsigned int) (quantum+0.5));
00530 #endif
00531 }
00532
00533 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00534 {
00535 if ((quantum/65537) >= (Quantum) MaxMap)
00536 return((unsigned int) MaxMap);
00537 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00538 return((unsigned int) ((quantum+MagickULLConstant(32768))/
00539 MagickULLConstant(65537)));
00540 #else
00541 if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00542 return(0U);
00543 return((unsigned int) (quantum/65537.0+0.5));
00544 #endif
00545 }
00546
00547 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00548 {
00549 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00550 return((unsigned short) ((quantum+MagickULLConstant(32768))/
00551 MagickULLConstant(65537)));
00552 #else
00553 if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00554 return(0);
00555 if ((quantum/65537.0) >= 65535.0)
00556 return(65535);
00557 return((unsigned short) (quantum/65537.0+0.5));
00558 #endif
00559 }
00560
00561 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00562 {
00563 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00564 return((Quantum) (65537UL*value));
00565 #else
00566 return((Quantum) (65537.0*value));
00567 #endif
00568 }
00569 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
00570 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00571 {
00572 return((Quantum) (72340172838076673.0*value));
00573 }
00574
00575 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00576 {
00577 return((Quantum) (4294967297.0*value));
00578 }
00579
00580 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00581 {
00582 if (value <= 0.0)
00583 return((Quantum) 0);
00584 if (value >= MaxMap)
00585 return(QuantumRange);
00586 return((Quantum) (281479271743489.0*value));
00587 }
00588
00589 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00590 {
00591 return((unsigned int) (quantum/4294967297.0+0.5));
00592 }
00593
00594 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00595 {
00596 if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00597 return(0U);
00598 if ((quantum/281479271743489.0) >= MaxMap)
00599 return((unsigned int) MaxMap);
00600 return((unsigned int) (quantum/281479271743489.0+0.5));
00601 }
00602
00603 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00604 {
00605 if ((IsNaN(quantum) != MagickFalse) || (quantum <= 0.0))
00606 return(0);
00607 if ((quantum/281479271743489.0) >= 65535.0)
00608 return(65535);
00609 return((unsigned short) (quantum/281479271743489.0+0.5));
00610 }
00611
00612 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00613 {
00614 return((Quantum) (281479271743489.0*value));
00615 }
00616 #endif
00617
00618 static inline unsigned short SinglePrecisionToHalf(const float value)
00619 {
00620 typedef union _SinglePrecision
00621 {
00622 unsigned int
00623 fixed_point;
00624
00625 float
00626 single_precision;
00627 } SinglePrecision;
00628
00629 register int
00630 exponent;
00631
00632 register unsigned int
00633 significand,
00634 sign_bit;
00635
00636 SinglePrecision
00637 map;
00638
00639 unsigned short
00640 half;
00641
00642
00643
00644
00645
00646
00647
00648
00649 map.single_precision=value;
00650 sign_bit=(map.fixed_point >> 16) & 0x00008000;
00651 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
00652 significand=map.fixed_point & 0x007fffff;
00653 if (exponent <= 0)
00654 {
00655 int
00656 shift;
00657
00658 if (exponent < -10)
00659 return((unsigned short) sign_bit);
00660 significand=significand | 0x00800000;
00661 shift=(int) (14-exponent);
00662 significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
00663 ((significand >> shift) & 0x01)) >> shift);
00664 return((unsigned short) (sign_bit | significand));
00665 }
00666 else
00667 if (exponent == (0xff-ExponentBias))
00668 {
00669 if (significand == 0)
00670 return((unsigned short) (sign_bit | ExponentMask));
00671 else
00672 {
00673 significand>>=SignificandShift;
00674 half=(unsigned short) (sign_bit | significand |
00675 (significand == 0) | ExponentMask);
00676 return(half);
00677 }
00678 }
00679 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
00680 if ((significand & 0x00800000) != 0)
00681 {
00682 significand=0;
00683 exponent++;
00684 }
00685 if (exponent > 30)
00686 {
00687 float
00688 alpha;
00689
00690 register int
00691 i;
00692
00693
00694
00695
00696 alpha=1.0e10;
00697 for (i=0; i < 10; i++)
00698 alpha*=alpha;
00699 return((unsigned short) (sign_bit | ExponentMask));
00700 }
00701 half=(unsigned short) (sign_bit | (exponent << 10) |
00702 (significand >> SignificandShift));
00703 return(half);
00704 }
00705
00706 #if defined(__cplusplus) || defined(c_plusplus)
00707 }
00708 #endif
00709
00710 #endif