MagickCore 6.9.13
Loading...
Searching...
No Matches
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 "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*/
82static 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*/
109MagickExport 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*/
157static 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*/
214MagickExport 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*/
249static 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*/
309MagickExport 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*/
363MagickExport 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*/
392MagickExport 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*/
423MagickExport 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*/
494MagickExport 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*/
526MagickExport 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*/
582MagickPrivate 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*/
630MagickExport 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*/
665MagickExport 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=(quantum_info->pad+6)*((quantum_info->depth+7)/8)*sizeof(double);
699 extent=MagickMax(image->columns,image->rows)*quantum;
700 if ((MagickMax(image->columns,image->rows) != 0) &&
701 (quantum != (extent/MagickMax(image->columns,image->rows))))
702 return(MagickFalse);
703 if (quantum_info->pixels != (MemoryInfo **) NULL)
704 {
705 if (extent <= quantum_info->extent)
706 return(MagickTrue);
707 DestroyQuantumPixels(quantum_info);
708 }
709 return(AcquireQuantumPixels(quantum_info,extent));
710}
711
712/*
713%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
714% %
715% %
716% %
717% S e t Q u a n t u m E n d i a n %
718% %
719% %
720% %
721%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
722%
723% SetQuantumEndian() sets the quantum endian.
724%
725% The endian of the SetQuantumEndian method is:
726%
727% MagickBooleanType SetQuantumEndian(const Image *image,
728% QuantumInfo *quantum_info,const EndianType endian)
729%
730% A description of each parameter follows:
731%
732% o image: the image.
733%
734% o quantum_info: the quantum info.
735%
736% o endian: the quantum endian.
737%
738*/
739MagickExport MagickBooleanType SetQuantumEndian(const Image *image,
740 QuantumInfo *quantum_info,const EndianType endian)
741{
742 assert(image != (Image *) NULL);
743 assert(image->signature == MagickCoreSignature);
744 assert(quantum_info != (QuantumInfo *) NULL);
745 assert(quantum_info->signature == MagickCoreSignature);
746 if (IsEventLogging() != MagickFalse)
747 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
748 quantum_info->endian=endian;
749 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
750}
751
752/*
753%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
754% %
755% %
756% %
757% S e t Q u a n t u m F o r m a t %
758% %
759% %
760% %
761%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
762%
763% SetQuantumFormat() sets the quantum format.
764%
765% The format of the SetQuantumFormat method is:
766%
767% MagickBooleanType SetQuantumFormat(const Image *image,
768% QuantumInfo *quantum_info,const QuantumFormatType format)
769%
770% A description of each parameter follows:
771%
772% o image: the image.
773%
774% o quantum_info: the quantum info.
775%
776% o format: the quantum format.
777%
778*/
779MagickExport MagickBooleanType SetQuantumFormat(const Image *image,
780 QuantumInfo *quantum_info,const QuantumFormatType format)
781{
782 assert(image != (Image *) NULL);
783 assert(image->signature == MagickCoreSignature);
784 assert(quantum_info != (QuantumInfo *) NULL);
785 assert(quantum_info->signature == MagickCoreSignature);
786 if (IsEventLogging() != MagickFalse)
787 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
788 quantum_info->format=format;
789 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
790}
791
792/*
793%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
794% %
795% %
796% %
797% S e t Q u a n t u m I m a g e T y p e %
798% %
799% %
800% %
801%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
802%
803% SetQuantumImageType() sets the image type based on the quantum type.
804%
805% The format of the SetQuantumImageType method is:
806%
807% void ImageType SetQuantumImageType(Image *image,
808% const QuantumType quantum_type)
809%
810% A description of each parameter follows:
811%
812% o image: the image.
813%
814% o quantum_type: Declare which pixel components to transfer (red, green,
815% blue, opacity, RGB, or RGBA).
816%
817*/
818MagickExport void SetQuantumImageType(Image *image,
819 const QuantumType quantum_type)
820{
821 assert(image != (Image *) NULL);
822 assert(image->signature == MagickCoreSignature);
823 if (IsEventLogging() != MagickFalse)
824 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
825 switch (quantum_type)
826 {
827 case IndexQuantum:
828 case IndexAlphaQuantum:
829 {
830 image->type=PaletteType;
831 break;
832 }
833 case GrayQuantum:
834 case GrayAlphaQuantum:
835 {
836 image->type=GrayscaleType;
837 if (image->depth == 1)
838 image->type=BilevelType;
839 break;
840 }
841 case CyanQuantum:
842 case MagentaQuantum:
843 case YellowQuantum:
844 case BlackQuantum:
845 case CMYKQuantum:
846 case CMYKAQuantum:
847 {
848 image->type=ColorSeparationType;
849 break;
850 }
851 default:
852 {
853 image->type=TrueColorType;
854 break;
855 }
856 }
857}
858
859/*
860%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
861% %
862% %
863% %
864% S e t Q u a n t u m P a c k %
865% %
866% %
867% %
868%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
869%
870% SetQuantumPack() sets the quantum pack flag.
871%
872% The format of the SetQuantumPack method is:
873%
874% void SetQuantumPack(QuantumInfo *quantum_info,
875% const MagickBooleanType pack)
876%
877% A description of each parameter follows:
878%
879% o quantum_info: the quantum info.
880%
881% o pack: the pack flag.
882%
883*/
884MagickExport void SetQuantumPack(QuantumInfo *quantum_info,
885 const MagickBooleanType pack)
886{
887 assert(quantum_info != (QuantumInfo *) NULL);
888 assert(quantum_info->signature == MagickCoreSignature);
889 quantum_info->pack=pack;
890}
891
892/*
893%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
894% %
895% %
896% %
897% S e t Q u a n t u m P a d %
898% %
899% %
900% %
901%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
902%
903% SetQuantumPad() sets the quantum pad.
904%
905% The format of the SetQuantumPad method is:
906%
907% MagickBooleanType SetQuantumPad(const Image *image,
908% QuantumInfo *quantum_info,const size_t pad)
909%
910% A description of each parameter follows:
911%
912% o image: the image.
913%
914% o quantum_info: the quantum info.
915%
916% o pad: the quantum pad.
917%
918*/
919MagickExport MagickBooleanType SetQuantumPad(const Image *image,
920 QuantumInfo *quantum_info,const size_t pad)
921{
922 assert(image != (Image *) NULL);
923 assert(image->signature == MagickCoreSignature);
924 assert(quantum_info != (QuantumInfo *) NULL);
925 assert(quantum_info->signature == MagickCoreSignature);
926 if (IsEventLogging() != MagickFalse)
927 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
928 if (pad >= (MAGICK_SSIZE_MAX/5))
929 return(MagickFalse);
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*/
959MagickExport 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*/
991MagickExport 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*/
1023MagickExport 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}