]> granicus.if.org Git - imagemagick/blob - MagickCore/quantum-private.h
(no commit message)
[imagemagick] / MagickCore / quantum-private.h
1 /*
2   Copyright 1999-2008 ImageMagick Studio LLC, a non-profit organization
3   dedicated to making software imaging solutions freely available.
4
5   You may not use this file except in compliance with the License.
6   obtain a copy of the License at
7
8     http://www.imagemagick.org/script/license.php
9
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15
16   MagickCore quantum inline methods.
17 */
18 #ifndef _MAGICKCORE_QUANTUM_PRIVATE_H
19 #define _MAGICKCORE_QUANTUM_PRIVATE_H
20
21 #if defined(__cplusplus) || defined(c_plusplus)
22 extern "C" {
23 #endif
24
25 #include "MagickCore/cache.h"
26
27 typedef struct _QuantumState
28 {
29   double
30     inverse_scale;
31
32   unsigned int
33     pixel;
34
35   size_t
36     bits;
37
38   const unsigned int
39     *mask;
40 } QuantumState;
41
42 struct _QuantumInfo
43 {
44   size_t
45     depth,
46     quantum;
47
48   QuantumFormatType
49     format;
50
51   double
52     minimum,
53     maximum,
54     scale;
55
56   size_t
57     pad;
58
59   MagickBooleanType
60     min_is_white,
61     pack;
62
63   QuantumAlphaType
64     alpha_type;
65
66   size_t
67     number_threads;
68
69   unsigned char
70     **pixels;
71
72   size_t
73     extent;
74
75   EndianType
76     endian;
77
78   QuantumState
79     state;
80
81   SemaphoreInfo
82     *semaphore;
83
84   size_t
85     signature;
86 };
87
88 extern MagickPrivate void
89   ResetQuantumState(QuantumInfo *);
90
91 static inline MagickSizeType GetQuantumRange(const size_t depth)
92 {
93   MagickSizeType
94     one;
95
96   one=1;
97   return((MagickSizeType) ((one << (depth-1))+((one << (depth-1))-1)));
98 }
99
100 static inline float HalfToSinglePrecision(const unsigned short half)
101 {
102 #define ExponentBias  (127-15)
103 #define ExponentMask  0x7c00
104 #define ExponentShift  23
105 #define SignBitShift  31
106 #define SignificandShift  13
107 #define SignificandMask  0x00000400
108
109   typedef union _SinglePrecision
110   {
111     unsigned int
112       fixed_point;
113
114     float
115       single_precision;
116   } SinglePrecision;
117
118   register unsigned int
119     exponent,
120     significand,
121     sign_bit;
122
123   SinglePrecision
124     map;
125
126   unsigned int
127     value;
128
129   /*
130     The IEEE 754 standard specifies half precision as having:
131
132       Sign bit: 1 bit
133       Exponent width: 5 bits
134       Significand precision: 11 (10 explicitly stored)
135   */
136   sign_bit=(unsigned int) ((half >> 15) & 0x00000001);
137   exponent=(unsigned int) ((half >> 10) & 0x0000001f);
138   significand=(unsigned int) (half & 0x000003ff);
139   if (exponent == 0)
140     {
141       if (significand == 0)
142         value=sign_bit << SignBitShift;
143       else
144         {
145           while ((significand & SignificandMask) == 0)
146           {
147             significand<<=1;
148             exponent--;
149           }
150           exponent++;
151           significand&=(~SignificandMask);
152           exponent+=ExponentBias;
153           value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
154             (significand << SignificandShift);
155         }
156     }
157   else
158     if (exponent == SignBitShift)
159       {
160         value=(sign_bit << SignBitShift) | 0x7f800000;
161         if (significand != 0)
162           value|=(significand << SignificandShift);
163       }
164     else
165       {
166         exponent+=ExponentBias;
167         significand<<=SignificandShift;
168         value=(sign_bit << SignBitShift) | (exponent << ExponentShift) |
169           significand;
170       }
171   map.fixed_point=value;
172   return(map.single_precision);
173 }
174
175 static inline unsigned char *PopCharPixel(const unsigned char pixel,
176   unsigned char *pixels)
177 {
178   *pixels++=pixel;
179   return(pixels);
180 }
181
182 static inline unsigned char *PopLongPixel(const EndianType endian,
183   const unsigned int pixel,unsigned char *pixels)
184 {
185   register unsigned int
186     quantum;
187
188   quantum=(unsigned int) pixel;
189   if (endian != LSBEndian)
190     {
191       *pixels++=(unsigned char) (quantum >> 24);
192       *pixels++=(unsigned char) (quantum >> 16);
193       *pixels++=(unsigned char) (quantum >> 8);
194       *pixels++=(unsigned char) (quantum);
195       return(pixels);
196     }
197   *pixels++=(unsigned char) (quantum);
198   *pixels++=(unsigned char) (quantum >> 8);
199   *pixels++=(unsigned char) (quantum >> 16);
200   *pixels++=(unsigned char) (quantum >> 24);
201   return(pixels);
202 }
203
204 static inline unsigned char *PopShortPixel(const EndianType endian,
205   const unsigned short pixel,unsigned char *pixels)
206 {
207   register unsigned int
208     quantum;
209
210   quantum=pixel;
211   if (endian != LSBEndian)
212     {
213       *pixels++=(unsigned char) (quantum >> 8);
214       *pixels++=(unsigned char) (quantum);
215       return(pixels);
216     }
217   *pixels++=(unsigned char) (quantum);
218   *pixels++=(unsigned char) (quantum >> 8);
219   return(pixels);
220 }
221
222 static inline const unsigned char *PushCharPixel(const unsigned char *pixels,
223   unsigned char *pixel)
224 {
225   *pixel=(*pixels++);
226   return(pixels);
227 }
228
229 static inline const unsigned char *PushLongPixel(const EndianType endian,
230   const unsigned char *pixels,unsigned int *pixel)
231 {
232   register unsigned int
233     quantum;
234
235   if (endian != LSBEndian)
236     {
237       quantum=(unsigned int) (*pixels++ << 24);
238       quantum|=(unsigned int) (*pixels++ << 16);
239       quantum|=(unsigned int) (*pixels++ << 8);
240       quantum|=(unsigned int) (*pixels++);
241     }
242   else
243     {
244       quantum=(unsigned int) (*pixels++);
245       quantum|=(unsigned int) (*pixels++ << 8);
246       quantum|=(unsigned int) (*pixels++ << 16);
247       quantum|=(unsigned int) (*pixels++ << 24);
248     }
249   *pixel=(unsigned int) (quantum & 0xffffffff);
250   return(pixels);
251 }
252
253 static inline const unsigned char *PushShortPixel(const EndianType endian,
254   const unsigned char *pixels,unsigned short *pixel)
255 {
256   register unsigned int
257     quantum;
258
259   if (endian != LSBEndian)
260     {
261       quantum=(unsigned int) (*pixels++ << 8);
262       quantum|=(unsigned int) *pixels++;
263     }
264   else
265     {
266       quantum=(unsigned int) *pixels++;
267       quantum|=(unsigned int) (*pixels++ << 8);
268     }
269   *pixel=(unsigned short) (quantum & 0xffff);
270   return(pixels);
271 }
272
273 static inline Quantum ScaleAnyToQuantum(const QuantumAny quantum,
274   const QuantumAny range)
275 {
276 #if !defined(MAGICKCORE_HDRI_SUPPORT)
277   return((Quantum) (((double) QuantumRange*quantum)/range+0.5));
278 #else
279   return((Quantum) (((double) QuantumRange*quantum)/range));
280 #endif
281 }
282
283 static inline QuantumAny ScaleQuantumToAny(const Quantum quantum,
284   const QuantumAny range)
285 {
286   return((QuantumAny) (((double) range*quantum)/QuantumRange+0.5));
287 }
288
289 #if (MAGICKCORE_QUANTUM_DEPTH == 8)
290 static inline Quantum ScaleCharToQuantum(const unsigned char value)
291 {
292   return((Quantum) value);
293 }
294
295 static inline Quantum ScaleLongToQuantum(const unsigned int value)
296 {
297 #if !defined(MAGICKCORE_HDRI_SUPPORT)
298   return((Quantum) ((value+8421504UL)/16843009UL));
299 #else
300   return((Quantum) (value/16843009.0));
301 #endif
302 }
303
304 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
305 {
306 #if !defined(MAGICKCORE_HDRI_SUPPORT)
307   return((Quantum) ((value+MagickULLConstant(551911719039))/
308     MagickULLConstant(1103823438079)));
309 #else
310   return((Quantum) (value/1103823438079.0));
311 #endif
312 }
313
314 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
315 {
316   if (value <= 0.0)
317     return((Quantum) 0);
318   if (value >= MaxMap)
319     return(QuantumRange);
320 #if !defined(MAGICKCORE_HDRI_SUPPORT)
321   return((Quantum) (value+0.5));
322 #else
323   return((Quantum) value);
324 #endif
325 }
326
327 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
328 {
329 #if !defined(MAGICKCORE_HDRI_SUPPORT)
330   return((unsigned int) (16843009UL*quantum));
331 #else
332   if (quantum <= 0.0)
333     return(0UL);
334   if ((16843009.0*quantum) >= 4294967295.0)
335     return(4294967295UL);
336   return((unsigned int) (16843009.0*quantum+0.5));
337 #endif
338 }
339
340 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
341 {
342 #if !defined(MAGICKCORE_HDRI_SUPPORT)
343   return((MagickSizeType) (MagickULLConstant(551911719039)*quantum));
344 #else
345   if (quantum <= 0.0)
346     return(0UL);
347   if ((551911719039.0*quantum) >= 18446744073709551615.0)
348     return(MagickULLConstant(18446744073709551615));
349   return((MagickSizeType) (1103823438079.0*quantum+0.5));
350 #endif
351 }
352
353 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
354 {
355   if (quantum >= (Quantum) MaxMap)
356     return((unsigned int) MaxMap);
357 #if !defined(MAGICKCORE_HDRI_SUPPORT)
358   return((unsigned int) quantum);
359 #else
360   if (quantum < 0.0)
361     return(0UL);
362   return((unsigned int) (quantum+0.5));
363 #endif
364 }
365
366 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
367 {
368 #if !defined(MAGICKCORE_HDRI_SUPPORT)
369   return((unsigned short) (257UL*quantum));
370 #else
371   if (quantum <= 0.0)
372     return(0);
373   if ((257.0*quantum) >= 65535.0)
374     return(65535);
375   return((unsigned short) (257.0*quantum+0.5));
376 #endif
377 }
378
379 static inline Quantum ScaleShortToQuantum(const unsigned short value)
380 {
381 #if !defined(MAGICKCORE_HDRI_SUPPORT)
382   return((Quantum) ((value+128U)/257U));
383 #else
384   return((Quantum) (value/257.0));
385 #endif
386 }
387 #elif (MAGICKCORE_QUANTUM_DEPTH == 16)
388 static inline Quantum ScaleCharToQuantum(const unsigned char value)
389 {
390 #if !defined(MAGICKCORE_HDRI_SUPPORT)
391   return((Quantum) (257U*value));
392 #else
393   return((Quantum) (257.0*value));
394 #endif
395 }
396
397 static inline Quantum ScaleLongToQuantum(const unsigned int value)
398 {
399 #if !defined(MAGICKCORE_HDRI_SUPPORT)
400   return((Quantum) ((value+MagickULLConstant(32768))/
401     MagickULLConstant(65537)));
402 #else
403   return((Quantum) (value/65537.0));
404 #endif
405 }
406
407 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
408 {
409 #if !defined(MAGICKCORE_HDRI_SUPPORT)
410   return((Quantum) ((value+MagickULLConstant(8421376))/
411     MagickULLConstant(16842752)));
412 #else
413   return((Quantum) (value/16842752.0));
414 #endif
415 }
416
417 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
418 {
419   if (value <= 0.0)
420     return((Quantum) 0);
421   if (value >= MaxMap)
422     return(QuantumRange);
423 #if !defined(MAGICKCORE_HDRI_SUPPORT)
424   return((Quantum) (value+0.5));
425 #else
426   return((Quantum) value);
427 #endif
428 }
429
430 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
431 {
432 #if !defined(MAGICKCORE_HDRI_SUPPORT)
433   return((unsigned int) (65537UL*quantum));
434 #else
435   if (quantum <= 0.0)
436     return(0UL);
437   if ((65537.0*quantum) >= 4294967295.0)
438     return(4294967295U);
439   return((unsigned int) (65537.0*quantum+0.5));
440 #endif
441 }
442
443 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
444 {
445 #if !defined(MAGICKCORE_HDRI_SUPPORT)
446   return((MagickSizeType) (MagickULLConstant(16842752)*quantum));
447 #else
448   if (quantum <= 0.0)
449     return(0UL);
450   if ((65537.0*quantum) >= 18446744073709551615.0)
451     return(MagickULLConstant(18446744073709551615));
452   return((MagickSizeType) (16842752.0*quantum+0.5));
453 #endif
454 }
455
456 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
457 {
458   if (quantum >= (Quantum) MaxMap)
459     return((unsigned int) MaxMap);
460 #if !defined(MAGICKCORE_HDRI_SUPPORT)
461   return((unsigned int) quantum);
462 #else
463   if (quantum < 0.0)
464     return(0UL);
465   return((unsigned int) (quantum+0.5));
466 #endif
467 }
468
469 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
470 {
471 #if !defined(MAGICKCORE_HDRI_SUPPORT)
472   return((unsigned short) quantum);
473 #else
474   if (quantum <= 0.0)
475     return(0);
476   if (quantum >= 65535.0)
477     return(65535);
478   return((unsigned short) (quantum+0.5));
479 #endif
480 }
481
482 static inline Quantum ScaleShortToQuantum(const unsigned short value)
483 {
484   return((Quantum) value);
485 }
486 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
487 static inline Quantum ScaleCharToQuantum(const unsigned char value)
488 {
489 #if !defined(MAGICKCORE_HDRI_SUPPORT)
490   return((Quantum) (16843009UL*value));
491 #else
492   return((Quantum) (16843009.0*value));
493 #endif
494 }
495
496 static inline Quantum ScaleLongToQuantum(const unsigned int value)
497 {
498   return((Quantum) value);
499 }
500
501 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
502 {
503   return((Quantum) value);
504 }
505
506 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
507 {
508   if (value <= 0.0)
509     return((Quantum) 0);
510   if (value >= (Quantum) MaxMap)
511     return(QuantumRange);
512 #if !defined(MAGICKCORE_HDRI_SUPPORT)
513   return((Quantum) (65537.0*value+0.5));
514 #else
515   return((Quantum) (65537.0*value));
516 #endif
517 }
518
519 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
520 {
521 #if !defined(MAGICKCORE_HDRI_SUPPORT)
522   return((unsigned int) quantum);
523 #else
524   return((unsigned int) (quantum+0.5));
525 #endif
526 }
527
528 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
529 {
530 #if !defined(MAGICKCORE_HDRI_SUPPORT)
531   return((MagickSizeType) quantum);
532 #else
533   return((MagickSizeType) (quantum+0.5));
534 #endif
535 }
536
537 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
538 {
539   if (quantum < 0.0)
540     return(0UL);
541   if ((quantum/65537) >= (Quantum) MaxMap)
542     return((unsigned int) MaxMap);
543 #if !defined(MAGICKCORE_HDRI_SUPPORT)
544   return((unsigned int) ((quantum+MagickULLConstant(32768))/
545     MagickULLConstant(65537)));
546 #else
547   return((unsigned int) (quantum/65537.0+0.5));
548 #endif
549 }
550
551 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
552 {
553 #if !defined(MAGICKCORE_HDRI_SUPPORT)
554   return((unsigned short) ((quantum+MagickULLConstant(32768))/
555     MagickULLConstant(65537)));
556 #else
557   if (quantum <= 0.0)
558     return(0);
559   if ((quantum/65537.0) >= 65535.0)
560     return(65535);
561   return((unsigned short) (quantum/65537.0+0.5));
562 #endif
563 }
564
565 static inline Quantum ScaleShortToQuantum(const unsigned short value)
566 {
567 #if !defined(MAGICKCORE_HDRI_SUPPORT)
568   return((Quantum) (65537UL*value));
569 #else
570   return((Quantum) (65537.0*value));
571 #endif
572 }
573 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
574 static inline Quantum ScaleCharToQuantum(const unsigned char value)
575 {
576   return((Quantum) (72340172838076673.0*value));
577 }
578
579 static inline Quantum ScaleLongToQuantum(const unsigned int value)
580 {
581   return((Quantum) (4294967297.0*value));
582 }
583
584 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
585 {
586   return((Quantum) (18446744073709551615.0*value));
587 }
588
589 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
590 {
591   if (value <= 0.0)
592     return((Quantum) 0);
593   if (value >= MaxMap)
594     return(QuantumRange);
595   return((Quantum) (281479271743489.0*value));
596 }
597
598 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
599 {
600   return((unsigned int) (quantum/4294967297.0+0.5));
601 }
602
603 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
604 {
605   return((MagickSizeType) (quantum/18446744073709551615.0+0.5));
606 }
607
608 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
609 {
610   if (quantum <= 0.0)
611     return(0UL);
612   if ((quantum/281479271743489.0) >= MaxMap)
613     return((unsigned int) MaxMap);
614   return((unsigned int) (quantum/281479271743489.0+0.5));
615 }
616
617 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
618 {
619   if (quantum <= 0.0)
620     return(0);
621   if ((quantum/281479271743489.0) >= 65535.0)
622     return(65535);
623   return((unsigned short) (quantum/281479271743489.0+0.5));
624 }
625
626 static inline Quantum ScaleShortToQuantum(const unsigned short value)
627 {
628   return((Quantum) (281479271743489.0*value));
629 }
630 #endif
631
632 static inline unsigned short SinglePrecisionToHalf(const float value)
633 {
634   typedef union _SinglePrecision
635   {
636     unsigned int
637       fixed_point;
638
639     float
640       single_precision;
641   } SinglePrecision;
642
643   register int
644     exponent;
645
646   register unsigned int
647     significand,
648     sign_bit;
649
650   SinglePrecision
651     map;
652
653   unsigned short
654     half;
655
656   /*
657     The IEEE 754 standard specifies half precision as having:
658
659       Sign bit: 1 bit
660       Exponent width: 5 bits
661       Significand precision: 11 (10 explicitly stored)
662   */
663   map.single_precision=value;
664   sign_bit=(map.fixed_point >> 16) & 0x00008000;
665   exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
666   significand=map.fixed_point & 0x007fffff;
667   if (exponent <= 0)
668     {
669       int
670         shift;
671
672       if (exponent < -10)
673         return((unsigned short) sign_bit);
674       significand=significand | 0x00800000;
675       shift=(int) (14-exponent);
676       significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
677         ((significand >> shift) & 0x01)) >> shift);
678       return((unsigned short) (sign_bit | significand));
679     }
680   else
681     if (exponent == (0xff-ExponentBias))
682       {
683         if (significand == 0)
684           return((unsigned short) (sign_bit | ExponentMask));
685         else
686           {
687             significand>>=SignificandShift;
688             half=(unsigned short) (sign_bit | significand |
689               (significand == 0) | ExponentMask);
690             return(half);
691           }
692       }
693   significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
694   if ((significand & 0x00800000) != 0)
695     {
696       significand=0;
697       exponent++;
698     }
699   if (exponent > 30)
700     {
701       float
702         alpha;
703
704       register int
705         i;
706
707       /*
708         Float overflow.
709       */
710       alpha=1.0e10;
711       for (i=0; i < 10; i++)
712         alpha*=alpha;
713       return((unsigned short) (sign_bit | ExponentMask));
714     }
715   half=(unsigned short) (sign_bit | (exponent << 10) |
716     (significand >> SignificandShift));
717   return(half);
718 }
719
720 #if defined(__cplusplus) || defined(c_plusplus)
721 }
722 #endif
723
724 #endif