Home | History | Annotate | Download | only in lib
      1 // This may look like C code, but it is really -*- C++ -*-
      2 //
      3 // Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002
      4 // Copyright Dirk Lemstra 2014-2015
      5 //
      6 // Implementation of ImageRef
      7 //
      8 // This is an internal implementation class.
      9 //
     10 
     11 #define MAGICKCORE_IMPLEMENTATION  1
     12 #define MAGICK_PLUSPLUS_IMPLEMENTATION 1
     13 
     14 #include "Magick++/ImageRef.h"
     15 #include "Magick++/Exception.h"
     16 #include "Magick++/Options.h"
     17 
     18 Magick::ImageRef::ImageRef(void)
     19   : _image(0),
     20     _mutexLock(),
     21     _options(new Options),
     22     _refCount(1)
     23 {
     24   GetPPException;
     25   _image=AcquireImage(_options->imageInfo(),exceptionInfo);
     26   ThrowPPException(false);
     27 }
     28 
     29 Magick::ImageRef::ImageRef(MagickCore::Image *image_)
     30   : _image(image_),
     31     _mutexLock(),
     32     _options(new Options),
     33     _refCount(1)
     34 {
     35 }
     36 
     37 Magick::ImageRef::~ImageRef(void)
     38 {
     39   // Deallocate image
     40   if (_image != (MagickCore::Image*) NULL)
     41     _image=DestroyImageList(_image);
     42 
     43   // Deallocate image options
     44   delete _options;
     45   _options=(Options *) NULL;
     46 }
     47 
     48 size_t Magick::ImageRef::decrease()
     49 {
     50   size_t
     51     count;
     52 
     53   _mutexLock.lock();
     54   if (_refCount == 0)
     55     {
     56       _mutexLock.unlock();
     57       throwExceptionExplicit(MagickCore::OptionError,
     58         "Invalid call to decrease");
     59       return(0);
     60     }
     61   count=--_refCount;
     62   _mutexLock.unlock();
     63   return(count);
     64 }
     65 
     66 MagickCore::Image *&Magick::ImageRef::image(void)
     67 {
     68   return(_image);
     69 }
     70 
     71 void Magick::ImageRef::increase()
     72 {
     73   _mutexLock.lock();
     74   _refCount++;
     75   _mutexLock.unlock();
     76 }
     77 
     78 bool Magick::ImageRef::isShared()
     79 {
     80   bool
     81     isShared;
     82 
     83   _mutexLock.lock();
     84   isShared=(_refCount > 1);
     85   _mutexLock.unlock();
     86   return(isShared);
     87 }
     88 
     89 void  Magick::ImageRef::options(Magick::Options *options_)
     90 {
     91   delete _options;
     92   _options=options_;
     93 }
     94 
     95 Magick::Options *Magick::ImageRef::options(void)
     96 {
     97   return(_options);
     98 }
     99 
    100 Magick::ImageRef *Magick::ImageRef::replaceImage(ImageRef *imgRef,
    101   MagickCore::Image *replacement_)
    102 {
    103   Magick::ImageRef
    104     *instance;
    105 
    106   imgRef->_mutexLock.lock();
    107   if (imgRef->_refCount == 1)
    108     {
    109       // We can replace the image if we own it.
    110       instance=imgRef;
    111       if (imgRef->_image != (MagickCore::Image*) NULL)
    112         (void) DestroyImageList(imgRef->_image);
    113       imgRef->_image=replacement_;
    114       imgRef->_mutexLock.unlock();
    115     }
    116   else
    117     {
    118       // We don't own the image, create a new ImageRef instance.
    119       instance=new ImageRef(replacement_,imgRef->_options);
    120       imgRef->_refCount--;
    121       imgRef->_mutexLock.unlock();
    122     }
    123   return(instance);
    124 }
    125 
    126 std::string Magick::ImageRef::signature(const bool force_)
    127 {
    128   const char
    129     *property;
    130 
    131   // Re-calculate image signature if necessary
    132   GetPPException;
    133   _mutexLock.lock();
    134   property=(const char *) NULL;
    135   if (!force_ && (_image->taint == MagickFalse))
    136     property=GetImageProperty(_image,"Signature",exceptionInfo);
    137   if (property == (const char *) NULL)
    138     {
    139       (void) SignatureImage(_image,exceptionInfo);
    140       property=GetImageProperty(_image,"Signature",exceptionInfo);
    141     }
    142   _mutexLock.unlock();
    143   ThrowPPException(true);
    144 
    145   return(std::string(property));
    146 }
    147 
    148 Magick::ImageRef::ImageRef(MagickCore::Image *image_,const Options *options_)
    149   : _image(image_),
    150     _mutexLock(),
    151     _options(0),
    152     _refCount(1)
    153 {
    154   _options=new Options(*options_);
    155 }