a6c30a587b6c1666d34d91fd64d340c348bbc76c
1 /*
2 * Authors:
3 * Christopher Brown <audiere@gmail.com>
4 * Ted Gould <ted@gould.cx>
5 *
6 * Copyright (C) 2007 Authors
7 *
8 * Released under GNU GPL, read the file 'COPYING' for more information
9 */
11 #include <libintl.h>
13 #include <gtkmm/box.h>
14 #include <gtkmm/adjustment.h>
15 #include <gtkmm/spinbutton.h>
16 #include <gtkmm.h>
18 #include <glib/gstdio.h>
20 #include "desktop.h"
21 #include "desktop-handles.h"
22 #include "selection.h"
23 #include "sp-object.h"
24 #include "util/glib-list-iterators.h"
26 #include "extension/effect.h"
27 #include "extension/system.h"
29 #include "imagemagick.h"
31 namespace Inkscape {
32 namespace Extension {
33 namespace Internal {
34 namespace Bitmap {
36 bool
37 ImageMagick::load(Inkscape::Extension::Extension *module)
38 {
39 _loaded = FALSE;
41 return TRUE;
42 }
44 void
45 ImageMagick::commitDocument(void) {
46 _loaded = FALSE;
47 }
49 /*void
50 ImageMagick::cancelDocument(void) {
51 for (int i = 0; i < _imageCount; i++) {
52 _nodes[i]->setAttribute("xlink:href", _originals[i], true);
54 if (strlen(_originals[i]) < 256)
55 _nodes[i]->setAttribute("sodipodi:absref", _originals[i], true);
56 }
58 _loaded = FALSE;
59 }*/
61 void
62 ImageMagick::readImage(const char *xlink, Magick::Image *image)
63 {
64 // Find if the xlink:href is base64 data, i.e. if the image is embedded
65 char *search = (char *) g_strndup(xlink, 30);
66 if (strstr(search, "base64") != (char*)NULL) {
67 // 7 = strlen("base64") + strlen(",")
68 char* pureBase64 = strstr(xlink, "base64") + 7;
69 Magick::Blob blob;
70 blob.base64(pureBase64);
71 image->read(blob);
72 }
73 else {
74 image->read(xlink);
75 }
76 }
78 void
79 ImageMagick::effect (Inkscape::Extension::Effect *module, Inkscape::UI::View::View *document)
80 {
81 refreshParameters(module);
83 if (!_loaded)
84 {
85 SPDesktop *desktop = (SPDesktop*)document;
86 const GSList *selectedReprList = desktop->selection->reprList();
87 int selectCount = g_slist_length((GSList *)selectedReprList);
89 // Init the data-holders
90 _nodes = new Inkscape::XML::Node*[selectCount];
91 _originals = new const char*[selectCount];
92 _caches = new char*[selectCount];
93 _cacheLengths = new unsigned[selectCount];
94 _images = new Magick::Image*[selectCount];
95 _imageCount = 0;
97 // Loop through selected nodes
98 for (; selectedReprList != NULL; selectedReprList = g_slist_next(selectedReprList))
99 {
100 Inkscape::XML::Node *node = reinterpret_cast<Inkscape::XML::Node *>(selectedReprList->data);
101 if (!strcmp(node->name(), "image") || !strcmp(node->name(), "svg:image"))
102 {
103 _nodes[_imageCount] = node;
104 char const *xlink = node->attribute("xlink:href");
106 _originals[_imageCount] = xlink;
107 _caches[_imageCount] = "";
108 _cacheLengths[_imageCount] = 0;
109 _images[_imageCount] = new Magick::Image();
110 readImage(xlink, _images[_imageCount]);
112 _imageCount++;
113 }
114 }
116 _loaded = 1;
117 }
119 for (int i = 0; i < _imageCount; i++)
120 {
121 try
122 {
123 Magick::Image effectedImage = *_images[i]; // make a copy
124 applyEffect(&effectedImage);
126 Magick::Blob *blob = new Magick::Blob();
127 effectedImage.write(blob);
129 std::string raw_string = blob->base64();
130 const int raw_len = raw_string.length();
131 const char *raw_i = raw_string.c_str();
133 unsigned new_len = (int)(raw_len * (77.0 / 76.0) + 100);
134 if (new_len > _cacheLengths[i]) {
135 _cacheLengths[i] = (int)(new_len * 1.2);
136 _caches[i] = new char[_cacheLengths[i]];
137 }
138 char *formatted_i = _caches[i];
139 const char *src;
141 for (src = "data:image/"; *src; )
142 *formatted_i++ = *src++;
143 for (src = effectedImage.magick().c_str(); *src ; )
144 *formatted_i++ = *src++;
145 for (src = ";base64, \n" ; *src; )
146 *formatted_i++ = *src++;
148 int col = 0;
149 while (*raw_i) {
150 *formatted_i++ = *raw_i++;
151 if (col++ > 76) {
152 *formatted_i++ = '\n';
153 col = 0;
154 }
155 }
156 if (col) {
157 *formatted_i++ = '\n';
158 }
159 *formatted_i = '\0';
161 _nodes[i]->setAttribute("xlink:href", _caches[i], true);
162 _nodes[i]->setAttribute("sodipodi:absref", NULL, true);
163 }
164 catch (Magick::Exception &error_) {
165 printf("Caught exception: %s \n", error_.what());
166 }
168 while(Gtk::Main::events_pending())
169 Gtk::Main::iteration();
170 }
171 }
173 /** \brief A function to get the prefences for the grid
174 \param moudule Module which holds the params
175 \param view Unused today - may get style information in the future.
177 Uses AutoGUI for creating the GUI.
178 */
179 Gtk::Widget *
180 ImageMagick::prefs_effect(Inkscape::Extension::Effect *module, Inkscape::UI::View::View * view, sigc::signal<void> * changeSignal)
181 {
182 SPDocument * current_document = view->doc();
184 using Inkscape::Util::GSListConstIterator;
185 GSListConstIterator<SPItem *> selected = sp_desktop_selection((SPDesktop *)view)->itemList();
186 Inkscape::XML::Node * first_select = NULL;
187 if (selected != NULL)
188 first_select = SP_OBJECT_REPR(*selected);
190 return module->autogui(current_document, first_select, changeSignal);
191 }
193 }; /* namespace Bitmap */
194 }; /* namespace Internal */
195 }; /* namespace Extension */
196 }; /* namespace Inkscape */