Tesseract  3.02
tesseract-ocr/ccstruct/coutln.h
Go to the documentation of this file.
00001 /**********************************************************************
00002  * File:                                                coutln.c      (Formerly:  coutline.c)
00003  * Description: Code for the C_OUTLINE class.
00004  * Author:                                      Ray Smith
00005  * Created:                                     Mon Oct 07 16:01:57 BST 1991
00006  *
00007  * (C) Copyright 1991, Hewlett-Packard Ltd.
00008  ** Licensed under the Apache License, Version 2.0 (the "License");
00009  ** you may not use this file except in compliance with the License.
00010  ** You may obtain a copy of the License at
00011  ** http://www.apache.org/licenses/LICENSE-2.0
00012  ** Unless required by applicable law or agreed to in writing, software
00013  ** distributed under the License is distributed on an "AS IS" BASIS,
00014  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  ** See the License for the specific language governing permissions and
00016  ** limitations under the License.
00017  *
00018  **********************************************************************/
00019 
00020 #ifndef           COUTLN_H
00021 #define           COUTLN_H
00022 
00023 #include          "crakedge.h"
00024 #include          "mod128.h"
00025 #include          "bits16.h"
00026 #include          "rect.h"
00027 #include          "blckerr.h"
00028 #include          "scrollview.h"
00029 
00030 #define INTERSECTING    MAX_INT16//no winding number
00031 
00032                                  //mask to get step
00033 #define STEP_MASK       3
00034 
00035 enum C_OUTLINE_FLAGS
00036 {
00037   COUT_INVERSE                   //White on black blob
00038 };
00039 
00040 class DLLSYM C_OUTLINE;          //forward declaration
00041 struct Pix;
00042 
00043 ELISTIZEH (C_OUTLINE)
00044 class DLLSYM C_OUTLINE:public ELIST_LINK
00045 {
00046   public:
00047     C_OUTLINE() {  //empty constructor
00048       steps = NULL;
00049     }
00050     C_OUTLINE(                     //constructor
00051               CRACKEDGE *startpt,  //from edge detector
00052               ICOORD bot_left,     //bounding box //length of loop
00053               ICOORD top_right,
00054               inT16 length);
00055     C_OUTLINE(ICOORD startpt,    //start of loop
00056               DIR128 *new_steps,  //steps in loop
00057               inT16 length);     //length of loop
00058                                  //outline to copy
00059     C_OUTLINE(C_OUTLINE *srcline, FCOORD rotation);  //and rotate
00060 
00061     // Build a fake outline, given just a bounding box and append to the list.
00062     static void FakeOutline(const TBOX& box, C_OUTLINE_LIST* outlines);
00063 
00064     ~C_OUTLINE () {              //destructor
00065       if (steps != NULL)
00066         free_mem(steps);
00067       steps = NULL;
00068     }
00069 
00070     BOOL8 flag(                               //test flag
00071                C_OUTLINE_FLAGS mask) const {  //flag to test
00072       return flags.bit (mask);
00073     }
00074     void set_flag(                       //set flag value
00075                   C_OUTLINE_FLAGS mask,  //flag to test
00076                   BOOL8 value) {         //value to set
00077       flags.set_bit (mask, value);
00078     }
00079 
00080     C_OUTLINE_LIST *child() {  //get child list
00081       return &children;
00082     }
00083 
00084                                  //access function
00085     const TBOX &bounding_box() const {
00086       return box;
00087     }
00088     void set_step(                    //set a step
00089                   inT16 stepindex,    //index of step
00090                   inT8 stepdir) {     //chain code
00091       int shift = stepindex%4 * 2;
00092       uinT8 mask = 3 << shift;
00093       steps[stepindex/4] = ((stepdir << shift) & mask) |
00094                            (steps[stepindex/4] & ~mask);
00095       //squeeze 4 into byte
00096     }
00097     void set_step(                    //set a step
00098                   inT16 stepindex,    //index of step
00099                   DIR128 stepdir) {   //direction
00100                                  //clean it
00101       inT8 chaindir = stepdir.get_dir() >> (DIRBITS - 2);
00102                                  //difference
00103       set_step(stepindex, chaindir);
00104       //squeeze 4 into byte
00105     }
00106 
00107                                  //get start position
00108     const ICOORD &start_pos() const {
00109       return start;
00110     }
00111     inT32 pathlength() const {  //get path length
00112       return stepcount;
00113     }
00114     // Return step at a given index as a DIR128.
00115     DIR128 step_dir(inT16 index) const {
00116       return DIR128((inT16)(((steps[index/4] >> (index%4 * 2)) & STEP_MASK) <<
00117                       (DIRBITS - 2)));
00118     }
00119     // Return the step vector for the given outline position.
00120     ICOORD step(inT16 index) const { //index of step
00121       return step_coords[(steps[index/4] >> (index%4 * 2)) & STEP_MASK];
00122     }
00123 
00124     inT32 area();  //return area
00125     inT32 perimeter();  // Total perimeter of self and 1st level children.
00126     inT32 outer_area();  //return area
00127     inT32 count_transitions(                   //count maxima
00128                             inT32 threshold);  //size threshold
00129 
00130     BOOL8 operator< (            //containment test
00131       const C_OUTLINE & other) const;
00132     BOOL8 operator> (            //containment test
00133       C_OUTLINE & other) const
00134     {
00135       return other < *this;      //use the < to do it
00136     }
00137     inT16 winding_number(                       //get winding number
00138                          ICOORD testpt) const;  //around this point
00139                                  //get direction
00140     inT16 turn_direction() const;
00141     void reverse();  //reverse direction
00142 
00143     void move(                    // reposition outline
00144               const ICOORD vec);  // by vector
00145 
00146     // If this outline is smaller than the given min_size, delete this and
00147     // remove from its list, via *it, after checking that *it points to this.
00148     // Otherwise, if any children of this are too small, delete them.
00149     // On entry, *it must be an iterator pointing to this. If this gets deleted
00150     // then this is extracted from *it, so an iteration can continue.
00151     void RemoveSmallRecursive(int min_size, C_OUTLINE_IT* it);
00152 
00153     // Renders the outline to the given pix, with left and top being
00154     // the coords of the upper-left corner of the pix.
00155     void render(int left, int top, Pix* pix) const;
00156 
00157     // Renders just the outline to the given pix (no fill), with left and top
00158     // being the coords of the upper-left corner of the pix.
00159     void render_outline(int left, int top, Pix* pix) const;
00160 
00161     void plot(                       //draw one
00162               ScrollView* window,         //window to draw in
00163               ScrollView::Color colour) const;  //colour to draw it
00164 
00165     C_OUTLINE& operator=(const C_OUTLINE& source);
00166 
00167     static C_OUTLINE* deep_copy(const C_OUTLINE* src) {
00168       C_OUTLINE* outline = new C_OUTLINE;
00169       *outline = *src;
00170       return outline;
00171     }
00172 
00173     static ICOORD chain_step(int chaindir);
00174 
00175   private:
00176     int step_mem() const { return (stepcount+3) / 4; }
00177 
00178     TBOX box;                     //boudning box
00179     ICOORD start;                //start coord
00180     uinT8 *steps;                //step array
00181     inT16 stepcount;             //no of steps
00182     BITS16 flags;                //flags about outline
00183     C_OUTLINE_LIST children;     //child elements
00184     static ICOORD step_coords[4];
00185 };
00186 #endif