MagickCore  6.9.13-50
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/license/ %
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  channels;
314 
315  assert(quantum_info != (QuantumInfo *) NULL);
316  assert(quantum_info->signature == MagickCoreSignature);
317  channels=1;
318  switch (quantum_type)
319  {
320  case GrayAlphaQuantum: channels=2; break;
321  case IndexAlphaQuantum: channels=2; break;
322  case RGBQuantum: channels=3; break;
323  case BGRQuantum: channels=3; break;
324  case RGBAQuantum: channels=4; break;
325  case RGBOQuantum: channels=4; break;
326  case BGRAQuantum: channels=4; break;
327  case CMYKQuantum: channels=4; break;
328  case CMYKAQuantum: channels=5; break;
329  case CbYCrAQuantum: channels=4; break;
330  case CbYCrQuantum: channels=3; break;
331  case CbYCrYQuantum: channels=4; break;
332  default: break;
333  }
334  if (quantum_info->pack == MagickFalse)
335  return((size_t) (channels*image->columns*((quantum_info->depth+7)/8))+
336  (quantum_info->pad*image->columns));
337  return((size_t) ((channels*image->columns*quantum_info->depth+7)/8)+
338  (quantum_info->pad*image->columns));
339 }
340 
341 /*
342 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
343 % %
344 % %
345 % %
346 % G e t Q u a n t u m E n d i a n %
347 % %
348 % %
349 % %
350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
351 %
352 % GetQuantumEndian() returns the quantum endian of the image.
353 %
354 % The endian of the GetQuantumEndian method is:
355 %
356 % EndianType GetQuantumEndian(const QuantumInfo *quantum_info)
357 %
358 % A description of each parameter follows:
359 %
360 % o quantum_info: the quantum info.
361 %
362 */
363 MagickExport EndianType GetQuantumEndian(const QuantumInfo *quantum_info)
364 {
365  assert(quantum_info != (QuantumInfo *) NULL);
366  assert(quantum_info->signature == MagickCoreSignature);
367  return(quantum_info->endian);
368 }
369 
370 /*
371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
372 % %
373 % %
374 % %
375 % G e t Q u a n t u m F o r m a t %
376 % %
377 % %
378 % %
379 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
380 %
381 % GetQuantumFormat() returns the quantum format of the image.
382 %
383 % The format of the GetQuantumFormat method is:
384 %
385 % QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info)
386 %
387 % A description of each parameter follows:
388 %
389 % o quantum_info: the quantum info.
390 %
391 */
392 MagickExport QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info)
393 {
394  assert(quantum_info != (QuantumInfo *) NULL);
395  assert(quantum_info->signature == MagickCoreSignature);
396  return(quantum_info->format);
397 }
398 
399 /*
400 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
401 % %
402 % %
403 % %
404 % G e t Q u a n t u m I n f o %
405 % %
406 % %
407 % %
408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
409 %
410 % GetQuantumInfo() initializes the QuantumInfo structure to default values.
411 %
412 % The format of the GetQuantumInfo method is:
413 %
414 % GetQuantumInfo(const ImageInfo *image_info,QuantumInfo *quantum_info)
415 %
416 % A description of each parameter follows:
417 %
418 % o image_info: the image info.
419 %
420 % o quantum_info: the quantum info.
421 %
422 */
423 MagickExport void GetQuantumInfo(const ImageInfo *image_info,
424  QuantumInfo *quantum_info)
425 {
426  const char
427  *option;
428 
429  assert(quantum_info != (QuantumInfo *) NULL);
430  (void) memset(quantum_info,0,sizeof(*quantum_info));
431  quantum_info->quantum=8;
432  quantum_info->maximum=1.0;
433  quantum_info->scale=QuantumRange;
434  quantum_info->pack=MagickTrue;
435  quantum_info->semaphore=AllocateSemaphoreInfo();
436  quantum_info->signature=MagickCoreSignature;
437  if (image_info == (const ImageInfo *) NULL)
438  return;
439  option=GetImageOption(image_info,"quantum:format");
440  if (option != (char *) NULL)
441  quantum_info->format=(QuantumFormatType) ParseCommandOption(
442  MagickQuantumFormatOptions,MagickFalse,option);
443  option=GetImageOption(image_info,"quantum:minimum");
444  if (option != (char *) NULL)
445  quantum_info->minimum=StringToDouble(option,(char **) NULL);
446  option=GetImageOption(image_info,"quantum:maximum");
447  if (option != (char *) NULL)
448  quantum_info->maximum=StringToDouble(option,(char **) NULL);
449  if ((quantum_info->minimum == 0.0) && (quantum_info->maximum == 0.0))
450  quantum_info->scale=0.0;
451  else
452  if (quantum_info->minimum == quantum_info->maximum)
453  {
454  quantum_info->scale=(MagickRealType) QuantumRange/quantum_info->minimum;
455  quantum_info->minimum=0.0;
456  }
457  else
458  quantum_info->scale=(MagickRealType) QuantumRange/(quantum_info->maximum-
459  quantum_info->minimum);
460  option=GetImageOption(image_info,"quantum:scale");
461  if (option != (char *) NULL)
462  quantum_info->scale=StringToDouble(option,(char **) NULL);
463  option=GetImageOption(image_info,"quantum:polarity");
464  if (option != (char *) NULL)
465  quantum_info->min_is_white=LocaleCompare(option,"min-is-white") == 0 ?
466  MagickTrue : MagickFalse;
467  quantum_info->endian=image_info->endian;
468  ResetQuantumState(quantum_info);
469 }
470 
471 /*
472 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
473 % %
474 % %
475 % %
476 % G e t Q u a n t u m P i x e l s %
477 % %
478 % %
479 % %
480 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
481 %
482 % GetQuantumPixels() returns the quantum pixels.
483 %
484 % The format of the GetQuantumPixels method is:
485 %
486 % unsigned char *QuantumPixels GetQuantumPixels(
487 % const QuantumInfo *quantum_info)
488 %
489 % A description of each parameter follows:
490 %
491 % o image: the image.
492 %
493 */
494 MagickExport unsigned char *GetQuantumPixels(const QuantumInfo *quantum_info)
495 {
496  const int
497  id = GetOpenMPThreadId();
498 
499  assert(quantum_info != (QuantumInfo *) NULL);
500  assert(quantum_info->signature == MagickCoreSignature);
501  return((unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[id]));
502 }
503 
504 /*
505 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
506 % %
507 % %
508 % %
509 % G e t Q u a n t u m T y p e %
510 % %
511 % %
512 % %
513 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
514 %
515 % GetQuantumType() returns the quantum type of the image.
516 %
517 % The format of the GetQuantumType method is:
518 %
519 % QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
520 %
521 % A description of each parameter follows:
522 %
523 % o image: the image.
524 %
525 */
526 MagickExport QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
527 {
528  QuantumType
529  quantum_type;
530 
531  assert(image != (Image *) NULL);
532  assert(image->signature == MagickCoreSignature);
533  if (IsEventLogging() != MagickFalse)
534  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
535  (void) exception;
536  quantum_type=RGBQuantum;
537  if (image->matte != MagickFalse)
538  quantum_type=RGBAQuantum;
539  if (image->colorspace == CMYKColorspace)
540  {
541  quantum_type=CMYKQuantum;
542  if (image->matte != MagickFalse)
543  quantum_type=CMYKAQuantum;
544  }
545  if (IsGrayColorspace(image->colorspace) != MagickFalse)
546  {
547  quantum_type=GrayQuantum;
548  if (image->matte != MagickFalse)
549  quantum_type=GrayAlphaQuantum;
550  }
551  if (image->storage_class == PseudoClass)
552  {
553  quantum_type=IndexQuantum;
554  if (image->matte != MagickFalse)
555  quantum_type=IndexAlphaQuantum;
556  }
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  /*
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  return(SetQuantumExtent(image,quantum_info));
692 }
693 
694 /*
695 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
696 % %
697 % %
698 % %
699 % S e t Q u a n t u m E n d i a n %
700 % %
701 % %
702 % %
703 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
704 %
705 % SetQuantumEndian() sets the quantum endian.
706 %
707 % The endian of the SetQuantumEndian method is:
708 %
709 % MagickBooleanType SetQuantumEndian(const Image *image,
710 % QuantumInfo *quantum_info,const EndianType endian)
711 %
712 % A description of each parameter follows:
713 %
714 % o image: the image.
715 %
716 % o quantum_info: the quantum info.
717 %
718 % o endian: the quantum endian.
719 %
720 */
721 MagickExport MagickBooleanType SetQuantumEndian(const Image *image,
722  QuantumInfo *quantum_info,const EndianType endian)
723 {
724  assert(image != (Image *) NULL);
725  assert(image->signature == MagickCoreSignature);
726  assert(quantum_info != (QuantumInfo *) NULL);
727  assert(quantum_info->signature == MagickCoreSignature);
728  if (IsEventLogging() != MagickFalse)
729  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
730  quantum_info->endian=endian;
731  return(SetQuantumExtent(image,quantum_info));
732 }
733 
734 /*
735 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
736 % %
737 % %
738 % %
739 % S e t Q u a n t u m E x t e n t %
740 % %
741 % %
742 % %
743 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
744 %
745 % SetQuantumExtent() sets the quantum pixel buffer extent.
746 %
747 % The format of the SetQuantumExtent method is:
748 %
749 % MagickBooleanType SetQuantumExtent(const Image *image,
750 % QuantumInfo *quantum_info)
751 %
752 % A description of each parameter follows:
753 %
754 % o image: the image.
755 %
756 % o quantum_info: the quantum info.
757 %
758 */
759 MagickExport MagickBooleanType SetQuantumExtent(const Image *image,
760  QuantumInfo *quantum_info)
761 {
762  size_t
763  extent,
764  quantum;
765 
766  /*
767  Speculative allocation since we don't yet know the quantum type.
768  */
769  assert(image != (Image *) NULL);
770  assert(image->signature == MagickCoreSignature);
771  assert(quantum_info != (QuantumInfo *) NULL);
772  assert(quantum_info->signature == MagickCoreSignature);
773  if (IsEventLogging() != MagickFalse)
774  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
775  quantum=(quantum_info->pad+6)*((quantum_info->depth+7)/8)*sizeof(double);
776  extent=MagickMax(image->columns,image->rows)*quantum;
777  if ((MagickMax(image->columns,image->rows) != 0) &&
778  (quantum != (extent/MagickMax(image->columns,image->rows))))
779  return(MagickFalse);
780  if (quantum_info->pixels != (MemoryInfo **) NULL)
781  {
782  if (extent <= quantum_info->extent)
783  return(MagickTrue);
784  DestroyQuantumPixels(quantum_info);
785  }
786  return(AcquireQuantumPixels(quantum_info,extent));
787 }
788 
789 /*
790 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
791 % %
792 % %
793 % %
794 % S e t Q u a n t u m F o r m a t %
795 % %
796 % %
797 % %
798 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
799 %
800 % SetQuantumFormat() sets the quantum format.
801 %
802 % The format of the SetQuantumFormat method is:
803 %
804 % MagickBooleanType SetQuantumFormat(const Image *image,
805 % QuantumInfo *quantum_info,const QuantumFormatType format)
806 %
807 % A description of each parameter follows:
808 %
809 % o image: the image.
810 %
811 % o quantum_info: the quantum info.
812 %
813 % o format: the quantum format.
814 %
815 */
816 MagickExport MagickBooleanType SetQuantumFormat(const Image *image,
817  QuantumInfo *quantum_info,const QuantumFormatType format)
818 {
819  assert(image != (Image *) NULL);
820  assert(image->signature == MagickCoreSignature);
821  assert(quantum_info != (QuantumInfo *) NULL);
822  assert(quantum_info->signature == MagickCoreSignature);
823  if (IsEventLogging() != MagickFalse)
824  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
825  quantum_info->format=format;
826  return(SetQuantumExtent(image,quantum_info));
827 }
828 
829 /*
830 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
831 % %
832 % %
833 % %
834 % S e t Q u a n t u m I m a g e T y p e %
835 % %
836 % %
837 % %
838 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
839 %
840 % SetQuantumImageType() sets the image type based on the quantum type.
841 %
842 % The format of the SetQuantumImageType method is:
843 %
844 % void ImageType SetQuantumImageType(Image *image,
845 % const QuantumType quantum_type)
846 %
847 % A description of each parameter follows:
848 %
849 % o image: the image.
850 %
851 % o quantum_type: Declare which pixel components to transfer (red, green,
852 % blue, opacity, RGB, or RGBA).
853 %
854 */
855 MagickExport void SetQuantumImageType(Image *image,
856  const QuantumType quantum_type)
857 {
858  assert(image != (Image *) NULL);
859  assert(image->signature == MagickCoreSignature);
860  if (IsEventLogging() != MagickFalse)
861  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
862  switch (quantum_type)
863  {
864  case IndexQuantum:
865  case IndexAlphaQuantum:
866  {
867  image->type=PaletteType;
868  break;
869  }
870  case GrayQuantum:
871  case GrayAlphaQuantum:
872  {
873  image->type=GrayscaleType;
874  if (image->depth == 1)
875  image->type=BilevelType;
876  break;
877  }
878  case CyanQuantum:
879  case MagentaQuantum:
880  case YellowQuantum:
881  case BlackQuantum:
882  case CMYKQuantum:
883  case CMYKAQuantum:
884  {
885  image->type=ColorSeparationType;
886  break;
887  }
888  default:
889  {
890  image->type=TrueColorType;
891  break;
892  }
893  }
894 }
895 
896 /*
897 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
898 % %
899 % %
900 % %
901 % S e t Q u a n t u m P a c k %
902 % %
903 % %
904 % %
905 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
906 %
907 % SetQuantumPack() sets the quantum pack flag.
908 %
909 % The format of the SetQuantumPack method is:
910 %
911 % void SetQuantumPack(QuantumInfo *quantum_info,
912 % const MagickBooleanType pack)
913 %
914 % A description of each parameter follows:
915 %
916 % o quantum_info: the quantum info.
917 %
918 % o pack: the pack flag.
919 %
920 */
921 MagickExport void SetQuantumPack(QuantumInfo *quantum_info,
922  const MagickBooleanType pack)
923 {
924  assert(quantum_info != (QuantumInfo *) NULL);
925  assert(quantum_info->signature == MagickCoreSignature);
926  quantum_info->pack=pack;
927 }
928 
929 /*
930 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
931 % %
932 % %
933 % %
934 % S e t Q u a n t u m P a d %
935 % %
936 % %
937 % %
938 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
939 %
940 % SetQuantumPad() sets the quantum pad.
941 %
942 % The format of the SetQuantumPad method is:
943 %
944 % MagickBooleanType SetQuantumPad(const Image *image,
945 % QuantumInfo *quantum_info,const size_t pad)
946 %
947 % A description of each parameter follows:
948 %
949 % o image: the image.
950 %
951 % o quantum_info: the quantum info.
952 %
953 % o pad: the quantum pad.
954 %
955 */
956 MagickExport MagickBooleanType SetQuantumPad(const Image *image,
957  QuantumInfo *quantum_info,const size_t pad)
958 {
959  assert(image != (Image *) NULL);
960  assert(image->signature == MagickCoreSignature);
961  assert(quantum_info != (QuantumInfo *) NULL);
962  assert(quantum_info->signature == MagickCoreSignature);
963  if (IsEventLogging() != MagickFalse)
964  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
965  if (pad >= (MAGICK_SSIZE_MAX/5))
966  return(MagickFalse);
967  quantum_info->pad=pad;
968  return(SetQuantumExtent(image,quantum_info));
969 }
970 
971 /*
972 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
973 % %
974 % %
975 % %
976 % S e t Q u a n t u m M i n I s W h i t e %
977 % %
978 % %
979 % %
980 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
981 %
982 % SetQuantumMinIsWhite() sets the quantum min-is-white flag.
983 %
984 % The format of the SetQuantumMinIsWhite method is:
985 %
986 % void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
987 % const MagickBooleanType min_is_white)
988 %
989 % A description of each parameter follows:
990 %
991 % o quantum_info: the quantum info.
992 %
993 % o min_is_white: the min-is-white flag.
994 %
995 */
996 MagickExport void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
997  const MagickBooleanType min_is_white)
998 {
999  assert(quantum_info != (QuantumInfo *) NULL);
1000  assert(quantum_info->signature == MagickCoreSignature);
1001  quantum_info->min_is_white=min_is_white;
1002 }
1003 
1004 /*
1005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1006 % %
1007 % %
1008 % %
1009 % S e t Q u a n t u m Q u a n t u m %
1010 % %
1011 % %
1012 % %
1013 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1014 %
1015 % SetQuantumQuantum() sets the quantum quantum.
1016 %
1017 % The format of the SetQuantumQuantum method is:
1018 %
1019 % void SetQuantumQuantum(QuantumInfo *quantum_info,const size_t quantum)
1020 %
1021 % A description of each parameter follows:
1022 %
1023 % o quantum_info: the quantum info.
1024 %
1025 % o quantum: the quantum quantum.
1026 %
1027 */
1028 MagickExport void SetQuantumQuantum(QuantumInfo *quantum_info,
1029  const size_t quantum)
1030 {
1031  assert(quantum_info != (QuantumInfo *) NULL);
1032  assert(quantum_info->signature == MagickCoreSignature);
1033  quantum_info->quantum=quantum;
1034 }
1035 
1036 /*
1037 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1038 % %
1039 % %
1040 % %
1041 % S e t Q u a n t u m S c a l e %
1042 % %
1043 % %
1044 % %
1045 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1046 %
1047 % SetQuantumScale() sets the quantum scale.
1048 %
1049 % The format of the SetQuantumScale method is:
1050 %
1051 % void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1052 %
1053 % A description of each parameter follows:
1054 %
1055 % o quantum_info: the quantum info.
1056 %
1057 % o scale: the quantum scale.
1058 %
1059 */
1060 MagickExport void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1061 {
1062  assert(quantum_info != (QuantumInfo *) NULL);
1063  assert(quantum_info->signature == MagickCoreSignature);
1064  quantum_info->scale=scale;
1065 }
Definition: image.h:133