void DebugFree(void * blk) { Memory * Block; if(lout_memory==NULL) ErrorInternal("Free:Кучи еще нет!"); if(blk==NULL) ErrorInternal("Попытка освободить память до ее размещения !"); if((Block=FindMem(blk))==NULL) { //ErrorInternal("Освобождаемая память не найдена !"); return; } //освобождение блока Block->id=MEMFREE; SizeFree+=Block->size; #ifdef DebugFile if(FileError){ fprintf(FileError,"\nFree \t= %8li\tRunning \t= %li\tAll %li", (long)Block->size, SizeAllocate-SizeFree, SizeMemory); } #endif }
void RootStripsGetLoopParameters(int yTop, int yBottom, ROOT **ppBegin, ROOT **ppAfter) { int iStripBegin; int iStripEnd; ROOT *pBegin; ROOT *pEnd; int iStrip; if (nRootStripsStep == 0) ErrorInternal((char *) "nRootStripsStep == 0"); iStripBegin = (yTop - nRootStripsOffset) / nRootStripsStep; iStripEnd = (yBottom - nRootStripsOffset) / nRootStripsStep; if (iStripBegin < 0) iStripBegin = 0; if (iStripEnd < 0) iStripEnd = 0; if (iStripBegin >= nRootStrips) iStripBegin = nRootStrips - 1; if (iStripEnd >= nRootStrips) iStripEnd = nRootStrips - 1; if (iStripBegin > iStripEnd) EXCHANGE_INTS(iStripBegin, iStripEnd); pBegin = NULL; pEnd = NULL; for (iStrip = iStripBegin; iStrip <= iStripEnd; iStrip++) { if (pRootStrips[iStrip].pBegin == NULL) continue; if (pBegin == NULL) { pBegin = pRootStrips[iStrip].pBegin; pEnd = pRootStrips[iStrip].pEnd; } else { if (pRootStrips[iStrip].pBegin < pBegin) pBegin = pRootStrips[iStrip].pBegin; if (pRootStrips[iStrip].pEnd > pEnd) pEnd = pRootStrips[iStrip].pEnd; } } if ((pBegin == NULL) != (pEnd == NULL)) ErrorInternal((char *) "(pBegin == NULL) != (pEnd == NULL)"); if (pBegin == NULL) { *ppBegin = NULL; *ppAfter = NULL; } else { *ppBegin = pBegin; *ppAfter = pEnd + 1; } }
void ConsumeOpcodeBytes(struct NCDecoderState* mstate) { uint8_t opcode = *mstate->nextbyte; mstate->opinfo = &kDecode1ByteOp[opcode]; DEBUG( printf("NACLi_1BYTE: opcode = %02x, ", opcode); PrintOpInfo(mstate->opinfo) ); mstate->nextbyte += 1; if (opcode == kTwoByteOpcodeByte1) { uint8_t opcode2 = *mstate->nextbyte; mstate->opinfo = GetExtendedOpInfo(mstate, opcode2); DEBUG( printf("NACLi_2BYTE: opcode2 = %02x, ", opcode2); PrintOpInfo(mstate->opinfo) ); mstate->inst.hasopbyte2 = 1; mstate->nextbyte += 1; if (mstate->opinfo->insttype == NACLi_3BYTE) { uint8_t opcode3 = *mstate->nextbyte; uint32_t pm; pm = mstate->inst.prefixmask; mstate->nextbyte += 1; mstate->inst.hasopbyte3 = 1; DEBUG( printf("NACLi_3BYTE: opcode3 = %02x, ", opcode3) ); switch (opcode2) { case 0x38: /* SSSE3, SSE4 */ if (pm & kPrefixDATA16) { mstate->opinfo = &kDecode660F38Op[opcode3]; } else if (pm & kPrefixREPNE) { mstate->opinfo = &kDecodeF20F38Op[opcode3]; } else if (pm == 0) { mstate->opinfo = &kDecode0F38Op[opcode3]; } else { /* Other prefixes like F3 cause an undefined instruction error. */ /* Note from decoder table that NACLi_3BYTE is only used with */ /* data16 and repne prefixes. */ ErrorInternal(mstate->vstate); } break; case 0x3A: /* SSSE3, SSE4 */ if (pm & kPrefixDATA16) { mstate->opinfo = &kDecode660F3AOp[opcode3]; } else if (pm == 0) { mstate->opinfo = &kDecode0F3AOp[opcode3]; } else { /* Other prefixes like F3 cause an undefined instruction error. */ /* Note from decoder table that NACLi_3BYTE is only used with */ /* data16 and repne prefixes. */ ErrorInternal(mstate->vstate); } break; default: /* if this happens there is a decoding table bug */ ErrorInternal(mstate->vstate); break; } DEBUG( PrintOpInfo(mstate->opinfo) ); } }
void * DebugRealloc(void * old_blk,size_t size) { void * new_blk; Memory * Block; if(lout_memory==NULL) ErrorInternal("Realloc:Кучи еще нет!"); if(size == 0) return NULL; if(old_blk==NULL){ new_blk=DebugMalloc(size); return new_blk; } if((Block=FindMem(old_blk))==NULL) ErrorInternal("\nИсходный буфер для REALLOC не найден!"); if(Block->size <= size + sizeof(Memory)){ // требуется блок больших размеров new_blk=DebugMalloc(size); if(new_blk!=NULL && old_blk!=NULL) memcpy(new_blk,old_blk,(Block->size<=size ? Block->size:size)); if(old_blk!=NULL) DebugFree(old_blk); } else { // требуется блок меньших размеров Memory * NewBlock = (Memory *)((char *)Block + size + sizeof(Memory)); NewBlock->id = MEMFREE; NewBlock->size= Block->size-(size+sizeof(Memory)); SizeFree += NewBlock->size; Block->size = size; new_blk = old_blk; #ifdef DebugFile if(FileError){ fprintf(FileError,"\nRealloc \t= %8li\tRunning \t= %li\tAll %li", (long)Block->size, SizeAllocate-SizeFree, SizeMemory); } #endif } return new_blk; }
static void JoinEmptyBlocks() { Memory * Block; Memory * NextBlock; if (lout_memory == NULL) ErrorInternal("Malloc:Кучи еще нет!"); // Укрупнение пустых блоков for (Block = (Memory *) lout_memory; Block->id != MEMEND; Block = (Memory *) ((char *) Block + Block->size + sizeof(Memory))) { NextBlock = (Memory *) ((char *) Block + Block->size + sizeof(Memory)); toNextBlock: if (Block->id == MEMFREE && (NextBlock->id == MEMFREE || NextBlock->id == MEMEND)) { Block->id = NextBlock->id; Block->size += NextBlock->size + sizeof(Memory); if (Block->id == MEMEND) { SizeMemory = (long) ((char *) Block - lout_memory); break; } NextBlock = (Memory *) ((char *) NextBlock + NextBlock->size +sizeof(Memory)); goto toNextBlock; } } }
long GetMaxSizeFreeMem() { int idblock; long sizeblock; long MaxSizeBlock; Memory * Block; if(lout_memory==NULL) ErrorInternal("Malloc:Кучи еще нет!"); JoinEmptyBlocks(); MaxSizeBlock = 0L; // поиск свободного места for(Block =(Memory *)lout_memory;(char *)Block<(lout_memory+SizeBuffer); Block=(Memory *)((char *)Block+sizeof(Memory)+Block->size)) { idblock = Block->id; sizeblock = Block->size; if((idblock==MEMEND || idblock==MEMFREE) && sizeblock>MaxSizeBlock) MaxSizeBlock = sizeblock; }// for ... return MaxSizeBlock; }
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 RootsRestoreNonLayoutData_ForDustAndRemoved(void) { if (pRootExts == NULL) ErrorInternal((char *) "RootsRestoreNonLayoutData: pRootExts == NULL"); for (int i = 0; i < nRootExts; i++) { if (cf::Roots::at(i)->nBlock == DUST_BLOCK_NUMBER || cf::Roots::at(i)->nBlock == REMOVED_BLOCK_NUMBER) { cf::Roots::at(i)->u1.u2.wSegmentPtr = pRootExts[i].wSegmentPtr; cf::Roots::at(i)->u1.u2.wLength = pRootExts[i].wLength; } } }
static void GetX87OpInfo(struct NCDecoderState* mstate) { /* WAIT is an x87 instruction but not in the coproc opcode space. */ const uint8_t kWAITOp = 0x9b; uint8_t kFirstX87Opcode = 0xd8; uint8_t kLastX87Opcode = 0xdf; uint8_t op1 = mstate->inst.maddr[mstate->inst.prefixbytes]; if (op1 < kFirstX87Opcode || op1 > kLastX87Opcode) { if (op1 != kWAITOp) ErrorInternal(mstate->vstate); return; } mstate->opinfo = &kDecodeX87Op[op1 - kFirstX87Opcode][mstate->inst.mrm]; DEBUG( printf("NACL_X87 op1 = %02x, ", op1); PrintOpInfo(mstate->opinfo) ); }
void RootsRestoreNonLayoutData(void) { if (pRootExts == NULL) ErrorInternal((char *) "RootsRestoreNonLayoutData: pRootExts == NULL"); for (int i = 0; i < nRootExts; i++) { cf::Roots::at(i)->u1.u2.wSegmentPtr = pRootExts[i].wSegmentPtr; cf::Roots::at(i)->u1.u2.wLength = pRootExts[i].wLength; } free(pRootExts); pRootExts = NULL; pAfterRootExts = NULL; nRootExts = 0; }
static const struct OpInfo *GetExtendedOpInfo(struct NCDecoderState* mstate, uint8_t opbyte2) { uint32_t pm; pm = mstate->inst.prefixmask; if ((pm & (kPrefixDATA16 | kPrefixREPNE | kPrefixREP)) == 0) { return &kDecode0FXXOp[opbyte2]; } else if (pm & kPrefixDATA16) { return &kDecode660FXXOp[opbyte2]; } else if (pm & kPrefixREPNE) { return &kDecodeF20FXXOp[opbyte2]; } else if (pm & kPrefixREP) { return &kDecodeF30FXXOp[opbyte2]; } ErrorInternal(mstate->vstate); return mstate->opinfo; }
void RootsRestoreNonLayoutData_ForBlock (BLOCK *p) { ROOT *pRoot, *pNext; if (pRootExts == NULL) ErrorInternal ("RootsRestoreNonLayoutData: pRootExts == NULL"); if (p -> pRoots == NULL) return; for (pRoot = p -> pRoots; pRoot != NULL; pRoot = pNext) { pNext = pRoot -> u1.pNext; pRoot -> u1.u2.wSegmentPtr = pRootExts [pRoot - pRoots].wSegmentPtr; pRoot -> u1.u2.wLength = pRootExts [pRoot - pRoots].wLength; } }
void RootsRestoreNonLayoutData_ForDustAndRemoved (void) { int i; if (pRootExts == NULL) ErrorInternal ("RootsRestoreNonLayoutData: pRootExts == NULL"); for (i = 0; i < nRootExts; i++) { if (pRoots [i].nBlock == DUST_BLOCK_NUMBER || pRoots [i].nBlock == REMOVED_BLOCK_NUMBER) { pRoots [i].u1.u2.wSegmentPtr = pRootExts [i].wSegmentPtr; pRoots [i].u1.u2.wLength = pRootExts [i].wLength; } } }
// поиск уже размещенного блока Memory * FindMem(void * blk) { Memory * Block; for (Block = (Memory *) lout_memory; Block->id != MEMEND; Block = (Memory *) ((char *) Block + Block->size + sizeof(Memory))) { #ifdef DebugFile if((char *)Block>(lout_memory+SizeBuffer)) ErrorInternal("\nСбой памяти при поиске блока..."); #endif if (blk == ((char *) Block + sizeof(Memory))) { #ifdef DebugFile if(Block->id==MEMFREE) fprintf(FileError,"\nНайден освобожденный блок..."); #endif return Block; } // if(blk... }// for(... return NULL; }
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; } }
void RootsRestoreNonLayoutData (void) { int i; if (pRootExts == NULL) ErrorInternal ("RootsRestoreNonLayoutData: pRootExts == NULL"); for (i = 0; i < nRootExts; i++) { pRoots [i].u1.u2.wSegmentPtr = pRootExts [i].wSegmentPtr; pRoots [i].u1.u2.wLength = pRootExts [i].wLength; } free (pRootExts); pRootExts = NULL; pAfterRootExts = NULL; nRootExts = 0; }
void BlocksHystogramsBuild(void) { ROOT *pRoot; BLOCK *pBlock; int iBegin; int iEnd; int i; BlocksHystogramsAllocate(); for (pRoot = pRoots; pRoot < pAfterRoots; pRoot++) { if (pRoot -> nBlock == REMOVED_BLOCK_NUMBER) continue; # ifdef SE_DEBUG if (pRoot -> nBlock > nBlocks) ErrorInternal ("Bad number of blocks"); # endif //if (IS_LAYOUT_DUST (*pRoot) || pRoot -> nHeight <= 4) //if (IS_LAYOUT_DUST (*pRoot)&& pRoot->nUserNum!=IS_IN_TABLE) if (pRoot->isLayoutDust()) continue; pBlock = pBlockPointer[pRoot -> nBlock]; if (pBlock == NULL) continue; iBegin = pRoot -> yRow - pBlock -> Rect.yTop; iEnd = (pRoot -> yRow + pRoot -> nHeight - 1) - pBlock -> Rect.yTop; if (iBegin < 0) iBegin = 0; if (iEnd >= pBlock->nHystColumns) iEnd = pBlock->nHystColumns - 1; for (i = iBegin; i <= iEnd; i++) pBlock -> pHystogram[i] += pRoot -> nWidth; } }
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 StringsForming (void) { # ifdef SE_DEBUG if (pCurrentBlock -> pHystogram == NULL || pCurrentBlock -> nHystColumns == 0) { ErrorInternal ("Empty hystogram"); } # endif StringPrepare (); StringsFill (); //RootsRestoreNonLayoutData_ForBlock (pCurrentBlock); if (bOptionBusinessCardsLayout) { StringFree (); StringsBreakOnVertical (); StringPrepare (); # ifdef SE_DEBUG if (SE_DebugGraphicsLevel >= 1) LT_GraphicsStringsOutput ("After breaking on vertical"); # endif } # ifdef SE_DEBUG if (SE_DebugGraphicsLevel >= 2) LT_GraphicsStringsOutput ("Before edit"); # endif StringsListEdit (); # ifdef SE_DEBUG if (SE_DebugGraphicsLevel >= 2) LT_GraphicsStringsOutput ("After edit"); # endif StringsProcessSpecials (); # ifdef SE_DEBUG if (SE_DebugGraphicsLevel >= 2) LT_GraphicsStringsOutput ("After processing specials"); # endif StringsDustAccount (); # ifdef SE_DEBUG if (SE_DebugGraphicsLevel >= 1) LT_GraphicsStringsOutput ("After dust accounting"); # endif StringFree (); if (! bOptionBusinessCardsLayout) { StringsBreakOnVertical (); # ifdef SE_DEBUG if (SE_DebugGraphicsLevel >= 1) LT_GraphicsStringsOutput ("After breaking on vertical"); # endif } StringsRemoveTrash (); # ifdef SE_DEBUG if (SE_DebugGraphicsLevel >= 1) LT_GraphicsStringsOutput ("After removing trash strings"); if (SE_DebugGraphicsLevel >= 3) { LT_GraphicsStringsForwardOrderOutput ("Forward strings order"); LT_GraphicsStringsBackwardOrderOutput ("Backward strings order"); LT_GraphicsStringsUpOrderOutput ("Up strings order"); LT_GraphicsStringsDownOrderOutput ("Down strings order"); } # endif StringsUpdatedByBukvica(); StringsListOutput (); }
Bool TryCutBlockOnHorizontal (BLOCK *p) { int iColumn; int iZeroEnd; Bool bNotSpace; int iBestPointSizeBreakingColumn; int nPointSizeDifference; int nBestPointSizeDifference = 0; /* To avoid warning on MPW C/C++ */ BLOCK *q, *r; # ifdef LT_DEBUG if (p -> pHorzHystogram == NULL) ErrorInternal ("pHorzHystogram not builded in TryCutBlockOnHorizontal"); # endif nHystColumnWidth = 1; nHystColumns = p -> Rect.yBottom - p -> Rect.yTop + 1; memcpy (pHystogram, p -> pHorzHystogram, nHystColumns * sizeof (int)); # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 4) if(!LDPUMA_Skip(hBlocksBreaking)) LT_GraphicsHystogramOutput ("Hystogram for horizontal breaking"); # endif bNotSpace = FALSE; for (iColumn = 0; iColumn < nHystColumns; iColumn++) { if (pHystogram [iColumn] != 0) { bNotSpace = TRUE; continue; } if (! bNotSpace) continue; for (iZeroEnd = iColumn + 1; iZeroEnd < nHystColumns && pHystogram [iZeroEnd] == 0; iZeroEnd++) { } if (iZeroEnd == nHystColumns) break; if (HorizontalBreakingCondition (p, iColumn, iZeroEnd - 1) && BlockBreakOnHorizontal (p, NULL, NULL, iColumn + p -> Rect.yTop)) { return (TRUE); } iColumn = iZeroEnd; } /* * Analysis with font accounting */ if (! bOptionPointSizeAnalysis) return (FALSE); BlockBuild_HystHorzHeightesSum (p); HystogramMakeIntegral (pHystInt1, pHystogram, nHystColumns); HystogramMakeIntegral (pHystInt2, pHystHorzHeightesSum, nHystColumns); iBestPointSizeBreakingColumn = 0; for (iColumn = 0; iColumn < nHystColumns; iColumn++) { int nAverageHeightBefore; int nAverageHeightAfter; if (pHystogram [iColumn] != 0) continue; if (pHystInt1 [iColumn] == 0 || pHystInt1 [nHystColumns - 1] - pHystInt1 [iColumn] <= 20) { continue; } nAverageHeightBefore = pHystInt2 [iColumn] / pHystInt1 [iColumn]; nAverageHeightAfter = (pHystInt2 [nHystColumns - 1] - pHystInt2 [iColumn]) / (pHystInt1 [nHystColumns - 1] - pHystInt1 [iColumn]); if (nAverageHeightBefore == 0 || nAverageHeightAfter == 0) continue; if (! ((nAverageHeightBefore-1)*2 >= nAverageHeightAfter * ZagolovokBreakingCoeff || (nAverageHeightAfter-1)*2 >= nAverageHeightBefore * ZagolovokBreakingCoeff)) { continue; } nPointSizeDifference = MAX (nAverageHeightBefore * 1000 / nAverageHeightAfter, nAverageHeightAfter * 1000 / nAverageHeightBefore); if (iBestPointSizeBreakingColumn == 0 || nPointSizeDifference > nBestPointSizeDifference) { iBestPointSizeBreakingColumn = iColumn; nBestPointSizeDifference = nPointSizeDifference; } } iColumn = iBestPointSizeBreakingColumn; if (pHystInt1 [nHystColumns - 1] - pHystInt1 [iColumn] > 0 && iColumn <= (pHystInt2 [nHystColumns - 1] - pHystInt2 [iColumn]) / (pHystInt1 [nHystColumns - 1] - pHystInt1 [iColumn]) / 2) { /* Strange case: its possibly dots above letters */ return (FALSE); } if (BlockBreakOnHorizontal (p, &q, &r, iBestPointSizeBreakingColumn + p -> Rect.yTop)) { # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 3) if(!LDPUMA_Skip(hBlocksBreaking)) { pDebugBlock = q; LT_GraphicsBlockOutput2 ("Block was breaked using " "Horz PointSizeAnalysis"); pDebugBlock = r; LT_GraphicsBlockOutput2 ("Block was breaked using " "Horz PointSizeAnalysis"); LT_Getch (); LT_GraphicsClearScreen (); } # endif return (TRUE); } return (FALSE); }
Bool TryCutBlockOnVertical (BLOCK *p, int bcr_cut, Bool32 SecondStage) { ROOT *pRoot; int iLeftColumn, iRightColumn; int iColumn; int nMaximum; int nLowLevel; int nSpaceWidth; int iSpace; int nHystSum; Bool bNotSpace; int iLeftLimit; int iRightLimit; int iBestPointSizeBreakingColumn; int nPointSizeDifference; int nBestPointSizeDifference = 0; /* To avoid warning on MPW C/C++ */ int nSum; int nAverage; int nColumns; BLOCK *q, *r; # ifdef LT_DEBUG if (p -> pHorzHystogram == NULL) ErrorInternal ("pHorzHystogram not builded in TryCutBlockOnVertical"); # endif nHystColumnWidth = p -> nStartColumnWidth; while (nHystColumnWidth >= p -> nConditionalMinColumnWidth) { /* Build vertical hystogram */ nHystColumns = (p -> Rect.xRight - p -> Rect.xLeft + 1) / nHystColumnWidth + 1; //memset (pHystogram, 0, nHystColumns * sizeof (int)); memset (pHystogram, 0, (nHystColumns + 1) * sizeof (int));// Piter 08.07.99 for (pRoot = p -> pRoots; pRoot != NULL; pRoot = pRoot -> u1.pNext) { iLeftColumn = (pRoot -> xColumn - p -> Rect.xLeft) / nHystColumnWidth; iRightColumn = (pRoot -> xColumn + pRoot -> nWidth - 1 - p -> Rect.xLeft) / nHystColumnWidth; pHystogram [iLeftColumn] ++; pHystogram [iRightColumn + 1] --; } nMaximum = 0; nHystSum = 0; for (iColumn = 0; iColumn < nHystColumns; iColumn++) { nHystSum += pHystogram [iColumn]; pHystogram [iColumn] = nHystSum; if (pHystogram [iColumn] > nMaximum) nMaximum = pHystogram [iColumn]; } nLowLevel = VERT_HYST_LOW_LEVEL (nMaximum); /* Rom */ if (SecondStage) { nSum = 0; for (iColumn = 0; iColumn < nHystColumns; iColumn++) { nSum += pHystogram [iColumn]; } if(nHystColumns!= 0) { nAverage = nSum/nHystColumns; } nSum = 0; nColumns = 0; for (iColumn = 0; iColumn < nHystColumns; iColumn++) { if(pHystogram [iColumn] > nAverage) { nSum += pHystogram [iColumn]; nColumns++; } } if(nColumns!= 0) { nAverage = nSum/nColumns; } for (iColumn = 0; iColumn < nHystColumns; iColumn++) { if(pHystogram [iColumn] < nAverage / 10) { pHystogram [iColumn] = 0; } } } /* Rom */ # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 4) if(!LDPUMA_Skip(hBlocksBreaking)) { pDebugBlock = p; // Piter 02-10-98 LT_GraphicsHystogramOutput ("Hystogram for vertical breaking"); } # endif bNotSpace = FALSE; for (iColumn = 0; iColumn < nHystColumns; iColumn++) { if (pHystogram [iColumn] == 0) { if (! bNotSpace) continue; if (nHystColumnWidth < p -> nUnconditionalMinColumnWidth && ! CorrectCondition (iColumn)) { continue; } nSpaceWidth = 0; for (iSpace = iColumn; iSpace < nHystColumns && pHystogram [iSpace] == 0; iSpace++) { nSpaceWidth += nHystColumnWidth; } if (iSpace == nHystColumns) break; if (BlockBreakOnVertical (p, NULL, NULL, iColumn * nHystColumnWidth + p -> Rect.xLeft, nSpaceWidth)) { return (TRUE); } iColumn += nSpaceWidth; } else { bNotSpace = TRUE; } } for (iColumn = 0; iColumn < nHystColumns; iColumn++) { if (pHystogram [iColumn] < nLowLevel) { nHystColumnWidth /= 2; break; } } if (iColumn == nHystColumns) break; } /* * Analysis with font accounting */ if (! (bOptionPointSizeAnalysis && bOptionBusinessCardsLayout)) return (FALSE); if (!bcr_cut) return (FALSE); // 940228 /* Build vertical hystogram */ if (nHystColumnWidth != 1) { nHystColumns = p -> Rect.xRight - p -> Rect.xLeft + 1; memset (pHystogram, 0, nHystColumns * sizeof (int)); for (pRoot = p -> pRoots; pRoot != NULL; pRoot = pRoot -> u1.pNext) { iLeftColumn = pRoot -> xColumn - p -> Rect.xLeft; iRightColumn = pRoot -> xColumn + pRoot -> nWidth - 1 - p -> Rect.xLeft; pHystogram [iLeftColumn] ++; pHystogram [iRightColumn + 1] --; } nHystSum = 0; for (iColumn = 0; iColumn < nHystColumns; iColumn++) { nHystSum += pHystogram [iColumn]; pHystogram [iColumn] = nHystSum; } } BlockBuild_HystVertHeightesSum (p); HystogramMakeIntegral (pHystInt1, pHystogram, nHystColumns); HystogramMakeIntegral (pHystInt2, pHystVertHeightesSum, nHystColumns); iLeftLimit = nHystColumns / 10; iRightLimit = nHystColumns - nHystColumns / 10; iBestPointSizeBreakingColumn = 0; for (iColumn = iLeftLimit; iColumn < iRightLimit; iColumn++) { int nAverageHeightBefore; int nAverageHeightAfter; if (pHystogram [iColumn] != 0) continue; if (pHystInt1 [iColumn] == 0 || pHystInt1 [nHystColumns - 1] - pHystInt1 [iColumn] == 0) { continue; } nAverageHeightBefore = pHystInt2 [iColumn] / pHystInt1 [iColumn]; nAverageHeightAfter = (pHystInt2 [nHystColumns - 1] - pHystInt2 [iColumn]) / (pHystInt1 [nHystColumns - 1] - pHystInt1 [iColumn]); if (nAverageHeightBefore == 0 || nAverageHeightAfter == 0) continue; if (! (nAverageHeightBefore >= nAverageHeightAfter * 2 || nAverageHeightAfter >= nAverageHeightBefore * 3)) { continue; } nPointSizeDifference = MAX (nAverageHeightBefore * 1000 / nAverageHeightAfter, nAverageHeightAfter * 1000 / nAverageHeightBefore); if (iBestPointSizeBreakingColumn == 0 || nPointSizeDifference > nBestPointSizeDifference) { iBestPointSizeBreakingColumn = iColumn; nBestPointSizeDifference = nPointSizeDifference; } } if (iBestPointSizeBreakingColumn != 0 && BlockBreakOnVertical (p, &q, &r, iBestPointSizeBreakingColumn + p -> Rect.xLeft, 0)) { # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 3) if(!LDPUMA_Skip(hBlocksBreaking)) { pDebugBlock = q; LT_GraphicsBlockOutput2 ("Block was breaked using " "Vert PointSizeAnalysis"); pDebugBlock = r; LT_GraphicsBlockOutput2 ("Block was breaked using " "Vert PointSizeAnalysis"); LT_Getch (); LT_GraphicsClearScreen (); } # endif return (TRUE); } return (FALSE); }
Bool TrySpecialHorizontalCutting (BLOCK *p) /* Debugging not completed */ { int nBlockWidth = p -> Rect.xRight - p -> Rect.xLeft + 1; int nBlockHeight = p -> Rect.yBottom - p -> Rect.yTop + 1; ROOT *pRoot; int iLeftColumn, iRightColumn; int yTop, yBottom; int i; int nMaximum; int iLeftMaximum; int iRightMaximum; int iMinBreakingPoint; # ifdef LT_DEBUG if (p -> pHorzHystogram == NULL) ErrorInternal ("pHorzHystogram not builded in TrySpecialHorizontalCutting"); # endif if (p -> nAverageHeight == 0) return (FALSE); if (p -> nActualHeight / p -> nAverageHeight < 10 || nBlockWidth / p -> nAverageHeight < 30) { return (FALSE); } /* * Hystogram building */ nHystColumns = nBlockWidth + 1; for (i = 0; i < nHystColumns; i++) { pHystogram [i] = 0; pHystTops [i] = nBlockHeight; pHystBottoms [i] = -1; } for (pRoot = p -> pRoots; pRoot != NULL; pRoot = pRoot -> u1.pNext) { iLeftColumn = pRoot -> xColumn - p -> Rect.xLeft; iRightColumn = iLeftColumn + pRoot -> nWidth - 1; yTop = pRoot -> yRow - p -> Rect.yTop; yBottom = yTop + pRoot -> nHeight - 1; for (i = iLeftColumn; i <= iRightColumn; i++) { pHystogram [i]++; if (yTop < pHystTops [i]) pHystTops [i] = yTop; if (yBottom > pHystBottoms [i]) pHystBottoms [i] = yBottom; } } /* * Finding maximums in hystogram */ nMaximum = 0; for (i = 0; i < nHystColumns; i++) { if (pHystogram [i] > nMaximum) nMaximum = pHystogram [i]; } for (i = 0; i < nHystColumns && pHystogram [i] < nMaximum * 3 / 4; i++) ; if (i == nHystColumns) ErrorInternal ("i == nHystColumns in TrySpecialHorizontalCutting"); iLeftMaximum = i; for (i = nHystColumns - 1; i >= 0 && pHystogram [i] < nMaximum * 3 / 4; i--) ; if (i == -1) ErrorInternal ("i == -1 in TrySpecialHorizontalCutting"); iRightMaximum = i; # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 1) if(!LDPUMA_Skip(hBlocksBreaking)) { pDebugBlock = p; LT_GraphicsSpecialCuttingOutput ("Special cutting condition"); } # endif /* * Finding minimum break point */ iMinBreakingPoint = -1; for (i = iLeftMaximum + 1; i < iRightMaximum; i++) { if (pHystogram [i] > nMaximum / 6) continue; if (pHystTops [i] == -1) continue; if (pHystTops [i] < nBlockHeight * 5 / 6) continue; if (p -> pHorzHystogram [pHystTops [i] - 1] != 0) continue; if (iMinBreakingPoint == -1 || pHystTops [i] > pHystTops [iMinBreakingPoint]) { iMinBreakingPoint = i; } } if (iMinBreakingPoint == -1) return (FALSE); return (BlockBreakOnHorizontal ( p, NULL, NULL, pHystTops [iMinBreakingPoint] - 1 + p -> Rect.yTop )); }
void PageLayoutPart1 (void) { int i; i=0; i=i; # ifdef MA_DEBUG AllocationsAccountingOpen (); # endif # ifdef LT_DUMP pfListing = fopen ("layout.dmp", "w"); if (pfListing == NULL) ErrorInternal ("Can't open dump file"); fprintf (pfListing, "nRoots: %d\n", (int) nRoots); { int i; for (i = 0; i < nRoots; i++) { fprintf (pfListing, "x: %4d, y: %4d, w: %4d, h: %4d, block: %4d/%4d [%4x %4x] %4x\n", (int) pRoots [i].xColumn, (int) pRoots [i].yRow, (int) pRoots [i].nWidth, (int) pRoots [i].nHeight, (int) pRoots [i].nBlock, (int) pRoots [i].nUserNum, 0, //(int) pRoots [i].wSegmentPtr, 0, //(int) pRoots [i].wLength); (int) pRoots [i].bType); } } fclose (pfListing); # endif if (nRoots == 0) //ErrorInternal ("Page is empty"); return; nNextBlockNumber = FIRST_REGULAR_BLOCK_NUMBER; # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel > 0) if( !LDPUMA_Skip (hPageBeforeEditing) || !LDPUMA_Skip (hPageMatrix) || !LDPUMA_Skip (hInitialBreaking) || !LDPUMA_Skip (hInclineCalculating) || !LDPUMA_Skip (hBlocksBreaking) || !LDPUMA_Skip (hBlocksGlueing) || !LDPUMA_Skip (hFirstDustAbsorbtion) || !LDPUMA_Skip (hRemoveEmptyBlocks) || !LDPUMA_Skip (hSecondDustAbsorbtion)) { LT_GraphicsOpen (); } if (bDebugTimeFlag) tTimeTotal = clock (); # endif RootsSaveNonLayoutData (); CalculatePageParameters (); SeparatorsGet (); # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 2) if (!LDPUMA_Skip(hPageBeforeEditing)) LT_GraphicsRootsOutput ("Page"); # endif if (bOptionInitialBreakingByPageMatrix || bOptionBlocksRemovingByPageMatrix) { PageMatrixBuild (); } # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 2) if (!LDPUMA_Skip(hPageMatrix)) LT_GraphicsPageMatrixOutput ("Page matrix"); # endif // выделить в матрице страницы компоненты связности; // настроить в рутах поле nBlock на хранение этой // полезной информации; сами компоненты связности -- не хранятся. InitialBreakingProceed (); # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 3) if (!LDPUMA_Skip(hInitialBreaking)) LT_GraphicsBlocksOutput ("Initial breaking"); # endif // InclinesAccount (); RotatePageToIdeal (); // InclinesFreeData (); RootStripsCalculate (); # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 3) if(!LDPUMA_Skip(hInclineCalculating)) { LT_GraphicsRootsOutput ("Roots after page rotation"); LT_GraphicsRootStripsOutput ("Root strips"); } # endif BlocksExtract (); //BlockAnalyse(); # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 2) // LT_GraphicsBlocksOutput ("Blocks after extraction.1"); # endif /* Pit 09-27-94 03:42pm new_picture(3,5,300,500); del_picture(0); new_picture(300,500,100,100); BlocksExtract (); # ifdef LT_DEBUG if (LT_DebugGraphicsLevel >= 2) LT_GraphicsBlocksOutput ("Blocks after extraction.2"); # endif */ BlocksBreak (); # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 2) if(!LDPUMA_Skip(hBlocksBreaking)) LT_GraphicsBlocksOutput ("Blocks after breaking"); # endif BlocksAddVirtualSeparatorsBlocks (); # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 2) // LT_GraphicsBlocksOutput ("Blocks after adding separators"); # endif BlocksRemoveFrameLikeRoots (); # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 2) // LT_GraphicsBlocksOutput ("After removing frame like roots"); # endif BlocksGlue (); # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 2) if(!LDPUMA_Skip(hBlocksGlueing)) LT_GraphicsBlocksOutput ("Blocks after glueing"); # endif BlocksBuildEmbeddingLists (); # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 3) //{ // LT_GraphicsHighEmbeddingBlocksListOutput ("High embedding blocks list"); // LT_GraphicsLowEmbeddingBlocksListOutput ("Low embedding blocks list"); //} # endif BlocksAbsorbDust (); # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 2) if(!LDPUMA_Skip(hFirstDustAbsorbtion)) LT_GraphicsBlocksOutput ("After first dust absorbtion"); # endif PageMatrixExcludeSeparators (TRUE); # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 2) // LT_GraphicsPageMatrixOutput ("Matrix after excluding separators"); # endif BlocksRemoveEmptyBlocks (); # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 2) if(!LDPUMA_Skip(hRemoveEmptyBlocks)) LT_GraphicsBlocksOutput ("After removing empty blocks"); # endif BlocksAbsorbDust (); BlocksDisAbsorbBoundaryDust (); # ifdef LT_DEBUG //if (LT_DebugGraphicsLevel >= 2) if(!LDPUMA_Skip(hSecondDustAbsorbtion)) LT_GraphicsBlocksOutput ("After second dust absorbtion"); # endif if (cut_page_left || cut_page_right) { BlocksCutPageEdges (); # ifdef LT_DEBUG // if (LT_DebugGraphicsLevel >= 2) // LT_GraphicsBlocksOutput ("After BlocksCutPageEdges"); # endif } LayoutBackupFreeData (); }
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 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; } } } }