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