MagickCore  6.9.13-15
Convert, Edit, Or Compose Bitmap Images
quantum.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % QQQ U U AAA N N TTTTT U U M M %
7 % Q Q U U A A NN N T U U MM MM %
8 % Q Q U U AAAAA N N N T U U M M M %
9 % Q QQ U U A A N NN T U U M M %
10 % QQQQ UUU A A N N T UUU M M %
11 % %
12 % MagicCore Methods to Acquire / Destroy Quantum Pixels %
13 % %
14 % Software Design %
15 % Cristy %
16 % October 1998 %
17 % %
18 % %
19 % Copyright 1999 ImageMagick Studio LLC, a non-profit organization %
20 % dedicated to making software imaging solutions freely available. %
21 % %
22 % You may not use this file except in compliance with the License. You may %
23 % obtain a copy of the License at %
24 % %
25 % https://imagemagick.org/script/license.php %
26 % %
27 % Unless required by applicable law or agreed to in writing, software %
28 % distributed under the License is distributed on an "AS IS" BASIS, %
29 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
30 % See the License for the specific language governing permissions and %
31 % limitations under the License. %
32 % %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 %
35 %
36 */
37 ␌
38 /*
39  Include declarations.
40 */
41 #include "magick/studio.h"
42 #include "magick/attribute.h"
43 #include "magick/blob.h"
44 #include "magick/blob-private.h"
45 #include "magick/color-private.h"
46 #include "magick/exception.h"
47 #include "magick/exception-private.h"
48 #include "magick/cache.h"
49 #include "magick/cache-private.h"
50 #include "magick/colorspace.h"
51 #include "magick/colorspace-private.h"
52 #include "magick/constitute.h"
53 #include "magick/delegate.h"
54 #include "magick/geometry.h"
55 #include "magick/list.h"
56 #include "magick/magick.h"
57 #include "magick/memory_.h"
58 #include "magick/monitor.h"
59 #include "magick/option.h"
60 #include "magick/pixel.h"
61 #include "magick/pixel-private.h"
62 #include "magick/property.h"
63 #include "magick/quantum.h"
64 #include "magick/quantum-private.h"
65 #include "magick/resource_.h"
66 #include "magick/semaphore.h"
67 #include "magick/statistic.h"
68 #include "magick/stream.h"
69 #include "magick/string_.h"
70 #include "magick/string-private.h"
71 #include "magick/thread-private.h"
72 #include "magick/utility.h"
73 ␌
74 /*
75  Define declarations.
76 */
77 #define QuantumSignature 0xab
78 ␌
79 /*
80  Forward declarations.
81 */
82 static void
83  DestroyQuantumPixels(QuantumInfo *);
84 ␌
85 /*
86 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
87 % %
88 % %
89 % %
90 % A c q u i r e Q u a n t u m I n f o %
91 % %
92 % %
93 % %
94 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
95 %
96 % AcquireQuantumInfo() allocates the QuantumInfo structure.
97 %
98 % The format of the AcquireQuantumInfo method is:
99 %
100 % QuantumInfo *AcquireQuantumInfo(const ImageInfo *image_info,Image *image)
101 %
102 % A description of each parameter follows:
103 %
104 % o image_info: the image info.
105 %
106 % o image: the image.
107 %
108 */
109 MagickExport QuantumInfo *AcquireQuantumInfo(const ImageInfo *image_info,
110  Image *image)
111 {
112  MagickBooleanType
113  status;
114 
116  *quantum_info;
117 
118  quantum_info=(QuantumInfo *) AcquireMagickMemory(sizeof(*quantum_info));
119  if (quantum_info == (QuantumInfo *) NULL)
120  ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
121  quantum_info->signature=MagickCoreSignature;
122  GetQuantumInfo(image_info,quantum_info);
123  if (image == (const Image *) NULL)
124  return(quantum_info);
125  status=SetQuantumDepth(image,quantum_info,image->depth);
126  quantum_info->endian=image->endian;
127  if (status == MagickFalse)
128  quantum_info=DestroyQuantumInfo(quantum_info);
129  return(quantum_info);
130 }
131 ␌
132 /*
133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
134 % %
135 % %
136 % %
137 + A c q u i r e Q u a n t u m P i x e l s %
138 % %
139 % %
140 % %
141 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
142 %
143 % AcquireQuantumPixels() allocates the pixel staging area.
144 %
145 % The format of the AcquireQuantumPixels method is:
146 %
147 % MagickBooleanType AcquireQuantumPixels(QuantumInfo *quantum_info,
148 % const size_t extent)
149 %
150 % A description of each parameter follows:
151 %
152 % o quantum_info: the quantum info.
153 %
154 % o extent: the quantum info.
155 %
156 */
157 static MagickBooleanType AcquireQuantumPixels(QuantumInfo *quantum_info,
158  const size_t extent)
159 {
160  ssize_t
161  i;
162 
163  assert(quantum_info != (QuantumInfo *) NULL);
164  assert(quantum_info->signature == MagickCoreSignature);
165  quantum_info->number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
166  quantum_info->pixels=(MemoryInfo **) AcquireQuantumMemory(
167  quantum_info->number_threads,sizeof(*quantum_info->pixels));
168  if (quantum_info->pixels == (MemoryInfo **) NULL)
169  return(MagickFalse);
170  quantum_info->extent=extent;
171  (void) memset(quantum_info->pixels,0,quantum_info->number_threads*
172  sizeof(*quantum_info->pixels));
173  for (i=0; i < (ssize_t) quantum_info->number_threads; i++)
174  {
175  unsigned char
176  *pixels;
177 
178  quantum_info->pixels[i]=AcquireVirtualMemory(extent+1,sizeof(*pixels));
179  if (quantum_info->pixels[i] == (MemoryInfo *) NULL)
180  {
181  DestroyQuantumPixels(quantum_info);
182  return(MagickFalse);
183  }
184  pixels=(unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[i]);
185  (void) memset(pixels,0,(extent+1)*sizeof(*pixels));
186  pixels[extent]=QuantumSignature;
187  }
188  return(MagickTrue);
189 }
190 ␌
191 /*
192 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
193 % %
194 % %
195 % %
196 % D e s t r o y Q u a n t u m I n f o %
197 % %
198 % %
199 % %
200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
201 %
202 % DestroyQuantumInfo() deallocates memory associated with the QuantumInfo
203 % structure.
204 %
205 % The format of the DestroyQuantumInfo method is:
206 %
207 % QuantumInfo *DestroyQuantumInfo(QuantumInfo *quantum_info)
208 %
209 % A description of each parameter follows:
210 %
211 % o quantum_info: the quantum info.
212 %
213 */
214 MagickExport QuantumInfo *DestroyQuantumInfo(QuantumInfo *quantum_info)
215 {
216  assert(quantum_info != (QuantumInfo *) NULL);
217  assert(quantum_info->signature == MagickCoreSignature);
218  if (quantum_info->pixels != (MemoryInfo **) NULL)
219  DestroyQuantumPixels(quantum_info);
220  if (quantum_info->semaphore != (SemaphoreInfo *) NULL)
221  DestroySemaphoreInfo(&quantum_info->semaphore);
222  quantum_info->signature=(~MagickCoreSignature);
223  quantum_info=(QuantumInfo *) RelinquishMagickMemory(quantum_info);
224  return(quantum_info);
225 }
226 ␌
227 /*
228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
229 % %
230 % %
231 % %
232 + D e s t r o y Q u a n t u m P i x e l s %
233 % %
234 % %
235 % %
236 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
237 %
238 % DestroyQuantumPixels() destroys the quantum pixels.
239 %
240 % The format of the DestroyQuantumPixels() method is:
241 %
242 % void DestroyQuantumPixels(QuantumInfo *quantum_info)
243 %
244 % A description of each parameter follows:
245 %
246 % o quantum_info: the quantum info.
247 %
248 */
249 static void DestroyQuantumPixels(QuantumInfo *quantum_info)
250 {
251  ssize_t
252  i;
253 
254  ssize_t
255  extent;
256 
257  assert(quantum_info != (QuantumInfo *) NULL);
258  assert(quantum_info->signature == MagickCoreSignature);
259  assert(quantum_info->pixels != (MemoryInfo **) NULL);
260  extent=(ssize_t) quantum_info->extent;
261  for (i=0; i < (ssize_t) quantum_info->number_threads; i++)
262  if (quantum_info->pixels[i] != (MemoryInfo *) NULL)
263  {
264 #ifndef NDEBUG
265  unsigned char
266  *pixels;
267 
268  /*
269  Did we overrun our quantum buffer?
270  */
271  pixels=(unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[i]);
272  assert(pixels[extent] == QuantumSignature);
273 #endif
274  quantum_info->pixels[i]=RelinquishVirtualMemory(
275  quantum_info->pixels[i]);
276  }
277  quantum_info->pixels=(MemoryInfo **) RelinquishMagickMemory(
278  quantum_info->pixels);
279 }
280 ␌
281 /*
282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
283 % %
284 % %
285 % %
286 % G e t Q u a n t u m E x t e n t %
287 % %
288 % %
289 % %
290 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
291 %
292 % GetQuantumExtent() returns the quantum pixel buffer extent.
293 %
294 % The format of the GetQuantumExtent method is:
295 %
296 % size_t GetQuantumExtent(Image *image,const QuantumInfo *quantum_info,
297 % const QuantumType quantum_type)
298 %
299 % A description of each parameter follows:
300 %
301 % o image: the image.
302 %
303 % o quantum_info: the quantum info.
304 %
305 % o quantum_type: Declare which pixel components to transfer (red, green,
306 % blue, opacity, RGB, or RGBA).
307 %
308 */
309 MagickExport size_t GetQuantumExtent(const Image *image,
310  const QuantumInfo *quantum_info,const QuantumType quantum_type)
311 {
312  size_t
313  channels;
314 
315  assert(quantum_info != (QuantumInfo *) NULL);
316  assert(quantum_info->signature == MagickCoreSignature);
317  channels=1;
318  switch (quantum_type)
319  {
320  case GrayAlphaQuantum: channels=2; break;
321  case IndexAlphaQuantum: channels=2; break;
322  case RGBQuantum: channels=3; break;
323  case BGRQuantum: channels=3; break;
324  case RGBAQuantum: channels=4; break;
325  case RGBOQuantum: channels=4; break;
326  case BGRAQuantum: channels=4; break;
327  case CMYKQuantum: channels=4; break;
328  case CMYKAQuantum: channels=5; break;
329  case CbYCrAQuantum: channels=4; break;
330  case CbYCrQuantum: channels=3; break;
331  case CbYCrYQuantum: channels=4; break;
332  default: break;
333  }
334  if (quantum_info->pack == MagickFalse)
335  return((size_t) (channels*image->columns*((quantum_info->depth+7)/8))+
336  (quantum_info->pad*image->columns));
337  return((size_t) ((channels*image->columns*quantum_info->depth+7)/8)+
338  (quantum_info->pad*image->columns));
339 }
340 ␌
341 /*
342 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
343 % %
344 % %
345 % %
346 % G e t Q u a n t u m E n d i a n %
347 % %
348 % %
349 % %
350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
351 %
352 % GetQuantumEndian() returns the quantum endian of the image.
353 %
354 % The endian of the GetQuantumEndian method is:
355 %
356 % EndianType GetQuantumEndian(const QuantumInfo *quantum_info)
357 %
358 % A description of each parameter follows:
359 %
360 % o quantum_info: the quantum info.
361 %
362 */
363 MagickExport EndianType GetQuantumEndian(const QuantumInfo *quantum_info)
364 {
365  assert(quantum_info != (QuantumInfo *) NULL);
366  assert(quantum_info->signature == MagickCoreSignature);
367  return(quantum_info->endian);
368 }
369 ␌
370 /*
371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
372 % %
373 % %
374 % %
375 % G e t Q u a n t u m F o r m a t %
376 % %
377 % %
378 % %
379 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
380 %
381 % GetQuantumFormat() returns the quantum format of the image.
382 %
383 % The format of the GetQuantumFormat method is:
384 %
385 % QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info)
386 %
387 % A description of each parameter follows:
388 %
389 % o quantum_info: the quantum info.
390 %
391 */
392 MagickExport QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info)
393 {
394  assert(quantum_info != (QuantumInfo *) NULL);
395  assert(quantum_info->signature == MagickCoreSignature);
396  return(quantum_info->format);
397 }
398 ␌
399 /*
400 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
401 % %
402 % %
403 % %
404 % G e t Q u a n t u m I n f o %
405 % %
406 % %
407 % %
408 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
409 %
410 % GetQuantumInfo() initializes the QuantumInfo structure to default values.
411 %
412 % The format of the GetQuantumInfo method is:
413 %
414 % GetQuantumInfo(const ImageInfo *image_info,QuantumInfo *quantum_info)
415 %
416 % A description of each parameter follows:
417 %
418 % o image_info: the image info.
419 %
420 % o quantum_info: the quantum info.
421 %
422 */
423 MagickExport void GetQuantumInfo(const ImageInfo *image_info,
424  QuantumInfo *quantum_info)
425 {
426  const char
427  *option;
428 
429  assert(quantum_info != (QuantumInfo *) NULL);
430  (void) memset(quantum_info,0,sizeof(*quantum_info));
431  quantum_info->quantum=8;
432  quantum_info->maximum=1.0;
433  quantum_info->scale=QuantumRange;
434  quantum_info->pack=MagickTrue;
435  quantum_info->semaphore=AllocateSemaphoreInfo();
436  quantum_info->signature=MagickCoreSignature;
437  if (image_info == (const ImageInfo *) NULL)
438  return;
439  option=GetImageOption(image_info,"quantum:format");
440  if (option != (char *) NULL)
441  quantum_info->format=(QuantumFormatType) ParseCommandOption(
442  MagickQuantumFormatOptions,MagickFalse,option);
443  option=GetImageOption(image_info,"quantum:minimum");
444  if (option != (char *) NULL)
445  quantum_info->minimum=StringToDouble(option,(char **) NULL);
446  option=GetImageOption(image_info,"quantum:maximum");
447  if (option != (char *) NULL)
448  quantum_info->maximum=StringToDouble(option,(char **) NULL);
449  if ((quantum_info->minimum == 0.0) && (quantum_info->maximum == 0.0))
450  quantum_info->scale=0.0;
451  else
452  if (quantum_info->minimum == quantum_info->maximum)
453  {
454  quantum_info->scale=(MagickRealType) QuantumRange/quantum_info->minimum;
455  quantum_info->minimum=0.0;
456  }
457  else
458  quantum_info->scale=(MagickRealType) QuantumRange/(quantum_info->maximum-
459  quantum_info->minimum);
460  option=GetImageOption(image_info,"quantum:scale");
461  if (option != (char *) NULL)
462  quantum_info->scale=StringToDouble(option,(char **) NULL);
463  option=GetImageOption(image_info,"quantum:polarity");
464  if (option != (char *) NULL)
465  quantum_info->min_is_white=LocaleCompare(option,"min-is-white") == 0 ?
466  MagickTrue : MagickFalse;
467  quantum_info->endian=image_info->endian;
468  ResetQuantumState(quantum_info);
469 }
470 ␌
471 /*
472 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
473 % %
474 % %
475 % %
476 % G e t Q u a n t u m P i x e l s %
477 % %
478 % %
479 % %
480 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
481 %
482 % GetQuantumPixels() returns the quantum pixels.
483 %
484 % The format of the GetQuantumPixels method is:
485 %
486 % unsigned char *QuantumPixels GetQuantumPixels(
487 % const QuantumInfo *quantum_info)
488 %
489 % A description of each parameter follows:
490 %
491 % o image: the image.
492 %
493 */
494 MagickExport unsigned char *GetQuantumPixels(const QuantumInfo *quantum_info)
495 {
496  const int
497  id = GetOpenMPThreadId();
498 
499  assert(quantum_info != (QuantumInfo *) NULL);
500  assert(quantum_info->signature == MagickCoreSignature);
501  return((unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[id]));
502 }
503 ␌
504 /*
505 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
506 % %
507 % %
508 % %
509 % G e t Q u a n t u m T y p e %
510 % %
511 % %
512 % %
513 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
514 %
515 % GetQuantumType() returns the quantum type of the image.
516 %
517 % The format of the GetQuantumType method is:
518 %
519 % QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
520 %
521 % A description of each parameter follows:
522 %
523 % o image: the image.
524 %
525 */
526 MagickExport QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
527 {
528  QuantumType
529  quantum_type;
530 
531  assert(image != (Image *) NULL);
532  assert(image->signature == MagickCoreSignature);
533  if (IsEventLogging() != MagickFalse)
534  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
535  (void) exception;
536  quantum_type=RGBQuantum;
537  if (image->matte != MagickFalse)
538  quantum_type=RGBAQuantum;
539  if (image->colorspace == CMYKColorspace)
540  {
541  quantum_type=CMYKQuantum;
542  if (image->matte != MagickFalse)
543  quantum_type=CMYKAQuantum;
544  }
545  if (IsGrayColorspace(image->colorspace) != MagickFalse)
546  {
547  quantum_type=GrayQuantum;
548  if (image->matte != MagickFalse)
549  quantum_type=GrayAlphaQuantum;
550  }
551  if (image->storage_class == PseudoClass)
552  {
553  quantum_type=IndexQuantum;
554  if (image->matte != MagickFalse)
555  quantum_type=IndexAlphaQuantum;
556  }
557  return(quantum_type);
558 }
559 ␌
560 /*
561 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
562 % %
563 % %
564 % %
565 % R e s e t Q u a n t u m S t a t e %
566 % %
567 % %
568 % %
569 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
570 %
571 % ResetQuantumState() resets the quantum state.
572 %
573 % The format of the ResetQuantumState method is:
574 %
575 % void ResetQuantumState(QuantumInfo *quantum_info)
576 %
577 % A description of each parameter follows:
578 %
579 % o quantum_info: the quantum info.
580 %
581 */
582 MagickPrivate void ResetQuantumState(QuantumInfo *quantum_info)
583 {
584  static const unsigned int mask[32] =
585  {
586  0x00000000U, 0x00000001U, 0x00000003U, 0x00000007U, 0x0000000fU,
587  0x0000001fU, 0x0000003fU, 0x0000007fU, 0x000000ffU, 0x000001ffU,
588  0x000003ffU, 0x000007ffU, 0x00000fffU, 0x00001fffU, 0x00003fffU,
589  0x00007fffU, 0x0000ffffU, 0x0001ffffU, 0x0003ffffU, 0x0007ffffU,
590  0x000fffffU, 0x001fffffU, 0x003fffffU, 0x007fffffU, 0x00ffffffU,
591  0x01ffffffU, 0x03ffffffU, 0x07ffffffU, 0x0fffffffU, 0x1fffffffU,
592  0x3fffffffU, 0x7fffffffU
593  };
594 
595  assert(quantum_info != (QuantumInfo *) NULL);
596  assert(quantum_info->signature == MagickCoreSignature);
597  quantum_info->state.inverse_scale=1.0;
598  if (fabs(quantum_info->scale) >= MagickEpsilon)
599  quantum_info->state.inverse_scale/=quantum_info->scale;
600  quantum_info->state.pixel=0U;
601  quantum_info->state.bits=0U;
602  quantum_info->state.mask=mask;
603 }
604 ␌
605 /*
606 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
607 % %
608 % %
609 % %
610 % S e t Q u a n t u m F o r m a t %
611 % %
612 % %
613 % %
614 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
615 %
616 % SetQuantumAlphaType() sets the quantum format.
617 %
618 % The format of the SetQuantumAlphaType method is:
619 %
620 % void SetQuantumAlphaType(QuantumInfo *quantum_info,
621 % const QuantumAlphaType type)
622 %
623 % A description of each parameter follows:
624 %
625 % o quantum_info: the quantum info.
626 %
627 % o type: the alpha type (e.g. associate).
628 %
629 */
630 MagickExport void SetQuantumAlphaType(QuantumInfo *quantum_info,
631  const QuantumAlphaType type)
632 {
633  assert(quantum_info != (QuantumInfo *) NULL);
634  assert(quantum_info->signature == MagickCoreSignature);
635  quantum_info->alpha_type=type;
636 }
637 ␌
638 /*
639 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
640 % %
641 % %
642 % %
643 % S e t Q u a n t u m D e p t h %
644 % %
645 % %
646 % %
647 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
648 %
649 % SetQuantumDepth() sets the quantum depth.
650 %
651 % The format of the SetQuantumDepth method is:
652 %
653 % MagickBooleanType SetQuantumDepth(const Image *image,
654 % QuantumInfo *quantum_info,const size_t depth)
655 %
656 % A description of each parameter follows:
657 %
658 % o image: the image.
659 %
660 % o quantum_info: the quantum info.
661 %
662 % o depth: the quantum depth.
663 %
664 */
665 MagickExport MagickBooleanType SetQuantumDepth(const Image *image,
666  QuantumInfo *quantum_info,const size_t depth)
667 {
668  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 */
739 MagickExport 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 */
779 MagickExport 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 */
818 MagickExport 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 */
884 MagickExport 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 */
919 MagickExport 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 */
959 MagickExport void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
960  const MagickBooleanType min_is_white)
961 {
962  assert(quantum_info != (QuantumInfo *) NULL);
963  assert(quantum_info->signature == MagickCoreSignature);
964  quantum_info->min_is_white=min_is_white;
965 }
966 ␌
967 /*
968 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
969 % %
970 % %
971 % %
972 % S e t Q u a n t u m Q u a n t u m %
973 % %
974 % %
975 % %
976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
977 %
978 % SetQuantumQuantum() sets the quantum quantum.
979 %
980 % The format of the SetQuantumQuantum method is:
981 %
982 % void SetQuantumQuantum(QuantumInfo *quantum_info,const size_t quantum)
983 %
984 % A description of each parameter follows:
985 %
986 % o quantum_info: the quantum info.
987 %
988 % o quantum: the quantum quantum.
989 %
990 */
991 MagickExport void SetQuantumQuantum(QuantumInfo *quantum_info,
992  const size_t quantum)
993 {
994  assert(quantum_info != (QuantumInfo *) NULL);
995  assert(quantum_info->signature == MagickCoreSignature);
996  quantum_info->quantum=quantum;
997 }
998 ␌
999 /*
1000 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1001 % %
1002 % %
1003 % %
1004 % S e t Q u a n t u m S c a l e %
1005 % %
1006 % %
1007 % %
1008 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1009 %
1010 % SetQuantumScale() sets the quantum scale.
1011 %
1012 % The format of the SetQuantumScale method is:
1013 %
1014 % void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1015 %
1016 % A description of each parameter follows:
1017 %
1018 % o quantum_info: the quantum info.
1019 %
1020 % o scale: the quantum scale.
1021 %
1022 */
1023 MagickExport void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
1024 {
1025  assert(quantum_info != (QuantumInfo *) NULL);
1026  assert(quantum_info->signature == MagickCoreSignature);
1027  quantum_info->scale=scale;
1028 }
Definition: image.h:134