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