Exemple #1
0
GimpImage *
gimp_create_image (Gimp              *gimp,
                   gint               width,
                   gint               height,
                   GimpImageBaseType  type,
                   GimpPrecision      precision,
                   gboolean           attach_comment)
{
  GimpImage *image;

  g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);

  image = gimp_image_new (gimp, width, height, type, precision);

  if (attach_comment)
    {
      const gchar *comment;

      comment = gimp_template_get_comment (gimp->config->default_image);

      if (comment)
        {
          GimpParasite *parasite = gimp_parasite_new ("gimp-comment",
                                                      GIMP_PARASITE_PERSISTENT,
                                                      strlen (comment) + 1,
                                                      comment);
          gimp_image_parasite_attach (image, parasite);
          gimp_parasite_free (parasite);
        }
    }

  return image;
}
Exemple #2
0
gboolean
gimp_image_set_icc_profile (GimpImage     *image,
                            const guint8  *data,
                            gsize          length,
                            GError       **error)
{
  GimpParasite *parasite = NULL;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
  g_return_val_if_fail (data == NULL || length != 0, FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if (data)
    {
      parasite = gimp_parasite_new (GIMP_ICC_PROFILE_PARASITE_NAME,
                                    GIMP_PARASITE_PERSISTENT |
                                    GIMP_PARASITE_UNDOABLE,
                                    length, data);

      if (! gimp_image_validate_icc_parasite (image, parasite, error))
        {
          gimp_parasite_free (parasite);
          return FALSE;
        }
    }

  gimp_image_set_icc_parasite (image, parasite);

  if (parasite)
    gimp_parasite_free (parasite);

  return TRUE;
}
Exemple #3
0
static void
save_defaults (void)
{
  GimpParasite *parasite;
  gchar        *def_str;

  def_str = g_strdup_printf ("%lf %lf %d %d %d %d %d %d %d %d %d %d %d %d %d",
                             jsvals.quality,
                             jsvals.smoothing,
                             jsvals.optimize,
                             jsvals.progressive,
                             (gint) jsvals.subsmp,
                             jsvals.baseline,
                             jsvals.restart,
                             jsvals.dct,
                             jsvals.preview,
                             jsvals.save_exif,
                             jsvals.save_thumbnail,
                             jsvals.save_xmp,
                             jsvals.use_orig_quality,
                             jsvals.save_iptc,
                             jsvals.arithmetic_coding);
  parasite = gimp_parasite_new (JPEG_DEFAULTS_PARASITE,
                                GIMP_PARASITE_PERSISTENT,
                                strlen (def_str), def_str);

  gimp_attach_parasite (parasite);

  gimp_parasite_free (parasite);
  g_free (def_str);
}
Exemple #4
0
static gint32
create_image (GdkPixbuf   *pixbuf,
              GdkRegion   *shape,
              const gchar *name)
{
  gint32     image;
  gint32     layer;
  gdouble    xres, yres;
  gchar     *comment;
  gint       width, height;
  gboolean   status;

  status = gimp_progress_init (_("Importing screenshot"));

  width  = gdk_pixbuf_get_width (pixbuf);
  height = gdk_pixbuf_get_height (pixbuf);

  image = gimp_image_new (width, height, GIMP_RGB);
  gimp_image_undo_disable (image);

  gimp_get_monitor_resolution (&xres, &yres);
  gimp_image_set_resolution (image, xres, yres);

  comment = gimp_get_default_comment ();
  if (comment)
    {
      GimpParasite *parasite;

      parasite = gimp_parasite_new ("gimp-comment", GIMP_PARASITE_PERSISTENT,
                                    strlen (comment) + 1, comment);

      gimp_image_parasite_attach (image, parasite);
      gimp_parasite_free (parasite);

      g_free (comment);
    }

  layer = gimp_layer_new_from_pixbuf (image,
                                      name ? name : _("Screenshot"),
                                      pixbuf,
                                      100, GIMP_NORMAL_MODE, 0.0, 1.0);
  gimp_image_add_layer (image, layer, 0);

  if (shape && ! gdk_region_empty (shape))
    {
      image_select_shape (image, shape);

      if (! gimp_selection_is_empty (image))
        {
          gimp_layer_add_alpha (layer);
          gimp_edit_clear (layer);
          gimp_selection_none (image);
        }
    }

  gimp_image_undo_enable (image);

  return image;
}
/* --------------------------------------
 * gap_dvref_assign_videoref_parasites
 * --------------------------------------
 * if gpp->drawable_vref contains vaild video reference
 * then
 * assign video reference parasites to the specified drawable_id (typically this is a layer.)
 * (one parasite contains only the videfilename and has variable length,
 * the other contains framenumber and other information that was used to fetch
 * the frame from the videofile).
 *
 * the video reference is typically set on successful fetch
 * from a video file. (and reset on all other types of frame fetches)
 *
 + TODO: query gimprc parameter that can configures using persitent drawable_videoref_parasites.
 *       (default shall be temporary parasites)
 */
void
gap_dvref_assign_videoref_parasites(GapDrawableVideoRef *dvref, gint32 drawable_id)
{
  GimpParasite    *l_parasite;

  if(gap_debug)
  {
    printf("gap_assign_drawable_videoref_parasite: START\n");
    gap_dvref_debug_print_GapDrawableVideoRef(dvref);
  }

  if(dvref->videofile == NULL)
  {
    /* no viedo reference available for the current frame */
    return;
  }


  l_parasite = gimp_parasite_new(GAP_DRAWABLE_VIDEOFILE_PARASITE_NAME
                                 ,0  /* GIMP_PARASITE_PERSISTENT  0 for non persistent */
                                 ,1 + strlen(dvref->videofile)
                                 ,dvref->videofile  /* parasite data */
                                 );
  if(l_parasite)
  {
    gimp_drawable_parasite_attach(drawable_id, l_parasite);
    gimp_parasite_free(l_parasite);
  }

  l_parasite = gimp_parasite_new(GAP_DRAWABLE_VIDEOPARAMS_PARASITE_NAME
                                 ,0 /* GIMP_PARASITE_PERSISTENT */
                                 ,sizeof(GapDrawableVideoParasite)
                                 ,&dvref->para  /* parasite data */
                                 );
  if(l_parasite)
  {
    gimp_drawable_parasite_attach(drawable_id, l_parasite);
    gimp_parasite_free(l_parasite);
  }

}       /* end gap_dvref_assign_videoref_parasites */
/**
 * gimp_drawable_attach_new_parasite:
 * @drawable_ID: the ID of the #GimpDrawable to attach the #GimpParasite to.
 * @name: the name of the #GimpParasite to create and attach.
 * @flags: the flags set on the #GimpParasite.
 * @size: the size of the parasite data in bytes.
 * @data: a pointer to the data attached with the #GimpParasite.
 *
 * Convenience function that creates a parasite and attaches it
 * to GIMP.
 *
 * Deprecated: use gimp_image_parasite_attach() instead.
 *
 * Return value: TRUE on successful creation and attachment of
 * the new parasite.
 *
 * See Also: gimp_drawable_parasite_attach()
 */
gboolean
gimp_drawable_attach_new_parasite (gint32          drawable_ID,
                                   const gchar    *name,
                                   gint            flags,
                                   gint            size,
                                   gconstpointer   data)
{
  GimpParasite *parasite = gimp_parasite_new (name, flags, size, data);
  gboolean      success;

  success = gimp_item_attach_parasite (drawable_ID, parasite);

  gimp_parasite_free (parasite);

  return success;
}
Exemple #7
0
/* -----------------------------------------
 * p_add_image_to_list_of_duplicated_images
 * -----------------------------------------
 * add specified image to the list of duplicated images.
 * this list contains temporary images of both fetched video frames
 * and merged duplicates of the cached original images.
 */
static void
p_add_image_to_list_of_duplicated_images(gint32 image_id, gint32 ffetch_user_id)
{
  GimpParasite  *l_parasite;

  /* attach a parasite to mark the image as part of the gap image duplicates cache */
  l_parasite = gimp_parasite_new(GAP_IMAGE_DUP_CACHE_PARASITE
                                 ,0  /* GIMP_PARASITE_PERSISTENT  0 for non persistent */
                                 , sizeof(gint32)     /* size of parasite data */
                                 ,&ffetch_user_id     /* parasite data */
                                 );

  if(l_parasite)
  {
    gimp_image_parasite_attach(image_id, l_parasite);
    gimp_parasite_free(l_parasite);
  }
}   /* end p_add_image_to_list_of_duplicated_images */
Exemple #8
0
GimpParasite *
gimp_grid_to_parasite (const GimpGrid *grid)
{
    GimpParasite *parasite;
    gchar        *str;

    g_return_val_if_fail (GIMP_IS_GRID (grid), NULL);

    str = gimp_config_serialize_to_string (GIMP_CONFIG (grid), NULL);
    g_return_val_if_fail (str != NULL, NULL);

    parasite = gimp_parasite_new (gimp_grid_parasite_name (),
                                  GIMP_PARASITE_PERSISTENT,
                                  strlen (str) + 1, str);
    g_free (str);

    return parasite;
}
Exemple #9
0
GimpParasite *
gimp_symmetry_to_parasite (const GimpSymmetry *sym)
{
  GimpParasite *parasite;
  gchar        *parasite_name;
  gchar        *str;

  g_return_val_if_fail (GIMP_IS_SYMMETRY (sym), NULL);

  str = gimp_config_serialize_to_string (GIMP_CONFIG (sym), NULL);
  g_return_val_if_fail (str != NULL, NULL);

  parasite_name = gimp_symmetry_parasite_name (G_TYPE_FROM_INSTANCE (sym));
  parasite = gimp_parasite_new (parasite_name,
                                GIMP_PARASITE_PERSISTENT,
                                strlen (str) + 1, str);
  g_free (parasite_name);
  g_free (str);

  return parasite;
}
Exemple #10
0
/* ----------------------------------------------------
 * p_load_cache_image
 * ----------------------------------------------------
 * load an image from cache or from file (in case image is not already cached)
 * in case the flag addToCache is TRUE the image will be automatically added
 * to the cache after read from file operation.
 */
static gint32
p_load_cache_image(const char* filename, gint32 ffetch_user_id, gboolean addToCache)
{
  gint32 l_image_id;
  char *l_filename;

  gint32 *images;
  gint    nimages;
  gint    l_idi;
  gint    l_number_of_cached_images;
  gint32  l_first_cached_image_id;
  GimpParasite  *l_parasite;


  if(filename == NULL)
  {
    printf("p_load_cache_image: ** ERROR cant load filename == NULL! pid:%d\n", (int)gap_base_getpid());
    return -1;
  }

  l_image_id = -1;
  l_first_cached_image_id = -1;
  l_number_of_cached_images = 0;
  images = gimp_image_list(&nimages);
  for(l_idi=0; l_idi < nimages; l_idi++)
  {
    l_parasite = gimp_image_parasite_find(images[l_idi], GAP_IMAGE_CACHE_PARASITE);

    if(l_parasite)
    {
      gint32 *mtime_ptr;
      gint32 *ffetch_id_ptr;
      gchar  *filename_ptr;
      
      mtime_ptr = (gint32 *) l_parasite->data;
      ffetch_id_ptr = (gint32 *)&l_parasite->data[sizeof(gint32)];
      filename_ptr = (gchar *)&l_parasite->data[sizeof(gint32) + sizeof(gint32)];
    
      l_number_of_cached_images++;
      if (l_first_cached_image_id < 0)
      {
        l_first_cached_image_id = images[l_idi];
      }
      
      if(strcmp(filename, filename_ptr) == 0)
      {
        gint32 mtimefile;
        
        mtimefile = gap_file_get_mtime(filename);
        if(mtimefile == *mtime_ptr)
        {
          /* image found in cache */
          l_image_id = images[l_idi];
        }
        else
        {
          /* image found in cache, but has changed modification timestamp
           * (delete from cache and reload)
           */
          if(gap_debug)
          {
            printf("FrameFetcher: DELETE because mtime changed : (image_id:%d) ffetchId:%d name:%s  mtimefile:%d mtimecache:%d  pid:%d\n"
                  , (int)images[l_idi]
                  , (int)*ffetch_id_ptr
                  , gimp_image_get_filename(images[l_idi])
                  , (int)mtimefile
                  , (int)*mtime_ptr
                  , (int)gap_base_getpid()
                  );
          }
          gap_image_delete_immediate(images[l_idi]);
        }
        l_idi = nimages -1;  /* force break at next loop iteration */
      }
      gimp_parasite_free(l_parasite);
    }
  }
  if(images)
  {
    g_free(images);
  }
  
  if (l_image_id >= 0)
  {
    if(gap_debug)
    {
      printf("FrameFetcher: p_load_cache_image CACHE-HIT :%s (image_id:%d) pid:%d\n"
            , filename, (int)l_image_id, (int)gap_base_getpid());
    }
    return(l_image_id);
  }

  l_filename = g_strdup(filename);
  l_image_id = gap_lib_load_image(l_filename);
  if(gap_debug)
  {
    printf("FrameFetcher: loaded image from disk:%s (image_id:%d) pid:%d\n"
      , l_filename, (int)l_image_id, (int)gap_base_getpid());
  }

  if((l_image_id >= 0) && (addToCache == TRUE))
  {
    guchar *parasite_data;
    gint32  parasite_size;
    gint32 *parasite_mtime_ptr;
    gint32 *parasite_ffetch_id_ptr;
    gchar  *parasite_filename_ptr;
    gint32  len_filename0;           /* filename length including the terminating 0 */
  
    if (l_number_of_cached_images > p_get_ffetch_max_img_cache_elements())
    {
      /* the image cache already has more elements than desired,
       * drop the 1st cached image
       */
      if(gap_debug)
      {
        printf("FrameFetcher: DELETE because cache is full: (image_id:%d)  name:%s number_of_cached_images:%d pid:%d\n"
              , (int)l_first_cached_image_id
              , gimp_image_get_filename(l_first_cached_image_id)
              , (int)l_number_of_cached_images
              , (int)gap_base_getpid()
              );
      }
      gap_image_delete_immediate(l_first_cached_image_id);
    }

    /* build parasite data including mtime and full filename with terminating 0 byte */
    len_filename0 = strlen(filename) + 1;
    parasite_size = sizeof(gint32) + sizeof(gint32) + len_filename0;  
    parasite_data = g_malloc0(parasite_size);
    parasite_mtime_ptr = (gint32 *)parasite_data;
    parasite_ffetch_id_ptr = (gint32 *)&parasite_data[sizeof(gint32)];
    parasite_filename_ptr = (gchar *)&parasite_data[sizeof(gint32) + sizeof(gint32)];
    
    *parasite_mtime_ptr = gap_file_get_mtime(filename);
    *parasite_ffetch_id_ptr = ffetch_user_id;
    memcpy(parasite_filename_ptr, filename, len_filename0);
    
    /* attach a parasite to mark the image as part of the gap image cache */
    l_parasite = gimp_parasite_new(GAP_IMAGE_CACHE_PARASITE
                                   ,0  /* GIMP_PARASITE_PERSISTENT  0 for non persistent */
                                   ,parasite_size
                                   ,parasite_data
                                   );

    if(l_parasite)
    {
      gimp_image_parasite_attach(l_image_id, l_parasite);
      gimp_parasite_free(l_parasite);
    }
    g_free(parasite_data);

  }

  g_free(l_filename);

  return(l_image_id);
}  /* end p_load_cache_image */
Exemple #11
0
/**
 * jpeg_detect_original_settings:
 * @cinfo: a pointer to a JPEG decompressor info.
 * @image_ID: the image to which the parasite should be attached.
 *
 * Analyze the image being decompressed (@cinfo) and extract the
 * sampling factors, quantization tables and overall image quality.
 * Store this information in a parasite and attach it to @image_ID.
 *
 * This function must be called after jpeg_read_header() so that
 * @cinfo contains the quantization tables and the sampling factors
 * for each component.
 *
 * Return Value: TRUE if a parasite has been attached to @image_ID.
 */
gboolean
jpeg_detect_original_settings (struct jpeg_decompress_struct *cinfo,
                               gint32                         image_ID)
{
  guint         parasite_size;
  guchar       *parasite_data;
  GimpParasite *parasite;
  guchar       *dest;
  gint          quality;
  gint          num_quant_tables = 0;
  gint          t;
  gint          i;

  g_return_val_if_fail (cinfo != NULL, FALSE);
  if (cinfo->jpeg_color_space == JCS_UNKNOWN
      || cinfo->out_color_space == JCS_UNKNOWN)
    return FALSE;

  quality = jpeg_detect_quality (cinfo);
  /* no need to attach quantization tables if they are the ones from IJG */
  if (quality <= 0)
    {
      for (t = 0; t < 4; t++)
        if (cinfo->quant_tbl_ptrs[t])
          num_quant_tables++;
    }

  parasite_size = 4 + cinfo->num_components * 2 + num_quant_tables * 128;
  parasite_data = g_new (guchar, parasite_size);
  dest = parasite_data;

  *dest++ = CLAMP0255 (cinfo->jpeg_color_space);
  *dest++ = ABS (quality);
  *dest++ = CLAMP0255 (cinfo->num_components);
  *dest++ = num_quant_tables;

  for (i = 0; i < cinfo->num_components; i++)
    {
      *dest++ = CLAMP0255 (cinfo->comp_info[i].h_samp_factor);
      *dest++ = CLAMP0255 (cinfo->comp_info[i].v_samp_factor);
    }

  if (quality <= 0)
    {
      for (t = 0; t < 4; t++)
        if (cinfo->quant_tbl_ptrs[t])
          for (i = 0; i < DCTSIZE2; i++)
            {
              guint16 c = cinfo->quant_tbl_ptrs[t]->quantval[i];
              *dest++ = c / 256;
              *dest++ = c & 255;
            }
    }

  parasite = gimp_parasite_new ("jpeg-settings",
                                GIMP_PARASITE_PERSISTENT,
                                parasite_size,
                                parasite_data);
  g_free (parasite_data);
  gimp_image_parasite_attach (image_ID, parasite);
  gimp_parasite_free (parasite);
  return TRUE;
}
Exemple #12
0
void ptRun(const gchar*     Name,
           gint       NrParameters,
           const GimpParam* Parameter,
           gint *nreturn_vals,
           GimpParam **return_vals) {
  printf("(%s,%d) '%s'\n",__FILE__,__LINE__,__PRETTY_FUNCTION__);
  printf("Name         : '%s'\n",Name);
  printf("NrParameters : %d\n",NrParameters);
  if (!strcmp(Name,"photivoSendToGimp")) {
    printf("RunMode      : %d\n",Parameter[0].data.d_int32);
    printf("FileName1    : '%s'\n",Parameter[1].data.d_string);
    printf("FileName2    : '%s'\n",Parameter[2].data.d_string);

    QFile GimpFile(Parameter[1].data.d_string);
    bool result = GimpFile.open(QIODevice::ReadOnly | QIODevice::Text);
    assert(result);

    QTextStream In(&GimpFile);

    QString ImageFileName = In.readLine();
    QString ExifFileName  = In.readLine();
    QString ICCFileName   = In.readLine();

    // Read image
    FILE *InputFile = fopen(ImageFileName.toLocal8Bit().data(),"rb");
    if (!InputFile) {
      ptLogError(1,ImageFileName.toLocal8Bit().data());
      return; // ptError_FileOpen;
    }

    short    Colors;
    unsigned short Width;
    unsigned short Height;
    unsigned short BitsPerColor;
    char     Buffer[128];

    // Extremely naive. Probably just enough for testcases.
    char *s = fgets(Buffer,127,InputFile);
    assert ( s );
    int n = sscanf(Buffer,"P%hd",&Colors);
    assert ( 1 == n );
    assert(Colors == 6 );
    do {
      s = fgets(Buffer,127,InputFile);
      assert ( s );
    } while (Buffer[0] == '#');
    sscanf(Buffer,"%hd %hd",&Width,&Height);
    s = fgets(Buffer,127,InputFile);
    assert ( s );
    sscanf(Buffer,"%hd",&BitsPerColor);
    assert(BitsPerColor == 0xffff);

    Colors = 3;

    unsigned short (* ImageForGimp)[3] =
      (unsigned short (*)[3]) CALLOC2(Width*Height,sizeof(*ImageForGimp));
    ptMemoryError(ImageForGimp,__FILE__,__LINE__);

    unsigned short*  PpmRow = (unsigned short *) CALLOC2(Width*Height,sizeof(*PpmRow));
    ptMemoryError(PpmRow,__FILE__,__LINE__);

    for (unsigned short Row=0; Row<Height; Row++) {
      size_t RV = fread(PpmRow,Colors*2,Width,InputFile);
      if (RV != (size_t) Width) {
        printf("ReadPpm error. Expected %d bytes. Got %d\n",Width,(int)RV);
        exit(EXIT_FAILURE);
      }
      if (htons(0x55aa) != 0x55aa) {
        swab((char *)PpmRow,(char *)PpmRow,Width*Colors*2);
      }
      for (unsigned short Col=0; Col<Width; Col++) {
        for (short c=0;c<3;c++) {
          ImageForGimp[Row*Width+Col][c] = PpmRow[Col*Colors+c];
        }
      }
    }

    FREE2(PpmRow);
    FCLOSE(InputFile);

    QFile ExifFile(ExifFileName);
    result = ExifFile.open(QIODevice::ReadOnly);
    assert(result);
    qint64 FileSize = ExifFile.size();
    QDataStream ExifIn(&ExifFile);
    char* ExifBuffer = (char *) MALLOC2(FileSize);
    ptMemoryError(ExifBuffer,__FILE__,__LINE__);
    unsigned ExifBufferLength = ExifIn.readRawData(ExifBuffer,FileSize);
    ExifFile.close();

    QFile ICCFile(ICCFileName);
    result = ICCFile.open(QIODevice::ReadOnly);
    assert(result);
    qint64 FileSize2 = ICCFile.size();
    QDataStream ICCIn(&ICCFile);
    char* ICCBuffer = (char *) MALLOC2(FileSize2);
    ptMemoryError(ICCBuffer,__FILE__,__LINE__);
    unsigned ICCBufferLength = ICCIn.readRawData(ICCBuffer,FileSize2);
    ICCFile.close();

    // And now copy to gimp.
    gint32 GimpImage = gimp_image_new(Width,
                                      Height,
                                      GIMP_RGB);
    assert (GimpImage != -1);
    gint32 GimpLayer = gimp_layer_new(GimpImage,
                                      "BG",
                                      Width,
                                      Height,
                                      GIMP_RGB_IMAGE,
                                      100.0,
                                      GIMP_NORMAL_MODE);
#if GIMP_MINOR_VERSION<=6
    gimp_image_add_layer(GimpImage,GimpLayer,0);
#else
    gimp_image_insert_layer(GimpImage,GimpLayer,0,0);
#endif
    GimpDrawable* Drawable = gimp_drawable_get(GimpLayer);
    GimpPixelRgn PixelRegion;
    gimp_pixel_rgn_init(&PixelRegion,
                        Drawable,
                        0,
                        0,
                        Drawable->width,
                        Drawable->height,
                        true,
                        false);
    unsigned short TileHeight = gimp_tile_height();
    for (unsigned short Row=0; Row<Height; Row+=TileHeight) {
      unsigned short NrRows = MIN(Height-Row, (int)TileHeight);
      guint8* Buffer = g_new(guint8,TileHeight*Width*3);
      for (unsigned short i=0; i<NrRows; i++) {
        for (unsigned short j=0; j<Width; j++) {
          for (short c=0;c<3;c++) {
            Buffer[3*(i*Width+j)+c] =
              ImageForGimp[(Row+i)*Width+j][c]>>8;
          }
        }
      }
      gimp_pixel_rgn_set_rect(&PixelRegion,
                              Buffer,
                              0,
                              Row,
                              Width,
                              NrRows);
      g_free(Buffer);
    }
    gimp_drawable_flush(Drawable);
    gimp_drawable_detach(Drawable);
    FREE2(ImageForGimp);
    GimpParasite* GimpExifData = gimp_parasite_new("exif-data",
                                                   GIMP_PARASITE_PERSISTENT,
                                                   ExifBufferLength,
                                                   ExifBuffer);
    gimp_image_parasite_attach(GimpImage,GimpExifData);
    gimp_parasite_free(GimpExifData);
    FREE2(ExifBuffer);

    GimpParasite* GimpICCData = gimp_parasite_new("icc-profile",
                                                   GIMP_PARASITE_PERSISTENT,
                                                   ICCBufferLength,
                                                   ICCBuffer);
    gimp_image_parasite_attach(GimpImage,GimpICCData);
    gimp_parasite_free(GimpICCData);
    FREE2(ICCBuffer);

    static GimpParam Values[2];
    *nreturn_vals = 2;
    *return_vals = Values;
    Values[0].type = GIMP_PDB_STATUS;
    Values[0].data.d_status = GIMP_PDB_SUCCESS;
    Values[1].type = GIMP_PDB_IMAGE;
    Values[1].data.d_image = GimpImage;

    QFile::remove(ImageFileName);
    QFile::remove(ExifFileName);
    QFile::remove(ICCFileName);
    QFile::remove(Parameter[1].data.d_string);

  }
Exemple #13
0
static void
run (const gchar      *name,
     gint              nparams,
     const GimpParam  *param,
     gint             *nreturn_vals,
     GimpParam       **return_vals)
{
  static GimpParam   values[4];
  gint32             image_ID;
  XMPModel          *xmp_model;
  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;
  GimpParasite      *parasite = NULL;

  *nreturn_vals = 1;
  *return_vals  = values;

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

  INIT_I18N();

  if (! strcmp (name, EDITOR_PROC))
    image_ID = param[1].data.d_image;
  else
    image_ID = param[0].data.d_image;

  xmp_model = xmp_model_new ();

  /* if there is already a metadata parasite, load it */
  parasite = gimp_image_get_parasite (image_ID, METADATA_PARASITE);
  if (parasite)
    {
      GError *error = NULL;

      if (!! strncmp (gimp_parasite_data (parasite),
                      METADATA_MARKER, METADATA_MARKER_LEN)
          || ! xmp_model_parse_buffer (xmp_model,
                                       (const gchar *) gimp_parasite_data (parasite)
                                       + METADATA_MARKER_LEN,
                                       gimp_parasite_data_size (parasite)
                                       - METADATA_MARKER_LEN,
                                       TRUE, &error))
        {
          g_printerr ("\nMetadata parasite seems to be corrupt\n");
          /* continue anyway, we will attach a clean parasite later */
        }
      gimp_parasite_free (parasite);
    }

  /* If we have no metadata yet, try to find an XMP packet in the file
   * (but ignore errors if nothing is found).
   *
   * FIXME: This is a workaround until all file plug-ins do the right
   * thing when loading their files.
   */
  if (xmp_model_is_empty (xmp_model)
      && !! strcmp (name, DECODE_XMP_PROC))
    {
      const gchar *filename;
      GError      *error = NULL;

      filename = gimp_image_get_filename (image_ID);
      if (filename != NULL)
        if (xmp_model_parse_file (xmp_model, filename, &error))
          /* g_message ("XMP loaded from file '%s'\n", filename) */;
    }

  /* Now check what we are supposed to do */
  if (! strcmp (name, DECODE_XMP_PROC))
    {
      const gchar *buffer;
      GError      *error = NULL;

      buffer = param[1].data.d_string;
      if (! xmp_model_parse_buffer (xmp_model, buffer, strlen (buffer),
                                    FALSE, &error))
        status = GIMP_PDB_EXECUTION_ERROR;

    }
  else if (! strcmp (name, ENCODE_XMP_PROC))
    {
      /* done below together with the parasite */
    }
  else if (! strcmp (name, DECODE_EXIF_PROC))
    {
        GError      *error         = NULL;

        if (! xmp_merge_from_exifbuffer (xmp_model, image_ID, &error))
          {
            status = GIMP_PDB_EXECUTION_ERROR;
            g_printerr ("\nExif to XMP merge failed.\n");
          }
    }
  else if (! strcmp (name, GET_PROC))
    {
      g_printerr ("Not implemented yet (GET_PROC)\n"); /* FIXME */
      status = GIMP_PDB_EXECUTION_ERROR;
    }
  else if (! strcmp (name, SET_PROC))
    {
      g_printerr ("Not implemented yet (SET_PROC)\n"); /* FIXME */
      status = GIMP_PDB_EXECUTION_ERROR;
    }
  else if (! strcmp (name, GET_SIMPLE_PROC))
    {
      const gchar *schema_name;
      const gchar *property_name;
      const gchar *value;

      schema_name = param[1].data.d_string;
      property_name = param[2].data.d_string;
      value = xmp_model_get_scalar_property (xmp_model, schema_name,
                                             property_name);
      if (value)
        {
          *nreturn_vals = 2;
          values[1].type = GIMP_PDB_STRING;
          values[1].data.d_string = g_strdup (value);
        }
      else
        status = GIMP_PDB_EXECUTION_ERROR;
    }
  else if (! strcmp (name, SET_SIMPLE_PROC))
    {
      const gchar *schema_name;
      const gchar *property_name;
      const gchar *property_value;

      schema_name = param[1].data.d_string;
      property_name = param[2].data.d_string;
      property_value = param[3].data.d_string;
      if (! xmp_model_set_scalar_property (xmp_model, schema_name,
                                           property_name, property_value))
        status = GIMP_PDB_EXECUTION_ERROR;
    }
  else if (! strcmp (name, IMPORT_PROC))
    {
      const gchar *filename;
      gchar       *buffer;
      gsize        buffer_length;
      GError      *error = NULL;

      filename = param[1].data.d_string;
      if (! g_file_get_contents (filename, &buffer, &buffer_length, &error))
        {
          g_error_free (error);
          status = GIMP_PDB_EXECUTION_ERROR;
        }
      else if (! xmp_model_parse_buffer (xmp_model, buffer, buffer_length,
                                         TRUE, &error))
        {
          g_error_free (error);
          status = GIMP_PDB_EXECUTION_ERROR;
        }
      g_free (buffer);
    }
  else if (! strcmp (name, EXPORT_PROC))
    {
      /* FIXME: this is easy to implement, but the first thing to do is */
      /* to improve the code of export_dialog_response() in interface.c */
      g_printerr ("Not implemented yet (EXPORT_PROC)\n");
      status = GIMP_PDB_EXECUTION_ERROR;
    }
  else if (! strcmp (name, EDITOR_PROC))
    {
      GimpRunMode run_mode;

      run_mode = param[0].data.d_int32;
      if (run_mode == GIMP_RUN_INTERACTIVE)
        {
          if (! metadata_dialog (image_ID, xmp_model))
            status = GIMP_PDB_CANCEL;
        }

      g_printerr ("Not implemented yet (EDITOR_PROC)\n");
      status = GIMP_PDB_EXECUTION_ERROR;
    }
  else
    {
      status = GIMP_PDB_CALLING_ERROR;
    }

  if (status == GIMP_PDB_SUCCESS)
    {
      GString *buffer;

      /* Generate the updated parasite and attach it to the image */
      buffer = g_string_new (METADATA_MARKER);
      xmp_generate_packet (xmp_model, buffer);
      parasite = gimp_parasite_new (METADATA_PARASITE,
                                    GIMP_PARASITE_PERSISTENT,
                                    buffer->len,
                                    (gpointer) buffer->str);
      gimp_image_attach_parasite (image_ID, parasite);
      if (! strcmp (name, ENCODE_XMP_PROC))
        {
          *nreturn_vals = 2;
          values[1].type = GIMP_PDB_STRING;
          values[1].data.d_string = g_strdup (buffer->str
                                              + METADATA_MARKER_LEN);
        }
      g_string_free (buffer, TRUE);
    }

  g_object_unref (xmp_model);

  values[0].data.d_status = status;
}
Exemple #14
0
static gboolean
lcms_image_set_profile (gint32       image,
                        cmsHPROFILE  profile,
                        const gchar *filename,
                        gboolean     undo_group)
{
  g_return_val_if_fail (image != -1, FALSE);

  if (filename)
    {
      GimpParasite *parasite;
      GMappedFile  *file;
      GError       *error = NULL;

      file = g_mapped_file_new (filename, FALSE, &error);

      if (! file)
        {
          g_message ("%s", error->message);
          g_error_free (error);

          return FALSE;
        }

      /* check that this file is actually an ICC profile */
      if (! profile)
        {
          profile = cmsOpenProfileFromMem (g_mapped_file_get_contents (file),
                                           g_mapped_file_get_length (file));

          if (profile)
            {
              cmsCloseProfile (profile);
            }
          else
            {
              g_message (_("'%s' does not appear to be an ICC color profile"),
                         gimp_filename_to_utf8 (filename));
              return FALSE;
            }
        }

      if (undo_group)
        gimp_image_undo_group_start (image);

      parasite = gimp_parasite_new ("icc-profile",
                                    GIMP_PARASITE_PERSISTENT |
                                    GIMP_PARASITE_UNDOABLE,
                                    g_mapped_file_get_length (file),
                                    g_mapped_file_get_contents (file));

      g_mapped_file_unref (file);

      gimp_image_attach_parasite (image, parasite);
      gimp_parasite_free (parasite);
    }
  else
    {
      if (undo_group)
        gimp_image_undo_group_start (image);

      gimp_image_detach_parasite (image, "icc-profile");
    }

  gimp_image_detach_parasite (image, "icc-profile-name");

  if (undo_group)
    gimp_image_undo_group_end (image);

  return TRUE;
}
Exemple #15
0
static gboolean
jpeg_exif_rotate_query_dialog (gint32 image_ID)
{
  GtkWidget *dialog;
  GtkWidget *hbox;
  GtkWidget *vbox;
  GtkWidget *label;
  GtkWidget *toggle;
  GdkPixbuf *pixbuf;
  gint       response;

  dialog = gimp_dialog_new (_("Rotate Image?"), PLUG_IN_BINARY,
                            NULL, 0, NULL, NULL,

                            _("_Keep Orientation"), GTK_RESPONSE_CANCEL,
                            GIMP_STOCK_TOOL_ROTATE, GTK_RESPONSE_OK,

                            NULL);

  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
                                           GTK_RESPONSE_OK,
                                           GTK_RESPONSE_CANCEL,
                                           -1);

  gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
  gimp_window_set_transient (GTK_WINDOW (dialog));

  hbox = gtk_hbox_new (FALSE, 12);
  gtk_container_set_border_width (GTK_CONTAINER (hbox), 12);
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
                      hbox, FALSE, FALSE, 0);
  gtk_widget_show (hbox);

  vbox = gtk_vbox_new (FALSE, 6);
  gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
  gtk_widget_show (vbox);

  pixbuf = gimp_image_get_thumbnail (image_ID,
                                     THUMBNAIL_SIZE, THUMBNAIL_SIZE,
                                     GIMP_PIXBUF_SMALL_CHECKS);

  if (pixbuf)
    {
      GtkWidget *image;
      gchar     *name;

      image = gtk_image_new_from_pixbuf (pixbuf);
      g_object_unref (pixbuf);

      gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0);
      gtk_widget_show (image);

      name = gimp_image_get_name (image_ID);

      label = gtk_label_new (name);
      gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
      gimp_label_set_attributes (GTK_LABEL (label),
                                 PANGO_ATTR_STYLE,  PANGO_STYLE_ITALIC,
                                 -1);
      gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
      gtk_widget_show (label);

      g_free (name);
    }

  vbox = gtk_vbox_new (FALSE, 12);
  gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
  gtk_widget_show (vbox);

  label = g_object_new (GTK_TYPE_LABEL,
                        "label",   _("According to the EXIF data, "
                                     "this image is rotated."),
                        "wrap",    TRUE,
                        "justify", GTK_JUSTIFY_LEFT,
                        "xalign",  0.0,
                        "yalign",  0.5,
                        NULL);
  gimp_label_set_attributes (GTK_LABEL (label),
                             PANGO_ATTR_SCALE,  PANGO_SCALE_LARGE,
                             PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD,
                             -1);
  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
  gtk_widget_show (label);

  label = g_object_new (GTK_TYPE_LABEL,
                        "label",   _("Would you like GIMP to rotate it "
                                     "into the standard orientation?"),
                        "wrap",    TRUE,
                        "justify", GTK_JUSTIFY_LEFT,
                        "xalign",  0.0,
                        "yalign",  0.5,
                        NULL);
  gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
  gtk_widget_show (label);

  toggle = gtk_check_button_new_with_mnemonic (_("_Don't ask me again"));
  gtk_box_pack_end (GTK_BOX (vbox), toggle, FALSE, FALSE, 0);
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), FALSE);
  gtk_widget_show (toggle);

  response = gimp_dialog_run (GIMP_DIALOG (dialog));

  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle)))
    {
      GimpParasite *parasite;
      const gchar  *str = (response == GTK_RESPONSE_OK) ? "yes" : "no";

      parasite = gimp_parasite_new (JPEG_EXIF_ROTATE_PARASITE,
                                    GIMP_PARASITE_PERSISTENT,
                                    strlen (str), str);
      gimp_parasite_attach (parasite);
      gimp_parasite_free (parasite);
    }

  gtk_widget_destroy (dialog);

  return (response == GTK_RESPONSE_OK);
}
Exemple #16
0
static gboolean
lcms_image_set_profile (gint32       image,
                        cmsHPROFILE  profile,
                        GFile       *file)
{
  g_return_val_if_fail (image != -1, FALSE);

  if (file)
    {
      cmsHPROFILE   file_profile;
      GimpParasite *parasite;
      guint8       *profile_data;
      gsize         profile_length;
      GError       *error = NULL;

      /* check that this file is actually an ICC profile */
      file_profile = gimp_lcms_profile_open_from_file (file, &error);

      if (! file_profile)
        {
          g_message ("%s", error->message);
          g_clear_error (&error);

          return FALSE;
        }

      profile_data = gimp_lcms_profile_save_to_data (file_profile,
                                                     &profile_length,
                                                     &error);
      cmsCloseProfile (file_profile);

      if (! profile_data)
        {
          g_message ("%s", error->message);
          g_clear_error (&error);

          return FALSE;
        }

      gimp_image_undo_group_start (image);

      parasite = gimp_parasite_new ("icc-profile",
                                    GIMP_PARASITE_PERSISTENT |
                                    GIMP_PARASITE_UNDOABLE,
                                    profile_length, profile_data);

      g_free (profile_data);

      gimp_image_attach_parasite (image, parasite);
      gimp_parasite_free (parasite);
    }
  else
    {
      gimp_image_undo_group_start (image);

      gimp_image_detach_parasite (image, "icc-profile");
    }

  gimp_image_detach_parasite (image, "icc-profile-name");

  gimp_image_undo_group_end (image);

  return TRUE;
}
Exemple #17
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;
}
Exemple #18
0
static void run ( const gchar *name, gint nparams, const GimpParam *param,
                  gint *nreturn_vals, GimpParam **return_vals)
{
  static GimpParam values[3];
  GimpRunMode run_mode;
  GimpPDBStatusType status = GIMP_PDB_SUCCESS;
  SeparateContext mysc;
  //enum separate_function func = SEP_NONE;
  run_mode = param[0].data.d_int32;


  /* setup for localization */
  INIT_I18N ();

  cmsErrorAction( LCMS_ERROR_IGNORE );

  mysc.filename = NULL;
  if( nparams != ( run_mode == GIMP_RUN_NONINTERACTIVE ? 2 : 1 ) )
    status = GIMP_PDB_CALLING_ERROR;
  else if( run_mode == GIMP_RUN_NONINTERACTIVE ) {
    if( param[1].type != GIMP_PDB_STRING || strlen( param[1].data.d_string ) == 0 )
      status = GIMP_PDB_CALLING_ERROR;
    else
      mysc.filename = g_strdup( param[1].data.d_string );
  } else {
    gint size = gimp_get_data_size( "plug-in-separate-import/lastpath" );
    if( size ) {
      mysc.filename = g_malloc( size );
      gimp_get_data( "plug-in-separate-import/lastpath", mysc.filename );
    }
  }

  if( status == GIMP_PDB_SUCCESS && ( run_mode == GIMP_RUN_NONINTERACTIVE || separate_import_dialog( &mysc ) ) ) {
    gint i, j, x, y;
    TIFF *in;
    guint32 width, height, stripSize, stripCount, stripHeight;
    gint16 bps, spp, step, planerConfig, photometric, inkset, resolutionUnit;
    float xres, yres;
    const gchar *layerNames[] = { "C", "M", "Y", "K" };
    guchar *buf, *maskbuf[4], *srcbuf, *destbuf[4], *iccProfile;
    gint32 layers[5], masks[4];
    GimpDrawable *drw[4];
    GimpPixelRgn rgn[4];
    GimpRGB primaries[4] = { { .180, .541, .870, 1.0 },
                             { .925, .149, .388, 1.0 },
                             { .929, .862, .129, 1.0 },
                             { 0, 0, 0, 1.0 }  };

    gchar *str = NULL;
    gchar *baseName = g_path_get_basename( gimp_filename_to_utf8( mysc.filename ) );

#ifdef G_OS_WIN32
    {
      gchar *_filename = NULL; // win32 filename encoding(not UTF-8)
      _filename = g_win32_locale_filename_from_utf8( mysc.filename );
      in = TIFFOpen( _filename ? _filename : mysc.filename, "r" );
      g_free( _filename );
    }
#else
    in = TIFFOpen( mysc.filename, "r" );
#endif

    if( !in ) {
      str = g_strdup_printf( _( "Cannot open : \"%s\"" ), baseName );
      gimp_message( str );
      g_free( str );
      status = GIMP_PDB_EXECUTION_ERROR;
    } else {
      if( ( TIFFGetField( in, TIFFTAG_BITSPERSAMPLE, &bps ) == FALSE || ( bps != 8 && bps != 16 ) ) ||
          ( TIFFGetField( in, TIFFTAG_SAMPLESPERPIXEL, &spp ) == FALSE || spp != 4 ) ||
          ( TIFFGetField( in, TIFFTAG_PHOTOMETRIC, &photometric ) == FALSE || photometric != PHOTOMETRIC_SEPARATED ) ||
          ( TIFFGetField( in, TIFFTAG_PLANARCONFIG, &planerConfig ) == FALSE || planerConfig != PLANARCONFIG_CONTIG ) ||
          ( TIFFGetField( in, TIFFTAG_INKSET, &inkset ) == TRUE && inkset != INKSET_CMYK ) ) {
        str = g_strdup_printf( _( "\"%s\" is unsupported." ), baseName );
        gimp_message( str );
        g_free( str );
        status = GIMP_PDB_EXECUTION_ERROR;
      } else {
        stripCount = TIFFNumberOfStrips( in );
        stripSize = TIFFStripSize( in );
        TIFFGetField( in, TIFFTAG_IMAGEWIDTH, &width );
        TIFFGetField( in, TIFFTAG_IMAGELENGTH, &height );
        TIFFGetField( in, TIFFTAG_ROWSPERSTRIP, &stripHeight );
        TIFFGetField( in, TIFFTAG_RESOLUTIONUNIT, &resolutionUnit );
        TIFFGetField( in, TIFFTAG_XRESOLUTION, &xres );
        TIFFGetField( in, TIFFTAG_YRESOLUTION, &yres );

#if 0
        str = g_strdup_printf( "Photometric : %d  BPS : %d  SPP : %d\nInkset : %d  StripCount : %d", photometric, bps, spp, inkset, stripCount );
        gimp_message( str );
        g_free( str );
#endif

        step = ( bps == 16 ) ? 2 : 1;

        buf = g_malloc( stripSize );

        values[1].data.d_image = gimp_image_new( width, height, GIMP_RGB );
        gimp_image_set_resolution( values[1].data.d_image, xres, yres );
        gimp_context_push();
        for( i = 0; i < 4; i++ ) {
          layers[i] = gimp_layer_new( values[1].data.d_image, layerNames[i], width, height, GIMP_RGBA_IMAGE, 100.0, GIMP_DARKEN_ONLY_MODE );
          gimp_context_set_foreground( &primaries[i] );
          gimp_drawable_fill( layers[i], GIMP_FOREGROUND_FILL );
          gimp_image_add_layer( values[1].data.d_image, layers[i], i );
          masks[i] = gimp_layer_create_mask( layers[i], GIMP_ADD_BLACK_MASK );
          gimp_layer_add_mask( layers[i], masks[i] );
          drw[i] = gimp_drawable_get( masks[i] );
          maskbuf[i] = g_malloc( width * stripHeight );
        }
        gimp_context_pop();
        layers[4] = gimp_layer_new( values[1].data.d_image, _( "Background" ), width, height, GIMP_RGB_IMAGE, 100.0, GIMP_NORMAL_MODE );
        gimp_drawable_fill( layers[4], GIMP_WHITE_FILL );
        gimp_image_add_layer( values[1].data.d_image, layers[4], 4 );

        str = g_strdup_printf( _( "Reading \"%s\"..." ), baseName );
        gimp_progress_init( str );
        g_free( str );

        for( i = 0; i < stripCount; i++ ) {
          guint32 size = TIFFReadEncodedStrip( in, i, buf, stripSize );
          guint32 rowCount = ( size < stripSize ? height % stripHeight : stripHeight );
          srcbuf = buf;
          if( bps == 16 )
            srcbuf++;
          for( j = 0; j < 4; j++ ) {
            gimp_pixel_rgn_init( &( rgn[j] ), drw[j],
                                 0, stripHeight * i, width, rowCount,
                                 FALSE, FALSE );
            destbuf[j] = maskbuf[j];
          }
          for( y = 0; y < rowCount; y++ ) {
            for( x = 0; x < width; x++ ) {
              *destbuf[0]++ = *srcbuf;
              srcbuf += step;
              *destbuf[1]++ = *srcbuf;
              srcbuf += step;
              *destbuf[2]++ = *srcbuf;
              srcbuf += step;
              *destbuf[3]++ = *srcbuf;
              srcbuf += step;
              //srcbuf += spp > 4 ? spp - 4 : 0;
            }
          }
          gimp_pixel_rgn_set_rect( &( rgn[0] ), maskbuf[0], 0, stripHeight * i, width, rowCount );
          gimp_pixel_rgn_set_rect( &( rgn[1] ), maskbuf[1], 0, stripHeight * i, width, rowCount );
          gimp_pixel_rgn_set_rect( &( rgn[2] ), maskbuf[2], 0, stripHeight * i, width, rowCount );
          gimp_pixel_rgn_set_rect( &( rgn[3] ), maskbuf[3], 0, stripHeight * i, width, rowCount );
          gimp_progress_update( (gdouble)i / stripCount );
        }
        g_free( buf );
        for( i = 0; i < 4; i++ ) {
          g_free( maskbuf[i] );
          gimp_drawable_detach( drw[i] );
        }

#ifdef ENABLE_COLOR_MANAGEMENT
        if ( TIFFGetField( in, TIFFTAG_ICCPROFILE, &width, &iccProfile ) ) {
          GimpParasite *parasite;

          parasite = gimp_parasite_new( CMYKPROFILE, 0, width, iccProfile );
          gimp_image_parasite_attach( values[1].data.d_image, parasite );
          gimp_parasite_free( parasite );

          //g_free( iccProfile ); // This causes clash on TIFFClose( in ).
        }
#endif
      }
      TIFFClose( in );
    }
    g_free( baseName );
  } else
    status = GIMP_PDB_CANCEL;

  *return_vals = values;
  values[0].type = GIMP_PDB_STATUS;
  values[0].data.d_status = status;
  if( status == GIMP_PDB_SUCCESS ) {
    *nreturn_vals = 2;
    values[1].type = GIMP_PDB_IMAGE;
    if( run_mode != GIMP_RUN_NONINTERACTIVE ) {
      gimp_image_undo_enable( values[1].data.d_image );
      gimp_display_new( values[1].data.d_image );
      gimp_displays_flush();
    }
    gimp_set_data( "plug-in-separate-import/lastpath", mysc.filename, strlen( mysc.filename ) + 1 );
  } else
    *nreturn_vals = 1;

  g_free( mysc.filename );
}
static gint
DoExtension (FILE *fd,
             gint  label)
{
  static guchar  buf[256];
  gchar         *str;

  switch (label)
    {
    case 0x01:                  /* Plain Text Extension */
      str = "Plain Text Extension";
#ifdef notdef
      if (GetDataBlock (fd, (guchar *) buf) == 0)
        ;

      lpos       = LM_to_uint (buf[0], buf[1]);
      tpos       = LM_to_uint (buf[2], buf[3]);
      width      = LM_to_uint (buf[4], buf[5]);
      height     = LM_to_uint (buf[6], buf[7]);
      cellw      = buf[8];
      cellh      = buf[9];
      foreground = buf[10];
      background = buf[11];

      while (GetDataBlock (fd, (guchar *) buf) > 0)
        {
          PPM_ASSIGN (image[ypos][xpos],
                      cmap[CM_RED][v],
                      cmap[CM_GREEN][v],
                      cmap[CM_BLUE][v]);
          ++index;
        }

      return FALSE;
#else
      break;
#endif

    case 0xff:                  /* Application Extension */
      str = "Application Extension";
      break;
    case 0xfe:                  /* Comment Extension */
      str = "Comment Extension";
      while (GetDataBlock (fd, (guchar *) buf) > 0)
        {
          gchar *comment = (gchar *) buf;

          if (! g_utf8_validate (comment, -1, NULL))
            continue;

          if (comment_parasite)
            gimp_parasite_free (comment_parasite);

          comment_parasite = gimp_parasite_new ("gimp-comment",
                                                GIMP_PARASITE_PERSISTENT,
                                                strlen (comment) + 1, comment);
        }
      return TRUE;
      break;

    case 0xf9:                  /* Graphic Control Extension */
      str = "Graphic Control Extension";
      (void) GetDataBlock (fd, (guchar *) buf);
      Gif89.disposal  = (buf[0] >> 2) & 0x7;
      Gif89.inputFlag = (buf[0] >> 1) & 0x1;
      Gif89.delayTime = LM_to_uint (buf[1], buf[2]);
      if ((buf[0] & 0x1) != 0)
        Gif89.transparent = buf[3];
      else
        Gif89.transparent = -1;

      while (GetDataBlock (fd, (guchar *) buf) > 0);

      return FALSE;
      break;

    default:
      str = (gchar *)buf;
      sprintf ((gchar *)buf, "UNKNOWN (0x%02x)", label);
      break;
    }

#ifdef GIFDEBUG
  g_print ("GIF: got a '%s'\n", str);
#endif

  while (GetDataBlock (fd, (guchar *) buf) > 0);

  return FALSE;
}
Exemple #20
0
static gboolean
gimp_parasite_list_deserialize (GimpConfig *list,
                                GScanner   *scanner,
                                gint        nest_level,
                                gpointer    data)
{
  GTokenType token;

  g_scanner_scope_add_symbol (scanner, 0,
                              parasite_symbol, (gpointer) parasite_symbol);

  token = G_TOKEN_LEFT_PAREN;

  while (g_scanner_peek_next_token (scanner) == token)
    {
      token = g_scanner_get_next_token (scanner);

      switch (token)
        {
        case G_TOKEN_LEFT_PAREN:
          token = G_TOKEN_SYMBOL;
          break;

        case G_TOKEN_SYMBOL:
          if (scanner->value.v_symbol == parasite_symbol)
            {
              gchar        *parasite_name      = NULL;
              gint          parasite_flags     = 0;
              guint8       *parasite_data      = NULL;
              gint          parasite_data_size = 0;
              GimpParasite *parasite;

              token = G_TOKEN_STRING;

              if (g_scanner_peek_next_token (scanner) != token)
                break;

              if (! gimp_scanner_parse_string (scanner, &parasite_name))
                break;

              token = G_TOKEN_INT;

              if (g_scanner_peek_next_token (scanner) != token)
                goto cleanup;

              if (! gimp_scanner_parse_int (scanner, &parasite_flags))
                goto cleanup;

              token = G_TOKEN_INT;

              if (g_scanner_peek_next_token (scanner) != token)
                {
                  /*  old format -- plain string  */

                  gchar *str;

                  if (g_scanner_peek_next_token (scanner) != G_TOKEN_STRING)
                    goto cleanup;

                  if (! gimp_scanner_parse_string (scanner, &str))
                    goto cleanup;

                  parasite_data_size = strlen (str);
                  parasite_data      = (guint8 *) str;
                }
              else
                {
                  /*  new format -- properly encoded binary data  */

                  if (! gimp_scanner_parse_int (scanner, &parasite_data_size))
                    goto cleanup;

                  token = G_TOKEN_STRING;

                  if (g_scanner_peek_next_token (scanner) != token)
                    goto cleanup;

                  if (! gimp_scanner_parse_data (scanner, parasite_data_size,
                                                 &parasite_data))
                    goto cleanup;
                }

              parasite = gimp_parasite_new (parasite_name,
                                            parasite_flags,
                                            parasite_data_size,
                                            parasite_data);
              gimp_parasite_list_add (GIMP_PARASITE_LIST (list),
                                      parasite);  /* adds a copy */
              gimp_parasite_free (parasite);

              token = G_TOKEN_RIGHT_PAREN;

              g_free (parasite_data);
            cleanup:
              g_free (parasite_name);
            }
          break;

        case G_TOKEN_RIGHT_PAREN:
          token = G_TOKEN_LEFT_PAREN;
          break;

        default: /* do nothing */
          break;
        }
    }

  return gimp_config_deserialize_return (scanner, token, nest_level);
}
Exemple #21
0
static void
run (const gchar      *name,
     gint              nparams,
     const GimpParam  *param,
     gint             *nreturn_vals,
     GimpParam       **return_vals)
{
  static GimpParam  values[MAX_EXTRACT_IMAGES + 1];
  GimpPDBStatusType status = GIMP_PDB_SUCCESS;
  gint32            num_images;
  gint32            image_ID_extract[MAX_EXTRACT_IMAGES];
  gint32            layer_ID_extract[MAX_EXTRACT_IMAGES];
  gint              j;
  gint32            layer;
  gint32            num_layers;
  gint32            image_ID;

  INIT_I18N ();
  gegl_init (NULL, NULL);

  run_mode = param[0].data.d_int32;
  image_ID = param[1].data.d_image;
  layer    = param[2].data.d_drawable;

  *nreturn_vals = MAX_EXTRACT_IMAGES + 1;
  *return_vals  = values;

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

  for (j = 0; j < MAX_EXTRACT_IMAGES; j++)
    {
      values[j+1].type         = GIMP_PDB_IMAGE;
      values[j+1].data.d_int32 = -1;
    }

  switch (run_mode)
    {
    case GIMP_RUN_INTERACTIVE:
      /*  Possibly retrieve data  */
      gimp_get_data (PLUG_IN_PROC, &decovals);

      /*  First acquire information with a dialog  */
      if (! decompose_dialog ())
        return;
      break;

    case GIMP_RUN_NONINTERACTIVE:
      /*  Make sure all the arguments are there!  */
      if (nparams != 4 && nparams != 5 && nparams != 6)
        {
          status = GIMP_PDB_CALLING_ERROR;
        }
      else
        {
          strncpy (decovals.extract_type, param[3].data.d_string,
                   sizeof (decovals.extract_type));
          decovals.extract_type[sizeof (decovals.extract_type) - 1] = '\0';

          decovals.as_layers = nparams > 4 ? param[4].data.d_int32 : FALSE;
          decovals.use_registration = (strcmp (name, PLUG_IN_PROC_REG) == 0);
        }
      break;

    case GIMP_RUN_WITH_LAST_VALS:
      /*  Possibly retrieve data  */
      gimp_get_data (PLUG_IN_PROC, &decovals);
      break;

    default:
      break;
    }

  if (status == GIMP_PDB_SUCCESS)
    {
      gimp_progress_init (_("Decomposing"));

      num_images = decompose (image_ID, layer,
                              decovals.extract_type,
                              image_ID_extract,
                              &num_layers,
                              layer_ID_extract);

      if (num_images <= 0)
        {
          status = GIMP_PDB_EXECUTION_ERROR;
        }
      else
        {
          /* create decompose-data parasite */
          GString *data = g_string_new ("");

          g_string_printf (data, "source=%d type=%s ",
                           layer, decovals.extract_type);

          for (j = 0; j < num_layers; j++)
            g_string_append_printf (data, "%d ", layer_ID_extract[j]);

          for (j = 0; j < num_images; j++)
            {
              GimpParasite *parasite;

              values[j+1].data.d_int32 = image_ID_extract[j];

              gimp_image_undo_enable (image_ID_extract[j]);
              gimp_image_clean_all (image_ID_extract[j]);

              parasite = gimp_parasite_new ("decompose-data",
                                            0, data->len + 1, data->str);
              gimp_image_attach_parasite (image_ID_extract[j], parasite);
              gimp_parasite_free (parasite);

              if (run_mode != GIMP_RUN_NONINTERACTIVE)
                gimp_display_new (image_ID_extract[j]);
            }

          /*  Store data  */
          if (run_mode == GIMP_RUN_INTERACTIVE)
            gimp_set_data (PLUG_IN_PROC, &decovals, sizeof (DecoVals));
        }

      gimp_progress_end ();
    }

  values[0].data.d_status = status;
}