Merge pull request #1705 from stweil/memory

Replace proprietary memory allocators from memry.c, memry.h
This commit is contained in:
Egor Pugin 2018-06-25 19:15:09 +03:00 committed by GitHub
commit a9369ffa48
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 204 additions and 367 deletions

View File

@ -21,7 +21,6 @@
#include <ctype.h>
#include <cstring>
#include "tessvars.h"
#include "memry.h"
#include "reject.h"
#include "control.h"
#include "stopper.h"

View File

@ -24,16 +24,15 @@
#include "config_auto.h"
#endif
#include "stderr.h"
#include "basedir.h"
#include "tessvars.h"
#include "control.h"
#include "reject.h"
#include "pageres.h"
#include "nwmain.h"
#include "pgedit.h"
#include "tprintf.h"
#include "tessedit.h"
#include "basedir.h"
#include "tessvars.h"
#include "control.h"
#include "reject.h"
#include "pageres.h"
#include "nwmain.h"
#include "pgedit.h"
#include "tprintf.h"
#include "tessedit.h"
#include "stopper.h"
#include "intmatcher.h"
#include "chop.h"

View File

@ -64,8 +64,7 @@ C_OUTLINE::C_OUTLINE(CRACKEDGE* startpt, ICOORD bot_left, ICOORD top_right,
return;
}
//get memory
steps = (uint8_t *) alloc_mem (step_mem());
memset(steps, 0, step_mem());
steps = (uint8_t *)calloc(step_mem(), 1);
edgept = startpt;
for (stepindex = 0; stepindex < length; stepindex++) {
@ -98,8 +97,7 @@ int16_t length //length of loop
pos = startpt;
stepcount = length; // No. of steps.
ASSERT_HOST(length >= 0);
steps = static_cast<uint8_t*>(alloc_mem(step_mem())); // Get memory.
memset(steps, 0, step_mem());
steps = static_cast<uint8_t*>(calloc(step_mem(), 1)); // Get memory.
lastdir = new_steps[length - 1];
prevdir = lastdir;
@ -162,8 +160,7 @@ C_OUTLINE::C_OUTLINE(C_OUTLINE* srcline, FCOORD rotation) : offsets(nullptr) {
return;
}
//get memory
steps = (uint8_t *) alloc_mem (step_mem());
memset(steps, 0, step_mem());
steps = (uint8_t *)calloc(step_mem(), 1);
for (int iteration = 0; iteration < 2; ++iteration) {
DIR128 round1 = iteration == 0 ? 32 : 0;
@ -1014,10 +1011,9 @@ void C_OUTLINE::plot_normed(const DENORM& denorm, ScrollView::Color colour,
C_OUTLINE& C_OUTLINE::operator=(const C_OUTLINE& source) {
box = source.box;
start = source.start;
if (steps != nullptr)
free_mem(steps);
free(steps);
stepcount = source.stepcount;
steps = (uint8_t *) alloc_mem (step_mem());
steps = (uint8_t *)malloc(step_mem());
memmove (steps, source.steps, step_mem());
if (!children.empty ())
children.clear ();

View File

@ -24,7 +24,6 @@
#include "bits16.h" // for BITS16
#include "elst.h" // for ELIST_ITERATOR, ELISTIZEH, ELIST_LINK
#include "ipoints.h" // for operator+=
#include "memry.h" // for free_mem
#include "mod128.h" // for DIR128, DIRBITS
#include "platform.h" // for DLLSYM
#include "points.h" // for ICOORD, FCOORD
@ -92,9 +91,7 @@ class DLLSYM C_OUTLINE:public ELIST_LINK {
static void FakeOutline(const TBOX& box, C_OUTLINE_LIST* outlines);
~C_OUTLINE () { //destructor
if (steps != nullptr)
free_mem(steps);
steps = nullptr;
free(steps);
delete [] offsets;
}
@ -286,9 +283,9 @@ class DLLSYM C_OUTLINE:public ELIST_LINK {
TBOX box; // bounding box
ICOORD start; // start coord
int16_t stepcount; // no of steps
int16_t stepcount; // no of steps
BITS16 flags; // flags about outline
uint8_t *steps; // step array
uint8_t *steps; // step array
EdgeOffset* offsets; // Higher precision edge.
C_OUTLINE_LIST children; // child elements
static ICOORD step_coords[4];

View File

@ -18,7 +18,6 @@
**********************************************************************/
#include "allheaders.h"
#include "memry.h"
#include "quadlsq.h"
#include "quspline.h"
@ -43,8 +42,8 @@ QSPLINE::QSPLINE( //constructor
int32_t index; //segment index
//get memory
xcoords = (int32_t *) alloc_mem ((count + 1) * sizeof (int32_t));
quadratics = (QUAD_COEFFS *) alloc_mem (count * sizeof (QUAD_COEFFS));
xcoords = new int32_t[count + 1];
quadratics = new QUAD_COEFFS[count];
segments = count;
for (index = 0; index < segments; index++) {
//copy them
@ -77,9 +76,9 @@ int degree //fit required
QLSQ qlsq; /*accumulator */
segments = segcount;
xcoords = (int32_t *) alloc_mem ((segcount + 1) * sizeof (int32_t));
ptcounts = (int32_t *) alloc_mem ((segcount + 1) * sizeof (int32_t));
quadratics = (QUAD_COEFFS *) alloc_mem (segcount * sizeof (QUAD_COEFFS));
xcoords = new int32_t[segcount + 1];
ptcounts = new int32_t[segcount + 1];
quadratics = new QUAD_COEFFS[segcount];
memmove (xcoords, xstarts, (segcount + 1) * sizeof (int32_t));
ptcounts[0] = 0; /*none in any yet */
for (segment = 0, pointindex = 0; pointindex < pointcount; pointindex++) {
@ -123,7 +122,7 @@ int degree //fit required
quadratics[segment].b = qlsq.get_b ();
quadratics[segment].c = qlsq.get_c ();
}
free_mem(ptcounts);
delete[] ptcounts;
}
@ -148,16 +147,9 @@ QSPLINE::QSPLINE( //constructor
* Destroy a QSPLINE.
**********************************************************************/
QSPLINE::~QSPLINE ( //constructor
) {
if (xcoords != nullptr) {
free_mem(xcoords);
xcoords = nullptr;
}
if (quadratics != nullptr) {
free_mem(quadratics);
quadratics = nullptr;
}
QSPLINE::~QSPLINE () {
delete[] xcoords;
delete[] quadratics;
}
@ -169,14 +161,12 @@ QSPLINE::~QSPLINE ( //constructor
QSPLINE & QSPLINE::operator= ( //assignment
const QSPLINE & source) {
if (xcoords != nullptr)
free_mem(xcoords);
if (quadratics != nullptr)
free_mem(quadratics);
delete[] xcoords;
delete[] quadratics;
segments = source.segments;
xcoords = (int32_t *) alloc_mem ((segments + 1) * sizeof (int32_t));
quadratics = (QUAD_COEFFS *) alloc_mem (segments * sizeof (QUAD_COEFFS));
xcoords = new int32_t[segments + 1];
quadratics = new QUAD_COEFFS[segments];
memmove (xcoords, source.xcoords, (segments + 1) * sizeof (int32_t));
memmove (quadratics, source.quadratics, segments * sizeof (QUAD_COEFFS));
return *this;
@ -303,7 +293,7 @@ void QSPLINE::extrapolate( //linear extrapolation
) {
int segment; /*current segment of spline */
int dest_segment; //dest index
int *xstarts; //new boundaries
int32_t* xstarts; //new boundaries
QUAD_COEFFS *quads; //new ones
int increment; //in size
@ -312,9 +302,8 @@ void QSPLINE::extrapolate( //linear extrapolation
increment++;
if (increment == 0)
return;
xstarts = (int *) alloc_mem ((segments + 1 + increment) * sizeof (int));
quads =
(QUAD_COEFFS *) alloc_mem ((segments + increment) * sizeof (QUAD_COEFFS));
xstarts = new int32_t[segments + 1 + increment];
quads = new QUAD_COEFFS[segments + increment];
if (xmin < xcoords[0]) {
xstarts[0] = xmin;
quads[0].a = 0;
@ -339,9 +328,9 @@ void QSPLINE::extrapolate( //linear extrapolation
xstarts[dest_segment] = xmax + 1;
}
segments = dest_segment;
free_mem(xcoords);
free_mem(quadratics);
xcoords = (int32_t *) xstarts;
delete[] xcoords;
delete[] quadratics;
xcoords = xstarts;
quadratics = quads;
}

View File

@ -1,8 +1,8 @@
/**********************************************************************
* File: quspline.h (Formerly qspline.h)
* Description: Code for the QSPLINE class.
* Author: Ray Smith
* Created: Tue Oct 08 17:16:12 BST 1991
* Author: Ray Smith
* Created: Tue Oct 08 17:16:12 BST 1991
*
* (C) Copyright 1991, Hewlett-Packard Ltd.
** Licensed under the Apache License, Version 2.0 (the "License");
@ -17,13 +17,12 @@
*
**********************************************************************/
#ifndef QUSPLINE_H
#define QUSPLINE_H
#ifndef QUSPLINE_H
#define QUSPLINE_H
#include "quadratc.h"
#include "serialis.h"
#include "memry.h"
#include "rect.h"
#include "quadratc.h"
#include "serialis.h"
#include "rect.h"
class ROW;
struct Pix;

View File

@ -19,8 +19,8 @@ pkginclude_HEADERS = \
noinst_HEADERS = \
ambigs.h basedir.h bits16.h bitvector.h ccutil.h clst.h doubleptr.h elst2.h \
elst.h errcode.h fileerr.h genericheap.h globaloc.h \
indexmapbidi.h kdpair.h lsterr.h memry.h \
nwmain.h object_cache.h params.h qrsequence.h sorthelper.h stderr.h \
indexmapbidi.h kdpair.h lsterr.h \
nwmain.h object_cache.h params.h qrsequence.h sorthelper.h \
scanutils.h tessdatamanager.h tprintf.h \
unicharcompress.h unicharmap.h unicharset.h unicity_table.h unicodes.h \
universalambigs.h
@ -32,7 +32,7 @@ libtesseract_ccutil_la_SOURCES = \
ccutil.cpp clst.cpp \
elst2.cpp elst.cpp errcode.cpp \
globaloc.cpp indexmapbidi.cpp \
mainblk.cpp memry.cpp \
mainblk.cpp \
serialis.cpp strngs.cpp scanutils.cpp \
tessdatamanager.cpp tprintf.cpp \
unichar.cpp unicharcompress.cpp unicharmap.cpp unicharset.cpp unicodes.cpp \

View File

@ -1,45 +0,0 @@
/**********************************************************************
* File: memry.cpp (Formerly memory.c)
* Description: Memory allocation with builtin safety checks.
* Author: Ray Smith
* Created: Wed Jan 22 09:43:33 GMT 1992
*
* (C) Copyright 1992, Hewlett-Packard Ltd.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** http://www.apache.org/licenses/LICENSE-2.0
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*
**********************************************************************/
#include "memry.h"
#include <stdlib.h>
// With improvements in OS memory allocators, internal memory management
// is no longer required, so all these functions now map to their malloc
// family equivalents.
// TODO(rays) further cleanup by redirecting calls to new and creating proper
// constructors.
char *alloc_string(int32_t count) {
// Round up the amount allocated to a multiple of 4
return static_cast<char*>(malloc((count + 3) & ~3));
}
void free_string(char *string) {
free(string);
}
void *alloc_mem(int32_t count) {
return malloc(static_cast<size_t>(count));
}
void free_mem(void *oldchunk) {
free(oldchunk);
}

View File

@ -1,34 +0,0 @@
/**********************************************************************
* File: memry.h (Formerly memory.h)
* Description: Header file for basic memory allocation/deallocation.
* Author: Ray Smith
* Created: Tue May 8 16:03:48 BST 1990
*
* (C) Copyright 1990, Hewlett-Packard Ltd.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** http://www.apache.org/licenses/LICENSE-2.0
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*
**********************************************************************/
#ifndef MEMRY_H
#define MEMRY_H
#include <cstdint>
// allocate string
extern char *alloc_string(int32_t count);
// free a string.
extern void free_string(char *string);
// get some memory
extern void *alloc_mem(int32_t count);
// free mem from alloc_mem
extern void free_mem(void *oldchunk);
#endif

View File

@ -1,26 +0,0 @@
/**********************************************************************
* File: stderr.h (Formerly stderrs.h)
* Description: File defining error messages fundamental of commonly used.
* Author: Ray Smith
* Created: Fri Aug 10 15:23:14 BST 1990
*
* (C) Copyright 1990, Hewlett-Packard Ltd.
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
** http://www.apache.org/licenses/LICENSE-2.0
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*
**********************************************************************/
#ifndef STDERR_H
#define STDERR_H
#include "errcode.h"
const ERRCODE MEMORY_OUT = "Out of memory";
#endif

View File

@ -19,10 +19,10 @@
#include "strngs.h"
#include <cassert> // for assert
#include <cstdlib> // for malloc, free
#include "errcode.h" // for ASSERT_HOST
#include "genericvector.h" // for GenericVector
#include "helpers.h" // for ReverseN
#include "memry.h" // for alloc_string, free_string
#include "serialis.h" // for TFile
using tesseract::TFile;
@ -51,7 +51,7 @@ const int kMaxDoubleSize = 16;
const int kMinCapacity = 16;
char* STRING::AllocData(int used, int capacity) {
data_ = (STRING_HEADER *)alloc_string(capacity + sizeof(STRING_HEADER));
data_ = (STRING_HEADER *)malloc(capacity + sizeof(STRING_HEADER));
// header is the metadata for this memory block
STRING_HEADER* header = GetHeader();
@ -61,7 +61,8 @@ char* STRING::AllocData(int used, int capacity) {
}
void STRING::DiscardData() {
free_string((char *)data_);
free(data_);
data_ = nullptr;
}
// This is a private method; ensure FixHeader is called (or used_ is well defined)
@ -78,7 +79,7 @@ char* STRING::ensure_cstr(int32_t min_capacity) {
min_capacity = 2 * orig_header->capacity_;
int alloc = sizeof(STRING_HEADER) + min_capacity;
STRING_HEADER* new_header = (STRING_HEADER*)(alloc_string(alloc));
STRING_HEADER* new_header = (STRING_HEADER*)(malloc(alloc));
memcpy(&new_header[1], GetCStr(), orig_header->used_);
new_header->capacity_ = min_capacity;

View File

@ -1,8 +1,8 @@
/**********************************************************************
* File: fpchop.cpp (Formerly fp_chop.c)
* Description: Code to chop fixed pitch text into character cells.
* Author: Ray Smith
* Created: Thu Sep 16 11:14:15 BST 1993
* Author: Ray Smith
* Created: Thu Sep 16 11:14:15 BST 1993
*
* (C) Copyright 1993, Hewlett-Packard Ltd.
** Licensed under the Apache License, Version 2.0 (the "License");
@ -17,7 +17,6 @@
*
**********************************************************************/
#include "stderr.h"
#include "blobbox.h"
#include "statistc.h"
#include "drawtord.h"

View File

@ -7,8 +7,9 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "statistc.h"
#include "gap_map.h"
#include "statistc.h"
#include "gap_map.h"
#define EXTERN
EXTERN BOOL_VAR (gapmap_debug, FALSE, "Say which blocks have tables");
@ -79,7 +80,7 @@ GAPMAP::GAPMAP( //Constructor
}
bucket_size = (int16_t) floor (xht_stats.median () + 0.5) / 2;
map_max = (max_right - min_left) / bucket_size;
map = (int16_t *) alloc_mem ((map_max + 1) * sizeof (int16_t));
map = new int16_t[map_max + 1];
for (i = 0; i <= map_max; i++)
map[i] = 0;

View File

@ -7,10 +7,11 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GAP_MAP_H
#define GAP_MAP_H
#include "blobbox.h"
#ifndef GAP_MAP_H
#define GAP_MAP_H
#include "blobbox.h"
class GAPMAP
{
@ -19,8 +20,7 @@ class GAPMAP
TO_BLOCK *block);
~GAPMAP () { //destructor
if (map != nullptr)
free_mem(map);
delete[] map;
}
bool table_gap( //Is gap a table?
@ -45,4 +45,5 @@ extern BOOL_VAR_H (gapmap_use_ends, FALSE,
extern BOOL_VAR_H (gapmap_no_isolated_quanta, FALSE,
"Ensure gaps not less than 2quanta wide");
extern double_VAR_H (gapmap_big_gaps, 1.75, "xht multiplier");
#endif

View File

@ -1,8 +1,8 @@
/**********************************************************************
* File: makerow.cpp (Formerly makerows.c)
* Description: Code to arrange blobs into rows of text.
* Author: Ray Smith
* Created: Mon Sep 21 14:34:48 BST 1992
* Author: Ray Smith
* Created: Mon Sep 21 14:34:48 BST 1992
*
* (C) Copyright 1992, Hewlett-Packard Ltd.
** Licensed under the Apache License, Version 2.0 (the "License");
@ -17,7 +17,7 @@
*
**********************************************************************/
#include "stderr.h"
#include <vector> // for std::vector
#include "blobbox.h"
#include "ccstruct.h"
#include "detlinefit.h"
@ -288,12 +288,10 @@ void compute_page_skew( //get average gradient
float &page_m, //average gradient
float &page_err //average error
) {
int32_t row_count; //total rows
int32_t blob_count; //total_blobs
int32_t row_err; //integer error
float *gradients; //of rows
float *errors; //of rows
int32_t row_index; //of total
int32_t row_count; //total rows
int32_t blob_count; //total_blobs
int32_t row_err; //integer error
int32_t row_index; //of total
TO_ROW *row; //current row
TO_BLOCK_IT block_it = blocks; //iterator
@ -315,11 +313,10 @@ void compute_page_skew( //get average gradient
page_err = 0.0f;
return;
}
gradients = (float *) alloc_mem (blob_count * sizeof (float));
//get mem
errors = (float *) alloc_mem (blob_count * sizeof (float));
if (gradients == nullptr || errors == nullptr)
MEMORY_OUT.error ("compute_page_skew", ABORT, nullptr);
// of rows
std::vector<float> gradients(blob_count);
// of rows
std::vector<float> errors(blob_count);
row_index = 0;
for (block_it.mark_cycle_pt (); !block_it.cycled_list ();
@ -369,13 +366,11 @@ void compute_page_skew( //get average gradient
}
row_count = row_index;
row_index = choose_nth_item ((int32_t) (row_count * textord_skew_ile),
gradients, row_count);
&gradients[0], row_count);
page_m = gradients[row_index];
row_index = choose_nth_item ((int32_t) (row_count * textord_skew_ile),
errors, row_count);
&errors[0], row_count);
page_err = errors[row_index];
free_mem(gradients);
free_mem(errors);
}
const double kNoiseSize = 0.5; // Fraction of xheight.
@ -580,8 +575,6 @@ void delete_non_dropout_rows( //find lines
bool testing_on //correct orientation
) {
TBOX block_box; //deskewed block
int32_t *deltas; //change in occupation
int32_t *occupation; //of pixel coords
int32_t max_y; //in block
int32_t min_y;
int32_t line_index; //of scan line
@ -610,12 +603,12 @@ void delete_non_dropout_rows( //find lines
line_count = max_y - min_y + 1;
if (line_count <= 0)
return; //empty block
deltas = (int32_t *) alloc_mem (line_count * sizeof (int32_t));
occupation = (int32_t *) alloc_mem (line_count * sizeof (int32_t));
if (deltas == nullptr || occupation == nullptr)
MEMORY_OUT.error ("compute_line_spacing", ABORT, nullptr);
// change in occupation
std::vector<int32_t> deltas(line_count);
// of pixel coords
std::vector<int32_t> occupation(line_count);
compute_line_occupation(block, gradient, min_y, max_y, occupation, deltas);
compute_line_occupation(block, gradient, min_y, max_y, &occupation[0], &deltas[0]);
compute_occupation_threshold ((int32_t)
ceil (block->line_spacing *
(tesseract::CCStruct::kDescenderFraction +
@ -623,13 +616,13 @@ void delete_non_dropout_rows( //find lines
(int32_t) ceil (block->line_spacing *
(tesseract::CCStruct::kXHeightFraction +
tesseract::CCStruct::kAscenderFraction)),
max_y - min_y + 1, occupation, deltas);
max_y - min_y + 1, &occupation[0], &deltas[0]);
#ifndef GRAPHICS_DISABLED
if (testing_on) {
draw_occupation(xleft, ybottom, min_y, max_y, occupation, deltas);
draw_occupation(xleft, ybottom, min_y, max_y, &occupation[0], &deltas[0]);
}
#endif
compute_dropout_distances(occupation, deltas, line_count);
compute_dropout_distances(&occupation[0], &deltas[0], line_count);
for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
row = row_it.data ();
line_index = (int32_t) floor (row->intercept ());
@ -648,9 +641,6 @@ void delete_non_dropout_rows( //find lines
for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ()) {
blob_it.add_list_after (row_it.data ()->blob_list ());
}
free_mem(deltas);
free_mem(occupation);
}
@ -779,10 +769,10 @@ TBOX deskew_block_coords( //block box
void compute_line_occupation( //project blobs
TO_BLOCK *block, //block to do
float gradient, //global skew
int32_t min_y, //min coord in block
int32_t max_y, //in block
int32_t min_y, //min coord in block
int32_t max_y, //in block
int32_t *occupation, //output projection
int32_t *deltas //derivative
int32_t *deltas //derivative
) {
int32_t line_count; //maxy-miny+1
int32_t line_index; //of scan line
@ -1162,11 +1152,8 @@ void compute_row_stats( //find lines
TO_ROW_IT row_it = block->get_rows ();
//number of rows
int16_t rowcount = row_it.length ();
TO_ROW **rows; //for choose nth
rows = (TO_ROW **) alloc_mem (rowcount * sizeof (TO_ROW *));
if (rows == nullptr)
MEMORY_OUT.error ("compute_row_stats", ABORT, nullptr);
// for choose nth
std::vector<TO_ROW*> rows(rowcount);
rowcount = 0;
prev_row = nullptr;
row_it.move_to_last (); //start at bottom
@ -1190,13 +1177,13 @@ void compute_row_stats( //find lines
tprintf ("Blob based spacing=(%g,%g), offset=%g",
block->line_size, block->line_spacing, block->baseline_offset);
if (rowcount > 0) {
row_index = choose_nth_item (rowcount * 3 / 4, rows, rowcount,
row_index = choose_nth_item(rowcount * 3 / 4, &rows[0], rowcount,
sizeof (TO_ROW *), row_spacing_order);
iqr = rows[row_index]->spacing;
row_index = choose_nth_item (rowcount / 4, rows, rowcount,
row_index = choose_nth_item(rowcount / 4, &rows[0], rowcount,
sizeof (TO_ROW *), row_spacing_order);
iqr -= rows[row_index]->spacing;
row_index = choose_nth_item (rowcount / 2, rows, rowcount,
row_index = choose_nth_item(rowcount / 2, &rows[0], rowcount,
sizeof (TO_ROW *), row_spacing_order);
block->key_row = rows[row_index];
if (testing_on)
@ -1232,7 +1219,6 @@ void compute_row_stats( //find lines
if (testing_on)
tprintf ("\nEstimate line size=%g, spacing=%g, offset=%g\n",
block->line_size, block->line_spacing, block->baseline_offset);
free_mem(rows);
}
@ -2070,26 +2056,25 @@ void Textord::make_spline_rows(TO_BLOCK* block, // block to do
*/
void make_baseline_spline(TO_ROW *row, //row to fit
TO_BLOCK *block) {
int32_t *xstarts; // spline boundaries
double *coeffs; // quadratic coeffs
int32_t segments; // no of segments
int32_t segments; // no of segments
xstarts =
(int32_t *) alloc_mem((row->blob_list()->length() + 1) * sizeof(int32_t));
// spline boundaries
int32_t *xstarts = new int32_t[row->blob_list()->length() + 1];
if (segment_baseline(row, block, segments, xstarts)
&& !textord_straight_baselines && !textord_parallel_baselines) {
coeffs = linear_spline_baseline(row, block, segments, xstarts);
} else {
xstarts[1] = xstarts[segments];
segments = 1;
coeffs = (double *) alloc_mem (3 * sizeof (double));
coeffs = new double[3];
coeffs[0] = 0;
coeffs[1] = row->line_m ();
coeffs[2] = row->line_c ();
}
row->baseline = QSPLINE (segments, xstarts, coeffs);
free_mem(coeffs);
free_mem(xstarts);
delete[] coeffs;
delete[] xstarts;
}
@ -2203,22 +2188,21 @@ double *
linear_spline_baseline ( //split baseline
TO_ROW * row, //row to fit
TO_BLOCK * block, //block it came from
int32_t & segments, //no fo segments
int32_t xstarts[] //coords of segments
int32_t & segments, //no fo segments
int32_t xstarts[] //coords of segments
) {
int blobcount; //no of blobs
int blobindex; //current blob
int index1, index2; //blob numbers
int blobs_per_segment; //blobs in each
TBOX box; //blob box
TBOX new_box; //new_it box
TBOX box; //blob box
TBOX new_box; //new_it box
//blobs
BLOBNBOX_IT blob_it = row->blob_list ();
BLOBNBOX_IT new_it = blob_it; //front end
float b, c; //fitted curve
tesseract::DetLineFit lms;
double *coeffs; //quadratic coeffs
int32_t segment; //current segment
int32_t segment; //current segment
box = box_next_pre_chopped (&blob_it);
xstarts[0] = box.left ();
@ -2231,7 +2215,8 @@ int32_t xstarts[] //coords of segments
if (segments < 1)
segments = 1;
blobs_per_segment = blobcount / segments;
coeffs = (double *) alloc_mem (segments * 3 * sizeof (double));
// quadratic coeffs
double *coeffs = new double[segments * 3];
if (textord_oldbl_debug)
tprintf
("Linear splining baseline of %d blobs at (%d,%d), into %d segments of %d blobs\n",

View File

@ -17,6 +17,7 @@
*
**********************************************************************/
#include <vector> // for std::vector
#include "ccstruct.h"
#include "statistc.h"
#include "quadlsq.h"
@ -121,7 +122,6 @@ void Textord::make_old_baselines(TO_BLOCK* block, // block to do
**********************************************************************/
void Textord::correlate_lines(TO_BLOCK *block, float gradient) {
TO_ROW **rows; //array of ptrs
int rowcount; /*no of rows to do */
int rowindex; /*no of row */
// iterator
@ -133,17 +133,18 @@ void Textord::correlate_lines(TO_BLOCK *block, float gradient) {
block->xheight = block->line_size;
return; /*none to do */
}
rows = (TO_ROW **) alloc_mem (rowcount * sizeof (TO_ROW *));
// array of ptrs
std::vector <TO_ROW *> rows(rowcount);
rowindex = 0;
for (row_it.mark_cycle_pt (); !row_it.cycled_list (); row_it.forward ())
//make array
rows[rowindex++] = row_it.data ();
/*try to fix bad lines */
correlate_neighbours(block, rows, rowcount);
correlate_neighbours(block, &rows[0], rowcount);
if (textord_really_old_xheight || textord_old_xheight) {
block->xheight = (float) correlate_with_stats(rows, rowcount, block);
block->xheight = (float) correlate_with_stats(&rows[0], rowcount, block);
if (block->xheight <= 0)
block->xheight = block->line_size * tesseract::CCStruct::kXHeightFraction;
if (block->xheight < textord_min_xheight)
@ -151,8 +152,6 @@ void Textord::correlate_lines(TO_BLOCK *block, float gradient) {
} else {
compute_block_xheight(block, gradient);
}
free_mem(rows);
}
@ -334,28 +333,28 @@ void Textord::find_textlines(TO_BLOCK *block, // block row is in
int partcount; /*no of partitions of */
bool holed_line = false; //lost too many blobs
int bestpart; /*biggest partition */
char *partids; /*partition no of each blob */
int partsizes[MAXPARTS]; /*no in each partition */
int lineheight; /*guessed x-height */
float jumplimit; /*allowed delta change */
int *xcoords; /*useful sample points */
int *ycoords; /*useful sample points */
TBOX *blobcoords; /*edges of blob rectangles */
int blobcount; /*no of blobs on line */
float *ydiffs; /*diffs from 1st approx */
int pointcount; /*no of coords */
int xstarts[SPLINESIZE + 1]; //segment boundaries
int segments; //no of segments
//no of blobs in row
blobcount = row->blob_list ()->length ();
partids = (char *) alloc_mem (blobcount * sizeof (char));
xcoords = (int *) alloc_mem (blobcount * sizeof (int));
ycoords = (int *) alloc_mem (blobcount * sizeof (int));
blobcoords = (TBOX *) alloc_mem (blobcount * sizeof (TBOX));
ydiffs = (float *) alloc_mem (blobcount * sizeof (float));
// partition no of each blob
std::vector<char> partids(blobcount);
// useful sample points
std::vector<int> xcoords(blobcount);
// useful sample points
std::vector<int> ycoords(blobcount);
// edges of blob rectangles
std::vector<TBOX> blobcoords(blobcount);
// diffs from 1st approx
std::vector<float> ydiffs(blobcount);
lineheight = get_blob_coords (row, (int) block->line_size, blobcoords,
lineheight = get_blob_coords(row, (int)block->line_size, &blobcoords[0],
holed_line, blobcount);
/*limit for line change */
jumplimit = lineheight * textord_oldbl_jumplimit;
@ -368,40 +367,34 @@ void Textord::find_textlines(TO_BLOCK *block, // block row is in
block->line_size, lineheight, jumplimit);
}
if (holed_line)
make_holed_baseline (blobcoords, blobcount, spline, &row->baseline,
make_holed_baseline(&blobcoords[0], blobcount, spline, &row->baseline,
row->line_m ());
else
make_first_baseline (blobcoords, blobcount,
xcoords, ycoords, spline, &row->baseline, jumplimit);
make_first_baseline(&blobcoords[0], blobcount,
&xcoords[0], &ycoords[0], spline, &row->baseline, jumplimit);
#ifndef GRAPHICS_DISABLED
if (textord_show_final_rows)
row->baseline.plot (to_win, ScrollView::GOLDENROD);
#endif
if (blobcount > 1) {
bestpart = partition_line (blobcoords, blobcount,
&partcount, partids, partsizes,
&row->baseline, jumplimit, ydiffs);
pointcount = partition_coords (blobcoords, blobcount,
partids, bestpart, xcoords, ycoords);
segments = segment_spline (blobcoords, blobcount,
xcoords, ycoords,
degree, pointcount, xstarts);
bestpart = partition_line(&blobcoords[0], blobcount,
&partcount, &partids[0], partsizes,
&row->baseline, jumplimit, &ydiffs[0]);
pointcount = partition_coords(&blobcoords[0], blobcount,
&partids[0], bestpart, &xcoords[0], &ycoords[0]);
segments = segment_spline(&blobcoords[0], blobcount,
&xcoords[0], &ycoords[0], degree, pointcount, xstarts);
if (!holed_line) {
do {
row->baseline = QSPLINE (xstarts, segments,
xcoords, ycoords, pointcount, degree);
row->baseline = QSPLINE(xstarts, segments,
&xcoords[0], &ycoords[0], pointcount, degree);
}
while (textord_oldbl_split_splines
&& split_stepped_spline (&row->baseline, jumplimit / 2,
xcoords, xstarts, segments));
&xcoords[0], xstarts, segments));
}
find_lesser_parts(row,
blobcoords,
blobcount,
partids,
partsizes,
partcount,
bestpart);
find_lesser_parts(row, &blobcoords[0], blobcount,
&partids[0], partsizes, partcount, bestpart);
}
else {
@ -414,20 +407,15 @@ void Textord::find_textlines(TO_BLOCK *block, // block row is in
block->block->pdblk.bounding_box ().right ());
if (textord_really_old_xheight) {
old_first_xheight (row, blobcoords, lineheight,
old_first_xheight (row, &blobcoords[0], lineheight,
blobcount, &row->baseline, jumplimit);
} else if (textord_old_xheight) {
make_first_xheight (row, blobcoords, lineheight, (int) block->line_size,
make_first_xheight (row, &blobcoords[0], lineheight, (int)block->line_size,
blobcount, &row->baseline, jumplimit);
} else {
compute_row_xheight(row, block->block->classify_rotation(),
row->line_m(), block->line_size);
}
free_mem(partids);
free_mem(xcoords);
free_mem(ycoords);
free_mem(blobcoords);
free_mem(ydiffs);
}
} // namespace tesseract.

View File

@ -1,8 +1,8 @@
/**********************************************************************
* File: pithsync.cpp (Formerly pitsync2.c)
* Description: Code to find the optimum fixed pitch segmentation of some blobs.
* Author: Ray Smith
* Created: Thu Nov 19 11:48:05 GMT 1992
* Author: Ray Smith
* Created: Thu Nov 19 11:48:05 GMT 1992
*
* (C) Copyright 1992, Hewlett-Packard Ltd.
** Licensed under the Apache License, Version 2.0 (the "License");
@ -18,7 +18,7 @@
**********************************************************************/
#include <math.h>
#include "memry.h"
#include <vector> // for std::vector
#include "makerow.h"
#include "pitsync1.h"
#include "topitch.h"
@ -320,7 +320,6 @@ double check_pitch_sync2( //find segmentation
TBOX this_box; //bounding box
TBOX next_box; //box of next blob
FPSEGPT *segpt; //segment point
FPCUTPT *cutpts; //array of points
double best_cost; //best path
double mean_sum; //computes result
FPCUTPT *best_end; //end of best path
@ -359,14 +358,16 @@ double check_pitch_sync2( //find segmentation
projection_scale, occupation_count, seg_list,
start, end);
array_origin = left_edge - pitch;
cutpts = (FPCUTPT *) alloc_mem ((right_edge - left_edge + pitch * 2 + 1)
* sizeof (FPCUTPT));
// array of points
std::vector<FPCUTPT> cutpts(right_edge - left_edge + pitch * 2 + 1);
for (x = array_origin; x < left_edge; x++)
//free cuts
cutpts[x - array_origin].setup (cutpts, array_origin, projection, zero_count, pitch, x, 0);
cutpts[x - array_origin].setup(&cutpts[0], array_origin, projection,
zero_count, pitch, x, 0);
for (offset = 0; offset <= pitch_error; offset++, x++)
//not quite free
cutpts[x - array_origin].setup (cutpts, array_origin, projection, zero_count, pitch, x, offset);
cutpts[x - array_origin].setup(&cutpts[0], array_origin, projection,
zero_count, pitch, x, offset);
this_it = *blob_it;
best_cost = MAX_FLOAT32;
@ -404,7 +405,7 @@ double check_pitch_sync2( //find segmentation
faking = true;
offset = projection->pile_count (x);
}
cutpts[x - array_origin].assign (cutpts, array_origin, x,
cutpts[x - array_origin].assign (&cutpts[0], array_origin, x,
faking, mid_cut, offset, projection,
projection_scale, zero_count, pitch,
pitch_error);
@ -416,7 +417,7 @@ double check_pitch_sync2( //find segmentation
best_count = INT16_MAX;
while (x < right_edge + pitch) {
offset = x < right_edge ? right_edge - x : 0;
cutpts[x - array_origin].assign (cutpts, array_origin, x,
cutpts[x - array_origin].assign (&cutpts[0], array_origin, x,
false, false, offset, projection,
projection_scale, zero_count, pitch,
pitch_error);
@ -473,7 +474,6 @@ double check_pitch_sync2( //find segmentation
if (seg_it.data ()->squares () - mean_sum < 0)
tprintf ("Impossible sqsum=%g, mean=%g, total=%d\n",
seg_it.data ()->squares (), seg_it.data ()->sum (), best_count);
free_mem(cutpts);
// tprintf("blob_count=%d, pitch=%d, sync=%g, occ=%d\n",
// blob_count,pitch,seg_it.data()->squares()-mean_sum,
// occupation_count);
@ -502,29 +502,27 @@ double check_pitch_sync3( //find segmentation
int16_t start, //start of good range
int16_t end //end of good range
) {
bool faking; //illegal cut pt
bool mid_cut; //cheap cut pt.
int16_t left_edge; //of word
int16_t right_edge; //of word
int16_t x; //current coord
int16_t array_origin; //x coord of array
int16_t offset; //dist to legal area
int16_t projection_offset; //from scaled projection
int16_t prev_zero; //previous zero dist
int16_t next_zero; //next zero dist
int16_t zero_offset; //scan window
int16_t best_left_x = 0; //for equals
int16_t best_right_x = 0; //right edge
bool faking; //illegal cut pt
bool mid_cut; //cheap cut pt.
int16_t left_edge; //of word
int16_t right_edge; //of word
int16_t x; //current coord
int16_t array_origin; //x coord of array
int16_t offset; //dist to legal area
int16_t projection_offset; //from scaled projection
int16_t prev_zero; //previous zero dist
int16_t next_zero; //next zero dist
int16_t zero_offset; //scan window
int16_t best_left_x = 0; //for equals
int16_t best_right_x = 0; //right edge
FPSEGPT *segpt; //segment point
FPCUTPT *cutpts; //array of points
BOOL8 *mins; //local min results
int minindex; //next input position
int test_index; //index to mins
double best_cost; //best path
double mean_sum; //computes result
FPCUTPT *best_end; //end of best path
int16_t best_fake; //best fake level
int16_t best_count; //no of cuts
int16_t best_fake; //best fake level
int16_t best_count; //no of cuts
FPSEGPT_IT seg_it = seg_list; //output iterator
end = (end - start) % pitch;
@ -539,16 +537,19 @@ double check_pitch_sync3( //find segmentation
for (right_edge = projection_right; projection->pile_count (right_edge) == 0
&& right_edge > left_edge; right_edge--);
array_origin = left_edge - pitch;
cutpts = (FPCUTPT *) alloc_mem ((right_edge - left_edge + pitch * 2 + 1)
* sizeof (FPCUTPT));
mins = (BOOL8 *) alloc_mem ((pitch_error * 2 + 1) * sizeof (BOOL8));
// array of points
std::vector<FPCUTPT> cutpts(right_edge - left_edge + pitch * 2 + 1);
// local min results
std::vector<BOOL8> mins(pitch_error * 2 + 1);
for (x = array_origin; x < left_edge; x++)
//free cuts
cutpts[x - array_origin].setup (cutpts, array_origin, projection, zero_count, pitch, x, 0);
cutpts[x - array_origin].setup(&cutpts[0], array_origin, projection,
zero_count, pitch, x, 0);
prev_zero = left_edge - 1;
for (offset = 0; offset <= pitch_error; offset++, x++)
//not quite free
cutpts[x - array_origin].setup (cutpts, array_origin, projection, zero_count, pitch, x, offset);
cutpts[x - array_origin].setup(&cutpts[0], array_origin, projection,
zero_count, pitch, x, offset);
best_cost = MAX_FLOAT32;
best_end = nullptr;
@ -609,12 +610,12 @@ double check_pitch_sync3( //find segmentation
if ((start == 0 && end == 0)
|| !textord_fast_pitch_test
|| (x - projection_left - start) % pitch <= end)
cutpts[x - array_origin].assign (cutpts, array_origin, x,
cutpts[x - array_origin].assign(&cutpts[0], array_origin, x,
faking, mid_cut, offset, projection,
projection_scale, zero_count, pitch,
pitch_error);
else
cutpts[x - array_origin].assign_cheap (cutpts, array_origin, x,
cutpts[x - array_origin].assign_cheap(&cutpts[0], array_origin, x,
faking, mid_cut, offset,
projection, projection_scale,
zero_count, pitch,
@ -631,7 +632,7 @@ double check_pitch_sync3( //find segmentation
best_count = INT16_MAX;
while (x < right_edge + pitch) {
offset = x < right_edge ? right_edge - x : 0;
cutpts[x - array_origin].assign (cutpts, array_origin, x,
cutpts[x - array_origin].assign(&cutpts[0], array_origin, x,
false, false, offset, projection,
projection_scale, zero_count, pitch,
pitch_error);
@ -686,7 +687,5 @@ double check_pitch_sync3( //find segmentation
if (seg_it.data ()->squares () - mean_sum < 0)
tprintf ("Impossible sqsum=%g, mean=%g, total=%d\n",
seg_it.data ()->squares (), seg_it.data ()->sum (), best_count);
free_mem(mins);
free_mem(cutpts);
return seg_it.data ()->squares () - mean_sum;
}

View File

@ -18,7 +18,6 @@
**********************************************************************/
#include <math.h>
#include "memry.h"
#include "pitsync1.h"
ELISTIZE (FPSEGPT) CLISTIZE (FPSEGPT_LIST)

View File

@ -1,8 +1,8 @@
/**********************************************************************
* File: topitch.cpp (Formerly to_pitch.c)
* Description: Code to determine fixed pitchness and the pitch if fixed.
* Author: Ray Smith
* Created: Tue Aug 24 16:57:29 BST 1993
* Author: Ray Smith
* Created: Tue Aug 24 16:57:29 BST 1993
*
* (C) Copyright 1993, Hewlett-Packard Ltd.
** Licensed under the Apache License, Version 2.0 (the "License");
@ -17,7 +17,6 @@
*
**********************************************************************/
#include "stderr.h"
#include "blobbox.h"
#include "statistc.h"
#include "drawtord.h"

View File

@ -1,8 +1,8 @@
/**********************************************************************
* File: tordmain.cpp (Formerly textordp.c)
* Description: C++ top level textord code.
* Author: Ray Smith
* Created: Tue Jul 28 17:12:33 BST 1992
* Author: Ray Smith
* Created: Tue Jul 28 17:12:33 BST 1992
*
* (C) Copyright 1992, Hewlett-Packard Ltd.
** Licensed under the Apache License, Version 2.0 (the "License");
@ -21,7 +21,6 @@
#include "config_auto.h"
#endif
#include "stderr.h"
#include "globaloc.h"
#include "blread.h"
#include "blobbox.h"
@ -459,16 +458,16 @@ bool Textord::clean_noise_from_row( //remove empties
ROW* row //row to clean
) {
bool testing_on;
TBOX blob_box; //bounding box
TBOX blob_box; //bounding box
C_BLOB *blob; //current blob
C_OUTLINE *outline; //current outline
WERD *word; //current word
int32_t blob_size; //biggest size
int32_t trans_count = 0; //no of transitions
int32_t trans_threshold; //noise tolerance
int32_t dot_count; //small objects
int32_t norm_count; //normal objects
int32_t super_norm_count; //real char-like
int32_t blob_size; //biggest size
int32_t trans_count = 0; //no of transitions
int32_t trans_threshold; //noise tolerance
int32_t dot_count; //small objects
int32_t norm_count; //normal objects
int32_t super_norm_count; //real char-like
//words of row
WERD_IT word_it = row->word_list ();
C_BLOB_IT blob_it; //blob iterator
@ -559,19 +558,18 @@ bool Textord::clean_noise_from_row( //remove empties
void Textord::clean_noise_from_words( //remove empties
ROW *row //row to clean
) {
TBOX blob_box; //bounding box
int8_t *word_dud; //was it chucked
TBOX blob_box; //bounding box
C_BLOB *blob; //current blob
C_OUTLINE *outline; //current outline
WERD *word; //current word
int32_t blob_size; //biggest size
int32_t trans_count; //no of transitions
int32_t trans_threshold; //noise tolerance
int32_t dot_count; //small objects
int32_t norm_count; //normal objects
int32_t dud_words; //number discarded
int32_t ok_words; //number remaining
int32_t word_index; //current word
int32_t blob_size; //biggest size
int32_t trans_count; //no of transitions
int32_t trans_threshold; //noise tolerance
int32_t dot_count; //small objects
int32_t norm_count; //normal objects
int32_t dud_words; //number discarded
int32_t ok_words; //number remaining
int32_t word_index; //current word
//words of row
WERD_IT word_it = row->word_list ();
C_BLOB_IT blob_it; //blob iterator
@ -580,7 +578,8 @@ void Textord::clean_noise_from_words( //remove empties
ok_words = word_it.length ();
if (ok_words == 0 || textord_no_rejects)
return;
word_dud = (int8_t *) alloc_mem (ok_words * sizeof (int8_t));
// was it chucked
std::vector<int8_t> word_dud(ok_words);
dud_words = 0;
ok_words = 0;
word_index = 0;
@ -664,7 +663,6 @@ void Textord::clean_noise_from_words( //remove empties
}
word_index++;
}
free_mem(word_dud);
}
// Remove outlines that are a tiny fraction in either width or height
@ -885,8 +883,6 @@ void tweak_row_baseline(ROW *row,
int32_t blob_count; //no of blobs
int32_t src_index; //source segment
int32_t dest_index; //destination segment
int32_t *xstarts; //spline segments
double *coeffs; //spline coeffs
float ydiff; //baseline error
float x_centre; //centre of blob
//words of row
@ -901,12 +897,10 @@ void tweak_row_baseline(ROW *row,
}
if (blob_count == 0)
return;
xstarts =
(int32_t *) alloc_mem ((blob_count + row->baseline.segments + 1) *
sizeof (int32_t));
coeffs =
(double *) alloc_mem ((blob_count + row->baseline.segments) * 3 *
sizeof (double));
// spline segments
std::vector<int32_t> xstarts(blob_count + row->baseline.segments + 1);
// spline coeffs
std::vector<double> coeffs((blob_count + row->baseline.segments) * 3);
src_index = 0;
dest_index = 0;
@ -978,7 +972,5 @@ void tweak_row_baseline(ROW *row,
xstarts[dest_index] = row->baseline.xcoords[src_index];
}
//turn to spline
row->baseline = QSPLINE (dest_index, xstarts, coeffs);
free_mem(xstarts);
free_mem(coeffs);
row->baseline = QSPLINE(dest_index, &xstarts[0], &coeffs[0]);
}

View File

@ -1,8 +1,8 @@
/**********************************************************************
* File: wordseg.cpp (Formerly wspace.c)
* Description: Code to segment the blobs into words.
* Author: Ray Smith
* Created: Fri Oct 16 11:32:28 BST 1992
* Author: Ray Smith
* Created: Fri Oct 16 11:32:28 BST 1992
*
* (C) Copyright 1992, Hewlett-Packard Ltd.
** Licensed under the Apache License, Version 2.0 (the "License");
@ -17,7 +17,6 @@
*
**********************************************************************/
#include "stderr.h"
#include "blobbox.h"
#include "statistc.h"
#include "drawtord.h"