• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %                QQQ   U   U   AAA   N   N  TTTTT  U   U  M   M               %
7 %               Q   Q  U   U  A   A  NN  N    T    U   U  MM MM               %
8 %               Q   Q  U   U  AAAAA  N N N    T    U   U  M M M               %
9 %               Q  QQ  U   U  A   A  N  NN    T    U   U  M   M               %
10 %                QQQQ   UUU   A   A  N   N    T     UUU   M   M               %
11 %                                                                             %
12 %             MagicCore Methods to Acquire / Destroy Quantum Pixels           %
13 %                                                                             %
14 %                             Software Design                                 %
15 %                                  Cristy                                     %
16 %                               October 1998                                  %
17 %                                                                             %
18 %                                                                             %
19 %  Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization      %
20 %  dedicated to making software imaging solutions freely available.           %
21 %                                                                             %
22 %  You may not use this file except in compliance with the License.  You may  %
23 %  obtain a copy of the License at                                            %
24 %                                                                             %
25 %    https://imagemagick.org/script/license.php                               %
26 %                                                                             %
27 %  Unless required by applicable law or agreed to in writing, software        %
28 %  distributed under the License is distributed on an "AS IS" BASIS,          %
29 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
30 %  See the License for the specific language governing permissions and        %
31 %  limitations under the License.                                             %
32 %                                                                             %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 %
35 %
36 */
37 
38 /*
39   Include declarations.
40 */
41 #include "MagickCore/studio.h"
42 #include "MagickCore/attribute.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/blob-private.h"
45 #include "MagickCore/color-private.h"
46 #include "MagickCore/exception.h"
47 #include "MagickCore/exception-private.h"
48 #include "MagickCore/cache.h"
49 #include "MagickCore/cache-private.h"
50 #include "MagickCore/colorspace.h"
51 #include "MagickCore/colorspace-private.h"
52 #include "MagickCore/constitute.h"
53 #include "MagickCore/delegate.h"
54 #include "MagickCore/geometry.h"
55 #include "MagickCore/list.h"
56 #include "MagickCore/magick.h"
57 #include "MagickCore/memory_.h"
58 #include "MagickCore/memory-private.h"
59 #include "MagickCore/monitor.h"
60 #include "MagickCore/option.h"
61 #include "MagickCore/pixel.h"
62 #include "MagickCore/pixel-accessor.h"
63 #include "MagickCore/property.h"
64 #include "MagickCore/quantum.h"
65 #include "MagickCore/quantum-private.h"
66 #include "MagickCore/resource_.h"
67 #include "MagickCore/semaphore.h"
68 #include "MagickCore/statistic.h"
69 #include "MagickCore/stream.h"
70 #include "MagickCore/string_.h"
71 #include "MagickCore/string-private.h"
72 #include "MagickCore/thread-private.h"
73 #include "MagickCore/utility.h"
74 
75 /*
76   Define declarations.
77 */
78 #define QuantumSignature  0xab
79 
80 /*
81   Forward declarations.
82 */
83 static void
84   DestroyQuantumPixels(QuantumInfo *);
85 
86 /*
87 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
88 %                                                                             %
89 %                                                                             %
90 %                                                                             %
91 %   A c q u i r e Q u a n t u m I n f o                                       %
92 %                                                                             %
93 %                                                                             %
94 %                                                                             %
95 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
96 %
97 %  AcquireQuantumInfo() allocates the QuantumInfo structure.
98 %
99 %  The format of the AcquireQuantumInfo method is:
100 %
101 %      QuantumInfo *AcquireQuantumInfo(const ImageInfo *image_info,Image *image)
102 %
103 %  A description of each parameter follows:
104 %
105 %    o image_info: the image info.
106 %
107 %    o image: the image.
108 %
109 */
AcquireQuantumInfo(const ImageInfo * image_info,Image * image)110 MagickExport QuantumInfo *AcquireQuantumInfo(const ImageInfo *image_info,
111   Image *image)
112 {
113   MagickBooleanType
114     status;
115 
116   QuantumInfo
117     *quantum_info;
118 
119   quantum_info=(QuantumInfo *) AcquireCriticalMemory(sizeof(*quantum_info));
120   quantum_info->signature=MagickCoreSignature;
121   GetQuantumInfo(image_info,quantum_info);
122   if (image == (const Image *) NULL)
123     return(quantum_info);
124   status=SetQuantumDepth(image,quantum_info,image->depth);
125   quantum_info->endian=image->endian;
126   if (status == MagickFalse)
127     quantum_info=DestroyQuantumInfo(quantum_info);
128   return(quantum_info);
129 }
130 
131 /*
132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
133 %                                                                             %
134 %                                                                             %
135 %                                                                             %
136 +   A c q u i r e Q u a n t u m P i x e l s                                   %
137 %                                                                             %
138 %                                                                             %
139 %                                                                             %
140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
141 %
142 %  AcquireQuantumPixels() allocates the pixel staging areas.
143 %
144 %  The format of the AcquireQuantumPixels method is:
145 %
146 %      MagickBooleanType AcquireQuantumPixels(QuantumInfo *quantum_info,
147 %        const size_t extent)
148 %
149 %  A description of each parameter follows:
150 %
151 %    o quantum_info: the quantum info.
152 %
153 %    o extent: the quantum info.
154 %
155 */
AcquireQuantumPixels(QuantumInfo * quantum_info,const size_t extent)156 static MagickBooleanType AcquireQuantumPixels(QuantumInfo *quantum_info,
157   const size_t extent)
158 {
159   register ssize_t
160     i;
161 
162   assert(quantum_info != (QuantumInfo *) NULL);
163   assert(quantum_info->signature == MagickCoreSignature);
164   quantum_info->number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
165   quantum_info->pixels=(MemoryInfo **) AcquireQuantumMemory(
166     quantum_info->number_threads,sizeof(*quantum_info->pixels));
167   if (quantum_info->pixels == (MemoryInfo **) NULL)
168     return(MagickFalse);
169   quantum_info->extent=extent;
170   (void) memset(quantum_info->pixels,0,quantum_info->number_threads*
171     sizeof(*quantum_info->pixels));
172   for (i=0; i < (ssize_t) quantum_info->number_threads; i++)
173   {
174     unsigned char
175       *pixels;
176 
177     quantum_info->pixels[i]=AcquireVirtualMemory((extent+1),sizeof(*pixels));
178     if (quantum_info->pixels[i] == (MemoryInfo *) NULL)
179       {
180         DestroyQuantumPixels(quantum_info);
181         return(MagickFalse);
182       }
183     pixels=(unsigned char *)  GetVirtualMemoryBlob(quantum_info->pixels[i]);
184     (void) memset(pixels,0,(extent+1)*sizeof(*pixels));
185     pixels[extent]=QuantumSignature;
186   }
187   return(MagickTrue);
188 }
189 
190 /*
191 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
192 %                                                                             %
193 %                                                                             %
194 %                                                                             %
195 %   D e s t r o y Q u a n t u m I n f o                                       %
196 %                                                                             %
197 %                                                                             %
198 %                                                                             %
199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
200 %
201 %  DestroyQuantumInfo() deallocates memory associated with the QuantumInfo
202 %  structure.
203 %
204 %  The format of the DestroyQuantumInfo method is:
205 %
206 %      QuantumInfo *DestroyQuantumInfo(QuantumInfo *quantum_info)
207 %
208 %  A description of each parameter follows:
209 %
210 %    o quantum_info: the quantum info.
211 %
212 */
DestroyQuantumInfo(QuantumInfo * quantum_info)213 MagickExport QuantumInfo *DestroyQuantumInfo(QuantumInfo *quantum_info)
214 {
215   assert(quantum_info != (QuantumInfo *) NULL);
216   assert(quantum_info->signature == MagickCoreSignature);
217   if (quantum_info->pixels != (MemoryInfo **) NULL)
218     DestroyQuantumPixels(quantum_info);
219   if (quantum_info->semaphore != (SemaphoreInfo *) NULL)
220     RelinquishSemaphoreInfo(&quantum_info->semaphore);
221   quantum_info->signature=(~MagickCoreSignature);
222   quantum_info=(QuantumInfo *) RelinquishMagickMemory(quantum_info);
223   return(quantum_info);
224 }
225 
226 /*
227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
228 %                                                                             %
229 %                                                                             %
230 %                                                                             %
231 +   D e s t r o y Q u a n t u m P i x e l s                                   %
232 %                                                                             %
233 %                                                                             %
234 %                                                                             %
235 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
236 %
237 %  DestroyQuantumPixels() destroys the quantum pixels.
238 %
239 %  The format of the DestroyQuantumPixels() method is:
240 %
241 %      void DestroyQuantumPixels(QuantumInfo *quantum_info)
242 %
243 %  A description of each parameter follows:
244 %
245 %    o quantum_info: the quantum info.
246 %
247 */
DestroyQuantumPixels(QuantumInfo * quantum_info)248 static void DestroyQuantumPixels(QuantumInfo *quantum_info)
249 {
250   register ssize_t
251     i;
252 
253   ssize_t
254     extent;
255 
256   assert(quantum_info != (QuantumInfo *) NULL);
257   assert(quantum_info->signature == MagickCoreSignature);
258   assert(quantum_info->pixels != (MemoryInfo **) NULL);
259   extent=(ssize_t) quantum_info->extent;
260   for (i=0; i < (ssize_t) quantum_info->number_threads; i++)
261     if (quantum_info->pixels[i] != (MemoryInfo *) NULL)
262       {
263         unsigned char
264           *pixels;
265 
266         /*
267           Did we overrun our quantum buffer?
268         */
269         pixels=(unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[i]);
270         assert(pixels[extent] == QuantumSignature);
271         quantum_info->pixels[i]=RelinquishVirtualMemory(
272           quantum_info->pixels[i]);
273       }
274   quantum_info->pixels=(MemoryInfo **) RelinquishMagickMemory(
275     quantum_info->pixels);
276 }
277 
278 /*
279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
280 %                                                                             %
281 %                                                                             %
282 %                                                                             %
283 %   G e t Q u a n t u m E x t e n t                                           %
284 %                                                                             %
285 %                                                                             %
286 %                                                                             %
287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
288 %
289 %  GetQuantumExtent() returns the quantum pixel buffer extent.
290 %
291 %  The format of the GetQuantumExtent method is:
292 %
293 %      size_t GetQuantumExtent(Image *image,const QuantumInfo *quantum_info,
294 %        const QuantumType quantum_type)
295 %
296 %  A description of each parameter follows:
297 %
298 %    o image: the image.
299 %
300 %    o quantum_info: the quantum info.
301 %
302 %    o quantum_type: Declare which pixel components to transfer (red, green,
303 %      blue, opacity, RGB, or RGBA).
304 %
305 */
GetQuantumExtent(const Image * image,const QuantumInfo * quantum_info,const QuantumType quantum_type)306 MagickExport size_t GetQuantumExtent(const Image *image,
307   const QuantumInfo *quantum_info,const QuantumType quantum_type)
308 {
309   size_t
310     packet_size;
311 
312   assert(quantum_info != (QuantumInfo *) NULL);
313   assert(quantum_info->signature == MagickCoreSignature);
314   packet_size=1;
315   switch (quantum_type)
316   {
317     case GrayAlphaQuantum: packet_size=2; break;
318     case IndexAlphaQuantum: packet_size=2; break;
319     case RGBQuantum: packet_size=3; break;
320     case BGRQuantum: packet_size=3; break;
321     case RGBAQuantum: packet_size=4; break;
322     case RGBOQuantum: packet_size=4; break;
323     case BGRAQuantum: packet_size=4; break;
324     case CMYKQuantum: packet_size=4; break;
325     case CMYKAQuantum: packet_size=5; break;
326     case CbYCrAQuantum: packet_size=4; break;
327     case CbYCrQuantum: packet_size=3; break;
328     case CbYCrYQuantum: packet_size=4; break;
329     default: break;
330   }
331   if (quantum_info->pack == MagickFalse)
332     return((size_t) (packet_size*image->columns*((quantum_info->depth+7)/8)));
333   return((size_t) ((packet_size*image->columns*quantum_info->depth+7)/8));
334 }
335 
336 /*
337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
338 %                                                                             %
339 %                                                                             %
340 %                                                                             %
341 %   G e t Q u a n t u m E n d i a n                                           %
342 %                                                                             %
343 %                                                                             %
344 %                                                                             %
345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
346 %
347 %  GetQuantumEndian() returns the quantum endian of the image.
348 %
349 %  The endian of the GetQuantumEndian method is:
350 %
351 %      EndianType GetQuantumEndian(const QuantumInfo *quantum_info)
352 %
353 %  A description of each parameter follows:
354 %
355 %    o quantum_info: the quantum info.
356 %
357 */
GetQuantumEndian(const QuantumInfo * quantum_info)358 MagickExport EndianType GetQuantumEndian(const QuantumInfo *quantum_info)
359 {
360   assert(quantum_info != (QuantumInfo *) NULL);
361   assert(quantum_info->signature == MagickCoreSignature);
362   return(quantum_info->endian);
363 }
364 
365 /*
366 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
367 %                                                                             %
368 %                                                                             %
369 %                                                                             %
370 %   G e t Q u a n t u m F o r m a t                                           %
371 %                                                                             %
372 %                                                                             %
373 %                                                                             %
374 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
375 %
376 %  GetQuantumFormat() returns the quantum format of the image.
377 %
378 %  The format of the GetQuantumFormat method is:
379 %
380 %      QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info)
381 %
382 %  A description of each parameter follows:
383 %
384 %    o quantum_info: the quantum info.
385 %
386 */
GetQuantumFormat(const QuantumInfo * quantum_info)387 MagickExport QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info)
388 {
389   assert(quantum_info != (QuantumInfo *) NULL);
390   assert(quantum_info->signature == MagickCoreSignature);
391   return(quantum_info->format);
392 }
393 
394 /*
395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
396 %                                                                             %
397 %                                                                             %
398 %                                                                             %
399 %   G e t Q u a n t u m I n f o                                               %
400 %                                                                             %
401 %                                                                             %
402 %                                                                             %
403 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
404 %
405 %  GetQuantumInfo() initializes the QuantumInfo structure to default values.
406 %
407 %  The format of the GetQuantumInfo method is:
408 %
409 %      GetQuantumInfo(const ImageInfo *image_info,QuantumInfo *quantum_info)
410 %
411 %  A description of each parameter follows:
412 %
413 %    o image_info: the image info.
414 %
415 %    o quantum_info: the quantum info.
416 %
417 */
GetQuantumInfo(const ImageInfo * image_info,QuantumInfo * quantum_info)418 MagickExport void GetQuantumInfo(const ImageInfo *image_info,
419   QuantumInfo *quantum_info)
420 {
421   const char
422     *option;
423 
424   assert(quantum_info != (QuantumInfo *) NULL);
425   (void) memset(quantum_info,0,sizeof(*quantum_info));
426   quantum_info->quantum=8;
427   quantum_info->maximum=1.0;
428   quantum_info->scale=QuantumRange;
429   quantum_info->pack=MagickTrue;
430   quantum_info->semaphore=AcquireSemaphoreInfo();
431   quantum_info->signature=MagickCoreSignature;
432   if (image_info == (const ImageInfo *) NULL)
433     return;
434   option=GetImageOption(image_info,"quantum:format");
435   if (option != (char *) NULL)
436     quantum_info->format=(QuantumFormatType) ParseCommandOption(
437       MagickQuantumFormatOptions,MagickFalse,option);
438   option=GetImageOption(image_info,"quantum:minimum");
439   if (option != (char *) NULL)
440     quantum_info->minimum=StringToDouble(option,(char **) NULL);
441   option=GetImageOption(image_info,"quantum:maximum");
442   if (option != (char *) NULL)
443     quantum_info->maximum=StringToDouble(option,(char **) NULL);
444   if ((quantum_info->minimum == 0.0) && (quantum_info->maximum == 0.0))
445     quantum_info->scale=0.0;
446   else
447     if (quantum_info->minimum == quantum_info->maximum)
448       {
449         quantum_info->scale=(double) QuantumRange/quantum_info->minimum;
450         quantum_info->minimum=0.0;
451       }
452     else
453       quantum_info->scale=(double) QuantumRange/(quantum_info->maximum-
454         quantum_info->minimum);
455   option=GetImageOption(image_info,"quantum:scale");
456   if (option != (char *) NULL)
457     quantum_info->scale=StringToDouble(option,(char **) NULL);
458   option=GetImageOption(image_info,"quantum:polarity");
459   if (option != (char *) NULL)
460     quantum_info->min_is_white=LocaleCompare(option,"min-is-white") == 0 ?
461       MagickTrue : MagickFalse;
462   quantum_info->endian=image_info->endian;
463   ResetQuantumState(quantum_info);
464 }
465 
466 /*
467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
468 %                                                                             %
469 %                                                                             %
470 %                                                                             %
471 %   G e t Q u a n t u m P i x e l s                                           %
472 %                                                                             %
473 %                                                                             %
474 %                                                                             %
475 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
476 %
477 %  GetQuantumPixels() returns the quantum pixels.
478 %
479 %  The format of the GetQuantumPixels method is:
480 %
481 %      unsigned char *QuantumPixels GetQuantumPixels(
482 %        const QuantumInfo *quantum_info)
483 %
484 %  A description of each parameter follows:
485 %
486 %    o image: the image.
487 %
488 */
GetQuantumPixels(const QuantumInfo * quantum_info)489 MagickExport unsigned char *GetQuantumPixels(const QuantumInfo *quantum_info)
490 {
491   const int
492     id = GetOpenMPThreadId();
493 
494   assert(quantum_info != (QuantumInfo *) NULL);
495   assert(quantum_info->signature == MagickCoreSignature);
496   return((unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[id]));
497 }
498 
499 /*
500 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
501 %                                                                             %
502 %                                                                             %
503 %                                                                             %
504 %   G e t Q u a n t u m T y p e                                               %
505 %                                                                             %
506 %                                                                             %
507 %                                                                             %
508 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
509 %
510 %  GetQuantumType() returns the quantum type of the image.
511 %
512 %  The format of the GetQuantumType method is:
513 %
514 %      QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
515 %
516 %  A description of each parameter follows:
517 %
518 %    o image: the image.
519 %
520 %    o exception: return any errors or warnings in this structure.
521 %
522 */
GetQuantumType(Image * image,ExceptionInfo * exception)523 MagickExport QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
524 {
525   QuantumType
526     quantum_type;
527 
528   assert(image != (Image *) NULL);
529   assert(image->signature == MagickCoreSignature);
530   if (image->debug != MagickFalse)
531     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
532   (void) exception;
533   quantum_type=RGBQuantum;
534   if (image->alpha_trait != UndefinedPixelTrait)
535     quantum_type=RGBAQuantum;
536   if (image->colorspace == CMYKColorspace)
537     {
538       quantum_type=CMYKQuantum;
539       if (image->alpha_trait != UndefinedPixelTrait)
540         quantum_type=CMYKAQuantum;
541     }
542   if (IsGrayColorspace(image->colorspace) != MagickFalse)
543     {
544       quantum_type=GrayQuantum;
545       if (image->alpha_trait != UndefinedPixelTrait)
546         quantum_type=GrayAlphaQuantum;
547     }
548   if (image->storage_class == PseudoClass)
549     {
550       quantum_type=IndexQuantum;
551       if (image->alpha_trait != UndefinedPixelTrait)
552         quantum_type=IndexAlphaQuantum;
553     }
554   return(quantum_type);
555 }
556 
557 /*
558 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
559 %                                                                             %
560 %                                                                             %
561 %                                                                             %
562 +   R e s e t Q u a n t u m S t a t e                                         %
563 %                                                                             %
564 %                                                                             %
565 %                                                                             %
566 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
567 %
568 %  ResetQuantumState() resets the quantum state.
569 %
570 %  The format of the ResetQuantumState method is:
571 %
572 %      void ResetQuantumState(QuantumInfo *quantum_info)
573 %
574 %  A description of each parameter follows:
575 %
576 %    o quantum_info: the quantum info.
577 %
578 */
ResetQuantumState(QuantumInfo * quantum_info)579 MagickPrivate void ResetQuantumState(QuantumInfo *quantum_info)
580 {
581   static const unsigned int mask[32] =
582   {
583     0x00000000U, 0x00000001U, 0x00000003U, 0x00000007U, 0x0000000fU,
584     0x0000001fU, 0x0000003fU, 0x0000007fU, 0x000000ffU, 0x000001ffU,
585     0x000003ffU, 0x000007ffU, 0x00000fffU, 0x00001fffU, 0x00003fffU,
586     0x00007fffU, 0x0000ffffU, 0x0001ffffU, 0x0003ffffU, 0x0007ffffU,
587     0x000fffffU, 0x001fffffU, 0x003fffffU, 0x007fffffU, 0x00ffffffU,
588     0x01ffffffU, 0x03ffffffU, 0x07ffffffU, 0x0fffffffU, 0x1fffffffU,
589     0x3fffffffU, 0x7fffffffU
590   };
591 
592   assert(quantum_info != (QuantumInfo *) NULL);
593   assert(quantum_info->signature == MagickCoreSignature);
594   quantum_info->state.inverse_scale=1.0;
595   if (fabs(quantum_info->scale) >= MagickEpsilon)
596     quantum_info->state.inverse_scale/=quantum_info->scale;
597   quantum_info->state.pixel=0U;
598   quantum_info->state.bits=0U;
599   quantum_info->state.mask=mask;
600 }
601 
602 /*
603 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
604 %                                                                             %
605 %                                                                             %
606 %                                                                             %
607 %   S e t Q u a n t u m F o r m a t                                           %
608 %                                                                             %
609 %                                                                             %
610 %                                                                             %
611 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
612 %
613 %  SetQuantumAlphaType() sets the quantum format.
614 %
615 %  The format of the SetQuantumAlphaType method is:
616 %
617 %      void SetQuantumAlphaType(QuantumInfo *quantum_info,
618 %        const QuantumAlphaType type)
619 %
620 %  A description of each parameter follows:
621 %
622 %    o quantum_info: the quantum info.
623 %
624 %    o type: the alpha type (e.g. associate).
625 %
626 */
SetQuantumAlphaType(QuantumInfo * quantum_info,const QuantumAlphaType type)627 MagickExport void SetQuantumAlphaType(QuantumInfo *quantum_info,
628   const QuantumAlphaType type)
629 {
630   assert(quantum_info != (QuantumInfo *) NULL);
631   assert(quantum_info->signature == MagickCoreSignature);
632   quantum_info->alpha_type=type;
633 }
634 
635 /*
636 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
637 %                                                                             %
638 %                                                                             %
639 %                                                                             %
640 %   S e t Q u a n t u m D e p t h                                             %
641 %                                                                             %
642 %                                                                             %
643 %                                                                             %
644 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
645 %
646 %  SetQuantumDepth() sets the quantum depth.
647 %
648 %  The format of the SetQuantumDepth method is:
649 %
650 %      MagickBooleanType SetQuantumDepth(const Image *image,
651 %        QuantumInfo *quantum_info,const size_t depth)
652 %
653 %  A description of each parameter follows:
654 %
655 %    o image: the image.
656 %
657 %    o quantum_info: the quantum info.
658 %
659 %    o depth: the quantum depth.
660 %
661 */
SetQuantumDepth(const Image * image,QuantumInfo * quantum_info,const size_t depth)662 MagickExport MagickBooleanType SetQuantumDepth(const Image *image,
663   QuantumInfo *quantum_info,const size_t depth)
664 {
665   size_t
666     extent,
667     quantum;
668 
669   /*
670     Allocate the quantum pixel buffer.
671   */
672   assert(image != (Image *) NULL);
673   assert(image->signature == MagickCoreSignature);
674   if (image->debug != MagickFalse)
675     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
676   assert(quantum_info != (QuantumInfo *) NULL);
677   assert(quantum_info->signature == MagickCoreSignature);
678   quantum_info->depth=depth;
679   if (quantum_info->format == FloatingPointQuantumFormat)
680     {
681       if (quantum_info->depth > 32)
682         quantum_info->depth=64;
683       else
684         if (quantum_info->depth > 16)
685           quantum_info->depth=32;
686         else
687           quantum_info->depth=16;
688     }
689   if (quantum_info->pixels != (MemoryInfo **) NULL)
690     DestroyQuantumPixels(quantum_info);
691   quantum=(quantum_info->pad+MaxPixelChannels)*(quantum_info->depth+7)/8;
692   extent=MagickMax(image->columns,image->rows)*quantum;
693   if ((MagickMax(image->columns,image->rows) != 0) &&
694       (quantum != (extent/MagickMax(image->columns,image->rows))))
695     return(MagickFalse);
696   return(AcquireQuantumPixels(quantum_info,extent));
697 }
698 
699 /*
700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
701 %                                                                             %
702 %                                                                             %
703 %                                                                             %
704 %   S e t Q u a n t u m E n d i a n                                           %
705 %                                                                             %
706 %                                                                             %
707 %                                                                             %
708 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
709 %
710 %  SetQuantumEndian() sets the quantum endian.
711 %
712 %  The endian of the SetQuantumEndian method is:
713 %
714 %      MagickBooleanType SetQuantumEndian(const Image *image,
715 %        QuantumInfo *quantum_info,const EndianType endian)
716 %
717 %  A description of each parameter follows:
718 %
719 %    o image: the image.
720 %
721 %    o quantum_info: the quantum info.
722 %
723 %    o endian: the quantum endian.
724 %
725 */
SetQuantumEndian(const Image * image,QuantumInfo * quantum_info,const EndianType endian)726 MagickExport MagickBooleanType SetQuantumEndian(const Image *image,
727   QuantumInfo *quantum_info,const EndianType endian)
728 {
729   assert(image != (Image *) NULL);
730   assert(image->signature == MagickCoreSignature);
731   if (image->debug != MagickFalse)
732     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
733   assert(quantum_info != (QuantumInfo *) NULL);
734   assert(quantum_info->signature == MagickCoreSignature);
735   quantum_info->endian=endian;
736   return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
737 }
738 
739 /*
740 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
741 %                                                                             %
742 %                                                                             %
743 %                                                                             %
744 %   S e t Q u a n t u m F o r m a t                                           %
745 %                                                                             %
746 %                                                                             %
747 %                                                                             %
748 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
749 %
750 %  SetQuantumFormat() sets the quantum format.
751 %
752 %  The format of the SetQuantumFormat method is:
753 %
754 %      MagickBooleanType SetQuantumFormat(const Image *image,
755 %        QuantumInfo *quantum_info,const QuantumFormatType format)
756 %
757 %  A description of each parameter follows:
758 %
759 %    o image: the image.
760 %
761 %    o quantum_info: the quantum info.
762 %
763 %    o format: the quantum format.
764 %
765 */
SetQuantumFormat(const Image * image,QuantumInfo * quantum_info,const QuantumFormatType format)766 MagickExport MagickBooleanType SetQuantumFormat(const Image *image,
767   QuantumInfo *quantum_info,const QuantumFormatType format)
768 {
769   assert(image != (Image *) NULL);
770   assert(image->signature == MagickCoreSignature);
771   if (image->debug != MagickFalse)
772     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
773   assert(quantum_info != (QuantumInfo *) NULL);
774   assert(quantum_info->signature == MagickCoreSignature);
775   quantum_info->format=format;
776   return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
777 }
778 
779 /*
780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
781 %                                                                             %
782 %                                                                             %
783 %                                                                             %
784 %   S e t Q u a n t u m I m a g e T y p e                                     %
785 %                                                                             %
786 %                                                                             %
787 %                                                                             %
788 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
789 %
790 %  SetQuantumImageType() sets the image type based on the quantum type.
791 %
792 %  The format of the SetQuantumImageType method is:
793 %
794 %      void ImageType SetQuantumImageType(Image *image,
795 %        const QuantumType quantum_type)
796 %
797 %  A description of each parameter follows:
798 %
799 %    o image: the image.
800 %
801 %    o quantum_type: Declare which pixel components to transfer (red, green,
802 %      blue, opacity, RGB, or RGBA).
803 %
804 */
SetQuantumImageType(Image * image,const QuantumType quantum_type)805 MagickExport void SetQuantumImageType(Image *image,
806   const QuantumType quantum_type)
807 {
808   assert(image != (Image *) NULL);
809   assert(image->signature == MagickCoreSignature);
810   if (image->debug != MagickFalse)
811     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
812   switch (quantum_type)
813   {
814     case IndexQuantum:
815     case IndexAlphaQuantum:
816     {
817       image->type=PaletteType;
818       break;
819     }
820     case GrayQuantum:
821     case GrayAlphaQuantum:
822     {
823       image->type=GrayscaleType;
824       if (image->depth == 1)
825         image->type=BilevelType;
826       break;
827     }
828     case CyanQuantum:
829     case MagentaQuantum:
830     case YellowQuantum:
831     case BlackQuantum:
832     case CMYKQuantum:
833     case CMYKAQuantum:
834     {
835       image->type=ColorSeparationType;
836       break;
837     }
838     default:
839     {
840       image->type=TrueColorType;
841       break;
842     }
843   }
844 }
845 
846 /*
847 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
848 %                                                                             %
849 %                                                                             %
850 %                                                                             %
851 %   S e t Q u a n t u m P a c k                                               %
852 %                                                                             %
853 %                                                                             %
854 %                                                                             %
855 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
856 %
857 %  SetQuantumPack() sets the quantum pack flag.
858 %
859 %  The format of the SetQuantumPack method is:
860 %
861 %      void SetQuantumPack(QuantumInfo *quantum_info,
862 %        const MagickBooleanType pack)
863 %
864 %  A description of each parameter follows:
865 %
866 %    o quantum_info: the quantum info.
867 %
868 %    o pack: the pack flag.
869 %
870 */
SetQuantumPack(QuantumInfo * quantum_info,const MagickBooleanType pack)871 MagickExport void SetQuantumPack(QuantumInfo *quantum_info,
872   const MagickBooleanType pack)
873 {
874   assert(quantum_info != (QuantumInfo *) NULL);
875   assert(quantum_info->signature == MagickCoreSignature);
876   quantum_info->pack=pack;
877 }
878 
879 /*
880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
881 %                                                                             %
882 %                                                                             %
883 %                                                                             %
884 %   S e t Q u a n t u m P a d                                                 %
885 %                                                                             %
886 %                                                                             %
887 %                                                                             %
888 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
889 %
890 %  SetQuantumPad() sets the quantum pad.
891 %
892 %  The format of the SetQuantumPad method is:
893 %
894 %      MagickBooleanType SetQuantumPad(const Image *image,
895 %        QuantumInfo *quantum_info,const size_t pad)
896 %
897 %  A description of each parameter follows:
898 %
899 %    o image: the image.
900 %
901 %    o quantum_info: the quantum info.
902 %
903 %    o pad: the quantum pad.
904 %
905 */
SetQuantumPad(const Image * image,QuantumInfo * quantum_info,const size_t pad)906 MagickExport MagickBooleanType SetQuantumPad(const Image *image,
907   QuantumInfo *quantum_info,const size_t pad)
908 {
909   assert(image != (Image *) NULL);
910   assert(image->signature == MagickCoreSignature);
911   if (image->debug != MagickFalse)
912     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
913   assert(quantum_info != (QuantumInfo *) NULL);
914   assert(quantum_info->signature == MagickCoreSignature);
915   quantum_info->pad=pad;
916   return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
917 }
918 
919 /*
920 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
921 %                                                                             %
922 %                                                                             %
923 %                                                                             %
924 %   S e t Q u a n t u m M i n I s W h i t e                                   %
925 %                                                                             %
926 %                                                                             %
927 %                                                                             %
928 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
929 %
930 %  SetQuantumMinIsWhite() sets the quantum min-is-white flag.
931 %
932 %  The format of the SetQuantumMinIsWhite method is:
933 %
934 %      void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
935 %        const MagickBooleanType min_is_white)
936 %
937 %  A description of each parameter follows:
938 %
939 %    o quantum_info: the quantum info.
940 %
941 %    o min_is_white: the min-is-white flag.
942 %
943 */
SetQuantumMinIsWhite(QuantumInfo * quantum_info,const MagickBooleanType min_is_white)944 MagickExport void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
945   const MagickBooleanType min_is_white)
946 {
947   assert(quantum_info != (QuantumInfo *) NULL);
948   assert(quantum_info->signature == MagickCoreSignature);
949   quantum_info->min_is_white=min_is_white;
950 }
951 
952 /*
953 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
954 %                                                                             %
955 %                                                                             %
956 %                                                                             %
957 %   S e t Q u a n t u m Q u a n t u m                                         %
958 %                                                                             %
959 %                                                                             %
960 %                                                                             %
961 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
962 %
963 %  SetQuantumQuantum() sets the quantum quantum.
964 %
965 %  The format of the SetQuantumQuantum method is:
966 %
967 %      void SetQuantumQuantum(QuantumInfo *quantum_info,
968 %        const size_t quantum)
969 %
970 %  A description of each parameter follows:
971 %
972 %    o quantum_info: the quantum info.
973 %
974 %    o quantum: the quantum quantum.
975 %
976 */
SetQuantumQuantum(QuantumInfo * quantum_info,const size_t quantum)977 MagickExport void SetQuantumQuantum(QuantumInfo *quantum_info,
978   const size_t quantum)
979 {
980   assert(quantum_info != (QuantumInfo *) NULL);
981   assert(quantum_info->signature == MagickCoreSignature);
982   quantum_info->quantum=quantum;
983 }
984 
985 /*
986 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
987 %                                                                             %
988 %                                                                             %
989 %                                                                             %
990 %   S e t Q u a n t u m S c a l e                                             %
991 %                                                                             %
992 %                                                                             %
993 %                                                                             %
994 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
995 %
996 %  SetQuantumScale() sets the quantum scale.
997 %
998 %  The format of the SetQuantumScale method is:
999 %
1000 %      void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1001 %
1002 %  A description of each parameter follows:
1003 %
1004 %    o quantum_info: the quantum info.
1005 %
1006 %    o scale: the quantum scale.
1007 %
1008 */
SetQuantumScale(QuantumInfo * quantum_info,const double scale)1009 MagickExport void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1010 {
1011   assert(quantum_info != (QuantumInfo *) NULL);
1012   assert(quantum_info->signature == MagickCoreSignature);
1013   quantum_info->scale=scale;
1014 }
1015