]> granicus.if.org Git - imagemagick/blob - MagickCore/quantum-private.h
(no commit message)
[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 ScaleMapToQuantum(const double value)
303 {
304   if (value <= 0.0)
305     return((Quantum) 0);
306   if (value >= MaxMap)
307     return(QuantumRange);
308 #if !defined(MAGICKCORE_HDRI_SUPPORT)
309   return((Quantum) (value+0.5));
310 #else
311   return((Quantum) value);
312 #endif
313 }
314
315 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
316 {
317 #if !defined(MAGICKCORE_HDRI_SUPPORT)
318   return((unsigned int) (16843009UL*quantum));
319 #else
320   if (quantum <= 0.0)
321     return(0UL);
322   if ((16843009.0*quantum) >= 4294967295.0)
323     return(4294967295UL);
324   return((unsigned int) (16843009.0*quantum+0.5));
325 #endif
326 }
327
328 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
329 {
330   if (quantum >= (Quantum) MaxMap)
331     return((unsigned int) MaxMap);
332 #if !defined(MAGICKCORE_HDRI_SUPPORT)
333   return((unsigned int) quantum);
334 #else
335   if (quantum < 0.0)
336     return(0UL);
337   return((unsigned int) (quantum+0.5));
338 #endif
339 }
340
341 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
342 {
343 #if !defined(MAGICKCORE_HDRI_SUPPORT)
344   return((unsigned short) (257UL*quantum));
345 #else
346   if (quantum <= 0.0)
347     return(0);
348   if ((257.0*quantum) >= 65535.0)
349     return(65535);
350   return((unsigned short) (257.0*quantum+0.5));
351 #endif
352 }
353
354 static inline Quantum ScaleShortToQuantum(const unsigned short value)
355 {
356 #if !defined(MAGICKCORE_HDRI_SUPPORT)
357   return((Quantum) ((value+128U)/257U));
358 #else
359   return((Quantum) (value/257.0));
360 #endif
361 }
362 #elif (MAGICKCORE_QUANTUM_DEPTH == 16)
363 static inline Quantum ScaleCharToQuantum(const unsigned char value)
364 {
365 #if !defined(MAGICKCORE_HDRI_SUPPORT)
366   return((Quantum) (257U*value));
367 #else
368   return((Quantum) (257.0*value));
369 #endif
370 }
371
372 static inline Quantum ScaleLongToQuantum(const unsigned int value)
373 {
374 #if !defined(MAGICKCORE_HDRI_SUPPORT)
375   return((Quantum) ((value+MagickULLConstant(32768))/
376     MagickULLConstant(65537)));
377 #else
378   return((Quantum) (value/65537.0));
379 #endif
380 }
381
382 static inline Quantum ScaleMapToQuantum(const double value)
383 {
384   if (value <= 0.0)
385     return((Quantum) 0);
386   if (value >= MaxMap)
387     return(QuantumRange);
388 #if !defined(MAGICKCORE_HDRI_SUPPORT)
389   return((Quantum) (value+0.5));
390 #else
391   return((Quantum) value);
392 #endif
393 }
394
395 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
396 {
397 #if !defined(MAGICKCORE_HDRI_SUPPORT)
398   return((unsigned int) (65537UL*quantum));
399 #else
400   if (quantum <= 0.0)
401     return(0UL);
402   if ((65537.0*quantum) >= 4294967295.0)
403     return(4294967295U);
404   return((unsigned int) (65537.0*quantum+0.5));
405 #endif
406 }
407
408 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
409 {
410   if (quantum >= (Quantum) MaxMap)
411     return((unsigned int) MaxMap);
412 #if !defined(MAGICKCORE_HDRI_SUPPORT)
413   return((unsigned int) quantum);
414 #else
415   if (quantum < 0.0)
416     return(0UL);
417   return((unsigned int) (quantum+0.5));
418 #endif
419 }
420
421 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
422 {
423 #if !defined(MAGICKCORE_HDRI_SUPPORT)
424   return((unsigned short) quantum);
425 #else
426   if (quantum <= 0.0)
427     return(0);
428   if (quantum >= 65535.0)
429     return(65535);
430   return((unsigned short) (quantum+0.5));
431 #endif
432 }
433
434 static inline Quantum ScaleShortToQuantum(const unsigned short value)
435 {
436   return((Quantum) value);
437 }
438 #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
439 static inline Quantum ScaleCharToQuantum(const unsigned char value)
440 {
441 #if !defined(MAGICKCORE_HDRI_SUPPORT)
442   return((Quantum) (16843009UL*value));
443 #else
444   return((Quantum) (16843009.0*value));
445 #endif
446 }
447
448 static inline Quantum ScaleLongToQuantum(const unsigned int value)
449 {
450   return((Quantum) value);
451 }
452
453 static inline Quantum ScaleMapToQuantum(const double value)
454 {
455   if (value <= 0.0)
456     return((Quantum) 0);
457   if (value >= (Quantum) MaxMap)
458     return(QuantumRange);
459 #if !defined(MAGICKCORE_HDRI_SUPPORT)
460   return((Quantum) (65537.0*value+0.5));
461 #else
462   return((Quantum) (65537.0*value));
463 #endif
464 }
465
466 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
467 {
468 #if !defined(MAGICKCORE_HDRI_SUPPORT)
469   return((unsigned int) quantum);
470 #else
471   if (quantum <= 0.0)
472     return(0);
473   if ((quantum) >= 4294967295.0)
474     return(4294967295);
475   return((unsigned int) (quantum+0.5));
476 #endif
477 }
478
479 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
480 {
481   if (quantum < 0.0)
482     return(0UL);
483   if ((quantum/65537) >= (Quantum) MaxMap)
484     return((unsigned int) MaxMap);
485 #if !defined(MAGICKCORE_HDRI_SUPPORT)
486   return((unsigned int) ((quantum+MagickULLConstant(32768))/
487     MagickULLConstant(65537)));
488 #else
489   return((unsigned int) (quantum/65537.0+0.5));
490 #endif
491 }
492
493 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
494 {
495 #if !defined(MAGICKCORE_HDRI_SUPPORT)
496   return((unsigned short) ((quantum+MagickULLConstant(32768))/
497     MagickULLConstant(65537)));
498 #else
499   if (quantum <= 0.0)
500     return(0);
501   if ((quantum/65537.0) >= 65535.0)
502     return(65535);
503   return((unsigned short) (quantum/65537.0+0.5));
504 #endif
505 }
506
507 static inline Quantum ScaleShortToQuantum(const unsigned short value)
508 {
509 #if !defined(MAGICKCORE_HDRI_SUPPORT)
510   return((Quantum) (65537UL*value));
511 #else
512   return((Quantum) (65537.0*value));
513 #endif
514 }
515 #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
516 static inline Quantum ScaleCharToQuantum(const unsigned char value)
517 {
518   return((Quantum) (72340172838076673.0*value));
519 }
520
521 static inline Quantum ScaleLongToQuantum(const unsigned int value)
522 {
523   return((Quantum) (4294967297.0*value));
524 }
525
526 static inline Quantum ScaleMapToQuantum(const double value)
527 {
528   if (value <= 0.0)
529     return((Quantum) 0);
530   if (value >= MaxMap)
531     return(QuantumRange);
532   return((Quantum) (281479271743489.0*value));
533 }
534
535 static inline unsigned int ScaleQuantumToLong(const Quantum quantum)
536 {
537   return((unsigned int) (quantum/4294967297.0+0.5));
538 }
539
540 static inline unsigned int ScaleQuantumToMap(const Quantum quantum)
541 {
542   if (quantum <= 0.0)
543     return(0UL);
544   if ((quantum/281479271743489.0) >= MaxMap)
545     return((unsigned int) MaxMap);
546   return((unsigned int) (quantum/281479271743489.0+0.5));
547 }
548
549 static inline unsigned short ScaleQuantumToShort(const Quantum quantum)
550 {
551   if (quantum <= 0.0)
552     return(0);
553   if ((quantum/281479271743489.0) >= 65535.0)
554     return(65535);
555   return((unsigned short) (quantum/281479271743489.0+0.5));
556 }
557
558 static inline Quantum ScaleShortToQuantum(const unsigned short value)
559 {
560   return((Quantum) (281479271743489.0*value));
561 }
562 #endif
563
564 static inline unsigned short SinglePrecisionToHalf(const float value)
565 {
566   typedef union _SinglePrecision
567   {
568     unsigned int
569       fixed_point;
570
571     float
572       single_precision;
573   } SinglePrecision;
574
575   register int
576     exponent;
577
578   register unsigned int
579     significand,
580     sign_bit;
581
582   SinglePrecision
583     map;
584
585   unsigned short
586     half;
587
588   /*
589     The IEEE 754 standard specifies half precision as having:
590
591       Sign bit: 1 bit
592       Exponent width: 5 bits
593       Significand precision: 11 (10 explicitly stored)
594   */
595   map.single_precision=value;
596   sign_bit=(map.fixed_point >> 16) & 0x00008000;
597   exponent=(int) ((map.fixed_point >> ExponentShift) & 0x000000ff)-ExponentBias;
598   significand=map.fixed_point & 0x007fffff;
599   if (exponent <= 0)
600     {
601       int
602         shift;
603
604       if (exponent < -10)
605         return((unsigned short) sign_bit);
606       significand=significand | 0x00800000;
607       shift=(int) (14-exponent);
608       significand=(unsigned int) ((significand+((1 << (shift-1))-1)+
609         ((significand >> shift) & 0x01)) >> shift);
610       return((unsigned short) (sign_bit | significand));
611     }
612   else
613     if (exponent == (0xff-ExponentBias))
614       {
615         if (significand == 0)
616           return((unsigned short) (sign_bit | ExponentMask));
617         else
618           {
619             significand>>=SignificandShift;
620             half=(unsigned short) (sign_bit | significand |
621               (significand == 0) | ExponentMask);
622             return(half);
623           }
624       }
625   significand=significand+((significand >> SignificandShift) & 0x01)+0x00000fff;
626   if ((significand & 0x00800000) != 0)
627     {
628       significand=0;
629       exponent++;
630     }
631   if (exponent > 30)
632     {
633       float
634         alpha;
635
636       register int
637         i;
638
639       /*
640         Float overflow.
641       */
642       alpha=1.0e10;
643       for (i=0; i < 10; i++)
644         alpha*=alpha;
645       return((unsigned short) (sign_bit | ExponentMask));
646     }
647   half=(unsigned short) (sign_bit | (exponent << 10) |
648     (significand >> SignificandShift));
649   return(half);
650 }
651
652 #if defined(__cplusplus) || defined(c_plusplus)
653 }
654 #endif
655
656 #endif