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