|
MagickCore
6.7.5
|
00001 /* 00002 Copyright 1999-2008 ImageMagick Studio LLC, a non-profit organization 00003 dedicated to making software imaging solutions freely available. 00004 00005 You may not use this file except in compliance with the License. 00006 obtain a copy of the License at 00007 00008 http://www.imagemagick.org/script/license.php 00009 00010 Unless required by applicable law or agreed to in writing, software 00011 distributed under the License is distributed on an "AS IS" BASIS, 00012 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 See the License for the specific language governing permissions and 00014 limitations under the License. 00015 00016 MagickCore quantum inline methods. 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 "MagickCore/cache.h" 00026 00027 typedef struct _QuantumState 00028 { 00029 double 00030 inverse_scale; 00031 00032 unsigned int 00033 pixel; 00034 00035 size_t 00036 bits; 00037 00038 const unsigned int 00039 *mask; 00040 } QuantumState; 00041 00042 struct _QuantumInfo 00043 { 00044 size_t 00045 depth, 00046 quantum; 00047 00048 QuantumFormatType 00049 format; 00050 00051 double 00052 minimum, 00053 maximum, 00054 scale; 00055 00056 size_t 00057 pad; 00058 00059 MagickBooleanType 00060 min_is_white, 00061 pack; 00062 00063 QuantumAlphaType 00064 alpha_type; 00065 00066 size_t 00067 number_threads; 00068 00069 unsigned char 00070 **pixels; 00071 00072 size_t 00073 extent; 00074 00075 EndianType 00076 endian; 00077 00078 QuantumState 00079 state; 00080 00081 SemaphoreInfo 00082 *semaphore; 00083 00084 size_t 00085 signature; 00086 }; 00087 00088 extern MagickPrivate void 00089 ResetQuantumState(QuantumInfo *); 00090 00091 static inline MagickSizeType GetQuantumRange(const size_t depth) 00092 { 00093 MagickSizeType 00094 one; 00095 00096 one=1; 00097 return((MagickSizeType) ((one << (depth-1))+((one << (depth-1))-1))); 00098 } 00099 00100 static inline float HalfToSinglePrecision(const unsigned short half) 00101 { 00102 #define ExponentBias (127-15) 00103 #define ExponentMask 0x7c00 00104 #define ExponentShift 23 00105 #define SignBitShift 31 00106 #define SignificandShift 13 00107 #define SignificandMask 0x00000400 00108 00109 typedef union _SinglePrecision 00110 { 00111 unsigned int 00112 fixed_point; 00113 00114 float 00115 single_precision; 00116 } SinglePrecision; 00117 00118 register unsigned int 00119 exponent, 00120 significand, 00121 sign_bit; 00122 00123 SinglePrecision 00124 map; 00125 00126 unsigned int 00127 value; 00128 00129 /* 00130 The IEEE 754 standard specifies half precision as having: 00131 00132 Sign bit: 1 bit 00133 Exponent width: 5 bits 00134 Significand precision: 11 (10 explicitly stored) 00135 */ 00136 sign_bit=(unsigned int) ((half >> 15) & 0x00000001); 00137 exponent=(unsigned int) ((half >> 10) & 0x0000001f); 00138 significand=(unsigned int) (half & 0x000003ff); 00139 if (exponent == 0) 00140 { 00141 if (significand == 0) 00142 value=sign_bit << SignBitShift; 00143 else 00144 { 00145 while ((significand & SignificandMask) == 0) 00146 { 00147 significand<<=1; 00148 exponent--; 00149 } 00150 exponent++; 00151 significand&=(~SignificandMask); 00152 exponent+=ExponentBias; 00153 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) | 00154 (significand << SignificandShift); 00155 } 00156 } 00157 else 00158 if (exponent == SignBitShift) 00159 { 00160 value=(sign_bit << SignBitShift) | 0x7f800000; 00161 if (significand != 0) 00162 value|=(significand << SignificandShift); 00163 } 00164 else 00165 { 00166 exponent+=ExponentBias; 00167 significand<<=SignificandShift; 00168 value=(sign_bit << SignBitShift) | (exponent << ExponentShift) | 00169 significand; 00170 } 00171 map.fixed_point=value; 00172 return(map.single_precision); 00173 } 00174 00175 static inline unsigned char *PopCharPixel(const unsigned char pixel, 00176 unsigned char *pixels) 00177 { 00178 *pixels++=pixel; 00179 return(pixels); 00180 } 00181 00182 static inline unsigned char *PopLongPixel(const EndianType endian, 00183 const unsigned int pixel,unsigned char *pixels) 00184 { 00185 register unsigned int 00186 quantum; 00187 00188 quantum=(unsigned int) pixel; 00189 if (endian != LSBEndian) 00190 { 00191 *pixels++=(unsigned char) (quantum >> 24); 00192 *pixels++=(unsigned char) (quantum >> 16); 00193 *pixels++=(unsigned char) (quantum >> 8); 00194 *pixels++=(unsigned char) (quantum); 00195 return(pixels); 00196 } 00197 *pixels++=(unsigned char) (quantum); 00198 *pixels++=(unsigned char) (quantum >> 8); 00199 *pixels++=(unsigned char) (quantum >> 16); 00200 *pixels++=(unsigned char) (quantum >> 24); 00201 return(pixels); 00202 } 00203 00204 static inline unsigned char *PopShortPixel(const EndianType endian, 00205 const unsigned short pixel,unsigned char *pixels) 00206 { 00207 register unsigned int 00208 quantum; 00209 00210 quantum=pixel; 00211 if (endian != LSBEndian) 00212 { 00213 *pixels++=(unsigned char) (quantum >> 8); 00214 *pixels++=(unsigned char) (quantum); 00215 return(pixels); 00216 } 00217 *pixels++=(unsigned char) (quantum); 00218 *pixels++=(unsigned char) (quantum >> 8); 00219 return(pixels); 00220 } 00221 00222 static inline const unsigned char *PushCharPixel(const unsigned char *pixels, 00223 unsigned char *pixel) 00224 { 00225 *pixel=(*pixels++); 00226 return(pixels); 00227 } 00228 00229 static inline const unsigned char *PushLongPixel(const EndianType endian, 00230 const unsigned char *pixels,unsigned int *pixel) 00231 { 00232 register unsigned int 00233 quantum; 00234 00235 if (endian != LSBEndian) 00236 { 00237 quantum=(unsigned int) (*pixels++ << 24); 00238 quantum|=(unsigned int) (*pixels++ << 16); 00239 quantum|=(unsigned int) (*pixels++ << 8); 00240 quantum|=(unsigned int) (*pixels++); 00241 } 00242 else 00243 { 00244 quantum=(unsigned int) (*pixels++); 00245 quantum|=(unsigned int) (*pixels++ << 8); 00246 quantum|=(unsigned int) (*pixels++ << 16); 00247 quantum|=(unsigned int) (*pixels++ << 24); 00248 } 00249 *pixel=(unsigned int) (quantum & 0xffffffff); 00250 return(pixels); 00251 } 00252 00253 static inline const unsigned char *PushShortPixel(const EndianType endian, 00254 const unsigned char *pixels,unsigned short *pixel) 00255 { 00256 register unsigned int 00257 quantum; 00258 00259 if (endian != LSBEndian) 00260 { 00261 quantum=(unsigned int) (*pixels++ << 8); 00262 quantum|=(unsigned int) *pixels++; 00263 } 00264 else 00265 { 00266 quantum=(unsigned int) *pixels++; 00267 quantum|=(unsigned int) (*pixels++ << 8); 00268 } 00269 *pixel=(unsigned short) (quantum & 0xffff); 00270 return(pixels); 00271 } 00272 00273 static inline Quantum ScaleAnyToQuantum(const QuantumAny quantum, 00274 const QuantumAny range) 00275 { 00276 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00277 return((Quantum) (((MagickRealType) QuantumRange*quantum)/range+0.5)); 00278 #else 00279 return((Quantum) (((MagickRealType) QuantumRange*quantum)/range)); 00280 #endif 00281 } 00282 00283 static inline QuantumAny ScaleQuantumToAny(const Quantum quantum, 00284 const QuantumAny range) 00285 { 00286 return((QuantumAny) (((MagickRealType) range*quantum)/QuantumRange+0.5)); 00287 } 00288 00289 #if (MAGICKCORE_QUANTUM_DEPTH == 8) 00290 static inline Quantum ScaleCharToQuantum(const unsigned char value) 00291 { 00292 return((Quantum) value); 00293 } 00294 00295 static inline Quantum ScaleLongToQuantum(const unsigned int value) 00296 { 00297 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00298 return((Quantum) ((value+8421504UL)/16843009UL)); 00299 #else 00300 return((Quantum) (value/16843009.0)); 00301 #endif 00302 } 00303 00304 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value) 00305 { 00306 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00307 return((Quantum) ((value+MagickULLConstant(551911719039))/ 00308 MagickULLConstant(1103823438079))); 00309 #else 00310 return((Quantum) (value/1103823438079.0)); 00311 #endif 00312 } 00313 00314 static inline Quantum ScaleMapToQuantum(const MagickRealType value) 00315 { 00316 if (value <= 0.0) 00317 return((Quantum) 0); 00318 if (value >= MaxMap) 00319 return((Quantum) QuantumRange); 00320 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00321 return((Quantum) (value+0.5)); 00322 #else 00323 return((Quantum) value); 00324 #endif 00325 } 00326 00327 static inline unsigned int ScaleQuantumToLong(const Quantum quantum) 00328 { 00329 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00330 return((unsigned int) (16843009UL*quantum)); 00331 #else 00332 if (quantum <= 0.0) 00333 return(0UL); 00334 if ((16843009.0*quantum) >= 4294967295.0) 00335 return(4294967295UL); 00336 return((unsigned int) (16843009.0*quantum+0.5)); 00337 #endif 00338 } 00339 00340 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum) 00341 { 00342 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00343 return((MagickSizeType) (MagickULLConstant(551911719039)*quantum)); 00344 #else 00345 if (quantum <= 0.0) 00346 return(0UL); 00347 if ((551911719039.0*quantum) >= 18446744073709551615.0) 00348 return(MagickULLConstant(18446744073709551615)); 00349 return((MagickSizeType) (1103823438079.0*quantum+0.5)); 00350 #endif 00351 } 00352 00353 static inline unsigned int ScaleQuantumToMap(const Quantum quantum) 00354 { 00355 if (quantum >= (Quantum) MaxMap) 00356 return((unsigned int) MaxMap); 00357 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00358 return((unsigned int) quantum); 00359 #else 00360 if (quantum < 0.0) 00361 return(0UL); 00362 return((unsigned int) (quantum+0.5)); 00363 #endif 00364 } 00365 00366 static inline unsigned short ScaleQuantumToShort(const Quantum quantum) 00367 { 00368 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00369 return((unsigned short) (257UL*quantum)); 00370 #else 00371 if (quantum <= 0.0) 00372 return(0); 00373 if ((257.0*quantum) >= 65535.0) 00374 return(65535); 00375 return((unsigned short) (257.0*quantum+0.5)); 00376 #endif 00377 } 00378 00379 static inline Quantum ScaleShortToQuantum(const unsigned short value) 00380 { 00381 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00382 return((Quantum) ((value+128U)/257U)); 00383 #else 00384 return((Quantum) (value/257.0)); 00385 #endif 00386 } 00387 #elif (MAGICKCORE_QUANTUM_DEPTH == 16) 00388 static inline Quantum ScaleCharToQuantum(const unsigned char value) 00389 { 00390 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00391 return((Quantum) (257U*value)); 00392 #else 00393 return((Quantum) (257.0*value)); 00394 #endif 00395 } 00396 00397 static inline Quantum ScaleLongToQuantum(const unsigned int value) 00398 { 00399 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00400 return((Quantum) ((value+MagickULLConstant(32768))/ 00401 MagickULLConstant(65537))); 00402 #else 00403 return((Quantum) (value/65537.0)); 00404 #endif 00405 } 00406 00407 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value) 00408 { 00409 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00410 return((Quantum) ((value+MagickULLConstant(8421376))/ 00411 MagickULLConstant(16842752))); 00412 #else 00413 return((Quantum) (value/16842752.0)); 00414 #endif 00415 } 00416 00417 static inline Quantum ScaleMapToQuantum(const MagickRealType value) 00418 { 00419 if (value <= 0.0) 00420 return((Quantum) 0); 00421 if (value >= MaxMap) 00422 return((Quantum) QuantumRange); 00423 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00424 return((Quantum) (value+0.5)); 00425 #else 00426 return((Quantum) value); 00427 #endif 00428 } 00429 00430 static inline unsigned int ScaleQuantumToLong(const Quantum quantum) 00431 { 00432 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00433 return((unsigned int) (65537UL*quantum)); 00434 #else 00435 if (quantum <= 0.0) 00436 return(0UL); 00437 if ((65537.0*quantum) >= 4294967295.0) 00438 return(4294967295U); 00439 return((unsigned int) (65537.0*quantum+0.5)); 00440 #endif 00441 } 00442 00443 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum) 00444 { 00445 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00446 return((MagickSizeType) (MagickULLConstant(16842752)*quantum)); 00447 #else 00448 if (quantum <= 0.0) 00449 return(0UL); 00450 if ((65537.0*quantum) >= 18446744073709551615.0) 00451 return(MagickULLConstant(18446744073709551615)); 00452 return((MagickSizeType) (16842752.0*quantum+0.5)); 00453 #endif 00454 } 00455 00456 static inline unsigned int ScaleQuantumToMap(const Quantum quantum) 00457 { 00458 if (quantum >= (Quantum) MaxMap) 00459 return((unsigned int) MaxMap); 00460 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00461 return((unsigned int) quantum); 00462 #else 00463 if (quantum < 0.0) 00464 return(0UL); 00465 return((unsigned int) (quantum+0.5)); 00466 #endif 00467 } 00468 00469 static inline unsigned short ScaleQuantumToShort(const Quantum quantum) 00470 { 00471 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00472 return((unsigned short) quantum); 00473 #else 00474 if (quantum <= 0.0) 00475 return(0); 00476 if (quantum >= 65535.0) 00477 return(65535); 00478 return((unsigned short) (quantum+0.5)); 00479 #endif 00480 } 00481 00482 static inline Quantum ScaleShortToQuantum(const unsigned short value) 00483 { 00484 return((Quantum) value); 00485 } 00486 #elif (MAGICKCORE_QUANTUM_DEPTH == 32) 00487 static inline Quantum ScaleCharToQuantum(const unsigned char value) 00488 { 00489 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00490 return((Quantum) (16843009UL*value)); 00491 #else 00492 return((Quantum) (16843009.0*value)); 00493 #endif 00494 } 00495 00496 static inline Quantum ScaleLongToQuantum(const unsigned int value) 00497 { 00498 return((Quantum) value); 00499 } 00500 00501 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value) 00502 { 00503 return((Quantum) value); 00504 } 00505 00506 static inline Quantum ScaleMapToQuantum(const MagickRealType value) 00507 { 00508 if (value <= 0.0) 00509 return((Quantum) 0); 00510 if (value >= (Quantum) MaxMap) 00511 return(QuantumRange); 00512 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00513 return((Quantum) (65537.0*value+0.5)); 00514 #else 00515 return((Quantum) (65537.0*value)); 00516 #endif 00517 } 00518 00519 static inline unsigned int ScaleQuantumToLong(const Quantum quantum) 00520 { 00521 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00522 return((unsigned int) quantum); 00523 #else 00524 return((unsigned int) (quantum+0.5)); 00525 #endif 00526 } 00527 00528 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum) 00529 { 00530 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00531 return((MagickSizeType) quantum); 00532 #else 00533 return((MagickSizeType) (quantum+0.5)); 00534 #endif 00535 } 00536 00537 static inline unsigned int ScaleQuantumToMap(const Quantum quantum) 00538 { 00539 if (quantum < 0.0) 00540 return(0UL); 00541 if ((quantum/65537) >= (Quantum) MaxMap) 00542 return((unsigned int) MaxMap); 00543 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00544 return((unsigned int) ((quantum+MagickULLConstant(32768))/ 00545 MagickULLConstant(65537))); 00546 #else 00547 return((unsigned int) (quantum/65537.0+0.5)); 00548 #endif 00549 } 00550 00551 static inline unsigned short ScaleQuantumToShort(const Quantum quantum) 00552 { 00553 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00554 return((unsigned short) ((quantum+MagickULLConstant(32768))/ 00555 MagickULLConstant(65537))); 00556 #else 00557 if (quantum <= 0.0) 00558 return(0); 00559 if ((quantum/65537.0) >= 65535.0) 00560 return(65535); 00561 return((unsigned short) (quantum/65537.0+0.5)); 00562 #endif 00563 } 00564 00565 static inline Quantum ScaleShortToQuantum(const unsigned short value) 00566 { 00567 #if !defined(MAGICKCORE_HDRI_SUPPORT) 00568 return((Quantum) (65537UL*value)); 00569 #else 00570 return((Quantum) (65537.0*value)); 00571 #endif 00572 } 00573 #elif (MAGICKCORE_QUANTUM_DEPTH == 64) 00574 static inline Quantum ScaleCharToQuantum(const unsigned char value) 00575 { 00576 return((Quantum) (72340172838076673.0*value)); 00577 } 00578 00579 static inline Quantum ScaleLongToQuantum(const unsigned int value) 00580 { 00581 return((Quantum) (4294967297.0*value)); 00582 } 00583 00584 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value) 00585 { 00586 return((Quantum) (18446744073709551615.0*value)); 00587 } 00588 00589 static inline Quantum ScaleMapToQuantum(const MagickRealType value) 00590 { 00591 if (value <= 0.0) 00592 return((Quantum) 0); 00593 if (value >= MaxMap) 00594 return(QuantumRange); 00595 return((Quantum) (281479271743489.0*value)); 00596 } 00597 00598 static inline unsigned int ScaleQuantumToLong(const Quantum quantum) 00599 { 00600 return((unsigned int) (quantum/4294967297.0+0.5)); 00601 } 00602 00603 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum) 00604 { 00605 return((MagickSizeType) (quantum/18446744073709551615.0+0.5)); 00606 } 00607 00608 static inline unsigned int ScaleQuantumToMap(const Quantum quantum) 00609 { 00610 if (quantum <= 0.0) 00611 return(0UL); 00612 if ((quantum/281479271743489.0) >= MaxMap) 00613 return((unsigned int) MaxMap); 00614 return((unsigned int) (quantum/281479271743489.0+0.5)); 00615 } 00616 00617 static inline unsigned short ScaleQuantumToShort(const Quantum quantum) 00618 { 00619 if (quantum <= 0.0) 00620 return(0); 00621 if ((quantum/281479271743489.0) >= 65535.0) 00622 return(65535); 00623 return((unsigned short) (quantum/281479271743489.0+0.5)); 00624 } 00625 00626 static inline Quantum ScaleShortToQuantum(const unsigned short value) 00627 { 00628 return((Quantum) (281479271743489.0*value)); 00629 } 00630 #endif 00631 00632 static inline unsigned short SinglePrecisionToHalf(const float value) 00633 { 00634 typedef union _SinglePrecision 00635 { 00636 unsigned int 00637 fixed_point; 00638 00639 float 00640 single_precision; 00641 } SinglePrecision; 00642 00643 register int 00644 exponent; 00645 00646 register unsigned int 00647 significand, 00648 sign_bit; 00649 00650 SinglePrecision 00651 map; 00652 00653 unsigned short 00654 half; 00655 00656 /* 00657 The IEEE 754 standard specifies half precision as having: 00658 00659 Sign bit: 1 bit 00660 Exponent width: 5 bits 00661 Significand precision: 11 (10 explicitly stored) 00662 */ 00663 map.single_precision=value; 00664 sign_bit=(map.fixed_point >> 16) & 0x00008000; 00665 exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias; 00666 significand=map.fixed_point & 0x007fffff; 00667 if (exponent <= 0) 00668 { 00669 int 00670 shift; 00671 00672 if (exponent < -10) 00673 return((unsigned short) sign_bit); 00674 significand=significand | 0x00800000; 00675 shift=(int) (14-exponent); 00676 significand=(unsigned int) ((significand+((1 << (shift-1))-1)+ 00677 ((significand >> shift) & 0x01)) >> shift); 00678 return((unsigned short) (sign_bit | significand)); 00679 } 00680 else 00681 if (exponent == (0xff-ExponentBias)) 00682 { 00683 if (significand == 0) 00684 return((unsigned short) (sign_bit | ExponentMask)); 00685 else 00686 { 00687 significand>>=SignificandShift; 00688 half=(unsigned short) (sign_bit | significand | 00689 (significand == 0) | ExponentMask); 00690 return(half); 00691 } 00692 } 00693 significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff; 00694 if ((significand & 0x00800000) != 0) 00695 { 00696 significand=0; 00697 exponent++; 00698 } 00699 if (exponent > 30) 00700 { 00701 float 00702 alpha; 00703 00704 register int 00705 i; 00706 00707 /* 00708 Float overflow. 00709 */ 00710 alpha=1.0e10; 00711 for (i=0; i < 10; i++) 00712 alpha*=alpha; 00713 return((unsigned short) (sign_bit | ExponentMask)); 00714 } 00715 half=(unsigned short) (sign_bit | (exponent << 10) | 00716 (significand >> SignificandShift)); 00717 return(half); 00718 } 00719 00720 #if defined(__cplusplus) || defined(c_plusplus) 00721 } 00722 #endif 00723 00724 #endif