00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include "magick/studio.h"
00042 #include "magick/property.h"
00043 #include "magick/blob.h"
00044 #include "magick/blob-private.h"
00045 #include "magick/color-private.h"
00046 #include "magick/exception.h"
00047 #include "magick/exception-private.h"
00048 #include "magick/cache.h"
00049 #include "magick/constitute.h"
00050 #include "magick/delegate.h"
00051 #include "magick/geometry.h"
00052 #include "magick/list.h"
00053 #include "magick/magick.h"
00054 #include "magick/memory_.h"
00055 #include "magick/monitor.h"
00056 #include "magick/option.h"
00057 #include "magick/pixel.h"
00058 #include "magick/pixel-private.h"
00059 #include "magick/quantum.h"
00060 #include "magick/quantum-private.h"
00061 #include "magick/resource_.h"
00062 #include "magick/semaphore.h"
00063 #include "magick/statistic.h"
00064 #include "magick/stream.h"
00065 #include "magick/string_.h"
00066 #include "magick/utility.h"
00067
00068
00069
00070
00071 #define QuantumSignature 0xab
00072
00073
00074
00075
00076 static void
00077 DestroyQuantumPixels(QuantumInfo *);
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 static inline unsigned long MagickMax(const unsigned long x,
00105 const unsigned long y)
00106 {
00107 if (x > y)
00108 return(x);
00109 return(y);
00110 }
00111
00112 MagickExport QuantumInfo *AcquireQuantumInfo(const ImageInfo *image_info,
00113 Image *image)
00114 {
00115 QuantumInfo
00116 *quantum_info;
00117
00118 quantum_info=(QuantumInfo *) AcquireMagickMemory(sizeof(*quantum_info));
00119 if (quantum_info == (QuantumInfo *) NULL)
00120 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00121 quantum_info->signature=MagickSignature;
00122 GetQuantumInfo(image_info,quantum_info);
00123 if (image != (const Image *) NULL)
00124 {
00125 MagickBooleanType
00126 status;
00127
00128 status=SetQuantumDepth(image,quantum_info,image->depth);
00129 if (status == MagickFalse)
00130 quantum_info=DestroyQuantumInfo(quantum_info);
00131 }
00132 return(quantum_info);
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 static MagickBooleanType AcquireQuantumPixels(QuantumInfo *quantum_info,
00161 const size_t extent)
00162 {
00163 register long
00164 i;
00165
00166 assert(quantum_info != (QuantumInfo *) NULL);
00167 assert(quantum_info->signature == MagickSignature);
00168 quantum_info->number_threads=GetPixelCacheMaximumThreads();
00169 quantum_info->pixels=(unsigned char **) AcquireQuantumMemory(
00170 quantum_info->number_threads,sizeof(*quantum_info->pixels));
00171 if (quantum_info->pixels == (unsigned char **) NULL)
00172 return(MagickFalse);
00173 quantum_info->extent=extent;
00174 (void) ResetMagickMemory(quantum_info->pixels,0,
00175 sizeof(*quantum_info->pixels));
00176 for (i=0; i < (long) quantum_info->number_threads; i++)
00177 {
00178 quantum_info->pixels[i]=(unsigned char *) AcquireQuantumMemory(extent+1,
00179 sizeof(**quantum_info->pixels));
00180 if (quantum_info->pixels[i] == (unsigned char *) NULL)
00181 return(MagickFalse);
00182 quantum_info->pixels[i][extent]=QuantumSignature;
00183 }
00184 return(MagickTrue);
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 MagickExport QuantumInfo *DestroyQuantumInfo(QuantumInfo *quantum_info)
00211 {
00212 assert(quantum_info != (QuantumInfo *) NULL);
00213 assert(quantum_info->signature == MagickSignature);
00214 if (quantum_info->pixels != (unsigned char **) NULL)
00215 DestroyQuantumPixels(quantum_info);
00216 if (quantum_info->semaphore != (SemaphoreInfo *) NULL)
00217 DestroySemaphoreInfo(&quantum_info->semaphore);
00218 quantum_info->signature=(~MagickSignature);
00219 quantum_info=(QuantumInfo *) RelinquishMagickMemory(quantum_info);
00220 return(quantum_info);
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 static void DestroyQuantumPixels(QuantumInfo *quantum_info)
00246 {
00247 register long
00248 i;
00249
00250 assert(quantum_info != (QuantumInfo *) NULL);
00251 assert(quantum_info->signature == MagickSignature);
00252 assert(quantum_info->pixels != (unsigned char **) NULL);
00253 for (i=0; i < (long) quantum_info->number_threads; i++)
00254 {
00255 assert(quantum_info->pixels[i][quantum_info->extent] == QuantumSignature);
00256 quantum_info->pixels[i]=(unsigned char *) RelinquishMagickMemory(
00257 quantum_info->pixels[i]);
00258 }
00259 quantum_info->pixels=(unsigned char **) RelinquishMagickMemory(
00260 quantum_info->pixels);
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 MagickExport size_t GetQuantumExtent(const Image *image,
00292 const QuantumInfo *quantum_info,const QuantumType quantum_type)
00293 {
00294 size_t
00295 packet_size;
00296
00297 assert(quantum_info != (QuantumInfo *) NULL);
00298 assert(quantum_info->signature == MagickSignature);
00299 packet_size=1;
00300 switch (quantum_type)
00301 {
00302 case GrayAlphaQuantum: packet_size=2; break;
00303 case IndexAlphaQuantum: packet_size=2; break;
00304 case RGBQuantum: packet_size=3; break;
00305 case RGBAQuantum: packet_size=4; break;
00306 case RGBOQuantum: packet_size=4; break;
00307 case CMYKQuantum: packet_size=4; break;
00308 case CMYKAQuantum: packet_size=5; break;
00309 default: break;
00310 }
00311 if (quantum_info->pack == MagickFalse)
00312 return((size_t) (packet_size*image->columns*((image->depth+7)/8)));
00313 return((size_t) ((packet_size*image->columns*image->depth+7)/8));
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 MagickExport void GetQuantumInfo(const ImageInfo *image_info,
00341 QuantumInfo *quantum_info)
00342 {
00343 const char
00344 *option;
00345
00346 assert(quantum_info != (QuantumInfo *) NULL);
00347 (void) ResetMagickMemory(quantum_info,0,sizeof(*quantum_info));
00348 quantum_info->quantum=8;
00349 quantum_info->maximum=1.0;
00350 quantum_info->scale=QuantumRange;
00351 quantum_info->pack=MagickTrue;
00352 quantum_info->semaphore=AllocateSemaphoreInfo();
00353 quantum_info->signature=MagickSignature;
00354 if (image_info == (const ImageInfo *) NULL)
00355 return;
00356 option=GetImageOption(image_info,"quantum:format");
00357 if (option != (char *) NULL)
00358 quantum_info->format=(QuantumFormatType) ParseMagickOption(
00359 MagickQuantumFormatOptions,MagickFalse,option);
00360 option=GetImageOption(image_info,"quantum:minimum");
00361 if (option != (char *) NULL)
00362 quantum_info->minimum=atof(option);
00363 option=GetImageOption(image_info,"quantum:maximum");
00364 if (option != (char *) NULL)
00365 quantum_info->maximum=atof(option);
00366 if ((quantum_info->minimum == 0.0) && (quantum_info->maximum == 0.0))
00367 quantum_info->scale=0.0;
00368 else
00369 if (quantum_info->minimum == quantum_info->maximum)
00370 {
00371 quantum_info->scale=(MagickRealType) QuantumRange/quantum_info->minimum;
00372 quantum_info->minimum=0.0;
00373 }
00374 else
00375 quantum_info->scale=(MagickRealType) QuantumRange/(quantum_info->maximum-
00376 quantum_info->minimum);
00377 option=GetImageOption(image_info,"quantum:scale");
00378 if (option != (char *) NULL)
00379 quantum_info->scale=atof(option);
00380 option=GetImageOption(image_info,"quantum:polarity");
00381 if (option != (char *) NULL)
00382 quantum_info->min_is_white=LocaleCompare(option,"min-is-white") == 0 ?
00383 MagickTrue : MagickFalse;
00384 }
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 MagickExport unsigned char *GetQuantumPixels(const QuantumInfo *quantum_info)
00410 {
00411 long
00412 id;
00413
00414 assert(quantum_info != (QuantumInfo *) NULL);
00415 assert(quantum_info->signature == MagickSignature);
00416 id=GetPixelCacheThreadId();
00417 return(quantum_info->pixels[id]);
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 MagickExport QuantumType GetQuantumType(Image *image,ExceptionInfo *exception)
00443 {
00444 QuantumType
00445 quantum_type;
00446
00447 assert(image != (Image *) NULL);
00448 assert(image->signature == MagickSignature);
00449 if (image->debug != MagickFalse)
00450 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00451 quantum_type=RGBQuantum;
00452 if (image->matte != MagickFalse)
00453 quantum_type=RGBAQuantum;
00454 if (image->colorspace == CMYKColorspace)
00455 {
00456 quantum_type=CMYKQuantum;
00457 if (image->matte != MagickFalse)
00458 quantum_type=CMYKAQuantum;
00459 }
00460 if (IsGrayImage(image,exception) != MagickFalse)
00461 {
00462 quantum_type=GrayQuantum;
00463 if (image->matte != MagickFalse)
00464 quantum_type=GrayAlphaQuantum;
00465 }
00466 else
00467 if (image->storage_class == PseudoClass)
00468 {
00469 quantum_type=IndexQuantum;
00470 if (image->matte != MagickFalse)
00471 quantum_type=IndexAlphaQuantum;
00472 }
00473 return(quantum_type);
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 MagickExport void SetQuantumAlphaType(QuantumInfo *quantum_info,
00502 const QuantumAlphaType type)
00503 {
00504 assert(quantum_info != (QuantumInfo *) NULL);
00505 assert(quantum_info->signature == MagickSignature);
00506 quantum_info->alpha_type=type;
00507 }
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536 MagickExport MagickBooleanType SetQuantumDepth(const Image *image,
00537 QuantumInfo *quantum_info,const unsigned long depth)
00538 {
00539 MagickBooleanType
00540 status;
00541
00542
00543
00544
00545 assert(image != (Image *) NULL);
00546 assert(image->signature == MagickSignature);
00547 if (image->debug != MagickFalse)
00548 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00549 assert(quantum_info != (QuantumInfo *) NULL);
00550 assert(quantum_info->signature == MagickSignature);
00551 quantum_info->depth=depth;
00552 if (quantum_info->format == FloatingPointQuantumFormat)
00553 {
00554 if (quantum_info->depth > 32)
00555 quantum_info->depth=64;
00556 else
00557 quantum_info->depth=32;
00558 }
00559 if (quantum_info->pixels != (unsigned char **) NULL)
00560 DestroyQuantumPixels(quantum_info);
00561 status=AcquireQuantumPixels(quantum_info,(quantum_info->pad+5)*image->columns*
00562 ((quantum_info->depth+7)/8));
00563 return(status);
00564 }
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593 MagickExport MagickBooleanType SetQuantumFormat(const Image *image,
00594 QuantumInfo *quantum_info,const QuantumFormatType format)
00595 {
00596 assert(image != (Image *) NULL);
00597 assert(image->signature == MagickSignature);
00598 if (image->debug != MagickFalse)
00599 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00600 assert(quantum_info != (QuantumInfo *) NULL);
00601 assert(quantum_info->signature == MagickSignature);
00602 quantum_info->format=format;
00603 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
00604 }
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 MagickExport void SetQuantumImageType(Image *image,
00633 const QuantumType quantum_type)
00634 {
00635 assert(image != (Image *) NULL);
00636 assert(image->signature == MagickSignature);
00637 if (image->debug != MagickFalse)
00638 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00639 switch (quantum_type)
00640 {
00641 case IndexQuantum:
00642 case IndexAlphaQuantum:
00643 {
00644 image->type=PaletteType;
00645 break;
00646 }
00647 case GrayQuantum:
00648 case GrayAlphaQuantum:
00649 {
00650 image->type=GrayscaleType;
00651 if (image->depth == 1)
00652 image->type=BilevelType;
00653 break;
00654 }
00655 case CyanQuantum:
00656 case MagentaQuantum:
00657 case YellowQuantum:
00658 case BlackQuantum:
00659 case CMYKQuantum:
00660 case CMYKAQuantum:
00661 {
00662 image->type=ColorSeparationType;
00663 break;
00664 }
00665 default:
00666 {
00667 image->type=TrueColorType;
00668 break;
00669 }
00670 }
00671 }
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698 MagickExport void SetQuantumPack(QuantumInfo *quantum_info,
00699 const MagickBooleanType pack)
00700 {
00701 assert(quantum_info != (QuantumInfo *) NULL);
00702 assert(quantum_info->signature == MagickSignature);
00703 quantum_info->pack=pack;
00704 }
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734 MagickExport MagickBooleanType SetQuantumPad(const Image *image,
00735 QuantumInfo *quantum_info,const unsigned long pad)
00736 {
00737 assert(image != (Image *) NULL);
00738 assert(image->signature == MagickSignature);
00739 if (image->debug != MagickFalse)
00740 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00741 assert(quantum_info != (QuantumInfo *) NULL);
00742 assert(quantum_info->signature == MagickSignature);
00743 quantum_info->pad=pad;
00744 return(SetQuantumDepth(image,quantum_info,quantum_info->depth));
00745 }
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772 MagickExport void SetQuantumMinIsWhite(QuantumInfo *quantum_info,
00773 const MagickBooleanType min_is_white)
00774 {
00775 assert(quantum_info != (QuantumInfo *) NULL);
00776 assert(quantum_info->signature == MagickSignature);
00777 quantum_info->min_is_white=min_is_white;
00778 }
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805 MagickExport void SetQuantumQuantum(QuantumInfo *quantum_info,
00806 const unsigned long quantum)
00807 {
00808 assert(quantum_info != (QuantumInfo *) NULL);
00809 assert(quantum_info->signature == MagickSignature);
00810 quantum_info->quantum=quantum;
00811 }
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837 MagickExport void SetQuantumScale(QuantumInfo *quantum_info,const double scale)
00838 {
00839 assert(quantum_info != (QuantumInfo *) NULL);
00840 assert(quantum_info->signature == MagickSignature);
00841 quantum_info->scale=scale;
00842 }