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