cxAny cxActionRootCreate(cxConstChars xml) { cxEngine engine = cxEngineInstance(); cxActionRoot this = cxHashGet(engine->actions, cxHashStrKey(xml)); if(this != NULL){ return this; } cxXMLScript script = cxEngineGetXMLScript(xml); if(script == NULL || script->bytes == NULL){ CX_ERROR("%s script not register",xml); return NULL; } this = CX_CREATE(cxActionRoot); xmlTextReaderPtr reader = cxXMLReaderForScript(script,cxActionRootReaderError, this); if(reader == NULL){ CX_ERROR("create xml reader failed"); return NULL; } CX_EVENT_FIRE(this, onBegin); cxActionRootLoadCodesWithReader(this, reader); cxHashKey key = cxHashStrKey(xml); cxHashSet(this->codes, key, script->bytes); cxHashSet(engine->actions, key, this); CX_EVENT_FIRE(this, onEnd); return this; }
cxTexture cxTextureCreate(cxConstChars file) { cxTexture texture = NULL; CX_ASSERT(file != NULL, "file args error"); cxStream stream = cxAssetsStreamCreate(file); if(stream == NULL){ CX_ERROR("create stream from file %s failed",file); return NULL; } char *ext = strrchr(file, '.'); if(ext == NULL){ CX_ERROR("unknow file ext name"); return NULL; } if(cxConstCharsEqu(ext, ".png")){ texture = cxTexturePNGLoadStream(stream); }else if(cxConstCharsEqu(ext, ".pvr")){ texture = cxTexturePVRLoadStream(stream); }else if(cxConstCharsEqu(ext, ".xml")){ texture = cxTextureXMLLoadStream(stream); }else if(cxConstCharsEqu(ext, ".pkm")){ texture = cxTexturePKMLoadStream(stream); }else if(cxConstCharsEqu(ext, ".jpg") || cxConstCharsEqu(ext, ".jpeg")){ texture = cxTextureJPGLoadStream(stream); }else{ CX_ERROR("load texture failed %s",file); } return texture; }
int cxAndroid::InitSurface() { EGLint w, h; if(InitDisplay() != 0){ return -1; } if(ANativeWindow_setBuffersGeometry(window, 0, 0, format) != 0){ CX_ERROR("ANativeWindow_setBuffersGeometry error"); return -1; } surface = eglCreateWindowSurface(display, eglConfig, window, NULL); if(surface == NULL){ CX_ERROR("eglCreateWindowSurface error"); return -1; } if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) { CX_ERROR("Unable to eglMakeCurrent"); return -1; } if(!eglQuerySurface(display, surface, EGL_WIDTH, &w)){ CX_ERROR("eglQuerySurface error"); return -1; } if(!eglQuerySurface(display, surface, EGL_HEIGHT, &h)){ CX_ERROR("eglQuerySurface error"); return -1; } width = w; height = h; return 0; }
static cxBool cxMp3StreamOpen(cxAny stream) { cxMp3Stream this = stream; this->fd = open(cxStringBody(this->path), O_RDONLY, 0600);; if(this->fd <= 0){ CX_ERROR("open strean file %s failed",cxStringBody(this->path)); return false; } int error = 0; this->mh = mpg123_new(NULL, &error); if(this->mh == NULL){ CX_ERROR("mpg123 new failed"); return false; } if(mpg123_open_fd(this->mh, this->fd) != MPG123_OK){ CX_ERROR("open mpg file failed %s",cxStringBody(this->path)); return false; } allocator->free(this->buffer); this->bufsiz = mpg123_outblock(this->mh); this->buffer = allocator->malloc(this->bufsiz); mpg123_getformat(this->mh, &this->freq, &this->channels, &this->encoding); this->super.canRead = true; this->super.canSeek = true; this->super.isOpen = true; return true; }
void cxActionGroup::Load(cxHash *values,cchars file) { const cxStr *data = cxUtil::Content(file); CX_ASSERT(cxStr::IsOK(data), "get %s file data error",file); cxCSV *csv = cxCSV::Create(data); cxStr *name = nullptr; cxInt nrow = 0; cxActionGroup *attr = nullptr; for(cxInt i=3; i < csv->Row(); i++){ const cxStr *cn = csv->At(i, 0); if(cxStr::IsOK(cn)){ cxObject::swap(&name, cn); nrow = i; attr = cxActionGroup::Alloc(); values->Set(name->ToString(), attr); attr->Release(); } cchars aname = nullptr; cxActionAttr av; for(cxInt j = 2;j < csv->Col(1);j++){ const cxStr *ktype = csv->At(1, j); const cxStr *value = csv->At(i, j); cxInt c = i; //向后查找 while(!cxStr::IsOK(value) && c > nrow){ value = csv->At(--c, j); } if(!cxStr::IsOK(value)){ continue; } if(ktype->IsCaseEqu("Action")){ aname = value->ToString();//动作名称 }else if(ktype->IsCaseEqu("Repeat")){ av.repeat = value->ToInt();//播放次数 =0表示循环播放 }else if(ktype->IsCaseEqu("Speed")){ av.speed = value->ToFloat();//播放速度 }else if(ktype->IsCaseEqu("From")){ av.from = value->ToInt();//开始帧 }else if(ktype->IsCaseEqu("To")){ av.to = value->ToInt();//结束帧 }else if(ktype->IsCaseEqu("Key")){ av.key = value->ToInt();//关键帧 } } if(av.from < 0 || av.to < 0){ CX_ERROR("cxActionAttr from or to < 0"); continue; } if(!cxStr::IsOK(aname)){ CX_ERROR("cxActionAttr name miss"); continue; } attr->actions.emplace(aname,av); } cxObject::release(&name); }
CX_METHOD_DEF(cxTextureJPG,Load,cxBool,cxStream stream) { cxBool ret = false; struct jpeg_decompress_struct cinfo; cxJPEGError error; cinfo.err = jpeg_std_error(&error.pub); error.error = false; error.pub.error_exit = cxJPGErrorExit; jpeg_create_decompress(&cinfo); if(error.error){ CX_ERROR("jpg create decompress failed"); goto finished; } cxString bytes = CX_CALL(stream, AllBytes, CX_M(cxString)); if(bytes == NULL){ CX_ERROR("jpg read stream data error"); goto finished; } jpeg_mem_src(&cinfo, (cxUChar *)cxStringBody(bytes), cxStringLength(bytes)); jpeg_read_header(&cinfo, true); if(error.error){ CX_ERROR("jpg read head failed"); goto finished; } this->cxTexture.size = cxSize2fv(cinfo.image_width, cinfo.image_height); this->cxTexture.hasAlpha = false; jpeg_start_decompress(&cinfo); if(error.error){ CX_ERROR("jpg start decompress failed"); goto finished; } int row_stride = cinfo.output_width * cinfo.output_components; cxAny data = allocator->malloc(row_stride * cinfo.output_height); JSAMPARRAY buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); int line = 0; while(cinfo.output_scanline < cinfo.output_height){ jpeg_read_scanlines(&cinfo, buffer, 1); memcpy(data + line * row_stride, buffer[0], row_stride); line++; } GLint unpack = 0; glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); cxOpenGLGenTextures(1, &this->cxTexture.textureId); cxOpenGLBindTexture(this->cxTexture.textureId, 0); cxOpenGLSetTexParameters(this->cxTexture.texParam); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, cinfo.image_width, cinfo.image_height, 0, GL_RGB, GL_UNSIGNED_BYTE, data); glPixelStorei(GL_UNPACK_ALIGNMENT, unpack); cxOpenGLBindTexture(0, 0); allocator->free(data); ret = true; finished: jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); return ret; }
cxAny cxPlayEffect(cxConstChars file,cxBool loop) { cxPlayer this = cxPlayerInstance(); JniMethodInfo methodInfo; cxBool ret = cxGetStaticMethodInfo(&methodInfo, CLASS_NAME, "cxEnginePlayEffect","(Ljava/lang/String;Z)I"); CX_ASSERT(ret, "get static method info failed"); CX_UNUSED_PARAM(ret); jstring path = (*methodInfo.env)->NewStringUTF(methodInfo.env,file); cxInt soundId = (*methodInfo.env)->CallStaticIntMethod(methodInfo.env, methodInfo.classID, methodInfo.methodID, path, loop); (*methodInfo.env)->DeleteLocalRef(methodInfo.env,path); if(soundId <= 0){ CX_ERROR("play file failed %s",file); return NULL; } cxTrack track = cxHashGet(this->tracks, cxHashStrKey(file)); //add or replace if(track == NULL || track->soundId != soundId){ track = CX_ALLOC(cxTrack); track->file = cxStringAllocChars(file); track->soundId = soundId; cxHashSet(this->tracks, cxHashStrKey(file), track); CX_RELEASE(track); } return track; }
cxBool cxDBOpen(cxAny db,cxString file,cxString table,cxBool rdonly) { CX_ASSERT(file != NULL && table != NULL, "args error"); cxDBEnv env = cxDBGetEnv(db); cxDB this = db; if(rdonly){ this->flags = DB_RDONLY; }else{ this->flags = DB_CREATE; } this->ret = db_create(&this->dbptr, env->env, 0); CX_RETURN(this->ret != 0,false); this->ret = CX_METHOD_FIRE(this->ret, this->OpenBefore,db); CX_RETURN(this->ret != 0,false); cxDBTxn txn = cxStackTop(env->txn); this->ret = this->dbptr->open(this->dbptr,cxDBTxnPtr(txn),cxStringBody(file),cxStringBody(table),this->type,this->flags,0); if(this->ret != 0){ CX_ERROR("open db error %s:%s",cxStringBody(file),cxStringBody(table)); return false; } CX_RETURN(this->ret != 0,false); CX_RETAIN_SWAP(this->file, file); CX_RETAIN_SWAP(this->table, table); return CX_METHOD_FIRE(true, this->OpenAfter,db); }
static void cxHashRootReadDB(cxDBEnv env,cxHashRoot root,xmlTextReaderPtr reader) { cxReaderAttrInfo *info = cxReaderAttrInfoMake(reader, root, env); int depth = xmlTextReaderDepth(reader); while(xmlTextReaderRead(reader) && depth != xmlTextReaderDepth(reader)){ if(xmlTextReaderNodeType(reader) != XML_READER_TYPE_ELEMENT){ continue; } cxConstChars temp = cxXMLReadElementName(reader); if(!ELEMENT_IS_TYPE(cxDB)){ continue; } cxConstChars file = cxXMLAttr(reader,"file"); cxConstChars table = cxXMLAttr(reader,"table"); cxConstChars type = cxXMLAttr(reader,"type"); cxConstChars sid = cxXMLAttr(reader,"id"); cxConstChars path = cxXMLAttr(reader,"path"); //assert file copy ->to document cxBool copy = cxXMLReadBoolAttr(info, "copy", false); if(copy && file != NULL){ cxCopyFile(file, NULL, NULL); } cxBool rdonly = cxXMLReadBoolAttr(info, "rdonly", false); if(sid == NULL){ CX_WARN("db id not set,will can't add dataset"); } cxString sfile = NULL; if(cxConstCharsEqu(path, "assert")){ sfile = cxAssetsPath(file); //assert must set true rdonly = true; }else if(cxConstCharsEqu(path, "document")){ sfile = cxDocumentPath(file); }else{ CX_ERROR("must set path assert or document"); } cxAny db = NULL; if(file != NULL && table != NULL && type != NULL){ db = cxDBCreate(env, cxStringBody(sfile), table, type, rdonly); } if(db != NULL && sid != NULL){ cxHashSet(root->items, cxHashStrKey(sid), cxDBTypesCreate(db)); }else{ CX_ERROR("open dbenv type %s,db %s:%s failed",cxStringBody(env->type),file,table); } } }
static void icxLogicSM( const void* srcarr, CxScalar* scalar, void* dstarr, const void* maskarr, CxArithmUniMaskFunc2D func ) { CX_FUNCNAME( "icxLogicSM" ); __BEGIN__; double buf[12]; int coi1 = 0, coi2 = 0; CxMat srcstub, *src = (CxMat*)srcarr; CxMat dststub, *dst = (CxMat*)dstarr; CxMat maskstub, *mask = (CxMat*)maskarr; int pix_size, type; int dst_step, mask_step; CxSize size; if( !CX_IS_MAT(src)) CX_CALL( src = cxGetMat( src, &srcstub, &coi1 )); if( !CX_IS_MAT(dst)) CX_CALL( dst = cxGetMat( dst, &dststub )); if( coi1 != 0 || coi2 != 0 ) CX_ERROR( CX_BadCOI, "" ); CX_CALL( mask = cxGetMat( mask, &maskstub )); if( !CX_IS_MASK_ARR(mask) ) CX_ERROR_FROM_CODE( CX_StsBadMask ); if( !CX_ARE_SIZES_EQ( mask, dst ) ) CX_ERROR_FROM_CODE( CX_StsUnmatchedSizes ); if( src->data.ptr != dst->data.ptr ) { CX_CALL( cxCopy( src, dst, mask )); } size = cxGetMatSize( dst ); dst_step = dst->step; mask_step = mask->step; if( CX_IS_MAT_CONT( mask->type & dst->type )) { size.width *= size.height; dst_step = mask_step = CX_STUB_STEP; size.height = 1; } type = CX_MAT_TYPE( src->type ); pix_size = icxPixSize[type]; CX_CALL( cxScalarToRawData( scalar, buf, type, 0 )); IPPI_CALL( func( dst->data.ptr, dst_step, mask->data.ptr, mask_step, size, buf, pix_size )); __END__; }
cxBool cxHashRootLoad(cxAny root,cxConstChars xml) { cxXMLScript script = cxEngineGetXMLScript(xml); if(script == NULL){ CX_ERROR("%s script not register",xml); return false; } if(script->bytes == NULL){ CX_ERROR("xml script not load bytes"); return false; } xmlTextReaderPtr reader = cxXMLReaderForScript(script, cxHashRootReaderError, root); if(reader == NULL){ CX_ERROR("create xml reader failed"); return false; } return cxHashRootLoadWithReader(root, reader); }
cxBool cxEngineLuaRunChars(cxConstChars code) { CX_ASSERT(cxConstCharsOK(code), "code args error"); if(luaL_dostring(gL, code) != 0){ CX_ERROR("cxLuaLoader run code error:%s",lua_tostring(gL, -1)); return false; } return true; }
const cxActionAttr *cxActionGroup::Action(cchars key) const { std::map<std::string,cxActionAttr>::const_iterator it = actions.find(key); if(it == actions.end()){ CX_ERROR("%s action miss",key); return nullptr; } return &it->second; }
cxu32 cx_str_utf8_decode (cxu32 *dst, const cxu8 *src) { CX_ASSERT (dst); CX_ASSERT (src); cxu32 ch = 0; cxu32 offset = 0; if ((src [0] & UTF8_BYTE6) == UTF8_BYTE6) { offset = 6; } else if ((src [0] & UTF8_BYTE5) == UTF8_BYTE5) { offset = 5; } else if ((src [0] & UTF8_BYTE4) == UTF8_BYTE4) { ch = ((src [0] & 0x07) << 18) | ((src [1] & 0x3f) << 12) | ((src [2] & 0x3f) << 6) | ((src [3] & 0x3f)); offset = 4; } else if ((src [0] & UTF8_BYTE3) == UTF8_BYTE3) { ch = ((src [0] & 0x0f) << 12) | ((src [1] & 0x3f) << 6) | ((src [2] & 0x3f)); offset = 3; } else if ((src [0] & UTF8_BYTE2) == UTF8_BYTE2) { ch = ((src [0] & 0x1f) << 6) | ((src [1] & 0x3f)); offset = 2; } else if (src [0] < UTF8_BYTE1) { ch = (src [0]); offset = 1; } else { offset = strlen ((const char *) src); CX_ERROR ("Invalid UTF8 character"); } *dst = ch; return offset; }
static cxUInt8 cxStencilRefAlloc() { for(int i=1; i < CX_STENCIL_MASK; i++){ if(!refs[i]){ refs[i] = true; return i; } } CX_ERROR("cxClipping not stencil ref use,default use CX_STENCIL_MASK"); return CX_STENCIL_MASK; }
CX_METHOD_DEF(cxAssetsStream,Open,cxBool) { CX_ASSERT(this->cxStream.isOpen == false,"stream repeat open"); cxConstChars path = cxStringBody(this->cxStream.path); this->asset = fopen(path, "rb"); if(this->asset == NULL){ CX_ERROR("open assets %s stream failed",path); return false; } struct stat stat={0}; if(lstat(path, &stat) != 0){ CX_ERROR("lstat assets %s stream failed",path); return false; } this->cxStream.Length = (cxInt)stat.st_size; this->cxStream.canRead = true; this->cxStream.canSeek = true; this->cxStream.canWrite = false; this->cxStream.isOpen = true; return true; }
static bool cxShaderCompile(cxAny pshader,GLuint *shader, GLenum type, cxStr source) { CX_ASSERT_THIS(pshader, cxShader); GLint status = 0; CX_ASSERT(source != NULL,"shader sources NULL"); *shader = glCreateShader(type); if(type == GL_VERTEX_SHADER){ const GLchar *sources[] = { "uniform highp mat4 "CX_UNIFORM_MATRIX_MODELVIEW_PROJECT";\n", cxStrBody(source), }; glShaderSource(*shader, sizeof(sources)/sizeof(*sources), sources, NULL); }else if(type == GL_FRAGMENT_SHADER){ const GLchar *sources[] = { "precision mediump float;\n", cxStrBody(source), }; glShaderSource(*shader, sizeof(sources)/sizeof(*sources), sources, NULL); } glCompileShader(*shader); glGetShaderiv(*shader, GL_COMPILE_STATUS, &status); if(status == GL_FALSE){ GLsizei length = 0; glGetShaderiv(*shader, GL_SHADER_SOURCE_LENGTH, &length); GLchar* src = (GLchar *)allocator->malloc(sizeof(GLchar) * length); glGetShaderSource(*shader, length, NULL, src); CX_ERROR("Failed to compile shader:%s\n", src); cxStr log = NULL; if (type == GL_VERTEX_SHADER){ log = cxShaderVertexLog(this); }else{ log = cxShaderFragmentLog(this); } CX_ERROR("compile shader error:%s",cxStrBody(log)); allocator->free(src); abort(); } return (status == GL_TRUE); }
//int AAsset_openFileDescriptor(AAsset* asset, off_t* outStart, off_t* outLength); //int AAsset_isAllocated(AAsset* asset); //const void* AAsset_getBuffer(AAsset* asset); CX_METHOD_DEF(cxMMapStream,Open,cxBool) { CX_ASSERT(this->cxStream.isOpen == false,"stream repeat open"); cxConstChars path = cxStringBody(this->cxStream.path); this->asset = AAssetManager_open(cxEngineGetAssetManager(), path, AASSET_MODE_UNKNOWN); if(this->asset == NULL){ CX_ERROR("open asset file %s failed",path); return false; } this->map = (cxAny)AAsset_getBuffer(this->asset); if(this->map == NULL){ CX_ERROR("asset get buffer error"); return false; } this->off = 0; this->cxStream.Length = (cxInt)AAsset_getLength(this->asset); this->cxStream.canRead = true; this->cxStream.canSeek = true; this->cxStream.canWrite = false; this->cxStream.isOpen = true; return true; }
int cxAndroid::InitDisplay() { if(display != NULL){ return 0; } display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if(display == NULL){ CX_ERROR("eglGetDisplay error"); return -1; } EGLint major = 0; EGLint minor = 0; if(!eglInitialize(display, &major, &minor)){ CX_ERROR("eglInitialize error"); return -1; } CX_LOGGER("EGL Version:%d.%d",major,minor); eglChooseConfig(display, display_attribs24, &eglConfig, 1, &numConfigs); if(!numConfigs){ eglChooseConfig(display, display_attribs16, &eglConfig, 1, &numConfigs); } if(!numConfigs){ CX_ERROR("get egl config error"); return -1; } CX_LOGGER("EGL Config Number:%d",numConfigs); if(!eglGetConfigAttrib(display, eglConfig, EGL_NATIVE_VISUAL_ID, &format)){ CX_ERROR("eglGetConfigAttrib error"); return -1; } context = eglCreateContext(display, eglConfig, NULL, context_attribs); if(context == NULL){ CX_ERROR("eglCreateContext error"); return -1; } return 0; }
//read to ->buffer static cxInt cxMp3StreamRead(cxAny stream,cxPointer buffer,cxInt size) { cxMp3Stream this = stream; if(!this->super.canRead){ return 0; } size_t done = 0; cxInt rv = mpg123_read(this->mh, buffer, size, &done); //error if(rv < 0 && rv != MPG123_DONE){ CX_ERROR("read mp3 stream error"); return 0; } return done; }
cxAny cxEventBaseHttpConnect(cxConstChars host,cxInt port) { cxEventBase this = cxEventBaseInstance(); cxConstChars key = CX_CONST_STRING("%s:%d",host,port); cxHttpConn conn = cxHashGet(this->conns, cxHashStrKey(key)); if(conn != NULL){ return conn; } conn = cxHttpConnectOpen(host, port); if(conn == NULL){ CX_ERROR("http open %s:%d failed",host,port); return NULL; } cxHashSet(this->conns, cxHashStrKey(key), conn); return conn; }
static cxString cxMp3StreamAllBytes(cxAny stream) { cxStream this = stream; if(!this->canRead){ cxStreamOpen(this); } if(!this->canRead){ CX_ERROR("file stream can't read"); return NULL; } cxInt bufsiz = 0; cxPointer buffer = cxMp3StreamBuffer(this, &bufsiz); cxString data = CX_CREATE(cxString); cxInt bytes = 0; while((bytes = cxStreamRead(this,buffer,bufsiz)) > 0){ cxStringAppend(data, buffer,bytes); } cxStreamClose(this); return data; }
CX_IMPL void cxBoxPoints( CxBox2D box, CxPoint2D32f pt[4] ) { CX_FUNCNAME( "cxBoxPoints" ); __BEGIN__; float a = (float)cos(box.angle)*0.5f; float b = (float)sin(box.angle)*0.5f; if( !pt ) CX_ERROR( CX_StsNullPtr, "NULL vertex array pointer" ); pt[0].x = box.center.x - a*box.size.height - b*box.size.width; pt[0].y = box.center.y + b*box.size.height - a*box.size.width; pt[1].x = box.center.x + a*box.size.height - b*box.size.width; pt[1].y = box.center.y - b*box.size.height - a*box.size.width; pt[2].x = 2*box.center.x - pt[0].x; pt[2].y = 2*box.center.y - pt[0].y; pt[3].x = 2*box.center.x - pt[1].x; pt[3].y = 2*box.center.y - pt[1].y; __END__; }
CX_IMPL void cxKMeans2( const CxArr* samples_arr, int cluster_count, CxArr* labels_arr, CxTermCriteria termcrit ) { CxMat* centers = 0; CxMat* old_centers = 0; CxMat* counters = 0; CX_FUNCNAME( "cxKMeans2" ); __BEGIN__; CxMat samples_stub, *samples = (CxMat*)samples_arr; CxMat cluster_idx_stub, *labels = (CxMat*)labels_arr; CxMat* temp = 0; CxRandState rng; int i, k, sample_count, dims; int ids_delta, iter; double max_dist; int pix_size; if( !CX_IS_MAT( samples )) CX_CALL( samples = cxGetMat( samples, &samples_stub )); if( !CX_IS_MAT( labels )) CX_CALL( labels = cxGetMat( labels, &cluster_idx_stub )); if( cluster_count < 1 ) CX_ERROR( CX_StsOutOfRange, "Number of clusters should be positive" ); if( CX_MAT_DEPTH(samples->type) != CX_32F || CX_MAT_TYPE(labels->type) != CX_32SC1 ) CX_ERROR( CX_StsUnsupportedFormat, "samples should be floating-point matrix, cluster_idx - integer vector" ); pix_size = CX_ELEM_SIZE(samples->type); if( labels->rows != 1 && labels->cols != 1 || labels->rows + labels->cols - 1 != samples->rows ) CX_ERROR( CX_StsUnmatchedSizes, "cluster_idx should be 1D vector of the same number of elements as samples' number of rows" ); switch( termcrit.type ) { case CX_TERMCRIT_EPS: if( termcrit.epsilon < 0 ) termcrit.epsilon = 0; termcrit.maxIter = 100; break; case CX_TERMCRIT_ITER: if( termcrit.maxIter < 1 ) termcrit.maxIter = 1; termcrit.epsilon = 1e-6; break; case CX_TERMCRIT_EPS|CX_TERMCRIT_ITER: if( termcrit.epsilon < 0 ) termcrit.epsilon = 0; if( termcrit.maxIter < 1 ) termcrit.maxIter = 1; break; default: CX_ERROR( CX_StsBadArg, "Invalid termination criteria" ); } termcrit.epsilon *= termcrit.epsilon; sample_count = samples->rows; if( cluster_count > sample_count ) cluster_count = sample_count; dims = samples->cols*CX_MAT_CN(samples->type); ids_delta = labels->step ? labels->step/(int)sizeof(int) : 1; cxRandInit( &rng, 0, 1, -1, CX_RAND_UNI ); CX_CALL( centers = cxCreateMat( cluster_count, dims, CX_64FC1 )); CX_CALL( old_centers = cxCreateMat( cluster_count, dims, CX_64FC1 )); // samples_count >= cluster_count, <samples_count> // elements are used during initialization #if 0 CX_CALL( counters = cxCreateMat( 1, sample_count, CX_32SC1 )); cxZero( counters ); // init centers for( i = 0; i < cluster_count; i++ ) { int j, idx; double* c = (double*)(centers->data.ptr + i*centers->step); float* s; do idx = cxRandNext( &rng ) % cluster_count; while( counters->data.i[idx] != 0 ); counters->data.i[idx] = 1; s = (float*)(samples->data.ptr + idx*samples->step); for( j = 0; j < samples->cols; j++ ) c[j] = s[j]; } counters->cols = cluster_count; #else CX_CALL( counters = cxCreateMat( 1, cluster_count, CX_32SC1 )); // init centers for( i = 0, k = 0; i < sample_count; i++ ) { labels->data.i[i] = k; k = k < cluster_count-1 ? k+1 : 0; } #endif counters->cols = cluster_count; // cut down counters max_dist = termcrit.epsilon*2; for( iter = 0; iter < termcrit.maxIter; iter++ ) { int i, j, k; // computer centers cxZero( centers ); cxZero( counters ); for( i = 0; i < sample_count; i++ ) { float* s = (float*)(samples->data.ptr + i*samples->step); int k = labels->data.i[i*ids_delta]; double* c = (double*)(centers->data.ptr + k*centers->step); j = 0; for( ; j <= dims - 4; j += 4 ) { double t0 = c[j] + s[j]; double t1 = c[j+1] + s[j+1]; c[j] = t0; c[j+1] = t1; t0 = c[j+2] + s[j+2]; t1 = c[j+3] + s[j+3]; c[j+2] = t0; c[j+3] = t1; } for( ; j < dims; j++ ) c[j] += s[j]; counters->data.i[k]++; } if( iter > 0 ) max_dist = 0; for( k = 0; k < cluster_count; k++ ) { double* c = (double*)(centers->data.ptr + k*centers->step); if( counters->data.i[k] != 0 ) { double scale = 1./counters->data.i[k]; for( j = 0; j < dims; j++ ) c[j] *= scale; } else { int i = cxRandNext( &rng ) % sample_count; float* s = (float*)(samples->data.ptr + i*samples->step); for( j = 0; j < dims; j++ ) c[j] = s[j]; } if( iter > 0 ) { double dist = 0; double* c_o = (double*)(old_centers->data.ptr + k*old_centers->step); for( j = 0; j < dims; j++ ) { double t = c[j] - c_o[j]; dist += t*t; } if( max_dist < dist ) max_dist = dist; } } // assign labels for( i = 0; i < sample_count; i++ ) { float* s = (float*)(samples->data.ptr + i*samples->step); int k_best = 0; double min_dist = DBL_MAX; for( k = 0; k < cluster_count; k++ ) { double* c = (double*)(centers->data.ptr + k*centers->step); double dist = 0; j = 0; for( ; j <= dims - 4; j += 4 ) { double t0 = c[j] - s[j]; double t1 = c[j+1] - s[j+1]; dist += t0*t0 + t1*t1; t0 = c[j+2] - s[j+2]; t1 = c[j+3] - s[j+3]; dist += t0*t0 + t1*t1; } for( ; j < dims; j++ ) { double t = c[j] - s[j]; dist += t*t; } if( min_dist > dist ) { min_dist = dist; k_best = k; } } labels->data.i[i*ids_delta] = k_best; } if( max_dist < termcrit.epsilon ) break; CX_SWAP( centers, old_centers, temp ); } __END__; cxReleaseMat( ¢ers ); cxReleaseMat( &old_centers ); cxReleaseMat( &counters ); }
static void cxHashRootReaderError(void *arg,const char *msg,xmlParserSeverities severity,xmlTextReaderLocatorPtr locator) { cxHashRoot this = arg; CX_ERROR("%s",msg); this->isError = true; }
CX_IMPL void cxAvgSdv( const void* img, CxScalar* _mean, CxScalar* _sdv, const void* mask ) { CxScalar mean = {{0,0,0,0}}; CxScalar sdv = {{0,0,0,0}}; static CxBigFuncTable meansdv_tab; static CxFuncTable meansdvcoi_tab; static CxBigFuncTable meansdvmask_tab; static CxFuncTable meansdvmaskcoi_tab; static int inittab = 0; CX_FUNCNAME("cxMean_StdDev"); __BEGIN__; int type, coi = 0; int mat_step, mask_step = 0; CxSize size; CxMat stub, maskstub, *mat = (CxMat*)img, *matmask = (CxMat*)mask; if( !inittab ) { icxInitMean_StdDevRTable( &meansdv_tab ); icxInitMean_StdDevCnCRTable( &meansdvcoi_tab ); icxInitMean_StdDevMRTable( &meansdvmask_tab ); icxInitMean_StdDevCnCMRTable( &meansdvmaskcoi_tab ); inittab = 1; } CX_CALL( mat = cxGetMat( mat, &stub, &coi )); type = CX_MAT_TYPE( mat->type ); size = cxGetMatSize( mat ); mat_step = mat->step; if( !mask ) { if( CX_IS_MAT_CONT( mat->type )) { size.width *= size.height; size.height = 1; mat_step = CX_STUB_STEP; } if( CX_MAT_CN(type) == 1 || coi == 0 ) { CxFunc2D_1A2P func = (CxFunc2D_1A2P)(meansdv_tab.fn_2d[type]); if( !func ) CX_ERROR( CX_StsBadArg, cxUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, mean.val, sdv.val )); } else { CxFunc2DnC_1A2P func = (CxFunc2DnC_1A2P) (meansdvcoi_tab.fn_2d[CX_MAT_DEPTH(type)]); if( !func ) CX_ERROR( CX_StsBadArg, cxUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, CX_MAT_CN(type), coi, mean.val, sdv.val )); } } else { CX_CALL( matmask = cxGetMat( matmask, &maskstub )); mask_step = matmask->step; if( !CX_IS_MASK_ARR( matmask )) CX_ERROR( CX_StsBadMask, "" ); if( !CX_ARE_SIZES_EQ( mat, matmask )) CX_ERROR( CX_StsUnmatchedSizes, "" ); if( CX_IS_MAT_CONT( mat->type & matmask->type )) { size.width *= size.height; size.height = 1; mat_step = mask_step = CX_STUB_STEP; } if( CX_MAT_CN(type) == 1 || coi == 0 ) { CxFunc2D_2A2P func = (CxFunc2D_2A2P)(meansdvmask_tab.fn_2d[type]); if( !func ) CX_ERROR( CX_StsBadArg, cxUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, matmask->data.ptr, mask_step, size, mean.val, sdv.val )); } else { CxFunc2DnC_2A2P func = (CxFunc2DnC_2A2P) (meansdvmaskcoi_tab.fn_2d[CX_MAT_DEPTH(type)]); if( !func ) CX_ERROR( CX_StsBadArg, cxUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, matmask->data.ptr, mask_step, size, CX_MAT_CN(type), coi, mean.val, sdv.val )); } } __END__; if( _mean ) *_mean = mean; if( _sdv ) *_sdv = sdv; }
static void icxLogicS( const void* srcarr, CxScalar* scalar, void* dstarr, CxFunc2D_2A1P1I fn_2d ) { CX_FUNCNAME( "icxLogicS" ); __BEGIN__; CxMat srcstub, *src = (CxMat*)srcarr; CxMat dststub, *dst = (CxMat*)dstarr; int coi1 = 0, coi2 = 0; int is_nd = 0; int pix_size, type; double buf[12]; CxSize size; int src_step, dst_step; if( !CX_IS_MAT(src)) { if( CX_IS_MATND(src) ) is_nd = 1; else CX_CALL( src = cxGetMat( src, &srcstub, &coi1 )); } if( !CX_IS_MAT(dst)) { if( CX_IS_MATND(dst) ) is_nd = 1; else CX_CALL( dst = cxGetMat( dst, &dststub, &coi2 )); } if( is_nd ) { CxArr* arrs[] = { src, dst }; CxMatND stubs[2]; CxNArrayIterator iterator; CX_CALL( cxInitNArrayIterator( 2, arrs, 0, stubs, &iterator )); type = CX_MAT_TYPE(iterator.hdr[0]->type); iterator.size.width *= icxPixSize[type]; pix_size = icxPixSize[type & CX_MAT_DEPTH_MASK]; CX_CALL( cxScalarToRawData( scalar, buf, type, 1 )); do { IPPI_CALL( fn_2d( iterator.ptr[0], CX_STUB_STEP, iterator.ptr[1], CX_STUB_STEP, iterator.size, buf, pix_size )); } while( cxNextNArraySlice( &iterator )); EXIT; } if( coi1 != 0 || coi2 != 0 ) CX_ERROR( CX_BadCOI, "" ); if( !CX_ARE_TYPES_EQ( src, dst ) ) CX_ERROR_FROM_CODE( CX_StsUnmatchedFormats ); if( !CX_ARE_SIZES_EQ( src, dst ) ) CX_ERROR_FROM_CODE( CX_StsUnmatchedSizes ); size = cxGetMatSize( src ); src_step = src->step; dst_step = dst->step; if( CX_IS_MAT_CONT( src->type & dst->type )) { size.width *= size.height; src_step = dst_step = CX_STUB_STEP; size.height = 1; } type = CX_MAT_TYPE( src->type ); size.width *= icxPixSize[type]; pix_size = icxPixSize[type & CX_MAT_DEPTH_MASK]; CX_CALL( cxScalarToRawData( scalar, buf, type, 1 )); IPPI_CALL( fn_2d( src->data.ptr, src_step, dst->data.ptr, dst_step, size, buf, pix_size )); __END__; }
static int cxEngineLuaPanic(lua_State*L) { CX_ERROR("PANIC: unprotected error in call to Lua API (%s)\n",lua_tostring(L, -1)); return 0; }
CX_IMPL void cxMinMaxLoc( const void* img, double* minVal, double* maxVal, CxPoint* minLoc, CxPoint* maxLoc, const void* mask ) { static CxFuncTable minmax_tab, minmaxcoi_tab; static CxFuncTable minmaxmask_tab, minmaxmaskcoi_tab; static int inittab = 0; CX_FUNCNAME("cxMinMaxLoc"); __BEGIN__; int type, depth, cn, coi = 0; int mat_step, mask_step = 0; CxSize size; CxMat stub, maskstub, *mat = (CxMat*)img, *matmask = (CxMat*)mask; if( !inittab ) { icxInitMinMaxIndxC1RTable( &minmax_tab ); icxInitMinMaxIndxCnCRTable( &minmaxcoi_tab ); icxInitMinMaxIndxC1MRTable( &minmaxmask_tab ); icxInitMinMaxIndxCnCMRTable( &minmaxmaskcoi_tab ); inittab = 1; } CX_CALL( mat = cxGetMat( mat, &stub, &coi )); type = CX_MAT_TYPE( mat->type ); depth = CX_MAT_DEPTH( type ); cn = CX_MAT_CN( type ); size = cxGetMatSize( mat ); if( cn > 1 && coi == 0 ) CX_ERROR( CX_StsBadArg, "" ); mat_step = mat->step; if( !mask ) { if( size.height == 1 ) mat_step = CX_STUB_STEP; if( CX_MAT_CN(type) == 1 || coi == 0 ) { CxFunc2D_1A4P func = (CxFunc2D_1A4P)(minmax_tab.fn_2d[depth]); if( !func ) CX_ERROR( CX_StsBadArg, cxUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, minVal, maxVal, minLoc, maxLoc )); } else { CxFunc2DnC_1A4P func = (CxFunc2DnC_1A4P)(minmaxcoi_tab.fn_2d[depth]); if( !func ) CX_ERROR( CX_StsBadArg, cxUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, size, cn, coi, minVal, maxVal, minLoc, maxLoc )); } } else { CX_CALL( matmask = cxGetMat( matmask, &maskstub )); if( !CX_IS_MASK_ARR( matmask )) CX_ERROR( CX_StsBadMask, "" ); if( !CX_ARE_SIZES_EQ( mat, matmask )) CX_ERROR( CX_StsUnmatchedSizes, "" ); mask_step = matmask->step; if( size.height == 1 ) mat_step = mask_step = CX_STUB_STEP; if( CX_MAT_CN(type) == 1 || coi == 0 ) { CxFunc2D_2A4P func = (CxFunc2D_2A4P)(minmaxmask_tab.fn_2d[depth]); if( !func ) CX_ERROR( CX_StsBadArg, cxUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, matmask->data.ptr, mask_step, size, minVal, maxVal, minLoc, maxLoc )); } else { CxFunc2DnC_2A4P func = (CxFunc2DnC_2A4P)(minmaxmaskcoi_tab.fn_2d[depth]); if( !func ) CX_ERROR( CX_StsBadArg, cxUnsupportedFormat ); IPPI_CALL( func( mat->data.ptr, mat_step, matmask->data.ptr, mask_step, size, cn, coi, minVal, maxVal, minLoc, maxLoc )); } } if( depth < CX_32S || depth == CX_32F ) { if( minVal ) *minVal = *(float*)minVal; if( maxVal ) *maxVal = *(float*)maxVal; } __END__; }
CX_IMPL void icxLogicM( const void* srcimg1, const void* srcimg2, void* dstarr, const void* maskarr, CxArithmBinMaskFunc2D func ) { CX_FUNCNAME( "icxLogicM" ); __BEGIN__; int coi1 = 0, coi2 = 0, coi3 = 0; CxMat srcstub1, *src1 = (CxMat*)srcimg1; CxMat srcstub2, *src2 = (CxMat*)srcimg2; CxMat dststub, *dst = (CxMat*)dstarr; CxMat maskstub, *mask = (CxMat*)maskarr; int src_step, dst_step, mask_step; int pix_size; CxSize size; CX_CALL( src1 = cxGetMat( src1, &srcstub1, &coi1 )); CX_CALL( src2 = cxGetMat( src2, &srcstub2, &coi2 )); CX_CALL( dst = cxGetMat( dst, &dststub, &coi3 )); CX_CALL( mask = cxGetMat( mask, &maskstub )); if( coi1 != 0 || coi2 != 0 || coi3 != 0 ) CX_ERROR( CX_BadCOI, "" ); if( !CX_IS_MASK_ARR(mask) ) CX_ERROR_FROM_CODE( CX_StsBadMask ); if( !CX_ARE_SIZES_EQ( mask, dst ) ) CX_ERROR_FROM_CODE( CX_StsUnmatchedSizes ); if( !CX_ARE_SIZES_EQ( src1, src2 ) ) CX_ERROR_FROM_CODE( CX_StsUnmatchedSizes ); size = cxGetMatSize( src1 ); pix_size = icxPixSize[CX_MAT_TYPE(src1->type)]; if( src2->data.ptr != dst->data.ptr ) { if( src1->data.ptr != dst->data.ptr ) { CX_CALL( cxCopy( src2, dst, mask )); } else src1 = src2; } if( !CX_ARE_TYPES_EQ( src1, dst )) CX_ERROR_FROM_CODE( CX_StsUnmatchedFormats ); if( !CX_ARE_SIZES_EQ( src1, dst )) CX_ERROR_FROM_CODE( CX_StsUnmatchedSizes ); src_step = src1->step; dst_step = dst->step; mask_step = mask->step; if( CX_IS_MAT_CONT( src1->type & dst->type & mask->type )) { size.width *= size.height; src_step = dst_step = mask_step = CX_STUB_STEP; size.height = 1; } IPPI_CALL( func( src1->data.ptr, src_step, mask->data.ptr, mask_step, dst->data.ptr, dst_step, size, pix_size )); __END__; }