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 }