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)
270 pixels=(
unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[i]);
271 assert(pixels[extent] == QuantumSignature);
272 quantum_info->pixels[i]=RelinquishVirtualMemory(
273 quantum_info->pixels[i]);
275 quantum_info->pixels=(
MemoryInfo **) RelinquishMagickMemory(
276 quantum_info->pixels);
307 MagickExport
size_t GetQuantumExtent(
const Image *image,
308 const QuantumInfo *quantum_info,
const QuantumType quantum_type)
314 assert(quantum_info->signature == MagickCoreSignature);
316 switch (quantum_type)
318 case GrayAlphaQuantum: packet_size=2;
break;
319 case IndexAlphaQuantum: packet_size=2;
break;
320 case RGBQuantum: packet_size=3;
break;
321 case BGRQuantum: packet_size=3;
break;
322 case RGBAQuantum: packet_size=4;
break;
323 case RGBOQuantum: packet_size=4;
break;
324 case BGRAQuantum: packet_size=4;
break;
325 case CMYKQuantum: packet_size=4;
break;
326 case CMYKAQuantum: packet_size=5;
break;
327 case CbYCrAQuantum: packet_size=4;
break;
328 case CbYCrQuantum: packet_size=3;
break;
329 case CbYCrYQuantum: packet_size=4;
break;
332 if (quantum_info->pack == MagickFalse)
333 return((
size_t) (packet_size*image->columns*((quantum_info->depth+7)/8)));
334 return((
size_t) ((packet_size*image->columns*quantum_info->depth+7)/8));
359 MagickExport EndianType GetQuantumEndian(
const QuantumInfo *quantum_info)
362 assert(quantum_info->signature == MagickCoreSignature);
363 return(quantum_info->endian);
388 MagickExport QuantumFormatType GetQuantumFormat(
const QuantumInfo *quantum_info)
391 assert(quantum_info->signature == MagickCoreSignature);
392 return(quantum_info->format);
419 MagickExport
void GetQuantumInfo(
const ImageInfo *image_info,
426 (void) memset(quantum_info,0,
sizeof(*quantum_info));
427 quantum_info->quantum=8;
428 quantum_info->maximum=1.0;
429 quantum_info->scale=QuantumRange;
430 quantum_info->pack=MagickTrue;
431 quantum_info->semaphore=AllocateSemaphoreInfo();
432 quantum_info->signature=MagickCoreSignature;
433 if (image_info == (
const ImageInfo *) NULL)
435 option=GetImageOption(image_info,
"quantum:format");
436 if (option != (
char *) NULL)
437 quantum_info->format=(QuantumFormatType) ParseCommandOption(
438 MagickQuantumFormatOptions,MagickFalse,option);
439 option=GetImageOption(image_info,
"quantum:minimum");
440 if (option != (
char *) NULL)
441 quantum_info->minimum=StringToDouble(option,(
char **) NULL);
442 option=GetImageOption(image_info,
"quantum:maximum");
443 if (option != (
char *) NULL)
444 quantum_info->maximum=StringToDouble(option,(
char **) NULL);
445 if ((quantum_info->minimum == 0.0) && (quantum_info->maximum == 0.0))
446 quantum_info->scale=0.0;
448 if (quantum_info->minimum == quantum_info->maximum)
450 quantum_info->scale=(MagickRealType) QuantumRange/quantum_info->minimum;
451 quantum_info->minimum=0.0;
454 quantum_info->scale=(MagickRealType) QuantumRange/(quantum_info->maximum-
455 quantum_info->minimum);
456 option=GetImageOption(image_info,
"quantum:scale");
457 if (option != (
char *) NULL)
458 quantum_info->scale=StringToDouble(option,(
char **) NULL);
459 option=GetImageOption(image_info,
"quantum:polarity");
460 if (option != (
char *) NULL)
461 quantum_info->min_is_white=LocaleCompare(option,
"min-is-white") == 0 ?
462 MagickTrue : MagickFalse;
463 quantum_info->endian=image_info->endian;
464 ResetQuantumState(quantum_info);
490 MagickExport
unsigned char *GetQuantumPixels(
const QuantumInfo *quantum_info)
493 id = GetOpenMPThreadId();
496 assert(quantum_info->signature == MagickCoreSignature);
497 return((
unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[
id]));
527 assert(image != (
Image *) NULL);
528 assert(image->signature == MagickCoreSignature);
529 if (IsEventLogging() != MagickFalse)
530 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
532 quantum_type=RGBQuantum;
533 if (image->matte != MagickFalse)
534 quantum_type=RGBAQuantum;
535 if (image->colorspace == CMYKColorspace)
537 quantum_type=CMYKQuantum;
538 if (image->matte != MagickFalse)
539 quantum_type=CMYKAQuantum;
541 if (IsGrayColorspace(image->colorspace) != MagickFalse)
543 quantum_type=GrayQuantum;
544 if (image->matte != MagickFalse)
545 quantum_type=GrayAlphaQuantum;
547 if (image->storage_class == PseudoClass)
549 quantum_type=IndexQuantum;
550 if (image->matte != MagickFalse)
551 quantum_type=IndexAlphaQuantum;
553 return(quantum_type);
578 MagickPrivate
void ResetQuantumState(
QuantumInfo *quantum_info)
580 static const unsigned int mask[32] =
582 0x00000000U, 0x00000001U, 0x00000003U, 0x00000007U, 0x0000000fU,
583 0x0000001fU, 0x0000003fU, 0x0000007fU, 0x000000ffU, 0x000001ffU,
584 0x000003ffU, 0x000007ffU, 0x00000fffU, 0x00001fffU, 0x00003fffU,
585 0x00007fffU, 0x0000ffffU, 0x0001ffffU, 0x0003ffffU, 0x0007ffffU,
586 0x000fffffU, 0x001fffffU, 0x003fffffU, 0x007fffffU, 0x00ffffffU,
587 0x01ffffffU, 0x03ffffffU, 0x07ffffffU, 0x0fffffffU, 0x1fffffffU,
588 0x3fffffffU, 0x7fffffffU
592 assert(quantum_info->signature == MagickCoreSignature);
593 quantum_info->state.inverse_scale=1.0;
594 if (fabs(quantum_info->scale) >= MagickEpsilon)
595 quantum_info->state.inverse_scale/=quantum_info->scale;
596 quantum_info->state.pixel=0U;
597 quantum_info->state.bits=0U;
598 quantum_info->state.mask=mask;
626 MagickExport
void SetQuantumAlphaType(
QuantumInfo *quantum_info,
627 const QuantumAlphaType type)
630 assert(quantum_info->signature == MagickCoreSignature);
631 quantum_info->alpha_type=type;
661 MagickExport MagickBooleanType SetQuantumDepth(
const Image *image,
671 assert(image != (
Image *) NULL);
672 assert(image->signature == MagickCoreSignature);
674 assert(quantum_info->signature == MagickCoreSignature);
675 if (IsEventLogging() != MagickFalse)
676 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
677 quantum_info->depth=MagickMin(depth,64);
678 if (quantum_info->format == FloatingPointQuantumFormat)
680 if (quantum_info->depth > 32)
681 quantum_info->depth=64;
683 if (quantum_info->depth > 24)
684 quantum_info->depth=32;
686 if (quantum_info->depth > 16)
687 quantum_info->depth=24;
689 quantum_info->depth=16;
694 quantum=(quantum_info->pad+6)*((quantum_info->depth+7)/8)*
sizeof(
double);
695 extent=MagickMax(image->columns,image->rows)*quantum;
696 if ((MagickMax(image->columns,image->rows) != 0) &&
697 (quantum != (extent/MagickMax(image->columns,image->rows))))
699 if (quantum_info->pixels != (
MemoryInfo **) NULL)
701 if (extent <= quantum_info->extent)
703 DestroyQuantumPixels(quantum_info);
705 return(AcquireQuantumPixels(quantum_info,extent));
735 MagickExport MagickBooleanType SetQuantumEndian(
const Image *image,
738 assert(image != (
Image *) NULL);
739 assert(image->signature == MagickCoreSignature);
741 assert(quantum_info->signature == MagickCoreSignature);
742 if (IsEventLogging() != MagickFalse)
743 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
744 quantum_info->endian=endian;
745 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
775 MagickExport MagickBooleanType SetQuantumFormat(
const Image *image,
776 QuantumInfo *quantum_info,
const QuantumFormatType format)
778 assert(image != (
Image *) NULL);
779 assert(image->signature == MagickCoreSignature);
781 assert(quantum_info->signature == MagickCoreSignature);
782 if (IsEventLogging() != MagickFalse)
783 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
784 quantum_info->format=format;
785 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
814 MagickExport
void SetQuantumImageType(
Image *image,
815 const QuantumType quantum_type)
817 assert(image != (
Image *) NULL);
818 assert(image->signature == MagickCoreSignature);
819 if (IsEventLogging() != MagickFalse)
820 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
821 switch (quantum_type)
824 case IndexAlphaQuantum:
826 image->type=PaletteType;
830 case GrayAlphaQuantum:
832 image->type=GrayscaleType;
833 if (image->depth == 1)
834 image->type=BilevelType;
844 image->type=ColorSeparationType;
849 image->type=TrueColorType;
880 MagickExport
void SetQuantumPack(
QuantumInfo *quantum_info,
881 const MagickBooleanType pack)
884 assert(quantum_info->signature == MagickCoreSignature);
885 quantum_info->pack=pack;
915 MagickExport MagickBooleanType SetQuantumPad(
const Image *image,
918 assert(image != (
Image *) NULL);
919 assert(image->signature == MagickCoreSignature);
921 assert(quantum_info->signature == MagickCoreSignature);
922 if (IsEventLogging() != MagickFalse)
923 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
924 quantum_info->pad=pad;
925 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
953 MagickExport
void SetQuantumMinIsWhite(
QuantumInfo *quantum_info,
954 const MagickBooleanType min_is_white)
957 assert(quantum_info->signature == MagickCoreSignature);
958 quantum_info->min_is_white=min_is_white;
985 MagickExport
void SetQuantumQuantum(
QuantumInfo *quantum_info,
986 const size_t quantum)
989 assert(quantum_info->signature == MagickCoreSignature);
990 quantum_info->quantum=quantum;
1017 MagickExport
void SetQuantumScale(
QuantumInfo *quantum_info,
const double scale)
1020 assert(quantum_info->signature == MagickCoreSignature);
1021 quantum_info->scale=scale;