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
ImageRef(void)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
ImageRef(MagickCore::Image * image_)29 Magick::ImageRef::ImageRef(MagickCore::Image *image_)
30 : _image(image_),
31 _mutexLock(),
32 _options(new Options),
33 _refCount(1)
34 {
35 }
36
~ImageRef(void)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
decrease()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
image(void)66 MagickCore::Image *&Magick::ImageRef::image(void)
67 {
68 return(_image);
69 }
70
increase()71 void Magick::ImageRef::increase()
72 {
73 _mutexLock.lock();
74 _refCount++;
75 _mutexLock.unlock();
76 }
77
isShared()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
options(Magick::Options * options_)89 void Magick::ImageRef::options(Magick::Options *options_)
90 {
91 delete _options;
92 _options=options_;
93 }
94
options(void)95 Magick::Options *Magick::ImageRef::options(void)
96 {
97 return(_options);
98 }
99
replaceImage(ImageRef * imgRef,MagickCore::Image * replacement_)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
signature(const bool force_)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
ImageRef(MagickCore::Image * image_,const Options * options_)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 }