diff -uNr gimp-2.8.16.original/plug-ins/common/Makefile.in gimp-2.8.16/plug-ins/common/Makefile.in
--- gimp-2.8.16.original/plug-ins/common/Makefile.in	2015-11-21 05:42:19.000000000 +0900
+++ gimp-2.8.16/plug-ins/common/Makefile.in	2016-04-28 18:49:14.055476720 +0900
@@ -109,7 +109,7 @@
 	despeckle$(EXEEXT) destripe$(EXEEXT) diffraction$(EXEEXT) \
 	displace$(EXEEXT) edge$(EXEEXT) edge-dog$(EXEEXT) \
 	edge-laplace$(EXEEXT) edge-neon$(EXEEXT) edge-sobel$(EXEEXT) \
-	emboss$(EXEEXT) engrave$(EXEEXT) $(FILE_AA) file-cel$(EXEEXT) \
+	emboss$(EXEEXT) engrave$(EXEEXT) $(FILE_AA) file-cel$(EXEEXT) file-cmyk-save$(EXEEXT) \
 	file-csource$(EXEEXT) file-desktop-link$(EXEEXT) \
 	file-dicom$(EXEEXT) file-gbr$(EXEEXT) file-gif-load$(EXEEXT) \
 	file-gif-save$(EXEEXT) file-gih$(EXEEXT) file-glob$(EXEEXT) \
@@ -516,6 +516,13 @@
 	$(libgimpconfig) $(libgimpcolor) $(libgimpbase) \
 	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_1) $(file_cel_RC)
+am_file_cmyk-save_OBJECTS = file-cmyk-save.$(OBJEXT)
+file_cmyk-save_OBJECTS = $(am_file_cmyk-save_OBJECTS)
+file_cmyk-save_DEPENDENCIES = $(libgimpui) $(libgimpwidgets) \
+	$(libgimpmodule) $(libgimp) $(am__DEPENDENCIES_2) \
+	$(libgimpconfig) $(libgimpcolor) $(libgimpbase) \
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1) $(file_cmyk-save_RC)
 am_file_csource_OBJECTS = file-csource.$(OBJEXT)
 file_csource_OBJECTS = $(am_file_csource_OBJECTS)
 file_csource_DEPENDENCIES = $(libgimpui) $(libgimpwidgets) \
@@ -1249,7 +1256,7 @@
 	$(diffraction_SOURCES) $(displace_SOURCES) $(edge_SOURCES) \
 	$(edge_dog_SOURCES) $(edge_laplace_SOURCES) \
 	$(edge_neon_SOURCES) $(edge_sobel_SOURCES) $(emboss_SOURCES) \
-	$(engrave_SOURCES) $(file_aa_SOURCES) $(file_cel_SOURCES) \
+	$(engrave_SOURCES) $(file_aa_SOURCES) $(file_cel_SOURCES) $(file_cmyk-save_SOURCES) \
 	$(file_csource_SOURCES) $(file_desktop_link_SOURCES) \
 	$(file_dicom_SOURCES) $(file_gbr_SOURCES) \
 	$(file_gif_load_SOURCES) $(file_gif_save_SOURCES) \
@@ -1311,7 +1318,7 @@
 	$(diffraction_SOURCES) $(displace_SOURCES) $(edge_SOURCES) \
 	$(edge_dog_SOURCES) $(edge_laplace_SOURCES) \
 	$(edge_neon_SOURCES) $(edge_sobel_SOURCES) $(emboss_SOURCES) \
-	$(engrave_SOURCES) $(file_aa_SOURCES) $(file_cel_SOURCES) \
+	$(engrave_SOURCES) $(file_aa_SOURCES) $(file_cel_SOURCES) $(file_cmyk-save_SOURCES) \
 	$(file_csource_SOURCES) $(file_desktop_link_SOURCES) \
 	$(file_dicom_SOURCES) $(file_gbr_SOURCES) \
 	$(file_gif_load_SOURCES) $(file_gif_save_SOURCES) \
@@ -1769,6 +1776,7 @@
 @HAVE_WINDRES_TRUE@engrave_RC = engrave.rc.o
 @HAVE_WINDRES_TRUE@file_aa_RC = file-aa.rc.o
 @HAVE_WINDRES_TRUE@file_cel_RC = file-cel.rc.o
+@HAVE_WINDRES_TRUE@file_cmyk-save_RC = file-cmyk-save.rc.o
 @HAVE_WINDRES_TRUE@file_compressor_RC = file-compressor.rc.o
 @HAVE_WINDRES_TRUE@file_csource_RC = file-csource.rc.o
 @HAVE_WINDRES_TRUE@file_desktop_link_RC = file-desktop-link.rc.o
@@ -2702,6 +2710,26 @@
 	$(INTLLIBS)		\
 	$(file_cel_RC)
 
+file_cmyk-save_SOURCES = \
+	file-cmyk-save.c
+
+file_cmyk-save_LDADD = \
+	$(libgimpui)		\
+	$(libgimpwidgets)	\
+	$(libgimpmodule)	\
+	$(libgimp)		\
+	$(libgimpmath)		\
+	$(libgimpconfig)	\
+	$(libgimpcolor)		\
+	$(libgimpbase)		\
+	$(GTK_LIBS)		\
+	$(RT_LIBS)		\
+	$(INTLLIBS)		\
+	$(JPEG_LIBS)	\
+	$(TIFF_LIBS)	\
+	$(LCMS1_LIBS)	\
+	$(file_cmyk-save_RC)
+
 file_csource_SOURCES = \
 	file-csource.c
 
@@ -4620,6 +4648,10 @@
 	@rm -f file-cel$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(file_cel_OBJECTS) $(file_cel_LDADD) $(LIBS)
 
+file-cmyk-save$(EXEEXT): $(file_cmyk-save_OBJECTS) $(file_cmyk-save_DEPENDENCIES) $(EXTRA_file_cmyk-save_DEPENDENCIES) 
+	@rm -f file-cmyk-save$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(file_cmyk-save_OBJECTS) $(file_cmyk-save_LDADD) $(LIBS)
+
 file-csource$(EXEEXT): $(file_csource_OBJECTS) $(file_csource_DEPENDENCIES) $(EXTRA_file_csource_DEPENDENCIES) 
 	@rm -f file-csource$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(file_csource_OBJECTS) $(file_csource_LDADD) $(LIBS)
@@ -5059,6 +5091,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/engrave.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file-aa.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file-cel.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file-cmyk-save.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file-csource.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file-desktop-link.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file-gbr.Po@am__quote@
diff -uNr gimp-2.8.16.original/plug-ins/common/file-cmyk-save.c gimp-2.8.16/plug-ins/common/file-cmyk-save.c
--- gimp-2.8.16.original/plug-ins/common/file-cmyk-save.c	1970-01-01 09:00:00.000000000 +0900
+++ gimp-2.8.16/plug-ins/common/file-cmyk-save.c	2016-04-28 18:49:14.055476720 +0900
@@ -0,0 +1,875 @@
+/* separate- : CMYK file export plug-in
+ *
+ * by Yoshinori Yamakawa
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Modified by Hiroshi Harada
+ */
+
+#include "config.h"
+
+#include <glib/gstdio.h>
+
+#include "libgimp/gimp.h"
+#include "libgimp/gimpui.h"
+
+#include <lcms.h>
+#include <tiffio.h>
+#include <jpeglib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <setjmp.h>
+
+#include "libgimp/stdplugins-intl.h"
+
+#define TIFF_SAVE_PROC "file-cmyk-tiff-save"
+#define JPEG_SAVE_PROC "file-cmyk-jpeg-save"
+#define PLUG_IN_BINARY "file-cmyk-save"
+
+typedef enum _SeparateFileType
+{
+  FILE_TYPE_TIFF = 0,
+  FILE_TYPE_JPEG = 1
+} SeparateFileType;
+
+const gchar *SeparateFileTypeDescription[] =
+{
+  N_("TIFF (CMYK)"),
+  N_("JPEG (CMYK)")
+};
+
+typedef struct _SeparateSettings
+{
+  gint32            compression;
+  gboolean          embed_profile;
+} SeparateSettings;
+
+typedef struct _SeparateContext
+{
+  const gchar      *proc_name;
+
+  gint32            image_id;
+  gint32            drawable_id;
+  GimpDrawable     *drawable;
+  gint32            width;
+  gint32            height;
+
+  cmsHPROFILE       source;
+  cmsHPROFILE       destination;
+  GimpColorRenderingIntent intent;
+  gchar            *source_profile_data;
+  gsize             source_profile_length;
+  gchar            *destination_profile_data;
+  gsize             destination_profile_length;
+
+  gchar            *filename;
+
+  GString          *message;
+
+  SeparateFileType  filetype;
+  SeparateSettings  settings;
+  gint              compression_type;
+} SeparateContext;
+
+static void      query                   (void);
+static void      run                     (const gchar      *name,
+                                          gint              nparams,
+                                          const GimpParam  *param,
+                                          gint             *nreturn_vals,
+                                          GimpParam       **return_vals);
+static gboolean  export_dialog           (SeparateContext  *context);
+static gboolean  export_tiff             (SeparateContext  *context);
+static gboolean  write_tiff_data         (TIFF             *out,
+                                          SeparateContext  *context,
+                                          gint32            width,
+                                          gint32            height);
+static gboolean  export_jpeg             (SeparateContext  *context);
+static void      write_jpeg_profile_data (j_compress_ptr    cinfo,
+                                          const gchar      *profile_data,
+                                          gsize             profile_length);
+static gboolean  write_jpeg_data         (j_compress_ptr    cinfo,
+                                          SeparateContext  *context);
+
+const GimpPlugInInfo PLUG_IN_INFO =
+{
+  NULL,   /* init_proc  */
+  NULL,   /* quit_proc  */
+  query,  /* query_proc */
+  run,    /* run_proc   */
+};
+
+MAIN()
+
+static void
+query (void)
+{
+  static const GimpParamDef tiff_save_args[] =
+  {
+    { GIMP_PDB_INT32,    "run-mode",      "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },
+    { GIMP_PDB_IMAGE,    "image",         "Input image" },
+    { GIMP_PDB_DRAWABLE, "drawable",      "Drawable to save" },
+    { GIMP_PDB_STRING,   "filename",      "The name of the file to save the image in" },
+    { GIMP_PDB_STRING,   "raw-filename",  "The name of the file to save the image in" },
+    { GIMP_PDB_INT32,    "embed-profile", "Embed color profile" },
+    { GIMP_PDB_INT32,    "compression",   "Compression type: { NONE (0), LZW (1), PACKBITS (2), DEFLATE (3) }" }
+  };
+
+  static const GimpParamDef jpeg_save_args[] =
+  {
+    { GIMP_PDB_INT32,    "run-mode",      "The run mode { RUN-INTERACTIVE (0), RUN-NONINTERACTIVE (1) }" },
+    { GIMP_PDB_IMAGE,    "image",         "Input image" },
+    { GIMP_PDB_DRAWABLE, "drawable",      "Drawable to save" },
+    { GIMP_PDB_STRING,   "filename",      "The name of the file to save the image in" },
+    { GIMP_PDB_STRING,   "raw-filename",  "The name of the file to save the image in" },
+    { GIMP_PDB_INT32,    "embed-profile", "Embed color profile" },
+    { GIMP_PDB_INT32,    "quality",       "Compression quality" }
+  };
+
+  gimp_install_procedure (TIFF_SAVE_PROC,
+                          "exports color separation in the TIFF file format",
+                          "Converts image from RGB to CMYK and\n"
+                          "exports in the TIFF file format.",
+                          "Yoshinori Yamakawa",
+                          "Yoshinori Yamakawa",
+                          "2011",
+                          N_("TIFF image (CMYK)"),
+                          "RGB",
+                          GIMP_PLUGIN,
+                          G_N_ELEMENTS (tiff_save_args), 0,
+                          tiff_save_args, NULL);
+
+  gimp_register_file_handler_mime (TIFF_SAVE_PROC, "image/tiff");
+  gimp_register_save_handler (TIFF_SAVE_PROC, "tif,tiff", "");
+
+  gimp_install_procedure (JPEG_SAVE_PROC,
+                          "exports color separation in the JPEG file format",
+                          "Converts image from RGB to CMYK and\n"
+                          "exports in the JPEG file format.",
+                          "Yoshinori Yamakawa",
+                          "Yoshinori Yamakawa",
+                          "2011",
+                          N_("JPEG image (CMYK)"),
+                          "RGB",
+                          GIMP_PLUGIN,
+                          G_N_ELEMENTS (jpeg_save_args), 0,
+                          jpeg_save_args, NULL);
+
+  gimp_register_file_handler_mime (JPEG_SAVE_PROC, "image/jpeg");
+  gimp_register_save_handler (JPEG_SAVE_PROC, "jpg,jpeg,jpe", "");
+}
+
+static void
+run (const gchar      *name,
+     gint              nparams,
+     const GimpParam  *param,
+     gint             *nreturn_vals,
+     GimpParam       **return_vals)
+{
+  static GimpParam   values[2];
+  GimpRunMode        run_mode;
+  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
+  SeparateContext    context;
+  GimpExportReturn   export = GIMP_EXPORT_CANCEL;
+  GimpColorConfig   *config;
+
+  INIT_I18N ();
+
+#ifdef DEBUG
+  cmsErrorAction (LCMS_ERROR_SHOW);
+#else
+  cmsErrorAction (LCMS_ERROR_IGNORE);
+#endif
+
+  run_mode = param[0].data.d_int32;
+
+  memset (&context, 0, sizeof (context));
+  context.proc_name   = name;
+  context.image_id    = param[1].data.d_int32;
+  context.drawable_id = param[2].data.d_int32;
+  context.drawable    = gimp_drawable_get (context.drawable_id);
+  context.width       = gimp_image_width (context.image_id);
+  context.height      = gimp_image_height (context.image_id);
+  context.filename    = param[3].data.d_string;
+
+  context.message = g_string_new ("");
+
+  if (strcmp (name, TIFF_SAVE_PROC) == 0)
+    {
+      context.filetype = FILE_TYPE_TIFF;
+    }
+  else if (strcmp (name, JPEG_SAVE_PROC) == 0)
+    {
+      context.filetype = FILE_TYPE_JPEG;
+      context.settings.compression = 95; /* default quality value */
+    }
+  else
+    {
+      g_string_printf (context.message, _("Invalid procedure name : %s"), name);
+      status = GIMP_PDB_CALLING_ERROR;
+    }  
+
+  /* Load the Color Management Preferences and ICC Profiles */
+  if ((config = gimp_get_color_configuration()))
+    {
+      GimpColorManagementMode mode;
+      gchar *rgb_filename, *cmyk_filename, *printer_filename;
+      GimpParasite *parasite;
+
+      g_object_get (config,
+                    "mode", &mode,
+                    "rgb-profile", &rgb_filename,
+                    "cmyk-profile", &cmyk_filename,
+                    "printer-profile", &printer_filename,
+                    "simulation-rendering-intent", &context.intent,
+                    NULL);
+
+       /* load source color profile */
+      if ((parasite = gimp_image_parasite_find (context.image_id, "icc-profile")))
+        {
+          context.source_profile_length = gimp_parasite_data_size (parasite);
+          context.source_profile_data = g_memdup (gimp_parasite_data (parasite),
+                                                  context.source_profile_length);
+
+          if ((context.source = cmsOpenProfileFromMem (context.source_profile_data,
+                                                       context.source_profile_length)) &&
+              cmsGetColorSpace (context.source) != icSigRgbData)
+            {
+              cmsCloseProfile (context.source);
+              context.source = NULL;
+              g_free (context.source_profile_data);
+              context.source_profile_data = NULL;
+              context.source_profile_length = 0;
+            }
+        }
+
+      if (! context.source && rgb_filename)
+        {
+          if ((context.source = cmsOpenProfileFromFile (rgb_filename, "r")) &&
+              cmsGetColorSpace (context.source) != icSigRgbData)
+            {
+              cmsCloseProfile (context.source);
+              context.source = NULL;
+            }
+        }
+
+      if (! context.source)
+        context.source = cmsCreate_sRGBProfile ();
+
+       /* load destination color profile */
+      if (mode == GIMP_COLOR_MANAGEMENT_SOFTPROOF && printer_filename)
+        {
+          if ((context.destination = cmsOpenProfileFromFile (printer_filename, "r")))
+            {
+              if (cmsGetColorSpace (context.destination) != icSigCmykData)
+                {
+                  cmsCloseProfile (context.destination);
+                  context.destination = NULL;
+                }
+              else
+                {
+                  g_file_get_contents (printer_filename,
+                                       &context.destination_profile_data,
+                                       &context.destination_profile_length,
+                                       NULL);
+                }
+            }
+        }
+
+      if (context.destination == NULL && cmyk_filename != NULL)
+        {
+          if ((context.destination = cmsOpenProfileFromFile (cmyk_filename, "r")))
+            {
+              if (cmsGetColorSpace (context.destination) != icSigCmykData)
+                {
+                  cmsCloseProfile (context.destination);
+                  context.destination = NULL;
+                }
+              else
+                {
+                  g_file_get_contents (cmyk_filename,
+                                       &context.destination_profile_data,
+                                       &context.destination_profile_length,
+                                       NULL);
+                }
+            }
+        }
+
+      if (! context.destination)
+        {
+          g_string_printf (context.message,
+                           _("Destination profile cannot be loaded or is not CMYK profile.\n"
+                             "Please check the color management preferences."));
+          status = GIMP_PDB_CALLING_ERROR;
+        }
+
+      g_object_unref (G_OBJECT (config));
+    }
+  else
+    {
+      g_string_printf (context.message, _("Cannot access the color management preferences."));
+      status = GIMP_PDB_CALLING_ERROR;
+    }
+
+  if (status != GIMP_PDB_SUCCESS)
+    {
+      goto cleanup;
+    }
+
+  if (run_mode == GIMP_RUN_INTERACTIVE ||
+      run_mode == GIMP_RUN_WITH_LAST_VALS)
+    {
+      gimp_get_data (context.proc_name, &context.settings);
+
+      gimp_ui_init (PLUG_IN_BINARY, FALSE);
+
+      export = gimp_export_image (&context.image_id,
+                                  &context.drawable_id,
+                                  NULL,
+                                  GIMP_EXPORT_CAN_HANDLE_RGB);
+
+      if (export == GIMP_EXPORT_CANCEL)
+        {
+          status = GIMP_PDB_CANCEL;
+        }
+      else if (run_mode == GIMP_RUN_INTERACTIVE && ! export_dialog (&context))
+        {
+          status = GIMP_PDB_CANCEL;
+        }
+    }
+  else if (nparams == 7)
+    {
+      context.settings.embed_profile = param[5].data.d_int32;
+      context.settings.compression = param[6].data.d_int32;
+    }
+  else
+    {
+      status = GIMP_PDB_CALLING_ERROR;
+    }
+
+  /* check parameter values */
+  switch (context.filetype)
+    {
+    case FILE_TYPE_TIFF:
+      switch (context.settings.compression)
+        {
+        case 0:
+          context.compression_type = COMPRESSION_NONE;
+          break;
+        case 1:
+          context.compression_type = COMPRESSION_LZW;
+          break;
+        case 2:
+          context.compression_type = COMPRESSION_PACKBITS;
+          break;
+        case 3:
+          context.compression_type = COMPRESSION_DEFLATE;
+          break;
+        default:
+          status = GIMP_PDB_CALLING_ERROR;
+        }
+      break;
+    case FILE_TYPE_JPEG:
+      if (context.settings.compression < 0 || context.settings.compression > 100)
+        {
+          status = GIMP_PDB_CALLING_ERROR;
+        }
+      break;
+    default:
+      break;
+    }
+
+  /* export */
+  if (status == GIMP_PDB_SUCCESS)
+    {
+      if ((context.filetype == FILE_TYPE_TIFF && export_tiff (&context)) ||
+          (context.filetype == FILE_TYPE_JPEG && export_jpeg (&context)))
+        {
+          if (run_mode == GIMP_RUN_INTERACTIVE)
+            {
+              gimp_set_data (context.proc_name, &context.settings, sizeof (context.settings));
+            }
+        }
+      else
+        {
+          status = GIMP_PDB_EXECUTION_ERROR;
+        }
+    }
+
+  if (export == GIMP_EXPORT_EXPORT)
+    gimp_image_delete (context.image_id);
+
+cleanup:
+  if (context.source)
+    {
+      cmsCloseProfile (context.source);
+    }
+  if (context.destination)
+    {
+      cmsCloseProfile (context.destination);
+    }
+
+  g_free (context.source_profile_data);
+  g_free (context.destination_profile_data);
+
+  *nreturn_vals = 1;
+  *return_vals = values;
+  values[0].type = GIMP_PDB_STATUS;
+  values[0].data.d_status = status;
+
+  if (context.message->len)
+    {
+      *nreturn_vals = 2;
+      values[1].type = GIMP_PDB_STRING;
+      values[1].data.d_string = context.message->str;
+      g_string_free (context.message, FALSE);
+    }
+  else
+    {
+      g_string_free (context.message, TRUE);
+    }
+}
+
+static gboolean
+export_dialog (SeparateContext  *context)
+{
+  GtkWidget *dialog;
+  GtkWidget *vbox;
+  GtkWidget *label;
+  GtkObject *quality = NULL;
+  GtkWidget *compression = NULL;
+  GtkWidget *embed_profile;
+
+  gchar *markup, *source_desc, *intent_desc;
+
+  gboolean run;
+
+  dialog = gimp_export_dialog_new (_(SeparateFileTypeDescription[context->filetype]),
+                                   PLUG_IN_BINARY, context->proc_name);
+
+  vbox = gtk_vbox_new (FALSE, 12);
+  gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
+  gtk_box_pack_start (GTK_BOX (gimp_export_dialog_get_content_area (dialog)),
+                      vbox, FALSE, TRUE, 0);
+
+  switch (context->intent)
+    {
+    case GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL:
+      intent_desc = N_("Perceptual");
+      break;
+    case GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC:
+      intent_desc = N_("Relative colorimetric with BPC");
+      break;
+    case GIMP_COLOR_RENDERING_INTENT_SATURATION:
+      intent_desc = N_("Saturation");
+      break;
+    case GIMP_COLOR_RENDERING_INTENT_ABSOLUTE_COLORIMETRIC:
+      intent_desc = N_("Absolute colorimetric");
+      break;
+    default:
+      intent_desc = N_("Unknown");
+    }
+
+  source_desc = g_strdup (cmsTakeProductDesc (context->source));
+
+  markup = g_strdup_printf (_("<b>Convert from:</b>\n  %s\n<b>to:</b>\n  %s\n\n"
+                              "<b>Rendering Intent:</b>\n %s"),
+                            source_desc,
+                            cmsTakeProductDesc (context->destination),
+                            _(intent_desc));
+
+  label = gtk_label_new (NULL);
+  gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
+  gtk_label_set_markup (GTK_LABEL (label), markup);
+  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+  g_free (source_desc);
+  g_free (markup);
+
+  if (context->filetype == FILE_TYPE_JPEG)
+    {
+      GtkWidget *table = gtk_table_new (1, 3, FALSE);
+      gtk_table_set_col_spacings (GTK_TABLE (table), 6);
+      gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+
+      quality = gimp_scale_entry_new (GTK_TABLE (table), 0, 0,
+                                      _("_Quality:"),
+                                      0, 0,
+                                      context->settings.compression,
+                                      0.0, 100.0, 1.0, 10.0, 0,
+                                      TRUE, 0.0, 0.0,
+                                      _("JPEG quality parameter"),
+                                      "file-jpeg-save-quality");
+    }
+  else
+    {
+      compression = gtk_check_button_new_with_mnemonic
+        (context->filetype == FILE_TYPE_TIFF ? _("_LZW compression") : _("_Packbits compression"));
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (compression), context->settings.compression > 0);
+      gtk_box_pack_start (GTK_BOX (vbox), compression, FALSE, FALSE, 0);
+    }
+
+  embed_profile = gtk_check_button_new_with_mnemonic (_("_Embed color profile"));
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (embed_profile), context->settings.embed_profile);
+  gtk_box_pack_start (GTK_BOX (vbox), embed_profile, FALSE, FALSE, 0);
+
+  gtk_widget_show_all (vbox);
+  gtk_widget_show (dialog);
+
+  if ((run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK)))
+    {
+      context->settings.compression = context->filetype == FILE_TYPE_JPEG ?
+        gtk_range_get_value (GTK_RANGE (GIMP_SCALE_ENTRY_SCALE (quality))) :
+        (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (compression)) ? 1 : 0);
+      context->settings.embed_profile = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (embed_profile));
+    }
+
+  gtk_widget_destroy (dialog);
+
+  return run;
+}
+
+/***** TIFF export functions *****/
+
+#define STRIPHEIGHT 64
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+static gboolean
+export_tiff (SeparateContext  *context)
+{
+  gint32 width, height;
+  gdouble xres, yres;
+  int fd;
+  TIFF *out;
+
+  gunichar2 *utf16_filename = g_utf8_to_utf16 (context->filename, -1, NULL, NULL, NULL);
+
+  out = TIFFOpenW (utf16_filename, "w");
+
+  gimp_image_get_resolution (context->image_id, &xres, &yres);
+  width = gimp_image_width (context->image_id);
+  height = gimp_image_height (context->image_id);
+
+  TIFFSetField (out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_SEPARATED);
+  TIFFSetField (out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+  TIFFSetField (out, TIFFTAG_INKSET, INKSET_CMYK);
+  TIFFSetField (out, TIFFTAG_BITSPERSAMPLE, 8);
+
+  TIFFSetField (out, TIFFTAG_SAMPLESPERPIXEL, 4);
+
+  TIFFSetField (out, TIFFTAG_IMAGEWIDTH, width);
+  TIFFSetField (out, TIFFTAG_IMAGELENGTH, height);
+  TIFFSetField (out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
+  TIFFSetField (out, TIFFTAG_XRESOLUTION, xres);
+  TIFFSetField (out, TIFFTAG_YRESOLUTION, yres);
+  TIFFSetField (out, TIFFTAG_ROWSPERSTRIP, STRIPHEIGHT);
+  TIFFSetField (out, TIFFTAG_COMPRESSION, context->compression_type);
+
+  if (context->settings.embed_profile && context->destination_profile_data)
+    {
+      TIFFSetField (out, TIFFTAG_ICCPROFILE,
+                    context->destination_profile_length,
+                    context->destination_profile_data);
+    }
+
+  write_tiff_data (out, context, width, height);
+
+  TIFFWriteDirectory (out);
+  TIFFClose (out);
+
+  return TRUE;
+}
+
+
+static gboolean
+write_tiff_data (TIFF    *out,
+                 SeparateContext *context,
+                 gint32  width,
+                 gint32  height)
+{
+  gint32 BufSizeOut = TIFFStripSize (out);
+  guchar *src, *BufferOut;
+  gint32 i;
+  gint StripCount = (height + (STRIPHEIGHT - 1)) / STRIPHEIGHT;
+  GimpPixelRgn region;
+  cmsHTRANSFORM transform;
+  GimpDrawable *drawable = gimp_drawable_get (context->drawable_id);
+
+  transform =
+    cmsCreateTransform (context->source, TYPE_RGB_8,
+                        context->destination, TYPE_CMYK_8,
+                        context->intent,
+                        context->intent == GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC ?
+                                           cmsFLAGS_BLACKPOINTCOMPENSATION : 0);
+
+  if (! transform)
+    {
+      g_string_printf (context->message, _("Cannot setup color separation."));
+      return FALSE;
+    }
+
+  if (! (BufferOut = (guchar *)_TIFFmalloc (BufSizeOut)) ||
+      ! (src = g_try_malloc (width * STRIPHEIGHT * 3)))
+    {
+      g_string_printf (context->message, _("Cannot allocate working memory."));
+
+      cmsDeleteTransform (transform);
+
+      return FALSE;
+    }
+
+  gimp_pixel_rgn_init (&region, drawable, 0, 0, width, height, FALSE, FALSE);
+
+  gimp_progress_init (_("Exporting TIFF..."));
+
+  for (i = 0; i < StripCount; i++)
+    {
+      gint32 top, buffer_height;
+
+      gimp_progress_update (((double)i) / ((double)StripCount));
+
+      top = i * STRIPHEIGHT;
+      buffer_height = (top + STRIPHEIGHT > height) ? height - top : STRIPHEIGHT;
+      gimp_pixel_rgn_get_rect (&region, src, 0, top, width, buffer_height);
+
+      cmsDoTransform (transform, src, BufferOut, width * buffer_height);
+
+      TIFFWriteEncodedStrip (out, i, BufferOut, BufSizeOut);
+    }
+
+  gimp_progress_update (1.0);
+
+  _TIFFfree (BufferOut);
+  g_free (src);
+
+  cmsDeleteTransform (transform);
+
+  gimp_drawable_detach (drawable);
+
+  return TRUE;
+}
+
+/***** JPEG export functions *****/
+
+typedef struct _JpegWriteErrMgr
+{
+  struct jpeg_error_mgr jerr;
+  jmp_buf buf;
+} JpegWriteErrMgr;
+
+static void
+jpeg_write_error_handler (j_common_ptr cinfo)
+{
+  JpegWriteErrMgr *mgr = (JpegWriteErrMgr *) (cinfo->err);
+
+  longjmp (mgr->buf, 1);
+}
+
+#define MARKER_LENGTH 65533
+#define ICC_MARKER_HEADER_LENGTH 14
+#define ICC_MARKER_DATA_LENGTH (MARKER_LENGTH - ICC_MARKER_HEADER_LENGTH)
+
+static gboolean
+export_jpeg (SeparateContext *context)
+{
+  FILE *stream;
+
+  stream = g_fopen (context->filename, "wb");
+
+  if (stream)
+    {
+      gdouble xres, yres;
+      struct jpeg_compress_struct cinfo;
+      JpegWriteErrMgr mgr;
+
+      mgr.jerr.error_exit = jpeg_write_error_handler;
+      cinfo.err = jpeg_std_error (&mgr.jerr);
+      jpeg_create_compress (&cinfo);
+
+      if (setjmp (mgr.buf) != 0)
+        {
+          gimp_message (_("Failed to exporting JPEG."));
+          return FALSE;
+        }
+
+      jpeg_stdio_dest (&cinfo, stream);
+
+      cinfo.image_width = gimp_image_width (context->image_id);
+      cinfo.image_height = gimp_image_height (context->image_id);
+      cinfo.input_components = 4;
+      cinfo.in_color_space = JCS_CMYK;
+      cinfo.jpeg_color_space = JCS_YCCK;
+
+      jpeg_set_defaults (&cinfo);
+
+      jpeg_set_colorspace (&cinfo, JCS_YCCK);
+
+      jpeg_set_quality (&cinfo, context->settings.compression, TRUE);
+
+      gimp_image_get_resolution (context->image_id, &xres, &yres);
+      cinfo.X_density = xres;
+      cinfo.Y_density = yres;
+      cinfo.density_unit = 1;
+      cinfo.optimize_coding = TRUE;
+      cinfo.dct_method = JDCT_FLOAT;
+      cinfo.write_JFIF_header = TRUE;
+      cinfo.write_Adobe_marker = TRUE;
+
+      jpeg_start_compress (&cinfo, TRUE);
+
+      if (context->settings.embed_profile && context->destination_profile_data)
+        write_jpeg_profile_data (&cinfo,
+                                 context->destination_profile_data,
+                                 context->destination_profile_length);
+
+      write_jpeg_data (&cinfo, context);
+
+      jpeg_finish_compress (&cinfo);
+
+      jpeg_destroy_compress (&cinfo);
+      fclose (stream);
+
+      return TRUE;
+    }
+  else
+    {
+      g_string_printf (context->message,
+                       _("Could not open '%s' for writing: %s"),
+                       gimp_filename_to_utf8 (context->filename), g_strerror (errno));
+    }
+
+  return FALSE;
+}
+
+
+static void
+write_jpeg_profile_data (j_compress_ptr  cinfo,
+                         const gchar    *profile_data,
+                         gsize           profile_length)
+{
+  gint n_markers, current_marker;
+
+  n_markers = profile_length / ICC_MARKER_DATA_LENGTH;
+
+  if (profile_length % ICC_MARKER_DATA_LENGTH)
+    n_markers++;
+
+  current_marker = 1;
+
+  while (profile_length > 0)
+    {
+      guint length;
+
+      length = MIN (profile_length, ICC_MARKER_DATA_LENGTH);
+      profile_length -= length;
+
+      jpeg_write_m_header (cinfo, JPEG_APP0 + 2, length + ICC_MARKER_HEADER_LENGTH);
+
+      jpeg_write_m_byte (cinfo, 'I');
+      jpeg_write_m_byte (cinfo, 'C');
+      jpeg_write_m_byte (cinfo, 'C');
+      jpeg_write_m_byte (cinfo, '_');
+      jpeg_write_m_byte (cinfo, 'P');
+      jpeg_write_m_byte (cinfo, 'R');
+      jpeg_write_m_byte (cinfo, 'O');
+      jpeg_write_m_byte (cinfo, 'F');
+      jpeg_write_m_byte (cinfo, 'I');
+      jpeg_write_m_byte (cinfo, 'L');
+      jpeg_write_m_byte (cinfo, 'E');
+      jpeg_write_m_byte (cinfo, 0);
+
+      jpeg_write_m_byte (cinfo, current_marker);
+      jpeg_write_m_byte (cinfo, n_markers);
+
+      while (length--)
+        {
+          jpeg_write_m_byte (cinfo, *profile_data);
+          profile_data++;
+        }
+
+      current_marker++;
+    }
+}
+
+static gboolean
+write_jpeg_data (j_compress_ptr   cinfo,
+                 SeparateContext *context)
+{
+  gint i;
+  guchar *src, *dest, *scanlines[64];
+  GimpPixelRgn region;
+  GimpDrawable *drawable = gimp_drawable_get (context->drawable_id);
+  cmsHTRANSFORM transform;
+
+  transform =
+    cmsCreateTransform (context->source, TYPE_RGB_8,
+                        context->destination, TYPE_CMYK_8 | FLAVOR_SH (1),
+                        context->intent,
+                        context->intent == GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC ?
+                                           cmsFLAGS_BLACKPOINTCOMPENSATION : 0);
+
+  if (! transform)
+    {
+      g_string_printf (context->message, _("Cannot setup color separation."));
+      return FALSE;
+    }
+
+  if (! (src  = g_try_malloc (cinfo->image_width * 3 * 64)) ||
+      ! (dest = g_try_malloc (cinfo->image_width * 4 * 64)))
+    {
+      g_string_printf (context->message, _("Cannot allocate working memory."));
+
+      g_free (src);
+      cmsDeleteTransform (transform);
+
+      return FALSE;
+    }
+
+  gimp_pixel_rgn_init (&region, drawable, 0, 0, cinfo->image_width, cinfo->image_height, FALSE, FALSE);
+
+  gimp_progress_init (_("Exporting JPEG..."));
+
+  for (i = 0; i < 64; i++)
+    scanlines[i] = dest + i * cinfo->image_width * 4;
+
+  for (i = 0; i < cinfo->image_height; i += 64)
+    {
+      gint n_lines;
+
+      n_lines = MIN (cinfo->image_height - i, 64);
+
+      gimp_progress_update ((gdouble)i / (gdouble)cinfo->image_height);
+
+      gimp_pixel_rgn_get_rect (&region, src, 0, i, cinfo->image_width, n_lines);
+
+      cmsDoTransform (transform, src, dest, cinfo->image_width * n_lines);
+
+      jpeg_write_scanlines (cinfo, (JSAMPARRAY)scanlines, n_lines);
+    }
+
+  gimp_progress_update (1.0);
+
+  g_free (src);
+  g_free (dest);
+
+  cmsDeleteTransform (transform);
+
+  gimp_drawable_detach (drawable);
+
+  return TRUE;
+}
diff -uNr gimp-2.8.16.original/plug-ins/common/gimprc.common gimp-2.8.16/plug-ins/common/gimprc.common
--- gimp-2.8.16.original/plug-ins/common/gimprc.common	2014-08-21 00:27:58.000000000 +0900
+++ gimp-2.8.16/plug-ins/common/gimprc.common	2016-04-28 18:49:14.055476720 +0900
@@ -47,6 +47,7 @@
 engrave_RC = engrave.rc.o
 file_aa_RC = file-aa.rc.o
 file_cel_RC = file-cel.rc.o
+file_cmyk-save_RC = file-cmyk-save.rc.o
 file_compressor_RC = file-compressor.rc.o
 file_csource_RC = file-csource.rc.o
 file_desktop_link_RC = file-desktop-link.rc.o
diff -uNr gimp-2.8.16.original/po-plug-ins/ja.po gimp-2.8.16/po-plug-ins/ja.po
--- gimp-2.8.16.original/po-plug-ins/ja.po	2014-08-25 03:54:15.000000000 +0900
+++ gimp-2.8.16/po-plug-ins/ja.po	2016-04-28 18:53:31.665756499 +0900
@@ -13362,6 +13362,102 @@
 msgid "No data captured"
 msgstr "何も取り込まれませんでした"
 
+#
+msgid "JPEG (CMYK)"
+msgstr "JPEG (CMYK形式)"
+
+#
+msgid "TIFF (CMYK)"
+msgstr "TIFF (CMYK形式)"
+
+#
+msgid "JPEG image (CMYK)"
+msgstr "JPEG 画像 (CMYK形式)"
+
+#
+msgid "TIFF image (CMYK)"
+msgstr "TIFF 画像 (CMYK形式)"
+
+#
+msgid "Perceptual"
+msgstr "知覚的"
+
+#
+msgid "Relative colorimetric with BPC"
+msgstr "相対的な色域を維持"
+
+#
+#msgid "Saturation"
+#msgstr "彩度"
+
+#
+msgid "Absolute colorimetric"
+msgstr "絶対的な色域を維持"
+
+#
+msgid "Unknown"
+msgstr "不明"
+
+#
+#msgid "_Quality:"
+#msgstr "品質(_Q):"
+
+#
+#msgid "JPEG quality parameter"
+#msgstr "JPEG 品質パラメーター"
+
+#
+msgid "_LZW compression"
+msgstr "LZW圧縮(_L)"
+
+#
+msgid "_Packbits compression"
+msgstr "Packbits圧縮(_P)"
+
+#
+msgid "_Embed color profile"
+msgstr "カラープロファイルを埋め込む"
+
+#
+msgid "Exporting JPEG..."
+msgstr "JPEGファイルのエクスポート中..."
+
+#
+msgid "Exporting TIFF..."
+msgstr "TIFFファイルのエクスポート中..."
+
+#
+msgid "<b>Convert from:</b>\n  %s\n<b>to:</b>\n  %s\n\n<b>Rendering Intent:</b>\n %s"
+msgstr "<b>変換元:</b>\n  %s\n<b>変換先:</b>\n  %s\n\n<b>レンダリングインテント:</b>\n %s"
+
+#
+msgid "Invalid procedure name : %s"
+msgstr "無効なプロシジャ名 : %s"
+
+#
+msgid "Destination profile cannot be loaded or is not CMYK profile.\nPlease check the color management preferences."
+msgstr "変換先のカラープロファイルがロードされていないかまたはCMYKカラープロファイルではありません。\nカラーマネジメントの設定を確認してください。"
+
+#
+msgid "Cannot access the color management preferences."
+msgstr "カラーマネジメントの設定にアクセスできません。"
+
+#
+msgid "Cannot setup color separation."
+msgstr "色分解のセットアップができませんでした。"
+
+#
+msgid "Cannot allocate working memory."
+msgstr "作業用メモリが確保できませんでした。"
+
+#
+msgid "Failed to exporting JPEG."
+msgstr "JPEGファイルのエクスポートに失敗しました。"
+
+#
+#msgid "Could not open '%s' for writing: %s"
+#msgstr "'%s' を書き込み用に開けません: %s"
+
 #~ msgid "The width of frame %d of '%s' is too big for X cursor."
 #~ msgstr "'%2$s' の 第 %1$d フレームの幅は X カーソルには大き過ぎます。"
 
