• 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-2021 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   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   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=MagickMin(depth,64);
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 > 24)
685           quantum_info->depth=32;
686         else
687           if (quantum_info->depth > 16)
688             quantum_info->depth=24;
689           else
690             quantum_info->depth=16;
691     }
692   if (quantum_info->pixels != (MemoryInfo **) NULL)
693     DestroyQuantumPixels(quantum_info);
694   quantum=(quantum_info->pad+MaxPixelChannels)*(quantum_info->depth+7)/8;
695   extent=MagickMax(image->columns,image->rows)*quantum;
696   if ((MagickMax(image->columns,image->rows) != 0) &&
697       (quantum != (extent/MagickMax(image->columns,image->rows))))
698     return(MagickFalse);
699   return(AcquireQuantumPixels(quantum_info,extent));
700 }
701 
702 /*
703 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
704 %                                                                             %
705 %                                                                             %
706 %                                                                             %
707 %   S e t Q u a n t u m E n d i a n                                           %
708 %                                                                             %
709 %                                                                             %
710 %                                                                             %
711 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
712 %
713 %  SetQuantumEndian() sets the quantum endian.
714 %
715 %  The endian of the SetQuantumEndian method is:
716 %
717 %      MagickBooleanType SetQuantumEndian(const Image *image,
718 %        QuantumInfo *quantum_info,const EndianType endian)
719 %
720 %  A description of each parameter follows:
721 %
722 %    o image: the image.
723 %
724 %    o quantum_info: the quantum info.
725 %
726 %    o endian: the quantum endian.
727 %
728 */
SetQuantumEndian(const Image * image,QuantumInfo * quantum_info,const EndianType endian)729 MagickExport MagickBooleanType SetQuantumEndian(const Image *image,
730   QuantumInfo *quantum_info,const EndianType endian)
731 {
732   assert(image != (Image *) NULL);
733   assert(image->signature == MagickCoreSignature);
734   if (image->debug != MagickFalse)
735     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
736   assert(quantum_info != (QuantumInfo *) NULL);
737   assert(quantum_info->signature == MagickCoreSignature);
738   quantum_info->endian=endian;
739   return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
740 }
741 
742 /*
743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
744 %                                                                             %
745 %                                                                             %
746 %                                                                             %
747 %   S e t Q u a n t u m F o r m a t                                           %
748 %                                                                             %
749 %                                                                             %
750 %                                                                             %
751 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
752 %
753 %  SetQuantumFormat() sets the quantum format.
754 %
755 %  The format of the SetQuantumFormat method is:
756 %
757 %      MagickBooleanType SetQuantumFormat(const Image *image,
758 %        QuantumInfo *quantum_info,const QuantumFormatType format)
759 %
760 %  A description of each parameter follows:
761 %
762 %    o image: the image.
763 %
764 %    o quantum_info: the quantum info.
765 %
766 %    o format: the quantum format.
767 %
768 */
SetQuantumFormat(const Image * image,QuantumInfo * quantum_info,const QuantumFormatType format)769 MagickExport MagickBooleanType SetQuantumFormat(const Image *image,
770   QuantumInfo *quantum_info,const QuantumFormatType format)
771 {
772   assert(image != (Image *) NULL);
773   assert(image->signature == MagickCoreSignature);
774   if (image->debug != MagickFalse)
775     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
776   assert(quantum_info != (QuantumInfo *) NULL);
777   assert(quantum_info->signature == MagickCoreSignature);
778   quantum_info->format=format;
779   return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
780 }
781 
782 /*
783 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
784 %                                                                             %
785 %                                                                             %
786 %                                                                             %
787 %   S e t Q u a n t u m I m a g e T y p e                                     %
788 %                                                                             %
789 %                                                                             %
790 %                                                                             %
791 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
792 %
793 %  SetQuantumImageType() sets the image type based on the quantum type.
794 %
795 %  The format of the SetQuantumImageType method is:
796 %
797 %      void ImageType SetQuantumImageType(Image *image,
798 %        const QuantumType quantum_type)
799 %
800 %  A description of each parameter follows:
801 %
802 %    o image: the image.
803 %
804 %    o quantum_type: Declare which pixel components to transfer (red, green,
805 %      blue, opacity, RGB, or RGBA).
806 %
807 */
SetQuantumImageType(Image * image,const QuantumType quantum_type)808 MagickExport void SetQuantumImageType(Image *image,
809   const QuantumType quantum_type)
810 {
811   assert(image != (Image *) NULL);
812   assert(image->signature == MagickCoreSignature);
813   if (image->debug != MagickFalse)
814     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
815   switch (quantum_type)
816   {
817     case IndexQuantum:
818     case IndexAlphaQuantum:
819     {
820       image->type=PaletteType;
821       break;
822     }
823     case GrayQuantum:
824     case GrayAlphaQuantum:
825     {
826       image->type=GrayscaleType;
827       if (image->depth == 1)
828         image->type=BilevelType;
829       break;
830     }
831     case CyanQuantum:
832     case MagentaQuantum:
833     case YellowQuantum:
834     case BlackQuantum:
835     case CMYKQuantum:
836     case CMYKAQuantum:
837     {
838       image->type=ColorSeparationType;
839       break;
840     }
841     default:
842     {
843       image->type=TrueColorType;
844       break;
845     }
846   }
847 }
848 
849 /*
850 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
851 %                                                                             %
852 %                                                                             %
853 %                                                                             %
854 %   S e t Q u a n t u m P a c k                                               %
855 %                                                                             %
856 %                                                                             %
857 %                                                                             %
858 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
859 %
860 %  SetQuantumPack() sets the quantum pack flag.
861 %
862 %  The format of the SetQuantumPack method is:
863 %
864 %      void SetQuantumPack(QuantumInfo *quantum_info,
865 %        const MagickBooleanType pack)
866 %
867 %  A description of each parameter follows:
868 %
869 %    o quantum_info: the quantum info.
870 %
871 %    o pack: the pack flag.
872 %
873 */
SetQuantumPack(QuantumInfo * quantum_info,const MagickBooleanType pack)874 MagickExport void SetQuantumPack(QuantumInfo *quantum_info,
875   const MagickBooleanType pack)
876 {
877   assert(quantum_info != (QuantumInfo *) NULL);
878   assert(quantum_info->signature == MagickCoreSignature);
879   quantum_info->pack=pack;
880 }
881 
882 /*
883 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
884 %                                                                             %
885 %                                                                             %
886 %                                                                             %
887 %   S e t Q u a n t u m P a d                                                 %
888 %                                                                             %
889 %                                                                             %
890 %                                                                             %
891 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
892 %
893 %  SetQuantumPad() sets the quantum pad.
894 %
895 %  The format of the SetQuantumPad method is:
896 %
897 %      MagickBooleanType SetQuantumPad(const Image *image,
898 %        QuantumInfo *quantum_info,const size_t pad)
899 %
900 %  A description of each parameter follows:
901 %
902 %    o image: the image.
903 %
904 %    o quantum_info: the quantum info.
905 %
906 %    o pad: the quantum pad.
907 %
908 */
SetQuantumPad(const Image * image,QuantumInfo * quantum_info,const size_t pad)909 MagickExport MagickBooleanType SetQuantumPad(const Image *image,
910   QuantumInfo *quantum_info,const size_t pad)
911 {
912   assert(image != (Image *) NULL);
913   assert(image->signature == MagickCoreSignature);
914   if (image->debug != MagickFalse)
915     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
916   assert(quantum_info != (QuantumInfo *) NULL);
917   assert(quantum_info->signature == MagickCoreSignature);
918   quantum_info->pad=pad;
919   return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
920 }
921 
922 /*
923 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
924 %                                                                             %
925 %                                                                             %
926 %                                                                             %
927 %   S e t Q u a n t u m M i n I s W h i t e                                   %
928 %                                                                             %
929 %                                                                             %
930 %                                                                             %
931 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
932 %
933 %  SetQuantumMinIsWhite() sets the quantum min-is-white flag.
934 %
935 %  The format of the SetQuantumMinIsWhite method is:
936 %
937 %      void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
938 %        const MagickBooleanType min_is_white)
939 %
940 %  A description of each parameter follows:
941 %
942 %    o quantum_info: the quantum info.
943 %
944 %    o min_is_white: the min-is-white flag.
945 %
946 */
SetQuantumMinIsWhite(QuantumInfo * quantum_info,const MagickBooleanType min_is_white)947 MagickExport void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
948   const MagickBooleanType min_is_white)
949 {
950   assert(quantum_info != (QuantumInfo *) NULL);
951   assert(quantum_info->signature == MagickCoreSignature);
952   quantum_info->min_is_white=min_is_white;
953 }
954 
955 /*
956 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
957 %                                                                             %
958 %                                                                             %
959 %                                                                             %
960 %   S e t Q u a n t u m Q u a n t u m                                         %
961 %                                                                             %
962 %                                                                             %
963 %                                                                             %
964 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
965 %
966 %  SetQuantumQuantum() sets the quantum quantum.
967 %
968 %  The format of the SetQuantumQuantum method is:
969 %
970 %      void SetQuantumQuantum(QuantumInfo *quantum_info,
971 %        const size_t quantum)
972 %
973 %  A description of each parameter follows:
974 %
975 %    o quantum_info: the quantum info.
976 %
977 %    o quantum: the quantum quantum.
978 %
979 */
SetQuantumQuantum(QuantumInfo * quantum_info,const size_t quantum)980 MagickExport void SetQuantumQuantum(QuantumInfo *quantum_info,
981   const size_t quantum)
982 {
983   assert(quantum_info != (QuantumInfo *) NULL);
984   assert(quantum_info->signature == MagickCoreSignature);
985   quantum_info->quantum=quantum;
986 }
987 
988 /*
989 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
990 %                                                                             %
991 %                                                                             %
992 %                                                                             %
993 %   S e t Q u a n t u m S c a l e                                             %
994 %                                                                             %
995 %                                                                             %
996 %                                                                             %
997 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
998 %
999 %  SetQuantumScale() sets the quantum scale.
1000 %
1001 %  The format of the SetQuantumScale method is:
1002 %
1003 %      void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1004 %
1005 %  A description of each parameter follows:
1006 %
1007 %    o quantum_info: the quantum info.
1008 %
1009 %    o scale: the quantum scale.
1010 %
1011 */
SetQuantumScale(QuantumInfo * quantum_info,const double scale)1012 MagickExport void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1013 {
1014   assert(quantum_info != (QuantumInfo *) NULL);
1015   assert(quantum_info->signature == MagickCoreSignature);
1016   quantum_info->scale=scale;
1017 }
1018