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"
78#define QuantumSignature 0xab
84 DestroyQuantumPixels(QuantumInfo *);
110MagickExport QuantumInfo *AcquireQuantumInfo(
const ImageInfo *image_info,
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);
156static MagickBooleanType AcquireQuantumPixels(QuantumInfo *quantum_info,
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)
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++)
177 quantum_info->pixels[i]=AcquireVirtualMemory(extent+1,
sizeof(*pixels));
178 if (quantum_info->pixels[i] == (MemoryInfo *) NULL)
180 DestroyQuantumPixels(quantum_info);
183 pixels=(
unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[i]);
184 (void) memset(pixels,0,(extent+1)*
sizeof(*pixels));
185 pixels[extent]=QuantumSignature;
213MagickExport QuantumInfo *DestroyQuantumInfo(QuantumInfo *quantum_info)
215 assert(quantum_info != (QuantumInfo *) NULL);
216 assert(quantum_info->signature == MagickCoreSignature);
217 if (quantum_info->pixels != (MemoryInfo **) NULL)
218 DestroyQuantumPixels(quantum_info);
220 RelinquishSemaphoreInfo(&quantum_info->semaphore);
221 quantum_info->signature=(~MagickCoreSignature);
222 quantum_info=(QuantumInfo *) RelinquishMagickMemory(quantum_info);
223 return(quantum_info);
248static void DestroyQuantumPixels(QuantumInfo *quantum_info)
253 assert(quantum_info != (QuantumInfo *) NULL);
254 assert(quantum_info->signature == MagickCoreSignature);
255 assert(quantum_info->pixels != (MemoryInfo **) NULL);
256 for (i=0; i < (ssize_t) quantum_info->number_threads; i++)
257 if (quantum_info->pixels[i] != (MemoryInfo *) NULL)
269 extent=(ssize_t) quantum_info->extent;
270 pixels=(
unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[i]);
271 assert(pixels[extent] == QuantumSignature);
273 quantum_info->pixels[i]=RelinquishVirtualMemory(
274 quantum_info->pixels[i]);
276 quantum_info->pixels=(MemoryInfo **) RelinquishMagickMemory(
277 quantum_info->pixels);
308MagickExport
size_t GetQuantumExtent(
const Image *image,
309 const QuantumInfo *quantum_info,
const QuantumType quantum_type)
314 assert(quantum_info != (QuantumInfo *) NULL);
315 assert(quantum_info->signature == MagickCoreSignature);
317 switch (quantum_type)
319 case GrayAlphaQuantum: channels=2;
break;
320 case IndexAlphaQuantum: channels=2;
break;
321 case RGBQuantum: channels=3;
break;
322 case BGRQuantum: channels=3;
break;
323 case RGBAQuantum: channels=4;
break;
324 case RGBOQuantum: channels=4;
break;
325 case BGRAQuantum: channels=4;
break;
326 case BGROQuantum: channels=4;
break;
327 case CMYKQuantum: channels=4;
break;
328 case CMYKAQuantum: channels=5;
break;
329 case MultispectralQuantum: channels=GetImageChannels(image);
break;
330 case CbYCrAQuantum: channels=4;
break;
331 case CbYCrQuantum: channels=3;
break;
332 case CbYCrYQuantum: channels=4;
break;
335 if (quantum_info->pack == MagickFalse)
336 return((
size_t) (channels*image->columns*((quantum_info->depth+7)/8))+
337 (quantum_info->pad*image->columns));
338 return((
size_t) ((channels*image->columns*quantum_info->depth+7)/8)+
339 (quantum_info->pad*image->columns));
364MagickExport EndianType GetQuantumEndian(
const QuantumInfo *quantum_info)
366 assert(quantum_info != (QuantumInfo *) NULL);
367 assert(quantum_info->signature == MagickCoreSignature);
368 return(quantum_info->endian);
393MagickExport QuantumFormatType GetQuantumFormat(
const QuantumInfo *quantum_info)
395 assert(quantum_info != (QuantumInfo *) NULL);
396 assert(quantum_info->signature == MagickCoreSignature);
397 return(quantum_info->format);
424MagickExport
void GetQuantumInfo(
const ImageInfo *image_info,
425 QuantumInfo *quantum_info)
430 assert(quantum_info != (QuantumInfo *) NULL);
431 (void) memset(quantum_info,0,
sizeof(*quantum_info));
432 quantum_info->quantum=8;
433 quantum_info->maximum=1.0;
434 quantum_info->scale=QuantumRange;
435 quantum_info->pack=MagickTrue;
436 quantum_info->semaphore=AcquireSemaphoreInfo();
437 quantum_info->signature=MagickCoreSignature;
438 if (image_info == (
const ImageInfo *) NULL)
440 option=GetImageOption(image_info,
"quantum:format");
441 if (option != (
char *) NULL)
442 quantum_info->format=(QuantumFormatType) ParseCommandOption(
443 MagickQuantumFormatOptions,MagickFalse,option);
444 option=GetImageOption(image_info,
"quantum:minimum");
445 if (option != (
char *) NULL)
446 quantum_info->minimum=StringToDouble(option,(
char **) NULL);
447 option=GetImageOption(image_info,
"quantum:maximum");
448 if (option != (
char *) NULL)
449 quantum_info->maximum=StringToDouble(option,(
char **) NULL);
450 if ((quantum_info->minimum == 0.0) && (quantum_info->maximum == 0.0))
451 quantum_info->scale=0.0;
453 if (quantum_info->minimum == quantum_info->maximum)
455 quantum_info->scale=(double) QuantumRange/quantum_info->minimum;
456 quantum_info->minimum=0.0;
459 quantum_info->scale=(double) QuantumRange/(quantum_info->maximum-
460 quantum_info->minimum);
461 option=GetImageOption(image_info,
"quantum:scale");
462 if (option != (
char *) NULL)
463 quantum_info->scale=StringToDouble(option,(
char **) NULL);
464 option=GetImageOption(image_info,
"quantum:polarity");
465 if (option != (
char *) NULL)
466 quantum_info->min_is_white=LocaleCompare(option,
"min-is-white") == 0 ?
467 MagickTrue : MagickFalse;
468 quantum_info->endian=image_info->endian;
469 ResetQuantumState(quantum_info);
495MagickExport
unsigned char *GetQuantumPixels(
const QuantumInfo *quantum_info)
498 id = GetOpenMPThreadId();
500 assert(quantum_info != (QuantumInfo *) NULL);
501 assert(quantum_info->signature == MagickCoreSignature);
502 return((
unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[
id]));
529MagickExport QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
534 assert(image != (Image *) NULL);
535 assert(image->signature == MagickCoreSignature);
536 if (IsEventLogging() != MagickFalse)
537 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
539 quantum_type=RGBQuantum;
540 if (image->alpha_trait != UndefinedPixelTrait)
541 quantum_type=RGBAQuantum;
542 if (image->colorspace == CMYKColorspace)
544 quantum_type=CMYKQuantum;
545 if (image->alpha_trait != UndefinedPixelTrait)
546 quantum_type=CMYKAQuantum;
548 if (IsGrayColorspace(image->colorspace) != MagickFalse)
550 quantum_type=GrayQuantum;
551 if (image->alpha_trait != UndefinedPixelTrait)
552 quantum_type=GrayAlphaQuantum;
554 if (image->storage_class == PseudoClass)
556 quantum_type=IndexQuantum;
557 if (image->alpha_trait != UndefinedPixelTrait)
558 quantum_type=IndexAlphaQuantum;
560 if (image->number_meta_channels != 0)
561 quantum_type=MultispectralQuantum;
562 return(quantum_type);
587MagickPrivate
void ResetQuantumState(QuantumInfo *quantum_info)
589 static const unsigned int mask[32] =
591 0x00000000U, 0x00000001U, 0x00000003U, 0x00000007U, 0x0000000fU,
592 0x0000001fU, 0x0000003fU, 0x0000007fU, 0x000000ffU, 0x000001ffU,
593 0x000003ffU, 0x000007ffU, 0x00000fffU, 0x00001fffU, 0x00003fffU,
594 0x00007fffU, 0x0000ffffU, 0x0001ffffU, 0x0003ffffU, 0x0007ffffU,
595 0x000fffffU, 0x001fffffU, 0x003fffffU, 0x007fffffU, 0x00ffffffU,
596 0x01ffffffU, 0x03ffffffU, 0x07ffffffU, 0x0fffffffU, 0x1fffffffU,
597 0x3fffffffU, 0x7fffffffU
600 assert(quantum_info != (QuantumInfo *) NULL);
601 assert(quantum_info->signature == MagickCoreSignature);
602 quantum_info->state.inverse_scale=1.0;
603 if (fabs(quantum_info->scale) >= MagickEpsilon)
604 quantum_info->state.inverse_scale/=quantum_info->scale;
605 quantum_info->state.pixel=0U;
606 quantum_info->state.bits=0U;
607 quantum_info->state.mask=mask;
635MagickExport
void SetQuantumAlphaType(QuantumInfo *quantum_info,
636 const QuantumAlphaType type)
638 assert(quantum_info != (QuantumInfo *) NULL);
639 assert(quantum_info->signature == MagickCoreSignature);
640 quantum_info->alpha_type=type;
670MagickExport MagickBooleanType SetQuantumDepth(
const Image *image,
671 QuantumInfo *quantum_info,
const size_t depth)
676 assert(image != (Image *) NULL);
677 assert(image->signature == MagickCoreSignature);
678 assert(quantum_info != (QuantumInfo *) NULL);
679 assert(quantum_info->signature == MagickCoreSignature);
680 if (IsEventLogging() != MagickFalse)
681 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
682 quantum_info->depth=MagickMin(depth,64);
683 if (quantum_info->format == FloatingPointQuantumFormat)
685 if (quantum_info->depth > 32)
686 quantum_info->depth=64;
688 if (quantum_info->depth > 24)
689 quantum_info->depth=32;
691 if (quantum_info->depth > 16)
692 quantum_info->depth=24;
694 quantum_info->depth=16;
696 return(SetQuantumExtent(image,quantum_info));
726MagickExport MagickBooleanType SetQuantumEndian(
const Image *image,
727 QuantumInfo *quantum_info,
const EndianType endian)
729 assert(image != (Image *) NULL);
730 assert(image->signature == MagickCoreSignature);
731 assert(quantum_info != (QuantumInfo *) NULL);
732 assert(quantum_info->signature == MagickCoreSignature);
733 if (IsEventLogging() != MagickFalse)
734 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
735 quantum_info->endian=endian;
736 return(SetQuantumExtent(image,quantum_info));
764MagickExport MagickBooleanType SetQuantumExtent(
const Image *image,
765 QuantumInfo *quantum_info)
774 assert(image != (Image *) NULL);
775 assert(image->signature == MagickCoreSignature);
776 assert(quantum_info != (QuantumInfo *) NULL);
777 assert(quantum_info->signature == MagickCoreSignature);
778 quantum=(GetPixelChannels(image)+quantum_info->pad+3)*
779 ((quantum_info->depth+7)/8)*
sizeof(double);
780 extent=MagickMax(image->columns,image->rows)*quantum;
781 if ((MagickMax(image->columns,image->rows) != 0) &&
782 (quantum != (extent/MagickMax(image->columns,image->rows))))
784 if (quantum_info->pixels != (MemoryInfo **) NULL)
786 if (extent <= quantum_info->extent)
788 DestroyQuantumPixels(quantum_info);
790 return(AcquireQuantumPixels(quantum_info,extent));
820MagickExport MagickBooleanType SetQuantumFormat(
const Image *image,
821 QuantumInfo *quantum_info,
const QuantumFormatType format)
823 assert(image != (Image *) NULL);
824 assert(image->signature == MagickCoreSignature);
825 assert(quantum_info != (QuantumInfo *) NULL);
826 assert(quantum_info->signature == MagickCoreSignature);
827 if (IsEventLogging() != MagickFalse)
828 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
829 quantum_info->format=format;
830 return(SetQuantumExtent(image,quantum_info));
859MagickExport
void SetQuantumImageType(Image *image,
860 const QuantumType quantum_type)
862 assert(image != (Image *) NULL);
863 assert(image->signature == MagickCoreSignature);
864 if (IsEventLogging() != MagickFalse)
865 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
866 switch (quantum_type)
869 case IndexAlphaQuantum:
871 image->type=PaletteType;
875 case GrayAlphaQuantum:
877 image->type=GrayscaleType;
878 if (image->depth == 1)
879 image->type=BilevelType;
888 case MultispectralQuantum:
890 image->type=ColorSeparationType;
895 image->type=TrueColorType;
930MagickExport MagickBooleanType SetQuantumMetaChannel(
const Image *image,
931 QuantumInfo *quantum_info,
const ssize_t meta_channel)
933 assert(quantum_info != (QuantumInfo *) NULL);
934 assert(quantum_info->signature == MagickCoreSignature);
935 if ((meta_channel < -1) ||
936 (meta_channel >= (ssize_t) image->number_meta_channels))
938 quantum_info->meta_channel=meta_channel+1;
967MagickExport
void SetQuantumPack(QuantumInfo *quantum_info,
968 const MagickBooleanType pack)
970 assert(quantum_info != (QuantumInfo *) NULL);
971 assert(quantum_info->signature == MagickCoreSignature);
972 quantum_info->pack=pack;
1002MagickExport MagickBooleanType SetQuantumPad(
const Image *image,
1003 QuantumInfo *quantum_info,
const size_t pad)
1005 assert(image != (Image *) NULL);
1006 assert(image->signature == MagickCoreSignature);
1007 assert(quantum_info != (QuantumInfo *) NULL);
1008 assert(quantum_info->signature == MagickCoreSignature);
1009 if (IsEventLogging() != MagickFalse)
1010 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1011 if (pad >= (MAGICK_SSIZE_MAX/GetImageChannels(image)))
1012 return(MagickFalse);
1013 quantum_info->pad=pad;
1014 return(SetQuantumExtent(image,quantum_info));
1042MagickExport
void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
1043 const MagickBooleanType min_is_white)
1045 assert(quantum_info != (QuantumInfo *) NULL);
1046 assert(quantum_info->signature == MagickCoreSignature);
1047 quantum_info->min_is_white=min_is_white;
1074MagickExport
void SetQuantumQuantum(QuantumInfo *quantum_info,
1075 const size_t quantum)
1077 assert(quantum_info != (QuantumInfo *) NULL);
1078 assert(quantum_info->signature == MagickCoreSignature);
1079 quantum_info->quantum=quantum;
1106MagickExport
void SetQuantumScale(QuantumInfo *quantum_info,
const double scale)
1108 assert(quantum_info != (QuantumInfo *) NULL);
1109 assert(quantum_info->signature == MagickCoreSignature);
1110 quantum_info->scale=scale;