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);
157static 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);
249static 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);
309MagickExport
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: channels=2;
break;
321 case IndexAlphaQuantum: channels=2;
break;
322 case RGBQuantum: channels=3;
break;
323 case BGRQuantum: channels=3;
break;
324 case RGBAQuantum: channels=4;
break;
325 case RGBOQuantum: channels=4;
break;
326 case BGRAQuantum: channels=4;
break;
327 case CMYKQuantum: channels=4;
break;
328 case CMYKAQuantum: channels=5;
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=AllocateSemaphoreInfo();
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=(MagickRealType) QuantumRange/quantum_info->minimum;
455 quantum_info->minimum=0.0;
458 quantum_info->scale=(MagickRealType) 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]));
531 assert(image != (
Image *) NULL);
532 assert(image->signature == MagickCoreSignature);
533 if (IsEventLogging() != MagickFalse)
534 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
536 quantum_type=RGBQuantum;
537 if (image->matte != MagickFalse)
538 quantum_type=RGBAQuantum;
539 if (image->colorspace == CMYKColorspace)
541 quantum_type=CMYKQuantum;
542 if (image->matte != MagickFalse)
543 quantum_type=CMYKAQuantum;
545 if (IsGrayColorspace(image->colorspace) != MagickFalse)
547 quantum_type=GrayQuantum;
548 if (image->matte != MagickFalse)
549 quantum_type=GrayAlphaQuantum;
551 if (image->storage_class == PseudoClass)
553 quantum_type=IndexQuantum;
554 if (image->matte != MagickFalse)
555 quantum_type=IndexAlphaQuantum;
557 return(quantum_type);
582MagickPrivate
void ResetQuantumState(
QuantumInfo *quantum_info)
584 static const unsigned int mask[32] =
586 0x00000000U, 0x00000001U, 0x00000003U, 0x00000007U, 0x0000000fU,
587 0x0000001fU, 0x0000003fU, 0x0000007fU, 0x000000ffU, 0x000001ffU,
588 0x000003ffU, 0x000007ffU, 0x00000fffU, 0x00001fffU, 0x00003fffU,
589 0x00007fffU, 0x0000ffffU, 0x0001ffffU, 0x0003ffffU, 0x0007ffffU,
590 0x000fffffU, 0x001fffffU, 0x003fffffU, 0x007fffffU, 0x00ffffffU,
591 0x01ffffffU, 0x03ffffffU, 0x07ffffffU, 0x0fffffffU, 0x1fffffffU,
592 0x3fffffffU, 0x7fffffffU
596 assert(quantum_info->signature == MagickCoreSignature);
597 quantum_info->state.inverse_scale=1.0;
598 if (fabs(quantum_info->scale) >= MagickEpsilon)
599 quantum_info->state.inverse_scale/=quantum_info->scale;
600 quantum_info->state.pixel=0U;
601 quantum_info->state.bits=0U;
602 quantum_info->state.mask=mask;
630MagickExport
void SetQuantumAlphaType(
QuantumInfo *quantum_info,
631 const QuantumAlphaType type)
634 assert(quantum_info->signature == MagickCoreSignature);
635 quantum_info->alpha_type=type;
665MagickExport MagickBooleanType SetQuantumDepth(
const Image *image,
675 assert(image != (
Image *) NULL);
676 assert(image->signature == MagickCoreSignature);
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;
698 quantum=(quantum_info->pad+6)*((quantum_info->depth+7)/8)*
sizeof(double);
699 extent=MagickMax(image->columns,image->rows)*quantum;
700 if ((MagickMax(image->columns,image->rows) != 0) &&
701 (quantum != (extent/MagickMax(image->columns,image->rows))))
703 if (quantum_info->pixels != (
MemoryInfo **) NULL)
705 if (extent <= quantum_info->extent)
707 DestroyQuantumPixels(quantum_info);
709 return(AcquireQuantumPixels(quantum_info,extent));
739MagickExport MagickBooleanType SetQuantumEndian(
const Image *image,
742 assert(image != (
Image *) NULL);
743 assert(image->signature == MagickCoreSignature);
745 assert(quantum_info->signature == MagickCoreSignature);
746 if (IsEventLogging() != MagickFalse)
747 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
748 quantum_info->endian=endian;
749 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
779MagickExport MagickBooleanType SetQuantumFormat(
const Image *image,
780 QuantumInfo *quantum_info,
const QuantumFormatType format)
782 assert(image != (
Image *) NULL);
783 assert(image->signature == MagickCoreSignature);
785 assert(quantum_info->signature == MagickCoreSignature);
786 if (IsEventLogging() != MagickFalse)
787 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
788 quantum_info->format=format;
789 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
818MagickExport
void SetQuantumImageType(
Image *image,
819 const QuantumType quantum_type)
821 assert(image != (
Image *) NULL);
822 assert(image->signature == MagickCoreSignature);
823 if (IsEventLogging() != MagickFalse)
824 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
825 switch (quantum_type)
828 case IndexAlphaQuantum:
830 image->type=PaletteType;
834 case GrayAlphaQuantum:
836 image->type=GrayscaleType;
837 if (image->depth == 1)
838 image->type=BilevelType;
848 image->type=ColorSeparationType;
853 image->type=TrueColorType;
884MagickExport
void SetQuantumPack(
QuantumInfo *quantum_info,
885 const MagickBooleanType pack)
888 assert(quantum_info->signature == MagickCoreSignature);
889 quantum_info->pack=pack;
919MagickExport MagickBooleanType SetQuantumPad(
const Image *image,
922 assert(image != (
Image *) NULL);
923 assert(image->signature == MagickCoreSignature);
925 assert(quantum_info->signature == MagickCoreSignature);
926 if (IsEventLogging() != MagickFalse)
927 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
928 if (pad >= (MAGICK_SSIZE_MAX/5))
930 quantum_info->pad=pad;
931 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
959MagickExport
void SetQuantumMinIsWhite(
QuantumInfo *quantum_info,
960 const MagickBooleanType min_is_white)
963 assert(quantum_info->signature == MagickCoreSignature);
964 quantum_info->min_is_white=min_is_white;
991MagickExport
void SetQuantumQuantum(
QuantumInfo *quantum_info,
992 const size_t quantum)
995 assert(quantum_info->signature == MagickCoreSignature);
996 quantum_info->quantum=quantum;
1023MagickExport
void SetQuantumScale(
QuantumInfo *quantum_info,
const double scale)
1026 assert(quantum_info->signature == MagickCoreSignature);
1027 quantum_info->scale=scale;