Exemple #1
0
int arUtilChangeToResourcesDirectory(AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR behavior, const char *path)
#endif
{
    char *wpath;
    AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR behaviorW;
    
    if (behavior == AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_BEST) {
#if defined(__APPLE__)
        behaviorW = AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_BUNDLE_RESOURCES_DIR;
#elif defined(ANDROID)
        behaviorW = AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_APP_CACHE_DIR;
#elif defined(_WIN32) || defined(__linux)
        behaviorW = AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_EXECUTABLE_DIR;
#else
        behaviorW = AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_CWD;
#endif
    } else {
        behaviorW = behavior;
    }
    
    if (behaviorW != AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_SUPPLIED_PATH) {
#ifdef ANDROID
        wpath = arUtilGetResourcesDirectoryPath(behavior, instanceOfAndroidContext);
#else
        wpath = arUtilGetResourcesDirectoryPath(behavior);
#endif
        if (wpath) {
            if (chdir(wpath) != 0) {
                ARLOGe("Error: Unable to change working directory to '%s'.\n", wpath);
                ARLOGperror(NULL);
                free (wpath);
                return (-1);
            }
            free(wpath);
        }
    }
    if (path) {
        if (chdir(path) != 0) {
            ARLOGe("Error: Unable to change working directory to '%s'.\n", path);
            ARLOGperror(NULL);
            return (-1);
        }
    }
    
    return (0);
}
Exemple #2
0
AR2SurfaceSetT *ar2ReadSurfaceSet( const char *filename, const char *ext, ARPattHandle *pattHandle )
{
    AR2SurfaceSetT  *surfaceSet;
    FILE            *fp = NULL;
    int              readMode;
    char             buf[256], name[256];
    int              i, j, k;

    if( ext == NULL || *ext == '\0' || strcmp(ext,"fset") == 0 ) {
        strncpy(name, filename, sizeof(name) - 1);
        name[sizeof(name) - 1] = '\0';
        readMode = 0;
    }
    else {
        char namebuf[512];
        sprintf(namebuf, "%s.%s", filename, ext);
        if ((fp = fopen(namebuf,"r")) == NULL) {
            ARLOGe("Error opening file '%s': ", filename);
            ARLOGperror(NULL);
            return (NULL);
        }
        readMode = 1;
    }
    arMalloc(surfaceSet, AR2SurfaceSetT, 1);

    if( readMode ) {
        if( get_buff(buf, 256, fp) == NULL ) {
            fclose(fp);
            free(surfaceSet);
            return (NULL);
        }
        if( sscanf(buf, "%d", &i) != 1 ) {
            fclose(fp);
            free(surfaceSet);
            return (NULL);
        }
        if( i < 1 ) {
            fclose(fp);
            free(surfaceSet);
            return (NULL);
        }
        surfaceSet->num     = i;
        surfaceSet->contNum = 0;
    }
    else {
        surfaceSet->num     = 1;
        surfaceSet->contNum = 0;
    }
    arMalloc(surfaceSet->surface, AR2SurfaceT, surfaceSet->num);

    for( i = 0; i < surfaceSet->num; i++ ) {
        ARLOGi("\n### Surface No.%d ###\n", i+1);
        if( readMode ) {
            if( get_buff(buf, 256, fp) == NULL ) break;
            if( sscanf(buf, "%s", name) != 1 ) break;
            ar2UtilRemoveExt( name );
        }
        ARLOGi("  Read ImageSet.\n");
        surfaceSet->surface[i].imageSet = ar2ReadImageSet( name );
        if( surfaceSet->surface[i].imageSet == NULL ) {
            ARLOGe("Error opening file '%s.iset'.\n", name);
            free(surfaceSet->surface);
            free(surfaceSet);
			if (fp) fclose(fp); //COVHI10426
            return (NULL);
        }
        ARLOGi("    end.\n");

        ARLOGi("  Read FeatureSet.\n");
        surfaceSet->surface[i].featureSet = ar2ReadFeatureSet( name, "fset" );
        if( surfaceSet->surface[i].featureSet == NULL ) {
            ARLOGe("Error opening file '%s.fset'.\n", name);
            ar2FreeImageSet(&surfaceSet->surface[i].imageSet);
            free(surfaceSet->surface);
            free(surfaceSet);
			if (fp) fclose(fp); //COVHI10426
            return (NULL);
        }
        ARLOGi("    end.\n");

        if (pattHandle) {
            ARLOGi("  Read MarkerSet.\n");
            ar2UtilRemoveExt( name );
            surfaceSet->surface[i].markerSet = ar2ReadMarkerSet( name, "mrk", pattHandle );
            if( surfaceSet->surface[i].markerSet == NULL ) {
                ARLOGe("Error opening file '%s.mrk'.\n", name);
                ar2FreeFeatureSet(&surfaceSet->surface[i].featureSet);
                ar2FreeImageSet(&surfaceSet->surface[i].imageSet);
                free(surfaceSet->surface);
                free(surfaceSet);
                if (fp) fclose(fp); //COVHI10426
                return (NULL);
            }
            ARLOGi("    end.\n");
        } else {
            surfaceSet->surface[i].markerSet = NULL;
        }

        if (readMode) {
            if( get_buff(buf, 256, fp) == NULL ) break;
            if( sscanf(buf, "%f %f %f %f",
                       &(surfaceSet->surface[i].trans[0][0]),
                       &(surfaceSet->surface[i].trans[0][1]),
                       &(surfaceSet->surface[i].trans[0][2]),
                       &(surfaceSet->surface[i].trans[0][3])) != 4 ) {
                ARLOGe("Transformation matrix read error!!\n");
                fclose(fp);
                exit(0);
            }
            if( get_buff(buf, 256, fp) == NULL ) break;
            if( sscanf(buf, "%f %f %f %f",
                       &(surfaceSet->surface[i].trans[1][0]),
                       &(surfaceSet->surface[i].trans[1][1]),
                       &(surfaceSet->surface[i].trans[1][2]),
                       &(surfaceSet->surface[i].trans[1][3])) != 4 ) {
                ARLOGe("Transformation matrix read error!!\n");
                fclose(fp);
                exit(0);
            }
            if( get_buff(buf, 256, fp) == NULL ) break;
            if( sscanf(buf, "%f %f %f %f",
                       &(surfaceSet->surface[i].trans[2][0]),
                       &(surfaceSet->surface[i].trans[2][1]),
                       &(surfaceSet->surface[i].trans[2][2]),
                       &(surfaceSet->surface[i].trans[2][3])) != 4 ) {
                ARLOGe("Transformation matrix read error!!\n");
                fclose(fp);
                exit(0);
            }
        } else {
            for( j = 0; j < 3; j++ ) {
                for( k = 0; k < 4; k++ ) {
                    surfaceSet->surface[i].trans[j][k] = (j == k)? 1.0f: 0.0f;
                }
            }
        }
        arUtilMatInvf( (const float (*)[4])surfaceSet->surface[i].trans, surfaceSet->surface[i].itrans );

        ar2UtilReplaceExt( name, 256, "jpg");
        arMalloc( surfaceSet->surface[i].jpegName, char, 256);
        strncpy( surfaceSet->surface[i].jpegName, name, 256 );
    }

    if (fp) fclose(fp); //COVHI10459

    if (i < surfaceSet->num) exit(0);

    return surfaceSet;
}
ARMultiMarkerInfoT *arMultiReadConfigFile( const char *filename, ARPattHandle *pattHandle )
{
    FILE                   *fp;
    ARMultiEachMarkerInfoT *marker;
    ARMultiMarkerInfoT     *marker_info;
    ARdouble               wpos3d[4][2];
    char                   buf[256], pattPath[2048], dummy;
    int                    num;
    int                    patt_type = 0;
    int                    i, j;

    if ((fp = fopen(filename, "r")) == NULL) {
        ARLOGe("Error: unable to open multimarker config file '%s'.\n", filename);
        ARLOGperror(NULL);
        return NULL;
    }

    get_buff(buf, 256, fp);
    if( sscanf(buf, "%d", &num) != 1 ) {
        ARLOGe("Error processing multimarker config file '%s': First line must be number of marker configs to read.\n", filename);
        fclose(fp);
        return NULL;
    }
    ARLOGd("Reading %d markers from multimarker file '%s'\n", num, filename);

    arMalloc(marker, ARMultiEachMarkerInfoT, num);

    for( i = 0; i < num; i++ ) {
        get_buff(buf, 256, fp);
        if (sscanf(buf, 
#if defined(__LP64__) && !defined(__APPLE__)
                        "%lu%c",
#else
                        "%llu%c",
#endif
                         &(marker[i].globalID), &dummy) != 1) { // Try first as matrix code.
            
            if (!pattHandle) {
                ARLOGe("Error processing multimarker config file '%s': pattern '%s' specified in multimarker configuration while in barcode-only mode.\n", filename, buf);
                goto bail;
            }
            if (!arUtilGetDirectoryNameFromPath(pattPath, filename, sizeof(pattPath), 1)) { // Get directory prefix.
                ARLOGe("Error processing multimarker config file '%s': Unable to determine directory name.\n", filename);
                goto bail;
            }
            strncat(pattPath, buf, sizeof(pattPath) - strlen(pattPath) - 1); // Add name of file to open.
            if ((marker[i].patt_id = arPattLoad(pattHandle, pattPath)) < 0) {
                ARLOGe("Error processing multimarker config file '%s': Unable to load pattern '%s'.\n", filename, pattPath);
                goto bail;
            }
            marker[i].patt_type = AR_MULTI_PATTERN_TYPE_TEMPLATE;
            patt_type |= 0x01;
        } else {
            
            if ((marker[i].globalID & 0xffff8000ULL) == 0ULL) marker[i].patt_id = (int)(marker[i].globalID & 0x00007fffULL); // If upper 33 bits are zero, use lower 31 bits as regular matrix code.
            else marker[i].patt_id = 0;
            ARLOGd("Marker %3d is matrix code %llu.\n", i + 1, marker[i].globalID);
            marker[i].patt_type = AR_MULTI_PATTERN_TYPE_MATRIX;
            patt_type |= 0x02;
        }

        get_buff(buf, 256, fp);
        if( sscanf(buf,
#ifdef ARDOUBLE_IS_FLOAT
                   "%f",
#else
                   "%lf",
#endif
                   &marker[i].width) != 1 ) {
            ARLOGe("Error processing multimarker config file '%s', marker definition %3d: First line must be pattern width.\n", filename, i + 1);
            goto bail;
        }
        
        j = 0;
        get_buff(buf, 256, fp);
        if( sscanf(buf,
#ifdef ARDOUBLE_IS_FLOAT
                   "%f %f %f %f",
#else
                   "%lf %lf %lf %lf",
#endif
                   &marker[i].trans[j][0],
                   &marker[i].trans[j][1],
                   &marker[i].trans[j][2],
                   &marker[i].trans[j][3]) != 4 ) {
            // Perhaps this is an old ARToolKit v2.x multimarker file?
            // If so, then the next line is two values (center) and should be skipped.
            float t1, t2;
            if( sscanf(buf,
                       "%f %f",
                       &t1, &t2) != 2 ) {
                ARLOGe("Error processing multimarker config file '%s', marker definition %3d: Lines 2 - 4 must be marker transform.\n", filename, i + 1);
                goto bail;
            }
        } else j++;
        do {
            get_buff(buf, 256, fp);
            if( sscanf(buf, 
#ifdef ARDOUBLE_IS_FLOAT
                       "%f %f %f %f",
#else
                       "%lf %lf %lf %lf",
#endif
                       &marker[i].trans[j][0],
                       &marker[i].trans[j][1],
                       &marker[i].trans[j][2],
                       &marker[i].trans[j][3]) != 4 ) {
                ARLOGe("Error processing multimarker config file '%s', marker definition %3d: Lines 2 - 4 must be marker transform.\n", filename, i + 1);
                goto bail;
            }
            j++;
        } while (j < 3);
        arUtilMatInv( (const ARdouble (*)[4])marker[i].trans, marker[i].itrans );

        wpos3d[0][0] =  -marker[i].width/2.0;
        wpos3d[0][1] =   marker[i].width/2.0;
        wpos3d[1][0] =   marker[i].width/2.0;
        wpos3d[1][1] =   marker[i].width/2.0;
        wpos3d[2][0] =   marker[i].width/2.0;
        wpos3d[2][1] =  -marker[i].width/2.0;
        wpos3d[3][0] =  -marker[i].width/2.0;
        wpos3d[3][1] =  -marker[i].width/2.0;
        for( j = 0; j < 4; j++ ) {
            marker[i].pos3d[j][0] = marker[i].trans[0][0] * wpos3d[j][0]
                                  + marker[i].trans[0][1] * wpos3d[j][1]
                                  + marker[i].trans[0][3];
            marker[i].pos3d[j][1] = marker[i].trans[1][0] * wpos3d[j][0]
                                  + marker[i].trans[1][1] * wpos3d[j][1]
                                  + marker[i].trans[1][3];
            marker[i].pos3d[j][2] = marker[i].trans[2][0] * wpos3d[j][0]
                                  + marker[i].trans[2][1] * wpos3d[j][1]
                                  + marker[i].trans[2][3];
        }
    }

    fclose(fp);

    arMalloc(marker_info, ARMultiMarkerInfoT, 1);
    marker_info->marker     = marker;
    marker_info->marker_num = num;
    marker_info->prevF      = 0;
    if( (patt_type & 0x03) == 0x03 ) marker_info->patt_type = AR_MULTI_PATTERN_DETECTION_MODE_TEMPLATE_AND_MATRIX;
    else if( patt_type & 0x01 )    marker_info->patt_type = AR_MULTI_PATTERN_DETECTION_MODE_TEMPLATE;
    else                           marker_info->patt_type = AR_MULTI_PATTERN_DETECTION_MODE_MATRIX;
    marker_info->cfPattCutoff = AR_MULTI_CONFIDENCE_PATTERN_CUTOFF_DEFAULT;
    marker_info->cfMatrixCutoff = AR_MULTI_CONFIDENCE_MATRIX_CUTOFF_DEFAULT;

    return marker_info;
    
bail:
    fclose(fp);
    free(marker);
    return NULL;
}
Exemple #4
0
char *arUtilGetResourcesDirectoryPath(AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR behavior)
#endif
{
#ifndef _WINRT
    char *wpath1;
    char *wpath2;
#  ifdef _WIN32
	DWORD len;
#  endif
#endif
    AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR behaviorW;

    if (behavior == AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_BEST) {
#if defined(__APPLE__)
        behaviorW = AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_BUNDLE_RESOURCES_DIR;
#elif defined(ANDROID)
        behaviorW = AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_APP_CACHE_DIR;
#elif defined(_WIN32) || defined(__linux)
        behaviorW = AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_EXECUTABLE_DIR;
#else
        behaviorW = AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_CWD;
#endif
    } else {
        behaviorW = behavior;
    }

	switch (behaviorW) {
            
            
        case AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_EXECUTABLE_DIR:
#if (defined(_WIN32) && !defined(_WINRT)) || defined(__APPLE__) || defined(__linux)
            arMallocClear(wpath1, char, MAXPATHLEN);
#  if defined(_WIN32)
            len = GetModuleFileName(NULL, wpath1, MAXPATHLEN);    // NULL implies the current process.
            if (!len) {
                free (wpath1);
                return (NULL);
            }
#  elif defined(__APPLE__)
            uint32_t size = MAXPATHLEN;
            if (_NSGetExecutablePath(wpath1, &size) != 0) {
                free (wpath1);
                return (NULL);
            }
#  elif defined(__linux)
            ssize_t len;
            len = readlink("/proc/self/exe", wpath1, MAXPATHLEN - 1); // -1 as it is not NULL terminated.
            if (len == -1) {
                ARLOGperror(NULL);
                free (wpath1);
                return (NULL);
            }
            wpath1[len] = '\0'; // NULL terminate.
#  endif
            arMallocClear(wpath2, char, MAXPATHLEN);
            if (!arUtilGetDirectoryNameFromPath(wpath2, wpath1, MAXPATHLEN, 0)) {
                free (wpath1);
                free (wpath2);
                return (NULL);
            }
            free (wpath1);
            return (wpath2);
#else
            return (NULL); // Unsupported OS.
#endif
            break;
            
            
        case AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_BUNDLE_RESOURCES_DIR:
            return (NULL); // Unsupported OS.
            break;
            
            
        case AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_CWD:
#ifndef _WINRT

            arMallocClear(wpath1, char, MAXPATHLEN);
            if (!getcwd(wpath1, MAXPATHLEN)) {
                free(wpath1);
                return (NULL);
            }
            return (wpath1);
#else
			return (NULL); // Unsupported OS.
#endif
			break;
            
            
        case AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_USER_ROOT:
#if defined(_WIN32) && !defined(_WINRT)
            arMallocClear(wpath1, char, MAXPATHLEN);
            if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, 0, wpath1))) {
                free (wpath1);
                return (NULL);
            }
            return (wpath1);
#elif defined(ANDROID)
        {
            // Make JNI calls to get the external storage directory.
            
            // To begin, get a reference to the env and attach to it.
            JNIEnv *env;
            int isAttached = 0;
            jthrowable exception;
            if (((*gJavaVM)->GetEnv(gJavaVM, (void**)&env, JNI_VERSION_1_6)) < 0) {
                // Couldn't get JNI environment, so this thread is native.
                if (((*gJavaVM)->AttachCurrentThread(gJavaVM, &env, NULL)) < 0) {
                    ARLOGe("Error: Couldn't attach to Java VM.\n");
                    return (NULL);
                }
                isAttached = 1;
            }
            
            // Get File object for the external storage directory.
            jclass classEnvironment = (*env)->FindClass(env, "android/os/Environment");
            if (!classEnvironment) goto bailAndroid;
            jmethodID methodIDgetExternalStorageDirectory = (*env)->GetStaticMethodID(env, classEnvironment, "getExternalStorageDirectory", "()Ljava/io/File;"); // public static File getExternalStorageDirectory ()
            if (!methodIDgetExternalStorageDirectory) goto bailAndroid;
            jobject objectFile = (*env)->CallStaticObjectMethod(env, classEnvironment, methodIDgetExternalStorageDirectory);
            exception = (*env)->ExceptionOccurred(env);
            if (exception) {
                (*env)->ExceptionDescribe(env);
                (*env)->ExceptionClear(env);
            }
            
            // Call method on File object to retrieve String object.
            jclass classFile = (*env)->GetObjectClass(env, objectFile);
            if (!classFile) goto bailAndroid;
            jmethodID methodIDgetAbsolutePath = (*env)->GetMethodID(env, classFile, "getAbsolutePath", "()Ljava/lang/String;");
            if (!methodIDgetAbsolutePath) goto bailAndroid;
            jstring stringPath = (*env)->CallObjectMethod(env, objectFile, methodIDgetAbsolutePath);
            exception = (*env)->ExceptionOccurred(env);
            if (exception) {
                (*env)->ExceptionDescribe(env);
                (*env)->ExceptionClear(env);
            }
            // Extract a C string from the String object and copy it.
            const char *wpath3 = (*env)->GetStringUTFChars(env, stringPath, NULL);
            wpath1 = strdup(wpath3);
            (*env)->ReleaseStringUTFChars(env, stringPath, wpath3);
            
            goto retAndroid;
            
        bailAndroid:
            ARLOGe("Error: JNI call failure.\n");
            wpath1 = NULL;
        retAndroid:
            if (isAttached) (*gJavaVM)->DetachCurrentThread(gJavaVM); // Clean up.
            return (wpath1);
        }
#elif defined(__linux) || defined(__APPLE__)
            if (!((wpath1 = getenv("HOME")))) {
                return (NULL);
            }
            return (strdup(wpath1));
#else
            return (NULL); // Unsupported OS.
#endif
            break;
            
            
        case AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_APP_CACHE_DIR:
#if defined(_WIN32)
            return (NULL);
#elif defined(ANDROID)
        {
            // Make JNI calls to get the Context's cache directory.
            
            // To begin, get a reference to the env and attach to it.
            JNIEnv *env;
            int isAttached = 0;
            int ret = 0;
            jthrowable exception;
            if (((*gJavaVM)->GetEnv(gJavaVM, (void**)&env, JNI_VERSION_1_6)) < 0) {
                // Couldn't get JNI environment, so this thread is native.
                if (((*gJavaVM)->AttachCurrentThread(gJavaVM, &env, NULL)) < 0) {
                    ARLOGe("Error: Couldn't attach to Java VM.\n");
                    return (NULL);
                }
                isAttached = 1;
            }
            
            // Get File object for the Context's files directory. This only works
            // if a subclass of Context is supplied.
            // e.g. JNIEXPORT void JNICALL Java_com_test_TestActivity_test(JNIEnv * env, jobject obj)
            // so make sure before call.
            jclass classOfSuppliedObject = (*env)->GetObjectClass(env, instanceOfAndroidContext);
            if (!classOfSuppliedObject) goto bailAndroid1;
            jclass classContext = (*env)->FindClass(env, "android/content/Context");
            if (!classContext) goto bailAndroid1;
            if (!(*env)->IsInstanceOf(env, instanceOfAndroidContext, classContext)) {
                ARLOGe("Error: supplied object is not an instance of android/content/Context.\n");
                wpath1 = NULL; // Bad parameter.
                goto retAndroid1;
            }
            jmethodID methodGetDir = (*env)->GetMethodID(env, classOfSuppliedObject, "getCacheDir", "()Ljava/io/File;"); // public abstract File getCacheDir();
            //jmethodID methodGetDir = (*env)->GetMethodID(env, classOfSuppliedObject, "getFilesDir", "(Ljava/lang/String;)Ljava/io/File;"); // public abstract File getFilesDir(String type);
            if (!methodGetDir) goto bailAndroid1;
            jobject objectFile = (*env)->CallObjectMethod(env, instanceOfAndroidContext, methodGetDir);
            exception = (*env)->ExceptionOccurred(env);
            if (exception) {
                (*env)->ExceptionDescribe(env);
                (*env)->ExceptionClear(env);
            }
            
            // Call method on File object to retrieve String object.
            jclass classFile = (*env)->GetObjectClass(env, objectFile);
            if (!classFile) goto bailAndroid1;
            jmethodID methodIDgetAbsolutePath = (*env)->GetMethodID(env, classFile, "getAbsolutePath", "()Ljava/lang/String;");
            if (!methodIDgetAbsolutePath) goto bailAndroid1;
            jstring stringPath = (*env)->CallObjectMethod(env, objectFile, methodIDgetAbsolutePath);
            exception = (*env)->ExceptionOccurred(env);
            if (exception) {
                (*env)->ExceptionDescribe(env);
                (*env)->ExceptionClear(env);
            }
            // Extract a C string from the String object, and chdir() to it.
            const char *wpath3 = (*env)->GetStringUTFChars(env, stringPath, NULL);
            wpath1 = strdup(wpath3);
            (*env)->ReleaseStringUTFChars(env, stringPath, wpath3);
            
            goto retAndroid1;
            
        bailAndroid1:
            ARLOGe("Error: JNI call failure.\n");
            wpath1 = NULL;
        retAndroid1:
            if (isAttached) (*gJavaVM)->DetachCurrentThread(gJavaVM); // Clean up.
            return (wpath1);
        }
#else
            return (NULL); // Unsupported OS.
#endif
            break;

		case AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_APP_DATA_DIR:
#ifdef _WINRT
			//auto folder = Windows::Storage::ApplicationData::Current->LocalFolder;
			//wpath1 = strdup(folder->Path->Data().c_str());
			//return (wpath1);
			return (NULL); // Unsupported OS.
#else
			return (NULL); // Unsupported OS.
#endif
			break;

        case AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_SUPPLIED_PATH:
        default:
            return (NULL); // Undefined behaviour.
            break;
    }
}
Exemple #5
0
char *arUtilGetResourcesDirectoryPath(AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR behavior)
#endif
{
#ifndef _WINRT
    char *wpath1;
    char *wpath2;
#  ifdef _WIN32
	DWORD len;
#  endif
#endif
    AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR behaviorW;

    if (behavior == AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_BEST) {
#if defined(__APPLE__)
        behaviorW = AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_BUNDLE_RESOURCES_DIR;
#elif defined(ANDROID)
        behaviorW = AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_APP_CACHE_DIR;
#elif defined(_WIN32) || defined(__linux)
        behaviorW = AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_EXECUTABLE_DIR;
#else
        behaviorW = AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_CWD;
#endif
    } else {
        behaviorW = behavior;
    }

	switch (behaviorW) {
            
            
        case AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_EXECUTABLE_DIR:
#if (defined(_WIN32) && !defined(_WINRT)) || defined(__APPLE__) || defined(__linux)
            arMallocClear(wpath1, char, MAXPATHLEN);
#  if defined(_WIN32)
            len = GetModuleFileName(NULL, wpath1, MAXPATHLEN);    // NULL implies the current process.
            if (!len) {
                free (wpath1);
                return (NULL);
            }
#  elif defined(__APPLE__)
            uint32_t size = MAXPATHLEN;
            if (_NSGetExecutablePath(wpath1, &size) != 0) {
                free (wpath1);
                return (NULL);
            }
#  elif defined(__linux)
            ssize_t len;
            len = readlink("/proc/self/exe", wpath1, MAXPATHLEN - 1); // -1 as it is not NULL terminated.
            if (len == -1) {
                ARLOGperror(NULL);
                free (wpath1);
                return (NULL);
            }
            wpath1[len] = '\0'; // NULL terminate.
#  endif
            arMallocClear(wpath2, char, MAXPATHLEN);
            if (!arUtilGetDirectoryNameFromPath(wpath2, wpath1, MAXPATHLEN, 0)) {
                free (wpath1);
                free (wpath2);
                return (NULL);
            }
            free (wpath1);
            return (wpath2);
#else
            return (NULL); // Unsupported OS.
#endif
            break;
            
            
        case AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_BUNDLE_RESOURCES_DIR:
#if defined(__APPLE__)
        {
            // Change working directory to resources directory inside app bundle.
            wpath1 = NULL;
            CFURLRef pathCFURLRef = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); // Get relative path to resources directory.
            if (pathCFURLRef) {
                wpath1 = (char *)calloc(MAXPATHLEN, sizeof(char)); //getcwd(path, MAXPATHLEN);
                if (wpath1) {
                    if (!CFURLGetFileSystemRepresentation(pathCFURLRef, true, (UInt8*)wpath1, MAXPATHLEN)) { // true in param 2 resolves against base.
                        ARLOGe("Error: Unable to get file system representation of a CFURL.\n");
                        free(wpath1);
                        wpath1 = NULL;
                    }
                }
                CFRelease(pathCFURLRef);
            }
            return (wpath1);
        }
#else
            return (NULL); // Unsupported OS.
#endif
            break;
            
            
        case AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_CWD:
#ifndef _WINRT

            arMallocClear(wpath1, char, MAXPATHLEN);
            if (!getcwd(wpath1, MAXPATHLEN)) {
                free(wpath1);
                return (NULL);
            }
            return (wpath1);
#else
			return (NULL); // Unsupported OS.
#endif
			break;
            
            
        case AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_USER_ROOT:
#if defined(_WIN32) && !defined(_WINRT)
            arMallocClear(wpath1, char, MAXPATHLEN);
            if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, 0, wpath1))) {
                free (wpath1);
                return (NULL);
            }
            return (wpath1);
#elif defined(ANDROID)
        {
            // Make JNI calls to get the external storage directory.
            
            // To begin, get a reference to the env and attach to it.
            JNIEnv *env;
            int isAttached = 0;
            jthrowable exception;
            if (((*gJavaVM)->GetEnv(gJavaVM, (void**)&env, JNI_VERSION_1_6)) < 0) {
                // Couldn't get JNI environment, so this thread is native.
                if (((*gJavaVM)->AttachCurrentThread(gJavaVM, &env, NULL)) < 0) {
                    ARLOGe("Error: Couldn't attach to Java VM.\n");
                    return (NULL);
                }
                isAttached = 1;
            }
            
            // Get File object for the external storage directory.
            jclass classEnvironment = (*env)->FindClass(env, "android/os/Environment");
            if (!classEnvironment) goto bailAndroid;
            jmethodID methodIDgetExternalStorageDirectory = (*env)->GetStaticMethodID(env, classEnvironment, "getExternalStorageDirectory", "()Ljava/io/File;"); // public static File getExternalStorageDirectory ()
            if (!methodIDgetExternalStorageDirectory) goto bailAndroid;
            jobject objectFile = (*env)->CallStaticObjectMethod(env, classEnvironment, methodIDgetExternalStorageDirectory);
            exception = (*env)->ExceptionOccurred(env);
            if (exception) {
                (*env)->ExceptionDescribe(env);
                (*env)->ExceptionClear(env);
            }
            
            // Call method on File object to retrieve String object.
            jclass classFile = (*env)->GetObjectClass(env, objectFile);
            if (!classFile) goto bailAndroid;
            jmethodID methodIDgetAbsolutePath = (*env)->GetMethodID(env, classFile, "getAbsolutePath", "()Ljava/lang/String;");
            if (!methodIDgetAbsolutePath) goto bailAndroid;
            jstring stringPath = (*env)->CallObjectMethod(env, objectFile, methodIDgetAbsolutePath);
            exception = (*env)->ExceptionOccurred(env);
            if (exception) {
                (*env)->ExceptionDescribe(env);
                (*env)->ExceptionClear(env);
            }
            // Extract a C string from the String object and copy it.
            const char *wpath3 = (*env)->GetStringUTFChars(env, stringPath, NULL);
            wpath1 = strdup(wpath3);
            (*env)->ReleaseStringUTFChars(env, stringPath, wpath3);
            
            goto retAndroid;
            
        bailAndroid:
            ARLOGe("Error: JNI call failure.\n");
            wpath1 = NULL;
        retAndroid:
            if (isAttached) (*gJavaVM)->DetachCurrentThread(gJavaVM); // Clean up.
            return (wpath1);
        }
#elif defined(__APPLE__) && defined(__OBJC__) // iOS/OS X.
        {
            NSString *nssHomeDir = NSHomeDirectory(); // CoreFoundation equivalent is CFCopyHomeDirectoryURL(), iOS 6.0+ only.
            if (!nssHomeDir) {
                return (NULL);
            }
            wpath1 = strdup([nssHomeDir UTF8String]);
            return wpath1;
        }
#elif defined(__linux)
            if (!((wpath1 = getenv("HOME")))) {
                return (NULL);
            }
            return (strdup(wpath1));
#else
            return (NULL); // Unsupported OS.
#endif
            break;
            
            
        case AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_APP_CACHE_DIR:
#if defined(_WIN32)
            return (NULL);
#elif defined(__APPLE__) // iOS/OS X.
        {
#  ifdef __OBJC__
            NSURL *cacheDir = [[[NSFileManager defaultManager] URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] objectAtIndex:0];
            if (!cacheDir) {
                return (NULL);
            }
            wpath1 = strdup([[cacheDir path] UTF8String]);
#  else
            size_t len = confstr(_CS_DARWIN_USER_CACHE_DIR, NULL, 0);
            if (!len) return (NULL);
            wpath1 = (char *)malloc(len);
            len = confstr(_CS_DARWIN_USER_CACHE_DIR, wpath1, len); // On OS X, returns a folder in the sandbox hierachy under /var/folders/.
            if (!len) return (NULL);
#  endif
            return (wpath1);
        }
#elif defined(ANDROID)
        {
            // Make JNI calls to get the Context's cache directory.
            
            // To begin, get a reference to the env and attach to it.
            JNIEnv *env;
            int isAttached = 0;
            int ret = 0;
            jthrowable exception;
            if (((*gJavaVM)->GetEnv(gJavaVM, (void**)&env, JNI_VERSION_1_6)) < 0) {
                // Couldn't get JNI environment, so this thread is native.
                if (((*gJavaVM)->AttachCurrentThread(gJavaVM, &env, NULL)) < 0) {
                    ARLOGe("Error: Couldn't attach to Java VM.\n");
                    return (NULL);
                }
                isAttached = 1;
            }
            
            // Get File object for the Context's files directory. This only works
            // if a subclass of Context is supplied.
            // e.g. JNIEXPORT void JNICALL Java_com_test_TestActivity_test(JNIEnv * env, jobject obj)
            // so make sure before call.
            jclass classOfSuppliedObject = (*env)->GetObjectClass(env, instanceOfAndroidContext);
            if (!classOfSuppliedObject) goto bailAndroid1;
            jclass classContext = (*env)->FindClass(env, "android/content/Context");
            if (!classContext) goto bailAndroid1;
            if (!(*env)->IsInstanceOf(env, instanceOfAndroidContext, classContext)) {
                ARLOGe("Error: supplied object is not an instance of android/content/Context.\n");
                wpath1 = NULL; // Bad parameter.
                goto retAndroid1;
            }
            jmethodID methodGetDir = (*env)->GetMethodID(env, classOfSuppliedObject, "getCacheDir", "()Ljava/io/File;"); // public abstract File getCacheDir();
            //jmethodID methodGetDir = (*env)->GetMethodID(env, classOfSuppliedObject, "getFilesDir", "(Ljava/lang/String;)Ljava/io/File;"); // public abstract File getFilesDir(String type);
            if (!methodGetDir) goto bailAndroid1;
            jobject objectFile = (*env)->CallObjectMethod(env, instanceOfAndroidContext, methodGetDir);
            exception = (*env)->ExceptionOccurred(env);
            if (exception) {
                (*env)->ExceptionDescribe(env);
                (*env)->ExceptionClear(env);
            }
            
            // Call method on File object to retrieve String object.
            jclass classFile = (*env)->GetObjectClass(env, objectFile);
            if (!classFile) goto bailAndroid1;
            jmethodID methodIDgetAbsolutePath = (*env)->GetMethodID(env, classFile, "getAbsolutePath", "()Ljava/lang/String;");
            if (!methodIDgetAbsolutePath) goto bailAndroid1;
            jstring stringPath = (*env)->CallObjectMethod(env, objectFile, methodIDgetAbsolutePath);
            exception = (*env)->ExceptionOccurred(env);
            if (exception) {
                (*env)->ExceptionDescribe(env);
                (*env)->ExceptionClear(env);
            }
            // Extract a C string from the String object, and chdir() to it.
            const char *wpath3 = (*env)->GetStringUTFChars(env, stringPath, NULL);
            wpath1 = strdup(wpath3);
            (*env)->ReleaseStringUTFChars(env, stringPath, wpath3);
            
            goto retAndroid1;
            
        bailAndroid1:
            ARLOGe("Error: JNI call failure.\n");
            wpath1 = NULL;
        retAndroid1:
            if (isAttached) (*gJavaVM)->DetachCurrentThread(gJavaVM); // Clean up.
            return (wpath1);
        }
#else
            return (NULL); // Unsupported OS.
#endif
            break;

		case AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_APP_DATA_DIR:
#ifdef _WINRT
			//auto folder = Windows::Storage::ApplicationData::Current->LocalFolder;
			//wpath1 = strdup(folder->Path->Data().c_str());
			//return (wpath1);
			return (NULL); // Unsupported OS.
#else
			return (NULL); // Unsupported OS.
#endif
			break;

        case AR_UTIL_RESOURCES_DIRECTORY_BEHAVIOR_USE_SUPPLIED_PATH:
        default:
            return (NULL); // Undefined behaviour.
            break;
    }
}