| @@ -37,6 +37,7 @@ · 36 unmodified lines |
| 37 | 37 | #endif |
| 38 | 38 | |
| 39 | 39 | #include "osdep/io.h" |
| 40 | +#include "misc/path_utils.h" |
| 40 | 41 | |
| 41 | 42 | #include "common/av_common.h" |
| 42 | 43 | #include "common/msg.h" |
| @@ -162,9 +163,14 @@ static void prepare_avframe(AVFrame *pic, AVCodecContext *avctx, · 119 unmodified lines |
| 162 | 163 | ); |
| 163 | 164 | } |
| 164 | 165 | |
| 165 | | −static bool write_lavc(struct image_writer_ctx *ctx, mp_image_t *image, const char *filename) |
| 166 | +static bool write_lavc(struct image_writer_ctx *ctx, mp_image_t *image, |
| 167 | + const char *filename, bool overwrite) |
| 166 | 168 | { |
| 167 | | − FILE *fp = fopen(filename, "wb"); |
| 169 | + FILE *fp = fopen(filename, overwrite ? "wb" : "wbx"); |
| 170 | + if (!fp && errno == EEXIST) { |
| 171 | + MP_ERR(ctx, "File '%s' already exists!\n", filename); |
| 172 | + return false; |
| 173 | + } |
| 168 | 174 | if (!fp) { |
| 169 | 175 | MP_ERR(ctx, "Error opening '%s' for writing!\n", filename); |
| 170 | 176 | return false; |
| @@ -277,9 +283,13 @@ static void write_jpeg_error_exit(j_common_ptr cinfo) · 106 unmodified lines |
| 277 | 283 | } |
| 278 | 284 | |
| 279 | 285 | static bool write_jpeg(struct image_writer_ctx *ctx, mp_image_t *image, |
| 280 | | − const char *filename) |
| 286 | + const char *filename, bool overwrite) |
| 281 | 287 | { |
| 282 | | − FILE *fp = fopen(filename, "wb"); |
| 288 | + FILE *fp = fopen(filename, overwrite ? "wb" : "wbx"); |
| 289 | + if (!fp && errno == EEXIST) { |
| 290 | + MP_ERR(ctx, "File '%s' already exists!\n", filename); |
| 291 | + return false; |
| 292 | + } |
| 283 | 293 | if (!fp) { |
| 284 | 294 | MP_ERR(ctx, "Error opening '%s' for writing!\n", filename); |
| 285 | 295 | return false; |
| @@ -361,7 +371,7 @@ static void log_side_data(struct image_writer_ctx *ctx, AVPacketSideData *data, · 75 unmodified lines |
| 361 | 371 | } |
| 362 | 372 | |
| 363 | 373 | static bool write_avif(struct image_writer_ctx *ctx, mp_image_t *image, |
| 364 | | − const char *filename) |
| 374 | + const char *filename, bool overwrite) |
| 365 | 375 | { |
| 366 | 376 | const AVCodec *codec = NULL; |
| 367 | 377 | const AVOutputFormat *ofmt = NULL; |
| @@ -429,6 +439,11 @@ static bool write_avif(struct image_writer_ctx *ctx, mp_image_t *image, · 61 unmodified lines |
| 429 | 439 | goto free_data; |
| 430 | 440 | } |
| 431 | 441 | |
| 442 | + if (!overwrite && mp_path_exists(filename)) { |
| 443 | + MP_ERR(ctx, "File '%s' already exists\n", filename); |
| 444 | + goto free_data; |
| 445 | + } |
| 446 | + |
| 432 | 447 | ret = avio_open(&avioctx, filename, AVIO_FLAG_WRITE); |
| 433 | 448 | if (ret < 0) { |
| 434 | 449 | MP_ERR(ctx, "Could not open file '%s' for saving images\n", filename); |
| @@ -705,7 +720,7 @@ static struct mp_image *convert_image(struct mp_image *image, int destfmt, · 270 unmodified lines |
| 705 | 720 | |
| 706 | 721 | bool write_image(struct mp_image *image, const struct image_writer_opts *opts, |
| 707 | 722 | const char *filename, struct mpv_global *global, |
| 708 | | − struct mp_log *log) |
| 723 | + struct mp_log *log, bool overwrite) |
| 709 | 724 | { |
| 710 | 725 | struct image_writer_opts defs = image_writer_opts_defaults; |
| 711 | 726 | if (!opts) |
| @@ -714,7 +729,7 @@ bool write_image(struct mp_image *image, const struct image_writer_opts *opts, · 2 unmodified lines |
| 714 | 729 | mp_verbose(log, "input: %s\n", mp_image_params_to_str(&image->params)); |
| 715 | 730 | |
| 716 | 731 | struct image_writer_ctx ctx = { log, opts, image->fmt }; |
| 717 | | − bool (*write)(struct image_writer_ctx *, mp_image_t *, const char *) = write_lavc; |
| 732 | + bool (*write)(struct image_writer_ctx *, mp_image_t *, const char *, bool) = write_lavc; |
| 718 | 733 | int destfmt = 0; |
| 719 | 734 | |
| 720 | 735 | #if HAVE_JPEG |
| @@ -751,7 +766,7 @@ bool write_image(struct mp_image *image, const struct image_writer_opts *opts, · 30 unmodified lines |
| 751 | 766 | if (!dst) |
| 752 | 767 | return false; |
| 753 | 768 | |
| 754 | | − bool success = write(&ctx, dst, filename); |
| 769 | + bool success = write(&ctx, dst, filename, overwrite); |
| 755 | 770 | if (!success) |
| 756 | 771 | mp_err(log, "Error writing file '%s'!\n", filename); |
| 757 | 772 | |
| @@ -763,5 +778,5 @@ void dump_png(struct mp_image *image, const char *filename, struct mp_log *log) · 5 unmodified lines |
| 763 | 778 | { |
| 764 | 779 | struct image_writer_opts opts = image_writer_opts_defaults; |
| 765 | 780 | opts.format = AV_CODEC_ID_PNG; |
| 766 | | − write_image(image, &opts, filename, NULL, log); |
| 781 | + write_image(image, &opts, filename, NULL, log, true); |
| 767 | 782 | } |