]> granicus.if.org Git - imagemagick/blob - MagickCore/quantum-private.h
The 8bim profile will be updated when the iptc profile is changed.
[imagemagick] / MagickCore / quantum-private.h
1 /*
2   Copyright 1999-2014 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 #include "MagickCore/cache.h"
22
23 #if defined(__cplusplus) || defined(c_plusplus)
24 extern "C" {
25 #endif
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);
192       *pixels++=(unsigned char) (quantum >> 8);
193       *pixels++=(unsigned char) (quantum >> 16);
194       *pixels++=(unsigned char) (quantum >> 24);
195       return(pixels);
196     }
197   *pixels++=(unsigned char) (quantum >> 24);
198   *pixels++=(unsigned char) (quantum >> 16);
199   *pixels++=(unsigned char) (quantum >> 8);
200   *pixels++=(unsigned char) (quantum);
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);
214       *pixels++=(unsigned char) (quantum >> 8);
215       return(pixels);
216     }
217   *pixels++=(unsigned char) (quantum >> 8);
218   *pixels++=(unsigned char) (quantum);
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++);
238       quantum|=(unsigned int) (*pixels++ << 8);
239       quantum|=(unsigned int) (*pixels++ << 16);
240       quantum|=(unsigned int) (*pixels++ << 24);
241       *pixel=(unsigned int) (quantum & 0xffffffff);
242       return(pixels);
243     }
244   quantum=(unsigned int) (*pixels++ << 24);
245   quantum|=(unsigned int) (*pixels++ << 16);
246   quantum|=(unsigned int) (*pixels++ << 8);
247   quantum|=(unsigned int) (*pixels++);
248   *pixel=(unsigned int) (quantum & 0xffffffff);
249   return(pixels);
250 }
251
252 static inline const unsigned char *PushShortPixel(const EndianType endian,
253   const unsigned char *pixels,unsigned short *pixel)
254 {
255   register unsigned int
256     quantum;
257
258   if (endian == LSBEndian)
259     {
260       quantum=(unsigned int) *pixels++;
261       quantum|=(unsigned int) (*pixels++ << 8);
262       *pixel=(unsigned short) (quantum & 0xffff);
263       return(pixels);
264     }
265   quantum=(unsigned int) (*pixels++ << 8);
266   quantum|=(unsigned int) *pixels++;
267   *pixel=(unsigned short) (quantum & 0xffff);
268   return(pixels);
269 }
270
271 static inline Quantum ScaleAnyToQuantum(const QuantumAny quantum,
272   const QuantumAny range)
273 {
274 #if !defined(MAGICKCORE_HDRI_SUPPORT)
275   return((Quantum) (((double) QuantumRange*quantum)/range+0.5));
276 #else
277   return((Quantum) (((double) QuantumRange*quantum)/range));
278 #endif
279 }
280
281 static inline QuantumAny ScaleQuantumToAny(const Quantum quantum,
282   const QuantumAny range)
283 {
284   return((QuantumAny) (((double) range*quantum)/QuantumRange+0.5));
285 }
286
287 #if (MAGICKCORE_QUANTUM_DEPTH == 8)
288 static inline Quantum ScaleCharToQuantum(const unsigned char value)
289 {
290   return((Quantum) value);
291 }
292
293 static inline Quantum ScaleLongToQuantum(const unsigned int value)
294 {
295 #if !defined(MAGICKCORE_HDRI_SUPPORT)
296   return((Quantum) ((value+8421504UL)/16843009UL));
297 #else
298   return((Quantum) (value/16843009.0));
299 #endif
300 }
301
302 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
303 {
304 #if !defined(MAGICKCORE_HDRI_SUPPORT)
305   return((Quantum) ((value+MagickULLConstant(551911719039))/
306     MagickULLConstant(1103823438079)));
307 #else
308   return((Quantum) (value/1103823438079.0));
309 #endif
310 }
311
312 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
313 {
314   if (value <= 0.0)
315     return((Quantum) 0);
316   if (value >= MaxMap)
317     return(QuantumRange);
318 #if !defined(MAGICKCORE_HDRI_SUPPORT)
319   return((Quantum) (value+0.5));
320 #else
321   return((Quantum) value);
322 #endif
323 }
324
325 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
326 {
327 #if !defined(MAGICKCORE_HDRI_SUPPORT)
328   return((unsigned int) (16843009UL*quantum));
329 #else
330   if (quantum <= 0.0)
331     return(0UL);
332   if ((16843009.0*quantum) >= 4294967295.0)
333     return(4294967295UL);
334   return((unsigned int) (16843009.0*quantum+0.5));
335 #endif
336 }
337
338 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
339 {
340 #if !defined(MAGICKCORE_HDRI_SUPPORT)
341   return((MagickSizeType) (MagickULLConstant(551911719039)*quantum));
342 #else
343   if (quantum <= 0.0)
344     return(0UL);
345   if ((551911719039.0*quantum) >= 18446744073709551615.0)
346     return(MagickULLConstant(18446744073709551615));
347   return((MagickSizeType) (1103823438079.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 ScaleLongLongToQuantum(const MagickSizeType value)
406 {
407 #if !defined(MAGICKCORE_HDRI_SUPPORT)
408   return((Quantum) ((value+MagickULLConstant(8421376))/
409     MagickULLConstant(16842752)));
410 #else
411   return((Quantum) (value/16842752.0));
412 #endif
413 }
414
415 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
416 {
417   if (value <= 0.0)
418     return((Quantum) 0);
419   if (value >= MaxMap)
420     return(QuantumRange);
421 #if !defined(MAGICKCORE_HDRI_SUPPORT)
422   return((Quantum) (value+0.5));
423 #else
424   return((Quantum) value);
425 #endif
426 }
427
428 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
429 {
430 #if !defined(MAGICKCORE_HDRI_SUPPORT)
431   return((unsigned int) (65537UL*quantum));
432 #else
433   if (quantum <= 0.0)
434     return(0UL);
435   if ((65537.0*quantum) >= 4294967295.0)
436     return(4294967295U);
437   return((unsigned int) (65537.0*quantum+0.5));
438 #endif
439 }
440
441 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
442 {
443 #if !defined(MAGICKCORE_HDRI_SUPPORT)
444   return((MagickSizeType) (MagickULLConstant(16842752)*quantum));
445 #else
446   if (quantum <= 0.0)
447     return(0UL);
448   if ((65537.0*quantum) >= 18446744073709551615.0)
449     return(MagickULLConstant(18446744073709551615));
450   return((MagickSizeType) (16842752.0*quantum+0.5));
451 #endif
452 }
453
454 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
455 {
456   if (quantum >= (Quantum) MaxMap)
457     return((unsigned int) MaxMap);
458 #if !defined(MAGICKCORE_HDRI_SUPPORT)
459   return((unsigned int) quantum);
460 #else
461   if (quantum < 0.0)
462     return(0UL);
463   return((unsigned int) (quantum+0.5));
464 #endif
465 }
466
467 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
468 {
469 #if !defined(MAGICKCORE_HDRI_SUPPORT)
470   return((unsigned short) quantum);
471 #else
472   if (quantum <= 0.0)
473     return(0);
474   if (quantum >= 65535.0)
475     return(65535);
476   return((unsigned short) (quantum+0.5));
477 #endif
478 }
479
480 static inline Quantum ScaleShortToQuantum(const unsigned short value)
481 {
482   return((Quantum) value);
483 }
484 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
485 static inline Quantum ScaleCharToQuantum(const unsigned char value)
486 {
487 #if !defined(MAGICKCORE_HDRI_SUPPORT)
488   return((Quantum) (16843009UL*value));
489 #else
490   return((Quantum) (16843009.0*value));
491 #endif
492 }
493
494 static inline Quantum ScaleLongToQuantum(const unsigned int value)
495 {
496   return((Quantum) value);
497 }
498
499 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
500 {
501   return((Quantum) value);
502 }
503
504 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
505 {
506   if (value <= 0.0)
507     return((Quantum) 0);
508   if (value >= (Quantum) MaxMap)
509     return(QuantumRange);
510 #if !defined(MAGICKCORE_HDRI_SUPPORT)
511   return((Quantum) (65537.0*value+0.5));
512 #else
513   return((Quantum) (65537.0*value));
514 #endif
515 }
516
517 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
518 {
519 #if !defined(MAGICKCORE_HDRI_SUPPORT)
520   return((unsigned int) quantum);
521 #else
522   return((unsigned int) (quantum+0.5));
523 #endif
524 }
525
526 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
527 {
528 #if !defined(MAGICKCORE_HDRI_SUPPORT)
529   return((MagickSizeType) quantum);
530 #else
531   return((MagickSizeType) (quantum+0.5));
532 #endif
533 }
534
535 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
536 {
537   if (quantum < 0.0)
538     return(0UL);
539   if ((quantum/65537) >= (Quantum) MaxMap)
540     return((unsigned int) MaxMap);
541 #if !defined(MAGICKCORE_HDRI_SUPPORT)
542   return((unsigned int) ((quantum+MagickULLConstant(32768))/
543     MagickULLConstant(65537)));
544 #else
545   return((unsigned int) (quantum/65537.0+0.5));
546 #endif
547 }
548
549 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
550 {
551 #if !defined(MAGICKCORE_HDRI_SUPPORT)
552   return((unsigned short) ((quantum+MagickULLConstant(32768))/
553     MagickULLConstant(65537)));
554 #else
555   if (quantum <= 0.0)
556     return(0);
557   if ((quantum/65537.0) >= 65535.0)
558     return(65535);
559   return((unsigned short) (quantum/65537.0+0.5));
560 #endif
561 }
562
563 static inline Quantum ScaleShortToQuantum(const unsigned short value)
564 {
565 #if !defined(MAGICKCORE_HDRI_SUPPORT)
566   return((Quantum) (65537UL*value));
567 #else
568   return((Quantum) (65537.0*value));
569 #endif
570 }
571 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
572 static inline Quantum ScaleCharToQuantum(const unsigned char value)
573 {
574   return((Quantum) (72340172838076673.0*value));
575 }
576
577 static inline Quantum ScaleLongToQuantum(const unsigned int value)
578 {
579   return((Quantum) (4294967297.0*value));
580 }
581
582 static inline Quantum ScaleLongLongToQuantum(const MagickSizeType value)
583 {
584   return((Quantum) (18446744073709551615.0*value));
585 }
586
587 static inline Quantum ScaleMapToQuantum(const MagickRealType value)
588 {
589   if (value <= 0.0)
590     return((Quantum) 0);
591   if (value >= MaxMap)
592     return(QuantumRange);
593   return((Quantum) (281479271743489.0*value));
594 }
595
596 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
597 {
598   return((unsigned int) (quantum/4294967297.0+0.5));
599 }
600
601 static inline MagickSizeType ScaleQuantumToLongLong(const Quantum quantum)
602 {
603   return((MagickSizeType) (quantum/18446744073709551615.0+0.5));
604 }
605
606 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
607 {
608   if (quantum <= 0.0)
609     return(0UL);
610   if ((quantum/281479271743489.0) >= MaxMap)
611     return((unsigned int) MaxMap);
612   return((unsigned int) (quantum/281479271743489.0+0.5));
613 }
614
615 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
616 {
617   if (quantum <= 0.0)
618     return(0);
619   if ((quantum/281479271743489.0) >= 65535.0)
620     return(65535);
621   return((unsigned short) (quantum/281479271743489.0+0.5));
622 }
623
624 static inline Quantum ScaleShortToQuantum(const unsigned short value)
625 {
626   return((Quantum) (281479271743489.0*value));
627 }
628 #endif
629
630 static inline unsigned short SinglePrecisionToHalf(const float value)
631 {
632   typedef union _SinglePrecision
633   {
634     unsigned int
635       fixed_point;
636
637     float
638       single_precision;
639   } SinglePrecision;
640
641   register int
642     exponent;
643
644   register unsigned int
645     significand,
646     sign_bit;
647
648   SinglePrecision
649     map;
650
651   unsigned short
652     half;
653
654   /*
655     The IEEE 754 standard specifies half precision as having:
656
657       Sign bit: 1 bit
658       Exponent width: 5 bits
659       Significand precision: 11 (10 explicitly stored)
660   */
661   map.single_precision=value;
662   sign_bit=(map.fixed_point >> 16) & 0x00008000;
663   exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
664   significand=map.fixed_point & 0x007fffff;
665   if (exponent <= 0)
666     {
667       int
668         shift;
669
670       if (exponent < -10)
671         return((unsigned short) sign_bit);
672       significand=significand | 0x00800000;
673       shift=(int) (14-exponent);
674       significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
675         ((significand >> shift) & 0x01)) >> shift);
676       return((unsigned short) (sign_bit | significand));
677     }
678   else
679     if (exponent == (0xff-ExponentBias))
680       {
681         if (significand == 0)
682           return((unsigned short) (sign_bit | ExponentMask));
683         else
684           {
685             significand>>=SignificandShift;
686             half=(unsigned short) (sign_bit | significand |
687               (significand == 0) | ExponentMask);
688             return(half);
689           }
690       }
691   significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
692   if ((significand & 0x00800000) != 0)
693     {
694       significand=0;
695       exponent++;
696     }
697   if (exponent > 30)
698     {
699       float
700         alpha;
701
702       register int
703         i;
704
705       /*
706         Float overflow.
707       */
708       alpha=1.0e10;
709       for (i=0; i < 10; i++)
710         alpha*=alpha;
711       return((unsigned short) (sign_bit | ExponentMask));
712     }
713   half=(unsigned short) (sign_bit | (exponent << 10) |
714     (significand >> SignificandShift));
715   return(half);
716 }
717
718 #if defined(__cplusplus) || defined(c_plusplus)
719 }
720 #endif
721
722 #endif