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 #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
00122
00123
00124
00125
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
00628
00629
00630
00631
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
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