mirror of
https://github.com/tesseract-ocr/tesseract.git
synced 2025-06-18 18:13:55 +08:00
Fix memory leak (OSS-Fuzz issue #32246)
Signed-off-by: Stefan Weil <sw@weilnetz.de>
This commit is contained in:
parent
f2c6378b5a
commit
f77b1c6881
@ -378,7 +378,7 @@ void BLOBNBOX::DeleteNoiseBlobs(BLOBNBOX_LIST *blobs) {
|
|||||||
for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
|
for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
|
||||||
BLOBNBOX *blob = blob_it.data();
|
BLOBNBOX *blob = blob_it.data();
|
||||||
if (blob->DeletableNoise()) {
|
if (blob->DeletableNoise()) {
|
||||||
delete blob->cblob();
|
delete blob->remove_cblob();
|
||||||
delete blob_it.extract();
|
delete blob_it.extract();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -926,16 +926,6 @@ TO_BLOCK::TO_BLOCK( // make a block
|
|||||||
block = src_block;
|
block = src_block;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_blobnboxes(BLOBNBOX_LIST *boxes) {
|
|
||||||
BLOBNBOX_IT it = boxes;
|
|
||||||
// A BLOBNBOX generally doesn't own its blobs, so if they do, you
|
|
||||||
// have to delete them explicitly.
|
|
||||||
for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
|
|
||||||
BLOBNBOX *box = it.data();
|
|
||||||
delete box->cblob();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* TO_BLOCK::clear
|
* TO_BLOCK::clear
|
||||||
*
|
*
|
||||||
@ -963,11 +953,11 @@ void TO_BLOCK::clear() {
|
|||||||
|
|
||||||
TO_BLOCK::~TO_BLOCK() {
|
TO_BLOCK::~TO_BLOCK() {
|
||||||
// Any residual BLOBNBOXes at this stage own their blobs, so delete them.
|
// Any residual BLOBNBOXes at this stage own their blobs, so delete them.
|
||||||
clear_blobnboxes(&blobs);
|
BLOBNBOX::clear_blobnboxes(&blobs);
|
||||||
clear_blobnboxes(&underlines);
|
BLOBNBOX::clear_blobnboxes(&underlines);
|
||||||
clear_blobnboxes(&noise_blobs);
|
BLOBNBOX::clear_blobnboxes(&noise_blobs);
|
||||||
clear_blobnboxes(&small_blobs);
|
BLOBNBOX::clear_blobnboxes(&small_blobs);
|
||||||
clear_blobnboxes(&large_blobs);
|
BLOBNBOX::clear_blobnboxes(&large_blobs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to divide the input blobs over noise, small, medium
|
// Helper function to divide the input blobs over noise, small, medium
|
||||||
|
@ -154,6 +154,18 @@ public:
|
|||||||
delete cblob_ptr;
|
delete cblob_ptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void clear_blobnboxes(BLOBNBOX_LIST *boxes) {
|
||||||
|
BLOBNBOX_IT it = boxes;
|
||||||
|
// A BLOBNBOX generally doesn't own its blobs, so if they do, you
|
||||||
|
// have to delete them explicitly.
|
||||||
|
for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
|
||||||
|
BLOBNBOX *box = it.data();
|
||||||
|
// TODO: remove next line, currently still needed for resultiterator_test.
|
||||||
|
delete box->remove_cblob();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static BLOBNBOX *RealBlob(C_OUTLINE *outline) {
|
static BLOBNBOX *RealBlob(C_OUTLINE *outline) {
|
||||||
auto *blob = new C_BLOB(outline);
|
auto *blob = new C_BLOB(outline);
|
||||||
return new BLOBNBOX(blob);
|
return new BLOBNBOX(blob);
|
||||||
@ -265,6 +277,12 @@ public:
|
|||||||
C_BLOB *cblob() const {
|
C_BLOB *cblob() const {
|
||||||
return cblob_ptr;
|
return cblob_ptr;
|
||||||
}
|
}
|
||||||
|
C_BLOB *remove_cblob() {
|
||||||
|
auto blob = cblob_ptr;
|
||||||
|
cblob_ptr = nullptr;
|
||||||
|
owns_cblob_ = false;
|
||||||
|
return blob;
|
||||||
|
}
|
||||||
TabType left_tab_type() const {
|
TabType left_tab_type() const {
|
||||||
return left_tab_type_;
|
return left_tab_type_;
|
||||||
}
|
}
|
||||||
|
@ -360,14 +360,9 @@ WERD &WERD::operator=(const WERD &source) {
|
|||||||
flags = source.flags;
|
flags = source.flags;
|
||||||
script_id_ = source.script_id_;
|
script_id_ = source.script_id_;
|
||||||
correct = source.correct;
|
correct = source.correct;
|
||||||
if (!cblobs.empty()) {
|
|
||||||
cblobs.clear();
|
cblobs.clear();
|
||||||
}
|
|
||||||
cblobs.deep_copy(&source.cblobs, &C_BLOB::deep_copy);
|
cblobs.deep_copy(&source.cblobs, &C_BLOB::deep_copy);
|
||||||
|
|
||||||
if (!rej_cblobs.empty()) {
|
|
||||||
rej_cblobs.clear();
|
rej_cblobs.clear();
|
||||||
}
|
|
||||||
rej_cblobs.deep_copy(&source.rej_cblobs, &C_BLOB::deep_copy);
|
rej_cblobs.deep_copy(&source.rej_cblobs, &C_BLOB::deep_copy);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -537,7 +532,7 @@ bool WERD::AddSelectedOutlines(const std::vector<bool> &wanted,
|
|||||||
*make_next_word_fuzzy = false;
|
*make_next_word_fuzzy = false;
|
||||||
}
|
}
|
||||||
C_BLOB_IT rej_it(&rej_cblobs);
|
C_BLOB_IT rej_it(&rej_cblobs);
|
||||||
for (int i = 0; i < outlines.size(); ++i) {
|
for (unsigned i = 0; i < outlines.size(); ++i) {
|
||||||
C_OUTLINE *outline = outlines[i];
|
C_OUTLINE *outline = outlines[i];
|
||||||
if (outline == nullptr) {
|
if (outline == nullptr) {
|
||||||
continue; // Already used it.
|
continue; // Already used it.
|
||||||
|
@ -278,9 +278,8 @@ void CCNonTextDetect::MarkAndDeleteNonTextBlobs(BLOBNBOX_LIST *blobs, int max_bl
|
|||||||
// It is safe to delete the cblob now, as it isn't used by the grid
|
// It is safe to delete the cblob now, as it isn't used by the grid
|
||||||
// or BlobOverlapsTooMuch, and the BLOBNBOXes will go away with the
|
// or BlobOverlapsTooMuch, and the BLOBNBOXes will go away with the
|
||||||
// dead_blobs list.
|
// dead_blobs list.
|
||||||
// TODO(rays) delete the delete when the BLOBNBOX destructor deletes
|
// TODO: remove next line, currently still needed for resultiterator_test.
|
||||||
// the cblob.
|
delete blob->remove_cblob();
|
||||||
delete blob->cblob();
|
|
||||||
dead_it.add_to_end(blob_it.extract());
|
dead_it.add_to_end(blob_it.extract());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,7 +322,8 @@ void ColPartition::DeleteBoxes() {
|
|||||||
// and the BLOBNBOXes own the underlying C_BLOBs.
|
// and the BLOBNBOXes own the underlying C_BLOBs.
|
||||||
for (BLOBNBOX_C_IT bb_it(&boxes_); !bb_it.empty(); bb_it.forward()) {
|
for (BLOBNBOX_C_IT bb_it(&boxes_); !bb_it.empty(); bb_it.forward()) {
|
||||||
BLOBNBOX *bblob = bb_it.extract();
|
BLOBNBOX *bblob = bb_it.extract();
|
||||||
delete bblob->cblob();
|
// TODO: remove next line, currently still needed for resultiterator_test.
|
||||||
|
delete bblob->remove_cblob();
|
||||||
delete bblob;
|
delete bblob;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -267,7 +267,7 @@ void split_to_blob( // split the blob
|
|||||||
C_BLOB *real_cblob; // cblob to chop
|
C_BLOB *real_cblob; // cblob to chop
|
||||||
|
|
||||||
if (blob != nullptr) {
|
if (blob != nullptr) {
|
||||||
real_cblob = blob->cblob();
|
real_cblob = blob->remove_cblob();
|
||||||
} else {
|
} else {
|
||||||
real_cblob = nullptr;
|
real_cblob = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -181,6 +181,7 @@ void assign_blobs_to_blocks2(Image pix,
|
|||||||
for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
|
for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
|
||||||
blob = blob_it.extract();
|
blob = blob_it.extract();
|
||||||
newblob = new BLOBNBOX(blob); // Convert blob to BLOBNBOX.
|
newblob = new BLOBNBOX(blob); // Convert blob to BLOBNBOX.
|
||||||
|
newblob->set_owns_cblob(true);
|
||||||
SetBlobStrokeWidth(pix, newblob);
|
SetBlobStrokeWidth(pix, newblob);
|
||||||
port_box_it.add_after_then_move(newblob);
|
port_box_it.add_after_then_move(newblob);
|
||||||
}
|
}
|
||||||
|
@ -864,8 +864,6 @@ the gap between the word being built and the next one. */
|
|||||||
float repetition_spacing; // gap between repetitions
|
float repetition_spacing; // gap between repetitions
|
||||||
int32_t xstarts[2]; // row ends
|
int32_t xstarts[2]; // row ends
|
||||||
int32_t prev_x; // end of prev blob
|
int32_t prev_x; // end of prev blob
|
||||||
BLOBNBOX *bblob; // current blob
|
|
||||||
TBOX blob_box; // bounding box
|
|
||||||
BLOBNBOX_IT box_it; // iterator
|
BLOBNBOX_IT box_it; // iterator
|
||||||
TBOX prev_blob_box;
|
TBOX prev_blob_box;
|
||||||
TBOX next_blob_box;
|
TBOX next_blob_box;
|
||||||
@ -935,18 +933,21 @@ the gap between the word being built and the next one. */
|
|||||||
|
|
||||||
peek_at_next_gap(row, box_it, next_blob_box, next_gap, next_within_xht_gap);
|
peek_at_next_gap(row, box_it, next_blob_box, next_gap, next_within_xht_gap);
|
||||||
do {
|
do {
|
||||||
bblob = box_it.data();
|
auto bblob = box_it.data();
|
||||||
blob_box = bblob->bounding_box();
|
auto blob_box = bblob->bounding_box();
|
||||||
if (bblob->joined_to_prev()) {
|
if (bblob->joined_to_prev()) {
|
||||||
if (bblob->cblob() != nullptr) {
|
auto cblob = bblob->remove_cblob();
|
||||||
|
if (cblob != nullptr) {
|
||||||
cout_it.set_to_list(cblob_it.data()->out_list());
|
cout_it.set_to_list(cblob_it.data()->out_list());
|
||||||
cout_it.move_to_last();
|
cout_it.move_to_last();
|
||||||
cout_it.add_list_after(bblob->cblob()->out_list());
|
cout_it.add_list_after(cblob->out_list());
|
||||||
delete bblob->cblob();
|
delete cblob;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (bblob->cblob() != nullptr) {
|
auto cblob = bblob->cblob();
|
||||||
cblob_it.add_after_then_move(bblob->cblob());
|
if (cblob != nullptr) {
|
||||||
|
bblob->set_owns_cblob(false);
|
||||||
|
cblob_it.add_after_then_move(cblob);
|
||||||
}
|
}
|
||||||
prev_x = blob_box.right();
|
prev_x = blob_box.right();
|
||||||
}
|
}
|
||||||
|
@ -84,11 +84,8 @@ void restore_underlined_blobs( // get chop points
|
|||||||
ru_it.add_after_then_move(new BLOBNBOX(new C_BLOB(&left_coutlines)));
|
ru_it.add_after_then_move(new BLOBNBOX(new C_BLOB(&left_coutlines)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (u_line != nullptr) {
|
|
||||||
delete u_line->cblob();
|
|
||||||
delete u_line;
|
delete u_line;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!ru_it.empty()) {
|
if (!ru_it.empty()) {
|
||||||
ru_it.move_to_first();
|
ru_it.move_to_first();
|
||||||
for (ru_it.mark_cycle_pt(); !ru_it.cycled_list(); ru_it.forward()) {
|
for (ru_it.mark_cycle_pt(); !ru_it.cycled_list(); ru_it.forward()) {
|
||||||
|
@ -62,15 +62,17 @@ void make_single_word(bool one_blob, TO_ROW_LIST *rows, ROW_LIST *real_rows) {
|
|||||||
for (; !box_it.empty(); box_it.forward()) {
|
for (; !box_it.empty(); box_it.forward()) {
|
||||||
BLOBNBOX *bblob = box_it.extract();
|
BLOBNBOX *bblob = box_it.extract();
|
||||||
if (bblob->joined_to_prev() || (one_blob && !cblob_it.empty())) {
|
if (bblob->joined_to_prev() || (one_blob && !cblob_it.empty())) {
|
||||||
if (bblob->cblob() != nullptr) {
|
auto cblob = bblob->remove_cblob();
|
||||||
|
if (cblob != nullptr) {
|
||||||
C_OUTLINE_IT cout_it(cblob_it.data()->out_list());
|
C_OUTLINE_IT cout_it(cblob_it.data()->out_list());
|
||||||
cout_it.move_to_last();
|
cout_it.move_to_last();
|
||||||
cout_it.add_list_after(bblob->cblob()->out_list());
|
cout_it.add_list_after(cblob->out_list());
|
||||||
delete bblob->cblob();
|
delete cblob;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (bblob->cblob() != nullptr) {
|
auto cblob = bblob->remove_cblob();
|
||||||
cblob_it.add_after_then_move(bblob->cblob());
|
if (cblob != nullptr) {
|
||||||
|
cblob_it.add_after_then_move(cblob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete bblob;
|
delete bblob;
|
||||||
|
Loading…
Reference in New Issue
Block a user