Ejemplo n.º 1
0
void write_image(char *file_name, int render_fmt, VInfo *ji, uint8_t *buf) {
  FILE *x;
  if ((x = open_outfile(file_name))) {
    switch (render_fmt) {
      case FMT_JPG:
	if (write_jpeg(ji, buf, JPEG_QUALITY, x))
	  dlog(LOG_ERR, "IMF: Could not write jpeg: %s\n", file_name);
	break;
      case FMT_PNG:
	if (write_png(ji, buf, x))
	  dlog(LOG_ERR, "IMF: Could not write png: %s\n", file_name);
	break;
      case FMT_PPM:
	if (write_ppm(ji, buf, x))
	  dlog(LOG_ERR, "IMF: Could not write ppm: %s\n", file_name);
	break;
      default:
	dlog(LOG_ERR, "IMF: Unknown outformat %d\n", render_fmt);
	break;
    }
    if (strcmp(file_name, "-")) fclose(x);
    dlog(LOG_INFO, "IMF: Outputfile %s closed\n", file_name);
  }
  else
    dlog(LOG_ERR, "IMF: Could not open outfile: %s\n", file_name);
  return;
}
Ejemplo n.º 2
0
/**
 * @brief ...
 * @param filename
 */
void dofile(char *filename)
{
    struct stat statbuf;

    currentfile = filename;

    /* Checks if this is a tex file */
    det_tflag(filename);
    det_defdupchar(filename);

    if ((infile = fopen(filename, "r")) == NULL) {
		fprintf(stderr, CANT_OPEN, filename);
		sleep((unsigned) 2);
		return;
    }

    det_readonly_access(filename);
    open_outfile(&statbuf);

    quit = 0;
    changes = 0;

    checkfile();

    fclose(infile);
    fclose(outfile);

    if (!cflag)
        treeoutput();

    if (changes && !readonly)
        update_file(filename, &statbuf);
    unlink(tempfile);
}
Ejemplo n.º 3
0
static int
do_export( strlist_t users, int secret, unsigned int options )
{
  IOBUF out = NULL;
  int any, rc;
  armor_filter_context_t *afx = NULL;
  compress_filter_context_t zfx;
  
  memset( &zfx, 0, sizeof zfx);
  
  rc = open_outfile( NULL, 0, &out );
  if (rc)
    return rc;

  if (!(options & EXPORT_SEXP_FORMAT))
    {
      if ( opt.armor )
        {
          afx = new_armor_context ();
          afx->what = secret? 5 : 1;
          push_armor_filter (afx, out);
        }
      if ( opt.compress_keys )
        push_compress_filter (out,&zfx,default_compress_algo());
    }

  rc = do_export_stream ( out, users, secret, NULL, options, &any );

  if ( rc || !any )
    iobuf_cancel (out);
  else
    iobuf_close (out);
  release_armor_context (afx);
  return rc;
}
Ejemplo n.º 4
0
void print_result(const char * outfile_name, int * data, int nitems) {
  
  FILE* file = open_outfile(outfile_name);
  
  for(int i=0;i < nitems;i++) 
     fprintf(file,"%d\n", data[i]);
  
  if(file != stdout) 
     fclose(file);
}
Ejemplo n.º 5
0
/**
 * Stream-based fast sort. The stream sort may be faster because you can start processing the data
 * before it has been fully read.
 * Before data arrives, you can pre-create threads and prepared to send output to the given ile
 * @param nthreads number of threads to use including the calling thread (these should created once and reused for multiple tasks)
 * @param verbose whether to print to standard out the number of unique values for each merged segment
 * @param outfile outoutfile_nameput FILE descriptor (either stdout or a output file)
*/
void stream_init() {
  outfile = open_outfile(outfile_name);
  // do awesome stuff
  
  int i;

  for(i = 1; i < nthreads; i++){
  	pthread_create(&tid[i], NULL, worker_funcs, NULL);
  }
  data = malloc(16777216 * sizeof(int));
}
Ejemplo n.º 6
0
static int switch_outfile(int cpu, int *fnum)
{
    int remove_file = 0;

    dbug(3, "thread %d switching file\n", cpu);
    close(out_fd[cpu]);
    *fnum += 1;
    if (fnum_max && *fnum >= fnum_max)
        remove_file = 1;
    if (open_outfile(*fnum, cpu, remove_file) < 0) {
        perr("Couldn't open file for cpu %d, exiting.", cpu);
        return -1;
    }
    return 0;
}
Ejemplo n.º 7
0
/****************
 * Take file and write it out with armor
 */
int
enarmor_file( const char *fname )
{
    armor_filter_context_t *afx;
    IOBUF inp = NULL, out = NULL;
    int rc = 0;
    int c;

    afx = new_armor_context ();

    /* prepare iobufs */
    inp = iobuf_open(fname);
    if (inp && is_secured_file (iobuf_get_fd (inp)))
      {
        iobuf_close (inp);
        inp = NULL;
        errno = EPERM;
      }
    if (!inp) {
        rc = gpg_error_from_syserror ();
	log_error(_("can't open `%s': %s\n"), fname? fname: "[stdin]",
                  strerror(errno) );
	goto leave;
    }


    if( (rc = open_outfile( fname, 1, &out )) )
	goto leave;

    afx->what = 4;
    afx->hdrlines = "Comment: Use \"gpg --dearmor\" for unpacking\n";
    push_armor_filter ( afx, out );

    while( (c = iobuf_get(inp)) != -1 )
	iobuf_put( out, c );


  leave:
    if( rc )
	iobuf_cancel(out);
    else
	iobuf_close(out);
    iobuf_close(inp);
    release_armor_context (afx);
    return rc;
}
Ejemplo n.º 8
0
int main(int argc, char **argv){
	char *in_filename;
	char *out_filename;
	char *in_line;
	char *out_line;
	char instruction_type = 'r'; //default to rtype.  You might change this.
	FILE *in;
	FILE *out;
	if(argc == 0){
		printf("Please specify a file to assemble...\n");
		return 1;
	}
	else{
		in_filename = argv[0][0];
		out_filename = argv[1][0];
	}
	in = open_infile(in_filename);
	out = open_outfile(out_filename);
	for(;;){
		fgets(in_line, 40, in); //40 here is arbitrary.
		if(in_line[0] == EOF) break;
		//instruction_type = type(in_line);
		/*switch (instruction_type){
			case 'r':
				rtype(out_line, in_line);
				break;
			case 'i':
				itype(out_line, in_line);
				break;
			case 'j':
				jtype(out_line, in_line);
				break;
			default:
				break;
		}*/
		fputs(out_line, out);
	}
	return 0;
}
Ejemplo n.º 9
0
int main(int argc, char** argv)
{
	// I'm using linux file descriptors instead of streams because it's easier to handle ints
	// than some polymorphic stream types (ostream, ofstream etc)
	int buf = 0, fileout = 1, sock;
	unsigned short number = 1;
	char base = 10; 
	bool fileio = false;
	const char* outfile;
	long long top = 100, bottom = 0;

	while ( -1 != (buf = getopt(argc,argv,"b:ho:n:vT:B:")) )
	{
		try {
			switch ( buf )
			{
				case 'n' :
					number = static_cast<short>(strtoul(optarg,0,10));
					break;
				case 'b' :
					base = strtoul(optarg,0,10);
					if ( base != 2 && base != 8 && base != 10 && base != 16 )
						throw err("The specified base is not valid for random.org!");

					break;
				case 'v' :
					verbose = true;
					break;
				case 'o' :
					fileio = true;
					outfile = optarg;
					break;
				case 'T' :
					top = strtoull(optarg,0,10);
					break;
				case 'B' :
					bottom = strtoull(optarg,0,10);
					break;
				case 'h' :
					std::cout << help_string;
					exit(0);
			}

			if ( top <= bottom )
				throw err("Invalid range!");

			if ( top < -1E9 || top > 1E9 )
				throw err("top is too big or too small");

			if ( bottom < -1E9 || bottom > 1E9 )
				throw err("bottom is too big or too small"); 
			if ( number > 1000 )
				throw err("Number too high");

		} catch (err error)
		{
			std::cout << "Exception raised: " << error.errmsg << std::endl;
			exit(1);
		}
	}

	if ( verbose == true )
		std::cout << "DBG: Done with processing arguments\n";
	
	if ( fileio == true )
	{
		fileout = open_outfile(outfile);
	}

	if ( verbose == true )
		std::cout << "DBG: Sending Request\n";

	// Build network connection and send the HTTP request
	sock = request(number,bottom,top,base);
	
	if ( verbose == true )
		std::cout << "DBG: Got answer, processing response\n";

	// Remove the HTTP header (algorithm is explained above)
	cut_header(sock);

	if ( verbose == true )
		std::cout << "DBG: Processed raw answer, continuing with getting numbers\n";

	// Simply read the numbers from the socket and write it to stdout
	get_data(sock,fileout);

	return 0;
}
Ejemplo n.º 10
0
static int main_loop(int argc, const char **argv_) {
  aom_codec_ctx_t decoder;
  char *fn = NULL;
  int i;
  int ret = EXIT_FAILURE;
  uint8_t *buf = NULL;
  size_t bytes_in_buffer = 0, buffer_size = 0;
  FILE *infile;
  int frame_in = 0, frame_out = 0, flipuv = 0, noblit = 0;
  int do_md5 = 0, progress = 0;
  int stop_after = 0, postproc = 0, summary = 0, quiet = 1;
  int arg_skip = 0;
  int keep_going = 0;
  const AvxInterface *interface = NULL;
  const AvxInterface *fourcc_interface = NULL;
  uint64_t dx_time = 0;
  struct arg arg;
  char **argv, **argi, **argj;

  int single_file;
  int use_y4m = 1;
  int opt_yv12 = 0;
  int opt_i420 = 0;
  int opt_raw = 0;
  aom_codec_dec_cfg_t cfg = { 0, 0, 0, CONFIG_LOWBITDEPTH, { 1 } };
  unsigned int fixed_output_bit_depth = 0;
  unsigned int is_annexb = 0;
  int frames_corrupted = 0;
  int dec_flags = 0;
  int do_scale = 0;
  int operating_point = 0;
  int output_all_layers = 0;
  int skip_film_grain = 0;
  aom_image_t *scaled_img = NULL;
  aom_image_t *img_shifted = NULL;
  int frame_avail, got_data, flush_decoder = 0;
  int num_external_frame_buffers = 0;
  struct ExternalFrameBufferList ext_fb_list = { 0, NULL };

  const char *outfile_pattern = NULL;
  char outfile_name[PATH_MAX] = { 0 };
  FILE *outfile = NULL;

  FILE *framestats_file = NULL;

  MD5Context md5_ctx;
  unsigned char md5_digest[16];

  struct AvxDecInputContext input = { NULL, NULL, NULL };
  struct AvxInputContext aom_input_ctx;
  memset(&aom_input_ctx, 0, sizeof(aom_input_ctx));
#if CONFIG_WEBM_IO
  struct WebmInputContext webm_ctx;
  memset(&webm_ctx, 0, sizeof(webm_ctx));
  input.webm_ctx = &webm_ctx;
#endif
  struct ObuDecInputContext obu_ctx = { NULL, NULL, 0, 0, 0 };

  obu_ctx.avx_ctx = &aom_input_ctx;
  input.obu_ctx = &obu_ctx;
  input.aom_input_ctx = &aom_input_ctx;

  /* Parse command line */
  exec_name = argv_[0];
  argv = argv_dup(argc - 1, argv_ + 1);

  for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
    memset(&arg, 0, sizeof(arg));
    arg.argv_step = 1;

    if (arg_match(&arg, &help, argi)) {
      show_help(stdout, 0);
      exit(EXIT_SUCCESS);
    } else if (arg_match(&arg, &codecarg, argi)) {
      interface = get_aom_decoder_by_name(arg.val);
      if (!interface)
        die("Error: Unrecognized argument (%s) to --codec\n", arg.val);
    } else if (arg_match(&arg, &looparg, argi)) {
      // no-op
    } else if (arg_match(&arg, &outputfile, argi)) {
      outfile_pattern = arg.val;
    } else if (arg_match(&arg, &use_yv12, argi)) {
      use_y4m = 0;
      flipuv = 1;
      opt_yv12 = 1;
      opt_i420 = 0;
      opt_raw = 0;
    } else if (arg_match(&arg, &use_i420, argi)) {
      use_y4m = 0;
      flipuv = 0;
      opt_yv12 = 0;
      opt_i420 = 1;
      opt_raw = 0;
    } else if (arg_match(&arg, &rawvideo, argi)) {
      use_y4m = 0;
      opt_yv12 = 0;
      opt_i420 = 0;
      opt_raw = 1;
    } else if (arg_match(&arg, &flipuvarg, argi)) {
      flipuv = 1;
    } else if (arg_match(&arg, &noblitarg, argi)) {
      noblit = 1;
    } else if (arg_match(&arg, &progressarg, argi)) {
      progress = 1;
    } else if (arg_match(&arg, &limitarg, argi)) {
      stop_after = arg_parse_uint(&arg);
    } else if (arg_match(&arg, &skiparg, argi)) {
      arg_skip = arg_parse_uint(&arg);
    } else if (arg_match(&arg, &postprocarg, argi)) {
      postproc = 1;
    } else if (arg_match(&arg, &md5arg, argi)) {
      do_md5 = 1;
    } else if (arg_match(&arg, &framestatsarg, argi)) {
      framestats_file = fopen(arg.val, "w");
      if (!framestats_file) {
        die("Error: Could not open --framestats file (%s) for writing.\n",
            arg.val);
      }
    } else if (arg_match(&arg, &summaryarg, argi)) {
      summary = 1;
    } else if (arg_match(&arg, &threadsarg, argi)) {
      cfg.threads = arg_parse_uint(&arg);
#if !CONFIG_MULTITHREAD
      if (cfg.threads > 1) {
        die("Error: --threads=%d is not supported when CONFIG_MULTITHREAD = "
            "0.\n",
            cfg.threads);
      }
#endif
    } else if (arg_match(&arg, &verbosearg, argi)) {
      quiet = 0;
    } else if (arg_match(&arg, &scalearg, argi)) {
      do_scale = 1;
    } else if (arg_match(&arg, &fb_arg, argi)) {
      num_external_frame_buffers = arg_parse_uint(&arg);
    } else if (arg_match(&arg, &continuearg, argi)) {
      keep_going = 1;
    } else if (arg_match(&arg, &outbitdeptharg, argi)) {
      fixed_output_bit_depth = arg_parse_uint(&arg);
    } else if (arg_match(&arg, &isannexb, argi)) {
      is_annexb = 1;
      input.obu_ctx->is_annexb = 1;
    } else if (arg_match(&arg, &oppointarg, argi)) {
      operating_point = arg_parse_int(&arg);
    } else if (arg_match(&arg, &outallarg, argi)) {
      output_all_layers = 1;
    } else if (arg_match(&arg, &skipfilmgrain, argi)) {
      skip_film_grain = 1;
    } else {
      argj++;
    }
  }

  /* Check for unrecognized options */
  for (argi = argv; *argi; argi++)
    if (argi[0][0] == '-' && strlen(argi[0]) > 1)
      die("Error: Unrecognized option %s\n", *argi);

  /* Handle non-option arguments */
  fn = argv[0];

  if (!fn) {
    free(argv);
    fprintf(stderr, "No input file specified!\n");
    usage_exit();
  }
  /* Open file */
  infile = strcmp(fn, "-") ? fopen(fn, "rb") : set_binary_mode(stdin);

  if (!infile) {
    fatal("Failed to open input file '%s'", strcmp(fn, "-") ? fn : "stdin");
  }
#if CONFIG_OS_SUPPORT
  /* Make sure we don't dump to the terminal, unless forced to with -o - */
  if (!outfile_pattern && isatty(STDOUT_FILENO) && !do_md5 && !noblit) {
    fprintf(stderr,
            "Not dumping raw video to your terminal. Use '-o -' to "
            "override.\n");
    return EXIT_FAILURE;
  }
#endif
  input.aom_input_ctx->filename = fn;
  input.aom_input_ctx->file = infile;
  if (file_is_ivf(input.aom_input_ctx))
    input.aom_input_ctx->file_type = FILE_TYPE_IVF;
#if CONFIG_WEBM_IO
  else if (file_is_webm(input.webm_ctx, input.aom_input_ctx))
    input.aom_input_ctx->file_type = FILE_TYPE_WEBM;
#endif
  else if (file_is_obu(&obu_ctx))
    input.aom_input_ctx->file_type = FILE_TYPE_OBU;
  else if (file_is_raw(input.aom_input_ctx))
    input.aom_input_ctx->file_type = FILE_TYPE_RAW;
  else {
    fprintf(stderr, "Unrecognized input file type.\n");
#if !CONFIG_WEBM_IO
    fprintf(stderr, "aomdec was built without WebM container support.\n");
#endif
    return EXIT_FAILURE;
  }

  outfile_pattern = outfile_pattern ? outfile_pattern : "-";
  single_file = is_single_file(outfile_pattern);

  if (!noblit && single_file) {
    generate_filename(outfile_pattern, outfile_name, PATH_MAX,
                      aom_input_ctx.width, aom_input_ctx.height, 0);
    if (do_md5)
      MD5Init(&md5_ctx);
    else
      outfile = open_outfile(outfile_name);
  }

  if (use_y4m && !noblit) {
    if (!single_file) {
      fprintf(stderr,
              "YUV4MPEG2 not supported with output patterns,"
              " try --i420 or --yv12 or --rawvideo.\n");
      return EXIT_FAILURE;
    }

#if CONFIG_WEBM_IO
    if (aom_input_ctx.file_type == FILE_TYPE_WEBM) {
      if (webm_guess_framerate(input.webm_ctx, input.aom_input_ctx)) {
        fprintf(stderr,
                "Failed to guess framerate -- error parsing "
                "webm file?\n");
        return EXIT_FAILURE;
      }
    }
#endif
  }

  fourcc_interface = get_aom_decoder_by_fourcc(aom_input_ctx.fourcc);
  if (interface && fourcc_interface && interface != fourcc_interface)
    warn("Header indicates codec: %s\n", fourcc_interface->name);
  else
    interface = fourcc_interface;

  if (!interface) interface = get_aom_decoder_by_index(0);

  dec_flags = (postproc ? AOM_CODEC_USE_POSTPROC : 0);
  if (aom_codec_dec_init(&decoder, interface->codec_interface(), &cfg,
                         dec_flags)) {
    fprintf(stderr, "Failed to initialize decoder: %s\n",
            aom_codec_error(&decoder));
    goto fail2;
  }

  if (!quiet) fprintf(stderr, "%s\n", decoder.name);

  if (aom_codec_control(&decoder, AV1D_SET_IS_ANNEXB, is_annexb)) {
    fprintf(stderr, "Failed to set is_annexb: %s\n", aom_codec_error(&decoder));
    goto fail;
  }

  if (aom_codec_control(&decoder, AV1D_SET_OPERATING_POINT, operating_point)) {
    fprintf(stderr, "Failed to set operating_point: %s\n",
            aom_codec_error(&decoder));
    goto fail;
  }

  if (aom_codec_control(&decoder, AV1D_SET_OUTPUT_ALL_LAYERS,
                        output_all_layers)) {
    fprintf(stderr, "Failed to set output_all_layers: %s\n",
            aom_codec_error(&decoder));
    goto fail;
  }

  if (aom_codec_control(&decoder, AV1D_SET_SKIP_FILM_GRAIN, skip_film_grain)) {
    fprintf(stderr, "Failed to set skip_film_grain: %s\n",
            aom_codec_error(&decoder));
    goto fail;
  }

  if (arg_skip) fprintf(stderr, "Skipping first %d frames.\n", arg_skip);
  while (arg_skip) {
    if (read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) break;
    arg_skip--;
  }

  if (num_external_frame_buffers > 0) {
    ext_fb_list.num_external_frame_buffers = num_external_frame_buffers;
    ext_fb_list.ext_fb = (struct ExternalFrameBuffer *)calloc(
        num_external_frame_buffers, sizeof(*ext_fb_list.ext_fb));
    if (aom_codec_set_frame_buffer_functions(&decoder, get_av1_frame_buffer,
                                             release_av1_frame_buffer,
                                             &ext_fb_list)) {
      fprintf(stderr, "Failed to configure external frame buffers: %s\n",
              aom_codec_error(&decoder));
      goto fail;
    }
  }

  frame_avail = 1;
  got_data = 0;

  if (framestats_file) fprintf(framestats_file, "bytes,qp\r\n");

  /* Decode file */
  while (frame_avail || got_data) {
    aom_codec_iter_t iter = NULL;
    aom_image_t *img;
    struct aom_usec_timer timer;
    int corrupted = 0;

    frame_avail = 0;
    if (!stop_after || frame_in < stop_after) {
      if (!read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) {
        frame_avail = 1;
        frame_in++;

        aom_usec_timer_start(&timer);

        if (aom_codec_decode(&decoder, buf, bytes_in_buffer, NULL)) {
          const char *detail = aom_codec_error_detail(&decoder);
          warn("Failed to decode frame %d: %s", frame_in,
               aom_codec_error(&decoder));

          if (detail) warn("Additional information: %s", detail);
          if (!keep_going) goto fail;
        }

        if (framestats_file) {
          int qp;
          if (aom_codec_control(&decoder, AOMD_GET_LAST_QUANTIZER, &qp)) {
            warn("Failed AOMD_GET_LAST_QUANTIZER: %s",
                 aom_codec_error(&decoder));
            if (!keep_going) goto fail;
          }
          fprintf(framestats_file, "%d,%d\r\n", (int)bytes_in_buffer, qp);
        }

        aom_usec_timer_mark(&timer);
        dx_time += aom_usec_timer_elapsed(&timer);
      } else {
        flush_decoder = 1;
      }
    } else {
      flush_decoder = 1;
    }

    aom_usec_timer_start(&timer);

    if (flush_decoder) {
      // Flush the decoder.
      if (aom_codec_decode(&decoder, NULL, 0, NULL)) {
        warn("Failed to flush decoder: %s", aom_codec_error(&decoder));
      }
    }

    aom_usec_timer_mark(&timer);
    dx_time += aom_usec_timer_elapsed(&timer);

    got_data = 0;
    while ((img = aom_codec_get_frame(&decoder, &iter))) {
      ++frame_out;
      got_data = 1;

      if (aom_codec_control(&decoder, AOMD_GET_FRAME_CORRUPTED, &corrupted)) {
        warn("Failed AOM_GET_FRAME_CORRUPTED: %s", aom_codec_error(&decoder));
        if (!keep_going) goto fail;
      }
      frames_corrupted += corrupted;

      if (progress) show_progress(frame_in, frame_out, dx_time);

      if (!noblit) {
        const int PLANES_YUV[] = { AOM_PLANE_Y, AOM_PLANE_U, AOM_PLANE_V };
        const int PLANES_YVU[] = { AOM_PLANE_Y, AOM_PLANE_V, AOM_PLANE_U };
        const int *planes = flipuv ? PLANES_YVU : PLANES_YUV;

        if (do_scale) {
          if (frame_out == 1) {
            // If the output frames are to be scaled to a fixed display size
            // then use the width and height specified in the container. If
            // either of these is set to 0, use the display size set in the
            // first frame header. If that is unavailable, use the raw decoded
            // size of the first decoded frame.
            int render_width = aom_input_ctx.width;
            int render_height = aom_input_ctx.height;
            if (!render_width || !render_height) {
              int render_size[2];
              if (aom_codec_control(&decoder, AV1D_GET_DISPLAY_SIZE,
                                    render_size)) {
                // As last resort use size of first frame as display size.
                render_width = img->d_w;
                render_height = img->d_h;
              } else {
                render_width = render_size[0];
                render_height = render_size[1];
              }
            }
            scaled_img =
                aom_img_alloc(NULL, img->fmt, render_width, render_height, 16);
            scaled_img->bit_depth = img->bit_depth;
            scaled_img->monochrome = img->monochrome;
            scaled_img->csp = img->csp;
          }

          if (img->d_w != scaled_img->d_w || img->d_h != scaled_img->d_h) {
#if CONFIG_LIBYUV
            libyuv_scale(img, scaled_img, kFilterBox);
            img = scaled_img;
#else
            fprintf(
                stderr,
                "Failed to scale output frame: %s.\n"
                "libyuv is required for scaling but is currently disabled.\n"
                "Be sure to specify -DCONFIG_LIBYUV=1 when running cmake.\n",
                aom_codec_error(&decoder));
            goto fail;
#endif
          }
        }
        // Default to codec bit depth if output bit depth not set
        unsigned int output_bit_depth;
        if (!fixed_output_bit_depth && single_file && !do_md5) {
          output_bit_depth = img->bit_depth;
        } else {
          output_bit_depth = fixed_output_bit_depth;
        }
        // Shift up or down if necessary
        if (output_bit_depth != 0)
          aom_shift_img(output_bit_depth, &img, &img_shifted);

        aom_input_ctx.width = img->d_w;
        aom_input_ctx.height = img->d_h;

        int num_planes = (opt_raw && img->monochrome) ? 1 : 3;
        if (single_file) {
          if (use_y4m) {
            char y4m_buf[Y4M_BUFFER_SIZE] = { 0 };
            size_t len = 0;
            if (frame_out == 1) {
              // Y4M file header
              len = y4m_write_file_header(
                  y4m_buf, sizeof(y4m_buf), aom_input_ctx.width,
                  aom_input_ctx.height, &aom_input_ctx.framerate,
                  img->monochrome, img->csp, img->fmt, img->bit_depth);
              if (img->csp == AOM_CSP_COLOCATED) {
                fprintf(stderr,
                        "Warning: Y4M lacks a colorspace for colocated "
                        "chroma. Using a placeholder.\n");
              }
              if (do_md5) {
                MD5Update(&md5_ctx, (md5byte *)y4m_buf, (unsigned int)len);
              } else {
                fputs(y4m_buf, outfile);
              }
            }

            // Y4M frame header
            len = y4m_write_frame_header(y4m_buf, sizeof(y4m_buf));
            if (do_md5) {
              MD5Update(&md5_ctx, (md5byte *)y4m_buf, (unsigned int)len);
              y4m_update_image_md5(img, planes, &md5_ctx);
            } else {
              fputs(y4m_buf, outfile);
              y4m_write_image_file(img, planes, outfile);
            }
          } else {
            if (frame_out == 1) {
              // Check if --yv12 or --i420 options are consistent with the
              // bit-stream decoded
              if (opt_i420) {
                if (img->fmt != AOM_IMG_FMT_I420 &&
                    img->fmt != AOM_IMG_FMT_I42016) {
                  fprintf(stderr,
                          "Cannot produce i420 output for bit-stream.\n");
                  goto fail;
                }
              }
              if (opt_yv12) {
                if ((img->fmt != AOM_IMG_FMT_I420 &&
                     img->fmt != AOM_IMG_FMT_YV12) ||
                    img->bit_depth != 8) {
                  fprintf(stderr,
                          "Cannot produce yv12 output for bit-stream.\n");
                  goto fail;
                }
              }
            }
            if (do_md5) {
              raw_update_image_md5(img, planes, num_planes, &md5_ctx);
            } else {
              raw_write_image_file(img, planes, num_planes, outfile);
            }
          }
        } else {
          generate_filename(outfile_pattern, outfile_name, PATH_MAX, img->d_w,
                            img->d_h, frame_in);
          if (do_md5) {
            MD5Init(&md5_ctx);
            if (use_y4m) {
              y4m_update_image_md5(img, planes, &md5_ctx);
            } else {
              raw_update_image_md5(img, planes, num_planes, &md5_ctx);
            }
            MD5Final(md5_digest, &md5_ctx);
            print_md5(md5_digest, outfile_name);
          } else {
            outfile = open_outfile(outfile_name);
            if (use_y4m) {
              y4m_write_image_file(img, planes, outfile);
            } else {
              raw_write_image_file(img, planes, num_planes, outfile);
            }
            fclose(outfile);
          }
        }
      }
    }
  }

  if (summary || progress) {
    show_progress(frame_in, frame_out, dx_time);
    fprintf(stderr, "\n");
  }

  if (frames_corrupted) {
    fprintf(stderr, "WARNING: %d frames corrupted.\n", frames_corrupted);
  } else {
    ret = EXIT_SUCCESS;
  }

fail:

  if (aom_codec_destroy(&decoder)) {
    fprintf(stderr, "Failed to destroy decoder: %s\n",
            aom_codec_error(&decoder));
  }

fail2:

  if (!noblit && single_file) {
    if (do_md5) {
      MD5Final(md5_digest, &md5_ctx);
      print_md5(md5_digest, outfile_name);
    } else {
      fclose(outfile);
    }
  }

#if CONFIG_WEBM_IO
  if (input.aom_input_ctx->file_type == FILE_TYPE_WEBM)
    webm_free(input.webm_ctx);
#endif
  if (input.aom_input_ctx->file_type == FILE_TYPE_OBU)
    obudec_free(input.obu_ctx);

  if (input.aom_input_ctx->file_type != FILE_TYPE_WEBM) free(buf);

  if (scaled_img) aom_img_free(scaled_img);
  if (img_shifted) aom_img_free(img_shifted);

  for (i = 0; i < ext_fb_list.num_external_frame_buffers; ++i) {
    free(ext_fb_list.ext_fb[i].data);
  }
  free(ext_fb_list.ext_fb);

  fclose(infile);
  if (framestats_file) fclose(framestats_file);

  free(argv);

  return ret;
}
Ejemplo n.º 11
0
static int main_loop(int argc, const char **argv_) {
  aom_codec_ctx_t decoder;
  char *fn = NULL;
  int i;
  int ret = EXIT_FAILURE;
  uint8_t *buf = NULL;
  size_t bytes_in_buffer = 0, buffer_size = 0;
  FILE *infile;
  int frame_in = 0, frame_out = 0, flipuv = 0, noblit = 0;
  int do_md5 = 0, progress = 0, frame_parallel = 0;
  int stop_after = 0, postproc = 0, summary = 0, quiet = 1;
  int arg_skip = 0;
  int ec_enabled = 0;
  int keep_going = 0;
  const AvxInterface *interface = NULL;
  const AvxInterface *fourcc_interface = NULL;
  uint64_t dx_time = 0;
  struct arg arg;
  char **argv, **argi, **argj;

  int single_file;
  int use_y4m = 1;
  int opt_yv12 = 0;
  int opt_i420 = 0;
  aom_codec_dec_cfg_t cfg = { 0, 0, 0 };
#if CONFIG_AOM_HIGHBITDEPTH
  unsigned int output_bit_depth = 0;
#endif
#if CONFIG_EXT_TILE
  int tile_row = -1;
  int tile_col = -1;
#endif  // CONFIG_EXT_TILE
  int frames_corrupted = 0;
  int dec_flags = 0;
  int do_scale = 0;
  aom_image_t *scaled_img = NULL;
#if CONFIG_AOM_HIGHBITDEPTH
  aom_image_t *img_shifted = NULL;
#endif
  int frame_avail, got_data, flush_decoder = 0;
  int num_external_frame_buffers = 0;
  struct ExternalFrameBufferList ext_fb_list = { 0, NULL };

  const char *outfile_pattern = NULL;
  char outfile_name[PATH_MAX] = { 0 };
  FILE *outfile = NULL;

  FILE *framestats_file = NULL;

  MD5Context md5_ctx;
  unsigned char md5_digest[16];

  struct AvxDecInputContext input = { NULL, NULL };
  struct AvxInputContext aom_input_ctx;
#if CONFIG_WEBM_IO
  struct WebmInputContext webm_ctx;
  memset(&(webm_ctx), 0, sizeof(webm_ctx));
  input.webm_ctx = &webm_ctx;
#endif
  input.aom_input_ctx = &aom_input_ctx;

  /* Parse command line */
  exec_name = argv_[0];
  argv = argv_dup(argc - 1, argv_ + 1);

  for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
    memset(&arg, 0, sizeof(arg));
    arg.argv_step = 1;

    if (arg_match(&arg, &codecarg, argi)) {
      interface = get_aom_decoder_by_name(arg.val);
      if (!interface)
        die("Error: Unrecognized argument (%s) to --codec\n", arg.val);
    } else if (arg_match(&arg, &looparg, argi)) {
      // no-op
    } else if (arg_match(&arg, &outputfile, argi)) {
      outfile_pattern = arg.val;
    } else if (arg_match(&arg, &use_yv12, argi)) {
      use_y4m = 0;
      flipuv = 1;
      opt_yv12 = 1;
    } else if (arg_match(&arg, &use_i420, argi)) {
      use_y4m = 0;
      flipuv = 0;
      opt_i420 = 1;
    } else if (arg_match(&arg, &rawvideo, argi)) {
      use_y4m = 0;
    } else if (arg_match(&arg, &flipuvarg, argi)) {
      flipuv = 1;
    } else if (arg_match(&arg, &noblitarg, argi)) {
      noblit = 1;
    } else if (arg_match(&arg, &progressarg, argi)) {
      progress = 1;
    } else if (arg_match(&arg, &limitarg, argi)) {
      stop_after = arg_parse_uint(&arg);
    } else if (arg_match(&arg, &skiparg, argi)) {
      arg_skip = arg_parse_uint(&arg);
    } else if (arg_match(&arg, &postprocarg, argi)) {
      postproc = 1;
    } else if (arg_match(&arg, &md5arg, argi)) {
      do_md5 = 1;
    } else if (arg_match(&arg, &framestatsarg, argi)) {
      framestats_file = fopen(arg.val, "w");
      if (!framestats_file) {
        die("Error: Could not open --framestats file (%s) for writing.\n",
            arg.val);
      }
    } else if (arg_match(&arg, &summaryarg, argi)) {
      summary = 1;
    } else if (arg_match(&arg, &threadsarg, argi)) {
      cfg.threads = arg_parse_uint(&arg);
    }
#if CONFIG_AV1_DECODER
    else if (arg_match(&arg, &frameparallelarg, argi))
      frame_parallel = 1;
#endif
    else if (arg_match(&arg, &verbosearg, argi))
      quiet = 0;
    else if (arg_match(&arg, &scalearg, argi))
      do_scale = 1;
    else if (arg_match(&arg, &fb_arg, argi))
      num_external_frame_buffers = arg_parse_uint(&arg);
    else if (arg_match(&arg, &continuearg, argi))
      keep_going = 1;
#if CONFIG_AOM_HIGHBITDEPTH
    else if (arg_match(&arg, &outbitdeptharg, argi)) {
      output_bit_depth = arg_parse_uint(&arg);
    }
#endif
#if CONFIG_EXT_TILE
    else if (arg_match(&arg, &tiler, argi))
      tile_row = arg_parse_int(&arg);
    else if (arg_match(&arg, &tilec, argi))
      tile_col = arg_parse_int(&arg);
#endif  // CONFIG_EXT_TILE
    else
      argj++;
  }

  /* Check for unrecognized options */
  for (argi = argv; *argi; argi++)
    if (argi[0][0] == '-' && strlen(argi[0]) > 1)
      die("Error: Unrecognized option %s\n", *argi);

  /* Handle non-option arguments */
  fn = argv[0];

  if (!fn) {
    free(argv);
    usage_exit();
  }
  /* Open file */
  infile = strcmp(fn, "-") ? fopen(fn, "rb") : set_binary_mode(stdin);

  if (!infile) {
    fatal("Failed to open input file '%s'", strcmp(fn, "-") ? fn : "stdin");
  }
#if CONFIG_OS_SUPPORT
  /* Make sure we don't dump to the terminal, unless forced to with -o - */
  if (!outfile_pattern && isatty(STDOUT_FILENO) && !do_md5 && !noblit) {
    fprintf(stderr,
            "Not dumping raw video to your terminal. Use '-o -' to "
            "override.\n");
    return EXIT_FAILURE;
  }
#endif
  input.aom_input_ctx->file = infile;
  if (file_is_ivf(input.aom_input_ctx))
    input.aom_input_ctx->file_type = FILE_TYPE_IVF;
#if CONFIG_WEBM_IO
  else if (file_is_webm(input.webm_ctx, input.aom_input_ctx))
    input.aom_input_ctx->file_type = FILE_TYPE_WEBM;
#endif
  else if (file_is_raw(input.aom_input_ctx))
    input.aom_input_ctx->file_type = FILE_TYPE_RAW;
  else {
    fprintf(stderr, "Unrecognized input file type.\n");
#if !CONFIG_WEBM_IO
    fprintf(stderr, "aomdec was built without WebM container support.\n");
#endif
    return EXIT_FAILURE;
  }

  outfile_pattern = outfile_pattern ? outfile_pattern : "-";
  single_file = is_single_file(outfile_pattern);

  if (!noblit && single_file) {
    generate_filename(outfile_pattern, outfile_name, PATH_MAX,
                      aom_input_ctx.width, aom_input_ctx.height, 0);
    if (do_md5)
      MD5Init(&md5_ctx);
    else
      outfile = open_outfile(outfile_name);
  }

  if (use_y4m && !noblit) {
    if (!single_file) {
      fprintf(stderr,
              "YUV4MPEG2 not supported with output patterns,"
              " try --i420 or --yv12 or --rawvideo.\n");
      return EXIT_FAILURE;
    }

#if CONFIG_WEBM_IO
    if (aom_input_ctx.file_type == FILE_TYPE_WEBM) {
      if (webm_guess_framerate(input.webm_ctx, input.aom_input_ctx)) {
        fprintf(stderr,
                "Failed to guess framerate -- error parsing "
                "webm file?\n");
        return EXIT_FAILURE;
      }
    }
#endif
  }

  fourcc_interface = get_aom_decoder_by_fourcc(aom_input_ctx.fourcc);
  if (interface && fourcc_interface && interface != fourcc_interface)
    warn("Header indicates codec: %s\n", fourcc_interface->name);
  else
    interface = fourcc_interface;

  if (!interface) interface = get_aom_decoder_by_index(0);

  dec_flags = (postproc ? AOM_CODEC_USE_POSTPROC : 0) |
              (ec_enabled ? AOM_CODEC_USE_ERROR_CONCEALMENT : 0) |
              (frame_parallel ? AOM_CODEC_USE_FRAME_THREADING : 0);
  if (aom_codec_dec_init(&decoder, interface->codec_interface(), &cfg,
                         dec_flags)) {
    fprintf(stderr, "Failed to initialize decoder: %s\n",
            aom_codec_error(&decoder));
    goto fail2;
  }

  if (!quiet) fprintf(stderr, "%s\n", decoder.name);

#if CONFIG_AV1_DECODER && CONFIG_EXT_TILE
  if (aom_codec_control(&decoder, AV1_SET_DECODE_TILE_ROW, tile_row)) {
    fprintf(stderr, "Failed to set decode_tile_row: %s\n",
            aom_codec_error(&decoder));
    goto fail;
  }

  if (aom_codec_control(&decoder, AV1_SET_DECODE_TILE_COL, tile_col)) {
    fprintf(stderr, "Failed to set decode_tile_col: %s\n",
            aom_codec_error(&decoder));
    goto fail;
  }
#endif

  if (arg_skip) fprintf(stderr, "Skipping first %d frames.\n", arg_skip);
  while (arg_skip) {
    if (read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) break;
    arg_skip--;
  }

  if (num_external_frame_buffers > 0) {
    ext_fb_list.num_external_frame_buffers = num_external_frame_buffers;
    ext_fb_list.ext_fb = (struct ExternalFrameBuffer *)calloc(
        num_external_frame_buffers, sizeof(*ext_fb_list.ext_fb));
    if (aom_codec_set_frame_buffer_functions(&decoder, get_av1_frame_buffer,
                                             release_av1_frame_buffer,
                                             &ext_fb_list)) {
      fprintf(stderr, "Failed to configure external frame buffers: %s\n",
              aom_codec_error(&decoder));
      goto fail;
    }
  }

  frame_avail = 1;
  got_data = 0;

  if (framestats_file) fprintf(framestats_file, "bytes,qp\r\n");

  /* Decode file */
  while (frame_avail || got_data) {
    aom_codec_iter_t iter = NULL;
    aom_image_t *img;
    struct aom_usec_timer timer;
    int corrupted = 0;

    frame_avail = 0;
    if (!stop_after || frame_in < stop_after) {
      if (!read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) {
        frame_avail = 1;
        frame_in++;

        aom_usec_timer_start(&timer);

        if (aom_codec_decode(&decoder, buf, (unsigned int)bytes_in_buffer, NULL,
                             0)) {
          const char *detail = aom_codec_error_detail(&decoder);
          warn("Failed to decode frame %d: %s", frame_in,
               aom_codec_error(&decoder));

          if (detail) warn("Additional information: %s", detail);
          if (!keep_going) goto fail;
        }

        if (framestats_file) {
          int qp;
          if (aom_codec_control(&decoder, AOMD_GET_LAST_QUANTIZER, &qp)) {
            warn("Failed AOMD_GET_LAST_QUANTIZER: %s",
                 aom_codec_error(&decoder));
            if (!keep_going) goto fail;
          }
          fprintf(framestats_file, "%d,%d\r\n", (int)bytes_in_buffer, qp);
        }

        aom_usec_timer_mark(&timer);
        dx_time += aom_usec_timer_elapsed(&timer);
      } else {
        flush_decoder = 1;
      }
    } else {
      flush_decoder = 1;
    }

    aom_usec_timer_start(&timer);

    if (flush_decoder) {
      // Flush the decoder in frame parallel decode.
      if (aom_codec_decode(&decoder, NULL, 0, NULL, 0)) {
        warn("Failed to flush decoder: %s", aom_codec_error(&decoder));
      }
    }

    got_data = 0;
    if ((img = aom_codec_get_frame(&decoder, &iter))) {
      ++frame_out;
      got_data = 1;
    }

    aom_usec_timer_mark(&timer);
    dx_time += (unsigned int)aom_usec_timer_elapsed(&timer);

    if (!frame_parallel &&
        aom_codec_control(&decoder, AOMD_GET_FRAME_CORRUPTED, &corrupted)) {
      warn("Failed AOM_GET_FRAME_CORRUPTED: %s", aom_codec_error(&decoder));
      if (!keep_going) goto fail;
    }
    frames_corrupted += corrupted;

    if (progress) show_progress(frame_in, frame_out, dx_time);

    if (!noblit && img) {
      const int PLANES_YUV[] = { AOM_PLANE_Y, AOM_PLANE_U, AOM_PLANE_V };
      const int PLANES_YVU[] = { AOM_PLANE_Y, AOM_PLANE_V, AOM_PLANE_U };
      const int *planes = flipuv ? PLANES_YVU : PLANES_YUV;

      if (do_scale) {
        if (frame_out == 1) {
          // If the output frames are to be scaled to a fixed display size then
          // use the width and height specified in the container. If either of
          // these is set to 0, use the display size set in the first frame
          // header. If that is unavailable, use the raw decoded size of the
          // first decoded frame.
          int render_width = aom_input_ctx.width;
          int render_height = aom_input_ctx.height;
          if (!render_width || !render_height) {
            int render_size[2];
            if (aom_codec_control(&decoder, AV1D_GET_DISPLAY_SIZE,
                                  render_size)) {
              // As last resort use size of first frame as display size.
              render_width = img->d_w;
              render_height = img->d_h;
            } else {
              render_width = render_size[0];
              render_height = render_size[1];
            }
          }
          scaled_img =
              aom_img_alloc(NULL, img->fmt, render_width, render_height, 16);
          scaled_img->bit_depth = img->bit_depth;
        }

        if (img->d_w != scaled_img->d_w || img->d_h != scaled_img->d_h) {
#if CONFIG_LIBYUV
          libyuv_scale(img, scaled_img, kFilterBox);
          img = scaled_img;
#else
          fprintf(stderr,
                  "Failed  to scale output frame: %s.\n"
                  "Scaling is disabled in this configuration. "
                  "To enable scaling, configure with --enable-libyuv\n",
                  aom_codec_error(&decoder));
          goto fail;
#endif
        }
      }
#if CONFIG_AOM_HIGHBITDEPTH
      // Default to codec bit depth if output bit depth not set
      if (!output_bit_depth && single_file && !do_md5) {
        output_bit_depth = img->bit_depth;
      }
      // Shift up or down if necessary
      if (output_bit_depth != 0 && output_bit_depth != img->bit_depth) {
        const aom_img_fmt_t shifted_fmt =
            output_bit_depth == 8
                ? img->fmt ^ (img->fmt & AOM_IMG_FMT_HIGHBITDEPTH)
                : img->fmt | AOM_IMG_FMT_HIGHBITDEPTH;
        if (img_shifted &&
            img_shifted_realloc_required(img, img_shifted, shifted_fmt)) {
          aom_img_free(img_shifted);
          img_shifted = NULL;
        }
        if (!img_shifted) {
          img_shifted =
              aom_img_alloc(NULL, shifted_fmt, img->d_w, img->d_h, 16);
          img_shifted->bit_depth = output_bit_depth;
        }
        if (output_bit_depth > img->bit_depth) {
          aom_img_upshift(img_shifted, img, output_bit_depth - img->bit_depth);
        } else {
          aom_img_downshift(img_shifted, img,
                            img->bit_depth - output_bit_depth);
        }
        img = img_shifted;
      }
#endif

#if CONFIG_EXT_TILE
      aom_input_ctx.width = img->d_w;
      aom_input_ctx.height = img->d_h;
#endif  // CONFIG_EXT_TILE

      if (single_file) {
        if (use_y4m) {
          char y4m_buf[Y4M_BUFFER_SIZE] = { 0 };
          size_t len = 0;
          if (img->fmt == AOM_IMG_FMT_I440 || img->fmt == AOM_IMG_FMT_I44016) {
            fprintf(stderr, "Cannot produce y4m output for 440 sampling.\n");
            goto fail;
          }
          if (frame_out == 1) {
            // Y4M file header
            len = y4m_write_file_header(
                y4m_buf, sizeof(y4m_buf), aom_input_ctx.width,
                aom_input_ctx.height, &aom_input_ctx.framerate, img->fmt,
                img->bit_depth);
            if (do_md5) {
              MD5Update(&md5_ctx, (md5byte *)y4m_buf, (unsigned int)len);
            } else {
              fputs(y4m_buf, outfile);
            }
          }

          // Y4M frame header
          len = y4m_write_frame_header(y4m_buf, sizeof(y4m_buf));
          if (do_md5) {
            MD5Update(&md5_ctx, (md5byte *)y4m_buf, (unsigned int)len);
          } else {
            fputs(y4m_buf, outfile);
          }
        } else {
          if (frame_out == 1) {
            // Check if --yv12 or --i420 options are consistent with the
            // bit-stream decoded
            if (opt_i420) {
              if (img->fmt != AOM_IMG_FMT_I420 &&
                  img->fmt != AOM_IMG_FMT_I42016) {
                fprintf(stderr, "Cannot produce i420 output for bit-stream.\n");
                goto fail;
              }
            }
            if (opt_yv12) {
              if ((img->fmt != AOM_IMG_FMT_I420 &&
                   img->fmt != AOM_IMG_FMT_YV12) ||
                  img->bit_depth != 8) {
                fprintf(stderr, "Cannot produce yv12 output for bit-stream.\n");
                goto fail;
              }
            }
          }
        }

        if (do_md5) {
          update_image_md5(img, planes, &md5_ctx);
        } else {
          write_image_file(img, planes, outfile);
        }
      } else {
        generate_filename(outfile_pattern, outfile_name, PATH_MAX, img->d_w,
                          img->d_h, frame_in);
        if (do_md5) {
          MD5Init(&md5_ctx);
          update_image_md5(img, planes, &md5_ctx);
          MD5Final(md5_digest, &md5_ctx);
          print_md5(md5_digest, outfile_name);
        } else {
          outfile = open_outfile(outfile_name);
          write_image_file(img, planes, outfile);
          fclose(outfile);
        }
      }
    }
  }

  if (summary || progress) {
    show_progress(frame_in, frame_out, dx_time);
    fprintf(stderr, "\n");
  }

  if (frames_corrupted) {
    fprintf(stderr, "WARNING: %d frames corrupted.\n", frames_corrupted);
  } else {
    ret = EXIT_SUCCESS;
  }

fail:

  if (aom_codec_destroy(&decoder)) {
    fprintf(stderr, "Failed to destroy decoder: %s\n",
            aom_codec_error(&decoder));
  }

fail2:

  if (!noblit && single_file) {
    if (do_md5) {
      MD5Final(md5_digest, &md5_ctx);
      print_md5(md5_digest, outfile_name);
    } else {
      fclose(outfile);
    }
  }

#if CONFIG_WEBM_IO
  if (input.aom_input_ctx->file_type == FILE_TYPE_WEBM)
    webm_free(input.webm_ctx);
#endif

  if (input.aom_input_ctx->file_type != FILE_TYPE_WEBM) free(buf);

  if (scaled_img) aom_img_free(scaled_img);
#if CONFIG_AOM_HIGHBITDEPTH
  if (img_shifted) aom_img_free(img_shifted);
#endif

  for (i = 0; i < ext_fb_list.num_external_frame_buffers; ++i) {
    free(ext_fb_list.ext_fb[i].data);
  }
  free(ext_fb_list.ext_fb);

  fclose(infile);
  if (framestats_file) fclose(framestats_file);

  free(argv);

  return ret;
}
Ejemplo n.º 12
0
/****************
 * Encrypt the file with the given userids (or ask if none
 * is supplied).
 */
int
encode_crypt( const char *filename, STRLIST remusr, int use_symkey )
{
    IOBUF inp = NULL, out = NULL;
    PACKET pkt;
    PKT_plaintext *pt = NULL;
    DEK *symkey_dek = NULL;
    STRING2KEY *symkey_s2k = NULL;
    int rc = 0, rc2 = 0;
    u32 filesize;
    cipher_filter_context_t cfx;
    armor_filter_context_t afx;
    compress_filter_context_t zfx;
    text_filter_context_t tfx;
    progress_filter_context_t pfx;
    PK_LIST pk_list,work_list;
    int do_compress = opt.compress_algo && !RFC1991;

    memset( &cfx, 0, sizeof cfx);
    memset( &afx, 0, sizeof afx);
    memset( &zfx, 0, sizeof zfx);
    memset( &tfx, 0, sizeof tfx);
    init_packet(&pkt);

    if(use_symkey
       && (rc=setup_symkey(&symkey_s2k,&symkey_dek)))
      return rc;

    if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) )
	return rc;

    if(PGP2) {
      for(work_list=pk_list; work_list; work_list=work_list->next)
	if(!(is_RSA(work_list->pk->pubkey_algo) &&
	     nbits_from_pk(work_list->pk)<=2048))
	  {
	    log_info(_("you can only encrypt to RSA keys of 2048 bits or "
		       "less in --pgp2 mode\n"));
	    compliance_failure();
	    break;
	  }
    }

    /* prepare iobufs */
    inp = iobuf_open(filename);
    if (inp)
      iobuf_ioctl (inp,3,1,NULL); /* disable fd caching */
    if (inp && is_secured_file (iobuf_get_fd (inp)))
      {
        iobuf_close (inp);
        inp = NULL;
        errno = EPERM;
      }
    if( !inp ) {
	log_error(_("can't open `%s': %s\n"), filename? filename: "[stdin]",
					strerror(errno) );
	rc = G10ERR_OPEN_FILE;
	goto leave;
    }
    else if( opt.verbose )
	log_info(_("reading from `%s'\n"), filename? filename: "[stdin]");

    handle_progress (&pfx, inp, filename);

    if( opt.textmode )
	iobuf_push_filter( inp, text_filter, &tfx );

    if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) )
	goto leave;

    if( opt.armor )
	iobuf_push_filter( out, armor_filter, &afx );

    /* create a session key */
    cfx.dek = xmalloc_secure_clear (sizeof *cfx.dek);
    if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
	cfx.dek->algo = select_algo_from_prefs(pk_list,PREFTYPE_SYM,-1,NULL);
	/* The only way select_algo_from_prefs can fail here is when
           mixing v3 and v4 keys, as v4 keys have an implicit
           preference entry for 3DES, and the pk_list cannot be empty.
           In this case, use 3DES anyway as it's the safest choice -
           perhaps the v3 key is being used in an OpenPGP
           implementation and we know that the implementation behind
           any v4 key can handle 3DES. */
	if( cfx.dek->algo == -1 ) {
	    cfx.dek->algo = CIPHER_ALGO_3DES;

	    if( PGP2 ) {
	      log_info(_("unable to use the IDEA cipher for all of the keys "
			 "you are encrypting to.\n"));
	      compliance_failure();
	    }
	}
    }
    else {
      if(!opt.expert &&
	 select_algo_from_prefs(pk_list,PREFTYPE_SYM,
				opt.def_cipher_algo,NULL)!=opt.def_cipher_algo)
	log_info(_("WARNING: forcing symmetric cipher %s (%d)"
		   " violates recipient preferences\n"),
		 cipher_algo_to_string(opt.def_cipher_algo),
		 opt.def_cipher_algo);

      cfx.dek->algo = opt.def_cipher_algo;
    }

    cfx.dek->use_mdc=use_mdc(pk_list,cfx.dek->algo);

    /* Only do the is-file-already-compressed check if we are using a
       MDC.  This forces compressed files to be re-compressed if we do
       not have a MDC to give some protection against chosen
       ciphertext attacks. */

    if (do_compress && cfx.dek->use_mdc && is_file_compressed(filename, &rc2) )
      {
        if (opt.verbose)
          log_info(_("`%s' already compressed\n"), filename);
        do_compress = 0;        
      }
    if (rc2)
      {
        rc = rc2;
        goto leave;
      }

    make_session_key( cfx.dek );
    if( DBG_CIPHER )
	log_hexdump("DEK is: ", cfx.dek->key, cfx.dek->keylen );

    rc = write_pubkey_enc_from_list( pk_list, cfx.dek, out );
    if( rc  )
	goto leave;

    /* We put the passphrase (if any) after any public keys as this
       seems to be the most useful on the recipient side - there is no
       point in prompting a user for a passphrase if they have the
       secret key needed to decrypt. */
    if(use_symkey && (rc=write_symkey_enc(symkey_s2k,symkey_dek,cfx.dek,out)))
      goto leave;

    if (!opt.no_literal) {
	/* setup the inner packet */
	if( filename || opt.set_filename ) {
	    char *s = make_basename( opt.set_filename ? opt.set_filename
						      : filename,
				     iobuf_get_real_fname( inp ) );
	    pt = xmalloc( sizeof *pt + strlen(s) - 1 );
	    pt->namelen = strlen(s);
	    memcpy(pt->name, s, pt->namelen );
	    xfree(s);
	}
	else { /* no filename */
	    pt = xmalloc( sizeof *pt - 1 );
	    pt->namelen = 0;
	}
    }

    if (!iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
      {
        off_t tmpsize;
        int overflow;

	if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
             && !overflow )
          log_info(_("WARNING: `%s' is an empty file\n"), filename );
        /* We can't encode the length of very large files because
           OpenPGP uses only 32 bit for file sizes.  So if the the
           size of a file is larger than 2^32 minus some bytes for
           packet headers, we switch to partial length encoding. */
        if (tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
          filesize = tmpsize;
        else
          filesize = 0;
      }
    else
      filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */

    if (!opt.no_literal) {
	pt->timestamp = make_timestamp();
	pt->mode = opt.textmode ? 't' : 'b';
	pt->len = filesize;
	pt->new_ctb = !pt->len && !RFC1991;
	pt->buf = inp;
	pkt.pkttype = PKT_PLAINTEXT;
	pkt.pkt.plaintext = pt;
	cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0;
    }
    else
	cfx.datalen = filesize && !do_compress ? filesize : 0;

    /* register the cipher filter */
    iobuf_push_filter( out, cipher_filter, &cfx );

    /* register the compress filter */
    if( do_compress ) {
	int compr_algo = opt.compress_algo;

	if(compr_algo==-1)
	  {
	    if((compr_algo=
		select_algo_from_prefs(pk_list,PREFTYPE_ZIP,-1,NULL))==-1)
	      compr_algo=DEFAULT_COMPRESS_ALGO;
	    /* Theoretically impossible to get here since uncompressed
	       is implicit. */
	  }
	else if(!opt.expert &&
		select_algo_from_prefs(pk_list,PREFTYPE_ZIP,
				       compr_algo,NULL)!=compr_algo)
	  log_info(_("WARNING: forcing compression algorithm %s (%d)"
		     " violates recipient preferences\n"),
		   compress_algo_to_string(compr_algo),compr_algo);

	/* algo 0 means no compression */
	if( compr_algo )
	  {
            if (cfx.dek && cfx.dek->use_mdc)
              zfx.new_ctb = 1;
	    push_compress_filter(out,&zfx,compr_algo);
	  }
    }

    /* do the work */
    if (!opt.no_literal) {
	if( (rc = build_packet( out, &pkt )) )
	    log_error("build_packet failed: %s\n", g10_errstr(rc) );
    }
    else {
	/* user requested not to create a literal packet, so we copy
           the plain data */
	byte copy_buffer[4096];
	int  bytes_copied;
	while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
	    if (iobuf_write(out, copy_buffer, bytes_copied) == -1) {
		rc = G10ERR_WRITE_FILE;
		log_error("copying input to output failed: %s\n",
                          g10_errstr(rc) );
		break;
	    }
	wipememory(copy_buffer, 4096); /* burn buffer */
    }

    /* finish the stuff */
  leave:
    iobuf_close(inp);
    if( rc )
	iobuf_cancel(out);
    else {
	iobuf_close(out); /* fixme: check returncode */
        write_status( STATUS_END_ENCRYPTION );
    }
    if( pt )
	pt->buf = NULL;
    free_packet(&pkt);
    xfree(cfx.dek);
    xfree(symkey_dek);
    xfree(symkey_s2k);
    release_pk_list( pk_list );
    return rc;
}
Ejemplo n.º 13
0
/* We don't want to use use_seskey yet because older gnupg versions
   can't handle it, and there isn't really any point unless we're
   making a message that can be decrypted by a public key or
   passphrase. */
static int
encode_simple( const char *filename, int mode, int use_seskey )
{
    IOBUF inp, out;
    PACKET pkt;
    PKT_plaintext *pt = NULL;
    STRING2KEY *s2k = NULL;
    byte enckey[33];
    int rc = 0;
    int seskeylen = 0;
    u32 filesize;
    cipher_filter_context_t cfx;
    armor_filter_context_t afx;
    compress_filter_context_t zfx;
    text_filter_context_t tfx;
    progress_filter_context_t pfx;
    int do_compress = !RFC1991 && default_compress_algo();

    memset( &cfx, 0, sizeof cfx);
    memset( &afx, 0, sizeof afx);
    memset( &zfx, 0, sizeof zfx);
    memset( &tfx, 0, sizeof tfx);
    init_packet(&pkt);
    
    /* prepare iobufs */
    inp = iobuf_open(filename);
    if (inp)
      iobuf_ioctl (inp,3,1,NULL); /* disable fd caching */
    if (inp && is_secured_file (iobuf_get_fd (inp)))
      {
        iobuf_close (inp);
        inp = NULL;
        errno = EPERM;
      }
    if( !inp ) {
	log_error(_("can't open `%s': %s\n"), filename? filename: "[stdin]",
                  strerror(errno) );
	return G10ERR_OPEN_FILE;
    }

    handle_progress (&pfx, inp, filename);

    if( opt.textmode )
	iobuf_push_filter( inp, text_filter, &tfx );

    /* Due the the fact that we use don't use an IV to encrypt the
       session key we can't use the new mode with RFC1991 because
       it has no S2K salt. RFC1991 always uses simple S2K. */
    if ( RFC1991 && use_seskey )
        use_seskey = 0;
    
    cfx.dek = NULL;
    if( mode ) {
	s2k = xmalloc_clear( sizeof *s2k );
	s2k->mode = RFC1991? 0:opt.s2k_mode;
	s2k->hash_algo=S2K_DIGEST_ALGO;
	cfx.dek = passphrase_to_dek( NULL, 0,
				     default_cipher_algo(), s2k, 2,
                                     NULL, NULL);
	if( !cfx.dek || !cfx.dek->keylen ) {
	    rc = G10ERR_PASSPHRASE;
	    xfree(cfx.dek);
	    xfree(s2k);
	    iobuf_close(inp);
	    log_error(_("error creating passphrase: %s\n"), g10_errstr(rc) );
	    return rc;
	}
        if (use_seskey && s2k->mode != 1 && s2k->mode != 3) {
            use_seskey = 0;
            log_info (_("can't use a symmetric ESK packet "
                        "due to the S2K mode\n"));
        }

        if ( use_seskey )
	  {
	    DEK *dek = NULL;
            seskeylen = cipher_get_keylen( default_cipher_algo() ) / 8;
            encode_seskey( cfx.dek, &dek, enckey );
            xfree( cfx.dek ); cfx.dek = dek;
	  }

	if(opt.verbose)
	  log_info(_("using cipher %s\n"),
		   cipher_algo_to_string(cfx.dek->algo));

	cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo);
    }

    if (do_compress && cfx.dek && cfx.dek->use_mdc
	&& is_file_compressed(filename, &rc))
      {
        if (opt.verbose)
          log_info(_("`%s' already compressed\n"), filename);
        do_compress = 0;        
      }

    if( rc || (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) {
	iobuf_cancel(inp);
	xfree(cfx.dek);
	xfree(s2k);
	return rc;
    }

    if( opt.armor )
	iobuf_push_filter( out, armor_filter, &afx );

    if( s2k && !RFC1991 ) {
	PKT_symkey_enc *enc = xmalloc_clear( sizeof *enc + seskeylen + 1 );
	enc->version = 4;
	enc->cipher_algo = cfx.dek->algo;
	enc->s2k = *s2k;
        if ( use_seskey && seskeylen ) {
            enc->seskeylen = seskeylen + 1; /* algo id */
            memcpy( enc->seskey, enckey, seskeylen + 1 );
        }
	pkt.pkttype = PKT_SYMKEY_ENC;
	pkt.pkt.symkey_enc = enc;
	if( (rc = build_packet( out, &pkt )) )
	    log_error("build symkey packet failed: %s\n", g10_errstr(rc) );
	xfree(enc);
    }

    if (!opt.no_literal)
      pt=setup_plaintext_name(filename,inp);

    /* Note that PGP 5 has problems decrypting symmetrically encrypted
       data if the file length is in the inner packet. It works when
       only partial length headers are use.  In the past, we always
       used partial body length here, but since PGP 2, PGP 6, and PGP
       7 need the file length, and nobody should be using PGP 5
       nowadays anyway, this is now set to the file length.  Note also
       that this only applies to the RFC-1991 style symmetric
       messages, and not the RFC-2440 style.  PGP 6 and 7 work with
       either partial length or fixed length with the new style
       messages. */

    if ( !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
      {
        off_t tmpsize;
        int overflow;

	if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
             && !overflow )
          log_info(_("WARNING: `%s' is an empty file\n"), filename );
        /* We can't encode the length of very large files because
           OpenPGP uses only 32 bit for file sizes.  So if the the
           size of a file is larger than 2^32 minus some bytes for
           packet headers, we switch to partial length encoding. */
        if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
          filesize = tmpsize;
        else
          filesize = 0;
      }
    else
      filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */

    if (!opt.no_literal) {
	pt->timestamp = make_timestamp();
	pt->mode = opt.textmode? 't' : 'b';
	pt->len = filesize;
	pt->new_ctb = !pt->len && !RFC1991;
	pt->buf = inp;
	pkt.pkttype = PKT_PLAINTEXT;
	pkt.pkt.plaintext = pt;
	cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0;
    }
    else
      {
        cfx.datalen = filesize && !do_compress ? filesize : 0;
        pkt.pkttype = 0;
        pkt.pkt.generic = NULL;
      }

    /* register the cipher filter */
    if( mode )
	iobuf_push_filter( out, cipher_filter, &cfx );
    /* register the compress filter */
    if( do_compress )
      {
        if (cfx.dek && cfx.dek->use_mdc)
          zfx.new_ctb = 1;
	push_compress_filter(out,&zfx,default_compress_algo());
      }

    /* do the work */
    if (!opt.no_literal) {
	if( (rc = build_packet( out, &pkt )) )
	    log_error("build_packet failed: %s\n", g10_errstr(rc) );
    }
    else {
	/* user requested not to create a literal packet,
	 * so we copy the plain data */
	byte copy_buffer[4096];
	int  bytes_copied;
	while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
	    if (iobuf_write(out, copy_buffer, bytes_copied) == -1) {
		rc = G10ERR_WRITE_FILE;
		log_error("copying input to output failed: %s\n", g10_errstr(rc) );
		break;
	    }
	wipememory(copy_buffer, 4096); /* burn buffer */
    }

    /* finish the stuff */
    iobuf_close(inp);
    if (rc)
	iobuf_cancel(out);
    else {
	iobuf_close(out); /* fixme: check returncode */
        if (mode)
            write_status( STATUS_END_ENCRYPTION );
    }
    if (pt)
	pt->buf = NULL;
    free_packet(&pkt);
    xfree(cfx.dek);
    xfree(s2k);
    return rc;
}
Ejemplo n.º 14
0
int
http_transfer(UrlResource *rsrc)
{
        FILE *out 		= NULL;
        Url *u			= NULL;
        Url *proxy_url		= NULL;
        Url *redir_u		= NULL;
        char *request		= NULL;
        char *raw_header	= NULL;
        HttpHeader *header	= NULL;
        char *len_string 	= NULL;
        char *new_location	= NULL;
        char buf[BUFSIZE];
        int sock 		= 0;
        ssize_t bytes_read	= 0;
        int retval		= 0;
        int i;

        /* make sure we haven't recursed too much */

        if( redirect_count > REDIRECT_MAX ) {
                report(ERR, "redirection max count exceeded " 
                      "(looping redirect?)");
                redirect_count = 0;
                return 0;
        }


        /* make sure everything's initialized to something useful */
        u = rsrc->url;
     
        if( ! *(u->host) ) {
                report(ERR, "no host specified");
                return 0;
        }

        /* fill in proxyness */
        if( !rsrc->proxy ) {
                rsrc->proxy = get_proxy("HTTP_PROXY");
        }

        if( !rsrc->outfile ) {
                if( u->file ) 
                        rsrc->outfile = strdup(u->file);
                else
                        rsrc->outfile = strdup("index.html");
        }

        if( !u->path )
                u->path = strdup("/");

        if( !u->file )
                u->file = strdup("");  /* funny looking */

        if( !u->port )
                u->port = 80;

        rsrc->options |= default_opts;
                
        /* send the request to either the proxy or the remote host */
        if( rsrc->proxy ) {
                proxy_url = url_new();
                url_init(proxy_url, rsrc->proxy);
                
                if( !proxy_url->port ) 
                        proxy_url->port = 80;

                if( !proxy_url->host ) {
                        report(ERR, "bad proxy `%s'", rsrc->proxy);
                        return 0;
                }

                if( proxy_url->username )
                        rsrc->proxy_username = strdup(proxy_url->username);

                if( proxy_url->password )
                        rsrc->proxy_password = strdup(proxy_url->password);

                /* Prompt for proxy password if not specified */
                if( proxy_url->username && !proxy_url->password ) {
                        char *prompt = NULL;
                        prompt = strconcat("Password for proxy ",
                                           proxy_url->username, "@",
                                           proxy_url->host, ": ", NULL);
                        proxy_url->password = strdup(getpass(prompt));
                        free(prompt);
                }

                if( ! (sock = tcp_connect(proxy_url->host, proxy_url->port)) )
                        return 0;


                u->path = strdup("");
                u->file = strdup(u->full_url);
                request = get_request(rsrc);

                write(sock, request, strlen(request));

        } else /* no proxy */ {

                if( ! (sock = tcp_connect(u->host, u->port)) )
                        return 0;

                request = get_request(rsrc);
                write(sock, request, strlen(request));
        }

        
        out = open_outfile(rsrc);
        if( !out ) {
                report(ERR, "opening %s: %s", rsrc->outfile, strerror(errno));
                return 0;
        }

        /* check to see if it returned a HTTP 1.x response */
        memset(buf, '\0', 5);

        bytes_read = read(sock, buf, 8);

        if( bytes_read == 0 ) {
                close(sock);
                return 0;
        }

        if( ! (buf[0] == 'H' && buf[1] == 'T' 
               && buf[2] == 'T' && buf[3] == 'P') ) {
                if ((rsrc->options & OPT_RESUME) && 
                    rsrc->outfile_offset) {
                        report(WARN,
                               "server does not support resume, "
                               "try again"
                               " with -n (no resume)");
                        retval = 0;
                        goto cleanup;
                }
                write(fileno(out), buf, bytes_read);
        } else {
                /* skip the header */
                buf[bytes_read] = '\0';
                raw_header = get_raw_header(sock);
                raw_header = strconcat(buf, raw_header, NULL);
                header = make_http_header(raw_header);

                if (rsrc->options & OPT_VERBOSE) {
                        fwrite(raw_header, 1, strlen(raw_header), stderr);
                }


                /* check for redirects */
                new_location = get_header_value("location", header);

                if (raw_header[9] == '3' && new_location ) {
                        redir_u = url_new();
                        
                        /* make sure we still send user/password along */
                        redir_u->username = safe_strdup(u->username);
                        redir_u->password = safe_strdup(u->password);

                        url_init(redir_u, new_location);
                        rsrc->url = redir_u;
                        redirect_count++;
                        retval = transfer(rsrc);
                        goto cleanup;
                }

                if (raw_header[9] == '4' || raw_header[9] == '5') {
                        for(i = 0; raw_header[i] && raw_header[i] != '\n'; i++);
                        raw_header[i] = '\0';
                        report(ERR, "HTTP error from server: %s", raw_header);
                        retval = 0;
                        goto cleanup;
                }
                        
                len_string = get_header_value("content-length", header);

                if (len_string)
                        rsrc->outfile_size = (off_t )atoi(len_string);

                if (get_header_value("content-range", header))
                        rsrc->outfile_size += rsrc->outfile_offset;

                if( (!rsrc->outfile_size) && 
                    (rsrc->options & OPT_RESUME) && 
                    !(rsrc->options & OPT_NORESUME)
                    && rsrc->outfile_offset ) {
                        report(WARN,
                             "unable to determine remote file size, try again"
                             " with -n (no resume)");
                        retval = 0;
                        goto cleanup;
                }
        }

        if( ! dump_data(rsrc, sock, out) )
                retval = 0;
        else
                retval = 1;
                        
 cleanup:
        free_http_header(header);
        close(sock); fclose(out);
        return retval;

}
Ejemplo n.º 15
0
/*
 * Encrypt the file with the given userids (or ask if none is
 * supplied).  Either FILENAME or FILEFD must be given, but not both.
 * The caller may provide a checked list of public keys in
 * PROVIDED_PKS; if not the function builds a list of keys on its own.
 *
 * Note that FILEFD is currently only used by cmd_encrypt in the the
 * not yet finished server.c.
 */
int
encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
               strlist_t remusr, int use_symkey, pk_list_t provided_keys,
               int outputfd)
{
  iobuf_t inp = NULL;
  iobuf_t out = NULL;
  PACKET pkt;
  PKT_plaintext *pt = NULL;
  DEK *symkey_dek = NULL;
  STRING2KEY *symkey_s2k = NULL;
  int rc = 0, rc2 = 0;
  u32 filesize;
  cipher_filter_context_t cfx;
  armor_filter_context_t *afx = NULL;
  compress_filter_context_t zfx;
  text_filter_context_t tfx;
  progress_filter_context_t *pfx;
  PK_LIST pk_list;
  int do_compress;

  if (filefd != -1 && filename)
    return gpg_error (GPG_ERR_INV_ARG);  /* Both given.  */

  do_compress = !!opt.compress_algo;

  pfx = new_progress_context ();
  memset( &cfx, 0, sizeof cfx);
  memset( &zfx, 0, sizeof zfx);
  memset( &tfx, 0, sizeof tfx);
  init_packet(&pkt);

  if (use_symkey
      && (rc=setup_symkey(&symkey_s2k,&symkey_dek)))
    {
      release_progress_context (pfx);
      return rc;
    }

  if (provided_keys)
    pk_list = provided_keys;
  else
    {
      if ((rc = build_pk_list (ctrl, remusr, &pk_list, PUBKEY_USAGE_ENC)))
        {
          release_progress_context (pfx);
          return rc;
        }
    }

  /* Prepare iobufs. */
#ifdef HAVE_W32_SYSTEM
  if (filefd == -1)
    inp = iobuf_open_fd_or_name (GNUPG_INVALID_FD, filename, "rb");
  else
    {
      inp = NULL;
      gpg_err_set_errno (ENOSYS);
    }
#else
  inp = iobuf_open_fd_or_name (filefd, filename, "rb");
#endif
  if (inp)
    iobuf_ioctl (inp, IOBUF_IOCTL_NO_CACHE, 1, NULL);
  if (inp && is_secured_file (iobuf_get_fd (inp)))
    {
      iobuf_close (inp);
      inp = NULL;
      gpg_err_set_errno (EPERM);
    }
  if (!inp)
    {
      char xname[64];

      rc = gpg_error_from_syserror ();
      if (filefd != -1)
        snprintf (xname, sizeof xname, "[fd %d]", filefd);
      else if (!filename)
        strcpy (xname, "[stdin]");
      else
        *xname = 0;
      log_error (_("can't open '%s': %s\n"),
                 *xname? xname : filename, gpg_strerror (rc) );
      goto leave;
    }

  if (opt.verbose)
    log_info (_("reading from '%s'\n"), iobuf_get_fname_nonnull (inp));

  handle_progress (pfx, inp, filename);

  if (opt.textmode)
    iobuf_push_filter (inp, text_filter, &tfx);

  rc = open_outfile (outputfd, filename, opt.armor? 1:0, 0, &out);
  if (rc)
    goto leave;

  if (opt.armor)
    {
      afx = new_armor_context ();
      push_armor_filter (afx, out);
    }

  /* Create a session key. */
  cfx.dek = xmalloc_secure_clear (sizeof *cfx.dek);
  if (!opt.def_cipher_algo)
    {
      /* Try to get it from the prefs.  */
      cfx.dek->algo = select_algo_from_prefs (pk_list, PREFTYPE_SYM, -1, NULL);
      /* The only way select_algo_from_prefs can fail here is when
         mixing v3 and v4 keys, as v4 keys have an implicit preference
         entry for 3DES, and the pk_list cannot be empty.  In this
         case, use 3DES anyway as it's the safest choice - perhaps the
         v3 key is being used in an OpenPGP implementation and we know
         that the implementation behind any v4 key can handle 3DES. */
      if (cfx.dek->algo == -1)
        {
          cfx.dek->algo = CIPHER_ALGO_3DES;
        }

      /* In case 3DES has been selected, print a warning if any key
         does not have a preference for AES.  This should help to
         indentify why encrypting to several recipients falls back to
         3DES. */
      if (opt.verbose && cfx.dek->algo == CIPHER_ALGO_3DES)
        warn_missing_aes_from_pklist (pk_list);
    }
  else
    {
      if (!opt.expert
          && (select_algo_from_prefs (pk_list, PREFTYPE_SYM,
                                      opt.def_cipher_algo, NULL)
              != opt.def_cipher_algo))
        {
          log_info(_("WARNING: forcing symmetric cipher %s (%d)"
                     " violates recipient preferences\n"),
                   openpgp_cipher_algo_name (opt.def_cipher_algo),
                   opt.def_cipher_algo);
        }

      cfx.dek->algo = opt.def_cipher_algo;
    }

  cfx.dek->use_mdc = use_mdc (pk_list,cfx.dek->algo);

  /* Only do the is-file-already-compressed check if we are using a
     MDC.  This forces compressed files to be re-compressed if we do
     not have a MDC to give some protection against chosen ciphertext
     attacks. */

  if (do_compress && cfx.dek->use_mdc && is_file_compressed(filename, &rc2))
    {
      if (opt.verbose)
        log_info(_("'%s' already compressed\n"), filename);
      do_compress = 0;
    }
  if (rc2)
    {
      rc = rc2;
      goto leave;
    }

  make_session_key (cfx.dek);
  if (DBG_CRYPTO)
    log_printhex ("DEK is: ", cfx.dek->key, cfx.dek->keylen );

  rc = write_pubkey_enc_from_list (pk_list, cfx.dek, out);
  if (rc)
    goto leave;

  /* We put the passphrase (if any) after any public keys as this
     seems to be the most useful on the recipient side - there is no
     point in prompting a user for a passphrase if they have the
     secret key needed to decrypt.  */
  if(use_symkey && (rc = write_symkey_enc(symkey_s2k,symkey_dek,cfx.dek,out)))
    goto leave;

  if (!opt.no_literal)
    pt = setup_plaintext_name (filename, inp);

  /* Get the size of the file if possible, i.e., if it is a real file.  */
  if (filename && *filename
      && !iobuf_is_pipe_filename (filename) && !opt.textmode )
    {
      off_t tmpsize;
      int overflow;

      if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
           && !overflow && opt.verbose)
        log_info(_("WARNING: '%s' is an empty file\n"), filename );
      /* We can't encode the length of very large files because
         OpenPGP uses only 32 bit for file sizes.  So if the the size
         of a file is larger than 2^32 minus some bytes for packet
         headers, we switch to partial length encoding. */
      if (tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
        filesize = tmpsize;
      else
        filesize = 0;
    }
  else
    filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */

  if (!opt.no_literal)
    {
      pt->timestamp = make_timestamp();
      pt->mode = opt.textmode ? 't' : 'b';
      pt->len = filesize;
      pt->new_ctb = !pt->len;
      pt->buf = inp;
      pkt.pkttype = PKT_PLAINTEXT;
      pkt.pkt.plaintext = pt;
      cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0;
    }
  else
    cfx.datalen = filesize && !do_compress ? filesize : 0;

  /* Register the cipher filter. */
  iobuf_push_filter (out, cipher_filter, &cfx);

  /* Register the compress filter. */
  if (do_compress)
    {
      int compr_algo = opt.compress_algo;

      if (compr_algo == -1)
        {
          compr_algo = select_algo_from_prefs (pk_list, PREFTYPE_ZIP, -1, NULL);
          if (compr_algo == -1)
            compr_algo = DEFAULT_COMPRESS_ALGO;
          /* Theoretically impossible to get here since uncompressed
             is implicit.  */
        }
      else if (!opt.expert
               && select_algo_from_prefs(pk_list, PREFTYPE_ZIP,
                                         compr_algo, NULL) != compr_algo)
        {
          log_info (_("WARNING: forcing compression algorithm %s (%d)"
                      " violates recipient preferences\n"),
                    compress_algo_to_string(compr_algo), compr_algo);
        }

      /* Algo 0 means no compression. */
      if (compr_algo)
        {
          if (cfx.dek && cfx.dek->use_mdc)
            zfx.new_ctb = 1;
          push_compress_filter (out,&zfx,compr_algo);
        }
    }

  /* Do the work. */
  if (!opt.no_literal)
    {
      if ((rc = build_packet( out, &pkt )))
        log_error ("build_packet failed: %s\n", gpg_strerror (rc));
    }
  else
    {
      /* User requested not to create a literal packet, so we copy the
         plain data. */
      byte copy_buffer[4096];
      int  bytes_copied;
      while ((bytes_copied = iobuf_read (inp, copy_buffer, 4096)) != -1)
        {
          rc = iobuf_write (out, copy_buffer, bytes_copied);
          if (rc)
            {
              log_error ("copying input to output failed: %s\n",
                         gpg_strerror (rc));
              break;
            }
        }
      wipememory (copy_buffer, 4096); /* Burn the buffer. */
    }

  /* Finish the stuff. */
 leave:
  iobuf_close (inp);
  if (rc)
    iobuf_cancel (out);
  else
    {
      iobuf_close (out); /* fixme: check returncode */
      write_status (STATUS_END_ENCRYPTION);
    }
  if (pt)
    pt->buf = NULL;
  free_packet (&pkt);
  xfree (cfx.dek);
  xfree (symkey_dek);
  xfree (symkey_s2k);
  if (!provided_keys)
    release_pk_list (pk_list);
  release_armor_context (afx);
  release_progress_context (pfx);
  return rc;
}
Ejemplo n.º 16
0
bool AlignCoderSNV::recode(string m5_file, string var_file, string recode_file, int left_len, int right_len, bool is_report_ref)
{
    // load var_file
    vector<VarData> var_data;
    ifstream fs_varfile;
    int64_t max_code = -1;
    open_infile(fs_varfile, var_file);
    while(true){
        string buf;
        getline(fs_varfile, buf);
        if(fs_varfile.eof())
            break;
        vector<string> buf_vec = split(buf, '\t');
        if (buf_vec.size()!=9)
            throw runtime_error("incorrect format in " + var_file);
        var_data.push_back(VarData(stod(buf_vec[0]), buf_vec[1][0], stod(buf_vec[2])));
        
        if (stod(buf_vec[2]) > max_code)
            max_code = stod(buf_vec[2]);
    }
    fs_varfile.close();
    
    // fill template of var_data
    vector<bool> var_data_temp(max_code + 4, false);
    for (int64_t i = 0; i < var_data.size(); ++i)
        var_data_temp[var_data[i].code] = true;
    
    
    // scan m5_file and recode
    if (p_alignreader==NULL)
        throw runtime_error("AlignCoderSNV::recode(): p_alignreader has not be set.");
    ofstream p_outfile;
    open_outfile(p_outfile, recode_file);
    ofstream p_outfile_ref;
    open_outfile(p_outfile_ref, recode_file + ".ref");
    
    p_alignreader->open(m5_file);
    Align align;
    int nline = 0;
    while(p_alignreader->readline(align)){
        ++nline;
        if (nline % 100 == 0)
            cout << nline << endl;
        //cout << nline << endl;
        
        // expections
        int alen = (int) align.matchPattern.size();
        if ( !(align.qAlignedSeq.size()==alen && align.tAlignedSeq.size()==alen) )
            throw runtime_error("incorrect match patter in line " + to_string(nline));
        if (align.qStrand != '+')
            throw runtime_error("qStrand should be + in line " + to_string(nline));
        
        // reverse alignment if it is aligned to negative strand
        if (align.tStrand != '+'){
            align.qAlignedSeq = getrevcomp(align.qAlignedSeq);
            align.tAlignedSeq = getrevcomp(align.tAlignedSeq);
        }
        
        // encode
        int cur_pos = align.tStart;
        for (int i=0; i<alen; i++){
            //cout << "nline=" << nline << ", i=" <<i << endl;
            if (align.tAlignedSeq[i]=='-')
                continue;
            
            if (4*cur_pos+3 > max_code + 3)
                break;
            
            // realign if hit detected variants
            int score_A = MIN_SCORE;
            int score_C = MIN_SCORE;
            int score_G = MIN_SCORE;
            int score_T = MIN_SCORE;
            bool is_var = false;

            seqan::Align<string, seqan::ArrayGaps> cur_realign_A;
            seqan::Align<string, seqan::ArrayGaps> cur_realign_C;
            seqan::Align<string, seqan::ArrayGaps> cur_realign_G;
            seqan::Align<string, seqan::ArrayGaps> cur_realign_T;
            
            string cur_qseq;
            string cur_rseq;
            pair<string, string> context;
            char ref_base;
            
            // align local sequence to the referece
            if (var_data_temp[4*cur_pos] || var_data_temp[4*cur_pos+1] || var_data_temp[4*cur_pos+2] || var_data_temp[4*cur_pos+3]){
                bool rl = this->get_context_m5(i, left_len, right_len, align.tAlignedSeq, context);
                if (!rl){
                    ++cur_pos;
                    continue;
                }
                
                is_var = true;

                // get left query sequence length
                int64_t k = 0;
                int64_t cur_qseq_start = i;
                while(true){
                    if (align.tAlignedSeq[cur_qseq_start]!='-')
                        k++;
                    if (k >= context.first.size())
                        break;
                    --cur_qseq_start;
                }
                
                
                // get right query sequence length
                k = 0;
                int64_t cur_qseq_end = i+1;
                while(true){
                    if (align.tAlignedSeq[cur_qseq_end]!='-')
                        k++;
                    if (k >= context.second.size())
                        break;
                    ++cur_qseq_end;
                }
                
                if (cur_qseq_start < 0)
                    throw runtime_error("cur_qseq_start < 0");
                if (cur_qseq_end >= alen)
                    throw runtime_error("cur_qseq_end >= alen");
                
                for (auto j = cur_qseq_start; j <= cur_qseq_end; ++j){
                    if (align.qAlignedSeq[j]!='-')
                        cur_qseq.push_back(align.qAlignedSeq[j]);
                }
                
                cur_rseq = context.first + context.second;
                
                if (cur_qseq == ""){
                    ++cur_pos;
                    continue;
                }
                
                if (cur_rseq == "")
                    throw runtime_error("cur_rseq is empty");
                
                ref_base = cur_rseq[context.first.size()-1];
                
                // realign
                cur_rseq[context.first.size()-1] = 'A';
                score_A = this->realign(cur_realign_A, cur_qseq, cur_rseq);
                
                cur_rseq[context.first.size()-1] = 'C';
                score_C = this->realign(cur_realign_C, cur_qseq, cur_rseq);
                
                cur_rseq[context.first.size()-1] = 'G';
                score_G = this->realign(cur_realign_G, cur_qseq, cur_rseq);
                
                cur_rseq[context.first.size()-1] = 'T';
                score_T = this->realign(cur_realign_T, cur_qseq, cur_rseq);
                
                // to be removed
                /*if ((cur_pos==253 || cur_pos==319 || cur_pos==325) && nline == 7445){
                    cout << "cur_pos = " << cur_pos << endl;
                    cout << "A: " << score_A << endl << cur_realign_A;
                    cout << "C: " << score_C << endl << cur_realign_C;
                    cout << "G: " << score_G << endl << cur_realign_G;
                    cout << "T: " << score_T << endl << cur_realign_T;
                    int tmp = 0;
                }*/
            }else{
                ++cur_pos;
                continue;
            }
            
            // recode
            if (score_A == MIN_SCORE && score_C == MIN_SCORE && score_G == MIN_SCORE && score_T == MIN_SCORE)
                throw runtime_error("A,C,G,T == MIN_SCORE, no alignment was done");
            // A
            if (score_A > score_C && score_A > score_G && score_A > score_T){
                if (align.tAlignedSeq[i]!='A'){
                    p_outfile << 4*cur_pos << '\t';
                }else{
                    if (is_report_ref)
                        p_outfile_ref << 4*cur_pos << '\t';
                }
            }
            
            // C
            if (score_C > score_A && score_C > score_G && score_C > score_T){
                if (align.tAlignedSeq[i]!='C'){
                    p_outfile << 4*cur_pos+1 << '\t';
                }else{
                    if (is_report_ref)
                        p_outfile_ref << 4*cur_pos+1 << '\t';
                }
            }
            
            // G
            if (score_G > score_A && score_G > score_C && score_G > score_T){
                if (align.tAlignedSeq[i]!='G'){
                    p_outfile << 4*cur_pos+2 << '\t';
                }else{
                    if (is_report_ref)
                        p_outfile_ref << 4*cur_pos+2 << '\t';
                }
            }
            
            // T
            if (score_T > score_A && score_T > score_C && score_T > score_G){
                if (align.tAlignedSeq[i]!='T'){
                    p_outfile << 4*cur_pos+3 << '\t';
                }else{
                    if (is_report_ref)
                        p_outfile_ref << 4*cur_pos+3 << '\t';
                }
                
            }
            
            ++cur_pos;
        }
        p_outfile << endl;
        p_outfile_ref << endl;
    }
    
    p_alignreader->close();
    
    
    p_outfile.close();
    p_outfile_ref.close();
    
    return true;
}
Ejemplo n.º 17
0
int main_loop(int argc, const char **argv_) {
  vpx_codec_ctx_t       decoder;
  char                  *fn = NULL;
  int                    i;
  uint8_t               *buf = NULL;
  size_t                 bytes_in_buffer = 0, buffer_size = 0;
  FILE                  *infile;
  int                    frame_in = 0, frame_out = 0, flipuv = 0, noblit = 0;
  int                    do_md5 = 0, progress = 0;
  int                    stop_after = 0, postproc = 0, summary = 0, quiet = 1;
  int                    arg_skip = 0;
  int                    ec_enabled = 0;
  const VpxInterface *interface = NULL;
  const VpxInterface *fourcc_interface = NULL;
  uint64_t dx_time = 0;
  struct arg               arg;
  char                   **argv, **argi, **argj;

  int                     single_file;
  int                     use_y4m = 1;
  vpx_codec_dec_cfg_t     cfg = {0};
#if CONFIG_VP8_DECODER
  vp8_postproc_cfg_t      vp8_pp_cfg = {0};
  int                     vp8_dbg_color_ref_frame = 0;
  int                     vp8_dbg_color_mb_modes = 0;
  int                     vp8_dbg_color_b_modes = 0;
  int                     vp8_dbg_display_mv = 0;
#endif
  int                     frames_corrupted = 0;
  int                     dec_flags = 0;
  int                     do_scale = 0;
  vpx_image_t             *scaled_img = NULL;
  int                     frame_avail, got_data;
  int                     num_external_frame_buffers = 0;
  struct ExternalFrameBufferList ext_fb_list = {0};

  const char *outfile_pattern = NULL;
  char outfile_name[PATH_MAX] = {0};
  FILE *outfile = NULL;

  MD5Context md5_ctx;
  unsigned char md5_digest[16];

  struct VpxDecInputContext input = {0};
  struct VpxInputContext vpx_input_ctx = {0};
  struct WebmInputContext webm_ctx = {0};
  input.vpx_input_ctx = &vpx_input_ctx;
  input.webm_ctx = &webm_ctx;

  /* Parse command line */
  exec_name = argv_[0];
  argv = argv_dup(argc - 1, argv_ + 1);

  for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
    memset(&arg, 0, sizeof(arg));
    arg.argv_step = 1;

    if (arg_match(&arg, &codecarg, argi)) {
      interface = get_vpx_decoder_by_name(arg.val);
      if (!interface)
        die("Error: Unrecognized argument (%s) to --codec\n", arg.val);
    } else if (arg_match(&arg, &looparg, argi)) {
      // no-op
    } else if (arg_match(&arg, &outputfile, argi))
      outfile_pattern = arg.val;
    else if (arg_match(&arg, &use_yv12, argi)) {
      use_y4m = 0;
      flipuv = 1;
    } else if (arg_match(&arg, &use_i420, argi)) {
      use_y4m = 0;
      flipuv = 0;
    } else if (arg_match(&arg, &flipuvarg, argi))
      flipuv = 1;
    else if (arg_match(&arg, &noblitarg, argi))
      noblit = 1;
    else if (arg_match(&arg, &progressarg, argi))
      progress = 1;
    else if (arg_match(&arg, &limitarg, argi))
      stop_after = arg_parse_uint(&arg);
    else if (arg_match(&arg, &skiparg, argi))
      arg_skip = arg_parse_uint(&arg);
    else if (arg_match(&arg, &postprocarg, argi))
      postproc = 1;
    else if (arg_match(&arg, &md5arg, argi))
      do_md5 = 1;
    else if (arg_match(&arg, &summaryarg, argi))
      summary = 1;
    else if (arg_match(&arg, &threadsarg, argi))
      cfg.threads = arg_parse_uint(&arg);
    else if (arg_match(&arg, &verbosearg, argi))
      quiet = 0;
    else if (arg_match(&arg, &scalearg, argi))
      do_scale = 1;
    else if (arg_match(&arg, &fb_arg, argi))
      num_external_frame_buffers = arg_parse_uint(&arg);

#if CONFIG_VP8_DECODER
    else if (arg_match(&arg, &addnoise_level, argi)) {
      postproc = 1;
      vp8_pp_cfg.post_proc_flag |= VP8_ADDNOISE;
      vp8_pp_cfg.noise_level = arg_parse_uint(&arg);
    } else if (arg_match(&arg, &demacroblock_level, argi)) {
      postproc = 1;
      vp8_pp_cfg.post_proc_flag |= VP8_DEMACROBLOCK;
      vp8_pp_cfg.deblocking_level = arg_parse_uint(&arg);
    } else if (arg_match(&arg, &deblock, argi)) {
      postproc = 1;
      vp8_pp_cfg.post_proc_flag |= VP8_DEBLOCK;
    } else if (arg_match(&arg, &mfqe, argi)) {
      postproc = 1;
      vp8_pp_cfg.post_proc_flag |= VP8_MFQE;
    } else if (arg_match(&arg, &pp_debug_info, argi)) {
      unsigned int level = arg_parse_uint(&arg);

      postproc = 1;
      vp8_pp_cfg.post_proc_flag &= ~0x7;

      if (level)
        vp8_pp_cfg.post_proc_flag |= level;
    } else if (arg_match(&arg, &pp_disp_ref_frame, argi)) {
      unsigned int flags = arg_parse_int(&arg);
      if (flags) {
        postproc = 1;
        vp8_dbg_color_ref_frame = flags;
      }
    } else if (arg_match(&arg, &pp_disp_mb_modes, argi)) {
      unsigned int flags = arg_parse_int(&arg);
      if (flags) {
        postproc = 1;
        vp8_dbg_color_mb_modes = flags;
      }
    } else if (arg_match(&arg, &pp_disp_b_modes, argi)) {
      unsigned int flags = arg_parse_int(&arg);
      if (flags) {
        postproc = 1;
        vp8_dbg_color_b_modes = flags;
      }
    } else if (arg_match(&arg, &pp_disp_mvs, argi)) {
      unsigned int flags = arg_parse_int(&arg);
      if (flags) {
        postproc = 1;
        vp8_dbg_display_mv = flags;
      }
    } else if (arg_match(&arg, &error_concealment, argi)) {
      ec_enabled = 1;
    }

#endif
    else
      argj++;
  }

  /* Check for unrecognized options */
  for (argi = argv; *argi; argi++)
    if (argi[0][0] == '-' && strlen(argi[0]) > 1)
      die("Error: Unrecognized option %s\n", *argi);

  /* Handle non-option arguments */
  fn = argv[0];

  if (!fn)
    usage_exit();

  /* Open file */
  infile = strcmp(fn, "-") ? fopen(fn, "rb") : set_binary_mode(stdin);

  if (!infile) {
    fprintf(stderr, "Failed to open file '%s'", strcmp(fn, "-") ? fn : "stdin");
    return EXIT_FAILURE;
  }
#if CONFIG_OS_SUPPORT
  /* Make sure we don't dump to the terminal, unless forced to with -o - */
  if (!outfile_pattern && isatty(fileno(stdout)) && !do_md5 && !noblit) {
    fprintf(stderr,
            "Not dumping raw video to your terminal. Use '-o -' to "
            "override.\n");
    return EXIT_FAILURE;
  }
#endif
  input.vpx_input_ctx->file = infile;
  if (file_is_ivf(input.vpx_input_ctx))
    input.vpx_input_ctx->file_type = FILE_TYPE_IVF;
#if CONFIG_WEBM_IO
  else if (file_is_webm(input.webm_ctx, input.vpx_input_ctx))
    input.vpx_input_ctx->file_type = FILE_TYPE_WEBM;
#endif
  else if (file_is_raw(input.vpx_input_ctx))
    input.vpx_input_ctx->file_type = FILE_TYPE_RAW;
  else {
    fprintf(stderr, "Unrecognized input file type.\n");
#if !CONFIG_WEBM_IO
    fprintf(stderr, "vpxdec was built without WebM container support.\n");
#endif
    return EXIT_FAILURE;
  }

  outfile_pattern = outfile_pattern ? outfile_pattern : "-";
  single_file = is_single_file(outfile_pattern);

  if (!noblit && single_file) {
    generate_filename(outfile_pattern, outfile_name, PATH_MAX,
                      vpx_input_ctx.width, vpx_input_ctx.height, 0);
    if (do_md5)
      MD5Init(&md5_ctx);
    else
      outfile = open_outfile(outfile_name);
  }

  if (use_y4m && !noblit) {
    if (!single_file) {
      fprintf(stderr, "YUV4MPEG2 not supported with output patterns,"
              " try --i420 or --yv12.\n");
      return EXIT_FAILURE;
    }

#if CONFIG_WEBM_IO
    if (vpx_input_ctx.file_type == FILE_TYPE_WEBM) {
      if (webm_guess_framerate(input.webm_ctx, input.vpx_input_ctx)) {
        fprintf(stderr, "Failed to guess framerate -- error parsing "
                "webm file?\n");
        return EXIT_FAILURE;
      }
    }
#endif
  }

  fourcc_interface = get_vpx_decoder_by_fourcc(vpx_input_ctx.fourcc);
  if (interface && fourcc_interface && interface != fourcc_interface)
    warn("Header indicates codec: %s\n", fourcc_interface->name);
  else
    interface = fourcc_interface;

  if (!interface)
    interface = get_vpx_decoder_by_index(0);

  dec_flags = (postproc ? VPX_CODEC_USE_POSTPROC : 0) |
              (ec_enabled ? VPX_CODEC_USE_ERROR_CONCEALMENT : 0);
  if (vpx_codec_dec_init(&decoder, interface->interface(), &cfg, dec_flags)) {
    fprintf(stderr, "Failed to initialize decoder: %s\n",
            vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }

  if (!quiet)
    fprintf(stderr, "%s\n", decoder.name);

#if CONFIG_VP8_DECODER

  if (vp8_pp_cfg.post_proc_flag
      && vpx_codec_control(&decoder, VP8_SET_POSTPROC, &vp8_pp_cfg)) {
    fprintf(stderr, "Failed to configure postproc: %s\n", vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }

  if (vp8_dbg_color_ref_frame
      && vpx_codec_control(&decoder, VP8_SET_DBG_COLOR_REF_FRAME, vp8_dbg_color_ref_frame)) {
    fprintf(stderr, "Failed to configure reference block visualizer: %s\n", vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }

  if (vp8_dbg_color_mb_modes
      && vpx_codec_control(&decoder, VP8_SET_DBG_COLOR_MB_MODES, vp8_dbg_color_mb_modes)) {
    fprintf(stderr, "Failed to configure macro block visualizer: %s\n", vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }

  if (vp8_dbg_color_b_modes
      && vpx_codec_control(&decoder, VP8_SET_DBG_COLOR_B_MODES, vp8_dbg_color_b_modes)) {
    fprintf(stderr, "Failed to configure block visualizer: %s\n", vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }

  if (vp8_dbg_display_mv
      && vpx_codec_control(&decoder, VP8_SET_DBG_DISPLAY_MV, vp8_dbg_display_mv)) {
    fprintf(stderr, "Failed to configure motion vector visualizer: %s\n", vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }
#endif


  if (arg_skip)
    fprintf(stderr, "Skipping first %d frames.\n", arg_skip);
  while (arg_skip) {
    if (read_frame(&input, &buf, &bytes_in_buffer, &buffer_size))
      break;
    arg_skip--;
  }

  if (num_external_frame_buffers > 0) {
    ext_fb_list.num_external_frame_buffers = num_external_frame_buffers;
    ext_fb_list.ext_fb = (struct ExternalFrameBuffer *)calloc(
        num_external_frame_buffers, sizeof(*ext_fb_list.ext_fb));
    if (vpx_codec_set_frame_buffer_functions(
            &decoder, get_vp9_frame_buffer, release_vp9_frame_buffer,
            &ext_fb_list)) {
      fprintf(stderr, "Failed to configure external frame buffers: %s\n",
              vpx_codec_error(&decoder));
      return EXIT_FAILURE;
    }
  }

  frame_avail = 1;
  got_data = 0;

  /* Decode file */
  while (frame_avail || got_data) {
    vpx_codec_iter_t  iter = NULL;
    vpx_image_t    *img;
    struct vpx_usec_timer timer;
    int                   corrupted;

    frame_avail = 0;
    if (!stop_after || frame_in < stop_after) {
      if (!read_frame(&input, &buf, &bytes_in_buffer, &buffer_size)) {
        frame_avail = 1;
        frame_in++;

        vpx_usec_timer_start(&timer);

        if (vpx_codec_decode(&decoder, buf, (unsigned int)bytes_in_buffer,
                             NULL, 0)) {
          const char *detail = vpx_codec_error_detail(&decoder);
          warn("Failed to decode frame %d: %s",
               frame_in, vpx_codec_error(&decoder));

          if (detail)
            warn("Additional information: %s", detail);
          goto fail;
        }

        vpx_usec_timer_mark(&timer);
        dx_time += vpx_usec_timer_elapsed(&timer);
      }
    }

    vpx_usec_timer_start(&timer);

    got_data = 0;
    if ((img = vpx_codec_get_frame(&decoder, &iter))) {
      ++frame_out;
      got_data = 1;
    }

    vpx_usec_timer_mark(&timer);
    dx_time += (unsigned int)vpx_usec_timer_elapsed(&timer);

    if (vpx_codec_control(&decoder, VP8D_GET_FRAME_CORRUPTED, &corrupted)) {
      warn("Failed VP8_GET_FRAME_CORRUPTED: %s", vpx_codec_error(&decoder));
      goto fail;
    }
    frames_corrupted += corrupted;

    if (progress)
      show_progress(frame_in, frame_out, dx_time);

    if (!noblit && img) {
      const int PLANES_YUV[] = {VPX_PLANE_Y, VPX_PLANE_U, VPX_PLANE_V};
      const int PLANES_YVU[] = {VPX_PLANE_Y, VPX_PLANE_V, VPX_PLANE_U};
      const int *planes = flipuv ? PLANES_YVU : PLANES_YUV;

      if (do_scale) {
        if (frame_out == 1) {
          // If the output frames are to be scaled to a fixed display size then
          // use the width and height specified in the container. If either of
          // these is set to 0, use the display size set in the first frame
          // header. If that is unavailable, use the raw decoded size of the
          // first decoded frame.
          int display_width = vpx_input_ctx.width;
          int display_height = vpx_input_ctx.height;
          if (!display_width || !display_height) {
            int display_size[2];
            if (vpx_codec_control(&decoder, VP9D_GET_DISPLAY_SIZE,
                                  display_size)) {
              // As last resort use size of first frame as display size.
              display_width = img->d_w;
              display_height = img->d_h;
            } else {
              display_width = display_size[0];
              display_height = display_size[1];
            }
          }
          scaled_img = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, display_width,
                                     display_height, 16);
        }

        if (img->d_w != scaled_img->d_w || img->d_h != scaled_img->d_h) {
          vpx_image_scale(img, scaled_img, kFilterBox);
          img = scaled_img;
        }
      }

      if (single_file) {
        if (use_y4m) {
          char buf[Y4M_BUFFER_SIZE] = {0};
          size_t len = 0;
          if (frame_out == 1) {
            // Y4M file header
            len = y4m_write_file_header(buf, sizeof(buf),
                                        vpx_input_ctx.width,
                                        vpx_input_ctx.height,
                                        &vpx_input_ctx.framerate, img->fmt);
            if (do_md5) {
              MD5Update(&md5_ctx, (md5byte *)buf, (unsigned int)len);
            } else {
              fputs(buf, outfile);
            }
          }

          // Y4M frame header
          len = y4m_write_frame_header(buf, sizeof(buf));
          if (do_md5) {
            MD5Update(&md5_ctx, (md5byte *)buf, (unsigned int)len);
          } else {
            fputs(buf, outfile);
          }
        }

        if (do_md5) {
          update_image_md5(img, planes, &md5_ctx);
        } else {
          write_image_file(img, planes, outfile);
        }
      } else {
        generate_filename(outfile_pattern, outfile_name, PATH_MAX,
                          img->d_w, img->d_h, frame_in);
        if (do_md5) {
          MD5Init(&md5_ctx);
          update_image_md5(img, planes, &md5_ctx);
          MD5Final(md5_digest, &md5_ctx);
          print_md5(md5_digest, outfile_name);
        } else {
          outfile = open_outfile(outfile_name);
          write_image_file(img, planes, outfile);
          fclose(outfile);
        }
      }
    }

    if (stop_after && frame_in >= stop_after)
      break;
  }

  if (summary || progress) {
    show_progress(frame_in, frame_out, dx_time);
    fprintf(stderr, "\n");
  }

  if (frames_corrupted)
    fprintf(stderr, "WARNING: %d frames corrupted.\n", frames_corrupted);

fail:

  if (vpx_codec_destroy(&decoder)) {
    fprintf(stderr, "Failed to destroy decoder: %s\n",
            vpx_codec_error(&decoder));
    return EXIT_FAILURE;
  }

  if (!noblit && single_file) {
    if (do_md5) {
      MD5Final(md5_digest, &md5_ctx);
      print_md5(md5_digest, outfile_name);
    } else {
      fclose(outfile);
    }
  }

#if CONFIG_WEBM_IO
  if (input.vpx_input_ctx->file_type == FILE_TYPE_WEBM)
    webm_free(input.webm_ctx);
#endif

  if (input.vpx_input_ctx->file_type != FILE_TYPE_WEBM)
    free(buf);

  if (scaled_img) vpx_img_free(scaled_img);

  for (i = 0; i < ext_fb_list.num_external_frame_buffers; ++i) {
    free(ext_fb_list.ext_fb[i].data);
  }
  free(ext_fb_list.ext_fb);

  fclose(infile);
  free(argv);

  return frames_corrupted ? EXIT_FAILURE : EXIT_SUCCESS;
}
Ejemplo n.º 18
0
void generate_code_csharp (batch *b) {
    umlclasslist tmplist = b->classlist;
    FILE *licensefile = NULL;

    /* open license file */
    if (b->license != NULL) {
        licensefile = fopen (b->license, "r"); 
        if (!licensefile) {
            fprintf (stderr, "Can't open the license file.\n");
            exit (1);
        }
    }

    while (tmplist != NULL) {
        char *tmpname;
        char outfilename[SMALL_BUFFER];
        umlclasslist used_classes;

        if (is_present (b->classes, tmplist->key->name) ^ b->mask) {
            tmplist = tmplist->next;
            continue;
        }

        sprintf (outfilename, "%s.cs", tmplist->key->name);

        spec = open_outfile (outfilename, b);
        if (spec == NULL) {
            tmplist = tmplist->next;
            continue;
        }

        /* add license to the header */
        if (b->license != NULL) {
            char lc;
            rewind (licensefile);
            while ((lc = fgetc (licensefile)) != EOF)
                print ("%c", lc);
        }
        emit ("%s", "using System;\n\n");

        /* We generate the import clauses */
        used_classes = list_classes (tmplist, b);
        if (used_classes != NULL) {
            while (used_classes != NULL) {
                umlpackagelist pkg = make_package_list (used_classes->key->package);
                if (pkg != NULL) {
                    if (strcmp (pkg->key->id, tmplist->key->package->id)) {
                        /* This class' package and our current class' package are
                           not the same */
                        emit ("using %s.%s;\n", pkgname (pkg), used_classes->key->name);
                    }
                } else {
                    /* No info for this class' package, we include it directly */
                    /*emit ("import %s;\n",used_classes->key->name);*/
                }
                used_classes = used_classes->next;
            }
            emit ("\n");
        }

        if (tmplist->key->package != NULL) {
            umlpackagelist pkg = make_package_list (tmplist->key->package);
            emit ("namespace %s {\n\n", pkgname (pkg));
            indentlevel++;
        }

        print ("public ");

        tmpname = strtolower (tmplist->key->stereotype);
        if (eq ("interface", tmpname)) {
            emit ("interface ");
        } else {
            if (tmplist->key->isabstract)
            {
                emit ("interface ");
            }
            else
                emit ("class ");
        }
        free (tmpname);

        emit ("%s", tmplist->key->name);

        if (tmplist->parents != NULL) {
            umlclasslist parents = tmplist->parents;
            while (parents != NULL) {
                tmpname = strtolower (parents->key->stereotype);
                if (eq (tmpname, "interface")) {
                    emit (" : ");
                } else {
                    emit (" : ");
                }
                free (tmpname);
                emit ("%s", parents->key->name);
                parents = parents->next;
            }
        }
        emit (" {\n\n");
        indentlevel++;

        if (tmplist->key->attributes != NULL) {
            umlattrlist umla = tmplist->key->attributes;

            print ("// Attributes and properties\n");

            while (umla != NULL) {
                switch (umla->key.visibility) {
                case '0':
                    print ("public ");
                    break;
                case '1':
                    print ("private ");
                    break;
                case '2':
                    print ("protected ");
                    break;
                }

                if (umla->key.isstatic) {
                    emit ("static ");
                }
                emit ("%s %s", umla->key.type, umla->key.name);
                if (umla->key.value[0] != 0) {
                    emit (" = %s", umla->key.value);
                }
                int wp = 0, rp = 0;
                if (eq (umla->key.comment, "rproperty"))
                    rp = 1;
                else if (eq (umla->key.comment, "wproperty"))
                    wp = 1;
                else if (eq (umla->key.comment, "rwproperty"))
                    rp = wp = 1;
                if (wp || rp) {
                    emit (" {\n");
                    indentlevel++;
                    if (rp)
                        print ("get;\n");
                    if (wp)
                        print ("set;\n");
                    indentlevel--;
                    print ("}\n");
                }
                else
                    emit (";\n");
                umla = umla->next;
            }
            emit ("\n");
        }

        if (tmplist->associations != NULL) {
            umlassoclist assoc = tmplist->associations;

            print ("// Associations \n");
            while (assoc != NULL)
            {
                /* Not sure how to do this actually...*/
                if (assoc->composite )
                    print ("protected ");
                else
                    print ("private ");
                emit ("%s %s;\n", assoc->key->name, assoc->name);
                assoc = assoc->next;
            }
            emit ("\n");
        }

        if (tmplist->key->operations != NULL) {
            umloplist umlo = tmplist->key->operations;
            while (umlo != NULL) {
                umlattrlist tmpa = umlo->key.parameters;

                print ("// Operation\n");
                while (tmpa != NULL) {
                    print ("// param %s\n", tmpa->key.name);
                    tmpa = tmpa->next;
                }
                if (strcmp (umlo->key.attr.type, "void"))
                    print ("// return %s\n", umlo->key.attr.type);


                print ("");

                if (umlo->key.attr.isabstract)
                {
                    /*emit ("public ");*/
                    umlo->key.attr.value[0] = '0';
                }
                else
                {
                    switch (umlo->key.attr.visibility) {
                    case '0':
                        emit ("public ");
                        break;
                    case '1':
                        emit ("private ");
                        break;
                    case '2':
                        emit ("protected ");
                        break;
                    }
                }
                if (umlo->key.attr.isstatic) {
                    emit ("static ");
                }
                if (strlen (umlo->key.attr.type) > 0) {
                    emit ("%s ", umlo->key.attr.type);
                }
                emit ("%s (", umlo->key.attr.name);
                tmpa = umlo->key.parameters;
                while (tmpa != NULL) {
                    emit ("%s %s", tmpa->key.type, tmpa->key.name);
                    /*
                    if ( tmpa->key.value[0] != 0 ){
                        emit (" = %s",tmpa->key.value);
                    }  */
                    tmpa = tmpa->next;
                    if (tmpa != NULL)
                        emit (", ");
                }
                emit (")");
                if (umlo->key.attr.isabstract ) {
                    emit (";\n");
                } else {
                    emit ("\n");
                    print ("{\n");
                    indentlevel++;
                    if (umlo->key.implementation != NULL) {
                        print ("%s\n", umlo->key.implementation);
                    } else if (strcmp (umlo->key.attr.type, "void") != 0) {
                        print ("%s\n", "throw new System.Exception (\"Not implemented yet!\");");
                    }
                    indentlevel--;
                    print ("}\n");
                }
                umlo = umlo->next;
            }
            emit ("\n");
        }
        indentlevel--;
        print ("}\n\n");

        if (tmplist->key->package != NULL) {
            indentlevel--;
            print ("}\n\n");
        }

        fclose (spec);
        tmplist = tmplist->next;
    }
}
Ejemplo n.º 19
0
/* We don't want to use use_seskey yet because older gnupg versions
   can't handle it, and there isn't really any point unless we're
   making a message that can be decrypted by a public key or
   passphrase. */
static int
encrypt_simple (const char *filename, int mode, int use_seskey)
{
  iobuf_t inp, out;
  PACKET pkt;
  PKT_plaintext *pt = NULL;
  STRING2KEY *s2k = NULL;
  void *enckey = NULL;
  size_t enckeylen = 0;
  int rc = 0;
  u32 filesize;
  cipher_filter_context_t cfx;
  armor_filter_context_t  *afx = NULL;
  compress_filter_context_t zfx;
  text_filter_context_t tfx;
  progress_filter_context_t *pfx;
  int do_compress = !!default_compress_algo();

  if (!gnupg_rng_is_compliant (opt.compliance))
    {
      rc = gpg_error (GPG_ERR_FORBIDDEN);
      log_error (_("%s is not compliant with %s mode\n"),
                 "RNG",
                 gnupg_compliance_option_string (opt.compliance));
      write_status_error ("random-compliance", rc);
      return rc;
    }

  pfx = new_progress_context ();
  memset( &cfx, 0, sizeof cfx);
  memset( &zfx, 0, sizeof zfx);
  memset( &tfx, 0, sizeof tfx);
  init_packet(&pkt);

  /* Prepare iobufs. */
  inp = iobuf_open(filename);
  if (inp)
    iobuf_ioctl (inp, IOBUF_IOCTL_NO_CACHE, 1, NULL);
  if (inp && is_secured_file (iobuf_get_fd (inp)))
    {
      iobuf_close (inp);
      inp = NULL;
      gpg_err_set_errno (EPERM);
    }
  if (!inp)
    {
      rc = gpg_error_from_syserror ();
      log_error(_("can't open '%s': %s\n"), filename? filename: "[stdin]",
                strerror(errno) );
      release_progress_context (pfx);
      return rc;
    }

  handle_progress (pfx, inp, filename);

  if (opt.textmode)
    iobuf_push_filter( inp, text_filter, &tfx );

  cfx.dek = NULL;
  if ( mode )
    {
      int canceled;
      aead_algo_t aead_algo;

      s2k = xmalloc_clear( sizeof *s2k );
      s2k->mode = opt.s2k_mode;
      s2k->hash_algo = S2K_DIGEST_ALGO;
      cfx.dek = passphrase_to_dek (default_cipher_algo (), s2k, 1, 0,
                                   NULL, &canceled);
      if ( !cfx.dek || !cfx.dek->keylen )
        {
          rc = gpg_error (canceled? GPG_ERR_CANCELED:GPG_ERR_INV_PASSPHRASE);
          xfree (cfx.dek);
          xfree (s2k);
          iobuf_close (inp);
          log_error (_("error creating passphrase: %s\n"), gpg_strerror (rc));
          release_progress_context (pfx);
          return rc;
        }
      if (use_seskey && s2k->mode != 1 && s2k->mode != 3)
        {
          use_seskey = 0;
          log_info (_("can't use a symmetric ESK packet "
                      "due to the S2K mode\n"));
        }

      /* See whether we want to use AEAD.  */
      aead_algo = use_aead (NULL, cfx.dek->algo);

      if ( use_seskey )
        {
          DEK *dek = NULL;

          rc = encrypt_seskey (cfx.dek, aead_algo, &dek, &enckey, &enckeylen);
          if (rc)
            {
              xfree (cfx.dek);
              xfree (s2k);
              iobuf_close (inp);
              release_progress_context (pfx);
              return rc;
            }
          /* Replace key in DEK.  */
          xfree (cfx.dek);
          cfx.dek = dek;
        }

      if (aead_algo)
        cfx.dek->use_aead = aead_algo;
      else
        cfx.dek->use_mdc = !!use_mdc (NULL, cfx.dek->algo);

      if (opt.verbose)
        log_info(_("using cipher %s.%s\n"),
                 openpgp_cipher_algo_name (cfx.dek->algo),
                 cfx.dek->use_aead? openpgp_aead_algo_name (cfx.dek->use_aead)
                 /**/             : "CFB");
    }

  if (do_compress
      && cfx.dek
      && (cfx.dek->use_mdc || cfx.dek->use_aead)
      && is_file_compressed(filename, &rc))
    {
      if (opt.verbose)
        log_info(_("'%s' already compressed\n"), filename);
      do_compress = 0;
    }

  if ( rc || (rc = open_outfile (-1, filename, opt.armor? 1:0, 0, &out )))
    {
      iobuf_cancel (inp);
      xfree (cfx.dek);
      xfree (s2k);
      release_progress_context (pfx);
      return rc;
    }

  if ( opt.armor )
    {
      afx = new_armor_context ();
      push_armor_filter (afx, out);
    }

  if ( s2k )
    {
      /* Fixme: This is quite similar to write_symkey_enc.  */
      PKT_symkey_enc *enc = xmalloc_clear (sizeof *enc + enckeylen);
      enc->version = cfx.dek->use_aead ? 5 : 4;
      enc->cipher_algo = cfx.dek->algo;
      enc->aead_algo = cfx.dek->use_aead;
      enc->s2k = *s2k;
      if (enckeylen)
        {
          enc->seskeylen = enckeylen;
          memcpy (enc->seskey, enckey, enckeylen);
        }
      pkt.pkttype = PKT_SYMKEY_ENC;
      pkt.pkt.symkey_enc = enc;
      if ((rc = build_packet( out, &pkt )))
        log_error("build symkey packet failed: %s\n", gpg_strerror (rc) );
      xfree (enc);
      xfree (enckey);
      enckey = NULL;
    }

  if (!opt.no_literal)
    pt = setup_plaintext_name (filename, inp);

  /* Note that PGP 5 has problems decrypting symmetrically encrypted
     data if the file length is in the inner packet. It works when
     only partial length headers are use.  In the past, we always used
     partial body length here, but since PGP 2, PGP 6, and PGP 7 need
     the file length, and nobody should be using PGP 5 nowadays
     anyway, this is now set to the file length.  Note also that this
     only applies to the RFC-1991 style symmetric messages, and not
     the RFC-2440 style.  PGP 6 and 7 work with either partial length
     or fixed length with the new style messages. */

  if ( !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode )
    {
      off_t tmpsize;
      int overflow;

      if ( !(tmpsize = iobuf_get_filelength(inp, &overflow))
           && !overflow && opt.verbose)
        log_info(_("WARNING: '%s' is an empty file\n"), filename );
      /* We can't encode the length of very large files because
         OpenPGP uses only 32 bit for file sizes.  So if the
         size of a file is larger than 2^32 minus some bytes for
         packet headers, we switch to partial length encoding. */
      if ( tmpsize < (IOBUF_FILELENGTH_LIMIT - 65536) )
        filesize = tmpsize;
      else
        filesize = 0;
    }
  else
    filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */

  if (!opt.no_literal)
    {
      /* Note that PT has been initialized above in !no_literal mode.  */
      pt->timestamp = make_timestamp();
      pt->mode = opt.mimemode? 'm' : opt.textmode? 't' : 'b';
      pt->len = filesize;
      pt->new_ctb = !pt->len;
      pt->buf = inp;
      pkt.pkttype = PKT_PLAINTEXT;
      pkt.pkt.plaintext = pt;
      cfx.datalen = filesize && !do_compress ? calc_packet_length( &pkt ) : 0;
    }
  else
    {
      cfx.datalen = filesize && !do_compress ? filesize : 0;
      pkt.pkttype = 0;
      pkt.pkt.generic = NULL;
    }

  /* Register the cipher filter. */
  if (mode)
    iobuf_push_filter (out,
                       cfx.dek->use_aead? cipher_filter_aead
                       /**/             : cipher_filter_cfb,
                       &cfx );

  /* Register the compress filter. */
  if ( do_compress )
    {
      if (cfx.dek && (cfx.dek->use_mdc || cfx.dek->use_aead))
        zfx.new_ctb = 1;
      push_compress_filter (out, &zfx, default_compress_algo());
    }

  /* Do the work. */
  if (!opt.no_literal)
    {
      if ( (rc = build_packet( out, &pkt )) )
        log_error("build_packet failed: %s\n", gpg_strerror (rc) );
    }
  else
    {
      /* User requested not to create a literal packet, so we copy the
         plain data.  */
    byte copy_buffer[4096];
    int  bytes_copied;
    while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
      if ( (rc=iobuf_write(out, copy_buffer, bytes_copied)) ) {
        log_error ("copying input to output failed: %s\n",
                   gpg_strerror (rc) );
        break;
      }
    wipememory (copy_buffer, 4096); /* burn buffer */
    }

  /* Finish the stuff.  */
  iobuf_close (inp);
  if (rc)
    iobuf_cancel(out);
  else
    {
      iobuf_close (out); /* fixme: check returncode */
      if (mode)
        write_status ( STATUS_END_ENCRYPTION );
    }
  if (pt)
    pt->buf = NULL;
  free_packet (&pkt, NULL);
  xfree (enckey);
  xfree (cfx.dek);
  xfree (s2k);
  release_armor_context (afx);
  release_progress_context (pfx);
  return rc;
}
Ejemplo n.º 20
0
int
main (int argc, char **argv)
{
  FILE *h_file, *s_file;
  unsigned int i, j, n, last_kind[5];
  optab_pattern *p;

  progname = "genopinit";

  if (NUM_OPTABS > 0xffff || MAX_MACHINE_MODE >= 0xff)
    fatal ("genopinit range assumptions invalid");

  if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
    return (FATAL_EXIT_CODE);

  h_file = open_outfile (header_file_name);
  s_file = open_outfile (source_file_name);

  /* Read the machine description.  */
  md_rtx_info info;
  while (read_md_rtx (&info))
    switch (GET_CODE (info.def))
      {
      case DEFINE_INSN:
      case DEFINE_EXPAND:
	gen_insn (&info);
	break;

      default:
	break;
      }

  /* Sort the collected patterns.  */
  patterns.qsort (pattern_cmp);

  /* Now that we've handled the "extra" patterns, eliminate them from
     the optabs array.  That way they don't get in the way below.  */
  n = num_optabs;
  for (i = 0; i < n; )
    if (optabs[i].base == NULL)
      optabs[i] = optabs[--n];
    else
      ++i;

  /* Sort the (real) optabs.  Better than forcing the optabs.def file to
     remain sorted by kind.  We also scrogged any real ordering with the
     purging of the X patterns above.  */
  qsort (optabs, n, sizeof (optab_def), optab_kind_cmp);

  fprintf (h_file, "#ifndef GCC_INSN_OPINIT_H\n");
  fprintf (h_file, "#define GCC_INSN_OPINIT_H 1\n");

  /* Emit the optab enumeration for the header file.  */
  fprintf (h_file, "enum optab_tag {\n");
  for (i = j = 0; i < n; ++i)
    {
      optabs[i].op = i;
      fprintf (h_file, "  %s,\n", optabs[i].name);
      if (optabs[i].kind != j)
	last_kind[j++] = i - 1;
    }
  fprintf (h_file, "  FIRST_CONV_OPTAB = %s,\n", optabs[last_kind[0]+1].name);
  fprintf (h_file, "  LAST_CONVLIB_OPTAB = %s,\n", optabs[last_kind[1]].name);
  fprintf (h_file, "  LAST_CONV_OPTAB = %s,\n", optabs[last_kind[2]].name);
  fprintf (h_file, "  FIRST_NORM_OPTAB = %s,\n", optabs[last_kind[2]+1].name);
  fprintf (h_file, "  LAST_NORMLIB_OPTAB = %s,\n", optabs[last_kind[3]].name);
  fprintf (h_file, "  LAST_NORM_OPTAB = %s\n", optabs[i-1].name);
  fprintf (h_file, "};\n\n");

  fprintf (h_file, "#define NUM_OPTABS          %u\n", n);
  fprintf (h_file, "#define NUM_CONVLIB_OPTABS  %u\n",
	   last_kind[1] - last_kind[0]);
  fprintf (h_file, "#define NUM_NORMLIB_OPTABS  %u\n",
	   last_kind[3] - last_kind[2]);
  fprintf (h_file, "#define NUM_OPTAB_PATTERNS  %u\n",
	   (unsigned) patterns.length ());

  fprintf (h_file, 
	   "typedef enum optab_tag optab;\n"
	   "typedef enum optab_tag convert_optab;\n"
	   "typedef enum optab_tag direct_optab;\n"
	   "\n"
	   "struct optab_libcall_d\n"
	   "{\n"
	   "  char libcall_suffix;\n"
	   "  const char *libcall_basename;\n"
	   "  void (*libcall_gen) (optab, const char *name,\n"
	   "		       char suffix, machine_mode);\n"
	   "};\n"
	   "\n"
	   "struct convert_optab_libcall_d\n"
	   "{\n"
	   "  const char *libcall_basename;\n"
	   "  void (*libcall_gen) (convert_optab, const char *name,\n"
	   "		       machine_mode, machine_mode);\n"
	   "};\n"
	   "\n"
	   "/* Given an enum insn_code, access the function to construct\n"
	   "   the body of that kind of insn.  */\n"
	   "#define GEN_FCN(CODE) (insn_data[CODE].genfun)\n"
	   "\n"
	   "#ifdef NUM_RTX_CODE\n"
	   "/* Contains the optab used for each rtx code, and vice-versa.  */\n"
	   "extern const optab code_to_optab_[NUM_RTX_CODE];\n"
	   "extern const enum rtx_code optab_to_code_[NUM_OPTABS];\n"
	   "\n"
	   "static inline optab\n"
	   "code_to_optab (enum rtx_code code)\n"
	   "{\n"
	   "  return code_to_optab_[code];\n"
	   "}\n"
	   "\n"
	   "static inline enum rtx_code\n"
	   "optab_to_code (optab op)\n"
	   "{\n"
	   "  return optab_to_code_[op];\n"
	   "}\n"
	   "#endif\n"
	   "\n"
	   "extern const struct convert_optab_libcall_d convlib_def[NUM_CONVLIB_OPTABS];\n"
	   "extern const struct optab_libcall_d normlib_def[NUM_NORMLIB_OPTABS];\n"
	   "\n"
	   "/* Returns the active icode for the given (encoded) optab.  */\n"
	   "extern enum insn_code raw_optab_handler (unsigned);\n"
	   "extern bool swap_optab_enable (optab, machine_mode, bool);\n"
	   "\n"
	   "/* Target-dependent globals.  */\n"
	   "struct target_optabs {\n"
	   "  /* Patterns that are used by optabs that are enabled for this target.  */\n"
	   "  bool pat_enable[NUM_OPTAB_PATTERNS];\n"
	   "};\n"
	   "extern void init_all_optabs (struct target_optabs *);\n"
	   "\n"
	   "extern struct target_optabs default_target_optabs;\n"
	   "extern struct target_optabs *this_fn_optabs;\n"
	   "#if SWITCHABLE_TARGET\n"
	   "extern struct target_optabs *this_target_optabs;\n"
	   "#else\n"
	   "#define this_target_optabs (&default_target_optabs)\n"
	   "#endif\n");

  fprintf (s_file,
	   "#include \"config.h\"\n"
	   "#include \"system.h\"\n"
	   "#include \"coretypes.h\"\n"
	   "#include \"backend.h\"\n"
	   "#include \"predict.h\"\n"
	   "#include \"tree.h\"\n"
	   "#include \"rtl.h\"\n"
	   "#include \"alias.h\"\n"
	   "#include \"varasm.h\"\n"
	   "#include \"stor-layout.h\"\n"
	   "#include \"calls.h\"\n"
	   "#include \"tm_p.h\"\n"
	   "#include \"flags.h\"\n"
	   "#include \"insn-config.h\"\n"
	   "#include \"expmed.h\"\n"
	   "#include \"dojump.h\"\n"
	   "#include \"explow.h\"\n"
	   "#include \"emit-rtl.h\"\n"
	   "#include \"stmt.h\"\n"
	   "#include \"expr.h\"\n"
	   "#include \"insn-codes.h\"\n"
	   "#include \"optabs.h\"\n"
	   "\n"
	   "struct optab_pat {\n"
	   "  unsigned scode;\n"
	   "  enum insn_code icode;\n"
	   "};\n\n");

  fprintf (s_file,
	   "static const struct optab_pat pats[NUM_OPTAB_PATTERNS] = {\n");
  for (i = 0; patterns.iterate (i, &p); ++i)
    fprintf (s_file, "  { %#08x, CODE_FOR_%s },\n", p->sort_num, p->name);
  fprintf (s_file, "};\n\n");

  fprintf (s_file, "void\ninit_all_optabs (struct target_optabs *optabs)\n{\n");
  fprintf (s_file, "  bool *ena = optabs->pat_enable;\n");
  for (i = 0; patterns.iterate (i, &p); ++i)
    fprintf (s_file, "  ena[%u] = HAVE_%s;\n", i, p->name);
  fprintf (s_file, "}\n\n");

  /* Perform a binary search on a pre-encoded optab+mode*2.  */
  /* ??? Perhaps even better to generate a minimal perfect hash.
     Using gperf directly is awkward since it's so geared to working
     with strings.  Plus we have no visibility into the ordering of
     the hash entries, which complicates the pat_enable array.  */
  fprintf (s_file,
	   "static int\n"
	   "lookup_handler (unsigned scode)\n"
	   "{\n"
	   "  int l = 0, h = ARRAY_SIZE (pats), m;\n"
	   "  while (h > l)\n"
	   "    {\n"
	   "      m = (h + l) / 2;\n"
	   "      if (scode == pats[m].scode)\n"
	   "        return m;\n"
	   "      else if (scode < pats[m].scode)\n"
	   "        h = m;\n"
	   "      else\n"
	   "        l = m + 1;\n"
	   "    }\n"
	   "  return -1;\n"
	   "}\n\n");

  fprintf (s_file,
	   "enum insn_code\n"
	   "raw_optab_handler (unsigned scode)\n"
	   "{\n"
	   "  int i = lookup_handler (scode);\n"
	   "  return (i >= 0 && this_fn_optabs->pat_enable[i]\n"
	   "          ? pats[i].icode : CODE_FOR_nothing);\n"
	   "}\n\n");

  fprintf (s_file,
	   "bool\n"
	   "swap_optab_enable (optab op, machine_mode m, bool set)\n"
	   "{\n"
	   "  unsigned scode = (op << 16) | m;\n"
	   "  int i = lookup_handler (scode);\n"
	   "  if (i >= 0)\n"
	   "    {\n"
	   "      bool ret = this_fn_optabs->pat_enable[i];\n"
	   "      this_fn_optabs->pat_enable[i] = set;\n"
	   "      return ret;\n"
	   "    }\n"
	   "  else\n"
	   "    {\n"
	   "      gcc_assert (!set);\n"
	   "      return false;\n"
	   "    }\n"
	   "}\n\n");

  /* C++ (even G++) does not support (non-trivial) designated initializers.
     To work around that, generate these arrays programatically rather than
     by our traditional multiple inclusion of def files.  */

  fprintf (s_file,
	   "const struct convert_optab_libcall_d "
	   "convlib_def[NUM_CONVLIB_OPTABS] = {\n");
  for (i = last_kind[0] + 1; i <= last_kind[1]; ++i)
    fprintf (s_file, "  { %s, %s },\n", optabs[i].base, optabs[i].libcall);
  fprintf (s_file, "};\n\n");

  fprintf (s_file,
	   "const struct optab_libcall_d "
	   "normlib_def[NUM_NORMLIB_OPTABS] = {\n");
  for (i = last_kind[2] + 1; i <= last_kind[3]; ++i)
    fprintf (s_file, "  { %s, %s, %s },\n",
	     optabs[i].suffix, optabs[i].base, optabs[i].libcall);
  fprintf (s_file, "};\n\n");

  fprintf (s_file, "enum rtx_code const optab_to_code_[NUM_OPTABS] = {\n");
  for (i = 0; i < n; ++i)
    fprintf (s_file, "  %s,\n", rtx_upname[optabs[i].fcode]);
  fprintf (s_file, "};\n\n");

  qsort (optabs, n, sizeof (optab_def), optab_rcode_cmp);

  fprintf (s_file, "const optab code_to_optab_[NUM_RTX_CODE] = {\n");
  for (j = 0; optabs[j].rcode == UNKNOWN; ++j)
    continue;
  for (i = 0; i < NON_GENERATOR_NUM_RTX_CODE; ++i)
    {
      if (j < n && optabs[j].rcode == i)
	fprintf (s_file, "  %s,\n", optabs[j++].name);
      else
	fprintf (s_file, "  unknown_optab,\n");
    }
  fprintf (s_file, "};\n\n");

  fprintf (h_file, "#endif\n");
  return (fclose (h_file) == 0 && fclose (s_file) == 0
	  ? SUCCESS_EXIT_CODE : FATAL_EXIT_CODE);
}
Ejemplo n.º 21
0
int
main (int argc, char **argv)
{
    FILE *h_file, *s_file;
    unsigned int i, j, n, last_kind[5];
    pattern *p;

    progname = "genopinit";

    if (NUM_OPTABS > 0xffff || MAX_MACHINE_MODE >= 0xff)
        fatal ("genopinit range assumptions invalid");

    if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
        return (FATAL_EXIT_CODE);

    h_file = open_outfile (header_file_name);
    s_file = open_outfile (source_file_name);

    /* Read the machine description.  */
    while (1)
    {
        int line_no, insn_code_number = 0;
        rtx desc = read_md_rtx (&line_no, &insn_code_number);
        if (desc == NULL)
            break;
        if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
            gen_insn (desc);
    }

    /* Sort the collected patterns.  */
    qsort (patterns.address (), patterns.length (),
           sizeof (pattern), pattern_cmp);

    /* Now that we've handled the "extra" patterns, eliminate them from
       the optabs array.  That way they don't get in the way below.  */
    n = ARRAY_SIZE (optabs);
    for (i = 0; i < n; )
        if (optabs[i].base == NULL)
            optabs[i] = optabs[--n];
        else
            ++i;

    /* Sort the (real) optabs.  Better than forcing the optabs.def file to
       remain sorted by kind.  We also scrogged any real ordering with the
       purging of the X patterns above.  */
    qsort (optabs, n, sizeof (optab_def), optab_kind_cmp);

    /* Emit the optab enumeration for the header file.  */
    fprintf (h_file, "enum optab_tag {\n");
    for (i = j = 0; i < n; ++i)
    {
        optabs[i].op = i;
        fprintf (h_file, "  %s,\n", optabs[i].name);
        if (optabs[i].kind != j)
            last_kind[j++] = i - 1;
    }
    fprintf (h_file, "  FIRST_CONV_OPTAB = %s,\n", optabs[last_kind[0]+1].name);
    fprintf (h_file, "  LAST_CONVLIB_OPTAB = %s,\n", optabs[last_kind[1]].name);
    fprintf (h_file, "  LAST_CONV_OPTAB = %s,\n", optabs[last_kind[2]].name);
    fprintf (h_file, "  FIRST_NORM_OPTAB = %s,\n", optabs[last_kind[2]+1].name);
    fprintf (h_file, "  LAST_NORMLIB_OPTAB = %s,\n", optabs[last_kind[3]].name);
    fprintf (h_file, "  LAST_NORM_OPTAB = %s\n", optabs[i-1].name);
    fprintf (h_file, "};\n\n");

    fprintf (h_file, "#define NUM_OPTABS          %u\n", n);
    fprintf (h_file, "#define NUM_CONVLIB_OPTABS  %u\n",
             last_kind[1] - last_kind[0]);
    fprintf (h_file, "#define NUM_NORMLIB_OPTABS  %u\n",
             last_kind[3] - last_kind[2]);
    fprintf (h_file, "#define NUM_OPTAB_PATTERNS  %u\n",
             (unsigned) patterns.length ());

    fprintf (s_file,
             "#include \"config.h\"\n"
             "#include \"system.h\"\n"
             "#include \"coretypes.h\"\n"
             "#include \"tm.h\"\n"
             "#include \"rtl.h\"\n"
             "#include \"tm_p.h\"\n"
             "#include \"flags.h\"\n"
             "#include \"insn-config.h\"\n"
             "#include \"expr.h\"\n"
             "#include \"optabs.h\"\n"
             "\n"
             "struct optab_pat {\n"
             "  unsigned scode;\n"
             "  enum insn_code icode;\n"
             "};\n\n");

    fprintf (s_file,
             "static const struct optab_pat pats[NUM_OPTAB_PATTERNS] = {\n");
    for (i = 0; patterns.iterate (i, &p); ++i)
        fprintf (s_file, "  { %#08x, CODE_FOR_%s },\n", p->sort_num, p->name);
    fprintf (s_file, "};\n\n");

    fprintf (s_file, "void\ninit_all_optabs (struct target_optabs *optabs)\n{\n");
    fprintf (s_file, "  bool *ena = optabs->pat_enable;\n");
    for (i = 0; patterns.iterate (i, &p); ++i)
        fprintf (s_file, "  ena[%u] = HAVE_%s;\n", i, p->name);
    fprintf (s_file, "}\n\n");

    /* Perform a binary search on a pre-encoded optab+mode*2.  */
    /* ??? Perhaps even better to generate a minimal perfect hash.
       Using gperf directly is awkward since it's so geared to working
       with strings.  Plus we have no visibility into the ordering of
       the hash entries, which complicates the pat_enable array.  */
    fprintf (s_file,
             "static int\n"
             "lookup_handler (unsigned scode)\n"
             "{\n"
             "  int l = 0, h = ARRAY_SIZE (pats), m;\n"
             "  while (h > l)\n"
             "    {\n"
             "      m = (h + l) / 2;\n"
             "      if (scode == pats[m].scode)\n"
             "        return m;\n"
             "      else if (scode < pats[m].scode)\n"
             "        h = m;\n"
             "      else\n"
             "        l = m + 1;\n"
             "    }\n"
             "  return -1;\n"
             "}\n\n");

    fprintf (s_file,
             "enum insn_code\n"
             "raw_optab_handler (unsigned scode)\n"
             "{\n"
             "  int i = lookup_handler (scode);\n"
             "  return (i >= 0 && this_fn_optabs->pat_enable[i]\n"
             "          ? pats[i].icode : CODE_FOR_nothing);\n"
             "}\n\n");

    fprintf (s_file,
             "bool\n"
             "swap_optab_enable (optab op, enum machine_mode m, bool set)\n"
             "{\n"
             "  unsigned scode = (op << 16) | m;\n"
             "  int i = lookup_handler (scode);\n"
             "  if (i >= 0)\n"
             "    {\n"
             "      bool ret = this_fn_optabs->pat_enable[i];\n"
             "      this_fn_optabs->pat_enable[i] = set;\n"
             "      return ret;\n"
             "    }\n"
             "  else\n"
             "    {\n"
             "      gcc_assert (!set);\n"
             "      return false;\n"
             "    }\n"
             "}\n\n");

    /* C++ (even G++) does not support (non-trivial) designated initializers.
       To work around that, generate these arrays programatically rather than
       by our traditional multiple inclusion of def files.  */

    fprintf (s_file,
             "const struct convert_optab_libcall_d "
             "convlib_def[NUM_CONVLIB_OPTABS] = {\n");
    for (i = last_kind[0] + 1; i <= last_kind[1]; ++i)
        fprintf (s_file, "  { %s, %s },\n", optabs[i].base, optabs[i].libcall);
    fprintf (s_file, "};\n\n");

    fprintf (s_file,
             "const struct optab_libcall_d "
             "normlib_def[NUM_NORMLIB_OPTABS] = {\n");
    for (i = last_kind[2] + 1; i <= last_kind[3]; ++i)
        fprintf (s_file, "  { %s, %s, %s },\n",
                 optabs[i].suffix, optabs[i].base, optabs[i].libcall);
    fprintf (s_file, "};\n\n");

    fprintf (s_file, "enum rtx_code const optab_to_code_[NUM_OPTABS] = {\n");
    for (i = 0; i < n; ++i)
        fprintf (s_file, "  %s,\n", rtx_upname[optabs[i].fcode]);
    fprintf (s_file, "};\n\n");

    qsort (optabs, n, sizeof (optab_def), optab_rcode_cmp);

    fprintf (s_file, "const optab code_to_optab_[NUM_RTX_CODE] = {\n");
    for (j = 0; optabs[j].rcode == UNKNOWN; ++j)
        continue;
    for (i = 0; i < NON_GENERATOR_NUM_RTX_CODE; ++i)
    {
        if (j < n && optabs[j].rcode == i)
            fprintf (s_file, "  %s,\n", optabs[j++].name);
        else
            fprintf (s_file, "  unknown_optab,\n");
    }
    fprintf (s_file, "};\n\n");

    return (fclose (h_file) == 0 && fclose (s_file) == 0
            ? SUCCESS_EXIT_CODE : FATAL_EXIT_CODE);
}
Ejemplo n.º 22
0
bool AlignCoderSNV::encode(string alignfile, string outfile)
{
    if (p_alignreader==NULL)
        throw runtime_error("AlignCoderSNV::encode: p_alignreader has not be set.");
    ofstream p_outfile;
    open_outfile(p_outfile, outfile);
    
    ofstream p_reffile;
    open_outfile(p_reffile, outfile + ".ref");
    
    p_alignreader->open(alignfile);
    Align align;
    int nline = 0;
    while(p_alignreader->readline(align)){
        ++nline;
        
        // expections
        int alen = (int) align.matchPattern.size();
        if ( !(align.qAlignedSeq.size()==alen && align.tAlignedSeq.size()==alen) )
            throw runtime_error("incorrect match patter in line " + to_string(nline));
        if (align.qStrand != '+')
            throw runtime_error("qStrand should be + in line " + to_string(nline));
        
        // reverse alignment if it is aligned to negative strand
        if (align.tStrand != '+'){
            align.qAlignedSeq = getrevcomp(align.qAlignedSeq);
            align.tAlignedSeq = getrevcomp(align.tAlignedSeq);
        }
        
        // encode
        int cur_pos = align.tStart;
        for (int i=0; i<alen; i++){
            if (align.tAlignedSeq[i] == 'A' || align.tAlignedSeq[i] == 'C' || align.tAlignedSeq[i] == 'G' || align.tAlignedSeq[i] == 'T'){
                if (align.qAlignedSeq[i] != '-'){
                    if (align.tAlignedSeq[i] != align.qAlignedSeq[i]){
                        p_outfile << this->binary_code(cur_pos, align.qAlignedSeq[i]) << '\t';
                    }else{
                        p_reffile << this->binary_code(cur_pos, align.tAlignedSeq[i]) << '\t';
                    }
                }
                ++cur_pos;
            }else{
                if (align.tAlignedSeq[i]!='-')
                    ++cur_pos;
            }
            
            /*if (align.tAlignedSeq[i]!=align.qAlignedSeq[i] && align.tAlignedSeq[i]!='-' && align.qAlignedSeq[i]!='-')
                p_outfile << this->binary_code(cur_pos, align.qAlignedSeq[i]) << '\t';
            if (align.tAlignedSeq[i]!='-')
                cur_pos++;*/
        }
        p_outfile << endl;
        p_reffile << endl;
    }
    
    p_alignreader->close();
    
    
    p_outfile.close();
    p_reffile.close();
    return true;
}