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"
77 #define QuantumSignature 0xab
118 quantum_info=(
QuantumInfo *) AcquireMagickMemory(
sizeof(*quantum_info));
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);
157 static MagickBooleanType AcquireQuantumPixels(
QuantumInfo *quantum_info,
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)
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++)
178 quantum_info->pixels[i]=AcquireVirtualMemory(extent+1,
sizeof(*pixels));
179 if (quantum_info->pixels[i] == (
MemoryInfo *) NULL)
181 DestroyQuantumPixels(quantum_info);
184 pixels=(
unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[i]);
185 (void) memset(pixels,0,(extent+1)*
sizeof(*pixels));
186 pixels[extent]=QuantumSignature;
217 assert(quantum_info->signature == MagickCoreSignature);
218 if (quantum_info->pixels != (
MemoryInfo **) NULL)
219 DestroyQuantumPixels(quantum_info);
221 DestroySemaphoreInfo(&quantum_info->semaphore);
222 quantum_info->signature=(~MagickCoreSignature);
223 quantum_info=(
QuantumInfo *) RelinquishMagickMemory(quantum_info);
224 return(quantum_info);
249 static void DestroyQuantumPixels(
QuantumInfo *quantum_info)
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)
271 pixels=(
unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[i]);
272 assert(pixels[extent] == QuantumSignature);
274 quantum_info->pixels[i]=RelinquishVirtualMemory(
275 quantum_info->pixels[i]);
277 quantum_info->pixels=(
MemoryInfo **) RelinquishMagickMemory(
278 quantum_info->pixels);
309 MagickExport
size_t GetQuantumExtent(
const Image *image,
310 const QuantumInfo *quantum_info,
const QuantumType quantum_type)
316 assert(quantum_info->signature == MagickCoreSignature);
318 switch (quantum_type)
320 case GrayAlphaQuantum: packet_size=2;
break;
321 case IndexAlphaQuantum: packet_size=2;
break;
322 case RGBQuantum: packet_size=3;
break;
323 case BGRQuantum: packet_size=3;
break;
324 case RGBAQuantum: packet_size=4;
break;
325 case RGBOQuantum: packet_size=4;
break;
326 case BGRAQuantum: packet_size=4;
break;
327 case CMYKQuantum: packet_size=4;
break;
328 case CMYKAQuantum: packet_size=5;
break;
329 case CbYCrAQuantum: packet_size=4;
break;
330 case CbYCrQuantum: packet_size=3;
break;
331 case CbYCrYQuantum: packet_size=4;
break;
334 if (quantum_info->pack == MagickFalse)
335 return((
size_t) (packet_size*image->columns*((quantum_info->depth+7)/8)));
336 return((
size_t) ((packet_size*image->columns*quantum_info->depth+7)/8));
361 MagickExport EndianType GetQuantumEndian(
const QuantumInfo *quantum_info)
364 assert(quantum_info->signature == MagickCoreSignature);
365 return(quantum_info->endian);
390 MagickExport QuantumFormatType GetQuantumFormat(
const QuantumInfo *quantum_info)
393 assert(quantum_info->signature == MagickCoreSignature);
394 return(quantum_info->format);
421 MagickExport
void GetQuantumInfo(
const ImageInfo *image_info,
428 (void) memset(quantum_info,0,
sizeof(*quantum_info));
429 quantum_info->quantum=8;
430 quantum_info->maximum=1.0;
431 quantum_info->scale=QuantumRange;
432 quantum_info->pack=MagickTrue;
433 quantum_info->semaphore=AllocateSemaphoreInfo();
434 quantum_info->signature=MagickCoreSignature;
435 if (image_info == (
const ImageInfo *) NULL)
437 option=GetImageOption(image_info,
"quantum:format");
438 if (option != (
char *) NULL)
439 quantum_info->format=(QuantumFormatType) ParseCommandOption(
440 MagickQuantumFormatOptions,MagickFalse,option);
441 option=GetImageOption(image_info,
"quantum:minimum");
442 if (option != (
char *) NULL)
443 quantum_info->minimum=StringToDouble(option,(
char **) NULL);
444 option=GetImageOption(image_info,
"quantum:maximum");
445 if (option != (
char *) NULL)
446 quantum_info->maximum=StringToDouble(option,(
char **) NULL);
447 if ((quantum_info->minimum == 0.0) && (quantum_info->maximum == 0.0))
448 quantum_info->scale=0.0;
450 if (quantum_info->minimum == quantum_info->maximum)
452 quantum_info->scale=(MagickRealType) QuantumRange/quantum_info->minimum;
453 quantum_info->minimum=0.0;
456 quantum_info->scale=(MagickRealType) QuantumRange/(quantum_info->maximum-
457 quantum_info->minimum);
458 option=GetImageOption(image_info,
"quantum:scale");
459 if (option != (
char *) NULL)
460 quantum_info->scale=StringToDouble(option,(
char **) NULL);
461 option=GetImageOption(image_info,
"quantum:polarity");
462 if (option != (
char *) NULL)
463 quantum_info->min_is_white=LocaleCompare(option,
"min-is-white") == 0 ?
464 MagickTrue : MagickFalse;
465 quantum_info->endian=image_info->endian;
466 ResetQuantumState(quantum_info);
492 MagickExport
unsigned char *GetQuantumPixels(
const QuantumInfo *quantum_info)
495 id = GetOpenMPThreadId();
498 assert(quantum_info->signature == MagickCoreSignature);
499 return((
unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[
id]));
529 assert(image != (
Image *) NULL);
530 assert(image->signature == MagickCoreSignature);
531 if (IsEventLogging() != MagickFalse)
532 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
534 quantum_type=RGBQuantum;
535 if (image->matte != MagickFalse)
536 quantum_type=RGBAQuantum;
537 if (image->colorspace == CMYKColorspace)
539 quantum_type=CMYKQuantum;
540 if (image->matte != MagickFalse)
541 quantum_type=CMYKAQuantum;
543 if (IsGrayColorspace(image->colorspace) != MagickFalse)
545 quantum_type=GrayQuantum;
546 if (image->matte != MagickFalse)
547 quantum_type=GrayAlphaQuantum;
549 if (image->storage_class == PseudoClass)
551 quantum_type=IndexQuantum;
552 if (image->matte != MagickFalse)
553 quantum_type=IndexAlphaQuantum;
555 return(quantum_type);
580 MagickPrivate
void ResetQuantumState(
QuantumInfo *quantum_info)
582 static const unsigned int mask[32] =
584 0x00000000U, 0x00000001U, 0x00000003U, 0x00000007U, 0x0000000fU,
585 0x0000001fU, 0x0000003fU, 0x0000007fU, 0x000000ffU, 0x000001ffU,
586 0x000003ffU, 0x000007ffU, 0x00000fffU, 0x00001fffU, 0x00003fffU,
587 0x00007fffU, 0x0000ffffU, 0x0001ffffU, 0x0003ffffU, 0x0007ffffU,
588 0x000fffffU, 0x001fffffU, 0x003fffffU, 0x007fffffU, 0x00ffffffU,
589 0x01ffffffU, 0x03ffffffU, 0x07ffffffU, 0x0fffffffU, 0x1fffffffU,
590 0x3fffffffU, 0x7fffffffU
594 assert(quantum_info->signature == MagickCoreSignature);
595 quantum_info->state.inverse_scale=1.0;
596 if (fabs(quantum_info->scale) >= MagickEpsilon)
597 quantum_info->state.inverse_scale/=quantum_info->scale;
598 quantum_info->state.pixel=0U;
599 quantum_info->state.bits=0U;
600 quantum_info->state.mask=mask;
628 MagickExport
void SetQuantumAlphaType(
QuantumInfo *quantum_info,
629 const QuantumAlphaType type)
632 assert(quantum_info->signature == MagickCoreSignature);
633 quantum_info->alpha_type=type;
663 MagickExport MagickBooleanType SetQuantumDepth(
const Image *image,
673 assert(image != (
Image *) NULL);
674 assert(image->signature == MagickCoreSignature);
676 assert(quantum_info->signature == MagickCoreSignature);
677 if (IsEventLogging() != MagickFalse)
678 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
679 quantum_info->depth=MagickMin(depth,64);
680 if (quantum_info->format == FloatingPointQuantumFormat)
682 if (quantum_info->depth > 32)
683 quantum_info->depth=64;
685 if (quantum_info->depth > 24)
686 quantum_info->depth=32;
688 if (quantum_info->depth > 16)
689 quantum_info->depth=24;
691 quantum_info->depth=16;
696 quantum=(quantum_info->pad+6)*((quantum_info->depth+7)/8)*
sizeof(
double);
697 extent=MagickMax(image->columns,image->rows)*quantum;
698 if ((MagickMax(image->columns,image->rows) != 0) &&
699 (quantum != (extent/MagickMax(image->columns,image->rows))))
701 if (quantum_info->pixels != (
MemoryInfo **) NULL)
703 if (extent <= quantum_info->extent)
705 DestroyQuantumPixels(quantum_info);
707 return(AcquireQuantumPixels(quantum_info,extent));
737 MagickExport MagickBooleanType SetQuantumEndian(
const Image *image,
740 assert(image != (
Image *) NULL);
741 assert(image->signature == MagickCoreSignature);
743 assert(quantum_info->signature == MagickCoreSignature);
744 if (IsEventLogging() != MagickFalse)
745 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
746 quantum_info->endian=endian;
747 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
777 MagickExport MagickBooleanType SetQuantumFormat(
const Image *image,
778 QuantumInfo *quantum_info,
const QuantumFormatType format)
780 assert(image != (
Image *) NULL);
781 assert(image->signature == MagickCoreSignature);
783 assert(quantum_info->signature == MagickCoreSignature);
784 if (IsEventLogging() != MagickFalse)
785 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
786 quantum_info->format=format;
787 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
816 MagickExport
void SetQuantumImageType(
Image *image,
817 const QuantumType quantum_type)
819 assert(image != (
Image *) NULL);
820 assert(image->signature == MagickCoreSignature);
821 if (IsEventLogging() != MagickFalse)
822 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
823 switch (quantum_type)
826 case IndexAlphaQuantum:
828 image->type=PaletteType;
832 case GrayAlphaQuantum:
834 image->type=GrayscaleType;
835 if (image->depth == 1)
836 image->type=BilevelType;
846 image->type=ColorSeparationType;
851 image->type=TrueColorType;
882 MagickExport
void SetQuantumPack(
QuantumInfo *quantum_info,
883 const MagickBooleanType pack)
886 assert(quantum_info->signature == MagickCoreSignature);
887 quantum_info->pack=pack;
917 MagickExport MagickBooleanType SetQuantumPad(
const Image *image,
920 assert(image != (
Image *) NULL);
921 assert(image->signature == MagickCoreSignature);
923 assert(quantum_info->signature == MagickCoreSignature);
924 if (IsEventLogging() != MagickFalse)
925 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
926 if (pad >= (MAGICK_SSIZE_MAX/5))
928 quantum_info->pad=pad;
929 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
957 MagickExport
void SetQuantumMinIsWhite(
QuantumInfo *quantum_info,
958 const MagickBooleanType min_is_white)
961 assert(quantum_info->signature == MagickCoreSignature);
962 quantum_info->min_is_white=min_is_white;
989 MagickExport
void SetQuantumQuantum(
QuantumInfo *quantum_info,
990 const size_t quantum)
993 assert(quantum_info->signature == MagickCoreSignature);
994 quantum_info->quantum=quantum;
1021 MagickExport
void SetQuantumScale(
QuantumInfo *quantum_info,
const double scale)
1024 assert(quantum_info->signature == MagickCoreSignature);
1025 quantum_info->scale=scale;