// создание нового блока или инициализация самого списка блоков BLOCK *BlocksAddDescriptor (void) { if (pBlocksList == NULL) { pBlocksList = malloc (sizeof (BLOCK)); if (pBlocksList == NULL) { #ifdef DebugFile strcpy(StringError,"BlocksAddDescriptor,if(pBlocksList==NULL)"); #endif ErrorNoEnoughMemory ("in LTBLOCKS.C,BlockAddDescriptor;part 1"); } memset (pBlocksList, 0, sizeof (BLOCK)); } else { pBlocksList -> pPrev = malloc (sizeof (BLOCK)); if (pBlocksList -> pPrev == NULL) { #ifdef DebugFile strcpy(StringError,"BlocksAddDescriptor,if(pPrev==NULL)"); #endif ErrorNoEnoughMemory ("in LTBLOCKS.C,BlockAddDescriptor;part 2"); } memset (pBlocksList -> pPrev, 0, sizeof (BLOCK)); pBlocksList -> pPrev -> pNext = pBlocksList; pBlocksList = pBlocksList -> pPrev; } pBlocksList->language=language; // Pit 02-??-94 return (pBlocksList); }
void * DebugMalloc(size_t size) { void * memvoid; int idblock; long sizeblock; Memory * Block; Memory * NextBlock; if(lout_memory==NULL) ErrorInternal("Malloc:Кучи еще нет!"); if(size == 0) return NULL; JoinEmptyBlocks(); // поиск свободного места for(Block =(Memory *)lout_memory;(char *)Block<(lout_memory+SizeBuffer); Block=(Memory *)((char *)Block+sizeof(Memory)+Block->size)) { idblock = Block->id; sizeblock = Block->size; NextBlock=Block; if(idblock==MEMEND || idblock==MEMFREE){ if(sizeblock>=size+sizeof(Memory)){ // заполняем найденный свободный блок Block->id=MEMMALLOC; Block->size=size; memvoid=(void *)((char *)Block+sizeof(Memory)); // создаем новый свободный блок Block=(Memory *)((char *)Block+size+sizeof(Memory)); Block->id =idblock; Block->size=sizeblock-(size+sizeof(Memory)); if(idblock==MEMEND) SizeMemory=(long)((char *)Block-lout_memory); goto YES; } else { if(idblock==MEMEND ) return NULL; // ErrorNoEnoughMemory("Вся память исчерпана..."); } } // if ... }// for ... ErrorNoEnoughMemory("Сбой при поиске свободного места..."); return NULL; YES: #ifdef DebugFile SizeAllocate+=size; if(FileError){ fprintf(FileError,"\nMalloc \t= %8li\tRunning \t= %li\tAll %li", (long)size, SizeAllocate-SizeFree, SizeMemory); } #endif return memvoid; }
void RootStripsCalculate(void) { ROOT * root; int yMin, yMax; int iStrip; int iStripBegin; int iStripEnd; if (cf::Roots::isEmpty()) ErrorInternal("nRoots == 0"); yMin = cf::Roots::first()->yRow; yMax = cf::Roots::first()->yRow + cf::Roots::first()->nHeight - 1; for (root = cf::Roots::first(); root < pAfterRoots; root++) { if ( root -> yRow < yMin) yMin = root -> yRow; if ( root -> yRow + root -> nHeight - 1 > yMax) yMax = root -> yRow + root -> nHeight - 1; } nRootStripsOffset = yMin; nRootStripsStep = 128; nRootStrips = (yMax - yMin + (nRootStripsStep - 1)) / nRootStripsStep + 1; if (pRootStrips)// Piter { free(pRootStrips);// Piter pRootStrips = NULL;// Piter }// Piter pRootStrips = (ROOT_STRIP*) malloc(nRootStrips * sizeof(ROOT_STRIP)); if (pRootStrips == NULL) ErrorNoEnoughMemory("in LTROOTS.C,RootStripsCalculate,part 1"); memset(pRootStrips, 0, nRootStrips * sizeof(ROOT_STRIP)); for ( root = cf::Roots::first(); root < pAfterRoots; root++) { iStripBegin = ( root -> yRow - nRootStripsOffset) / nRootStripsStep; iStripEnd = ( root -> yRow + root -> nHeight - 1 - nRootStripsOffset) / nRootStripsStep; assert(nRootStrips>iStripEnd); // Piter assert(nRootStrips>iStripBegin);// Piter for (iStrip = iStripBegin; iStrip <= iStripEnd; iStrip++) { if (pRootStrips[iStrip].pBegin == NULL || root < pRootStrips[iStrip].pBegin) { pRootStrips[iStrip].pBegin = root; } if (pRootStrips[iStrip].pEnd == NULL || root > pRootStrips[iStrip].pEnd) { pRootStrips[iStrip].pEnd = root; } } } }
void BlocksHystogramsAllocate(void) { BLOCK *p; for (p = pBlocksList; p != NULL; p = p -> pNext) { p -> nHystColumns = p -> Rect.yBottom - p -> Rect.yTop + 1; p -> pHystogram = static_cast<int*> (malloc(p -> nHystColumns * sizeof(int))); if (p -> pHystogram == NULL) ErrorNoEnoughMemory("in SEHYST.C,BlocksHystogramsAllocate,part 1"); memset(p -> pHystogram, 0, p -> nHystColumns * sizeof(int)); } }
void SeparatorsGet (void) { int i; int j; SeparatorsFreeData (); if (nl == 0) return; nSeps = nf + nl; pSeps = malloc (nSeps * sizeof (SEPARATOR)); if (pSeps == NULL) ErrorNoEnoughMemory ("in LTSEPS.C,SeparatorsGet,part 1"); for (i = 0, j = 0; i < nf; i++, j++) { pSeps [j].Type = SEP_RECT; pSeps [j].uFlags = SEPF_NULL; pSeps [j].xBegin = frames [i].topleft.col; pSeps [j].yBegin = frames [i].topleft.row; pSeps [j].xEnd = frames [i].botright.col; pSeps [j].yEnd = frames [i].botright.row; pSeps [j].nWidth = 1; } for (i = 0; i < nl; i++, j++) { if (lines [i].type & UNDRLN) pSeps [j].Type = SEP_NULL; else if (lines [i].type & VERT_LN) pSeps [j].Type = SEP_VERT; else if (lines [i].type & HOR_LN) pSeps [j].Type = SEP_HORZ; else pSeps [j].Type = SEP_NULL; pSeps [j].uFlags = lines [i].type & FRM_LN ? SEPF_IS_PART : SEPF_NULL; pSeps [j].xBegin = lines [i].beg.col; pSeps [j].yBegin = lines [i].beg.row; pSeps [j].xEnd = lines [i].end.col; pSeps [j].yEnd = lines [i].end.row; pSeps [j].nWidth = lines [i].width; } q_sort ((char *)pSeps, nSeps, sizeof (SEPARATOR), SepComp); //AK 04.03.97 }
void RootsSaveNonLayoutData(void) { if (pRootExts != NULL) ErrorInternal((char *) "RootsSaveNonLayoutData: pRootExts != NULL"); nRootExts = cf::Roots::count(); pRootExts = (ROOT_EXT*) malloc(nRootExts * sizeof(ROOT_EXT)); if (pRootExts == NULL) ErrorNoEnoughMemory("in LTROOTS.C,RootStripsCalculate,part 2"); pAfterRootExts = pRootExts + nRootExts; for (int i = 0; i < nRootExts; i++) { pRootExts[i].wSegmentPtr = cf::Roots::at(i)->u1.u2.wSegmentPtr; pRootExts[i].wLength = cf::Roots::at(i)->u1.u2.wLength; } }
Bool RootsLoadFile (char * pFilename) { /* typedef int HANDLE;*/ HANDLE hFile; ROOT RootRecord; RootsFreeData (); hFile = (HANDLE)open (pFilename, O_RDONLY | O_BINARY); if (hFile == (HANDLE)(-1)) { ErrorFile (); return (FALSE); } while (read (hFile, &RootRecord, sizeof (ROOT)) == sizeof (ROOT)) { RootRecord.bReached = FALSE; if (nRoots % ROOTS_MEMORY_QUANTUM == 0) { pRoots = realloc (pRoots, (size_t) ((nRoots / ROOTS_MEMORY_QUANTUM + 1) * ROOTS_MEMORY_QUANTUM * sizeof (ROOT))); } nRoots++; if (pRoots == NULL) { ErrorNoEnoughMemory ("in LTROOTS.C,RootsLoadFile,part 1"); nRoots = 0; close (hFile); return (FALSE); } pRoots [nRoots - 1] = RootRecord; } close (hFile); return (TRUE); }
void RootsSaveNonLayoutData (void) { int i; if (pRootExts != NULL) ErrorInternal ("RootsSaveNonLayoutData: pRootExts != NULL"); nRootExts = nRoots; pRootExts = (PROOT_EXT) malloc (nRootExts * sizeof (ROOT_EXT)); if (pRootExts == NULL) ErrorNoEnoughMemory ("in LTROOTS.C,RootStripsCalculate,part 2"); pAfterRootExts = pRootExts + nRootExts; for (i = 0; i < nRootExts; i++) { pRootExts [i].wSegmentPtr = pRoots [i].u1.u2.wSegmentPtr; pRootExts [i].wLength = pRoots [i].u1.u2.wLength; } }
void RootStripsCalculate (void) { ROOT *pRoot; int yMin, yMax; int iStrip; int iStripBegin; int iStripEnd; if (nRoots == 0) ErrorInternal ((char *)"nRoots == 0"); yMin = pRoots [0].yRow; yMax = pRoots [0].yRow + pRoots [0].nHeight - 1; for (pRoot = pRoots; pRoot < pAfterRoots; pRoot++) { if (pRoot -> yRow < yMin) yMin = pRoot -> yRow; if (pRoot -> yRow + pRoot -> nHeight - 1 > yMax) yMax = pRoot -> yRow + pRoot -> nHeight - 1; } nRootStripsOffset = yMin; nRootStripsStep = 128; nRootStrips = (yMax - yMin + (nRootStripsStep - 1)) / nRootStripsStep + 1; if(pRootStrips)// Piter { free(pRootStrips);// Piter pRootStrips=NULL;// Piter }// Piter pRootStrips =(ROOT_STRIP*) malloc (nRootStrips * sizeof (ROOT_STRIP)); if (pRootStrips==NULL) ErrorNoEnoughMemory ("in LTROOTS.C,RootStripsCalculate,part 1"); memset (pRootStrips, 0, nRootStrips * sizeof (ROOT_STRIP)); for (pRoot = pRoots; pRoot < pAfterRoots; pRoot++) { iStripBegin = (pRoot -> yRow - nRootStripsOffset) / nRootStripsStep; iStripEnd = (pRoot -> yRow + pRoot -> nHeight - 1 - nRootStripsOffset) / nRootStripsStep; _ASSERT(nRootStrips>iStripEnd); // Piter _ASSERT(nRootStrips>iStripBegin);// Piter for (iStrip = iStripBegin; iStrip <= iStripEnd; iStrip++) { if (pRootStrips [iStrip].pBegin == NULL || pRoot < pRootStrips [iStrip].pBegin) { pRootStrips [iStrip].pBegin = pRoot; } if (pRootStrips [iStrip].pEnd == NULL || pRoot > pRootStrips [iStrip].pEnd) { pRootStrips [iStrip].pEnd = pRoot; } } } }
// результат имеет максимумы в серединах линий, минимумы // (~нули!) -- между линиями (~строками). void BlockHorzHystogramBuild (BLOCK *p) { int *pHystogram; int nHystColumns; // длина гистограммы ROOT *pRoot; int iTopColumn, iBottomColumn; // assert(botom>top) int iColumn; int nSum; nHystColumns = p -> Rect.yBottom - p -> Rect.yTop + 1; pHystogram = malloc ((nHystColumns + 1) * sizeof (int)); if (pHystogram == NULL) ErrorNoEnoughMemory ("in LTBREAK.C,BlockHorzHystogramBuild,part 1"); memset (pHystogram, 0, (nHystColumns + 1) * sizeof (int)); for (pRoot = p -> pRoots; pRoot != NULL; pRoot = pRoot -> u1.pNext) { // пыль не учитываем if (IS_LAYOUT_DUST (* pRoot)) continue; // относительное начало текущего рута (по у) iTopColumn = (pRoot -> yRow - p -> Rect.yTop); // относительное окончание текущего рута (по высоте же) iBottomColumn = (pRoot -> yRow + pRoot -> nHeight - 1 - p -> Rect.yTop); pHystogram [iTopColumn] ++; pHystogram [iBottomColumn + 1] --; // то есть вокруг "боттом-линии" будет отрицательный пик, // вокруг "топ-линии" -- положительный, // а близкие топ- и боттом- линии взаимоуничтожаются } nSum = 0; // "интегрирование" ("dx==1") исходной гистограммы: // получаем, естественно, экстремумы в бывших нулях; // точнее -- максимумы в серединах линий, минимумы // (~нули!) -- между линиями for (iColumn = 0; iColumn < nHystColumns; iColumn++) { nSum += pHystogram [iColumn]; pHystogram [iColumn] = nSum; } p -> nActualHeight = 0; for (iColumn = 0; iColumn < nHystColumns; iColumn++) { if (pHystogram [iColumn] != 0) p -> nActualHeight++; // ~количество реальных ординат // (высот) } if (p -> pHorzHystogram != NULL) { free (p -> pHorzHystogram); p -> pHorzHystogram = NULL; } p -> pHorzHystogram = pHystogram; }
Bool HystogramAllocateBody(void) { BLOCK *p; int nBlockWidth; int nBlockHeight; int nMaxValue; HystogramFreeData(); nMaxValue = 0; for (p = pBlocksList; p != NULL; p = p -> pNext) { nBlockWidth = p -> Rect.xRight - p -> Rect.xLeft + 1; nBlockHeight = p -> Rect.yBottom - p -> Rect.yTop + 1; if (nBlockWidth > nMaxValue) nMaxValue = nBlockWidth; if (nBlockHeight > nMaxValue) nMaxValue = nBlockHeight; } if (nMaxValue == 0) return (FALSE); nMaxValue++; pHystogram = static_cast<int*> (malloc((nMaxValue + 1) * sizeof(int))); //Andrey 05.03.2003: +1 т.к. в дальнейшем будет использоваться именно до такого значения if (pHystogram == NULL) ErrorNoEnoughMemory("in LTHYST.C,HystogramAllocateBody,part 1"); if (bOptionPointSizeAnalysis) { pHystVertHeightesSum = static_cast<int*> (malloc(nMaxValue * sizeof(int))); if (pHystVertHeightesSum == NULL) ErrorNoEnoughMemory("in LTHYST.C,HystogramAllocateBody,part 2"); pHystHorzHeightesSum = static_cast<int*> (malloc(nMaxValue * sizeof(int))); if (pHystHorzHeightesSum == NULL) ErrorNoEnoughMemory("in LTHYST.C,HystogramAllocateBody,part 3"); pHystInt1 = static_cast<int*> (malloc(nMaxValue * sizeof(int))); if (pHystInt1 == NULL) ErrorNoEnoughMemory("in LTHYST.C,HystogramAllocateBody,part 4"); pHystInt2 = static_cast<int*> (malloc(nMaxValue * sizeof(int))); if (pHystInt2 == NULL) ErrorNoEnoughMemory("in LTHYST.C,HystogramAllocateBody,part 5"); } if (bOptionSpecialHorizontalCutting) { pHystTops = static_cast<int*> (malloc(nMaxValue * sizeof(int))); if (pHystTops == NULL) ErrorNoEnoughMemory("in LTHYST.C,HystogramAllocateBody,part 6"); pHystBottoms = static_cast<int*> (malloc(nMaxValue * sizeof(int))); if (pHystBottoms == NULL) ErrorNoEnoughMemory("in LTHYST.C,HystogramAllocateBody,part 7"); } return (TRUE); }
Bool AddRoot(CCOM_comp * comp, Bool32 FirstTime) { ROOT RootRecord = {0}; int h=comp->h; int w=comp->w; _ASSERT(comp); //***************Rom******************** if ( (h/w > 20) || (w/h > 20)) return FALSE;// Piter //************************************** //***************Rom******************** if ( h*w < 6 ) return FALSE;// Piter //************************************** RootRecord.bReached = FALSE; RootRecord.pComp = comp; RootRecord.yRow = comp->upper; RootRecord.xColumn = comp->left; RootRecord.u1.pNext = NULL; RootRecord.nHeight = h; RootRecord.nWidth = w; RootRecord.nBlock = 0; RootRecord.nUserNum = 0; RootRecord.bType = ROOT_DUST|ROOT_RECOGNIZED ; if(comp->type & CCOM_CH_LETTER) RootRecord.bType = ROOT_DUST | ROOT_LETTER | ROOT_RECOGNIZED; if(comp->type & (CCOM_CH_DUST | CCOM_CH_PUNCT )) RootRecord.bType = ROOT_DUST; if(comp->type & CCOM_CH_DUST && (comp->w+7)/8*comp->h<2 ) RootRecord.bType = 0 ; if(comp->type & CCOM_CH_GREAT ) RootRecord.bType = 0; if (nRoots % ROOTS_QUANTUM == 0 && FirstTime) { pRoots =(ROOT*) realloc (pRoots, (size_t) ((nRoots / ROOTS_QUANTUM + 10) * ROOTS_QUANTUM * sizeof (ROOT))); } nRoots++; if (pRoots == NULL) { ErrorNoEnoughMemory ((uchar*)"in LTROOTS.C, AddRoot"); nRoots = 0; return FALSE; } pRoots [nRoots - 1] = RootRecord; if(nRoots>1&&FirstTime) pRoots [nRoots - 2].u1.pNext = pRoots + nRoots - 1; return TRUE; }
void RootStripsCalculate (void) { ROOT *pRoot; int yMin, yMax; // впоследствии -- это ординаты начала // и конца массива проекций всех рутов (на вертикаль) int iStrip; int iStripBegin; int iStripEnd; if (nRoots == 0) ErrorInternal ("nRoots == 0"); // вычисление минимальной и максимальной ординаты // коробок символов ("рутов"). yMin = pRoots [0].yRow; yMax = pRoots [0].yRow + pRoots [0].nHeight - 1; for (pRoot = pRoots; pRoot < pAfterRoots; pRoot++) { if (pRoot -> yRow < yMin) yMin = pRoot -> yRow; if (pRoot -> yRow + pRoot -> nHeight - 1 > yMax) yMax = pRoot -> yRow + pRoot -> nHeight - 1; } nRootStripsOffset = yMin; nRootStripsStep = 128; nRootStrips = (yMax - yMin + (nRootStripsStep - 1)) / nRootStripsStep + 1; // то есть nRootStrips -- это ближайшее сверху // к (yMax - yMin) кратное 128; например, при совпадении // yMax и yMin это просто 128 и есть if(pRootStrips)// Piter { free(pRootStrips);// Piter pRootStrips=NULL;// Piter }// Piter pRootStrips = malloc (nRootStrips * sizeof (ROOT_STRIP)); if (pRootStrips==NULL) ErrorNoEnoughMemory ("in LTROOTS.C,RootStripsCalculate,part 1"); memset (pRootStrips, 0, nRootStrips * sizeof (ROOT_STRIP)); for (pRoot = pRoots; pRoot < pAfterRoots; pRoot++) { iStripBegin = (pRoot -> yRow - nRootStripsOffset) / nRootStripsStep; iStripEnd = (pRoot -> yRow + pRoot -> nHeight - 1 - nRootStripsOffset) / nRootStripsStep; _ASSERT(nRootStrips>iStripEnd); // Piter _ASSERT(nRootStrips>iStripBegin);// Piter for (iStrip = iStripBegin; iStrip <= iStripEnd; iStrip++) { if (pRootStrips [iStrip].pBegin == NULL || pRoot < pRootStrips [iStrip].pBegin) { pRootStrips [iStrip].pBegin = pRoot; } if (pRootStrips [iStrip].pEnd == NULL || pRoot > pRootStrips [iStrip].pEnd) { pRootStrips [iStrip].pEnd = pRoot; } } } }