diff --git a/video/image_writer.c b/video/image_writer.c index c3cf930401..cc795735ef 100644 --- a/video/image_writer.c +++ b/video/image_writer.c @@ -163,19 +163,8 @@ static void prepare_avframe(AVFrame *pic, AVCodecContext *avctx, ); } -static bool write_lavc(struct image_writer_ctx *ctx, mp_image_t *image, - const char *filename, bool overwrite) +static bool write_lavc(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp) { - FILE *fp = fopen(filename, overwrite ? "wb" : "wbx"); - if (!fp && errno == EEXIST) { - MP_ERR(ctx, "File '%s' already exists!\n", filename); - return false; - } - if (!fp) { - MP_ERR(ctx, "Error opening '%s' for writing!\n", filename); - return false; - } - bool success = false; AVFrame *pic = NULL; AVPacket *pkt = NULL; @@ -265,9 +254,6 @@ error_exit: avcodec_free_context(&avctx); av_frame_free(&pic); av_packet_free(&pkt); - success = success && !fclose(fp); - if (!success) - unlink(filename); return success; } @@ -282,19 +268,8 @@ static void write_jpeg_error_exit(j_common_ptr cinfo) longjmp(*(jmp_buf*)cinfo->client_data, 1); } -static bool write_jpeg(struct image_writer_ctx *ctx, mp_image_t *image, - const char *filename, bool overwrite) +static bool write_jpeg(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp) { - FILE *fp = fopen(filename, overwrite ? "wb" : "wbx"); - if (!fp && errno == EEXIST) { - MP_ERR(ctx, "File '%s' already exists!\n", filename); - return false; - } - if (!fp) { - MP_ERR(ctx, "Error opening '%s' for writing!\n", filename); - return false; - } - struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; @@ -305,8 +280,6 @@ static bool write_jpeg(struct image_writer_ctx *ctx, mp_image_t *image, cinfo.client_data = &error_return_jmpbuf; if (setjmp(cinfo.client_data)) { jpeg_destroy_compress(&cinfo); - fclose(fp); - unlink(filename); return false; } @@ -343,10 +316,7 @@ static bool write_jpeg(struct image_writer_ctx *ctx, mp_image_t *image, jpeg_destroy_compress(&cinfo); - if (!fclose(fp)) - return true; - unlink(filename); - return false; + return true; } #endif @@ -370,8 +340,7 @@ static void log_side_data(struct image_writer_ctx *ctx, AVPacketSideData *data, } } -static bool write_avif(struct image_writer_ctx *ctx, mp_image_t *image, - const char *filename, bool overwrite) +static bool write_avif(struct image_writer_ctx *ctx, mp_image_t *image, FILE *fp) { const AVCodec *codec = NULL; const AVOutputFormat *ofmt = NULL; @@ -439,16 +408,8 @@ static bool write_avif(struct image_writer_ctx *ctx, mp_image_t *image, goto free_data; } - if (!overwrite && mp_path_exists(filename)) { - MP_ERR(ctx, "File '%s' already exists\n", filename); - goto free_data; - } - - ret = avio_open(&avioctx, filename, AVIO_FLAG_WRITE); - if (ret < 0) { - MP_ERR(ctx, "Could not open file '%s' for saving images\n", filename); - goto free_data; - } + avio_open_dyn_buf(&avioctx); + MP_HANDLE_OOM(avioctx); fmtctx = avformat_alloc_context(); if (!fmtctx) { @@ -526,10 +487,12 @@ static bool write_avif(struct image_writer_ctx *ctx, mp_image_t *image, } MP_DBG(ctx, "write_avif(): avio_size() = %"PRIi64"\n", avio_size(avioctx)); - success = true; + uint8_t *buf = NULL; + int written_size = avio_close_dyn_buf(avioctx, &buf); + success = fwrite(buf, written_size, 1, fp) == 1; + av_freep(&buf); free_data: - success = !avio_closep(&avioctx) && success; avformat_free_context(fmtctx); avcodec_free_context(&avctx); av_packet_free(&pkt); @@ -729,7 +692,7 @@ bool write_image(struct mp_image *image, const struct image_writer_opts *opts, mp_verbose(log, "input: %s\n", mp_image_params_to_str(&image->params)); struct image_writer_ctx ctx = { log, opts, image->fmt }; - bool (*write)(struct image_writer_ctx *, mp_image_t *, const char *, bool) = write_lavc; + bool (*write)(struct image_writer_ctx *, mp_image_t *, FILE *) = write_lavc; int destfmt = 0; #if HAVE_JPEG @@ -766,10 +729,21 @@ bool write_image(struct mp_image *image, const struct image_writer_opts *opts, if (!dst) return false; - bool success = write(&ctx, dst, filename, overwrite); - if (!success) - mp_err(log, "Error writing file '%s'!\n", filename); + bool success = false; + FILE *fp = fopen(filename, overwrite ? "wb" : "wbx"); + if (!fp) { + mp_err(log, "Error creating '%s' for writing: %s!\n", + filename, mp_strerror(errno)); + goto done; + } + success = write(&ctx, dst, fp); + if (fclose(fp) || !success) { + mp_err(log, "Error writing file '%s'!\n", filename); + unlink(filename); + } + +done: talloc_free(dst); return success; }