home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / plug-ins / gap / gap_split.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-06  |  11.0 KB  |  340 lines

  1. /* gap_split.c
  2.  * 1997.11.06 hof (Wolfgang Hofer)
  3.  *
  4.  * GAP ... Gimp Animation Plugins
  5.  *
  6.  * This Module contains 
  7.  * - gap_split_image
  8.  *
  9.  */
  10. /* The GIMP -- an image manipulation program
  11.  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
  12.  *
  13.  * This program is free software; you can redistribute it and/or modify
  14.  * it under the terms of the GNU General Public License as published by
  15.  * the Free Software Foundation; either version 2 of the License, or
  16.  * (at your option) any later version.
  17.  *
  18.  * This program is distributed in the hope that it will be useful,
  19.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  * GNU General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License
  24.  * along with this program; if not, write to the Free Software
  25.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  26.  */
  27.  
  28. /* revision history
  29.  * 1.1.28a; 2000/10/29   hof: subsequent save calls use GIMP_RUN_WITH_LAST_VALS
  30.  * 1.1.9a;  1999/09/21   hof: bugfix GIMP_RUN_NONINTERACTIVE mode did not work
  31.  * 1.1.8a;  1999/08/31   hof: accept anim framenames without underscore '_'
  32.  * 1.1.5a;  1999/05/08   hof: bugix (dont mix GimpImageType with GimpImageBaseType)
  33.  * 0.96.00; 1998/07/01   hof: - added scale, resize and crop 
  34.  *                              (affects full range == all anim frames)
  35.  *                            - now using gap_arr_dialog.h
  36.  * 0.94.01; 1998/04/28   hof: added flatten_mode to plugin: gap_range_to_multilayer
  37.  * 0.92.00  1998.01.10   hof: bugfix in p_frames_to_multilayer
  38.  *                            layers need alpha (to be raise/lower able) 
  39.  * 0.90.00               first development release
  40.  */
  41. #include "config.h"
  42.  
  43. /* SYTEM (UNIX) includes */ 
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46. #include <string.h>
  47. #include <sys/types.h>
  48. #include <errno.h>
  49. #ifdef HAVE_UNISTD_H
  50. #include <unistd.h>
  51. #endif
  52.  
  53. /* GIMP includes */
  54. #include "gtk/gtk.h"
  55. #include "config.h"
  56. #include "libgimp/stdplugins-intl.h"
  57. #include "libgimp/gimp.h"
  58.  
  59. /* GAP includes */
  60. #include "gap_layer_copy.h"
  61. #include "gap_lib.h"
  62. #include "gap_arr_dialog.h"
  63.  
  64. extern      int gap_debug; /* ==0  ... dont print debug infos */
  65.  
  66. /* ============================================================================
  67.  * p_split_image
  68.  *
  69.  * returns   value >= 0 if all is ok  return the image_id of 
  70.  *                      the new created image (the last handled anim frame)
  71.  *           (or -1 on error)
  72.  * ============================================================================
  73.  */
  74. static int
  75. p_split_image(t_anim_info *ainfo_ptr,
  76.               char *new_extension,
  77.               gint invers, gint no_alpha)
  78. {
  79.   GimpImageBaseType l_type;
  80.   guint   l_width, l_height;
  81.   GimpRunModeType l_run_mode;
  82.   gint32  l_new_image_id;
  83.   gint    l_nlayers;
  84.   gint32 *l_layers_list;
  85.   gint32  l_src_layer_id;
  86.   gint32  l_cp_layer_id;
  87.   gint    l_src_offset_x, l_src_offset_y;    /* layeroffsets as they were in src_image */
  88.   gdouble l_percentage, l_percentage_step;
  89.   char   *l_sav_name;
  90.   char   *l_str;
  91.   gint32  l_rc;
  92.   int     l_idx;
  93.   long    l_layer_idx;
  94.  
  95.   if(gap_debug) printf("DEBUG: p_split_image inv:%d no_alpha:%d ext:%s\n", (int)invers, (int)no_alpha, new_extension);
  96.   l_rc = -1;
  97.   l_percentage = 0.0;
  98.   l_run_mode  = ainfo_ptr->run_mode;
  99.   if(ainfo_ptr->run_mode == GIMP_RUN_INTERACTIVE)
  100.   { 
  101.     gimp_progress_init( _("Splitting into Frames..."));
  102.   }
  103.  
  104.   l_new_image_id = -1;
  105.   /* get info about the image  */
  106.   l_width  = gimp_image_width(ainfo_ptr->image_id);
  107.   l_height = gimp_image_height(ainfo_ptr->image_id);
  108.   l_type = gimp_image_base_type(ainfo_ptr->image_id);
  109.  
  110.   l_layers_list = gimp_image_get_layers(ainfo_ptr->image_id, &l_nlayers);
  111.   if(l_layers_list != NULL)
  112.   {
  113.     l_percentage_step = 1.0 / (l_nlayers);
  114.  
  115.     for(l_idx = 0; l_idx < l_nlayers; l_idx++)
  116.     {
  117.        if(l_new_image_id >= 0)
  118.        {
  119.           /* destroy the tmp image (it was saved to disk before) */
  120.           gimp_image_delete(l_new_image_id);
  121.       }
  122.        
  123.        if(invers == TRUE) l_layer_idx = l_idx;
  124.        else               l_layer_idx = (l_nlayers - 1 ) - l_idx;
  125.  
  126.        l_src_layer_id = l_layers_list[l_layer_idx];
  127.  
  128.        /* create new image */
  129.        l_new_image_id =  gimp_image_new(l_width, l_height,l_type);
  130.        if(l_new_image_id < 0)
  131.        {
  132.          l_rc = -1;
  133.          break;
  134.        }
  135.  
  136.        /* copy the layer */
  137.        l_cp_layer_id = p_my_layer_copy(l_new_image_id,
  138.                                      l_src_layer_id,
  139.                                      100.0,   /* Opacity */
  140.                                      0,       /* NORMAL */
  141.                                      &l_src_offset_x,
  142.                                      &l_src_offset_y);
  143.        /* add the copied layer to current destination image */
  144.         gimp_image_add_layer(l_new_image_id, l_cp_layer_id, 0);
  145.         gimp_layer_set_offsets(l_cp_layer_id, l_src_offset_x, l_src_offset_y);
  146.      
  147.        /* delete alpha channel ? */
  148.        if (no_alpha == TRUE)
  149.        {
  150.            /* add a dummy layer (flatten needs at least 2 layers) */
  151.            l_cp_layer_id = gimp_layer_new(l_new_image_id, "dummy",
  152.                                           4, 4,         /* width, height */
  153.                                           ((l_type * 2 ) + 1),  /* convert from GimpImageBaseType to GimpImageType, and add alpha */
  154.                                           0.0,          /* Opacity full transparent */     
  155.                                           0);           /* NORMAL */
  156.            gimp_image_add_layer(l_new_image_id, l_cp_layer_id, 0);
  157.            gimp_image_flatten (l_new_image_id);
  158.          
  159.        }
  160.        
  161.        
  162.        /* build the name for output image */
  163.        l_str = p_strdup_add_underscore(ainfo_ptr->basename);
  164.        l_sav_name = p_alloc_fname(l_str,
  165.                                   (l_idx +1),       /* start at 1 (not at 0) */
  166.                                   new_extension);
  167.        g_free(l_str);
  168.        if(l_sav_name != NULL)
  169.        {
  170.          /* save with selected save procedure
  171.           * (regardless if image was flattened or not)
  172.           */
  173.           l_rc = p_save_named_image(l_new_image_id, l_sav_name, l_run_mode);
  174.           if(l_rc < 0)
  175.           {
  176.             p_msg_win(ainfo_ptr->run_mode, _("Split Frames: SAVE operation FAILED.\n"
  177.                          "desired save plugin can't handle type\n"
  178.                          "or desired save plugin not available."));
  179.             break;
  180.           }
  181.  
  182.           l_run_mode  = GIMP_RUN_WITH_LAST_VALS;  /* for all further calls */
  183.  
  184.           /* set image name */
  185.           gimp_image_set_filename (l_new_image_id, l_sav_name);
  186.           
  187.           /* prepare return value */
  188.           l_rc = l_new_image_id;
  189.  
  190.           g_free(l_sav_name);
  191.        }
  192.        
  193.        /* save as frame */
  194.        
  195.  
  196.        /* show progress bar */
  197.        if(ainfo_ptr->run_mode == GIMP_RUN_INTERACTIVE)
  198.        { 
  199.          l_percentage += l_percentage_step;
  200.          gimp_progress_update (l_percentage);
  201.        }
  202.  
  203.       
  204.     }
  205.     g_free (l_layers_list);
  206.   }
  207.   
  208.  
  209.   return l_rc;  
  210. }    /* end p_split_image */
  211.  
  212.  
  213. /* ============================================================================
  214.  * p_split_dialog
  215.  *
  216.  *   return  0 (OK) 
  217.  *          or  -1 in case of Error or cancel
  218.  * ============================================================================
  219.  */
  220. static long
  221. p_split_dialog(t_anim_info *ainfo_ptr, gint *inverse_order, gint *no_alpha, char *extension, gint len_ext)
  222. {
  223.   static t_arr_arg  argv[4];
  224.   gchar   *buf;
  225.   
  226.   buf = g_strdup_printf (_("%s\n%s\n(%s_0001.%s)\n"),
  227.              _("Make a frame (diskfile) from each Layer"),
  228.              _("frames are named: base_nr.extension"),
  229.              ainfo_ptr->basename, extension);
  230.   
  231.   p_init_arr_arg(&argv[0], WGT_LABEL);
  232.   argv[0].label_txt = &buf[0];
  233.  
  234.   p_init_arr_arg(&argv[1], WGT_TEXT);
  235.   argv[1].label_txt = _("Extension:");
  236.   argv[1].help_txt  = _("extension of resulting frames (is also used to define Fileformat)");
  237.   argv[1].text_buf_len = len_ext;
  238.   argv[1].text_buf_ret = extension;
  239.  
  240.   p_init_arr_arg(&argv[2], WGT_TOGGLE);
  241.   argv[2].label_txt = _("Inverse Order:");
  242.   argv[2].help_txt  = _("Start frame 0001 at Top Layer");
  243.   argv[2].int_ret   = 0;
  244.  
  245.   p_init_arr_arg(&argv[3], WGT_TOGGLE);
  246.   argv[3].label_txt = _("Flatten:");
  247.   argv[3].help_txt  = _("Remove Alpha Channel in resulting Frames. Transparent parts are filled with BG color.");
  248.   argv[3].int_ret   = 0;
  249.  
  250.   if(TRUE == p_array_dialog( _("Split Image into Frames"),
  251.                  _("Split Settings"), 
  252.                  4, argv))
  253.   {
  254.     g_free (buf);
  255.     *inverse_order = argv[2].int_ret;
  256.     *no_alpha      = argv[3].int_ret;
  257.     return 0;
  258.   }
  259.   else
  260.   {
  261.     g_free (buf);
  262.     return -1;
  263.   }
  264. }        /* end p_split_dialog */
  265.  
  266. /* ============================================================================
  267.  * gap_split_image
  268.  *    Split one (multilayer) image into anim-frames
  269.  *    one frame per layer.
  270.  * ============================================================================
  271.  */
  272. int gap_split_image(GimpRunModeType run_mode,
  273.                       gint32     image_id,
  274.                       gint32     inverse_order,
  275.                       gint32     no_alpha,
  276.                       char      *extension)
  277.  
  278. {
  279.   gint32  l_new_image_id;
  280.   gint32  l_rc;
  281.   gint32  l_inverse_order;
  282.   gint32  l_no_alpha;
  283.   
  284.   t_anim_info *ainfo_ptr;
  285.   char l_extension[32];
  286.  
  287.   strcpy(l_extension, ".xcf");
  288.  
  289.   l_rc = -1;
  290.   ainfo_ptr = p_alloc_ainfo(image_id, run_mode);
  291.   if(ainfo_ptr != NULL)
  292.   {
  293.     if (0 == p_dir_ainfo(ainfo_ptr))
  294.     {
  295.       if(ainfo_ptr->frame_cnt != 0)
  296.       {
  297.          p_msg_win(run_mode,
  298.            _("OPERATION CANCELLED.\n"
  299.          "This image is already an AnimFrame.\n"
  300.          "Try again on a Duplicate (Image/Duplicate)."));
  301.          return -1;
  302.       }
  303.       else
  304.       {
  305.         if(run_mode == GIMP_RUN_INTERACTIVE)
  306.         {
  307.            l_rc = p_split_dialog (ainfo_ptr, &l_inverse_order, &l_no_alpha, &l_extension[0], sizeof(l_extension));
  308.         }
  309.         else
  310.         {
  311.            l_rc = 0;
  312.            l_inverse_order  =  inverse_order;
  313.            l_no_alpha       =  no_alpha;
  314.            strncpy(l_extension, extension, sizeof(l_extension) -1);
  315.            l_extension[sizeof(l_extension) -1] = '\0';
  316.  
  317.         }
  318.  
  319.         if(l_rc >= 0)
  320.         {
  321.            l_new_image_id = p_split_image(ainfo_ptr,
  322.                                l_extension,
  323.                                l_inverse_order,
  324.                                l_no_alpha);
  325.            
  326.            /* create a display for the new created image
  327.             * (it is the first or the last frame of the 
  328.             *  new created animation sequence)
  329.             */                    
  330.            gimp_display_new(l_new_image_id);
  331.            l_rc = l_new_image_id;
  332.         }
  333.       }
  334.     }
  335.     p_free_ainfo(&ainfo_ptr);
  336.   }
  337.   
  338.   return(l_rc);    
  339. }    /* end   gap_split_image */
  340.