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 (quantum < 0)
00328 return((QuantumAny) 0);
00329 return((QuantumAny) (((MagickRealType) range*quantum)/QuantumRange+0.5));
00330 }
00331
00332 #if (MAGICKCORE_QUANTUM_DEPTH == 8)
00333 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00334 {
00335 return((Quantum) value);
00336 }
00337
00338 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00339 {
00340 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00341 return((Quantum) ((value)/16843009UL));
00342 #else
00343 return((Quantum) (value/16843009.0));
00344 #endif
00345 }
00346
00347 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00348 {
00349 if (value <= 0.0)
00350 return((Quantum) 0);
00351 if (value >= MaxMap)
00352 return(QuantumRange);
00353 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00354 return((Quantum) (value+0.5));
00355 #else
00356 return((Quantum) value);
00357 #endif
00358 }
00359
00360 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00361 {
00362 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00363 return((unsigned int) (16843009UL*quantum));
00364 #else
00365 if (quantum <= 0.0)
00366 return(0UL);
00367 if ((16843009.0*quantum) >= 4294967295.0)
00368 return(4294967295UL);
00369 return((unsigned int) (16843009.0*quantum+0.5));
00370 #endif
00371 }
00372
00373 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00374 {
00375 if (quantum >= (Quantum) MaxMap)
00376 return((unsigned int) MaxMap);
00377 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00378 return((unsigned int) quantum);
00379 #else
00380 if (quantum < 0.0)
00381 return(0UL);
00382 return((unsigned int) (quantum+0.5));
00383 #endif
00384 }
00385
00386 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00387 {
00388 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00389 return((unsigned short) (257UL*quantum));
00390 #else
00391 if (quantum <= 0.0)
00392 return(0);
00393 if ((257.0*quantum) >= 65535.0)
00394 return(65535);
00395 return((unsigned short) (257.0*quantum+0.5));
00396 #endif
00397 }
00398
00399 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00400 {
00401 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00402 return((Quantum) ((value+128U)/257U));
00403 #else
00404 return((Quantum) (value/257.0));
00405 #endif
00406 }
00407 #elif (MAGICKCORE_QUANTUM_DEPTH == 16)
00408 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00409 {
00410 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00411 return((Quantum) (257U*value));
00412 #else
00413 return((Quantum) (257.0*value));
00414 #endif
00415 }
00416
00417 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00418 {
00419 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00420 return((Quantum) ((value)/MagickULLConstant(65537)));
00421 #else
00422 return((Quantum) (value/65537.0));
00423 #endif
00424 }
00425
00426 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00427 {
00428 if (value <= 0.0)
00429 return((Quantum) 0);
00430 if (value >= MaxMap)
00431 return(QuantumRange);
00432 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00433 return((Quantum) (value+0.5));
00434 #else
00435 return((Quantum) value);
00436 #endif
00437 }
00438
00439 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00440 {
00441 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00442 return((unsigned int) (65537UL*quantum));
00443 #else
00444 if (quantum <= 0.0)
00445 return(0UL);
00446 if ((65537.0*quantum) >= 4294967295.0)
00447 return(4294967295U);
00448 return((unsigned int) (65537.0*quantum+0.5));
00449 #endif
00450 }
00451
00452 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00453 {
00454 if (quantum >= (Quantum) MaxMap)
00455 return((unsigned int) MaxMap);
00456 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00457 return((unsigned int) quantum);
00458 #else
00459 if (quantum < 0.0)
00460 return(0UL);
00461 return((unsigned int) (quantum+0.5));
00462 #endif
00463 }
00464
00465 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00466 {
00467 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00468 return((unsigned short) quantum);
00469 #else
00470 if (quantum <= 0.0)
00471 return(0);
00472 if (quantum >= 65535.0)
00473 return(65535);
00474 return((unsigned short) (quantum+0.5));
00475 #endif
00476 }
00477
00478 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00479 {
00480 return((Quantum) value);
00481 }
00482 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
00483 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00484 {
00485 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00486 return((Quantum) (16843009UL*value));
00487 #else
00488 return((Quantum) (16843009.0*value));
00489 #endif
00490 }
00491
00492 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00493 {
00494 return((Quantum) value);
00495 }
00496
00497 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00498 {
00499 if (value <= 0.0)
00500 return((Quantum) 0);
00501 if (value >= (Quantum) MaxMap)
00502 return(QuantumRange);
00503 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00504 return((Quantum) (65537.0*value+0.5));
00505 #else
00506 return((Quantum) (65537.0*value));
00507 #endif
00508 }
00509
00510 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00511 {
00512 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00513 return((unsigned int) quantum);
00514 #else
00515 if (quantum <= 0.0)
00516 return(0);
00517 if ((quantum) >= 4294967295.0)
00518 return(4294967295);
00519 return((unsigned int) (quantum+0.5));
00520 #endif
00521 }
00522
00523 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00524 {
00525 if (quantum < 0.0)
00526 return(0UL);
00527 if ((quantum/65537) >= (Quantum) MaxMap)
00528 return((unsigned int) MaxMap);
00529 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00530 return((unsigned int) ((quantum+MagickULLConstant(32768))/
00531 MagickULLConstant(65537)));
00532 #else
00533 return((unsigned int) (quantum/65537.0+0.5));
00534 #endif
00535 }
00536
00537 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00538 {
00539 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00540 return((unsigned short) ((quantum+MagickULLConstant(32768))/
00541 MagickULLConstant(65537)));
00542 #else
00543 if (quantum <= 0.0)
00544 return(0);
00545 if ((quantum/65537.0) >= 65535.0)
00546 return(65535);
00547 return((unsigned short) (quantum/65537.0+0.5));
00548 #endif
00549 }
00550
00551 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00552 {
00553 #if !defined(MAGICKCORE_HDRI_SUPPORT)
00554 return((Quantum) (65537UL*value));
00555 #else
00556 return((Quantum) (65537.0*value));
00557 #endif
00558 }
00559 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
00560 static inline Quantum ScaleCharToQuantum(const unsigned char value)
00561 {
00562 return((Quantum) (72340172838076673.0*value));
00563 }
00564
00565 static inline Quantum ScaleLongToQuantum(const unsigned int value)
00566 {
00567 return((Quantum) (4294967297.0*value));
00568 }
00569
00570 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
00571 {
00572 if (value <= 0.0)
00573 return((Quantum) 0);
00574 if (value >= MaxMap)
00575 return(QuantumRange);
00576 return((Quantum) (281479271743489.0*value));
00577 }
00578
00579 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
00580 {
00581 return((unsigned int) (quantum/4294967297.0+0.5));
00582 }
00583
00584 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
00585 {
00586 if (quantum <= 0.0)
00587 return(0UL);
00588 if ((quantum/281479271743489.0) >= MaxMap)
00589 return((unsigned int) MaxMap);
00590 return((unsigned int) (quantum/281479271743489.0+0.5));
00591 }
00592
00593 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
00594 {
00595 if (quantum <= 0.0)
00596 return(0);
00597 if ((quantum/281479271743489.0) >= 65535.0)
00598 return(65535);
00599 return((unsigned short) (quantum/281479271743489.0+0.5));
00600 }
00601
00602 static inline Quantum ScaleShortToQuantum(const unsigned short value)
00603 {
00604 return((Quantum) (281479271743489.0*value));
00605 }
00606 #endif
00607
00608 static inline unsigned short SinglePrecisionToHalf(const float value)
00609 {
00610 typedef union _SinglePrecision
00611 {
00612 unsigned int
00613 fixed_point;
00614
00615 float
00616 single_precision;
00617 } SinglePrecision;
00618
00619 register int
00620 exponent;
00621
00622 register unsigned int
00623 significand,
00624 sign_bit;
00625
00626 SinglePrecision
00627 map;
00628
00629 unsigned short
00630 half;
00631
00632
00633
00634
00635
00636
00637
00638
00639 map.single_precision=value;
00640 sign_bit=(map.fixed_point >> 16) & 0x00008000;
00641 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
00642 significand=map.fixed_point & 0x007fffff;
00643 if (exponent <= 0)
00644 {
00645 int
00646 shift;
00647
00648 if (exponent < -10)
00649 return((unsigned short) sign_bit);
00650 significand=significand | 0x00800000;
00651 shift=(int) (14-exponent);
00652 significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
00653 ((significand >> shift) & 0x01)) >> shift);
00654 return((unsigned short) (sign_bit | significand));
00655 }
00656 else
00657 if (exponent == (0xff-ExponentBias))
00658 {
00659 if (significand == 0)
00660 return((unsigned short) (sign_bit | ExponentMask));
00661 else
00662 {
00663 significand>>=SignificandShift;
00664 half=(unsigned short) (sign_bit | significand |
00665 (significand == 0) | ExponentMask);
00666 return(half);
00667 }
00668 }
00669 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
00670 if ((significand & 0x00800000) != 0)
00671 {
00672 significand=0;
00673 exponent++;
00674 }
00675 if (exponent > 30)
00676 {
00677 float
00678 alpha;
00679
00680 register int
00681 i;
00682
00683
00684
00685
00686 alpha=1.0e10;
00687 for (i=0; i < 10; i++)
00688 alpha*=alpha;
00689 return((unsigned short) (sign_bit | ExponentMask));
00690 }
00691 half=(unsigned short) (sign_bit | (exponent << 10) |
00692 (significand >> SignificandShift));
00693 return(half);
00694 }
00695
00696 #if defined(__cplusplus) || defined(c_plusplus)
00697 }
00698 #endif
00699
00700 #endif