diff --git a/src/accountmigrationview.cpp b/src/accountmigrationview.cpp
index a6d9a052cc5bbe19b8dd3477aa04e62df96a09d9..382186fd87655db0944372f8670d0319b17367a1 100644
--- a/src/accountmigrationview.cpp
+++ b/src/accountmigrationview.cpp
@@ -240,19 +240,22 @@ build_migration_view(AccountMigrationView *view)
     }
 
     /* get the current or default profile avatar */
-    auto default_avatar = Interfaces::PixbufManipulator().generateAvatar("", "");
-    auto default_scaled = Interfaces::PixbufManipulator().scaleAndFrame(default_avatar.get(), QSize(AVATAR_WIDTH, AVATAR_HEIGHT));
-    auto photo = default_scaled;
+    GdkPixbuf *p = pxbm_generate_avatar("", "");
+    GdkPixbuf *photo = pxbm_scale_and_frame(
+        p, QSize(AVATAR_WIDTH, AVATAR_HEIGHT));
+    g_object_unref(p);
     auto photostr = (*priv->accountInfo_)->profileInfo.avatar;
     if (!photostr.isEmpty()) {
         QByteArray byteArray = photostr.toUtf8();
-        QVariant avatar = Interfaces::PixbufManipulator().personPhoto(byteArray);
-        auto pixbuf_photo = Interfaces::PixbufManipulator().scaleAndFrame(avatar.value<std::shared_ptr<GdkPixbuf>>().get(), QSize(AVATAR_WIDTH, AVATAR_HEIGHT));
-        if (avatar.isValid()) {
-            photo = pixbuf_photo;
+        GdkPixbuf *p = pxbm_person_photo(byteArray);
+        if (p) {
+            g_object_unref(photo);
+            photo = pxbm_scale_and_frame(p, QSize(AVATAR_WIDTH, AVATAR_HEIGHT));
+            g_object_unref(p);
         }
     }
-    gtk_image_set_from_pixbuf(GTK_IMAGE(priv->image_avatar), photo.get());
+    gtk_image_set_from_pixbuf(GTK_IMAGE(priv->image_avatar), photo);
+    g_object_unref(photo);
 
     // CSS styles
     auto provider = gtk_css_provider_new();
diff --git a/src/avatarmanipulation.cpp b/src/avatarmanipulation.cpp
index 1319c9223acaa23af710aae3eb1759b1fd94bbda..049bc257cc40f8a070cbae6106866cbfc90e64d6 100644
--- a/src/avatarmanipulation.cpp
+++ b/src/avatarmanipulation.cpp
@@ -23,7 +23,6 @@
 /* LRC */
 #include <api/newaccountmodel.h>
 #include <api/avmodel.h>
-#include <globalinstances.h>
 #include <QSize>
 
 /* client */
@@ -235,19 +234,22 @@ set_state(AvatarManipulation *self, AvatarManipulationState state)
         case AVATAR_MANIPULATION_STATE_CURRENT:
         {
             /* get the current or default profile avatar */
-            auto default_avatar = Interfaces::PixbufManipulator().generateAvatar("", "");
-            auto default_scaled = Interfaces::PixbufManipulator().scaleAndFrame(default_avatar.get(), QSize(AVATAR_WIDTH, AVATAR_HEIGHT));
-            auto photo = default_scaled;
+            GdkPixbuf *default_avatar = pxbm_generate_avatar("", "");
+            GdkPixbuf *photo = pxbm_scale_and_frame(
+                default_avatar, QSize(AVATAR_WIDTH, AVATAR_HEIGHT));
+            g_object_unref(default_avatar);
             if ((priv->accountInfo_ && (*priv->accountInfo_)) || priv->temporaryAvatar) {
                 auto photostr = priv->temporaryAvatar? priv->temporaryAvatar : (*priv->accountInfo_)->profileInfo.avatar;
                 QByteArray byteArray = photostr.toUtf8();
-                QVariant avatar = Interfaces::PixbufManipulator().personPhoto(byteArray);
-                if (avatar.isValid()) {
-                    auto size = QSize(AVATAR_WIDTH, AVATAR_HEIGHT);
-                    photo = Interfaces::PixbufManipulator().scaleAndFrame(avatar.value<std::shared_ptr<GdkPixbuf>>().get(), size);
+                GdkPixbuf *avatar = pxbm_person_photo(byteArray);
+                if (avatar) {
+                    g_object_unref(photo);
+                    photo = pxbm_scale_and_frame(avatar, QSize(AVATAR_WIDTH, AVATAR_HEIGHT));
+                    g_object_unref(avatar);
                 }
             }
-            gtk_image_set_from_pixbuf(GTK_IMAGE(priv->image_avatar), photo.get());
+            gtk_image_set_from_pixbuf(GTK_IMAGE(priv->image_avatar), photo);
+            g_object_unref(photo);
 
             gtk_stack_set_visible_child_name(GTK_STACK(priv->stack_views), "page_avatar");
 
diff --git a/src/chatview.cpp b/src/chatview.cpp
index d07dd30ca9233cb15a77bd09f8b266b5ec466703..34682a86feacf401f3dd0e325d0e65706d1ae43c 100644
--- a/src/chatview.cpp
+++ b/src/chatview.cpp
@@ -1036,15 +1036,14 @@ load_participants_images(ChatView *self)
         auto& contact = (*priv->accountInfo_)->contactModel->getContact(contactUri);
         std::string avatar_str = contact.profileInfo.avatar.toStdString();
         if (avatar_str.empty()) {
-            auto var_photo = Interfaces::PixbufManipulator().conversationPhoto(
+            GdkPixbuf *p = pxbm_conversation_photo(
                 *priv->conversation_,
                 **(priv->accountInfo_),
                 QSize(AVATAR_WIDTH, AVATAR_HEIGHT),
                 contact.isPresent
             );
-            auto image = var_photo.value<std::shared_ptr<GdkPixbuf>>();
-            auto ba = Interfaces::PixbufManipulator().toByteArray(var_photo);
-            avatar_str = ba.toBase64().toStdString();
+            avatar_str = pxbm_to_QByteArray(p).toBase64().toStdString();
+            g_object_unref(p);
         }
         webkit_chat_container_set_sender_image(
             WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container),
@@ -1058,11 +1057,12 @@ load_participants_images(ChatView *self)
     // For this account
     std::string avatar_str = (*priv->accountInfo_)->profileInfo.avatar.toStdString();
     if (avatar_str.empty()) {
-        auto default_photo = QVariant::fromValue(Interfaces::PixbufManipulator().scaleAndFrame(
-            Interfaces::PixbufManipulator().generateAvatar("", "").get(),
-            QSize(AVATAR_WIDTH, AVATAR_HEIGHT), false));
-        auto ba = Interfaces::PixbufManipulator().toByteArray(default_photo);
-        avatar_str = ba.toBase64().toStdString();
+        GdkPixbuf *p = pxbm_generate_avatar("", "");
+        GdkPixbuf *default_photo = pxbm_scale_and_frame(
+            p, QSize(AVATAR_WIDTH, AVATAR_HEIGHT), false);
+        g_object_unref(p);
+        avatar_str = pxbm_to_QByteArray(default_photo).toBase64().toStdString();
+        g_object_unref(default_photo);
     }
     webkit_chat_container_set_sender_image(
         WEBKIT_CHAT_CONTAINER(priv->webkit_chat_container),
diff --git a/src/client.cpp b/src/client.cpp
index a27e71598581468f12970db407e07b724ce64501..68f6035b9fad9585a22b8840260ef751af195ad7 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -540,7 +540,6 @@ client_startup(GApplication *app)
     }
 
     /* init delegates */
-    GlobalInstances::setPixmapManipulator(std::unique_ptr<Interfaces::PixbufManipulator>(new Interfaces::PixbufManipulator()));
     GlobalInstances::setDBusErrorHandler(std::unique_ptr<Interfaces::DBusErrorHandler>(new Interfaces::DBusErrorHandler()));
 
     /* Override theme since we don't have appropriate icons for a dark them (yet) */
diff --git a/src/conversationsview.cpp b/src/conversationsview.cpp
index f4960f268af22a3ee1868c2c424ea4107b516a9d..c57929379fdca92b7c43d5cd20dbf84fdab2599a 100644
--- a/src/conversationsview.cpp
+++ b/src/conversationsview.cpp
@@ -31,7 +31,6 @@
 #include <QSize>
 
 // LRC
-#include <globalinstances.h>
 #include <api/conversationmodel.h>
 #include <api/contactmodel.h>
 #include <api/call.h>
@@ -132,21 +131,20 @@ render_contact_photo(G_GNUC_UNUSED GtkTreeViewColumn *tree_column,
             isBanned = contactInfo.isBanned;
         } catch (...) { }
     }
-    std::shared_ptr<GdkPixbuf> image;
     static lrc::api::conversation::Info invalidConversation;
     auto convOpt = (*priv->accountInfo_)->conversationModel->getConversationForUid(uid);
-    auto var_photo = GlobalInstances::pixmapManipulator().conversationPhoto(
+    GdkPixbuf *p = pxbm_conversation_photo(
         convOpt ? convOpt->get() : invalidConversation,
         **(priv->accountInfo_),
         QSize(50, 50),
         isPresent
     );
-    image = var_photo.value<std::shared_ptr<GdkPixbuf>>();
 
     // set the width of the cell rendered to the width of the photo
     // so that the other renderers are shifted to the right
     g_object_set(G_OBJECT(cell), "width", 50, NULL);
-    g_object_set(G_OBJECT(cell), "pixbuf", image.get(), NULL);
+    g_object_set(G_OBJECT(cell), "pixbuf", p, NULL);
+    g_object_unref(p);
 
     // Banned contacts should be displayed with grey bg
     g_object_set(G_OBJECT(cell), "cell-background", isBanned ? "#BDBDBD" : NULL, NULL);
diff --git a/src/currentcallview.cpp b/src/currentcallview.cpp
index d38055138b2ceed11a16f4f38b990c324dd0d4b6..ae724e0794febc166d3232ad7e0f85997c21e1c6 100644
--- a/src/currentcallview.cpp
+++ b/src/currentcallview.cpp
@@ -36,7 +36,6 @@
 #include <api/contactmodel.h>
 #include <api/newcallmodel.h>
 #include <api/newcodecmodel.h>
-#include <globalinstances.h>
 #include <smartinfohub.h>
 
 // Gtk
@@ -1262,9 +1261,11 @@ void
 CppImpl::add_present_contact(const QString& uri, const QString& custom_data, RowType custom_type, const QString& accountId)
 {
     QString bestName = uri, bestUri = uri;
-    auto default_avatar = Interfaces::PixbufManipulator().generateAvatar("", "");
-    auto default_scaled = Interfaces::PixbufManipulator().scaleAndFrame(default_avatar.get(), QSize(48, 48), true, IconStatus::PRESENT);
-    auto photo = default_scaled;
+    GdkPixbuf *default_avatar = pxbm_generate_avatar("", "");
+    GdkPixbuf *photo = pxbm_scale_and_frame(
+        default_avatar,
+        QSize(48, 48), true, IconStatus::PRESENT);
+    g_object_unref(default_avatar);
 
     try {
         auto &accInfo = lrc_.getAccountModel().getAccountInfo(accountId);
@@ -1282,10 +1283,12 @@ CppImpl::add_present_contact(const QString& uri, const QString& custom_data, Row
 
         if (!photostr.isEmpty()) {
             QByteArray byteArray = photostr.toUtf8();
-            QVariant avatar = Interfaces::PixbufManipulator().personPhoto(byteArray);
-            auto pixbuf_photo = Interfaces::PixbufManipulator().scaleAndFrame(avatar.value<std::shared_ptr<GdkPixbuf>>().get(), QSize(48, 48), true, IconStatus::PRESENT);
-            if (avatar.isValid()) {
-                photo = pixbuf_photo;
+            GdkPixbuf *p = pxbm_person_photo(byteArray);
+            if (p) {
+                g_object_unref(photo);
+                photo = pxbm_scale_and_frame(
+                    p, QSize(48, 48), true, IconStatus::PRESENT);
+                g_object_unref(p);
             }
         } else {
             auto name = alias.isEmpty()? contactInfo.registeredName : alias;
@@ -1296,8 +1299,11 @@ CppImpl::add_present_contact(const QString& uri, const QString& custom_data, Row
                 fullUri = "ring:" + fullUri;
             else
                 fullUri = "sip:" + fullUri;
-            photo = Interfaces::PixbufManipulator().generateAvatar(firstLetter.toStdString(), fullUri.toStdString());
-            photo = Interfaces::PixbufManipulator().scaleAndFrame(photo.get(), QSize(48, 48), true, IconStatus::PRESENT);
+            GdkPixbuf *photo_tmp = pxbm_generate_avatar(
+                firstLetter.toStdString(), fullUri.toStdString());
+            photo = pxbm_scale_and_frame(
+                photo_tmp, QSize(48, 48), true, IconStatus::PRESENT);
+            g_object_unref(photo_tmp);
         }
     } catch (const std::out_of_range&) {
         // ContactModel::getContact() exception
@@ -1320,7 +1326,8 @@ CppImpl::add_present_contact(const QString& uri, const QString& custom_data, Row
     }
 
     auto* box_item = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
-    auto* avatar = gtk_image_new_from_pixbuf(photo.get());
+    auto* avatar = gtk_image_new_from_pixbuf(photo);
+    g_object_unref(photo);
     auto* info = gtk_label_new(nullptr);
     gtk_label_set_markup(GTK_LABEL(info), text);
     gtk_container_add(GTK_CONTAINER(box_item), GTK_WIDGET(avatar));
@@ -1337,17 +1344,15 @@ void
 CppImpl::add_conference(const VectorString& uris, const QString& custom_data, const QString& accountId)
 {
     GError *error = nullptr;
-    auto default_avatar = std::shared_ptr<GdkPixbuf>(
-        gdk_pixbuf_new_from_resource_at_scale("/net/jami/JamiGnome/contacts_list", 50, 50, true, &error),
-        g_object_unref
-    );
-    if (default_avatar == nullptr) {
+    GdkPixbuf *default_avatar = gdk_pixbuf_new_from_resource_at_scale(
+        "/net/jami/JamiGnome/contacts_list", 50, 50, true, &error);
+    if (!default_avatar) {
         g_debug("Could not load icon: %s", error->message);
         g_clear_error(&error);
         return;
     }
-    auto default_scaled = Interfaces::PixbufManipulator().scaleAndFrame(default_avatar.get(), QSize(50, 50));
-    auto photo = default_scaled;
+    GdkPixbuf *photo = pxbm_scale_and_frame(default_avatar, QSize(50, 50));
+    g_object_unref(default_avatar);
 
     std::string label;
     auto idx = 0;
@@ -1382,7 +1387,8 @@ CppImpl::add_conference(const VectorString& uris, const QString& custom_data, co
     );
 
     auto* box_item = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
-    auto* avatar = gtk_image_new_from_pixbuf(photo.get());
+    auto* avatar = gtk_image_new_from_pixbuf(photo);
+    g_object_unref(photo);
     auto* info = gtk_label_new(nullptr);
     gtk_label_set_markup(GTK_LABEL(info), text);
     gtk_container_add(GTK_CONTAINER(box_item), GTK_WIDGET(avatar));
@@ -1398,12 +1404,13 @@ CppImpl::add_conference(const VectorString& uris, const QString& custom_data, co
 void
 CppImpl::add_transfer_contact(const std::string& uri)
 {
-    auto* box_item = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
-    auto pixbufmanipulator = Interfaces::PixbufManipulator();
-    auto image_buf = pixbufmanipulator.generateAvatar("", uri.empty() ? uri : "sip" + uri);
-    auto scaled = pixbufmanipulator.scaleAndFrame(image_buf.get(), QSize(48, 48));
-    auto* avatar = gtk_image_new_from_pixbuf(scaled.get());
-    auto* address = gtk_label_new(uri.c_str());
+    auto *box_item = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
+    GdkPixbuf *p = pxbm_generate_avatar("", uri.empty() ? uri : "sip" + uri);
+    GdkPixbuf *scaled = pxbm_scale_and_frame(p, QSize(48, 48));
+    g_object_unref(p);
+    auto *avatar = gtk_image_new_from_pixbuf(scaled);
+    g_object_unref(scaled);
+    auto *address = gtk_label_new(uri.c_str());
     gtk_container_add(GTK_CONTAINER(box_item), GTK_WIDGET(avatar));
     gtk_container_add(GTK_CONTAINER(box_item), GTK_WIDGET(address));
     gtk_list_box_insert(GTK_LIST_BOX(widgets->list_conversations), GTK_WIDGET(box_item), -1);
@@ -1852,14 +1859,14 @@ CppImpl::updateNameAndPhoto()
     } catch (std::out_of_range& e) {
     }
 
-    QVariant var_i = GlobalInstances::pixmapManipulator().conversationPhoto(
+    GdkPixbuf *p = pxbm_conversation_photo(
         *conversation,
         **(accountInfo),
         photoSize,
         false
     );
-    std::shared_ptr<GdkPixbuf> image = var_i.value<std::shared_ptr<GdkPixbuf>>();
-    gtk_image_set_from_pixbuf(GTK_IMAGE(widgets->image_peer), image.get());
+    gtk_image_set_from_pixbuf(GTK_IMAGE(widgets->image_peer), p);
+    g_object_unref(p);
 
     auto contacts = (*accountInfo)->conversationModel->peersForConversation(conversation->uid);
     if (contacts.empty()) return;
diff --git a/src/incomingcallview.cpp b/src/incomingcallview.cpp
index 45cb117e8d61c7d3b1e60c0a859de92ae1b3e084..16280f9c331d5a3cad6abf8e3982710d99c9abc0 100644
--- a/src/incomingcallview.cpp
+++ b/src/incomingcallview.cpp
@@ -39,7 +39,6 @@
 #include <api/contactmodel.h>
 #include <api/conversationmodel.h>
 #include <api/contact.h>
-#include <globalinstances.h>
 
 // Client
 #include "chatview.h"
@@ -268,14 +267,14 @@ update_name_and_photo(IncomingCallView *view)
     g_return_if_fail(IS_INCOMING_CALL_VIEW(view));
     auto priv = INCOMING_CALL_VIEW_GET_PRIVATE(view);
 
-    QVariant var_i = GlobalInstances::pixmapManipulator().conversationPhoto(
+    GdkPixbuf *p = pxbm_conversation_photo(
         *priv->conversation_,
         **(priv->accountInfo_),
         QSize(110, 110),
         false
     );
-    std::shared_ptr<GdkPixbuf> image = var_i.value<std::shared_ptr<GdkPixbuf>>();
-    gtk_image_set_from_pixbuf(GTK_IMAGE(priv->image_incoming), image.get());
+    gtk_image_set_from_pixbuf(GTK_IMAGE(priv->image_incoming), p);
+    g_object_unref(p);
 
     try {
         auto contacts = (*priv->accountInfo_)->conversationModel->peersForConversation(priv->conversation_->uid);
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index fde3a8361ec0464637da5f16259b255a59b68e29..715199938655789ed722deb7914089a97076179b 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -274,24 +274,26 @@ render_account_avatar(GtkCellLayout*,
     } else if (statusStr == "CONNECTED") {
         iconStatus = IconStatus::CONNECTED;
     }
-    auto default_avatar = Interfaces::PixbufManipulator().generateAvatar("", "");
-    auto default_scaled = Interfaces::PixbufManipulator().scaleAndFrame(default_avatar.get(), QSize(32, 32), true, iconStatus);
-    auto photo = default_scaled;
+    GdkPixbuf *default_avatar = pxbm_generate_avatar("", "");
+    GdkPixbuf *photo = pxbm_scale_and_frame(default_avatar, QSize(32, 32), true, iconStatus);
+    g_object_unref(default_avatar);
 
     std::string photostr = avatar;
     if (!photostr.empty()) {
         QByteArray byteArray(photostr.c_str(), photostr.length());
-        QVariant avatar = Interfaces::PixbufManipulator().personPhoto(byteArray);
-        auto pixbuf_photo = Interfaces::PixbufManipulator().scaleAndFrame(avatar.value<std::shared_ptr<GdkPixbuf>>().get(), QSize(32, 32), true, iconStatus);
-        if (avatar.isValid()) {
-            photo = pixbuf_photo;
+        GdkPixbuf *p = pxbm_person_photo(byteArray);
+        if (p) {
+            g_object_unref(photo);
+            photo = pxbm_scale_and_frame(p, QSize(32, 32), true, iconStatus);
+            g_object_unref(p);
         }
     }
 
     g_object_set(G_OBJECT(cell), "width", 32, nullptr);
     g_object_set(G_OBJECT(cell), "height", 32, nullptr);
-    g_object_set(G_OBJECT(cell), "pixbuf", photo.get(), nullptr);
+    g_object_set(G_OBJECT(cell), "pixbuf", photo, nullptr);
 
+    g_object_unref(photo);
     g_free(status);
     g_free(avatar);
     g_free(id);
diff --git a/src/native/pixbufmanipulator.cpp b/src/native/pixbufmanipulator.cpp
index 8c6ebf26147b7cdafe4193912e2e3787bb54cd48..8201b7f59e732ca6ba6b41a453a253841e7633a4 100644
--- a/src/native/pixbufmanipulator.cpp
+++ b/src/native/pixbufmanipulator.cpp
@@ -2,6 +2,7 @@
  *  Copyright (C) 2015-2021 Savoir-faire Linux Inc.
  *  Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
  *  Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
+ *  Author: Amin Bandali <amin.bandali@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -20,10 +21,6 @@
 
 #include "pixbufmanipulator.h"
 
-#include <QtCore/QSize>
-#include <QtCore/QMetaType>
-#include <memory>
-
 #include <string>
 #include <algorithm>
 
@@ -34,32 +31,10 @@
 #include <api/account.h>
 #include <api/contact.h>
 
-namespace Interfaces {
-
-PixbufManipulator::PixbufManipulator()
-    : conferenceAvatar_{draw_conference_avatar(FALLBACK_AVATAR_SIZE), g_object_unref}
-{
-}
+#define FALLBACK_AVATAR_SIZE 100
 
-std::shared_ptr<GdkPixbuf>
-PixbufManipulator::temporaryItemAvatar() const
-{
-    GError *error = nullptr;
-    std::shared_ptr<GdkPixbuf> result(
-        gdk_pixbuf_new_from_resource("/net/jami/JamiGnome/temporary-item", &error),
-        g_object_unref
-    );
-
-    if (result == nullptr) {
-        g_debug("Could not load icon: %s", error->message);
-        g_clear_error(&error);
-        return generateAvatar("", "");
-    }
-    return result;
-}
-
-std::shared_ptr<GdkPixbuf>
-PixbufManipulator::generateAvatar(const std::string& alias, const std::string& uri) const
+GdkPixbuf *pxbm_generate_avatar(const std::string& alias,
+                                const std::string& uri)
 {
     std::string letter = {};
     if (!alias.empty()) {
@@ -72,22 +47,14 @@ PixbufManipulator::generateAvatar(const std::string& alias, const std::string& u
         color = std::string("0123456789abcdef").find(md5[0]);
     }
 
-    return std::shared_ptr<GdkPixbuf> {
-        draw_fallback_avatar(
-            FALLBACK_AVATAR_SIZE,
-            letter,
-            color
-        ),
-        g_object_unref
-    };
+    return draw_fallback_avatar(FALLBACK_AVATAR_SIZE, letter, color);
 }
 
-std::shared_ptr<GdkPixbuf>
-PixbufManipulator::scaleAndFrame(const GdkPixbuf *photo,
-                                 const QSize& size,
-                                 bool displayInformation,
-                                 IconStatus status,
-                                 uint unreadMessages)
+GdkPixbuf *pxbm_scale_and_frame(const GdkPixbuf *photo,
+                                const QSize& size,
+                                bool displayInformation,
+                                IconStatus status,
+                                uint unreadMessages)
 {
     /**
      * for now, respect the height requested
@@ -109,32 +76,32 @@ PixbufManipulator::scaleAndFrame(const GdkPixbuf *photo,
     if (w > h)
         photo_h = h * ((double)photo_w / w);
 
-    std::unique_ptr<GdkPixbuf, decltype(g_object_unref)&> scaled_photo{
-        gdk_pixbuf_scale_simple(photo, photo_w, photo_h, GDK_INTERP_BILINEAR),
-        g_object_unref};
+    GdkPixbuf *scaled_photo = gdk_pixbuf_scale_simple(
+        photo, photo_w, photo_h, GDK_INTERP_BILINEAR);
 
     /* frame photo */
-    std::shared_ptr<GdkPixbuf> result {
-        frame_avatar(scaled_photo.get()),
-        g_object_unref
-    };
+    GdkPixbuf *result = frame_avatar(scaled_photo);
 
     /* draw information */
     if (displayInformation) {
         /* draw status */
-        result.reset(draw_status(result.get(), status), g_object_unref);
+        GdkPixbuf *result2 = draw_status(result, status);
+        g_object_unref(result);
 
         /* draw visual notification for unread messages */
-        if (unreadMessages)
-            result.reset(draw_unread_messages(result.get(), unreadMessages), g_object_unref);
+        if (unreadMessages) {
+            result = draw_unread_messages(result2, unreadMessages);
+            g_object_unref(result2);
+        } else {
+            result = result2;
+        }
     }
 
     return result;
 }
 
-QVariant PixbufManipulator::personPhoto(const QByteArray& data, const QString& type)
+GdkPixbuf *pxbm_person_photo(const QByteArray& data)
 {
-    Q_UNUSED(type);
     /* Try to load the image from the data provided by lrc vcard utils;
      * lrc is getting the image data assuming that it is inlined in the vcard,
      * for now URIs are not supported.
@@ -176,20 +143,27 @@ QVariant PixbufManipulator::personPhoto(const QByteArray& data, const QString& t
         }
     }
 
-    if (pixbuf) {
-        std::shared_ptr<GdkPixbuf> avatar(pixbuf, g_object_unref);
-        return QVariant::fromValue(avatar);
-    }
+    return pixbuf;
+}
 
-    /* could not load image, return emtpy QVariant */
-    return QVariant();
+static GdkPixbuf *temporary_item_avatar()
+{
+    GError *error = nullptr;
+    GdkPixbuf *result = gdk_pixbuf_new_from_resource(
+        "/net/jami/JamiGnome/temporary-item", &error);
+
+    if (result == nullptr) {
+        g_debug("Could not load icon: %s", error->message);
+        g_clear_error(&error);
+        return pxbm_generate_avatar("", "");
+    }
+    return result;
 }
 
-QVariant
-PixbufManipulator::conversationPhoto(const lrc::api::conversation::Info& conversationInfo,
-                                     const lrc::api::account::Info& accountInfo,
-                                     const QSize& size,
-                                     bool displayInformation)
+GdkPixbuf *pxbm_conversation_photo(const lrc::api::conversation::Info& conversationInfo,
+                                   const lrc::api::account::Info& accountInfo,
+                                   const QSize& size,
+                                   bool displayInformation)
 {
     auto contacts = accountInfo.conversationModel->peersForConversation(conversationInfo.uid);
     if (!contacts.empty()) {
@@ -201,95 +175,80 @@ PixbufManipulator::conversationPhoto(const lrc::api::conversation::Info& convers
             auto alias = contactInfo.profileInfo.alias;
             alias.remove('\r');
             alias.remove('\n');
-            auto bestName = alias.isEmpty() ? contactInfo.registeredName : alias;
+            auto bestName = alias.isEmpty()
+                ? contactInfo.registeredName
+                : alias;
             auto unreadMessages = conversationInfo.unreadMessages;
-            auto status = contactInfo.isPresent? IconStatus::PRESENT : IconStatus::ABSENT;
-            if (accountInfo.profileInfo.type == lrc::api::profile::Type::SIP && contactInfo.profileInfo.type == lrc::api::profile::Type::TEMPORARY)
+            auto status = contactInfo.isPresent
+                ? IconStatus::PRESENT
+                : IconStatus::ABSENT;
+
+            GdkPixbuf *tmp, *ret;
+            if (accountInfo.profileInfo.type == lrc::api::profile::Type::SIP
+                && contactInfo.profileInfo.type == lrc::api::profile::Type::TEMPORARY)
             {
-                return QVariant::fromValue(scaleAndFrame(generateAvatar("", "").get(), size, displayInformation, status));
+                tmp = pxbm_generate_avatar("", "");
+                ret = pxbm_scale_and_frame(tmp, size, displayInformation, status);
             } else if (accountInfo.profileInfo.type == lrc::api::profile::Type::SIP) {
-                return QVariant::fromValue(scaleAndFrame(generateAvatar("", "sip:" + contactInfo.profileInfo.uri.toStdString()).get(), size, displayInformation, status));
-            } else if (contactInfo.profileInfo.type == lrc::api::profile::Type::TEMPORARY && contactInfo.profileInfo.uri.isEmpty()) {
-                return QVariant::fromValue(scaleAndFrame(temporaryItemAvatar().get(), size, false, status, unreadMessages));
+                tmp = pxbm_generate_avatar(
+                    "", "sip:" + contactInfo.profileInfo.uri.toStdString());
+                ret = pxbm_scale_and_frame(tmp, size, displayInformation, status);
+            } else if (contactInfo.profileInfo.type == lrc::api::profile::Type::TEMPORARY
+                       && contactInfo.profileInfo.uri.isEmpty()) {
+                tmp = temporary_item_avatar();
+                ret = pxbm_scale_and_frame(tmp, size, false, status, unreadMessages);
             } else if (!contactPhoto.isEmpty()) {
-                QByteArray byteArray = contactPhoto.toUtf8();
-                QVariant photo = personPhoto(byteArray);
-                if (GDK_IS_PIXBUF(photo.value<std::shared_ptr<GdkPixbuf>>().get())) {
-                    return QVariant::fromValue(scaleAndFrame(
-                        photo.value<std::shared_ptr<GdkPixbuf>>().get(), size,
-                        displayInformation, status, unreadMessages));
+                tmp = pxbm_person_photo(contactPhoto.toUtf8());
+                if (GDK_IS_PIXBUF(tmp)) {
+                    ret = pxbm_scale_and_frame(
+                        tmp, size, displayInformation, status, unreadMessages);
                 } else {
-                    return QVariant::fromValue(scaleAndFrame(
-                        generateAvatar(bestName.toStdString(),
-                            "ring:" + contactInfo.profileInfo.uri.toStdString()).get(),
-                        size, displayInformation, status, unreadMessages));
+                    g_object_unref(tmp);
+                    tmp = pxbm_generate_avatar(
+                        bestName.toStdString(),
+                        "ring:" + contactInfo.profileInfo.uri.toStdString());
+                    ret = pxbm_scale_and_frame(
+                        tmp, size, displayInformation, status, unreadMessages);
                 }
             } else {
-                return QVariant::fromValue(scaleAndFrame(generateAvatar(bestName.toStdString(),
-                     "ring:" + contactInfo.profileInfo.uri.toStdString()).get(), size, displayInformation, status, unreadMessages));
+                tmp = pxbm_generate_avatar(
+                    bestName.toStdString(),
+                    "ring:" + contactInfo.profileInfo.uri.toStdString());
+                ret = pxbm_scale_and_frame(
+                    tmp, size, displayInformation, status, unreadMessages);
             }
+            g_object_unref(tmp);
+            return ret;
         } catch (...) {}
     }
-    return QVariant::fromValue(scaleAndFrame(temporaryItemAvatar().get(), size, displayInformation));
+    GdkPixbuf *tmp = temporary_item_avatar();
+    GdkPixbuf *ret = pxbm_scale_and_frame(tmp, size, displayInformation);
+    g_object_unref(tmp);
+    return ret;
 
 }
 
-QVariant
-PixbufManipulator::numberCategoryIcon(const QVariant& p, const QSize& size, bool displayInformation, bool isPresent)
+QByteArray pxbm_to_QByteArray(GdkPixbuf *pxm)
 {
-    Q_UNUSED(p)
-    Q_UNUSED(size)
-    Q_UNUSED(displayInformation)
-    Q_UNUSED(isPresent)
-    return QVariant();
-}
-
-QByteArray
-PixbufManipulator::toByteArray(const QVariant& pxm)
-{
-    std::shared_ptr<GdkPixbuf> pixbuf_photo = pxm.value<std::shared_ptr<GdkPixbuf>>();
-
-    if(pixbuf_photo.get()) {
-        gchar* png_buffer = nullptr;
+    if(pxm) {
+        gchar *png_buffer = nullptr;
         gsize png_buffer_size;
         GError *error = nullptr;
 
-        gdk_pixbuf_save_to_buffer(pixbuf_photo.get(), &png_buffer, &png_buffer_size, "png", &error, NULL);
+        gdk_pixbuf_save_to_buffer(pxm, &png_buffer, &png_buffer_size,
+                                  "png", &error, NULL);
         QByteArray array = QByteArray(png_buffer, png_buffer_size);
-
         g_free(png_buffer);
 
         if (error != NULL) {
-            g_warning("in toByteArray, gdk_pixbuf_save_to_buffer failed : %s\n", error->message);
+            g_warning("in toByteArray, gdk_pixbuf_save_to_buffer failed: %s\n",
+                      error->message);
             g_clear_error(&error);
         }
 
         return array;
     } else {
-        g_debug("in toByteArray, failed to retrieve data from parameter pxm");
+        g_debug("in toByteArray, the pxm parameter was null");
         return QByteArray();
     }
 }
-
-QVariant
-PixbufManipulator::userActionIcon(const UserActionElement& state) const
-{
-    Q_UNUSED(state)
-    return QVariant();
-}
-
-QVariant PixbufManipulator::decorationRole(const QModelIndex& index)
-{
-    Q_UNUSED(index)
-    return QVariant();
-}
-
-QVariant PixbufManipulator::decorationRole(const lrc::api::conversation::Info& conversation,
-                                           const lrc::api::account::Info& accountInfo)
-{
-    Q_UNUSED(conversation)
-    Q_UNUSED(accountInfo)
-    return QVariant();
-}
-
-} // namespace Interfaces
diff --git a/src/native/pixbufmanipulator.h b/src/native/pixbufmanipulator.h
index deaf87266bf2b15c116846954a7d76ffc9158434..6cc5a2d93368e8a5038a1a7d92547c0aa23449c9 100644
--- a/src/native/pixbufmanipulator.h
+++ b/src/native/pixbufmanipulator.h
@@ -2,6 +2,7 @@
  *  Copyright (C) 2015-2021 Savoir-faire Linux Inc.
  *  Author: Stepan Salenikovich <stepan.salenikovich@savoirfairelinux.com>
  *  Author: Sebastien Blin <sebastien.blin@savoirfairelinux.com>
+ *  Author: Amin Bandali <amin.bandali@savoirfairelinux.com>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -18,49 +19,45 @@
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
  */
 
-#pragma once
+#ifndef _PIXBUFMANIPULATOR_H
+#define _PIXBUFMANIPULATOR_H
 
 #include <gtk/gtk.h>
-#include <memory>
-#include <interfaces/pixmapmanipulatori.h>
+#include <QSize>
 #include "../utils/drawing.h"
 
-Q_DECLARE_METATYPE(std::shared_ptr<GdkPixbuf>);
-
-class Person;
-
-namespace Interfaces {
-
-/**
- * TODO remove old methods (methods which use Call, ContactMethod, Person, etc)
- * But before, they should be removed from PixmapManipulatorI
- */
-class PixbufManipulator : public PixmapManipulatorI {
-    constexpr static int FALLBACK_AVATAR_SIZE {100};
-public:
-    PixbufManipulator();
-
-    QVariant conversationPhoto(const lrc::api::conversation::Info& conversation,
-                               const lrc::api::account::Info& accountInfo,
-                               const QSize& size,
-                               bool displayInformation = true) override;
-    QVariant personPhoto(const QByteArray& data, const QString& type = "PNG") override;
-
-    QVariant   numberCategoryIcon(const QVariant& p, const QSize& size, bool displayInformation = false, bool isPresent = false) override;
-    QByteArray toByteArray(const QVariant& pxm) override;
-    QVariant   userActionIcon(const UserActionElement& state) const override;
-    QVariant   decorationRole(const QModelIndex& index) override;
-    QVariant   decorationRole(const lrc::api::conversation::Info& conversation,
-                              const lrc::api::account::Info& accountInfo) override;
-
-    // Helpers
-    std::shared_ptr<GdkPixbuf> temporaryItemAvatar() const;
-    std::shared_ptr<GdkPixbuf> generateAvatar(const std::string& alias, const std::string& uri) const;
-
-    std::shared_ptr<GdkPixbuf> scaleAndFrame(const GdkPixbuf *photo, const QSize &size, bool displayInformation = false, IconStatus status = IconStatus::INVALID, uint unreadMessages = 0);
-
-  private:
-    std::shared_ptr<GdkPixbuf> conferenceAvatar_;
-};
-
-} // namespace Interfaces
+namespace lrc
+{
+namespace api
+{
+namespace account
+{
+    struct Info;
+}
+namespace conversation
+{
+    struct Info;
+}
+}
+}
+
+G_BEGIN_DECLS
+
+GdkPixbuf *pxbm_conversation_photo(const lrc::api::conversation::Info& conversation,
+                              const lrc::api::account::Info& accountInfo,
+                              const QSize& size,
+                              bool displayInformation = true);
+GdkPixbuf *pxbm_person_photo(const QByteArray& data);
+GdkPixbuf *pxbm_generate_avatar(const std::string& alias,
+                           const std::string& uri);
+GdkPixbuf *pxbm_scale_and_frame(const GdkPixbuf *photo,
+                           const QSize &size,
+                           bool displayInformation = false,
+                           IconStatus status = IconStatus::INVALID,
+                           uint unreadMessages = 0);
+QByteArray pxbm_to_QByteArray(GdkPixbuf *pxm);
+
+
+G_END_DECLS
+
+#endif /* _PIXBUFMANIPULATOR_H */
diff --git a/src/notifier.cpp b/src/notifier.cpp
index 47b31a35a986f91222a0765f07a04ae7e73e4e76..59b7d2c2bed0c1c4b3448886e0a267e716aab4b5 100644
--- a/src/notifier.cpp
+++ b/src/notifier.cpp
@@ -30,9 +30,9 @@
 #include <glib/gi18n.h>
 #include <libnotify/notify.h>
 #include <memory>
-#include <globalinstances.h>
 #include "native/pixbufmanipulator.h"
-#include <QtCore/QSize>
+#include <QSize>
+#include <QString>
 #include <map>
 #endif
 
@@ -310,17 +310,20 @@ show_notification(Notifier* view, const std::string& icon,
     // Draw icon
     auto firstLetter = (name == uri || name.empty()) ?
         "" : QString(QString(name.c_str()).at(0)).toStdString();  // NOTE best way to be compatible with UTF-8
-    auto default_avatar = Interfaces::PixbufManipulator().generateAvatar(firstLetter, "ring:" + uri);
-    auto photo = Interfaces::PixbufManipulator().scaleAndFrame(default_avatar.get(), QSize(50, 50));
+    GdkPixbuf *default_avatar = pxbm_generate_avatar(firstLetter, "ring:" + uri);
+    GdkPixbuf *photo = pxbm_scale_and_frame(default_avatar, QSize(50, 50));
+    g_object_unref(default_avatar);
     if (!icon.empty()) {
         QByteArray byteArray(icon.c_str(), icon.length());
-        QVariant avatar = Interfaces::PixbufManipulator().personPhoto(byteArray);
-        auto pixbuf_photo = Interfaces::PixbufManipulator().scaleAndFrame(avatar.value<std::shared_ptr<GdkPixbuf>>().get(), QSize(50, 50));
-        if (avatar.isValid()) {
-            photo = pixbuf_photo;
+        GdkPixbuf *avatar = pxbm_person_photo(byteArray);
+        if (avatar) {
+            g_object_unref(photo);
+            photo = pxbm_scale_and_frame(avatar, QSize(50, 50));
+            g_object_unref(avatar);
         }
     }
-    notify_notification_set_image_from_pixbuf(notification.get(), photo.get());
+    notify_notification_set_image_from_pixbuf(notification.get(), photo);
+    g_object_unref(photo);
 
     if (type != NotificationType::CHAT) {
         notify_notification_set_urgency(notification.get(), NOTIFY_URGENCY_CRITICAL);
diff --git a/src/profileview.cpp b/src/profileview.cpp
index 2addac7131d6327ec15bfaa911a69062b5594ebe..77e2c00b9fc9451d1ef0aab9fd3cfaada0ccb52a 100644
--- a/src/profileview.cpp
+++ b/src/profileview.cpp
@@ -31,7 +31,6 @@
 #include <api/contact.h>
 #include <api/contactmodel.h>
 #include <api/conversationmodel.h>
-#include <globalinstances.h>
 
 namespace { namespace details {
 class CppImpl;
@@ -140,15 +139,14 @@ build_view(ProfileView* view)
         gtk_label_set_text(GTK_LABEL(priv->id_label), qUtf8Printable(contact.profileInfo.uri));
 
         uint32_t img_size = 128;
-        std::shared_ptr<GdkPixbuf> image;
-        auto var_photo = GlobalInstances::pixmapManipulator().conversationPhoto(
+        GdkPixbuf *p = pxbm_conversation_photo(
             *convOpt,
             **(priv->accountInfo_),
             QSize(img_size, img_size),
             false
         );
-        image = var_photo.value<std::shared_ptr<GdkPixbuf>>();
-        gtk_image_set_from_pixbuf(GTK_IMAGE(priv->avatar), image.get());
+        gtk_image_set_from_pixbuf(GTK_IMAGE(priv->avatar), p);
+        g_object_unref(p);
 
         auto* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, img_size, img_size);
         auto* cr = cairo_create(surface);
diff --git a/src/webkitchatcontainer.cpp b/src/webkitchatcontainer.cpp
index 0c13bb24cd136377cbe9fbc7862bbc8cd2931c83..83b30bb5d745abc76434ea61f00b2892dcaea0ed 100644
--- a/src/webkitchatcontainer.cpp
+++ b/src/webkitchatcontainer.cpp
@@ -31,7 +31,6 @@
 #include <QtCore/QJsonDocument>
 
 // LRC
-#include <globalinstances.h>
 #include <api/conversationmodel.h>
 #include <api/account.h>
 #include <api/chatview.h>