bool read_files (struct file_data filevec[], bool pretend_binary) { int i; bool skip_test = text | pretend_binary; bool appears_binary = pretend_binary | sip (&filevec[0], skip_test); if (filevec[0].desc != filevec[1].desc) appears_binary |= sip (&filevec[1], skip_test | appears_binary); else { filevec[1].buffer = filevec[0].buffer; filevec[1].bufsize = filevec[0].bufsize; filevec[1].buffered = filevec[0].buffered; } if (appears_binary) { set_binary_mode (filevec[0].desc, true); set_binary_mode (filevec[1].desc, true); return true; } find_identical_ends (filevec); equivs_alloc = filevec[0].alloc_lines + filevec[1].alloc_lines + 1; if (PTRDIFF_MAX / sizeof *equivs <= equivs_alloc) xalloc_die (); equivs = xmalloc (equivs_alloc * sizeof *equivs); /* Equivalence class 0 is permanently safe for lines that were not hashed. Real equivalence classes start at 1. */ equivs_index = 1; /* Allocate (one plus) a prime number of hash buckets. Use a prime number between 1/3 and 2/3 of the value of equiv_allocs, approximately. */ for (i = 9; (size_t) 1 << i < equivs_alloc / 3; i++) continue; nbuckets = ((size_t) 1 << i) - prime_offset[i]; if (PTRDIFF_MAX / sizeof *buckets <= nbuckets) xalloc_die (); buckets = zalloc ((nbuckets + 1) * sizeof *buckets); buckets++; for (i = 0; i < 2; i++) find_and_hash_each_line (&filevec[i]); filevec[0].equiv_max = filevec[1].equiv_max = equivs_index; free (equivs); free (buckets - 1); return false; }
static bool sip (struct file_data *current, bool skip_test) { /* If we have a nonexistent file at this stage, treat it as empty. */ if (current->desc < 0) { /* Leave room for a sentinel. */ current->bufsize = sizeof (word); current->buffer = xmalloc (current->bufsize); } else { current->bufsize = buffer_lcm (sizeof (word), STAT_BLOCKSIZE (current->stat), PTRDIFF_MAX - 2 * sizeof (word)); current->buffer = xmalloc (current->bufsize); #ifdef __KLIBC__ /* Skip test if seek is not possible */ skip_test = skip_test || (lseek (current->desc, 0, SEEK_CUR) < 0 && errno == ESPIPE); #endif if (! skip_test) { /* Check first part of file to see if it's a binary file. */ int prev_mode = set_binary_mode (current->desc, O_BINARY); off_t buffered; file_block_read (current, current->bufsize); buffered = current->buffered; if (prev_mode != O_BINARY) { /* Revert to text mode and seek back to the start to reread the file. Use relative seek, since file descriptors like stdin might not start at offset zero. */ if (lseek (current->desc, - buffered, SEEK_CUR) < 0) pfatal_with_name (current->name); set_binary_mode (current->desc, prev_mode); current->buffered = 0; current->eof = false; } return binary_file_p (current->buffer, buffered); } } current->buffered = 0; current->eof = false; return false; }
static bool sip (struct file_data *current, bool skip_test) { /* If we have a nonexistent file at this stage, treat it as empty. */ if (current->desc < 0) { /* Leave room for a sentinel. */ current->bufsize = sizeof (word); current->buffer = xmalloc (current->bufsize); } else { current->bufsize = buffer_lcm (sizeof (word), STAT_BLOCKSIZE (current->stat), PTRDIFF_MAX - 2 * sizeof (word)); current->buffer = xmalloc (current->bufsize); if (! skip_test) { /* Check first part of file to see if it's a binary file. */ bool was_binary = set_binary_mode (current->desc, true); off_t buffered; file_block_read (current, current->bufsize); buffered = current->buffered; if (! was_binary) { /* Revert to text mode and seek back to the beginning to reread the file. Use relative seek, since file descriptors like stdin might not start at offset zero. */ if (lseek (current->desc, - buffered, SEEK_CUR) == -1) pfatal_with_name (current->name); set_binary_mode (current->desc, false); current->buffered = 0; current->eof = false; } return binary_file_p (current->buffer, buffered); } } current->buffered = 0; current->eof = false; return false; }
pngquant_error read_image(const char *filename, int using_stdin, read_info *input_image_p) { FILE *infile; if (using_stdin) { set_binary_mode(stdin); infile = stdin; } else if ((infile = fopen(filename, "rb")) == NULL) { fprintf(stderr, " error: cannot open %s for reading\n", filename); return READ_ERROR; } /* ** Step 1: read in the alpha-channel image. */ /* GRR: returns RGBA (4 channels), 8 bps */ pngquant_error retval = rwpng_read_image(infile, input_image_p); if (!using_stdin) fclose(infile); if (retval) { fprintf(stderr, " rwpng_read_image() error\n"); return retval; } return SUCCESS; }
static FILE *open_outfile(const char *name) { if (strcmp("-", name) == 0) { set_binary_mode(stdout); return stdout; } else { FILE *file = fopen(name, "wb"); if (!file) fatal("Failed to open output file '%s'", name); return file; } }
static pngquant_error write_image(png8_image *output_image, png24_image *output_image24, const char *outname, struct pngquant_options *options) { FILE *outfile; if (options->using_stdin) { set_binary_mode(stdout); outfile = stdout; if (output_image) { verbose_printf(options, " writing %d-color image to stdout", output_image->num_palette); } else { verbose_printf(options, " writing truecolor image to stdout"); } } else { if ((outfile = fopen(outname, "wb")) == NULL) { fprintf(stderr, " error: cannot open %s for writing\n", outname); return CANT_WRITE_ERROR; } const char *outfilename = strrchr(outname, '/'); if (outfilename) { outfilename++; } else { outfilename = outname; } if (output_image) { verbose_printf(options, " writing %d-color image as %s", output_image->num_palette, outfilename); } else { verbose_printf(options, " writing truecolor image as %s", outfilename); } } pngquant_error retval; #pragma omp critical (libpng) { if (output_image) { retval = rwpng_write_image8(outfile, output_image); } else { retval = rwpng_write_image24(outfile, output_image24); } } if (retval && retval != TOO_LARGE_FILE) { fprintf(stderr, " error: failed writing image to %s\n", outname); } if (!options->using_stdin) { fclose(outfile); } return retval; }
void Geomview_stream::pickplane(const Bbox_3 &bbox) { bool bin_bak = set_binary_mode(); (*this) << "(geometry pickplane {QUAD BINARY\n" << 1 // here are the four corners << bbox.xmin() << bbox.ymin() << bbox.zmin() << bbox.xmin() << bbox.ymax() << bbox.zmin() << bbox.xmax() << bbox.ymax() << bbox.zmin() << bbox.xmax() << bbox.ymin() << bbox.zmin() // close the text bracket << "}) (pickable pickplane no)"; set_ascii_mode(bin_bak); }
static pngquant_error read_image(liq_attr *options, const char *filename, int using_stdin, png24_image *input_image_p, liq_image **liq_image_p, bool keep_input_pixels, bool verbose) { FILE *infile; if (using_stdin) { set_binary_mode(stdin); infile = stdin; } else if ((infile = fopen(filename, "rb")) == NULL) { fprintf(stderr, " error: cannot open %s for reading\n", filename); return READ_ERROR; } pngquant_error retval; #pragma omp critical (libpng) { retval = rwpng_read_image24(infile, input_image_p, verbose); } if (!using_stdin) { fclose(infile); } if (retval) { fprintf(stderr, " error: cannot decode image %s\n", using_stdin ? "from stdin" : filename_part(filename)); return retval; } *liq_image_p = liq_image_create_rgba_rows(options, (void**)input_image_p->row_pointers, input_image_p->width, input_image_p->height, input_image_p->gamma); if (!*liq_image_p) { return OUT_OF_MEMORY_ERROR; } if (!keep_input_pixels) { if (LIQ_OK != liq_image_set_memory_ownership(*liq_image_p, LIQ_OWN_ROWS | LIQ_OWN_PIXELS)) { return OUT_OF_MEMORY_ERROR; } input_image_p->row_pointers = NULL; input_image_p->rgba_data = NULL; } return SUCCESS; }
pngquant_error write_image(write_info *output_image,const char *filename,const char *newext,int force,int using_stdin) { FILE *outfile; if (using_stdin) { set_binary_mode(stdout); outfile = stdout; } else { char *outname = add_filename_extension(filename,newext); if (!force) { if ((outfile = fopen(outname, "rb")) != NULL) { fprintf(stderr, " error: %s exists; not overwriting\n", outname); fclose(outfile); free(outname); return NOT_OVERWRITING_ERROR; } } if ((outfile = fopen(outname, "wb")) == NULL) { fprintf(stderr, " error: cannot open %s for writing\n", outname); free(outname); return CANT_WRITE_ERROR; } free(outname); } pngquant_error retval = rwpng_write_image_init(outfile, output_image); if (retval) { fprintf(stderr, " rwpng_write_image_init() error\n"); if (!using_stdin) fclose(outfile); return retval; } /* write entire interlaced palette PNG */ retval = rwpng_write_image_whole(output_image); if (!using_stdin) fclose(outfile); /* now we're done with the OUTPUT data and row_pointers, too */ return retval; }
void *out_open(const char *out_fn, int do_md5) { void *out = NULL; if (do_md5) { #if CONFIG_MD5 MD5Context *md5_ctx = out = malloc(sizeof(MD5Context)); (void)out_fn; MD5Init(md5_ctx); #endif } else { FILE *outfile = out = strcmp("-", out_fn) ? fopen(out_fn, "wb") : set_binary_mode(stdout); if (!outfile) { fprintf(stderr, "Failed to output file"); exit(EXIT_FAILURE); } } return out; }
int main (int argc, char *argv[]) { /* Test the O_BINARY macro. */ { int fd = open ("t-bin-out0.tmp", O_CREAT | O_TRUNC | O_RDWR | O_BINARY, 0600); if (write (fd, "Hello\n", 6) < 0) exit (1); close (fd); } { struct stat statbuf; if (stat ("t-bin-out0.tmp", &statbuf) < 0) exit (1); ASSERT (statbuf.st_size == 6); } switch (argv[1][0]) { case '1': /* Test the set_binary_mode() function. */ set_binary_mode (1, O_BINARY); fputs ("Hello\n", stdout); break; case '2': /* Test the SET_BINARY macro. */ SET_BINARY (1); fputs ("Hello\n", stdout); break; default: break; } return 0; }
int pipe2 (int fd[2], int flags) { /* Mingw _pipe() corrupts fd on failure; also, if we succeed at creating the pipe but later fail at changing fcntl, we want to leave fd unchanged: http://austingroupbugs.net/view.php?id=467 */ int tmp[2]; tmp[0] = fd[0]; tmp[1] = fd[1]; #if HAVE_PIPE2 # undef pipe2 /* Try the system call first, if it exists. (We may be running with a glibc that has the function but with an older kernel that lacks it.) */ { /* Cache the information whether the system call really exists. */ static int have_pipe2_really; /* 0 = unknown, 1 = yes, -1 = no */ if (have_pipe2_really >= 0) { int result = pipe2 (fd, flags); if (!(result < 0 && errno == ENOSYS)) { have_pipe2_really = 1; return result; } have_pipe2_really = -1; } } #endif /* Check the supported flags. */ if ((flags & ~(O_CLOEXEC | O_NONBLOCK | O_BINARY | O_TEXT)) != 0) { errno = EINVAL; return -1; } #if defined _WIN32 && ! defined __CYGWIN__ /* Native Windows API. */ if (_pipe (fd, 4096, flags & ~O_NONBLOCK) < 0) { fd[0] = tmp[0]; fd[1] = tmp[1]; return -1; } /* O_NONBLOCK handling. On native Windows platforms, O_NONBLOCK is defined by gnulib. Use the functions defined by the gnulib module 'nonblocking'. */ # if GNULIB_defined_O_NONBLOCK if (flags & O_NONBLOCK) { if (set_nonblocking_flag (fd[0], true) != 0 || set_nonblocking_flag (fd[1], true) != 0) goto fail; } # else { verify (O_NONBLOCK == 0); } # endif return 0; #else /* Unix API. */ if (pipe (fd) < 0) return -1; /* POSIX <http://www.opengroup.org/onlinepubs/9699919799/functions/pipe.html> says that initially, the O_NONBLOCK and FD_CLOEXEC flags are cleared on both fd[0] and fd[1]. */ /* O_NONBLOCK handling. On Unix platforms, O_NONBLOCK is defined by the system. Use fcntl(). */ if (flags & O_NONBLOCK) { int fcntl_flags; if ((fcntl_flags = fcntl (fd[1], F_GETFL, 0)) < 0 || fcntl (fd[1], F_SETFL, fcntl_flags | O_NONBLOCK) == -1 || (fcntl_flags = fcntl (fd[0], F_GETFL, 0)) < 0 || fcntl (fd[0], F_SETFL, fcntl_flags | O_NONBLOCK) == -1) goto fail; } if (flags & O_CLOEXEC) { int fcntl_flags; if ((fcntl_flags = fcntl (fd[1], F_GETFD, 0)) < 0 || fcntl (fd[1], F_SETFD, fcntl_flags | FD_CLOEXEC) == -1 || (fcntl_flags = fcntl (fd[0], F_GETFD, 0)) < 0 || fcntl (fd[0], F_SETFD, fcntl_flags | FD_CLOEXEC) == -1) goto fail; } # if O_BINARY if (flags & O_BINARY) { set_binary_mode (fd[1], O_BINARY); set_binary_mode (fd[0], O_BINARY); } else if (flags & O_TEXT) { set_binary_mode (fd[1], O_TEXT); set_binary_mode (fd[0], O_TEXT); } # endif return 0; #endif #if GNULIB_defined_O_NONBLOCK || !(defined _WIN32 && ! defined __CYGWIN__) fail: { int saved_errno = errno; close (fd[0]); close (fd[1]); fd[0] = tmp[0]; fd[1] = tmp[1]; errno = saved_errno; return -1; } #endif }
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; }
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; }
int accept4 (int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) { int fd; #if HAVE_ACCEPT4 # undef accept4 /* Try the system call first, if it exists. (We may be running with a glibc that has the function but with an older kernel that lacks it.) */ { /* Cache the information whether the system call really exists. */ static int have_accept4_really; /* 0 = unknown, 1 = yes, -1 = no */ if (have_accept4_really >= 0) { int result = accept4 (sockfd, addr, addrlen, flags); if (!(result < 0 && errno == ENOSYS)) { have_accept4_really = 1; return result; } have_accept4_really = -1; } } #endif /* Check the supported flags. */ if ((flags & ~(SOCK_CLOEXEC | O_TEXT | O_BINARY)) != 0) { errno = EINVAL; return -1; } fd = accept (sockfd, addr, addrlen); if (fd < 0) return -1; #if SOCK_CLOEXEC # if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ /* Native Windows API. */ if (flags & SOCK_CLOEXEC) { HANDLE curr_process = GetCurrentProcess (); HANDLE old_handle = (HANDLE) _get_osfhandle (fd); HANDLE new_handle; int nfd; if (!DuplicateHandle (curr_process, /* SourceProcessHandle */ old_handle, /* SourceHandle */ curr_process, /* TargetProcessHandle */ (PHANDLE) &new_handle, /* TargetHandle */ (DWORD) 0, /* DesiredAccess */ FALSE, /* InheritHandle */ DUPLICATE_SAME_ACCESS)) /* Options */ { close (fd); errno = EBADF; /* arbitrary */ return -1; } /* Closing fd before allocating the new fd ensures that the new fd will have the minimum possible value. */ close (fd); nfd = _open_osfhandle ((intptr_t) new_handle, O_NOINHERIT | (flags & (O_TEXT | O_BINARY))); if (nfd < 0) { CloseHandle (new_handle); return -1; } return nfd; } # else /* Unix API. */ if (flags & SOCK_CLOEXEC) { int fcntl_flags; if ((fcntl_flags = fcntl (fd, F_GETFD, 0)) < 0 || fcntl (fd, F_SETFD, fcntl_flags | FD_CLOEXEC) == -1) { int saved_errno = errno; close (fd); errno = saved_errno; return -1; } } # endif #endif #if O_BINARY if (flags & O_BINARY) set_binary_mode (fd, O_BINARY); else if (flags & O_TEXT) set_binary_mode (fd, O_TEXT); #endif return fd; }
int main (int argc, char **argv) { int i; progname = argv[0]; /* If first two args are -o FILE, output to FILE. */ i = 1; if (argc > i + 1 && !strcmp (argv[i], "-o")) { if (! freopen (argv[i + 1], "w", stdout)) { perror (argv[i + 1]); return EXIT_FAILURE; } i += 2; } if (argc > i + 1 && !strcmp (argv[i], "-a")) { if (! freopen (argv[i + 1], "a", stdout)) { perror (argv[i + 1]); return EXIT_FAILURE; } i += 2; } if (argc > i + 1 && !strcmp (argv[i], "-d")) { if (chdir (argv[i + 1]) != 0) { perror (argv[i + 1]); return EXIT_FAILURE; } i += 2; } if (argc > i && !strcmp (argv[i], "-g")) { generate_globals = true; ++i; } set_binary_mode (fileno (stdout), O_BINARY); if (generate_globals) start_globals (); if (argc <= i) scan_c_stream (stdin); else { int first_infile = i; for (; i < argc; i++) { int j; /* Don't process one file twice. */ for (j = first_infile; j < i; j++) if (strcmp (argv[i], argv[j]) == 0) break; if (j == i) scan_file (argv[i]); } } if (generate_globals) write_globals (); if (ferror (stdout) || fclose (stdout) != 0) fatal ("write error"); return EXIT_SUCCESS; }
int main (int argc, char **argv) { int status = EXIT_SUCCESS; int DEFAULT_GROUPING = 0x01; int group_by = DEFAULT_GROUPING; bool un_flag = false, iso_flag = false; progname = *argv++; /* ** -hex hex dump ** -group-by-8-bits ** -group-by-16-bits ** -group-by-32-bits ** -group-by-64-bits ** -iso iso character set. ** -un || -de from hexl format to binary. ** -- End switch list. ** <filename> dump filename ** - (as filename == stdin) */ for (; *argv && *argv[0] == '-' && (*argv)[1]; argv++) { /* A switch! */ if (!strcmp (*argv, "--")) { argv++; break; } else if (!strcmp (*argv, "-un") || !strcmp (*argv, "-de")) { un_flag = true; set_binary_mode (fileno (stdout), O_BINARY); } else if (!strcmp (*argv, "-hex")) /* Hex is the default and is only base supported. */; else if (!strcmp (*argv, "-iso")) iso_flag = true; else if (!strcmp (*argv, "-group-by-8-bits")) group_by = 0x00; else if (!strcmp (*argv, "-group-by-16-bits")) group_by = 0x01; else if (!strcmp (*argv, "-group-by-32-bits")) group_by = 0x03; else if (!strcmp (*argv, "-group-by-64-bits")) group_by = 0x07; else { fprintf (stderr, "%s: invalid switch: \"%s\".\n", progname, *argv); fprintf (stderr, "usage: %s [-de] [-iso]\n", progname); return EXIT_FAILURE; } } char const *filename = *argv ? *argv++ : "-"; do { FILE *fp; if (!strcmp (filename, "-")) { fp = stdin; if (!un_flag) set_binary_mode (fileno (stdin), O_BINARY); } else { fp = fopen (filename, un_flag ? "r" : "rb"); if (!fp) { perror (filename); status = EXIT_FAILURE; continue; } } if (un_flag) { for (int c; 0 <= (c = getc (fp)); ) { /* Skip address at start of line. */ if (c != ' ') continue; for (int i = 0; i < 16; i++) { c = getc (fp); if (c < 0 || c == ' ') break; int hc = hexchar (c); c = getc (fp); if (c < 0) break; putchar (hc * 0x10 + hexchar (c)); if ((i & group_by) == group_by) { c = getc (fp); if (c < 0) break; } } while (0 <= c && c != '\n') c = getc (fp); if (c < 0) break; if (ferror (stdout)) output_error (); } } else { int c = 0; char string[18]; string[0] = ' '; string[17] = '\0'; for (uintmax_t address = 0; 0 <= c; address += 0x10) { int i; for (i = 0; i < 16; i++) { if (0 <= c) c = getc (fp); if (c < 0) { if (!i) break; fputs (" ", stdout); string[i + 1] = '\0'; } else { if (!i) printf ("%08"PRIxMAX": ", address); string[i + 1] = (c < 0x20 || (0x7F <= c && (!iso_flag || c < 0xa0)) ? '.' : c); printf ("%02x", c + 0u); } if ((i & group_by) == group_by) putchar (' '); } if (i) puts (string); if (ferror (stdout)) output_error (); } } bool trouble = ferror (fp) != 0; trouble |= fp != stdin && fclose (fp) != 0; if (trouble) { fprintf (stderr, "%s: read error\n", progname); status = EXIT_FAILURE; } filename = *argv++; } while (filename); if (ferror (stdout) || fclose (stdout) != 0) output_error (); return status; }
static pngquant_error write_image(png8_image *output_image, png24_image *output_image24, const char *outname, struct pngquant_options *options) { FILE *outfile; char *tempname = NULL; if (options->using_stdout) { set_binary_mode(stdout); outfile = stdout; if (output_image) { verbose_printf(options, " writing %d-color image to stdout", output_image->num_palette); } else { verbose_printf(options, " writing truecolor image to stdout"); } } else { tempname = temp_filename(outname); if (!tempname) return OUT_OF_MEMORY_ERROR; if ((outfile = fopen(tempname, "wb")) == NULL) { fprintf(stderr, " error: cannot open '%s' for writing\n", tempname); free(tempname); return CANT_WRITE_ERROR; } if (output_image) { verbose_printf(options, " writing %d-color image as %s", output_image->num_palette, filename_part(outname)); } else { verbose_printf(options, " writing truecolor image as %s", filename_part(outname)); } } pngquant_error retval; #pragma omp critical (libpng) { if (output_image) { retval = rwpng_write_image8(outfile, output_image); } else { retval = rwpng_write_image24(outfile, output_image24); } } if (!options->using_stdout) { fclose(outfile); if (SUCCESS == retval) { // Image has been written to a temporary file and then moved over destination. // This makes replacement atomic and avoids damaging destination file on write error. if (!replace_file(tempname, outname, options->force)) { retval = CANT_WRITE_ERROR; } } if (retval) { unlink(tempname); } } free(tempname); if (retval && retval != TOO_LARGE_FILE) { fprintf(stderr, " error: failed writing image to %s\n", outname); } return retval; }
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; }
int main(int argc, char *argv[]) { char view_file_type; int num_files; int i, j; char **view_files; char dest_file[LINE_BUF_SIZE]; file_merger_error_t error; cb_thread_t exit_thread; int status = 0; (void) argc; (void) argv; /* * Disable buffering for stdout since file merger messages needs * to be immediately available at erlang side */ setvbuf(stdout, (char *) NULL, _IONBF, 0); if (set_binary_mode() < 0) { fprintf(stderr, "Error setting binary mode\n"); exit(EXIT_FAILURE); } if (fscanf(stdin, "%c\n", &view_file_type) != 1) { fprintf(stderr, "Error reading view file type.\n"); exit(EXIT_FAILURE); } if (view_file_type != 'i' && view_file_type != 'v') { fprintf(stderr, "View file type must be 'i' or 'v'.\n"); exit(EXIT_FAILURE); } if (fscanf(stdin, "%d\n", &num_files) != 1) { fprintf(stderr, "Error reading number of files to merge.\n"); exit(EXIT_FAILURE); } if (num_files <= 0) { fprintf(stderr, "Number of files to merge is negative or zero.\n"); exit(EXIT_FAILURE); } view_files = (char **) malloc(sizeof(char *) * num_files); if (view_files == NULL) { fprintf(stderr, "Memory allocation failure.\n"); exit(EXIT_FAILURE); } for (i = 0; i < num_files; ++i) { view_files[i] = (char *) malloc(LINE_BUF_SIZE); if (view_files[i] == NULL) { for (j = 0; j < i; ++j) { free(view_files[j]); } free(view_files); fprintf(stderr, "Memory allocation failure.\n"); exit(EXIT_FAILURE); } if (couchstore_read_line(stdin, view_files[i], LINE_BUF_SIZE) != view_files[i]) { for (j = 0; j <= i; ++j) { free(view_files[j]); } free(view_files); fprintf(stderr, "Error reading view file number %d.\n", (i + 1)); exit(EXIT_FAILURE); } } if (couchstore_read_line(stdin, dest_file, LINE_BUF_SIZE) != dest_file) { fprintf(stderr, "Error reading destination file name.\n"); status = 1; goto finished; } status = start_exit_listener(&exit_thread); if (status) { fprintf(stderr, "Error starting stdin exit listener thread\n"); goto finished; } if (num_files > 1) { const char **src_files = (const char **) view_files; switch (view_file_type) { case 'i': error = merge_view_ids_ops_files(src_files, num_files, dest_file); break; case 'v': error = merge_view_kvs_ops_files(src_files, num_files, dest_file); break; default: fprintf(stderr, "Unknown view file type: %c\n", view_file_type); status = 1; goto finished; } if (error == FILE_MERGER_SUCCESS) { for (i = 0; i < num_files; ++i) { /* Ignore failures. Erlang side will eventually delete the files later. */ remove(view_files[i]); } } else { status = MERGE_ERROR_CODE(error); goto finished; } } else { if (rename(view_files[0], dest_file) != 0) { fprintf(stderr, "Error renaming file %s to %s: %s\n", view_files[0], dest_file, strerror(errno)); status = 1; goto finished; } } finished: for (i = 0; i < num_files; ++i) { free(view_files[i]); } free(view_files); return status; }
int main (int argc, char **argv) { // Optimize allocation for Tornado (2GB hash allocated after 1GB dictionary) AllocTopDown = FALSE; // Operation mode OPMODE global_mode=AUTO; // Record that stores all the info required for ReadWriteCallback static Results r; r.use_cpu_time = r.quiet_title = r.quiet_header = r.quiet_progress = r.quiet_result = FALSE; // Default compression parameters are equivalent to option -5 r.method = std_Tornado_method [default_Tornado_method]; // Delete successfully (de)compressed input files bool delete_input_files = FALSE; // Count of files to process int fcount=0; // Output path/filename const char *output_filename = NULL; // Process options until "--" // 1. First, process -1..-16 option if any for (char **argv_ptr = argv; *++argv_ptr!=NULL; ) { char *param = *argv_ptr; if (*param == '-') { param++; if (strcasecmp(param,"-")==0) break; // "--" is a "stop processing" option else if (isdigit(*param)) r.method = std_Tornado_method[check_parse_int (param, 1, elements(std_Tornado_method)-1, param-1)]; } } // 2. Second, process rest of options for (char **argv_ptr = argv; *++argv_ptr!=NULL; ) { char *param = *argv_ptr; if (param[0] != '-' || param[1]=='\0') { fcount++; } else { param++; int error=0; if (strcasecmp(param,"-")==0) break; else if (strcasecmp(param,"") ==0) continue; else if (strcasecmp(param,"z")==0) global_mode=_COMPRESS; else if (strcasecmp(param,"d")==0) global_mode=_DECOMPRESS; else if (strcasecmp(param,"delete")==0) delete_input_files=TRUE; else if (strcasecmp(param,"t")==0) output_filename=""; else if (strcasecmp(param,"q")==0) r.quiet_title = r.quiet_header = r.quiet_progress = r.quiet_result = TRUE; #ifndef FREEARC_NO_TIMING else if (strcasecmp(param,"cpu")==0) r.use_cpu_time=TRUE; #endif else if (strcasecmp(param,"h")==0) global_mode=HELP; else if (strcasecmp(param,"b")==0) r.method.buffer = MAX_BUFFER_SIZE; // set buffer size to the maximum supported by LZ coders else if (strcasecmp(param,"x")==0) r.method.caching_finder = CACHING_MF4; else if (strcasecmp(param,"xx")==0) r.method.caching_finder = CYCLED_MF4; else if (strcasecmp(param,"x+")==0) r.method.caching_finder = CACHING_MF4; else if (strcasecmp(param,"x-")==0) r.method.caching_finder = NON_CACHING_MF; else if (strcasecmp(param,"t+")==0) r.method.find_tables = TRUE; else if (strcasecmp(param,"t-")==0) r.method.find_tables = FALSE; else if (strcasecmp(param,"t1")==0) r.method.find_tables = TRUE; else if (strcasecmp(param,"t0")==0) r.method.find_tables = FALSE; else if (strcasecmp(param,"s")==0) r.method.hash3 = 1; else if (strcasecmp(param,"ss")==0) r.method.hash3 = 2; else if (strcasecmp(param,"s+")==0) r.method.hash3 = 1; else if (strcasecmp(param,"s-")==0) r.method.hash3 = 0; else if (start_with(param,"fb")) r.method.fast_bytes = check_parse_int (param+2, MIN_FAST_BYTES, MAX_FAST_BYTES, *argv_ptr); #ifdef FREEARC_WIN else if (strcasecmp(param,"slp-")==0) DefaultLargePageMode = DISABLE; else if (strcasecmp(param,"slp" )==0) DefaultLargePageMode = TRY; else if (strcasecmp(param,"slp+")==0) DefaultLargePageMode = FORCE; #endif else if (start_with(param,"rem")) /* ignore option */; else if (isdigit(*param)) ; // -1..-16 option is already processed :) else switch( tolower(*param++) ) { case 'b': r.method.buffer = check_parse_mem (param, MIN_BUFFER_SIZE, MAX_BUFFER_SIZE, *argv_ptr); break; case 'h': r.method.hashsize = check_parse_mem (param, MIN_HASH_SIZE, MAX_HASH_SIZE, *argv_ptr); break; case 'l': r.method.hash_row_width = check_parse_int (param, 1, MAX_HASH_ROW_WIDTH, *argv_ptr); break; case 'u': r.method.update_step = check_parse_int (param, 1, MAX_UPDATE_STEP, *argv_ptr); break; case 'c': r.method.encoding_method = check_parse_int (param, BYTECODER, ARICODER, *argv_ptr); break; case 's': r.method.hash3 = check_parse_int (param, 0, 2, *argv_ptr); break; case 'p': r.method.match_parser = parseInt (param, &error); break; case 'x': r.method.caching_finder = parseInt (param, &error); break; case 'o': output_filename = param; break; case 'q': #ifndef FREEARC_NO_TIMING r.quiet_title = strchr (param, 't'); r.quiet_progress = strchr (param, 'p'); #endif r.quiet_header = strchr (param, 'h'); r.quiet_result = strchr (param, 'r'); break; case 'a': switch( tolower(*param++) ) { case 'h': r.method.auxhash_size = check_parse_mem (param, MIN_HASH_SIZE, MAX_HASH_SIZE, *argv_ptr); goto check_for_errors; case 'l': r.method.auxhash_row_width = check_parse_int (param, 1, MAX_HASH_ROW_WIDTH, *argv_ptr); goto check_for_errors; } // 'a' should be the last case! default : fprintf (stderr, "ERROR: unknown option '%s'\n", *argv_ptr); exit(FREEARC_EXIT_ERROR); } check_for_errors: if (error) { fprintf (stderr, "ERROR: bad option format: '%s'\n", *argv_ptr); exit(FREEARC_EXIT_ERROR); } if (!(r.method.match_parser==GREEDY || r.method.match_parser==LAZY || r.method.match_parser==OPTIMAL)) { fprintf (stderr, "ERROR: bad option value: '%s'\n", *argv_ptr); exit(FREEARC_EXIT_ERROR); } int mf = r.method.caching_finder; r.method.caching_finder = mf = (mf==CACHING_MF4_DUB? CACHING_MF4 : (mf==CYCLED_MF4_DUB? CYCLED_MF4 : mf)); if (!(mf==NON_CACHING_MF || (CYCLED_MF4<=mf && mf<=CYCLED_MF7) || (CACHING_MF4<=mf && mf<=CACHING_MF7) || (BT_MF4<=mf && mf<=BT_MF7))) { fprintf (stderr, "ERROR: non-existing match finder: '%s'\n", *argv_ptr); exit(FREEARC_EXIT_ERROR); } } } // No files to compress: read from stdin and write to stdout if (global_mode!=HELP && fcount==0 && (global_mode!=AUTO || !isatty(0) && !isatty(1)) ) { static char *_argv[] = {argv[0], (char*)"-", NULL}; argv = _argv; fcount = 1; } else if (global_mode==HELP || fcount==0) { char h[100], ah[100], b[100], MinHashSizeStr[100], MaxHashSizeStr[100], MinBufSizeStr[100], MaxBufSizeStr[100]; showMem64 (r.method.hashsize, h); showMem64 (r.method.auxhash_size, ah); showMem64 (r.method.buffer, b); showMem64 (MIN_HASH_SIZE, MinHashSizeStr); showMem64 (MAX_HASH_SIZE+1, MaxHashSizeStr); showMem64 (MIN_BUFFER_SIZE, MinBufSizeStr); showMem64 (MAX_BUFFER_SIZE, MaxBufSizeStr); printf( "Tornado compressor v0.6 (c) [email protected] http://freearc.org 2014-03-08\n" "\n" " Usage: tor [options and files in any order]\n" " -# -- compression level (1..%d), default %d\n", int(elements(std_Tornado_method))-1, default_Tornado_method); printf( " -z -- force compression\n" " -d -- force decompression\n" " -oNAME -- output filename/directory (default %s/%s)\n", COMPRESS_EXT, DECOMPRESS_EXT); printf( " -t -- test (de)compression (redirect output to nul)\n" " -delete -- delete successfully (de)compressed input files\n" #ifdef FREEARC_NO_TIMING " -q -- be quiet; -q[hr]* disables header/results individually\n" #else " -q -- be quiet; -q[thpr]* disables title/header/progress/results individually\n" " -cpu -- compute raw CPU time (for benchmarking)\n" #endif #ifdef FREEARC_WIN " -slp[+/-/] -- force/disable/try(default) large pages support (2mb/4mb)\n" #endif " -rem... -- command-line remark\n" " -h -- display this help\n" " -- -- stop flags processing\n" " \"-\" used as filename means stdin/stdout\n" "\n" " Advanced compression parameters:\n" " -b# -- buffer size (%s..%s), default %s\n", MinBufSizeStr, MaxBufSizeStr, b); printf( " -h# -- hash size (%s..%s-1), default %s\n", MinHashSizeStr, MaxHashSizeStr, h); printf( " -l# -- length of hash row (1..%d), default %d\n", int(MAX_HASH_ROW_WIDTH), r.method.hash_row_width); printf( " -ah# -- auxiliary hash size (%s..%s-1), default %s\n", MinHashSizeStr, MaxHashSizeStr, ah); printf( " -al# -- auxiliary hash row length (1..%d), default %d\n", int(MAX_HASH_ROW_WIDTH), r.method.auxhash_row_width); printf( " -u# -- update step (1..%d), default %d\n", int(MAX_UPDATE_STEP), r.method.update_step); printf( " -c# -- coder (1-bytes, 2-bits, 3-huf, 4-arith), default %d\n", r.method.encoding_method); printf( " -p# -- parser (1-greedy, 2-lazy, 4-optimal), default %d\n", r.method.match_parser); printf( " -x# -- match finder (0: non-caching ht4, 4-7: cycling cached ht4..ht7,\n" " 14-17: shifting cached ht4..ht7, 24-27: bt4..bt7), default %d\n", r.method.caching_finder); printf( " -s# -- 2/3-byte hash (0-disabled, 1-fast, 2-max), default %d\n", r.method.hash3); printf( " -t# -- table diffing (0-disabled, 1-enabled), default %d\n", r.method.find_tables); printf( " -fb# -- fast bytes in the optimal parser (%d..%d), default %d\n", int(MIN_FAST_BYTES), int(MAX_FAST_BYTES), r.method.fast_bytes); printf( "\n" " Predefined methods:\n"); for (int i=1; i<elements(std_Tornado_method); i++) { printf(" %-8d-- %s\n", -i, name(std_Tornado_method[i])); } exit(EXIT_SUCCESS); } // (De)compress all files given on cmdline bool parse_options=TRUE; // options will be parsed until "--" Install_signal_handler(signal_handler); for (char **parameters = argv; *++parameters!=NULL; ) { // If options are still parsed and this argument starts with "-" - it's an option if (parse_options && parameters[0][0]=='-' && parameters[0][1]) { if (strequ(*parameters,"--")) parse_options=FALSE; continue; } // Save input filename r.filename = *parameters; // Select operation mode if it was not specified on cmdline r.mode = global_mode != AUTO? global_mode : end_with (r.filename, COMPRESS_EXT)? _DECOMPRESS : _COMPRESS; // Extension that should be added to output filenames const char *MODE_EXT = r.mode==_COMPRESS? COMPRESS_EXT : DECOMPRESS_EXT; // Construct output filename if (r.mode==BENCHMARK || output_filename && strequ (output_filename, "")) { // Redirect output to nul strcpy (r.outname, ""); } else if (output_filename) { if (strequ(output_filename,"-")) strcpy (r.outname, output_filename); else if (is_path_char (last_char (output_filename))) {sprintf(r.outname, "%s%s", output_filename, drop_dirname(r.filename)); goto add_remove_ext;} else if (dir_exists (output_filename)) {sprintf(r.outname, "%s%c%s", output_filename, PATH_DELIMITER, drop_dirname(r.filename)); goto add_remove_ext;} else strcpy (r.outname, output_filename); } else if (strequ(r.filename,"-")) { strcpy (r.outname, r.filename); } else { // No output filename was given on cmdline: // on compression - add COMPRESS_EXT // on decompression - remove COMPRESS_EXT (and add DECOMPRESS_EXT if file already exists) strcpy (r.outname, r.filename); add_remove_ext: // Remove COMPRESS_EXT on the end of name or add DECOMPRESS_EXT (unless we are in _COMPRESS mode) if (r.mode!=_COMPRESS && end_with (r.outname, COMPRESS_EXT)) { r.outname [strlen(r.outname) - strlen(COMPRESS_EXT)] = '\0'; if (file_exists (r.outname)) strcat(r.outname, MODE_EXT); } else { strcat(r.outname, MODE_EXT); } } // Open input file r.fin = strequ (r.filename, "-")? stdin : file_open_read_binary(r.filename); if (r.fin == NULL) { fprintf (stderr, "\n Can't open %s for read\n", r.filename); exit(FREEARC_EXIT_ERROR); } set_binary_mode (r.fin); // Open output file if (*r.outname) { r.fout = strequ (r.outname, "-")? stdout : file_open_write_binary(r.outname); if (r.fout == NULL) { fprintf (stderr, "\n Can't open %s for write\n", r.outname); exit(FREEARC_EXIT_ERROR); } set_binary_mode (r.fout); } else { r.fout = NULL; } // Prepare to (de)compression int result; char filesize_str[100]; start_print_stats(r); // Perform actual (de)compression switch (r.mode) { case _COMPRESS: { if (!r.quiet_header && r.filesize >= 0) fprintf (stderr, "Compressing %s bytes with %s\n", show3(r.filesize,filesize_str), name(r.method)); PackMethod m = r.method; if (r.filesize >= 0) m.buffer = mymin (m.buffer, r.filesize+LOOKAHEAD*2); result = tor_compress (m, ReadWriteCallback, &r, NULL, -1); break; } case _DECOMPRESS: { //if (!r.quiet_header && !strequ (r.outname, "-")) fprintf (stderr, "Unpacking %.3lf mb\n", double(r.filesize)/1000/1000); result = tor_decompress (ReadWriteCallback, &r, NULL, -1); break; } } // Finish (de)compression print_final_stats(r); fclose (r.fin); if (r.fout) fclose (r.fout); if (result == FREEARC_OK) { if (delete_input_files && !strequ(r.filename,"-")) delete_file(r.filename); } else { if (!strequ(r.outname,"-") && !strequ(r.outname,"")) delete_file(r.outname); switch (result) { case FREEARC_ERRCODE_INVALID_COMPRESSOR: fprintf (stderr, "\nThis compression mode isn't supported by small Tornado version, use full version instead!"); break; case FREEARC_ERRCODE_NOT_ENOUGH_MEMORY: fprintf (stderr, "\nNot enough memory for (de)compression!"); break; case FREEARC_ERRCODE_READ: fprintf (stderr, "\nRead error! Bad media?"); break; case FREEARC_ERRCODE_WRITE: fprintf (stderr, "\nWrite error! Disk full?"); break; case FREEARC_ERRCODE_BAD_COMPRESSED_DATA: fprintf (stderr, "\nData can't be decompressed!"); break; default: fprintf (stderr, "\n(De)compression failed with error code %d!", result); break; } exit(FREEARC_EXIT_ERROR); } // going to next file... } return EXIT_SUCCESS; }