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
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,
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;
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)
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)
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)
366 assert(quantum_info->signature == MagickCoreSignature);
367 return(quantum_info->endian);
392MagickExport QuantumFormatType GetQuantumFormat(
const QuantumInfo *quantum_info)
395 assert(quantum_info->signature == MagickCoreSignature);
396 return(quantum_info->format);
423MagickExport
void GetQuantumInfo(
const ImageInfo *image_info,
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();
500 assert(quantum_info->signature == MagickCoreSignature);
501 return((
unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[
id]));
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
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)
638 assert(quantum_info->signature == MagickCoreSignature);
639 quantum_info->alpha_type=type;
669MagickExport MagickBooleanType SetQuantumDepth(
const Image *image,
679 assert(image != (
Image *) NULL);
680 assert(image->signature == MagickCoreSignature);
682 assert(quantum_info->signature == MagickCoreSignature);
683 if (IsEventLogging() != MagickFalse)
684 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
685 quantum_info->depth=MagickMin(depth,64);
686 if (quantum_info->format == FloatingPointQuantumFormat)
688 if (quantum_info->depth > 32)
689 quantum_info->depth=64;
691 if (quantum_info->depth > 24)
692 quantum_info->depth=32;
694 if (quantum_info->depth > 16)
695 quantum_info->depth=24;
697 quantum_info->depth=16;
702 quantum=(GetPixelChannels(image)+quantum_info->pad+3)*
703 ((quantum_info->depth+7)/8)*
sizeof(double);
704 extent=MagickMax(image->columns,image->rows)*quantum;
705 if ((MagickMax(image->columns,image->rows) != 0) &&
706 (quantum != (extent/MagickMax(image->columns,image->rows))))
708 if (quantum_info->pixels != (
MemoryInfo **) NULL)
710 if (extent <= quantum_info->extent)
712 DestroyQuantumPixels(quantum_info);
714 return(AcquireQuantumPixels(quantum_info,extent));
744MagickExport MagickBooleanType SetQuantumEndian(
const Image *image,
747 assert(image != (
Image *) NULL);
748 assert(image->signature == MagickCoreSignature);
750 assert(quantum_info->signature == MagickCoreSignature);
751 if (IsEventLogging() != MagickFalse)
752 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
753 quantum_info->endian=endian;
754 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
784MagickExport MagickBooleanType SetQuantumFormat(
const Image *image,
785 QuantumInfo *quantum_info,
const QuantumFormatType format)
787 assert(image != (
Image *) NULL);
788 assert(image->signature == MagickCoreSignature);
790 assert(quantum_info->signature == MagickCoreSignature);
791 if (IsEventLogging() != MagickFalse)
792 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
793 quantum_info->format=format;
794 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
823MagickExport
void SetQuantumImageType(
Image *image,
824 const QuantumType quantum_type)
826 assert(image != (
Image *) NULL);
827 assert(image->signature == MagickCoreSignature);
828 if (IsEventLogging() != MagickFalse)
829 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
830 switch (quantum_type)
833 case IndexAlphaQuantum:
835 image->type=PaletteType;
839 case GrayAlphaQuantum:
841 image->type=GrayscaleType;
842 if (image->depth == 1)
843 image->type=BilevelType;
852 case MultispectralQuantum:
854 image->type=ColorSeparationType;
859 image->type=TrueColorType;
890MagickExport
void SetQuantumPack(
QuantumInfo *quantum_info,
891 const MagickBooleanType pack)
894 assert(quantum_info->signature == MagickCoreSignature);
895 quantum_info->pack=pack;
925MagickExport MagickBooleanType SetQuantumPad(
const Image *image,
928 assert(image != (
Image *) NULL);
929 assert(image->signature == MagickCoreSignature);
931 assert(quantum_info->signature == MagickCoreSignature);
932 if (IsEventLogging() != MagickFalse)
933 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
934 if (pad >= (MAGICK_SSIZE_MAX/GetImageChannels(image)))
936 quantum_info->pad=pad;
937 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
965MagickExport
void SetQuantumMinIsWhite(
QuantumInfo *quantum_info,
966 const MagickBooleanType min_is_white)
969 assert(quantum_info->signature == MagickCoreSignature);
970 quantum_info->min_is_white=min_is_white;
997MagickExport
void SetQuantumQuantum(
QuantumInfo *quantum_info,
998 const size_t quantum)
1001 assert(quantum_info->signature == MagickCoreSignature);
1002 quantum_info->quantum=quantum;
1029MagickExport
void SetQuantumScale(
QuantumInfo *quantum_info,
const double scale)
1032 assert(quantum_info->signature == MagickCoreSignature);
1033 quantum_info->scale=scale;