Re: Mogrify -preserve implementation
Niko Rosvall <[email protected]> Wed, 24 Feb 2016 11:32:32 +0200
| Newsgroups | gmane.comp.video.graphicsmagick.core |
|---|---|
| Message-ID | <[email protected]> |
This is a multi-part message in MIME format.
--------------050209000100040906050103
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: 7bit
On 02/23/2016 07:19 PM, Niko Rosvall wrote:
> On 02/23/2016 04:47 PM, Bob Friesenhahn wrote:
>> On Tue, 23 Feb 2016, Niko Rosvall wrote:
>>
>>> Hi,
>>>
>>> I wrote a fairly naive implementation to keep file timestamps when
>>> running mogrify. I added an option -preserve to the command mogrify.
>>>
>>> By no means it's not perfect as it does not care about Windows. I hardly
>>> use Windows at all, so it fairly hard for me to implement support for
>>> it. However, I'm willing to do it, if this is a feature that GM wants to
>>> include.
>>
>> Few of us love Windows, but we are dedicated to making sure that
>> GraphicsMagick Windows users are well supported within the
>> capabilities of the operating system.
>>
>>> Some questions: Would it be better to implement the actual code into
>>> separate files (now it's just all in magick/command.c). Maybe
>>> magic/preserve.c?
>>
>> What is currently typically done is to put Unix-specific code in
>> magick/unix_port.c and Windows-specific code in magick/nt_base.c.
>> Similar functions added to each place can allow a common
>> implementation in magick/command.c to work.
>>
>> The magick/studio.h header provides a MagickFstat() macro which
>> provides porting definitions. Windows does provide fstat as well as a
>> a _fstati64() function (for large files). I am not sure how one sets
>> file timestamps under Windows.
>>
>> Bob
>>
>
> Thanks!
>
> I did take a look, and it's not too hard to set timetamps on Windows, so
> I will take a closer look and send a better patch later! Thanks for the
> instructions. :)
>
> Niko
Hi,
Here's a patch which works on Windows too (and it better written in
general). In the end, setting the file timestamps on Windows is almost
the same as on Posix systems.
Niko
--------------050209000100040906050103
Content-Type: text/x-patch;
name="mogrify-preserve.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="mogrify-preserve.diff"
diff -r 43a59a8ef281 magick/command.c
--- a/magick/command.c Sun Feb 21 18:35:51 2016 -0600
+++ b/magick/command.c Wed Feb 24 11:24:02 2016 +0200
@@ -8983,7 +8983,7 @@
unsigned int
matte;
-
+
/*
Verify option length.
*/
@@ -11663,6 +11663,7 @@
const char *output_directory;
MagickBool create_directories;
MagickBool global_colormap;
+ MagickBool preserve_file_attr;
MagickPassFail status;
ExceptionInfo exception;
} TransmogrifyOptions;
@@ -11677,6 +11678,14 @@
MagickPassFail
status = MagickPass;
+ int
+ fileatt_error;
+
+ MagickStatStruct_t
+ statbuf;
+
+ fileatt_error = -1;
+
assert(options != (TransmogrifyOptions *) NULL);
assert(options->input_filename != (char *) NULL);
@@ -11717,7 +11726,7 @@
}
if (status == MagickFail)
break;
-
+
/*
Write transmogrified image to disk.
*/
@@ -11751,6 +11760,10 @@
AppendImageFormat(options->output_format,output_filename);
(void) strlcpy(image->magick,options->output_format,MaxTextExtent);
}
+
+ if (options->preserve_file_attr)
+ fileatt_error = MagicGetFileAttributes(image->filename, &statbuf);
+
if (options->create_directories)
{
/*
@@ -11805,7 +11818,21 @@
Write the output file.
*/
(void) strlcpy(image->filename,output_filename,MaxTextExtent);
+
+
status = WriteImages(image_info,image,image->filename,&options->exception);
+
+ if (options->preserve_file_attr)
+ {
+ if (fileatt_error == 0)
+ {
+ if (MagickSetFileAttributes(image->filename, &statbuf) != 0)
+ {
+ fprintf(stderr, "Error preserving file timestamps\n");
+ }
+ }
+ }
+
if ((status != MagickFail) && (temporary_filename[0] != 0))
{
/*
@@ -11907,7 +11934,8 @@
MagickBool
create_directories,
- global_colormap;
+ global_colormap,
+ preserve_file_attr;
unsigned int
status;
@@ -11939,6 +11967,7 @@
output_directory[0]='\0';
create_directories=MagickFalse;
global_colormap=MagickFalse;
+ preserve_file_attr=MagickFalse;
status=True;
/*
@@ -11971,6 +12000,7 @@
transmogrify_options.output_directory=output_directory;
transmogrify_options.create_directories=create_directories;
transmogrify_options.global_colormap=global_colormap;
+ transmogrify_options.preserve_file_attr=preserve_file_attr;
transmogrify_options.status=MagickPass;
GetExceptionInfo(&transmogrify_options.exception);
status &= *TransmogrifyImage(&transmogrify_options);
@@ -13112,6 +13142,11 @@
ThrowMogrifyException(OptionError,MissingArgument,option);
break;
}
+ if (LocaleCompare("preserve", option+1) == 0)
+ {
+ preserve_file_attr = MagickTrue;
+ break;
+ }
ThrowMogrifyException(OptionError,UnrecognizedOption,option)
}
case 'q':
@@ -13772,6 +13807,7 @@
"-fill color color for annotating or changing opaque color",
"-pointsize value font point size",
"-profile filename add ICM or IPTC information profile to image",
+ "-preserve preverve original modification timestamp of the file",
"-quality value JPEG/MIFF/PNG compression level",
"-raise value lighten/darken image edges to create a 3-D effect",
"-random-threshold channeltype LOWxHIGH",
diff -r 43a59a8ef281 magick/nt_base.c
--- a/magick/nt_base.c Sun Feb 21 18:35:51 2016 -0600
+++ b/magick/nt_base.c Wed Feb 24 11:24:02 2016 +0200
@@ -36,6 +36,8 @@
/*
Include declarations.
*/
+#include <sys/types.h>
+#include <sys/utime.h>
#include "magick/log.h"
#include "magick/magick.h"
#include "magick/utility.h"
@@ -256,7 +258,32 @@
{
return 4096;
}
-
+
+MagickExport int MagicGetFileAttributes(const char *filename, MagickStatStruct_t *statbuf)
+{
+ if (MagickStat(filename, statbuf) != 0)
+ return -1;
+
+ return 0;
+}
+
+MagickExport int MagickSetFileAttributes(const char *filename, MagickStatStruct_t *statbuf)
+{
+ /*
+ Setting file timestamps on Windows is actually almost the same as on Posix systems.
+ https://msdn.microsoft.com/en-us/library/4wacf567.aspx
+ */
+ struct _utimbuf ut;
+
+ ut.actime = statbuf->st_atime;
+ ut.modtime = statbuf->st_mtime;
+
+ if (_utime(filename, &utbuf) == -1)
+ return -1;
+
+ return 0;
+}
+
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
diff -r 43a59a8ef281 magick/nt_base.h
--- a/magick/nt_base.h Sun Feb 21 18:35:51 2016 -0600
+++ b/magick/nt_base.h Wed Feb 24 11:24:02 2016 +0200
@@ -356,6 +356,12 @@
NTftruncate(int filedes, off_t length),
NTmsync(void *addr, size_t len, int flags),
NTmunmap(void *addr, size_t len);
+
+extern MagickExport int
+ MagicGetFileAttributes(const char *filename, MagickStatStruct_t *statbuf);
+
+extern MagickExport int
+ MagickSetFileAttributes(const char *filename, MagickStatStruct_t *statbuf);
#define MagickMmap(address,length,protection,access,file,offset) \
NTmmap(address,length,protection,access,file,offset)
diff -r 43a59a8ef281 magick/unix_port.c
--- a/magick/unix_port.c Sun Feb 21 18:35:51 2016 -0600
+++ b/magick/unix_port.c Wed Feb 24 11:24:02 2016 +0200
@@ -43,7 +43,8 @@
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
-
+#include <sys/types.h>
+#include <utime.h>
#include "magick/utility.h"
/*
@@ -86,4 +87,26 @@
return pagesize;
}
+MagickExport int MagicGetFileAttributes(const char *filename, MagickStatStruct_t *statbuf)
+{
+ if (MagickStat(filename, statbuf) != 0)
+ return -1;
+
+ return 0;
+}
+
+MagickExport int MagickSetFileAttributes(const char *filename, MagickStatStruct_t *statbuf)
+{
+ struct utimbuf
+ utbuf;
+
+ utbuf.actime = statbuf->st_atime;
+ utbuf.modtime = statbuf->st_mtime;
+
+ if (utime(filename, &utbuf) != 0)
+ return -1;
+
+ return 0;
+}
+
#endif /* defined(POSIX) */
diff -r 43a59a8ef281 magick/unix_port.h
--- a/magick/unix_port.h Sun Feb 21 18:35:51 2016 -0600
+++ b/magick/unix_port.h Wed Feb 24 11:24:02 2016 +0200
@@ -18,6 +18,12 @@
extern MagickExport long
MagickGetMMUPageSize(void);
+extern MagickExport int
+ MagicGetFileAttributes(const char *filename, struct stat *statbuf);
+
+extern MagickExport int
+ MagickSetFileAttributes(const char *filename, struct stat *statbuf);
+
/*
Size type passed to read/write
*/
--------------050209000100040906050103
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
------------------------------------------------------------------------------
Site24x7 APM Insight: Get Deep Visibility into Application Performance
APM + Mobile APM + RUM: Monitor 3 App instances at just $35/Month
Monitor end-to-end web transactions and take corrective actions now
Troubleshoot faster and improve end-user experience. Signup Now!
http://pubads.g.doubleclick.net/gampad/clk?id=272487151&iu=/4140
--------------050209000100040906050103
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
Graphicsmagick-core mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/graphicsmagick-core
--------------050209000100040906050103--