stream.c

Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %                  SSSSS  TTTTT  RRRR   EEEEE   AAA   M   M                   %
00007 %                  SS       T    R   R  E      A   A  MM MM                   %
00008 %                   SSS     T    RRRR   EEE    AAAAA  M M M                   %
00009 %                     SS    T    R R    E      A   A  M   M                   %
00010 %                  SSSSS    T    R  R   EEEEE  A   A  M   M                   %
00011 %                                                                             %
00012 %                                                                             %
00013 %                       MagickCore Pixel Stream Methods                       %
00014 %                                                                             %
00015 %                              Software Design                                %
00016 %                                John Cristy                                  %
00017 %                                 March 2000                                  %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2008 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.imagemagick.org/script/license.php                            %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 %
00038 */
00039 
00040 /*
00041   Include declarations.
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/constitute.h"
00051 #include "magick/exception.h"
00052 #include "magick/exception-private.h"
00053 #include "magick/geometry.h"
00054 #include "magick/memory_.h"
00055 #include "magick/quantum.h"
00056 #include "magick/quantum-private.h"
00057 #include "magick/semaphore.h"
00058 #include "magick/stream.h"
00059 #include "magick/stream-private.h"
00060 #include "magick/string_.h"
00061 
00062 /*
00063   Typedef declaractions.
00064 */
00065 struct _StreamInfo
00066 {
00067   const ImageInfo
00068     *image_info;
00069 
00070   const Image
00071     *image;
00072 
00073   Image
00074     *stream;
00075 
00076   QuantumInfo
00077     *quantum_info;
00078 
00079   char
00080     *map;
00081 
00082   StorageType
00083     storage_type;
00084 
00085   unsigned char
00086     *pixels;
00087 
00088   RectangleInfo
00089     extract_info;
00090 
00091   long
00092     y;
00093 
00094   ExceptionInfo
00095     *exception;
00096 
00097   const void
00098     *client_data;
00099 
00100   unsigned long
00101     signature;
00102 };
00103 
00104 /*
00105   Declare pixel cache interfaces.
00106 */
00107 #if defined(__cplusplus) || defined(c_plusplus)
00108 extern "C" {
00109 #endif
00110 
00111 static MagickBooleanType
00112   GetOneVirtualPixelFromStream(const Image *,const VirtualPixelMethod,
00113     const long,const long,PixelPacket *,ExceptionInfo *),
00114   GetOneAuthenticPixelFromStream(Image *,const long,const long,PixelPacket *,
00115     ExceptionInfo *),
00116   StreamImagePixels(const StreamInfo *,const Image *,ExceptionInfo *),
00117   SyncPixelStream(Image *,ExceptionInfo *);
00118 
00119 static const PixelPacket
00120   *AcquirePixelStream(const Image *,const VirtualPixelMethod,const long,
00121     const long,const unsigned long,const unsigned long,ExceptionInfo *);
00122 
00123 static PixelPacket
00124   *GetPixelStream(Image *,const long,const long,const unsigned long,
00125     const unsigned long,ExceptionInfo *),
00126   *GetPixelsFromStream(const Image *),
00127   *SetPixelStream(Image *,const long,const long,const unsigned long,
00128     const unsigned long,ExceptionInfo *);
00129 
00130 static void
00131   DestroyPixelStream(Image *);
00132 
00133 #if defined(__cplusplus) || defined(c_plusplus)
00134 }
00135 #endif
00136 
00137 /*
00138 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00139 %                                                                             %
00140 %                                                                             %
00141 %                                                                             %
00142 +   A c q u i r e I n d e x e s F r o m S t r e a m                           %
00143 %                                                                             %
00144 %                                                                             %
00145 %                                                                             %
00146 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00147 %
00148 %  AcquireIndexesFromStream() returns the indexes associated with the last
00149 %  call to SetPixelStream() or AcquirePixelStream().
00150 %
00151 %  The format of the AcquireIndexesFromStream() method is:
00152 %
00153 %      const IndexPacket *AcquireIndexesFromStream(const Image *image)
00154 %
00155 %  A description of each parameter follows:
00156 %
00157 %    o indexes: return the indexes associated with the last call to
00158 %      SetPixelStream() or AcquirePixelStream().
00159 %
00160 %    o image: the image.
00161 %
00162 */
00163 static const IndexPacket *AcquireIndexesFromStream(const Image *image)
00164 {
00165   CacheInfo
00166     *cache_info;
00167 
00168   assert(image != (Image *) NULL);
00169   assert(image->signature == MagickSignature);
00170   if (image->debug != MagickFalse)
00171     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00172   cache_info=(CacheInfo *) image->cache;
00173   assert(cache_info->signature == MagickSignature);
00174   return(cache_info->indexes);
00175 }
00176 
00177 /*
00178 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00179 %                                                                             %
00180 %                                                                             %
00181 %                                                                             %
00182 +   A c q u i r e P i x e l s F r o m S t r e a m                             %
00183 %                                                                             %
00184 %                                                                             %
00185 %                                                                             %
00186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00187 %
00188 %  AcquirePixelsFromStream() returns the pixels associated with the last
00189 %  call to SetPixelStream() or AcquirePixelStream().
00190 %
00191 %  The format of the AcquirePixelsFromStream() method is:
00192 %
00193 %      const IndexPacket *AcquirePixelsFromStream(const Image *image)
00194 %
00195 %  A description of each parameter follows:
00196 %
00197 %    o pixels: return the pixels associated with the last call to
00198 %      SetPixelStream() or AcquirePixelStream().
00199 %
00200 %    o image: the image.
00201 %
00202 */
00203 static const PixelPacket *AcquirePixelsFromStream(const Image *image)
00204 {
00205   CacheInfo
00206     *cache_info;
00207 
00208   assert(image != (Image *) NULL);
00209   assert(image->signature == MagickSignature);
00210   if (image->debug != MagickFalse)
00211     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00212   cache_info=(CacheInfo *) image->cache;
00213   assert(cache_info->signature == MagickSignature);
00214   return(cache_info->pixels);
00215 }
00216 
00217 /*
00218 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00219 %                                                                             %
00220 %                                                                             %
00221 %                                                                             %
00222 +   A c q u i r e P i x e l S t r e a m                                       %
00223 %                                                                             %
00224 %                                                                             %
00225 %                                                                             %
00226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00227 %
00228 %  AcquirePixelStream() gets pixels from the in-memory or disk pixel cache as
00229 %  defined by the geometry parameters.   A pointer to the pixels is returned if
00230 %  the pixels are transferred, otherwise a NULL is returned.  For streams this
00231 %  method is a no-op.
00232 %
00233 %  The format of the AcquirePixelStream() method is:
00234 %
00235 %      const PixelPacket *AcquirePixelStream(const Image *image,
00236 %        const VirtualPixelMethod virtual_pixel_method,const long x,
00237 %        const long y,const unsigned long columns,const unsigned long rows,
00238 %        ExceptionInfo *exception)
00239 %
00240 %  A description of each parameter follows:
00241 %
00242 %    o image: the image.
00243 %
00244 %    o virtual_pixel_method: the virtual pixel method.
00245 %
00246 %    o x,y,columns,rows:  These values define the perimeter of a region of
00247 %      pixels.
00248 %
00249 %    o exception: return any errors or warnings in this structure.
00250 %
00251 */
00252 
00253 static inline void AcquireStreamPixels(CacheInfo *cache_info)
00254 {
00255   assert(cache_info != (CacheInfo *) NULL);
00256   assert(cache_info->length == (MagickSizeType) ((size_t) cache_info->length));
00257   cache_info->mapped=MagickFalse;
00258   cache_info->pixels=(PixelPacket *) AcquireMagickMemory((size_t)
00259     cache_info->length);
00260   if (cache_info->pixels == (PixelPacket *) NULL)
00261     {
00262       cache_info->mapped=MagickTrue;
00263       cache_info->pixels=(PixelPacket *) MapBlob(-1,IOMode,0,(size_t)
00264         cache_info->length);
00265     }
00266 }
00267 
00268 static const PixelPacket *AcquirePixelStream(const Image *image,
00269   const VirtualPixelMethod magick_unused(virtual_pixel_method),const long x,
00270   const long y,const unsigned long columns,const unsigned long rows,
00271   ExceptionInfo *exception)
00272 {
00273   CacheInfo
00274     *cache_info;
00275 
00276   MagickSizeType
00277     number_pixels;
00278 
00279   size_t
00280     length;
00281 
00282   /*
00283     Validate pixel cache geometry.
00284   */
00285   assert(image != (const Image *) NULL);
00286   assert(image->signature == MagickSignature);
00287   if (image->debug != MagickFalse)
00288     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00289   if ((x < 0) || (y < 0) || ((x+(long) columns) > (long) image->columns) ||
00290       ((y+(long) rows) > (long) image->rows) || (columns == 0) || (rows == 0))
00291     {
00292       (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
00293         "ImageDoesNotContainTheStreamGeometry","`%s'",image->filename);
00294       return((PixelPacket *) NULL);
00295     }
00296   cache_info=(CacheInfo *) image->cache;
00297   assert(cache_info->signature == MagickSignature);
00298   if (cache_info->type == UndefinedCache)
00299     {
00300       (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
00301         "PixelCacheIsNotOpen","`%s'",image->filename);
00302       return((PixelPacket *) NULL);
00303     }
00304   /*
00305     Pixels are stored in a temporary buffer until they are synced to the cache.
00306   */
00307   number_pixels=(MagickSizeType) columns*rows;
00308   length=(size_t) number_pixels*sizeof(PixelPacket);
00309   if ((image->storage_class == PseudoClass) ||
00310       (image->colorspace == CMYKColorspace))
00311     length+=number_pixels*sizeof(IndexPacket);
00312   cache_info->length=length;
00313   AcquireStreamPixels(cache_info);
00314   if (cache_info->pixels == (void *) NULL)
00315     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00316   cache_info->length=(MagickSizeType) length;
00317   cache_info->indexes=(IndexPacket *) NULL;
00318   if ((image->storage_class == PseudoClass) ||
00319       (image->colorspace == CMYKColorspace))
00320     cache_info->indexes=(IndexPacket *) (cache_info->pixels+number_pixels);
00321   return(cache_info->pixels);
00322 }
00323 
00324 /*
00325 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00326 %                                                                             %
00327 %                                                                             %
00328 %                                                                             %
00329 +   A c q u i r e S t r e a m I n f o                                         %
00330 %                                                                             %
00331 %                                                                             %
00332 %                                                                             %
00333 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00334 %
00335 %  AcquireStreamInfo() allocates the StreamInfo structure.
00336 %
00337 %  The format of the AcquireStreamInfo method is:
00338 %
00339 %      StreamInfo *AcquireStreamInfo(const ImageInfo *image_info)
00340 %
00341 %  A description of each parameter follows:
00342 %
00343 %    o image_info: the image info.
00344 %
00345 */
00346 MagickExport StreamInfo *AcquireStreamInfo(const ImageInfo *image_info)
00347 {
00348   StreamInfo
00349     *stream_info;
00350 
00351   stream_info=(StreamInfo *) AcquireMagickMemory(sizeof(*stream_info));
00352   if (stream_info == (StreamInfo *) NULL)
00353     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00354   (void) ResetMagickMemory(stream_info,0,sizeof(*stream_info));
00355   stream_info->pixels=(unsigned char *) AcquireMagickMemory(
00356     sizeof(*stream_info->pixels));
00357   if (stream_info->pixels == (unsigned char *) NULL)
00358     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
00359   stream_info->map=ConstantString("RGB");
00360   stream_info->storage_type=CharPixel;
00361   stream_info->stream=AcquireImage(image_info);
00362   stream_info->signature=MagickSignature;
00363   return(stream_info);
00364 }
00365 
00366 /*
00367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00368 %                                                                             %
00369 %                                                                             %
00370 %                                                                             %
00371 +   D e s t r o y P i x e l S t r e a m                                       %
00372 %                                                                             %
00373 %                                                                             %
00374 %                                                                             %
00375 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00376 %
00377 %  DestroyPixelStream() deallocates memory associated with the pixel stream.
00378 %
00379 %  The format of the DestroyPixelStream() method is:
00380 %
00381 %      void DestroyPixelStream(Image *image)
00382 %
00383 %  A description of each parameter follows:
00384 %
00385 %    o image: the image.
00386 %
00387 */
00388 
00389 static inline void RelinquishStreamPixels(CacheInfo *cache_info)
00390 {
00391   assert(cache_info != (CacheInfo *) NULL);
00392   if (cache_info->mapped == MagickFalse)
00393     (void) RelinquishMagickMemory(cache_info->pixels);
00394   else
00395     (void) UnmapBlob(cache_info->pixels,(size_t) cache_info->length);
00396   cache_info->pixels=(PixelPacket *) NULL;
00397   cache_info->indexes=(IndexPacket *) NULL;
00398 }
00399 
00400 static void DestroyPixelStream(Image *image)
00401 {
00402   CacheInfo
00403     *cache_info;
00404 
00405   MagickBooleanType
00406     destroy;
00407 
00408   assert(image != (Image *) NULL);
00409   assert(image->signature == MagickSignature);
00410   if (image->debug != MagickFalse)
00411     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00412   cache_info=(CacheInfo *) image->cache;
00413   assert(cache_info->signature == MagickSignature);
00414   destroy=MagickFalse;
00415   (void) LockSemaphoreInfo(cache_info->semaphore);
00416   cache_info->reference_count--;
00417   if (cache_info->reference_count == 0)
00418     destroy=MagickTrue;
00419   (void) UnlockSemaphoreInfo(cache_info->semaphore);
00420   if (destroy == MagickFalse)
00421     return;
00422   RelinquishStreamPixels(cache_info);
00423   if (cache_info->nexus_info != (NexusInfo **) NULL)
00424     cache_info->nexus_info=DestroyNexusInfo(cache_info->nexus_info,
00425       cache_info->number_threads);
00426   if (cache_info->disk_semaphore != (SemaphoreInfo *) NULL)
00427     DestroySemaphoreInfo(&cache_info->disk_semaphore);
00428   if (cache_info->nexus_semaphore != (SemaphoreInfo *) NULL)
00429     DestroySemaphoreInfo(&cache_info->nexus_semaphore);
00430   if (cache_info->semaphore != (SemaphoreInfo *) NULL)
00431     DestroySemaphoreInfo(&cache_info->semaphore);
00432   cache_info=(CacheInfo *) RelinquishMagickMemory(cache_info);
00433 }
00434 
00435 /*
00436 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00437 %                                                                             %
00438 %                                                                             %
00439 %                                                                             %
00440 +   D e s t r o y S t r e a m I n f o                                         %
00441 %                                                                             %
00442 %                                                                             %
00443 %                                                                             %
00444 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00445 %
00446 %  DestroyStreamInfo() destroys memory associated with the StreamInfo
00447 %  structure.
00448 %
00449 %  The format of the DestroyStreamInfo method is:
00450 %
00451 %      StreamInfo *DestroyStreamInfo(StreamInfo *stream_info)
00452 %
00453 %  A description of each parameter follows:
00454 %
00455 %    o stream_info: the stream info.
00456 %
00457 */
00458 MagickExport StreamInfo *DestroyStreamInfo(StreamInfo *stream_info)
00459 {
00460   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
00461   assert(stream_info != (StreamInfo *) NULL);
00462   assert(stream_info->signature == MagickSignature);
00463   if (stream_info->map != (char *) NULL)
00464     stream_info->map=DestroyString(stream_info->map);
00465   if (stream_info->pixels != (unsigned char *) NULL)
00466     stream_info->pixels=(unsigned char *) RelinquishMagickMemory(
00467       stream_info->pixels);
00468   if (stream_info->stream != (Image *) NULL)
00469     {
00470       (void) CloseBlob(stream_info->stream);
00471       stream_info->stream=DestroyImage(stream_info->stream);
00472     }
00473   if (stream_info->quantum_info != (QuantumInfo *) NULL)
00474     stream_info->quantum_info=DestroyQuantumInfo(stream_info->quantum_info);
00475   stream_info->signature=(~MagickSignature);
00476   stream_info=(StreamInfo *) RelinquishMagickMemory(stream_info);
00477   return(stream_info);
00478 }
00479 
00480 /*
00481 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00482 %                                                                             %
00483 %                                                                             %
00484 %                                                                             %
00485 +   G e t I n d e x e s F r o m S t r e a m                                   %
00486 %                                                                             %
00487 %                                                                             %
00488 %                                                                             %
00489 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00490 %
00491 %  GetIndexesFromStream() returns the indexes associated with the last call to
00492 %  SetPixelStream() or GetPixelStream().
00493 %
00494 %  The format of the GetIndexesFromStream() method is:
00495 %
00496 %      IndexPacket *GetIndexesFromStream(const Image *image)
00497 %
00498 %  A description of each parameter follows:
00499 %
00500 %    o indexes: Method GetIndexesFromStream() returns the indexes associated
00501 %      with the last call to SetPixelStream() or GetPixelStream().
00502 %
00503 %    o image: the image.
00504 %
00505 */
00506 static IndexPacket *GetIndexesFromStream(const Image *image)
00507 {
00508   CacheInfo
00509     *cache_info;
00510 
00511   assert(image != (Image *) NULL);
00512   assert(image->signature == MagickSignature);
00513   if (image->debug != MagickFalse)
00514     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00515   cache_info=(CacheInfo *) image->cache;
00516   assert(cache_info->signature == MagickSignature);
00517   return(cache_info->indexes);
00518 }
00519 
00520 /*
00521 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00522 %                                                                             %
00523 %                                                                             %
00524 %                                                                             %
00525 +   G e t O n e V i r t u a l P i x e l F r o m S t r e a m               %
00526 %                                                                             %
00527 %                                                                             %
00528 %                                                                             %
00529 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00530 %
00531 %  GetOneVirtualPixelFromStream() returns a single pixel at the specified
00532 %  (x.y) location.  The image background color is returned if an error occurs.
00533 %
00534 %  The format of the GetOneVirtualPixelFromStream() method is:
00535 %
00536 %      MagickBooleanType GetOneVirtualPixelFromStream(const Image image,
00537 %        const VirtualPixelMethod virtual_pixel_method,const long x,
00538 %        const long y,PixelPacket *pixel,ExceptionInfo *exception)
00539 %
00540 %  A description of each parameter follows:
00541 %
00542 %    o image: the image.
00543 %
00544 %    o virtual_pixel_method: the virtual pixel method.
00545 %
00546 %    o x,y:  These values define the location of the pixel to return.
00547 %
00548 %    o pixel: return a pixel at the specified (x,y) location.
00549 %
00550 %    o exception: return any errors or warnings in this structure.
00551 %
00552 */
00553 static MagickBooleanType GetOneVirtualPixelFromStream(const Image *image,
00554   const VirtualPixelMethod virtual_pixel_method,const long x,const long y,
00555   PixelPacket *pixel,ExceptionInfo *exception)
00556 {
00557   const PixelPacket
00558     *pixels;
00559 
00560   assert(image != (Image *) NULL);
00561   assert(image->signature == MagickSignature);
00562   *pixel=image->background_color;
00563   pixels=AcquirePixelStream(image,virtual_pixel_method,x,y,1,1,exception);
00564   if (pixels != (const PixelPacket *) NULL)
00565     return(MagickFalse);
00566   *pixel=(*pixels);
00567   return(MagickTrue);
00568 }
00569 
00570 /*
00571 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00572 %                                                                             %
00573 %                                                                             %
00574 %                                                                             %
00575 +   G e t O n e A u t h e n t i c P i x e l F r o m S t r e a m                   %
00576 %                                                                             %
00577 %                                                                             %
00578 %                                                                             %
00579 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00580 %
00581 %  GetOneAuthenticPixelFromStream() returns a single pixel at the specified (x,y)
00582 %  location.  The image background color is returned if an error occurs.
00583 %
00584 %  The format of the GetOneAuthenticPixelFromStream() method is:
00585 %
00586 %      MagickBooleanType GetOneAuthenticPixelFromStream(const Image image,
00587 %        const long x,const long y,PixelPacket *pixel,ExceptionInfo *exception)
00588 %
00589 %  A description of each parameter follows:
00590 %
00591 %    o image: the image.
00592 %
00593 %    o pixel: return a pixel at the specified (x,y) location.
00594 %
00595 %    o x,y:  These values define the location of the pixel to return.
00596 %
00597 %    o exception: return any errors or warnings in this structure.
00598 %
00599 */
00600 static MagickBooleanType GetOneAuthenticPixelFromStream(Image *image,const long x,
00601   const long y,PixelPacket *pixel,ExceptionInfo *exception)
00602 {
00603   register PixelPacket
00604     *pixels;
00605 
00606   assert(image != (Image *) NULL);
00607   assert(image->signature == MagickSignature);
00608   *pixel=image->background_color;
00609   pixels=GetPixelStream(image,x,y,1,1,exception);
00610   if (pixels != (PixelPacket *) NULL)
00611     return(MagickFalse);
00612   *pixel=(*pixels);
00613   return(MagickTrue);
00614 }
00615 
00616 /*
00617 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00618 %                                                                             %
00619 %                                                                             %
00620 %                                                                             %
00621 +   G e t P i x e l S t r e a m                                               %
00622 %                                                                             %
00623 %                                                                             %
00624 %                                                                             %
00625 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00626 %
00627 %  GetPixelStream() gets pixels from the in-memory or disk pixel cache as
00628 %  defined by the geometry parameters.   A pointer to the pixels is returned if
00629 %  the pixels are transferred, otherwise a NULL is returned.  For streams
00630 %  this method is a no-op.
00631 %
00632 %  The format of the GetPixelStream() method is:
00633 %
00634 %      PixelPacket *GetPixelStream(Image *image,const long x,const long y,
00635 %        const unsigned long columns,const unsigned long rows,
00636 %        ExceptionInfo *exception)
00637 %
00638 %  A description of each parameter follows:
00639 %
00640 %    o image: the image.
00641 %
00642 %    o x,y,columns,rows:  These values define the perimeter of a region of
00643 %      pixels.
00644 %
00645 %    o exception: return any errors or warnings in this structure.
00646 %
00647 */
00648 static PixelPacket *GetPixelStream(Image *image,const long x,const long y,
00649   const unsigned long columns,const unsigned long rows,ExceptionInfo *exception)
00650 {
00651   PixelPacket
00652     *pixels;
00653 
00654   assert(image != (Image *) NULL);
00655   assert(image->signature == MagickSignature);
00656   if (image->debug != MagickFalse)
00657     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00658   pixels=SetPixelStream(image,x,y,columns,rows,exception);
00659   return(pixels);
00660 }
00661 
00662 /*
00663 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00664 %                                                                             %
00665 %                                                                             %
00666 %                                                                             %
00667 +   G e t P i x e l F r o m S t e a m                                         %
00668 %                                                                             %
00669 %                                                                             %
00670 %                                                                             %
00671 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00672 %
00673 %  GetPixelsFromStream() returns the pixels associated with the last call to
00674 %  SetPixelStream() or GetPixelStream().
00675 %
00676 %  The format of the GetPixelsFromStream() method is:
00677 %
00678 %      PixelPacket *GetPixelsFromStream(const Image image)
00679 %
00680 %  A description of each parameter follows:
00681 %
00682 %    o pixels: Method GetPixelsFromStream returns the pixels associated with
00683 %      the last call to SetPixelStream() or GetPixelStream().
00684 %
00685 %    o image: the image.
00686 %
00687 */
00688 static PixelPacket *GetPixelsFromStream(const Image *image)
00689 {
00690   CacheInfo
00691     *cache_info;
00692 
00693   assert(image != (Image *) NULL);
00694   assert(image->signature == MagickSignature);
00695   if (image->debug != MagickFalse)
00696     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
00697   cache_info=(CacheInfo *) image->cache;
00698   assert(cache_info->signature == MagickSignature);
00699   return(cache_info->pixels);
00700 }
00701 
00702 /*
00703 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00704 %                                                                             %
00705 %                                                                             %
00706 %                                                                             %
00707 +   G e t S t r e a m I n f o C l i e n t D a t a                             %
00708 %                                                                             %
00709 %                                                                             %
00710 %                                                                             %
00711 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00712 %
00713 %  GetStreamInfoClientData() gets the stream info client data.
00714 %
00715 %  The format of the SetStreamInfoClientData method is:
00716 %
00717 %      const void *GetStreamInfoClientData(StreamInfo *stream_info)
00718 %
00719 %  A description of each parameter follows:
00720 %
00721 %    o stream_info: the stream info.
00722 %
00723 */
00724 MagickExport const void *GetStreamInfoClientData(StreamInfo *stream_info)
00725 {
00726   assert(stream_info != (StreamInfo *) NULL);
00727   assert(stream_info->signature == MagickSignature);
00728   return(stream_info->client_data);
00729 }
00730 
00731 /*
00732 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00733 %                                                                             %
00734 %                                                                             %
00735 %                                                                             %
00736 +   O p e n S t r e a m                                                       %
00737 %                                                                             %
00738 %                                                                             %
00739 %                                                                             %
00740 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00741 %
00742 %  OpenStream() opens a stream for writing by the StreamImage() method.
00743 %
00744 %  The format of the OpenStream method is:
00745 %
00746 %       MagickBooleanType OpenStream(const ImageInfo *image_info,
00747 %        StreamInfo *stream_info,const char *filename,ExceptionInfo *exception)
00748 %
00749 %  A description of each parameter follows:
00750 %
00751 %    o image_info: the image info.
00752 %
00753 %    o stream_info: the stream info.
00754 %
00755 %    o filename: the stream filename.
00756 %
00757 %    o exception: return any errors or warnings in this structure.
00758 %
00759 */
00760 MagickExport MagickBooleanType OpenStream(const ImageInfo *image_info,
00761   StreamInfo *stream_info,const char *filename,ExceptionInfo *exception)
00762 {
00763   MagickBooleanType
00764     status;
00765 
00766   (void) CopyMagickString(stream_info->stream->filename,filename,MaxTextExtent);
00767   status=OpenBlob(image_info,stream_info->stream,WriteBinaryBlobMode,exception);
00768   return(status);
00769 }
00770 
00771 /*
00772 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00773 %                                                                             %
00774 %                                                                             %
00775 %                                                                             %
00776 %   R e a d S t r e a m                                                       %
00777 %                                                                             %
00778 %                                                                             %
00779 %                                                                             %
00780 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00781 %
00782 %  ReadStream() makes the image pixels available to a user supplied
00783 %  callback method immediately upon reading a scanline with the ReadImage()
00784 %  method.
00785 %
00786 %  The format of the ReadStream() method is:
00787 %
00788 %      Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
00789 %        ExceptionInfo *exception)
00790 %
00791 %  A description of each parameter follows:
00792 %
00793 %    o image_info: the image info.
00794 %
00795 %    o stream: a callback method.
00796 %
00797 %    o exception: return any errors or warnings in this structure.
00798 %
00799 */
00800 MagickExport Image *ReadStream(const ImageInfo *image_info,StreamHandler stream,
00801   ExceptionInfo *exception)
00802 {
00803   CacheMethods
00804     cache_methods;
00805 
00806   Image
00807     *image;
00808 
00809   ImageInfo
00810     *read_info;
00811 
00812   /*
00813     Stream image pixels.
00814   */
00815   assert(image_info != (ImageInfo *) NULL);
00816   assert(image_info->signature == MagickSignature);
00817   if (image_info->debug != MagickFalse)
00818     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
00819       image_info->filename);
00820   assert(exception != (ExceptionInfo *) NULL);
00821   assert(exception->signature == MagickSignature);
00822   read_info=CloneImageInfo(image_info);
00823   (void) GetCacheInfo(&read_info->cache,0);
00824   GetCacheMethods(&cache_methods);
00825   cache_methods.acquire_pixel_handler=AcquirePixelStream;
00826   cache_methods.acquire_indexes_from_handler=AcquireIndexesFromStream;
00827   cache_methods.acquire_pixels_from_handler=AcquirePixelsFromStream;
00828   cache_methods.get_pixel_handler=GetPixelStream;
00829   cache_methods.set_pixel_handler=SetPixelStream;
00830   cache_methods.sync_pixel_handler=SyncPixelStream;
00831   cache_methods.get_pixels_from_handler=GetPixelsFromStream;
00832   cache_methods.get_indexes_from_handler=GetIndexesFromStream;
00833   cache_methods.acquire_one_pixel_from_handler=GetOneVirtualPixelFromStream;
00834   cache_methods.get_one_pixel_from_handler=GetOneAuthenticPixelFromStream;
00835   cache_methods.destroy_pixel_handler=DestroyPixelStream;
00836   SetCacheMethods(read_info->cache,&cache_methods);
00837   read_info->stream=stream;
00838   image=ReadImage(read_info,exception);
00839   read_info=DestroyImageInfo(read_info);
00840   return(image);
00841 }
00842 
00843 /*
00844 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00845 %                                                                             %
00846 %                                                                             %
00847 %                                                                             %
00848 +   S e t P i x e l S t r e a m                                               %
00849 %                                                                             %
00850 %                                                                             %
00851 %                                                                             %
00852 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00853 %
00854 %  SetPixelStream() allocates an area to store image pixels as defined by the
00855 %  region rectangle and returns a pointer to the area.  This area is
00856 %  subsequently transferred from the pixel cache with method SyncPixelStream().
00857 %  A pointer to the pixels is returned if the pixels are transferred,
00858 %  otherwise a NULL is returned.
00859 %
00860 %  The format of the SetPixelStream() method is:
00861 %
00862 %      PixelPacket *SetPixelStream(Image *image,const long x,const long y,
00863 %        const unsigned long columns,const unsigned long rows,
00864 %        ExceptionInfo *exception)
00865 %
00866 %  A description of each parameter follows:
00867 %
00868 %    o image: the image.
00869 %
00870 %    o x,y,columns,rows:  These values define the perimeter of a region of
00871 %      pixels.
00872 %
00873 */
00874 static PixelPacket *SetPixelStream(Image *image,const long x,const long y,
00875   const unsigned long columns,const unsigned long rows,ExceptionInfo *exception)
00876 {
00877   CacheInfo
00878     *cache_info;
00879 
00880   MagickSizeType
00881     number_pixels;
00882 
00883   size_t
00884     length;
00885 
00886   StreamHandler
00887     stream_handler;
00888 
00889   /*
00890     Validate pixel cache geometry.
00891   */
00892   assert(image != (Image *) NULL);
00893   if ((x < 0) || (y < 0) || ((x+(long) columns) > (long) image->columns) ||
00894       ((y+(long) rows) > (long) image->rows) || (columns == 0) || (rows == 0))
00895     {
00896       (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
00897         "ImageDoesNotContainTheStreamGeometry","`%s'",image->filename);
00898       return((PixelPacket *) NULL);
00899     }
00900   stream_handler=GetBlobStreamHandler(image);
00901   if (stream_handler == (StreamHandler) NULL)
00902     {
00903       (void) ThrowMagickException(exception,GetMagickModule(),StreamError,
00904         "NoStreamHandlerIsDefined","`%s'",image->filename);
00905       return((PixelPacket *) NULL);
00906     }
00907   cache_info=(CacheInfo *) image->cache;
00908   assert(cache_info->signature == MagickSignature);
00909   if ((image->storage_class != GetCacheClass(image->cache)) ||
00910       (image->colorspace != GetCacheColorspace(image->cache)))
00911     {
00912       if (GetCacheClass(image->cache) == UndefinedClass)
00913         (void) stream_handler(image,(const void *) NULL,(size_t)
00914           cache_info->columns);
00915       cache_info->storage_class=image->storage_class;
00916       cache_info->colorspace=image->colorspace;
00917       cache_info->columns=image->columns;
00918       cache_info->rows=image->rows;
00919       image->cache=cache_info;
00920     }
00921   /*
00922     Pixels are stored in a temporary buffer until they are synced to the cache.
00923   */
00924   cache_info->columns=columns;
00925   cache_info->rows=rows;
00926   number_pixels=(MagickSizeType) columns*rows;
00927   length=(size_t) number_pixels*sizeof(PixelPacket);
00928   if ((image->storage_class == PseudoClass) ||
00929       (image->colorspace == CMYKColorspace))
00930     length+=number_pixels*sizeof(IndexPacket);
00931   if (cache_info->pixels == (PixelPacket *) NULL)
00932     {
00933       cache_info->pixels=(PixelPacket *) AcquireMagickMemory(length);
00934       cache_info->length=(MagickSizeType) length;
00935     }
00936   else
00937     if (cache_info->length < (MagickSizeType) length)
00938       {
00939         cache_info->pixels=(PixelPacket *) ResizeMagickMemory(
00940           cache_info->pixels,length);
00941         cache_info->length=(MagickSizeType) length;
00942       }
00943   if (cache_info->pixels == (void *) NULL)
00944     ThrowFatalException(ResourceLimitFatalError,
00945       "UnableToGetVirtualPixels");
00946   cache_info->indexes=(IndexPacket *) NULL;
00947   if ((image->storage_class == PseudoClass) ||
00948       (image->colorspace == CMYKColorspace))
00949     cache_info->indexes=(IndexPacket *) (cache_info->pixels+number_pixels);
00950   return(cache_info->pixels);
00951 }
00952 
00953 /*
00954 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00955 %                                                                             %
00956 %                                                                             %
00957 %                                                                             %
00958 +   S e t S t r e a m I n f o C l i e n t D a t a                             %
00959 %                                                                             %
00960 %                                                                             %
00961