// Applies the box file based on the image name fname, and resegments // the words in the block_list (page), with: // blob-mode: one blob per line in the box file, words as input. // word/line-mode: one blob per space-delimited unit after the #, and one word // per line in the box file. (See comment above for box file format.) // If find_segmentation is true, (word/line mode) then the classifier is used // to re-segment words/lines to match the space-delimited truth string for // each box. In this case, the input box may be for a word or even a whole // text line, and the output words will contain multiple blobs corresponding // to the space-delimited input string. // With find_segmentation false, no classifier is needed, but the chopper // can still be used to correctly segment touching characters with the help // of the input boxes. // In the returned PAGE_RES, the WERD_RES are setup as they would be returned // from normal classification, ie. with a word, chopped_word, rebuild_word, // seam_array, denorm, box_word, and best_state, but NO best_choice or // raw_choice, as they would require a UNICHARSET, which we aim to avoid. // Instead, the correct_text member of WERD_RES is set, and this may be later // converted to a best_choice using CorrectClassifyWords. CorrectClassifyWords // is not required before calling ApplyBoxTraining. PAGE_RES* Tesseract::ApplyBoxes(const STRING& fname, bool find_segmentation, BLOCK_LIST *block_list) { GenericVector<TBOX> boxes; GenericVector<STRING> texts, full_texts; if (!ReadAllBoxes(applybox_page, true, fname, &boxes, &texts, &full_texts, NULL)) { return NULL; // Can't do it. } int box_count = boxes.size(); int box_failures = 0; // Add an empty everything to the end. boxes.push_back(TBOX()); texts.push_back(STRING()); full_texts.push_back(STRING()); // In word mode, we use the boxes to make a word for each box, but // in blob mode we use the existing words and maximally chop them first. PAGE_RES* page_res = find_segmentation ? NULL : SetupApplyBoxes(boxes, block_list); clear_any_old_text(block_list); for (int i = 0; i < boxes.size() - 1; i++) { bool foundit = false; if (page_res != NULL) { if (i == 0) { foundit = ResegmentCharBox(page_res, NULL, boxes[i], boxes[i + 1], full_texts[i].string()); } else { foundit = ResegmentCharBox(page_res, &boxes[i-1], boxes[i], boxes[i + 1], full_texts[i].string()); } } else { foundit = ResegmentWordBox(block_list, boxes[i], boxes[i + 1], texts[i].string()); } if (!foundit) { box_failures++; ReportFailedBox(i, boxes[i], texts[i].string(), "FAILURE! Couldn't find a matching blob"); } } if (page_res == NULL) { // In word/line mode, we now maximally chop all the words and resegment // them with the classifier. page_res = SetupApplyBoxes(boxes, block_list); ReSegmentByClassification(page_res); } if (applybox_debug > 0) { tprintf("APPLY_BOXES:\n"); tprintf(" Boxes read from boxfile: %6d\n", box_count); if (box_failures > 0) tprintf(" Boxes failed resegmentation: %6d\n", box_failures); } TidyUp(page_res); return page_res; }
BufferPool_Generic_c::~BufferPool_Generic_c( void ) { TidyUp(); if( ReferenceCount != 0 ) report( severity_error, "BufferPool_Generic_c::~BufferPool_Generic_c - Destroying pool of type '%s', Final reference count = %d\n", (BufferDescriptor->TypeName == NULL) ? "Unnamed" : BufferDescriptor->TypeName, ReferenceCount ); }
BufferPool_Generic_c::BufferPool_Generic_c( BufferManager_Generic_t Manager, BufferDataDescriptor_t *Descriptor, unsigned int NumberOfBuffers, unsigned int Size, void *MemoryPool[3], void *ArrayOfMemoryBlocks[][3], char *DeviceMemoryPartitionName ) { unsigned int i,j; BufferStatus_t Status; Buffer_Generic_t Buffer; unsigned int ItemSize; // InitializationStatus = BufferError; // // Initialize class data // this->Manager = Manager; Next = NULL; OS_InitializeMutex( &Lock ); OS_InitializeEvent( &BufferReleaseSignal ); ReferenceCount = 0; BufferDescriptor = NULL; this->NumberOfBuffers = 0; CountOfBuffers = 0; this->Size = 0; ListOfBuffers = NULL; FreeBuffer = NULL; this->MemoryPool[0] = NULL; this->MemoryPool[1] = NULL; this->MemoryPool[2] = NULL; MemoryPoolAllocator = NULL; MemoryPoolAllocatorDevice = ALLOCATOR_INVALID_DEVICE; memset( MemoryPartitionName, 0x00, ALLOCATOR_MAX_PARTITION_NAME_SIZE ); if( DeviceMemoryPartitionName != NULL ) strncpy( MemoryPartitionName, DeviceMemoryPartitionName, ALLOCATOR_MAX_PARTITION_NAME_SIZE-1 ); BufferBlock = NULL; ListOfMetaData = NULL; AbortGetBuffer = false; BufferReleaseSignalWaitedOn = false; CountOfReferencedBuffers = 0; TotalAllocatedMemory = 0; TotalUsedMemory = 0; // // Record parameters // this->BufferDescriptor = Descriptor; this->NumberOfBuffers = NumberOfBuffers; this->Size = Size; if( MemoryPool != NULL ) { this->MemoryPool[0] = MemoryPool[0]; this->MemoryPool[1] = MemoryPool[1]; this->MemoryPool[2] = MemoryPool[2]; } // // Shall we create the buffer class instances // if( NumberOfBuffers != NOT_SPECIFIED ) { // // Get a ring to hold the free buffers // FreeBuffer = new RingGeneric_c(NumberOfBuffers); if( (FreeBuffer == NULL) || (FreeBuffer->InitializationStatus != RingNoError) ) { report( severity_error, "BufferPool_Generic_c::BufferPool_Generic_c - Failed to create free buffer ring.\n" ); TidyUp(); return; } // // Can we allocate the memory for the buffers // if( Descriptor->AllocateOnPoolCreation ) { Status = CheckMemoryParameters( Descriptor, true, Size, MemoryPool, ArrayOfMemoryBlocks, DeviceMemoryPartitionName, "BufferPool_Generic_c::BufferPool_Generic_c", &ItemSize ); if( Status != BufferNoError ) { TidyUp(); return; } // // Create a buffer block descriptor record // BufferBlock = new struct BlockDescriptor_s; if( BufferBlock == NULL ) { report( severity_error, "BufferPool_Generic_c::BufferPool_Generic_c - Failed to allocate block descriptor.\n" ); TidyUp(); return; } BufferBlock->Descriptor = Descriptor; BufferBlock->AttachedToPool = true; BufferBlock->Size = ItemSize * NumberOfBuffers; BufferBlock->MemoryAllocatorDevice = ALLOCATOR_INVALID_DEVICE; Status = AllocateMemoryBlock( BufferBlock, true, 0, NULL, MemoryPool, ArrayOfMemoryBlocks, DeviceMemoryPartitionName, "BufferPool_Generic_c::BufferPool_Generic_c" ); if( Status != BufferNoError ) { TidyUp(); return; } } // // Now create the buffers // for( i=0; i<NumberOfBuffers; i++ ) { Buffer = new Buffer_Generic_c( Manager, this, Descriptor ); if( (Buffer == NULL) || (Buffer->InitializationStatus != BufferNoError) ) { InitializationStatus = BufferInsufficientMemoryForBuffer; if( Buffer != NULL ) { InitializationStatus = Buffer->InitializationStatus; delete Buffer; } report( severity_error, "BufferPool_Generic_c::BufferPool_Generic_c - Failed to create buffer (%08x)\n", InitializationStatus ); TidyUp(); return; } Buffer->Next = ListOfBuffers; Buffer->Index = i; ListOfBuffers = Buffer; FreeBuffer->Insert( (unsigned int)Buffer ); // // Have we allocated the buffer data block // if( Descriptor->AllocateOnPoolCreation ) { Buffer->DataSize = 0; Buffer->BufferBlock->AttachedToPool = true; Buffer->BufferBlock->Size = ItemSize; Buffer->BufferBlock->MemoryAllocatorDevice = ALLOCATOR_INVALID_DEVICE; Buffer->BufferBlock->Address[CachedAddress] = NULL; Buffer->BufferBlock->Address[UnCachedAddress] = NULL; Buffer->BufferBlock->Address[PhysicalAddress] = NULL; if( Descriptor->AllocationSource == AllocateIndividualSuppliedBlocks ) { for( j=0; j<3; j++ ) Buffer->BufferBlock->Address[j] = ArrayOfMemoryBlocks[i][j]; } else { for( j=0; j<3; j++ ) if( BufferBlock->Address[j] != NULL ) Buffer->BufferBlock->Address[j] = (unsigned char *)BufferBlock->Address[j] + (i * ItemSize); } } } } // // If we have pool memory, and we have not used it already, then we need to initialize the allocation mechanism. // if( (MemoryPool != NULL) && !Descriptor->AllocateOnPoolCreation ) { #if 0 MemoryPoolAllocator = new AllocatorSimple_c( Size, Descriptor->AllocationUnitSize, (unsigned char *)MemoryPool[PhysicalAddress] ); #else MemoryPoolAllocator = new AllocatorSimple_c( Size, 1, (unsigned char *)MemoryPool[PhysicalAddress] ); #endif if( (MemoryPoolAllocator == NULL) || (MemoryPoolAllocator->InitializationStatus != AllocatorNoError) ) { report( severity_error, "BufferPool_Generic_c::BufferPool_Generic_c - Failed to initialize MemoryPool allocator\n" ); TidyUp(); return; } } // InitializationStatus = BufferNoError; }