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 CMYKQuantum: channels=4;
break;
327 case CMYKAQuantum: channels=5;
break;
328 case MultispectralQuantum: channels=GetImageChannels(image);
break;
329 case CbYCrAQuantum: channels=4;
break;
330 case CbYCrQuantum: channels=3;
break;
331 case CbYCrYQuantum: channels=4;
break;
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));
363MagickExport EndianType GetQuantumEndian(
const QuantumInfo *quantum_info)
365 assert(quantum_info != (QuantumInfo *) NULL);
366 assert(quantum_info->signature == MagickCoreSignature);
367 return(quantum_info->endian);
392MagickExport QuantumFormatType GetQuantumFormat(
const QuantumInfo *quantum_info)
394 assert(quantum_info != (QuantumInfo *) NULL);
395 assert(quantum_info->signature == MagickCoreSignature);
396 return(quantum_info->format);
423MagickExport
void GetQuantumInfo(
const ImageInfo *image_info,
424 QuantumInfo *quantum_info)
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=AcquireSemaphoreInfo();
436 quantum_info->signature=MagickCoreSignature;
437 if (image_info == (
const ImageInfo *) NULL)
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;
452 if (quantum_info->minimum == quantum_info->maximum)
454 quantum_info->scale=(double) QuantumRange/quantum_info->minimum;
455 quantum_info->minimum=0.0;
458 quantum_info->scale=(double) 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);
494MagickExport
unsigned char *GetQuantumPixels(
const QuantumInfo *quantum_info)
497 id = GetOpenMPThreadId();
499 assert(quantum_info != (QuantumInfo *) NULL);
500 assert(quantum_info->signature == MagickCoreSignature);
501 return((
unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[
id]));
528MagickExport QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
533 assert(image != (Image *) NULL);
534 assert(image->signature == MagickCoreSignature);
535 if (IsEventLogging() != MagickFalse)
536 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
538 quantum_type=RGBQuantum;
539 if (image->alpha_trait != UndefinedPixelTrait)
540 quantum_type=RGBAQuantum;
541 if (image->colorspace == CMYKColorspace)
543 quantum_type=CMYKQuantum;
544 if (image->alpha_trait != UndefinedPixelTrait)
545 quantum_type=CMYKAQuantum;
547 if (IsGrayColorspace(image->colorspace) != MagickFalse)
549 quantum_type=GrayQuantum;
550 if (image->alpha_trait != UndefinedPixelTrait)
551 quantum_type=GrayAlphaQuantum;
553 if (image->storage_class == PseudoClass)
555 quantum_type=IndexQuantum;
556 if (image->alpha_trait != UndefinedPixelTrait)
557 quantum_type=IndexAlphaQuantum;
559 if (image->number_meta_channels != 0)
560 quantum_type=MultispectralQuantum;
561 return(quantum_type);
586MagickPrivate
void ResetQuantumState(QuantumInfo *quantum_info)
588 static const unsigned int mask[32] =
590 0x00000000U, 0x00000001U, 0x00000003U, 0x00000007U, 0x0000000fU,
591 0x0000001fU, 0x0000003fU, 0x0000007fU, 0x000000ffU, 0x000001ffU,
592 0x000003ffU, 0x000007ffU, 0x00000fffU, 0x00001fffU, 0x00003fffU,
593 0x00007fffU, 0x0000ffffU, 0x0001ffffU, 0x0003ffffU, 0x0007ffffU,
594 0x000fffffU, 0x001fffffU, 0x003fffffU, 0x007fffffU, 0x00ffffffU,
595 0x01ffffffU, 0x03ffffffU, 0x07ffffffU, 0x0fffffffU, 0x1fffffffU,
596 0x3fffffffU, 0x7fffffffU
599 assert(quantum_info != (QuantumInfo *) NULL);
600 assert(quantum_info->signature == MagickCoreSignature);
601 quantum_info->state.inverse_scale=1.0;
602 if (fabs(quantum_info->scale) >= MagickEpsilon)
603 quantum_info->state.inverse_scale/=quantum_info->scale;
604 quantum_info->state.pixel=0U;
605 quantum_info->state.bits=0U;
606 quantum_info->state.mask=mask;
634MagickExport
void SetQuantumAlphaType(QuantumInfo *quantum_info,
635 const QuantumAlphaType type)
637 assert(quantum_info != (QuantumInfo *) NULL);
638 assert(quantum_info->signature == MagickCoreSignature);
639 quantum_info->alpha_type=type;
669MagickExport MagickBooleanType SetQuantumDepth(
const Image *image,
670 QuantumInfo *quantum_info,
const size_t depth)
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)
684 if (quantum_info->depth > 32)
685 quantum_info->depth=64;
687 if (quantum_info->depth > 24)
688 quantum_info->depth=32;
690 if (quantum_info->depth > 16)
691 quantum_info->depth=24;
693 quantum_info->depth=16;
695 return(SetQuantumExtent(image,quantum_info));
725MagickExport MagickBooleanType SetQuantumEndian(
const Image *image,
726 QuantumInfo *quantum_info,
const EndianType endian)
728 assert(image != (Image *) NULL);
729 assert(image->signature == MagickCoreSignature);
730 assert(quantum_info != (QuantumInfo *) NULL);
731 assert(quantum_info->signature == MagickCoreSignature);
732 if (IsEventLogging() != MagickFalse)
733 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
734 quantum_info->endian=endian;
735 return(SetQuantumExtent(image,quantum_info));
763MagickExport MagickBooleanType SetQuantumExtent(
const Image *image,
764 QuantumInfo *quantum_info)
773 assert(image != (Image *) NULL);
774 assert(image->signature == MagickCoreSignature);
775 assert(quantum_info != (QuantumInfo *) NULL);
776 assert(quantum_info->signature == MagickCoreSignature);
777 quantum=(GetPixelChannels(image)+quantum_info->pad+3)*
778 ((quantum_info->depth+7)/8)*
sizeof(double);
779 extent=MagickMax(image->columns,image->rows)*quantum;
780 if ((MagickMax(image->columns,image->rows) != 0) &&
781 (quantum != (extent/MagickMax(image->columns,image->rows))))
783 if (quantum_info->pixels != (MemoryInfo **) NULL)
785 if (extent <= quantum_info->extent)
787 DestroyQuantumPixels(quantum_info);
789 return(AcquireQuantumPixels(quantum_info,extent));
819MagickExport MagickBooleanType SetQuantumFormat(
const Image *image,
820 QuantumInfo *quantum_info,
const QuantumFormatType format)
822 assert(image != (Image *) NULL);
823 assert(image->signature == MagickCoreSignature);
824 assert(quantum_info != (QuantumInfo *) NULL);
825 assert(quantum_info->signature == MagickCoreSignature);
826 if (IsEventLogging() != MagickFalse)
827 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
828 quantum_info->format=format;
829 return(SetQuantumExtent(image,quantum_info));
858MagickExport
void SetQuantumImageType(Image *image,
859 const QuantumType quantum_type)
861 assert(image != (Image *) NULL);
862 assert(image->signature == MagickCoreSignature);
863 if (IsEventLogging() != MagickFalse)
864 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
865 switch (quantum_type)
868 case IndexAlphaQuantum:
870 image->type=PaletteType;
874 case GrayAlphaQuantum:
876 image->type=GrayscaleType;
877 if (image->depth == 1)
878 image->type=BilevelType;
887 case MultispectralQuantum:
889 image->type=ColorSeparationType;
894 image->type=TrueColorType;
929MagickExport MagickBooleanType SetQuantumMetaChannel(
const Image *image,
930 QuantumInfo *quantum_info,
const ssize_t meta_channel)
932 assert(quantum_info != (QuantumInfo *) NULL);
933 assert(quantum_info->signature == MagickCoreSignature);
934 if ((meta_channel < -1) ||
935 (meta_channel >= (ssize_t) image->number_meta_channels))
937 quantum_info->meta_channel=meta_channel+1;
966MagickExport
void SetQuantumPack(QuantumInfo *quantum_info,
967 const MagickBooleanType pack)
969 assert(quantum_info != (QuantumInfo *) NULL);
970 assert(quantum_info->signature == MagickCoreSignature);
971 quantum_info->pack=pack;
1001MagickExport MagickBooleanType SetQuantumPad(
const Image *image,
1002 QuantumInfo *quantum_info,
const size_t pad)
1004 assert(image != (Image *) NULL);
1005 assert(image->signature == MagickCoreSignature);
1006 assert(quantum_info != (QuantumInfo *) NULL);
1007 assert(quantum_info->signature == MagickCoreSignature);
1008 if (IsEventLogging() != MagickFalse)
1009 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
1010 if (pad >= (MAGICK_SSIZE_MAX/GetImageChannels(image)))
1011 return(MagickFalse);
1012 quantum_info->pad=pad;
1013 return(SetQuantumExtent(image,quantum_info));
1041MagickExport
void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
1042 const MagickBooleanType min_is_white)
1044 assert(quantum_info != (QuantumInfo *) NULL);
1045 assert(quantum_info->signature == MagickCoreSignature);
1046 quantum_info->min_is_white=min_is_white;
1073MagickExport
void SetQuantumQuantum(QuantumInfo *quantum_info,
1074 const size_t quantum)
1076 assert(quantum_info != (QuantumInfo *) NULL);
1077 assert(quantum_info->signature == MagickCoreSignature);
1078 quantum_info->quantum=quantum;
1105MagickExport
void SetQuantumScale(QuantumInfo *quantum_info,
const double scale)
1107 assert(quantum_info != (QuantumInfo *) NULL);
1108 assert(quantum_info->signature == MagickCoreSignature);
1109 quantum_info->scale=scale;