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
00042
00043 #include "magick/studio.h"
00044 #include "magick/blob.h"
00045 #include "magick/blob-private.h"
00046 #include "magick/cache.h"
00047 #include "magick/cache-private.h"
00048 #include "magick/color-private.h"
00049 #include "magick/composite-private.h"
00050 #include "magick/exception.h"
00051 #include "magick/exception-private.h"
00052 #include "magick/list.h"
00053 #include "magick/log.h"
00054 #include "magick/magick.h"
00055 #include "magick/memory_.h"
00056 #include "magick/pixel-private.h"
00057 #include "magick/quantum.h"
00058 #include "magick/random_.h"
00059 #include "magick/resource_.h"
00060 #include "magick/semaphore.h"
00061 #include "magick/splay-tree.h"
00062 #include "magick/string_.h"
00063 #include "magick/utility.h"
00064 #if defined(MAGICKCORE_ZLIB_DELEGATE)
00065 #include "zlib.h"
00066 #endif
00067 #if defined(MAGICKCORE_HAVE_PTHREAD)
00068 #include <pthread.h>
00069 #endif
00070 #if defined(__WINDOWS__)
00071 #include <windows.h>
00072 #endif
00073
00074
00075
00076
00077 struct _NexusInfo
00078 {
00079 MagickBooleanType
00080 reserve,
00081 mapped;
00082
00083 RectangleInfo
00084 region;
00085
00086 MagickSizeType
00087 length;
00088
00089 PixelPacket
00090 *cache,
00091 *pixels;
00092
00093 IndexPacket
00094 *indexes;
00095
00096 unsigned long
00097 signature;
00098 };
00099
00100
00101
00102
00103 #if defined(__cplusplus) || defined(c_plusplus)
00104 extern "C" {
00105 #endif
00106
00107 static const PixelPacket
00108 *AcquirePixelCache(const Image *,const VirtualPixelMethod,const long,
00109 const long,const unsigned long,const unsigned long,ExceptionInfo *);
00110
00111 static IndexPacket
00112 *GetIndexesFromCache(const Image *);
00113
00114 static MagickBooleanType
00115 GetOneVirtualPixelFromCache(const Image *,const VirtualPixelMethod,
00116 const long,const long,PixelPacket *,ExceptionInfo *),
00117 GetOneAuthenticPixelFromCache(Image *,const long,const long,PixelPacket *,
00118 ExceptionInfo *),
00119 OpenCache(Image *,const MapMode,ExceptionInfo *),
00120 SyncCache(Image *,ExceptionInfo *),
00121 SyncPixelCache(Image *,ExceptionInfo *),
00122 SyncImagePixelCache(Image *,ExceptionInfo *);
00123
00124 static PixelPacket
00125 *GetPixelCache(Image *,const long,const long,const unsigned long,
00126 const unsigned long,ExceptionInfo *),
00127 *GetPixelsFromCache(const Image *),
00128 *SetPixelCache(Image *,const long,const long,const unsigned long,
00129 const unsigned long,ExceptionInfo *);
00130
00131 static void
00132 DestroyPixelCache(Image *);
00133
00134 #if defined(__cplusplus) || defined(c_plusplus)
00135 }
00136 #endif
00137
00138
00139
00140
00141 static PixelPacket
00142 *SetNexus(const Image *,const RectangleInfo *,NexusInfo *);
00143
00144 static MagickBooleanType
00145 ReadCacheIndexes(CacheInfo *,NexusInfo *,ExceptionInfo *),
00146 ReadCachePixels(CacheInfo *,NexusInfo *,ExceptionInfo *),
00147 WriteCacheIndexes(CacheInfo *,NexusInfo *,ExceptionInfo *),
00148 WriteCachePixels(CacheInfo *,NexusInfo *,ExceptionInfo *);
00149
00150
00151
00152
00153 static volatile MagickBooleanType
00154 instantiate_cache = MagickFalse;
00155
00156 static SemaphoreInfo
00157 *cache_semaphore = (SemaphoreInfo *) NULL;
00158
00159 static SplayTreeInfo
00160 *cache_resources = (SplayTreeInfo *) NULL;
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 static long
00200 DitherMatrix[64] =
00201 {
00202 0, 48, 12, 60, 3, 51, 15, 63,
00203 32, 16, 44, 28, 35, 19, 47, 31,
00204 8, 56, 4, 52, 11, 59, 7, 55,
00205 40, 24, 36, 20, 43, 27, 39, 23,
00206 2, 50, 14, 62, 1, 49, 13, 61,
00207 34, 18, 46, 30, 33, 17, 45, 29,
00208 10, 58, 6, 54, 9, 57, 5, 53,
00209 42, 26, 38, 22, 41, 25, 37, 21
00210 };
00211
00212 static inline long DitherX(const unsigned long columns,const long x)
00213 {
00214 long
00215 index;
00216
00217 index=x+DitherMatrix[x & 0x07]-32L;
00218 if (index < 0L)
00219 return(0L);
00220 if (index >= (long) columns)
00221 return((long) columns-1L);
00222 return(index);
00223 }
00224
00225 static inline long DitherY(const unsigned long rows,const long y)
00226 {
00227 long
00228 index;
00229
00230 index=y+DitherMatrix[y & 0x07]-32L;
00231 if (index < 0L)
00232 return(0L);
00233 if (index >= (long) rows)
00234 return((long) rows-1L);
00235 return(index);
00236 }
00237
00238 static inline long EdgeX(const unsigned long columns,const long x)
00239 {
00240 if (x < 0L)
00241 return(0L);
00242 if (x >= (long) columns)
00243 return((long) columns-1L);
00244 return(x);
00245 }
00246
00247 static inline long EdgeY(const unsigned long rows,const long y)
00248 {
00249 if (y < 0L)
00250 return(0L);
00251 if (y >= (long) rows)
00252 return((long) rows-1L);
00253 return(y);
00254 }
00255
00256 static inline MagickSizeType MagickMax(const MagickSizeType x,
00257 const MagickSizeType y)
00258 {
00259 if (x > y)
00260 return(x);
00261 return(y);
00262 }
00263
00264 static inline MagickSizeType MagickMin(const MagickSizeType x,
00265 const MagickSizeType y)
00266 {
00267 if (x < y)
00268 return(x);
00269 return(y);
00270 }
00271
00272
00273 static inline long RandomX(const unsigned long columns)
00274 {
00275 long
00276 x;
00277
00278 x=(long) (columns*GetPseudoRandomValue()+0.5);
00279 if (x >= (long) columns)
00280 return((long) columns-1L);
00281 return(x);
00282 }
00283
00284 static inline long RandomY(const unsigned long rows)
00285 {
00286 long
00287 y;
00288
00289 y=(long) (rows*GetPseudoRandomValue()+0.5);
00290 if (y >= (long) rows)
00291 return((long) rows-1L);
00292 return(y);
00293 }
00294
00295 static inline long TileX(const unsigned long columns,const long x)
00296 {
00297 if (x < 0L)
00298 return((long) columns+((x+1) % (long) columns)-1);
00299 if (x >= (long) columns)
00300 return(x % (long) columns);
00301 return(x);
00302 }
00303
00304 static inline long TileY(const unsigned long rows,const long y)
00305 {
00306 if (y < 0L)
00307 return((long) rows+((y+1) % (long) rows)-1L);
00308 if (y >= (long) rows)
00309 return(y % (long) rows);
00310 return(y);
00311 }
00312
00313 static inline long MirrorX(const unsigned long columns,const long x)
00314 {
00315 if ((x < 0) || (x >= (long) columns))
00316 return((long) columns-TileX(columns,x)-1L);
00317 return(x);
00318 }
00319
00320 static inline long MirrorY(const unsigned long rows,const long y)
00321 {
00322 if ((y < 0) || (y >= (long) rows))
00323 return((long) rows-TileX(rows,y)-1L);
00324 return(y);
00325 }
00326
00327 static inline MagickBooleanType IsNexusInCore(const CacheInfo *cache_info,
00328 NexusInfo *nexus_info)
00329 {
00330 MagickOffsetType
00331 offset;
00332
00333 offset=(MagickOffsetType) nexus_info->region.y*cache_info->columns+
00334 nexus_info->region.x;
00335 if (nexus_info->pixels != (cache_info->pixels+offset))
00336 return(MagickFalse);
00337 return(MagickTrue);
00338 }
00339
00340 MagickExport const PixelPacket *AcquireCacheNexus(const Image *image,
00341 const VirtualPixelMethod virtual_pixel_method,const long x,const long y,
00342 const unsigned long columns,const unsigned long rows,NexusInfo *nexus_info,
00343 ExceptionInfo *exception)
00344 {
00345 CacheInfo
00346 *cache_info;
00347
00348 IndexPacket
00349 *indexes;
00350
00351 MagickOffsetType
00352 offset;
00353
00354 MagickSizeType
00355 length,
00356 number_pixels;
00357
00358 NexusInfo
00359 *virtual_nexus;
00360
00361 PixelPacket
00362 *pixels;
00363
00364 RectangleInfo
00365 region;
00366
00367 register const IndexPacket
00368 *nexus_indexes;
00369
00370 register const PixelPacket
00371 *p;
00372
00373 register long
00374 u,
00375 v;
00376
00377 register PixelPacket
00378 *q;
00379
00380
00381
00382
00383 if (image->debug != MagickFalse)
00384 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00385 cache_info=(CacheInfo *) image->cache;
00386 if (cache_info->type == UndefinedCache)
00387 return((const PixelPacket *) NULL);
00388 region.x=x;
00389 region.y=y;
00390 region.width=columns;
00391 region.height=rows;
00392 pixels=SetNexus(image,®ion,nexus_info);
00393 if (pixels == (PixelPacket *) NULL)
00394 return((const PixelPacket *) NULL);
00395 offset=(MagickOffsetType) region.y*cache_info->columns+region.x;
00396 length=(MagickSizeType) (region.height-1)*cache_info->columns+region.width-1;
00397 number_pixels=(MagickSizeType) cache_info->columns*cache_info->rows;
00398 if ((offset >= 0) && (((MagickSizeType) offset+length) < number_pixels))
00399 if ((x >= 0) && ((long) (x+columns) <= (long) cache_info->columns) &&
00400 (y >= 0) && ((long) (y+rows) <= (long) cache_info->rows))
00401 {
00402
00403
00404
00405 if (IsNexusInCore(cache_info,nexus_info) != MagickFalse)
00406 return(pixels);
00407 if (ReadCachePixels(cache_info,nexus_info,exception) == MagickFalse)
00408 return((const PixelPacket *) NULL);
00409 if ((cache_info->storage_class == PseudoClass) ||
00410 (cache_info->colorspace == CMYKColorspace))
00411 if (ReadCacheIndexes(cache_info,nexus_info,exception) == MagickFalse)
00412 return((const PixelPacket *) NULL);
00413 return(pixels);
00414 }
00415
00416
00417
00418 q=pixels;
00419 indexes=GetNexusIndexes(cache_info,nexus_info);
00420 virtual_nexus=AcquireNexusInfo();
00421 if (virtual_nexus == (NexusInfo *) NULL)
00422 {
00423 (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
00424 "UnableToGetCacheNexus","`%s'",image->filename);
00425 return((const PixelPacket *) NULL);
00426 }
00427 for (v=0; v < (long) rows; v++)
00428 {
00429 for (u=0; u < (long) columns; u+=length)
00430 {
00431 length=(MagickSizeType) MagickMin(cache_info->columns-(x+u),columns-u);
00432 if ((((x+u) < 0) || ((x+u) >= (long) cache_info->columns)) ||
00433 (((y+v) < 0) || ((y+v) >= (long) cache_info->rows)) || (length == 0))
00434 {
00435
00436
00437
00438 length=(MagickSizeType) 1;
00439 switch (virtual_pixel_method)
00440 {
00441 case BackgroundVirtualPixelMethod:
00442 case ConstantVirtualPixelMethod:
00443 {
00444 p=AcquireCacheNexus(image,virtual_pixel_method,
00445 EdgeX(cache_info->columns,x+u),EdgeY(cache_info->rows,y+v),
00446 1UL,1UL,virtual_nexus,exception);
00447 cache_info->virtual_pixel=image->background_color;
00448 p=(&cache_info->virtual_pixel);
00449 break;
00450 }
00451 case BlackVirtualPixelMethod:
00452 {
00453 p=AcquireCacheNexus(image,virtual_pixel_method,
00454 EdgeX(cache_info->columns,x+u),EdgeY(cache_info->rows,y+v),
00455 1UL,1UL,virtual_nexus,exception);
00456 cache_info->virtual_pixel.red=0;
00457 cache_info->virtual_pixel.green=0;
00458 cache_info->virtual_pixel.blue=0;
00459 cache_info->virtual_pixel.opacity=OpaqueOpacity;
00460 p=(&cache_info->virtual_pixel);
00461 break;
00462 }
00463 case DitherVirtualPixelMethod:
00464 {
00465 p=AcquireCacheNexus(image,virtual_pixel_method,
00466 DitherX(cache_info->columns,x+u),DitherY(cache_info->rows,y+v),
00467 1UL,1UL,virtual_nexus,exception);
00468 break;
00469 }
00470 case EdgeVirtualPixelMethod:
00471 default:
00472 {
00473 p=AcquireCacheNexus(image,virtual_pixel_method,
00474 EdgeX(cache_info->columns,x+u),EdgeY(cache_info->rows,y+v),
00475 1UL,1UL,virtual_nexus,exception);
00476 break;
00477 }
00478 case GrayVirtualPixelMethod:
00479 {
00480 p=AcquireCacheNexus(image,virtual_pixel_method,
00481 EdgeX(cache_info->columns,x+u),EdgeY(cache_info->rows,y+v),
00482 1UL,1UL,virtual_nexus,exception);
00483 cache_info->virtual_pixel.red=(Quantum) QuantumRange/2;
00484 cache_info->virtual_pixel.green=(Quantum) QuantumRange/2;
00485 cache_info->virtual_pixel.blue=(Quantum) QuantumRange/2;
00486 cache_info->virtual_pixel.opacity=(Quantum) OpaqueOpacity;
00487 p=(&cache_info->virtual_pixel);
00488 break;
00489 }
00490 case HorizontalTileVirtualPixelMethod:
00491 {
00492 p=AcquireCacheNexus(image,virtual_pixel_method,
00493 TileX(cache_info->columns,x+u),TileY(cache_info->rows,y+v),
00494 1UL,1UL,virtual_nexus,exception);
00495 if (((y+v) < 0) || ((y+v) >= (long) cache_info->rows))
00496 {
00497 cache_info->virtual_pixel=image->background_color;
00498 p=(&cache_info->virtual_pixel);
00499 }
00500 break;
00501 }
00502 case MirrorVirtualPixelMethod:
00503 {
00504 p=AcquireCacheNexus(image,virtual_pixel_method,
00505 MirrorX(cache_info->columns,x+u),MirrorY(cache_info->rows,y+v),
00506 1UL,1UL,virtual_nexus,exception);
00507 break;
00508 }
00509 case RandomVirtualPixelMethod:
00510 {
00511 p=AcquireCacheNexus(image,virtual_pixel_method,
00512 RandomX(cache_info->columns),RandomY(cache_info->rows),
00513 1UL,1UL,virtual_nexus,exception);
00514 break;
00515 }
00516 case TileVirtualPixelMethod:
00517 {
00518 p=AcquireCacheNexus(image,virtual_pixel_method,
00519 TileX(cache_info->columns,x+u),TileY(cache_info->rows,y+v),
00520 1UL,1UL,virtual_nexus,exception);
00521 break;
00522 }
00523 case TransparentVirtualPixelMethod:
00524 {
00525 p=AcquireCacheNexus(image,virtual_pixel_method,
00526 EdgeX(cache_info->columns,x+u),EdgeY(cache_info->rows,y+v),
00527 1UL,1UL,virtual_nexus,exception);
00528 cache_info->virtual_pixel.red=(Quantum) 0;
00529 cache_info->virtual_pixel.green=(Quantum) 0;
00530 cache_info->virtual_pixel.blue=(Quantum) 0;
00531 cache_info->virtual_pixel.opacity=(Quantum) TransparentOpacity;
00532 p=(&cache_info->virtual_pixel);
00533 break;
00534 }
00535 case VerticalTileVirtualPixelMethod:
00536 {
00537 p=AcquireCacheNexus(image,virtual_pixel_method,
00538 TileX(cache_info->columns,x+u),TileY(cache_info->rows,y+v),
00539 1UL,1UL,virtual_nexus,exception);
00540 if (((x+u) < 0) || ((x+u) >= (long) cache_info->columns))
00541 {
00542 cache_info->virtual_pixel=image->background_color;
00543 p=(&cache_info->virtual_pixel);
00544 }
00545 break;
00546 }
00547 case MaskVirtualPixelMethod:
00548 case WhiteVirtualPixelMethod:
00549 {
00550 p=AcquireCacheNexus(image,virtual_pixel_method,
00551 EdgeX(cache_info->columns,x+u),EdgeY(cache_info->rows,y+v),
00552 1UL,1UL,virtual_nexus,exception);
00553 cache_info->virtual_pixel.red=(Quantum) QuantumRange;
00554 cache_info->virtual_pixel.green=(Quantum) QuantumRange;
00555 cache_info->virtual_pixel.blue=(Quantum) QuantumRange;
00556 cache_info->virtual_pixel.opacity=OpaqueOpacity;
00557 p=(&cache_info->virtual_pixel);
00558 break;
00559 }
00560 }
00561 if (p == (const PixelPacket *) NULL)
00562 break;
00563 *q++=(*p);
00564 if (indexes != (IndexPacket *) NULL)
00565 {
00566 nexus_indexes=AcquireNexusIndexes(cache_info,virtual_nexus);
00567 if (nexus_indexes != (const IndexPacket *) NULL)
00568 *indexes++=(*nexus_indexes);
00569 }
00570 continue;
00571 }
00572
00573
00574
00575 p=AcquireCacheNexus(image,virtual_pixel_method,x+u,y+v,(unsigned long)
00576 length,1UL,virtual_nexus,exception);
00577 if (p == (const PixelPacket *) NULL)
00578 break;
00579 (void) CopyMagickMemory(q,p,(size_t) length*sizeof(*p));
00580 q+=length;
00581 if (indexes != (IndexPacket *) NULL)
00582 {
00583 nexus_indexes=AcquireNexusIndexes(cache_info,virtual_nexus);
00584 if (nexus_indexes != (const IndexPacket *) NULL)
00585 {
00586 (void) CopyMagickMemory(indexes,nexus_indexes,(size_t) length*
00587 sizeof(*nexus_indexes));
00588 indexes+=length;
00589 }
00590 }
00591 }
00592 }
00593 virtual_nexus=DestroyNexusInfo(virtual_nexus);
00594 return(pixels);
00595 }
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621 static inline long GetNexusInfoThreadId(void)
00622 {
00623 #if defined(MAGICKCORE_OPENMP_SUPPORT)
00624 return(omp_get_thread_num());
00625 #else
00626 return(0);
00627 #endif
00628 }
00629
00630 static const IndexPacket *AcquireIndexesFromCache(const Image *image)
00631 {
00632 CacheInfo
00633 *cache_info;
00634
00635 const IndexPacket
00636 *indexes;
00637
00638 long
00639 id;
00640
00641 if (image->debug != MagickFalse)
00642 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00643 cache_info=(CacheInfo *) image->cache;
00644 id=GetNexusInfoThreadId();
00645 indexes=AcquireNexusIndexes(image->cache,cache_info->nexus_info[id]);
00646 return(indexes);
00647 }
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675 static const PixelPacket *AcquirePixelsFromCache(const Image *image)
00676 {
00677 CacheInfo
00678 *cache_info;
00679
00680 const PixelPacket
00681 *pixels;
00682
00683 long
00684 id;
00685
00686 if (image->debug != MagickFalse)
00687 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00688 cache_info=(CacheInfo *) image->cache;
00689 id=GetNexusInfoThreadId();
00690 pixels=AcquireNexusPixels(image->cache,cache_info->nexus_info[id]);
00691 return(pixels);
00692 }
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 MagickExport const IndexPacket *AcquireNexusIndexes(const Cache cache,
00721 NexusInfo *nexus_info)
00722 {
00723 CacheInfo
00724 *cache_info;
00725
00726 if (cache == (Cache) NULL)
00727 return((IndexPacket *) NULL);
00728 cache_info=(CacheInfo *) cache;
00729 assert(cache_info->signature == MagickSignature);
00730 if (cache_info->storage_class == UndefinedClass)
00731 return((IndexPacket *) NULL);
00732 return(nexus_info->indexes);
00733 }
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753 MagickExport NexusInfo *AcquireNexusInfo(void)
00754 {
00755 NexusInfo
00756 *nexus_info;
00757
00758 nexus_info=(NexusInfo *) AcquireMagickMemory(sizeof(*nexus_info));
00759 if (nexus_info == (NexusInfo *) NULL)
00760 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00761 (void) ResetMagickMemory(nexus_info,0,sizeof(*nexus_info));
00762 nexus_info->signature=MagickSignature;
00763 return(nexus_info);
00764 }
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789 MagickExport NexusInfo **AcquireNexusInfoThreadSet(const unsigned long nexuses)
00790 {
00791 register long
00792 i;
00793
00794 NexusInfo
00795 **nexus_info;
00796
00797 nexus_info=(NexusInfo **) AcquireQuantumMemory(nexuses,sizeof(**nexus_info));
00798 if (nexus_info == (NexusInfo **) NULL)
00799 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00800 for (i=0; i < (long) nexuses; i++)
00801 nexus_info[i]=AcquireNexusInfo();
00802 return(nexus_info);
00803 }
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831 MagickExport const PixelPacket *AcquireNexusPixels(const Cache cache,
00832 NexusInfo *nexus_info)
00833 {
00834 CacheInfo
00835 *cache_info;
00836
00837 if (cache == (Cache) NULL)
00838 return((PixelPacket *) NULL);
00839 cache_info=(CacheInfo *) cache;
00840 assert(cache_info->signature == MagickSignature);
00841 if (cache_info->storage_class == UndefinedClass)
00842 return((PixelPacket *) NULL);
00843 return((const PixelPacket *) nexus_info->pixels);
00844 }
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880 static const PixelPacket *AcquirePixelCache(const Image *image,
00881 const VirtualPixelMethod virtual_pixel_method,const long x,const long y,
00882 const unsigned long columns,const unsigned long rows,ExceptionInfo *exception)
00883 {
00884 CacheInfo
00885 *cache_info;
00886
00887 const PixelPacket
00888 *pixels;
00889
00890 long
00891 id;
00892
00893 if (image->debug != MagickFalse)
00894 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00895 cache_info=(CacheInfo *) image->cache;
00896 id=GetNexusInfoThreadId();
00897 pixels=AcquireCacheNexus(image,virtual_pixel_method,x,y,columns,rows,
00898 cache_info->nexus_info[id],exception);
00899 return(pixels);
00900 }
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928 static MagickBooleanType ClipCacheNexus(Image *image,
00929 NexusInfo *nexus_info)
00930 {
00931 CacheInfo
00932 *cache_info;
00933
00934 MagickSizeType
00935 number_pixels;
00936
00937 NexusInfo
00938 *clip_nexus,
00939 *image_nexus;
00940
00941 register const PixelPacket
00942 *r;
00943
00944 register IndexPacket
00945 *nexus_indexes,
00946 *indexes;
00947
00948 register long
00949 i;
00950
00951 register PixelPacket
00952 *p,
00953 *q;
00954
00955
00956
00957
00958 if (image->debug != MagickFalse)
00959 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00960 if (image->clip_mask == (Image *) NULL)
00961 return(MagickFalse);
00962 cache_info=(CacheInfo *) image->cache;
00963 image_nexus=AcquireNexusInfo();
00964 clip_nexus=AcquireNexusInfo();
00965 if ((image_nexus == (NexusInfo *) NULL) || (clip_nexus == (NexusInfo *) NULL))
00966 ThrowBinaryException(CacheError,"UnableToGetCacheNexus",image->filename);
00967 p=GetCacheNexus(image,nexus_info->region.x,nexus_info->region.y,
00968 nexus_info->region.width,nexus_info->region.height,image_nexus,
00969 &image->exception);
00970 indexes=GetNexusIndexes(image->cache,image_nexus);
00971 q=nexus_info->pixels;
00972 nexus_indexes=nexus_info->indexes;
00973 r=AcquireCacheNexus(image->clip_mask,MaskVirtualPixelMethod,
00974 nexus_info->region.x,nexus_info->region.y,nexus_info->region.width,
00975 nexus_info->region.height,clip_nexus,&image->exception);
00976 number_pixels=(MagickSizeType) nexus_info->region.width*
00977 nexus_info->region.height;
00978 for (i=0; i < (long) number_pixels; i++)
00979 {
00980 if ((p == (PixelPacket *) NULL) || (r == (const PixelPacket *) NULL))
00981 break;
00982 if (PixelIntensityToQuantum(r) > ((Quantum) QuantumRange/2))
00983 {
00984 q->red=p->red;
00985 q->green=p->green;
00986 q->blue=p->blue;
00987 q->opacity=p->opacity;
00988 if ((cache_info->storage_class == PseudoClass) ||
00989 (cache_info->colorspace == CMYKColorspace))
00990 nexus_indexes[i]=indexes[i];
00991 }
00992 p++;
00993 q++;
00994 r++;