Advertisement
Guest User

3D MPO Plug-in

a guest
Apr 26th, 2013
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.23 KB | None | 0 0
  1. /* 3D MPO loader and saver plug-in for Gimp
  2. *
  3. * This plug-in is based on mposplit.c
  4. * A small tool for splitting MPO files into their JPG components.
  5. * $Id: mposplit.c,v 1.5 2012/06/24 01:16:33 chris Exp $
  6. * Copyright (C) 2009-2012, Christian Steinruecken. All rights reserved.
  7. *
  8. * This code is released under the Revised BSD Licence.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. *
  14. * - Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. * - Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. * - The names of the author(s) and contributors may not be used to
  20. * endorse or promote products derived from this software without
  21. * specific prior written permission.
  22. *
  23. * DISCLAIMER:
  24. * This software is provided by the copyright holders and contributors
  25. * "as is" and any express or implied warranties, including, but not
  26. * limited to, the implied warranties of merchantability and fitness for
  27. * a particular purpose are disclaimed. In no event shall the copyright
  28. * holders be liable for any direct, indirect, incidental, special,
  29. * exemplary, or consequential damages (including, but not limited to,
  30. * procurement of substitute goods or services; loss of use, data, or
  31. * profits; or business interruption) however caused and on any theory of
  32. * liability, whether in contract, strict liability, or tort (including
  33. * negligence or otherwise) arising in any way out of the use of this
  34. * software, even if advised of the possibility of such damage.
  35. *
  36. *
  37. *
  38. * This program is free software: you can redistribute it and/or modify
  39. * it under the terms of the GNU General Public License as published by
  40. * the Free Software Foundation; either version 3 of the License, or
  41. * (at your option) any later version.
  42. *
  43. * This program is distributed in the hope that it will be useful,
  44. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  45. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  46. * GNU General Public License for more details.
  47. *
  48. * You should have received a copy of the GNU General Public License
  49. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  50. */
  51.  
  52.  
  53. #include "config.h"
  54.  
  55. #include <errno.h>
  56. #include <string.h>
  57. #include <stdlib.h>
  58.  
  59. #include <fcntl.h>
  60. #include <sys/stat.h>
  61. #include <sys/types.h>
  62.  
  63. #ifdef HAVE_UNISTD_H
  64. #include <unistd.h>
  65. #endif
  66.  
  67. #include <glib/gstdio.h>
  68.  
  69. #ifdef G_OS_WIN32
  70. #include <io.h>
  71. #endif
  72.  
  73. #include "libgimp/gimp.h"
  74. #include "libgimp/gimpui.h"
  75. #include "libgimp/stdplugins-intl.h"
  76.  
  77.  
  78. #define LOAD_PROC "file-mpo-load"
  79. #define SAVE_PROC "file-mpo-save"
  80. #define PLUG_IN_BINARY "file-mpo"
  81. #define PLUG_IN_ROLE "gimp-file-mpo"
  82.  
  83. static void query (void);
  84. static void run (const gchar *name,
  85.                                               gint nparams,
  86.                                               const GimpParam *param,
  87.                                               gint *nreturn_vals,
  88.                                               GimpParam **return_vals);
  89.  
  90.  
  91. static gboolean load_image (const gchar *filename,
  92.                                               GError **error);
  93. static gboolean split_mpo (const gchar *filename);
  94.  
  95.  
  96. static gint num_images = 0; /* Number of images in MPO file */
  97. static gchar **image_name;
  98. static FILE *fp;
  99. static gint32 image_id;
  100.  
  101. const GimpPlugInInfo PLUG_IN_INFO =
  102. {
  103.   NULL, /* init_proc */
  104.   NULL, /* quit_proc */
  105.   query, /* query_proc */
  106.   run, /* run_proc */
  107. };
  108.  
  109. MAIN()
  110.  
  111. static void
  112. query (void)
  113. {
  114.   static const GimpParamDef load_args[] =
  115.   {
  116.     { GIMP_PDB_INT32, "run-mode", "The run mode { RUN-NONINTERACTIVE (1) }" },
  117.     { GIMP_PDB_STRING, "filename", "The name of the file to load" },
  118.     { GIMP_PDB_STRING, "raw-filename", "The name entered" }
  119.   };
  120.  
  121.   static const GimpParamDef load_return_vals[] =
  122.   {
  123.     { GIMP_PDB_IMAGE, "image", "Output image" }
  124.   };
  125.  
  126.   gimp_install_procedure (LOAD_PROC,
  127.                           "Load MPO files",
  128.                           "No help till now",
  129.                           "Sashi Kumar <ksashikumark93@gmail.com>",
  130.                           "Sashi Kumar <ksashikumark93@gmail.com>",
  131.                           "24th April 2013",
  132.                           N_("3D MPO Data"),
  133.                           NULL,
  134.                           GIMP_PLUGIN,
  135.                           G_N_ELEMENTS (load_args),
  136.                           G_N_ELEMENTS (load_return_vals),
  137.                           load_args, load_return_vals);
  138.  
  139.   gimp_register_load_handler (LOAD_PROC, "mpo", "");
  140.  
  141.  
  142. }
  143.  
  144. static void
  145. run (const gchar *name,
  146.      gint nparams,
  147.      const GimpParam *param,
  148.      gint *nreturn_vals,
  149.      GimpParam **return_vals)
  150. {
  151.   static GimpParam values[2];
  152.   GimpRunMode run_mode;
  153.   GimpPDBStatusType status = GIMP_PDB_SUCCESS;
  154.   GError *error = NULL;
  155.  
  156.   INIT_I18N ();
  157.  
  158.   run_mode = param[0].data.d_int32;
  159.  
  160.   *nreturn_vals = 1;
  161.   *return_vals = values;
  162.  
  163.   values[0].type = GIMP_PDB_STATUS;
  164.   values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
  165.  
  166.   if (strcmp (name, LOAD_PROC) == 0)
  167.     {
  168.      
  169.       if (load_image (param[1].data.d_string, &error))
  170.         {
  171.           *nreturn_vals = 2;
  172.            values[1].type = GIMP_PDB_IMAGE;
  173.            values[1].data.d_image = image_id;
  174.         }
  175.       else
  176.         {
  177.           status = GIMP_PDB_EXECUTION_ERROR;
  178.         }
  179.     }
  180.   else
  181.     {
  182.       status = GIMP_PDB_CALLING_ERROR;
  183.     }
  184.  
  185.  
  186.   if (status != GIMP_PDB_SUCCESS && error)
  187.     {
  188.       *nreturn_vals = 2;
  189.       values[1].type = GIMP_PDB_STRING;
  190.       values[1].data.d_string = error->message;
  191.     }
  192.  
  193.   values[0].data.d_status = status;
  194. }
  195.  
  196. static gboolean
  197. load_image (const gchar *filename,
  198.             GError **error)
  199. {
  200.   gint32 layer_id;
  201.   gint32 size;
  202.   gint i;
  203.   GdkPixbuf* pixbuf;
  204.   gboolean status;
  205.  
  206.   fp = g_fopen (filename, "rb");
  207.  
  208.   if (!fp)
  209.     {
  210.       g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
  211.                    _("Could not open '%s' for reading: %s"),
  212.                    gimp_filename_to_utf8 (filename), g_strerror (errno));
  213.       return FALSE;
  214.     }
  215.  
  216.   if (split_mpo (filename))
  217.     {
  218.       for (i = num_images - 1; i >= 0; i--)
  219.         {
  220.  
  221.           gchar *layer_name = g_new0 (gchar, 100); /* Bad Assumption */
  222.           sprintf (layer_name, "image#%d", i+1);
  223.           pixbuf = gdk_pixbuf_new_from_file(image_name[i], NULL);
  224.  
  225.           remove (image_name[i]); /* Delete the temporary JPEG files */
  226.          
  227.           if (pixbuf)
  228.             {
  229.            
  230.               if (i == num_images - 1)
  231.                 {
  232.                   image_id = gimp_image_new (gdk_pixbuf_get_width (pixbuf),
  233.                                              gdk_pixbuf_get_height (pixbuf),
  234.                                              GIMP_RGB);
  235.                   gimp_image_set_filename (image_id, filename);
  236.                 }
  237.  
  238.               layer_id = gimp_layer_new_from_pixbuf (image_id, _(layer_name),
  239.                                                      pixbuf,
  240.                                                      100.,
  241.                                                      GIMP_NORMAL_MODE, 0, 0);
  242.               g_object_unref (pixbuf);
  243.    
  244.               gimp_image_insert_layer (image_id, layer_id, -1, -1);
  245.               status = TRUE;
  246.    
  247.            }
  248.           else
  249.             status = FALSE;
  250.           free (layer_name);
  251.         }
  252.       gimp_image_resize_to_layers (image_id); /* Resize the image to the maximum layer size */
  253.     }
  254.   else
  255.     status = FALSE;
  256.  
  257.   free (image_name);
  258.  
  259.   return status;
  260.  
  261. }
  262.  
  263. /* mposplit - Split MPO file into their JPG components. */
  264. static gboolean
  265. split_mpo (const gchar *filename)
  266. {
  267.   size_t length; /* Total length of file */
  268.   size_t amount; /* Amount read */
  269.   gint i = 0;
  270.   gchar* buffer;
  271.   gchar* fnmbase;
  272.   gchar* ext;
  273.   gchar *temp;
  274.  
  275.   fnmbase = strdup(filename);
  276.  
  277.   ext = strstr(fnmbase,".MPO");
  278.  
  279.   if (ext != NULL)
  280.       ext[0] = '\0';
  281.  
  282.   ext = strstr(fnmbase,".mpo");
  283.  
  284.   if (ext != NULL)
  285.       ext[0] = '\0';
  286.  
  287.   /* Obtain file size: */
  288.   fseek(fp, 0, SEEK_END);
  289.   length = ftell(fp);
  290.   rewind(fp);
  291.  
  292.   /* Allocate memory to contain the whole file: */
  293.   buffer = g_new0 (gchar ,length);
  294.  
  295.   amount = fread(buffer,1,length,fp);
  296.   if (amount != length)
  297.       return FALSE;
  298.   fclose(fp);
  299.  
  300.   /* Now find the individual images */
  301.  
  302.   gchar* view = buffer;
  303.   gchar* last = NULL;
  304.   image_name = g_new (gchar *, 128); /* Assuming a maximum of 128 layers */
  305.  
  306.   while (view < buffer+length-4)
  307.     {
  308.       if (((char) view[0] % 255) == (char) 0xff)
  309.         {
  310.           if (((char) view[1] % 255) == (char) 0xd8)
  311.             {
  312.               if (((char) view[2] % 255) == (char) 0xff)
  313.                 {
  314.                   if (((char) view[3] % 255) == (char) 0xe1)/* FIXME: Make generalized check
  315. for JFIF tag 0xff 0xe0 */
  316.                     {
  317.                       num_images++;
  318.                       if (last != NULL)
  319.                         {
  320.                           /* copy out the previous view */
  321.                           image_name[i] = malloc (sizeof(gchar) * 200); /* Bad Assumption */
  322.                           sprintf(image_name[i], "%s.image#%d", fnmbase, num_images-1);
  323.                           FILE* w = fopen(image_name[i], "wb");
  324.                           fwrite(last, 1, view-last, w);
  325.                           fclose(w);
  326.                           i++;
  327.                         }
  328.                       last = view;
  329.                       view+=4;
  330.                     }
  331.                   else
  332.                     view+=2;
  333.                 }
  334.               else
  335.                 view+=3;
  336.             }
  337.           else
  338.             view+=1;
  339.         }
  340.       else
  341.         view+=1;
  342.     }
  343.  
  344.   if (num_images > 1)
  345.     {
  346.      
  347.       image_name[i] = malloc (sizeof(gchar) * 200);
  348.       sprintf(image_name[i], "%s.image#%d", fnmbase, num_images);
  349.       FILE* w = fopen(image_name[i], "wb");
  350.       fwrite(last, 1, buffer+length-last, w);
  351.       fclose(w);
  352.     }
  353.  
  354.   g_free(buffer);
  355.  
  356.   return TRUE;
  357.  
  358. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement