Exemplo n.º 1
0
/* ============================================================================
 * gap_image_new_with_layer_of_samesize
 * ============================================================================
 * create empty image
 *  if layer_id is NOT NULL then create one full transparent layer at full image size
 *  and return the layer_id
 */
gint32
gap_image_new_with_layer_of_samesize(gint32 old_image_id, gint32 *layer_id)
{
  GimpImageBaseType  l_type;
  guint       l_width;
  guint       l_height;
  gint32      new_image_id;
  gdouble     l_xresoulution, l_yresoulution;
  gint32     l_unit;


  /* create empty image  */
  l_width  = gimp_image_width(old_image_id);
  l_height = gimp_image_height(old_image_id);
  l_type   = gimp_image_base_type(old_image_id);
  l_unit   = gimp_image_get_unit(old_image_id);
  gimp_image_get_resolution(old_image_id, &l_xresoulution, &l_yresoulution);

  new_image_id = gimp_image_new(l_width, l_height,l_type);
  gimp_image_set_resolution(new_image_id, l_xresoulution, l_yresoulution);
  gimp_image_set_unit(new_image_id, l_unit);

  if(layer_id)
  {
    l_type   = (l_type * 2); /* convert from GimpImageBaseType to GimpImageType */
    *layer_id = gimp_layer_new(new_image_id, "dummy",
                                 l_width, l_height,  l_type,
                                 0.0,       /* Opacity full transparent */
                                 0);        /* NORMAL */
    gimp_image_insert_layer(new_image_id, *layer_id, 0, 0);
  }

  return (new_image_id);

}  /* end gap_image_new_with_layer_of_samesize */
Exemplo n.º 2
0
static gboolean apply_sharpblur(sharpblur_settings settings, image_output out)
{
    gboolean success = TRUE;
    gint nreturn_vals;

    if (settings->amount < 0) {
        /* do sharp */
        GimpParam *return_vals = gimp_run_procedure(
                                     "plug_in_sharpen", /* could use plug_in_unsharp_mask, but there's a datatype bug in 2.6.x version */
                                     &nreturn_vals,
                                     GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE,
                                     GIMP_PDB_IMAGE, out->image_id,
                                     GIMP_PDB_DRAWABLE, out->drawable_id,
                                     GIMP_PDB_INT32, -(settings->amount),
                                     GIMP_PDB_END
                                 );
    } else if (settings->amount > 0) {
        /* do blur */
        float minsize = bimp_min(gimp_image_width(out->image_id)/4, gimp_image_height(out->image_id)/4);
        float radius = (minsize / 100) * settings->amount;
        GimpParam *return_vals = gimp_run_procedure(
                                     "plug_in_gauss",
                                     &nreturn_vals,
                                     GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE,
                                     GIMP_PDB_IMAGE, out->image_id,
                                     GIMP_PDB_DRAWABLE, out->drawable_id,
                                     GIMP_PDB_FLOAT, radius,
                                     GIMP_PDB_FLOAT, radius,
                                     GIMP_PDB_INT32, 0,
                                     GIMP_PDB_END
                                 );
    }

    return success;
}
Exemplo n.º 3
0
/* ============================================================================
 * gap_image_merge_visible_layers
 *    merge visible layer an return layer_id of the resulting merged layer.
 *    (with workaround, for empty images return transparent layer)
 * ============================================================================
 */
gint32
gap_image_merge_visible_layers(gint32 image_id, GimpMergeType mergemode)
{
  GimpImageBaseType l_type;
  guint   l_width, l_height;
  gint32  l_layer_id;

  /* get info about the image */
  l_width  = gimp_image_width(image_id);
  l_height = gimp_image_height(image_id);
  l_type   = gimp_image_base_type(image_id);

  l_type   = (l_type * 2); /* convert from GimpImageBaseType to GimpImageType */

  /* add 2 full transparent dummy layers at top
   * (because gimp_image_merge_visible_layers complains
   * if there are less than 2 visible layers)
   */
  l_layer_id = gimp_layer_new(image_id, "dummy",
                                 l_width, l_height,  l_type,
                                 0.0,       /* Opacity full transparent */
                                 0);        /* NORMAL */
  gimp_image_insert_layer(image_id, l_layer_id, 0, 0);

  l_layer_id = gimp_layer_new(image_id, "dummy",
                                 10, 10,  l_type,
                                 0.0,       /* Opacity full transparent */
                                 0);        /* NORMAL */
  gimp_image_insert_layer(image_id, l_layer_id, 0, 0);

  return gimp_image_merge_visible_layers (image_id, mergemode);
}       /* end gap_image_merge_visible_layers */
Exemplo n.º 4
0
/* ---------------------------------------
 * gap_detail_tracking_dialog_cfg_set_vals
 * ---------------------------------------
 *   return  TRUE.. OK
 *           FALSE.. in case of Error or cancel
 */
gboolean
gap_detail_tracking_dialog_cfg_set_vals(gint32 image_id)
{
    gboolean     rc;
    FilterValues fiVals;

    gap_detail_tracking_get_values(&fiVals);
    if(image_id >= 0)
    {
        if (fiVals.coordsRelToFrame1)
        {
            if(gap_image_is_alive(image_id))
            {
                /* default offsets for handle at center */
                fiVals.offsX = gimp_image_width(image_id) / 2.0;
                fiVals.offsY = gimp_image_height(image_id) / 2.0;
            }
        }
    }

    rc = gap_detail_tracking_dialog(&fiVals);

    return(rc);

}  /* end gap_detail_tracking_dialog_cfg_set_vals */
Exemplo n.º 5
0
void gap_image_prevent_empty_image(gint32 image_id)
{
  GimpImageBaseType l_type;
  guint   l_width, l_height;
  gint32  l_layer_id;
  gint    l_nlayers;
  gint32 *l_layers_list;

  l_layers_list = gimp_image_get_layers(image_id, &l_nlayers);
  if(l_layers_list != NULL)
  {
     g_free (l_layers_list);
  }
  else l_nlayers = 0;

  if(l_nlayers == 0)
  {
     /* the resulting image has no layer, add a transparent dummy layer */

     /* get info about the image */
     l_width  = gimp_image_width(image_id);
     l_height = gimp_image_height(image_id);
     l_type   = gimp_image_base_type(image_id);

     l_type   = (l_type * 2); /* convert from GimpImageBaseType to GimpImageType */

     /* add a transparent dummy layer */
     l_layer_id = gimp_layer_new(image_id, "dummy",
                                    l_width, l_height,  l_type,
                                    0.0,       /* Opacity full transparent */
                                    0);        /* NORMAL */
     gimp_image_insert_layer(image_id, l_layer_id, 0, 0);
  }

}       /* end gap_image_prevent_empty_image */
Exemplo n.º 6
0
/**
 * Get a tile stream for a drawable.
 */
int
drawable_new_tile_stream (int image, int drawable)
{
  return rectangle_new_tile_stream (image, drawable,
                                    0, 0, 
                                    gimp_image_width (image),
                                    gimp_image_height (image));
} // drawable_new_tile_stream
Exemplo n.º 7
0
static gboolean apply_crop(crop_settings settings, image_output out)
{
    gboolean success = TRUE;
    gint newWidth, newHeight, oldWidth, oldHeight, posX, posY;

    oldWidth = gimp_image_width(out->image_id);
    oldHeight = gimp_image_height(out->image_id);

    if (settings->manual) {
        newWidth = settings->new_w;
        newHeight = settings->new_h;
        posX = (oldWidth - newWidth) / 2;
        posY = (oldHeight - newHeight) / 2;
    }
    else {
        float ratio1, ratio2;
        if (settings->ratio == CROP_PRESET_CUSTOM) {
            ratio1 = settings->custom_ratio1;
            ratio2 = settings->custom_ratio2;
        }
        else {
            ratio1 = (float)crop_preset_ratio[settings->ratio][0];
            ratio2 = (float)crop_preset_ratio[settings->ratio][1];
        }

        if (( (float)oldWidth / oldHeight ) > ( ratio1 / ratio2) ) {
            /* crop along the width */
            newHeight = oldHeight;
            newWidth = round(( ratio1 * (float)newHeight ) / ratio2);
            posX = (oldWidth - newWidth) / 2;
            posY = 0;
        } else {
            /* crop along the height */
            newWidth = oldWidth;
            newHeight = round(( ratio2 * (float)newWidth) / ratio1);
            posX = 0;
            posY = (oldHeight - newHeight) / 2;
        }
    }

    success = gimp_image_crop (
                  out->image_id,
                  newWidth,
                  newHeight,
                  posX,
                  posY
              );

    return success;
}
Exemplo n.º 8
0
static void modos (GimpDrawable *drawable ,gint image)
{
  gint width, height;

  // getting the image size
  width = gimp_image_width(image);
  height = gimp_image_height(image);

  // filling in the various parameters of rect_select which is image, x-cord, y-cord, width, height, Operation, feather, feather_radius
  gimp_rect_select(image, 0, 0, width, height, 0, 0, 0);
  // filling the various parameters of ellipse_select which is image, x-cord, y-cord (in this thickness of the frame), adjusted width and height with regards to thickness, SUBTRACT operation, Making the pic clear, feather, feather-radius
  gimp_ellipse_select (image, vals.xcord,vals.ycord, width - (2*vals.xcord), height - (2*vals.ycord), 1, TRUE, vals.xcord/4, vals.ycord/8);
  //Two parameters: drawable id, and fill type. (0-Foreground, 1-Background, 2-Whitefill, 3-Transparentfill, 4-Patterfill)
  gimp_edit_fill (drawable->drawable_id, vals.framecolor);
}
Exemplo n.º 9
0
static void
webx_run (gint32 image_ID, gint32 drawable_ID)
{
  GtkWidget *dlg;

  gimp_ui_init (PLUG_IN_BINARY, FALSE);

  global_image_ID = image_ID;
  global_drawable_ID = drawable_ID;
 
  if (gimp_image_width (image_ID) > WEBX_MAX_SIZE
      || gimp_image_height (image_ID) > WEBX_MAX_SIZE)
    {
      gimp_message (_("The image is too large for Save for Web!"));
      return;
    }

  dlg = webx_dialog_new (image_ID, drawable_ID);
  webx_dialog_run (WEBX_DIALOG (dlg));
}
Exemplo n.º 10
0
GtkObject*
webx_pipeline_new (gint image_ID,
                   gint drawable_ID)
{
  WebxPipeline *pipeline;

  pipeline = g_object_new (WEBX_TYPE_PIPELINE, NULL);
  pipeline->user_image = image_ID;
  pipeline->user_drawable = drawable_ID;
  pipeline->original_width = gimp_image_width (image_ID);
  pipeline->original_height = gimp_image_height (image_ID);
  pipeline->resize_width = pipeline->original_width;
  pipeline->resize_height = pipeline->original_height;
  pipeline->crop_width = pipeline->original_width;
  pipeline->crop_height = pipeline->original_height;
  pipeline->crop_offsx = 0;
  pipeline->crop_offsy = 0;

  return GTK_OBJECT (pipeline);
}
Exemplo n.º 11
0
void
jpeg_setup_exif_for_save (ExifData     *exif_data,
                          const gint32  image_ID)
{
  ExifRational  r;
  gdouble       xres, yres;
  ExifEntry    *entry;
  gint          byte_order = exif_data_get_byte_order (exif_data);

  /* set orientation to top - left */
  if ((entry = exif_content_get_entry (exif_data->ifd[EXIF_IFD_0],
                                       EXIF_TAG_ORIENTATION)))
    {
      exif_set_short (entry->data, byte_order, (ExifShort) 1);
    }

  /* set x and y resolution */
  gimp_image_get_resolution (image_ID, &xres, &yres);
  r.numerator =   xres;
  r.denominator = 1;
  if ((entry = exif_content_get_entry (exif_data->ifd[EXIF_IFD_0],
                                       EXIF_TAG_X_RESOLUTION)))
    {
      exif_set_rational (entry->data, byte_order, r);
    }
  r.numerator = yres;
  if ((entry = exif_content_get_entry (exif_data->ifd[EXIF_IFD_0],
                                       EXIF_TAG_Y_RESOLUTION)))
    {
      exif_set_rational (entry->data, byte_order, r);
    }

  /* set resolution unit, always inches */
  if ((entry = exif_content_get_entry (exif_data->ifd[EXIF_IFD_0],
                                       EXIF_TAG_RESOLUTION_UNIT)))
    {
      exif_set_short (entry->data, byte_order, (ExifShort) 2);
    }

  /* set software to "GIMP" and include the version number */
  if ((entry = exif_content_get_entry (exif_data->ifd[EXIF_IFD_0],
                                       EXIF_TAG_SOFTWARE)))
    {
      const gchar *name = "GIMP " GIMP_VERSION;

      entry->data = (guchar *) g_strdup (name);
      entry->size = strlen (name) + 1;
      entry->components = entry->size;
    }

  /* set the width and height */
  if ((entry = exif_content_get_entry (exif_data->ifd[EXIF_IFD_EXIF],
                                       EXIF_TAG_PIXEL_X_DIMENSION)))
    {
      exif_set_long (entry->data, byte_order,
                     (ExifLong) gimp_image_width (image_ID));
    }
  if ((entry = exif_content_get_entry (exif_data->ifd[EXIF_IFD_EXIF],
                                       EXIF_TAG_PIXEL_Y_DIMENSION)))
    {
      exif_set_long (entry->data, byte_order,
                     (ExifLong) gimp_image_height (image_ID));
    }

  /*
   * set the date & time image was saved
   * note, date & time of original photo is stored elsewwhere, we
   * aren't losing it.
   */
  if ((entry = exif_content_get_entry (exif_data->ifd[EXIF_IFD_0],
                                       EXIF_TAG_DATE_TIME)))
    {
      /* small memory leak here */
      entry->data = NULL;
      exif_entry_initialize (entry, EXIF_TAG_DATE_TIME);
    }

  /* should set components configuration, don't know how */

  /*
   * remove entries that don't apply to jpeg
   * (may have come from tiff or raw)
   */
  gimp_exif_data_remove_entry (exif_data, EXIF_IFD_0, EXIF_TAG_COMPRESSION);
  gimp_exif_data_remove_entry (exif_data, EXIF_IFD_0, EXIF_TAG_IMAGE_WIDTH);
  gimp_exif_data_remove_entry (exif_data, EXIF_IFD_0, EXIF_TAG_IMAGE_LENGTH);
  gimp_exif_data_remove_entry (exif_data, EXIF_IFD_0, EXIF_TAG_BITS_PER_SAMPLE);
  gimp_exif_data_remove_entry (exif_data, EXIF_IFD_0, EXIF_TAG_SAMPLES_PER_PIXEL);
  gimp_exif_data_remove_entry (exif_data, EXIF_IFD_0, EXIF_TAG_PHOTOMETRIC_INTERPRETATION);
  gimp_exif_data_remove_entry (exif_data, EXIF_IFD_0, EXIF_TAG_STRIP_OFFSETS);
  gimp_exif_data_remove_entry (exif_data, EXIF_IFD_0, EXIF_TAG_PLANAR_CONFIGURATION);
  gimp_exif_data_remove_entry (exif_data, EXIF_IFD_0, EXIF_TAG_YCBCR_SUB_SAMPLING);

  /* should set thumbnail attributes */
}
Exemplo n.º 12
0
static void
run (const gchar      *name,
     gint              nparams,
     const GimpParam  *param,
     gint             *nreturn_vals,
     GimpParam       **return_vals)
{
  static GimpParam   values[2];
  GimpDrawable      *drawable;
  GimpRunMode        run_mode;
  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;

  run_mode = param[0].data.d_int32;

  *nreturn_vals = 1;
  *return_vals  = values;

  values[0].type          = GIMP_PDB_STATUS;
  values[0].data.d_status = status;

  image_ID = param[1].data.d_image;
  drawable = gimp_drawable_get (param[2].data.d_drawable);

  width = gimp_image_width (image_ID);
  height = gimp_image_height (image_ID);

    switch (run_mode)
    {
      case GIMP_RUN_INTERACTIVE:
        if (! border_dialog (image_ID, drawable))
          return;
        break;

      case GIMP_RUN_NONINTERACTIVE:
        break;

      case GIMP_RUN_WITH_LAST_VALS:
        break;

      default:
        break;
    }

  if ((status == GIMP_PDB_SUCCESS) &&
      (gimp_drawable_is_rgb(drawable->drawable_id) ||
       gimp_drawable_is_gray(drawable->drawable_id)))
    {
      /* Run! */
      gimp_image_undo_group_start (image_ID);
      border (image_ID);
      gimp_image_undo_group_end (image_ID);

      /* If run mode is interactive, flush displays */
      if (run_mode != GIMP_RUN_NONINTERACTIVE)
        gimp_displays_flush ();

      /* Store data */
      /*if (run_mode == GIMP_RUN_INTERACTIVE)
        gimp_set_data (PLUG_IN_PROC, &rbvals, sizeof (BorderValues));*/

    }

  gimp_drawable_detach (drawable);
}
Exemplo n.º 13
0
static void
border (gint32 image_ID)
{
  GdkPixbuf *pixbuf = NULL;
  int        texture_width;
  int        texture_height;
  gdouble    margin_x;
  gdouble    margin_y;

  pixbuf = gdk_pixbuf_new_from_inline (-1, bvals.border->texture, FALSE, NULL);

  if (pixbuf)
  {
    texture_width = gdk_pixbuf_get_width (pixbuf);
    texture_height = gdk_pixbuf_get_height (pixbuf);

    gint32 texture_image = gimp_image_new (texture_width, texture_height, GIMP_RGB);
    gint32 texture_layer = gimp_layer_new_from_pixbuf (texture_image, "texture", pixbuf, 100, GIMP_NORMAL_MODE, 0, 0);
    gimp_image_add_layer (texture_image, texture_layer, -1);

    gint width = gimp_image_width (image_ID);
    gint height = gimp_image_height (image_ID);

    if (bvals.border->top || bvals.border->bottom || bvals.border->left || bvals.border->right)
    {
      width += bvals.border->left + bvals.border->right;
      height += bvals.border->top + bvals.border->bottom;
      gimp_image_resize (image_ID,
                         width,
                         height,
                         bvals.border->left,
                         bvals.border->top);
    }

    gint32 layer = gimp_layer_new (image_ID, "border",
                                   width, height,
                                   GIMP_RGBA_IMAGE,
                                   100,
                                   GIMP_NORMAL_MODE);
    gimp_image_add_layer (image_ID, layer, -1);

    if (width > texture_width - bvals.border->length)
      margin_x = (texture_width - bvals.border->length) / 2;
    else
      margin_x = (gdouble) width / 2;
    if (height > texture_height - bvals.border->length)
      margin_y = (texture_height - bvals.border->length) / 2;
    else
      margin_y = (gdouble) height / 2;

    /* fix gimp_context_set_pattern ("Clipboard") only works on English versions of Gimp */
    //gimp_context_set_pattern ("Clipboard");
    INIT_I18N ();
    gimp_context_set_pattern (_("Clipboard"));

    if (width > margin_x * 2) {
      /* top */
      gimp_rect_select (texture_image,
                        margin_x,
                        0,
                        texture_width - margin_x * 2,
                        margin_y,
                        GIMP_CHANNEL_OP_REPLACE, FALSE, 0);
      gimp_edit_copy (texture_layer);
      gimp_rect_select (image_ID,
                        margin_x,
                        0,
                        width - margin_x * 2,
                        margin_y,
                        GIMP_CHANNEL_OP_REPLACE, FALSE, 0);
      gimp_edit_fill (layer, GIMP_PATTERN_FILL);

      /* bottom */
      gimp_rect_select (texture_image,
                        margin_x,
                        texture_height - margin_y,
                        texture_width - margin_x * 2,
                        texture_height,
                        GIMP_CHANNEL_OP_REPLACE, FALSE, 0);
      gimp_edit_copy (texture_layer);
      gimp_rect_select (image_ID,
                        margin_x,
                        height - margin_y,
                        width - margin_x * 2,
                        height,
                        GIMP_CHANNEL_OP_REPLACE, FALSE, 0);
      gimp_edit_fill (layer, GIMP_PATTERN_FILL);
    }

    if (height > margin_y * 2) {
      /* left */
      gimp_rect_select (texture_image,
                        0,
                        margin_y,
                        margin_x,
                        texture_height - margin_y * 2,
                        GIMP_CHANNEL_OP_REPLACE, FALSE, 0);
      gimp_edit_copy (texture_layer);
      gimp_rect_select (image_ID,
                        0,
                        margin_y,
                        margin_x,
                        height - margin_y * 2,
                        GIMP_CHANNEL_OP_REPLACE, FALSE, 0);
      gimp_edit_fill (layer, GIMP_PATTERN_FILL);

      /* right */
      gimp_rect_select (texture_image,
                        texture_width - margin_x,
                        margin_y,
                        margin_x,
                        texture_height - margin_y * 2,
                        GIMP_CHANNEL_OP_REPLACE, FALSE, 0);
      gimp_edit_copy (texture_layer);
      gimp_rect_select (image_ID,
                        width - margin_x,
                        margin_y,
                        margin_x,
                        height - margin_y * 2,
                        GIMP_CHANNEL_OP_REPLACE, FALSE, 0);
      gimp_edit_fill (layer, GIMP_PATTERN_FILL);
    }

    /* top left */
    gimp_rect_select (texture_image,
                      0,
                      0,
                      margin_x,
                      margin_y,
                      GIMP_CHANNEL_OP_REPLACE, FALSE, 0);
    gimp_edit_copy (texture_layer);
    gimp_rect_select (image_ID,
                      0,
                      0,
                      margin_x,
                      margin_y,
                      GIMP_CHANNEL_OP_REPLACE, FALSE, 0);
    gimp_edit_fill (layer, GIMP_PATTERN_FILL);

    /* top right */
    gimp_rect_select (texture_image,
                      texture_width - margin_x,
                      0,
                      margin_x,
                      margin_y,
                      GIMP_CHANNEL_OP_REPLACE, FALSE, 0);
    gimp_edit_copy (texture_layer);
    gimp_rect_select (image_ID,
                      width - margin_x,
                      0,
                      margin_x,
                      margin_y,
                      GIMP_CHANNEL_OP_REPLACE, FALSE, 0);
    gimp_edit_fill (layer, GIMP_PATTERN_FILL);

    /* bottom left */
    gimp_rect_select (texture_image,
                      0,
                      texture_height - margin_y,
                      margin_x,
                      margin_y,
                      GIMP_CHANNEL_OP_REPLACE, FALSE, 0);
    gimp_edit_copy (texture_layer);
    gimp_rect_select (image_ID,
                      0,
                      height - margin_y,
                      margin_x,
                      margin_y,
                      GIMP_CHANNEL_OP_REPLACE, FALSE, 0);
    gimp_edit_fill (layer, GIMP_PATTERN_FILL);

    /* bottom right */
    gimp_rect_select (texture_image,
                      texture_width - margin_x,
                      texture_height - margin_y,
                      margin_x,
                      margin_y,
                      GIMP_CHANNEL_OP_REPLACE, FALSE, 0);
    gimp_edit_copy (texture_layer);
    gimp_rect_select (image_ID,
                      width - margin_x,
                      height - margin_y,
                      margin_x,
                      margin_y,
                      GIMP_CHANNEL_OP_REPLACE, FALSE, 0);
    gimp_edit_fill (layer, GIMP_PATTERN_FILL);

    gimp_image_merge_down(image_ID, layer, GIMP_CLIP_TO_IMAGE);

    gimp_selection_none (image_ID);
  }
}
Exemplo n.º 14
0
static gboolean apply_resize(resize_settings settings, image_output out)
{
    gboolean success = FALSE;
    gint final_w, final_h;
    gdouble orig_res_x, orig_res_y;

    if (settings->change_res) {
        success = gimp_image_get_resolution(
                      out->image_id,
                      &orig_res_x,
                      &orig_res_y
                  );

        if ((settings->new_res_x != orig_res_x) || (settings->new_res_y != orig_res_y)) {
            /* change resolution */
            success = gimp_image_set_resolution(
                          out->image_id,
                          settings->new_res_x,
                          settings->new_res_y
                      );
        }
    }


    if (settings->resize_mode == RESIZE_PERCENT) {
        /* user selected a percentage of the original size */
        final_w = round((gimp_image_width(out->image_id) * settings->new_w_pc) / 100.0);
        final_h = round((gimp_image_height(out->image_id) * settings->new_h_pc) / 100.0);
    }
    else {
        /* user typed exact pixel size */
        if (settings->resize_mode == RESIZE_PIXEL_WIDTH) {
            /* width only */
            final_w = settings->new_w_px;
            if (settings->aspect_ratio) {
                /* and maintain aspect ratio */
                final_h = round(((float)settings->new_w_px * gimp_image_height(out->image_id)) / gimp_image_width(out->image_id));
            }
            else {
                final_h = gimp_image_height(out->image_id);
            }
        }
        else if (settings->resize_mode == RESIZE_PIXEL_HEIGHT) {
            /* height only */
            final_h = settings->new_h_px;
            if (settings->aspect_ratio) {
                /* and maintain aspect ratio */
                final_w = round(((float)settings->new_h_px * gimp_image_width(out->image_id)) / gimp_image_height(out->image_id));
            }
            else {
                final_w = gimp_image_width(out->image_id);
            }
        }
        else {
            /* both dimensions are defined */
            if (settings->aspect_ratio) {
                // Find which new dimension is the smallest percentage of the existing image dimension
                gdouble newwpct = (float)settings->new_w_px / (float)gimp_image_width(out->image_id);
                gdouble newhpct = (float)settings->new_h_px / (float)gimp_image_height(out->image_id);
                gdouble newpct = (newwpct < newhpct) ? newwpct : newhpct;

                final_w = round((float)gimp_image_width(out->image_id) * newpct);
                final_h = round((float)gimp_image_height(out->image_id) * newpct);
            }
            else {
                final_w = settings->new_w_px;
                final_h = settings->new_h_px;
            }
        }
    }

    /* do resize */
#if defined _WIN32 || (!defined _WIN32 && (GIMP_MAJOR_VERSION == 2) && (GIMP_MINOR_VERSION <= 6))

    success = gimp_image_scale_full (
                  out->image_id,
                  final_w,
                  final_h,
                  settings->interpolation
              );

#else

    /* starting from 2.8, gimp_image_scale_full is deprecated.
    * use gimp_image_scale instead */
    GimpInterpolationType oldInterpolation;
    oldInterpolation = gimp_context_get_interpolation();

    success = gimp_context_set_interpolation (settings->interpolation);

    success = gimp_image_scale (
                  out->image_id,
                  final_w,
                  final_h
              );

    success = gimp_context_set_interpolation (oldInterpolation);

#endif

    return success;
}
Exemplo n.º 15
0
gint
gap_resi_dialog (gint32 image_id, GapRangeOpsAsiz asiz_mode, char *title_text,
               long *size_x, long *size_y,
               long *offs_x, long *offs_y)
{
  gint   l_run;

  GapResizePrivateType *res_private;
  GtkWidget *hbbox;
  GtkWidget *button;
  GtkWidget *vbox;


  GtkWidget     *main_vbox;
  GtkWidget     *table;
  GtkWidget     *table2;
  GtkWidget     *table3;
  GtkWidget     *label;
  GtkWidget     *frame;
  GtkWidget     *spinbutton;
  GtkWidget     *abox;

  gdouble l_max_image_width;
  gdouble l_max_image_height;
  gdouble l_max_ratio_x;
  gdouble l_max_ratio_y;


  abox  = NULL;
  frame = NULL;

  /*  Initialize the GapResizePrivateType structure  */
  res_private = (GapResizePrivateType *) g_malloc (sizeof (GapResizePrivateType));
  res_private->image_id = image_id;
  res_private->run = FALSE;
  res_private->in_call = FALSE;
  res_private->asiz_mode = asiz_mode;

  /* get info about the image (size is common to all frames) */
  res_private->orig_width = gimp_image_width(image_id);
  res_private->orig_height = gimp_image_height(image_id);
  res_private->width = res_private->orig_width;
  res_private->height = res_private->orig_height;
  res_private->offset_x = 0;
  res_private->offset_y = 0;
  res_private->ratio_x = 1.0;
  res_private->ratio_y = 1.0;


  l_max_image_width = GIMP_MAX_IMAGE_SIZE;
  l_max_image_height = GIMP_MAX_IMAGE_SIZE;
  l_max_ratio_x = (gdouble) GIMP_MAX_IMAGE_SIZE / (double) res_private->width;
  l_max_ratio_y = (gdouble) GIMP_MAX_IMAGE_SIZE / (double) res_private->height;

  /* for CROP mode only: set sizelimit to original width/height */
  if(res_private->asiz_mode == GAP_ASIZ_CROP)
  {
    l_max_image_width = res_private->orig_width;
    l_max_image_height = res_private->orig_height;
    l_max_ratio_x = 1.0;
    l_max_ratio_y = 1.0;
  }

  res_private->offset_area = NULL;

  gimp_ui_init ("gap_res_dialog", FALSE);


  /*  the dialog  */
  res_private->shell = gtk_dialog_new ();
  res_private->dlg = res_private->shell;
  gtk_window_set_title (GTK_WINDOW (res_private->shell), title_text);
  gtk_window_set_position (GTK_WINDOW (res_private->shell), GTK_WIN_POS_MOUSE);
  g_signal_connect (G_OBJECT (res_private->shell), "destroy",
                    G_CALLBACK (p_res_cancel_callback),
                    NULL);

  switch(res_private->asiz_mode)
  {
    case GAP_ASIZ_SCALE:
      frame        = gimp_frame_new (_("Scale Frames"));
      break;
    case GAP_ASIZ_RESIZE:
      frame        = gimp_frame_new (_("Resize Frames"));
      break;
    case GAP_ASIZ_CROP:
      frame        = gimp_frame_new (_("Crop Frames"));
      break;
  }

  /*  the main vbox  */
  main_vbox = gtk_vbox_new (FALSE, 4);
  gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 4);
  /* gtk_container_add (GTK_CONTAINER (GTK_DIALOG (res_private->shell)->vbox), main_vbox);
   */
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (res_private->shell)->vbox), main_vbox, TRUE, TRUE, 0);

  /* button hbox */
  gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (res_private->shell)->action_area), 2);
  gtk_box_set_homogeneous (GTK_BOX (GTK_DIALOG (res_private->shell)->action_area), FALSE);

  hbbox = gtk_hbutton_box_new ();
  gtk_box_set_spacing (GTK_BOX (hbbox), 4);
  gtk_box_pack_end (GTK_BOX (GTK_DIALOG (res_private->shell)->action_area), hbbox, FALSE, FALSE, 0);
  gtk_widget_show (hbbox);

  /*  the pixel dimensions frame  */
  gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
  gtk_widget_show (frame);

  vbox = gtk_vbox_new (FALSE, 2);
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
  gtk_container_add (GTK_CONTAINER (frame), vbox);

  table = gtk_table_new (6, 2, FALSE);
  gtk_container_set_border_width (GTK_CONTAINER (table), 2);
  gtk_table_set_col_spacings (GTK_TABLE (table), 2);
  gtk_table_set_col_spacing (GTK_TABLE (table), 0, 4);
  gtk_table_set_row_spacings (GTK_TABLE (table), 2);
  gtk_table_set_row_spacing (GTK_TABLE (table), 0, 4);
  gtk_table_set_row_spacing (GTK_TABLE (table), 1, 4);
  gtk_table_set_row_spacing (GTK_TABLE (table), 3, 4);
  gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);


  /*  the original width & height labels  */
  label = gtk_label_new (_("Current width:"));
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  gtk_widget_show (label);

  label = gtk_label_new (_("Current height:"));
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  gtk_widget_show (label);


  /*  the original width & height Values labels  */
  res_private->orig_width_label = gtk_label_new ("");
  gtk_misc_set_alignment (GTK_MISC (res_private->orig_width_label), 0.0, 0.5);
  gtk_table_attach (GTK_TABLE (table),  res_private->orig_width_label, 1, 2, 0, 1,
                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  gtk_widget_show (res_private->orig_width_label);

  res_private->orig_height_label = gtk_label_new ("");
  gtk_misc_set_alignment (GTK_MISC (res_private->orig_height_label), 0.0, 0.5);
  gtk_table_attach (GTK_TABLE (table), res_private->orig_height_label, 1, 2, 1, 2,
                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  gtk_widget_show (res_private->orig_height_label);


  /*  the new size labels  */
  label = gtk_label_new (_("New width:"));
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  gtk_widget_show (label);

  label = gtk_label_new (_("New height:"));
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4,
                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  gtk_widget_show (label);


  /* the spinbutton entry new_width */
  spinbutton = gimp_spin_button_new (&res_private->width_adj,
                                     res_private->orig_width,
                                     GIMP_MIN_IMAGE_SIZE,
                                     l_max_image_width,
                                     1, 10, 0,
                                     1, 2);
  gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), SB_WIDTH);

  gtk_widget_show (spinbutton);

  gtk_table_attach (GTK_TABLE (table), spinbutton, 1, 2, 2, 3,
                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  g_signal_connect (res_private->width_adj, "value_changed",
                    G_CALLBACK (p_size_callback),
                    res_private);


  /* the spinbutton entry new_height */
  spinbutton = gimp_spin_button_new (&res_private->height_adj,
                                     res_private->orig_height,
                                     GIMP_MIN_IMAGE_SIZE,
                                     l_max_image_height,
                                     1, 10, 0,
                                     1, 2);
  gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), SB_WIDTH);

  gtk_widget_show (spinbutton);

  gtk_table_attach (GTK_TABLE (table), spinbutton, 1, 2, 3, 4,
                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  g_signal_connect (res_private->height_adj, "value_changed",
                    G_CALLBACK (p_size_callback),
                    res_private);


  /*  initialize the original width & height labels  */
  p_orig_labels_update(NULL, res_private);


  /*  the scale ratio labels  */
  label = gtk_label_new (_("X ratio:"));
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 4, 5,
                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  gtk_widget_show (label);

  label = gtk_label_new (_("Y ratio:"));
  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
  gtk_table_attach (GTK_TABLE (table), label, 0, 1, 5, 6,
                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  gtk_widget_show (label);

  /*  a (2nd) table for the spinbuttons and the chainbutton  */
  abox = gtk_alignment_new (0.0, 0.5, 0.0, 1.0);
  table2 = gtk_table_new (2, 2, FALSE);
  gtk_table_set_col_spacing (GTK_TABLE (table2), 0, 2);
  gtk_table_set_row_spacing (GTK_TABLE (table2), 0, 2);
  gtk_container_add (GTK_CONTAINER (abox), table2);
  gtk_table_attach (GTK_TABLE (table), abox, 1, 2, 4, 6,
                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
  gtk_widget_show (abox);

  /* the spinbutton entry X-scale ratio */
  spinbutton =
    gimp_spin_button_new (&res_private->ratio_x_adj,
                          res_private->ratio_x,
                          (double) GIMP_MIN_IMAGE_SIZE / (double) res_private->width,
                          (double) l_max_ratio_x,
                          0.01, 0.1, 0,
                          0.01, 4);
  gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), SB_WIDTH);
  gtk_table_attach_defaults (GTK_TABLE (table2), spinbutton, 0, 1, 0, 1);
  gtk_widget_show (spinbutton);

  g_signal_connect (res_private->ratio_x_adj, "value_changed",
                    G_CALLBACK (p_ratio_callback),
                    res_private);

  /* the spinbutton entry Y-scale ratio */
  spinbutton =
    gimp_spin_button_new (&res_private->ratio_y_adj,
                          res_private->ratio_y,
                          (double) GIMP_MIN_IMAGE_SIZE / (double) res_private->height,
                          (double) l_max_ratio_y,
                          0.01, 0.1, 0,
                          0.01, 4);
  gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), SB_WIDTH);
  gtk_table_attach_defaults (GTK_TABLE (table2), spinbutton, 0, 1, 1, 2);
  gtk_widget_show (spinbutton);

  g_signal_connect (res_private->ratio_y_adj, "value_changed",
                    G_CALLBACK (p_ratio_callback),
                    res_private);


  /*  the constrain ratio chainbutton  */
  res_private->constrain = gimp_chain_button_new (GIMP_CHAIN_RIGHT);
  gimp_chain_button_set_active (GIMP_CHAIN_BUTTON (res_private->constrain), TRUE);
  gtk_table_attach_defaults (GTK_TABLE (table2), res_private->constrain, 1, 2, 0, 2);
  gtk_widget_show (res_private->constrain);

  gimp_help_set_help_data (GIMP_CHAIN_BUTTON (res_private->constrain)->button,
                           _("Constrain aspect ratio"), NULL);

  /* the state of the contrain ratio chainbutton is checked in other callbacks (where needed)
   * there is no need for the chainbutton to have its own callback procedure
   */


  gtk_widget_show (table2);
  gtk_widget_show (table);
  gtk_widget_show (vbox);


  /* code for GAP_ASIZ_RESIZE GAP_ASIZ_CROP using offsets, GAP_ASIZ_SCALE does not */
  if(res_private->asiz_mode != GAP_ASIZ_SCALE)
  {
    /*  the offset frame  */
    frame = gimp_frame_new (_("Offset"));
    gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
    gtk_widget_show (frame);

    vbox = gtk_vbox_new (FALSE, 4);
    gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
    gtk_container_add (GTK_CONTAINER (frame), vbox);

    abox = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
    gtk_box_pack_start (GTK_BOX (vbox), abox, FALSE, FALSE, 0);

    /*  a (3rd) table for the offset spinbuttons  */
    table3 = gtk_table_new (2, 3, FALSE);
    gtk_table_set_col_spacing (GTK_TABLE (table3), 0, 2);
    gtk_table_set_row_spacing (GTK_TABLE (table3), 0, 2);

    /* gtk_container_add (GTK_CONTAINER (abox), table3); */

    /* the x/y offest labels */
    label = gtk_label_new (_("X:"));
    gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
    gtk_table_attach (GTK_TABLE (table3), label, 0, 1, 0, 1,
                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
    gtk_widget_show (label);

    label = gtk_label_new (_("Y:"));
    gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
    gtk_table_attach (GTK_TABLE (table3), label, 0, 1, 1, 2,
                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
    gtk_widget_show (label);

    /* the spinbutton entry offset_x */
    spinbutton = gimp_spin_button_new (&res_private->offset_x_adj,
                                         0,
                                         -GIMP_MAX_IMAGE_SIZE,
                                         GIMP_MAX_IMAGE_SIZE,
                                         1, 10, 0,
                                         1, 2);
    gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), SB_WIDTH);
    gtk_table_attach (GTK_TABLE (table3), spinbutton, 1, 2, 0, 1,
                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
    gtk_widget_show (spinbutton);


    g_signal_connect (res_private->offset_x_adj, "value_changed",
                     G_CALLBACK (p_offset_update),
                     res_private);

    /* the spinbutton entry offset_y */
    spinbutton = gimp_spin_button_new (&res_private->offset_y_adj,
                                         0,
                                         -GIMP_MAX_IMAGE_SIZE,
                                         GIMP_MAX_IMAGE_SIZE,
                                         1, 10, 0,
                                         1, 2);
    gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), SB_WIDTH);
    gtk_table_attach (GTK_TABLE (table3), spinbutton, 1, 2, 1, 2,
                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
    gtk_widget_show (spinbutton);

    g_signal_connect (res_private->offset_y_adj, "value_changed",
                     G_CALLBACK (p_offset_update),
                     res_private);


    /* the center offsetX button */
    button = gtk_button_new_with_label (_("Center Horizontal"));
    gtk_widget_show (button);
    gtk_table_attach (GTK_TABLE (table3), button, 2, 3, 0, 1,
                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);

    g_signal_connect (button, "clicked",
                      G_CALLBACK (p_offset_x_center_clicked),
                      res_private);


    /* the center offsetY button */
    button = gtk_button_new_with_label (_("Center Vertical"));
    gtk_widget_show (button);
    gtk_table_attach (GTK_TABLE (table3), button, 2, 3, 1, 2,
                    GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);

    g_signal_connect (button, "clicked",
                      G_CALLBACK (p_offset_y_center_clicked),
                      res_private);

    gtk_container_add (GTK_CONTAINER (abox), table3);
    gtk_widget_show (table3);
    gtk_widget_show (abox);


    /*  frame to hold GimpOffsetArea  */
    abox = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
    gtk_box_pack_start (GTK_BOX (vbox), abox, FALSE, FALSE, 0);

    frame = gimp_frame_new (NULL);
    gtk_container_add (GTK_CONTAINER (abox), frame);

    /* the GimpOffsetArea widget */
    res_private->offset_area = gimp_offset_area_new (res_private->orig_width
                                                   , res_private->orig_height);
    gtk_container_add (GTK_CONTAINER (frame), res_private->offset_area);

    gtk_widget_show (res_private->offset_area);
    g_signal_connect (res_private->offset_area, "offsets_changed",
                        G_CALLBACK (p_offset_area_offsets_changed),
                        res_private);

    gtk_widget_show (frame);
    gtk_widget_show (abox);
    gtk_widget_show (vbox);
  }


  /*  Action area  */

  if (gimp_show_help_button ())
    {
      button = gtk_button_new_from_stock ( GTK_STOCK_HELP);
      gtk_box_pack_end (GTK_BOX (hbbox), button, TRUE, TRUE, 0);
      gtk_widget_show (button);
      g_signal_connect (GTK_OBJECT (button), "clicked",
                        G_CALLBACK  (p_res_help_callback),
                        res_private);
    }

  button = gtk_button_new_from_stock ( GIMP_STOCK_RESET);
  gtk_box_pack_start (GTK_BOX (hbbox), button, TRUE, TRUE, 0);
  gtk_widget_show (button);
  g_signal_connect (GTK_OBJECT (button), "clicked",
                    G_CALLBACK  (p_res_reset_callback),
                    res_private);

  button = gtk_button_new_from_stock ( GTK_STOCK_CANCEL);
  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
  gtk_box_pack_start (GTK_BOX (hbbox), button, TRUE, TRUE, 0);
  gtk_widget_show (button);
  g_signal_connect (G_OBJECT (button), "clicked",
                    G_CALLBACK  (p_res_cancel_callback),
                    NULL);

  button = gtk_button_new_from_stock ( GTK_STOCK_OK);
  GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
  gtk_box_pack_start (GTK_BOX (hbbox), button, TRUE, TRUE, 0);
  gtk_widget_grab_default (button);
  gtk_widget_show (button);
  g_signal_connect (GTK_OBJECT (button), "clicked",
                    G_CALLBACK  (p_res_ok_callback),
                    res_private);


  gtk_widget_show (main_vbox);
  gtk_widget_show (res_private->shell);

  gtk_main ();
  gdk_flush ();



  *size_x  = res_private->width;
  *size_y  = res_private->height;
  *offs_x  = res_private->offset_x;
  *offs_y  = res_private->offset_y;

  if(res_private->asiz_mode == GAP_ASIZ_CROP)
  {
     /* the widgets deliver negative offsets when new size is smaller
      * than original (as needed for gimp_image_resize calls)
      * but gimp_image_crop needs positive offets
      * therefore the sign is switched just for CROP operations
      */
     *offs_x  = - res_private->offset_x;
     *offs_y  = - res_private->offset_y;
  }

  l_run = res_private->run;
  g_free(res_private);
  return (l_run);

}  /* end gap_resi_dialog */
Exemplo n.º 16
0
static gint32
do_optimizations (GimpRunMode run_mode,
                  gboolean    diff_only)
{
  GimpPixelRgn   pixel_rgn;
  static guchar *rawframe = NULL;
  guchar        *srcptr;
  guchar        *destptr;
  gint           row, this_frame_num;
  guint32        frame_sizebytes;
  gint32         new_layer_id;
  DisposeType    dispose;
  guchar        *this_frame = NULL;
  guchar        *last_frame = NULL;
  guchar        *opti_frame = NULL;
  guchar        *back_frame = NULL;

  gint           this_delay;
  gint           cumulated_delay = 0;
  gint           last_true_frame = -1;
  gint           buflen;

  gchar         *oldlayer_name;
  gchar         *newlayer_name;

  gboolean       can_combine;

  gint32         bbox_top, bbox_bottom, bbox_left, bbox_right;
  gint32         rbox_top, rbox_bottom, rbox_left, rbox_right;

  switch (opmode)
    {
    case OPUNOPTIMIZE:
      gimp_progress_init (_("Unoptimizing animation"));
      break;
    case OPFOREGROUND:
      gimp_progress_init (_("Removing animation background"));
      break;
    case OPBACKGROUND:
      gimp_progress_init (_("Finding animation background"));
      break;
    case OPOPTIMIZE:
    default:
      gimp_progress_init (_("Optimizing animation"));
      break;
    }

  width     = gimp_image_width (image_id);
  height    = gimp_image_height (image_id);
  layers    = gimp_image_get_layers (image_id, &total_frames);
  imagetype = gimp_image_base_type (image_id);
  pixelstep = (imagetype == GIMP_RGB) ? 4 : 2;

  /*  gimp_tile_cache_ntiles(total_frames * (width / gimp_tile_width() + 1) );*/


  drawabletype_alpha = (imagetype == GIMP_RGB) ? GIMP_RGBA_IMAGE :
    ((imagetype == GIMP_INDEXED) ? GIMP_INDEXEDA_IMAGE : GIMP_GRAYA_IMAGE);

  frame_sizebytes = width * height * pixelstep;

  this_frame = g_malloc (frame_sizebytes);
  last_frame = g_malloc (frame_sizebytes);
  opti_frame = g_malloc (frame_sizebytes);

  if (opmode == OPBACKGROUND ||
      opmode == OPFOREGROUND)
    back_frame = g_malloc (frame_sizebytes);

  total_alpha (this_frame, width*height, pixelstep);
  total_alpha (last_frame, width*height, pixelstep);

  new_image_id = gimp_image_new(width, height, imagetype);
  gimp_image_undo_disable (new_image_id);

  if (imagetype == GIMP_INDEXED)
    {
      palette = gimp_image_get_colormap (image_id, &ncolours);
      gimp_image_set_colormap (new_image_id, palette, ncolours);
    }

#if 1
  if (opmode == OPBACKGROUND ||
      opmode == OPFOREGROUND)
    {
      /* iterate through all rows of all frames, find statistical
         mode for each pixel position. */
      gint     i,j;
      guchar **these_rows;
      guchar **red;
      guchar **green;
      guchar **blue;
      guint  **count;
      guint   *num_colours;

      these_rows = g_new (guchar *, total_frames);
      red =        g_new (guchar *, total_frames);
      green =      g_new (guchar *, total_frames);
      blue =       g_new (guchar *, total_frames);
      count =      g_new (guint *, total_frames);

      num_colours = g_new (guint, width);

      for (this_frame_num=0; this_frame_num<total_frames; this_frame_num++)
        {
          these_rows[this_frame_num] = g_malloc(width * pixelstep);

          red[this_frame_num]   = g_new (guchar, width);
          green[this_frame_num] = g_new (guchar, width);
          blue[this_frame_num]  = g_new (guchar, width);

          count[this_frame_num] = g_new0(guint, width);
        }

      for (row = 0; row < height; row++)
        {
          memset(num_colours, 0, width * sizeof(guint));

          for (this_frame_num=0; this_frame_num<total_frames; this_frame_num++)
            {
              drawable =
                gimp_drawable_get (layers[total_frames-(this_frame_num+1)]);

              dispose = get_frame_disposal (this_frame_num);

              compose_row(this_frame_num,
                          dispose,
                          row,
                          these_rows[this_frame_num],
                          width,
                          drawable,
                          FALSE
                          );

              gimp_drawable_detach(drawable);
            }

          for (this_frame_num=0; this_frame_num<total_frames; this_frame_num++)
            {
              for (i=0; i<width; i++)
                {
                  if (these_rows[this_frame_num][i * pixelstep + pixelstep -1]
                      >= 128)
                    {
                      for (j=0; j<num_colours[i]; j++)
                        {

                          switch (pixelstep)
                            {
                            case 4:
                              if (these_rows[this_frame_num][i * 4 +0] ==
                                  red[j][i] &&
                                  these_rows[this_frame_num][i * 4 +1] ==
                                  green[j][i] &&
                                  these_rows[this_frame_num][i * 4 +2] ==
                                  blue[j][i])
                                {
                                  (count[j][i])++;
                                  goto same;
                                }
                              break;
                            case 2:
                              if (these_rows[this_frame_num][i * 2 +0] ==
                                  red[j][i])
                                {
                                  (count[j][i])++;
                                  goto same;
                                }
                              break;
                            default:
                              g_error ("Eeep!");
                              break;
                            }
                        }

                      count[num_colours[i]][i] = 1;
                      red[num_colours[i]][i] =
                        these_rows[this_frame_num][i * pixelstep];
                      if (pixelstep == 4)
                        {
                          green[num_colours[i]][i] =
                            these_rows[this_frame_num][i * 4 +1];
                          blue[num_colours[i]][i] =
                            these_rows[this_frame_num][i * 4 +2];
                        }
                      num_colours[i]++;
                    }
                same:
                  /* nop */;
                }
            }

          for (i=0; i<width; i++)
            {
              guint  best_count = 0;
              guchar best_r = 255, best_g = 0, best_b = 255;

              for (j=0; j<num_colours[i]; j++)
                {
                  if (count[j][i] > best_count)
                    {
                      best_count = count[j][i];
                      best_r = red[j][i];
                      best_g = green[j][i];
                      best_b = blue[j][i];
                    }
                }

              back_frame[width * pixelstep * row +i*pixelstep + 0] = best_r;
              if (pixelstep == 4)
                {
                  back_frame[width * pixelstep * row +i*pixelstep + 1] =
                    best_g;
                  back_frame[width * pixelstep * row +i*pixelstep + 2] =
                    best_b;
                }
              back_frame[width * pixelstep * row +i*pixelstep +pixelstep-1] =
                (best_count == 0) ? 0 : 255;

              if (best_count == 0)
                g_warning("yayyyy!");
            }
          /*      memcpy(&back_frame[width * pixelstep * row],
                  these_rows[0],
                  width * pixelstep);*/
        }

      for (this_frame_num=0; this_frame_num<total_frames; this_frame_num++)
        {
          g_free (these_rows[this_frame_num]);
          g_free (red[this_frame_num]);
          g_free (green[this_frame_num]);
          g_free (blue[this_frame_num]);
          g_free (count[this_frame_num]);
        }

      g_free (these_rows);
      g_free (red);
      g_free (green);
      g_free (blue);
      g_free (count);
      g_free (num_colours);
    }
static gboolean apply_watermark(watermark_settings settings, image_output out) 
{
    gboolean success = TRUE;
    gint32 layerId;
    gdouble posX, posY;
    gint wmwidth, wmheight, wmasc, wmdesc;
    
    if (settings->mode) {
        if (strlen(settings->text) == 0) {
            return TRUE;
        }
        
        GimpRGB old_foreground, new_foreground;
        
        gimp_context_get_foreground(&old_foreground);
        gimp_rgb_parse_hex (&new_foreground, gdk_color_to_string(&(settings->color)), strlen(gdk_color_to_string(&(settings->color))));
        gimp_context_set_foreground(&new_foreground);
        
        gimp_text_get_extents_fontname(
            settings->text,
            pango_font_description_get_size(settings->font) / PANGO_SCALE,
            GIMP_PIXELS,
            pango_font_description_get_family(settings->font),
            &wmwidth,
            &wmheight,
            &wmasc,
            &wmdesc
        );

        if (settings->position == WM_POS_TL) {
            posX = 10;
            posY = 5;
        }
        else if (settings->position == WM_POS_TC) {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = 5;
        }
        else if (settings->position == WM_POS_TR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = 5;
        }
        else if (settings->position == WM_POS_BL) {
            posX = 10;
            posY = gimp_image_height(out->image_id) - wmheight - 5;
        }
        else if (settings->position == WM_POS_BC) {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = gimp_image_height(out->image_id) - wmheight - 5;
        }
        else if (settings->position == WM_POS_BR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = gimp_image_height(out->image_id) - wmheight - 5;
        }
        else if (settings->position == WM_POS_CL) {
            posX = 10;
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        else if (settings->position == WM_POS_CR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        else {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        
        layerId = gimp_text_fontname(
            out->image_id,
            -1,
            posX,
            posY,
            settings->text,
            -1,
            TRUE,
            pango_font_description_get_size(settings->font) / PANGO_SCALE,
            GIMP_PIXELS,
            pango_font_description_get_family(settings->font)
        );
        gimp_context_set_foreground(&old_foreground);
        gimp_layer_set_opacity(layerId, settings->opacity);
    }
    else {
        if (!g_file_test(settings->image_file, G_FILE_TEST_IS_REGULAR)) {//((access(settings->image_file, R_OK) == -1)) {
            // error, can't access image file
            return TRUE;
        }
        
        layerId = gimp_file_load_layer(
            GIMP_RUN_NONINTERACTIVE,
            out->image_id,
            settings->image_file
        );
        
        gimp_layer_set_opacity(layerId, settings->opacity);
        wmwidth = gimp_drawable_width(layerId);
        wmheight = gimp_drawable_height(layerId);
        
        #if USE_API26
        
            gimp_image_add_layer(
                out->image_id,
                layerId,
                0
            );
        
        #else
        
            // starting from 2.8, gimp_image_add_layer is deprecated. 
            // use gimp_image_insert_layer instead
            gimp_image_insert_layer(
                out->image_id,
                layerId,
                0,
                0
            );
            
        #endif
        
        if (settings->position == WM_POS_TL) {
            posX = 10;
            posY = 10;
        }
        else if (settings->position == WM_POS_TC) {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = 10;
        }
        else if (settings->position == WM_POS_TR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = 10;
        }
        else if (settings->position == WM_POS_BL) {
            posX = 10;
            posY = gimp_image_height(out->image_id) - wmheight - 10;
        }
        else if (settings->position == WM_POS_BC) {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = gimp_image_height(out->image_id) - wmheight - 10;
        }
        else if (settings->position == WM_POS_BR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = gimp_image_height(out->image_id) - wmheight - 10;
        }
        else if (settings->position == WM_POS_CL) {
            posX = 10;
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        else if (settings->position == WM_POS_CR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        else {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        
        gimp_layer_set_offsets(
            layerId,
            posX,
            posY
        );   
    }
    
    // refresh all drawables
    g_free(out->drawable_ids);
    out->drawable_ids = gimp_image_get_layers(out->image_id, &out->drawable_count);
    
    return success;
}
Exemplo n.º 18
0
static void
run (const gchar      *name,
     gint              nparams,
     const GimpParam  *param,
     gint             *nreturn_vals,
     GimpParam       **return_vals)
{
  static GimpParam        values[1];
  GimpPDBStatusType       status = GIMP_PDB_SUCCESS;
  GimpRunMode             run_mode;

  /* Plug-in variables */
  gboolean                single_image;
  gboolean                defaults_proc;

  /* Plug-In variables */
  cairo_surface_t        *pdf_file;
  cairo_t                *cr;
  GimpExportCapabilities  capabilities;

  guint32                 i = 0;
  gint32                  j = 0;

  gdouble                 x_res, y_res;
  gdouble                 x_scale, y_scale;

  gint32                  image_id;
  gboolean                exported;
  GimpImageBaseType       type;

  gint32                  temp;

  gint                   *layers;
  gint32                  num_of_layers;
  GimpDrawable           *layer;
  cairo_surface_t        *layer_image;
  gdouble                 opacity;
  gint                    x, y;
  GimpRGB                 layer_color;
  gboolean                single_color;

  gint32                  mask_id = -1;
  GimpDrawable           *mask = NULL;
  cairo_surface_t        *mask_image = NULL;
  FILE                   *fp;

  INIT_I18N ();

  /* Setting mandatory output values */
  *nreturn_vals = 1;
  *return_vals  = values;

  values[0].type = GIMP_PDB_STATUS;
  values[0].data.d_status = status;

  /* Initializing all the settings */
  multi_page.image_count = 0;

  if (! init_vals (name, nparams, param, &single_image,
             &defaults_proc, &run_mode))
    {
      values[0].data.d_status = GIMP_PDB_CALLING_ERROR;
      return;
    }

  /* Starting the executions */
  if (run_mode == GIMP_RUN_INTERACTIVE)
    {
      if (single_image)
        {
          if (! gui_single ())
            {
              values[0].data.d_status = GIMP_PDB_CANCEL;
              return;
            }
        }
      else if (! gui_multi ())
        {
          values[0].data.d_status = GIMP_PDB_CANCEL;
          return;
        }

      if (file_name == NULL)
        {
          values[0].data.d_status = GIMP_PDB_CALLING_ERROR;
          gimp_message (_("You must select a file to save!"));
          return;
        }
    }

  fp = g_fopen (file_name, "wb");
  pdf_file = cairo_pdf_surface_create_for_stream (write_func, fp, 1, 1);
  if (cairo_surface_status (pdf_file) != CAIRO_STATUS_SUCCESS)
    {
      char *str = g_strdup_printf
        (_("An error occured while creating the PDF file:\n"
           "%s\n"
           "Make sure you entered a valid filename and that the selected location isn't read only!"),
         cairo_status_to_string (cairo_surface_status (pdf_file)));

      gimp_message (str);
      g_free (str);

      values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
      return;
    }
  cr = cairo_create (pdf_file);

  capabilities = GIMP_EXPORT_CAN_HANDLE_RGB | GIMP_EXPORT_CAN_HANDLE_ALPHA |
    GIMP_EXPORT_CAN_HANDLE_GRAY | GIMP_EXPORT_CAN_HANDLE_LAYERS |
    GIMP_EXPORT_CAN_HANDLE_INDEXED;
  if (optimize.apply_masks)
    capabilities |= GIMP_EXPORT_CAN_HANDLE_LAYER_MASKS;

  for (i = 0; i < multi_page.image_count; i++)
    {
      /* Save the state of the surface before any changes, so that settings
       * from one page won't affect all the others */
      cairo_save (cr);

      image_id =  multi_page.images[i];

      /* We need the active layer in order to use gimp_image_export */
      temp = gimp_image_get_active_drawable (image_id);
      if (temp == -1)
        exported = gimp_export_image (&image_id, &temp, NULL, capabilities) == GIMP_EXPORT_EXPORT;
      else
        exported = FALSE;
      type = gimp_image_base_type (image_id);

      gimp_image_get_resolution (image_id, &x_res, &y_res);
      x_scale = 72.0 / x_res;
      y_scale = 72.0 / y_res;

      cairo_pdf_surface_set_size (pdf_file,
                                  gimp_image_width (image_id) * x_scale,
                                  gimp_image_height (image_id) * y_scale);

      /* This way we set how many pixels are there in every inch.
       * It's very important for PangoCairo */
      cairo_surface_set_fallback_resolution (pdf_file, x_res, y_res);

      /* PDF is usually 72 points per inch. If we have a different resolution,
       * we will need this to fit our drawings */
      cairo_scale (cr, x_scale, y_scale);

      /* Now, we should loop over the layers of each image */
      layers = gimp_image_get_layers (image_id, &num_of_layers);

      for (j = 0; j < num_of_layers; j++)
        {
          layer = gimp_drawable_get (layers [num_of_layers-j-1]);
          opacity = gimp_layer_get_opacity (layer->drawable_id)/100.0;

          /* Gimp doesn't display indexed layers with opacity below 50%
           * And if it's above 50%, it will be rounded to 100% */
          if (type == GIMP_INDEXED)
            {
              if (opacity <= 0.5)
                opacity = 0.0;
              else
                opacity = 1.0;
            }

          if (gimp_item_get_visible (layer->drawable_id)
              && (! optimize.ignore_hidden || (optimize.ignore_hidden && opacity > 0.0)))
            {
              mask_id = gimp_layer_get_mask (layer->drawable_id);
              if (mask_id != -1)
                {
                  mask = gimp_drawable_get (mask_id);
                  mask_image = get_drawable_image (mask);
                }

              gimp_drawable_offsets (layer->drawable_id, &x, &y);

              /* For raster layers */
              if (!gimp_item_is_text_layer (layer->drawable_id))
                {
                  layer_color = get_layer_color (layer, &single_color);
                  cairo_rectangle (cr, x, y, layer->width, layer->height);

                  if (optimize.vectorize && single_color)
                    {
                      cairo_set_source_rgba (cr, layer_color.r, layer_color.g, layer_color.b, layer_color.a * opacity);
                      if (mask_id != -1)
                        cairo_mask_surface (cr, mask_image, x, y);
                      else
                        cairo_fill (cr);
                    }
                  else
                    {
                      cairo_clip (cr);
                      layer_image = get_drawable_image (layer);
                      cairo_set_source_surface (cr, layer_image, x, y);
                      cairo_push_group (cr);
                      cairo_paint_with_alpha (cr, opacity);
                      cairo_pop_group_to_source (cr);
                      if (mask_id != -1)
                        cairo_mask_surface (cr, mask_image, x, y);
                      else
                        cairo_paint (cr);
                      cairo_reset_clip (cr);

                      cairo_surface_destroy (layer_image);
                    }
                }
              /* For text layers */
              else
                {
                  drawText (layer, opacity, cr, x_res, y_res);
                }
            }

          /* We are done with the layer - time to free some resources */
          gimp_drawable_detach (layer);
          if (mask_id != -1)
            {
              gimp_drawable_detach (mask);
              cairo_surface_destroy (mask_image);
            }
        }
      /* We are done with this image - Show it! */
      cairo_show_page (cr);
      cairo_restore (cr);

      if (exported)
        gimp_image_delete (image_id);
    }

  /* We are done with all the images - time to free the resources */
  cairo_surface_destroy (pdf_file);
  cairo_destroy (cr);

  fclose (fp);
  /* Finally done, let's save the parameters */
  gimp_set_data (DATA_OPTIMIZE, &optimize, sizeof (optimize));
  if (!single_image)
    {
      g_strlcpy (multi_page.file_name, file_name, MAX_FILE_NAME_LENGTH);
      gimp_set_data (DATA_IMAGE_LIST, &multi_page, sizeof (multi_page));
    }

}
Exemplo n.º 19
0
/* Compose a roll film image from several images */
static gint32
film (void)
{
  gint          width, height;
  guchar       *hole;
  gint          film_height, film_width;
  gint          picture_width, picture_height;
  gint          picture_space, picture_x0, picture_y0;
  gint          hole_offset, hole_width, hole_height, hole_space, hole_x;
  gint          number_height, num_images, num_pictures;
  gint          j, k, picture_count;
  gdouble       f;
  gint          num_layers;
  gint32       *image_ID_src, image_ID_dst, layer_ID_src, layer_ID_dst;
  gint          image_ID_tmp;
  gint32       *layers;
  GimpDrawable *drawable_dst;
  GimpPixelRgn  pixel_rgn_dst;
  gint          new_layer;
  gint          floating_sel;

  /* initialize */

  layers = NULL;

  num_images = filmvals.num_images;
  image_ID_src = filmvals.image;

  if (num_images <= 0)
    return (-1);

  gimp_context_push ();
  gimp_context_set_foreground (&filmvals.number_color);
  gimp_context_set_background (&filmvals.film_color);

  if (filmvals.keep_height) /* Search maximum picture height */
    {
      picture_height = 0;
      for (j = 0; j < num_images; j++)
        {
          height = gimp_image_height (image_ID_src[j]);
          if (height > picture_height) picture_height = height;
        }
      film_height = (int)(picture_height / filmvals.picture_height + 0.5);
      filmvals.film_height = film_height;
    }
  else
    {
      film_height = filmvals.film_height;
      picture_height = (int)(film_height * filmvals.picture_height + 0.5);
    }

  picture_space = (int)(film_height * filmvals.picture_space + 0.5);
  picture_y0 = (film_height - picture_height)/2;

  number_height = film_height * filmvals.number_height;

  /* Calculate total film width */
  film_width = 0;
  num_pictures = 0;
  for (j = 0; j < num_images; j++)
    {
      layers = gimp_image_get_layers (image_ID_src[j], &num_layers);
      /* Get scaled image size */
      width = gimp_image_width (image_ID_src[j]);
      height = gimp_image_height (image_ID_src[j]);
      f = ((double)picture_height) / (double)height;
      picture_width = width * f;

      for (k = 0; k < num_layers; k++)
        {
          if (gimp_layer_is_floating_sel (layers[k]))
            continue;

          film_width += (picture_space/2);  /* Leading space */
          film_width += picture_width;      /* Scaled image width */
          film_width += (picture_space/2);  /* Trailing space */
          num_pictures++;
        }

      g_free (layers);
    }

#ifdef FILM_DEBUG
  g_printerr ("film_height = %d, film_width = %d\n", film_height, film_width);
  g_printerr ("picture_height = %d, picture_space = %d, picture_y0 = %d\n",
              picture_height, picture_space, picture_y0);
  g_printerr ("Number of pictures = %d\n", num_pictures);
#endif

  image_ID_dst = create_new_image (_("Untitled"),
                                   (guint) film_width, (guint) film_height,
                                   GIMP_RGB_IMAGE, &layer_ID_dst,
                                   &drawable_dst, &pixel_rgn_dst);

  /* Fill film background */
  gimp_drawable_fill (layer_ID_dst, GIMP_FILL_BACKGROUND);

  /* Draw all the holes */
  hole_offset = film_height * filmvals.hole_offset;
  hole_width = film_height * filmvals.hole_width;
  hole_height = film_height * filmvals.hole_height;
  hole_space = film_height * filmvals.hole_space;
  hole_x = hole_space / 2;

#ifdef FILM_DEBUG
  g_printerr ("hole_x %d hole_offset %d hole_width %d hole_height %d hole_space %d\n",
              hole_x, hole_offset, hole_width, hole_height, hole_space );
#endif

  hole = create_hole_rgb (hole_width, hole_height);
  if (hole)
    {
      while (hole_x < film_width)
        {
          draw_hole_rgb (drawable_dst, hole_x,
                         hole_offset,
                         hole_width, hole_height, hole);
          draw_hole_rgb (drawable_dst, hole_x,
                         film_height-hole_offset-hole_height,
                         hole_width, hole_height, hole);

          hole_x += hole_width + hole_space;
        }
      g_free (hole);
    }
  gimp_drawable_detach (drawable_dst);


  /* Compose all images and layers */
  picture_x0 = 0;
  picture_count = 0;
  for (j = 0; j < num_images; j++)
    {
      image_ID_tmp = gimp_image_duplicate (image_ID_src[j]);
      width = gimp_image_width (image_ID_tmp);
      height = gimp_image_height (image_ID_tmp);
      f = ((gdouble) picture_height) / (gdouble) height;
      picture_width = width * f;
      if (gimp_image_base_type (image_ID_tmp) != GIMP_RGB)
        gimp_image_convert_rgb (image_ID_tmp);
      gimp_image_scale (image_ID_tmp, picture_width, picture_height);

      layers = gimp_image_get_layers (image_ID_tmp, &num_layers);
      for (k = 0; k < num_layers; k++)
        {
          if (gimp_layer_is_floating_sel (layers[k]))
            continue;

          picture_x0 += picture_space / 2;

          layer_ID_src = layers[k];
          gimp_layer_resize_to_image_size (layer_ID_src);
          new_layer = gimp_layer_new_from_drawable (layer_ID_src,
                                                    image_ID_dst);
          gimp_image_insert_layer (image_ID_dst, new_layer, -1, -1);
          gimp_layer_set_offsets (new_layer, picture_x0, picture_y0);

          /* Draw picture numbers */
          if ((number_height > 0) &&
              (filmvals.number_pos[0] || filmvals.number_pos[1]))
            {
              if (filmvals.number_pos[0])
                draw_number (layer_ID_dst,
                             filmvals.number_start + picture_count,
                             picture_x0 + picture_width/2,
                             (hole_offset-number_height)/2, number_height);
              if (filmvals.number_pos[1])
                draw_number (layer_ID_dst,
                             filmvals.number_start + picture_count,
                             picture_x0 + picture_width/2,
                             film_height - (hole_offset + number_height)/2,
                             number_height);
            }

          picture_x0 += picture_width + (picture_space/2);

          gimp_progress_update (((gdouble) (picture_count + 1)) /
                                (gdouble) num_pictures);

          picture_count++;
        }

      g_free (layers);
      gimp_image_delete (image_ID_tmp);
    }
  gimp_progress_update (1.0);

  gimp_image_flatten (image_ID_dst);

  /* Drawing text/numbers leaves us with a floating selection. Stop it */
  floating_sel = gimp_image_get_floating_sel (image_ID_dst);
  if (floating_sel != -1)
    gimp_floating_sel_anchor (floating_sel);

  gimp_context_pop ();

  return image_ID_dst;
}
Exemplo n.º 20
0
/* ----------------------------
 * p_coords_logging
 * ----------------------------
 * log coordinates to stdout
 * or to move-path controlpoint XML file.
 *
 */
static void
p_coords_logging(gint32 frameNr, PixelCoords *currCoords,  PixelCoords *currCoords2
                 , PixelCoords *startCoords, PixelCoords *startCoords2, FilterValues *valPtr
                 , gint32 imageId
                )
{
    gint32  px;
    gint32  py;
    gint32  px1;
    gint32  py1;
    gint32  px2;
    gint32  py2;
    gdouble rotation;
    gchar  *logString;
    gdouble scaleFactor;
    gboolean center;
    gint     width;
    gint     height;
    gint     precision_digits;
    gchar   *rotValueAsString;

    if(currCoords->valid != TRUE)
    {
        /* do not record invalid coordinates */
        return;
    }

    width = gimp_image_width(imageId);
    height = gimp_image_height(imageId);
    center = FALSE;
    if ((valPtr->coordsRelToFrame1)
            &&  (valPtr->offsX != 0)
            &&  (valPtr->offsY != 0))
    {
        center = TRUE;
    }

    scaleFactor = 1.0;
    rotation = 0.0;
    px1 = currCoords->px;
    py1 = currCoords->py;

    px2 = currCoords2->px;
    py2 = currCoords2->py;

    if ((valPtr->coordsRelToFrame1)
            &&  (startCoords->valid == TRUE))
    {
        px1 = startCoords->px -px1;
        py1 = startCoords->py -py1;
    }


    px = px1 + valPtr->offsX;
    py = py1 + valPtr->offsY;

    if ((valPtr->coordsRelToFrame1)
            &&  (startCoords2->valid == TRUE))
    {
        px2 = startCoords2->px -px2;
        py2 = startCoords2->py -py2;

    }

    if((currCoords2->valid  == TRUE)
            && (startCoords2->valid == TRUE)
            && (startCoords->valid  == TRUE))
    {
        gdouble startAngle;
        gdouble currAngle;

        /* we have 2 valid coordinate points and can calculate rotate compensation
         * in this case movement offest compensation is the average
         * of both tracked coordinate points
         */
        px = ((px1 + px2) / 2) + valPtr->offsX;
        py = ((py1 + py2) / 2) + valPtr->offsY;


        startAngle = p_calculate_angle_in_degree( startCoords->px
                     , startCoords->py
                     , startCoords2->px
                     , startCoords2->py
                                                );
        currAngle = p_calculate_angle_in_degree(  currCoords->px
                    , currCoords->py
                    , currCoords2->px
                    , currCoords2->py
                                               );
        rotation = startAngle - currAngle;
        if (rotation >= 360.0)
        {
            rotation = 360.0 - rotation;
        }
        if (rotation <= -360.0)
        {
            rotation += 360.0;
        }
        scaleFactor = p_calculate_scale_factor( startCoords->px
                                                , startCoords->py
                                                , startCoords2->px
                                                , startCoords2->py
                                                , currCoords->px
                                                , currCoords->py
                                                , currCoords2->px
                                                , currCoords2->py
                                              );
    }

    logString = NULL;

    if(currCoords2->valid == TRUE)
    {
        /* double point detail coordinate tracking (allows calculation of rotate and scale factors) */
        gchar *scaleValueAsString;


        precision_digits = 7;
        rotValueAsString = gap_base_gdouble_to_ascii_string(rotation + valPtr->offsRotate, precision_digits);
        precision_digits = 5;
        scaleValueAsString = gap_base_gdouble_to_ascii_string(scaleFactor * 100, precision_digits);

        if(valPtr->enableScaling == TRUE)
        {
            logString = g_strdup_printf("    <controlpoint px=\"%04d\" py=\"%04d\" rotation=\"%s\" width_resize=\"%s\" height_resize=\"%s\" keyframe_abs=\"%d\" p1x=\"%04d\"  p1y=\"%04d\"  p2x=\"%04d\" p2y=\"%04d\"/>"
                                        , px
                                        , py
                                        , rotValueAsString
                                        , scaleValueAsString
                                        , scaleValueAsString
                                        , frameNr
                                        , currCoords->px
                                        , currCoords->py
                                        , currCoords2->px
                                        , currCoords2->py
                                       );
        }
        else
        {
            logString = g_strdup_printf("    <controlpoint px=\"%04d\" py=\"%04d\" rotation=\"%s\" keyframe_abs=\"%d\" p1x=\"%04d\"  p1y=\"%04d\"  p2x=\"%04d\" p2y=\"%04d\"/>"
                                        , px
                                        , py
                                        , rotValueAsString
                                        , frameNr
                                        , currCoords->px
                                        , currCoords->py
                                        , currCoords2->px
                                        , currCoords2->py
                                       );
        }


        g_free(rotValueAsString);
        g_free(scaleValueAsString);
    }
    else
    {
        /* single point detail coordinate tracking */
        if (valPtr->offsRotate == 0.0)
        {
            logString = g_strdup_printf("    <controlpoint px=\"%04d\" py=\"%04d\"  keyframe_abs=\"%d\" p1x=\"%04d\"  p1y=\"%04d\"/>"
                                        , px
                                        , py
                                        , frameNr
                                        , currCoords->px
                                        , currCoords->py
                                       );
        }
        else
        {
            rotValueAsString = gap_base_gdouble_to_ascii_string(valPtr->offsRotate, precision_digits);
            precision_digits = 7;

            logString = g_strdup_printf("    <controlpoint px=\"%04d\" py=\"%04d\"  rotation=\"%s\" keyframe_abs=\"%d\" p1x=\"%04d\"  p1y=\"%04d\"/>"
                                        , px
                                        , py
                                        , rotValueAsString
                                        , frameNr
                                        , currCoords->px
                                        , currCoords->py
                                       );
            g_free(rotValueAsString);
        }

    }

    if ((valPtr->moveLogFile[0] == '\0')
            ||  (valPtr->moveLogFile[0] == '-'))
    {
        printf("%s\n", logString);
    }
    else
    {
        p_log_to_file(&valPtr->moveLogFile[0], logString
                      , frameNr
                      , center
                      , width
                      , height
                     );
    }

    if (logString)
    {
        g_free(logString);
    }


}  /* end p_coords_logging */
Exemplo n.º 21
0
static void
run (const gchar      *name,
     gint              nparams,
     const GimpParam  *param,
     gint             *nreturn_vals,
     GimpParam       **return_vals)
{
  static GimpParam   values[4];
  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
  GError            *error  = NULL;
  gint32             image_ID;

  INIT_I18N ();

  *nreturn_vals = 1;
  *return_vals  = values;

  values[0].type          = GIMP_PDB_STATUS;
  values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;

  if (strcmp (name, LOAD_PROC) == 0)
    {
      image_ID = load_image (param[1].data.d_string, FALSE, &error);
    }
  else if (strcmp (name, LOAD_THUMB_PROC) == 0)
    {
      image_ID = load_image (param[0].data.d_string, TRUE, &error);
    }
  else
    {
      status = GIMP_PDB_CALLING_ERROR;
    }

  if (status == GIMP_PDB_SUCCESS)
    {
      if (image_ID != -1)
        {
          /* The GIF format only tells you how many bits per pixel
           *  are in the image, not the actual number of used indices (D'OH!)
           *
           * So if we're not careful, repeated load/save of a transparent GIF
           *  without intermediate indexed->RGB->indexed pumps up the number of
           *  bits used, as we add an index each time for the transparent
           *  colour.  Ouch.  We either do some heavier analysis at save-time,
           *  or trim down the number of GIMP colours at load-time.  We do the
           *  latter for now.
           */
#ifdef GIFDEBUG
          g_print ("GIF: Highest used index is %d\n", highest_used_index);
#endif
          if (! promote_to_rgb)
            gimp_image_set_colormap (image_ID,
                                     gimp_cmap, highest_used_index + 1);

          *nreturn_vals = 2;
          values[1].type         = GIMP_PDB_IMAGE;
          values[1].data.d_image = image_ID;

          if (strcmp (name, LOAD_THUMB_PROC) == 0)
            {
              *nreturn_vals = 4;
              values[2].type         = GIMP_PDB_INT32;
              values[2].data.d_int32 = gimp_image_width (image_ID);
              values[3].type         = GIMP_PDB_INT32;
              values[3].data.d_int32 = gimp_image_height (image_ID);
            }
        }
      else
        {
          status = GIMP_PDB_EXECUTION_ERROR;

          if (error)
            {
              *nreturn_vals = 2;
              values[1].type          = GIMP_PDB_STRING;
              values[1].data.d_string = error->message;
            }
        }
    }

  values[0].data.d_status = status;
}
Exemplo n.º 22
0
/* ============================================================================
 * p_movtar_encode
 *    The main "productive" routine 
 *    movtar encoding of anim frames, based on the buz_tools' encoding routines.
 *    (flattens the images if nedded)
 *    Optional you can provide audio, too 
 *    (wav_audiofile must be provided in that case)
 *
 * returns   value >= 0 if all went ok 
 *           (or -1 on error)
 * ============================================================================
 */
static int
p_movtar_encode(t_anim_info *ainfo_ptr,
		long range_from, long range_to,
		char *vidname, gint32 dont_recode_frames, 
		char *wavname, gint32 auto_videoparam, 
		char *videonorm, gint32 jpeg_interlaced, 
		char *text_author, char *text_software,
		char *text_device, char *text_input, 
		char *text_contdescription, char *text_contclassification,
		gint32 jpeg_quality
		)
{
  gint32     l_tmp_image_id = -1;
  gint32     l_layer_id = -1;
  GDrawable *l_drawable;
  long       l_cur_frame_nr;
  long       l_step, l_begin, l_end;
  int  l_width, l_height;
  gint       l_nlayers;
  gint32    *l_layers_list;
  gdouble    l_percentage, l_percentage_step;
  int        l_rc; 
  FILE *movtar, *inwav = NULL;
  gint32 JPEG_size, datasize;
  gint32 audio_x100;

  char *buffer;
  static struct tarinfotype frameinfo;
  //  static struct tarinfotype frcopyinfo;
  static struct tarinfotype audioinfo;

  gint32 wavsize; /* Data size of the wav file */
  long audio_margin = 8192; 
  long audio_filled_100 = 0;
  gchar databuffer[300000];

  gchar *name_examine;
  
  l_rc = 0;
  l_layer_id = -1; l_width = 0; l_height = 0;
  
  movtar_init(FALSE);
  tarblock_makedefault(&frameinfo, "tja.jpeg", 1024);
  tarblock_makedefault(&audioinfo, "tja.raw", 1024);

  /* create file */
  if (movtar_debug) printf("Creating movtar file.\n");
  movtar = movtar_create(vidname);
  if (movtar == NULL) { perror("Creation of movtar file failed."); exit(1); }

  l_percentage = 0.0;
  if(ainfo_ptr->run_mode == RUN_INTERACTIVE)
    gimp_progress_init("Encoding movtar...");

  l_begin = range_from;
  l_end   = range_to;  
 
  /* special setup (makes it possible to code sequences backwards) */
  if(range_from > range_to)
  {
    l_step  = -1;     /* operate in descending (reverse) order */
    l_percentage_step = 1.0 / ((1.0 + range_from) - range_to);

    if(range_to < ainfo_ptr->first_frame_nr)
      l_begin = ainfo_ptr->first_frame_nr;
    
    if(range_from > ainfo_ptr->last_frame_nr)
      l_end = ainfo_ptr->last_frame_nr;    
  }
  else
  {
    l_step  = 1;      /* operate in ascending order */
    l_percentage_step = 1.0 / ((1.0 + range_to) - range_from);

    if(range_from < ainfo_ptr->first_frame_nr)
      l_begin = ainfo_ptr->first_frame_nr;
    
    if(range_to > ainfo_ptr->last_frame_nr)
      l_end = ainfo_ptr->last_frame_nr;    
  }  
  
  /* start with the first frame to encode */
  l_cur_frame_nr = l_begin;
  while(l_rc >= 0)
  {
    /* build the frame name */
    if(ainfo_ptr->new_filename != NULL) g_free(ainfo_ptr->new_filename);
    /* Use the gap functions to generate the frame filename */
    ainfo_ptr->new_filename = p_alloc_fname(ainfo_ptr->basename,
                                        l_cur_frame_nr,
                                        ainfo_ptr->extension);
    /* can't find the frame ? */
    if(ainfo_ptr->new_filename == NULL) return -1;

    if(l_cur_frame_nr == l_begin) /* setup things first if this is the first frame */
      {
	/* load current frame ... */
	l_tmp_image_id = p_load_image(ainfo_ptr->new_filename);
	if(l_tmp_image_id < 0) return -1;
	/* to determine these parameters */
	l_width = (int) gimp_image_width(l_tmp_image_id);
	l_height = (int) gimp_image_height(l_tmp_image_id);
	    
	/* create the MOVTAR Info file, based on the information
	   stored in the first JPEG */
	inwav = p_make_movtar_info(movtar, wavname,
				   l_width, l_height, 
				   auto_videoparam, videonorm,
				   jpeg_interlaced, 
				   text_author, text_software,
				   text_device, text_input, 
				   text_contdescription, text_contclassification, 
				   &audio_x100, &wavsize);

	/* destroy the tmp image, dont_recode doesn't need it */
	if (dont_recode_frames) gimp_image_delete(l_tmp_image_id);    
      }


    if (dont_recode_frames)
      { 
	JPEG_size = p_get_filesize(ainfo_ptr->new_filename);
	buffer = p_load_file(ainfo_ptr->new_filename);
        if (buffer == NULL) { printf("gap_movtar: Failed opening encoded input frame %s.", 
				     ainfo_ptr->new_filename); return -1; }
	/* generate the file name for the frame to be stored */
	/* store the compressed video frame */    
	/* A quick hack to replace the extension with raw */
	strcpy(frameinfo.name, g_basename(ainfo_ptr->new_filename));
	name_examine = frameinfo.name + strlen(frameinfo.name);
	while (frameinfo.name != name_examine && *name_examine != '.')
	  { *name_examine = '\0'; name_examine--; }
	strcpy(name_examine, ".jpeg");
	sprintf(frameinfo.size, "%o", JPEG_size);
	tarblock_create_checksum(&frameinfo);

	if (movtar_debug) printf("gap_movtar: Writing frame nr. %ld, size %d\n", 
			      l_cur_frame_nr, JPEG_size);
	if (movtar_write(movtar, buffer, JPEG_size, &frameinfo) != TRUE) 
  	    { printf("gap_movtar: Failed in writing a frame."); return -1; }
      }
    else
      {
	if(l_cur_frame_nr != l_begin) /* frame has already been loaded if l_begin */
	  {
	    /* load current frame */
	    l_tmp_image_id = p_load_image(ainfo_ptr->new_filename);
	    if (l_tmp_image_id < 0) return -1;
	  }

	/* Examine the layers of the picture */
	l_layers_list = gimp_image_get_layers(l_tmp_image_id, &l_nlayers);
	if(l_layers_list != NULL)
	  {
	    l_layer_id = l_layers_list[0];
	    g_free (l_layers_list);
	  }

	if(l_nlayers > 1 )
	  {
	    if (movtar_debug) fprintf(stderr, "DEBUG: p_movtar_encode flatten tmp image'\n");	    
	    /* flatten current frame image (reduce to single layer) */
	    l_layer_id = gimp_image_flatten (l_tmp_image_id);
	  }
	
	l_drawable = gimp_drawable_get (l_layer_id);
	if (movtar_debug) fprintf(stderr, "DEBUG: JPEG encoding frame %s\n", 
			       ainfo_ptr->new_filename);
	/* Compress the picture into a JPEG */
    	buffer = p_drawable_encode_jpeg(l_drawable, jpeg_interlaced, 
				        &JPEG_size, jpeg_quality, 0, FALSE, NULL, 0);
	if (movtar_debug) fprintf(stderr, "DEBUG: Ready with encoding, now saving %s\n", 
			       ainfo_ptr->new_filename);
	
	/* store the compressed video frame */    
	/* A quick hack to replace the extension with raw */
	strcpy(frameinfo.name, g_basename(ainfo_ptr->new_filename));
	name_examine = frameinfo.name + strlen(frameinfo.name);
	while (frameinfo.name != name_examine && *name_examine != '.')
	  { *name_examine = '\0'; name_examine--; }
	strcpy(name_examine, ".jpeg");
	sprintf(frameinfo.size, "%o", JPEG_size);
	tarblock_create_checksum(&frameinfo);

	if (movtar_debug) printf("gap_movtar: Writing frame nr. %ld, size %d\n", 
			      l_cur_frame_nr, JPEG_size);
	if (movtar_write(movtar, buffer, JPEG_size, &frameinfo) != TRUE) 
  	    { printf("Failed in writing a frame."); return -1; }
	/* free the compressed JPEG data */
	g_free(buffer);

	/* destroy the tmp image */
	gimp_image_delete(l_tmp_image_id);    
      }

    /* As long as there is a video frame, "fill" the fake audio buffer */
    if (inwav) audio_filled_100 += audio_x100;
    
    /* Now "empty" the fake audio buffer, until it goes under the margin again */
    while ((audio_filled_100 >= (audio_margin * 100)) && (wavsize > 0))
      {
	if (wavsize >= audio_margin)
	  { datasize = fread(databuffer, 1, audio_margin, inwav); 
	  if (datasize != audio_margin)
	    { perror("Warning: Read from wav file failed. (non-critical)\n"); }
	  wavsize -= audio_margin;
	  }  
	else
	  { datasize = fread(databuffer, 1, wavsize, inwav);
	  if (datasize != wavsize)
	    { perror("Warning: Read from wav file failed. (non-critical)\n"); }
	  wavsize = 0;
	  }

	/* create a filename, with the sequence number and 
	   the timestamp info in brackets. Checksum the new tarheader. */

	/* A quick hack to replace the extension with raw */
	name_examine = frameinfo.name + strlen(frameinfo.name);
	while (frameinfo.name != name_examine && *name_examine != '.')
	  { *name_examine = '\0'; name_examine--; }
	strcpy(name_examine, ".raw");
	sprintf(frameinfo.size, "%o", datasize);
	tarblock_create_checksum(&frameinfo);
	if (movtar_debug) printf("Now saving audio frame %s\n", frameinfo.name);
	
	movtar_write(movtar, databuffer, datasize, &frameinfo);
	audio_filled_100 -= audio_margin * 100;
      }
    
    if(ainfo_ptr->run_mode == RUN_INTERACTIVE)
      { 
	l_percentage += l_percentage_step;
	gimp_progress_update (l_percentage);
      }

    /* advance to next frame */
    if((l_cur_frame_nr == l_end) || (l_rc < 0))
      break;
    l_cur_frame_nr += l_step;	

  }

  movtar_finish_close(movtar);

  return l_rc;  
}
static gboolean apply_resize(resize_settings settings, image_output out) 
{
    gboolean success = FALSE;
    gint orig_w, orig_h, final_w, final_h, view_w, view_h;
    gdouble orig_res_x, orig_res_y;
    
    if (settings->change_res) {
        success = gimp_image_get_resolution(
            out->image_id,
            &orig_res_x,
            &orig_res_y
        );
        
        if ((settings->new_res_x != orig_res_x) || (settings->new_res_y != orig_res_y)) {
            // change resolution 
            success = gimp_image_set_resolution(
                out->image_id,
                settings->new_res_x,
                settings->new_res_y
            );
        }
    }

    orig_w = gimp_image_width(out->image_id);
    orig_h = gimp_image_height(out->image_id);
    
    if (settings->resize_mode == RESIZE_PERCENT) {
        
        if (settings->stretch_mode == STRETCH_ASPECT) {
            gdouble newpct = min(settings->new_w_pc, settings->new_h_pc);
            
            final_w = view_w = round((orig_w * newpct) / 100.0);
            final_h = view_h = round((orig_h * newpct) / 100.0);
        }
        else if (settings->stretch_mode == STRETCH_PADDED) {
            gdouble newpct = min(settings->new_w_pc, settings->new_h_pc);
            
            final_w = round((orig_w * newpct) / 100.0);
            final_h = round((orig_h * newpct) / 100.0);
            view_w = round((orig_w * settings->new_w_pc) / 100.0);
            view_h = round((orig_h * settings->new_h_pc) / 100.0);
        }
        else {
            final_w = view_w = round((orig_w * settings->new_w_pc) / 100.0);
            final_h = view_h = round((orig_h * settings->new_h_pc) / 100.0);
        }
    }
    else {
        // user typed exact pixel size 
        if (settings->resize_mode == RESIZE_PIXEL_WIDTH) {
            view_w = settings->new_w_px; // width is fixed 
            
            if (settings->stretch_mode == STRETCH_ASPECT) {
                final_w = view_w;
                final_h = view_h = round(((float)final_w * orig_h) / orig_w);
            }
            else if (settings->stretch_mode == STRETCH_PADDED) {
                final_w = min(view_w, orig_w);
                final_h = round(((float)final_w * orig_h) / orig_w);
                view_h = max(orig_h, final_h);
            }
            else {
                final_w = view_w;
                final_h = view_h = orig_h;
            }
        }
        else if (settings->resize_mode == RESIZE_PIXEL_HEIGHT) {
            view_h = settings->new_h_px; // height is fixed
            
            if (settings->stretch_mode == STRETCH_ASPECT) {
                final_h = view_h;
                final_w = view_w = round(((float)final_h * orig_w) / orig_h);
            }
            else if (settings->stretch_mode == STRETCH_PADDED) {
                final_h = min(view_h, orig_h);
                final_w = round(((float)final_h * orig_w) / orig_h);
                view_w = max(orig_w, final_w);
            }
            else {
                final_h = view_h;
                final_w = view_w = orig_w;
            }
        }
        else {
            // both dimensions are defined 
            if (settings->stretch_mode == STRETCH_ASPECT) {
                // Find which new dimension is the smallest percentage of the existing image dimension
                gdouble newwpct = (float)settings->new_w_px / (float)orig_w;
                gdouble newhpct = (float)settings->new_h_px / (float)orig_h;
                gdouble newpct = min(newwpct, newhpct);

                final_w = view_w = round(orig_w * newpct);
                final_h = view_h = round(orig_h * newpct);
            }
            else if (settings->stretch_mode == STRETCH_PADDED) {
                // Find which new dimension is the smallest percentage of the existing image dimension
                gdouble newwpct = (float)settings->new_w_px / (float)orig_w;
                gdouble newhpct = (float)settings->new_h_px / (float)orig_h;
                gdouble newpct = min(newwpct, newhpct);
                
                final_w = round(orig_w * newpct);
                final_h = round(orig_h * newpct);
                view_w = round(orig_w * newwpct);
                view_h = round(orig_h * newhpct);
            }
            else {
                final_w = view_w = settings->new_w_px;
                final_h = view_h = settings->new_h_px;
            }
        }
    }
    
    // do resize 
    #if USE_API26
    
        success = gimp_image_scale_full (
            out->image_id, 
            final_w, 
            final_h, 
            settings->interpolation
        );
        
    #else
    
        // starting from 2.8, gimp_image_scale_full is deprecated. 
        // use gimp_image_scale instead
        GimpInterpolationType old_interpolation;
        old_interpolation = gimp_context_get_interpolation();
        
        success = gimp_context_set_interpolation (settings->interpolation);
        
        success = gimp_image_scale (
            out->image_id, 
            final_w, 
            final_h
        );
        
        success = gimp_context_set_interpolation (old_interpolation);
    
    #endif
    
    // add a padding if requested
    if (settings->stretch_mode == STRETCH_PADDED) {
        
        // the padding will be drawn using a coloured layer at the bottom of the image
        gint32 layerId = gimp_layer_new(
            out->image_id,
            "padding_layer",
            view_w, view_h,
            GIMP_RGBA_IMAGE,
            (settings->padding_color_alpha / (float)G_MAXUINT16) * 100,
            GIMP_NORMAL_MODE
        );
        
        #if USE_API26
        
            gimp_image_add_layer (
                out->image_id,
                layerId,
                0
            );
            
            gimp_image_lower_layer_to_bottom(out->image_id, layerId);
        
        #else
            
            gimp_image_insert_layer(
                out->image_id,
                layerId,
                0,
                0
            );
            
            gimp_image_lower_item_to_bottom(out->image_id, layerId);
            
        #endif
        
        // fill it with the selected color
        GimpRGB old_background, new_background;
            
        gimp_context_get_background(&old_background);
        gimp_rgb_parse_hex (&new_background, gdk_color_to_string(&(settings->padding_color)), strlen(gdk_color_to_string(&(settings->padding_color))));
        gimp_context_set_background(&new_background);
        gimp_drawable_fill(layerId, GIMP_BACKGROUND_FILL);
        gimp_context_set_background(&old_background);
        
        // move it to the center
        gimp_layer_translate(layerId, -abs(view_w - final_w) / 2, -abs(view_h - final_h) / 2);
        
        // finish changing the canvas size accordingly
        success = gimp_image_resize_to_layers(out->image_id);
    }
    
    return success;
}
Exemplo n.º 24
0
static gint
save_dialog (gint32 image_ID)
{
  GtkWidget *dialog;
  GtkWidget *main_vbox;
  GtkWidget *frame;
  GtkWidget *vbox;
  GtkWidget *table;
  GtkWidget *spinbutton;
  GtkObject *adj;
  GtkWidget *entry;
  GtkWidget *toggle;
  gboolean   run;

  gimp_ui_init (PLUG_IN_BINARY, FALSE);

  dialog = gimp_export_dialog_new (_("HTML table"), PLUG_IN_BINARY, SAVE_PROC);

  main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
  gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
  gtk_box_pack_start (GTK_BOX (gimp_export_dialog_get_content_area (dialog)),
                      main_vbox, TRUE, TRUE, 0);

  if (gimp_image_width (image_ID) * gimp_image_height (image_ID) > 4096)
    {
      GtkWidget *eek;
      GtkWidget *label;
      GtkWidget *hbox;

      frame = gimp_frame_new (_("Warning"));
      gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
      gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);

      hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 12);
      gtk_container_add (GTK_CONTAINER (frame), hbox);

      eek = gtk_image_new_from_stock (GIMP_STOCK_WILBER_EEK,
                                      GTK_ICON_SIZE_DIALOG);
      gtk_box_pack_start (GTK_BOX (hbox), eek, FALSE, FALSE, 0);

      label = gtk_label_new (_("You are about to create a huge\n"
                               "HTML file which will most likely\n"
                               "crash your browser."));
      gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);

      gtk_widget_show_all (frame);
    }

  /* HTML Page Options */
  frame = gimp_frame_new (_("HTML Page Options"));
  gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);

  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
  gtk_container_add (GTK_CONTAINER (frame), vbox);
  gtk_widget_show (vbox);

  toggle = gtk_check_button_new_with_mnemonic (_("_Generate full HTML document"));
  gtk_box_pack_start (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), gtmvals.fulldoc);
  gtk_widget_show (toggle);

  gimp_help_set_help_data (toggle,
                           _("If checked GTM will output a full HTML document "
                             "with <HTML>, <BODY>, etc. tags instead of just "
                             "the table html."),
                           NULL);

  g_signal_connect (toggle, "toggled",
                    G_CALLBACK (gimp_toggle_button_update),
                    &gtmvals.fulldoc);

  gtk_widget_show (main_vbox);
  gtk_widget_show (frame);

  /* HTML Table Creation Options */
  frame = gimp_frame_new (_("Table Creation Options"));
  gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);

  table = gtk_table_new (4, 2, FALSE);
  gtk_table_set_col_spacings (GTK_TABLE (table), 6);
  gtk_table_set_row_spacings (GTK_TABLE (table), 6);
  gtk_container_add (GTK_CONTAINER (frame), table);

  toggle = gtk_check_button_new_with_mnemonic (_("_Use cellspan"));
  gtk_table_attach (GTK_TABLE (table), toggle, 0, 2, 0, 1, GTK_FILL, 0, 0, 0);
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), gtmvals.spantags);
  gtk_widget_show (toggle);

  gimp_help_set_help_data (toggle,
                           _("If checked GTM will replace any rectangular "
                             "sections of identically colored blocks with one "
                             "large cell with ROWSPAN and COLSPAN values."),
                           NULL);

  g_signal_connect (toggle, "toggled",
                    G_CALLBACK (gimp_toggle_button_update),
                    &gtmvals.spantags);

  toggle = gtk_check_button_new_with_mnemonic (_("Co_mpress TD tags"));
  gtk_table_attach (GTK_TABLE (table), toggle, 0, 2, 1, 2, GTK_FILL, 0, 0, 0);
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), gtmvals.tdcomp);
  gtk_widget_show (toggle);

  gimp_help_set_help_data (toggle,
                           _("Checking this tag will cause GTM to leave no "
                             "whitespace between the TD tags and the "
                             "cellcontent.  This is only necessary for pixel "
                             "level positioning control."),
                           NULL);

  g_signal_connect (toggle, "toggled",
                    G_CALLBACK (gimp_toggle_button_update),
                    &gtmvals.tdcomp);

  toggle = gtk_check_button_new_with_mnemonic (_("C_aption"));
  gtk_table_attach (GTK_TABLE (table), toggle, 0, 1, 2, 3, GTK_FILL, 0, 0, 0);
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), gtmvals.caption);
  gtk_widget_show (toggle);

  gimp_help_set_help_data (toggle,
                           _("Check if you would like to have the table "
                             "captioned."),
                           NULL);

  g_signal_connect (toggle, "toggled",
                    G_CALLBACK (gimp_toggle_button_update),
                    &gtmvals.caption);

  entry = gtk_entry_new ();
  gtk_widget_set_size_request (entry, 200, -1);
  gtk_entry_set_text (GTK_ENTRY (entry), gtmvals.captiontxt);
  gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 2, 3,
                    GTK_FILL | GTK_EXPAND, 0, 0, 0);
  gtk_widget_show (entry);

  gimp_help_set_help_data (entry, _("The text for the table caption."), NULL);

  g_signal_connect (entry, "changed",
                    G_CALLBACK (gtm_caption_callback),
                    NULL);

  g_object_bind_property (toggle, "active",
                          entry,  "sensitive",
                          G_BINDING_SYNC_CREATE);

  entry = gtk_entry_new ();
  gtk_widget_set_size_request (entry, 200, -1);
  gtk_entry_set_text (GTK_ENTRY (entry), gtmvals.cellcontent);
  gimp_table_attach_aligned (GTK_TABLE (table), 0, 3,
                             _("C_ell content:"), 0.0, 0.5,
                             entry, 1, FALSE);
  gtk_widget_show (entry);

  gimp_help_set_help_data (entry, _("The text to go into each cell."), NULL);

  g_signal_connect (entry, "changed",
                    G_CALLBACK (gtm_cellcontent_callback),
                    NULL);

  gtk_widget_show (table);
  gtk_widget_show (frame);

  /* HTML Table Options */
  frame = gimp_frame_new (_("Table Options"));
  gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);

  table = gtk_table_new (5, 2, FALSE);
  gtk_table_set_col_spacings (GTK_TABLE (table), 6);
  gtk_table_set_row_spacings (GTK_TABLE (table), 6);
  gtk_container_add (GTK_CONTAINER (frame), table);

  spinbutton = gimp_spin_button_new (&adj, gtmvals.border,
                                     0, 1000, 1, 10, 0, 1, 0);
  gimp_table_attach_aligned (GTK_TABLE (table), 0, 0,
                             _("_Border:"), 0.0, 0.5,
                             spinbutton, 1, TRUE);

  gimp_help_set_help_data (spinbutton,
                           _("The number of pixels in the table border."),
                           NULL);

  g_signal_connect (adj, "value-changed",
                    G_CALLBACK (gimp_int_adjustment_update),
                    &gtmvals.border);

  entry = gtk_entry_new ();
  gtk_widget_set_size_request (entry, 60, -1);
  gtk_entry_set_text (GTK_ENTRY (entry), gtmvals.clwidth);
  gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
                             _("_Width:"), 0.0, 0.5,
                             entry, 1, TRUE);

  gimp_help_set_help_data (entry,
                           _("The width for each table cell.  "
                             "Can be a number or a percent."),
                           NULL);

  g_signal_connect (entry, "changed",
                    G_CALLBACK (gtm_clwidth_callback),
                    NULL);

  entry = gtk_entry_new ();
  gtk_widget_set_size_request (entry, 60, -1);
  gtk_entry_set_text (GTK_ENTRY (entry), gtmvals.clheight);
  gimp_table_attach_aligned (GTK_TABLE (table), 0, 2,
                             _("_Height:"), 0.0, 0.5,
                             entry, 1, TRUE);

  gimp_help_set_help_data (entry,
                           _("The height for each table cell.  "
                             "Can be a number or a percent."),
                           NULL);

  g_signal_connect (entry, "changed",
                    G_CALLBACK (gtm_clheight_callback),
                    NULL);

  spinbutton = gimp_spin_button_new (&adj, gtmvals.cellpadding,
                                     0, 1000, 1, 10, 0, 1, 0);
  gimp_table_attach_aligned (GTK_TABLE (table), 0, 3,
                             _("Cell-_padding:"), 0.0, 0.5,
                             spinbutton, 1, TRUE);

  gimp_help_set_help_data (spinbutton,
                           _("The amount of cell padding."), NULL);

  g_signal_connect (adj, "value-changed",
                    G_CALLBACK (gimp_int_adjustment_update),
                    &gtmvals.cellpadding);

  spinbutton = gimp_spin_button_new (&adj, gtmvals.cellspacing,
                                     0, 1000, 1, 10, 0, 1, 0);
  gimp_table_attach_aligned (GTK_TABLE (table), 0, 4,
                             _("Cell-_spacing:"), 0.0, 0.5,
                             spinbutton, 1, TRUE);

  gimp_help_set_help_data (spinbutton,
                           _("The amount of cell spacing."), NULL);

  g_signal_connect (adj, "value-changed",
                    G_CALLBACK (gimp_int_adjustment_update),
                    &gtmvals.cellspacing);

  gtk_widget_show (table);
  gtk_widget_show (frame);

  gtk_widget_show (dialog);

  run = (gimp_dialog_run (GIMP_DIALOG (dialog)) == GTK_RESPONSE_OK);

  gtk_widget_destroy (dialog);

  return run;
}
static gboolean apply_crop(crop_settings settings, image_output out) 
{
    gboolean success = TRUE;
    gint newWidth, newHeight, oldWidth, oldHeight, posX = 0, posY = 0;
    gboolean keepX = FALSE, keepY = FALSE;
    
    oldWidth = gimp_image_width(out->image_id);
    oldHeight = gimp_image_height(out->image_id);
    
    if (settings->manual) {
        newWidth = min(oldWidth, settings->new_w);
        newHeight = min(oldHeight, settings->new_h);
    }
    else {
        float ratio1, ratio2;
        if (settings->ratio == CROP_PRESET_CUSTOM) {
            ratio1 = settings->custom_ratio1;
            ratio2 = settings->custom_ratio2;
        }
        else {
            ratio1 = (float)crop_preset_ratio[settings->ratio][0];
            ratio2 = (float)crop_preset_ratio[settings->ratio][1];
        }
        
        if (( (float)oldWidth / oldHeight ) > ( ratio1 / ratio2) ) { 
            // crop along the width 
            newHeight = oldHeight;
            newWidth = round(( ratio1 * (float)newHeight ) / ratio2);
            keepY = TRUE;
        } else { 
            // crop along the height 
            newWidth = oldWidth;
            newHeight = round(( ratio2 * (float)newWidth) / ratio1);
            keepX = TRUE;
        }
    }
    
    switch (settings->start_pos) {
        case CROP_START_TL: 
            posX = 0;
            posY = 0;
            break;
            
        case CROP_START_TR: 
            posX = (oldWidth - newWidth);
            posY = 0;
            break;
            
        case CROP_START_BL: 
            posX = 0;
            posY = (oldHeight - newHeight);
            break;
            
        case CROP_START_BR: 
            posX = (oldWidth - newWidth);
            posY = (oldHeight - newHeight);
            break;
        
        default: 
            if (!keepX) posX = (oldWidth - newWidth) / 2;
            if (!keepY) posY = (oldHeight - newHeight) / 2;
            break;
    }
    
    success = gimp_image_crop (
        out->image_id,
        newWidth,
        newHeight,
        posX,
        posY
    );
    
    return success;
}
Exemplo n.º 26
0
gboolean
dialog (gint32              image_ID,
        GimpDrawable       *drawable,
        PlugInVals         *vals,
        PlugInImageVals    *image_vals,
        PlugInDrawableVals *drawable_vals,
        PlugInUIVals       *ui_vals) {
  GtkWidget *dlg;
  GtkWidget *main_vbox;
  GtkWidget *frame;
  GtkWidget *table;
  GtkWidget *tileable_checkbox;
  GtkObject *adj;
  gint row;
  gboolean   run = FALSE;

  image_vals->width_p  = gimp_image_width(image_ID);
  image_vals->height_p = gimp_image_height(image_ID);
  // Here are the default values of the dialog box
  image_vals->width_i  = 2 * image_vals->width_p;
  image_vals->height_i = 2 * image_vals->height_p;
  vals->overlap = 100;
  vals->make_tileable = FALSE;

  ui_state = ui_vals;

  gimp_ui_init (PLUGIN_NAME, TRUE);

  dlg = gimp_dialog_new (
    _("Texturize Plug-in for GIMP"),
    PLUGIN_NAME,
    NULL, GTK_DIALOG_MODAL,
    gimp_standard_help_func, "plug-in-template",
    GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
    GTK_STOCK_OK,     GTK_RESPONSE_OK,
    NULL);

  main_vbox = gtk_vbox_new (FALSE, 12);
  gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12);
  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dlg)->vbox), main_vbox);


  // Size of the new image ?
  frame = gimp_frame_new (_("Please set the size of the new image\nand the maximum overlap between patches."));
  gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
  gtk_widget_show (frame);

  table = gtk_table_new (3, 3, FALSE);
  gtk_table_set_col_spacings (GTK_TABLE (table), 6);
  gtk_table_set_row_spacings (GTK_TABLE (table), 2);
  gtk_container_add (GTK_CONTAINER (frame), table);
  gtk_widget_show (table);

  row = 0;

  // Width of the new image?
  adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,_("Width :"), SCALE_WIDTH, SPIN_BUTTON_WIDTH,
                              image_vals->width_i, image_vals->width_p,20*image_vals->width_p, 1, 10, 0, TRUE, 0, 0,
                              _("Set the new image's width"), NULL);
  g_signal_connect (adj, "value_changed",
                    G_CALLBACK (gimp_int_adjustment_update), &image_vals->width_i);

  // Height of the new image?
  adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++,_("Height :"), SCALE_WIDTH, SPIN_BUTTON_WIDTH,
                              image_vals->height_i, image_vals->height_p,20*image_vals->height_p, 1, 10, 0, TRUE, 0, 0,
                              _("Set the new image's height"), NULL);
  g_signal_connect (adj, "value_changed",
                    G_CALLBACK (gimp_int_adjustment_update),
                    &image_vals->height_i);

  // Patch overlap?
  adj = gimp_scale_entry_new (GTK_TABLE (table), 0, row++, _("Overlap (pixels) :"), SCALE_WIDTH, SPIN_BUTTON_WIDTH,
                              vals->overlap,
                              MIN(25, MIN(image_vals->width_p - 1 ,image_vals->height_p - 1)),
                              MIN(image_vals->width_p, image_vals->height_p),
                              5, 10, 0, TRUE, 0, 0,
                              _("Set the overlap between patches (larger values make better "
                                "but longer texturizing "
                                "and tend to make periodic results)"),
                              NULL);
  g_signal_connect (adj,
                    "value_changed",
                    G_CALLBACK (gimp_int_adjustment_update),
                    &vals->overlap);


  // Tileable texture?
  tileable_checkbox = gtk_check_button_new_with_mnemonic (_("_Tileable"));
  gtk_box_pack_start (GTK_BOX (main_vbox), tileable_checkbox, FALSE, FALSE, 0);
  gtk_widget_show (tileable_checkbox);
  gimp_help_set_help_data (tileable_checkbox,
                           _("Selects if to create a tileable texture"),
                           NULL);
  g_signal_connect (GTK_WIDGET (tileable_checkbox), "toggled",
                    G_CALLBACK (gimp_toggle_button_update),
                    &vals->make_tileable);

  // Show the main containers.
  gtk_widget_show (main_vbox);
  gtk_widget_show (dlg);

  run = (gimp_dialog_run (GIMP_DIALOG (dlg)) == GTK_RESPONSE_OK);

  gtk_widget_destroy (dlg);

  return run;
}
Exemplo n.º 27
0
GtkWidget*
webx_dialog_new (gint image_ID,
                 gint drawable_ID)
{
  WebxDialog   *dlg;
  GtkWidget    *splitter;
  GtkWidget    *tbscroll;
  GtkWidget    *toolbox;
  GtkWidget    *format_table;
  GtkWidget    *left_box;
  GtkWidget    *preview_box;
  GtkWidget    *box;
  GtkWidget    *vbox;
  GtkWidget    *frame;
  GtkWidget    *separator;
  GtkWidget    *target;
  GtkWidget    *radio;
  GtkWidget    *notebook;
  GtkWidget    *label;
  GSList       *group;
  GSList       *target_list;
  GSList       *radio_list;
  gint          bg_width;
  gint          bg_height;
  gint          align;
  gint          row;
  
  
  webx_prefs_load (&webx_prefs);

  dlg = g_object_new (WEBX_TYPE_DIALOG,
                      "title",     (gchar*)_("Save for Web"),
                      "role",      (gchar*)PLUG_IN_BINARY,
                      "modal",     (GtkDialogFlags)GTK_DIALOG_MODAL,
                      "help-func", (GimpHelpFunc)gimp_standard_help_func,
                      "help-id",   (gchar*)PLUG_IN_PROC,
                      NULL);
  gimp_dialog_add_buttons (GIMP_DIALOG (dlg),

                           GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                           GTK_STOCK_SAVE,   GTK_RESPONSE_OK,

                           NULL);
  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dlg),
                                           GTK_RESPONSE_OK,
                                           GTK_RESPONSE_CANCEL,
                                           -1);
  gimp_window_set_transient (GTK_WINDOW (dlg));

  if (webx_prefs.dlg_width && webx_prefs.dlg_height)
    {
      gtk_window_set_default_size (GTK_WINDOW (dlg),
                                   webx_prefs.dlg_width, webx_prefs.dlg_height);
    }
  else
    {
      gtk_window_set_default_size (GTK_WINDOW (dlg), 728, 480);
    }

  if (webx_prefs.dlg_x && webx_prefs.dlg_y)
    {
      gtk_window_move (GTK_WINDOW (dlg),
                       webx_prefs.dlg_x,
                       webx_prefs.dlg_y);
    }

  g_signal_connect (dlg, "response",
                    G_CALLBACK (webx_dialog_response), NULL);
  g_signal_connect (dlg, "destroy",
                    G_CALLBACK (gtk_main_quit), NULL);


  dlg->pipeline = webx_pipeline_new (image_ID,
                                 drawable_ID);
  g_signal_connect_swapped (dlg->pipeline, "invalidated",
                            G_CALLBACK (webx_dialog_reset),
                            dlg);
  g_signal_connect_swapped (dlg->pipeline, "output-changed",
                            G_CALLBACK (webx_dialog_update),
                            dlg);
  g_object_ref_sink (dlg->pipeline);
  
  bg_width = gimp_image_width (image_ID);
  bg_height = gimp_image_height (image_ID);

  splitter = gtk_hpaned_new ();
  dlg->splitter = splitter;
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), GTK_WIDGET (splitter),
                      TRUE, TRUE, 0);
  gtk_widget_show (GTK_WIDGET (splitter));

  left_box = gtk_vbox_new (FALSE, 0);
  gtk_paned_pack1 (GTK_PANED (splitter), GTK_WIDGET (left_box),
                   FALSE, FALSE);
  gtk_widget_show (left_box);

  frame = gtk_frame_new (NULL);
  gtk_box_pack_start (GTK_BOX (left_box), frame,
                      FALSE, FALSE, 0);
  gtk_container_set_border_width (GTK_CONTAINER (frame), 4);
  gtk_widget_show (frame);

  notebook = gtk_notebook_new ();
  gtk_box_pack_start (GTK_BOX (left_box), notebook,
                      TRUE, TRUE, 0);
  gtk_widget_show (notebook);
  
  tbscroll = gtk_scrolled_window_new (NULL, NULL);
  label = gtk_image_new_from_stock (GIMP_STOCK_IMAGE,
                                    GTK_ICON_SIZE_MENU);
  gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
                            tbscroll,
                            label);

  gtk_container_set_border_width (GTK_CONTAINER (tbscroll), 4);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (tbscroll),
                                  GTK_POLICY_AUTOMATIC,
                                  GTK_POLICY_AUTOMATIC);
  gtk_widget_show (GTK_WIDGET (tbscroll));

  toolbox = gtk_vbox_new (FALSE, 0);
  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (tbscroll),
                                         GTK_WIDGET (toolbox));
  gtk_container_set_border_width (GTK_CONTAINER (toolbox), 4);
  gtk_widget_show (GTK_WIDGET (toolbox));

  vbox = gtk_vbox_new (FALSE, 0);
  gtk_container_add (GTK_CONTAINER (frame), vbox);
  gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
  gtk_widget_show (vbox);

  format_table = gtk_table_new (3, 2, TRUE);
  gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (format_table),
                      FALSE, FALSE, 0);

  separator = gtk_hseparator_new ();
  gtk_box_pack_start (GTK_BOX (vbox), separator,
                      FALSE, FALSE, 8);

  box = gtk_hbox_new (FALSE, 0);
  gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (box),
                      FALSE, FALSE, 0);
  gtk_widget_show (GTK_WIDGET (box));
  dlg->file_size_label = gtk_label_new ("");
  gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (dlg->file_size_label),
                      FALSE, FALSE, 0);

  target = webx_jpeg_target_new ();
  dlg->target_list = g_slist_append (dlg->target_list, target);
  radio = gtk_radio_button_new_with_label (NULL, _("JPEG"));
  dlg->radio_list = g_slist_append (dlg->radio_list, radio);
  group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio));

  target = NULL; 
  dlg->target_list = g_slist_append (dlg->target_list, target);
  radio = gtk_radio_button_new_with_label (group, _("JPEG 2000"));
  dlg->radio_list = g_slist_append (dlg->radio_list, radio);
  group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio));

  target = webx_png8_target_new ();
  dlg->target_list = g_slist_append (dlg->target_list, target);
  radio = gtk_radio_button_new_with_label (group, _("PNG-8"));
  dlg->radio_list = g_slist_append (dlg->radio_list, radio);
  group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio));

  target = webx_png24_target_new ();
  dlg->target_list = g_slist_append (dlg->target_list, target);
  radio = gtk_radio_button_new_with_label (group, _("PNG-24"));
  dlg->radio_list = g_slist_append (dlg->radio_list, radio);
  group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio));

  target = webx_gif_target_new ();
  dlg->target_list = g_slist_append (dlg->target_list, target);
  radio = gtk_radio_button_new_with_label (group, _("GIF"));
  dlg->radio_list = g_slist_append (dlg->radio_list, radio);
  group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio));

  align = 0;
  row = 0;
  for (target_list = dlg->target_list, radio_list = dlg->radio_list;
       target_list && radio_list;
       target_list = target_list->next, radio_list = radio_list->next)
    {
      gtk_table_attach (GTK_TABLE (format_table), GTK_WIDGET (radio_list->data),
                        align, align+1, row, row+1,
                        GTK_FILL, GTK_FILL, 0, 0);
      g_signal_connect (radio_list->data, "toggled",
                        G_CALLBACK (webx_dialog_format_changed), dlg);
      gtk_widget_show (GTK_WIDGET (radio_list->data));

      if (target_list->data)
        {
          gtk_box_pack_start (GTK_BOX (toolbox), GTK_WIDGET (target_list->data),
                              FALSE, FALSE, 0);
          g_signal_connect (target_list->data, "target-changed",
                            G_CALLBACK (webx_dialog_target_changed), dlg);
        }
      else
        {
          gtk_widget_set_sensitive (GTK_WIDGET (radio_list->data), FALSE);
        }

      align ^= 1;
      if (! align)
        row++;
    }

  gtk_widget_show_all (GTK_WIDGET (format_table));
  dlg->target = NULL;

  tbscroll = gtk_scrolled_window_new (NULL, NULL);
  label = gtk_image_new_from_stock (GIMP_STOCK_RESIZE,
                                    GTK_ICON_SIZE_MENU);
  gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
                            tbscroll,
                            label);

  gtk_container_set_border_width (GTK_CONTAINER (tbscroll), 4);
  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (tbscroll),
                                  GTK_POLICY_AUTOMATIC,
                                  GTK_POLICY_AUTOMATIC);
  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (tbscroll),
                                       GTK_SHADOW_NONE);
  gtk_widget_show (GTK_WIDGET (tbscroll));

  toolbox = gtk_vbox_new (FALSE, 0);
  gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (tbscroll),
                                         GTK_WIDGET (toolbox));
  gtk_container_set_border_width (GTK_CONTAINER (toolbox), 4);
  gtk_widget_show (GTK_WIDGET (toolbox));

  dlg->resize = webx_resize_widget_new (bg_width, bg_height);
  gtk_box_pack_start (GTK_BOX (toolbox), dlg->resize,
                      FALSE, FALSE, 0);
  g_signal_connect (WEBX_RESIZE_WIDGET (dlg->resize), "resized",
                    G_CALLBACK (webx_dialog_target_resized), dlg);
  webx_resize_widget_set_default_size (WEBX_RESIZE_WIDGET (dlg->resize),
                                       bg_width, bg_height);
  gtk_widget_show (dlg->resize);

  dlg->crop = webx_crop_widget_new (bg_width, bg_height);
  gtk_box_pack_start (GTK_BOX (toolbox), dlg->crop,
                      FALSE, FALSE, 0);
  g_signal_connect (WEBX_CROP_WIDGET (dlg->crop), "crop-changed",
                    G_CALLBACK (webx_dialog_crop_changed), dlg);
  gtk_widget_show (dlg->crop);

  preview_box = gtk_vbox_new (TRUE, 0);
  gtk_paned_pack2 (GTK_PANED (splitter), GTK_WIDGET (preview_box),
                   TRUE, FALSE);
  gtk_widget_show (GTK_WIDGET (preview_box));

  dlg->preview = webx_preview_new (bg_width, bg_height);
  gtk_box_pack_start (GTK_BOX (preview_box), dlg->preview,
                      TRUE, TRUE, 0);
  g_signal_connect (WEBX_PREVIEW (dlg->preview), "crop-changed",
                    G_CALLBACK (webx_dialog_crop_changed), dlg);
  gtk_widget_show (GTK_WIDGET (dlg->preview));

  dlg->progress_bar = gimp_progress_bar_new ();
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), dlg->progress_bar,
                      FALSE, FALSE, 0);

  if (webx_prefs.dlg_splitpos)
    {
      gtk_paned_set_position (GTK_PANED (splitter),
                              webx_prefs.dlg_splitpos);
    }

  return GTK_WIDGET (dlg);
}
Exemplo n.º 28
0
gboolean
separate_psd_export (gchar         *filename,
                     gint32         imageID,
                     gconstpointer  profile_data,
                     gsize          profile_length,
                     gconstpointer  path_data,
                     gsize          path_length,
                     gboolean       compression)
{
  int fd;
  PSDHeader header;
  PSDResResource res;
  PSDIccResource icc;

  fd = g_open (filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 00644);

  if (fd != -1)
    {
      gint32 length;
      gint32 width, height;
      gdouble xres, yres;

      width = gimp_image_width (imageID);
      height = gimp_image_height (imageID);

      /* header */
      header.signature = GUINT32_TO_BE (0x38425053);
      header.version = GUINT16_TO_BE (1);
      memset (header.reserved, 0, sizeof (header.reserved));
      header.channels = GINT16_TO_BE (4); /* C, M, Y, K, and no alpha channels */
      header.height = GINT32_TO_BE (height);
      header.width = GINT32_TO_BE (width);
      header.depth = GINT16_TO_BE (8); /* 8bit per channels */
      header.mode = GINT16_TO_BE (4); /* CMYK Mode */

      write (fd, &header, sizeof (header));

      /***** color mode data *****/
      length = 0;
      write (fd, &length, sizeof (gint32));

      /***** image resources *****/
      length = 0;

      /* resolution info */
      gimp_image_get_resolution (imageID, &xres, &yres);
      res.type = GUINT32_TO_BE (0x3842494d);
      res.id = GUINT16_TO_BE (0x03ed);
      memset (res.name, 0, 2);
      res.size = GINT32_TO_BE (16);
      res.hres = GINT32_TO_BE (xres * 65536.0);
      res.hres_unit = GINT16_TO_BE (1);
      res.width_unit = GINT16_TO_BE (1);
      res.vres = GINT32_TO_BE (yres * 65536.0);
      res.vres_unit = GINT16_TO_BE (1);
      res.height_unit = GINT16_TO_BE (1);

      length += sizeof (PSDResResource);

      /* ICC profile */
      if (profile_data)
        {
          icc.type = res.type;
          icc.id = GUINT16_TO_BE (0x040f);
          memset (icc.name, 0, 2);
          icc.size = GINT32_TO_BE (profile_length);

          length += sizeof (PSDIccResource) + profile_length;
        }

      /* path */
      if (path_data)
        length += path_length;

      /* write data... */
      length = GINT32_TO_BE (length);
      write (fd, &length, sizeof (gint32));

      write (fd, &res, sizeof (PSDResResource));

      if (profile_data)
        {
          write (fd, &icc, sizeof (PSDIccResource));
          write (fd, profile_data, profile_length);
        }

      if (path_data)
        write (fd, path_data, path_length);

      /***** layer and mask info *****/
      length = 0;
      write (fd, &length, sizeof (gint32));

      /***** image data *****/
      if (compression)
        psd_write_image_data_packbits (fd, imageID, width, height);
      else
        psd_write_image_data_raw (fd, imageID, width, height);

      close (fd);

      return TRUE;
    }

  return FALSE;
}
Exemplo n.º 29
0
static void
guillotine (gint32 image_ID)
{
  gint      guide;
  gint      image_width;
  gint      image_height;
  gboolean  guides_found = FALSE;
  GList    *hguides, *hg;
  GList    *vguides, *vg;

  image_width  = gimp_image_width (image_ID);
  image_height = gimp_image_height (image_ID);

  hguides = g_list_append (NULL,    GINT_TO_POINTER (0));
  hguides = g_list_append (hguides, GINT_TO_POINTER (image_height));

  vguides = g_list_append (NULL,    GINT_TO_POINTER (0));
  vguides = g_list_append (vguides, GINT_TO_POINTER (image_width));

  for (guide = gimp_image_find_next_guide (image_ID, 0);
       guide > 0;
       guide = gimp_image_find_next_guide (image_ID, guide))
    {
      gint position = gimp_image_get_guide_position (image_ID, guide);

      switch (gimp_image_get_guide_orientation (image_ID, guide))
        {
        case GIMP_ORIENTATION_HORIZONTAL:
          if (! g_list_find (hguides, GINT_TO_POINTER (position)))
            {
              hguides = g_list_insert_sorted (hguides,
                                              GINT_TO_POINTER (position),
                                              guide_sort_func);
              guides_found = TRUE;
            }
          break;

        case GIMP_ORIENTATION_VERTICAL:
          if (! g_list_find (vguides, GINT_TO_POINTER (position)))
            {
              vguides = g_list_insert_sorted (vguides,
                                              GINT_TO_POINTER (position),
                                              guide_sort_func);
              guides_found = TRUE;
            }
          break;

        case GIMP_ORIENTATION_UNKNOWN:
          g_assert_not_reached ();
          break;
        }
    }

  if (guides_found)
    {
      gchar *filename;
      gint   h, v, hpad, vpad;
      gint   x, y;
      gchar *hformat;
      gchar *format;

      filename = gimp_image_get_filename (image_ID);
      if (!filename)
        filename = g_strdup (_("Untitled"));

      /* get the number horizontal and vertical slices */
      h = g_list_length (hguides);
      v = g_list_length (vguides);

      /* need the number of digits of h and v for the padding */
      hpad = log10(h) + 1;
      vpad = log10(v) + 1;

      /* format for the x-y coordinates in the filename */
      hformat = g_strdup_printf ("%%0%i", MAX (hpad, vpad));
      format  = g_strdup_printf ("-%si-%si", hformat, hformat);

      /*  Do the actual dup'ing and cropping... this isn't a too naive a
       *  way to do this since we got copy-on-write tiles, either.
       */
      for (y = 0, hg = hguides; hg && hg->next; y++, hg = hg->next)
        {
          for (x = 0, vg = vguides; vg && vg->next; x++, vg = vg->next)
            {
              gint32   new_image = gimp_image_duplicate (image_ID);
              GString *new_filename;
              gchar   *fileextension;
              gchar   *fileindex;
              gint     pos;

              if (new_image == -1)
                {
                  g_warning ("Couldn't create new image.");
                  return;
                }

              gimp_image_undo_disable (new_image);

              gimp_image_crop (new_image,
                               GPOINTER_TO_INT (vg->next->data) -
                               GPOINTER_TO_INT (vg->data),
                               GPOINTER_TO_INT (hg->next->data) -
                               GPOINTER_TO_INT (hg->data),
                               GPOINTER_TO_INT (vg->data),
                               GPOINTER_TO_INT (hg->data));


              new_filename = g_string_new (filename);

              /* show the rough coordinates of the image in the title */
              fileindex    = g_strdup_printf (format, x, y);

              /* get the position of the file extension - last . in filename */
              fileextension = strrchr (new_filename->str, '.');
              pos           = fileextension - new_filename->str;

              /* insert the coordinates before the extension */
              g_string_insert (new_filename, pos, fileindex);
	      g_free (fileindex);

              gimp_image_set_filename (new_image, new_filename->str);
              g_string_free (new_filename, TRUE);

              while ((guide = gimp_image_find_next_guide (new_image, 0)))
                gimp_image_delete_guide (new_image, guide);

              gimp_image_undo_enable (new_image);

              gimp_display_new (new_image);
            }
        }

      g_free (filename);
      g_free (hformat);
      g_free (format);
    }

  g_list_free (hguides);
  g_list_free (vguides);
}
Exemplo n.º 30
0
static void
do_acrop (GimpDrawable *drawable,
          gint32        image_id)
{
  GimpPixelRgn  srcPR;
  gint          iwidth, iheight;
  gint          x, y, l;
  guchar       *buffer;
  gint          xmin, xmax, ymin, ymax;
  gint         *layers = NULL;
  gint          numlayers;

  iwidth = gimp_image_width(image_id);
  iheight = gimp_image_height(image_id);

  /* Set each edge to the opposite side -- i.e. xmin (the left edge
   * of the final cropped image) starts at the right edge.
   */
  xmin = iwidth - 1;
  xmax = 1;
  ymin = iheight - 1;
  ymax = 1;

  buffer = g_malloc ((iwidth > iheight ? iwidth : iheight) * drawable->bpp);

  layers = gimp_image_get_layers (image_id, &numlayers);

  for (l=0; l<numlayers; ++l)
    {
      gint dwidth, dheight;
      gint layerOffsetX, layerOffsetY;
      gint bytes;
      gint start;

      drawable = gimp_drawable_get(layers[l]);
      dwidth  = drawable->width;
      dheight = drawable->height;
      bytes = drawable->bpp;

      /* Relate the layer coordinates to the image coordinates */
      gimp_drawable_offsets (layers[l], &layerOffsetX, &layerOffsetY);

      /*  initialize the pixel region to this layer */
      gimp_pixel_rgn_init (&srcPR, drawable, 0, 0, dwidth, dheight,
                           FALSE, FALSE);

      /* Update ymin. If the layer offset is greater than ymin,
       * then the region to be cropped already contains the whole layer
       * and we don't have to look any farther.
       */
      start = 0;
      if (layerOffsetY < 0)
          start = -layerOffsetY;
      for (y = start; y < dheight && layerOffsetY + y < ymin; y++)
        {
          gimp_pixel_rgn_get_row (&srcPR, buffer, 0, y, dwidth);

          for (x = 0; x < dwidth * bytes; x += bytes)
            {
              if (!colours_equal (buffer, &buffer[x], bytes))
                {
                  /* convert this layer coordinate back to image coord */
                  ymin = y + layerOffsetY;
                  break;
                }
            }
        }

      /* Update ymax. If the layer's offset plus height is less than
       * ymax, then the region to be cropped already contains the
       * whole layer and we don't have to look any farther.
       */
      start = dheight - 1;
      if (layerOffsetY + dheight > iheight)
          start = iheight - layerOffsetY - 1;
      for (y = start; y > 0 && layerOffsetY + y > ymax; y--)
        {
          gimp_pixel_rgn_get_row (&srcPR, buffer, 0, y, dwidth);

          for (x = 0; x < dwidth * bytes; x += bytes)
            {
              if (!colours_equal (buffer, &buffer[x], bytes))
                {
                  /* convert this layer coordinate back to image coord */
                  ymax = y + layerOffsetY + 1;
                  break;
                }
            }
        }

      /* Update xmin. If the layer offset is greater than ymin,
       * then the region to be cropped already contains the whole layer
       * and we don't have to look any farther.
       */
      start = 0;
      if (layerOffsetX < 0)
          start = -layerOffsetX;
      for (x = start; x < dwidth && layerOffsetX + x < xmin; x++)
        {
          gimp_pixel_rgn_get_col (&srcPR, buffer, x, 0, dheight);

          for (y = 0; y < dheight * bytes; y += bytes)
            {
              if (!colours_equal (buffer, &buffer[y], bytes))
                {
                  /* convert this layer coordinate back to image coord */
                  xmin = x + layerOffsetX;
                  break;
                }
            }
        }

      /* Update xmax. If the layer's offset plus width is less than
       * xmax, then the region to be cropped already contains the
       * whole layer and we don't have to look any farther.
       */
      start = dwidth - 1;
      if (layerOffsetX + dwidth > iwidth)
          start = iwidth - layerOffsetX - 1;
      for (x = start; x > 0 && layerOffsetX + x > xmax; x--)
        {
          gimp_pixel_rgn_get_col (&srcPR, buffer, x, 0, dheight);

          for (y = 0; y < dheight * bytes; y += bytes)
            {
              if (!colours_equal (buffer, &buffer[y], bytes))
                {
                  /* convert this layer coordinate back to image coord */
                  xmax = x + layerOffsetX + 1;
                  break;
                }
            }
        }

      gimp_progress_update ((gdouble)l / numlayers);
    }

  if (xmin == 0 && xmax == iwidth &&
      ymin == 0 && ymax == iheight)
    {
      g_message ("Nothing to crop.");
      return;
    }

  gimp_image_undo_group_start (image_id);

  gimp_image_crop(image_id,
                  xmax - xmin, ymax - ymin,
                  xmin, ymin);

  g_free (layers);
  g_free (buffer);

  gimp_progress_update (1.00);
  gimp_image_undo_group_end (image_id);
}