[gimp] file-compressor: Use compression libraries instead of programs



commit f80892bf507ad1faf102887f71923b4c3fcab6fa
Author: Mukund Sivaraman <muks banu com>
Date:   Wed Jan 11 19:29:32 2012 +0530

    file-compressor: Use compression libraries instead of programs
    
    This commit will temporarily cause the build to break, because
    file-compressor doesn't link -lz and -lbz2 after this commit. I'll fix
    it soon, but if any of you want to kill me for breaking the build, feel
    free to revert it. The commit will stay and can be used later.
    
    This change was made so that file-compressor isn't crappy on Windows. It
    also removes win32-specific code.

 configure.ac                      |   16 ++
 plug-ins/common/file-compressor.c |  539 +++++++++++++++++--------------------
 2 files changed, 262 insertions(+), 293 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 6500897..67bb8bb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1148,6 +1148,22 @@ AC_SUBST(FILE_PSP)
 AC_SUBST(Z_LIBS)
 
 
+####################
+# Check for libbzip2
+####################
+
+have_libbzip2=yes
+if test -z "$BZIP2_LIBS"; then
+  AC_CHECK_LIB(bz2, BZ2_bzCompress,
+    [AC_CHECK_HEADER(bzlib.h,
+      BZIP2_LIBS='-lbz2',
+      [have_libbzip2="no (libbzip2 header files not found)"])],
+    [have_libbzip2="no (libbzip2 library not found)"])
+fi
+
+AC_SUBST(BZIP2_LIBS)
+
+
 ##################
 # Check for libpng
 ##################
diff --git a/plug-ins/common/file-compressor.c b/plug-ins/common/file-compressor.c
index 44d5ab2..47210c8 100644
--- a/plug-ins/common/file-compressor.c
+++ b/plug-ins/common/file-compressor.c
@@ -81,16 +81,10 @@
 
 #include <libgimp/gimp.h>
 
-#ifdef G_OS_WIN32
-#define STRICT
-#define WinMain WinMain_foo
-#include <windows.h>
-#include <io.h> /* _get_osfhandle */
-#undef WinMain
-#endif
-
 #include "libgimp/stdplugins-intl.h"
 
+#include <zlib.h>
+#include <bzlib.h>
 
 /* Author 1: Josh MacDonald (url.c)          */
 /* Author 2: Daniel Risacher (gz.c)          */
@@ -101,6 +95,10 @@
  * that metric, I figure this plug-in is worth about $10,000 USD */
 /* But you got it free.   Magic of Gnu. */
 
+typedef gboolean (*LoadFn) (const char *infile,
+                            const char *outfile);
+typedef gboolean (*SaveFn) (const char *infile,
+                            const char *outfile);
 
 typedef struct _Compressor Compressor;
 
@@ -116,16 +114,12 @@ struct _Compressor
   const gchar *load_proc;
   const gchar *load_blurb;
   const gchar *load_help;
-  const gchar *load_program;
-  const gchar *load_options;
-  const gchar *load_program_win32;
+  LoadFn       load_fn;
 
   const gchar *save_proc;
   const gchar *save_blurb;
   const gchar *save_help;
-  const gchar *save_program;
-  const gchar *save_options;
-  const gchar *save_program_win32;
+  SaveFn       save_fn;
 };
 
 
@@ -151,7 +145,18 @@ static gint32              load_image     (const Compressor   *compressor,
 static gboolean            valid_file     (const gchar        *filename);
 static const gchar       * find_extension (const Compressor   *compressor,
                                            const gchar        *filename);
-
+static gboolean
+gzip_load                                 (const char         *infile,
+                                           const char         *outfile);
+static gboolean
+gzip_save                                 (const char         *infile,
+                                           const char         *outfile);
+static gboolean
+bzip2_load                                (const char         *infile,
+                                           const char         *outfile);
+static gboolean
+bzip2_save                                (const char         *infile,
+                                           const char         *outfile);
 
 static const Compressor compressors[] =
 {
@@ -166,14 +171,12 @@ static const Compressor compressors[] =
     "file-gz-load",
     "loads files compressed with gzip",
     "You need to have gzip installed.",
-    "gzip", "-cfd",
-    "minigzip -d",
+    gzip_load,
 
     "file-gz-save",
     "saves files compressed with gzip",
     "You need to have gzip installed.",
-    "gzip", "-cfn",
-    "minigzip"
+    gzip_save
   },
 
   {
@@ -187,14 +190,12 @@ static const Compressor compressors[] =
     "file-bz2-load",
     "loads files compressed with bzip2",
     "You need to have bzip2 installed.",
-    "bzip2", "-cfd",
-    "bzip2 -cfd",
+    bzip2_load,
 
     "file-bz2-save",
     "saves files compressed with bzip2",
     "You need to have bzip2 installed",
-    "bzip2", "-cf",
-    "bzip2 -cf"
+    bzip2_save
   }
 };
 
@@ -409,139 +410,13 @@ save_image (const Compressor  *compressor,
       return GIMP_PDB_EXECUTION_ERROR;
     }
 
-#ifndef G_OS_WIN32
-  {
-    FILE *f;
-    gint  pid;
-
-    f = g_fopen (filename, "wb");
-
-    if (! f)
-      {
-        g_unlink (tmpname);
-        g_free (tmpname);
-
-        g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
-                     _("Could not open '%s' for writing: %s"),
-                     gimp_filename_to_utf8 (filename), g_strerror (errno));
-
-        return GIMP_PDB_EXECUTION_ERROR;
-      }
-
-    /* fork off a compressor process */
-    if ((pid = fork ()) < 0)
-      {
-        g_message ("fork() failed: %s", g_strerror (errno));
-
-        fclose (f);
-        g_unlink (tmpname);
-        g_free (tmpname);
-
-        return GIMP_PDB_EXECUTION_ERROR;
-      }
-    else if (pid == 0)  /* child process */
-      {
-        /* make stdout for this process be the output file */
-        if (dup2 (fileno (f), fileno (stdout)) == -1)
-          g_printerr ("dup2() failed: %s", g_strerror (errno));
-
-        /* and compress into it */
-        execlp (compressor->save_program,
-                compressor->save_program,
-                compressor->save_options, tmpname, NULL);
-
-        g_printerr ("execlp(\"%s %s\") failed: %s",
-                    compressor->save_program,
-                    compressor->save_options,
-                    g_strerror (errno));
-
-        _exit(127);
-      }
-    else
-      {
-        gint wpid;
-        gint process_status;
-
-        fclose (f);
-
-        wpid = waitpid (pid, &process_status, 0);
-
-        if ((wpid < 0)
-            || !WIFEXITED (process_status)
-            || (WEXITSTATUS (process_status) != 0))
-          {
-            g_message ("%s exited abnormally on file '%s'",
-                       compressor->save_program,
-                       gimp_filename_to_utf8 (tmpname));
-
-            g_unlink (tmpname);
-            g_free (tmpname);
-
-            return GIMP_PDB_EXECUTION_ERROR;
-          }
-      }
-  }
-#else  /* G_OS_WIN32 */
-  {
-    FILE                *in;
-    FILE                *out;
-    STARTUPINFO          startupinfo;
-    PROCESS_INFORMATION  processinfo;
-
-    in  = g_fopen (tmpname, "rb");
-    out = g_fopen (filename, "wb");
-
-    if (in == NULL)
-      {
-        g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
-                     _("Could not open '%s' for reading: %s"),
-                     gimp_filename_to_utf8 (tmpname), g_strerror (errno));
-        g_free (tmpname);
-
-        return GIMP_PDB_EXECUTION_ERROR;
-      }
-
-    if (out == NULL)
-      {
-        g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
-                     _("Could not open '%s' for writing: %s"),
-                     gimp_filename_to_utf8 (filename), g_strerror (errno));
-        g_free (tmpname);
-
-        return GIMP_PDB_EXECUTION_ERROR;
-      }
-
-    startupinfo.cb          = sizeof (STARTUPINFO);
-    startupinfo.lpReserved  = NULL;
-    startupinfo.lpDesktop   = NULL;
-    startupinfo.lpTitle     = NULL;
-    startupinfo.dwFlags     = (STARTF_FORCEOFFFEEDBACK |
-                               STARTF_USESHOWWINDOW    |
-                               STARTF_USESTDHANDLES);
-    startupinfo.wShowWindow = SW_SHOWMINNOACTIVE;
-    startupinfo.cbReserved2 = 0;
-    startupinfo.lpReserved2 = NULL;
-    startupinfo.hStdInput   = (HANDLE) _get_osfhandle (fileno (in));
-    startupinfo.hStdOutput  = (HANDLE) _get_osfhandle (fileno (out));
-    startupinfo.hStdError   = GetStdHandle (STD_ERROR_HANDLE);
-
-    if (! CreateProcess (NULL, compressor->save_program_win32, NULL, NULL,
-                         TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL,
-                         &startupinfo, &processinfo))
-      {
-        g_message ("CreateProcess failed: %d", GetLastError ());
-        g_free (tmpname);
-
-        return GIMP_PDB_EXECUTION_ERROR;
-      }
-
-    CloseHandle (processinfo.hThread);
-    WaitForSingleObject (processinfo.hProcess, INFINITE);
+  if (!compressor->save_fn (tmpname, filename))
+    {
+      g_unlink (tmpname);
+      g_free (tmpname);
 
-    fclose (in);
-    fclose (out);
-  }
-#endif /* G_OS_WIN32 */
+      return GIMP_PDB_EXECUTION_ERROR;
+    }
 
   g_unlink (tmpname);
   g_free (tmpname);
@@ -576,144 +451,12 @@ load_image (const Compressor   *compressor,
   /* find a temp name */
   tmpname = gimp_temp_name (ext + 1);
 
-#ifndef G_OS_WIN32
-  {
-    FILE *f;
-    gint  pid;
-
-    f = g_fopen (tmpname, "wb");
-
-    if (! f)
-      {
-        g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
-                     _("Could not open '%s' for writing: %s"),
-                     gimp_filename_to_utf8 (tmpname), g_strerror (errno));
-        g_free (tmpname);
-
-        *status = GIMP_PDB_EXECUTION_ERROR;
-        return -1;
-      }
-
-    /* fork off a compressor and wait for it */
-    if ((pid = fork ()) < 0)
-      {
-        g_message ("fork() failed: %s", g_strerror (errno));
-
-        g_unlink (tmpname);
-        g_free (tmpname);
-        fclose (f);
-
-        *status = GIMP_PDB_EXECUTION_ERROR;
-        return -1;
-      }
-    else if (pid == 0)  /* child process */
-      {
-        /* make stdout for this child process be the temp file */
-        if (dup2 (fileno (f), fileno (stdout)) == -1)
-          g_printerr ("dup2() failed: %s", g_strerror (errno));
-
-        /* and uncompress into it */
-        execlp (compressor->load_program,
-                compressor->load_program,
-                compressor->load_options, filename, NULL);
-
-        g_printerr ("execlp(\"%s %s\") failed: %s",
-                    compressor->load_program,
-                    compressor->load_options,
-                    g_strerror (errno));
-
-        _exit(127);
-      }
-    else  /* parent process */
-      {
-        gint wpid;
-        gint process_status;
-
-        fclose (f);
-
-        wpid = waitpid (pid, &process_status, 0);
-
-        if ((wpid < 0)
-            || !WIFEXITED (process_status)
-            || (WEXITSTATUS (process_status) != 0))
-          {
-            g_message ("%s exited abnormally on file '%s'",
-                       compressor->load_program,
-                       gimp_filename_to_utf8 (filename));
-
-            g_unlink (tmpname);
-            g_free (tmpname);
-
-            *status = GIMP_PDB_EXECUTION_ERROR;
-            return -1;
-          }
-      }
-  }
-#else
-  {
-    FILE                *in;
-    FILE                *out;
-    SECURITY_ATTRIBUTES  secattr;
-    STARTUPINFO          startupinfo;
-    PROCESS_INFORMATION  processinfo;
-
-    in  = g_fopen (filename, "rb");
-    out = g_fopen (tmpname, "wb");
-
-    if (in == NULL)
-      {
-        g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
-                     _("Could not open '%s' for reading: %s"),
-                     gimp_filename_to_utf8 (filename), g_strerror (errno));
-        g_free (tmpname);
-
-        *status = GIMP_PDB_EXECUTION_ERROR;
-        return -1;
-      }
-
-    if (out == NULL)
-      {
-        g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
-                     _("Could not open '%s' for writing: %s"),
-                     gimp_filename_to_utf8 (tmpname), g_strerror (errno));
-        g_free (tmpname);
-
-        *status = GIMP_PDB_EXECUTION_ERROR;
-        return -1;
-      }
-
-    startupinfo.cb          = sizeof (STARTUPINFO);
-    startupinfo.lpReserved  = NULL;
-    startupinfo.lpDesktop   = NULL;
-    startupinfo.lpTitle     = NULL;
-    startupinfo.dwFlags     = (STARTF_FORCEOFFFEEDBACK |
-                               STARTF_USESHOWWINDOW    |
-                               STARTF_USESTDHANDLES);
-    startupinfo.wShowWindow = SW_SHOWMINNOACTIVE;
-    startupinfo.cbReserved2 = 0;
-    startupinfo.lpReserved2 = NULL;
-    startupinfo.hStdInput   = (HANDLE) _get_osfhandle (fileno (in));
-    startupinfo.hStdOutput  = (HANDLE) _get_osfhandle (fileno (out));
-    startupinfo.hStdError   = GetStdHandle (STD_ERROR_HANDLE);
-
-    if (! CreateProcess (NULL, compressor->load_program_win32, NULL, NULL,
-                         TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL,
-                         &startupinfo, &processinfo))
-      {
-        g_message ("CreateProcess failed: %d", GetLastError ());
-        g_free (tmpname);
-
-        *status = GIMP_PDB_EXECUTION_ERROR;
-        return -1;
-      }
-
-    CloseHandle (processinfo.hThread);
-    WaitForSingleObject (processinfo.hProcess, INFINITE);
-
-    fclose (in);
-    fclose (out);
-  }
-#endif /* G_OS_WIN32 */
+  if (!compressor->load_fn (filename, tmpname))
+    {
+      g_free (tmpname);
+      *status = GIMP_PDB_EXECUTION_ERROR;
+      return -1;
+    }
 
   /* now that we uncompressed it, load the temp file */
 
@@ -783,3 +526,213 @@ find_extension (const Compressor *compressor,
         }
     }
 }
+
+static gboolean
+gzip_load (const char *infile,
+           const char *outfile)
+{
+  gboolean ret;
+  gzFile in;
+  FILE *out;
+  char buf[16384];
+  int len;
+
+  ret = FALSE;
+  in = NULL;
+  out = NULL;
+
+  do
+    {
+      in = gzopen (infile, "rb");
+      if (!in)
+        break;
+
+      out = fopen (outfile, "wb");
+      if (!out)
+        break;
+
+      while (TRUE)
+        {
+          len = gzread (in, buf, sizeof buf);
+
+          if (len < 0)
+            break;
+          else if (len == 0)
+            {
+              ret = TRUE;
+              break;
+            }
+
+          if (fwrite(buf, 1, len, out) != len)
+            break;
+        }
+    }
+  while (0);
+
+  if (in)
+    if (gzclose (in) != Z_OK)
+      ret = FALSE;
+
+  if (out)
+    fclose (out);
+
+  return ret;
+}
+
+static gboolean
+gzip_save (const char *infile,
+           const char *outfile)
+{
+  gboolean ret;
+  FILE *in;
+  gzFile out;
+  char buf[16384];
+  int len;
+
+  ret = FALSE;
+  in = NULL;
+  out = NULL;
+
+  do
+    {
+      in = fopen (infile, "rb");
+      if (!in)
+        break;
+
+      out = gzopen (outfile, "wb");
+      if (!out)
+        break;
+
+      while (TRUE)
+        {
+          len = fread (buf, 1, sizeof buf, in);
+          if (ferror (in))
+            break;
+
+          if (len < 0)
+            break;
+          else if (len == 0)
+            {
+              ret = TRUE;
+              break;
+            }
+
+          if (gzwrite (out, buf, len) != len)
+            break;
+        }
+    }
+  while (0);
+
+  if (in)
+    fclose (in);
+
+  if (out)
+    if (gzclose (out) != Z_OK)
+      ret = FALSE;
+
+  return ret;
+}
+
+static gboolean
+bzip2_load (const char *infile,
+            const char *outfile)
+{
+  gboolean ret;
+  BZFILE *in;
+  FILE *out;
+  char buf[16384];
+  int len;
+
+  ret = FALSE;
+  in = NULL;
+  out = NULL;
+
+  do
+    {
+      in = BZ2_bzopen (infile, "rb");
+      if (!in)
+        break;
+
+      out = fopen (outfile, "wb");
+      if (!out)
+        break;
+
+      while (TRUE)
+        {
+          len = BZ2_bzread (in, buf, sizeof buf);
+
+          if (len < 0)
+            break;
+          else if (len == 0)
+            {
+              ret = TRUE;
+              break;
+            }
+
+          if (fwrite(buf, 1, len, out) != len)
+            break;
+        }
+    }
+  while (0);
+
+  if (in)
+    BZ2_bzclose (in);
+
+  if (out)
+    fclose (out);
+
+  return ret;
+}
+
+static gboolean
+bzip2_save (const char *infile,
+            const char *outfile)
+{
+  gboolean ret;
+  FILE *in;
+  BZFILE *out;
+  char buf[16384];
+  int len;
+
+  ret = FALSE;
+  in = NULL;
+  out = NULL;
+
+  do
+    {
+      in = fopen (infile, "rb");
+      if (!in)
+        break;
+
+      out = BZ2_bzopen (outfile, "wb");
+      if (!out)
+        break;
+
+      while (TRUE)
+        {
+          len = fread (buf, 1, sizeof buf, in);
+          if (ferror (in))
+            break;
+
+          if (len < 0)
+            break;
+          else if (len == 0)
+            {
+              ret = TRUE;
+              break;
+            }
+
+          if (BZ2_bzwrite (out, buf, len) != len)
+            break;
+        }
+    }
+  while (0);
+
+  if (in)
+    fclose (in);
+
+  if (out)
+    BZ2_bzclose (out);
+
+  return ret;
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]