Пример #1
0
static int grab_command(shell_t *shell, shell_argv_t *cmd_argv, char *tag)
{
  int argc = cmd_argv->argc;
  char **argv = cmd_argv->argv;
  char *hdr = log_hdr_(tag);
  int ret = -1;

  /* Set error reporting tag */
  error_default_tag(tag);

  /* The 'stop' qualifier */
  if ( (argc > 1) && (strcmp(argv[1], "stop") == 0) ) {
    /* Check number of arguments */
    if ( check_argc(shell, cmd_argv, tag, 2, 2) )
      return -1;

    grab_end = 0;

    if ( grab_n > 0 ) {
      printf("%s%d frames recorded\n", hdr, grab_n);
      grab_n = 0;
    }
    else {
      printf("%sNo recording in progress\n", hdr);
    }

    ret = 0;
  }

  /* Unknown qualifier */
  else {
    frame_t *frame = grab_display->root;
    char *window_str = NULL;
    frame_geometry_t window;
    char *fname = NULL;
    int grab_animation = 0;
    long grab_dt = 0;
    int n;

    /* Check number of arguments */
    if ( check_argc(shell, cmd_argv, tag, 1, 4) )
      return -1;

    for (n = 1; n < argc; n++) {
      char *str = argv[n];
      char *eq = strchr(str, '=');

      if ( eq != NULL ) {
	*(eq++) = '\0';
	if ( strcmp(str, "frame") == 0 ) {
	  frame = frame_get_child_by_id(grab_display->root, eq);
	  if ( frame == NULL ) {
	    error(NULL, "Unknown frame '%s'", eq);
	    return -1;
	  }
	}
	else if ( strcmp(str, "window") == 0 ) {
	  window_str = eq;
	}
	else if ( strcmp(str, "t") == 0 ) {
	  grab_begin = (tstamp_get() / 1000);
	  grab_end = 0;
	  grab_n = 0;
	  grab_dt = (atoi(eq) * 1000);
	  if ( grab_dt < 0 )
	    grab_dt = 0;

	  grab_end = grab_begin + grab_dt;
	  grab_animation = 1;
	}
	else {
	  error(tag, "Illegal qualifier '%s'", str);
	  return -1;
	}
      }
      else {
	fname = str;
      }
    }

    /* Set source frame */
    if ( window_str != NULL ) {
      if ( frame_rgb_parse_geometry(&(frame->hdr.fb->rgb), window_str, &window) ) {
	error(NULL, "Syntax error in window geometry");
	return -1;
      }
    }
    else {
      window = frame->g;
      window.x = 0;
      window.y = 0;
    }

    /* Retrieve output format */
    grab_ppm = (ppm_filename_suffix(fname) != NULL);

    /* Construct an image file name */
    fname = grab_ppm ? ppm_filename(fname) : png_filename(fname);
    if ( fname == NULL ) {
      error(tag, "Failed to construct a valid image file name");
      return -1;
    }

    if ( grab_animation ) {
      char *suffix_str;
      char *suffix;

      if ( grab_ppm ) {
	suffix_str = PPM_SUFFIX;
	suffix = ppm_filename_suffix(fname);
      }
      else {
	suffix_str = PNG_SUFFIX;
	suffix = png_filename_suffix(fname);
      }

      if ( suffix != NULL )
	*suffix = '\0';

      grab_fname_size = strlen(fname) + 16;
      if ( grab_fname_fmt != NULL )
	free(grab_fname_fmt);
      grab_fname_fmt = (char *) malloc(grab_fname_size);
      snprintf(grab_fname_fmt, grab_fname_size, "%s.%%09lu%s", fname, suffix_str);

      grab_frame = frame;
      grab_window = window;

      ret = grab_save(0);
      if ( ret == 0 ) {
	printf("%sframe=%s window=%s t=%ld %s.*%s\n", hdr,
	       frame->hdr.id, frame_geometry_str(&window),
	       grab_dt / 1000, fname, suffix_str);
      }
      else {
	printf("%sFailed to write image file '%s'", hdr, grab_fname);

	grab_end = 0;
      }
    }
    else {
      if ( grab_ppm )
	ret = ppm_save(&(frame->hdr.fb->rgb), &window, fname);
      else
	ret = png_save(&(frame->hdr.fb->rgb), &window, fname);

      if ( ret == 0 )
	printf("%sframe=%s window=%s %s\n", hdr, frame->hdr.id, frame_geometry_str(&window), fname);
      else
	printf("%sFailed to write image file '%s'", hdr, fname);
    }

    free(fname);
  }

  return ret;
}
Пример #2
0
int png_save_vidframe(const struct vidframe *vf, const char *path)
{
	png_byte **png_row_pointers = NULL;
	png_byte *row;
	const png_byte *p;
	png_byte red, green, blue;
	png_structp png_ptr = NULL;
	png_infop info_ptr = NULL;
	FILE *fp = NULL;
	size_t x, y;
	unsigned int width = vf->size.w & ~1;
	unsigned int height = vf->size.h & ~1;
	unsigned int bytes_per_pixel = 3; /* RGB format */
	time_t tnow;
	struct tm *tmx;
	char filename_buf[64];
	struct vidframe *f2 = NULL;
	int err = 0;

	tnow = time(NULL);
	tmx = localtime(&tnow);

	if (vf->fmt != VID_FMT_RGB32) {

		err = vidframe_alloc(&f2, VID_FMT_RGB32, &vf->size);
		if (err)
			goto out;

		vidconv(f2, vf, NULL);
		vf = f2;
	}

	/* Initialize the write struct. */
	png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
					  NULL, NULL, NULL);
	if (png_ptr == NULL) {
		err = ENOMEM;
		goto out;
	}

	/* Initialize the info struct. */
	info_ptr = png_create_info_struct(png_ptr);
	if (info_ptr == NULL) {
		err = ENOMEM;
		goto out;
	}

	/* Set up error handling. */
	if (setjmp(png_jmpbuf(png_ptr))) {
		err = ENOMEM;
		goto out;
	}

	/* Set image attributes. */
	png_set_IHDR(png_ptr,
		     info_ptr,
		     width,
		     height,
		     8,
		     PNG_COLOR_TYPE_RGB,
		     PNG_INTERLACE_NONE,
		     PNG_COMPRESSION_TYPE_DEFAULT,
		     PNG_FILTER_TYPE_DEFAULT);

	/* Initialize rows of PNG
	 *    bytes_per_row = width * bytes_per_pixel;
	 */
	png_row_pointers = png_malloc(png_ptr,
				      height * sizeof(png_byte *));

	for (y = 0; y < height; ++y) {
		png_row_pointers[y] =
			(png_byte *) png_malloc(png_ptr,
						width * sizeof(uint8_t) *
						bytes_per_pixel);
	}

	p = vf->data[0];
	for (y = 0; y < height; ++y) {

		row = png_row_pointers[y];

		for (x = 0; x < width; ++x) {

			red   = *p++;
			green = *p++;
			blue  = *p++;

			*row++ = blue;
			*row++ = green;
			*row++ = red;

			++p;		/* skip alpha */
		}
	}

	/* Write the image data. */
	fp = fopen(png_filename(tmx, path,
				filename_buf, sizeof(filename_buf)), "wb");
	if (fp == NULL) {
		err = errno;
		goto out;
	}

	png_init_io(png_ptr, fp);
	png_set_rows(png_ptr, info_ptr, png_row_pointers);
	png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);

	info("png: wrote %s\n", filename_buf);

 out:
	/* Finish writing. */
	mem_deref(f2);
	png_save_free(png_ptr, png_row_pointers, height);
	png_destroy_write_struct(&png_ptr, &info_ptr);
	if (fp)
		fclose(fp);

	return 0;
}