summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiam P. White <inkscapebronyat-signgmaildotcom>2014-03-26 01:54:08 +0000
committerLiam P. White <inkscapebronyat-signgmaildotcom>2014-03-26 01:54:08 +0000
commite80a86b84d1e5cd64139df6aee147795067cb938 (patch)
tree53fb3e0050a406d48dd4c869997db4ff92832bc1 /src
parentUpdate to trunk (diff)
parentPatch for several issues in libuemf. (diff)
downloadinkscape-e80a86b84d1e5cd64139df6aee147795067cb938.tar.gz
inkscape-e80a86b84d1e5cd64139df6aee147795067cb938.zip
Update to trunk
(bzr r13090.1.32)
Diffstat (limited to 'src')
-rw-r--r--src/desktop.cpp6
-rw-r--r--src/display/nr-filter-turbulence.cpp6
-rw-r--r--src/extension/error-file.cpp2
-rw-r--r--src/extension/internal/emf-inout.cpp2
-rw-r--r--src/extension/internal/emf-print.cpp4
-rw-r--r--src/extension/internal/text_reassemble.c5
-rw-r--r--src/extension/internal/wmf-inout.cpp2
-rw-r--r--src/extension/prefdialog.cpp4
-rw-r--r--src/libdepixelize/kopftracer2011.cpp415
-rw-r--r--src/libdepixelize/kopftracer2011.h26
-rw-r--r--src/libdepixelize/priv/homogeneoussplines.h21
-rw-r--r--src/libdepixelize/priv/pixelgraph.h80
-rw-r--r--src/libdepixelize/priv/simplifiedvoronoi.h271
-rw-r--r--src/libuemf/uemf.c6
-rw-r--r--src/libuemf/uemf_endian.c6
-rw-r--r--src/libuemf/uemf_utf.c72
-rw-r--r--src/libuemf/upmf.c68
-rw-r--r--src/libuemf/upmf_print.c7
-rw-r--r--src/libuemf/uwmf.c101
-rw-r--r--src/libuemf/uwmf.h23
-rw-r--r--src/libuemf/uwmf_print.c8
-rw-r--r--src/live_effects/effect.cpp2
-rw-r--r--src/object-snapper.cpp54
-rw-r--r--src/path-chemistry.cpp25
-rw-r--r--src/sp-object.cpp20
-rw-r--r--src/style.cpp2
-rw-r--r--src/unicoderange.cpp4
-rw-r--r--src/xml/node.h16
28 files changed, 926 insertions, 332 deletions
diff --git a/src/desktop.cpp b/src/desktop.cpp
index a02baeac8..22c00d4f1 100644
--- a/src/desktop.cpp
+++ b/src/desktop.cpp
@@ -663,8 +663,8 @@ SPDesktop::change_document (SPDocument *theDocument)
SPDesktopWidget *dtw = (SPDesktopWidget *) parent->get_data("desktopwidget");
if (dtw) {
dtw->desktop = this;
+ dtw->updateNamedview();
}
- dtw->updateNamedview();
_namedview_modified (namedview, SP_OBJECT_MODIFIED_FLAG, this);
_document_replaced_signal.emit (this, theDocument);
@@ -1537,7 +1537,9 @@ SPDesktop::updateCanvasNow()
void
SPDesktop::setDocument (SPDocument *doc)
{
- if (this->doc() && doc) {
+ if (!doc) return;
+
+ if (this->doc()) {
namedview->hide(this);
this->doc()->getRoot()->invoke_hide(dkey);
}
diff --git a/src/display/nr-filter-turbulence.cpp b/src/display/nr-filter-turbulence.cpp
index e63b335d2..a2a8c5756 100644
--- a/src/display/nr-filter-turbulence.cpp
+++ b/src/display/nr-filter-turbulence.cpp
@@ -288,7 +288,7 @@ private:
static double constexpr PerlinOffset = 4096.0;
#else
#if (__cplusplus < 201103L)
- static double const PerlinOffset = 4096.0;
+ static double const PerlinOffset;
#else
static double constexpr PerlinOffset = 4096.0;
#endif
@@ -309,6 +309,10 @@ private:
bool _fractalnoise;
};
+#if !defined(CPP11) && __cplusplus < 201103L
+ double const TurbulenceGenerator::PerlinOffset = 4096.0;
+#endif
+
FilterTurbulence::FilterTurbulence()
: gen(new TurbulenceGenerator())
, XbaseFrequency(0)
diff --git a/src/extension/error-file.cpp b/src/extension/error-file.cpp
index 5a8bede70..f60af870f 100644
--- a/src/extension/error-file.cpp
+++ b/src/extension/error-file.cpp
@@ -39,7 +39,7 @@ namespace Extension {
probably good to check anyway).
*/
ErrorFileNotice::ErrorFileNotice (void) :
- Gtk::MessageDialog::MessageDialog(
+ Gtk::MessageDialog(
"", /* message */
false, /* use markup */
Gtk::MESSAGE_WARNING, /* dialog type */
diff --git a/src/extension/internal/emf-inout.cpp b/src/extension/internal/emf-inout.cpp
index a4d204472..eae3bfb5a 100644
--- a/src/extension/internal/emf-inout.cpp
+++ b/src/extension/internal/emf-inout.cpp
@@ -123,7 +123,7 @@ Emf::print_document_to_file(SPDocument *doc, const gchar *filename)
throw Inkscape::Extension::Output::save_failed();
}
mod->base->invoke_print(&context);
- ret = mod->finish();
+ (void) mod->finish();
/* Release arena */
mod->base->invoke_hide(mod->dkey);
mod->base = NULL;
diff --git a/src/extension/internal/emf-print.cpp b/src/extension/internal/emf-print.cpp
index ed25bf767..f4f7f08cb 100644
--- a/src/extension/internal/emf-print.cpp
+++ b/src/extension/internal/emf-print.cpp
@@ -366,11 +366,13 @@ int PrintEmf::create_brush(SPStyle const *style, PU_COLORREF fcolor)
if (!fcolor && style) {
if (style->fill.isColor()) {
fill_mode = DRAW_PAINT;
+#if 0
+// opacity not supported by EMF
float opacity = SP_SCALE24_TO_FLOAT(style->fill_opacity.value);
if (opacity <= 0.0) {
opacity = 0.0; // basically the same as no fill
}
-
+#endif
sp_color_get_rgb_floatv(&style->fill.value.color, rgb);
hatchColor = U_RGB(255 * rgb[0], 255 * rgb[1], 255 * rgb[2]);
diff --git a/src/extension/internal/text_reassemble.c b/src/extension/internal/text_reassemble.c
index e28e5effb..c62c83120 100644
--- a/src/extension/internal/text_reassemble.c
+++ b/src/extension/internal/text_reassemble.c
@@ -67,8 +67,8 @@ Optional compiler switches for development:
File: text_reassemble.c
-Version: 0.0.12
-Date: 07-FEB-2014
+Version: 0.0.13
+Date: 24-MAR-2014
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
Copyright: 2014 David Mathog and California Institute of Technology (Caltech)
@@ -2055,7 +2055,6 @@ void TR_layout_2_svg(TR_INFO *tri){
}
- tsp = tpi->chunks;
/* over all complex members from phase2. Paragraphs == TR_PARA_* */
for(i=cxi->phase1; i<cxi->used;i++){
csp = &(cxi->cx[i]);
diff --git a/src/extension/internal/wmf-inout.cpp b/src/extension/internal/wmf-inout.cpp
index 9980d9d6d..ef95dbe45 100644
--- a/src/extension/internal/wmf-inout.cpp
+++ b/src/extension/internal/wmf-inout.cpp
@@ -1527,7 +1527,7 @@ int Wmf::myMetaFileProc(const char *contents, unsigned int length, PWMF_CALLBACK
iType = *(uint8_t *)(contents + off + offsetof(U_METARECORD, iType ) );
if(iType == U_WMR_SETWINDOWEXT){
OK=0;
- nSize = U_WMRSETWINDOWEXT_get(contents + off, &Dst);
+ (void) U_WMRSETWINDOWEXT_get(contents + off, &Dst);
Placeable.Dst.right = Dst.x;
Placeable.Dst.bottom = Dst.y;
}
diff --git a/src/extension/prefdialog.cpp b/src/extension/prefdialog.cpp
index f3c6508af..1b657f644 100644
--- a/src/extension/prefdialog.cpp
+++ b/src/extension/prefdialog.cpp
@@ -42,9 +42,9 @@ namespace Extension {
*/
PrefDialog::PrefDialog (Glib::ustring name, gchar const * help, Gtk::Widget * controls, Effect * effect) :
#if WITH_GTKMM_3_0
- Gtk::Dialog::Dialog(_(name.c_str()), true),
+ Gtk::Dialog(_(name.c_str()), true),
#else
- Gtk::Dialog::Dialog(_(name.c_str()), true, true),
+ Gtk::Dialog(_(name.c_str()), true, true),
#endif
_help(help),
_name(name),
diff --git a/src/libdepixelize/kopftracer2011.cpp b/src/libdepixelize/kopftracer2011.cpp
index ab31d05c3..e2f387c86 100644
--- a/src/libdepixelize/kopftracer2011.cpp
+++ b/src/libdepixelize/kopftracer2011.cpp
@@ -31,7 +31,6 @@
#include <glibmm/threads.h>
#endif
-#include <utility>
#include <algorithm>
#include "kopftracer2011.h"
#include "priv/colorspace.h"
@@ -40,6 +39,11 @@
#include "priv/splines-kopf2011.h"
#include "priv/iterator.h"
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+#include <glibmm/datetime.h>
+#include <iostream>
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
namespace Tracer {
namespace Heuristics {
@@ -86,7 +90,95 @@ Splines Kopf2011::to_voronoi(const std::string &filename,
Splines Kopf2011::to_voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
const Options &options)
{
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ SimplifiedVoronoi<Precision, false> voronoi
+ = _voronoi<Precision, false>(buf, options);
+
+ Glib::DateTime profiling_info[2];
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+
+ Splines ret(voronoi);
+
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Splines construction time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+
+ return ret;
+#else // LIBDEPIXELIZE_PROFILE_KOPF2011
return Splines(_voronoi<Precision, false>(buf, options));
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+}
+
+Splines Kopf2011::to_grouped_voronoi(const std::string &filename,
+ const Options &options)
+{
+ return to_grouped_voronoi(Gdk::Pixbuf::create_from_file(filename), options);
+}
+
+Splines Kopf2011::to_grouped_voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
+ const Options &options)
+{
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ SimplifiedVoronoi<Precision, false> voronoi
+ = _voronoi<Precision, false>(buf, options);
+
+ Glib::DateTime profiling_info[2];
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+
+ HomogeneousSplines<Precision> splines(voronoi);
+
+#else // LIBDEPIXELIZE_PROFILE_KOPF2011
+ HomogeneousSplines<Precision> splines(_voronoi<Precision, false>
+ (buf, options));
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::HomogeneousSplines<" << typeid(Precision).name()
+ << ">(Tracer::SimplifiedVoronoi<" << typeid(Precision).name()
+ << ",false>) construction time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
+ for ( HomogeneousSplines<Precision>::iterator it = splines.begin(),
+ end = splines.end() ; it != end ; ++it ) {
+ for ( HomogeneousSplines<Precision>::Polygon::points_iter
+ it2 = it->vertices.begin(), end2 = it->vertices.end()
+ ; it2 != end2 ; ++it2 ) {
+ it2->smooth = false;
+ }
+ for ( HomogeneousSplines<Precision>::Polygon::holes_iter
+ it2 = it->holes.begin(), end2 = it->holes.end()
+ ; it2 != end2 ; ++it2 ) {
+ for ( HomogeneousSplines<Precision>::Polygon::points_iter
+ it3 = it2->begin(), end3 = it2->end()
+ ; it3 != end3 ; ++it3 ) {
+ it3->smooth = false;
+ }
+ }
+ }
+
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Kopf2011::to_grouped_voronoi internal work time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+
+ Splines ret(splines, false, options.nthreads);
+
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Splines construction time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+
+ return ret;
+#else // LIBDEPIXELIZE_PROFILE_KOPF2011
+ return Splines(splines, false, options.nthreads);
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
}
Splines Kopf2011::to_splines(const std::string &filename,
@@ -98,9 +190,36 @@ Splines Kopf2011::to_splines(const std::string &filename,
Splines Kopf2011::to_splines(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
const Options &options)
{
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ SimplifiedVoronoi<Precision, true> voronoi
+ = _voronoi<Precision, true>(buf, options);
+
+ Glib::DateTime profiling_info[2];
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+
+ HomogeneousSplines<Precision> splines(voronoi);
+
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::HomogeneousSplines<" << typeid(Precision).name()
+ << "> construction time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+
+ Splines ret(splines, options.optimize, options.nthreads);
+
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Splines construction time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+
+ return ret;
+#else // LIBDEPIXELIZE_PROFILE_KOPF2011
HomogeneousSplines<Precision> splines(_voronoi<Precision, true>
(buf, options));
return Splines(splines, options.optimize, options.nthreads);
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
}
template<class T, bool adjust_splines>
@@ -108,47 +227,131 @@ SimplifiedVoronoi<T, adjust_splines>
Kopf2011::_voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
const Options &options)
{
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ Glib::DateTime profiling_info[2];
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
PixelGraph graph(buf);
- /*if ( !graph.width() || !graph.height() )
- return;*/
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::PixelGraph creation time: "
+ << profiling_info[1].difference(profiling_info[0]) << std::endl;
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
+ // gdk-pixbuf2 already checks if image size is meaningful, but asserts state
+ // preconditions and will be useful if gdk-pixbuf is replaced later
+ assert(graph.width() > 0);
+ assert(graph.height() > 0);
#ifndef NDEBUG
graph.checkConsistency();
#endif
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
// This step could be part of the initialization of PixelGraph
// and decrease the necessary number of passes
graph.connectAllNeighbors();
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::PixelGraph::connectAllNeighbors() time: "
+ << profiling_info[1].difference(profiling_info[0]) << std::endl;
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
#ifndef NDEBUG
graph.checkConsistency();
#endif
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
// This step can't be part of PixelGraph initilization without adding some
// cache misses due to random access patterns that might be injected
_disconnect_neighbors_with_dissimilar_colors(graph);
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Kopf2011::"
+ "_disconnect_neighbors_with_dissimilar_colors(Tracer::PixelGraph) time: "
+ << profiling_info[1].difference(profiling_info[0]) << std::endl;
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
#ifndef NDEBUG
graph.checkConsistency();
#endif
- // This and below steps must be executed in separate.
- // Otherwise, there will be colateral effects due to misassumption about the
- // data being read.
- _remove_crossing_edges_safe(graph);
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
+ {
+ // edges_safe and edges_unsafe must be executed in separate.
+ // Otherwise, there will be colateral effects due to misassumption about
+ // the data being read.
+ PixelGraph::EdgePairContainer edges = graph.crossingEdges();
+
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::PixelGraph::crossingEdges() time: "
+ << profiling_info[1].difference(profiling_info[0]) << std::endl;
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
+ _remove_crossing_edges_safe(edges);
+
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Kopf2011::_remove_crossing_edges_safe"
+ "(Tracer::PixelGraph) time: "
+ << profiling_info[1].difference(profiling_info[0])
+ << std::endl;
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
#ifndef NDEBUG
- graph.checkConsistency();
+ graph.checkConsistency();
#endif
- _remove_crossing_edges_unsafe(graph, options);
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
+
+ _remove_crossing_edges_unsafe(graph, edges, options);
+ }
+
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::Kopf2011::_remove_crossing_edges_unsafe"
+ "(Tracer::PixelGraph) time: "
+ << profiling_info[1].difference(profiling_info[0]) << std::endl;
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
#ifndef NDEBUG
graph.checkConsistency();
#endif
+ assert(graph.crossingEdges().size() == 0);
+
+#ifdef LIBDEPIXELIZE_PROFILE_KOPF2011
+ profiling_info[0] = Glib::DateTime::create_now_utc();
+
+ SimplifiedVoronoi<T, adjust_splines> ret(graph);
+
+ profiling_info[1] = Glib::DateTime::create_now_utc();
+ std::cerr << "Tracer::SimplifiedVoronoi<" << typeid(T).name() << ','
+ << (adjust_splines ? "true" : "false")
+ << ">(Tracer::PixelGraph) construction time: "
+ << profiling_info[1].difference(profiling_info[0]) << std::endl;
+
+ return ret;
+#else // LIBDEPIXELIZE_PROFILE_KOPF2011
return SimplifiedVoronoi<T, adjust_splines>(graph);
+#endif // LIBDEPIXELIZE_PROFILE_KOPF2011
}
// TODO: move this function (plus connectAllNeighbors) to PixelGraph constructor
@@ -192,123 +395,115 @@ Kopf2011::_disconnect_neighbors_with_dissimilar_colors(PixelGraph &graph)
*
* In this case the two diagonal connections can be safely removed without
* affecting the final result.
- *
- * \TODO: It should remember/cache who are the unsafe crossing edges?
*/
-inline void Kopf2011::_remove_crossing_edges_safe(PixelGraph &graph)
+template<class T>
+void Kopf2011::_remove_crossing_edges_safe(T &container)
{
- if ( graph.width() < 2 || graph.height() < 2 )
- return;
-
- PixelGraph::iterator it = graph.begin();
- for ( int i = 0 ; i != graph.height() - 1 ; ++i, ++it ) {
- for ( int j = 0 ; j != graph.width() - 1 ; ++j, ++it ) {
- // this <-> right
- if ( !it->adj.right )
- continue;
-
- // this <-> down
- if ( !it->adj.bottom )
- continue;
-
- PixelGraph::iterator down_right = it + graph.width() + 1;
-
- // down_right <-> right
- if ( !down_right->adj.top )
- continue;
+ for ( typename T::reverse_iterator it = container.rbegin(),
+ end = container.rend() ; it != end ; ) {
+ /* A | B
+ --+--
+ C | D */
+ PixelGraph::iterator a = it->first.first;
+ PixelGraph::iterator b = it->second.first;
+ PixelGraph::iterator c = it->second.second;
+ PixelGraph::iterator d = it->first.second;
+
+ if ( !a->adj.right || !a->adj.bottom || !b->adj.bottom
+ || !c->adj.right ) {
+ ++it;
+ continue;
+ }
- // down_right <-> down
- if ( !down_right->adj.left )
- continue;
+ // main diagonal
+ a->adj.bottomright = 0;
+ d->adj.topleft = 0;
- // main diagonal
- // this <-> down_right
- it->adj.bottomright = 0;
- down_right->adj.topleft = 0;
+ // secondary diagonal
+ b->adj.bottomleft = 0;
+ c->adj.topright = 0;
- // secondary diagonal
- // right <-> down
- (it + 1)->adj.bottomleft = 0;
- (it + graph.width())->adj.topright = 0;
- }
+ // base iterator is always past one
+ typename T::iterator current = --(it.base());
+ ++it;
+ container.erase(current);
}
}
/**
* This method removes crossing edges using the heuristics.
*/
-inline
-void Kopf2011::_remove_crossing_edges_unsafe(PixelGraph &graph,
+template<class T>
+void Kopf2011::_remove_crossing_edges_unsafe(PixelGraph &graph, T &edges,
const Options &options)
{
- if ( graph.width() < 2 || graph.height() < 2 )
- return;
-
- // Iterate over the graph, 2x2 blocks at time
- PixelGraph::iterator it = graph.begin();
- for (int i = 0 ; i != graph.height() - 1 ; ++i, ++it ) {
- for ( int j = 0 ; j != graph.width() - 1 ; ++j, ++it ) {
- using std::pair;
- using std::make_pair;
-
- typedef pair<PixelGraph::iterator, PixelGraph::iterator> Edge;
- typedef pair<Edge, int> EdgeWeight;
-
- EdgeWeight diagonals[2] = {
- make_pair(make_pair(it, graph.nodeBottomRight(it)), 0),
- make_pair(make_pair(graph.nodeRight(it), graph.nodeBottom(it)),
- 0)
- };
-
- // Check if there are crossing edges
- if ( !diagonals[0].first.first->adj.bottomright
- || !diagonals[1].first.first->adj.bottomleft ) {
- continue;
- }
-
- // Compute weights
- for ( int i = 0 ; i != 2 ; ++i ) {
- // Curves and islands heuristics
- PixelGraph::const_iterator a = diagonals[i].first.first;
- PixelGraph::const_iterator b = diagonals[i].first.second;
-
- diagonals[i].second += Heuristics::curves(graph, a, b)
- * options.curvesMultiplier;
-
- diagonals[i].second += Heuristics::islands(a, b)
- * options.islandsWeight;
- }
-
- {
- // Sparse pixels heuristic
- Heuristics::SparsePixels sparse_pixels;
-
- for ( int i = 0 ; i != 2 ; ++i )
- sparse_pixels.diagonals[i] = diagonals[i];
-
- sparse_pixels(graph, options.sparsePixelsRadius);
-
- for ( int i = 0 ; i != 2 ; ++i ) {
- diagonals[i].second += sparse_pixels.diagonals[i].second
- * options.sparsePixelsMultiplier;
- }
- }
+ std::vector< std::pair<int, int> > weights(edges.size(),
+ std::make_pair(0, 0));
+
+ // Compute weights
+ for ( typename T::size_type i = 0 ; i != edges.size() ; ++i ) {
+ /* A | B
+ --+--
+ C | D */
+ PixelGraph::iterator a = edges[i].first.first;
+ PixelGraph::iterator b = edges[i].second.first;
+ PixelGraph::iterator c = edges[i].second.second;
+ PixelGraph::iterator d = edges[i].first.second;
+
+ // Curves heuristic
+ weights[i].first += Heuristics::curves(graph, a, d)
+ * options.curvesMultiplier;
+ weights[i].second += Heuristics::curves(graph, b, c)
+ * options.curvesMultiplier;
+
+ // Islands heuristic
+ weights[i].first += Heuristics::islands(a, d) * options.islandsWeight;
+ weights[i].second += Heuristics::islands(b, c) * options.islandsWeight;
+
+ // Sparse pixels heuristic
+ using Heuristics::SparsePixels;
+ SparsePixels sparse_pixels;
+
+ sparse_pixels.diagonals[SparsePixels::MAIN_DIAGONAL].first
+ = edges[i].first;
+ sparse_pixels.diagonals[SparsePixels::SECONDARY_DIAGONAL].first
+ = edges[i].second;
+
+ sparse_pixels(graph, options.sparsePixelsRadius);
+
+ weights[i].first
+ += sparse_pixels.diagonals[SparsePixels::MAIN_DIAGONAL].second
+ * options.sparsePixelsMultiplier;
+ weights[i].second
+ += sparse_pixels.diagonals[SparsePixels::SECONDARY_DIAGONAL].second
+ * options.sparsePixelsMultiplier;
+ }
- // Remove edges with lower weight
- if ( diagonals[0].second > diagonals[1].second ) {
- diagonals[1].first.first->adj.bottomleft = 0;
- diagonals[1].first.second->adj.topright = 0;
- } else if ( diagonals[0].second < diagonals[1].second ) {
- diagonals[0].first.first->adj.bottomright = 0;
- diagonals[0].first.second->adj.topleft = 0;
- } else {
- diagonals[0].first.first->adj.bottomright = 0;
- diagonals[0].first.second->adj.topleft = 0;
- diagonals[1].first.first->adj.bottomleft = 0;
- diagonals[1].first.second->adj.topright = 0;
- }
+ // Remove edges with lower weight
+ for ( typename T::size_type i = 0 ; i != edges.size() ; ++i ) {
+ /* A | B
+ --+--
+ C | D */
+ PixelGraph::iterator a = edges[i].first.first;
+ PixelGraph::iterator b = edges[i].second.first;
+ PixelGraph::iterator c = edges[i].second.second;
+ PixelGraph::iterator d = edges[i].first.second;
+
+ if ( weights[i].first > weights[i].second ) {
+ b->adj.bottomleft = 0;
+ c->adj.topright = 0;
+ } else if ( weights[i].first < weights[i].second ) {
+ a->adj.bottomright = 0;
+ d->adj.topleft = 0;
+ } else {
+ a->adj.bottomright = 0;
+ b->adj.bottomleft = 0;
+ c->adj.topright = 0;
+ d->adj.topleft = 0;
}
}
+
+ edges.clear();
}
inline int Heuristics::curves(const PixelGraph &graph,
diff --git a/src/libdepixelize/kopftracer2011.h b/src/libdepixelize/kopftracer2011.h
index c224abe9a..598f6c79c 100644
--- a/src/libdepixelize/kopftracer2011.h
+++ b/src/libdepixelize/kopftracer2011.h
@@ -88,6 +88,23 @@ public:
/**
* # Exceptions
*
+ * \p options.optimize and options.nthreads will be ignored
+ *
+ * Glib::FileError
+ * Gdk::PixbufError
+ */
+ static Splines to_grouped_voronoi(const std::string &filename,
+ const Options &options = Options());
+
+ /*
+ * \p options.optimize and options.nthreads will be ignored
+ */
+ static Splines to_grouped_voronoi(const Glib::RefPtr<Gdk::Pixbuf const> &buf,
+ const Options &options = Options());
+
+ /**
+ * # Exceptions
+ *
* Glib::FileError
* Gdk::PixbufError
*/
@@ -106,8 +123,13 @@ private:
const Options &options);
static void _disconnect_neighbors_with_dissimilar_colors(PixelGraph &graph);
- static void _remove_crossing_edges_safe(PixelGraph &graph);
- static void _remove_crossing_edges_unsafe(PixelGraph &graph,
+
+ // here, T/template is only used as an easy way to not expose internal
+ // symbols
+ template<class T>
+ static void _remove_crossing_edges_safe(T &container);
+ template<class T>
+ static void _remove_crossing_edges_unsafe(PixelGraph &graph, T &edges,
const Options &options);
};
diff --git a/src/libdepixelize/priv/homogeneoussplines.h b/src/libdepixelize/priv/homogeneoussplines.h
index 57c77a163..6c4894dd8 100644
--- a/src/libdepixelize/priv/homogeneoussplines.h
+++ b/src/libdepixelize/priv/homogeneoussplines.h
@@ -38,6 +38,12 @@ class HomogeneousSplines
public:
struct Polygon
{
+ typedef std::vector< Point<T> > Points;
+ typedef typename Points::iterator points_iter;
+ typedef typename Points::const_iterator const_points_iter;
+ typedef typename std::vector<Points>::iterator holes_iter;
+ typedef typename std::vector<Points>::const_iterator const_holes_iter;
+
Polygon() {}
Polygon(const guint8 (&rgba)[4])
{
@@ -59,7 +65,8 @@ public:
typedef typename std::vector<Polygon>::const_iterator const_iterator;
typedef typename std::vector<Polygon>::size_type size_type;
- HomogeneousSplines(const SimplifiedVoronoi<T> &voronoi);
+ template<bool adjust_splines>
+ HomogeneousSplines(const SimplifiedVoronoi<T, adjust_splines> &voronoi);
// Iterators
iterator begin()
@@ -98,12 +105,7 @@ public:
}
private:
- typedef typename SimplifiedVoronoi<T>::Cell Cell;
typedef std::vector< Point<T> > Points;
-
- typedef typename SimplifiedVoronoi<T>::iterator voronoi_iter;
- typedef typename SimplifiedVoronoi<T>::const_iterator voronoi_citer;
-
typedef typename Points::iterator points_iter;
typedef typename Points::const_iterator points_citer;
typedef typename Points::reverse_iterator points_riter;
@@ -171,7 +173,9 @@ private:
};
template<class T>
-HomogeneousSplines<T>::HomogeneousSplines(const SimplifiedVoronoi<T> &voronoi) :
+template<bool adjust_splines>
+HomogeneousSplines<T>::HomogeneousSplines(const SimplifiedVoronoi<T,
+ adjust_splines> &voronoi) :
_width(voronoi.width()),
_height(voronoi.height())
{
@@ -179,6 +183,9 @@ HomogeneousSplines<T>::HomogeneousSplines(const SimplifiedVoronoi<T> &voronoi) :
// return;
using colorspace::same_color;
+ typedef typename SimplifiedVoronoi<T, adjust_splines>::const_iterator
+ voronoi_citer;
+
// Identify visible edges (group polygons with the same color)
for ( voronoi_citer cell_it = voronoi.begin(), cell_end = voronoi.end()
; cell_it != cell_end ; ++cell_it ) {
diff --git a/src/libdepixelize/priv/pixelgraph.h b/src/libdepixelize/priv/pixelgraph.h
index 9e8c2124a..112242647 100644
--- a/src/libdepixelize/priv/pixelgraph.h
+++ b/src/libdepixelize/priv/pixelgraph.h
@@ -28,6 +28,7 @@
#include <gdkmm/pixbuf.h>
#include <vector>
#include <cassert>
+#include <utility>
namespace Tracer {
@@ -76,6 +77,10 @@ public:
typedef std::vector<Node>::reverse_iterator reverse_iterator;
typedef std::vector<Node>::const_reverse_iterator const_reverse_iterator;
+ typedef std::pair<iterator, iterator> Edge;
+ typedef std::pair<Edge, Edge> EdgePair;
+ typedef std::vector<EdgePair> EdgePairContainer;
+
class ColumnView
{
public:
@@ -162,6 +167,7 @@ public:
// Algorithms
void connectAllNeighbors();
+ EdgePairContainer crossingEdges();
int toX(const_iterator n) const
{
@@ -389,14 +395,23 @@ inline void PixelGraph::connectAllNeighbors()
// ...then the "top" nodes...
if ( _width > 2 ) {
Node *it = &_nodes[1];
- for ( int i = 1 ; i != _width - 1 ; ++i ) {
- it->adj.right = 1;
- it->adj.bottomright = 1;
- it->adj.bottom = 1;
- it->adj.bottomleft = 1;
- it->adj.left = 1;
+ if ( _height > 1 ) {
+ for ( int i = 1 ; i != _width - 1 ; ++i ) {
+ it->adj.right = 1;
+ it->adj.bottomright = 1;
+ it->adj.bottom = 1;
+ it->adj.bottomleft = 1;
+ it->adj.left = 1;
- ++it;
+ ++it;
+ }
+ } else {
+ for ( int i = 1 ; i != _width - 1 ; ++i ) {
+ it->adj.right = 1;
+ it->adj.left = 1;
+
+ ++it;
+ }
}
}
@@ -417,14 +432,23 @@ inline void PixelGraph::connectAllNeighbors()
// ...then the "left" nodes...
if ( _height > 2 ) {
iterator it = nodeBottom(begin()); // [0][1]
- for ( int i = 1 ; i != _height - 1 ; ++i ) {
- it->adj.top = 1;
- it->adj.topright = 1;
- it->adj.right = 1;
- it->adj.bottomright = 1;
- it->adj.bottom = 1;
+ if ( _width > 1 ) {
+ for ( int i = 1 ; i != _height - 1 ; ++i ) {
+ it->adj.top = 1;
+ it->adj.topright = 1;
+ it->adj.right = 1;
+ it->adj.bottomright = 1;
+ it->adj.bottom = 1;
- it = nodeBottom(it);
+ it = nodeBottom(it);
+ }
+ } else {
+ for ( int i = 1 ; i != _height - 1 ; ++i ) {
+ it->adj.top = 1;
+ it->adj.bottom = 1;
+
+ it = nodeBottom(it);
+ }
}
}
@@ -482,6 +506,34 @@ inline void PixelGraph::connectAllNeighbors()
}
}
+PixelGraph::EdgePairContainer PixelGraph::crossingEdges()
+{
+ EdgePairContainer ret;
+
+ if ( width() < 2 || height() < 2 )
+ return ret;
+
+ // Iterate over the graph, 2x2 blocks at time
+ PixelGraph::iterator it = begin();
+ for (int i = 0 ; i != height() - 1 ; ++i, ++it ) {
+ for ( int j = 0 ; j != width() - 1 ; ++j, ++it ) {
+ EdgePair diagonals(
+ Edge(it, nodeBottomRight(it)),
+ Edge(nodeRight(it), nodeBottom(it)));
+
+ // Check if there are crossing edges
+ if ( !diagonals.first.first->adj.bottomright
+ || !diagonals.second.first->adj.bottomleft ) {
+ continue;
+ }
+
+ ret.push_back(diagonals);
+ }
+ }
+
+ return ret;
+}
+
inline PixelGraph::Node &PixelGraph::ColumnView::operator[](int line)
{
return _nodes[line * _width + _column];
diff --git a/src/libdepixelize/priv/simplifiedvoronoi.h b/src/libdepixelize/priv/simplifiedvoronoi.h
index 8a25bc626..84feab08d 100644
--- a/src/libdepixelize/priv/simplifiedvoronoi.h
+++ b/src/libdepixelize/priv/simplifiedvoronoi.h
@@ -296,21 +296,40 @@ SimplifiedVoronoi<T, adjust_splines>
PixelGraph::const_iterator graph_it = graph.begin() + 1;
Cell *cells_it = &_cells.front() + 1;
- for ( int i = 1 ; i != _width - 1 ; ++i, ++graph_it, ++cells_it ) {
- for ( int j = 0 ; j != 4 ; ++j )
- cells_it->rgba[j] = graph_it->rgba[j];
+ if ( _height > 1 ) {
+ for ( int i = 1 ; i != _width - 1 ; ++i, ++graph_it, ++cells_it ) {
+ for ( int j = 0 ; j != 4 ; ++j )
+ cells_it->rgba[j] = graph_it->rgba[j];
- // Top-left
- cells_it->vertices.push_back(Point<T>(i, 0, false));
+ // Top-left
+ cells_it->vertices.push_back(Point<T>(i, 0, false));
- // Top-right
- cells_it->vertices.push_back(Point<T>(i + 1, 0, false));
+ // Top-right
+ cells_it->vertices.push_back(Point<T>(i + 1, 0, false));
- // Bottom-right
- _complexBottomRight(graph, graph_it, cells_it, i, 0);
+ // Bottom-right
+ _complexBottomRight(graph, graph_it, cells_it, i, 0);
- // Bottom-left
- _complexBottomLeft(graph, graph_it, cells_it, i, 0);
+ // Bottom-left
+ _complexBottomLeft(graph, graph_it, cells_it, i, 0);
+ }
+ } else {
+ for ( int i = 1 ; i != _width - 1 ; ++i, ++graph_it, ++cells_it ) {
+ for ( int j = 0 ; j != 4 ; ++j )
+ cells_it->rgba[j] = graph_it->rgba[j];
+
+ // Top-left
+ cells_it->vertices.push_back(Point<T>(i, 0, false));
+
+ // Top-right
+ cells_it->vertices.push_back(Point<T>(i + 1, 0, false));
+
+ // Bottom-right
+ cells_it->vertices.push_back(Point<T>(i + 1, 1, false));
+
+ // Bottom-left
+ cells_it->vertices.push_back(Point<T>(i, 1, false));
+ }
}
}
@@ -344,24 +363,46 @@ SimplifiedVoronoi<T, adjust_splines>
PixelGraph::const_iterator graph_it = graph.begin() + _width;
Cell *cells_it = &_cells.front() + _width;
- for ( int i = 1 ; i != _height - 1 ; ++i) {
- for ( int j = 0 ; j != 4 ; ++j )
- cells_it->rgba[j] = graph_it->rgba[j];
+ if ( _width > 1 ) {
+ for ( int i = 1 ; i != _height - 1 ; ++i) {
+ for ( int j = 0 ; j != 4 ; ++j )
+ cells_it->rgba[j] = graph_it->rgba[j];
- // Top-left
- cells_it->vertices.push_back(Point<T>(0, i, false));
+ // Top-left
+ cells_it->vertices.push_back(Point<T>(0, i, false));
- // Top-right
- _complexTopRight(graph, graph_it, cells_it, 0, i);
+ // Top-right
+ _complexTopRight(graph, graph_it, cells_it, 0, i);
- // Bottom-right
- _complexBottomRight(graph, graph_it, cells_it, 0, i);
+ // Bottom-right
+ _complexBottomRight(graph, graph_it, cells_it, 0, i);
- // Bottom-left
- cells_it->vertices.push_back(Point<T>(0, i + 1, false));
+ // Bottom-left
+ cells_it->vertices.push_back(Point<T>(0, i + 1, false));
- graph_it += _width;
- cells_it += _width;
+ graph_it += _width;
+ cells_it += _width;
+ }
+ } else {
+ for ( int i = 1 ; i != _height - 1 ; ++i) {
+ for ( int j = 0 ; j != 4 ; ++j )
+ cells_it->rgba[j] = graph_it->rgba[j];
+
+ // Top-left
+ cells_it->vertices.push_back(Point<T>(0, i, false));
+
+ // Top-right
+ cells_it->vertices.push_back(Point<T>(1, i, false));
+
+ // Bottom-right
+ cells_it->vertices.push_back(Point<T>(1, i, false));
+
+ // Bottom-left
+ cells_it->vertices.push_back(Point<T>(0, i + 1, false));
+
+ graph_it += _width;
+ cells_it += _width;
+ }
}
}
@@ -890,7 +931,11 @@ SimplifiedVoronoi<T, adjust_splines>
}
if ( !smooth[0] && adjust_splines ) {
- cells_it->vertices.push_back(vertices[0].invisible());
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
+ cells_it->vertices.push_back(vertices[0].invisible());
+#else
+ cells_it->vertices.push_back(vertices[0]);
+#endif
{
Point<T> another = vertices[0];
transform(another,
@@ -899,7 +944,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
- ( 0.5625
- ( topright(a_it) + topleft(b_it) ) * 0.1875 ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertices[0];
@@ -910,7 +959,11 @@ SimplifiedVoronoi<T, adjust_splines>
- ( 0.1875
- ( topright(a_it) + topleft(b_it) ) * 0.0625) );
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertices[0];
@@ -920,7 +973,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
0.0625
+ ( bottomright(b_it) - topright(d_it) ) * 0.0625);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
transform(vertices[0],
@@ -932,7 +989,9 @@ SimplifiedVoronoi<T, adjust_splines>
+ ( topright(d_it) - topright(a_it)
- topleft(b_it) - bottomright(b_it) )
* 0.03125 ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertices[0].visible = false;
+#endif
}
}
@@ -950,7 +1009,11 @@ SimplifiedVoronoi<T, adjust_splines>
0.0625
+ ( bottomleft(a_it) - bottomleft(d_it)
- topleft(c_it) - bottomright(c_it) ) * 0.03125);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertices[1];
@@ -960,7 +1023,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
0.1875
- ( bottomright(c_it) + bottomleft(d_it) ) * 0.0625);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertices[1];
@@ -973,7 +1040,11 @@ SimplifiedVoronoi<T, adjust_splines>
- ( bottomleft(a_it) - topleft(c_it) )
* 0.0625 ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertices[1];
@@ -985,9 +1056,15 @@ SimplifiedVoronoi<T, adjust_splines>
- ( 0.1875
- ( bottomleft(a_it) - topleft(c_it) )
* 0.1875 ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertices[1].visible = false;
+#endif
}
cells_it->vertices.push_back(vertices[1]);
@@ -1029,13 +1106,21 @@ SimplifiedVoronoi<T, adjust_splines>
- ( ( bottomright(c_it) + topleft(c_it) )
* 0.03125 );
transform(another, - amount, amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.0625 * bottomright(c_it);
transform(another, amount, 0.25 - amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1043,16 +1128,26 @@ SimplifiedVoronoi<T, adjust_splines>
transform(another, - ( 0.25 - amount ),
- amount);
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.1875 * topleft(c_it);
transform(another, - ( 0.75 - amount ),
- amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
} else if ( twin_is_contour ) {
T amount = 0.125
- ( ( bottomleft(d_it) + topright(d_it) )
@@ -1076,7 +1171,11 @@ SimplifiedVoronoi<T, adjust_splines>
- amount
* ( topleft(c_it) + topright(d_it)
- bottomleft(a_it) - bottomright(b_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1087,7 +1186,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
- amount
* ( topright(d_it) - bottomright(b_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1099,7 +1202,11 @@ SimplifiedVoronoi<T, adjust_splines>
- amount
* ( topleft(c_it) - bottomleft(a_it) ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1110,9 +1217,15 @@ SimplifiedVoronoi<T, adjust_splines>
// y
- amount
* ( topleft(c_it) - bottomleft(a_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
}
} else {
// {this, right} is the pair with the angle
@@ -1146,13 +1259,21 @@ SimplifiedVoronoi<T, adjust_splines>
if ( !vertex.smooth ) {
if ( another_is_contour ) {
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(vertex.invisible());
+#else
+ cells_it->vertices.push_back(vertex);
+#endif
{
Point<T> another = vertex;
T amount = 0.1875 * topleft(b_it);
transform(another, - amount,
- ( 0.75 - amount ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1160,20 +1281,30 @@ SimplifiedVoronoi<T, adjust_splines>
transform(another, - amount,
- ( 0.25 - amount ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.0625 * bottomright(b_it);
transform(another, 0.25 - amount, amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
T amount = 0.125
- (bottomright(b_it) + topleft(b_it))
* 0.03125;
transform(vertex, amount, - amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
}
} else if ( twin_is_contour ) {
T amount = 0.125
@@ -1187,7 +1318,11 @@ SimplifiedVoronoi<T, adjust_splines>
// I REALLY NEED lambdas to improve this code without
// creating yet another interface that takes a million
// of function parameters and keep code locality
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(vertex.invisible());
+#else
+ cells_it->vertices.push_back(vertex);
+#endif
{
Point<T> another = vertex;
T amount = 0.1875;
@@ -1197,7 +1332,11 @@ SimplifiedVoronoi<T, adjust_splines>
- ( 0.75
- ( topleft(b_it) + topright(a_it) )
* amount ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1209,7 +1348,11 @@ SimplifiedVoronoi<T, adjust_splines>
- ( topleft(b_it) + topright(a_it) )
* amount ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1219,7 +1362,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
0.25 - amount
* ( bottomleft(d_it) + bottomright(c_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
transform(vertex,
@@ -1230,7 +1377,9 @@ SimplifiedVoronoi<T, adjust_splines>
( topleft(b_it) - bottomleft(d_it)
+ topright(a_it) - bottomright(c_it) )
* 0.03125);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
}
}
} else {
@@ -1273,28 +1422,46 @@ SimplifiedVoronoi<T, adjust_splines>
- ( topleft(c_it) + bottomright(c_it) )
* 0.03125;
transform(another, - amount, amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.0625 * bottomright(c_it);
transform(another, amount, 0.25 - amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.0625 * topleft(c_it);
transform(another, - ( 0.25 - amount ), - amount);
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.1875 * topleft(c_it);
transform(another, - ( 0.75 - amount ), - amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
} else {
special = true;
}
@@ -1308,7 +1475,11 @@ SimplifiedVoronoi<T, adjust_splines>
}
if ( special ) {
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(vertex.invisible());
+#else
+ cells_it->vertices.push_back(vertex);
+#endif
{
Point<T> another = vertex;
T amount = 0.1875;
@@ -1318,7 +1489,11 @@ SimplifiedVoronoi<T, adjust_splines>
- ( 0.75
- ( topleft(b_it) + topright(a_it) )
* amount ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1330,7 +1505,11 @@ SimplifiedVoronoi<T, adjust_splines>
- ( topleft(b_it) + topright(a_it) )
* amount ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1340,7 +1519,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
0.25 - amount
* ( bottomleft(d_it) + bottomright(c_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
transform(vertex,
@@ -1351,7 +1534,9 @@ SimplifiedVoronoi<T, adjust_splines>
( topleft(b_it) - bottomleft(d_it)
+ topright(a_it) - bottomright(c_it) )
* 0.03125);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
}
}
} else if ( right(c_it) && adjust_splines ) {
@@ -1372,31 +1557,49 @@ SimplifiedVoronoi<T, adjust_splines>
if ( !vertex.smooth ) {
if ( similar_neighbor_is_contour ) {
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(vertex.invisible());
+#else
+ cells_it->vertices.push_back(vertex);
+#endif
{
Point<T> another = vertex;
T amount = 0.1875 * topleft(b_it);
transform(another, - amount, - ( 0.75 - amount ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.0625 * topleft(b_it);
transform(another, - amount, - ( 0.25 - amount ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
T amount = 0.0625 * bottomright(b_it);
transform(another, 0.25 - amount, amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
T amount = 0.125
- 0.03125 * (topleft(b_it) + bottomright(b_it));
transform(vertex, amount, - amount);
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
}
} else {
special = true;
@@ -1422,7 +1625,11 @@ SimplifiedVoronoi<T, adjust_splines>
- amount
* ( topleft(c_it) + topright(d_it)
- bottomleft(a_it) - bottomright(b_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_1ST_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1433,7 +1640,11 @@ SimplifiedVoronoi<T, adjust_splines>
// y
- amount
* ( topright(d_it) - bottomright(b_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_2ND_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1445,7 +1656,11 @@ SimplifiedVoronoi<T, adjust_splines>
- amount
* ( topleft(c_it) - bottomleft(a_it) ));
another.smooth = true;
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_3RD_IS_INVISIBLE
+ cells_it->vertices.push_back(another.invisible());
+#else
cells_it->vertices.push_back(another);
+#endif
}
{
Point<T> another = vertex;
@@ -1456,9 +1671,15 @@ SimplifiedVoronoi<T, adjust_splines>
// y
- amount
* ( topleft(c_it) - bottomleft(a_it) ));
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_4TH_IS_INVISIBLE
cells_it->vertices.push_back(another.invisible());
+#else
+ cells_it->vertices.push_back(another);
+#endif
}
+#ifdef LIBDEPIXELIZE_ENABLE_EXPERIMENTAL_FEATURES_5TH_IS_INVISIBLE
vertex.visible = false;
+#endif
}
} else {
// there is a 4-color pattern, where the current node
diff --git a/src/libuemf/uemf.c b/src/libuemf/uemf.c
index 55388cf53..069cf901b 100644
--- a/src/libuemf/uemf.c
+++ b/src/libuemf/uemf.c
@@ -16,8 +16,8 @@
/*
File: uemf.c
-Version: 0.0.25
-Date: 15-JAN-2014
+Version: 0.0.26
+Date: 24-MAR-2014
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
Copyright: 2014 David Mathog and California Institute of Technology (Caltech)
@@ -660,7 +660,6 @@ int RGBA_to_DIB(
bs = colortype/8;
if(bs<1){
- bs=1;
usedbytes = (w*colortype + 7)/8; // width of line in fully and partially occupied bytes
}
else {
@@ -956,7 +955,6 @@ int DIB_to_RGBA(
cbRgba_px = stride * h;
bs = colortype/8;
if(bs<1){
- bs=1;
usedbytes = (w*colortype + 7)/8; // width of line in fully and partially occupied bytes
}
else {
diff --git a/src/libuemf/uemf_endian.c b/src/libuemf/uemf_endian.c
index f5dcf829a..8f2be57da 100644
--- a/src/libuemf/uemf_endian.c
+++ b/src/libuemf/uemf_endian.c
@@ -19,8 +19,8 @@
/*
File: uemf_endian.c
-Version: 0.0.14
-Date: 15-JAN-2014
+Version: 0.0.15
+Date: 24-MAR-2014
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
Copyright: 2014 David Mathog and California Institute of Technology (Caltech)
@@ -1193,10 +1193,8 @@ void U_EMREXTSELECTCLIPRGN_swap(char *record, int torev){
int nextroff=0;
int limit=0;
PU_EMREXTSELECTCLIPRGN pEmr = (PU_EMREXTSELECTCLIPRGN) (record);
- roff = 0;
if(torev){
limit = pEmr->emr.nSize;
- nextroff = 0;
}
core5_swap(record, torev);
if(!torev){
diff --git a/src/libuemf/uemf_utf.c b/src/libuemf/uemf_utf.c
index 0c07148a4..0159d51cd 100644
--- a/src/libuemf/uemf_utf.c
+++ b/src/libuemf/uemf_utf.c
@@ -239,8 +239,13 @@ uint16_t *U_Utf32leToUtf16le(
iconv_t conv = iconv_open("UTF-16LE", "UTF-32LE");
status = iconv(conv, ICONV_CAST &src, &srclen, &dst, &dstlen);
iconv_close(conv);
- if(status == (size_t) -1)return(NULL);
- if(len)*len=wchar16len((uint16_t *)dst2);
+ if(status == (size_t) -1){
+ free(dst2);
+ dst2 = NULL;
+ }
+ else if(len){
+ *len=wchar16len((uint16_t *)dst2);
+ }
return((uint16_t *)dst2);
}
@@ -270,8 +275,13 @@ uint32_t *U_Utf16leToUtf32le(
if ( conv == (iconv_t)-1)return(NULL);
status = iconv(conv, ICONV_CAST &src2, &srclen, &dst, &dstlen);
iconv_close(conv);
- if(status == (size_t) -1)return(NULL);
- if(len)*len=wchar32len((uint32_t *)dst2);
+ if(status == (size_t) -1){
+ free(dst2);
+ dst2 = NULL;
+ }
+ else if(len){
+ *len=wchar32len((uint32_t *)dst2);
+ }
return((uint32_t *) dst2);
}
@@ -307,8 +317,13 @@ uint32_t *U_Latin1ToUtf32le(
if ( conv == (iconv_t) -1)return(NULL);
status = iconv(conv, ICONV_CAST &src2, &srclen, &dst, &dstlen);
iconv_close(conv);
- if(status == (size_t) -1)return(NULL);
- if(len)*len=wchar32len((uint32_t *)dst2);
+ if(status == (size_t) -1){
+ free(dst2);
+ dst2 = NULL;
+ }
+ else if(len){
+ *len=wchar32len((uint32_t *)dst2);
+ }
return((uint32_t *) dst2);
}
@@ -338,8 +353,13 @@ uint32_t *U_Utf8ToUtf32le(
if ( conv == (iconv_t) -1)return(NULL);
status = iconv(conv, ICONV_CAST &src2, &srclen, &dst, &dstlen);
iconv_close(conv);
- if(status == (size_t) -1)return(NULL);
- if(len)*len=wchar32len((uint32_t *)dst2);
+ if(status == (size_t) -1){
+ free(dst2);
+ dst2 = NULL;
+ }
+ else if(len){
+ *len=wchar32len((uint32_t *)dst2);
+ }
return((uint32_t *) dst2);
}
@@ -369,8 +389,13 @@ char *U_Utf32leToUtf8(
if ( conv == (iconv_t)-1)return(NULL);
status = iconv(conv, ICONV_CAST &src2, &srclen, &dst, &dstlen);
iconv_close(conv);
- if(status == (size_t) -1)return(NULL);
- if(len)*len=strlen(dst2);
+ if(status == (size_t) -1){
+ free(dst2);
+ dst2 = NULL;
+ }
+ else if(len){
+ *len=strlen(dst2);
+ }
return(dst2);
}
@@ -400,8 +425,13 @@ uint16_t *U_Utf8ToUtf16le(
if (conv == (iconv_t) -1)return(NULL);
status = iconv(conv, ICONV_CAST &src, &srclen, &dst, &dstlen);
iconv_close(conv);
- if(status == (size_t) -1)return(NULL);
- if(len)*len=wchar16len((uint16_t *)dst2);
+ if(status == (size_t) -1){
+ free(dst2);
+ dst2 = NULL;
+ }
+ else if(len){
+ *len=wchar16len((uint16_t *)dst2);
+ }
return((uint16_t *)dst2);
}
@@ -514,8 +544,13 @@ char *U_Utf8ToLatin1(
if ( conv == (iconv_t) -1)return(NULL);
status = iconv(conv, ICONV_CAST &src, &srclen, &dst, &dstlen);
iconv_close(conv);
- if(status == (size_t) -1)return(NULL);
- if(len)*len=strlen(dst2);
+ if(status == (size_t) -1){
+ free(dst2);
+ dst2 = NULL;
+ }
+ else if(len){
+ *len=strlen(dst2);
+ }
return((char *) dst2);
}
@@ -546,8 +581,13 @@ char *U_Latin1ToUtf8(
if ( conv == (iconv_t) -1)return(NULL);
status = iconv(conv, ICONV_CAST &src, &srclen, &dst, &dstlen);
iconv_close(conv);
- if(status == (size_t) -1)return(NULL);
- if(len)*len=strlen(dst2);
+ if(status == (size_t) -1){
+ free(dst2);
+ dst2 = NULL;
+ }
+ else if(len){
+ *len=strlen(dst2);
+ }
return((char *) dst2);
}
diff --git a/src/libuemf/upmf.c b/src/libuemf/upmf.c
index 742b8b0f7..a7a5e42b5 100644
--- a/src/libuemf/upmf.c
+++ b/src/libuemf/upmf.c
@@ -21,11 +21,11 @@
/*
File: upmf.c
-Version: 0.0.4
-Date: 27-NOV-2013
+Version: 0.0.5
+Date: 24-MAR-2014
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
-Copyright: 2013 David Mathog and California Institute of Technology (Caltech)
+Copyright: 2014 David Mathog and California Institute of Technology (Caltech)
*/
#ifdef __cplusplus
@@ -608,7 +608,7 @@ int U_PO_free(U_PSEUDO_OBJ **po){
Data fields: an array of a basic type of Units bytes repeated Reps times with the target byte order
described in TE.
- Ptrs: Address of the first byte of the data fields.
+ Ptrs: Address of the first byte of the data fields.
Units: Number of bytes of in each data field unit
@@ -1303,8 +1303,9 @@ uint8_t *U_LOAD_GUID(char *string){
if(3 != sscanf(string + 0,"%8X",&Data1) +
sscanf(string + 8,"%4X",&tData2) +
sscanf(string + 12,"%4X",&tData3)){
- free(lf);
- return(NULL);
+ free(hold);
+ hold = NULL;
+ goto bye;
}
Data2=tData2;
Data3=tData3;
@@ -1318,12 +1319,14 @@ uint8_t *U_LOAD_GUID(char *string){
/* remainder is converted byte by byte and stored in that order */
for(i=0;i<8;i++,Data4+=2,lf++){
if(1 != sscanf(Data4,"%2X",&tByte)){
- free(lf);
- return(NULL);
+ free(hold);
+ hold = NULL;
+ goto bye;
}
*lf=tByte;
}
}
+bye:
return(hold);
}
@@ -1767,7 +1770,7 @@ U_PSEUDO_OBJ *U_PMF_PEN_set(uint32_t Version, const U_PSEUDO_OBJ *PenData, const
EMF+ manual 2.2.1.8, Microsoft name: EmfPlusRegion Object
*/
U_PSEUDO_OBJ *U_PMF_REGION_set(uint32_t Version, uint32_t Count, const U_PSEUDO_OBJ *Nodes){
- if(Nodes->Type != U_PMF_REGIONNODE_OID)return(NULL);
+ if(!Nodes || Nodes->Type != U_PMF_REGIONNODE_OID)return(NULL);
const U_SERIAL_DESC List[] = {
{&Version, 4, 1, U_LE},
{&Count, 4, 1, U_LE},
@@ -1787,6 +1790,7 @@ U_PSEUDO_OBJ *U_PMF_REGION_set(uint32_t Version, uint32_t Count, const U_PSEUDO_
EMF+ manual 2.2.1.9, Microsoft name: EmfPlusStringFormat Object
*/
U_PSEUDO_OBJ *U_PMF_STRINGFORMAT_set(U_PMF_STRINGFORMAT *Sfs, const U_PSEUDO_OBJ *Sfd){
+ if(!Sfs){ return(NULL); }
if(Sfd){
if((!Sfs->TabStopCount && !Sfs->RangeCount) || (Sfd->Type != U_PMF_STRINGFORMATDATA_OID))return(NULL);
}
@@ -1901,6 +1905,7 @@ U_PMF_ARGB U_PMF_ARGBOBJ_set(uint8_t Alpha, uint8_t Red, uint8_t Green, uint8_t
EMF+ manual 2.2.2.2, Microsoft name: EmfPlusBitmap Object
*/
U_PSEUDO_OBJ *U_PMF_BITMAP_set(const U_PMF_BITMAP *Bs, const U_PSEUDO_OBJ *Bm){
+ if(!Bs)return(NULL);
if(Bm->Type != U_PMF_BITMAPDATA_OID &&
Bm->Type != U_PMF_COMPRESSEDIMAGE_OID )return(NULL);
uint32_t Pad = UP4(Bm->Used) - Bm->Used; /* undocumented padding, must be present for at least PNG */
@@ -1925,6 +1930,7 @@ U_PSEUDO_OBJ *U_PMF_BITMAP_set(const U_PMF_BITMAP *Bs, const U_PSEUDO_OBJ *Bm){
*/
U_PSEUDO_OBJ *U_PMF_BITMAPDATA_set( const U_PSEUDO_OBJ *Ps, int cbBm, const char *Bm){
if(Ps && (Ps->Type != U_PMF_PALETTE_OID))return(NULL);
+ if(!Bm && cbBm)return(NULL);
const U_SERIAL_DESC List[] = {
{(Ps ? Ps->Data : NULL), (Ps ? Ps->Used : 0), (Ps ? 1 : 0), U_LE},
{Bm, cbBm, 1, U_XE},
@@ -2020,7 +2026,7 @@ U_PSEUDO_OBJ *U_PMF_BLENDCOLORS_linear_set(uint32_t Elements, U_PMF_ARGB StartCo
\return Pointer to PseudoObject, NULL on error
\param Elements members in each array
\param Positions positions along gradient line. The first position MUST be 0.0 and the last MUST be 1.0.
- \param Factors blending factors, 0.0->1.0 values, inclusiv
+ \param Factors blending factors, 0.0->1.0 values, inclusive
EMF+ manual 2.2.2.5, Microsoft name: EmfPlusBlendFactors Object
*/
@@ -2088,7 +2094,7 @@ U_PSEUDO_OBJ *U_PMF_BLENDFACTORS_linear_set(uint32_t Elements, U_FLOAT StartFact
EMF+ manual 2.2.2.6, Microsoft name: EmfPlusBoundaryPathData Object
*/
U_PSEUDO_OBJ *U_PMF_BOUNDARYPATHDATA_set(const U_PSEUDO_OBJ *Path){
- if(Path->Type != U_PMF_PATH_OID)return(NULL);
+ if(!Path || Path->Type != U_PMF_PATH_OID)return(NULL);
/* PO Used is size_t, might be 8 bytes, value in record must be 4 bytes */
uint32_t Used = Path->Used;
const U_SERIAL_DESC List[] = {
@@ -2183,7 +2189,7 @@ U_PSEUDO_OBJ *U_PMF_COMPRESSEDIMAGE_set(int32_t cbImage, const char *Image){
EMF+ manual 2.2.2.11, Microsoft name: EmfPlusCustomEndCapData Object
*/
U_PSEUDO_OBJ *U_PMF_CUSTOMENDCAPDATA_set(const U_PSEUDO_OBJ *Clc){
- if(Clc->Type != U_PMF_CUSTOMLINECAP_OID)return(NULL);
+ if(!Clc || Clc->Type != U_PMF_CUSTOMLINECAP_OID)return(NULL);
/* PO Used is size_t, might be 8 bytes, value in record must be 4 bytes */
uint32_t Used = Clc->Used;
const U_SERIAL_DESC List[] = {
@@ -2252,7 +2258,7 @@ U_PSEUDO_OBJ *U_PMF_CUSTOMLINECAPDATA_set(uint32_t Flags, uint32_t Cap,
uint32_t Join, U_FLOAT MiterLimit, U_FLOAT WidthScale,
const U_PSEUDO_OBJ *Clcod
){
- if(Clcod->Type != U_PMF_CUSTOMLINECAPOPTIONALDATA_OID)return(NULL);
+ if(!Clcod || Clcod->Type != U_PMF_CUSTOMLINECAPOPTIONALDATA_OID)return(NULL);
const U_SERIAL_DESC List[] = {
{&Flags, 4, 1, U_LE},
{&Cap, 4, 1, U_LE},
@@ -2282,8 +2288,8 @@ U_PSEUDO_OBJ *U_PMF_CUSTOMLINECAPOPTIONALDATA_set(const U_PSEUDO_OBJ *Fill, cons
if(Fill && (Fill->Type != U_PMF_FILLPATHOBJ_OID))return(NULL);
if(Line && (Line->Type != U_PMF_LINEPATH_OID))return(NULL);
const U_SERIAL_DESC List[] = {
- {Fill->Data, Fill->Used, 1, U_XE},
- {Line->Data, Line->Used, 1, U_XE},
+ {(Fill ? Fill->Data : NULL), (Fill ? Fill->Used : 0), 1, U_XE},
+ {(Line ? Line->Data : NULL), (Line ? Line->Used : 0), 1, U_XE},
{NULL,0,0,U_XX}
};
U_PSEUDO_OBJ *po = U_PMF_SERIAL_set(U_PMF_CUSTOMLINECAPOPTIONALDATA_OID, List);
@@ -2298,7 +2304,7 @@ U_PSEUDO_OBJ *U_PMF_CUSTOMLINECAPOPTIONALDATA_set(const U_PSEUDO_OBJ *Fill, cons
EMF+ manual 2.2.2.15, Microsoft name: EmfPlusCustomStartCapData Object
*/
U_PSEUDO_OBJ *U_PMF_CUSTOMSTARTCAPDATA_set(const U_PSEUDO_OBJ *Clc){
- if(Clc && (Clc->Type != U_PMF_CUSTOMLINECAP_OID))return(NULL);
+ if(!Clc || Clc->Type != U_PMF_CUSTOMLINECAP_OID)return(NULL);
const U_SERIAL_DESC List[] = {
{Clc->Data, Clc->Used, 1, U_XE},
{NULL,0,0,U_XX}
@@ -2464,7 +2470,7 @@ U_PSEUDO_OBJ *U_PMF_DASHEDLINEDATA_set3(U_FLOAT Unit, uint32_t BitPat){
EMF+ manual 2.2.2.17, Microsoft name: EmfPlusFillPath Object
*/
U_PSEUDO_OBJ *U_PMF_FILLPATHOBJ_set(const U_PSEUDO_OBJ *Path){
- if(Path && (Path->Type != U_PMF_PATH_OID))return(NULL);
+ if(!Path || (Path->Type != U_PMF_PATH_OID))return(NULL);
const U_SERIAL_DESC List[] = {
{Path->Data, Path->Used, 1, U_XE},
{NULL,0,0,U_XX}
@@ -2642,10 +2648,10 @@ U_PSEUDO_OBJ *U_PMF_LINEARGRADIENTBRUSHDATA_set(const U_PMF_LINEARGRADIENTBRUSHD
\brief Create and set a U_PMF_LINEARGRADIENTBRUSHOPTIONALDATA PseudoObject
\return Pointer to PseudoObject, NULL on error
\param Flags Bits are set that indicate which of the following were included. The caller must clear before passing it in.
- \param Tm U_PSEUDO_OBJ containing a U_PMF_TRANSFORMMATRIX object
- \param Bc U_PSEUDO_OBJ containing a U_PMF_BLENDCOLORS object or NULL
- \param BfH U_PSEUDO_OBJ containing a U_PMF_BLENDFACTORS (H) object or NULL
- \param BfV U_PSEUDO_OBJ containing a U_PMF_BLENDFACTORS (V) object or NULL (WARNING, GDI+ defines this field but does not render it. DO NOT USE.)
+ \param Tm (optional) U_PSEUDO_OBJ containing a U_PMF_TRANSFORMMATRIX object
+ \param Bc (optional) U_PSEUDO_OBJ containing a U_PMF_BLENDCOLORS object or NULL
+ \param BfH (optional) U_PSEUDO_OBJ containing a U_PMF_BLENDFACTORS (H) object or NULL
+ \param BfV (optional) U_PSEUDO_OBJ containing a U_PMF_BLENDFACTORS (V) object or NULL (WARNING, GDI+ defines this field but does not render it. DO NOT USE.)
EMF+ manual 2.2.2.25, Microsoft name: EmfPlusLinearGradientBrushOptionalData Object
@@ -2746,7 +2752,7 @@ U_PSEUDO_OBJ *U_PMF_PATHGRADIENTBRUSHDATA_set(uint32_t Flags, int32_t WrapMode,
const U_PSEUDO_OBJ *Gradient, const U_PSEUDO_OBJ *Boundary, const U_PSEUDO_OBJ *Data){
if( (Flags & U_BD_Path) && (!Boundary || (Boundary->Type != U_PMF_BOUNDARYPATHDATA_OID)))return(NULL);
if(!(Flags & U_BD_Path) && (!Boundary || (Boundary->Type != U_PMF_BOUNDARYPOINTDATA_OID)))return(NULL);
- if(!(Gradient) || (Gradient->Type != (U_PMF_ARGB_OID | U_PMF_ARRAY_OID)))return(NULL);
+ if(!Gradient || (Gradient->Type != (U_PMF_ARGB_OID | U_PMF_ARRAY_OID)))return(NULL);
if(!(Flags & U_BD_Transform) &&
!(Flags & U_BD_PresetColors) &&
!(Flags & U_BD_BlendFactorsH) &&
@@ -2925,7 +2931,7 @@ U_PSEUDO_OBJ *U_PMF_PENOPTIONALDATA_set(uint32_t Flags, U_PSEUDO_OBJ *Tm, int32_
if((Flags & U_PD_DLData) && (!DLData || (DLData->Type != U_PMF_DASHEDLINEDATA_OID)) )return(NULL);
if((Flags & U_PD_CLData) && (!CmpndLineData || (CmpndLineData->Type != U_PMF_COMPOUNDLINEDATA_OID)) )return(NULL);
if((Flags & U_PD_CustomStartCap) && (!CSCapData || (CSCapData->Type != U_PMF_CUSTOMSTARTCAPDATA_OID)))return(NULL);
- if((Flags & U_PD_CustomEndCap) &&(!CECapData || (CECapData->Type != U_PMF_CUSTOMENDCAPDATA_OID)) )return(NULL);
+ if((Flags & U_PD_CustomEndCap) && (!CECapData || (CECapData->Type != U_PMF_CUSTOMENDCAPDATA_OID)) )return(NULL);
/* prepend the Flags field to the PseudoObject proper */
const U_SERIAL_DESC List[] = {
@@ -3092,13 +3098,15 @@ U_PSEUDO_OBJ *U_PMF_RECT_set(U_PMF_RECT *Rect){
U_PSEUDO_OBJ *U_PMF_RECTN_set(uint32_t Elements, U_PMF_RECT *Rects){
if(!Rects){ return(NULL); }
uint32_t count = Elements;
- U_SERIAL_DESC *Lptr = (U_SERIAL_DESC *) malloc(4 + (Elements * 2 * 4) + 4);
- U_SERIAL_DESC *List = List;
+ U_SERIAL_DESC *List = (U_SERIAL_DESC *) malloc((Elements + 2) * sizeof(U_SERIAL_DESC));
+ U_SERIAL_DESC *Lptr = List;
if(!List){ return(NULL); }
*Lptr++ = (U_SERIAL_DESC){&Elements, 4, 1, U_LE};
- for(; count; count--, Lptr++, Rects++){ *Lptr = (U_SERIAL_DESC){Rects, 2, 4, U_LE}; }
+ for(; count; count--, Lptr++, Rects++){
+ *Lptr = (U_SERIAL_DESC){Rects, 2, 4, U_LE};
+ }
*Lptr = (U_SERIAL_DESC){NULL,0,0,U_XX};
- U_PSEUDO_OBJ *po = U_PMF_SERIAL_set(U_PMF_RECTF_OID | U_PMF_ARRAY_OID, List);
+ U_PSEUDO_OBJ *po = U_PMF_SERIAL_set(U_PMF_RECT_OID | U_PMF_ARRAY_OID, List);
free(List);
return(po);
}
@@ -3777,6 +3785,7 @@ U_PSEUDO_OBJ *U_PMR_SETCLIPREGION_set(uint32_t PathID, uint32_t CMenum){
*/
U_PSEUDO_OBJ *U_PMR_COMMENT_set(size_t cbData, const void *Data){
if(UP4(cbData) != cbData){ return(NULL); }
+ if(cbData && !Data){ return(NULL); }
int Size=cbData;
U_PSEUDO_OBJ *ph = U_PMR_CMN_HDR_set(U_PMR_COMMENT,0,Size);
@@ -4365,6 +4374,7 @@ U_PSEUDO_OBJ *U_PMR_DRAWSTRING_set(uint32_t FontID, const U_PSEUDO_OBJ *BrushID,
int btype;
if(FontID>63){ return(NULL); }
if(!Length){ return(NULL); }
+ else if (!Text){ return(NULL); }
if(!Rect || Rect->Type != U_PMF_RECTF_OID){ return(NULL); }
if(BrushID){
if( BrushID->Used != 4){ return(NULL); }
@@ -4668,6 +4678,7 @@ U_PSEUDO_OBJ *U_PMR_FILLREGION_set(uint32_t RgnID, const U_PSEUDO_OBJ *BrushID){
\param Po U_PSEUDO_OBJ containing an object type that may be stored in the EMF+ object table
*/
U_PSEUDO_OBJ *U_PMR_OBJECT_PO_set(uint32_t ObjID, U_PSEUDO_OBJ *Po){
+ if(!Po){ return(NULL); }
int otype = U_OID_To_OT(Po->Type); /* This will return 0 if the type is not valid for an object */
if(!otype){ return(NULL); }
U_PSEUDO_OBJ *po = U_PMR_OBJECT_set(ObjID, otype, 0, 0, Po->Used, Po->Data); /* 0,0 = rec. not continued, TSize value (ignored) */
@@ -4703,6 +4714,7 @@ U_PSEUDO_OBJ *U_PMR_OBJECT_set(uint32_t ObjID, int otype, int ntype, uint32_t TS
int Pad = UP4(TSize) - TSize;
if((otype < U_OT_Brush) || (otype > U_OT_CustomLineCap)){ return(NULL); }
if(ntype && (cbData > U_OBJRECLIM)){ return(NULL); }
+ if(!Data){ return(NULL); }
U_PSEUDO_OBJ *po;
if(!ntype && !TSize && (cbData > U_OBJRECLIM)){
@@ -6268,11 +6280,11 @@ int U_PMF_POINTR_get(const char **contents, U_FLOAT *X, U_FLOAT *Y){
\param Points Caller must free. Array of U_PMF_POINTF coordinates.
*/
int U_PMF_VARPOINTS_get(const char **contents, uint16_t Flags, int Elements, U_PMF_POINTF **Points){
+ if(!contents || !*contents || !Points || !Elements){ return(0); }
U_PMF_POINTF *pts = (U_PMF_POINTF *)malloc(Elements * sizeof(U_PMF_POINTF));
U_FLOAT XF, YF;
U_FLOAT XFS, YFS;
- if(!contents || !*contents || !Points){ return(0); }
*Points = pts;
for(XFS = YFS = 0.0; Elements; Elements--, pts++){
if(Flags & U_PPF_P){
diff --git a/src/libuemf/upmf_print.c b/src/libuemf/upmf_print.c
index f446d6caf..13bbfade8 100644
--- a/src/libuemf/upmf_print.c
+++ b/src/libuemf/upmf_print.c
@@ -6,11 +6,11 @@
/*
File: upmf_print.c
-Version: 0.0.2
-Date: 17-OCT-2013
+Version: 0.0.3
+Date: 24-MAR-2014
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
-Copyright: 2013 David Mathog and California Institute of Technology (Caltech)
+Copyright: 2014 David Mathog and California Institute of Technology (Caltech)
*/
/* compiler options:
@@ -790,7 +790,6 @@ int U_PMF_BLENDCOLORS_print(const char *contents){
const char *Colors;
int status = U_PMF_BLENDCOLORS_get(contents, &Elements, &Positions, &Colors);
if(status){
- status = 0;
printf(" + BlendColors: Entries:%d (entry,pos,color): ", Elements);
for(i=0; i<Elements; i++){
printf(" (%d,%f,", i, Positions[i]);
diff --git a/src/libuemf/uwmf.c b/src/libuemf/uwmf.c
index be1feadea..82be9f324 100644
--- a/src/libuemf/uwmf.c
+++ b/src/libuemf/uwmf.c
@@ -19,8 +19,8 @@
/*
File: uwmf.c
-Version: 0.0.13
-Date: 30-JAN-2014
+Version: 0.0.14
+Date: 24-MAR-2014
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
Copyright: 2014 David Mathog and California Institute of Technology (Caltech)
@@ -327,9 +327,9 @@ uint32_t U_wmr_values(int idx){
\param idx WMR record type.
*/
-char *U_wmr_names(int idx){
+const char *U_wmr_names(int idx){
int ret;
- static char *U_WMR_NAMES[257]={
+ static const char *U_WMR_NAMES[257]={
"U_WMR_EOF",
"U_WMR_SETBKCOLOR",
"U_WMR_SETBKMODE",
@@ -597,8 +597,8 @@ char *U_wmr_names(int idx){
\return name of the WMR record, "UNKNOWN_ESCAPE" if out of range.
\param idx Escape record type.
*/
-char *U_wmr_escnames(int idx){
- char *name;
+const char *U_wmr_escnames(int idx){
+ const char *name;
if(idx>=0 && idx <= 0x0023){
switch(idx){
case 0x0001: name = "NEWFRAME"; break;
@@ -1461,6 +1461,7 @@ int wmf_start(
wtl->chunk = chunksize;
wtl->largest = 0; /* only used by WMF */
wtl->sumObjects = 0; /* only used by WMF */
+ (void) wmf_highwater(U_HIGHWATER_CLEAR);
*wt=wtl;
return(0);
}
@@ -1480,6 +1481,7 @@ int wmf_free(
free(wtl->buf);
free(wtl);
*wt=NULL;
+ (void)wmf_highwater(U_HIGHWATER_CLEAR);
return(0);
}
@@ -1509,8 +1511,9 @@ int wmf_finish(
memcpy(record + offsetof(U_WMRHEADER,Sizew), &tmp, 4); /* 16 bit words in file. not aligned */
tmp = (wt->largest)/2;
memcpy(record + offsetof(U_WMRHEADER,maxSize), &tmp, 4); /* 16 bit words in largest record, not aligned */
- if(wt->sumObjects > UINT16_MAX)return(3);
- tmp16 = wt->sumObjects;
+ uint32_t maxobj = wmf_highwater(U_HIGHWATER_READ);
+ if(maxobj > UINT16_MAX)return(3);
+ tmp16 = maxobj;
memcpy(record + offsetof(U_WMRHEADER,nObjects), &tmp16, 2); /* Total number of brushes, pens, and other graphics objects defined in this file */
#if U_BYTE_SWAP
@@ -1654,6 +1657,28 @@ int wmf_header_append(
}
/**
+ \brief Keep track of the largest number used.
+ \return The largest object number used.
+ \param setval U_HIGHWATER_READ only return value, U_HIGHWATER_CLEAR also set value to 0, anything else, set to this if higher than stored.
+*/
+int wmf_highwater(uint32_t setval){
+ static uint32_t value=0;
+ uint32_t retval;
+ if(setval == U_HIGHWATER_READ){
+ retval = value;
+ }
+ else if(setval == U_HIGHWATER_CLEAR){
+ retval = value;
+ value = 0;
+ }
+ else {
+ if(setval > value)value = setval;
+ retval = value;
+ }
+ return(retval);
+}
+
+/**
\brief Create a handle table. Entries filled with 0 are empty, entries >0 hold a handle.
\return 0 for success, >=1 for failure.
\param initsize Initialize with space for this number of handles
@@ -1736,8 +1761,13 @@ int wmf_htable_insert(
}
*ih = wht->lolimit; // handle that is inserted in first available slot
wht->table[*ih] = *ih; // handle goes into preexisting (but zero) slot in table, handle number is the same as the slot number
- if(*ih > wht->hilimit){ wht->hilimit = *ih; }
- if(*ih > wht->peak){ wht->peak = *ih; }
+ if(*ih > wht->hilimit){
+ wht->hilimit = *ih;
+ (void) wmf_highwater(wht->hilimit);
+ }
+ if(*ih > wht->peak){
+ wht->peak = *ih;
+ }
/* Find the next available slot, it will be at least one higher than the present position, and will have a zero in it. */
wht->lolimit++;
while(wht->lolimit<= wht->hilimit && wht->table[wht->lolimit]){ wht->lolimit++; }
@@ -2034,7 +2064,7 @@ char *U_WMRCORE_PALETTE_set(
off = U_SIZE_METARECORD;
memcpy(record+off, &Palette->Start, 2); off+=2;
memcpy(record+off, &Palette->NumEntries, 2); off+=2;
- memcpy(record+off, &Palette->PalEntries, nPE); off+=2;
+ memcpy(record+off, &Palette->PalEntries, nPE);
}
return(record);
}
@@ -2157,9 +2187,9 @@ char *wcreatedibpatternbrush_srcdib_set(
}
/**
- \brief Allocate and construct a U_WMRCREATEPATTERNBRUSH record from a U_BITMAP16 object.
- Use this function instead of calling U_WMRCREATEPATTERNBRUSH_set() directly.
- \return pointer to the U_WMRCREATEPATTERNBRUSH record, or NULL on error.
+ \brief Allocate and construct a U_WMRDIBCREATEPATTERNBRUSH record from a U_BITMAP16 object.
+ Use this function instead of calling U_WMRDIBCREATEPATTERNBRUSH_set() directly.
+ \return pointer to the U_WMRDIBCREATEPATTERNBRUSH record, or NULL on error.
\param ihBrush handle to be used by new object
\param wht WMF handle table
\param iUsage DIBColors enumeration
@@ -2179,7 +2209,8 @@ char *wcreatedibpatternbrush_srcbm16_set(
/**
\brief Allocate and construct a U_WMRCREATEPATTERNBRUSH record, create a handle and returns it
Use this function instead of calling U_WMRCREATEPATTERNBRUSH_set() directly.
- Warning - application support for U_WMRCREATEPATTERNBRUSH is spotty, better to use U_WMRDIBCREATEPATTERNBRUSH.
+ WARNING - U_WMRCREATEPATTERNBRUSH has been declared obsolete and application support is spotty -
+ use U_WMRDIBCREATEPATTERNBRUSH instead.
\return pointer to the U_WMRCREATEPATTERNBRUSH record, or NULL on error.
\param ihBrush handle to be used by new object
\param wht WMF handle table
@@ -2804,13 +2835,13 @@ char *U_WMRTEXTOUT_set(U_POINT16 Dst, char *string){
if(record){
U_WMRCORE_SETRECHEAD(record,irecsize,U_WMR_TEXTOUT);
off = U_SIZE_METARECORD;
- memcpy(record+off,&Length,2); off+=2;
- memcpy(record+off,string,Length); off+=Length;
+ memcpy(record+off,&Length,2); off+=2;
+ memcpy(record+off,string,Length); off+=Length;
if(Length!=L2){
- memset(record+off,0,1); off+=1;
+ memset(record+off,0,1); off+=1;
}
- memcpy(record+off,&Dst.y,2); off+=2;
- memcpy(record+off,&Dst.x,2); off+=2;
+ memcpy(record+off,&Dst.y,2); off+=2;
+ memcpy(record+off,&Dst.x,2);
}
return(record);
}
@@ -3427,7 +3458,7 @@ char *U_WMRDIBCREATEPATTERNBRUSH_set(
if(cbBm164 - cbBm16)memset(record+off,0,cbBm164 - cbBm16);
}
}
- else if(Bmi){
+ else if(Bmi && Px){
SET_CB_FROM_PXBMI(Px,Bmi,cbImage,cbImage4,cbBmi,cbPx);
irecsize = U_SIZE_WMRDIBCREATEPATTERNBRUSH + cbBmi + cbImage4;
record = malloc(irecsize);
@@ -4257,7 +4288,8 @@ char *U_WMRF8_set(void){
/**
\brief Allocate and construct a U_WMRCREATEPATTERNBRUSH record.
- Warning - application support for U_WMRCREATEPATTERNBRUSH is spotty, better to use U_WMRDIBCREATEPATTERNBRUSH.
+ WARNING - U_WMRCREATEPATTERNBRUSH has been declared obsolete and application support is spotty -
+ use U_WMRDIBCREATEPATTERNBRUSH instead.
\return pointer to the U_WMRCREATEPATTERNBRUSH record, or NULL on error.
\param Bm16 Pointer to a Bitmap16 Object, only the first 10 bytes are used.
\param Pattern byte array pattern, described by Bm16, for brush
@@ -4450,23 +4482,17 @@ int U_WMRCORE_RECSAFE_get(
/* records like U_WMRFLOODFILL and others. all args are optional, Color is not */
int U_WMRCORE_1U16_CRF_2U16_get(
const char *contents,
- int minsize,
uint16_t *arg1,
U_COLORREF *Color,
uint16_t *arg2,
uint16_t *arg3
){
- int size = U_WMRCORE_RECSAFE_get(contents, minsize);
- int irecsize,off;
- irecsize = U_SIZE_METARECORD + U_SIZE_COLORREF;
- if(arg1)irecsize+=2;
- if(arg2)irecsize+=2;
- if(arg3)irecsize+=2;
- off = U_SIZE_METARECORD;
- if(arg1){ memcpy(arg1, contents + off, 2); off+=2; }
- memcpy(Color, contents + off, 4); off+=4;
- if(arg2){ memcpy(arg2, contents + off, 2); off+=2; }
- if(arg3){ memcpy(arg3, contents + off, 2); off+=2; }
+ int size = 0;
+ int off = U_SIZE_METARECORD;
+ if(arg1){ memcpy(arg1, contents + off, 2); off+=2; size+=2;}
+ memcpy(Color, contents + off, 4); off+=4; size+=4;
+ if(arg2){ memcpy(arg2, contents + off, 2); off+=2; size+=2;}
+ if(arg3){ memcpy(arg3, contents + off, 2); size+=2;}
return(size);
}
@@ -5191,7 +5217,6 @@ int U_WMRFLOODFILL_get(
){
return U_WMRCORE_1U16_CRF_2U16_get(
contents,
- (U_SIZE_WMRFLOODFILL),
Mode,
Color,
U_P16(coord->y),
@@ -5321,7 +5346,6 @@ int U_WMRSETPIXEL_get(
U_POINT16 *Coord){
return U_WMRCORE_1U16_CRF_2U16_get(
contents,
- (U_SIZE_WMRSETPIXEL),
NULL,
Color,
U_P16(Coord->y),
@@ -5366,7 +5390,7 @@ int U_WMRTEXTOUT_get(
if(L2 & 1)L2++;
off = U_SIZE_METARECORD + 2 + L2;
memcpy(&Dst->y, contents + off, 2); off+=2;
- memcpy(&Dst->x, contents + off, 2); off+=2;
+ memcpy(&Dst->x, contents + off, 2);
return(size);
}
@@ -5982,6 +6006,8 @@ int U_WMRDIBSTRETCHBLT_get(
/**
\brief Get data from a U_WMRDIBCREATEPATTERNBRUSH record.
Returns an image as either a DIB (Bmi/CbPx/Px defined) or a Bitmap16 (Bm16 defined).
+ WARNING - U_WMRCREATEPATTERNBRUSH has been declared obsolete and application support is spotty -
+ this function is still valid though, for those instances where old WMF input files are encountered.
\return length of the U_WMRDIBCREATEPATTERNBRUSH record in bytes, or 0 on error
\param contents record to extract data from
\param Style BrushStyle Enumeration
@@ -6096,7 +6122,6 @@ int U_WMREXTFLOODFILL_get(
){
return U_WMRCORE_1U16_CRF_2U16_get(
contents,
- (U_SIZE_WMREXTFLOODFILL),
Mode,
Color,
U_P16(coord->y),
diff --git a/src/libuemf/uwmf.h b/src/libuemf/uwmf.h
index 65424cad1..54f7f36fe 100644
--- a/src/libuemf/uwmf.h
+++ b/src/libuemf/uwmf.h
@@ -36,11 +36,11 @@
/*
File: uwmf.h
-Version: 0.0.8
-Date: 27-FEB-2013
+Version: 0.0.10
+Date: 24-MAR-2014
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
-Copyright: 2013 David Mathog and California Institute of Technology (Caltech)
+Copyright: 2014 David Mathog and California Institute of Technology (Caltech)
*/
#ifndef _UWMF_
@@ -60,6 +60,13 @@ extern "C" {
#include "uwmf_endian.h"
+/** HighWater Enumeration not in WMF manual
+ @{
+*/
+#define U_HIGHWATER_READ 0x00000000 //!< nondestructive read of highwater value
+#define U_HIGHWATER_CLEAR 0xFFFFFFFF //!< destructive read, value is reset to 0
+/** @} */
+
@@ -1959,6 +1966,9 @@ typedef struct {
/* Index F9 U_WMRCREATEPATTERNBRUSH WMF manual 2.3.4.4 */
/** WMF manual 2.3.4.4
+ WARNING - U_WMRCREATEPATTERNBRUSH has been declared obsolete and application support is spotty -
+ use U_WMRDIBCREATEPATTERNBRUSH instead.
+
This record is peculiar...
After the core structure there is:
@@ -2040,7 +2050,7 @@ typedef struct {
uint32_t chunk; //!< Number of bytes to add when more space is needed
char *buf; //!< Buffer for constructing the EMF in memory
uint32_t largest; //!< Largest record size, in bytes (used by WMF, not by EMF)
- uint32_t sumObjects; //!< Number of objects created (used by WMF, not by EMF)
+ uint32_t sumObjects; //!< Number of objects appended (used by WMF, not by EMF) [ also see wmf_highwater() ]
} WMFTRACK;
/**
@@ -2072,6 +2082,7 @@ int wmf_append(U_METARECORD *rec, WMFTRACK *wt, int freerec);
int wmf_header_append(U_METARECORD *rec,WMFTRACK *et, int freerec);
int wmf_readdata(const char *filename, char **contents, size_t*length);
#define wmf_fopen emf_fopen
+int wmf_highwater(uint32_t setval);
int wmf_htable_create(uint32_t initsize, uint32_t chunksize, WMFHANDLES **wht);
int wmf_htable_delete(uint32_t *ih, WMFHANDLES *wht);
int wmf_htable_insert(uint32_t *ih, WMFHANDLES *wht);
@@ -2082,8 +2093,8 @@ uint32_t U_wmr_properties(uint32_t type);
uint32_t U_wmr_size(const U_METARECORD *record);
uint32_t U_wmr_values(int idx);
-char *U_wmr_names(int idx);
-char *U_wmr_escnames(int idx);
+const char *U_wmr_names(int idx);
+const char *U_wmr_escnames(int idx);
void U_sanerect16(U_RECT16 rc, double *left, double *top, double *right, double *bottom);
diff --git a/src/libuemf/uwmf_print.c b/src/libuemf/uwmf_print.c
index d120a2da0..0e089a5cd 100644
--- a/src/libuemf/uwmf_print.c
+++ b/src/libuemf/uwmf_print.c
@@ -6,11 +6,11 @@
/*
File: uwmf_print.c
-Version: 0.0.3
-Date: 17-OCT-2013
+Version: 0.0.4
+Date: 05-FEB-2014
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
-Copyright: 2012 David Mathog and California Institute of Technology (Caltech)
+Copyright: 2014 David Mathog and California Institute of Technology (Caltech)
*/
#ifdef __cplusplus
@@ -715,7 +715,7 @@ void U_WMRTEXTOUT_print(const char *contents){
U_POINT16 Dst;
int size = U_WMRTEXTOUT_get(contents, &Dst, &Length, &string);
if(size > 0){
- printf(" X,Y:{%d,%d}\n", Dst.y,Dst.x); /* y/x order in record is reversed, fix that here */
+ printf(" X,Y:{%d,%d}\n", Dst.x,Dst.y);
printf(" Length:%d\n", Length);
printf(" String:<%.*s>\n", Length, string); /* May not be null terminated */
}
diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp
index 337fe631f..d6840e5b8 100644
--- a/src/live_effects/effect.cpp
+++ b/src/live_effects/effect.cpp
@@ -5,7 +5,7 @@
* Released under GNU GPL, read the file 'COPYING' for more information
*/
-#define LPE_ENABLE_TEST_EFFECTS //uncomment for toy effects
+//#define LPE_ENABLE_TEST_EFFECTS //uncomment for toy effects
#ifdef HAVE_CONFIG_H
# include "config.h"
diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp
index de50f0dd8..3b8956bc8 100644
--- a/src/object-snapper.cpp
+++ b/src/object-snapper.cpp
@@ -119,35 +119,35 @@ void Inkscape::ObjectSnapper::_findCandidates(SPObject* parent,
_findCandidates(obj, it, false, bbox_to_snap, true, item->i2doc_affine());
}
}
- }
- if (SP_IS_GROUP(o)) {
- _findCandidates(o, it, false, bbox_to_snap, clip_or_mask, additional_affine);
- } else {
- Geom::OptRect bbox_of_item;
- Preferences *prefs = Preferences::get();
- int prefs_bbox = prefs->getBool("/tools/bounding_box", 0);
- // We'll only need to obtain the visual bounding box if the user preferences tell
- // us to, AND if we are snapping to the bounding box itself. If we're snapping to
- // paths only, then we can just as well use the geometric bounding box (which is faster)
- SPItem::BBoxType bbox_type = (!prefs_bbox && _snapmanager->snapprefs.isTargetSnappable(SNAPTARGET_BBOX_CATEGORY)) ?
- SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX;
- if (clip_or_mask) {
- // Oh oh, this will get ugly. We cannot use sp_item_i2d_affine directly because we need to
- // insert an additional transformation in document coordinates (code copied from sp_item_i2d_affine)
- bbox_of_item = item->bounds(bbox_type, item->i2doc_affine() * additional_affine * dt->doc2dt());
+ if (SP_IS_GROUP(o)) {
+ _findCandidates(o, it, false, bbox_to_snap, clip_or_mask, additional_affine);
} else {
- bbox_of_item = item->desktopBounds(bbox_type);
- }
- if (bbox_of_item) {
- // See if the item is within range
- if (bbox_to_snap_incl.intersects(*bbox_of_item)
- || (_snapmanager->snapprefs.isTargetSnappable(SNAPTARGET_ROTATION_CENTER) && bbox_to_snap_incl.contains(item->getCenter()))) { // rotation center might be outside of the bounding box
- // This item is within snapping range, so record it as a candidate
- _candidates->push_back(SnapCandidateItem(item, clip_or_mask, additional_affine));
- // For debugging: print the id of the candidate to the console
- // SPObject *obj = (SPObject*)item;
- // std::cout << "Snap candidate added: " << obj->getId() << std::endl;
+ Geom::OptRect bbox_of_item;
+ Preferences *prefs = Preferences::get();
+ int prefs_bbox = prefs->getBool("/tools/bounding_box", 0);
+ // We'll only need to obtain the visual bounding box if the user preferences tell
+ // us to, AND if we are snapping to the bounding box itself. If we're snapping to
+ // paths only, then we can just as well use the geometric bounding box (which is faster)
+ SPItem::BBoxType bbox_type = (!prefs_bbox && _snapmanager->snapprefs.isTargetSnappable(SNAPTARGET_BBOX_CATEGORY)) ?
+ SPItem::VISUAL_BBOX : SPItem::GEOMETRIC_BBOX;
+ if (clip_or_mask) {
+ // Oh oh, this will get ugly. We cannot use sp_item_i2d_affine directly because we need to
+ // insert an additional transformation in document coordinates (code copied from sp_item_i2d_affine)
+ bbox_of_item = item->bounds(bbox_type, item->i2doc_affine() * additional_affine * dt->doc2dt());
+ } else {
+ bbox_of_item = item->desktopBounds(bbox_type);
+ }
+ if (bbox_of_item) {
+ // See if the item is within range
+ if (bbox_to_snap_incl.intersects(*bbox_of_item)
+ || (_snapmanager->snapprefs.isTargetSnappable(SNAPTARGET_ROTATION_CENTER) && bbox_to_snap_incl.contains(item->getCenter()))) { // rotation center might be outside of the bounding box
+ // This item is within snapping range, so record it as a candidate
+ _candidates->push_back(SnapCandidateItem(item, clip_or_mask, additional_affine));
+ // For debugging: print the id of the candidate to the console
+ // SPObject *obj = (SPObject*)item;
+ // std::cout << "Snap candidate added: " << obj->getId() << std::endl;
+ }
}
}
}
diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp
index 456af3731..a72601276 100644
--- a/src/path-chemistry.cpp
+++ b/src/path-chemistry.cpp
@@ -84,10 +84,10 @@ sp_selected_path_combine(SPDesktop *desktop)
gint position = 0;
char const *id = NULL;
char const *transform = NULL;
- gchar *style = NULL;
- gchar *path_effect = NULL;
+ char const *style = NULL;
+ char const *path_effect = NULL;
- SPCurve* curve = 0;
+ SPCurve* curve = NULL;
SPItem *first = NULL;
Inkscape::XML::Node *parent = NULL;
@@ -115,18 +115,15 @@ sp_selected_path_combine(SPDesktop *desktop)
id = first->getRepr()->attribute("id");
transform = first->getRepr()->attribute("transform");
// FIXME: merge styles of combined objects instead of using the first one's style
- style = g_strdup(first->getRepr()->attribute("style"));
- path_effect = g_strdup(first->getRepr()->attribute("inkscape:path-effect"));
+ style = first->getRepr()->attribute("style");
+ path_effect = first->getRepr()->attribute("inkscape:path-effect");
//c->transform(item->transform);
curve = c;
} else {
c->transform(item->getRelativeTransform(first));
curve->append(c, false);
c->unref();
- }
- // unless this is the topmost object,
- if (item != first) {
// reduce position only if the same parent
if (item->getRepr()->parent() == parent) {
position--;
@@ -151,10 +148,8 @@ sp_selected_path_combine(SPDesktop *desktop)
repr->setAttribute("transform", transform);
}
repr->setAttribute("style", style);
- g_free(style);
repr->setAttribute("inkscape:path-effect", path_effect);
- g_free(path_effect);
// set path data corresponding to new curve
gchar *dstring = sp_svg_write_path(curve->get_pathvector());
@@ -371,7 +366,7 @@ sp_item_list_to_curves(const GSList *items, GSList **selected, GSList **to_selec
items = items->next) {
SPItem *item = SP_ITEM(items->data);
- SPDocument *document = item->document;
+ SPDocument *document = item->document;
if ( skip_all_lpeitems &&
SP_IS_LPE_ITEM(item) &&
@@ -453,12 +448,12 @@ sp_item_list_to_curves(const GSList *items, GSList **selected, GSList **to_selec
parent->appendChild(repr);
SPObject* newObj = document->getObjectByRepr(repr);
if (title && newObj) {
- newObj->setTitle(title);
- g_free(title);
+ newObj->setTitle(title);
+ g_free(title);
}
if (desc && newObj) {
- newObj->setDesc(desc);
- g_free(desc);
+ newObj->setDesc(desc);
+ g_free(desc);
}
if (highlight_color && newObj) {
SP_ITEM(newObj)->setHighlightColor( highlight_color );
diff --git a/src/sp-object.cpp b/src/sp-object.cpp
index 764b5f260..be3a1ab9d 100644
--- a/src/sp-object.cpp
+++ b/src/sp-object.cpp
@@ -967,31 +967,29 @@ static gchar const *sp_xml_get_space_string(unsigned int space)
}
Inkscape::XML::Node* SPObject::write(Inkscape::XML::Document *doc, Inkscape::XML::Node *repr, guint flags) {
- SPObject* object = this;
-
if (!repr && (flags & SP_OBJECT_WRITE_BUILD)) {
- repr = object->getRepr()->duplicate(doc);
+ repr = this->getRepr()->duplicate(doc);
if (!( flags & SP_OBJECT_WRITE_EXT )) {
repr->setAttribute("inkscape:collect", NULL);
}
- } else {
- repr->setAttribute("id", object->getId());
+ } else if (repr) {
+ repr->setAttribute("id", this->getId());
- if (object->xml_space.set) {
+ if (this->xml_space.set) {
char const *xml_space;
- xml_space = sp_xml_get_space_string(object->xml_space.value);
+ xml_space = sp_xml_get_space_string(this->xml_space.value);
repr->setAttribute("xml:space", xml_space);
}
if ( flags & SP_OBJECT_WRITE_EXT &&
- object->collectionPolicy() == SPObject::ALWAYS_COLLECT )
+ this->collectionPolicy() == SPObject::ALWAYS_COLLECT )
{
repr->setAttribute("inkscape:collect", "always");
} else {
repr->setAttribute("inkscape:collect", NULL);
}
- SPStyle const *const obj_style = object->style;
+ SPStyle const *const obj_style = this->style;
if (obj_style) {
gchar *s = sp_style_write_string(obj_style, SP_STYLE_FLAG_IFSET);
@@ -1028,7 +1026,7 @@ Inkscape::XML::Node* SPObject::write(Inkscape::XML::Document *doc, Inkscape::XML
g_warning("Item's style is NULL; repr style attribute is %s", style_str);
}
- /** \note We treat object->style as authoritative. Its effects have
+ /** \note We treat this->style as authoritative. Its effects have
* been written to the style attribute above; any properties that are
* unset we take to be deliberately unset (e.g. so that clones can
* override the property).
@@ -1038,7 +1036,7 @@ Inkscape::XML::Node* SPObject::write(Inkscape::XML::Document *doc, Inkscape::XML
* possibly we should write property attributes instead of a style
* attribute.
*/
- sp_style_unset_property_attrs (object);
+ sp_style_unset_property_attrs (this);
}
return repr;
diff --git a/src/style.cpp b/src/style.cpp
index c57cf6349..bc869b127 100644
--- a/src/style.cpp
+++ b/src/style.cpp
@@ -3677,7 +3677,7 @@ sp_style_read_itextdecoration(SPITextDecorationLine *line, SPITextDecorationStyl
int slen = str - hstr;
gchar *frag = g_strndup(hstr,slen+1); // only send one piece at a time, since keywords may be intermixed
sp_style_read_itextdecorationColor(color, frag);
- free(frag);
+ g_free(frag);
if(color->set)break;
if(*str == '\0')break;
hstr = str + 1;
diff --git a/src/unicoderange.cpp b/src/unicoderange.cpp
index 803e1a884..5a9c4b331 100644
--- a/src/unicoderange.cpp
+++ b/src/unicoderange.cpp
@@ -39,7 +39,7 @@ int UnicodeRange::add_range(gchar* val){
while(val[i]!='\0' && val[i]!='-' && val[i]!=' ' && val[i]!=','){
i++;
}
- r.start = (gchar*) malloc((i+1)*sizeof(gchar*));
+ r.start = (gchar*) malloc((i+1)*sizeof(gchar));
strncpy(r.start, val, i);
r.start[i] = '\0';
val+=i;
@@ -48,7 +48,7 @@ int UnicodeRange::add_range(gchar* val){
if (val[0]=='-'){
val++;
while(val[i]!='\0' && val[i]!='-' && val[i]!=' ' && val[i]!=',') i++;
- r.end = (gchar*) malloc((i+1)*sizeof(gchar*));
+ r.end = (gchar*) malloc((i+1)*sizeof(gchar));
strncpy(r.end, val, i);
r.end[i] = '\0';
// val+=i;
diff --git a/src/xml/node.h b/src/xml/node.h
index e83d8a7b7..c1977b0a8 100644
--- a/src/xml/node.h
+++ b/src/xml/node.h
@@ -19,6 +19,7 @@
#define SEEN_INKSCAPE_XML_NODE_H
#include <glibmm/value.h>
+#include <glibmm/ustring.h>
#include "gc-anchored.h"
#include "util/list.h"
@@ -194,6 +195,7 @@ public:
*/
virtual void setContent(gchar const *value)=0;
+ //@{
/**
* @brief Change an attribute of this node
*
@@ -204,7 +206,19 @@ public:
* @param is_interactive Ignored
*/
virtual void setAttribute(gchar const *key, gchar const *value, bool is_interactive=false)=0;
-
+
+ void setAttribute(char const *key, Glib::ustring const &value, bool is_interactive=false)
+ {
+ setAttribute(key, value.empty() ? NULL : value.c_str(), is_interactive);
+ }
+
+ void setAttribute(Glib::ustring const &key, Glib::ustring const &value, bool is_interactive=false)
+ {
+ setAttribute( key.empty() ? NULL : key.c_str(),
+ value.empty() ? NULL : value.c_str(), is_interactive);
+ }
+ //@}
+
/**
* @brief Directly set the integer GQuark code for the name of the node
*