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-2019 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 register 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 register 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=depth;
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 > 16)
685 quantum_info->depth=32;
686 else
687 quantum_info->depth=16;
688 }
689 if (quantum_info->pixels != (MemoryInfo **) NULL)
690 DestroyQuantumPixels(quantum_info);
691 quantum=(quantum_info->pad+MaxPixelChannels)*(quantum_info->depth+7)/8;
692 extent=MagickMax(image->columns,image->rows)*quantum;
693 if ((MagickMax(image->columns,image->rows) != 0) &&
694 (quantum != (extent/MagickMax(image->columns,image->rows))))
695 return(MagickFalse);
696 return(AcquireQuantumPixels(quantum_info,extent));
697 }
698
699 /*
700 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
701 % %
702 % %
703 % %
704 % S e t Q u a n t u m E n d i a n %
705 % %
706 % %
707 % %
708 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
709 %
710 % SetQuantumEndian() sets the quantum endian.
711 %
712 % The endian of the SetQuantumEndian method is:
713 %
714 % MagickBooleanType SetQuantumEndian(const Image *image,
715 % QuantumInfo *quantum_info,const EndianType endian)
716 %
717 % A description of each parameter follows:
718 %
719 % o image: the image.
720 %
721 % o quantum_info: the quantum info.
722 %
723 % o endian: the quantum endian.
724 %
725 */
SetQuantumEndian(const Image * image,QuantumInfo * quantum_info,const EndianType endian)726 MagickExport MagickBooleanType SetQuantumEndian(const Image *image,
727 QuantumInfo *quantum_info,const EndianType endian)
728 {
729 assert(image != (Image *) NULL);
730 assert(image->signature == MagickCoreSignature);
731 if (image->debug != MagickFalse)
732 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
733 assert(quantum_info != (QuantumInfo *) NULL);
734 assert(quantum_info->signature == MagickCoreSignature);
735 quantum_info->endian=endian;
736 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
737 }
738
739 /*
740 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
741 % %
742 % %
743 % %
744 % S e t Q u a n t u m F o r m a t %
745 % %
746 % %
747 % %
748 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
749 %
750 % SetQuantumFormat() sets the quantum format.
751 %
752 % The format of the SetQuantumFormat method is:
753 %
754 % MagickBooleanType SetQuantumFormat(const Image *image,
755 % QuantumInfo *quantum_info,const QuantumFormatType format)
756 %
757 % A description of each parameter follows:
758 %
759 % o image: the image.
760 %
761 % o quantum_info: the quantum info.
762 %
763 % o format: the quantum format.
764 %
765 */
SetQuantumFormat(const Image * image,QuantumInfo * quantum_info,const QuantumFormatType format)766 MagickExport MagickBooleanType SetQuantumFormat(const Image *image,
767 QuantumInfo *quantum_info,const QuantumFormatType format)
768 {
769 assert(image != (Image *) NULL);
770 assert(image->signature == MagickCoreSignature);
771 if (image->debug != MagickFalse)
772 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
773 assert(quantum_info != (QuantumInfo *) NULL);
774 assert(quantum_info->signature == MagickCoreSignature);
775 quantum_info->format=format;
776 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
777 }
778
779 /*
780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
781 % %
782 % %
783 % %
784 % S e t Q u a n t u m I m a g e T y p e %
785 % %
786 % %
787 % %
788 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
789 %
790 % SetQuantumImageType() sets the image type based on the quantum type.
791 %
792 % The format of the SetQuantumImageType method is:
793 %
794 % void ImageType SetQuantumImageType(Image *image,
795 % const QuantumType quantum_type)
796 %
797 % A description of each parameter follows:
798 %
799 % o image: the image.
800 %
801 % o quantum_type: Declare which pixel components to transfer (red, green,
802 % blue, opacity, RGB, or RGBA).
803 %
804 */
SetQuantumImageType(Image * image,const QuantumType quantum_type)805 MagickExport void SetQuantumImageType(Image *image,
806 const QuantumType quantum_type)
807 {
808 assert(image != (Image *) NULL);
809 assert(image->signature == MagickCoreSignature);
810 if (image->debug != MagickFalse)
811 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
812 switch (quantum_type)
813 {
814 case IndexQuantum:
815 case IndexAlphaQuantum:
816 {
817 image->type=PaletteType;
818 break;
819 }
820 case GrayQuantum:
821 case GrayAlphaQuantum:
822 {
823 image->type=GrayscaleType;
824 if (image->depth == 1)
825 image->type=BilevelType;
826 break;
827 }
828 case CyanQuantum:
829 case MagentaQuantum:
830 case YellowQuantum:
831 case BlackQuantum:
832 case CMYKQuantum:
833 case CMYKAQuantum:
834 {
835 image->type=ColorSeparationType;
836 break;
837 }
838 default:
839 {
840 image->type=TrueColorType;
841 break;
842 }
843 }
844 }
845
846 /*
847 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
848 % %
849 % %
850 % %
851 % S e t Q u a n t u m P a c k %
852 % %
853 % %
854 % %
855 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
856 %
857 % SetQuantumPack() sets the quantum pack flag.
858 %
859 % The format of the SetQuantumPack method is:
860 %
861 % void SetQuantumPack(QuantumInfo *quantum_info,
862 % const MagickBooleanType pack)
863 %
864 % A description of each parameter follows:
865 %
866 % o quantum_info: the quantum info.
867 %
868 % o pack: the pack flag.
869 %
870 */
SetQuantumPack(QuantumInfo * quantum_info,const MagickBooleanType pack)871 MagickExport void SetQuantumPack(QuantumInfo *quantum_info,
872 const MagickBooleanType pack)
873 {
874 assert(quantum_info != (QuantumInfo *) NULL);
875 assert(quantum_info->signature == MagickCoreSignature);
876 quantum_info->pack=pack;
877 }
878
879 /*
880 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
881 % %
882 % %
883 % %
884 % S e t Q u a n t u m P a d %
885 % %
886 % %
887 % %
888 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
889 %
890 % SetQuantumPad() sets the quantum pad.
891 %
892 % The format of the SetQuantumPad method is:
893 %
894 % MagickBooleanType SetQuantumPad(const Image *image,
895 % QuantumInfo *quantum_info,const size_t pad)
896 %
897 % A description of each parameter follows:
898 %
899 % o image: the image.
900 %
901 % o quantum_info: the quantum info.
902 %
903 % o pad: the quantum pad.
904 %
905 */
SetQuantumPad(const Image * image,QuantumInfo * quantum_info,const size_t pad)906 MagickExport MagickBooleanType SetQuantumPad(const Image *image,
907 QuantumInfo *quantum_info,const size_t pad)
908 {
909 assert(image != (Image *) NULL);
910 assert(image->signature == MagickCoreSignature);
911 if (image->debug != MagickFalse)
912 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
913 assert(quantum_info != (QuantumInfo *) NULL);
914 assert(quantum_info->signature == MagickCoreSignature);
915 quantum_info->pad=pad;
916 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
917 }
918
919 /*
920 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
921 % %
922 % %
923 % %
924 % S e t Q u a n t u m M i n I s W h i t e %
925 % %
926 % %
927 % %
928 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
929 %
930 % SetQuantumMinIsWhite() sets the quantum min-is-white flag.
931 %
932 % The format of the SetQuantumMinIsWhite method is:
933 %
934 % void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
935 % const MagickBooleanType min_is_white)
936 %
937 % A description of each parameter follows:
938 %
939 % o quantum_info: the quantum info.
940 %
941 % o min_is_white: the min-is-white flag.
942 %
943 */
SetQuantumMinIsWhite(QuantumInfo * quantum_info,const MagickBooleanType min_is_white)944 MagickExport void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
945 const MagickBooleanType min_is_white)
946 {
947 assert(quantum_info != (QuantumInfo *) NULL);
948 assert(quantum_info->signature == MagickCoreSignature);
949 quantum_info->min_is_white=min_is_white;
950 }
951
952 /*
953 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
954 % %
955 % %
956 % %
957 % S e t Q u a n t u m Q u a n t u m %
958 % %
959 % %
960 % %
961 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
962 %
963 % SetQuantumQuantum() sets the quantum quantum.
964 %
965 % The format of the SetQuantumQuantum method is:
966 %
967 % void SetQuantumQuantum(QuantumInfo *quantum_info,
968 % const size_t quantum)
969 %
970 % A description of each parameter follows:
971 %
972 % o quantum_info: the quantum info.
973 %
974 % o quantum: the quantum quantum.
975 %
976 */
SetQuantumQuantum(QuantumInfo * quantum_info,const size_t quantum)977 MagickExport void SetQuantumQuantum(QuantumInfo *quantum_info,
978 const size_t quantum)
979 {
980 assert(quantum_info != (QuantumInfo *) NULL);
981 assert(quantum_info->signature == MagickCoreSignature);
982 quantum_info->quantum=quantum;
983 }
984
985 /*
986 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
987 % %
988 % %
989 % %
990 % S e t Q u a n t u m S c a l e %
991 % %
992 % %
993 % %
994 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
995 %
996 % SetQuantumScale() sets the quantum scale.
997 %
998 % The format of the SetQuantumScale method is:
999 %
1000 % void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1001 %
1002 % A description of each parameter follows:
1003 %
1004 % o quantum_info: the quantum info.
1005 %
1006 % o scale: the quantum scale.
1007 %
1008 */
SetQuantumScale(QuantumInfo * quantum_info,const double scale)1009 MagickExport void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1010 {
1011 assert(quantum_info != (QuantumInfo *) NULL);
1012 assert(quantum_info->signature == MagickCoreSignature);
1013 quantum_info->scale=scale;
1014 }
1015