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