diff --git a/src/lib/Imlib2.h.in b/src/lib/Imlib2.h.in index 38ae41f..0a2b768 100644 --- a/src/lib/Imlib2.h.in +++ b/src/lib/Imlib2.h.in @@ -2576,6 +2576,21 @@ EAPI void imlib_save_image(const char *file); EAPI void imlib_save_image_with_errno_return(const char *file, int *error_return); +/** + * Save image to file descriptor + * + * Saves the current image in the format specified by the current + * image's format setting to the file given by @p fd. + * The file name @p file is used only to derive the file format if the + * image's format is not set. + * + * @p fd will be closed after calling this function. + * + * @param fd Image file descriptor + * @param file The file name + */ +EAPI void imlib_save_image_fd(int fd, const char *file); + /*-------------------------------- * Image rotation/skewing */ diff --git a/src/lib/api.c b/src/lib/api.c index 3f160ba..1ecac0a 100644 --- a/src/lib/api.c +++ b/src/lib/api.c @@ -1879,7 +1879,7 @@ imlib_image_remove_and_free_attached_data_value(const char *key) } static void -_imlib_save_image(const char *file) +_imlib_save_image(const char *file, FILE * fp) { ImlibImage *im; ImlibLoadArgs ila = { ILA0(ctx, 0, 0) }; @@ -1891,6 +1891,7 @@ _imlib_save_image(const char *file) if (ctx->error) return; + ila.fp = fp; __imlib_SaveImage(im, file, &ila); ctx->error = ila.err; } @@ -1900,7 +1901,7 @@ imlib_save_image(const char *file) { CHECK_PARAM_POINTER("file", file); - _imlib_save_image(file); + _imlib_save_image(file, NULL); } EAPI void @@ -1909,7 +1910,7 @@ imlib_save_image_with_error_return(const char *file, { CHECK_PARAM_POINTER("file", file); - _imlib_save_image(file); + _imlib_save_image(file, NULL); if (error_return) *error_return = __imlib_ErrorFromErrno(ctx->error, 1); @@ -1920,12 +1921,31 @@ imlib_save_image_with_errno_return(const char *file, int *error_return) { CHECK_PARAM_POINTER("file", file); - _imlib_save_image(file); + _imlib_save_image(file, NULL); if (error_return) *error_return = ctx->error; } +EAPI void +imlib_save_image_fd(int fd, const char *file) +{ + FILE *fp; + + fp = fdopen(fd, "wb"); + if (!fp) + { + ctx->error = errno; + close(fd); + printf("Boo\n"); + return; + } + + _imlib_save_image(file, fp); + + fclose(fp); +} + EAPI Imlib_Image imlib_create_rotated_image(double angle) { diff --git a/src/lib/image.c b/src/lib/image.c index 5f81236..ef0f396 100644 --- a/src/lib/image.c +++ b/src/lib/image.c @@ -866,10 +866,10 @@ __imlib_SaveImage(ImlibImage * im, const char *file, ImlibLoadArgs * ila) { ImlibLoader *l; ImlibLoaderCtx ilc; - FILE *fp; + FILE *fp = ila->fp; int loader_ret; - if (!file) + if (!file && !fp) { ila->err = ENOENT; return; @@ -884,23 +884,27 @@ __imlib_SaveImage(ImlibImage * im, const char *file, ImlibLoadArgs * ila) return; } - fp = __imlib_FileOpen(file, "wb"); if (!fp) { - ila->err = errno; - return; + fp = __imlib_FileOpen(file, "wb"); + if (!fp) + { + ila->err = errno; + return; + } } if (ila->pfunc) __imlib_LoadCtxInit(im, &ilc, ila->pfunc, ila->pgran); - __imlib_ImageFileContextPush(im, strdup(file)); + __imlib_ImageFileContextPush(im, file ? strdup(file) : NULL); im->fi->fp = fp; /* call the saver */ loader_ret = l->module->save(im); - fclose(fp); + if (!ila->fp) + fclose(fp); __imlib_ImageFileContextPop(im); diff --git a/test/test_save.cpp b/test/test_save.cpp index f73f858..3bd1563 100644 --- a/test/test_save.cpp +++ b/test/test_save.cpp @@ -1,6 +1,7 @@ #include #include "config.h" +#include #include #include "test.h" @@ -191,7 +192,7 @@ test_save_2(const char *file, const char *fmt, bool load_imm, bool sok, { char filei[256]; char fileo[256]; - int err; + int err, fd; Imlib_Image im; unsigned int crc; @@ -230,6 +231,39 @@ test_save_2(const char *file, const char *fmt, bool load_imm, bool sok, imlib_free_image_and_decache(); + if (!sok) + return; + + D("Check '%s' ... ", fileo); + im = imlib_load_image(fileo); + ASSERT_TRUE(im); + crc = image_get_crc32(im); + EXPECT_EQ(crc_exp, crc); + D("ok\n"); + unlink(fileo); + + D("Save to fd '%s'\n", fileo); + imlib_image_set_format(fmt); + fd = open(fileo, O_WRONLY | O_CREAT | O_TRUNC, 0644); + imlib_save_image_fd(fd, NULL); + err = imlib_get_error(); + if (sok) + { + EXPECT_EQ(err, 0); + if (err) + D("Error %d saving '%s'\n", err, fileo); + } + else + { + EXPECT_EQ(err, IMLIB_ERR_NO_SAVER); + if (err != IMLIB_ERR_NO_SAVER) + D("Error %d saving '%s'\n", err, fileo); + } + err = close(fd); + EXPECT_NE(err, 0); + + imlib_free_image_and_decache(); + if (!sok) return;