MagickCore  7.1.0
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  ssize_t
254  extent;
255 
256  assert(quantum_info != (QuantumInfo *) NULL);
257  assert(quantum_info->signature == MagickCoreSignature);
258  assert(quantum_info->pixels != (MemoryInfo **) NULL);
259  extent=(ssize_t) quantum_info->extent;
260  for (i=0; i < (ssize_t) quantum_info->number_threads; i++)
261  if (quantum_info->pixels[i] != (MemoryInfo *) NULL)
262  {
263  unsigned char
264  *pixels;
265 
266  /*
267  Did we overrun our quantum buffer?
268  */
269  pixels=(unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[i]);
270  assert(pixels[extent] == QuantumSignature);
271  quantum_info->pixels[i]=RelinquishVirtualMemory(
272  quantum_info->pixels[i]);
273  }
274  quantum_info->pixels=(MemoryInfo **) RelinquishMagickMemory(
275  quantum_info->pixels);
276 }
277 ␌
278 /*
279 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
280 % %
281 % %
282 % %
283 % G e t Q u a n t u m E x t e n t %
284 % %
285 % %
286 % %
287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
288 %
289 % GetQuantumExtent() returns the quantum pixel buffer extent.
290 %
291 % The format of the GetQuantumExtent method is:
292 %
293 % size_t GetQuantumExtent(Image *image,const QuantumInfo *quantum_info,
294 % const QuantumType quantum_type)
295 %
296 % A description of each parameter follows:
297 %
298 % o image: the image.
299 %
300 % o quantum_info: the quantum info.
301 %
302 % o quantum_type: Declare which pixel components to transfer (red, green,
303 % blue, opacity, RGB, or RGBA).
304 %
305 */
306 MagickExport size_t GetQuantumExtent(const Image *image,
307  const QuantumInfo *quantum_info,const QuantumType quantum_type)
308 {
309  size_t
310  packet_size;
311 
312  assert(quantum_info != (QuantumInfo *) NULL);
313  assert(quantum_info->signature == MagickCoreSignature);
314  packet_size=1;
315  switch (quantum_type)
316  {
317  case GrayAlphaQuantum: packet_size=2; break;
318  case IndexAlphaQuantum: packet_size=2; break;
319  case RGBQuantum: packet_size=3; break;
320  case BGRQuantum: packet_size=3; break;
321  case RGBAQuantum: packet_size=4; break;
322  case RGBOQuantum: packet_size=4; break;
323  case BGRAQuantum: packet_size=4; break;
324  case CMYKQuantum: packet_size=4; break;
325  case CMYKAQuantum: packet_size=5; break;
326  case MultispectralQuantum: packet_size=6; 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=AcquireSemaphoreInfo();
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=(double) QuantumRange/quantum_info->minimum;
451  quantum_info->minimum=0.0;
452  }
453  else
454  quantum_info->scale=(double) 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 % o exception: return any errors or warnings in this structure.
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->alpha_trait != UndefinedPixelTrait)
536  quantum_type=RGBAQuantum;
537  if (image->colorspace == CMYKColorspace)
538  {
539  quantum_type=CMYKQuantum;
540  if (image->alpha_trait != UndefinedPixelTrait)
541  quantum_type=CMYKAQuantum;
542  }
543  if (IsGrayColorspace(image->colorspace) != MagickFalse)
544  {
545  quantum_type=GrayQuantum;
546  if (image->alpha_trait != UndefinedPixelTrait)
547  quantum_type=GrayAlphaQuantum;
548  }
549  if (image->storage_class == PseudoClass)
550  {
551  quantum_type=IndexQuantum;
552  if (image->alpha_trait != UndefinedPixelTrait)
553  quantum_type=IndexAlphaQuantum;
554  }
555  if (image->number_meta_channels != 0)
556  quantum_type=MultispectralQuantum;
557  return(quantum_type);
558 }
559 ␌
560 /*
561 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
562 % %
563 % %
564 % %
565 + R e s e t Q u a n t u m S t a t e %
566 % %
567 % %
568 % %
569 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
570 %
571 % ResetQuantumState() resets the quantum state.
572 %
573 % The format of the ResetQuantumState method is:
574 %
575 % void ResetQuantumState(QuantumInfo *quantum_info)
576 %
577 % A description of each parameter follows:
578 %
579 % o quantum_info: the quantum info.
580 %
581 */
582 MagickPrivate void ResetQuantumState(QuantumInfo *quantum_info)
583 {
584  static const unsigned int mask[32] =
585  {
586  0x00000000U, 0x00000001U, 0x00000003U, 0x00000007U, 0x0000000fU,
587  0x0000001fU, 0x0000003fU, 0x0000007fU, 0x000000ffU, 0x000001ffU,
588  0x000003ffU, 0x000007ffU, 0x00000fffU, 0x00001fffU, 0x00003fffU,
589  0x00007fffU, 0x0000ffffU, 0x0001ffffU, 0x0003ffffU, 0x0007ffffU,
590  0x000fffffU, 0x001fffffU, 0x003fffffU, 0x007fffffU, 0x00ffffffU,
591  0x01ffffffU, 0x03ffffffU, 0x07ffffffU, 0x0fffffffU, 0x1fffffffU,
592  0x3fffffffU, 0x7fffffffU
593  };
594 
595  assert(quantum_info != (QuantumInfo *) NULL);
596  assert(quantum_info->signature == MagickCoreSignature);
597  quantum_info->state.inverse_scale=1.0;
598  if (fabs(quantum_info->scale) >= MagickEpsilon)
599  quantum_info->state.inverse_scale/=quantum_info->scale;
600  quantum_info->state.pixel=0U;
601  quantum_info->state.bits=0U;
602  quantum_info->state.mask=mask;
603 }
604 ␌
605 /*
606 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
607 % %
608 % %
609 % %
610 % S e t Q u a n t u m F o r m a t %
611 % %
612 % %
613 % %
614 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
615 %
616 % SetQuantumAlphaType() sets the quantum format.
617 %
618 % The format of the SetQuantumAlphaType method is:
619 %
620 % void SetQuantumAlphaType(QuantumInfo *quantum_info,
621 % const QuantumAlphaType type)
622 %
623 % A description of each parameter follows:
624 %
625 % o quantum_info: the quantum info.
626 %
627 % o type: the alpha type (e.g. associate).
628 %
629 */
630 MagickExport void SetQuantumAlphaType(QuantumInfo *quantum_info,
631  const QuantumAlphaType type)
632 {
633  assert(quantum_info != (QuantumInfo *) NULL);
634  assert(quantum_info->signature == MagickCoreSignature);
635  quantum_info->alpha_type=type;
636 }
637 ␌
638 /*
639 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
640 % %
641 % %
642 % %
643 % S e t Q u a n t u m D e p t h %
644 % %
645 % %
646 % %
647 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
648 %
649 % SetQuantumDepth() sets the quantum depth.
650 %
651 % The format of the SetQuantumDepth method is:
652 %
653 % MagickBooleanType SetQuantumDepth(const Image *image,
654 % QuantumInfo *quantum_info,const size_t depth)
655 %
656 % A description of each parameter follows:
657 %
658 % o image: the image.
659 %
660 % o quantum_info: the quantum info.
661 %
662 % o depth: the quantum depth.
663 %
664 */
665 MagickExport MagickBooleanType SetQuantumDepth(const Image *image,
666  QuantumInfo *quantum_info,const size_t depth)
667 {
668  size_t
669  extent,
670  quantum;
671 
672  /*
673  Allocate the quantum pixel buffer.
674  */
675  assert(image != (Image *) NULL);
676  assert(image->signature == MagickCoreSignature);
677  assert(quantum_info != (QuantumInfo *) NULL);
678  assert(quantum_info->signature == MagickCoreSignature);
679  if (IsEventLogging() != MagickFalse)
680  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
681  quantum_info->depth=MagickMin(depth,64);
682  if (quantum_info->format == FloatingPointQuantumFormat)
683  {
684  if (quantum_info->depth > 32)
685  quantum_info->depth=64;
686  else
687  if (quantum_info->depth > 24)
688  quantum_info->depth=32;
689  else
690  if (quantum_info->depth > 16)
691  quantum_info->depth=24;
692  else
693  quantum_info->depth=16;
694  }
695  /*
696  Speculative allocation since we don't yet know the quantum type.
697  */
698  quantum=(GetPixelChannels(image)+quantum_info->pad+3)*
699  ((quantum_info->depth+7)/8)*sizeof(double);
700  extent=MagickMax(image->columns,image->rows)*quantum;
701  if ((MagickMax(image->columns,image->rows) != 0) &&
702  (quantum != (extent/MagickMax(image->columns,image->rows))))
703  return(MagickFalse);
704  if (quantum_info->pixels != (MemoryInfo **) NULL)
705  {
706  if (extent <= quantum_info->extent)
707  return(MagickTrue);
708  DestroyQuantumPixels(quantum_info);
709  }
710  return(AcquireQuantumPixels(quantum_info,extent));
711 }
712 ␌
713 /*
714 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
715 % %
716 % %
717 % %
718 % S e t Q u a n t u m E n d i a n %
719 % %
720 % %
721 % %
722 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
723 %
724 % SetQuantumEndian() sets the quantum endian.
725 %
726 % The endian of the SetQuantumEndian method is:
727 %
728 % MagickBooleanType SetQuantumEndian(const Image *image,
729 % QuantumInfo *quantum_info,const EndianType endian)
730 %
731 % A description of each parameter follows:
732 %
733 % o image: the image.
734 %
735 % o quantum_info: the quantum info.
736 %
737 % o endian: the quantum endian.
738 %
739 */
740 MagickExport MagickBooleanType SetQuantumEndian(const Image *image,
741  QuantumInfo *quantum_info,const EndianType endian)
742 {
743  assert(image != (Image *) NULL);
744  assert(image->signature == MagickCoreSignature);
745  assert(quantum_info != (QuantumInfo *) NULL);
746  assert(quantum_info->signature == MagickCoreSignature);
747  if (IsEventLogging() != MagickFalse)
748  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
749  quantum_info->endian=endian;
750  return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
751 }
752 ␌
753 /*
754 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
755 % %
756 % %
757 % %
758 % S e t Q u a n t u m F o r m a t %
759 % %
760 % %
761 % %
762 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
763 %
764 % SetQuantumFormat() sets the quantum format.
765 %
766 % The format of the SetQuantumFormat method is:
767 %
768 % MagickBooleanType SetQuantumFormat(const Image *image,
769 % QuantumInfo *quantum_info,const QuantumFormatType format)
770 %
771 % A description of each parameter follows:
772 %
773 % o image: the image.
774 %
775 % o quantum_info: the quantum info.
776 %
777 % o format: the quantum format.
778 %
779 */
780 MagickExport MagickBooleanType SetQuantumFormat(const Image *image,
781  QuantumInfo *quantum_info,const QuantumFormatType format)
782 {
783  assert(image != (Image *) NULL);
784  assert(image->signature == MagickCoreSignature);
785  assert(quantum_info != (QuantumInfo *) NULL);
786  assert(quantum_info->signature == MagickCoreSignature);
787  if (IsEventLogging() != MagickFalse)
788  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
789  quantum_info->format=format;
790  return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
791 }
792 ␌
793 /*
794 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
795 % %
796 % %
797 % %
798 % S e t Q u a n t u m I m a g e T y p e %
799 % %
800 % %
801 % %
802 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
803 %
804 % SetQuantumImageType() sets the image type based on the quantum type.
805 %
806 % The format of the SetQuantumImageType method is:
807 %
808 % void ImageType SetQuantumImageType(Image *image,
809 % const QuantumType quantum_type)
810 %
811 % A description of each parameter follows:
812 %
813 % o image: the image.
814 %
815 % o quantum_type: Declare which pixel components to transfer (red, green,
816 % blue, opacity, RGB, or RGBA).
817 %
818 */
819 MagickExport void SetQuantumImageType(Image *image,
820  const QuantumType quantum_type)
821 {
822  assert(image != (Image *) NULL);
823  assert(image->signature == MagickCoreSignature);
824  if (IsEventLogging() != MagickFalse)
825  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
826  switch (quantum_type)
827  {
828  case IndexQuantum:
829  case IndexAlphaQuantum:
830  {
831  image->type=PaletteType;
832  break;
833  }
834  case GrayQuantum:
835  case GrayAlphaQuantum:
836  {
837  image->type=GrayscaleType;
838  if (image->depth == 1)
839  image->type=BilevelType;
840  break;
841  }
842  case CyanQuantum:
843  case MagentaQuantum:
844  case YellowQuantum:
845  case BlackQuantum:
846  case CMYKQuantum:
847  case CMYKAQuantum:
848  case MultispectralQuantum:
849  {
850  image->type=ColorSeparationType;
851  break;
852  }
853  default:
854  {
855  image->type=TrueColorType;
856  break;
857  }
858  }
859 }
860 ␌
861 /*
862 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
863 % %
864 % %
865 % %
866 % S e t Q u a n t u m P a c k %
867 % %
868 % %
869 % %
870 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
871 %
872 % SetQuantumPack() sets the quantum pack flag.
873 %
874 % The format of the SetQuantumPack method is:
875 %
876 % void SetQuantumPack(QuantumInfo *quantum_info,
877 % const MagickBooleanType pack)
878 %
879 % A description of each parameter follows:
880 %
881 % o quantum_info: the quantum info.
882 %
883 % o pack: the pack flag.
884 %
885 */
886 MagickExport void SetQuantumPack(QuantumInfo *quantum_info,
887  const MagickBooleanType pack)
888 {
889  assert(quantum_info != (QuantumInfo *) NULL);
890  assert(quantum_info->signature == MagickCoreSignature);
891  quantum_info->pack=pack;
892 }
893 ␌
894 /*
895 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
896 % %
897 % %
898 % %
899 % S e t Q u a n t u m P a d %
900 % %
901 % %
902 % %
903 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
904 %
905 % SetQuantumPad() sets the quantum pad.
906 %
907 % The format of the SetQuantumPad method is:
908 %
909 % MagickBooleanType SetQuantumPad(const Image *image,
910 % QuantumInfo *quantum_info,const size_t pad)
911 %
912 % A description of each parameter follows:
913 %
914 % o image: the image.
915 %
916 % o quantum_info: the quantum info.
917 %
918 % o pad: the quantum pad.
919 %
920 */
921 MagickExport MagickBooleanType SetQuantumPad(const Image *image,
922  QuantumInfo *quantum_info,const size_t pad)
923 {
924  assert(image != (Image *) NULL);
925  assert(image->signature == MagickCoreSignature);
926  assert(quantum_info != (QuantumInfo *) NULL);
927  assert(quantum_info->signature == MagickCoreSignature);
928  if (IsEventLogging() != MagickFalse)
929  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
930  quantum_info->pad=pad;
931  return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
932 }
933 ␌
934 /*
935 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
936 % %
937 % %
938 % %
939 % S e t Q u a n t u m M i n I s W h i t e %
940 % %
941 % %
942 % %
943 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
944 %
945 % SetQuantumMinIsWhite() sets the quantum min-is-white flag.
946 %
947 % The format of the SetQuantumMinIsWhite method is:
948 %
949 % void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
950 % const MagickBooleanType min_is_white)
951 %
952 % A description of each parameter follows:
953 %
954 % o quantum_info: the quantum info.
955 %
956 % o min_is_white: the min-is-white flag.
957 %
958 */
959 MagickExport void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
960  const MagickBooleanType min_is_white)
961 {
962  assert(quantum_info != (QuantumInfo *) NULL);
963  assert(quantum_info->signature == MagickCoreSignature);
964  quantum_info->min_is_white=min_is_white;
965 }
966 ␌
967 /*
968 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
969 % %
970 % %
971 % %
972 % S e t Q u a n t u m Q u a n t u m %
973 % %
974 % %
975 % %
976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
977 %
978 % SetQuantumQuantum() sets the quantum quantum.
979 %
980 % The format of the SetQuantumQuantum method is:
981 %
982 % void SetQuantumQuantum(QuantumInfo *quantum_info,const size_t quantum)
983 %
984 % A description of each parameter follows:
985 %
986 % o quantum_info: the quantum info.
987 %
988 % o quantum: the quantum quantum.
989 %
990 */
991 MagickExport void SetQuantumQuantum(QuantumInfo *quantum_info,
992  const size_t quantum)
993 {
994  assert(quantum_info != (QuantumInfo *) NULL);
995  assert(quantum_info->signature == MagickCoreSignature);
996  quantum_info->quantum=quantum;
997 }
998 ␌
999 /*
1000 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1001 % %
1002 % %
1003 % %
1004 % S e t Q u a n t u m S c a l e %
1005 % %
1006 % %
1007 % %
1008 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1009 %
1010 % SetQuantumScale() sets the quantum scale.
1011 %
1012 % The format of the SetQuantumScale method is:
1013 %
1014 % void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1015 %
1016 % A description of each parameter follows:
1017 %
1018 % o quantum_info: the quantum info.
1019 %
1020 % o scale: the quantum scale.
1021 %
1022 */
1023 MagickExport void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1024 {
1025  assert(quantum_info != (QuantumInfo *) NULL);
1026  assert(quantum_info->signature == MagickCoreSignature);
1027  quantum_info->scale=scale;
1028 }
Definition: image.h:152