| @@ -37,6 +37,7 @@ · 36 unmodified lines |
| 37 | #endif | 37 | #endif |
| 38 | | 38 | |
| 39 | #include "osdep/io.h" | 39 | #include "osdep/io.h" |
| | 40 | #include "misc/path_utils.h" |
| 40 | | 41 | |
| 41 | #include "common/av_common.h" | 42 | #include "common/av_common.h" |
| 42 | #include "common/msg.h" | 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 | if (!fp) { | 174 | if (!fp) { |
| 169 | MP_ERR(ctx, "Error opening '%s' for writing!\n", filename); | 175 | MP_ERR(ctx, "Error opening '%s' for writing!\n", filename); |
| 170 | return false; | 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 | static bool write_jpeg(struct image_writer_ctx *ctx, mp_image_t *image, | 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 | if (!fp) { | 293 | if (!fp) { |
| 284 | MP_ERR(ctx, "Error opening '%s' for writing!\n", filename); | 294 | MP_ERR(ctx, "Error opening '%s' for writing!\n", filename); |
| 285 | return false; | 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 | static bool write_avif(struct image_writer_ctx *ctx, mp_image_t *image, | 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 | const AVCodec *codec = NULL; | 376 | const AVCodec *codec = NULL; |
| 367 | const AVOutputFormat *ofmt = NULL; | 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 | goto free_data; | 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 | ret = avio_open(&avioctx, filename, AVIO_FLAG_WRITE); | 447 | ret = avio_open(&avioctx, filename, AVIO_FLAG_WRITE); |
| 433 | if (ret < 0) { | 448 | if (ret < 0) { |
| 434 | MP_ERR(ctx, "Could not open file '%s' for saving images\n", filename); | 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 | bool write_image(struct mp_image *image, const struct image_writer_opts *opts, | 721 | bool write_image(struct mp_image *image, const struct image_writer_opts *opts, |
| 707 | const char *filename, struct mpv_global *global, | 722 | const char *filename, struct mpv_global *global, |
| 708 | struct mp_log *log) | 723 | struct mp_log *log, bool overwrite) |
| 709 | { | 724 | { |
| 710 | struct image_writer_opts defs = image_writer_opts_defaults; | 725 | struct image_writer_opts defs = image_writer_opts_defaults; |
| 711 | if (!opts) | 726 | if (!opts) |
| @@ -714,7 +729,7 @@ bool write_image(struct mp_image *image, const struct image_writer_opts *opts, · 2 unmodified lines |
| 714 | mp_verbose(log, "input: %s\n", mp_image_params_to_str(&image->params)); | 729 | mp_verbose(log, "input: %s\n", mp_image_params_to_str(&image->params)); |
| 715 | | 730 | |
| 716 | struct image_writer_ctx ctx = { log, opts, image->fmt }; | 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 | int destfmt = 0; | 733 | int destfmt = 0; |
| 719 | | 734 | |
| 720 | #if HAVE_JPEG | 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 | if (!dst) | 766 | if (!dst) |
| 752 | return false; | 767 | return false; |
| 753 | | 768 | |
| 754 | bool success = write(&ctx, dst, filename); | 769 | bool success = write(&ctx, dst, filename, overwrite); |
| 755 | if (!success) | 770 | if (!success) |
| 756 | mp_err(log, "Error writing file '%s'!\n", filename); | 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 | struct image_writer_opts opts = image_writer_opts_defaults; | 779 | struct image_writer_opts opts = image_writer_opts_defaults; |
| 765 | opts.format = AV_CODEC_ID_PNG; | 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 | } |