Mogrify -preserve implementation

Niko Rosvall <[email protected]> Tue, 23 Feb 2016 10:50:41 +0200
Newsgroups gmane.comp.video.graphicsmagick.core
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--------------080509030700080306090809
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit

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.

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?

Here's a patch.

Cheers,
Niko Rosvall

--------------080509030700080306090809
Content-Type: text/x-patch;
 name="mogrify-preserve.diff"
Content-Transfer-Encoding: quoted-printable
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	Tue Feb 23 10:16:18 2016 +0200
@@ -37,6 +37,9 @@
 /*
   Include declarations.
 */
+
+#include <sys/types.h>
+#include <utime.h>
 #include "magick/studio.h"
 #include "magick/analyze.h"
 #include "magick/attribute.h"
@@ -8983,7 +8986,7 @@
=20
   unsigned int
     matte;
-
+=20
   /*
     Verify option length.
   */
@@ -11663,6 +11666,7 @@
   const char *output_directory;
   MagickBool create_directories;
   MagickBool global_colormap;
+  MagickBool preserve_file_attr;
   MagickPassFail status;
   ExceptionInfo exception;
 } TransmogrifyOptions;
@@ -11677,6 +11681,17 @@
   MagickPassFail
     status =3D MagickPass;
=20
+  int
+    uterror;
+ =20
+  struct utimbuf
+    utbuf;
+
+  struct stat
+    statbuf;
+
+  uterror =3D 0;
+ =20
   assert(options !=3D (TransmogrifyOptions *) NULL);
   assert(options->input_filename !=3D (char *) NULL);
=20
@@ -11717,7 +11732,7 @@
         }
       if (status =3D=3D MagickFail)
         break;
-         =20
+
       /*
         Write transmogrified image to disk.
       */
@@ -11751,6 +11766,16 @@
           AppendImageFormat(options->output_format,output_filename);
           (void) strlcpy(image->magick,options->output_format,MaxTextExt=
ent);
         }
+     =20
+      if (options->preserve_file_attr)
+       {
+        if(stat(image->filename, &statbuf) !=3D 0)
+          uterror =3D -1;
+
+        utbuf.actime =3D statbuf.st_atime;
+        utbuf.modtime =3D statbuf.st_mtime;
+       }
+     =20
       if (options->create_directories)
         {
           /*
@@ -11805,7 +11830,19 @@
         Write the output file.
       */
       (void) strlcpy(image->filename,output_filename,MaxTextExtent);
+
+    =20
       status =3D WriteImages(image_info,image,image->filename,&options->=
exception);
+
+      if (options->preserve_file_attr)
+        {
+          if (uterror !=3D -1)
+            {
+              if (utime(image->filename, &utbuf) !=3D 0)
+                fprintf(stderr, "Error preserving file timestamps\n");
+	          }
+	      }
+	   =20
       if ((status !=3D MagickFail) && (temporary_filename[0] !=3D 0))
         {
           /*
@@ -11907,7 +11944,8 @@
=20
   MagickBool
     create_directories,
-    global_colormap;
+    global_colormap,
+    preserve_file_attr; =20
=20
   unsigned int
     status;
@@ -11939,6 +11977,7 @@
   output_directory[0]=3D'\0';
   create_directories=3DMagickFalse;
   global_colormap=3DMagickFalse;
+  preserve_file_attr=3DMagickFalse;
   status=3DTrue;
=20
   /*
@@ -11971,6 +12010,7 @@
         transmogrify_options.output_directory=3Doutput_directory;
         transmogrify_options.create_directories=3Dcreate_directories;
         transmogrify_options.global_colormap=3Dglobal_colormap;
+        transmogrify_options.preserve_file_attr=3Dpreserve_file_attr;
         transmogrify_options.status=3DMagickPass;
         GetExceptionInfo(&transmogrify_options.exception);
         status &=3D *TransmogrifyImage(&transmogrify_options);
@@ -13112,6 +13152,11 @@
               ThrowMogrifyException(OptionError,MissingArgument,option);=

             break;
           }
+        if (LocaleCompare("preserve", option+1) =3D=3D 0)
+          {
+            preserve_file_attr =3D MagickTrue;
+            break;
+          }
         ThrowMogrifyException(OptionError,UnrecognizedOption,option)
       }
       case 'q':
@@ -13772,6 +13817,7 @@
       "-fill color           color for annotating or changing opaque col=
or",
       "-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 e=
ffect",
       "-random-threshold channeltype LOWxHIGH",

--------------080509030700080306090809
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
--------------080509030700080306090809
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

--------------080509030700080306090809--