1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3%                                                                             %
4%                                                                             %
5%                                                                             %
6%                      CCCC   AAA    CCCC  H   H  EEEEE                       %
7%                     C      A   A  C      H   H  E                           %
8%                     C      AAAAA  C      HHHHH  EEE                         %
9%                     C      A   A  C      H   H  E                           %
10%                      CCCC  A   A   CCCC  H   H  EEEEE                       %
11%                                                                             %
12%                        V   V  IIIII  EEEEE  W   W                           %
13%                        V   V    I    E      W   W                           %
14%                        V   V    I    EEE    W W W                           %
15%                         V V     I    E      WW WW                           %
16%                          V    IIIII  EEEEE  W   W                           %
17%                                                                             %
18%                                                                             %
19%                        MagickCore Cache View Methods                        %
20%                                                                             %
21%                              Software Design                                %
22%                                   Cristy                                    %
23%                               February 2000                                 %
24%                                                                             %
25%                                                                             %
26%  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
27%  dedicated to making software imaging solutions freely available.           %
28%                                                                             %
29%  You may not use this file except in compliance with the License.  You may  %
30%  obtain a copy of the License at                                            %
31%                                                                             %
32%    http://www.imagemagick.org/script/license.php                            %
33%                                                                             %
34%  Unless required by applicable law or agreed to in writing, software        %
35%  distributed under the License is distributed on an "AS IS" BASIS,          %
36%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
37%  See the License for the specific language governing permissions and        %
38%  limitations under the License.                                             %
39%                                                                             %
40%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41%
42%
43%
44*/
45
46/*
47  Include declarations.
48*/
49#include "MagickCore/studio.h"
50#include "MagickCore/cache.h"
51#include "MagickCore/cache-private.h"
52#include "MagickCore/cache-view.h"
53#include "MagickCore/memory_.h"
54#include "MagickCore/memory-private.h"
55#include "MagickCore/exception.h"
56#include "MagickCore/exception-private.h"
57#include "MagickCore/pixel-accessor.h"
58#include "MagickCore/resource_.h"
59#include "MagickCore/string_.h"
60#include "MagickCore/thread-private.h"
61
62/*
63  Typedef declarations.
64*/
65struct _CacheView
66{
67  Image
68    *image;
69
70  VirtualPixelMethod
71    virtual_pixel_method;
72
73  size_t
74    number_threads;
75
76  NexusInfo
77    **nexus_info;
78
79  MagickBooleanType
80    debug;
81
82  size_t
83    signature;
84};
85
86/*
87%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
88%                                                                             %
89%                                                                             %
90%                                                                             %
91%   A c q u i r e A u t h e n t i c C a c h e V i e w                         %
92%                                                                             %
93%                                                                             %
94%                                                                             %
95%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
96%
97%  AcquireAuthenticCacheView() acquires an authentic view into the pixel cache.
98%  It always succeeds but may return a warning or informational exception.
99%
100%  The format of the AcquireAuthenticCacheView method is:
101%
102%      CacheView *AcquireAuthenticCacheView(const Image *image,
103%        ExceptionInfo *exception)
104%
105%  A description of each parameter follows:
106%
107%    o image: the image.
108%
109%    o exception: return any errors or warnings in this structure.
110%
111*/
112MagickExport CacheView *AcquireAuthenticCacheView(const Image *image,
113  ExceptionInfo *exception)
114{
115  CacheView
116    *magick_restrict cache_view;
117
118  cache_view=AcquireVirtualCacheView(image,exception);
119  return(cache_view);
120}
121
122/*
123%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
124%                                                                             %
125%                                                                             %
126%                                                                             %
127%   A c q u i r e V i r t u a l C a c h e V i e w                             %
128%                                                                             %
129%                                                                             %
130%                                                                             %
131%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
132%
133%  AcquireVirtualCacheView() acquires a virtual view into the pixel cache,
134%  using the VirtualPixelMethod that is defined within the given image itself.
135%  It always succeeds but may return a warning or informational exception.
136%
137%  The format of the AcquireVirtualCacheView method is:
138%
139%      CacheView *AcquireVirtualCacheView(const Image *image,
140%        ExceptionInfo *exception)
141%
142%  A description of each parameter follows:
143%
144%    o image: the image.
145%
146%    o exception: return any errors or warnings in this structure.
147%
148*/
149MagickExport CacheView *AcquireVirtualCacheView(const Image *image,
150  ExceptionInfo *exception)
151{
152  CacheView
153    *magick_restrict cache_view;
154
155  magick_unreferenced(exception);
156  assert(image != (Image *) NULL);
157  assert(image->signature == MagickCoreSignature);
158  if (image->debug != MagickFalse)
159    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
160#if defined(MAGICKCORE_OPENCL_SUPPORT)
161  SyncAuthenticOpenCLBuffer(image);
162#endif
163  cache_view=(CacheView *) MagickAssumeAligned(AcquireAlignedMemory(1,
164    sizeof(*cache_view)));
165  if (cache_view == (CacheView *) NULL)
166    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
167  (void) ResetMagickMemory(cache_view,0,sizeof(*cache_view));
168  cache_view->image=ReferenceImage((Image *) image);
169  cache_view->number_threads=GetOpenMPMaximumThreads();
170  if (GetMagickResourceLimit(ThreadResource) > cache_view->number_threads)
171    cache_view->number_threads=(size_t) GetMagickResourceLimit(ThreadResource);
172  if (cache_view->number_threads == 0)
173    cache_view->number_threads=1;
174  cache_view->nexus_info=AcquirePixelCacheNexus(cache_view->number_threads);
175  cache_view->virtual_pixel_method=GetImageVirtualPixelMethod(image);
176  cache_view->debug=IsEventLogging();
177  cache_view->signature=MagickCoreSignature;
178  if (cache_view->nexus_info == (NexusInfo **) NULL)
179    ThrowFatalException(CacheFatalError,"UnableToAcquireCacheView");
180  return(cache_view);
181}
182
183/*
184%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
185%                                                                             %
186%                                                                             %
187%                                                                             %
188%   C l o n e C a c h e V i e w                                               %
189%                                                                             %
190%                                                                             %
191%                                                                             %
192%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
193%
194%  CloneCacheView()  makes an exact copy of the specified cache view.
195%
196%  The format of the CloneCacheView method is:
197%
198%      CacheView *CloneCacheView(const CacheView *cache_view)
199%
200%  A description of each parameter follows:
201%
202%    o cache_view: the cache view.
203%
204*/
205MagickExport CacheView *CloneCacheView(const CacheView *cache_view)
206{
207  CacheView
208    *magick_restrict clone_view;
209
210  assert(cache_view != (CacheView *) NULL);
211  assert(cache_view->signature == MagickCoreSignature);
212  if (cache_view->debug != MagickFalse)
213    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
214      cache_view->image->filename);
215  clone_view=(CacheView *) MagickAssumeAligned(AcquireAlignedMemory(1,
216    sizeof(*clone_view)));
217  if (clone_view == (CacheView *) NULL)
218    ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
219  (void) ResetMagickMemory(clone_view,0,sizeof(*clone_view));
220  clone_view->image=ReferenceImage(cache_view->image);
221  clone_view->number_threads=cache_view->number_threads;
222  clone_view->nexus_info=AcquirePixelCacheNexus(cache_view->number_threads);
223  clone_view->virtual_pixel_method=cache_view->virtual_pixel_method;
224  clone_view->debug=cache_view->debug;
225  clone_view->signature=MagickCoreSignature;
226  return(clone_view);
227}
228
229/*
230%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
231%                                                                             %
232%                                                                             %
233%                                                                             %
234%   D e s t r o y C a c h e V i e w                                           %
235%                                                                             %
236%                                                                             %
237%                                                                             %
238%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
239%
240%  DestroyCacheView() destroys the specified view returned by a previous call
241%  to AcquireCacheView().
242%
243%  The format of the DestroyCacheView method is:
244%
245%      CacheView *DestroyCacheView(CacheView *cache_view)
246%
247%  A description of each parameter follows:
248%
249%    o cache_view: the cache view.
250%
251*/
252MagickExport CacheView *DestroyCacheView(CacheView *cache_view)
253{
254  assert(cache_view != (CacheView *) NULL);
255  assert(cache_view->signature == MagickCoreSignature);
256  if (cache_view->debug != MagickFalse)
257    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
258      cache_view->image->filename);
259  if (cache_view->nexus_info != (NexusInfo **) NULL)
260    cache_view->nexus_info=DestroyPixelCacheNexus(cache_view->nexus_info,
261      cache_view->number_threads);
262  cache_view->image=DestroyImage(cache_view->image);
263  cache_view->signature=(~MagickCoreSignature);
264  cache_view=(CacheView *) RelinquishAlignedMemory(cache_view);
265  return(cache_view);
266}
267
268/*
269%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
270%                                                                             %
271%                                                                             %
272%                                                                             %
273%   G e t C a c h e V i e w A u t h e n t i c P i x e l s                     %
274%                                                                             %
275%                                                                             %
276%                                                                             %
277%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
278%
279%  GetCacheViewAuthenticPixels() gets pixels from the in-memory or disk pixel
280%  cache as defined by the geometry parameters.   A pointer to the pixels is
281%  returned if the pixels are transferred, otherwise a NULL is returned.
282%
283%  The format of the GetCacheViewAuthenticPixels method is:
284%
285%      Quantum *GetCacheViewAuthenticPixels(CacheView *cache_view,
286%        const ssize_t x,const ssize_t y,const size_t columns,
287%        const size_t rows,ExceptionInfo *exception)
288%
289%  A description of each parameter follows:
290%
291%    o cache_view: the cache view.
292%
293%    o x,y,columns,rows:  These values define the perimeter of a region of
294%      pixels.
295%
296%    o exception: return any errors or warnings in this structure.
297%
298*/
299MagickExport Quantum *GetCacheViewAuthenticPixels(CacheView *cache_view,
300  const ssize_t x,const ssize_t y,const size_t columns,const size_t rows,
301  ExceptionInfo *exception)
302{
303  const int
304    id = GetOpenMPThreadId();
305
306  Quantum
307    *magick_restrict pixels;
308
309  assert(cache_view != (CacheView *) NULL);
310  assert(cache_view->signature == MagickCoreSignature);
311  assert(id < (int) cache_view->number_threads);
312  pixels=GetAuthenticPixelCacheNexus(cache_view->image,x,y,columns,rows,
313    cache_view->nexus_info[id],exception);
314  return(pixels);
315}
316
317/*
318%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
319%                                                                             %
320%                                                                             %
321%                                                                             %
322%   G e t C a c h e V i e w A u t h e n t i c M e t a c o n t e n t           %
323%                                                                             %
324%                                                                             %
325%                                                                             %
326%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
327%
328%  GetCacheViewAuthenticMetacontent() returns the meta-content corresponding
329%  with the last call to SetCacheViewIndexes() or
330%  GetCacheViewAuthenticMetacontent().  The meta-content are authentic and can
331%  be updated.
332%
333%  The format of the GetCacheViewAuthenticMetacontent() method is:
334%
335%      void *GetCacheViewAuthenticMetacontent(CacheView *cache_view)
336%
337%  A description of each parameter follows:
338%
339%    o cache_view: the cache view.
340%
341*/
342MagickExport void *GetCacheViewAuthenticMetacontent(CacheView *cache_view)
343{
344  const int
345    id = GetOpenMPThreadId();
346
347  assert(cache_view != (CacheView *) NULL);
348  assert(cache_view->signature == MagickCoreSignature);
349  assert(cache_view->image->cache != (Cache) NULL);
350  assert(id < (int) cache_view->number_threads);
351  return(cache_view->nexus_info[id]->metacontent);
352}
353
354/*
355%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
356%                                                                             %
357%                                                                             %
358%                                                                             %
359%   G e t C a c h e V i e w A u t h e n t i c P i x e l Q u e u e             %
360%                                                                             %
361%                                                                             %
362%                                                                             %
363%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
364%
365%  GetCacheViewAuthenticPixelQueue() returns the pixels associated with the
366%  last call to QueueCacheViewAuthenticPixels() or
367%  GetCacheViewAuthenticPixels().  The pixels are authentic and therefore can be
368%  updated.
369%
370%  The format of the GetCacheViewAuthenticPixelQueue() method is:
371%
372%      Quantum *GetCacheViewAuthenticPixelQueue(CacheView *cache_view)
373%
374%  A description of each parameter follows:
375%
376%    o cache_view: the cache view.
377%
378*/
379MagickExport Quantum *GetCacheViewAuthenticPixelQueue(CacheView *cache_view)
380{
381  const int
382    id = GetOpenMPThreadId();
383
384  assert(cache_view != (CacheView *) NULL);
385  assert(cache_view->signature == MagickCoreSignature);
386  assert(cache_view->image->cache != (Cache) NULL);
387  assert(id < (int) cache_view->number_threads);
388  return(cache_view->nexus_info[id]->pixels);
389}
390
391/*
392%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
393%                                                                             %
394%                                                                             %
395%                                                                             %
396%   G e t C a c h e V i e w C o l o r s p a c e                               %
397%                                                                             %
398%                                                                             %
399%                                                                             %
400%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
401%
402%  GetCacheViewColorspace() returns the image colorspace associated with the
403%  specified view.
404%
405%  The format of the GetCacheViewColorspace method is:
406%
407%      ColorspaceType GetCacheViewColorspace(const CacheView *cache_view)
408%
409%  A description of each parameter follows:
410%
411%    o cache_view: the cache view.
412%
413*/
414MagickExport ColorspaceType GetCacheViewColorspace(const CacheView *cache_view)
415{
416  assert(cache_view != (CacheView *) NULL);
417  assert(cache_view->signature == MagickCoreSignature);
418  if (cache_view->debug != MagickFalse)
419    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
420      cache_view->image->filename);
421  return(GetPixelCacheColorspace(cache_view->image->cache));
422}
423
424/*
425%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
426%                                                                             %
427%                                                                             %
428%                                                                             %
429+   G e t C a c h e V i e w E x t e n t                                       %
430%                                                                             %
431%                                                                             %
432%                                                                             %
433%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
434%
435%  GetCacheViewExtent() returns the extent of the pixels associated with the
436%  last call to QueueCacheViewAuthenticPixels() or
437%  GetCacheViewAuthenticPixels().
438%
439%  The format of the GetCacheViewExtent() method is:
440%
441%      MagickSizeType GetCacheViewExtent(const CacheView *cache_view)
442%
443%  A description of each parameter follows:
444%
445%    o cache_view: the cache view.
446%
447*/
448MagickExport MagickSizeType GetCacheViewExtent(const CacheView *cache_view)
449{
450  const int
451    id = GetOpenMPThreadId();
452
453  MagickSizeType
454    extent;
455
456  assert(cache_view != (CacheView *) NULL);
457  assert(cache_view->signature == MagickCoreSignature);
458  if (cache_view->debug != MagickFalse)
459    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
460      cache_view->image->filename);
461  assert(cache_view->image->cache != (Cache) NULL);
462  assert(id < (int) cache_view->number_threads);
463  extent=GetPixelCacheNexusExtent(cache_view->image->cache,
464    cache_view->nexus_info[id]);
465  return(extent);
466}
467
468/*
469%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
470%                                                                             %
471%                                                                             %
472%                                                                             %
473%   G e t C a c h e V i e w I m a g e                                         %
474%                                                                             %
475%                                                                             %
476%                                                                             %
477%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
478%
479%  GetCacheViewImage() returns the image associated with the specified view.
480%
481%  The format of the GetCacheViewImage method is:
482%
483%      const Image *GetCacheViewImage(const CacheView *cache_view)
484%
485%  A description of each parameter follows:
486%
487%    o cache_view: the cache view.
488%
489*/
490MagickExport const Image *GetCacheViewImage(const CacheView *cache_view)
491{
492  assert(cache_view != (CacheView *) NULL);
493  assert(cache_view->signature == MagickCoreSignature);
494  if (cache_view->debug != MagickFalse)
495    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
496      cache_view->image->filename);
497  return(cache_view->image);
498}
499
500/*
501%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
502%                                                                             %
503%                                                                             %
504%                                                                             %
505%   G e t C a c h e V i e w S t o r a g e C l a s s                           %
506%                                                                             %
507%                                                                             %
508%                                                                             %
509%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
510%
511%  GetCacheViewStorageClass() returns the image storage class associated with
512%  the specified view.
513%
514%  The format of the GetCacheViewStorageClass method is:
515%
516%      ClassType GetCacheViewStorageClass(const CacheView *cache_view)
517%
518%  A description of each parameter follows:
519%
520%    o cache_view: the cache view.
521%
522*/
523MagickExport ClassType GetCacheViewStorageClass(const CacheView *cache_view)
524{
525  assert(cache_view != (CacheView *) NULL);
526  assert(cache_view->signature == MagickCoreSignature);
527  if (cache_view->debug != MagickFalse)
528    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
529      cache_view->image->filename);
530  return(GetPixelCacheStorageClass(cache_view->image->cache));
531}
532
533/*
534%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
535%                                                                             %
536%                                                                             %
537%                                                                             %
538%   G e t C a c h e V i e w V i r t u a l M e t a c o n t e n t               %
539%                                                                             %
540%                                                                             %
541%                                                                             %
542%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
543%
544%  GetCacheViewVirtualMetacontent() returns the meta-content corresponding
545%  with the last call to GetCacheViewVirtualMetacontent().  The meta-content
546%  is virtual and therefore cannot be updated.
547%
548%  The format of the GetCacheViewVirtualMetacontent() method is:
549%
550%      const void *GetCacheViewVirtualMetacontent(
551%        const CacheView *cache_view)
552%
553%  A description of each parameter follows:
554%
555%    o cache_view: the cache view.
556%
557*/
558MagickExport const void *GetCacheViewVirtualMetacontent(
559  const CacheView *cache_view)
560{
561  const int
562    id = GetOpenMPThreadId();
563
564  const void
565    *magick_restrict metacontent;
566
567  assert(cache_view != (const CacheView *) NULL);
568  assert(cache_view->signature == MagickCoreSignature);
569  assert(cache_view->image->cache != (Cache) NULL);
570  assert(id < (int) cache_view->number_threads);
571  metacontent=GetVirtualMetacontentFromNexus(cache_view->image->cache,
572    cache_view->nexus_info[id]);
573  return(metacontent);
574}
575
576/*
577%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
578%                                                                             %
579%                                                                             %
580%                                                                             %
581%   G e t C a c h e V i e w V i r t u a l P i x e l Q u e u e                 %
582%                                                                             %
583%                                                                             %
584%                                                                             %
585%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
586%
587%  GetCacheViewVirtualPixelQueue() returns the the pixels associated with
588%  the last call to GetCacheViewVirtualPixels().  The pixels are virtual
589%  and therefore cannot be updated.
590%
591%  The format of the GetCacheViewVirtualPixelQueue() method is:
592%
593%      const Quantum *GetCacheViewVirtualPixelQueue(
594%        const CacheView *cache_view)
595%
596%  A description of each parameter follows:
597%
598%    o cache_view: the cache view.
599%
600*/
601MagickExport const Quantum *GetCacheViewVirtualPixelQueue(
602  const CacheView *cache_view)
603{
604  const int
605    id = GetOpenMPThreadId();
606
607  const Quantum
608    *magick_restrict pixels;
609
610  assert(cache_view != (const CacheView *) NULL);
611  assert(cache_view->signature == MagickCoreSignature);
612  assert(cache_view->image->cache != (Cache) NULL);
613  assert(id < (int) cache_view->number_threads);
614  pixels=GetVirtualPixelsNexus(cache_view->image->cache,
615    cache_view->nexus_info[id]);
616  return(pixels);
617}
618
619/*
620%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
621%                                                                             %
622%                                                                             %
623%                                                                             %
624%   G e t C a c h e V i e w V i r t u a l P i x e l s                         %
625%                                                                             %
626%                                                                             %
627%                                                                             %
628%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
629%
630%  GetCacheViewVirtualPixels() gets virtual pixels from the in-memory or
631%  disk pixel cache as defined by the geometry parameters.   A pointer to the
632%  pixels is returned if the pixels are transferred, otherwise a NULL is
633%  returned.
634%
635%  The format of the GetCacheViewVirtualPixels method is:
636%
637%      const Quantum *GetCacheViewVirtualPixels(
638%        const CacheView *cache_view,const ssize_t x,const ssize_t y,
639%        const size_t columns,const size_t rows,ExceptionInfo *exception)
640%
641%  A description of each parameter follows:
642%
643%    o cache_view: the cache view.
644%
645%    o x,y,columns,rows:  These values define the perimeter of a region of
646%      pixels.
647%
648%    o exception: return any errors or warnings in this structure.
649%
650*/
651MagickExport const Quantum *GetCacheViewVirtualPixels(
652  const CacheView *cache_view,const ssize_t x,const ssize_t y,
653  const size_t columns,const size_t rows,ExceptionInfo *exception)
654{
655  const int
656    id = GetOpenMPThreadId();
657
658  const Quantum
659    *magick_restrict pixels;
660
661  assert(cache_view != (CacheView *) NULL);
662  assert(cache_view->signature == MagickCoreSignature);
663  assert(id < (int) cache_view->number_threads);
664  pixels=GetVirtualPixelsFromNexus(cache_view->image,
665    cache_view->virtual_pixel_method,x,y,columns,rows,
666    cache_view->nexus_info[id],exception);
667  return(pixels);
668}
669
670/*
671%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
672%                                                                             %
673%                                                                             %
674%                                                                             %
675%   G e t O n e C a c h e V i e w A u t h e n t i c P i x e l                 %
676%                                                                             %
677%                                                                             %
678%                                                                             %
679%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
680%
681%  GetOneCacheViewAuthenticPixel() returns a single pixel at the specified (x,y)
682%  location.  The image background color is returned if an error occurs.
683%
684%  The format of the GetOneCacheViewAuthenticPixel method is:
685%
686%      MagickBooleaNType GetOneCacheViewAuthenticPixel(
687%        const CacheView *cache_view,const ssize_t x,const ssize_t y,
688%        Quantum *pixel,ExceptionInfo *exception)
689%
690%  A description of each parameter follows:
691%
692%    o cache_view: the cache view.
693%
694%    o x,y:  These values define the offset of the pixel.
695%
696%    o pixel: return a pixel at the specified (x,y) location.
697%
698%    o exception: return any errors or warnings in this structure.
699%
700*/
701MagickExport MagickBooleanType GetOneCacheViewAuthenticPixel(
702  const CacheView *cache_view,const ssize_t x,const ssize_t y,Quantum *pixel,
703  ExceptionInfo *exception)
704{
705  const int
706    id = GetOpenMPThreadId();
707
708  Quantum
709    *magick_restrict q;
710
711  register ssize_t
712    i;
713
714  assert(cache_view != (CacheView *) NULL);
715  assert(cache_view->signature == MagickCoreSignature);
716  assert(id < (int) cache_view->number_threads);
717  (void) memset(pixel,0,MaxPixelChannels*sizeof(*pixel));
718  q=GetAuthenticPixelCacheNexus(cache_view->image,x,y,1,1,
719    cache_view->nexus_info[id],exception);
720  if (q == (const Quantum *) NULL)
721    {
722      PixelInfo
723        background_color;
724
725      background_color=cache_view->image->background_color;
726      pixel[RedPixelChannel]=ClampToQuantum(background_color.red);
727      pixel[GreenPixelChannel]=ClampToQuantum(background_color.green);
728      pixel[BluePixelChannel]=ClampToQuantum(background_color.blue);
729      pixel[BlackPixelChannel]=ClampToQuantum(background_color.black);
730      pixel[AlphaPixelChannel]=ClampToQuantum(background_color.alpha);
731      return(MagickFalse);
732    }
733  for (i=0; i < (ssize_t) GetPixelChannels(cache_view->image); i++)
734  {
735    PixelChannel channel=GetPixelChannelChannel(cache_view->image,i);
736    pixel[channel]=q[i];
737  }
738  return(MagickTrue);
739}
740
741/*
742%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
743%                                                                             %
744%                                                                             %
745%                                                                             %
746%   G e t O n e C a c h e V i e w V i r t u a l P i x e l                     %
747%                                                                             %
748%                                                                             %
749%                                                                             %
750%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
751%
752%  GetOneCacheViewVirtualPixel() returns a single pixel at the specified (x,y)
753%  location.  The image background color is returned if an error occurs.  If
754%  you plan to modify the pixel, use GetOneCacheViewAuthenticPixel() instead.
755%
756%  The format of the GetOneCacheViewVirtualPixel method is:
757%
758%      MagickBooleanType GetOneCacheViewVirtualPixel(
759%        const CacheView *cache_view,const ssize_t x,const ssize_t y,
760%        Quantum *pixel,ExceptionInfo *exception)
761%
762%  A description of each parameter follows:
763%
764%    o cache_view: the cache view.
765%
766%    o x,y:  These values define the offset of the pixel.
767%
768%    o pixel: return a pixel at the specified (x,y) location.
769%
770%    o exception: return any errors or warnings in this structure.
771%
772*/
773MagickExport MagickBooleanType GetOneCacheViewVirtualPixel(
774  const CacheView *cache_view,const ssize_t x,const ssize_t y,Quantum *pixel,
775  ExceptionInfo *exception)
776{
777  const int
778    id = GetOpenMPThreadId();
779
780  register const Quantum
781    *magick_restrict p;
782
783  register ssize_t
784    i;
785
786  assert(cache_view != (CacheView *) NULL);
787  assert(cache_view->signature == MagickCoreSignature);
788  assert(id < (int) cache_view->number_threads);
789  (void) memset(pixel,0,MaxPixelChannels*sizeof(*pixel));
790  p=GetVirtualPixelsFromNexus(cache_view->image,
791    cache_view->virtual_pixel_method,x,y,1,1,cache_view->nexus_info[id],
792    exception);
793  if (p == (const Quantum *) NULL)
794    {
795      PixelInfo
796        background_color;
797
798      background_color=cache_view->image->background_color;
799      pixel[RedPixelChannel]=ClampToQuantum(background_color.red);
800      pixel[GreenPixelChannel]=ClampToQuantum(background_color.green);
801      pixel[BluePixelChannel]=ClampToQuantum(background_color.blue);
802      pixel[BlackPixelChannel]=ClampToQuantum(background_color.black);
803      pixel[AlphaPixelChannel]=ClampToQuantum(background_color.alpha);
804      return(MagickFalse);
805    }
806  for (i=0; i < (ssize_t) GetPixelChannels(cache_view->image); i++)
807  {
808    PixelChannel channel=GetPixelChannelChannel(cache_view->image,i);
809    pixel[channel]=p[i];
810  }
811  return(MagickTrue);
812}
813
814/*
815%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
816%                                                                             %
817%                                                                             %
818%                                                                             %
819%   G e t O n e C a c h e V i e w V i r t u a l P i x e l I n f o             %
820%                                                                             %
821%                                                                             %
822%                                                                             %
823%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
824%
825%  GetOneCacheViewVirtualPixelInfo() returns a single pixel at the specified
826%  (x,y) location.  The image background color is returned if an error occurs.
827%  If you plan to modify the pixel, use GetOneCacheViewAuthenticPixel() instead.
828%
829%  The format of the GetOneCacheViewVirtualPixelInfo method is:
830%
831%      MagickBooleanType GetOneCacheViewVirtualPixelInfo(
832%        const CacheView *cache_view,const ssize_t x,const ssize_t y,
833%        PixelInfo *pixel,ExceptionInfo *exception)
834%
835%  A description of each parameter follows:
836%
837%    o cache_view: the cache view.
838%
839%    o x,y:  These values define the offset of the pixel.
840%
841%    o pixel: return a pixel at the specified (x,y) location.
842%
843%    o exception: return any errors or warnings in this structure.
844%
845*/
846MagickExport MagickBooleanType GetOneCacheViewVirtualPixelInfo(
847  const CacheView *cache_view,const ssize_t x,const ssize_t y,PixelInfo *pixel,
848  ExceptionInfo *exception)
849{
850  const int
851    id = GetOpenMPThreadId();
852
853  register const Quantum
854    *magick_restrict p;
855
856  assert(cache_view != (CacheView *) NULL);
857  assert(cache_view->signature == MagickCoreSignature);
858  assert(id < (int) cache_view->number_threads);
859  GetPixelInfo(cache_view->image,pixel);
860  p=GetVirtualPixelsFromNexus(cache_view->image,
861    cache_view->virtual_pixel_method,x,y,1,1,cache_view->nexus_info[id],
862    exception);
863  if (p == (const Quantum *) NULL)
864    return(MagickFalse);
865  GetPixelInfoPixel(cache_view->image,p,pixel);
866  return(MagickTrue);
867}
868
869/*
870%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
871%                                                                             %
872%                                                                             %
873%                                                                             %
874%   G e t O n e C a c h e V i e w V i r t u a l P i x e l                     %
875%                                                                             %
876%                                                                             %
877%                                                                             %
878%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
879%
880%  GetOneCacheViewVirtualMethodPixel() returns a single virtual pixel at
881%  the specified (x,y) location.  The image background color is returned if an
882%  error occurs.  If you plan to modify the pixel, use
883%  GetOneCacheViewAuthenticPixel() instead.
884%
885%  The format of the GetOneCacheViewVirtualPixel method is:
886%
887%      MagickBooleanType GetOneCacheViewVirtualMethodPixel(
888%        const CacheView *cache_view,
889%        const VirtualPixelMethod virtual_pixel_method,const ssize_t x,
890%        const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
891%
892%  A description of each parameter follows:
893%
894%    o cache_view: the cache view.
895%
896%    o virtual_pixel_method: the virtual pixel method.
897%
898%    o x,y:  These values define the offset of the pixel.
899%
900%    o pixel: return a pixel at the specified (x,y) location.
901%
902%    o exception: return any errors or warnings in this structure.
903%
904*/
905MagickExport MagickBooleanType GetOneCacheViewVirtualMethodPixel(
906  const CacheView *cache_view,const VirtualPixelMethod virtual_pixel_method,
907  const ssize_t x,const ssize_t y,Quantum *pixel,ExceptionInfo *exception)
908{
909  const int
910    id = GetOpenMPThreadId();
911
912  const Quantum
913    *magick_restrict p;
914
915  register ssize_t
916    i;
917
918  assert(cache_view != (CacheView *) NULL);
919  assert(cache_view->signature == MagickCoreSignature);
920  assert(id < (int) cache_view->number_threads);
921  (void) memset(pixel,0,MaxPixelChannels*sizeof(*pixel));
922  p=GetVirtualPixelsFromNexus(cache_view->image,virtual_pixel_method,x,y,1,1,
923    cache_view->nexus_info[id],exception);
924  if (p == (const Quantum *) NULL)
925    {
926      PixelInfo
927        background_color;
928
929      background_color=cache_view->image->background_color;
930      pixel[RedPixelChannel]=ClampToQuantum(background_color.red);
931      pixel[GreenPixelChannel]=ClampToQuantum(background_color.green);
932      pixel[BluePixelChannel]=ClampToQuantum(background_color.blue);
933      pixel[BlackPixelChannel]=ClampToQuantum(background_color.black);
934      pixel[AlphaPixelChannel]=ClampToQuantum(background_color.alpha);
935      return(MagickFalse);
936    }
937  for (i=0; i < (ssize_t) GetPixelChannels(cache_view->image); i++)
938  {
939    PixelChannel channel=GetPixelChannelChannel(cache_view->image,i);
940    pixel[channel]=p[i];
941  }
942  return(MagickTrue);
943}
944
945/*
946%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
947%                                                                             %
948%                                                                             %
949%                                                                             %
950%   Q u e u e C a c h e V i e w A u t h e n t i c P i x e l s                 %
951%                                                                             %
952%                                                                             %
953%                                                                             %
954%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
955%
956%  QueueCacheViewAuthenticPixels() queues authentic pixels from the in-memory or
957%  disk pixel cache as defined by the geometry parameters.   A pointer to the
958%  pixels is returned if the pixels are transferred, otherwise a NULL is
959%  returned.
960%
961%  The format of the QueueCacheViewAuthenticPixels method is:
962%
963%      Quantum *QueueCacheViewAuthenticPixels(CacheView *cache_view,
964%        const ssize_t x,const ssize_t y,const size_t columns,
965%        const size_t rows,ExceptionInfo *exception)
966%
967%  A description of each parameter follows:
968%
969%    o cache_view: the cache view.
970%
971%    o x,y,columns,rows:  These values define the perimeter of a region of
972%      pixels.
973%
974%    o exception: return any errors or warnings in this structure.
975%
976*/
977MagickExport Quantum *QueueCacheViewAuthenticPixels(CacheView *cache_view,
978  const ssize_t x,const ssize_t y,const size_t columns,const size_t rows,
979  ExceptionInfo *exception)
980{
981  const int
982    id = GetOpenMPThreadId();
983
984  Quantum
985    *magick_restrict pixels;
986
987  assert(cache_view != (CacheView *) NULL);
988  assert(cache_view->signature == MagickCoreSignature);
989  assert(id < (int) cache_view->number_threads);
990  pixels=QueueAuthenticPixelCacheNexus(cache_view->image,x,y,columns,rows,
991    MagickFalse,cache_view->nexus_info[id],exception);
992  return(pixels);
993}
994
995/*
996%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
997%                                                                             %
998%                                                                             %
999%                                                                             %
1000%   S e t C a c h e V i e w S t o r a g e C l a s s                           %
1001%                                                                             %
1002%                                                                             %
1003%                                                                             %
1004%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1005%
1006%  SetCacheViewStorageClass() sets the image storage class associated with
1007%  the specified view.
1008%
1009%  The format of the SetCacheViewStorageClass method is:
1010%
1011%      MagickBooleanType SetCacheViewStorageClass(CacheView *cache_view,
1012%        const ClassType storage_class,ExceptionInfo *exception)
1013%
1014%  A description of each parameter follows:
1015%
1016%    o cache_view: the cache view.
1017%
1018%    o storage_class: the image storage class: PseudoClass or DirectClass.
1019%
1020%    o exception: return any errors or warnings in this structure.
1021%
1022*/
1023MagickExport MagickBooleanType SetCacheViewStorageClass(CacheView *cache_view,
1024  const ClassType storage_class,ExceptionInfo *exception)
1025{
1026  assert(cache_view != (CacheView *) NULL);
1027  assert(cache_view->signature == MagickCoreSignature);
1028  if (cache_view->debug != MagickFalse)
1029    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1030      cache_view->image->filename);
1031  return(SetImageStorageClass(cache_view->image,storage_class,exception));
1032}
1033
1034/*
1035%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1036%                                                                             %
1037%                                                                             %
1038%                                                                             %
1039%   S e t C a c h e V i e w V i r t u a l P i x e l M e t h o d               %
1040%                                                                             %
1041%                                                                             %
1042%                                                                             %
1043%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1044%
1045%  SetCacheViewVirtualPixelMethod() sets the virtual pixel method associated
1046%  with the specified cache view.
1047%
1048%  The format of the SetCacheViewVirtualPixelMethod method is:
1049%
1050%      MagickBooleanType SetCacheViewVirtualPixelMethod(CacheView *cache_view,
1051%        const VirtualPixelMethod virtual_pixel_method)
1052%
1053%  A description of each parameter follows:
1054%
1055%    o cache_view: the cache view.
1056%
1057%    o virtual_pixel_method: the virtual pixel method.
1058%
1059*/
1060MagickExport MagickBooleanType SetCacheViewVirtualPixelMethod(
1061  CacheView *magick_restrict cache_view,
1062  const VirtualPixelMethod virtual_pixel_method)
1063{
1064  assert(cache_view != (CacheView *) NULL);
1065  assert(cache_view->signature == MagickCoreSignature);
1066  if (cache_view->debug != MagickFalse)
1067    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1068      cache_view->image->filename);
1069  cache_view->virtual_pixel_method=virtual_pixel_method;
1070  return(MagickTrue);
1071}
1072
1073/*
1074%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1075%                                                                             %
1076%                                                                             %
1077%                                                                             %
1078%   S y n c C a c h e V i e w A u t h e n t i c P i x e l s                   %
1079%                                                                             %
1080%                                                                             %
1081%                                                                             %
1082%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1083%
1084%  SyncCacheViewAuthenticPixels() saves the cache view pixels to the in-memory
1085%  or disk cache.  It returns MagickTrue if the pixel region is flushed,
1086%  otherwise MagickFalse.
1087%
1088%  The format of the SyncCacheViewAuthenticPixels method is:
1089%
1090%      MagickBooleanType SyncCacheViewAuthenticPixels(CacheView *cache_view,
1091%        ExceptionInfo *exception)
1092%
1093%  A description of each parameter follows:
1094%
1095%    o cache_view: the cache view.
1096%
1097%    o exception: return any errors or warnings in this structure.
1098%
1099*/
1100MagickExport MagickBooleanType SyncCacheViewAuthenticPixels(
1101  CacheView *magick_restrict cache_view,ExceptionInfo *exception)
1102{
1103  const int
1104    id = GetOpenMPThreadId();
1105
1106  MagickBooleanType
1107    status;
1108
1109  assert(cache_view != (CacheView *) NULL);
1110  assert(cache_view->signature == MagickCoreSignature);
1111  assert(id < (int) cache_view->number_threads);
1112  status=SyncAuthenticPixelCacheNexus(cache_view->image,
1113    cache_view->nexus_info[id],exception);
1114  return(status);
1115}
1116