MagickCore  7.1.1-43
Convert, Edit, Or Compose Bitmap Images
quantum.c
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 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 */
110 MagickExport QuantumInfo *AcquireQuantumInfo(const ImageInfo *image_info,
111  Image *image)
112 {
113  MagickBooleanType
114  status;
115 
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 */
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 */
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 */
248 static void DestroyQuantumPixels(QuantumInfo *quantum_info)
249 {
250  ssize_t
251  i;
252 
253  assert(quantum_info != (QuantumInfo *) NULL);
254  assert(quantum_info->signature == MagickCoreSignature);
255  assert(quantum_info->pixels != (MemoryInfo **) NULL);
256  for (i=0; i < (ssize_t) quantum_info->number_threads; i++)
257  if (quantum_info->pixels[i] != (MemoryInfo *) NULL)
258  {
259 #ifndef NDEBUG
260  ssize_t
261  extent;
262 
263  unsigned char
264  *pixels;
265 
266  /*
267  Did we overrun our quantum buffer?
268  */
269  extent=(ssize_t) quantum_info->extent;
270  pixels=(unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[i]);
271  assert(pixels[extent] == QuantumSignature);
272 #endif
273  quantum_info->pixels[i]=RelinquishVirtualMemory(
274  quantum_info->pixels[i]);
275  }
276  quantum_info->pixels=(MemoryInfo **) RelinquishMagickMemory(
277  quantum_info->pixels);
278 }
279 
280 /*
281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
282 % %
283 % %
284 % %
285 % G e t Q u a n t u m E x t e n t %
286 % %
287 % %
288 % %
289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
290 %
291 % GetQuantumExtent() returns the quantum pixel buffer extent.
292 %
293 % The format of the GetQuantumExtent method is:
294 %
295 % size_t GetQuantumExtent(Image *image,const QuantumInfo *quantum_info,
296 % const QuantumType quantum_type)
297 %
298 % A description of each parameter follows:
299 %
300 % o image: the image.
301 %
302 % o quantum_info: the quantum info.
303 %
304 % o quantum_type: Declare which pixel components to transfer (red, green,
305 % blue, opacity, RGB, or RGBA).
306 %
307 */
308 MagickExport size_t GetQuantumExtent(const Image *image,
309  const QuantumInfo *quantum_info,const QuantumType quantum_type)
310 {
311  size_t
312  channels;
313 
314  assert(quantum_info != (QuantumInfo *) NULL);
315  assert(quantum_info->signature == MagickCoreSignature);
316  channels=1;
317  switch (quantum_type)
318  {
319  case GrayAlphaQuantum: channels=2; break;
320  case IndexAlphaQuantum: channels=2; break;
321  case RGBQuantum: channels=3; break;
322  case BGRQuantum: channels=3; break;
323  case RGBAQuantum: channels=4; break;
324  case RGBOQuantum: channels=4; break;
325  case BGRAQuantum: channels=4; break;
326  case CMYKQuantum: channels=4; break;
327  case CMYKAQuantum: channels=5; break;
328  case MultispectralQuantum: channels=GetImageChannels(image); break;
329  case CbYCrAQuantum: channels=4; break;
330  case CbYCrQuantum: channels=3; break;
331  case CbYCrYQuantum: channels=4; break;
332  default: break;
333  }
334  if (quantum_info->pack == MagickFalse)
335  return((size_t) (channels*image->columns*((quantum_info->depth+7)/8))+
336  (quantum_info->pad*image->columns));
337  return((size_t) ((channels*image->columns*quantum_info->depth+7)/8)+
338  (quantum_info->pad*image->columns));
339 }
340 
341 /*
342 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
343 % %
344 % %
345 % %
346 % G e t Q u a n t u m E n d i a n %
347 % %
348 % %
349 % %
350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
351 %
352 % GetQuantumEndian() returns the quantum endian of the image.
353 %
354 % The endian of the GetQuantumEndian method is:
355 %
356 % EndianType GetQuantumEndian(const QuantumInfo *quantum_info)
357 %
358 % A description of each parameter follows:
359 %
360 % o quantum_info: the quantum info.
361 %
362 */
363 MagickExport EndianType GetQuantumEndian(const QuantumInfo *quantum_info)
364 {
365  assert(quantum_info != (QuantumInfo *) NULL);
366  assert(quantum_info->signature == MagickCoreSignature);
367  return(quantum_info->endian);
368 }
369 
370 /*
371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
372 % %
373 % %
374 % %
375 % G e t Q u a n t u m F o r m a t %
376 % %
377 % %
378 % %
379 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
380 %
381 % GetQuantumFormat() returns the quantum format of the image.
382 %
383 % The format of the GetQuantumFormat method is:
384 %
385 % QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info)
386 %
387 % A description of each parameter follows:
388 %
389 % o quantum_info: the quantum info.
390 %
391 */
392 MagickExport QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info)
393 {
394  assert(quantum_info != (QuantumInfo *) NULL);
395  assert(quantum_info->signature == MagickCoreSignature);
396  return(quantum_info->format);
397 }
398 
399 /*
400 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
401 % %
402 % %
403 % %
404 % G e t Q u a n t u m I n f o %
405 % %
406 % %
407 % %
408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
409 %
410 % GetQuantumInfo() initializes the QuantumInfo structure to default values.
411 %
412 % The format of the GetQuantumInfo method is:
413 %
414 % GetQuantumInfo(const ImageInfo *image_info,QuantumInfo *quantum_info)
415 %
416 % A description of each parameter follows:
417 %
418 % o image_info: the image info.
419 %
420 % o quantum_info: the quantum info.
421 %
422 */
423 MagickExport void GetQuantumInfo(const ImageInfo *image_info,
424  QuantumInfo *quantum_info)
425 {
426  const char
427  *option;
428 
429  assert(quantum_info != (QuantumInfo *) NULL);
430  (void) memset(quantum_info,0,sizeof(*quantum_info));
431  quantum_info->quantum=8;
432  quantum_info->maximum=1.0;
433  quantum_info->scale=QuantumRange;
434  quantum_info->pack=MagickTrue;
435  quantum_info->semaphore=AcquireSemaphoreInfo();
436  quantum_info->signature=MagickCoreSignature;
437  if (image_info == (const ImageInfo *) NULL)
438  return;
439  option=GetImageOption(image_info,"quantum:format");
440  if (option != (char *) NULL)
441  quantum_info->format=(QuantumFormatType) ParseCommandOption(
442  MagickQuantumFormatOptions,MagickFalse,option);
443  option=GetImageOption(image_info,"quantum:minimum");
444  if (option != (char *) NULL)
445  quantum_info->minimum=StringToDouble(option,(char **) NULL);
446  option=GetImageOption(image_info,"quantum:maximum");
447  if (option != (char *) NULL)
448  quantum_info->maximum=StringToDouble(option,(char **) NULL);
449  if ((quantum_info->minimum == 0.0) && (quantum_info->maximum == 0.0))
450  quantum_info->scale=0.0;
451  else
452  if (quantum_info->minimum == quantum_info->maximum)
453  {
454  quantum_info->scale=(double) QuantumRange/quantum_info->minimum;
455  quantum_info->minimum=0.0;
456  }
457  else
458  quantum_info->scale=(double) QuantumRange/(quantum_info->maximum-
459  quantum_info->minimum);
460  option=GetImageOption(image_info,"quantum:scale");
461  if (option != (char *) NULL)
462  quantum_info->scale=StringToDouble(option,(char **) NULL);
463  option=GetImageOption(image_info,"quantum:polarity");
464  if (option != (char *) NULL)
465  quantum_info->min_is_white=LocaleCompare(option,"min-is-white") == 0 ?
466  MagickTrue : MagickFalse;
467  quantum_info->endian=image_info->endian;
468  ResetQuantumState(quantum_info);
469 }
470 
471 /*
472 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
473 % %
474 % %
475 % %
476 % G e t Q u a n t u m P i x e l s %
477 % %
478 % %
479 % %
480 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
481 %
482 % GetQuantumPixels() returns the quantum pixels.
483 %
484 % The format of the GetQuantumPixels method is:
485 %
486 % unsigned char *QuantumPixels GetQuantumPixels(
487 % const QuantumInfo *quantum_info)
488 %
489 % A description of each parameter follows:
490 %
491 % o image: the image.
492 %
493 */
494 MagickExport unsigned char *GetQuantumPixels(const QuantumInfo *quantum_info)
495 {
496  const int
497  id = GetOpenMPThreadId();
498 
499  assert(quantum_info != (QuantumInfo *) NULL);
500  assert(quantum_info->signature == MagickCoreSignature);
501  return((unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[id]));
502 }
503 
504 /*
505 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
506 % %
507 % %
508 % %
509 % G e t Q u a n t u m T y p e %
510 % %
511 % %
512 % %
513 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
514 %
515 % GetQuantumType() returns the quantum type of the image.
516 %
517 % The format of the GetQuantumType method is:
518 %
519 % QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
520 %
521 % A description of each parameter follows:
522 %
523 % o image: the image.
524 %
525 % o exception: return any errors or warnings in this structure.
526 %
527 */
528 MagickExport QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
529 {
530  QuantumType
531  quantum_type;
532 
533  assert(image != (Image *) NULL);
534  assert(image->signature == MagickCoreSignature);
535  if (IsEventLogging() != MagickFalse)
536  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
537  (void) exception;
538  quantum_type=RGBQuantum;
539  if (image->alpha_trait != UndefinedPixelTrait)
540  quantum_type=RGBAQuantum;
541  if (image->colorspace == CMYKColorspace)
542  {
543  quantum_type=CMYKQuantum;
544  if (image->alpha_trait != UndefinedPixelTrait)
545  quantum_type=CMYKAQuantum;
546  }
547  if (IsGrayColorspace(image->colorspace) != MagickFalse)
548  {
549  quantum_type=GrayQuantum;
550  if (image->alpha_trait != UndefinedPixelTrait)
551  quantum_type=GrayAlphaQuantum;
552  }
553  if (image->storage_class == PseudoClass)
554  {
555  quantum_type=IndexQuantum;
556  if (image->alpha_trait != UndefinedPixelTrait)
557  quantum_type=IndexAlphaQuantum;
558  }
559  if (image->number_meta_channels != 0)
560  quantum_type=MultispectralQuantum;
561  return(quantum_type);
562 }
563 
564 /*
565 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
566 % %
567 % %
568 % %
569 + R e s e t Q u a n t u m S t a t e %
570 % %
571 % %
572 % %
573 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
574 %
575 % ResetQuantumState() resets the quantum state.
576 %
577 % The format of the ResetQuantumState method is:
578 %
579 % void ResetQuantumState(QuantumInfo *quantum_info)
580 %
581 % A description of each parameter follows:
582 %
583 % o quantum_info: the quantum info.
584 %
585 */
586 MagickPrivate void ResetQuantumState(QuantumInfo *quantum_info)
587 {
588  static const unsigned int mask[32] =
589  {
590  0x00000000U, 0x00000001U, 0x00000003U, 0x00000007U, 0x0000000fU,
591  0x0000001fU, 0x0000003fU, 0x0000007fU, 0x000000ffU, 0x000001ffU,
592  0x000003ffU, 0x000007ffU, 0x00000fffU, 0x00001fffU, 0x00003fffU,
593  0x00007fffU, 0x0000ffffU, 0x0001ffffU, 0x0003ffffU, 0x0007ffffU,
594  0x000fffffU, 0x001fffffU, 0x003fffffU, 0x007fffffU, 0x00ffffffU,
595  0x01ffffffU, 0x03ffffffU, 0x07ffffffU, 0x0fffffffU, 0x1fffffffU,
596  0x3fffffffU, 0x7fffffffU
597  };
598 
599  assert(quantum_info != (QuantumInfo *) NULL);
600  assert(quantum_info->signature == MagickCoreSignature);
601  quantum_info->state.inverse_scale=1.0;
602  if (fabs(quantum_info->scale) >= MagickEpsilon)
603  quantum_info->state.inverse_scale/=quantum_info->scale;
604  quantum_info->state.pixel=0U;
605  quantum_info->state.bits=0U;
606  quantum_info->state.mask=mask;
607 }
608 
609 /*
610 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
611 % %
612 % %
613 % %
614 % S e t Q u a n t u m F o r m a t %
615 % %
616 % %
617 % %
618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
619 %
620 % SetQuantumAlphaType() sets the quantum format.
621 %
622 % The format of the SetQuantumAlphaType method is:
623 %
624 % void SetQuantumAlphaType(QuantumInfo *quantum_info,
625 % const QuantumAlphaType type)
626 %
627 % A description of each parameter follows:
628 %
629 % o quantum_info: the quantum info.
630 %
631 % o type: the alpha type (e.g. associate).
632 %
633 */
634 MagickExport void SetQuantumAlphaType(QuantumInfo *quantum_info,
635  const QuantumAlphaType type)
636 {
637  assert(quantum_info != (QuantumInfo *) NULL);
638  assert(quantum_info->signature == MagickCoreSignature);
639  quantum_info->alpha_type=type;
640 }
641 
642 /*
643 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
644 % %
645 % %
646 % %
647 % S e t Q u a n t u m D e p t h %
648 % %
649 % %
650 % %
651 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
652 %
653 % SetQuantumDepth() sets the quantum depth.
654 %
655 % The format of the SetQuantumDepth method is:
656 %
657 % MagickBooleanType SetQuantumDepth(const Image *image,
658 % QuantumInfo *quantum_info,const size_t depth)
659 %
660 % A description of each parameter follows:
661 %
662 % o image: the image.
663 %
664 % o quantum_info: the quantum info.
665 %
666 % o depth: the quantum depth.
667 %
668 */
669 MagickExport MagickBooleanType SetQuantumDepth(const Image *image,
670  QuantumInfo *quantum_info,const size_t depth)
671 {
672  size_t
673  extent,
674  quantum;
675 
676  /*
677  Allocate the quantum pixel buffer.
678  */
679  assert(image != (Image *) NULL);
680  assert(image->signature == MagickCoreSignature);
681  assert(quantum_info != (QuantumInfo *) NULL);
682  assert(quantum_info->signature == MagickCoreSignature);
683  if (IsEventLogging() != MagickFalse)
684  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
685  quantum_info->depth=MagickMin(depth,64);
686  if (quantum_info->format == FloatingPointQuantumFormat)
687  {
688  if (quantum_info->depth > 32)
689  quantum_info->depth=64;
690  else
691  if (quantum_info->depth > 24)
692  quantum_info->depth=32;
693  else
694  if (quantum_info->depth > 16)
695  quantum_info->depth=24;
696  else
697  quantum_info->depth=16;
698  }
699  /*
700  Speculative allocation since we don't yet know the quantum type.
701  */
702  quantum=(GetPixelChannels(image)+quantum_info->pad+3)*
703  ((quantum_info->depth+7)/8)*sizeof(double);
704  extent=MagickMax(image->columns,image->rows)*quantum;
705  if ((MagickMax(image->columns,image->rows) != 0) &&
706  (quantum != (extent/MagickMax(image->columns,image->rows))))
707  return(MagickFalse);
708  if (quantum_info->pixels != (MemoryInfo **) NULL)
709  {
710  if (extent <= quantum_info->extent)
711  return(MagickTrue);
712  DestroyQuantumPixels(quantum_info);
713  }
714  return(AcquireQuantumPixels(quantum_info,extent));
715 }
716 
717 /*
718 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
719 % %
720 % %
721 % %
722 % S e t Q u a n t u m E n d i a n %
723 % %
724 % %
725 % %
726 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
727 %
728 % SetQuantumEndian() sets the quantum endian.
729 %
730 % The endian of the SetQuantumEndian method is:
731 %
732 % MagickBooleanType SetQuantumEndian(const Image *image,
733 % QuantumInfo *quantum_info,const EndianType endian)
734 %
735 % A description of each parameter follows:
736 %
737 % o image: the image.
738 %
739 % o quantum_info: the quantum info.
740 %
741 % o endian: the quantum endian.
742 %
743 */
744 MagickExport MagickBooleanType SetQuantumEndian(const Image *image,
745  QuantumInfo *quantum_info,const EndianType endian)
746 {
747  assert(image != (Image *) NULL);
748  assert(image->signature == MagickCoreSignature);
749  assert(quantum_info != (QuantumInfo *) NULL);
750  assert(quantum_info->signature == MagickCoreSignature);
751  if (IsEventLogging() != MagickFalse)
752  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
753  quantum_info->endian=endian;
754  return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
755 }
756 
757 /*
758 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
759 % %
760 % %
761 % %
762 % S e t Q u a n t u m F o r m a t %
763 % %
764 % %
765 % %
766 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
767 %
768 % SetQuantumFormat() sets the quantum format.
769 %
770 % The format of the SetQuantumFormat method is:
771 %
772 % MagickBooleanType SetQuantumFormat(const Image *image,
773 % QuantumInfo *quantum_info,const QuantumFormatType format)
774 %
775 % A description of each parameter follows:
776 %
777 % o image: the image.
778 %
779 % o quantum_info: the quantum info.
780 %
781 % o format: the quantum format.
782 %
783 */
784 MagickExport MagickBooleanType SetQuantumFormat(const Image *image,
785  QuantumInfo *quantum_info,const QuantumFormatType format)
786 {
787  assert(image != (Image *) NULL);
788  assert(image->signature == MagickCoreSignature);
789  assert(quantum_info != (QuantumInfo *) NULL);
790  assert(quantum_info->signature == MagickCoreSignature);
791  if (IsEventLogging() != MagickFalse)
792  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
793  quantum_info->format=format;
794  return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
795 }
796 
797 /*
798 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
799 % %
800 % %
801 % %
802 % S e t Q u a n t u m I m a g e T y p e %
803 % %
804 % %
805 % %
806 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
807 %
808 % SetQuantumImageType() sets the image type based on the quantum type.
809 %
810 % The format of the SetQuantumImageType method is:
811 %
812 % void ImageType SetQuantumImageType(Image *image,
813 % const QuantumType quantum_type)
814 %
815 % A description of each parameter follows:
816 %
817 % o image: the image.
818 %
819 % o quantum_type: Declare which pixel components to transfer (red, green,
820 % blue, opacity, RGB, or RGBA).
821 %
822 */
823 MagickExport void SetQuantumImageType(Image *image,
824  const QuantumType quantum_type)
825 {
826  assert(image != (Image *) NULL);
827  assert(image->signature == MagickCoreSignature);
828  if (IsEventLogging() != MagickFalse)
829  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
830  switch (quantum_type)
831  {
832  case IndexQuantum:
833  case IndexAlphaQuantum:
834  {
835  image->type=PaletteType;
836  break;
837  }
838  case GrayQuantum:
839  case GrayAlphaQuantum:
840  {
841  image->type=GrayscaleType;
842  if (image->depth == 1)
843  image->type=BilevelType;
844  break;
845  }
846  case CyanQuantum:
847  case MagentaQuantum:
848  case YellowQuantum:
849  case BlackQuantum:
850  case CMYKQuantum:
851  case CMYKAQuantum:
852  case MultispectralQuantum:
853  {
854  image->type=ColorSeparationType;
855  break;
856  }
857  default:
858  {
859  image->type=TrueColorType;
860  break;
861  }
862  }
863 }
864 
865 /*
866 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
867 % %
868 % %
869 % %
870 % S e t Q u a n t u m P a c k %
871 % %
872 % %
873 % %
874 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
875 %
876 % SetQuantumPack() sets the quantum pack flag.
877 %
878 % The format of the SetQuantumPack method is:
879 %
880 % void SetQuantumPack(QuantumInfo *quantum_info,
881 % const MagickBooleanType pack)
882 %
883 % A description of each parameter follows:
884 %
885 % o quantum_info: the quantum info.
886 %
887 % o pack: the pack flag.
888 %
889 */
890 MagickExport void SetQuantumPack(QuantumInfo *quantum_info,
891  const MagickBooleanType pack)
892 {
893  assert(quantum_info != (QuantumInfo *) NULL);
894  assert(quantum_info->signature == MagickCoreSignature);
895  quantum_info->pack=pack;
896 }
897 
898 /*
899 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
900 % %
901 % %
902 % %
903 % S e t Q u a n t u m P a d %
904 % %
905 % %
906 % %
907 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
908 %
909 % SetQuantumPad() sets the quantum pad.
910 %
911 % The format of the SetQuantumPad method is:
912 %
913 % MagickBooleanType SetQuantumPad(const Image *image,
914 % QuantumInfo *quantum_info,const size_t pad)
915 %
916 % A description of each parameter follows:
917 %
918 % o image: the image.
919 %
920 % o quantum_info: the quantum info.
921 %
922 % o pad: the quantum pad.
923 %
924 */
925 MagickExport MagickBooleanType SetQuantumPad(const Image *image,
926  QuantumInfo *quantum_info,const size_t pad)
927 {
928  assert(image != (Image *) NULL);
929  assert(image->signature == MagickCoreSignature);
930  assert(quantum_info != (QuantumInfo *) NULL);
931  assert(quantum_info->signature == MagickCoreSignature);
932  if (IsEventLogging() != MagickFalse)
933  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
934  if (pad >= (MAGICK_SSIZE_MAX/GetImageChannels(image)))
935  return(MagickFalse);
936  quantum_info->pad=pad;
937  return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
938 }
939 
940 /*
941 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
942 % %
943 % %
944 % %
945 % S e t Q u a n t u m M i n I s W h i t e %
946 % %
947 % %
948 % %
949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
950 %
951 % SetQuantumMinIsWhite() sets the quantum min-is-white flag.
952 %
953 % The format of the SetQuantumMinIsWhite method is:
954 %
955 % void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
956 % const MagickBooleanType min_is_white)
957 %
958 % A description of each parameter follows:
959 %
960 % o quantum_info: the quantum info.
961 %
962 % o min_is_white: the min-is-white flag.
963 %
964 */
965 MagickExport void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
966  const MagickBooleanType min_is_white)
967 {
968  assert(quantum_info != (QuantumInfo *) NULL);
969  assert(quantum_info->signature == MagickCoreSignature);
970  quantum_info->min_is_white=min_is_white;
971 }
972 
973 /*
974 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
975 % %
976 % %
977 % %
978 % S e t Q u a n t u m Q u a n t u m %
979 % %
980 % %
981 % %
982 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
983 %
984 % SetQuantumQuantum() sets the quantum quantum.
985 %
986 % The format of the SetQuantumQuantum method is:
987 %
988 % void SetQuantumQuantum(QuantumInfo *quantum_info,const size_t quantum)
989 %
990 % A description of each parameter follows:
991 %
992 % o quantum_info: the quantum info.
993 %
994 % o quantum: the quantum quantum.
995 %
996 */
997 MagickExport void SetQuantumQuantum(QuantumInfo *quantum_info,
998  const size_t quantum)
999 {
1000  assert(quantum_info != (QuantumInfo *) NULL);
1001  assert(quantum_info->signature == MagickCoreSignature);
1002  quantum_info->quantum=quantum;
1003 }
1004 
1005 /*
1006 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1007 % %
1008 % %
1009 % %
1010 % S e t Q u a n t u m S c a l e %
1011 % %
1012 % %
1013 % %
1014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1015 %
1016 % SetQuantumScale() sets the quantum scale.
1017 %
1018 % The format of the SetQuantumScale method is:
1019 %
1020 % void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1021 %
1022 % A description of each parameter follows:
1023 %
1024 % o quantum_info: the quantum info.
1025 %
1026 % o scale: the quantum scale.
1027 %
1028 */
1029 MagickExport void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1030 {
1031  assert(quantum_info != (QuantumInfo *) NULL);
1032  assert(quantum_info->signature == MagickCoreSignature);
1033  quantum_info->scale=scale;
1034 }
_QuantumInfo
Definition: quantum-private.h:45
_MemoryInfo
Definition: memory.c:163
SemaphoreInfo
Definition: semaphore.c:60
_Image
Definition: image.h:131
_ImageInfo
Definition: image.h:358
_ExceptionInfo
Definition: exception.h:101