Exemple #1
0
void print_polygon(FILE* fptr, struct Polygon* self)
{
    if (!self)
        return;

    size_t ncaps=0;
    struct CapVec* cap_vec=NULL;
    cap_vec = self->cap_vec;
    ncaps = cap_vec ? cap_vec->size : 0;

    fprintf(fptr,
            "polygon %ld ( %ld caps, %.16g weight, %ld pixel, %.16g str):\n",
            self->poly_id, ncaps, self->weight, 
            self->pixel_id, self->area);
    if (ncaps > 0) {
        size_t i=0;
        struct Cap *cap = &cap_vec->data[0];
        for (i=0; i<ncaps; i++) {
            print_cap(fptr,cap);
            cap++;
        }
    }

}
Exemple #2
0
int main(int argc, char**argv){

	//--- create variables and initialize them. init()
	char* video_device = VIDEO_DEVICE;
	// 1) -------- 打开设备 /dev/video*: --------
	printf("--------------------------------------\n");
	printf("Step 1: Open devide using V4L2.\n");
	if(argc>1) {
		video_device=argv[1];
		printf("        Select: %s\n", video_device);
	}
	// create a handler for /dev/video* device:
	// 采用阻塞模式打开;若为非阻塞模式:O_RDWR | O_NONBLOCK
	int fdwr = 0;  // for /dev/video* handler
	if(NON_BLOCK_VIDEO){
		fdwr = open(video_device, O_RDWR | O_NONBLOCK);
		printf("        Open: %s using NON_BLOCK mode\n", video_device);
	} else{
		fdwr = open(video_device, O_RDWR);
		printf("        Open: %s using BLOCK mode\n", video_device);
	}
	assert(fdwr >= 0);
	printf("--------------------------------------\n");

	// 2) -------- 查询设备属性 --------
	printf("Step 2: v4l2_capacity check:\n");
	struct v4l2_capability vid_caps;
	memset(&vid_caps, 0, sizeof(vid_caps));
	int ret_code = 0; // for checking the V4L2 ioctl() method return status. 
	ret_code = ioctl(fdwr, VIDIOC_QUERYCAP, &vid_caps);
	assert(ret_code != -1);
	if(debug==1) 
		print_cap(&vid_caps);

	// 3) 设置视频的制式和帧格式:
	printf("Step 3: v4l2_format check/set:\n");
	struct v4l2_format vid_format;
	memset(&vid_format, 0, sizeof(vid_format));
//	ret_code = ioctl(fdwr, VIDIOC_G_FMT, &vid_format);

	if(V4L2_BUF_TYPE == CAPTURE){
		vid_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	} else{
		vid_format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
	}
	
	vid_format.fmt.pix.width = FRAME_WIDTH;
	vid_format.fmt.pix.height = FRAME_HEIGHT;
	vid_format.fmt.pix.pixelformat = FRAME_FORMAT;

//	size_t framesize;
//	size_t linewidth;
	__u32 framesize;
	__u32 linewidth;
	if(!format_properties(vid_format.fmt.pix.pixelformat, vid_format.fmt.pix.width, 
						vid_format.fmt.pix.height, &linewidth, &framesize)) {
		printf("unable to guess correct settings for format '%d'\n", FRAME_FORMAT);
	} else{
//		printf("FrameSize = %d\n", framesize);
//		printf("linewidth = %d\n", linewidth);
	}

	// check: http://lxr.free-electrons.com/source/include/uapi/linux/videodev2.h#L87
	vid_format.fmt.pix.field = V4L2_FIELD_NONE; // V4L2_FIELD_ANY

	// check: http://lxr.free-electrons.com/source/include/uapi/linux/videodev2.h#L185
	vid_format.fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
//	vid_format.fmt.pix.colorspace = V4L2_COLORSPACE_JPEG;

	vid_format.fmt.pix.sizeimage = framesize;
	vid_format.fmt.pix.bytesperline = linewidth;

	if(debug==1)
		print_format(&vid_format);

	ret_code = ioctl(fdwr, VIDIOC_S_FMT, &vid_format);
	assert(ret_code != -1);
/*
	// After set v4l2_format, read it back for double check. 
	// Just to make sure that there is no mis-set and the sys 'secretly' 
	// set the parameters to some 'default' value. 
	if(debug == 1){
		ret_code = ioctl(fdwr, VIDIOC_G_FMT, &vid_format);
		assert(ret_code != -1);
		printf("after set, get it back to double check:\n");
		print_format(&vid_format);
	}
*/	

/*
	struct v4l2_fmtdesc vid_desc;
	vid_desc.index = 0;
	if(debug==1)
		print_desc(fdwr,&vid_desc);
*/

	// 4) Check the video standard:
	// in general the standard is either PAL(720*576) for asian; or NTSC (720*480) for EU.
	// in our virtual camera scenario, the "v4l2_standard" does not matter much. 
	// 4.1) get the current video standard:
	printf("Step 4: check the video standard.\n");
	//struct v4l2_std_id vid_std_id;  // 64 bit length var.
	struct v4l2_standard vid_std;
	v4l2_std_id std_id;

	ret_code = ioctl(fdwr, VIDIOC_G_STD, &std_id);
	if(ret_code == -1){
		printf("        Acquire video standard ERROR:%d\n",ret_code);
	} else{
		memset(&vid_std, 0, sizeof(vid_std));
		vid_std.index = 0; // emun from the first one:
		while(0 == ioctl(fdwr, VIDIOC_ENUMSTD, &vid_std)){
			if(vid_std.id & std_id){
				printf("Current video standard: %s\n", vid_std.name);
			}
			vid_std.index++;
		}
	}

	struct v4l2_streamparm parm;
    memset(&parm, 0, sizeof(parm));
    parm.type =vid_format.type;
    ret_code = ioctl(fdwr,VIDIOC_G_PARM,&parm);
    if(ret_code == -1)
    	printf("get parameter failed.");
    parm.parm.output.timeperframe.numerator = 1000;
    parm.parm.output.timeperframe.denominator = FPS * parm.parm.output.timeperframe.numerator;
    if(ioctl(fdwr,VIDIOC_S_PARM,&parm)==0){
    	struct v4l2_fract *tf = &parm.parm.output.timeperframe;
    	if(!tf->denominator || !tf->numerator)
    		printf("invalid frame rate\n");
    	else
    		printf("        Frame Rate                     =%.3f fps\n", 
    			                            1.0 * tf->denominator/tf->numerator);
    }
//    printf("        v4l2_streamparm set/check:\n");
    printf("        parm.type(capture=1/output=2)  =%d\n", parm.type);
    printf("        parm.parm.output.capability    =0x%4x\n", parm.parm.output.capability);
	printf("--------------------------------------\n");

// 5) request buffer:
	printf("Step 5: Request video buffers\n");
	struct v4l2_requestbuffers req;
	req.count = NUM_BUFFER;
	req.memory = V4L2_MEMORY_MMAP;
    req.type = vid_format.type;  // V4L2_BUF_TYPE_VIDEO_OUTPUT = 2;

	ret_code = ioctl(fdwr, VIDIOC_REQBUFS, &req);
	if(debug == 1){
		print_requestbuffers(&req);
	}
    
  	tp_buffers *data;
    // malloc() + memset (p, 0, size);
    data= (struct buffer*) calloc(req.count, sizeof( tp_buffers));
    //data=(tp_buffers*) calloc(req.count,sizeof (tp_buffers));
	if(!data){
		printf ("Out of memory/n");
		exit (EXIT_FAILURE);
	}

	int index = 0;
	// set the parameter for every buffer in the buf_arr[], 
	// to make sure they are the same as thos in the 'req'. 
    for(index=0; index<req.count; index++){
        memset(&buf_arr[index], 0, sizeof(buf_arr[index]));
        buf_arr[index].index = index;
        buf_arr[index].type = vid_format.type;
        buf_arr[index].memory = req.memory; // should be V4L2_MEMORY_MMAP;

        // 查询序号为i 的缓冲区,得到其起始物理地址和大小
		if(-1 == ioctl (fdwr, VIDIOC_QUERYBUF, &buf_arr[index]))
			exit(-1);
		
		data[index].length = buf_arr[index].length;
		// 映射内存
		data[index].start = mmap(NULL, buf_arr[index].length, PROT_READ | PROT_WRITE, 
						MAP_SHARED, fdwr, buf_arr[index].m.offset);

		if(MAP_FAILED == data[index].start)
			exit(-1);

//		printf("        data[%d].start = 0x%08x", index, data[index].start);
		printf("        data[%d].length                     = %d\n", index, data[index].length);
//		printf("buf.length = %d, framesize = %d ,buf.m.offset = %d\n",
//					buf_arr[index].length,(int)framesize,buf_arr[index].m.offset);   
    }

    // 6) assign buffers to the queue.
	printf("step 6: assign buffers to the queue.\n");

	// Queue buffers:
    for(index = 0; index < req.count; index++){
    	ioctl(fdwr, VIDIOC_QBUF, &buf_arr[index]);
    }

    // STREAM-ON
    enum v4l2_buf_type type = vid_format.type;
    ret_code = ioctl(fdwr, VIDIOC_STREAMON, &type);
    assert(ret_code != -1);

    // image streaming testing. 
    // need to convert from RGBA format to YUYV format, 
    // and then QBUF to the buffer array. 
    int color = 128;
	// write AVOS mFrame image to buffers[ind]:
	const int BENCH = 255;

	FILE * bmp_fd = NULL;
	BYTE bmp_header[128];
	int bmp_width;
	int bmp_height;
	int bmp_header_len;
	BYTE * rgb = NULL;
	BYTE * yuv = NULL;
	char *pic[4]={"1.bmp","2.bmp","3.bmp","4.bmp"}; 		
// 	char *pic[4]={"5.bmp","5.bmp","5.bmp","5.bmp"}; 		
	while(1){
	/*
	// set image/
		if(color >= BENCH)
			color = color % BENCH;
		else
			color++;

		for(index=0; index < req.count; index++){
//			memset(data[index].start, color,1179648);
			memset(data[index].start, 128,1024);
			memset(data[index].start+1024, 255,vid_format.fmt.pix.sizeimage-1024);
		}*/
		for(index=0; index < req.count; index++){
	//		printf("%s\n",pic[index]);
			bmp_fd = fopen(pic[index],"rb");
			if(!bmp_fd)
			{
				fprintf(stderr,"open bmp file failed!\n");
				exit(1);
			}
			fgets(bmp_header,sizeof(bmp_header),bmp_fd);
			bmp_header_len = get_long_value(&bmp_header[10]);
			bmp_width = get_long_value(&bmp_header[18]);
			bmp_height = get_long_value(&bmp_header[22]);
			fclose(bmp_fd);
	//		printf("hearder_len:%d\n",bmp_header_len);	
		//	printf("image :%d*%d\n",bmp_width,bmp_height);
		//	printf("width*height*2:%d\n",bmp_width*bmp_height*2);
	//		printf("sizeimage:%d\n",vid_format.fmt.pix.sizeimage);
			rgb = malloc(bmp_width*bmp_height*sizeof(RGBTRIPLE)+bmp_header_len);
			if(!rgb)
			{
				fprintf(stderr,"rgb malloc failed\n");
			}
			yuv = malloc(bmp_width*bmp_height*sizeof(YUVTRIPLE));
			if(!yuv)
			{
				fprintf(stderr,"yuv malloc failed\n");
			}
//			fread(rgb,bmp_width*bmp_height*3+bmp_header_len,1,bmp_fd);
			bmp_fd = fopen(pic[index],"rb");
			fread(rgb,bmp_width*bmp_height*sizeof(RGBTRIPLE)+bmp_header_len,1,bmp_fd);
			bgr2yuv(yuv,(RGBTRIPLE *)(rgb+bmp_header_len),bmp_width,bmp_height);	
			memcpy(data[index].start, yuv,vid_format.fmt.pix.sizeimage);
			if(rgb)
			{
			free(rgb);
			}
			if(yuv)
			{
				free(yuv);
			}
			fclose(bmp_fd);
		}
		for(index = 0; index < req.count; index++){
		//buf_arr[index].m.offset = 0;
	//		usleep(40000);
			sleep(1);
			ioctl(fdwr, VIDIOC_QBUF, &buf_arr[index]);
		}

<<<<<<< HEAD
//		usleep(1/FPS * 1000 * 1000);
		usleep(40000);
=======
	//	usleep(40000);
>>>>>>> d1308ed6e339365aa9876a4e3f265d74eb880e0a
Exemple #3
0
static
int read_eegsignal(int bsigcheck, int pass)
{
	struct eegdev* dev;
	int type = grp[0].datatype;
	size_t strides[3];
	void *eeg_t = NULL, *exg_t = NULL;
	int32_t *tri_t = NULL;
	int ntri, fs, i, baddata, retcode = 1;
	size_t tsize = (type == EGD_FLOAT ? sizeof(float) : sizeof(double));

	// Reset global variable used to track the expected signal
	checking = 0;
	nstot = nsread = 0;

	if (!(dev = open_device(grp)))
		goto exit;

	// Get number of channels and configure structures
	grp[0].sensortype = egd_sensor_type("eeg");
	grp[1].sensortype = egd_sensor_type("undefined");
	grp[2].sensortype = egd_sensor_type("trigger");
	strides[0] = grp[0].nch*tsize;
	strides[1] = grp[1].nch*tsize;
	strides[2] = grp[2].nch*sizeof(int32_t);
	ntri = grp[2].nch;

	eeg_t = calloc(strides[0], NSAMPLE);
	exg_t = calloc(strides[1], NSAMPLE);
	tri_t = calloc(strides[2], NSAMPLE);

	fs = print_cap(dev);

	
	if (test_chinfo(dev)) {
		fprintf(stderr, "\tTest_chinfo failed\n");
		goto exit;
	}

	if (egd_acq_setup(dev, 3, strides, 3, grp))
	    	goto exit;

	if (egd_start(dev))
		goto exit;
	
	for (i=0; i < fs*DURATION; i += NSAMPLE) {
		if (egd_get_data(dev, NSAMPLE, eeg_t, exg_t, tri_t) < 0) {
			fprintf(stderr, "\tAcq failed at sample %i\n",i);
			goto exit;
		}

		// No checking
		if (!bsigcheck) {
			if (simple_trigger_check(i, NSAMPLE, ntri, tri_t))
				retcode = 2;
			continue;
		}

		if (type == EGD_FLOAT)
			baddata = check_signals_f(NSAMPLE, eeg_t, exg_t, tri_t);
		else
			baddata = check_signals_d(NSAMPLE, eeg_t, exg_t, tri_t);

		if (baddata) {
			retcode = 2;
			break;
		}
	}

	if (egd_stop(dev))
		goto exit;

	if (egd_close(dev))
		goto exit;
	dev = NULL;

	if (retcode == 1)
		retcode = 0;
exit:
	if (retcode == 1)
		fprintf(stderr, "\terror caught at pass %i: %s",
		                pass, strerror(errno));

	egd_close(dev);
	free(eeg_t);
	free(exg_t);
	free(tri_t);

	return retcode;
}
Exemple #4
0
int main(int argc, char **argv) {
	int width = 640;
	int height = 480;
    int fd = open("/dev/video0", O_RDWR | O_NONBLOCK);
    int stat = 0;

    if (fd < 0) {
        D_ERROR("can not open device.");
        return -1;
    }

    struct v4l2_capability cap = {0};
    stat = ioctl(fd, VIDIOC_QUERYCAP, &cap);

    if (stat == -1) {
        D_ERROR("can not get device capability.");
        return -1;
    }

    print_cap(&cap);

    int input_index = 0;
    stat = ioctl(fd, VIDIOC_G_INPUT, &input_index);

    if (stat == -1) {
        D_ERROR("can not get current input");
        return -1;
    }


    D_PVAR_INT(input_index);
    struct v4l2_input input;
    memset(&input, 0, sizeof(input));
    input.index = 0;

    D_PRINT("enum input");

    do {
        stat = ioctl(fd, VIDIOC_ENUMINPUT, &input);

        if (stat == -1) {
            break;
        }

        D_PVAR_INT(input.index);
        D_PVAR_STR(input.name);
        input.index++;
    } while (1);

    D_PRINT("enum input end");


    v4l2_std_id std;
    do {
        stat = ioctl(fd, VIDIOC_QUERYSTD, &std);
    } while (stat == -1 && errno == EAGAIN);
    if (stat == -1) {
        D_ERROR("can not get current video standard.");
        //return -1;
    }

    struct v4l2_standard standard;
    memset(&standard, 0, sizeof(standard));

    D_PRINT("enum video standard.");
    while (1) {
        stat = ioctl(fd, VIDIOC_ENUMSTD, &standard);

        if (stat == -1) {
            break;
        }

        D_PVAR_INT(standard.index);
        D_PVAR_STR(standard.name);
        if (std == standard.id) {
            D_PRINT("above is current video standard.");
        }

        standard.index++;
    }
    D_PRINT("enum video standard end.");



    struct v4l2_fmtdesc fmtdesc;
    memset(&fmtdesc, 0, sizeof(fmtdesc));
    fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    D_PRINT("enum image format.");
    while (1) {
        stat = ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc);

        if (stat == -1) {
            break;
        }

        D_PVAR_INT(fmtdesc.index);
        D_PVAR_STR(fmtdesc.description);
        fmtdesc.index++;
    }
    D_PRINT("enum image format end.");


    struct v4l2_format fmt;
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width = width;
    fmt.fmt.pix.height = height;
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG;
    fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;

    D_PRINT("set format");

    stat = ioctl(fd, VIDIOC_S_FMT, &fmt);

    if (stat == -1) {
    	D_ERROR("can not set video format");
    	return -1;
    }

    if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) {
    	D_ERROR("can not set specific format");
    	struct v4l2_fmtdesc fmtqury;
    	memset(&fmtqury, 0, sizeof(fmtqury));

    	fmtqury.pixelformat == fmt.fmt.pix.pixelformat;
    	stat = ioctl(fd, VIDIOC_ENUM_FMT, &fmtqury);

    	if (stat == -1) {
    		printf("real format: %s\n", fmtqury.description);
    	}
    	printf("format = %d\n", fmt.fmt.pix.pixelformat);
    	return -1;
    }

    struct v4l2_requestbuffers req;

    memset(&req, 0, sizeof(struct v4l2_requestbuffers));

    req.count = 4;
    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    req.memory = V4L2_MEMORY_MMAP;

    stat = ioctl(fd, VIDIOC_REQBUFS, &req);

    if (stat == -1) {
    	D_ERROR("can not require buffers");
    	return -1;
    }

    buffers = (struct buffer *)malloc(sizeof(struct buffer) * req.count);

    int i = 0;
    for (i = 0; i < req.count; i++) {
    	struct v4l2_buffer buf;
    	memset(&buf, 0, sizeof(buf));

    	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    	buf.memory = V4L2_MEMORY_MMAP;
    	buf.index = i;

    	stat = ioctl(fd, VIDIOC_QUERYBUF, &buf);

    	if (stat == -1) {
    		D_ERROR("can not query buffer");
    		return -1;
    	}

    	buffers[i].length = buf.length;
    	buffers[i].start = mmap(NULL, buf.length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, buf.m.offset);

    	if (MAP_FAILED == buffers[i].start) {
    		D_ERROR("mmap error");
    		return -1;
    	}

    	stat = ioctl(fd, VIDIOC_QBUF, &buf);

    	if (stat == -1) {
    		D_ERROR("can not put buf in queue");
    		return -1;
    	}
    }




    enum v4l2_buf_type stream_type =  V4L2_BUF_TYPE_VIDEO_CAPTURE;

    D_PRINT("stream on.");
    stat = ioctl(fd, VIDIOC_STREAMON, &stream_type);

    if (stat == -1) {
    	D_ERROR("can not turn stream on");
    	return -1;
    }

    i = 0;
    char filename[4096] = {0};

    D_PRINT("start loop");

    while (1) {
    	fd_set fds;
    	FD_ZERO(&fds);
    	FD_SET(fd, &fds);
    	int ret = 0;
    	ret = select(fd + 1, &fds, NULL, NULL, NULL);

    	if (ret == -1) {
    		if (EINTR == errno) {
    			continue;
    		}

    		D_ERROR("select error.");
    		return -1;
    	}

    	struct v4l2_buffer buf;
    	buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    	buf.memory = V4L2_MEMORY_MMAP;
    	stat = ioctl(fd, VIDIOC_DQBUF, &buf);

    	if (stat == -1) {
    		D_ERROR("can not out queue");
    		return -1;
    	}


    	sprintf(filename, "out/frame%d.jpg", i);

    	printf("index: %d, out: %s\n", buf.index, filename);
    	FILE *out = fopen(filename, "wb");

    	//fprintf(out, "P6\n%d %d\n255\n",640, 480);

    	fwrite(buffers[buf.index].start, 1, buf.length, out);
    	fclose(out);

    	ioctl(fd, VIDIOC_QBUF, &buf);
    	i++;
    }


    stat = ioctl(fd, VIDIOC_STREAMOFF, &stream_type);

        if (stat == -1) {
        	D_ERROR("can not turn stream off");
        	return -1;
        }
    close(fd);
    return 0;
}
Exemple #5
0
/*
 * Common body for the cap: module commands. These commands
 * share a large amount of common behavior, so it is convenient
 * to centralize things and use the cmd argument to handle the
 * small differences.
 *
 * entry:
 *	cmd - One of the CAP_CMD_T_* constants listed above, specifying
 *		which command to implement.
 *	obj_state, argc, argv - Standard command arguments
 */
static elfedit_cmdret_t
cmd_body(CAP_CMD_T cmd, elfedit_obj_state_t *obj_state,
    int argc, const char *argv[])
{
	ARGSTATE		argstate;
	Cap			*cap;
	const char		*cap_name;
	Word			cap_ndx;
	elfedit_cmdret_t	ret = ELFEDIT_CMDRET_NONE;
	PRINT_CAP_T		print_type = PRINT_CAP_T_ALL;
	Word			ndx;
	int			print_only = 0;
	int			do_autoprint = 1;

	/* Process the optional arguments */
	process_args(obj_state, argc, argv, &argstate);

	cap = argstate.cap.data;
	cap_name = argstate.cap.sec->sec_name;
	cap_ndx = argstate.cap.sec->sec_shndx;

	/* Check number of arguments, gather information */
	switch (cmd) {
	case CAP_CMD_T_DUMP:
		/* cap:dump can accept an optional index argument */
		if (argstate.argc > 1)
			elfedit_command_usage();
		print_only = 1;
		if (argstate.argc == 1)
			ndx = arg_to_index(&argstate, argstate.argv[0],
			    MSG_ORIG(MSG_STR_ELT), print_only, &print_type);
		break;

	case CAP_CMD_T_TAG:
	case CAP_CMD_T_VALUE:
		print_only = (argstate.argc != 2);
		if (argstate.argc > 0) {
			if (argstate.argc > 2)
				elfedit_command_usage();
			ndx = arg_to_index(&argstate, argstate.argv[0],
			    MSG_ORIG(MSG_STR_ELT), print_only, &print_type);
		}
		break;

	case CAP_CMD_T_DELETE:
		if ((argstate.argc < 1) || (argstate.argc > 2))
			elfedit_command_usage();
		ndx = arg_to_index(&argstate, argstate.argv[0],
		    MSG_ORIG(MSG_STR_ELT),
		    0, &print_type);
		do_autoprint = 0;
		break;

	case CAP_CMD_T_MOVE:
		if ((argstate.argc < 2) || (argstate.argc > 3))
			elfedit_command_usage();
		ndx = arg_to_index(&argstate, argstate.argv[0],
		    MSG_ORIG(MSG_STR_ELT), 0, &print_type);
		do_autoprint = 0;
		break;

	case CAP_CMD_T_HW1:
		print_only = (argstate.argc == 0);
		ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str(
		    ELFEDIT_CONST_CA, CA_SUNW_HW_1, 1),
		    MSG_ORIG(MSG_STR_VALUE), print_only, &print_type);
		break;

	case CAP_CMD_T_SF1:
		print_only = (argstate.argc == 0);
		ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str(
		    ELFEDIT_CONST_CA, CA_SUNW_SF_1, 1),
		    MSG_ORIG(MSG_STR_VALUE), print_only, &print_type);
		break;

	case CAP_CMD_T_HW2:
		print_only = (argstate.argc == 0);
		ndx = arg_to_index(&argstate, elfedit_atoconst_value_to_str(
		    ELFEDIT_CONST_CA, CA_SUNW_HW_2, 1),
		    MSG_ORIG(MSG_STR_VALUE), print_only, &print_type);
		break;

	default:
		/* Note expected: All commands should have been caught above */
		elfedit_command_usage();
		break;
	}


	/* If this is a request to print current values, do it and return */
	if (print_only) {
		print_cap(cmd, 0, &argstate, print_type, ndx);
		return (ELFEDIT_CMDRET_NONE);
	}


	switch (cmd) {
		/*
		 * CAP_CMD_T_DUMP can't get here: It is a print-only
		 * command.
		 */

	case CAP_CMD_T_TAG:
		{
			Conv_inv_buf_t	inv_buf1, inv_buf2;
			Word c_tag = (Word) elfedit_atoconst(argstate.argv[1],
			    ELFEDIT_CONST_CA);

			if (cap[ndx].c_tag == c_tag) {
				elfedit_msg(ELFEDIT_MSG_DEBUG,
				    MSG_INTL(MSG_DEBUG_S_OK),
				    cap_ndx, cap_name, EC_WORD(ndx),
				    conv_cap_tag(c_tag, 0, &inv_buf1));
			} else {
				elfedit_msg(ELFEDIT_MSG_DEBUG,
				    MSG_INTL(MSG_DEBUG_S_CHG),
				    cap_ndx, cap_name, EC_WORD(ndx),
				    conv_cap_tag(cap[ndx].c_tag, 0, &inv_buf1),
				    conv_cap_tag(c_tag, 0, &inv_buf2));
				cap[ndx].c_tag = c_tag;
				ret = ELFEDIT_CMDRET_MOD;
			}
		}
		break;

	case CAP_CMD_T_VALUE:
		{
			Xword c_val;

			if (argstate.optmask & CAP_OPT_F_STRVAL) {
				argstate_add_str(&argstate, TRUE);
				c_val = elfedit_strtab_insert(obj_state,
				    argstate.str.sec, NULL, argstate.argv[1]);
			} else {
				c_val = (Xword)
				    elfedit_atoui(argstate.argv[1], NULL);
			}

			if (cap[ndx].c_un.c_val == c_val) {
				elfedit_msg(ELFEDIT_MSG_DEBUG,
				    MSG_INTL(MSG_DEBUG_X_OK),
				    argstate.cap.sec->sec_shndx,
				    argstate.cap.sec->sec_name,
				    EC_WORD(ndx), EC_XWORD(c_val));
			} else {
				elfedit_msg(ELFEDIT_MSG_DEBUG,
				    MSG_INTL(MSG_DEBUG_X_CHG),
				    argstate.cap.sec->sec_shndx,
				    argstate.cap.sec->sec_name,
				    EC_WORD(ndx), EC_XWORD(cap[ndx].c_un.c_val),
				    EC_XWORD(c_val));
				cap[ndx].c_un.c_val = c_val;
				ret = ELFEDIT_CMDRET_MOD;
			}
		}
		break;

	case CAP_CMD_T_DELETE:
		{
			Word cnt = (argstate.argc == 1) ? 1 :
			    (Word) elfedit_atoui_range(argstate.argv[1],
			    MSG_ORIG(MSG_STR_COUNT), 1,
			    argstate.cap.grp_end_ndx - ndx + 1, NULL);
			const char *msg_prefix =
			    elfedit_sec_msgprefix(argstate.cap.sec);

			/*
			 * We want to limit the deleted elements to be
			 * in the range of the current capabilities group,
			 * and for the resulting NULL elements to be inserted
			 * at the end of the group, rather than at the end
			 * of the section. To do this, we set the array length
			 * in the call to the delete function so that it thinks
			 * the array ends with the current group.
			 *
			 * The delete function will catch attempts to delete
			 * past this virtual end, but the error message will
			 * not make sense to the user. In order to prevent that,
			 * we check for the condition here and provide a more
			 * useful error.
			 */
			if ((ndx + cnt - 1) > argstate.cap.grp_end_ndx)
				elfedit_msg(ELFEDIT_MSG_ERR,
				    MSG_INTL(MSG_ERR_GRPARRBNDS), msg_prefix,
				    argstate.cap.grp_start_ndx,
				    argstate.cap.grp_end_ndx,
				    cap_group_id(&argstate));
			elfedit_array_elts_delete(msg_prefix, cap, sizeof (Cap),
			    argstate.cap.grp_end_ndx + 1, ndx, cnt);
			ret = ELFEDIT_CMDRET_MOD;
		}
		break;

	case CAP_CMD_T_MOVE:
		{
			Cap	save;
			Word	cnt;
			Word	dstndx;
			const char *msg_prefix =
			    elfedit_sec_msgprefix(argstate.cap.sec);

			dstndx = (Word)
			    elfedit_atoui_range(argstate.argv[1],
			    MSG_ORIG(MSG_STR_DST_INDEX),
			    argstate.cap.grp_start_ndx,
			    argstate.cap.grp_end_ndx, NULL);
			if (argstate.argc == 2) {
				cnt = 1;
			} else {
				Word max;

				max = argstate.cap.grp_end_ndx -
				    ((ndx > dstndx) ? ndx : dstndx) + 1;
				cnt = (Word) elfedit_atoui_range(
				    argstate.argv[2], MSG_ORIG(MSG_STR_COUNT),
				    1, max, NULL);
			}

			/*
			 * Moves are required to be self contained within
			 * the bounds of the selected capability group.
			 * The move utility function contains bounds checking,
			 * but is not sub-array aware. Hence, we bounds check
			 * check it here, and then hand of the validated
			 * operation to the move utility function to execute.
			 */
			if ((ndx < argstate.cap.grp_start_ndx) ||
			    ((ndx + cnt) > argstate.cap.grp_end_ndx) ||
			    (dstndx < argstate.cap.grp_start_ndx) ||
			    ((dstndx + cnt) > argstate.cap.grp_end_ndx))
				elfedit_msg(ELFEDIT_MSG_ERR,
				    MSG_INTL(MSG_ERR_GRPARRBNDS), msg_prefix,
				    argstate.cap.grp_start_ndx,
				    argstate.cap.grp_end_ndx,
				    cap_group_id(&argstate));
			elfedit_array_elts_move(msg_prefix, cap, sizeof (save),
			    argstate.cap.grp_end_ndx + 1, ndx, dstndx,
			    cnt, &save);
			ret = ELFEDIT_CMDRET_MOD;
		}
		break;


	case CAP_CMD_T_HW1:
		{
			ret = cap_set(&argstate, cap, ndx, cap_ndx, cap_name,
			    CA_SUNW_HW_1, ELFEDIT_CONST_HW1_SUNW);
		}
		break;

	case CAP_CMD_T_SF1:
		{
			ret = cap_set(&argstate, cap, ndx, cap_ndx, cap_name,
			    CA_SUNW_SF_1, ELFEDIT_CONST_SF1_SUNW);
		}
		break;

	case CAP_CMD_T_HW2:
		{
			ret = cap_set(&argstate, cap, ndx, cap_ndx, cap_name,
			    CA_SUNW_HW_2, ELFEDIT_CONST_HW2_SUNW);
		}
		break;
	}

	/*
	 * If we modified the capabilities section header, tell libelf.
	 */
	if (ret == ELFEDIT_CMDRET_MOD)
		elfedit_modified_data(argstate.cap.sec);

	/* Do autoprint */
	if (do_autoprint)
		print_cap(cmd, 1, &argstate, print_type, ndx);

	return (ret);
}