RectShape(const GBitmap& bm, int x, int y) : Shape(x, y) { fRect.setXYWH(x, y, bm.width(), bm.height()); fRect.offset(-fRect.centerX(), -fRect.centerY()); fPaint.setRGB(gRand.nextF(), gRand.nextF(), gRand.nextF()); }
void ClipMap::fillWithTestPattern() { AssertISV(false, "ClipMap::fillWithTestPattern - assumes bitmaps, which " "are no longer present, switch to lock() semantics if you need this!"); // Table of random colors. U8 colorTbl[16][3] = { { 0xFF, 0x00, 0x0F }, { 0xFF, 0x00, 0xA0 }, { 0xFF, 0x00, 0xFF }, { 0x00, 0xA0, 0x00 }, { 0x00, 0xA0, 0xAF }, { 0x00, 0xA0, 0xF0 }, { 0xA0, 0xFF, 0xA0 }, { 0x00, 0xF0, 0xA0 }, { 0x00, 0xF0, 0xFF }, { 0xA0, 0x00, 0x00 }, { 0xA0, 0x00, 0xAF }, { 0xA0, 0x00, 0xF0 }, { 0xA0, 0xF0, 0x0F }, { 0xA0, 0xF0, 0xA0 }, { 0xA0, 0xF0, 0xFF }, { 0x00, 0xFF, 0x00 }, }; // Lock each layer of each texture and write a test pattern in. // Base levels first. for(S32 i=0; i<mClipStackDepth; i++) { GTexHandle >h = mLevels[i].mTex; U8 *bmpData = (U8*)gth.getBitmap()->getWritableBits(0); for(S32 x=0; x<gth.getHeight(); x++) { for(S32 y=0; y<gth.getWidth(); y++) { S32 xFlag = x & 4; S32 yFlag = y & 4; U32 offset = (x * gth.getWidth() + y) * 4; if(xFlag ^ yFlag) { // Set bright. bmpData[offset+0] = colorTbl[i][0]; bmpData[offset+1] = colorTbl[i][1]; bmpData[offset+2] = colorTbl[i][2]; bmpData[offset+3] = 0xFF; } else { // Set dim. bmpData[offset+0] = colorTbl[i][0] / 3; bmpData[offset+1] = colorTbl[i][1] / 3; bmpData[offset+2] = colorTbl[i][2] / 3; bmpData[offset+3] = 0xFF; } } } if(i == mClipStackDepth - 1) gth.getBitmap()->extrudeMipLevels(); else { // Write black/translucent in the higher levels. GBitmap *gb = gth.getBitmap(); for(S32 j=1; j<gb->getNumMipLevels(); j++) { U8 *b = gb->getWritableBits(j); dMemset(b, 0, 4 * gb->getWidth(j) * gb->getHeight(j)); } } gth.refresh(); } }
void JB2Dict::JB2Codec::Encode::code_absolute_mark_size(GBitmap &bm, int border) { CodeNum(bm.columns(), 0, BIGPOSITIVE, abs_size_x); CodeNum(bm.rows(), 0, BIGPOSITIVE, abs_size_y); }
void JB2Dict::JB2Codec::Encode::code_relative_mark_size(GBitmap &bm, int cw, int ch, int border) { CodeNum(bm.columns()-cw, BIGNEGATIVE, BIGPOSITIVE, rel_size_x); CodeNum(bm.rows()-ch, BIGNEGATIVE, BIGPOSITIVE, rel_size_y); }
Point2I GuiColorPickerCtrl::findColor(const ColorF & color, const Point2I& offset, const Point2I& resolution, GBitmap& bmp) { RectI rect; Point2I ext = getExtent(); if (mDisplayMode != pDropperBackground) { ext.x -= 3; ext.y -= 2; rect = RectI(Point2I(1, 1), ext); } else { rect = RectI(Point2I(0, 0), ext); } Point2I closestPos(-1, -1); /* Debugging char filename[256]; dSprintf( filename, 256, "%s.%s", "colorPickerTest", "png" ); // Open up the file on disk. FileStream fs; if ( !fs.open( filename, Torque::FS::File::Write ) ) Con::errorf( "GuiObjectView::saveAsImage() - Failed to open output file '%s'!", filename ); else { // Write it and close. bmp.writeBitmap( "png", fs ); fs.close(); } */ ColorI tmp; U32 buf_x; U32 buf_y; ColorF curColor; F32 val(10000.0f); F32 closestVal(10000.0f); bool closestSet = false; for (S32 x = rect.point.x; x <= rect.extent.x; x++) { for (S32 y = rect.point.y; y <= rect.extent.y; y++) { buf_x = offset.x + x + 1; buf_y = (resolution.y - (offset.y + y + 1)); buf_y = resolution.y - buf_y; //Get the color at that position bmp.getColor(buf_x, buf_y, tmp); curColor = (ColorF)tmp; //Evaluate how close the color is to our desired color val = mFabs(color.red - curColor.red) + mFabs(color.green - curColor.green) + mFabs(color.blue - curColor.blue); if (!closestSet) { closestVal = val; closestPos.set(x, y); closestSet = true; } else if (val < closestVal) { closestVal = val; closestPos.set(x, y); } } } return closestPos; }
S32 GuiControlProfile::constructBitmapArray() { if(mBitmapArrayRects.size()) return mBitmapArrayRects.size(); if( mTextureObject.isNull() ) { if ( !mBitmapName || !mBitmapName[0] || !mTextureObject.set( mBitmapName, &GFXDefaultPersistentProfile, avar("%s() - mTextureObject (line %d)", __FUNCTION__, __LINE__) )) return 0; } GBitmap *bmp = mTextureObject->getBitmap(); //get the separator color ColorI sepColor; if ( !bmp || !bmp->getColor( 0, 0, sepColor ) ) { Con::errorf("Failed to create bitmap array from %s for profile %s - couldn't ascertain seperator color!", mBitmapName, getName()); AssertFatal( false, avar("Failed to create bitmap array from %s for profile %s - couldn't ascertain seperator color!", mBitmapName, getName())); return 0; } //now loop through all the scroll pieces, and find the bounding rectangle for each piece in each state S32 curY = 0; // ascertain the height of this row... ColorI color; mBitmapArrayRects.clear(); while(curY < bmp->getHeight()) { // skip any sep colors bmp->getColor( 0, curY, color); if(color == sepColor) { curY++; continue; } // ok, process left to right, grabbing bitmaps as we go... S32 curX = 0; while(curX < bmp->getWidth()) { bmp->getColor(curX, curY, color); if(color == sepColor) { curX++; continue; } S32 startX = curX; while(curX < bmp->getWidth()) { bmp->getColor(curX, curY, color); if(color == sepColor) break; curX++; } S32 stepY = curY; while(stepY < bmp->getHeight()) { bmp->getColor(startX, stepY, color); if(color == sepColor) break; stepY++; } mBitmapArrayRects.push_back(RectI(startX, curY, curX - startX, stepY - curY)); } // ok, now skip to the next separation color on column 0 while(curY < bmp->getHeight()) { bmp->getColor(0, curY, color); if(color == sepColor) break; curY++; } } return mBitmapArrayRects.size(); }
void blInteriorProxy::addToShadowVolume(ShadowVolumeBSP * shadowVolume, LightInfo * light, S32 level) { if(light->getType() != LightInfo::Vector) return; ColorF ambient = light->getAmbient(); bool shadowedTree = true; InteriorInstance* interior = dynamic_cast<InteriorInstance*>(getObject()); if (!interior) return; Resource<InteriorResource> mInteriorRes = interior->getResource(); // check if just getting shadow detail if(level == SceneLighting::SHADOW_DETAIL) { shadowedTree = false; level = mInteriorRes->getNumDetailLevels() - 1; } Interior * detail = mInteriorRes->getDetailLevel(level); bool hasAlarm = detail->hasAlarmState(); // make sure surfaces do not get processed more than once BitVector surfaceProcessed; surfaceProcessed.setSize(detail->mSurfaces.size()); surfaceProcessed.clear(); ColorI color = light->getAmbient(); // go through the zones of the interior and grab outside visible surfaces for(U32 i = 0; i < detail->getNumZones(); i++) { Interior::Zone & zone = detail->mZones[i]; for(U32 j = 0; j < zone.surfaceCount; j++) { U32 surfaceIndex = detail->mZoneSurfaces[zone.surfaceStart + j]; // dont reprocess a surface if(surfaceProcessed.test(surfaceIndex)) continue; surfaceProcessed.set(surfaceIndex); Interior::Surface & surface = detail->mSurfaces[surfaceIndex]; // outside visible? if(!(surface.surfaceFlags & Interior::SurfaceOutsideVisible)) continue; // good surface? PlaneF plane = detail->getPlane(surface.planeIndex); if(Interior::planeIsFlipped(surface.planeIndex)) plane.neg(); // project the plane PlaneF projPlane; mTransformPlane(interior->getTransform(), interior->getScale(), plane, &projPlane); // fill with ambient? (need to do here, because surface will not be // added to the SVBSP tree) F32 dot = mDot(projPlane, light->getDirection()); if(dot > -gParellelVectorThresh)// && !(GFX->getPixelShaderVersion() > 0.0) ) { if(shadowedTree) { // alarm lighting GFXTexHandle normHandle = gInteriorLMManager.duplicateBaseLightmap(detail->getLMHandle(), interior->getLMHandle(), detail->getNormalLMapIndex(surfaceIndex)); GFXTexHandle alarmHandle; GBitmap * normLightmap = normHandle->getBitmap(); GBitmap * alarmLightmap = 0; // check if they share the lightmap if(hasAlarm) { if(detail->getNormalLMapIndex(surfaceIndex) != detail->getAlarmLMapIndex(surfaceIndex)) { alarmHandle = gInteriorLMManager.duplicateBaseLightmap(detail->getLMHandle(), interior->getLMHandle(), detail->getAlarmLMapIndex(surfaceIndex)); alarmLightmap = alarmHandle->getBitmap(); } } // // Support for interior light map border sizes. // U32 xlen, ylen, xoff, yoff; U32 lmborder = detail->getLightMapBorderSize(); xlen = surface.mapSizeX + (lmborder * 2); ylen = surface.mapSizeY + (lmborder * 2); xoff = surface.mapOffsetX - lmborder; yoff = surface.mapOffsetY - lmborder; // attemp to light normal and alarm lighting for(U32 c = 0; c < 2; c++) { GBitmap * lightmap = (c == 0) ? normLightmap : alarmLightmap; if(!lightmap) continue; // fill it for(U32 y = 0; y < ylen; y++) { for(U32 x = 0; x < xlen; x++) { ColorI outColor(255, 0, 0, 255); #ifndef SET_COLORS ColorI lmColor(0, 0, 0, 255); lightmap->getColor(xoff + x, yoff + y, lmColor); U32 _r = static_cast<U32>( color.red ) + static_cast<U32>( lmColor.red ); U32 _g = static_cast<U32>( color.green ) + static_cast<U32>( lmColor.green ); U32 _b = static_cast<U32>( color.blue ) + static_cast<U32>( lmColor.blue ); outColor.red = mClamp(_r, 0, 255); outColor.green = mClamp(_g, 0, 255); outColor.blue = mClamp(_b, 0, 255); #endif lightmap->setColor(xoff + x, yoff + y, outColor); } } } } continue; } ShadowVolumeBSP::SVPoly * poly = buildInteriorPoly(shadowVolume, detail, surfaceIndex, light, shadowedTree); // insert it into the SVBSP tree shadowVolume->insertPoly(poly); } } }
void GBitsetOCR::textOCR_(vector<stringOCR>&correctionTable,GLogicProcessor *logicProcessor, int mode){ int baseCount; unsigned int letterW,letterH; int print=0; int w,h,yLimit0,yLimit1,id_index; string letter; int indexW; mainString=""; indexW=0; id_index=0; vector<wordOCR>lineText; vector<OCRMatch>matchLine; static float bestScale=0; static int bestCorrelation=0; int needLineSize=0; int lineCorrelation=0; float scalePage=(float)atoi(inputData.data["scale"].c_str())/100; //1 не выполняется масштабирование if(scalePage<0)scalePage=0; if(scalePage>5)scalePage=5; //cout<<"scale="<<scalePage<<endl; GBitmap *line; #define c_out_ cout int draw=0; if(inputData.data["ocrData"]=="drawLetter"){ draw=1; print=0; c_out_<<"<span style=\"font-family:OCRUnicode;\">"; c_out_<<"inputData.ocrData="<<inputData.data["ocrData"]<<END; } DT("//_________________________print text OCR"<<END); DT("//_________________________start correlation"<<END); if(strArray[0].size()==0)return; baseCount=0; letterW=0; letterH=0; //setOCRCorrelation(0,1,ROOT_LETTER); return; if(!aliKali)return; if(aliKali->letterCount()<1)return; //int OCRMode=1; //- Tibetan print text int OCRMode=2; //- Tibetan woodblock text TIME_START //for (int index=15;index>=15; --index){ //for every string for (int indexLine=(int)strArray[0].size()-1;indexLine>=0; --indexLine){ //for every string if((inputData.data["ocrData"]=="testOCRLine")&&!strArray[0][indexLine].selectFlag){continue;} //if(index!=21)continue; lineCorrelation=0; lineText.resize(0); //if(readFromCorrectionTable(correctionTable,pageText,strArray[0].size()-3-index))continue; //read string from human prof reading pages. //##if(readFromCorrectionTable(correctionTable,pageText,index))continue; //read string from human prof reading pages. //Create GBitsetMatrix for matrix correlation //SH(inputData.borderSize()); w=inputBitmap->columns(); h=inputBitmap->rows(); //*** ВЫЧИСЛЕНИЕ ГАБАРИТОВ ПОИСКА БУКВ В СТРОКЕ ***/// yLimit0=(strArray[0][indexLine].y1-strArray[0][indexLine].y0)*3; yLimit1=(strArray[0][indexLine].y1-strArray[0][indexLine].y0)*4; int LimY0=yLimit0*0.8; //normalisation DT2("w="<<w<<"h="<<h<< "y0="<< strArray[0][indexLine].y0<<" y1="<< strArray[0][indexLine].y1<<" yLimit0="<<yLimit0<<" yLimit1="<<yLimit1<<END); if(strArray[0][indexLine].y0-yLimit0<0)yLimit0=strArray[0][indexLine].y0; if(strArray[0][indexLine].y1+yLimit1>h)yLimit1=h-strArray[0][indexLine].y1; DT2("w="<<w<<"h="<<h<< "y0="<< strArray[0][indexLine].y0<<" y1="<< strArray[0][indexLine].y1<<" yLimit0="<<yLimit0<<" yLimit1="<<yLimit1<<END); DT2("@@Y0="<<strArray[0][indexLine].y0-yLimit0<<endl); DT2("@@H="<<strArray[0][indexLine].y1-strArray[0][indexLine].y0+yLimit0+yLimit1); int textLineSize=strArray[0][indexLine].y1-strArray[0][indexLine].y0; DT2(" textLineSize1="<<textLineSize); float scale=0,k; int needScaleFlag=1; //1 если нужно масштабировать строку if(scalePage!=1){ line=GBitmap::createRegion(inputBitmap, 0, strArray[0][indexLine].y0-LimY0, inputBitmap->columns(), yLimit0*2.5 ); if(scalePage!=0)needScaleFlag=0; } int correlation; GBitmap *lineScale; //pageTextSize0=pageText.size(); //размер текста до распознавания строки ScaleDetector:; DT("needScaleFlag="<<needScaleFlag<<" needLineSize="<<needLineSize<<endl); strArray[0][indexLine].clearOCR(); lineText.resize(0); //pageTextSize1=pageText.size(); //размер текста до распознавания строки или после первого распознавания с выбранным масштабом (после возврата по GOTO) if(scalePage==1){ scale=1; needScaleFlag=0; } if(needScaleFlag){ if(needLineSize<3){ scale=1; scale=lineOCRScaleDetector(line, matchLine, LimY0*scale, (LimY0+textLineSize)*scale, scale, indexLine, &correlation, 1); if(scale){ k=bestScale/scale; DT("bestScale="<<bestScale<<" scale="<<scale<<" k="<<k<<endl); if(k>0.8&&k<1.2){needLineSize++;}else{needLineSize=0;} }else{needLineSize=0;} bestScale=scale; bestCorrelation=correlation; }else{ scale=bestScale; } if(scale==0){ scale=1; //no rezult from scale detector //continue; //stepCount++; //if(stepCount>2){needLineSize=0;continue;} //goto_ScaleDetector; } //cout<<"@3index="<<index<<" scalePage="<<scalePage<<" needScaleFlag="<<needScaleFlag<<endl; DT("m0_1"); ///scale=1.74; lineScale=GBitmap::createScale(line,scale); setMatrix=GBitsetMatrix::createRegion(lineScale, 0, 0, lineScale->columns(), lineScale->rows(), 1,1, IMGNOFLIP ); lineScale->destroy(); }else { if(scalePage!=1){ scale=scalePage; lineScale=GBitmap::createScale(line,scale); setMatrix=GBitsetMatrix::createRegion(lineScale, 0, 0, lineScale->columns(), lineScale->rows(), 1,1, IMGNOFLIP ); lineScale->destroy(); }else{ setMatrix=GBitsetMatrix::createRegion(inputBitmap, 0, strArray[0][indexLine].y0-LimY0, inputBitmap->columns()/2, yLimit0*2.5, 1,1, IMGNOFLIP ); } } DT("m0_2"); //GImageEditor *editor=GImageEditor::create(); //editor->WriteImageData(lineScale,"/__XML__/1.jpg",0); //exit(0); DT("m1"); setMatrix->letterCorrelation(matchLine, aliKali, indexLine, LimY0*scale, (LimY0+textLineSize)*scale, 0, //no scale mode OCRMode, 0); //0 no print DT2("m3"); #ifndef REPORT_DRAW setMatrix->destroy(); #endif cout<<"new string"<<endl; sleep(10); //now we start check result of correlation and make decision about place of every letter DT2("m3_1"); //разборка строки на буквы в соответствии с величиной корреляции и вложенностью букв. например О-С } TIME_PRINT DT2("start grammar corrector"<<END); // logicProcessor->grammarCorrector(strArray,correctionTable,mainString,xmlString,LOCAL_MODE); DT2("done Grammar"<<endl); }////////////////////////////////////////////////////////////////////////////////
void TerrainFile::import( const GBitmap &heightMap, F32 heightScale, const Vector<U8> &layerMap, const Vector<String> &materials, bool flipYAxis ) { AssertFatal( heightMap.getWidth() == heightMap.getHeight(), "TerrainFile::import - Height map is not square!" ); AssertFatal( isPow2( heightMap.getWidth() ), "TerrainFile::import - Height map is not power of two!" ); const U32 newSize = heightMap.getWidth(); if ( newSize != mSize ) { mHeightMap.setSize( newSize * newSize ); mHeightMap.compact(); mSize = newSize; } // Convert the height map to heights. U16 *oBits = mHeightMap.address(); if ( heightMap.getFormat() == GFXFormatR5G6B5 ) { const F32 toFixedPoint = ( 1.0f / (F32)U16_MAX ) * floatToFixed( heightScale ); const U16 *iBits = (const U16*)heightMap.getBits(); if ( flipYAxis ) { for ( U32 i = 0; i < mSize * mSize; i++ ) { U16 height = convertBEndianToHost( *iBits ); *oBits = (U16)mCeil( (F32)height * toFixedPoint ); ++oBits; ++iBits; } } else { for(S32 y = mSize - 1; y >= 0; y--) { for(U32 x = 0; x < mSize; x++) { U16 height = convertBEndianToHost( *iBits ); mHeightMap[x + y * mSize] = (U16)mCeil( (F32)height * toFixedPoint ); ++iBits; } } } } else { const F32 toFixedPoint = ( 1.0f / (F32)U8_MAX ) * floatToFixed( heightScale ); const U8 *iBits = heightMap.getBits(); if ( flipYAxis ) { for ( U32 i = 0; i < mSize * mSize; i++ ) { *oBits = (U16)mCeil( ((F32)*iBits) * toFixedPoint ); ++oBits; iBits += heightMap.getBytesPerPixel(); } } else { for(S32 y = mSize - 1; y >= 0; y--) { for(U32 x = 0; x < mSize; x++) { mHeightMap[x + y * mSize] = (U16)mCeil( ((F32)*iBits) * toFixedPoint ); iBits += heightMap.getBytesPerPixel(); } } } } // Copy over the layer map. AssertFatal( layerMap.size() == mHeightMap.size(), "TerrainFile::import - Layer map is the wrong size!" ); mLayerMap = layerMap; mLayerMap.compact(); // Resolve the materials. _resolveMaterials( materials ); // Rebuild the collision grid map. _buildGridMap(); }
void blTerrainProxy::light(LightInfo * light) { // If we don't have terrain or its not a directional // light then skip processing. TerrainBlock * terrain = getObject(); if ( !terrain || light->getType() != LightInfo::Vector ) return; S32 time = Platform::getRealMilliseconds(); // reset mShadowVolume = new ShadowVolumeBSP; // build interior shadow volume for(ObjectProxy ** itr = gLighting->mLitObjects.begin(); itr != gLighting->mLitObjects.end(); itr++) { ObjectProxy* objproxy = *itr; if (markObjectShadow(objproxy)) objproxy->addToShadowVolume(mShadowVolume, light, SceneLighting::SHADOW_DETAIL); } lightVector(light); // set the lightmap... terrain->clearLightMap(); // Blur... F32 kernel[3][3] = { {1, 2, 1}, {2, 3, 2}, {1, 2, 1} }; F32 modifier = 1; F32 divisor = 0; for( U32 i=0; i<3; i++ ) { for( U32 j=0; j<3; j++ ) { if( i==1 && j==1 ) { kernel[i][j] = 1 + kernel[i][j] * modifier; } else { kernel[i][j] = kernel[i][j] * modifier; } divisor += kernel[i][j]; } } for( U32 i=0; i < mLightMapSize; i++ ) { for( U32 j=0; j < mLightMapSize; j++ ) { ColorF val; val = _getValue( i-1, j-1 ) * kernel[0][0]; val += _getValue( i-1, j ) * kernel[0][1]; val += _getValue( i-1, j+1 ) * kernel[0][2]; val += _getValue( i, j-1 ) * kernel[1][0]; val += _getValue( i, j ) * kernel[1][1]; val += _getValue( i, j+1 ) * kernel[1][2]; val += _getValue( i+1, j-1 ) * kernel[2][0]; val += _getValue( i+1, j ) * kernel[2][1]; val += _getValue( i+1, j+1 ) * kernel[2][2]; U32 edge = 0; if( j == 0 || j == mLightMapSize - 1 ) edge++; if( i == 0 || i == mLightMapSize - 1 ) edge++; if( !edge ) val = val / divisor; else val = mLightmap[ i * mLightMapSize + j ]; // clamp values mLightmap[ i * mLightMapSize + j ]= val; } } // And stuff it into the texture... GBitmap *terrLightMap = terrain->getLightMap(); for(U32 y = 0; y < mLightMapSize; y++) { for(U32 x = 0; x < mLightMapSize; x++) { ColorI color(255, 255, 255, 255); color.red = mLightmap[x + y * mLightMapSize].red * 255; color.green = mLightmap[x + y * mLightMapSize].green * 255; color.blue = mLightmap[x + y * mLightMapSize].blue * 255; terrLightMap->setColor(x, y, color); } } /* // This handles matching up the outer edges of the terrain // lightmap when it has neighbors if (!terrain->isTiling()) { for (S32 y = 0; y < terrLightMap->getHeight(); y++) { ColorI c; if (terrain->getFile()->mEdgeTerrainFiles[0]) { terrLightMap->getColor(terrLightMap->getWidth()-1,y,c); terrLightMap->setColor(0,y,c); terrLightMap->setColor(1,y,c); } else { terrLightMap->getColor(0,y,c); terrLightMap->setColor(terrLightMap->getWidth()-1,y,c); terrLightMap->setColor(terrLightMap->getWidth()-2,y,c); } } for (S32 x = 0; x < terrLightMap->getHeight(); x++) { ColorI c; if (terrain->getFile()->mEdgeTerrainFiles[1]) { terrLightMap->getColor(x,terrLightMap->getHeight()-1,c); terrLightMap->setColor(x,0,c); terrLightMap->setColor(x,1,c); } else { terrLightMap->getColor(x,0,c); terrLightMap->setColor(x,terrLightMap->getHeight()-1,c); terrLightMap->setColor(x,terrLightMap->getHeight()-2,c); } } } */ delete mShadowVolume; Con::printf(" = terrain lit in %3.3f seconds", (Platform::getRealMilliseconds()-time)/1000.f); }
void GMainEditor::startOCRBatch(){ imageEditor=(GImageEditor*)inputData.imageEditor; fontEditor=(GFontEditor*)inputData.fontEditor; logicProcessor=(GLogicProcessor*)inputData.logicProcessor; if(!logicProcessor->dictionaryReady)logicProcessor->readDictionary(); aliKali=fontEditor->aliKali; string strHeaderHTML,srcLine,str; string path=inputData.data["tablePath"]+"/header.xml"; DIR *dir; //int mode; int i=0; //читаем статистику использования букв книги //readLetterStat(); //загружаем базу данных букв #ifdef FORK int maxFork=inputData.num_cores*0.75; int pid; pidID *pidIDArray; if(inputData.fileList.size()>1){ int countFork=0; MemoryFile *pidData_mf; //main file for conection with child process //inputData.data["statPath"].c_str() time_t seconds; seconds = time (NULL); ostringstream out; out<<"/tmp/"<<seconds; string path=out.str(); pidData_mf=MemoryFile::create(path.c_str(), MemoryFile::if_exists_keep_if_dont_exists_create); pidData_mf->resize(sizeof(pidID)*maxFork); pidIDArray=(pidID*)pidData_mf->data(); //array which can be share between processes. for(int index=0;index<maxFork;index++){ //cout_<<"pidIDArray["<<index<<"].status="<<pidIDArray[index].status<<endl; pidIDArray[index].status=0; } int ID=0; while(i<inputData.fileList.size()){ cout<<"NEW file#1 "<<inputData.fileList[i]<<endl; if( ( dir=opendir(inputData.fileList[i].c_str()))!=NULL){ i++; continue; } inputData.data["inputFile"]=inputData.fileList[i]; string path=inputData.data["inputFile"]; //проверяем есть ли такой распознаный файл path=substr(0,(int)path.rfind("."),path); string volume=path; string fileIndex=fileName(path); path+=".xml"; if(is_file(path)){i++; continue;} if(!forkProccesOCR_(pidIDArray,ID,maxFork)){ cout<<"ERROR on fork return"; sleep(1); continue; }; i++;if(i==inputData.fileList.size())break; countFork++; for(int index=0;index<maxFork;index++)cout<<pidIDArray[index].status<<" "; cout<<endl; ID=100; int status; while(ID==100){ if(countFork<=maxFork){ //есть свободные слоты для новых процессов for(int index=0;index<maxFork;index++){ //маркируем слот как занятый //cout_<<"pidIDArray["<<index<<"].status="<<pidIDArray[index].status<<endl; if(pidIDArray[index].status==0){ ID=index; pidIDArray[index].status=1; break; } } }else{ int forkStatusCount=0; for(int index=0;index<maxFork;index++){ //подсчитываем количество активных процессов if(pidIDArray[index].status==1)forkStatusCount++; } if(forkStatusCount==countFork){sleep(1); continue;}; //ждем завершения процесса wait(&status); //регистрируем с системе завершенный процесс countFork--; } } } }else{ inputData.data["inputFile"]=inputData.fileList[0]; pechaImg=LoadImageData(inputData.data["inputFile"],0); startOCR(pechaImg); } #else cout<<"NO FORK"; while(i<inputData.fileList.size()){ if( ( dir=opendir(inputData.fileList[i].c_str()))!=NULL){ readDirectoryToArray(inputData.fileList, inputData.fileList[i],"img"); i++; continue; } GBitmap* pechaImg; inputData.data["inputFile"]=inputData.fileList[i]; if(!is_file(inputData.data["inputFile"]))continue; pechaImg=LoadImageData(inputData.data["inputFile"],0); if(!pechaImg){cout_<<"no open file"<<inputData.data["inputFile"]<<endl; return;} str=inputData.data["inputFile"]; str=substr(0,str.rfind("."),str); str+=".html"; //cout_<<str<<endl; inputData.data["inputFileName"]=inputData.data["siteName"]; inputData.data["inputFileName"]+=substr(inputData.data["siteRoot"].size(),inputData.data["inputFile"]); //readPageHTML(); inputData.c_out.open(str.c_str()); pechaDataLoaded=0; startOCR(pechaImg); pechaImg->destroy(); inputData.c_out.close(); i++; } #endif //drawLettersInCorrectionTable(DRAW_BASE); cout_<<"COMPLETE"<<endl; }//____________________________________________________________________________
/** * Scale and translate the bitmap such that is fills the specific rectangle. * * Any area in the rectangle that is outside of the bounds of the canvas is ignored. * * If a given pixel in the bitmap is not opaque (e.g. GPixel_GetA() < 255) then blend it * using SRCOVER blend mode. */ void fillBitmapRect(const GBitmap& src, const GRect& dst) { // Store dimensions of dst rectangle int left = dst.left(); int top = dst.top(); int right = dst.right(); int bottom = dst.bottom(); int rW = dst.width(); int rH = dst.height(); // Store dimensions of src bitmap int bW = src.width(); int bH = src.height(); // Find necessary scale factor for both width and height float sx = (float)bW/(float)rW; float sy = (float)bH/(float)rH; float tx = 0 - left; float ty = 0 - top; // Create matrix for scaling float scale[6] = {sx, 0, 0, 0, sy, 0}; // Create matrix for translating float translate[6] = {1, 0, tx, 0, 1, ty}; // Combine the matrices float both[6] = {sx, 0, sx*tx, 0, sy, sy*ty}; // For loop that takes each point in dst and find corresponding point in src GPixel* d = draw.fPixels; d = (GPixel*)((char*)d + (int)top * draw.rowBytes()); for (int y = top; y < bottom; ++y) { for (int x = left; x < right; ++x) { // Only map pixels that are in the bitmap if ((x >= 0 && x < draw.width()) && (y >= 0 && y < draw.height())) { // Find corresponding point in src bitmap int xP; int yP; xP = both[0] * x + both[1] * y + both[2]; yP = both[3] * x + both[4] * y + both[5]; // Apply CTM to x and y int nX = (CTM[0] * x) + (CTM[1] * y) + (CTM[2]); int nY = (CTM[3] * x) + (CTM[4] * y) + (CTM[5]); // Prepare color to fill unsigned a = GPixel_GetA(*src.getAddr(xP, yP)); unsigned r = GPixel_GetR(*src.getAddr(xP, yP)); unsigned g = GPixel_GetG(*src.getAddr(xP, yP)); unsigned b = GPixel_GetB(*src.getAddr(xP, yP)); unsigned nA = a; unsigned nR = r; unsigned nG = g; unsigned nB = b; if (GPixel_GetA(*draw.getAddr(x, y)) > 0) { // blend float lA = GPixel_GetA(*src.getAddr(xP, yP)) / 255.99999; float lR = GPixel_GetR(*src.getAddr(xP, yP)) / 255.99999; float lG = GPixel_GetG(*src.getAddr(xP, yP)) / 255.99999; float lB = GPixel_GetB(*src.getAddr(xP, yP)) / 255.99999; float sA = lA + ((GPixel_GetA(*draw.getAddr(x, y)) / 255.99999) * (1.0f - lA)); float sR = lR + ((GPixel_GetR(*draw.getAddr(x, y)) / 255.99999) * (1.0f - lA)); float sG = lG + ((GPixel_GetG(*draw.getAddr(x, y)) / 255.99999) * (1.0f - lA)); float sB = lB + ((GPixel_GetB(*draw.getAddr(x, y)) / 255.99999) * (1.0f - lA)); /* float sA = lA + ((GPixel_GetA(*draw.getAddr(nX, nY)) / 255.99999) * (1.0f - lA)); float sR = lR + ((GPixel_GetR(*draw.getAddr(nX, nY)) / 255.99999) * (1.0f - lA)); float sG = lG + ((GPixel_GetG(*draw.getAddr(nX, nY)) / 255.99999) * (1.0f - lA)); float sB = lB + ((GPixel_GetB(*draw.getAddr(nX, nY)) / 255.99999) * (1.0f - lA)); */ nA = (int)(sA * 255.99999); nR = (int)(sR * 255.99999); nG = (int)(sG * 255.99999); nB = (int)(sB * 255.99999); d[x] = GPixel_PackARGB(nA, nR, nG, nB); //d = (GPixel*)((char*)d + (int)nY * draw.rowBytes()); //d[nX] = GPixel_PackARGB(nA, nR, nG, nB); //d = (GPixel*)((char*)d - (int)nY * draw.rowBytes()); } else { d[x] = GPixel_PackARGB(a, r, g, b); //d = (GPixel*)((char*)d + (int)nY * draw.rowBytes()); //d[nX] = GPixel_PackARGB(a, r, g, b); //d = (GPixel*)((char*)d - (int)nY * draw.rowBytes()); } } } d = (GPixel*)((char*)d + draw.rowBytes()); } }
BitmapShape(const GBitmap& bm) : fBM(bm) { const int w = std::max(bm.width(), 100); const int h = std::max(bm.height(), 100); fRect = GRect::MakeXYWH(100, 100, w, h); }
void ScreenShot::capture( GuiCanvas *canvas ) { AssertFatal( mPending, "ScreenShot::capture() - The capture wasn't pending!" ); if ( mTiles == 1 ) { _singleCapture( canvas ); return; } char filename[256]; Point2I canvasSize = canvas->getPlatformWindow()->getVideoMode().resolution; // Calculate the real final size taking overlap in account Point2I overlapPixels( canvasSize.x * mPixelOverlap.x, canvasSize.y * mPixelOverlap.y ); // Calculate the overlap to be used by the frustum tiling, // so it properly expands the frustum to overlap the amount of pixels we want mFrustumOverlap.x = ((F32)canvasSize.x/(canvasSize.x - overlapPixels.x*2)) * ((F32)overlapPixels.x/(F32)canvasSize.x); mFrustumOverlap.y = ((F32)canvasSize.y/(canvasSize.y - overlapPixels.y*2)) * ((F32)overlapPixels.y/(F32)canvasSize.y); //overlapPixels.set(0,0); // Get a buffer to write a row of tiles into. GBitmap *outBuffer = new GBitmap( canvasSize.x * mTiles - overlapPixels.x * mTiles * 2 , canvasSize.y - overlapPixels.y ); // Open up the file on disk. dSprintf( filename, 256, "%s.%s", mFilename, "png" ); FileStream fs; if ( !fs.open( filename, Torque::FS::File::Write ) ) Con::errorf( "ScreenShot::capture() - Failed to open output file '%s'!", filename ); // Open a PNG stream for the final image DeferredPNGWriter pngWriter; pngWriter.begin(outBuffer->getFormat(), outBuffer->getWidth(), canvasSize.y * mTiles - overlapPixels.y * mTiles * 2, fs, 0); // Render each tile to generate a huge screenshot. for( U32 ty=0; ty < mTiles; ty++ ) { for( S32 tx=0; tx < mTiles; tx++ ) { // Set the current tile offset for tileFrustum(). mCurrTile.set( tx, mTiles - ty - 1 ); // Let the canvas render the scene. canvas->renderFrame( false ); // Now grab the current back buffer. GBitmap *gb = _captureBackBuffer(); // The current GFX device couldn't capture the backbuffer or it's unable of doing so. if (gb == NULL) return; // Copy the captured bitmap into its tile // within the output bitmap. const U32 inStride = gb->getWidth() * gb->getBytesPerPixel(); const U8 *inColor = gb->getBits() + inStride * overlapPixels.y; const U32 outStride = outBuffer->getWidth() * outBuffer->getBytesPerPixel(); const U32 inOverlapOffset = overlapPixels.x * gb->getBytesPerPixel(); const U32 inOverlapStride = overlapPixels.x * gb->getBytesPerPixel()*2; const U32 outOffset = (tx * (gb->getWidth() - overlapPixels.x*2 )) * gb->getBytesPerPixel(); U8 *outColor = outBuffer->getWritableBits() + outOffset; for( U32 row=0; row < gb->getHeight() - overlapPixels.y; row++ ) { dMemcpy( outColor, inColor + inOverlapOffset, inStride - inOverlapStride ); //Grandient blend the left overlap area of this tile over the previous tile left border if (tx && !(ty && row < overlapPixels.y)) { U8 *blendOverlapSrc = (U8*)inColor; U8 *blendOverlapDst = outColor - inOverlapOffset; for ( U32 px=0; px < overlapPixels.x; px++) { F32 blendFactor = (F32)px / (F32)overlapPixels.x; sBlendPixelRGB888(blendOverlapSrc, blendOverlapDst, blendFactor); blendOverlapSrc += gb->getBytesPerPixel(); blendOverlapDst += outBuffer->getBytesPerPixel(); } } //Gradient blend against the rows the excess overlap rows already in the buffer if (ty && row < overlapPixels.y) { F32 rowBlendFactor = (F32)row / (F32)overlapPixels.y; U8 *blendSrc = outColor + outStride * (outBuffer->getHeight() - overlapPixels.y); U8 *blendDst = outColor; for ( U32 px=0; px < gb->getWidth() - overlapPixels.x*2; px++) { sBlendPixelRGB888(blendSrc, blendDst, 1.0-rowBlendFactor); blendSrc += gb->getBytesPerPixel(); blendDst += outBuffer->getBytesPerPixel(); } } inColor += inStride; outColor += outStride; } delete gb; } // Write the captured tile row into the PNG stream pngWriter.append(outBuffer, outBuffer->getHeight()-overlapPixels.y); } //Close the PNG stream pngWriter.end(); // We captured... clear the flag. mPending = false; }
void ImposterCapture::_separateAlpha( GBitmap *imposterOut ) { PROFILE_START(TSShapeInstance_snapshot_sb_separate); // TODO: Remove all this when we get rid of the 'render on black/white'. // now separate the color and alpha channels GBitmap *bmp = new GBitmap; bmp->allocateBitmap(mDim, mDim, false, GFXFormatR8G8B8A8); U8 * wbmp = (U8*)mWhiteBmp->getBits(0); U8 * bbmp = (U8*)mBlackBmp->getBits(0); U8 * dst = (U8*)bmp->getBits(0); const U32 pixCount = mDim * mDim; // simpler, probably faster... for ( U32 i=0; i < pixCount; i++ ) { // Shape on black background is alpha * color, shape on white // background is alpha * color + (1-alpha) * 255 we want 255 * // alpha, or 255 - (white - black). // // JMQ: or more verbosely: // cB = alpha * color + (0 * (1 - alpha)) // cB = alpha * color // cW = alpha * color + (255 * (1 - alpha)) // cW = cB + (255 * (1 - alpha)) // solving for alpha // cW - cB = 255 * (1 - alpha) // (cW - cB)/255 = (1 - alpha) // alpha = 1 - (cW - cB)/255 // since we want alpha*255, multiply through by 255 // alpha * 255 = 255 - cW - cB U32 alpha = 255 - (wbmp[i*3+0] - bbmp[i*3+0]); alpha += 255 - (wbmp[i*3+1] - bbmp[i*3+1]); alpha += 255 - (wbmp[i*3+2] - bbmp[i*3+2]); if ( alpha != 0 ) { F32 floatAlpha = ((F32)alpha)/(3.0f*255.0f); dst[i*4+0] = (U8)(bbmp[i*3+0] / floatAlpha); dst[i*4+1] = (U8)(bbmp[i*3+1] / floatAlpha); dst[i*4+2] = (U8)(bbmp[i*3+2] / floatAlpha); // Before we assign the alpha we "fizzle" the value // if its greater than 84. This causes the imposter // to dissolve instead of popping into view. alpha /= 3; dst[i*4+3] = (U8)alpha; } else { dst[i*4+0] = dst[i*4+1] = dst[i*4+2] = dst[i*4+3] = 0; } } PROFILE_END(); // TSShapeInstance_snapshot_sb_separate PROFILE_START(TSShapeInstance_snapshot_sb_filter); // We now run a special kernel filter over the image that // averages color into the transparent areas. This should // in essence give us a border around the edges of the // imposter silhouette which fixes the artifacts around the // alpha test billboards. U8* dst2 = (U8*)imposterOut->getBits(0); _colorAverageFilter( mDim, dst, dst2 ); if ( 0 ) { FileStream fs; if ( fs.open( "./imposterout.png", Torque::FS::File::Write ) ) imposterOut->writeBitmap( "png", fs ); fs.close(); if ( fs.open( "./temp.png", Torque::FS::File::Write ) ) bmp->writeBitmap( "png", fs ); fs.close(); } PROFILE_END(); // TSShapeInstance_snapshot_sb_filter delete bmp; }
static void maskedSubsample(const GPixmap* img, const GBitmap *p_mask, GPixmap& subsampled_image, GBitmap& subsampled_mask, int gridwidth, int inverted_mask, int minpixels=1 ) { const GPixmap& image= *img; const GBitmap& mask = *p_mask; int imageheight = image.rows(); int imagewidth = image.columns(); // compute the size of the resulting subsampled image int subheight = imageheight/gridwidth; if(imageheight%gridwidth) subheight++; int subwidth = imagewidth/gridwidth; if(imagewidth%gridwidth) subwidth++; // set the sizes unless in incremental mode subsampled_image.init(subheight, subwidth); subsampled_mask.init(subheight, subwidth); // go subsampling int row, col; // row and col in the subsampled image int posx, posxend, posy, posyend; // corresponding square in the original image for(row=0, posy=0; row<subheight; row++, posy+=gridwidth) { GPixel* subsampled_image_row = subsampled_image[row]; // row row of subsampled image unsigned char* subsampled_mask_row = subsampled_mask[row]; // row row of subsampled mask posyend = posy+gridwidth; if(posyend>imageheight) posyend = imageheight; for(col=0, posx=0; col<subwidth; col++, posx+=gridwidth) { posxend = posx+gridwidth; if(posxend>imagewidth) posxend = imagewidth; int count = 0; int r = 0; int g = 0; int b = 0; for(int y=posy; y<posyend; y++) { const unsigned char* mask_y = mask[y]; // Row y of the mask for(int x=posx; x<posxend; x++) { unsigned char masked = (inverted_mask ? !mask_y[x] :mask_y[x]); if(!masked) { GPixel p = image[y][x]; r += p.r; g += p.g; b += p.b; count ++; } } } /* minpixels pixels are enough to give the color */ /* so set it, and do not mask this point */ if(count >= minpixels) { GPixel p; p.r = r/count; p.g = g/count; p.b = b/count; subsampled_image_row[col] = p; subsampled_mask_row[col] = 0; } else /* make it bright red and masked */ { subsampled_image_row[col] = GPixel::RED; subsampled_mask_row[col] = 1; } } } }
// This code draws a bitmap assuming that we only have translation and scale, // which allows us to perform certain optimizations... void drawBitmapSimple(const GBitmap &bm, const GPaint &paint) { const GBitmap &ctxbm = GetInternalBitmap(); GRect ctxRect = GRect::MakeXYWH(0, 0, ctxbm.width(), ctxbm.height()); GRect bmRect = GRect::MakeXYWH(0, 0, bm.width(), bm.height()); GRect pixelRect = GetTransformedBoundingBox(bmRect); GRect rect; if(!(rect.setIntersection(ctxRect, pixelRect))) { return; } // We know that since we're only doing scale and translation, that all of the pixel // centers contained in rect are going to be drawn, so we only need to know the // dimensions of the mapping... GVec3f origin(0, 0, 1); GVec3f offset(1, 1, 1); origin = m_CTM * origin; offset = m_CTM * offset; float xScale = 1.0f / (offset.X() - origin.X()); float yScale = 1.0f / (offset.Y() - origin.Y()); GVec2f start = GVec2f(0, 0); if(xScale < 0.0f) { start.X() = pixelRect.fRight - 1.0f; } if(yScale < 0.0f) { start.Y() = pixelRect.fBottom - 1.0f; } GIRect dstRect = rect.round(); // Construct new bitmap int32_t offsetX = ::std::max(0, -dstRect.fLeft); int32_t offsetY = ::std::max(0, -dstRect.fTop); GBitmap fbm; fbm.fWidth = bm.width(); fbm.fHeight = bm.height(); fbm.fPixels = GetRow(bm, offsetY) + offsetX; fbm.fRowBytes = bm.fRowBytes; BlendFunc blend = blend_srcover; float alpha = paint.getAlpha(); if(alpha >= kOpaqueAlpha) { for(uint32_t j = 0; j < dstRect.height(); j++) { uint32_t srcIdxY = static_cast<uint32_t>(start.Y() + static_cast<float>(j) * yScale); GPixel *srcPixels = GetRow(fbm, Clamp<int>(srcIdxY, 0, fbm.height())); GPixel *dstPixels = GetRow(ctxbm, dstRect.fTop + j) + dstRect.fLeft; for(uint32_t i = 0; i < dstRect.width(); i++) { uint32_t srcIdxX = static_cast<uint32_t>(start.X() + static_cast<float>(i) * xScale); dstPixels[i] = blend(dstPixels[i], srcPixels[Clamp<int>(srcIdxX, 0, fbm.width())]); } } } else { const uint32_t alphaVal = static_cast<uint32_t>((alpha * 255.0f) + 0.5f); for(uint32_t j = 0; j < dstRect.height(); j++) { uint32_t srcIdxY = static_cast<uint32_t>(start.Y() + static_cast<float>(j) * yScale); GPixel *srcPixels = GetRow(fbm, srcIdxY); GPixel *dstPixels = GetRow(ctxbm, dstRect.fTop + j) + dstRect.fLeft; for(uint32_t i = 0; i < dstRect.width(); i++) { uint32_t srcIdxX = static_cast<uint32_t>(start.X() + static_cast<float>(i) * xScale); uint32_t srcA = fixed_multiply(GPixel_GetA(srcPixels[srcIdxX]), alphaVal); uint32_t srcR = fixed_multiply(GPixel_GetR(srcPixels[srcIdxX]), alphaVal); uint32_t srcG = fixed_multiply(GPixel_GetG(srcPixels[srcIdxX]), alphaVal); uint32_t srcB = fixed_multiply(GPixel_GetB(srcPixels[srcIdxX]), alphaVal); GPixel src = GPixel_PackARGB(srcA, srcR, srcG, srcB); dstPixels[i] = blend(dstPixels[i], src); } } } }