/** * connect to the host * @param sock the sock object to use when connecting */ int sock_connect(sock_t * sock) { struct hostent *he; #ifdef DEBUG assert(NULL != sock); assert(NULL != sock->host); assert(0 != sock->port); #endif sock_create(sock); if (NULL == (he = gethostbyname(sock->host))) { ERRF(__FILE__, __LINE__, "gethostbyname: %s!\n", strerror(errno)); return 0; } sock->addr.sin_family = AF_INET; sock->addr.sin_port = htons(sock->port); sock->addr.sin_addr = *((struct in_addr *)he->h_addr); memset(&(sock->addr.sin_zero), '\0', 8); if (connect(sock->sock, (struct sockaddr *)&(sock->addr), sizeof(struct sockaddr)) == -1) { ERRF(__FILE__, __LINE__, "connecting to our host: %s!\n", strerror(errno)); return 0; } sock->connected = 1; return 1; }
/** * close a socket * @param sock the socket to destroy */ void sock_disconnect(sock_t * sock) { #ifdef DEBUG assert(NULL != sock); #endif if (INVALID_SOCKET == sock->sock) { /* do nothing. */ return; } if (shutdown(sock->sock, SHUT_WR)) { if (errno != WSAENOTCONN) { ERRF(__FILE__, __LINE__, "shutting down socket(%d)! %s\n", sock->sock, strerror(errno)); return; } } if (INVALID_SOCKET != sock->sock) { if (closesocket(sock->sock)) { ERRF(__FILE__, __LINE__, "closing socket! %s\n", strerror(errno)); return; } } sock->sock = INVALID_SOCKET; sock->connected = 0; }
/** * create a socket * @param sock the socket to create * @param type the type of socket to use; * @param host the hostname to use or contact * @param port the port to listen on or connect to */ int sock_create(sock_t * sock) { int y = 1; #ifdef DEBUG assert(NULL != sock); #endif sock_disconnect(sock); /* create the socket */ if ((sock->sock = socket(PF_INET, sock->proto, 0)) == -1) { ERRF(__FILE__, __LINE__, "creating socket: %s!\n", strerror(errno)); return 0; } /* get rid of any sockets that are sticking around if we are * encroaching on their port */ #ifdef WIN32 if (setsockopt (sock->sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&y, sizeof(int)) == -1) #else if (setsockopt(sock->sock, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(int)) == -1) #endif { ERRF(__FILE__, __LINE__, "removing any lingering sockets: %s!\n", strerror(errno)); return 0; } return 1; }
int tag_reg(struct file_operations * const fops, struct kobject *kobj) { int ret; kobj_tag = kobject_create_and_add("tag", kobj); if (kobj_tag == NULL) { ERRF("can not create kobject: kobj_bus\n"); return -1; } ret = sysfs_create_file(kobj_tag, &enable_attr.attr); if (ret != 0) { ERRF("Failed to create enable in sysfs\n"); kobject_del(kobj_tag); kobject_put(kobj_tag); kobj_tag = NULL; return ret; } ret = sysfs_create_file(kobj_tag, &dump_buffer_attr.attr); if (ret != 0) { ERRF("Failed to create dump_buffer in sysfs\n"); sysfs_remove_file(kobj_tag, &enable_attr.attr); kobject_del(kobj_tag); kobject_put(kobj_tag); kobj_tag = NULL; return ret; } ret = sysfs_create_file(kobj_tag, &options_attr.attr); if (ret != 0) { ERRF("Failed to create options in sysfs\n"); sysfs_remove_file(kobj_tag, &enable_attr.attr); sysfs_remove_file(kobj_tag, &dump_buffer_attr.attr); kobject_del(kobj_tag); kobject_put(kobj_tag); kobj_tag = NULL; return ret; } fops->open = met_open; fops->release = met_close; fops->unlocked_ioctl = met_ioctl; fops->read = met_read; fops->write = met_write; met_tag_init(); met_ext_api.met_tag_start = met_tag_start_real; met_ext_api.met_tag_end = met_tag_end_real; met_ext_api.met_tag_oneshot = met_tag_oneshot_real; met_ext_api.met_tag_dump = met_tag_dump_real; met_ext_api.met_tag_disable = met_tag_disable_real; met_ext_api.met_tag_enable = met_tag_enable_real; met_ext_api.met_set_dump_buffer = met_set_dump_buffer_real; met_ext_api.met_save_dump_buffer = met_save_dump_buffer_real; met_ext_api.met_save_log = met_save_log_real; return 0; }
/** * push an entry onto the stack * @param stack the stack to push on to * @param entry the data to place in the node */ void stack_push(sstack_t * stk, void *entry) { stacknode_t *node; void *tmp; #ifdef DEBUG assert(NULL != stk); assert(NULL != stk->data_alloc); #endif if (NULL == entry) { tmp = stk->data_alloc(NULL); if (NULL == tmp) { /* sigh... */ ERRF(__FILE__, __LINE__, "ERROR: allocating for new data entry in stack node!\n"); exit(1); } } else { tmp = stk->data_alloc(entry); } if (NULL == stk->node) { stk->node = calloc(1, sizeof *(stk->node)); if (NULL == stk->node) { ERRF(__FILE__, __LINE__, "ERROR: allocating for a new stack node!\n"); exit(1); } stk->node->next = NULL; stk->node->prev = NULL; stk->node->data = tmp; stk->first = stk->node; } else { node = calloc(1, sizeof *node); if (NULL == node) { ERRF(__FILE__, __LINE__, "ERROR: allocating for a new stack node!\n"); exit(1); } node->prev = stk->node; node->next = NULL; node->data = tmp; stk->node = node; } ++stk->count; }
/** * initialize an allocated socket * @param sock the socket to initialize * @param port the port to listen on */ int sock_init(sock_t * sock, unsigned int proto, unsigned int type, const char *host, unsigned short port) { #ifdef DEBUG assert(NULL != sock); assert(proto != 0); assert(NULL != host); assert(0 != port); #endif #ifdef WIN32 WSADATA data; if (SOCKET_ERROR == WSAStartup(0x0202, &data)) { ERRF(__FILE__, __LINE__, "error starting up Windows sockets!\n"); return 0; } #endif sock->sock = INVALID_SOCKET; sock->port = port; sock->host = strdup(host); memset(sock->ip, 0, sizeof sock->ip); sock->proto = proto; sock->connected = 0; /* clear sockaddr structures */ memset(&sock->addr, 0, sizeof sock->addr); return 1; }
/** * send data to the sock * @param sock the sock structure object * @param buf the buffer to send * @param size the size of the data to send */ size_t sock_send(sock_t * sock, const void *buf, size_t size) { int nleft = (signed)size; int wrote = 0; #ifdef DEBUG assert(NULL != sock); assert(NULL != buf); assert(size != 0); #endif while (nleft > 0) { if ((wrote = send(sock->sock, (char *)buf + wrote, nleft, 0)) <= 0) { if (errno == EINTR) { wrote = 0; } else { ERRF(__FILE__, __LINE__, "sending data! %s\n", strerror(errno)); return 0; } } nleft -= wrote; } return size; }
int met_set_dump_buffer_real(int size) { if (dump_buffer_size && dump_buffer) { free_pages((unsigned long)dump_buffer, get_order(dump_buffer_size)); dump_data_size = 0; dump_overrun = 0; dump_overrun_size = 0; dump_seq_no = 0; dump_buffer_size = 0; } //size is 0 means free dump buffer if (size == 0) return 0; size = (size + (PAGE_SIZE - 1)) & (~(PAGE_SIZE - 1)); dump_buffer = (void*)__get_free_pages(GFP_KERNEL, get_order(size)); if (dump_buffer == NULL) { ERRF("can not allocate buffer to copy\n"); return -ENOMEM; } dump_buffer_size = size; return dump_buffer_size; }
/** * initialize an allocated vector * @param vec the vector to initialize * @param slots the number of slots to allocate. * @param size the size of each member */ int vector_init(vector_t * vec, unsigned int slots, unsigned int size) { #ifdef DEBUG assert(NULL != vec); assert(0 != size); #endif if (!slots) { /* guess 16 *shrug* */ vec->slots = 16; } else { vec->slots = slots; } vec->size = size; vec->count = 0; vec->data = calloc(1, vec->slots * vec->size); if (NULL == vec->data) { ERRF(__FILE__, __LINE__, "allocating vector data table (slots=%u,size=%u)!\n", vec->slots, vec->size); return 0; } memset(vec->data, '\0', (vec->slots * vec->size)); return 1; }
int main(int argc, char *argv[]) { char *host; unsigned int port, i; if (argc != 3) { ERRF(__FILE__, __LINE__, "./srvtest hostname port\n"); return 1; } host = strdup(argv[1]); port = (unsigned int)strtol(argv[2], NULL, 0); for (i = 0; i < SRV_TEST_LEVEL; i++) { /* get these threads rollin' */ sock_init(&sock[i], SOCK_STREAM, SOCK_TYPE_CLIENT, host, port); pthread_mutex_init(&mt[i], NULL); pthread_create(&p[i], NULL, srv_test_handler, (void *)i); pthread_detach(p[i]); } free(host); for (i = 0; i < SRV_TEST_LEVEL; i++) { /* shut it down */ pthread_mutex_lock(&mt[i]); } return 0; }
int initialize_cdev(void) { int ret; if((ret = register_chrdev(MAJOR_NUM, DEVICE_NAME, &fops)) < 0) { ERRF("Failed to register device. ERR: %d", ret); return ret; } LOGF("Got %d, lets get cracking", ret); return ret; }
/** * close a socket */ void srv_conn_cleanup(conn_t * conn) { #ifdef DEBUG assert(NULL != conn); #endif if (-1 == conn->sock) { /* do nothing. */ return; } if (conn->state != CONN_STATE_DESTROY) DEBUGF(__FILE__, __LINE__, "(sock:%d) preemptive close of connection\n", conn->sock); /* nicer way to close instead of straight disconnect */ if (shutdown(conn->sock, SHUT_WR)) { if (errno != ENOTCONN) { ERRF(__FILE__, __LINE__, "shutting down socket(%d)! %s\n", conn->sock, strerror(errno)); return; } } /* if the shutdown wasn't respected... */ if (-1 != conn->sock) { if (close(conn->sock)) { ERRF(__FILE__, __LINE__, "closing socket! %s\n", strerror(errno)); return; } } if (conn->fd) { /* our filehandle still open */ close(conn->fd); } conn->fd = 0; conn->sock = -1; conn->state = CONN_STATE_NEW; conn->locked = 0; memset(&conn->addr, 0, sizeof &conn->addr); }
/** * list a directory */ file_t *srv_list_dir(const char *dir, unsigned int *cnt) { file_t *list, *f; struct dirent **ent; char tmp[512], *c; struct stat st; struct tm *tm; int i; #ifdef DEBUG assert(NULL != dir); assert(NULL != cnt); #endif i = scandir(dir, &ent, _srv_list_filter, alphasort); if (i < 0) { /* an error occurred! */ *cnt = 0; return NULL; } *cnt = i; list = calloc(*cnt, sizeof *list); if (NULL == list) { ERRF(__FILE__, __LINE__, "allocation error!\n"); return NULL; } /* filename thinnng */ snprintf(tmp, sizeof tmp, "%s/", dir); c = &tmp[strlen(tmp)]; /* right after the '/' */ /* lets fill our list */ for (i = 0; i < (signed)*cnt; i++) { f = &list[i]; strcpy(c, ent[i]->d_name); stat(tmp, &st); tm = localtime(&st.st_mtime); f->name = strdup(ent[i]->d_name); f->size = st.st_size; f->type = st.st_mode; snprintf(f->mod, sizeof f->mod, "%02u/%02u/%02u %02u:%02u:%02u", tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900, tm->tm_hour, tm->tm_min, tm->tm_sec); free(ent[i]); } return list; }
int met_save_dump_buffer_real(const char *pathname) { int size, ret = 0; struct file *outfp = NULL; mm_segment_t oldfs; if (dump_data_size == 0) return 0; outfp = filp_open(pathname, O_WRONLY|O_TRUNC|O_CREAT, 0644); if (unlikely(outfp == NULL)) { ERRF("can not open saved file for write\n"); return -EIO; } oldfs = get_fs(); set_fs(KERNEL_DS); if (dump_overrun) { size = dump_overrun_size; } else { size = dump_data_size; } ret = vfs_write(outfp, dump_buffer, size, &(outfp->f_pos)); if (ret < 0) { ERRF("can not write to dump file\n"); } else { dump_data_size = 0; dump_overrun = 0; dump_overrun_size = 0; dump_seq_no = 0; } set_fs(oldfs); return 0; }
/** * create a new vector * @param slots the initial number of slots to allocate. If 0, we guess. * @param size the size of each data member we'll be inserting */ vector_t *vector_new(unsigned int slots, unsigned int size) { vector_t *vec = calloc(1, sizeof *vec); if (NULL == vec) { ERRF(__FILE__, __LINE__, "allocating for a new vector!\n"); return NULL; } vector_init(vec, slots, size); return vec; }
/** * create a new listening socket * @param port the port to listen on */ sock_t *sock_new(unsigned int proto, unsigned int type, const char *host, unsigned short port) { sock_t *sock; #ifdef DEBUG assert(proto != 0); #endif sock = calloc(1, sizeof *sock); if (NULL == sock) { ERRF(__FILE__, __LINE__, "error allocating memory for new sock!\n"); return NULL; } memset(sock, 0, sizeof *sock); if (!sock_init(sock, proto, type, host, port)) { ERRF(__FILE__, __LINE__, "error creating socket, aborting...\n"); exit(1); } return sock; }
/* create */ int tpool_init(tpool_t * tp, unsigned int cnt, tfunc controller, tfunc handler) { int i; #ifdef DEBUG assert(NULL != tp); assert(NULL != handler); #endif tp->cnt = cnt; tp->pool = malloc(tp->cnt * (sizeof *(tp->pool))); tp->handler = handler; tp->controller = controller; tp->jobcount = 0; /* set up mutex */ pthread_mutex_init(&tp->mutex, NULL); /* get work queue ready */ stack_init(&tp->work); /* set up the control thread */ pthread_create(&tp->boss.th, NULL, tp->controller, NULL); tp->boss.id = 0; tp->boss.job = 0; tp->boss.busy = 0; pthread_mutex_init(&tp->boss.mt, NULL); pthread_mutex_lock(&tp->boss.mt); pthread_detach(tp->boss.th); for (i = 0; i < (signed)tp->cnt; ++i) { if (pthread_create (&tp->pool[i].th, NULL, tp->handler, (void *)i)) { /* trouble... */ ERRF(__FILE__, __LINE__, "error creating thread %d in pool.\n", i); return 0; } /* automatic cleanup */ tp->pool[i].id = i; tp->pool[i].job = 0; tp->pool[i].busy = 0; pthread_mutex_init(&tp->pool[i].mt, NULL); pthread_mutex_lock(&tp->pool[i].mt); pthread_detach(tp->pool[i].th); } return 1; }
/** * wrap the listen call * @param sock the sock to listen on */ int sock_listen(sock_t * sock) { #ifdef DEBUG assert(NULL != sock); #endif /* begin listening on the desired port */ if (listen(sock->sock, 512) == -1) { ERRF(__FILE__, __LINE__, "listening on socket: %s!\n", strerror(errno)); return 0; } return 1; }
/** * create a new stack */ sstack_t *stack_new(void) { sstack_t *stk; stk = calloc(1, sizeof *stk); if (NULL == stk) { ERRF(__FILE__, __LINE__, "ERROR: allocating for a new stack!\n"); exit(1); } stack_init(stk); return stk; }
void *srv_test_handler(void *arg) { char *request; char buf[1024]; unsigned int i, id; sock_t *s; id = (unsigned int)arg; s = &sock[id]; pthread_mutex_lock(&mt[id]); request = strdup("GET / HTTP/1.0\r\n\r\n"); for (i = 0; i < SRV_TEST_ITERS; i++) { memset(buf, '\0', sizeof buf); if (!sock_connect(s)) ERRF(__FILE__, __LINE__, "connecting to host!\n"); if (!sock_send(s, request, strlen(request))) ERRF(__FILE__, __LINE__, "sending request!\n"); usleep(500); if (!sock_recv(s, buf, sizeof buf)) ERRF(__FILE__, __LINE__, "getting response!\n"); sock_disconnect(s); usleep(500); printf("%s\n", buf); } pthread_mutex_unlock(&mt[id]); free(request); return NULL; }
/** * recv some data from the sock! * @param sock the sock structure object * @param buf a void pointer to a buffer to fille * @param size the number of bytes to read into buf */ size_t sock_recv(sock_t * sock, void *buf, size_t size) { int got; #ifdef DEBUG assert(NULL != sock); assert(size != 0); #endif got = recv(sock->sock, (char *)buf, (int)size, 0); if (!got) { return 0; } else if (got == -1) { ERRF(__FILE__, __LINE__, "recieving data! %s\n", strerror(errno)); return 0; } return (size_t) got; }
/** * double the number of slots available to a vector * @param vec the vector to grow */ int vector_resize(vector_t * vec) { void *tmp; #ifdef DEBUG assert(NULL != vec); #endif tmp = realloc(vec->data, vec->slots * 2 * vec->size); if (NULL == tmp) { ERRF(__FILE__, __LINE__, "reallocating vector data buffer\n"); return 0; } vec->data = tmp; vec->slots *= 2; return 1; }
/** * add a value to the vector * @param vec the vector to append the value to * @param val the vlue to add */ int vector_push(vector_t * vec, void *val) { #ifdef DEBUG assert(NULL != vec); assert(NULL != val); #endif if (vec->count == (vec->slots - 1)) { /* too big, add more slots */ if (!vector_resize(vec)) { /* sorry! */ ERRF(__FILE__, __LINE__, "could not resize vector, failed...\n"); return 0; } } vector_set_at(vec, vec->count, val); return 1; }
/** * set a value at a certain point on the vector * @param vec the vector whose value to modify * @param index the location of the value to modify * @param val the new value to insert */ int vector_set_at(vector_t * vec, unsigned int index, void *val) { #ifdef DEBUG assert(NULL != vec); assert(NULL != val); #endif while (index >= vec->slots) { /* resize until our table is big enough. */ if (!vector_resize(vec)) { ERRF(__FILE__, __LINE__, "could not set value at specified location\n"); return 0; } } memcpy((char *)vec->data + (index * vec->size), val, vec->size); ++vec->count; return 1; }
int srv_resp_cache(resp_t * resp, const char *path) { int fd; size_t got, pos = 0; resp->data = calloc(1, resp->len); if (NULL == resp->data) return 0; if (!(fd = open(resp->file, O_RDONLY))) { ERRF(__FILE__, __LINE__, "opening file for caching\n"); return 0; } while ((got = read(fd, &resp->data[pos], 1024))) pos += got; resp->pregen = 1; close(fd); return 1; }
/** * the bind call * @param sock the socket to bind to */ int sock_bind(sock_t * sock) { #ifdef DEBUG assert(NULL != sock); #endif sock_create(sock); sock->addr.sin_family = AF_INET; sock->addr.sin_port = htons(sock->port); sock->addr.sin_addr.s_addr = INADDR_ANY; memset(&(sock->addr.sin_zero), '\0', 8); /* bind to the port we want */ if (bind(sock->sock, (struct sockaddr *)&sock->addr, sizeof(struct sockaddr)) == -1) { ERRF(__FILE__, __LINE__, "binding socket to port %u: %s!\n", sock->port, strerror(errno)); return 0; } return 1; }
/** @brief SIFT driver entry point **/ int main(int argc, char **argv) { /* algorithm parameters */ double edge_thresh = -1 ; double peak_thresh = -1 ; double magnif = -1 ; int O = -1, S = 3, omin = -1 ; vl_bool err = VL_ERR_OK ; char err_msg [1024] ; int n ; int exit_code = 0 ; int verbose = 0 ; vl_bool force_output = 0 ; vl_bool force_orientations = 0 ; VlFileMeta out = {1, "%.sift", VL_PROT_ASCII, "", 0} ; VlFileMeta frm = {0, "%.frame", VL_PROT_ASCII, "", 0} ; VlFileMeta dsc = {0, "%.descr", VL_PROT_ASCII, "", 0} ; VlFileMeta met = {0, "%.meta", VL_PROT_ASCII, "", 0} ; VlFileMeta gss = {0, "%.pgm", VL_PROT_ASCII, "", 0} ; VlFileMeta ifr = {0, "%.frame", VL_PROT_ASCII, "", 0} ; #define ERRF(msg, arg) { \ err = VL_ERR_BAD_ARG ; \ snprintf(err_msg, sizeof(err_msg), msg, arg) ; \ break ; \ } #define ERR(msg) { \ err = VL_ERR_BAD_ARG ; \ snprintf(err_msg, sizeof(err_msg), msg) ; \ break ; \ } /* ----------------------------------------------------------------- * Parse options * -------------------------------------------------------------- */ while (!err) { int ch = getopt_long(argc, argv, opts, longopts, 0) ; /* If there are no files passed as input, print the help and settings */ if (ch == -1 && argc - optind == 0) ch = 'h'; /* end of option list? */ if (ch == -1) break; switch (ch) { case '?' : /* unkown option ............................................ */ ERRF("Invalid option '%s'.", argv [optind - 1]) ; break ; case ':' : /* missing argument ......................................... */ ERRF("Missing mandatory argument for option '%s'.", argv [optind - 1]) ; break ; case 'h' : /* --help ................................................... */ printf (help_message, argv [0]) ; printf ("SIFT filespec: `%s'\n", out.pattern) ; printf ("Frames filespec: `%s'\n", frm.pattern) ; printf ("Descriptors filespec: `%s'\n", dsc.pattern) ; printf ("Meta filespec: `%s'\n", met.pattern) ; printf ("GSS filespec: '%s'\n", gss.pattern) ; printf ("Read frames filespec: '%s'\n", ifr.pattern) ; printf ("Version: driver %s; libvl %s\n", VL_XSTRINGIFY(VL_SIFT_DRIVER_VERSION), vl_get_version_string()) ; exit (0) ; break ; case 'v' : /* --verbose ................................................ */ ++ verbose ; break ; case 'o' : /* --output ................................................ */ err = vl_file_meta_parse (&out, optarg) ; if (err) ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ; force_output = 1 ; break ; case opt_frames : /* --frames ................................................ */ err = vl_file_meta_parse (&frm, optarg) ; if (err) ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ; break ; case opt_descriptors : /* --descriptor ............................................. */ err = vl_file_meta_parse (&dsc, optarg) ; if (err) ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ; break; case opt_meta : /* --meta ................................................... */ err = vl_file_meta_parse (&met, optarg) ; if (err) ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ; if (met.protocol != VL_PROT_ASCII) ERR("meta file supports only ASCII protocol") ; break ; case opt_read_frames : /* --read_frames ............................................ */ err = vl_file_meta_parse (&ifr, optarg) ; if (err) ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ; break ; case opt_gss : /* --gss .................................................... */ err = vl_file_meta_parse (&gss, optarg) ; if (err) ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ; break ; case 'O' : /* --octaves ............................................... */ n = sscanf (optarg, "%d", &O) ; if (n == 0 || O < 0) ERRF("The argument of '%s' must be a non-negative integer.", argv [optind - 1]) ; break ; case 'S' : /* --levels ............................................... */ n = sscanf (optarg, "%d", &S) ; if (n == 0 || S < 0) ERRF("The argument of '%s' must be a non-negative integer.", argv [optind - 1]) ; break ; case opt_first_octave : /* --first-octave ......................................... */ n = sscanf (optarg, "%d", &omin) ; if (n == 0) ERRF("The argument of '%s' must be an integer.", argv [optind - 1]) ; break ; case opt_edge_thresh : /* --edge-thresh ........................................... */ n = sscanf (optarg, "%lf", &edge_thresh) ; if (n == 0 || edge_thresh < 1) ERRF("The argument of '%s' must be not smaller than 1.", argv [optind - 1]) ; break ; case opt_peak_thresh : /* --edge-thresh ........................................... */ n = sscanf (optarg, "%lf", &peak_thresh) ; if (n == 0 || peak_thresh < 0) ERRF("The argument of '%s' must be a non-negative float.", argv [optind - 1]) ; break ; case opt_magnif : /* --magnif .............................................. */ n = sscanf (optarg, "%lf", &magnif) ; if (n == 0 || magnif < 1) ERRF("The argument of '%s' must be a non-negative float.", argv [optind - 1]) ; break ; case opt_orientations : /* --orientations ......................................... */ force_orientations = 1 ; break ; case 0 : default : /* should not get here ...................................... */ assert (0) ; break ; } } /* check for parsing errors */ if (err) { fprintf(stderr, "%s: error: %s (%d)\n", argv [0], err_msg, err) ; exit (1) ; } /* parse other arguments (filenames) */ argc -= optind ; argv += optind ; /* if --output is not specified, specifying --frames or --descriptors prevent the aggregate outout file to be produced. */ if (! force_output && (frm.active || dsc.active)) { out.active = 0 ; } if (verbose > 1) { #define PRNFO(name,fm) \ printf("sift: " name) ; \ printf("%3s ", (fm).active ? "yes" : "no") ; \ printf("%-6s ", vl_string_protocol_name ((fm).protocol)) ; \ printf("%-10s\n", (fm).pattern) ; PRNFO("write aggregate . ", out) ; PRNFO("write frames .... ", frm) ; PRNFO("write descriptors ", dsc) ; PRNFO("write meta ...... ", met) ; PRNFO("write GSS ....... ", gss) ; PRNFO("read frames .... ", ifr) ; if (force_orientations) printf("sift: will compute orientations\n") ; } /* ------------------------------------------------------------------ * Process one image per time * --------------------------------------------------------------- */ while (argc--) { char basename [1024] ; char const *name = *argv++ ; FILE *in = 0 ; vl_uint8 *data = 0 ; vl_sift_pix *fdata = 0 ; VlPgmImage pim ; VlSiftFilt *filt = 0 ; int q, i ; vl_bool first ; double *ikeys = 0 ; int nikeys = 0, ikeys_size = 0 ; /* ............................................................... * Determine files * ............................................................ */ /* get basenmae from filename */ q = vl_string_basename (basename, sizeof(basename), name, 1) ; err = (q >= sizeof(basename)) ; if (err) { snprintf(err_msg, sizeof(err_msg), "Basename of '%s' is too long", name); err = VL_ERR_OVERFLOW ; goto done ; } if (verbose) { printf ("sift: <== '%s'\n", name) ; } if (verbose > 1) { printf ("sift: basename is '%s'\n", basename) ; } /* open input file */ in = fopen (name, "rb") ; if (!in) { err = VL_ERR_IO ; snprintf(err_msg, sizeof(err_msg), "Could not open '%s' for reading.", name) ; goto done ; } /* ............................................................... * Read data * ............................................................ */ /* read PGM header */ err = vl_pgm_extract_head (in, &pim) ; if (err) { switch (vl_err_no) { case VL_ERR_PGM_IO : snprintf(err_msg, sizeof(err_msg), "Cannot read from '%s'.", name) ; err = VL_ERR_IO ; break ; case VL_ERR_PGM_INV_HEAD : snprintf(err_msg, sizeof(err_msg), "'%s' contains a malformed PGM header.", name) ; err = VL_ERR_IO ; goto done ; } } if (verbose) printf ("sift: image is %d by %d pixels\n", pim. width, pim. height) ; /* allocate buffer */ data = malloc(vl_pgm_get_npixels (&pim) * vl_pgm_get_bpp (&pim) * sizeof (vl_uint8) ) ; fdata = malloc(vl_pgm_get_npixels (&pim) * vl_pgm_get_bpp (&pim) * sizeof (vl_sift_pix)) ; if (!data || !fdata) { err = VL_ERR_ALLOC ; snprintf(err_msg, sizeof(err_msg), "Could not allocate enough memory.") ; goto done ; } /* read PGM body */ err = vl_pgm_extract_data (in, &pim, data) ; if (err) { snprintf(err_msg, sizeof(err_msg), "PGM body malformed.") ; err = VL_ERR_IO ; goto done ; } /* convert data type */ for (q = 0 ; q < pim.width * pim.height ; ++q) fdata [q] = data [q] ; /* ............................................................... * Optionally source keypoints * ............................................................ */ #define WERR(name,op) \ if (err == VL_ERR_OVERFLOW) { \ snprintf(err_msg, sizeof(err_msg), \ "Output file name too long.") ; \ goto done ; \ } else if (err) { \ snprintf(err_msg, sizeof(err_msg), \ "Could not open '%s' for " #op, name) ; \ goto done ; \ } if (ifr.active) { /* open file */ err = vl_file_meta_open (&ifr, basename, "rb") ; WERR(ifr.name, reading) ; #define QERR \ if (err ) { \ snprintf (err_msg, sizeof(err_msg), \ "'%s' malformed", ifr.name) ; \ err = VL_ERR_IO ; \ goto done ; \ } while (1) { double x, y, s, th ; /* read next guy */ err = vl_file_meta_get_double (&ifr, &x) ; if (err == VL_ERR_EOF) break; else QERR ; err = vl_file_meta_get_double (&ifr, &y ) ; QERR ; err = vl_file_meta_get_double (&ifr, &s ) ; QERR ; err = vl_file_meta_get_double (&ifr, &th) ; if (err == VL_ERR_EOF) break; else QERR ; /* make enough space */ if (ikeys_size < nikeys + 1) { ikeys_size += 10000 ; ikeys = realloc (ikeys, 4 * sizeof(double) * ikeys_size) ; } /* add the guy to the buffer */ ikeys [4 * nikeys + 0] = x ; ikeys [4 * nikeys + 1] = y ; ikeys [4 * nikeys + 2] = s ; ikeys [4 * nikeys + 3] = th ; ++ nikeys ; } /* now order by scale */ qsort (ikeys, nikeys, 4 * sizeof(double), korder) ; if (verbose) { printf ("sift: read %d keypoints from '%s'\n", nikeys, ifr.name) ; } /* close file */ vl_file_meta_close (&ifr) ; } /* ............................................................... * Open output files * ............................................................ */ err = vl_file_meta_open (&out, basename, "wb") ; WERR(out.name, writing) ; err = vl_file_meta_open (&dsc, basename, "wb") ; WERR(dsc.name, writing) ; err = vl_file_meta_open (&frm, basename, "wb") ; WERR(frm.name, writing) ; err = vl_file_meta_open (&met, basename, "wb") ; WERR(met.name, writing) ; if (verbose > 1) { if (out.active) printf("sift: writing all ....... to . '%s'\n", out.name); if (frm.active) printf("sift: writing frames .... to . '%s'\n", frm.name); if (dsc.active) printf("sift: writing descriptors to . '%s'\n", dsc.name); if (met.active) printf("sift: writign meta ...... to . '%s'\n", met.name); } /* ............................................................... * Make filter * ............................................................ */ filt = vl_sift_new (pim.width, pim.height, O, S, omin) ; if (edge_thresh >= 0) vl_sift_set_edge_thresh (filt, edge_thresh) ; if (peak_thresh >= 0) vl_sift_set_peak_thresh (filt, peak_thresh) ; if (magnif >= 0) vl_sift_set_magnif (filt, magnif) ; if (!filt) { snprintf (err_msg, sizeof(err_msg), "Could not create SIFT filter.") ; err = VL_ERR_ALLOC ; goto done ; } if (verbose > 1) { printf ("sift: filter settings:\n") ; printf ("sift: octaves (O) = %d\n", vl_sift_get_noctaves (filt)) ; printf ("sift: levels (S) = %d\n", vl_sift_get_nlevels (filt)) ; printf ("sift: first octave (o_min) = %d\n", vl_sift_get_octave_first (filt)) ; printf ("sift: edge thresh = %g\n", vl_sift_get_edge_thresh (filt)) ; printf ("sift: peak thresh = %g\n", vl_sift_get_peak_thresh (filt)) ; printf ("sift: magnif = %g\n", vl_sift_get_magnif (filt)) ; printf ("sift: will source frames? %s\n", ikeys ? "yes" : "no") ; printf ("sift: will force orientations? %s\n", force_orientations ? "yes" : "no") ; } /* ............................................................... * Process each octave * ............................................................ */ i = 0 ; first = 1 ; while (1) { VlSiftKeypoint const *keys ; int nkeys ; /* calculate the GSS for the next octave .................... */ if (first) { first = 0 ; err = vl_sift_process_first_octave (filt, fdata) ; } else { err = vl_sift_process_next_octave (filt) ; } if (err) { err = VL_ERR_OK ; break ; } if (verbose > 1) { printf("sift: GSS octave %d computed\n", vl_sift_get_octave_index (filt)); } /* optionally save GSS */ if (gss.active) { err = save_gss (filt, &gss, basename, verbose) ; if (err) { snprintf (err_msg, sizeof(err_msg), "Could not write GSS to PGM file.") ; goto done ; } } /* run detector ............................................. */ if (ikeys == 0) { vl_sift_detect (filt) ; keys = vl_sift_get_keypoints (filt) ; nkeys = vl_sift_get_nkeypoints (filt) ; i = 0 ; if (verbose > 1) { printf ("sift: detected %d (unoriented) keypoints\n", nkeys) ; } } else { nkeys = nikeys ; } /* for each keypoint ........................................ */ for (; i < nkeys ; ++i) { double angles [4] ; int nangles ; VlSiftKeypoint ik ; VlSiftKeypoint const *k ; /* obtain keypoint orientations ........................... */ if (ikeys) { vl_sift_keypoint_init (filt, &ik, ikeys [4 * i + 0], ikeys [4 * i + 1], ikeys [4 * i + 2]) ; if (ik.o != vl_sift_get_octave_index (filt)) { break ; } k = &ik ; /* optionally compute orientations too */ if (force_orientations) { nangles = vl_sift_calc_keypoint_orientations (filt, angles, k) ; } else { angles [0] = ikeys [4 * i + 3] ; nangles = 1 ; } } else { k = keys + i ; nangles = vl_sift_calc_keypoint_orientations (filt, angles, k) ; } /* for each orientation ................................... */ for (q = 0 ; q < nangles ; ++q) { vl_sift_pix descr [128] ; /* compute descriptor (if necessary) */ if (out.active || dsc.active) { vl_sift_calc_keypoint_descriptor (filt, descr, k, angles [q]) ; } if (out.active) { int l ; vl_file_meta_put_double (&out, k -> x ) ; vl_file_meta_put_double (&out, k -> y ) ; vl_file_meta_put_double (&out, k -> sigma ) ; vl_file_meta_put_double (&out, angles [q] ) ; for (l = 0 ; l < 128 ; ++l) { vl_file_meta_put_uint8 (&out, (vl_uint8) (512.0 * descr [l])) ; } if (out.protocol == VL_PROT_ASCII) fprintf(out.file, "\n") ; } if (frm.active) { vl_file_meta_put_double (&frm, k -> x ) ; vl_file_meta_put_double (&frm, k -> y ) ; vl_file_meta_put_double (&frm, k -> sigma ) ; vl_file_meta_put_double (&frm, angles [q] ) ; if (frm.protocol == VL_PROT_ASCII) fprintf(frm.file, "\n") ; } if (dsc.active) { int l ; for (l = 0 ; l < 128 ; ++l) { double x = 512.0 * descr[l] ; x = (x < 255.0) ? x : 255.0 ; vl_file_meta_put_uint8 (&dsc, (vl_uint8) (x)) ; } if (dsc.protocol == VL_PROT_ASCII) fprintf(dsc.file, "\n") ; } } } } /* ............................................................... * Finish up * ............................................................ */ if (met.active) { fprintf(met.file, "<sift\n") ; fprintf(met.file, " input = '%s'\n", name) ; if (dsc.active) { fprintf(met.file, " descriptors = '%s'\n", dsc.name) ; } if (frm.active) { fprintf(met.file," frames = '%s'\n", frm.name) ; } fprintf(met.file, ">\n") ; } done : /* release input keys buffer */ if (ikeys) { free (ikeys) ; ikeys_size = nikeys = 0 ; ikeys = 0 ; } /* release filter */ if (filt) { vl_sift_delete (filt) ; filt = 0 ; } /* release image data */ if (fdata) { free (fdata) ; fdata = 0 ; } /* release image data */ if (data) { free (data) ; data = 0 ; } /* close files */ if (in) { fclose (in) ; in = 0 ; } vl_file_meta_close (&out) ; vl_file_meta_close (&frm) ; vl_file_meta_close (&dsc) ; vl_file_meta_close (&met) ; vl_file_meta_close (&gss) ; vl_file_meta_close (&ifr) ; /* if bad print error message */ if (err) { fprintf (stderr, "sift: err: %s (%d)\n", err_msg, err) ; exit_code = 1 ; } } /* quit */ return exit_code ; }
/** @brief MSER driver entry point **/ int main(int argc, char **argv) { /* algorithm parameters */ double delta = -1 ; double max_area = -1 ; double min_area = -1 ; double max_variation = -1 ; double min_diversity = -1 ; int bright_on_dark = 1 ; int dark_on_bright = 1 ; vl_bool err = VL_ERR_OK ; char err_msg [1024] ; int n ; int exit_code = 0 ; int verbose = 0 ; VlFileMeta frm = {0, "%.frame", VL_PROT_ASCII, "", 0} ; VlFileMeta piv = {0, "%.mser", VL_PROT_ASCII, "", 0} ; VlFileMeta met = {0, "%.meta", VL_PROT_ASCII, "", 0} ; #define ERRF(msg, arg) { \ err = VL_ERR_BAD_ARG ; \ snprintf(err_msg, sizeof(err_msg), msg, arg) ; \ break ; \ } #define ERR(msg) { \ err = VL_ERR_BAD_ARG ; \ snprintf(err_msg, sizeof(err_msg), msg) ; \ break ; \ } /* ------------------------------------------------------------------ * Parse options * --------------------------------------------------------------- */ while (!err) { int ch = getopt_long(argc, argv, opts, longopts, 0) ; /* If there are no files passed as input, print the help and settings */ if (ch == -1 && argc - optind == 0) ch = 'h'; /* end of option list? */ if (ch == -1) break; /* process options */ switch (ch) { /* .......................................................... */ case '?' : ERRF("Invalid option '%s'.", argv [optind - 1]) ; break ; case ':' : ERRF("Missing mandatory argument for option '%s'.", argv [optind - 1]) ; break ; case 'h' : printf (help_message, argv [0]) ; printf ("MSERs filespec: `%s'\n", piv.pattern) ; printf ("Frames filespec: `%s'\n", frm.pattern) ; printf ("Meta filespec: `%s'\n", met.pattern) ; printf ("Version: driver %s; libvl %s\n", VL_XSTRINGIFY(VL_MSER_DRIVER_VERSION), vl_get_version_string()) ; exit (0) ; break ; case 'v' : ++ verbose ; break ; /* .......................................................... */ case 'd' : n = sscanf (optarg, "%lf", &delta) ; if (n == 0 || delta < 0) ERRF("The argument of '%s' must be a non-negative number.", argv [optind - 1]) ; break ; /* ........................................................... */ case opt_max_area : n = sscanf (optarg, "%lf", &max_area) ; if (n == 0 || max_area < 0 || max_area > 1) ERR("max-area argument must be in the [0,1] range.") ; break ; case opt_min_area : n = sscanf (optarg, "%lf", &min_area) ; if (n == 0 || min_area < 0 || min_area > 1) ERR("min-area argument must be in the [0,1] range.") ; break ; case opt_max_variation : n = sscanf (optarg, "%lf", &max_variation) ; if (n == 0 || max_variation < 0) ERR("max-variation argument must be non-negative.") ; break ; case opt_min_diversity : n = sscanf (optarg, "%lf", &min_diversity) ; if (n == 0 || min_diversity < 0 || min_diversity > 1) ERR("min-diversity argument must be in the [0,1] range.") ; break ; /* ........................................................... */ case opt_frame : err = vl_file_meta_parse (&frm, optarg) ; if (err) ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ; break ; case opt_seed : err = vl_file_meta_parse (&piv, optarg) ; if (err) ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ; break ; case opt_meta : err = vl_file_meta_parse (&met, optarg) ; if (err) ERRF("The arguments of '%s' is invalid.", argv [optind - 1]) ; if (met.protocol != VL_PROT_ASCII) ERR("meta file supports only ASCII protocol") ; break ; case opt_bright : n = sscanf (optarg, "%d", &bright_on_dark) ; if (n == 0 || (bright_on_dark != 0 && bright_on_dark != 1)) ERR("bright_on_dark must be 0 or 1.") ; break ; case opt_dark : n = sscanf (optarg, "%d", &dark_on_bright) ; if (n == 0 || (dark_on_bright != 0 && dark_on_bright != 1)) ERR("dark_on_bright must be 0 or 1.") ; break ; /* .......................................................... */ case 0 : default : abort() ; } } /* check for parsing errors */ if (err) { fprintf(stderr, "%s: error: %s (%d)\n", argv [0], err_msg, err) ; exit (1) ; } /* parse other arguments (filenames) */ argc -= optind ; argv += optind ; /* make sure at least one file */ if (piv.active == 0 && frm.active == 0) { frm.active = 1 ; } if (verbose > 1) { printf("mser: frames output\n") ; printf("mser: active %d\n", frm.active ) ; printf("mser: pattern %s\n", frm.pattern) ; printf("mser: protocol %s\n", vl_string_protocol_name (frm.protocol)) ; printf("mser: seeds output\n") ; printf("mser: active %d\n", piv.active ) ; printf("mser: pattern %s\n", piv.pattern) ; printf("mser: protocol %s\n", vl_string_protocol_name (piv.protocol)) ; printf("mser: meta output\n") ; printf("mser: active %d\n", met.active ) ; printf("mser: pattern %s\n", met.pattern) ; printf("mser: protocol %s\n", vl_string_protocol_name (met.protocol)) ; } /* ------------------------------------------------------------------ * Process one image per time * --------------------------------------------------------------- */ while (argc--) { char basename [1024] ; char const *name = *argv++ ; VlMserFilt *filt = 0 ; VlMserFilt *filtinv = 0 ; vl_uint8 *data = 0 ; vl_uint8 *datainv = 0 ; VlPgmImage pim ; vl_uint const *regions ; vl_uint const *regionsinv ; float const *frames ; float const *framesinv ; enum {ndims = 2} ; int dims [ndims] ; int nregions = 0, nregionsinv = 0, nframes = 0, nframesinv =0; int i, j, dof ; vl_size q ; FILE *in = 0 ; /* Open files ------------------------------------------------ */ /* get basenmae from filename */ q = vl_string_basename (basename, sizeof(basename), name, 1) ; err = (q >= sizeof(basename)) ; if (err) { snprintf(err_msg, sizeof(err_msg), "Basename of '%s' is too long", name); err = VL_ERR_OVERFLOW ; goto done ; } if (verbose) { printf("mser: processing '%s'\n", name) ; } if (verbose > 1) { printf("mser: basename is '%s'\n", basename) ; } #define WERR(name) \ if (err == VL_ERR_OVERFLOW) { \ snprintf(err_msg, sizeof(err_msg), \ "Output file name too long.") ; \ goto done ; \ } else if (err) { \ snprintf(err_msg, sizeof(err_msg), \ "Could not open '%s' for writing.", name) ; \ goto done ; \ } /* open input file */ in = fopen (name, "rb") ; if (!in) { err = VL_ERR_IO ; snprintf(err_msg, sizeof(err_msg), "Could not open '%s' for reading.", name) ; goto done ; } /* open output files */ err = vl_file_meta_open (&piv, basename, "w") ; WERR(piv.name) ; err = vl_file_meta_open (&frm, basename, "w") ; WERR(frm.name) ; err = vl_file_meta_open (&met, basename, "w") ; WERR(met.name) ; if (verbose > 1) { if (piv.active) printf("mser: writing seeds to '%s'\n", piv.name); if (frm.active) printf("mser: writing frames to '%s'\n", frm.name); if (met.active) printf("mser: writing meta to '%s'\n", met.name); } /* Read image data -------------------------------------------- */ /* read source image header */ err = vl_pgm_extract_head (in, &pim) ; if (err) { err = VL_ERR_IO ; snprintf(err_msg, sizeof(err_msg), "PGM header corrputed.") ; goto done ; } if (verbose) { printf("mser: image is %d by %d pixels\n", pim. width, pim. height) ; } /* allocate buffer */ data = malloc(vl_pgm_get_npixels (&pim) * vl_pgm_get_bpp (&pim)) ; if (!data) { err = VL_ERR_ALLOC ; snprintf(err_msg, sizeof(err_msg), "Could not allocate enough memory.") ; goto done ; } /* read PGM */ err = vl_pgm_extract_data (in, &pim, data) ; if (err) { snprintf(err_msg, sizeof(err_msg), "PGM body corrputed.") ; goto done ; } /* Process data ---------------------------------------------- */ dims[0] = pim.width ; dims[1] = pim.height ; filt = vl_mser_new (ndims, dims) ; filtinv = vl_mser_new (ndims, dims) ; if (!filt || !filtinv) { snprintf(err_msg, sizeof(err_msg), "Could not create an MSER filter.") ; goto done ; } if (delta >= 0) vl_mser_set_delta (filt, (vl_mser_pix) delta) ; if (max_area >= 0) vl_mser_set_max_area (filt, max_area) ; if (min_area >= 0) vl_mser_set_min_area (filt, min_area) ; if (max_variation >= 0) vl_mser_set_max_variation (filt, max_variation) ; if (min_diversity >= 0) vl_mser_set_min_diversity (filt, min_diversity) ; if (delta >= 0) vl_mser_set_delta (filtinv, (vl_mser_pix) delta) ; if (max_area >= 0) vl_mser_set_max_area (filtinv, max_area) ; if (min_area >= 0) vl_mser_set_min_area (filtinv, min_area) ; if (max_variation >= 0) vl_mser_set_max_variation (filtinv, max_variation) ; if (min_diversity >= 0) vl_mser_set_min_diversity (filtinv, min_diversity) ; if (verbose) { printf("mser: parameters:\n") ; printf("mser: delta = %d\n", vl_mser_get_delta (filt)) ; printf("mser: max_area = %g\n", vl_mser_get_max_area (filt)) ; printf("mser: min_area = %g\n", vl_mser_get_min_area (filt)) ; printf("mser: max_variation = %g\n", vl_mser_get_max_variation (filt)) ; printf("mser: min_diversity = %g\n", vl_mser_get_min_diversity (filt)) ; } if (dark_on_bright) { vl_mser_process (filt, (vl_mser_pix*) data) ; /* Save result ----------------------------------------------- */ nregions = vl_mser_get_regions_num (filt) ; regions = vl_mser_get_regions (filt) ; if (piv.active) { for (i = 0 ; i < nregions ; ++i) { fprintf(piv.file, "%d ", regions [i]) ; } } if (frm.active) { vl_mser_ell_fit (filt) ; nframes = vl_mser_get_ell_num (filt) ; dof = vl_mser_get_ell_dof (filt) ; frames = vl_mser_get_ell (filt) ; for (i = 0 ; i < nframes ; ++i) { for (j = 0 ; j < dof ; ++j) { fprintf(frm.file, "%f ", *frames++) ; } fprintf(frm.file, "\n") ; } } } if (bright_on_dark) { /* allocate buffer */ datainv = malloc(vl_pgm_get_npixels (&pim) * vl_pgm_get_bpp (&pim)) ; for (i = 0; i < vl_pgm_get_npixels (&pim); i++) { datainv[i] = ~data[i]; /* 255 - data[i] */ } if (!datainv) { err = VL_ERR_ALLOC ; snprintf(err_msg, sizeof(err_msg), "Could not allocate enough memory.") ; goto done ; } vl_mser_process (filtinv, (vl_mser_pix*) datainv) ; /* Save result ----------------------------------------------- */ nregionsinv = vl_mser_get_regions_num (filtinv) ; regionsinv = vl_mser_get_regions (filtinv) ; if (piv.active) { for (i = 0 ; i < nregionsinv ; ++i) { fprintf(piv.file, "%d ", -regionsinv [i]) ; } } if (frm.active) { vl_mser_ell_fit (filtinv) ; nframesinv = vl_mser_get_ell_num (filtinv) ; dof = vl_mser_get_ell_dof (filtinv) ; framesinv = vl_mser_get_ell (filtinv) ; for (i = 0 ; i < nframesinv ; ++i) { for (j = 0 ; j < dof ; ++j) { fprintf(frm.file, "%f ", *framesinv++) ; } fprintf(frm.file, "\n") ; } } } if (met.active) { fprintf(met.file, "<mser\n") ; fprintf(met.file, " input = '%s'\n", name) ; if (piv.active) { fprintf(met.file, " seeds = '%s'\n", piv.name) ; } if (frm.active) { fprintf(met.file," frames = '%s'\n", frm.name) ; } fprintf(met.file, ">\n") ; } /* Next guy ----------------------------------------------- */ done : /* release filter */ if (filt) { vl_mser_delete (filt) ; filt = 0 ; } if (filtinv) { vl_mser_delete (filtinv) ; filtinv = 0 ; } /* release image data */ if (data) { free (data) ; data = 0 ; } if (datainv) { free (datainv) ; datainv = 0 ; } /* close files */ if (in) { fclose (in) ; in = 0 ; } vl_file_meta_close (&frm) ; vl_file_meta_close (&piv) ; vl_file_meta_close (&met) ; /* if bad print error message */ if (err) { fprintf (stderr, "mser: err: %s (%d)\n", err_msg, err) ; exit_code = 1 ; } } /* quit */ return exit_code ; }
static long met_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { /* mtag_cmd_t cblk; */ mtag_cmd_t *pUserCmd; int ret = 0; DEBF("mtag_ioctl cmd=%X, arg=%lX\n", cmd, arg); if (_IOC_TYPE(cmd) != MTAG_IOC_MAGIC) return -ENOTTY; /* Hanlde command without copying data from user space */ if (cmd == MTAG_CMD_ENABLE) return met_tag_enable_real((unsigned int)arg); else if (cmd == MTAG_CMD_DISABLE) return met_tag_disable_real((unsigned int)arg); else if (cmd == MTAG_CMD_REC_SET) { if (arg) tracing_on(); else tracing_off(); return 0; } else if (cmd == MTAG_CMD_DUMP_SIZE) { ret = met_set_dump_buffer_real((int)arg); return (long)ret; } /* Handle commands with user space data */ if (_IOC_DIR(cmd) & _IOC_WRITE) ret = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd)); if (ret) return -EFAULT; pUserCmd = (mtag_cmd_t *) arg; #if 0 __get_user(cblk.class_id, (unsigned int __user *)(&(pUserCmd->class_id))); __get_user(cblk.value, (unsigned int __user *)(&(pUserCmd->value))); __get_user(cblk.slen, (unsigned int __user *)(&(pUserCmd->slen))); ret = __copy_from_user(cblk.tname, (char __user *)(&(pUserCmd->tname)), cblk.slen); if (unlikely(ret)) { ERRF("Failed to __copy_from_user: ret=%d\n", ret); return -EFAULT; } switch (cmd) { case MTAG_CMD_START: ret = met_tag_start_real(cblk.class_id, (char *)cblk.tname); break; case MTAG_CMD_END: ret = met_tag_end_real(cblk.class_id, (char *)cblk.tname); break; case MTAG_CMD_ONESHOT: ret = met_tag_oneshot_real(cblk.class_id, (char *)cblk.tname, cblk.value); break; default: return -EINVAL; } #else switch (cmd) { case MTAG_CMD_START: ret = met_tag_start_real(pUserCmd->class_id, pUserCmd->tname); break; case MTAG_CMD_END: ret = met_tag_end_real(pUserCmd->class_id, pUserCmd->tname); break; case MTAG_CMD_ONESHOT: ret = met_tag_oneshot_real(pUserCmd->class_id, pUserCmd->tname, pUserCmd->value); break; case MTAG_CMD_DUMP: ret = !access_ok(VERIFY_READ, (void __user *)pUserCmd->data, pUserCmd->size); if (ret) return -EFAULT; ret = met_tag_dump_real(pUserCmd->class_id, pUserCmd->tname, pUserCmd->data, pUserCmd->size); break; case MTAG_CMD_DUMP_SAVE: ret = met_save_dump_buffer_real(pUserCmd->tname); break; default: return -EINVAL; } #endif return ret; }
int met_save_log_real(const char *pathname) { int len, ret = 0; struct file *infp = NULL; struct file *outfp = NULL; void *ptr = NULL; mm_segment_t oldfs; infp = filp_open("/sys/kernel/debug/tracing/trace", O_RDONLY, 0); if (unlikely(infp == NULL)) { ERRF("can not open trace file for read\n"); ret = -1; goto save_out; } outfp = filp_open(pathname, O_WRONLY | O_TRUNC | O_CREAT, 0644); if (unlikely(outfp == NULL)) { ERRF("can not open saved file for write\n"); ret = -2; goto save_out; } ptr = (void *)__get_free_pages(GFP_KERNEL, 2); if (ptr == NULL) { ERRF("can not allocate buffer to copy\n"); ret = -3; goto save_out; } oldfs = get_fs(); set_fs(KERNEL_DS); while (1) { len = vfs_read(infp, ptr, PAGE_SIZE << 2, &(infp->f_pos)); if (len < 0) { ERRF("can not read from trace file\n"); ret = -3; break; } else if (len == 0) { break; } ret = vfs_write(outfp, ptr, len, &(outfp->f_pos)); if (ret < 0) { ERRF("can not write to saved file\n"); break; } } set_fs(oldfs); save_out: if (ptr != NULL) free_pages((unsigned long)ptr, 2); if (infp != NULL) filp_close(infp, NULL); if (outfp != NULL) filp_close(outfp, NULL); return ret; }