diff --git a/Magick++/lib/Blob.cpp b/Magick++/lib/Blob.cpp
new file mode 100644
index 0000000..96b97ec
--- /dev/null
+++ b/Magick++/lib/Blob.cpp
@@ -0,0 +1,169 @@
+// This may look like C code, but it is really -*- C++ -*-
+//
+// Copyright Bob Friesenhahn, 1999, 2000, 2001, 2002, 2004
+//
+// Implementation of Blob
+//
+
+#define MAGICKCORE_IMPLEMENTATION 1
+#define MAGICK_PLUSPLUS_IMPLEMENTATION 1
+
+#include "Magick++/Include.h"
+#include "Magick++/Blob.h"
+#include "Magick++/BlobRef.h"
+
+#include <string.h>
+
+//
+// Implementation of Magick::Blob
+//
+
+// Default constructor
+Magick::Blob::Blob ( void )
+ : _blobRef(new Magick::BlobRef( 0, 0 ))
+{
+}
+
+// Construct with data
+Magick::Blob::Blob ( const void* data_, size_t length_ )
+ : _blobRef(new Magick::BlobRef( data_, length_ ))
+{
+}
+
+// Copy constructor (reference counted)
+Magick::Blob::Blob ( const Magick::Blob& blob_ )
+ : _blobRef(blob_._blobRef)
+{
+ // Increase reference count
+ Lock( &_blobRef->_mutexLock );
+ ++_blobRef->_refCount;
+}
+
+// Destructor (reference counted)
+Magick::Blob::~Blob ()
+{
+ bool doDelete = false;
+ {
+ Lock( &_blobRef->_mutexLock );
+ if ( --_blobRef->_refCount == 0 )
+ doDelete = true;
+ }
+
+ if ( doDelete )
+ {
+ // Delete old blob reference with associated data
+ delete _blobRef;
+ }
+ _blobRef=0;
+}
+
+// Assignment operator (reference counted)
+Magick::Blob& Magick::Blob::operator= ( const Magick::Blob& blob_ )
+{
+ if(this != &blob_)
+ {
+ {
+ Lock( &blob_._blobRef->_mutexLock );
+ ++blob_._blobRef->_refCount;
+ }
+ bool doDelete = false;
+ {
+ Lock( &_blobRef->_mutexLock );
+ if ( --_blobRef->_refCount == 0 )
+ doDelete = true;
+ }
+ if ( doDelete )
+ {
+ delete _blobRef;
+ }
+ _blobRef = blob_._blobRef;
+ }
+ return *this;
+}
+
+// Update object contents from Base64-encoded string representation.
+void Magick::Blob::base64 ( const std::string base64_ )
+{
+ size_t length;
+
+ unsigned char *decoded =
+ Base64Decode( base64_.c_str(), &length );
+
+ if(decoded)
+ updateNoCopy( static_cast<void*>(decoded), length,
+ Magick::Blob::MallocAllocator );
+}
+
+// Return Base64-encoded string representation.
+std::string Magick::Blob::base64 ( void )
+{
+ size_t encoded_length = 0;
+
+ char *encoded =
+ Base64Encode(static_cast<const unsigned char*>(data()), length(), &encoded_length);
+
+ if(encoded)
+ {
+ std::string result(encoded,encoded_length);
+ encoded=(char *) RelinquishMagickMemory(encoded);
+ return result;
+ }
+
+ return std::string();
+}
+
+// Update object contents, making a copy of the supplied data.
+// Any existing data in the object is deallocated.
+void Magick::Blob::update ( const void* data_, size_t length_ )
+{
+ bool doDelete = false;
+ {
+ Lock( &_blobRef->_mutexLock );
+ if ( --_blobRef->_refCount == 0 )
+ doDelete = true;
+ }
+ if ( doDelete )
+ {
+ // Delete old blob reference with associated data
+ delete _blobRef;
+ }
+
+ _blobRef = new Magick::BlobRef( data_, length_ );
+}
+
+// Update object contents, using supplied pointer directly (no copy)
+// Any existing data in the object is deallocated. The user must
+// ensure that the pointer supplied is not deleted or otherwise
+// modified after it has been supplied to this method.
+void Magick::Blob::updateNoCopy ( void* data_, size_t length_,
+ Magick::Blob::Allocator allocator_ )
+{
+ bool doDelete = false;
+ {
+ Lock( &_blobRef->_mutexLock );
+ if ( --_blobRef->_refCount == 0 )
+ doDelete = true;
+ }
+ if ( doDelete )
+ {
+ // Delete old blob reference with associated data
+ delete _blobRef;
+ }
+ _blobRef = new Magick::BlobRef( 0, 0 );
+ _blobRef->_data = data_;
+ _blobRef->_length = length_;
+ _blobRef->_allocator = allocator_;
+}
+
+// Obtain pointer to data
+const void* Magick::Blob::data( void ) const
+{
+ return _blobRef->_data;
+}
+
+// Obtain data length
+size_t Magick::Blob::length( void ) const
+{
+ return _blobRef->_length;
+}
+