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