Home | History | Annotate | Download | only in MagickCore
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                QQQ   U   U   AAA   N   N  TTTTT  U   U  M   M               %
      7 %               Q   Q  U   U  A   A  NN  N    T    U   U  MM MM               %
      8 %               Q   Q  U   U  AAAAA  N N N    T    U   U  M M M               %
      9 %               Q  QQ  U   U  A   A  N  NN    T    U   U  M   M               %
     10 %                QQQQ   UUU   A   A  N   N    T     UUU   M   M               %
     11 %                                                                             %
     12 %             MagicCore Methods to Acquire / Destroy Quantum Pixels           %
     13 %                                                                             %
     14 %                             Software Design                                 %
     15 %                                  Cristy                                     %
     16 %                               October 1998                                  %
     17 %                                                                             %
     18 %                                                                             %
     19 %  Copyright 1999-2019 ImageMagick Studio LLC, a non-profit organization      %
     20 %  dedicated to making software imaging solutions freely available.           %
     21 %                                                                             %
     22 %  You may not use this file except in compliance with the License.  You may  %
     23 %  obtain a copy of the License at                                            %
     24 %                                                                             %
     25 %    https://imagemagick.org/script/license.php                               %
     26 %                                                                             %
     27 %  Unless required by applicable law or agreed to in writing, software        %
     28 %  distributed under the License is distributed on an "AS IS" BASIS,          %
     29 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
     30 %  See the License for the specific language governing permissions and        %
     31 %  limitations under the License.                                             %
     32 %                                                                             %
     33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     34 %
     35 %
     36 */
     37 
     38 /*
     40   Include declarations.
     41 */
     42 #include "MagickCore/studio.h"
     43 #include "MagickCore/attribute.h"
     44 #include "MagickCore/blob.h"
     45 #include "MagickCore/blob-private.h"
     46 #include "MagickCore/color-private.h"
     47 #include "MagickCore/exception.h"
     48 #include "MagickCore/exception-private.h"
     49 #include "MagickCore/cache.h"
     50 #include "MagickCore/cache-private.h"
     51 #include "MagickCore/colorspace.h"
     52 #include "MagickCore/colorspace-private.h"
     53 #include "MagickCore/constitute.h"
     54 #include "MagickCore/delegate.h"
     55 #include "MagickCore/geometry.h"
     56 #include "MagickCore/list.h"
     57 #include "MagickCore/magick.h"
     58 #include "MagickCore/memory_.h"
     59 #include "MagickCore/memory-private.h"
     60 #include "MagickCore/monitor.h"
     61 #include "MagickCore/option.h"
     62 #include "MagickCore/pixel.h"
     63 #include "MagickCore/pixel-accessor.h"
     64 #include "MagickCore/property.h"
     65 #include "MagickCore/quantum.h"
     66 #include "MagickCore/quantum-private.h"
     67 #include "MagickCore/resource_.h"
     68 #include "MagickCore/semaphore.h"
     69 #include "MagickCore/statistic.h"
     70 #include "MagickCore/stream.h"
     71 #include "MagickCore/string_.h"
     72 #include "MagickCore/string-private.h"
     73 #include "MagickCore/thread-private.h"
     74 #include "MagickCore/utility.h"
     75 
     76 /*
     78   Define declarations.
     79 */
     80 #define QuantumSignature  0xab
     81 
     82 /*
     84   Forward declarations.
     85 */
     86 static void
     87   DestroyQuantumPixels(QuantumInfo *);
     88 
     89 /*
     91 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     92 %                                                                             %
     93 %                                                                             %
     94 %                                                                             %
     95 %   A c q u i r e Q u a n t u m I n f o                                       %
     96 %                                                                             %
     97 %                                                                             %
     98 %                                                                             %
     99 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    100 %
    101 %  AcquireQuantumInfo() allocates the QuantumInfo structure.
    102 %
    103 %  The format of the AcquireQuantumInfo method is:
    104 %
    105 %      QuantumInfo *AcquireQuantumInfo(const ImageInfo *image_info,Image *image)
    106 %
    107 %  A description of each parameter follows:
    108 %
    109 %    o image_info: the image info.
    110 %
    111 %    o image: the image.
    112 %
    113 */
    114 MagickExport QuantumInfo *AcquireQuantumInfo(const ImageInfo *image_info,
    115   Image *image)
    116 {
    117   MagickBooleanType
    118     status;
    119 
    120   QuantumInfo
    121     *quantum_info;
    122 
    123   quantum_info=(QuantumInfo *) AcquireCriticalMemory(sizeof(*quantum_info));
    124   quantum_info->signature=MagickCoreSignature;
    125   GetQuantumInfo(image_info,quantum_info);
    126   if (image == (const Image *) NULL)
    127     return(quantum_info);
    128   status=SetQuantumDepth(image,quantum_info,image->depth);
    129   quantum_info->endian=image->endian;
    130   if (status == MagickFalse)
    131     quantum_info=DestroyQuantumInfo(quantum_info);
    132   return(quantum_info);
    133 }
    134 
    135 /*
    137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    138 %                                                                             %
    139 %                                                                             %
    140 %                                                                             %
    141 +   A c q u i r e Q u a n t u m P i x e l s                                   %
    142 %                                                                             %
    143 %                                                                             %
    144 %                                                                             %
    145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    146 %
    147 %  AcquireQuantumPixels() allocates the pixel staging areas.
    148 %
    149 %  The format of the AcquireQuantumPixels method is:
    150 %
    151 %      MagickBooleanType AcquireQuantumPixels(QuantumInfo *quantum_info,
    152 %        const size_t extent)
    153 %
    154 %  A description of each parameter follows:
    155 %
    156 %    o quantum_info: the quantum info.
    157 %
    158 %    o extent: the quantum info.
    159 %
    160 */
    161 static MagickBooleanType AcquireQuantumPixels(QuantumInfo *quantum_info,
    162   const size_t extent)
    163 {
    164   register ssize_t
    165     i;
    166 
    167   assert(quantum_info != (QuantumInfo *) NULL);
    168   assert(quantum_info->signature == MagickCoreSignature);
    169   quantum_info->number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
    170   quantum_info->pixels=(MemoryInfo **) AcquireQuantumMemory(
    171     quantum_info->number_threads,sizeof(*quantum_info->pixels));
    172   if (quantum_info->pixels == (MemoryInfo **) NULL)
    173     return(MagickFalse);
    174   quantum_info->extent=extent;
    175   (void) memset(quantum_info->pixels,0,quantum_info->number_threads*
    176     sizeof(*quantum_info->pixels));
    177   for (i=0; i < (ssize_t) quantum_info->number_threads; i++)
    178   {
    179     unsigned char
    180       *pixels;
    181 
    182     quantum_info->pixels[i]=AcquireVirtualMemory((extent+1),sizeof(*pixels));
    183     if (quantum_info->pixels[i] == (MemoryInfo *) NULL)
    184       {
    185         DestroyQuantumPixels(quantum_info);
    186         return(MagickFalse);
    187       }
    188     pixels=(unsigned char *)  GetVirtualMemoryBlob(quantum_info->pixels[i]);
    189     (void) memset(pixels,0,(extent+1)*sizeof(*pixels));
    190     pixels[extent]=QuantumSignature;
    191   }
    192   return(MagickTrue);
    193 }
    194 
    195 /*
    197 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    198 %                                                                             %
    199 %                                                                             %
    200 %                                                                             %
    201 %   D e s t r o y Q u a n t u m I n f o                                       %
    202 %                                                                             %
    203 %                                                                             %
    204 %                                                                             %
    205 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    206 %
    207 %  DestroyQuantumInfo() deallocates memory associated with the QuantumInfo
    208 %  structure.
    209 %
    210 %  The format of the DestroyQuantumInfo method is:
    211 %
    212 %      QuantumInfo *DestroyQuantumInfo(QuantumInfo *quantum_info)
    213 %
    214 %  A description of each parameter follows:
    215 %
    216 %    o quantum_info: the quantum info.
    217 %
    218 */
    219 MagickExport QuantumInfo *DestroyQuantumInfo(QuantumInfo *quantum_info)
    220 {
    221   assert(quantum_info != (QuantumInfo *) NULL);
    222   assert(quantum_info->signature == MagickCoreSignature);
    223   if (quantum_info->pixels != (MemoryInfo **) NULL)
    224     DestroyQuantumPixels(quantum_info);
    225   if (quantum_info->semaphore != (SemaphoreInfo *) NULL)
    226     RelinquishSemaphoreInfo(&quantum_info->semaphore);
    227   quantum_info->signature=(~MagickCoreSignature);
    228   quantum_info=(QuantumInfo *) RelinquishMagickMemory(quantum_info);
    229   return(quantum_info);
    230 }
    231 
    232 /*
    234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    235 %                                                                             %
    236 %                                                                             %
    237 %                                                                             %
    238 +   D e s t r o y Q u a n t u m P i x e l s                                   %
    239 %                                                                             %
    240 %                                                                             %
    241 %                                                                             %
    242 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    243 %
    244 %  DestroyQuantumPixels() destroys the quantum pixels.
    245 %
    246 %  The format of the DestroyQuantumPixels() method is:
    247 %
    248 %      void DestroyQuantumPixels(QuantumInfo *quantum_info)
    249 %
    250 %  A description of each parameter follows:
    251 %
    252 %    o quantum_info: the quantum info.
    253 %
    254 */
    255 static void DestroyQuantumPixels(QuantumInfo *quantum_info)
    256 {
    257   register ssize_t
    258     i;
    259 
    260   ssize_t
    261     extent;
    262 
    263   assert(quantum_info != (QuantumInfo *) NULL);
    264   assert(quantum_info->signature == MagickCoreSignature);
    265   assert(quantum_info->pixels != (MemoryInfo **) NULL);
    266   extent=(ssize_t) quantum_info->extent;
    267   for (i=0; i < (ssize_t) quantum_info->number_threads; i++)
    268     if (quantum_info->pixels[i] != (MemoryInfo *) NULL)
    269       {
    270         unsigned char
    271           *pixels;
    272 
    273         /*
    274           Did we overrun our quantum buffer?
    275         */
    276         pixels=(unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[i]);
    277         assert(pixels[extent] == QuantumSignature);
    278         quantum_info->pixels[i]=RelinquishVirtualMemory(
    279           quantum_info->pixels[i]);
    280       }
    281   quantum_info->pixels=(MemoryInfo **) RelinquishMagickMemory(
    282     quantum_info->pixels);
    283 }
    284 
    285 /*
    287 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    288 %                                                                             %
    289 %                                                                             %
    290 %                                                                             %
    291 %   G e t Q u a n t u m E x t e n t                                           %
    292 %                                                                             %
    293 %                                                                             %
    294 %                                                                             %
    295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    296 %
    297 %  GetQuantumExtent() returns the quantum pixel buffer extent.
    298 %
    299 %  The format of the GetQuantumExtent method is:
    300 %
    301 %      size_t GetQuantumExtent(Image *image,const QuantumInfo *quantum_info,
    302 %        const QuantumType quantum_type)
    303 %
    304 %  A description of each parameter follows:
    305 %
    306 %    o image: the image.
    307 %
    308 %    o quantum_info: the quantum info.
    309 %
    310 %    o quantum_type: Declare which pixel components to transfer (red, green,
    311 %      blue, opacity, RGB, or RGBA).
    312 %
    313 */
    314 MagickExport size_t GetQuantumExtent(const Image *image,
    315   const QuantumInfo *quantum_info,const QuantumType quantum_type)
    316 {
    317   size_t
    318     packet_size;
    319 
    320   assert(quantum_info != (QuantumInfo *) NULL);
    321   assert(quantum_info->signature == MagickCoreSignature);
    322   packet_size=1;
    323   switch (quantum_type)
    324   {
    325     case GrayAlphaQuantum: packet_size=2; break;
    326     case IndexAlphaQuantum: packet_size=2; break;
    327     case RGBQuantum: packet_size=3; break;
    328     case BGRQuantum: packet_size=3; break;
    329     case RGBAQuantum: packet_size=4; break;
    330     case RGBOQuantum: packet_size=4; break;
    331     case BGRAQuantum: packet_size=4; break;
    332     case CMYKQuantum: packet_size=4; break;
    333     case CMYKAQuantum: packet_size=5; break;
    334     case CbYCrAQuantum: packet_size=4; break;
    335     case CbYCrQuantum: packet_size=3; break;
    336     case CbYCrYQuantum: packet_size=4; break;
    337     default: break;
    338   }
    339   if (quantum_info->pack == MagickFalse)
    340     return((size_t) (packet_size*image->columns*((quantum_info->depth+7)/8)));
    341   return((size_t) ((packet_size*image->columns*quantum_info->depth+7)/8));
    342 }
    343 
    344 /*
    346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    347 %                                                                             %
    348 %                                                                             %
    349 %                                                                             %
    350 %   G e t Q u a n t u m E n d i a n                                           %
    351 %                                                                             %
    352 %                                                                             %
    353 %                                                                             %
    354 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    355 %
    356 %  GetQuantumEndian() returns the quantum endian of the image.
    357 %
    358 %  The endian of the GetQuantumEndian method is:
    359 %
    360 %      EndianType GetQuantumEndian(const QuantumInfo *quantum_info)
    361 %
    362 %  A description of each parameter follows:
    363 %
    364 %    o quantum_info: the quantum info.
    365 %
    366 */
    367 MagickExport EndianType GetQuantumEndian(const QuantumInfo *quantum_info)
    368 {
    369   assert(quantum_info != (QuantumInfo *) NULL);
    370   assert(quantum_info->signature == MagickCoreSignature);
    371   return(quantum_info->endian);
    372 }
    373 
    374 /*
    376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    377 %                                                                             %
    378 %                                                                             %
    379 %                                                                             %
    380 %   G e t Q u a n t u m F o r m a t                                           %
    381 %                                                                             %
    382 %                                                                             %
    383 %                                                                             %
    384 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    385 %
    386 %  GetQuantumFormat() returns the quantum format of the image.
    387 %
    388 %  The format of the GetQuantumFormat method is:
    389 %
    390 %      QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info)
    391 %
    392 %  A description of each parameter follows:
    393 %
    394 %    o quantum_info: the quantum info.
    395 %
    396 */
    397 MagickExport QuantumFormatType GetQuantumFormat(const QuantumInfo *quantum_info)
    398 {
    399   assert(quantum_info != (QuantumInfo *) NULL);
    400   assert(quantum_info->signature == MagickCoreSignature);
    401   return(quantum_info->format);
    402 }
    403 
    404 /*
    406 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    407 %                                                                             %
    408 %                                                                             %
    409 %                                                                             %
    410 %   G e t Q u a n t u m I n f o                                               %
    411 %                                                                             %
    412 %                                                                             %
    413 %                                                                             %
    414 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    415 %
    416 %  GetQuantumInfo() initializes the QuantumInfo structure to default values.
    417 %
    418 %  The format of the GetQuantumInfo method is:
    419 %
    420 %      GetQuantumInfo(const ImageInfo *image_info,QuantumInfo *quantum_info)
    421 %
    422 %  A description of each parameter follows:
    423 %
    424 %    o image_info: the image info.
    425 %
    426 %    o quantum_info: the quantum info.
    427 %
    428 */
    429 MagickExport void GetQuantumInfo(const ImageInfo *image_info,
    430   QuantumInfo *quantum_info)
    431 {
    432   const char
    433     *option;
    434 
    435   assert(quantum_info != (QuantumInfo *) NULL);
    436   (void) memset(quantum_info,0,sizeof(*quantum_info));
    437   quantum_info->quantum=8;
    438   quantum_info->maximum=1.0;
    439   quantum_info->scale=QuantumRange;
    440   quantum_info->pack=MagickTrue;
    441   quantum_info->semaphore=AcquireSemaphoreInfo();
    442   quantum_info->signature=MagickCoreSignature;
    443   if (image_info == (const ImageInfo *) NULL)
    444     return;
    445   option=GetImageOption(image_info,"quantum:format");
    446   if (option != (char *) NULL)
    447     quantum_info->format=(QuantumFormatType) ParseCommandOption(
    448       MagickQuantumFormatOptions,MagickFalse,option);
    449   option=GetImageOption(image_info,"quantum:minimum");
    450   if (option != (char *) NULL)
    451     quantum_info->minimum=StringToDouble(option,(char **) NULL);
    452   option=GetImageOption(image_info,"quantum:maximum");
    453   if (option != (char *) NULL)
    454     quantum_info->maximum=StringToDouble(option,(char **) NULL);
    455   if ((quantum_info->minimum == 0.0) && (quantum_info->maximum == 0.0))
    456     quantum_info->scale=0.0;
    457   else
    458     if (quantum_info->minimum == quantum_info->maximum)
    459       {
    460         quantum_info->scale=(double) QuantumRange/quantum_info->minimum;
    461         quantum_info->minimum=0.0;
    462       }
    463     else
    464       quantum_info->scale=(double) QuantumRange/(quantum_info->maximum-
    465         quantum_info->minimum);
    466   option=GetImageOption(image_info,"quantum:scale");
    467   if (option != (char *) NULL)
    468     quantum_info->scale=StringToDouble(option,(char **) NULL);
    469   option=GetImageOption(image_info,"quantum:polarity");
    470   if (option != (char *) NULL)
    471     quantum_info->min_is_white=LocaleCompare(option,"min-is-white") == 0 ?
    472       MagickTrue : MagickFalse;
    473   quantum_info->endian=image_info->endian;
    474   ResetQuantumState(quantum_info);
    475 }
    476 
    477 /*
    479 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    480 %                                                                             %
    481 %                                                                             %
    482 %                                                                             %
    483 %   G e t Q u a n t u m P i x e l s                                           %
    484 %                                                                             %
    485 %                                                                             %
    486 %                                                                             %
    487 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    488 %
    489 %  GetQuantumPixels() returns the quantum pixels.
    490 %
    491 %  The format of the GetQuantumPixels method is:
    492 %
    493 %      unsigned char *QuantumPixels GetQuantumPixels(
    494 %        const QuantumInfo *quantum_info)
    495 %
    496 %  A description of each parameter follows:
    497 %
    498 %    o image: the image.
    499 %
    500 */
    501 MagickExport unsigned char *GetQuantumPixels(const QuantumInfo *quantum_info)
    502 {
    503   const int
    504     id = GetOpenMPThreadId();
    505 
    506   assert(quantum_info != (QuantumInfo *) NULL);
    507   assert(quantum_info->signature == MagickCoreSignature);
    508   return((unsigned char *) GetVirtualMemoryBlob(quantum_info->pixels[id]));
    509 }
    510 
    511 /*
    513 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    514 %                                                                             %
    515 %                                                                             %
    516 %                                                                             %
    517 %   G e t Q u a n t u m T y p e                                               %
    518 %                                                                             %
    519 %                                                                             %
    520 %                                                                             %
    521 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    522 %
    523 %  GetQuantumType() returns the quantum type of the image.
    524 %
    525 %  The format of the GetQuantumType method is:
    526 %
    527 %      QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
    528 %
    529 %  A description of each parameter follows:
    530 %
    531 %    o image: the image.
    532 %
    533 %    o exception: return any errors or warnings in this structure.
    534 %
    535 */
    536 MagickExport QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
    537 {
    538   QuantumType
    539     quantum_type;
    540 
    541   assert(image != (Image *) NULL);
    542   assert(image->signature == MagickCoreSignature);
    543   if (image->debug != MagickFalse)
    544     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    545   (void) exception;
    546   quantum_type=RGBQuantum;
    547   if (image->alpha_trait != UndefinedPixelTrait)
    548     quantum_type=RGBAQuantum;
    549   if (image->colorspace == CMYKColorspace)
    550     {
    551       quantum_type=CMYKQuantum;
    552       if (image->alpha_trait != UndefinedPixelTrait)
    553         quantum_type=CMYKAQuantum;
    554     }
    555   if (IsGrayColorspace(image->colorspace) != MagickFalse)
    556     {
    557       quantum_type=GrayQuantum;
    558       if (image->alpha_trait != UndefinedPixelTrait)
    559         quantum_type=GrayAlphaQuantum;
    560     }
    561   if (image->storage_class == PseudoClass)
    562     {
    563       quantum_type=IndexQuantum;
    564       if (image->alpha_trait != UndefinedPixelTrait)
    565         quantum_type=IndexAlphaQuantum;
    566     }
    567   return(quantum_type);
    568 }
    569 
    570 /*
    572 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    573 %                                                                             %
    574 %                                                                             %
    575 %                                                                             %
    576 +   R e s e t Q u a n t u m S t a t e                                         %
    577 %                                                                             %
    578 %                                                                             %
    579 %                                                                             %
    580 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    581 %
    582 %  ResetQuantumState() resets the quantum state.
    583 %
    584 %  The format of the ResetQuantumState method is:
    585 %
    586 %      void ResetQuantumState(QuantumInfo *quantum_info)
    587 %
    588 %  A description of each parameter follows:
    589 %
    590 %    o quantum_info: the quantum info.
    591 %
    592 */
    593 MagickPrivate void ResetQuantumState(QuantumInfo *quantum_info)
    594 {
    595   static const unsigned int mask[32] =
    596   {
    597     0x00000000U, 0x00000001U, 0x00000003U, 0x00000007U, 0x0000000fU,
    598     0x0000001fU, 0x0000003fU, 0x0000007fU, 0x000000ffU, 0x000001ffU,
    599     0x000003ffU, 0x000007ffU, 0x00000fffU, 0x00001fffU, 0x00003fffU,
    600     0x00007fffU, 0x0000ffffU, 0x0001ffffU, 0x0003ffffU, 0x0007ffffU,
    601     0x000fffffU, 0x001fffffU, 0x003fffffU, 0x007fffffU, 0x00ffffffU,
    602     0x01ffffffU, 0x03ffffffU, 0x07ffffffU, 0x0fffffffU, 0x1fffffffU,
    603     0x3fffffffU, 0x7fffffffU
    604   };
    605 
    606   assert(quantum_info != (QuantumInfo *) NULL);
    607   assert(quantum_info->signature == MagickCoreSignature);
    608   quantum_info->state.inverse_scale=1.0;
    609   if (fabs(quantum_info->scale) >= MagickEpsilon)
    610     quantum_info->state.inverse_scale/=quantum_info->scale;
    611   quantum_info->state.pixel=0U;
    612   quantum_info->state.bits=0U;
    613   quantum_info->state.mask=mask;
    614 }
    615 
    616 /*
    618 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    619 %                                                                             %
    620 %                                                                             %
    621 %                                                                             %
    622 %   S e t Q u a n t u m F o r m a t                                           %
    623 %                                                                             %
    624 %                                                                             %
    625 %                                                                             %
    626 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    627 %
    628 %  SetQuantumAlphaType() sets the quantum format.
    629 %
    630 %  The format of the SetQuantumAlphaType method is:
    631 %
    632 %      void SetQuantumAlphaType(QuantumInfo *quantum_info,
    633 %        const QuantumAlphaType type)
    634 %
    635 %  A description of each parameter follows:
    636 %
    637 %    o quantum_info: the quantum info.
    638 %
    639 %    o type: the alpha type (e.g. associate).
    640 %
    641 */
    642 MagickExport void SetQuantumAlphaType(QuantumInfo *quantum_info,
    643   const QuantumAlphaType type)
    644 {
    645   assert(quantum_info != (QuantumInfo *) NULL);
    646   assert(quantum_info->signature == MagickCoreSignature);
    647   quantum_info->alpha_type=type;
    648 }
    649 
    650 /*
    652 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    653 %                                                                             %
    654 %                                                                             %
    655 %                                                                             %
    656 %   S e t Q u a n t u m D e p t h                                             %
    657 %                                                                             %
    658 %                                                                             %
    659 %                                                                             %
    660 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    661 %
    662 %  SetQuantumDepth() sets the quantum depth.
    663 %
    664 %  The format of the SetQuantumDepth method is:
    665 %
    666 %      MagickBooleanType SetQuantumDepth(const Image *image,
    667 %        QuantumInfo *quantum_info,const size_t depth)
    668 %
    669 %  A description of each parameter follows:
    670 %
    671 %    o image: the image.
    672 %
    673 %    o quantum_info: the quantum info.
    674 %
    675 %    o depth: the quantum depth.
    676 %
    677 */
    678 MagickExport MagickBooleanType SetQuantumDepth(const Image *image,
    679   QuantumInfo *quantum_info,const size_t depth)
    680 {
    681   size_t
    682     extent,
    683     quantum;
    684 
    685   /*
    686     Allocate the quantum pixel buffer.
    687   */
    688   assert(image != (Image *) NULL);
    689   assert(image->signature == MagickCoreSignature);
    690   if (image->debug != MagickFalse)
    691     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    692   assert(quantum_info != (QuantumInfo *) NULL);
    693   assert(quantum_info->signature == MagickCoreSignature);
    694   quantum_info->depth=depth;
    695   if (quantum_info->format == FloatingPointQuantumFormat)
    696     {
    697       if (quantum_info->depth > 32)
    698         quantum_info->depth=64;
    699       else
    700         if (quantum_info->depth > 16)
    701           quantum_info->depth=32;
    702         else
    703           quantum_info->depth=16;
    704     }
    705   if (quantum_info->pixels != (MemoryInfo **) NULL)
    706     DestroyQuantumPixels(quantum_info);
    707   quantum=(quantum_info->pad+MaxPixelChannels)*(quantum_info->depth+7)/8;
    708   extent=MagickMax(image->columns,image->rows)*quantum;
    709   if ((MagickMax(image->columns,image->rows) != 0) &&
    710       (quantum != (extent/MagickMax(image->columns,image->rows))))
    711     return(MagickFalse);
    712   return(AcquireQuantumPixels(quantum_info,extent));
    713 }
    714 
    715 /*
    717 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    718 %                                                                             %
    719 %                                                                             %
    720 %                                                                             %
    721 %   S e t Q u a n t u m E n d i a n                                           %
    722 %                                                                             %
    723 %                                                                             %
    724 %                                                                             %
    725 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    726 %
    727 %  SetQuantumEndian() sets the quantum endian.
    728 %
    729 %  The endian of the SetQuantumEndian method is:
    730 %
    731 %      MagickBooleanType SetQuantumEndian(const Image *image,
    732 %        QuantumInfo *quantum_info,const EndianType endian)
    733 %
    734 %  A description of each parameter follows:
    735 %
    736 %    o image: the image.
    737 %
    738 %    o quantum_info: the quantum info.
    739 %
    740 %    o endian: the quantum endian.
    741 %
    742 */
    743 MagickExport MagickBooleanType SetQuantumEndian(const Image *image,
    744   QuantumInfo *quantum_info,const EndianType endian)
    745 {
    746   assert(image != (Image *) NULL);
    747   assert(image->signature == MagickCoreSignature);
    748   if (image->debug != MagickFalse)
    749     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    750   assert(quantum_info != (QuantumInfo *) NULL);
    751   assert(quantum_info->signature == MagickCoreSignature);
    752   quantum_info->endian=endian;
    753   return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
    754 }
    755 
    756 /*
    758 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    759 %                                                                             %
    760 %                                                                             %
    761 %                                                                             %
    762 %   S e t Q u a n t u m F o r m a t                                           %
    763 %                                                                             %
    764 %                                                                             %
    765 %                                                                             %
    766 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    767 %
    768 %  SetQuantumFormat() sets the quantum format.
    769 %
    770 %  The format of the SetQuantumFormat method is:
    771 %
    772 %      MagickBooleanType SetQuantumFormat(const Image *image,
    773 %        QuantumInfo *quantum_info,const QuantumFormatType format)
    774 %
    775 %  A description of each parameter follows:
    776 %
    777 %    o image: the image.
    778 %
    779 %    o quantum_info: the quantum info.
    780 %
    781 %    o format: the quantum format.
    782 %
    783 */
    784 MagickExport MagickBooleanType SetQuantumFormat(const Image *image,
    785   QuantumInfo *quantum_info,const QuantumFormatType format)
    786 {
    787   assert(image != (Image *) NULL);
    788   assert(image->signature == MagickCoreSignature);
    789   if (image->debug != MagickFalse)
    790     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    791   assert(quantum_info != (QuantumInfo *) NULL);
    792   assert(quantum_info->signature == MagickCoreSignature);
    793   quantum_info->format=format;
    794   return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
    795 }
    796 
    797 /*
    799 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    800 %                                                                             %
    801 %                                                                             %
    802 %                                                                             %
    803 %   S e t Q u a n t u m I m a g e T y p e                                     %
    804 %                                                                             %
    805 %                                                                             %
    806 %                                                                             %
    807 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    808 %
    809 %  SetQuantumImageType() sets the image type based on the quantum type.
    810 %
    811 %  The format of the SetQuantumImageType method is:
    812 %
    813 %      void ImageType SetQuantumImageType(Image *image,
    814 %        const QuantumType quantum_type)
    815 %
    816 %  A description of each parameter follows:
    817 %
    818 %    o image: the image.
    819 %
    820 %    o quantum_type: Declare which pixel components to transfer (red, green,
    821 %      blue, opacity, RGB, or RGBA).
    822 %
    823 */
    824 MagickExport void SetQuantumImageType(Image *image,
    825   const QuantumType quantum_type)
    826 {
    827   assert(image != (Image *) NULL);
    828   assert(image->signature == MagickCoreSignature);
    829   if (image->debug != MagickFalse)
    830     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    831   switch (quantum_type)
    832   {
    833     case IndexQuantum:
    834     case IndexAlphaQuantum:
    835     {
    836       image->type=PaletteType;
    837       break;
    838     }
    839     case GrayQuantum:
    840     case GrayAlphaQuantum:
    841     {
    842       image->type=GrayscaleType;
    843       if (image->depth == 1)
    844         image->type=BilevelType;
    845       break;
    846     }
    847     case CyanQuantum:
    848     case MagentaQuantum:
    849     case YellowQuantum:
    850     case BlackQuantum:
    851     case CMYKQuantum:
    852     case CMYKAQuantum:
    853     {
    854       image->type=ColorSeparationType;
    855       break;
    856     }
    857     default:
    858     {
    859       image->type=TrueColorType;
    860       break;
    861     }
    862   }
    863 }
    864 
    865 /*
    867 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    868 %                                                                             %
    869 %                                                                             %
    870 %                                                                             %
    871 %   S e t Q u a n t u m P a c k                                               %
    872 %                                                                             %
    873 %                                                                             %
    874 %                                                                             %
    875 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    876 %
    877 %  SetQuantumPack() sets the quantum pack flag.
    878 %
    879 %  The format of the SetQuantumPack method is:
    880 %
    881 %      void SetQuantumPack(QuantumInfo *quantum_info,
    882 %        const MagickBooleanType pack)
    883 %
    884 %  A description of each parameter follows:
    885 %
    886 %    o quantum_info: the quantum info.
    887 %
    888 %    o pack: the pack flag.
    889 %
    890 */
    891 MagickExport void SetQuantumPack(QuantumInfo *quantum_info,
    892   const MagickBooleanType pack)
    893 {
    894   assert(quantum_info != (QuantumInfo *) NULL);
    895   assert(quantum_info->signature == MagickCoreSignature);
    896   quantum_info->pack=pack;
    897 }
    898 
    899 /*
    901 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    902 %                                                                             %
    903 %                                                                             %
    904 %                                                                             %
    905 %   S e t Q u a n t u m P a d                                                 %
    906 %                                                                             %
    907 %                                                                             %
    908 %                                                                             %
    909 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    910 %
    911 %  SetQuantumPad() sets the quantum pad.
    912 %
    913 %  The format of the SetQuantumPad method is:
    914 %
    915 %      MagickBooleanType SetQuantumPad(const Image *image,
    916 %        QuantumInfo *quantum_info,const size_t pad)
    917 %
    918 %  A description of each parameter follows:
    919 %
    920 %    o image: the image.
    921 %
    922 %    o quantum_info: the quantum info.
    923 %
    924 %    o pad: the quantum pad.
    925 %
    926 */
    927 MagickExport MagickBooleanType SetQuantumPad(const Image *image,
    928   QuantumInfo *quantum_info,const size_t pad)
    929 {
    930   assert(image != (Image *) NULL);
    931   assert(image->signature == MagickCoreSignature);
    932   if (image->debug != MagickFalse)
    933     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    934   assert(quantum_info != (QuantumInfo *) NULL);
    935   assert(quantum_info->signature == MagickCoreSignature);
    936   quantum_info->pad=pad;
    937   return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
    938 }
    939 
    940 /*
    942 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    943 %                                                                             %
    944 %                                                                             %
    945 %                                                                             %
    946 %   S e t Q u a n t u m M i n I s W h i t e                                   %
    947 %                                                                             %
    948 %                                                                             %
    949 %                                                                             %
    950 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    951 %
    952 %  SetQuantumMinIsWhite() sets the quantum min-is-white flag.
    953 %
    954 %  The format of the SetQuantumMinIsWhite method is:
    955 %
    956 %      void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
    957 %        const MagickBooleanType min_is_white)
    958 %
    959 %  A description of each parameter follows:
    960 %
    961 %    o quantum_info: the quantum info.
    962 %
    963 %    o min_is_white: the min-is-white flag.
    964 %
    965 */
    966 MagickExport void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
    967   const MagickBooleanType min_is_white)
    968 {
    969   assert(quantum_info != (QuantumInfo *) NULL);
    970   assert(quantum_info->signature == MagickCoreSignature);
    971   quantum_info->min_is_white=min_is_white;
    972 }
    973 
    974 /*
    976 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    977 %                                                                             %
    978 %                                                                             %
    979 %                                                                             %
    980 %   S e t Q u a n t u m Q u a n t u m                                         %
    981 %                                                                             %
    982 %                                                                             %
    983 %                                                                             %
    984 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    985 %
    986 %  SetQuantumQuantum() sets the quantum quantum.
    987 %
    988 %  The format of the SetQuantumQuantum method is:
    989 %
    990 %      void SetQuantumQuantum(QuantumInfo *quantum_info,
    991 %        const size_t quantum)
    992 %
    993 %  A description of each parameter follows:
    994 %
    995 %    o quantum_info: the quantum info.
    996 %
    997 %    o quantum: the quantum quantum.
    998 %
    999 */
   1000 MagickExport void SetQuantumQuantum(QuantumInfo *quantum_info,
   1001   const size_t quantum)
   1002 {
   1003   assert(quantum_info != (QuantumInfo *) NULL);
   1004   assert(quantum_info->signature == MagickCoreSignature);
   1005   quantum_info->quantum=quantum;
   1006 }
   1007 
   1008 /*
   1010 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1011 %                                                                             %
   1012 %                                                                             %
   1013 %                                                                             %
   1014 %   S e t Q u a n t u m S c a l e                                             %
   1015 %                                                                             %
   1016 %                                                                             %
   1017 %                                                                             %
   1018 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1019 %
   1020 %  SetQuantumScale() sets the quantum scale.
   1021 %
   1022 %  The format of the SetQuantumScale method is:
   1023 %
   1024 %      void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
   1025 %
   1026 %  A description of each parameter follows:
   1027 %
   1028 %    o quantum_info: the quantum info.
   1029 %
   1030 %    o scale: the quantum scale.
   1031 %
   1032 */
   1033 MagickExport void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
   1034 {
   1035   assert(quantum_info != (QuantumInfo *) NULL);
   1036   assert(quantum_info->signature == MagickCoreSignature);
   1037   quantum_info->scale=scale;
   1038 }
   1039