Bool readImageToTexture(CompScreen *screen, CompTexture *texture, const char *imageFileName, unsigned int *returnWidth, unsigned int *returnHeight) { void *image; int width, height; Bool status; if (!readImageFromFile(screen->display, imageFileName, &width, &height, &image)) return FALSE; status = imageBufferToTexture(screen, texture, image, width, height); free(image); if (returnWidth) *returnWidth = width; if (returnHeight) *returnHeight = height; return status; }
API OpenGLPrimitive *parseOpenGLScenePrimitiveHeightmap(Scene *scene, const char *path_prefix, const char *name, Store *store) { // Parse num parameter Store *heightmapParam; if((heightmapParam = getStorePath(store, "heightmap")) == NULL || heightmapParam->type != STORE_STRING) { logError("Failed to parse OpenGL scene primitive heightmap '%s': String parameter 'heightmap' not found", name); return NULL; } GString *path = g_string_new(path_prefix); g_string_append_printf(path, "/%s", heightmapParam->content.string); Image *image = readImageFromFile(path->str); if(image == NULL) { logError("Failed to parse OpenGL scene primitive heightmap '%s': Failed to load heightmap image from '%s'", name, path->str); g_string_free(path, true); return NULL; } g_string_free(path, true); // Create heightmap OpenGLPrimitive *primitive; if((primitive = createOpenGLPrimitiveHeightmap(image, image->width, image->height)) == NULL) { logError("Failed to parse OpenGL scene primitive heightmap '%s': Failed to create heightmap primitive from heightmap image", name); freeImage(image); return NULL; } return primitive; }
int main( int argc, char *argv[] ) { AR2JpegImageT *jpegImage = NULL; ARUint8 *image = NULL; AR2ImageSetT *imageSet = NULL; AR2FeatureMapT *featureMap = NULL; AR2FeatureSetT *featureSet = NULL; KpmRefDataSet *refDataSet = NULL; float scale1, scale2; int procMode; char buf[1024]; int num; int i, j; char *sep = NULL; time_t clock; int maxFeatureNum; int err; for( i = 1; i < argc; i++ ) { if( strncmp(argv[i], "-dpi=", 5) == 0 ) { if( sscanf(&argv[i][5], "%f", &dpi) != 1 ) usage(argv[0]); } else if( strncmp(argv[i], "-sd_thresh=", 11) == 0 ) { if( sscanf(&argv[i][11], "%f", &sd_thresh) != 1 ) usage(argv[0]); } else if( strncmp(argv[i], "-max_thresh=", 12) == 0 ) { if( sscanf(&argv[i][12], "%f", &max_thresh) != 1 ) usage(argv[0]); } else if( strncmp(argv[i], "-min_thresh=", 12) == 0 ) { if( sscanf(&argv[i][12], "%f", &min_thresh) != 1 ) usage(argv[0]); } else if( strncmp(argv[i], "-feature_density=", 13) == 0 ) { if( sscanf(&argv[i][13], "%d", &featureDensity) != 1 ) usage(argv[0]); } else if( strncmp(argv[i], "-level=", 7) == 0 ) { if( sscanf(&argv[i][7], "%d", &tracking_extraction_level) != 1 ) usage(argv[0]); } else if( strncmp(argv[i], "-leveli=", 8) == 0 ) { if( sscanf(&argv[i][8], "%d", &initialization_extraction_level) != 1 ) usage(argv[0]); } else if( strncmp(argv[i], "-max_dpi=", 9) == 0 ) { if( sscanf(&argv[i][9], "%f", &dpiMax) != 1 ) usage(argv[0]); } else if( strncmp(argv[i], "-min_dpi=", 9) == 0 ) { if( sscanf(&argv[i][9], "%f", &dpiMin) != 1 ) usage(argv[0]); } else if( strcmp(argv[i], "-background") == 0 ) { background = 1; } else if( strcmp(argv[i], "-nofset") == 0 ) { genfset = 0; } else if( strcmp(argv[i], "-fset") == 0 ) { genfset = 1; } else if( strcmp(argv[i], "-nofset2") == 0 ) { ARLOGe("Error: -nofset2 option no longer supported as of ARToolKit v5.3.\n"); exit(-1); } else if( strcmp(argv[i], "-fset2") == 0 ) { ARLOGe("Error: -fset2 option no longer supported as of ARToolKit v5.3.\n"); exit(-1); } else if( strcmp(argv[i], "-nofset3") == 0 ) { genfset3 = 0; } else if( strcmp(argv[i], "-fset3") == 0 ) { genfset3 = 1; } else if( strncmp(argv[i], "-log=", 5) == 0 ) { strncpy(logfile, &(argv[i][5]), sizeof(logfile) - 1); logfile[sizeof(logfile) - 1] = '\0'; // Ensure NULL termination. } else if( strncmp(argv[i], "-loglevel=", 10) == 0 ) { if (strcmp(&(argv[i][10]), "DEBUG") == 0) arLogLevel = AR_LOG_LEVEL_DEBUG; else if (strcmp(&(argv[i][10]), "INFO") == 0) arLogLevel = AR_LOG_LEVEL_INFO; else if (strcmp(&(argv[i][10]), "WARN") == 0) arLogLevel = AR_LOG_LEVEL_WARN; else if (strcmp(&(argv[i][10]), "ERROR") == 0) arLogLevel = AR_LOG_LEVEL_ERROR; else usage(argv[0]); } else if( strncmp(argv[i], "-exitcode=", 10) == 0 ) { strncpy(exitcodefile, &(argv[i][10]), sizeof(exitcodefile) - 1); exitcodefile[sizeof(exitcodefile) - 1] = '\0'; // Ensure NULL termination. } else if (strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-version") == 0 || strcmp(argv[i], "-v") == 0) { ARLOG("%s version %s\n", argv[0], AR_HEADER_VERSION_STRING); exit(0); } else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-?") == 0) { usage(argv[0]); } else if( filename[0] == '\0' ) { strncpy(filename, argv[i], sizeof(filename) - 1); filename[sizeof(filename) - 1] = '\0'; // Ensure NULL termination. } else { ARLOGe("Error: unrecognised option '%s'\n", argv[i]); usage(argv[0]); } } // Do some checks on the input. if (filename[0] == '\0') { ARLOGe("Error: no input file specified. Exiting.\n"); usage(argv[0]); } sep = strrchr(filename, '.'); if (!sep || (strcmp(sep, ".jpeg") && strcmp(sep, ".jpg") && strcmp(sep, ".jpe") && strcmp(sep, ".JPEG") && strcmp(sep, ".JPE") && strcmp(sep, ".JPG"))) { ARLOGe("Error: input file must be a JPEG image (with suffix .jpeg/.jpg/.jpe). Exiting.\n"); usage(argv[0]); } if (background) { #if HAVE_DAEMON_FUNC if (filename[0] != '/' || logfile[0] != '/' || exitcodefile[0] != '/') { ARLOGe("Error: -background flag requires full pathname of files (input, -log or -exitcode) to be specified. Exiting.\n"); EXIT(E_BAD_PARAMETER); } if (tracking_extraction_level == -1 && (sd_thresh == -1.0 || min_thresh == -1.0 || max_thresh == -1.0)) { ARLOGe("Error: -background flag requires -level or -sd_thresh, -min_thresh and -max_thresh -to be set. Exiting.\n"); EXIT(E_BAD_PARAMETER); } if (initialization_extraction_level == -1 && (featureDensity == -1)) { ARLOGe("Error: -background flag requires -leveli or -surf_thresh to be set. Exiting.\n"); EXIT(E_BAD_PARAMETER); } if (dpi == -1.0) { ARLOGe("Error: -background flag requires -dpi to be set. Exiting.\n"); EXIT(E_BAD_PARAMETER); } if (dpiMin != -1.0f && (dpiMin <= 0.0f || dpiMin > dpi)) { ARLOGe("Error: -min_dpi must be greater than 0 and less than or equal to -dpi. Exiting.n\n"); EXIT(E_BAD_PARAMETER); } if (dpiMax != -1.0f && (dpiMax < dpiMin || dpiMax > dpi)) { ARLOGe("Error: -max_dpi must be greater than or equal to -min_dpi and less than or equal to -dpi. Exiting.n\n"); EXIT(E_BAD_PARAMETER); } #else ARLOGe("Error: -background flag not supported on this operating system. Exiting.\n"); exit(E_BACKGROUND_OPERATION_UNSUPPORTED); #endif } if (background) { #if HAVE_DAEMON_FUNC // Daemonize. if (daemon(0, 0) == -1) { perror("Unable to detach from controlling terminal"); EXIT(E_UNABLE_TO_DETACH_FROM_CONTROLLING_TERMINAL); } // At this point, stdin, stdout and stderr point to /dev/null. #endif } if (logfile[0]) { if (!freopen(logfile, "a", stdout) || !freopen(logfile, "a", stderr)) ARLOGe("Unable to redirect stdout or stderr to logfile.\n"); } if (exitcodefile[0]) { atexit(write_exitcode); } // Print the start date and time. clock = time(NULL); if (clock != (time_t)-1) { struct tm *timeptr = localtime(&clock); if (timeptr) { char stime[26+8] = ""; if (strftime(stime, sizeof(stime), "%Y-%m-%d %H:%M:%S %z", timeptr)) // e.g. "1999-12-31 23:59:59 NZDT". ARLOGi("--\nGenerator started at %s\n", stime); } } if (genfset) { if (tracking_extraction_level == -1 && (sd_thresh == -1.0 || min_thresh == -1.0 || max_thresh == -1.0 || occ_size == -1)) { do { printf("Select extraction level for tracking features, 0(few) <--> 4(many), [default=%d]: ", TRACKING_EXTRACTION_LEVEL_DEFAULT); if( fgets(buf, sizeof(buf), stdin) == NULL ) EXIT(E_USER_INPUT_CANCELLED); if (buf[0] == '\n') tracking_extraction_level = TRACKING_EXTRACTION_LEVEL_DEFAULT; else sscanf(buf, "%d", &tracking_extraction_level); } while (tracking_extraction_level < 0 || tracking_extraction_level > 4); } switch (tracking_extraction_level) { case 0: if( sd_thresh == -1.0f ) sd_thresh = AR2_DEFAULT_SD_THRESH_L0; if( min_thresh == -1.0f ) min_thresh = AR2_DEFAULT_MIN_SIM_THRESH_L0; if( max_thresh == -1.0f ) max_thresh = AR2_DEFAULT_MAX_SIM_THRESH_L0; if( occ_size == -1 ) occ_size = AR2_DEFAULT_OCCUPANCY_SIZE; break; case 1: if( sd_thresh == -1.0f ) sd_thresh = AR2_DEFAULT_SD_THRESH_L1; if( min_thresh == -1.0f ) min_thresh = AR2_DEFAULT_MIN_SIM_THRESH_L1; if( max_thresh == -1.0f ) max_thresh = AR2_DEFAULT_MAX_SIM_THRESH_L1; if( occ_size == -1 ) occ_size = AR2_DEFAULT_OCCUPANCY_SIZE; break; case 2: if( sd_thresh == -1.0f ) sd_thresh = AR2_DEFAULT_SD_THRESH_L2; if( min_thresh == -1.0f ) min_thresh = AR2_DEFAULT_MIN_SIM_THRESH_L2; if( max_thresh == -1.0f ) max_thresh = AR2_DEFAULT_MAX_SIM_THRESH_L2; if( occ_size == -1 ) occ_size = AR2_DEFAULT_OCCUPANCY_SIZE*2/3; break; case 3: if( sd_thresh == -1.0f ) sd_thresh = AR2_DEFAULT_SD_THRESH_L3; if( min_thresh == -1.0f ) min_thresh = AR2_DEFAULT_MIN_SIM_THRESH_L3; if( max_thresh == -1.0f ) max_thresh = AR2_DEFAULT_MAX_SIM_THRESH_L3; if( occ_size == -1 ) occ_size = AR2_DEFAULT_OCCUPANCY_SIZE*2/3; break; case 4: // Same as 3, but with smaller AR2_DEFAULT_OCCUPANCY_SIZE. if( sd_thresh == -1.0f ) sd_thresh = AR2_DEFAULT_SD_THRESH_L3; if( min_thresh == -1.0f ) min_thresh = AR2_DEFAULT_MIN_SIM_THRESH_L3; if( max_thresh == -1.0f ) max_thresh = AR2_DEFAULT_MAX_SIM_THRESH_L3; if( occ_size == -1 ) occ_size = AR2_DEFAULT_OCCUPANCY_SIZE*1/2; break; default: // We only get to here if the parameters are already set. break; } ARLOGi("MAX_THRESH = %f\n", max_thresh); ARLOGi("MIN_THRESH = %f\n", min_thresh); ARLOGi("SD_THRESH = %f\n", sd_thresh); } if (genfset3) { if (initialization_extraction_level == -1 && featureDensity == -1) { do { printf("Select extraction level for initializing features, 0(few) <--> 3(many), [default=%d]: ", INITIALIZATION_EXTRACTION_LEVEL_DEFAULT); if( fgets(buf,1024,stdin) == NULL ) EXIT(E_USER_INPUT_CANCELLED); if (buf[0] == '\n') initialization_extraction_level = INITIALIZATION_EXTRACTION_LEVEL_DEFAULT; else sscanf(buf, "%d", &initialization_extraction_level); } while (initialization_extraction_level < 0 || initialization_extraction_level > 3); } switch(initialization_extraction_level) { case 0: if( featureDensity == -1 ) featureDensity = KPM_SURF_FEATURE_DENSITY_L0; break; default: case 1: if( featureDensity == -1 ) featureDensity = KPM_SURF_FEATURE_DENSITY_L1; break; case 2: if( featureDensity == -1 ) featureDensity = KPM_SURF_FEATURE_DENSITY_L2; break; case 3: if( featureDensity == -1 ) featureDensity = KPM_SURF_FEATURE_DENSITY_L3; break; } ARLOGi("SURF_FEATURE = %d\n", featureDensity); } if ((err = readImageFromFile(filename, &image, &xsize, &ysize, &nc, &dpi)) != 0) { ARLOGe("Error reading image from file '%s'.\n", filename); EXIT(err); } setDPI(); ARLOGi("Generating ImageSet...\n"); ARLOGi(" (Source image xsize=%d, ysize=%d, channels=%d, dpi=%.1f).\n", xsize, ysize, nc, dpi); imageSet = ar2GenImageSet( image, xsize, ysize, nc, dpi, dpi_list, dpi_num ); ar2FreeJpegImage(&jpegImage); if( imageSet == NULL ) { ARLOGe("ImageSet generation error!!\n"); EXIT(E_DATA_PROCESSING_ERROR); } ARLOGi(" Done.\n"); ar2UtilRemoveExt( filename ); ARLOGi("Saving to %s.iset...\n", filename); if( ar2WriteImageSet( filename, imageSet ) < 0 ) { ARLOGe("Save error: %s.iset\n", filename ); EXIT(E_DATA_PROCESSING_ERROR); } ARLOGi(" Done.\n"); if (genfset) { arMalloc( featureSet, AR2FeatureSetT, 1 ); // A featureSet with a single image, arMalloc( featureSet->list, AR2FeaturePointsT, imageSet->num ); // and with 'num' scale levels of this image. featureSet->num = imageSet->num; ARLOGi("Generating FeatureList...\n"); for( i = 0; i < imageSet->num; i++ ) { ARLOGi("Start for %f dpi image.\n", imageSet->scale[i]->dpi); featureMap = ar2GenFeatureMap( imageSet->scale[i], AR2_DEFAULT_TS1*AR2_TEMP_SCALE, AR2_DEFAULT_TS2*AR2_TEMP_SCALE, AR2_DEFAULT_GEN_FEATURE_MAP_SEARCH_SIZE1, AR2_DEFAULT_GEN_FEATURE_MAP_SEARCH_SIZE2, AR2_DEFAULT_MAX_SIM_THRESH2, AR2_DEFAULT_SD_THRESH2 ); if( featureMap == NULL ) { ARLOGe("Error!!\n"); EXIT(E_DATA_PROCESSING_ERROR); } ARLOGi(" Done.\n"); featureSet->list[i].coord = ar2SelectFeature2( imageSet->scale[i], featureMap, AR2_DEFAULT_TS1*AR2_TEMP_SCALE, AR2_DEFAULT_TS2*AR2_TEMP_SCALE, AR2_DEFAULT_GEN_FEATURE_MAP_SEARCH_SIZE2, occ_size, max_thresh, min_thresh, sd_thresh, &num ); if( featureSet->list[i].coord == NULL ) num = 0; featureSet->list[i].num = num; featureSet->list[i].scale = i; scale1 = 0.0f; for( j = 0; j < imageSet->num; j++ ) { if( imageSet->scale[j]->dpi < imageSet->scale[i]->dpi ) { if( imageSet->scale[j]->dpi > scale1 ) scale1 = imageSet->scale[j]->dpi; } } if( scale1 == 0.0f ) { featureSet->list[i].mindpi = imageSet->scale[i]->dpi * 0.5f; } else { /* scale2 = imageSet->scale[i]->dpi; scale = sqrtf( scale1 * scale2 ); featureSet->list[i].mindpi = scale2 / ((scale2/scale - 1.0f)*1.1f + 1.0f); */ featureSet->list[i].mindpi = scale1; } scale1 = 0.0f; for( j = 0; j < imageSet->num; j++ ) { if( imageSet->scale[j]->dpi > imageSet->scale[i]->dpi ) { if( scale1 == 0.0f || imageSet->scale[j]->dpi < scale1 ) scale1 = imageSet->scale[j]->dpi; } } if( scale1 == 0.0f ) { featureSet->list[i].maxdpi = imageSet->scale[i]->dpi * 2.0f; } else { //scale2 = imageSet->scale[i]->dpi * 1.2f; scale2 = imageSet->scale[i]->dpi; /* scale = sqrtf( scale1 * scale2 ); featureSet->list[i].maxdpi = scale2 * ((scale/scale2 - 1.0f)*1.1f + 1.0f); */ featureSet->list[i].maxdpi = scale2*0.8f + scale1*0.2f; } ar2FreeFeatureMap( featureMap ); } ARLOGi(" Done.\n"); ARLOGi("Saving FeatureSet...\n"); if( ar2SaveFeatureSet( filename, "fset", featureSet ) < 0 ) { ARLOGe("Save error: %s.fset\n", filename ); EXIT(E_DATA_PROCESSING_ERROR); } ARLOGi(" Done.\n"); ar2FreeFeatureSet( &featureSet ); } if (genfset3) { ARLOGi("Generating FeatureSet3...\n"); refDataSet = NULL; procMode = KpmProcFullSize; for( i = 0; i < imageSet->num; i++ ) { //if( imageSet->scale[i]->dpi > 100.0f ) continue; maxFeatureNum = featureDensity * imageSet->scale[i]->xsize * imageSet->scale[i]->ysize / (480*360); ARLOGi("(%d, %d) %f[dpi]\n", imageSet->scale[i]->xsize, imageSet->scale[i]->ysize, imageSet->scale[i]->dpi); if( kpmAddRefDataSet ( #if AR2_CAPABLE_ADAPTIVE_TEMPLATE imageSet->scale[i]->imgBWBlur[1], #else imageSet->scale[i]->imgBW, #endif AR_PIXEL_FORMAT_MONO, imageSet->scale[i]->xsize, imageSet->scale[i]->ysize, imageSet->scale[i]->dpi, procMode, KpmCompNull, maxFeatureNum, 1, i, &refDataSet) < 0 ) { // Page number set to 1 by default. ARLOGe("Error at kpmAddRefDataSet.\n"); EXIT(E_DATA_PROCESSING_ERROR); } } ARLOGi(" Done.\n"); ARLOGi("Saving FeatureSet3...\n"); if( kpmSaveRefDataSet(filename, "fset3", refDataSet) != 0 ) { ARLOGe("Save error: %s.fset2\n", filename ); EXIT(E_DATA_PROCESSING_ERROR); } ARLOGi(" Done.\n"); kpmDeleteRefDataSet( &refDataSet ); } ar2FreeImageSet( &imageSet ); // Print the start date and time. clock = time(NULL); if (clock != (time_t)-1) { struct tm *timeptr = localtime(&clock); if (timeptr) { char stime[26+8] = ""; if (strftime(stime, sizeof(stime), "%Y-%m-%d %H:%M:%S %z", timeptr)) // e.g. "1999-12-31 23:59:59 NZDT". ARLOGi("Generator finished at %s\n--\n", stime); } } exitcode = E_NO_ERROR; return (exitcode); }