コード例 #1
0
static void
webx_pipeline_destroy (GtkObject *object)
{
  WebxPipeline *pipeline;
  pipeline = WEBX_PIPELINE (object);

  if (pipeline->rgb_image != -1)
    {
      gimp_image_delete (pipeline->rgb_image);
      pipeline->rgb_image = -1;
    }
  if (pipeline->indexed_image != -1)
    {
      gimp_image_delete (pipeline->indexed_image);
      pipeline->indexed_image = -1;
    }
  if (pipeline->background)
    {
      g_object_unref (pipeline->background);
      pipeline->background = NULL;
    }

  if (GTK_OBJECT_CLASS (parent_class)->destroy)
    GTK_OBJECT_CLASS (parent_class)->destroy (GTK_OBJECT (pipeline));
}
コード例 #2
0
ファイル: gap_image.c プロジェクト: GNOME/gimp-gap
/* ============================================================================
 * gap_image_delete_immediate
 *    delete image (with workaround to ensure that most of the
 *    allocatd memory is freed)
 * ============================================================================
 * The workaround disables undo and scales the image down to miniumum size
 * before calling the gimp_image_delete procedure.
 * this way memory resources for big layers will be freed up immediate.
 */
void
gap_image_delete_immediate (gint32 image_id)
{
  gboolean imageDeleteWorkaroundDefault = TRUE;
  if(gap_base_get_gimprc_gboolean_value("gap-image-delete-workaround"
         , imageDeleteWorkaroundDefault))
  {
    if(gap_debug)
    {
      printf("gap_image_delete_immediate: SCALED down to 2x2 id = %d (workaround for gimp_image-delete problem)\n"
              , (int)image_id
              );
    }

    gimp_image_undo_disable(image_id);
    
    //gimp_image_scale_full(image_id, 2, 2, 0 /*INTERPOLATION_NONE*/);

    gimp_context_push();
    gimp_context_set_interpolation(0);
    gimp_image_scale(image_id, 2, 2);
    gimp_context_pop();


    gimp_image_undo_enable(image_id); /* clear undo stack */
  }

  gimp_image_delete(image_id);
}       /* end  gap_image_delete_immediate */
コード例 #3
0
static void
do_texture_press ()
{
  gimp_image_delete (preview_image);
  preview_image = gimp_image_duplicate(image_ID);

  border (preview_image);

  preview_update (preview);
}
コード例 #4
0
ファイル: dog.c プロジェクト: Amerekanets/gimp
static void
preview_update_preview (GimpPreview  *preview,
                        GimpDrawable *drawable)
{
  gint          x1, y1;
  gint          width, height;
  gint          bpp;
  guchar       *buffer;
  GimpPixelRgn  src_rgn;
  GimpPixelRgn  preview_rgn;
  gint32        image_id, src_image_id;
  gint32        preview_id;
  GimpDrawable *preview_drawable;

  bpp = gimp_drawable_bpp (drawable->drawable_id);

  gimp_preview_get_position (preview, &x1, &y1);
  gimp_preview_get_size (preview, &width, &height);

  buffer = g_new (guchar, width * height * bpp);

  gimp_pixel_rgn_init (&src_rgn, drawable,
                       x1, y1, width, height, FALSE, FALSE);
  gimp_pixel_rgn_get_rect (&src_rgn, buffer,
                           x1, y1, width, height);

  /* set up gimp drawable for rendering preview into */
  src_image_id = gimp_drawable_get_image (drawable->drawable_id);
  image_id = gimp_image_new (width, height,
                             gimp_image_base_type (src_image_id));
  preview_id = gimp_layer_new (image_id, "preview", width, height,
                               gimp_drawable_type (drawable->drawable_id),
                               100,
                               GIMP_NORMAL_MODE);
  preview_drawable = gimp_drawable_get (preview_id);
  gimp_image_add_layer (image_id, preview_id, 0);
  gimp_layer_set_offsets (preview_id, 0, 0);
  gimp_pixel_rgn_init (&preview_rgn, preview_drawable,
                       0, 0, width, height, TRUE, TRUE);
  gimp_pixel_rgn_set_rect (&preview_rgn, buffer,
                           0, 0, width, height);
  gimp_drawable_flush (preview_drawable);
  gimp_drawable_merge_shadow (preview_id, TRUE);
  gimp_drawable_update (preview_id, 0, 0, width, height);

  dog (image_id, preview_drawable, dogvals.inner, dogvals.outer, FALSE);

  gimp_pixel_rgn_get_rect (&preview_rgn, buffer,
                           0, 0, width, height);

  gimp_preview_draw_buffer (preview, buffer, width * bpp);

  gimp_image_delete (image_id);
  g_free (buffer);
}
コード例 #5
0
void
webx_indexed_target_free_image (WebxIndexedTarget      *indexed,
                                WebxTargetInput        *input,
                                gint                    image)
{
  if (indexed->image == image)
    {
      gimp_image_delete (image);
      indexed->image = -1;
    }
}
コード例 #6
0
gint
webx_indexed_target_get_image (WebxIndexedTarget       *indexed,
                               WebxTargetInput         *input,
                               gint                    *layer)
{
  gint          tmp_image;
  gint          tmp_layer;
  gint       *layers;
  gint        num_layers;
  gchar      *custom_palette;
  gint        num_colors;
  gboolean    converted;

  g_return_val_if_fail (WEBX_IS_INDEXED_TARGET (indexed), -1);

  if (indexed->palette_type == GIMP_REUSE_PALETTE)
    {
      *layer = input->indexed_layer;
      return input->indexed_image;
    }

  custom_palette = indexed->custom_palette;
  if (! custom_palette)
    custom_palette = "";

  tmp_image = input->rgb_image;
  tmp_layer = input->rgb_layer;
  num_colors = indexed->num_colors;
  if (num_colors == 256 && gimp_drawable_has_alpha (tmp_layer))
    num_colors = 255;
  tmp_image = gimp_image_duplicate (tmp_image);
  converted = gimp_image_convert_indexed (tmp_image, indexed->dither_type,
                                          indexed->palette_type,
                                          num_colors,
                                          indexed->alpha_dither,
                                          indexed->remove_unused,
                                          custom_palette);
  if (! converted)
    {
      gimp_image_delete (tmp_image);
      *layer = -1;
      return -1;
    }
  layers = gimp_image_get_layers (tmp_image, &num_layers);
  g_assert (num_layers == 1);
  tmp_layer = layers[0];
  indexed->image = tmp_image;
  indexed->layer = tmp_layer;

  *layer= tmp_layer;
  return tmp_image;
}
コード例 #7
0
ファイル: gap_decode_xanim.c プロジェクト: AquaSoftGmbH/mjpeg
static int
p_convert_frames(gint32 frame_from, gint32 frame_to, char *basename, char *ext, char *ext2)
{
   GimpParam          *return_vals;
   int              nreturn_vals;
   gint32           l_tmp_image_id;
   char             l_first_xa_frame[200];

  /* load 1st one of those frames generated by xanim  */
   p_build_xanim_framename(l_first_xa_frame, frame_from, ext);
   l_tmp_image_id = p_load_image(l_first_xa_frame);

   /* convert the xanim frames (from ppm) to xcf fileformat
    * (the gap module for range convert is not linked to the frontends
    *  main program, therefore i call the convert procedure by PDB-interface)
    */   
   return_vals = gimp_run_procedure ("plug_in_gap_range_convert2",
                                    &nreturn_vals,
                                    GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE,     /* runmode  */
                                    GIMP_PDB_IMAGE, l_tmp_image_id,
                                    GIMP_PDB_DRAWABLE, 0,         /* (unused)  */
                                    GIMP_PDB_INT32, frame_from,
                                    GIMP_PDB_INT32, frame_to,
                                    GIMP_PDB_INT32, 0,            /* dont flatten */
                                    GIMP_PDB_INT32, 4444,         /* dest type (keep type) */
                                    GIMP_PDB_INT32, 256,          /* colors (unused)  */
                                    GIMP_PDB_INT32, 0,            /* no dither (unused)  */
                                    GIMP_PDB_STRING, ext2,        /* extension for dest. filetype  */
                                    GIMP_PDB_STRING, basename,    /* basename for dest. filetype  */
                                    GIMP_PDB_INT32, 0,            /* (unused)  */
                                    GIMP_PDB_INT32, 0,            /* (unused)  */
                                    GIMP_PDB_INT32, 0,            /* (unused)  */
                                    GIMP_PDB_STRING, "none",      /* (unused) palettename */
                                    GIMP_PDB_END);

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

   if (return_vals[0].data.d_status != GIMP_PDB_SUCCESS)
   {
      return(-1);  
   }

   return(0);  /* OK */
}
コード例 #8
0
static void
webx_pipeline_create_background (WebxPipeline *pipeline)
{
  g_return_if_fail (WEBX_IS_PIPELINE (pipeline));

  if (gimp_drawable_is_rgb (pipeline->rgb_layer))
    {
      pipeline->background = webx_drawable_to_pixbuf (pipeline->rgb_layer);
    }
  else
    {
      /* pipeline->rgb_image is still original image, which can be
         non rgb (as we create background early in pipeline). */
      gint duplicate = gimp_image_duplicate (pipeline->rgb_image);
      gimp_image_undo_disable (duplicate);
      pipeline->background = webx_image_to_pixbuf (duplicate);
      gimp_image_delete (duplicate);
    }
}
コード例 #9
0
ファイル: gap_pview_da.c プロジェクト: kleopatra999/gimp-gap
/* ---------------------------------------
 * gap_pview_render_f_from_image_duplicate
 * ---------------------------------------
 * render preview widget from image.
 * This procedure creates a temorary copy of the image
 * for rendering of the preview.
 * NOTE: if the caller wants to render a temporary image
 *       that is not needed anymore after the rendering,
 *       the procedure gap_pview_render_f_from_image should be used
 *       to avoid duplicating of the image.
 *
 * hint: call gtk_widget_queue_draw(pv_ptr->da_widget);
 * after this procedure to make the changes appear on screen.
 */
void
gap_pview_render_f_from_image_duplicate (GapPView *pv_ptr
  , gint32 image_id
  , gint32 flip_request
  , gint32 flip_status
  )
{
  gint32 dup_image_id;
  
  dup_image_id = gimp_image_duplicate(image_id);
  gimp_image_undo_disable (dup_image_id); 
  gap_pview_render_f_from_image(pv_ptr
                 , dup_image_id
                 , flip_request
                 , flip_status
                 );
  gimp_image_delete(dup_image_id);
  
}  /* end gap_pview_render_f_from_image_duplicate */
コード例 #10
0
ファイル: gimp-plugin-vtf.cpp プロジェクト: lxndr/vtf
gint32
file_vtf_load_image (const gchar *fname, GError **error)
{
    gimp_progress_init_printf ("Opening '%s'", gimp_filename_to_utf8 (fname));

    gint32 image = -1;
    std::auto_ptr<Vtf::File> vtf (new Vtf::File);

    try {
        vtf->load(fname);

        Vtf::HiresImageResource* vres = (Vtf::HiresImageResource*)
                                        vtf->findResource (Vtf::Resource::TypeHires);
        if (!vres)
            throw Vtf::Exception ("Cound not find high-resolution image");

        image = gimp_image_new (vres->width (), vres->height  (), GIMP_RGB);
        gimp_image_set_filename (image, fname);

        guint16 i, frame_count = vres->frameCount ();
        for (i = 0; i < frame_count; i++) {
            if (!file_vtf_load_layer (vres, image, i)) {
                g_set_error (error, 0, 0, "Unsupported format %s",
                             Vtf::formatToString (vres->format()));
                gimp_image_delete (image);
                image = -1;
                break;
            }
        }

        gimp_progress_update (1.0);
    } catch (std::exception& e) {
        g_set_error (error, 0, 0, e.what ());
    }

    return image;
}
コード例 #11
0
ファイル: gimp-plugin-vtf.cpp プロジェクト: lxndr/vtf
gint32
file_vtf_load_thumbnail_image (const gchar *fname, gint *width, gint *height,
                               GError **error)
{
    gint32 image = -1;
    gimp_progress_init_printf ("Opening thumbnail for '%s'",
                               gimp_filename_to_utf8 (fname));

    Vtf::File *vtf = new Vtf::File;
    try {
        vtf->load(fname);

        Vtf::HiresImageResource* vres = (Vtf::HiresImageResource*)
                                        vtf->findResource(Vtf::Resource::TypeHires);
        if (!vres)
            throw Vtf::Exception ("Cound not find high-resolution image");

        *width = static_cast<gint> (vres->width ());
        *height = static_cast<gint> (vres->height ());

        image = gimp_image_new (*width, *height, GIMP_RGB);
        if (!file_vtf_load_layer (vres, image, 0)) {
            g_set_error (error, 0, 0, "Unsupported format %s",
                         Vtf::formatToString(vres->format()));
            gimp_image_delete (image);
            image = -1;
        }

        gimp_progress_update (1.0);
    } catch (std::exception& e) {
        g_set_error (error, 0, 0, e.what());
    }

    delete vtf;
    return image;
}
コード例 #12
0
ファイル: psd-thumb-load.c プロジェクト: jdburton/gimp-osx
/* Main file load function */
gint32
load_thumbnail_image (const gchar  *filename,
                      gint         *width,
                      gint         *height,
                      GError      **load_error)
{
  FILE        *f;
  struct stat  st;
  PSDimage     img_a;
  gint32       image_id = -1;
  GError      *error    = NULL;

  /* ----- Open PSD file ----- */
  if (g_stat (filename, &st) == -1)
    return -1;

  IFDBG(1) g_debug ("Open file %s", gimp_filename_to_utf8 (filename));
  f = g_fopen (filename, "rb");
  if (f == NULL)
    {
      g_set_error (load_error, G_FILE_ERROR, g_file_error_from_errno (errno),
                   _("Could not open '%s' for reading: %s"),
                   gimp_filename_to_utf8 (filename), g_strerror (errno));
      return -1;
    }

  gimp_progress_init_printf (_("Opening thumbnail for '%s'"),
                             gimp_filename_to_utf8 (filename));

  /* ----- Read the PSD file Header block ----- */
  IFDBG(2) g_debug ("Read header block");
  if (read_header_block (&img_a, f, &error) < 0)
    goto load_error;
  gimp_progress_update (0.2);

  /* ----- Read the PSD file Colour Mode block ----- */
  IFDBG(2) g_debug ("Read colour mode block");
  if (read_color_mode_block (&img_a, f, &error) < 0)
    goto load_error;
  gimp_progress_update (0.4);

  /* ----- Read the PSD file Image Resource block ----- */
  IFDBG(2) g_debug ("Read image resource block");
  if (read_image_resource_block (&img_a, f, &error) < 0)
    goto load_error;
  gimp_progress_update (0.6);

  /* ----- Create GIMP image ----- */
  IFDBG(2) g_debug ("Create GIMP image");
  image_id = create_gimp_image (&img_a, filename);
  if (image_id < 0)
    goto load_error;

  /* ----- Add image resources ----- */
  IFDBG(2) g_debug ("Add image resources");
  if (add_image_resources (image_id, &img_a, f, &error) < 1)
    goto load_error;
  gimp_progress_update (1.0);

  gimp_image_clean_all (image_id);
  gimp_image_undo_enable (image_id);
  fclose (f);

  *width = img_a.columns;
  *height = img_a.rows;
  return image_id;

  /* ----- Process load errors ----- */
 load_error:
  if (error)
    {
      g_set_error (load_error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                   _("Error loading PSD file: %s"), error->message);
      g_error_free (error);
    }

  /* Delete partially loaded image */
  if (image_id > 0)
    gimp_image_delete (image_id);

  /* Close file if Open */
  if (! (f == NULL))
    fclose (f);

  return -1;
}
コード例 #13
0
ファイル: main.c プロジェクト: brion/gimp-icns
static void
run (const gchar      *name,
     gint              nparams,
     const GimpParam  *param,
     gint             *nreturn_vals,
     GimpParam       **return_vals)
{
  static GimpParam   values[2];
  gint32             image_ID;
  gint32             drawable_ID;
  GimpRunMode        run_mode;
  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
  GimpExportReturn   export = GIMP_EXPORT_CANCEL;

  run_mode = param[0].data.d_int32;

  *nreturn_vals = 1;
  *return_vals  = values;
  values[0].type          = GIMP_PDB_STATUS;
  values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;

  if (strcmp (name, "file_icns_load") == 0)
    {
      switch (run_mode)
        {
        case GIMP_RUN_INTERACTIVE:
          interactive_ico = TRUE;
          break;

        case GIMP_RUN_NONINTERACTIVE:
          interactive_ico = FALSE;
          if (nparams != 3)
            status = GIMP_PDB_CALLING_ERROR;
          break;

        default:
          break;
        }

      if (status == GIMP_PDB_SUCCESS)
        {
          image_ID = LoadICNS (param[1].data.d_string);

           if (image_ID != -1)
             {
               *nreturn_vals = 2;
               values[1].type         = GIMP_PDB_IMAGE;
               values[1].data.d_image = image_ID;
             }
           else
             {
               status = GIMP_PDB_EXECUTION_ERROR;
             }
        }
    }
  else if (strcmp (name, "file_icns_save") == 0)
    {
      gchar *file_name;

      image_ID    = param[1].data.d_int32;
      drawable_ID = param[2].data.d_int32;
      file_name   = param[3].data.d_string;

      switch (run_mode)
        {
        case GIMP_RUN_INTERACTIVE:
          interactive_ico = TRUE;
          break;

        case GIMP_RUN_NONINTERACTIVE:
          interactive_ico = FALSE;
          /*  Make sure all the arguments are there!  */
          if (nparams < 5)
            status = GIMP_PDB_CALLING_ERROR;
          break;

        case GIMP_RUN_WITH_LAST_VALS:
          interactive_ico = FALSE;
          break;

        default:
          break;
        }

      if (status == GIMP_PDB_SUCCESS)
        {
          status = SaveICNS (file_name, image_ID);
        }

      if (export == GIMP_EXPORT_EXPORT)
        gimp_image_delete (image_ID);
    }
コード例 #14
0
gint32
load_image (const gchar  *filename,
            GimpRunMode   runmode,
            gboolean      preview,
            gboolean     *resolution_loaded,
            GError      **error)
{
  gint32 volatile  image_ID;
  gint32           layer_ID;
  struct jpeg_decompress_struct cinfo;
  struct my_error_mgr           jerr;
  jpeg_saved_marker_ptr         marker;
  FILE            *infile;
  guchar          *buf;
  guchar         **rowbuf;
  GimpImageBaseType image_type;
  GimpImageType    layer_type;
  GeglBuffer      *buffer = NULL;
  const Babl      *format;
  gint             tile_height;
  gint             scanlines;
  gint             i, start, end;
  cmsHTRANSFORM    cmyk_transform = NULL;

  /* We set up the normal JPEG error routines. */
  cinfo.err = jpeg_std_error (&jerr.pub);
  jerr.pub.error_exit = my_error_exit;

  if (!preview)
    {
      jerr.pub.output_message = my_output_message;

      gimp_progress_init_printf (_("Opening '%s'"),
                                 gimp_filename_to_utf8 (filename));
    }

  if ((infile = g_fopen (filename, "rb")) == NULL)
    {
      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
                   _("Could not open '%s' for reading: %s"),
                   gimp_filename_to_utf8 (filename), g_strerror (errno));
      return -1;
    }

  image_ID = -1;

  /* Establish the setjmp return context for my_error_exit to use. */
  if (setjmp (jerr.setjmp_buffer))
    {
      /* If we get here, the JPEG code has signaled an error.
       * We need to clean up the JPEG object, close the input file, and return.
       */
      jpeg_destroy_decompress (&cinfo);
      if (infile)
        fclose (infile);

      if (image_ID != -1 && !preview)
        gimp_image_delete (image_ID);

      if (preview)
        destroy_preview ();

      if (buffer)
        g_object_unref (buffer);

      return -1;
    }

  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress (&cinfo);

  /* Step 2: specify data source (eg, a file) */

  jpeg_stdio_src (&cinfo, infile);

  if (! preview)
    {
      /* - step 2.1: tell the lib to save the comments */
      jpeg_save_markers (&cinfo, JPEG_COM, 0xffff);

      /* - step 2.2: tell the lib to save APP1 data (Exif or XMP) */
      jpeg_save_markers (&cinfo, JPEG_APP0 + 1, 0xffff);

      /* - step 2.3: tell the lib to save APP2 data (ICC profiles) */
      jpeg_save_markers (&cinfo, JPEG_APP0 + 2, 0xffff);
    }

  /* Step 3: read file parameters with jpeg_read_header() */

  jpeg_read_header (&cinfo, TRUE);

  /* We can ignore the return value from jpeg_read_header since
   *   (a) suspension is not possible with the stdio data source, and
   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
   * See libjpeg.doc for more info.
   */

  /* Step 4: set parameters for decompression */

  /* In this example, we don't need to change any of the defaults set by
   * jpeg_read_header(), so we do nothing here.
   */

  /* Step 5: Start decompressor */

  jpeg_start_decompress (&cinfo);

  /* We may need to do some setup of our own at this point before reading
   * the data.  After jpeg_start_decompress() we have the correct scaled
   * output image dimensions available, as well as the output colormap
   * if we asked for color quantization.
   */

  /* temporary buffer */
  tile_height = gimp_tile_height ();
  buf = g_new (guchar,
               tile_height * cinfo.output_width * cinfo.output_components);

  rowbuf = g_new (guchar *, tile_height);

  for (i = 0; i < tile_height; i++)
    rowbuf[i] = buf + cinfo.output_width * cinfo.output_components * i;

  switch (cinfo.output_components)
    {
    case 1:
      image_type = GIMP_GRAY;
      layer_type = GIMP_GRAY_IMAGE;
      break;

    case 3:
      image_type = GIMP_RGB;
      layer_type = GIMP_RGB_IMAGE;
      break;

    case 4:
      if (cinfo.out_color_space == JCS_CMYK)
        {
          image_type = GIMP_RGB;
          layer_type = GIMP_RGB_IMAGE;
          break;
        }
      /*fallthrough*/

    default:
      g_message ("Don't know how to load JPEG images "
                 "with %d color channels, using colorspace %d (%d).",
                 cinfo.output_components, cinfo.out_color_space,
                 cinfo.jpeg_color_space);
      return -1;
      break;
    }

  if (preview)
    {
      image_ID = preview_image_ID;
    }
  else
    {
      image_ID = gimp_image_new_with_precision (cinfo.output_width,
                                                cinfo.output_height,
                                                image_type,
                                                GIMP_PRECISION_U8_GAMMA);

      gimp_image_undo_disable (image_ID);
      gimp_image_set_filename (image_ID, filename);
    }

  if (preview)
    {
      preview_layer_ID = gimp_layer_new (preview_image_ID, _("JPEG preview"),
                                         cinfo.output_width,
                                         cinfo.output_height,
                                         layer_type, 100, GIMP_NORMAL_MODE);
      layer_ID = preview_layer_ID;
    }
  else
    {
      layer_ID = gimp_layer_new (image_ID, _("Background"),
                                 cinfo.output_width,
                                 cinfo.output_height,
                                 layer_type, 100, GIMP_NORMAL_MODE);
    }

  if (! preview)
    {
      GString  *comment_buffer = NULL;
      guint8   *profile        = NULL;
      guint     profile_size   = 0;

      /* Step 5.0: save the original JPEG settings in a parasite */
      jpeg_detect_original_settings (&cinfo, image_ID);

      /* Step 5.1: check for comments, or Exif metadata in APP1 markers */
      for (marker = cinfo.marker_list; marker; marker = marker->next)
        {
          const gchar *data = (const gchar *) marker->data;
          gsize        len  = marker->data_length;

          if (marker->marker == JPEG_COM)
            {
#ifdef GIMP_UNSTABLE
              g_print ("jpeg-load: found image comment (%d bytes)\n",
                       marker->data_length);
#endif

              if (! comment_buffer)
                {
                  comment_buffer = g_string_new_len (data, len);
                }
              else
                {
                  /* concatenate multiple comments, separate them with LF */
                  g_string_append_c (comment_buffer, '\n');
                  g_string_append_len (comment_buffer, data, len);
                }
            }
          else if ((marker->marker == JPEG_APP0 + 1)
                   && (len > sizeof (JPEG_APP_HEADER_EXIF) + 8)
                   && ! strcmp (JPEG_APP_HEADER_EXIF, data))
            {
#ifdef GIMP_UNSTABLE
              g_print ("jpeg-load: found Exif block (%d bytes)\n",
                       (gint) (len - sizeof (JPEG_APP_HEADER_EXIF)));
#endif
            }
        }

      if (jpeg_load_resolution (image_ID, &cinfo))
        {
          if (resolution_loaded)
            *resolution_loaded = TRUE;
        }

      /* if we found any comments, then make a parasite for them */
      if (comment_buffer && comment_buffer->len)
        {
          GimpParasite *parasite;

          jpeg_load_sanitize_comment (comment_buffer->str);
          parasite = gimp_parasite_new ("gimp-comment",
                                        GIMP_PARASITE_PERSISTENT,
                                        strlen (comment_buffer->str) + 1,
                                        comment_buffer->str);
          gimp_image_attach_parasite (image_ID, parasite);
          gimp_parasite_free (parasite);

          g_string_free (comment_buffer, TRUE);
        }

      /* Step 5.3: check for an embedded ICC profile in APP2 markers */
      jpeg_icc_read_profile (&cinfo, &profile, &profile_size);

      if (cinfo.out_color_space == JCS_CMYK)
        {
          cmyk_transform = jpeg_load_cmyk_transform (profile, profile_size);
        }
      else if (profile) /* don't attach the profile if we are transforming */
        {
          GimpParasite *parasite;

          parasite = gimp_parasite_new ("icc-profile",
                                        GIMP_PARASITE_PERSISTENT |
                                        GIMP_PARASITE_UNDOABLE,
                                        profile_size, profile);
          gimp_image_attach_parasite (image_ID, parasite);
          gimp_parasite_free (parasite);
        }

      g_free (profile);

      /* Do not attach the "jpeg-save-options" parasite to the image
       * because this conflicts with the global defaults (bug #75398).
       */
    }

  /* Step 6: while (scan lines remain to be read) */
  /*           jpeg_read_scanlines(...); */

  /* Here we use the library's state variable cinfo.output_scanline as the
   * loop counter, so that we don't have to keep track ourselves.
   */

  buffer = gimp_drawable_get_buffer (layer_ID);
  format = babl_format (image_type == GIMP_RGB ? "R'G'B' u8" : "Y' u8");

  while (cinfo.output_scanline < cinfo.output_height)
    {
      start = cinfo.output_scanline;
      end   = cinfo.output_scanline + tile_height;
      end   = MIN (end, cinfo.output_height);

      scanlines = end - start;

      for (i = 0; i < scanlines; i++)
        jpeg_read_scanlines (&cinfo, (JSAMPARRAY) &rowbuf[i], 1);

      if (cinfo.out_color_space == JCS_CMYK)
        jpeg_load_cmyk_to_rgb (buf, cinfo.output_width * scanlines,
                               cmyk_transform);

      gegl_buffer_set (buffer,
                       GEGL_RECTANGLE (0, start, cinfo.output_width, scanlines),
                       0,
                       format,
                       buf,
                       GEGL_AUTO_ROWSTRIDE);

      if (! preview && (cinfo.output_scanline % 32) == 0)
        gimp_progress_update ((gdouble) cinfo.output_scanline /
                              (gdouble) cinfo.output_height);
    }

  /* Step 7: Finish decompression */

  jpeg_finish_decompress (&cinfo);
  /* We can ignore the return value since suspension is not possible
   * with the stdio data source.
   */

  if (cmyk_transform)
    cmsDeleteTransform (cmyk_transform);

  /* Step 8: Release JPEG decompression object */

  /* This is an important step since it will release a good deal of memory. */
  jpeg_destroy_decompress (&cinfo);

  g_object_unref (buffer);

  /* free up the temporary buffers */
  g_free (rowbuf);
  g_free (buf);

  /* After finish_decompress, we can close the input file.
   * Here we postpone it until after no more JPEG errors are possible,
   * so as to simplify the setjmp error logic above.  (Actually, I don't
   * think that jpeg_destroy can do an error exit, but why assume anything...)
   */
  fclose (infile);

  /* At this point you may want to check to see whether any corrupt-data
   * warnings occurred (test whether jerr.num_warnings is nonzero).
   */

  /* Detach from the drawable and add it to the image.
   */
  if (! preview)
    {
      gimp_progress_update (1.0);
    }

  gimp_image_insert_layer (image_ID, layer_ID, -1, 0);

  return image_ID;
}
コード例 #15
0
gint32
load_thumbnail_image (GFile         *file,
                      gint          *width,
                      gint          *height,
                      GimpImageType *type,
                      GError       **error)
{
  gint32 volatile               image_ID = -1;
  struct jpeg_decompress_struct cinfo;
  struct my_error_mgr           jerr;
  FILE                         *infile   = NULL;

  gimp_progress_init_printf (_("Opening thumbnail for '%s'"),
                             g_file_get_parse_name (file));

  image_ID = gimp_image_metadata_load_thumbnail (file, error);
  if (image_ID < 1)
    return -1;

  cinfo.err = jpeg_std_error (&jerr.pub);
  jerr.pub.error_exit     = my_error_exit;
  jerr.pub.output_message = my_output_message;

  if ((infile = g_fopen (g_file_get_path (file), "rb")) == NULL)
    {
      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
                   _("Could not open '%s' for reading: %s"),
                   g_file_get_parse_name (file), g_strerror (errno));

      if (image_ID != -1)
        gimp_image_delete (image_ID);

      return -1;
    }

  /* Establish the setjmp return context for my_error_exit to use. */
  if (setjmp (jerr.setjmp_buffer))
    {
      /* If we get here, the JPEG code has signaled an error.  We
       * need to clean up the JPEG object, close the input file,
       * and return.
       */
      jpeg_destroy_decompress (&cinfo);

      if (image_ID != -1)
        gimp_image_delete (image_ID);

      return -1;
    }

  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress (&cinfo);

  /* Step 2: specify data source (eg, a file) */

  jpeg_stdio_src (&cinfo, infile);

  /* Step 3: read file parameters with jpeg_read_header() */

  jpeg_read_header (&cinfo, TRUE);

  jpeg_start_decompress (&cinfo);

  *width  = cinfo.output_width;
  *height = cinfo.output_height;

  switch (cinfo.output_components)
    {
    case 1:
      *type = GIMP_GRAY_IMAGE;
      break;

    case 3:
      *type = GIMP_RGB_IMAGE;
      break;

    case 4:
      if (cinfo.out_color_space == JCS_CMYK)
        {
          *type = GIMP_RGB_IMAGE;
          break;
        }
      /*fallthrough*/

    default:
      g_message ("Don't know how to load JPEG images "
                 "with %d color channels, using colorspace %d (%d).",
                 cinfo.output_components, cinfo.out_color_space,
                 cinfo.jpeg_color_space);

      gimp_image_delete (image_ID);
      image_ID = -1;
      break;
    }

  /* Step 4: Release JPEG decompression object */

  /* This is an important step since it will release a good deal
   * of memory.
   */
  jpeg_destroy_decompress (&cinfo);

  fclose (infile);

  return image_ID;
}
コード例 #16
0
ファイル: gap_movtar_main.c プロジェクト: AquaSoftGmbH/mjpeg
/* ============================================================================
 * 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;  
}
コード例 #17
0
ファイル: ico-dialog.c プロジェクト: Amerekanets/gimp-1
static void
ico_dialog_update_icon_preview (GtkWidget *dialog,
                                gint32     layer,
                                gint       bpp)
{
  GtkWidget *preview = ico_dialog_get_layer_preview (dialog, layer);
  GdkPixbuf *pixbuf;
  gint       w       = gimp_drawable_width (layer);
  gint       h       = gimp_drawable_height (layer);

  if (! preview)
    return;

  if (bpp <= 8)
    {
      GimpDrawable *drawable;
      GimpDrawable *tmp;
      GimpPixelRgn  src_pixel_rgn, dst_pixel_rgn;
      gint32        image;
      gint32        tmp_image;
      gint32        tmp_layer;
      guchar       *buffer;
      guchar       *cmap;
      gint          num_colors;

      image = gimp_item_get_image (layer);

      tmp_image = gimp_image_new (w, h, gimp_image_base_type (image));
      gimp_image_undo_disable (tmp_image);

      if (gimp_drawable_is_indexed (layer))
        {
          cmap = gimp_image_get_colormap (image, &num_colors);
          gimp_image_set_colormap (tmp_image, cmap, num_colors);
          g_free (cmap);
        }

      tmp_layer = gimp_layer_new (tmp_image, "temporary", w, h,
                                  gimp_drawable_type (layer),
                                  100, GIMP_NORMAL_MODE);
      gimp_image_insert_layer (tmp_image, tmp_layer, -1, 0);

      drawable = gimp_drawable_get (layer);
      tmp      = gimp_drawable_get (tmp_layer);

      gimp_pixel_rgn_init (&src_pixel_rgn, drawable, 0, 0, w, h, FALSE, FALSE);
      gimp_pixel_rgn_init (&dst_pixel_rgn, tmp,      0, 0, w, h, TRUE, FALSE);

      buffer = g_malloc (w * h * 4);
      gimp_pixel_rgn_get_rect (&src_pixel_rgn, buffer, 0, 0, w, h);
      gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);

      gimp_drawable_detach (tmp);
      gimp_drawable_detach (drawable);

      if (gimp_drawable_is_indexed (layer))
        gimp_image_convert_rgb (tmp_image);

      gimp_image_convert_indexed (tmp_image,
                                  GIMP_FS_DITHER, GIMP_MAKE_PALETTE,
                                  1 <<bpp, TRUE, FALSE, "dummy");

      cmap = gimp_image_get_colormap (tmp_image, &num_colors);
      if ( num_colors == (1 << bpp) &&
           !ico_cmap_contains_black (cmap, num_colors))
        {
          /* Windows icons with color maps need the color black.
           * We need to eliminate one more color to make room for black.
           */
          if (gimp_drawable_is_indexed (layer))
            {
              g_free (cmap);
              cmap = gimp_image_get_colormap (image, &num_colors);
              gimp_image_set_colormap (tmp_image, cmap, num_colors);
            }
          else if (gimp_drawable_is_gray (layer))
            {
              gimp_image_convert_grayscale (tmp_image);
            }
          else
            {
              gimp_image_convert_rgb (tmp_image);
            }

          tmp = gimp_drawable_get (tmp_layer);
          gimp_pixel_rgn_init (&dst_pixel_rgn,
                               tmp, 0, 0, w, h, TRUE, FALSE);
          gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);
          gimp_drawable_detach (tmp);

          if (!gimp_drawable_is_rgb (layer))
            gimp_image_convert_rgb (tmp_image);

          gimp_image_convert_indexed (tmp_image,
                                      GIMP_FS_DITHER, GIMP_MAKE_PALETTE,
                                      (1<<bpp) - 1, TRUE, FALSE, "dummy");
        }
      g_free (cmap);
      g_free (buffer);

      pixbuf = gimp_drawable_get_thumbnail (tmp_layer,
                                            MIN (w, 128), MIN (h, 128),
                                            GIMP_PIXBUF_SMALL_CHECKS);

      gimp_image_delete (tmp_image);
    }
  else if (bpp == 24)
    {
      GimpDrawable *drawable;
      GimpDrawable *tmp;
      GimpPixelRgn  src_pixel_rgn, dst_pixel_rgn;
      gint32        image;
      gint32        tmp_image;
      gint32        tmp_layer;
      guchar       *buffer;
      GimpParam    *return_vals;
      gint          n_return_vals;

      image = gimp_item_get_image (layer);

      tmp_image = gimp_image_new (w, h, gimp_image_base_type (image));
      gimp_image_undo_disable (tmp_image);

      if (gimp_drawable_is_indexed (layer))
        {
          guchar *cmap;
          gint    num_colors;

          cmap = gimp_image_get_colormap (image, &num_colors);
          gimp_image_set_colormap (tmp_image, cmap, num_colors);
          g_free (cmap);
        }

      tmp_layer = gimp_layer_new (tmp_image, "temporary", w, h,
                                  gimp_drawable_type (layer),
                                  100, GIMP_NORMAL_MODE);
      gimp_image_insert_layer (tmp_image, tmp_layer, -1, 0);

      drawable = gimp_drawable_get (layer);
      tmp      = gimp_drawable_get (tmp_layer);

      gimp_pixel_rgn_init (&src_pixel_rgn, drawable, 0, 0, w, h, FALSE, FALSE);
      gimp_pixel_rgn_init (&dst_pixel_rgn, tmp,      0, 0, w, h, TRUE, FALSE);

      buffer = g_malloc (w * h * 4);
      gimp_pixel_rgn_get_rect (&src_pixel_rgn, buffer, 0, 0, w, h);
      gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);
      g_free (buffer);

      gimp_drawable_detach (tmp);
      gimp_drawable_detach (drawable);

      if (gimp_drawable_is_indexed (layer))
        gimp_image_convert_rgb (tmp_image);

      return_vals =
        gimp_run_procedure ("plug-in-threshold-alpha", &n_return_vals,
                            GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE,
                            GIMP_PDB_IMAGE, tmp_image,
                            GIMP_PDB_DRAWABLE, tmp_layer,
                            GIMP_PDB_INT32, ICO_ALPHA_THRESHOLD,
                            GIMP_PDB_END);
      gimp_destroy_params (return_vals, n_return_vals);

      pixbuf = gimp_drawable_get_thumbnail (tmp_layer,
                                            MIN (w, 128), MIN (h, 128),
                                            GIMP_PIXBUF_SMALL_CHECKS);

      gimp_image_delete (tmp_image);
    }
  else
    {
      pixbuf = gimp_drawable_get_thumbnail (layer,
                                            MIN (w, 128), MIN (h, 128),
                                            GIMP_PIXBUF_SMALL_CHECKS);
    }

  gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
  g_object_unref (pixbuf);
}
コード例 #18
0
ファイル: jpeg-load.c プロジェクト: Three-DS/gimp-2.8.10
gint32
load_thumbnail_image (const gchar  *filename,
                      gint         *width,
                      gint         *height,
                      GError      **error)
{
  gint32 volatile  image_ID;
  ExifData        *exif_data;
  GimpPixelRgn     pixel_rgn;
  GimpDrawable    *drawable;
  gint32           layer_ID;
  struct jpeg_decompress_struct cinfo;
  struct my_error_mgr           jerr;
  guchar          *buf;
  guchar         **rowbuf;
  gint             image_type;
  gint             layer_type;
  gint             tile_height;
  gint             scanlines;
  gint             i, start, end;
  gint             orientation;
  my_src_ptr       src;
  FILE            *infile;

  image_ID = -1;
  exif_data = jpeg_exif_data_new_from_file (filename, NULL);

  if (! ((exif_data) && (exif_data->data) && (exif_data->size > 0)))
    return -1;

  orientation = jpeg_exif_get_orientation (exif_data);

  cinfo.err = jpeg_std_error (&jerr.pub);
  jerr.pub.error_exit     = my_error_exit;
  jerr.pub.output_message = my_output_message;

  gimp_progress_init_printf (_("Opening thumbnail for '%s'"),
                             gimp_filename_to_utf8 (filename));

  /* Establish the setjmp return context for my_error_exit to use. */
  if (setjmp (jerr.setjmp_buffer))
    {
      /* If we get here, the JPEG code has signaled an error.  We
       * need to clean up the JPEG object, close the input file,
       * and return.
       */
      jpeg_destroy_decompress (&cinfo);

      if (image_ID != -1)
        gimp_image_delete (image_ID);

      if (exif_data)
        {
          exif_data_unref (exif_data);
          exif_data = NULL;
        }

      return -1;
    }

  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress (&cinfo);

  /* Step 2: specify data source (eg, a file) */

  if (cinfo.src == NULL)
    cinfo.src = (struct jpeg_source_mgr *)(*cinfo.mem->alloc_small)
      ((j_common_ptr) &cinfo, JPOOL_PERMANENT,
       sizeof (my_source_mgr));

  src = (my_src_ptr) cinfo.src;

  src->pub.init_source       = init_source;
  src->pub.fill_input_buffer = fill_input_buffer;
  src->pub.skip_input_data   = skip_input_data;
  src->pub.resync_to_restart = jpeg_resync_to_restart;
  src->pub.term_source       = term_source;

  src->pub.bytes_in_buffer   = exif_data->size;
  src->pub.next_input_byte   = exif_data->data;

  src->buffer = exif_data->data;
  src->size = exif_data->size;

  /* Step 3: read file parameters with jpeg_read_header() */

  jpeg_read_header (&cinfo, TRUE);

  /* Step 4: set parameters for decompression */

  /* In this example, we don't need to change any of the defaults set by
   * jpeg_read_header(), so we do nothing here.
   */

  /* Step 5: Start decompressor */

  jpeg_start_decompress (&cinfo);

  /* We may need to do some setup of our own at this point before
   * reading the data.  After jpeg_start_decompress() we have the
   * correct scaled output image dimensions available, as well as
   * the output colormap if we asked for color quantization.  In
   * this example, we need to make an output work buffer of the
   * right size.
   */

  /* temporary buffer */
  tile_height = gimp_tile_height ();
  buf = g_new (guchar,
               tile_height * cinfo.output_width * cinfo.output_components);

  rowbuf = g_new (guchar *, tile_height);

  for (i = 0; i < tile_height; i++)
    rowbuf[i] = buf + cinfo.output_width * cinfo.output_components * i;

  /* Create a new image of the proper size and associate the
   * filename with it.
   */
  switch (cinfo.output_components)
    {
    case 1:
      image_type = GIMP_GRAY;
      layer_type = GIMP_GRAY_IMAGE;
      break;

    case 3:
      image_type = GIMP_RGB;
      layer_type = GIMP_RGB_IMAGE;
      break;

    case 4:
      if (cinfo.out_color_space == JCS_CMYK)
        {
          image_type = GIMP_RGB;
          layer_type = GIMP_RGB_IMAGE;
          break;
        }
      /*fallthrough*/

    default:
      g_message ("Don't know how to load JPEG images "
                 "with %d color channels, using colorspace %d (%d).",
                 cinfo.output_components, cinfo.out_color_space,
                 cinfo.jpeg_color_space);

      if (exif_data)
        {
          exif_data_unref (exif_data);
          exif_data = NULL;
        }

      return -1;
      break;
    }

  image_ID = gimp_image_new (cinfo.output_width, cinfo.output_height,
                             image_type);

  gimp_image_undo_disable (image_ID);
  gimp_image_set_filename (image_ID, filename);

  jpeg_load_resolution (image_ID, &cinfo);

  layer_ID = gimp_layer_new (image_ID, _("Background"),
                             cinfo.output_width,
                             cinfo.output_height,
                             layer_type, 100, GIMP_NORMAL_MODE);

  drawable_global = drawable = gimp_drawable_get (layer_ID);
  gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0,
                       drawable->width, drawable->height, TRUE, FALSE);

  /* Step 6: while (scan lines remain to be read) */
  /*           jpeg_read_scanlines(...); */

  /* Here we use the library's state variable cinfo.output_scanline as the
   * loop counter, so that we don't have to keep track ourselves.
   */
  while (cinfo.output_scanline < cinfo.output_height)
    {
      start = cinfo.output_scanline;
      end   = cinfo.output_scanline + tile_height;
      end   = MIN (end, cinfo.output_height);
      scanlines = end - start;

      for (i = 0; i < scanlines; i++)
        jpeg_read_scanlines (&cinfo, (JSAMPARRAY) &rowbuf[i], 1);

      if (cinfo.out_color_space == JCS_CMYK)
        jpeg_load_cmyk_to_rgb (buf, drawable->width * scanlines, NULL);

      gimp_pixel_rgn_set_rect (&pixel_rgn, buf,
                               0, start, drawable->width, scanlines);

      gimp_progress_update ((gdouble) cinfo.output_scanline /
                            (gdouble) cinfo.output_height);
    }

  /* Step 7: Finish decompression */

  jpeg_finish_decompress (&cinfo);
  /* We can ignore the return value since suspension is not possible
   * with the stdio data source.
   */

  /* Step 8: Release JPEG decompression object */

  /* This is an important step since it will release a good deal
   * of memory.
   */
  jpeg_destroy_decompress (&cinfo);

  /* free up the temporary buffers */
  g_free (rowbuf);
  g_free (buf);

  /* At this point you may want to check to see whether any
   * corrupt-data warnings occurred (test whether
   * jerr.num_warnings is nonzero).
   */
  gimp_image_insert_layer (image_ID, layer_ID, -1, 0);


  /* NOW to get the dimensions of the actual image to return the
   * calling app
   */
  cinfo.err = jpeg_std_error (&jerr.pub);
  jerr.pub.error_exit = my_error_exit;
  jerr.pub.output_message = my_output_message;

  if ((infile = g_fopen (filename, "rb")) == NULL)
    {
      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
                   _("Could not open '%s' for reading: %s"),
                   gimp_filename_to_utf8 (filename), g_strerror (errno));

      if (exif_data)
        {
          exif_data_unref (exif_data);
          exif_data = NULL;
        }

      return -1;
    }

  /* Establish the setjmp return context for my_error_exit to use. */
  if (setjmp (jerr.setjmp_buffer))
    {
      /* If we get here, the JPEG code has signaled an error.  We
       * need to clean up the JPEG object, close the input file,
       * and return.
       */
      jpeg_destroy_decompress (&cinfo);

      if (image_ID != -1)
        gimp_image_delete (image_ID);

      if (exif_data)
        {
          exif_data_unref (exif_data);
          exif_data = NULL;
        }

      return -1;
    }

  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress (&cinfo);

  /* Step 2: specify data source (eg, a file) */

  jpeg_stdio_src (&cinfo, infile);

  /* Step 3: read file parameters with jpeg_read_header() */

  jpeg_read_header (&cinfo, TRUE);

  jpeg_start_decompress (&cinfo);

  *width  = cinfo.output_width;
  *height = cinfo.output_height;

  /* Step 4: Release JPEG decompression object */

  /* This is an important step since it will release a good deal
   * of memory.
   */
  jpeg_destroy_decompress (&cinfo);

  fclose (infile);

  if (exif_data)
    {
      exif_data_unref (exif_data);
      exif_data = NULL;
    }

  jpeg_exif_rotate (image_ID, orientation);

  return image_ID;
}
コード例 #19
0
ファイル: file-pdf-save.c プロジェクト: mardy/gimb
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));
    }

}
コード例 #20
0
ファイル: ico-dialog.c プロジェクト: AjayRamanathan/gimp
static void
ico_dialog_update_icon_preview (GtkWidget *dialog,
                                gint32     layer,
                                gint       bpp)
{
  GtkWidget  *preview = ico_dialog_get_layer_preview (dialog, layer);
  GdkPixbuf  *pixbuf;
  const Babl *format;
  gint        w       = gimp_drawable_width (layer);
  gint        h       = gimp_drawable_height (layer);

  if (! preview)
    return;

  switch (gimp_drawable_type (layer))
    {
    case GIMP_RGB_IMAGE:
      format = babl_format ("R'G'B' u8");
      break;

    case GIMP_RGBA_IMAGE:
      format = babl_format ("R'G'B'A u8");
      break;

    case GIMP_GRAY_IMAGE:
      format = babl_format ("Y' u8");
      break;

    case GIMP_GRAYA_IMAGE:
      format = babl_format ("Y'A u8");
      break;

    case GIMP_INDEXED_IMAGE:
    case GIMP_INDEXEDA_IMAGE:
      format = gimp_drawable_get_format (layer);

    default:
      g_return_if_reached ();
    }

  if (bpp <= 8)
    {
      GeglBuffer *buffer;
      GeglBuffer *tmp;
      gint32      image;
      gint32      tmp_image;
      gint32      tmp_layer;
      guchar     *buf;
      guchar     *cmap;
      gint        num_colors;

      image = gimp_item_get_image (layer);

      tmp_image = gimp_image_new (w, h, gimp_image_base_type (image));
      gimp_image_undo_disable (tmp_image);

      if (gimp_drawable_is_indexed (layer))
        {
          cmap = gimp_image_get_colormap (image, &num_colors);
          gimp_image_set_colormap (tmp_image, cmap, num_colors);
          g_free (cmap);
        }

      tmp_layer = gimp_layer_new (tmp_image, "temporary", w, h,
                                  gimp_drawable_type (layer),
                                  100, GIMP_NORMAL_MODE);
      gimp_image_insert_layer (tmp_image, tmp_layer, -1, 0);

      buffer = gimp_drawable_get_buffer (layer);
      tmp    = gimp_drawable_get_buffer (tmp_layer);

      buf = g_malloc (w * h * 4);

      gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, w, h), 1.0,
                       format, buf,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

      gegl_buffer_copy (buffer, NULL, tmp, NULL);

      g_object_unref (tmp);
      g_object_unref (buffer);

      if (gimp_drawable_is_indexed (layer))
        gimp_image_convert_rgb (tmp_image);

      gimp_image_convert_indexed (tmp_image,
                                  GIMP_FS_DITHER, GIMP_MAKE_PALETTE,
                                  1 << bpp, TRUE, FALSE, "dummy");

      cmap = gimp_image_get_colormap (tmp_image, &num_colors);

      if (num_colors == (1 << bpp) &&
          ! ico_cmap_contains_black (cmap, num_colors))
        {
          /* Windows icons with color maps need the color black.
           * We need to eliminate one more color to make room for black.
           */
          if (gimp_drawable_is_indexed (layer))
            {
              g_free (cmap);
              cmap = gimp_image_get_colormap (image, &num_colors);
              gimp_image_set_colormap (tmp_image, cmap, num_colors);
            }
          else if (gimp_drawable_is_gray (layer))
            {
              gimp_image_convert_grayscale (tmp_image);
            }
          else
            {
              gimp_image_convert_rgb (tmp_image);
            }

          tmp = gimp_drawable_get_buffer (tmp_layer);

          gegl_buffer_set (tmp, GEGL_RECTANGLE (0, 0, w, h), 0,
                           format, buf, GEGL_AUTO_ROWSTRIDE);

          g_object_unref (tmp);

          if (!gimp_drawable_is_rgb (layer))
            gimp_image_convert_rgb (tmp_image);

          gimp_image_convert_indexed (tmp_image,
                                      GIMP_FS_DITHER, GIMP_MAKE_PALETTE,
                                      (1 << bpp) - 1, TRUE, FALSE, "dummy");
        }

      g_free (cmap);
      g_free (buf);

      pixbuf = gimp_drawable_get_thumbnail (tmp_layer,
                                            MIN (w, 128), MIN (h, 128),
                                            GIMP_PIXBUF_SMALL_CHECKS);

      gimp_image_delete (tmp_image);
    }
  else if (bpp == 24)
    {
      GeglBuffer *buffer;
      GeglBuffer *tmp;
      gint32      image;
      gint32      tmp_image;
      gint32      tmp_layer;
      GimpParam  *return_vals;
      gint        n_return_vals;

      image = gimp_item_get_image (layer);

      tmp_image = gimp_image_new (w, h, gimp_image_base_type (image));
      gimp_image_undo_disable (tmp_image);

      if (gimp_drawable_is_indexed (layer))
        {
          guchar *cmap;
          gint    num_colors;

          cmap = gimp_image_get_colormap (image, &num_colors);
          gimp_image_set_colormap (tmp_image, cmap, num_colors);
          g_free (cmap);
        }

      tmp_layer = gimp_layer_new (tmp_image, "temporary", w, h,
                                  gimp_drawable_type (layer),
                                  100, GIMP_NORMAL_MODE);
      gimp_image_insert_layer (tmp_image, tmp_layer, -1, 0);

      buffer = gimp_drawable_get_buffer (layer);
      tmp    = gimp_drawable_get_buffer (tmp_layer);

      gegl_buffer_copy (buffer, NULL, tmp, NULL);

      g_object_unref (tmp);
      g_object_unref (buffer);

      if (gimp_drawable_is_indexed (layer))
        gimp_image_convert_rgb (tmp_image);

      return_vals =
        gimp_run_procedure ("plug-in-threshold-alpha", &n_return_vals,
                            GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE,
                            GIMP_PDB_IMAGE, tmp_image,
                            GIMP_PDB_DRAWABLE, tmp_layer,
                            GIMP_PDB_INT32, ICO_ALPHA_THRESHOLD,
                            GIMP_PDB_END);
      gimp_destroy_params (return_vals, n_return_vals);

      pixbuf = gimp_drawable_get_thumbnail (tmp_layer,
                                            MIN (w, 128), MIN (h, 128),
                                            GIMP_PIXBUF_SMALL_CHECKS);

      gimp_image_delete (tmp_image);
    }
  else
    {
      pixbuf = gimp_drawable_get_thumbnail (layer,
                                            MIN (w, 128), MIN (h, 128),
                                            GIMP_PIXBUF_SMALL_CHECKS);
    }

  gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
  g_object_unref (pixbuf);
}
コード例 #21
0
static gboolean
webx_pipeline_check_update (WebxPipeline *pipeline)
{
  gint *layers;
  gint  num_layers;
  gint  i;

  g_return_val_if_fail (WEBX_IS_PIPELINE (pipeline), FALSE);

  if (pipeline->rgb_image != -1)
    {
      gimp_image_delete (pipeline->rgb_image);
      pipeline->rgb_image = -1;
    }
  if (pipeline->indexed_image != -1)
    {
      gimp_image_delete (pipeline->indexed_image);
      pipeline->indexed_image = -1;
    }
  if (pipeline->background)
    {
      g_object_unref (pipeline->background);
      pipeline->background = NULL;
    }

  pipeline->rgb_image = gimp_image_duplicate (pipeline->user_image);
  gimp_image_undo_disable (pipeline->rgb_image);
  pipeline->rgb_layer =
    gimp_image_merge_visible_layers (pipeline->rgb_image,
                                     GIMP_CLIP_TO_IMAGE);

  /* make sure there is only one layer, where all visible layers were merged */
  layers = gimp_image_get_layers (pipeline->rgb_image, &num_layers);
  for (i = 0; i < num_layers; i++)
    {
      if (layers[i] != pipeline->rgb_layer)
        gimp_image_remove_layer (pipeline->rgb_image, layers[i]);
    }
  g_free (layers);

  /* we don't want layer to be smaller than image */
  gimp_layer_resize_to_image_size (pipeline->rgb_layer);
  gimp_image_scale (pipeline->rgb_image,
                    pipeline->resize_width, pipeline->resize_height);
  webx_pipeline_create_background (pipeline);

  pipeline->crop_offsx *= pipeline->crop_scale_x;
  pipeline->crop_offsy *= pipeline->crop_scale_y;
  pipeline->crop_width *= pipeline->crop_scale_x;
  pipeline->crop_height *= pipeline->crop_scale_y;
  pipeline->crop_scale_x = 1.0;
  pipeline->crop_scale_y = 1.0;
  webx_pipeline_crop_clip (pipeline);

  if (pipeline->crop_width != pipeline->resize_width
      || pipeline->crop_height != pipeline->resize_height )
    {
      gimp_image_crop (pipeline->rgb_image,
                       pipeline->crop_width, pipeline->crop_height,
                       pipeline->crop_offsx, pipeline->crop_offsy);
    }
    
  if (gimp_drawable_is_indexed (pipeline->rgb_layer))
    {
      pipeline->indexed_image = gimp_image_duplicate (pipeline->rgb_image);
      gimp_image_undo_disable (pipeline->indexed_image);
      pipeline->indexed_layer =
        gimp_image_merge_visible_layers (pipeline->indexed_image,
                                         GIMP_CLIP_TO_IMAGE);
    }
  else
    {
      pipeline->indexed_image = -1;
      pipeline->indexed_layer = -1;
    }

  if ( ! gimp_drawable_is_rgb (pipeline->rgb_layer))
    gimp_image_convert_rgb (pipeline->rgb_image);

  return TRUE;
}
コード例 #22
0
ファイル: file-xpm.c プロジェクト: MichaelMure/Gimp-Cage-Tool
static void
run (const gchar      *name,
     gint              nparams,
     const GimpParam  *param,
     gint             *nreturn_vals,
     GimpParam       **return_vals)
{
  static GimpParam   values[2];
  GimpRunMode        run_mode;
  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
  gint32             image_ID;
  gint32             drawable_ID;
  GimpExportReturn   export = GIMP_EXPORT_CANCEL;
  GError            *error  = NULL;

  run_mode = param[0].data.d_int32;

  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, &error);

      if (image_ID != -1)
        {
          *nreturn_vals = 2;
          values[1].type         = GIMP_PDB_IMAGE;
          values[1].data.d_image = image_ID;
        }
      else
        {
          status = GIMP_PDB_EXECUTION_ERROR;
        }
    }
  else if (strcmp (name, SAVE_PROC) == 0)
    {
      gimp_ui_init (PLUG_IN_BINARY, FALSE);

      image_ID    = param[1].data.d_int32;
      drawable_ID = param[2].data.d_int32;

      /*  eventually export the image */
      switch (run_mode)
        {
        case GIMP_RUN_INTERACTIVE:
        case GIMP_RUN_WITH_LAST_VALS:
          export = gimp_export_image (&image_ID, &drawable_ID, NULL,
                                      (GIMP_EXPORT_CAN_HANDLE_RGB |
                                       GIMP_EXPORT_CAN_HANDLE_GRAY |
                                       GIMP_EXPORT_CAN_HANDLE_INDEXED |
                                       GIMP_EXPORT_CAN_HANDLE_ALPHA ));
          if (export == GIMP_EXPORT_CANCEL)
            {
              values[0].data.d_status = GIMP_PDB_CANCEL;
              return;
            }
          break;
        default:
          break;
        }

      switch (run_mode)
        {
        case GIMP_RUN_INTERACTIVE:
          /*  Possibly retrieve data  */
          gimp_get_data ("file_xpm_save", &xpmvals);

          /*  First acquire information with a dialog  */
          if (gimp_drawable_has_alpha (drawable_ID))
            if (! save_dialog ())
              status = GIMP_PDB_CANCEL;
          break;

        case GIMP_RUN_NONINTERACTIVE:
          /*  Make sure all the arguments are there!  */
          if (nparams != 6)
            {
              status = GIMP_PDB_CALLING_ERROR;
            }
          else
            {
              xpmvals.threshold = param[5].data.d_int32;

              if (xpmvals.threshold < 0 ||
                  xpmvals.threshold > 255)
                status = GIMP_PDB_CALLING_ERROR;
            }
          break;

        case GIMP_RUN_WITH_LAST_VALS:
          /*  Possibly retrieve data  */
          gimp_get_data ("file_xpm_save", &xpmvals);
          break;

        default:
          break;
        }

      if (status == GIMP_PDB_SUCCESS)
        {
          if (save_image (param[3].data.d_string,
                          image_ID, drawable_ID, &error))
            {
              gimp_set_data ("file_xpm_save", &xpmvals, sizeof (XpmSaveVals));
            }
          else
            {
              status = GIMP_PDB_EXECUTION_ERROR;
            }
        }

      if (export == GIMP_EXPORT_EXPORT)
        gimp_image_delete (image_ID);
    }
コード例 #23
0
ファイル: gimp-plugin-vtf.cpp プロジェクト: lxndr/vtf
static void
run (const gchar *name, gint nparams, const GimpParam *param,
     gint *nreturn_vals, GimpParam **return_vals)
{
    static GimpParam	values[4];
    GimpRunMode			run_mode;
    GimpPDBStatusType	status = GIMP_PDB_SUCCESS;
    GimpExportReturn	ret = GIMP_EXPORT_CANCEL;
    GError				*error  = NULL;

    run_mode = (GimpRunMode) param[0].data.d_int32;

    *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) {
        switch (run_mode) {
        case GIMP_RUN_INTERACTIVE:
            break;

        case GIMP_RUN_NONINTERACTIVE:
            if (nparams != 3)
                status = GIMP_PDB_CALLING_ERROR;
            break;

        default:
            break;
        }

        if (status == GIMP_PDB_SUCCESS) {
            gint32 image_ID;

            image_ID = file_vtf_load_image (param[1].data.d_string, &error);
            if (image_ID != -1) {
                *nreturn_vals = 2;
                values[1].type			= GIMP_PDB_IMAGE;
                values[1].data.d_image	= image_ID;
            } else {
                status = GIMP_PDB_EXECUTION_ERROR;
            }
        }

    } else if (strcmp (name, LOAD_THUMB_PROC) == 0) {
        if (nparams < 2) {
            status = GIMP_PDB_CALLING_ERROR;
        } else {
            const gchar *filename = param[0].data.d_string;
            gint width  = param[1].data.d_int32;
            gint height = param[1].data.d_int32;
            gint32 image_ID;

            image_ID = file_vtf_load_thumbnail_image (filename,
                       &width, &height, &error);

            if (image_ID != -1) {
                *nreturn_vals = 4;

                values[1].type         = GIMP_PDB_IMAGE;
                values[1].data.d_image = image_ID;
                values[2].type         = GIMP_PDB_INT32;
                values[2].data.d_int32 = width;
                values[3].type         = GIMP_PDB_INT32;
                values[3].data.d_int32 = height;
            } else {
                status = GIMP_PDB_EXECUTION_ERROR;
            }
        }

    } else if (strcmp (name, SAVE_PROC) == 0) {
        gchar *file_name;
        gint32 image_ID;

        image_ID = param[1].data.d_int32;
        file_name = param[3].data.d_string;

        switch (run_mode) {
        case GIMP_RUN_INTERACTIVE:
            break;

        case GIMP_RUN_NONINTERACTIVE:
            if (nparams < 5)
                status = GIMP_PDB_CALLING_ERROR;
            break;

        case GIMP_RUN_WITH_LAST_VALS:
            break;

        default:
            break;
        }

        if (status == GIMP_PDB_SUCCESS) {
            status = file_vtf_save_image (file_name, image_ID, run_mode, &error);
        }

        if (ret == GIMP_EXPORT_EXPORT)
            gimp_image_delete (image_ID);

    } else {
        status = GIMP_PDB_CALLING_ERROR;
    }

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

    values[0].data.d_status = status;
}
コード例 #24
0
static GimpPDBStatusType plt_load(gchar *filename, gint32 *image_id)
{
    FILE *stream = 0;
    unsigned int i;

    // Using uint for guaranteed sizes across all systems
    // guint may or may not work (?)
    uint8_t  plt_version[8];
    uint32_t plt_width  = 0;
    uint32_t plt_height = 0;
    uint8_t *buffer;

    uint8_t px_value = 0;
    uint8_t px_layer = 0;
    uint32_t num_px = 0;

    gint32 newImgID   = -1;
    gint32 newLayerID = -1;
    gint32 plt_layer_ids[PLT_NUM_LAYERS];
    guint8 pixel[2] = {0, 255}; // GRAYA image = 2 Channels: Value + Alpha

    stream = fopen(filename, "rb");
    if(stream == 0)
    {
        g_message("Error opening file.\n");
        return (GIMP_PDB_EXECUTION_ERROR);
    }

    gimp_progress_init_printf("Opening %s", filename);
    gimp_progress_update(0.0);

    // Read header: Version, should be 8x1 bytes = "PLT V1  "
    if (fread(plt_version, 1, 8, stream) < 8)
    {
        g_message("Invalid plt file: Unable to read version information.\n");
        fclose(stream);
        return (GIMP_PDB_EXECUTION_ERROR);
    }
    if (g_ascii_strncasecmp(plt_version, PLT_HEADER_VERSION, 8) != 0)
    {

        g_message("Invalid plt file: Version mismatch.\n");
        fclose(stream);
        return (GIMP_PDB_EXECUTION_ERROR);
    }
    // Read header: Next 8 bytes don't matter
    fseek(stream, 8, SEEK_CUR);
    // Read header: Width
    if (fread(&plt_width, 4, 1, stream) < 1)
    {
        g_message("Invalid plt file: Unable to read width.\n");
        fclose(stream);
        return (GIMP_PDB_EXECUTION_ERROR);
    }
    // Read header: Height
    if (fread(&plt_height, 4, 1, stream) < 1)
    {
        g_message("Invalid plt file: Unable to read height.\n");
        fclose(stream);
        return (GIMP_PDB_EXECUTION_ERROR);
    }

    // Create a new image
    newImgID = gimp_image_new(plt_width, plt_height, GIMP_GRAY);
    if(newImgID == -1)
    {
        g_message("Unable to allocate new image.\n");
        fclose(stream);
        return (GIMP_PDB_EXECUTION_ERROR);
    }
    gimp_image_set_filename(newImgID, filename);

    // Create the 10 plt layers, add them to the new image and save their ID's
    for (i = 0; i < PLT_NUM_LAYERS; i++)
    {
        newLayerID = gimp_layer_new(newImgID,
                                    plt_layernames[i],
                                    plt_width, plt_height,
                                    GIMP_GRAYA_IMAGE,
                                    100.0,
                                    GIMP_NORMAL_MODE);
        gimp_image_insert_layer(newImgID, newLayerID, 0, 0);
        plt_layer_ids[i] = newLayerID;
    }

    // Read image data
    // Expecting width*height (value, layer) tuples = 2*width*height bytes
    num_px = plt_width * plt_height;
    buffer = (uint8_t*) g_malloc(sizeof(uint8_t)*2*num_px);
    if (fread(buffer, 1, 2*num_px, stream) < (2*num_px))
    {
        g_message("Image size mismatch.\n");
        fclose(stream);
        g_free(buffer);
        gimp_image_delete(newImgID);
        return (GIMP_PDB_EXECUTION_ERROR);
    }
    for (i = 0; i < num_px; i++)
    {
        pixel[0] = buffer[2*i];
        px_layer = buffer[2*i+1];
        gimp_drawable_set_pixel(plt_layer_ids[px_layer],
                                i % plt_width,
                                plt_height - (int)(floor(i / plt_width)) - 1,
                                2,
                                pixel);
        gimp_progress_update((float) i/ (float) num_px);
    }
    gimp_progress_update(1.0);
    gimp_image_set_active_layer(newImgID, plt_layer_ids[0]);

    fclose(stream);

    g_free(buffer);

    *image_id = newImgID;
    return (GIMP_PDB_SUCCESS);
}
コード例 #25
0
ファイル: file-exr.c プロジェクト: AjayRamanathan/gimp
static gint32
load_image (const gchar  *filename,
            gboolean      interactive,
            GError      **error)
{
  gint32 status = -1;
  EXRLoader *loader;
  int width;
  int height;
  gboolean has_alpha;
  GimpImageBaseType image_type;
  GimpPrecision image_precision;
  gint32 image = -1;
  GimpImageType layer_type;
  int layer;
  const Babl *format;
  GeglBuffer *buffer = NULL;
  int bpp;
  int tile_height;
  gchar *pixels = NULL;
  int begin;
  int end;
  int num;

  loader = exr_loader_new (filename);
  if (!loader)
    {
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                   _("Error opening file '%s' for reading"),
                   gimp_filename_to_utf8 (filename));
      goto out;
    }

  width = exr_loader_get_width (loader);
  height = exr_loader_get_height (loader);
  if ((width < 1) || (height < 1))
    {
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                   _("Error querying image dimensions from '%s'"),
                   gimp_filename_to_utf8 (filename));
      goto out;
    }

  has_alpha = exr_loader_has_alpha (loader) ? TRUE : FALSE;

  switch (exr_loader_get_precision (loader))
    {
    case PREC_UINT:
      image_precision = GIMP_PRECISION_U32;
      break;
    case PREC_HALF:
      image_precision = GIMP_PRECISION_HALF;
      break;
    case PREC_FLOAT:
      image_precision = GIMP_PRECISION_FLOAT;
      break;
    default:
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                   _("Error querying image precision from '%s'"),
                   gimp_filename_to_utf8 (filename));
      goto out;
    }

  switch (exr_loader_get_image_type (loader))
    {
    case IMAGE_TYPE_RGB:
      image_type = GIMP_RGB;
      layer_type = has_alpha ? GIMP_RGBA_IMAGE : GIMP_RGB_IMAGE;
      break;
    case IMAGE_TYPE_GRAY:
      image_type = GIMP_GRAY;
      layer_type = has_alpha ? GIMP_GRAYA_IMAGE : GIMP_GRAY_IMAGE;
      break;
    default:
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                   _("Error querying image type from '%s'"),
                   gimp_filename_to_utf8 (filename));
      goto out;
    }

  gimp_progress_init_printf (_("Opening '%s'"),
                             gimp_filename_to_utf8 (filename));

  image = gimp_image_new_with_precision (width, height,
                                         image_type, image_precision);
  if (image == -1)
    {
      g_set_error (error, 0, 0,
                   _("Could not create new image for '%s': %s"),
                   gimp_filename_to_utf8 (filename), gimp_get_pdb_error ());
      goto out;
    }

  gimp_image_set_filename (image, filename);

  layer = gimp_layer_new (image, _("Background"), width, height,
                          layer_type, 100, GIMP_NORMAL_MODE);
  gimp_image_insert_layer (image, layer, -1, 0);

  buffer = gimp_drawable_get_buffer (layer);
  format = gimp_drawable_get_format (layer);
  bpp = babl_format_get_bytes_per_pixel (format);

  tile_height = gimp_tile_height ();
  pixels = g_new0 (gchar, tile_height * width * bpp);

  for (begin = 0; begin < height; begin += tile_height)
    {
      int retval;
      int i;
      end = MIN (begin + tile_height, height);
      num = end - begin;

      for (i = 0; i < num; i++)
        {
          retval = exr_loader_read_pixel_row (loader,
                                              pixels + (i * width * bpp),
                                              bpp, begin + i);
          if (retval < 0)
            {
              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                           _("Error reading pixel data from '%s'"),
                           gimp_filename_to_utf8 (filename));
              goto out;
            }
        }

      gegl_buffer_set (buffer, GEGL_RECTANGLE (0, begin, width, num),
                       0, NULL, pixels, GEGL_AUTO_ROWSTRIDE);

      gimp_progress_update ((gdouble) begin / (gdouble) height);
    }

  gimp_progress_update (1.0);

  status = image;

 out:
  if (buffer)
    g_object_unref (buffer);

  if ((status != image) && (image != -1))
    {
      /* This should clean up any associated layers too. */
      gimp_image_delete (image);
    }

  if (pixels)
    g_free (pixels);

  if (loader)
    exr_loader_unref (loader);

  return status;
}
コード例 #26
0
ファイル: film.c プロジェクト: LebedevRI/gimp
/* 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;
}
コード例 #27
0
static gboolean process_image(gpointer parent)
{
    gboolean success = TRUE;
    
    image_output imageout = (image_output)g_malloc(sizeof(struct imageout_str));
    char* orig_filename = NULL;
    char* orig_basename = NULL;
    char* orig_file_ext = NULL;
    char* output_file_comp = NULL;
    
    // store original file path and name 
    orig_filename = g_slist_nth (bimp_input_filenames, processed_count)->data;
    orig_basename = g_strdup(comp_get_filename(orig_filename)); 
    
    // store original extension and check error cases 
    orig_file_ext = g_strdup(strrchr(orig_basename, '.'));
    if (orig_file_ext == NULL) {
        /* under Linux, GtkFileChooser lets to pick an image file without extension, but GIMP cannot 
         * save it back if its format remains unchanged. Operation can continue only if a MANIP_CHANGEFORMAT
         * is present */
        if (list_contains_changeformat) {
            orig_file_ext = g_malloc0(sizeof(char));
        }        
        else {
            bimp_show_error_dialog(g_strdup_printf(_("Can't save image \"%s\": input file has no extension.\nYou can solve this error by adding a \"Change format or compression\" step"), orig_basename), bimp_window_main);
            success = FALSE;
            goto process_end;
        }
    }
    else if (g_ascii_strcasecmp(orig_file_ext, ".svg") == 0 && !list_contains_changeformat) {
        bimp_show_error_dialog(g_strdup_printf(_("GIMP can't save %s back to its original SVG format.\nYou can solve this error by adding a \"Change format or compression\" step"), orig_basename), bimp_window_main);
        success = FALSE;
        goto process_end;
    }
    
    g_print("\nWorking on file %d of %d (%s)\n", processed_count + 1, total_images, orig_filename);
    bimp_progress_bar_set(((double)processed_count)/total_images, g_strdup_printf(_("Working on file \"%s\"..."), orig_basename));

    // rename and save process... 
    orig_basename[strlen(orig_basename) - strlen(orig_file_ext)] = '\0'; // remove extension from basename 
    
    // check if a rename pattern is defined 
    if(list_contains_rename) {
        g_print("Applying RENAME...\n");
        apply_rename((rename_settings)(bimp_list_get_manip(MANIP_RENAME))->settings, imageout, orig_basename);
    }
    else {
        imageout->filename = orig_basename;
    }

    // To keep the folder hierarchy 
    if (common_folder_path == NULL)    {
        // Not selected or required, everything goes into the same destination folder
        output_file_comp = g_malloc0(sizeof(char));
    }
    else {
        // keep folders to add to output path
        output_file_comp = 
            g_strndup(&orig_filename[strlen(common_folder_path)+1],
            strlen(orig_filename)-(strlen(common_folder_path)+1)
            -strlen(orig_basename)-strlen(orig_file_ext)); 
    }
    
    if (strlen(output_file_comp) > 0) {
#ifdef _WIN32        
        // Clean output_file_comp
        // Should only be concerned for ':' in Drive letter
        int i;
        for (i = 0; i < strlen(output_file_comp); ++i)
            if ( output_file_comp[i] == ':' )
                output_file_comp[i] = '_';
#endif
        // Create path if needed
        g_mkdir_with_parents(
            g_strconcat(bimp_output_folder, FILE_SEPARATOR_STR, output_file_comp, NULL), 
            0777
        );
    }
    
    // save the final image in output dir with proper format and params 
    format_type final_format = -1;
    format_params params = NULL;
    
    if(list_contains_changeformat) {
        changeformat_settings settings = (changeformat_settings)(bimp_list_get_manip(MANIP_CHANGEFORMAT))->settings;
        final_format = settings->format;
        params = settings->params;

        g_print("Changing FORMAT to %s\n", format_type_string[final_format][0]);
        imageout->filename = g_strconcat(imageout->filename, ".", format_type_string[final_format][0], NULL); // append new file extension 
        imageout->filepath = g_strconcat(bimp_output_folder, FILE_SEPARATOR_STR, output_file_comp, imageout->filename, NULL); // build new path 
    }
    // TO CHECK what apply_userdef does once coded 

    else if (list_contains_savingplugin) {
        // leave filename without extension and proceed calling each saving plugin
        imageout->filename = g_strconcat(imageout->filename, ".dds", NULL);
        imageout->filepath = g_strconcat(bimp_output_folder, FILE_SEPARATOR_STR, output_file_comp, imageout->filename, NULL); // build new path 
        
        GSList *iterator = NULL;
        manipulation man;
        for (iterator = bimp_selected_manipulations; iterator; iterator = iterator->next) {
            man = (manipulation)(iterator->data);
            if (man->type == MANIP_USERDEF && strstr(((userdef_settings)(man->settings))->procedure, "-save") != NULL) {
                /* found a saving plugin, execute it
                // TODO!!!! This won't work yet, we need a way to extract the file extension managed by the selected saving plugin
                 * e.g. "file-dds-save" -> "dds" (don't do it with regexp on plugin's name... too easy...) */
                apply_userdef((userdef_settings)(man->settings), imageout);
            }
        }
    }
    else {
        // if not specified, save in original format 
        imageout->filename = g_strconcat(imageout->filename, orig_file_ext, NULL); // append old file extension     
        imageout->filepath = g_strconcat(bimp_output_folder, FILE_SEPARATOR_STR, output_file_comp, imageout->filename, NULL); // build new path         
        final_format = -1;    
    }
    
    // check if writing possible 
    gboolean will_overwrite = FALSE;
    if (bimp_opt_alertoverwrite != BIMP_OVERWRITE_SKIP_ASK) {
        // file already exists ?
        will_overwrite = g_file_test(imageout->filepath, G_FILE_TEST_IS_REGULAR);        
        if (will_overwrite) {
            // "Don't overwrite" without confirmation
            if (bimp_opt_alertoverwrite == BIMP_DONT_OVERWRITE_SKIP_ASK) {
                g_print("Destination file already exists and won't be overwritten\n");
                goto process_end;
            }
            else {
                // Ask what to do
                int ow_res = overwrite_result(imageout->filepath, parent);
                if (ow_res == 0) {
                    g_print("Destination file already exists and user select to don't overwrite\n");
                    goto process_end;
                }
            }
        }
    }
    
    // apply all the main manipulations 
    bimp_apply_drawable_manipulations(imageout, (gchar*)orig_filename, (gchar*)orig_basename); 
    
    time_t mod_time = -1;
    if (will_overwrite && bimp_opt_keepdates) {
        // I must keep the dates even if the file has been overwritten
        mod_time = get_modification_time(imageout->filepath);
        if (mod_time == -1) g_print("An error occurred when retrieving the modification date of file.\n");
    }
    
    // Save 
    g_print("Saving file %s in %s\n", imageout->filename, imageout->filepath);
    image_save(final_format, imageout, params);
    
    if (will_overwrite && bimp_opt_keepdates && mod_time > -1) {
        // replace with the old dates
        int res = set_modification_time(imageout->filepath, mod_time);
        if (res == -1) g_print("An error occurred when replacing the modification date of file.\n");
    }

    gimp_image_delete(imageout->image_id); // is it useful? 
    
process_end:

    g_free(orig_basename);
    g_free(orig_file_ext);
    g_free(output_file_comp);
    g_free(imageout->filename);
    g_free(imageout->filepath);
    g_free(imageout);

    processed_count++;
    if (success) success_count++; 
    
    // TODO: errors check here 
    if (!bimp_is_busy) {
        bimp_progress_bar_set(0.0, _("Operations stopped"));
        g_print("\nStopped, %d files processed.\n", processed_count);
        return FALSE;
    }
    else {
        if (processed_count == total_images) {
            int errors_count = processed_count - success_count;
            bimp_progress_bar_set(1.0, g_strdup_printf(_("End, all files have been processed with %d errors"), errors_count));
            g_print("\nEnd, %d files have been processed with %d errors.\n", processed_count, errors_count);
            
            bimp_set_busy(FALSE);
            
            return FALSE;
        }
        else {
            return TRUE;
        }
    }
}
コード例 #28
0
ファイル: ico-save.c プロジェクト: Distrotech/gimp
static void
ico_image_get_reduced_buf (guint32   layer,
                           gint      bpp,
                           gint     *num_colors,
                           guchar  **cmap_out,
                           guchar  **buf_out)
{
  gint32      tmp_image;
  gint32      tmp_layer;
  gint        w, h;
  guchar     *buf;
  guchar     *cmap   = NULL;
  GeglBuffer *buffer = gimp_drawable_get_buffer (layer);
  const Babl *format;

  w = gegl_buffer_get_width  (buffer);
  h = gegl_buffer_get_height (buffer);

  switch (gimp_drawable_type (layer))
    {
    case GIMP_RGB_IMAGE:
      format = babl_format ("R'G'B' u8");
      break;

    case GIMP_RGBA_IMAGE:
      format = babl_format ("R'G'B'A u8");
      break;

    case GIMP_GRAY_IMAGE:
      format = babl_format ("Y' u8");
      break;

    case GIMP_GRAYA_IMAGE:
      format = babl_format ("Y'A u8");
      break;

    case GIMP_INDEXED_IMAGE:
    case GIMP_INDEXEDA_IMAGE:
      format = gegl_buffer_get_format (buffer);

    default:
      g_return_if_reached ();
    }

  *num_colors = 0;

  buf = g_new (guchar, w * h * 4);

  if (bpp <= 8 || bpp == 24 || babl_format_get_bytes_per_pixel (format) != 4)
    {
      gint32      image = gimp_item_get_image (layer);
      GeglBuffer *tmp;

      tmp_image = gimp_image_new (w, h, gimp_image_base_type (image));
      gimp_image_undo_disable (tmp_image);

      if (gimp_drawable_is_indexed (layer))
        {
          guchar *cmap;
          gint    num_colors;

          cmap = gimp_image_get_colormap (image, &num_colors);
          gimp_image_set_colormap (tmp_image, cmap, num_colors);
          g_free (cmap);
        }

      tmp_layer = gimp_layer_new (tmp_image, "tmp", w, h,
                                  gimp_drawable_type (layer),
                                  100, GIMP_NORMAL_MODE);
      gimp_image_insert_layer (tmp_image, tmp_layer, -1, 0);

      tmp = gimp_drawable_get_buffer (tmp_layer);

      gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, w, h), 1.0,
                       format, buf,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

      gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE, tmp, NULL);

      g_object_unref (tmp);

      if (! gimp_drawable_is_rgb (tmp_layer))
        gimp_image_convert_rgb (tmp_image);

      if (bpp <= 8)
        {
          gimp_image_convert_indexed (tmp_image,
                                      GIMP_FS_DITHER, GIMP_MAKE_PALETTE,
                                      1 << bpp, TRUE, FALSE, "dummy");

          cmap = gimp_image_get_colormap (tmp_image, num_colors);

          if (*num_colors == (1 << bpp) &&
              ! ico_cmap_contains_black (cmap, *num_colors))
            {
              /* Windows icons with color maps need the color black.
               * We need to eliminate one more color to make room for black.
               */

              if (gimp_drawable_is_indexed (layer))
                {
                  g_free (cmap);
                  cmap = gimp_image_get_colormap (image, num_colors);
                  gimp_image_set_colormap (tmp_image, cmap, *num_colors);
                }
              else if (gimp_drawable_is_gray (layer))
                {
                  gimp_image_convert_grayscale (tmp_image);
                }
              else
                {
                  gimp_image_convert_rgb (tmp_image);
                }

              tmp = gimp_drawable_get_buffer (tmp_layer);

              gegl_buffer_set (tmp, GEGL_RECTANGLE (0, 0, w, h), 0,
                               format, buf, GEGL_AUTO_ROWSTRIDE);

              g_object_unref (tmp);

              if (! gimp_drawable_is_rgb (layer))
                gimp_image_convert_rgb (tmp_image);

              gimp_image_convert_indexed (tmp_image,
                                          GIMP_FS_DITHER, GIMP_MAKE_PALETTE,
                                          (1<<bpp) - 1, TRUE, FALSE, "dummy");
              g_free (cmap);
              cmap = gimp_image_get_colormap (tmp_image, num_colors);
            }

          gimp_image_convert_rgb (tmp_image);
        }
      else if (bpp == 24)
        {
          GimpParam    *return_vals;
          gint          n_return_vals;

          return_vals =
            gimp_run_procedure ("plug-in-threshold-alpha", &n_return_vals,
                                GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE,
                                GIMP_PDB_IMAGE, tmp_image,
                                GIMP_PDB_DRAWABLE, tmp_layer,
                                GIMP_PDB_INT32, ICO_ALPHA_THRESHOLD,
                                GIMP_PDB_END);
          gimp_destroy_params (return_vals, n_return_vals);
        }

      gimp_layer_add_alpha (tmp_layer);

      tmp = gimp_drawable_get_buffer (tmp_layer);

      gegl_buffer_get (tmp, GEGL_RECTANGLE (0, 0, w, h), 1.0,
                       NULL, buf,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

      g_object_unref (tmp);

      gimp_image_delete (tmp_image);
    }
  else
    {
      gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, w, h), 1.0,
                       format, buf,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
    }

  g_object_unref (buffer);

  *cmap_out = cmap;
  *buf_out = buf;
}
コード例 #29
0
ファイル: jpeg.c プロジェクト: milankni/cinepaint-oyranos
static gint32
load_image (char *filename)
{
  GPixelRgn pixel_rgn;
  TileDrawable *drawable;
  gint32 image_ID;
  gint32 layer_ID;
  struct jpeg_decompress_struct cinfo;
  struct my_error_mgr jerr;
  FILE *infile;
  guchar *buf;
  guchar **rowbuf;
  char *name;
  int image_type;
  int layer_type;
  int tile_height;
  int scanlines;
  int i, start, end;
  int m;
  int depth = 8;

  /* We set up the normal JPEG error routines. */
  cinfo.err = jpeg_std_error (&jerr.pub);
  jerr.pub.error_exit = my_error_exit;

  if ((infile = fopen (filename, "rb")) == NULL)
    {
      g_warning ("can't open \"%s\"\n", filename);
      gimp_quit ();
    }

  if( strrchr(filename,'.') &&
      strcmp( strrchr(filename, '.'), ".jp4") == 0 )
    depth = 16;

  name = malloc (strlen (filename) + 12);
  sprintf (name, "%s %s:", _("Loading"), filename);
  gimp_progress_init (name);
  free (name);

  image_ID = -1;
  /* Establish the setjmp return context for my_error_exit to use. */
  if (setjmp (jerr.setjmp_buffer))
    {
      /* If we get here, the JPEG code has signaled an error.
       * We need to clean up the JPEG object, close the input file, and return.
       */
      jpeg_destroy_decompress (&cinfo);
      if (infile)
	fclose (infile);
      if (image_ID != -1)
	gimp_image_delete (image_ID);
      gimp_quit ();
    }
  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress (&cinfo);

  /* Step 2: specify data source (eg, a file) */

  jpeg_stdio_src (&cinfo, infile);

  setup_read_icc_profile(&cinfo);  
  for (m = 0; m < 16; m++)
    jpeg_save_markers(&cinfo, JPEG_APP0 + m, 0xFFFF);

  /* Step 3: read file parameters with jpeg_read_header() */

  (void) jpeg_read_header (&cinfo, TRUE);
  /* We can ignore the return value from jpeg_read_header since
   *   (a) suspension is not possible with the stdio data source, and
   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
   * See libjpeg.doc for more info.
   */

  /* Step 4: set parameters for decompression */

  /* In this example, we don't need to change any of the defaults set by
   * jpeg_read_header(), so we do nothing here.
   */
  prepareColour( &cinfo );

  /* Step 5: Start decompressor */

  jpeg_start_decompress (&cinfo);

  /* We may need to do some setup of our own at this point before reading
   * the data.  After jpeg_start_decompress() we have the correct scaled
   * output image dimensions available, as well as the output colormap
   * if we asked for color quantization.
   * In this example, we need to make an output work buffer of the right size.
   */
  /* temporary buffer */
  tile_height = gimp_tile_height ();
  buf = g_new (guchar, tile_height * cinfo.output_width * cinfo.output_components);
  rowbuf = g_new (guchar*, tile_height);

  for (i = 0; i < tile_height; i++)
    rowbuf[i] = buf + cinfo.output_width * cinfo.output_components * i;

  /* Create a new image of the proper size and associate the filename with it.
   */
  if(depth == 8)
  {
    switch (cinfo.output_components)
    {
    case 1:
      image_type = GRAY;
      layer_type = GRAY_IMAGE;
      break;
    case 3:
      image_type = RGB;
      layer_type = RGB_IMAGE;
      break;
    case 4:
      image_type = RGB;
      layer_type = RGBA_IMAGE;
      break;
    default:
      gimp_quit ();
    }
  } else {
    switch (cinfo.output_components)
    {
    case 1:
      image_type = U16_GRAY;
      layer_type = U16_GRAY_IMAGE;
      break;
    case 3:
      image_type = U16_RGB;
      layer_type = U16_RGB_IMAGE;
      break;
    case 4:
      image_type = U16_RGB;
      layer_type = U16_RGBA_IMAGE;
      break;
    default:
      gimp_quit ();
    }
  }

  image_ID = gimp_image_new (cinfo.output_width / (depth/8), cinfo.output_height,
                             image_type);
  gimp_image_set_filename (image_ID, filename);

  layer_ID = gimp_layer_new (image_ID, _("Background"),
			     cinfo.output_width / (depth/8),
			     cinfo.output_height,
			     layer_type, 100, NORMAL_MODE);
  gimp_image_add_layer (image_ID, layer_ID, 0);

  drawable = gimp_drawable_get (layer_ID);
  gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width, drawable->height, TRUE, FALSE);

  /* Step 6: while (scan lines remain to be read) */
  /*           jpeg_read_scanlines(...); */

  /* Here we use the library's state variable cinfo.output_scanline as the
   * loop counter, so that we don't have to keep track ourselves.
   */
  while (cinfo.output_scanline < cinfo.output_height)
    {
      start = cinfo.output_scanline;
      end = cinfo.output_scanline + tile_height;
      end = MIN (end,CAST(int) cinfo.output_height);
      scanlines = end - start;

      for (i = 0; i < scanlines; i++)
	jpeg_read_scanlines (&cinfo, (JSAMPARRAY) &rowbuf[i], 1);

      /*
      for (i = start; i < end; i++)
	gimp_pixel_rgn_set_row (&pixel_rgn, tilerow[i - start], 0, i, drawable->width);
	*/

      if(cinfo.out_color_space == JCS_CMYK)
        for(i = 0; i < scanlines*drawable->width*cinfo.output_components; ++i)
          buf[i] = 255 - buf[i];

      if(depth == 16 && 0)
        for(i = 0; i < scanlines*drawable->width*cinfo.output_components; ++i)
        {
          unsigned char c = buf[2*i];
          buf[2*i] = buf[2*i+1];
          buf[2*i+1] = c;
        }

      gimp_pixel_rgn_set_rect (&pixel_rgn, buf, 0, start, drawable->width, scanlines);

      gimp_progress_update ((double) cinfo.output_scanline / (double) cinfo.output_height);
    }

  // Step 6a: read icc profile
  {
    LPBYTE Buffer = NULL;
    size_t Len = 0;
    cmsHPROFILE hProfile=NULL;

    if (read_icc_profile(&cinfo, &Buffer, &Len))
    {
      printf ("%s:%d %s() embedded profile found\n",__FILE__,__LINE__,__func__);
    } else if (read_icc_profile2(&cinfo, &Buffer, &Len)) {
      printf ("%s:%d %s() default profile selected\n",__FILE__,__LINE__,__func__);
    }

    if(Buffer && Len)
    {
      hProfile = cmsOpenProfileFromMem(Buffer, Len);
      if (hProfile) {
        gimp_image_set_icc_profile_by_mem (image_ID, Len, Buffer, ICC_IMAGE_PROFILE);
        cmsCloseProfile (hProfile);
        free(Buffer);
        printf ("%s:%d %s() set profile\n",__FILE__,__LINE__,__func__);
      }
    }
  }

  /* Step 7: Finish decompression */

  jpeg_finish_decompress (&cinfo);
  /* We can ignore the return value since suspension is not possible
   * with the stdio data source.
   */

  /* Step 8: Release JPEG decompression object */

  /* This is an important step since it will release a good deal of memory. */
  jpeg_destroy_decompress (&cinfo);

  /* free up the temporary buffers */
  g_free (rowbuf);
  g_free (buf);

  /* After finish_decompress, we can close the input file.
   * Here we postpone it until after no more JPEG errors are possible,
   * so as to simplify the setjmp error logic above.  (Actually, I don't
   * think that jpeg_destroy can do an error exit, but why assume anything...)
   */
  fclose (infile);

  /* At this point you may want to check to see whether any corrupt-data
   * warnings occurred (test whether jerr.num_warnings is nonzero).
   */

  /* Tell the GIMP to display the image.
   */
  gimp_drawable_flush (drawable);

  return image_ID;
}
コード例 #30
0
/* --------------------------
 * p_process_layer
 * --------------------------
 */
static gint32
p_process_layer(gint32 image_id, gint32 drawable_id, TransValues *val_ptr)
{
  gboolean has_selection;
  gboolean non_empty;
  gboolean alt_selection_success;
  gint     x1, y1, x2, y2;
  gint32   trans_drawable_id;

  if(gap_debug)
  {
    printf("corpus_border_radius: %d\n", (int)val_ptr->corpus_border_radius);
    printf("alt_selection: %d\n", (int)val_ptr->alt_selection);
    printf("seed: %d\n", (int)val_ptr->seed);
  }

  gimp_image_undo_group_start(image_id);


  trans_drawable_id = -1;
  alt_selection_success = FALSE;

  if(val_ptr->alt_selection >= 0)
  {
    if(gap_debug)
    {
      printf("p_process_layer creating alt_selection: %d\n", (int)val_ptr->alt_selection);
    }
    alt_selection_success = p_set_alt_selection(image_id, drawable_id, val_ptr);
  }

  has_selection  = gimp_selection_bounds(image_id, &non_empty, &x1, &y1, &x2, &y2);
  if(gap_debug)
  {
    printf("p_process_layer has_selection: %d\n", (int)has_selection);
  }

  /* here the action starts, we create the corpus_layer_id that builds the reference pattern
   * (the corpus is created in a spearate image and has an expanded selection
   * that excludes the unwanted parts)
   * then start the resynthesizer plug-in to replace selected (i.e. unwanted parts) of the
   * processed layer (i.e. drawable_id)
   */
  if (non_empty)
  {
    gint32 corpus_layer_id;
    gint32 corpus_image_id;

    trans_drawable_id = drawable_id;

    corpus_layer_id = p_create_corpus_layer(image_id, drawable_id, val_ptr);

    p_pdb_call_resynthesizer(image_id, drawable_id, corpus_layer_id, val_ptr->seed);

    /* delete the temporary working duplicate */
    corpus_image_id = gimp_item_get_image(corpus_layer_id);
    gimp_image_delete(corpus_image_id);
  }
  else
  {
    g_message("Please make a selection (cant operate on empty selection)");
  }

  if(alt_selection_success)
  {
    gimp_selection_none(image_id);
  }

  gimp_image_undo_group_end(image_id);

  return (trans_drawable_id);

}  /* end p_process_layer */