Code

Belarusian translation for 0.47, by Hleb Valoshka
[inkscape.git] / src / trace / siox.h
1 #ifndef __SIOX_H__
2 #define __SIOX_H__
3 /**
4  *  Copyright 2005, 2006 by Gerald Friedland, Kristian Jantz and Lars Knipping
5  *
6  *  Conversion to C++ for Inkscape by Bob Jamison
7  *
8  *  Licensed under the Apache License, Version 2.0 (the "License");
9  *  you may not use this file except in compliance with the License.
10  *  You may obtain a copy of the License at
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
14  *  Unless required by applicable law or agreed to in writing, software
15  *  distributed under the License is distributed on an "AS IS" BASIS,
16  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  *  See the License for the specific language governing permissions and
18  *  limitations under the License.
19  */
21 /**
22  * Note by Bob Jamison:
23  * After translating the siox.org Java API to C++ and receiving an
24  * education into this wonderful code,  I began again,
25  * and started this version using lessons learned.  This version is
26  * an attempt to provide an dependency-free SIOX engine that anyone
27  * can use in their project with minimal effort.
28  *
29  * Many thanks to the fine people at siox.org.
30  */
32 #include <string>
33 #include <vector>
35 #define HAVE_GLIB
37 #ifdef HAVE_GLIB
38 #include <glib.h>
39 #include <gdk-pixbuf/gdk-pixbuf.h>
40 #endif
43 namespace org
44 {
46 namespace siox
47 {
50 //########################################################################
51 //#  C L A B
52 //########################################################################
54 /**
55  *
56  */
57 class CieLab
58 {
59 public:
61     /**
62      *
63      */
64     CieLab()
65         {
66         init();
67         C = 0;
68         L = A = B = 0.0f;
69         }
72     /**
73      *
74      */
75     CieLab(unsigned long rgb);
78     /**
79      *
80      */
81     CieLab(float lArg, float aArg, float bArg)
82         {
83         init();
84         C = 0;
85         L = lArg;
86         A = aArg;
87         B = bArg;
88         }
91     /**
92      *
93      */
94     CieLab(const CieLab &other)
95         {
96         init();
97         C = other.C;
98         L = other.L;
99         A = other.A;
100         B = other.B;
101         }
104     /**
105      *
106      */
107     CieLab &operator=(const CieLab &other)
108         {
109         init();
110         C = other.C;
111         L = other.L;
112         A = other.A;
113         B = other.B;
114         return *this;
115         }
117     /**
118      *
119      */
120     virtual ~CieLab()
121         {}
123     /**
124      * Retrieve a CieLab value via index.
125      */
126     virtual float operator()(unsigned int index)
127         {
128         if      (index==0) return L;
129         else if (index==1) return A;
130         else if (index==2) return B;
131         else return 0;
132         }
135     /**
136      *
137      */
138     virtual void add(const CieLab &other)
139         {
140         C += other.C;
141         L += other.L;
142         A += other.A;
143         B += other.B;
144         }
147     /**
148      *
149      */
150     virtual void mul(float scale)
151         {
152         L *= scale;
153         A *= scale;
154         B *= scale;
155         }
158     /**
159      *
160      */
161     virtual unsigned long toRGB();
163     /**
164      * Approximate cube roots
165      */
166     double cbrt(double x);
168     /**
169      *
170      */
171     double qnrt(double x);
173     /**
174      * Raise to the 2.4 power
175      */
176     double pow24(double x);
178     /**
179      * Squared Euclidian distance between this and another color
180      */
181     float diffSq(const CieLab &other);
183     /**
184      * Computes squared euclidian distance in CieLab space for two colors
185      * given as RGB values.
186      */
187     static float diffSq(unsigned int rgb1, unsigned int rgb2);
189     /**
190      * Computes squared euclidian distance in CieLab space for two colors
191      * given as RGB values.
192      */
193     static float diff(unsigned int rgb0, unsigned int rgb1);
196     unsigned int C;
197     float L;
198     float A;
199     float B;
201 private:
203     /**
204      *
205      */
206     void init();
209 };
212 //########################################################################
213 //#  S I O X    I M A G E
214 //########################################################################
216 /**
217  * This is a generic image type that provides a consistent interface
218  * to Siox, so that developers will not need to worry about data arrays.
219  */
220 class SioxImage
222 public:
224     /**
225      *  Create an image with the given width and height
226      */
227     SioxImage(unsigned int width, unsigned int height);
229     /**
230      *  Copy constructor
231      */
232     SioxImage(const SioxImage &other);
234     /**
235      *  Assignment
236      */
237     SioxImage &operator=(const SioxImage &other);
239     /**
240      * Clean up after use.
241      */
242     virtual ~SioxImage();
244     /**
245      * Returns true if the previous operation on this image
246      * was successful, else false.
247      */
248     virtual bool isValid();
250     /**
251      * Sets whether an operation was successful, and whether
252      * this image should be considered a valid one.
253      * was successful, else false.
254      */
255     virtual void setValid(bool val);
257     /**
258      * Set a pixel at the x,y coordinates to the given value.
259      * If the coordinates are out of range, do nothing.
260      */
261     virtual void setPixel(unsigned int x,
262                           unsigned int y,
263                           unsigned int pixval);
265     /**
266      * Set a pixel at the x,y coordinates to the given r, g, b values.
267      * If the coordinates are out of range, do nothing.
268      */
269     virtual void setPixel(unsigned int x, unsigned int y,
270                           unsigned int a,
271                           unsigned int r,
272                           unsigned int g,
273                           unsigned int b);
275     /**
276      *  Get a pixel at the x,y coordinates given.  If
277      *  the coordinates are out of range, return 0
278      */
279     virtual unsigned int getPixel(unsigned int x, unsigned int y);
282     /**
283      *  Return the image data buffer
284      */
285     virtual unsigned int *getImageData();
287     /**
288      * Set a confidence value at the x,y coordinates to the given value.
289      * If the coordinates are out of range, do nothing.
290      */
291     virtual void setConfidence(unsigned int x,
292                                unsigned int y,
293                                float conf);
295     /**
296      *  Get a confidence value at the x,y coordinates given.  If
297      *  the coordinates are out of range, return 0
298      */
299     virtual float getConfidence(unsigned int x, unsigned int y);
301     /**
302      *  Return the confidence data buffer
303      */
304     virtual float *getConfidenceData();
306     /**
307      * Return the width of this image
308      */
309     virtual int getWidth();
311     /**
312      * Return the height of this image
313      */
314     virtual int getHeight();
316     /**
317      * Saves this image as a simple color PPM
318      */
319     bool writePPM(const std::string fileName);
323 #ifdef HAVE_GLIB
325     /**
326      * Special constructor to create an image from a GdkPixbuf.
327      */
328     SioxImage(GdkPixbuf *buf);
330     /**
331      * Creates a GdkPixbuf from this image.  The user must
332      * remember to destroy the image when no longer needed.
333      * with g_free(pixbuf)
334      */
335     GdkPixbuf *getGdkPixbuf();
337 #endif
339 private:
341     SioxImage()
342         {}
344     /**
345      * Assign values to that of another
346      */
347     void assign(const SioxImage &other);
349     /**
350      * Initialize values.  Used by constructors
351      */
352     void init(unsigned int width, unsigned int height);
354     bool valid;
356     unsigned int width;
358     unsigned int height;
360     unsigned long imageSize;
362     /**
363      * Pixel data
364      */
365     unsigned int *pixdata;
367     /**
368      * Confidence matrix data
369      */
370     float *cmdata;
372 private:
374     /**
375      * Error logging
376      */
377     void error(const char *fmt, ...) G_GNUC_PRINTF(2,3);
379 };
383 //########################################################################
384 //#  S I O X    O B S E R V E R
385 //########################################################################
386 class Siox;
388 /**
389  *  This is a class for observing the progress of a Siox engine.  Overload
390  *  the methods in your subclass to get the desired behaviour.
391  */
392 class SioxObserver
394 public:
396     /**
397      *  Constructor.  Context can point to anything, and is usually
398      *  used to point to a C++ object or C state object, to delegate
399      *  callback processing to something else.  Use NULL to ignore.
400      */
401     SioxObserver(void *contextArg) : context(NULL)
402         { context = contextArg; }
404     /**
405      *  Destructor
406      */
407     virtual ~SioxObserver()
408         { }
410     /**
411      *  Informs the observer how much has been completed.
412      *  Return false if the processing should be aborted.
413      */
414     virtual bool progress(float /*percentCompleted*/)
415         {
416         return true;
417         }
419     /**
420      *  Send an error string to the Observer.  Processing will
421      *  be halted.
422      */
423     virtual void error(const std::string &/*msg*/)
424         {
425         }
427 protected:
429     void *context;
431 };
435 //########################################################################
436 //#  S I O X
437 //########################################################################
439 /**
440  *
441  */
442 class Siox
444 public:
446     /**
447      * Confidence corresponding to a certain foreground region (equals one).
448      */
449     static const float CERTAIN_FOREGROUND_CONFIDENCE; //=1.0f;
451     /**
452      * Confidence for a region likely being foreground.
453      */
454     static const float FOREGROUND_CONFIDENCE; //=0.8f;
456     /**
457      * Confidence for foreground or background type being equally likely.
458      */
459     static const float UNKNOWN_REGION_CONFIDENCE; //=0.5f;
461     /**
462      * Confidence for a region likely being background.
463      */
464     static const float BACKGROUND_CONFIDENCE; //=0.1f;
466     /**
467      * Confidence corresponding to a certain background reagion (equals zero).
468      */
469     static const float CERTAIN_BACKGROUND_CONFIDENCE; //=0.0f;
471     /**
472      *  Construct a Siox engine
473      */
474     Siox();
476     /**
477      *  Construct a Siox engine.  Use null to ignore
478      */
479     Siox(SioxObserver *observer);
481     /**
482      *
483      */
484     virtual ~Siox();
486     /**
487      *  Extract the foreground of the original image, according
488      *  to the values in the confidence matrix.  If the operation fails,
489      *  sioxImage.isValid()  will be false.
490      *  backgroundFillColor is any ARGB color,  such as 0xffffff (white)
491      *  or 0x000000 (black)
492      */
493     virtual SioxImage extractForeground(const SioxImage &originalImage,
494                                         unsigned int backgroundFillColor);
496 private:
498     SioxObserver *sioxObserver;
500     /**
501      * Progress reporting
502      */
503     bool progressReport(float percentCompleted);
505     /**
506      * Flag this as false during processing to abort
507      */
508     bool keepGoing;
510     /**
511      * Our signature limits
512      */
513     float limits[3];
515     /**
516      * Image width
517      */
518     unsigned int width;
520     /**
521      * Image height
522      */
523     unsigned int height;
525     /**
526      * Image size in pixels
527      */
528     unsigned long pixelCount;
530     /**
531      * Image data
532      */
533     unsigned int *image;
535     /**
536      * Image confidence matrix
537      */
538     float *cm;
540     /**
541      * Markup for image editing
542      */
543     int *labelField;
546     /**
547      * Maximum distance of two lab values.
548      */
549     float clusterSize;
551     /**
552      *  Initialize the Siox engine to its 'pristine' state.
553      *  Performed at the beginning of extractForeground().
554      */
555     void init();
557     /**
558      *  Clean up any debris from processing.
559      */
560     void cleanup();
562     /**
563      * Error logging
564      */
565     void error(const char *fmt, ...) G_GNUC_PRINTF(2,3);
567     /**
568      * Trace logging
569      */
570     void trace(const char *fmt, ...) G_GNUC_PRINTF(2,3);
572     /**
573      *  Stage 1 of the color signature work.  'dims' will be either
574      *  2 for grays, or 3 for colors
575      */
576     void colorSignatureStage1(CieLab *points,
577                               unsigned int leftBase,
578                               unsigned int rightBase,
579                               unsigned int recursionDepth,
580                               unsigned int *clusters,
581                               const unsigned int dims);
583     /**
584      *  Stage 2 of the color signature work
585      */
586     void colorSignatureStage2(CieLab         *points,
587                               unsigned int leftBase,
588                               unsigned int rightBase,
589                               unsigned int recursionDepth,
590                               unsigned int *clusters,
591                               const float  threshold,
592                               const unsigned int dims);
594     /**
595      *  Main color signature method
596      */
597     bool colorSignature(const std::vector<CieLab> &inputVec,
598                         std::vector<CieLab> &result,
599                         const unsigned int dims);
602     /**
603      *
604      */
605     void keepOnlyLargeComponents(float threshold,
606                                  double sizeFactorToKeep);
608     /**
609      *
610      */
611     int depthFirstSearch(int startPos, float threshold, int curLabel);
614     /**
615      *
616      */
617     void fillColorRegions();
619     /**
620      * Applies the morphological dilate operator.
621      *
622      * Can be used to close small holes in the given confidence matrix.
623      */
624     void dilate(float *cm, int xres, int yres);
626     /**
627      * Applies the morphological erode operator.
628      */
629     void erode(float *cm, int xres, int yres);
631     /**
632      * Normalizes the matrix to values to [0..1].
633      */
634     void normalizeMatrix(float *cm, int cmSize);
636     /**
637      * Multiplies matrix with the given scalar.
638      */
639     void premultiplyMatrix(float alpha, float *cm, int cmSize);
641     /**
642      * Blurs confidence matrix with a given symmetrically weighted kernel.
643      */
644     void smooth(float *cm, int xres, int yres,
645                   float f1, float f2, float f3);
647     /**
648      * Squared Euclidian distance of p and q.
649      */
650     float sqrEuclidianDist(float *p, int pSize, float *q);
655 };
660 } // namespace siox
661 } // namespace org
663 #endif /* __SIOX_H__ */
664 //########################################################################
665 //#  E N D    O F    F I L E
666 //########################################################################