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 CMYKOQuantum: channels=5;
break;
330 case MultispectralQuantum: channels=GetImageChannels(image);
break;
331 case CbYCrAQuantum: channels=4;
break;
332 case CbYCrQuantum: channels=3;
break;
333 case CbYCrYQuantum: channels=4;
break;
336 if (quantum_info->pack == MagickFalse)
337 return((
size_t) (channels*image->columns*((quantum_info->depth+7)/8))+
338 (quantum_info->pad*image->columns));
339 return((
size_t) ((channels*image->columns*quantum_info->depth+7)/8)+
340 (quantum_info->pad*image->columns));
365MagickExport EndianType GetQuantumEndian(
const QuantumInfo *quantum_info)
367 assert(quantum_info != (QuantumInfo *) NULL);
368 assert(quantum_info->signature == MagickCoreSignature);
369 return(quantum_info->endian);
394MagickExport QuantumFormatType GetQuantumFormat(
const QuantumInfo *quantum_info)
396 assert(quantum_info != (QuantumInfo *) NULL);
397 assert(quantum_info->signature == MagickCoreSignature);
398 return(quantum_info->format);
425MagickExport
void GetQuantumInfo(
const ImageInfo *image_info,
426 QuantumInfo *quantum_info)
431 assert(quantum_info != (QuantumInfo *) NULL);
432 (void) memset(quantum_info,0,
sizeof(*quantum_info));
433 quantum_info->quantum=8;
434 quantum_info->maximum=1.0;
435 quantum_info->scale=QuantumRange;
436 quantum_info->pack=MagickTrue;
437 quantum_info->semaphore=AcquireSemaphoreInfo();
438 quantum_info->signature=MagickCoreSignature;
439 if (image_info == (
const ImageInfo *) NULL)
441 option=GetImageOption(image_info,
"quantum:format");
442 if (option != (
char *) NULL)
443 quantum_info->format=(QuantumFormatType) ParseCommandOption(
444 MagickQuantumFormatOptions,MagickFalse,option);
445 option=GetImageOption(image_info,
"quantum:minimum");
446 if (option != (
char *) NULL)
447 quantum_info->minimum=StringToDouble(option,(
char **) NULL);
448 option=GetImageOption(image_info,
"quantum:maximum");
449 if (option != (
char *) NULL)
450 quantum_info->maximum=StringToDouble(option,(
char **) NULL);
451 if ((quantum_info->minimum == 0.0) && (quantum_info->maximum == 0.0))
452 quantum_info->scale=0.0;
454 if (quantum_info->minimum == quantum_info->maximum)
456 quantum_info->scale=(double) QuantumRange/quantum_info->minimum;
457 quantum_info->minimum=0.0;
460 quantum_info->scale=(double) QuantumRange/(quantum_info->maximum-
461 quantum_info->minimum);
462 option=GetImageOption(image_info,
"quantum:scale");
463 if (option != (
char *) NULL)
464 quantum_info->scale=StringToDouble(option,(
char **) NULL);
465 option=GetImageOption(image_info,
"quantum:polarity");
466 if (option != (
char *) NULL)
467 quantum_info->min_is_white=LocaleCompare(option,
"min-is-white") == 0 ?
468 MagickTrue : MagickFalse;
469 quantum_info->endian=image_info->endian;
470 ResetQuantumState(quantum_info);
496MagickExport
unsigned char *GetQuantumPixels(
const QuantumInfo *quantum_info)
499 id = GetOpenMPThreadId();
501 assert(quantum_info != (QuantumInfo *) NULL);
502 assert(quantum_info->signature == MagickCoreSignature);
503 return((
unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[
id]));
530MagickExport QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
535 assert(image != (Image *) NULL);
536 assert(image->signature == MagickCoreSignature);
537 if (IsEventLogging() != MagickFalse)
538 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
540 quantum_type=RGBQuantum;
541 if (image->alpha_trait != UndefinedPixelTrait)
542 quantum_type=RGBAQuantum;
543 if (image->colorspace == CMYKColorspace)
545 quantum_type=CMYKQuantum;
546 if (image->alpha_trait != UndefinedPixelTrait)
547 quantum_type=CMYKAQuantum;
549 if (IsGrayColorspace(image->colorspace) != MagickFalse)
551 quantum_type=GrayQuantum;
552 if (image->alpha_trait != UndefinedPixelTrait)
553 quantum_type=GrayAlphaQuantum;
555 if (image->storage_class == PseudoClass)
557 quantum_type=IndexQuantum;
558 if (image->alpha_trait != UndefinedPixelTrait)
559 quantum_type=IndexAlphaQuantum;
561 if (image->number_meta_channels != 0)
562 quantum_type=MultispectralQuantum;
563 return(quantum_type);
588MagickPrivate
void ResetQuantumState(QuantumInfo *quantum_info)
590 static const unsigned int mask[32] =
592 0x00000000U, 0x00000001U, 0x00000003U, 0x00000007U, 0x0000000fU,
593 0x0000001fU, 0x0000003fU, 0x0000007fU, 0x000000ffU, 0x000001ffU,
594 0x000003ffU, 0x000007ffU, 0x00000fffU, 0x00001fffU, 0x00003fffU,
595 0x00007fffU, 0x0000ffffU, 0x0001ffffU, 0x0003ffffU, 0x0007ffffU,
596 0x000fffffU, 0x001fffffU, 0x003fffffU, 0x007fffffU, 0x00ffffffU,
597 0x01ffffffU, 0x03ffffffU, 0x07ffffffU, 0x0fffffffU, 0x1fffffffU,
598 0x3fffffffU, 0x7fffffffU
601 assert(quantum_info != (QuantumInfo *) NULL);
602 assert(quantum_info->signature == MagickCoreSignature);
603 quantum_info->state.inverse_scale=1.0;
604 if (fabs(quantum_info->scale) >= MagickEpsilon)
605 quantum_info->state.inverse_scale/=quantum_info->scale;
606 quantum_info->state.pixel=0U;
607 quantum_info->state.bits=0U;
608 quantum_info->state.mask=mask;
636MagickExport
void SetQuantumAlphaType(QuantumInfo *quantum_info,
637 const QuantumAlphaType type)
639 assert(quantum_info != (QuantumInfo *) NULL);
640 assert(quantum_info->signature == MagickCoreSignature);
641 quantum_info->alpha_type=type;
671MagickExport MagickBooleanType SetQuantumDepth(
const Image *image,
672 QuantumInfo *quantum_info,
const size_t depth)
677 assert(image != (Image *) NULL);
678 assert(image->signature == MagickCoreSignature);
679 assert(quantum_info != (QuantumInfo *) NULL);
680 assert(quantum_info->signature == MagickCoreSignature);
681 if (IsEventLogging() != MagickFalse)
682 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
683 quantum_info->depth=MagickMin(depth,64);
684 if (quantum_info->format == FloatingPointQuantumFormat)
686 if (quantum_info->depth > 32)
687 quantum_info->depth=64;
689 if (quantum_info->depth > 24)
690 quantum_info->depth=32;
692 if (quantum_info->depth > 16)
693 quantum_info->depth=24;
695 quantum_info->depth=16;
697 return(SetQuantumExtent(image,quantum_info));
727MagickExport MagickBooleanType SetQuantumEndian(
const Image *image,
728 QuantumInfo *quantum_info,
const EndianType endian)
730 assert(image != (Image *) NULL);
731 assert(image->signature == MagickCoreSignature);
732 assert(quantum_info != (QuantumInfo *) NULL);
733 assert(quantum_info->signature == MagickCoreSignature);
734 if (IsEventLogging() != MagickFalse)
735 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
736 quantum_info->endian=endian;
737 return(SetQuantumExtent(image,quantum_info));
765MagickExport MagickBooleanType SetQuantumExtent(
const Image *image,
766 QuantumInfo *quantum_info)
775 assert(image != (Image *) NULL);
776 assert(image->signature == MagickCoreSignature);
777 assert(quantum_info != (QuantumInfo *) NULL);
778 assert(quantum_info->signature == MagickCoreSignature);
779 quantum=(GetPixelChannels(image)+quantum_info->pad+3)*
780 ((quantum_info->depth+7)/8)*
sizeof(double);
781 extent=MagickMax(image->columns,image->rows)*quantum;
782 if ((MagickMax(image->columns,image->rows) != 0) &&
783 (quantum != (extent/MagickMax(image->columns,image->rows))))
785 if (quantum_info->pixels != (MemoryInfo **) NULL)
787 if (extent <= quantum_info->extent)
789 DestroyQuantumPixels(quantum_info);
791 return(AcquireQuantumPixels(quantum_info,extent));
821MagickExport MagickBooleanType SetQuantumFormat(
const Image *image,
822 QuantumInfo *quantum_info,
const QuantumFormatType format)
824 assert(image != (Image *) NULL);
825 assert(image->signature == MagickCoreSignature);
826 assert(quantum_info != (QuantumInfo *) NULL);
827 assert(quantum_info->signature == MagickCoreSignature);
828 if (IsEventLogging() != MagickFalse)
829 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
830 quantum_info->format=format;
831 return(SetQuantumExtent(image,quantum_info));
860MagickExport
void SetQuantumImageType(Image *image,
861 const QuantumType quantum_type)
863 assert(image != (Image *) NULL);
864 assert(image->signature == MagickCoreSignature);
865 if (IsEventLogging() != MagickFalse)
866 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
867 switch (quantum_type)
870 case IndexAlphaQuantum:
872 image->type=PaletteType;
876 case GrayAlphaQuantum:
878 image->type=GrayscaleType;
879 if (image->depth == 1)
880 image->type=BilevelType;
889 case MultispectralQuantum:
891 image->type=ColorSeparationType;
896 image->type=TrueColorType;
931MagickExport MagickBooleanType SetQuantumMetaChannel(
const Image *image,
932 QuantumInfo *quantum_info,
const ssize_t meta_channel)
934 assert(quantum_info != (QuantumInfo *) NULL);
935 assert(quantum_info->signature == MagickCoreSignature);
936 if ((meta_channel < -1) ||
937 (meta_channel >= (ssize_t) image->number_meta_channels))
939 quantum_info->meta_channel=meta_channel+1;
968MagickExport
void SetQuantumPack(QuantumInfo *quantum_info,
969 const MagickBooleanType pack)
971 assert(quantum_info != (QuantumInfo *) NULL);
972 assert(quantum_info->signature == MagickCoreSignature);
973 quantum_info->pack=pack;
1003MagickExport MagickBooleanType SetQuantumPad(
const Image *image,
1004 QuantumInfo *quantum_info,
const size_t pad)
1006 assert(image != (Image *) NULL);
1007 assert(image->signature == MagickCoreSignature);
1008 assert(quantum_info != (QuantumInfo *) NULL);
1009 assert(quantum_info->signature == MagickCoreSignature);
1010 if (IsEventLogging() != MagickFalse)
1011 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1012 if (pad >= (MAGICK_SSIZE_MAX/GetImageChannels(image)))
1013 return(MagickFalse);
1014 quantum_info->pad=pad;
1015 return(SetQuantumExtent(image,quantum_info));
1043MagickExport
void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
1044 const MagickBooleanType min_is_white)
1046 assert(quantum_info != (QuantumInfo *) NULL);
1047 assert(quantum_info->signature == MagickCoreSignature);
1048 quantum_info->min_is_white=min_is_white;
1075MagickExport
void SetQuantumQuantum(QuantumInfo *quantum_info,
1076 const size_t quantum)
1078 assert(quantum_info != (QuantumInfo *) NULL);
1079 assert(quantum_info->signature == MagickCoreSignature);
1080 quantum_info->quantum=quantum;
1107MagickExport
void SetQuantumScale(QuantumInfo *quantum_info,
const double scale)
1109 assert(quantum_info != (QuantumInfo *) NULL);
1110 assert(quantum_info->signature == MagickCoreSignature);
1111 quantum_info->scale=scale;