Ejemplo n.º 1
0
GimpPDBStatusType
file_vtf_save_image (const gchar *fname, gint32 image, gint32 run_mode,
                     GError **error)
{
    SaveInfo info;
    info.version = 4;
    info.format = Vtf::FormatDXT5;
    info.layer = 0;
    info.mipmap = TRUE;
    info.lowres = TRUE;
    info.crc = TRUE;

    if (run_mode == GIMP_RUN_INTERACTIVE)
        if (!file_vtf_save_dialog (&info))
            return GIMP_PDB_CANCEL;

    gimp_progress_init_printf ("Saving '%s'", gimp_filename_to_utf8 (fname));

    std::auto_ptr<Vtf::File> vtf (new Vtf::File);

    try {
        Vtf::HiresImageResource* vres = new Vtf::HiresImageResource;
//		vres->setup (info.format, info.width, info.height, info);
        vres->check ();

        vtf->addResource (vres);
        vtf->save (fname, info.version);
    } catch (std::exception& e) {
    }

    gimp_progress_update (1.0);

    return GIMP_PDB_SUCCESS;
}
Ejemplo n.º 2
0
static void
load_changed_cb (WebKitWebView   *view,
                 WebKitLoadEvent  event,
                 gpointer         user_data)
{
  if (event == WEBKIT_LOAD_FINISHED)
    {
      if (! webpagevals.error)
        {
          gimp_progress_init_printf (_("Transferring webpage image for '%s'"),
                                     webpagevals.url);

          g_timeout_add (100, load_finished_idle, view);

          return;
        }

      gtk_main_quit ();
    }
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
gboolean
uri_backend_load_image (const gchar  *uri,
                        const gchar  *tmpname,
                        GimpRunMode   run_mode,
                        GError      **error)
{
  gint pid;
  gint p[2];

  if (pipe (p) != 0)
    {
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                   "pipe() failed: %s", g_strerror (errno));
      return FALSE;
    }

  /*  open a process group, so killing the plug-in will kill wget too  */
  setpgid (0, 0);

  if ((pid = fork()) < 0)
    {
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                   "fork() failed: %s", g_strerror (errno));
      return FALSE;
    }
  else if (pid == 0)
    {
      gchar timeout_str[16];

      close (p[0]);
      close (2);
      dup (p[1]);
      close (p[1]);

      /* produce deterministic output */
      g_setenv ("LANGUAGE", "C", TRUE);
      g_setenv ("LC_ALL", "C", TRUE);
      g_setenv ("LANG", "C", TRUE);

      g_snprintf (timeout_str, sizeof (timeout_str), "%d", TIMEOUT);

      execlp ("wget",
              "wget", "-v", "-e", "server-response=off", "--progress=dot", "-T", timeout_str,
              uri, "-O", tmpname, NULL);
      _exit (127);
    }
  else
    {
      FILE     *input;
      gchar     buf[BUFSIZE];
      gboolean  seen_resolve = FALSE;
      gboolean  seen_ftp     = FALSE;
      gboolean  connected    = FALSE;
      gboolean  redirect     = FALSE;
      gboolean  file_found   = FALSE;
      gchar     sizestr[37];
      gchar    *endptr;
      guint64   size         = 0;
      gint      i, j;
      gchar     dot;
      guint64   kilobytes    = 0;
      gboolean  finished     = FALSE;
      gboolean  debug        = FALSE;
      gchar    *memsize;
      gchar    *message;
      gchar    *timeout_msg;

#define DEBUG(x) if (debug) g_printerr (x)

      close (p[1]);

      input = fdopen (p[0], "r");

      /*  hardcoded and not-really-foolproof scanning of wget putput  */

    wget_begin:
      /* Eat any Location lines */
      if (redirect && fgets (buf, sizeof (buf), input) == NULL)
        {
          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                       _("wget exited abnormally on URI '%s'"), uri);
          return FALSE;
        }

      redirect = FALSE;

      if (fgets (buf, sizeof (buf), input) == NULL)
        {
          /*  no message here because failing on the first line means
           *  that wget was not found
           */
          return FALSE;
        }

      DEBUG (buf);

      /*  The second line is the local copy of the file  */
      if (fgets (buf, sizeof (buf), input) == NULL)
        {
          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                       _("wget exited abnormally on URI '%s'"), uri);
          return FALSE;
        }
      /* with an ftp url wget has a "=> `filename.foo" */
      else if ( !seen_ftp && strstr (buf, "=> `"))
        {
          seen_ftp = TRUE;
        }

      DEBUG (buf);

      /*  The third line is "Connecting to..."  */

      timeout_msg = g_strdup_printf (ngettext ("(timeout is %d second)",
                                               "(timeout is %d seconds)",
                                               TIMEOUT), TIMEOUT);

      gimp_progress_init_printf ("%s %s",
                                 _("Connecting to server"), timeout_msg);

    read_connect:
      if (fgets (buf, sizeof (buf), input) == NULL)
        {
          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                       _("wget exited abnormally on URI '%s'"), uri);
          return FALSE;
        }
      else if (strstr (buf, "connected"))
        {
          connected = TRUE;
        }
      /* newer wgets have a "Resolving foo" line, so eat it */
      else if (!seen_resolve && strstr (buf, "Resolving"))
        {
          seen_resolve = TRUE;
          goto read_connect;
        }

      DEBUG (buf);

      /*  The fourth line is either the network request or an error  */

      gimp_progress_set_text_printf ("%s %s", _("Opening URI"), timeout_msg);

      if (fgets (buf, sizeof (buf), input) == NULL)
        {
          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                       _("wget exited abnormally on URI '%s'"), uri);
          return FALSE;
        }
      else if (! connected)
        {
          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                       _("A network error occurred: %s"), buf);

          DEBUG (buf);

          return FALSE;
        }
      /* on successful ftp login wget prints a "Logged in" message */
      else if ( seen_ftp && !strstr(buf, "Logged in!"))
        {
          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                       _("A network error occurred: %s"), buf);

          DEBUG (buf);

          return FALSE;
        }
      else if (strstr (buf, "302 Found"))
        {
          DEBUG (buf);

          connected = FALSE;
          seen_resolve = FALSE;

          redirect = TRUE;
          goto wget_begin;
        }

      DEBUG (buf);

      /* for an ftp session wget has extra output*/
    ftp_session:
      if (seen_ftp)
        {
          if (fgets (buf, sizeof (buf), input) == NULL)
            {
              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                           _("A network error occurred: %s"), buf);

              DEBUG (buf);

              return FALSE;
            }
          /* if there is no size output file does not exist on server */
          else if (strstr (buf, "==> SIZE") && strstr (buf, "... done"))
            {
              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                           _("wget exited abnormally on URI '%s'"), uri);

              DEBUG (buf);

              return FALSE;
            }
          /* while no PASV line we eat other messages */
          else if (!strstr (buf, "==> PASV"))
            {
              DEBUG (buf);
              goto ftp_session;
            }
        }

      /*  The fifth line is either the length of the file or an error  */
      if (fgets (buf, sizeof (buf), input) == NULL)
        {
          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                       _("wget exited abnormally on URI '%s'"), uri);
          return FALSE;
        }
      else if (strstr (buf, "Length"))
        {
          file_found = TRUE;
        }
      else
        {
          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                       _("A network error occurred: %s"), buf);

          DEBUG (buf);

          return FALSE;
        }

      DEBUG (buf);

      if (sscanf (buf, "Length: %37s", sizestr) != 1)
        {
          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                       "Could not parse wget's file length message");
          return FALSE;
        }

      /*  strip away commas  */
      for (i = 0, j = 0; i < sizeof (sizestr); i++, j++)
        {
          if (sizestr[i] == ',')
            i++;

          sizestr[j] = sizestr[i];

          if (sizestr[j] == '\0')
            break;
        }

      if (*sizestr != '\0')
        {
          size = g_ascii_strtoull (sizestr, &endptr, 10);

          if (*endptr != '\0' || size == G_MAXUINT64)
            size = 0;
        }

      /* on http sessions wget has "Saving to: ..." */
      if (!seen_ftp)
        {
          if (fgets (buf, sizeof (buf), input) == NULL)
            {
              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                           _("wget exited abnormally on URI '%s'"), uri);

              return FALSE;
            }
        }

      /*  Start the actual download...  */
      if (size > 0)
        {
          memsize = g_format_size_for_display (size);
          message = g_strdup_printf (_("Downloading %s of image data"),
                                     memsize);
        }
      else
        {
          message = g_strdup (_("Downloading unknown amount of image data"));
          memsize = NULL;
        }

      gimp_progress_set_text_printf ("%s %s", message, timeout_msg);

      g_free (message);
      g_free (memsize);

      /*  Switch to byte parsing wget's output...  */

      while (TRUE)
        {
          dot = fgetc (input);

          if (feof (input))
            break;

          if (debug)
            {
              fputc (dot, stderr);
              fflush (stderr);
            }

          if (dot == '.')  /* one kilobyte */
            {
              kilobytes++;

              if (size > 0)
                {
                  gimp_progress_update ((gdouble) (kilobytes * 1024) /
                                        (gdouble) size);
                }
              else
                {
                  memsize = g_format_size_for_display (kilobytes * 1024);

                  gimp_progress_set_text_printf
                    (_("Downloaded %s of image data"), memsize);
                  gimp_progress_pulse ();

                  g_free (memsize);
                }
            }
          else if (dot == ':')  /* the time string contains a ':' */
            {
              fgets (buf, sizeof (buf), input);

              DEBUG (buf);

              if (! strstr (buf, "error"))
                {
                  finished = TRUE;
                  gimp_progress_update (1.0);
                }

              break;
            }
        }

      if (! finished)
        {
          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                       "wget exited before finishing downloading URI\n'%s'",
                       uri);
          return FALSE;
        }
    }

  return TRUE;
}
Ejemplo n.º 6
0
static gint32
load_image (PopplerDocument        *doc,
            const gchar            *filename,
            GimpRunMode             run_mode,
            GimpPageSelectorTarget  target,
            guint32                 resolution,
            PdfSelectedPages       *pages)
{
    gint32   image_ID = 0;
    gint32  *images   = NULL;
    gint     i;
    gdouble  scale;
    gdouble  doc_progress = 0;

    if (target == GIMP_PAGE_SELECTOR_TARGET_IMAGES)
        images = g_new0 (gint32, pages->n_pages);

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

    scale = resolution / gimp_unit_get_factor (GIMP_UNIT_POINT);

    /* read the file */

    for (i = 0; i < pages->n_pages; i++)
    {
        PopplerPage *page;
        gchar       *page_label;
        gdouble      page_width;
        gdouble      page_height;

        GdkPixbuf   *buf;
        gint         width;
        gint         height;

        page = poppler_document_get_page (doc, pages->pages[i]);

        poppler_page_get_size (page, &page_width, &page_height);
        width  = page_width  * scale;
        height = page_height * scale;

        g_object_get (G_OBJECT (page), "label", &page_label, NULL);

        if (! image_ID)
        {
            gchar *name;

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

            if (target == GIMP_PAGE_SELECTOR_TARGET_IMAGES)
                name = g_strdup_printf (_("%s-%s"), filename, page_label);
            else
                name = g_strdup_printf (_("%s-pages"), filename);

            gimp_image_set_filename (image_ID, name);
            g_free (name);

            gimp_image_set_resolution (image_ID, resolution, resolution);
        }

        buf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height);

        poppler_page_render_to_pixbuf (page, 0, 0, width, height, scale, 0, buf);

        layer_from_pixbuf (image_ID, page_label, i, buf,
                           doc_progress, 1.0 / pages->n_pages);

        g_free (page_label);
        g_object_unref (buf);

        doc_progress = (double) (i + 1) / pages->n_pages;
        gimp_progress_update (doc_progress);

        if (target == GIMP_PAGE_SELECTOR_TARGET_IMAGES)
        {
            images[i] = image_ID;

            gimp_image_undo_enable (image_ID);
            gimp_image_clean_all (image_ID);

            image_ID = 0;
        }
    }

    if (image_ID)
    {
        gimp_image_undo_enable (image_ID);
        gimp_image_clean_all (image_ID);
    }

    if (target == GIMP_PAGE_SELECTOR_TARGET_IMAGES)
    {
        if (run_mode != GIMP_RUN_NONINTERACTIVE)
        {
            /* Display images in reverse order.  The last will be
             * displayed by GIMP itself
             */
            for (i = pages->n_pages - 1; i > 0; i--)
                gimp_display_new (images[i]);
        }

        image_ID = images[0];

        g_free (images);
    }

    return image_ID;
}
Ejemplo n.º 7
0
static gint32
load_image (const gchar  *filename,
            gboolean      thumbnail,
            GError      **error)
{
  FILE     *fd;
  guchar    buf[16];
  guchar    c;
  CMap      localColorMap;
  gint      grayScale;
  gboolean  useGlobalColormap;
  gint      bitPixel;
  gint      imageCount = 0;
  gchar     version[4];
  gint32    image_ID = -1;

  fd = g_fopen (filename, "rb");

  if (! fd)
    {
      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;
    }

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

  if (! ReadOK (fd, buf, 6))
    {
      g_message ("Error reading magic number");
      return -1;
    }

  if (strncmp ((gchar *) buf, "GIF", 3) != 0)
    {
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                   "%s", _("This is not a GIF file"));
      return -1;
    }

  strncpy (version, (gchar *) buf + 3, 3);
  version[3] = '\0';

  if ((strcmp (version, "87a") != 0) && (strcmp (version, "89a") != 0))
    {
      g_message ("Bad version number, not '87a' or '89a'");
      return -1;
    }

  if (! ReadOK (fd, buf, 7))
    {
      g_message ("Failed to read screen descriptor");
      return -1;
    }

  GifScreen.Width           = LM_to_uint (buf[0], buf[1]);
  GifScreen.Height          = LM_to_uint (buf[2], buf[3]);
  GifScreen.BitPixel        = 2 << (buf[4] & 0x07);
  GifScreen.ColorResolution = (((buf[4] & 0x70) >> 3) + 1);
  GifScreen.Background      = buf[5];
  GifScreen.AspectRatio     = buf[6];

  if (BitSet (buf[4], LOCALCOLORMAP))
    {
      /* Global Colormap */
      if (! ReadColorMap (fd, GifScreen.BitPixel, GifScreen.ColorMap,
                          &GifScreen.GrayScale))
        {
          g_message ("Error reading global colormap");
          return -1;
        }
    }

  if (GifScreen.AspectRatio != 0 && GifScreen.AspectRatio != 49)
    {
      g_message (_("Non-square pixels.  Image might look squashed."));
    }


  highest_used_index = 0;

  while (TRUE)
    {
      if (! ReadOK (fd, &c, 1))
        {
          g_message ("EOF / read error on image data");
          return image_ID; /* will be -1 if failed on first image! */
        }

      if (c == ';')
        {
          /* GIF terminator */
          return image_ID;
        }

      if (c == '!')
        {
          /* Extension */
          if (! ReadOK (fd, &c, 1))
            {
              g_message ("EOF / read error on extension function code");
              return image_ID; /* will be -1 if failed on first image! */
            }

          DoExtension (fd, c);
          continue;
        }

      if (c != ',')
        {
          /* Not a valid start character */
          g_printerr ("GIF: bogus character 0x%02x, ignoring.\n", (int) c);
          continue;
        }

      ++imageCount;

      if (! ReadOK (fd, buf, 9))
        {
          g_message ("Couldn't read left/top/width/height");
          return image_ID; /* will be -1 if failed on first image! */
        }

      useGlobalColormap = !BitSet (buf[8], LOCALCOLORMAP);

      bitPixel = 1 << ((buf[8] & 0x07) + 1);

      if (! useGlobalColormap)
        {
          if (! ReadColorMap (fd, bitPixel, localColorMap, &grayScale))
            {
              g_message ("Error reading local colormap");
              return image_ID; /* will be -1 if failed on first image! */
            }

          image_ID = ReadImage (fd, filename, LM_to_uint (buf[4], buf[5]),
                                LM_to_uint (buf[6], buf[7]),
                                localColorMap, bitPixel,
                                grayScale,
                                BitSet (buf[8], INTERLACE), imageCount,
                                (guint) LM_to_uint (buf[0], buf[1]),
                                (guint) LM_to_uint (buf[2], buf[3]),
                                GifScreen.Width,
                                GifScreen.Height);
        }
      else
        {
          image_ID = ReadImage (fd, filename, LM_to_uint (buf[4], buf[5]),
                                LM_to_uint (buf[6], buf[7]),
                                GifScreen.ColorMap, GifScreen.BitPixel,
                                GifScreen.GrayScale,
                                BitSet (buf[8], INTERLACE), imageCount,
                                (guint) LM_to_uint (buf[0], buf[1]),
                                (guint) LM_to_uint (buf[2], buf[3]),
                                GifScreen.Width,
                                GifScreen.Height);
        }

      if (comment_parasite != NULL)
        {
          if (! thumbnail)
            gimp_image_attach_parasite (image_ID, comment_parasite);

          gimp_parasite_free (comment_parasite);
          comment_parasite = NULL;
        }

      /* If we are loading a thumbnail, we stop after the first frame. */
      if (thumbnail)
        break;
    }

  return image_ID;
}
Ejemplo n.º 8
0
static gint32
webpage_capture (void)
{
  gint32 image = -1;
  gchar *scheme;
  GtkWidget *window;
  GtkWidget *view;
  WebKitWebSettings *settings;
  char *ua_old;
  char *ua;

  if (webpagevals.pixbuf)
    {
      g_object_unref (webpagevals.pixbuf);
      webpagevals.pixbuf = NULL;
    }
  if (webpagevals.error)
    {
      g_error_free (webpagevals.error);
      webpagevals.error = NULL;
    }

  if ((!webpagevals.url) ||
      (strlen (webpagevals.url) == 0))
    {
      g_set_error (&webpagevals.error, 0, 0, _("No URL was specified"));
      return -1;
    }

  scheme = g_uri_parse_scheme (webpagevals.url);
  if (!scheme)
    {
      char *url;

      /* If we were not given a well-formed URL, make one. */

      url = g_strconcat ("http://", webpagevals.url, NULL);
      g_free (webpagevals.url);
      webpagevals.url = url;

      g_free (scheme);
    }

  if (webpagevals.width < 32)
    {
      g_warning ("Width '%d' is too small. Clamped to 32.",
                 webpagevals.width);
      webpagevals.width = 32;
    }
  else if (webpagevals.width > 8192)
    {
      g_warning ("Width '%d' is too large. Clamped to 8192.",
                 webpagevals.width);
      webpagevals.width = 8192;
    }

  window = gtk_offscreen_window_new ();
  gtk_widget_show (window);

  view = webkit_web_view_new ();
  gtk_widget_show (view);

  gtk_widget_set_size_request (view, webpagevals.width, -1);
  gtk_container_add (GTK_CONTAINER (window), view);

  /* Append "GIMP/<GIMP_VERSION>" to the user agent string */
  settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (view));
  g_object_get (settings,
                "user-agent", &ua_old,
                NULL);
  ua = g_strdup_printf ("%s GIMP/%s", ua_old, GIMP_VERSION);
  g_object_set (settings,
                "user-agent", ua,
                NULL);
  g_free (ua_old);
  g_free (ua);

  /* Set font size */
  g_object_set (settings,
                "default-font-size", webpagevals.font_size,
                NULL);

  g_signal_connect (view, "notify::progress",
                    G_CALLBACK (notify_progress_cb),
                    window);
  g_signal_connect (view, "load-error",
                    G_CALLBACK (load_error_cb),
                    window);
  g_signal_connect (view, "notify::load-status",
                    G_CALLBACK (notify_load_status_cb),
                    window);

  gimp_progress_init_printf (_("Downloading webpage '%s'"), webpagevals.url);

  webkit_web_view_open (WEBKIT_WEB_VIEW (view),
                        webpagevals.url);

  gtk_main ();

  gtk_widget_destroy (window);

  gimp_progress_update (1.0);

  if (webpagevals.pixbuf)
    {
      gint width;
      gint height;
      gint32 layer;

      gimp_progress_init_printf (_("Transferring webpage image for '%s'"),
                                 webpagevals.url);

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

      image = gimp_image_new (width, height, GIMP_RGB);

      gimp_image_undo_disable (image);
      layer = gimp_layer_new_from_pixbuf (image, _("Webpage"), webpagevals.pixbuf,
                                          100, GIMP_NORMAL_MODE, 0.0, 1.0);
      gimp_image_insert_layer (image, layer, -1, 0);
      gimp_image_undo_enable (image);

      g_object_unref (webpagevals.pixbuf);
      webpagevals.pixbuf = NULL;

      gimp_progress_update (1.0);
    }

  return image;
}
Ejemplo n.º 9
0
static gboolean
copy_uri (const gchar  *src_uri,
          const gchar  *dest_uri,
          const gchar  *copying_format_str,
          const gchar  *copied_format_str,
          GError      **error)
{
  GnomeVFSHandle   *read_handle;
  GnomeVFSHandle   *write_handle;
  GnomeVFSFileInfo *src_info;
  GnomeVFSFileSize  file_size  = 0;
  GnomeVFSFileSize  bytes_read = 0;
  guchar            buffer[BUFSIZE];
  GnomeVFSResult    result;
  gchar            *memsize;
  GTimeVal          last_time = { 0, 0 };

  gimp_progress_init (_("Connecting to server"));

  src_info = gnome_vfs_file_info_new ();
  result = gnome_vfs_get_file_info (src_uri, src_info, 0);

  /*  ignore errors here, they will be noticed below  */
  if (result == GNOME_VFS_OK &&
      (src_info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE))
    {
      file_size = src_info->size;
    }

  gnome_vfs_file_info_unref (src_info);

  result = gnome_vfs_open (&read_handle, src_uri, GNOME_VFS_OPEN_READ);

  if (result != GNOME_VFS_OK)
    {
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                   _("Could not open '%s' for reading: %s"),
                   src_uri, gnome_vfs_result_to_string (result));
      return FALSE;
    }

  result = gnome_vfs_create (&write_handle, dest_uri,
                             GNOME_VFS_OPEN_WRITE, FALSE, 0644);

  if (result != GNOME_VFS_OK)
    {
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                   _("Could not open '%s' for writing: %s"),
                   dest_uri, gnome_vfs_result_to_string (result));
      gnome_vfs_close (read_handle);
      return FALSE;
    }

  memsize = g_format_size_for_display (file_size);

  gimp_progress_init_printf (file_size > 0 ?
                             copying_format_str : copied_format_str,
                             memsize);

  g_free (memsize);

  while (TRUE)
    {
      GnomeVFSFileSize  chunk_read;
      GnomeVFSFileSize  chunk_written;
      GTimeVal          now;

      result = gnome_vfs_read (read_handle, buffer, sizeof (buffer),
                               &chunk_read);

      if (chunk_read == 0)
        {
          if (result != GNOME_VFS_ERROR_EOF)
            {
              memsize = g_format_size_for_display (sizeof (buffer));
              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                           _("Failed to read %s from '%s': %s"),
                           memsize, src_uri,
                           gnome_vfs_result_to_string (result));
              g_free (memsize);

              gnome_vfs_close (read_handle);
              gnome_vfs_close (write_handle);
              return FALSE;
            }
          else
            {
              gimp_progress_update (1.0);
              break;
            }
        }

      bytes_read += chunk_read;

      /*  update the progress only up to 10 times a second  */

      g_get_current_time (&now);

      if (((now.tv_sec - last_time.tv_sec) * 1000 +
           (now.tv_usec - last_time.tv_usec) / 1000) > 100)
        {
          if (file_size > 0)
            {
              gimp_progress_update ((gdouble) bytes_read / (gdouble) file_size);
            }
          else
            {
              memsize = g_format_size_for_display (bytes_read);

              gimp_progress_set_text_printf (copied_format_str, memsize);
              gimp_progress_pulse ();

              g_free (memsize);
            }

          last_time = now;
        }

      result = gnome_vfs_write (write_handle, buffer, chunk_read,
                                &chunk_written);

      if (chunk_written < chunk_read)
        {
          memsize = g_format_size_for_display (chunk_read);
          g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                       _("Failed to write %s to '%s': %s"),
                       memsize, dest_uri,
                       gnome_vfs_result_to_string (result));
          g_free (memsize);

          gnome_vfs_close (read_handle);
          gnome_vfs_close (write_handle);
          return FALSE;
        }
    }

  gnome_vfs_close (read_handle);
  gnome_vfs_close (write_handle);

  return TRUE;
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
0
static GimpPDBStatusType plt_save(gchar *filename, gint32 image_id)
{
    FILE *stream = 0;
    unsigned int i, j;

    uint8_t  plt_version[8] = PLT_HEADER_VERSION;
    uint8_t  plt_info[8]    = {10, 0, 0, 0, 0, 0, 0, 0};
    uint32_t plt_width  = 0;
    uint32_t plt_height = 0;

    uint8_t *buffer;
    uint8_t *pixel;
    uint32_t num_px = 0;

    GimpImageBaseType img_basetype;
    gint img_num_layers; // num layers in image
    gint *img_layer_ids; // all layers in image
    gint32 layer_id;
    gint *plt_layer_ids;
    gint max_layer_id;
    gint32 detected_plt_layers = 0;
    gint x, y;

    gint num_channels; // Channels in image

    // Only get image data if it's valid
    if (!gimp_image_is_valid(image_id))
    {
        g_message("Invalid image.\n");
        return (GIMP_PDB_EXECUTION_ERROR);
    }
    plt_width  = gimp_image_width(image_id);
    plt_height = gimp_image_height(image_id);
    img_basetype = gimp_image_base_type(image_id);

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


    img_layer_ids = gimp_image_get_layers(image_id, &img_num_layers);
    if (img_num_layers < PLT_NUM_LAYERS)
    {
        g_message("Requires an image with at least 10 layers.\n");
        g_free(img_layer_ids);
        return (GIMP_PDB_EXECUTION_ERROR);
    }

    max_layer_id  = -1;
    for (i = 0; i < img_num_layers; i++)
    {
        if (img_layer_ids[i] > max_layer_id)
        {
            max_layer_id = img_layer_ids[i];
        }
    }

    // Try to find the 10 plt layers by looking for matching layer names
    plt_layer_ids = g_malloc(sizeof(gint)*max_layer_id);
    for (i = 0; i < max_layer_id; i++)
    {
        plt_layer_ids[i] = -1;
    }
    for (i = 0; i < PLT_NUM_LAYERS; i++)
    {
        for (j = 0; j < img_num_layers; j++)
        {
            if (!g_ascii_strcasecmp(plt_layernames[i], gimp_item_get_name(img_layer_ids[j])))
            {
                plt_layer_ids[img_layer_ids[j]] = i;
                detected_plt_layers++;
                break;
            }
        }
    }
    // If we can't find the layers by name, use the 10 topmost layers instead
    // (Interpreted as tattoo2, tattoo1, ... from the top)
    if (detected_plt_layers < PLT_NUM_LAYERS)
    {
        for (i = 0; i < PLT_NUM_LAYERS; i++)
        {
            plt_layer_ids[img_layer_ids[i]] = PLT_NUM_LAYERS-i-1;
        }
    }

    // Write image data to buffer
    num_px = plt_width * plt_height;
    buffer = (uint8_t*) g_malloc(sizeof(uint8_t)*2*num_px);
    switch(img_basetype)
    {
        case GIMP_GRAY:
        {
            // Gray Image
            // >= 1 channels: value (+ alpha). We ignore alpha though, so it
            // doesn't matter wether its present or not.
            for (i = 0; i < num_px; i++)
            {
                x = (gint)(i % plt_width);
                y = plt_height - (gint)(floor(i / plt_width)) - 1;
                layer_id = gimp_image_pick_correlate_layer(image_id, x, y);
                if ((layer_id >= 0) && (plt_layer_ids[layer_id] >= 0))
                {
                    pixel = gimp_drawable_get_pixel(layer_id,
                                                    x,
                                                    y,
                                                    &num_channels);
                    buffer[2*i]   = pixel[0];
                    buffer[2*i+1] = plt_layer_ids[layer_id];
                }
                else
                {
                    buffer[2*i]   = 255;
                    buffer[2*i+1] = 0;
                }
                gimp_progress_update((float) i/ (float) num_px);
            }
            break;
        }
        case GIMP_RGB:
        {
            // RGB Image
            // >= 3 channels: r +g + b (+ alpha). We ignore alpha though, so it
            // doesn't matter wether its present or not.
            // We'll calculate gray value with (r+g+b)/3.
            for (i = 0; i < num_px; i++)
            {
                x = (gint)(i % plt_width);
                y = plt_height - (gint)(floor(i / plt_width)) - 1;
                layer_id = gimp_image_pick_correlate_layer(image_id, x, y);
                if ((layer_id >= 0) && (plt_layer_ids[layer_id] >= 0))
                {
                    pixel = gimp_drawable_get_pixel(layer_id,
                                                    x,
                                                    y,
                                                    &num_channels);
                    buffer[2*i]   = pixel[0];
                    buffer[2*i+1] = plt_layer_ids[layer_id];
                }
                else
                {
                    buffer[2*i]   = 255;
                    buffer[2*i+1] = 0;
                }
                gimp_progress_update((float) i/ (float) num_px);
            }
            break;
        }
        case GIMP_INDEXED: // You're out of luck buddy
        default:
        {
            g_message("Image type has to be Grayscale or RGB.\n");
            g_free(buffer);
            g_free(img_layer_ids);
            g_free(plt_layer_ids);
            return (GIMP_PDB_EXECUTION_ERROR);
        }
    }
    gimp_progress_update(1.0);

    stream = fopen(filename, "wb");
    if (stream == 0)
    {
        g_message("Error opening %s\n", filename);
        g_free(buffer);
        g_free(img_layer_ids);
        g_free(plt_layer_ids);
        return (GIMP_PDB_EXECUTION_ERROR);
    }

    // Write header
    fwrite(plt_version, 1, 8, stream);
    fwrite(plt_info, 1, 8, stream);
    fwrite(&plt_width, 4, 1, stream);
    fwrite(&plt_height, 4, 1, stream);

    // Write image data
    fwrite(buffer, 1, 2*num_px, stream);

    fclose(stream);

    g_free(buffer);
    g_free(img_layer_ids);
    g_free(plt_layer_ids);

    return (GIMP_PDB_SUCCESS);
}
Ejemplo n.º 13
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);
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
static void
run (const gchar      *name,
     gint              nparams,
     const GimpParam  *param,
     gint             *nreturn_vals,
     GimpParam       **return_vals)
{
  GimpDrawable      *drawable;
  GimpRunMode        run_mode;
  GimpPDBStatusType  status = GIMP_PDB_SUCCESS;        /* assume the best! */
  static GimpParam   values[1];

  INIT_I18N ();

  /*
   *  Get the specified drawable, do standard initialization.
   */
  if (strcmp (name, PLUG_IN_PROC[0]) == 0)
    rndm_type = RNDM_HURL;
  else if (strcmp (name, PLUG_IN_PROC[1]) == 0)
    rndm_type = RNDM_PICK;
  else if (strcmp (name, PLUG_IN_PROC[2]) == 0)
    rndm_type = RNDM_SLUR;

  run_mode = param[0].data.d_int32;
  drawable = gimp_drawable_get(param[2].data.d_drawable);

  *nreturn_vals = 1;
  *return_vals  = values;

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

  gr = g_rand_new ();
  /*
   *  Make sure the drawable type is appropriate.
   */
  if (gimp_drawable_is_rgb (drawable->drawable_id)  ||
      gimp_drawable_is_gray (drawable->drawable_id) ||
      gimp_drawable_is_indexed (drawable->drawable_id))
    {
      gimp_tile_cache_ntiles (2 * drawable->ntile_cols);

      switch (run_mode)
        {
          /*
           *  If we're running interactively, pop up the dialog box.
           */
        case GIMP_RUN_INTERACTIVE:
          gimp_get_data (PLUG_IN_PROC[rndm_type - 1], &pivals);

          if (! randomize_dialog (drawable)) /* return on Cancel */
            return;
          break;
          /*
           *  If we're not interactive (probably scripting), we
           *  get the parameters from the param[] array, since
           *  we don't use the dialog box.  Make sure they all
           *  parameters have legitimate values.
           */
        case GIMP_RUN_NONINTERACTIVE:
          if (nparams != 7)
            {
              status = GIMP_PDB_CALLING_ERROR;
            }
          else
            {
              pivals.rndm_pct    = (gdouble) param[3].data.d_float;
              pivals.rndm_rcount = (gdouble) param[4].data.d_float;
              pivals.randomize   = (gboolean) param[5].data.d_int32;
              pivals.seed        = (gint) param[6].data.d_int32;

              if (pivals.randomize)
                pivals.seed = g_random_int ();

              if ((rndm_type != RNDM_PICK &&
                   rndm_type != RNDM_SLUR &&
                   rndm_type != RNDM_HURL) ||
                  (pivals.rndm_pct < 1.0 || pivals.rndm_pct > 100.0) ||
                  (pivals.rndm_rcount < 1.0 || pivals.rndm_rcount > 100.0))
                {
                  status = GIMP_PDB_CALLING_ERROR;
                }
            }
          break;
          /*
           *  If we're running with the last set of values, get those values.
           */
        case GIMP_RUN_WITH_LAST_VALS:
          gimp_get_data (PLUG_IN_PROC[rndm_type - 1], &pivals);

          if (pivals.randomize)
            pivals.seed = g_random_int ();
          break;
          /*
           *  Hopefully we never get here!
           */
        default:
          break;
        }

      if (status == GIMP_PDB_SUCCESS)
        {
          gimp_progress_init_printf ("%s", gettext (RNDM_NAME[rndm_type - 1]));

          /*
           *  Initialize the g_rand() function seed
           */
          g_rand_set_seed (gr, pivals.seed);

          randomize (drawable, NULL);
          /*
           *  If we ran interactively (even repeating) update the display.
           */
          if (run_mode != GIMP_RUN_NONINTERACTIVE)
            {
              gimp_displays_flush ();
            }
          /*
           *  If we use the dialog popup, set the data for future use.
           */
          if (run_mode == GIMP_RUN_INTERACTIVE)
            {
              gimp_set_data (PLUG_IN_PROC[rndm_type - 1], &pivals,
                             sizeof (RandomizeVals));
            }
        }
    }
  else
    {
      /*
       *  If we got the wrong drawable type, we need to complain.
       */
      status = GIMP_PDB_EXECUTION_ERROR;
    }
  /*
   *  DONE!
   *  Set the status where GIMP can see it, and let go
   *  of the drawable.
   */
  g_rand_free (gr);
  values[0].data.d_status = status;
  gimp_drawable_detach(drawable);
}
Ejemplo n.º 16
0
gboolean
save_image (const gchar  *filename,
            gint32        image_ID,
            gint32        drawable_ID,
            gint32        orig_image_ID,
            gboolean      preview,
            GError      **error)
{
  GimpImageType  drawable_type;
  GeglBuffer    *buffer = NULL;
  const Babl    *format;
  GimpParasite  *parasite;
  static struct jpeg_compress_struct cinfo;
  static struct my_error_mgr         jerr;
  JpegSubsampling             subsampling;
  FILE     * volatile outfile;
  guchar   *data;
  guchar   *src;
  gboolean  has_alpha;
  gint      rowstride, yend;

  drawable_type = gimp_drawable_type (drawable_ID);
  buffer = gimp_drawable_get_buffer (drawable_ID);

  if (! preview)
    gimp_progress_init_printf (_("Saving '%s'"),
                               gimp_filename_to_utf8 (filename));

  /* Step 1: allocate and initialize JPEG compression object */

  /* We have to set up the error handler first, in case the initialization
   * step fails.  (Unlikely, but it could happen if you are out of memory.)
   * This routine fills in the contents of struct jerr, and returns jerr's
   * address which we place into the link field in cinfo.
   */
  cinfo.err = jpeg_std_error (&jerr.pub);
  jerr.pub.error_exit = my_error_exit;

  outfile = NULL;
  /* 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_compress (&cinfo);
      if (outfile)
        fclose (outfile);
      if (buffer)
        g_object_unref (buffer);

      return FALSE;
    }

  /* Now we can initialize the JPEG compression object. */
  jpeg_create_compress (&cinfo);

  /* Step 2: specify data destination (eg, a file) */
  /* Note: steps 2 and 3 can be done in either order. */

  /* Here we use the library-supplied code to send compressed data to a
   * stdio stream.  You can also write your own code to do something else.
   * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
   * requires it in order to write binary files.
   */
  if ((outfile = g_fopen (filename, "wb")) == NULL)
    {
      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
                   _("Could not open '%s' for writing: %s"),
                   gimp_filename_to_utf8 (filename), g_strerror (errno));
      return FALSE;
    }

  jpeg_stdio_dest (&cinfo, outfile);

  /* Get the input image and a pointer to its data.
   */
  switch (drawable_type)
    {
    case GIMP_RGB_IMAGE:
      /* # of color components per pixel */
      cinfo.input_components = 3;
      has_alpha = FALSE;
      format = babl_format ("R'G'B' u8");
      break;

    case GIMP_GRAY_IMAGE:
      /* # of color components per pixel */
      cinfo.input_components = 1;
      has_alpha = FALSE;
      format = babl_format ("Y' u8");
      break;

    case GIMP_RGBA_IMAGE:
      /* # of color components per pixel (minus the GIMP alpha channel) */
      cinfo.input_components = 4 - 1;
      has_alpha = TRUE;
      format = babl_format ("R'G'B' u8");
      break;

    case GIMP_GRAYA_IMAGE:
      /* # of color components per pixel (minus the GIMP alpha channel) */
      cinfo.input_components = 2 - 1;
      has_alpha = TRUE;
      format = babl_format ("Y' u8");
      break;

    case GIMP_INDEXED_IMAGE:
    default:
      return FALSE;
    }

  /* Step 3: set parameters for compression */

  /* First we supply a description of the input image.
   * Four fields of the cinfo struct must be filled in:
   */
  /* image width and height, in pixels */
  cinfo.image_width  = gegl_buffer_get_width (buffer);
  cinfo.image_height = gegl_buffer_get_height (buffer);
  /* colorspace of input image */
  cinfo.in_color_space = (drawable_type == GIMP_RGB_IMAGE ||
                          drawable_type == GIMP_RGBA_IMAGE)
    ? JCS_RGB : JCS_GRAYSCALE;
  /* Now use the library's routine to set default compression parameters.
   * (You must set at least cinfo.in_color_space before calling this,
   * since the defaults depend on the source color space.)
   */
  jpeg_set_defaults (&cinfo);

  jpeg_set_quality (&cinfo, (gint) (jsvals.quality + 0.5), jsvals.baseline);

  if (jsvals.use_orig_quality && num_quant_tables > 0)
    {
      guint **quant_tables;
      gint    t;

      /* override tables generated by jpeg_set_quality() with custom tables */
      quant_tables = jpeg_restore_original_tables (image_ID, num_quant_tables);
      if (quant_tables)
        {
          for (t = 0; t < num_quant_tables; t++)
            {
              jpeg_add_quant_table (&cinfo, t, quant_tables[t],
                                    100, jsvals.baseline);
              g_free (quant_tables[t]);
            }
          g_free (quant_tables);
        }
    }

  if (arithc_supported)
    {
      cinfo.arith_code = jsvals.arithmetic_coding;
      if (!jsvals.arithmetic_coding)
        cinfo.optimize_coding = jsvals.optimize;
    }
  else
    cinfo.optimize_coding = jsvals.optimize;

  subsampling = (gimp_drawable_is_rgb (drawable_ID) ?
                 jsvals.subsmp : JPEG_SUBSAMPLING_1x1_1x1_1x1);

  /*  smoothing is not supported with nonstandard sampling ratios  */
  if (subsampling != JPEG_SUBSAMPLING_2x1_1x1_1x1 &&
      subsampling != JPEG_SUBSAMPLING_1x2_1x1_1x1)
    {
      cinfo.smoothing_factor = (gint) (jsvals.smoothing * 100);
    }

  if (jsvals.progressive)
    {
      jpeg_simple_progression (&cinfo);
    }

  switch (subsampling)
    {
    case JPEG_SUBSAMPLING_2x2_1x1_1x1:
    default:
      cinfo.comp_info[0].h_samp_factor = 2;
      cinfo.comp_info[0].v_samp_factor = 2;
      cinfo.comp_info[1].h_samp_factor = 1;
      cinfo.comp_info[1].v_samp_factor = 1;
      cinfo.comp_info[2].h_samp_factor = 1;
      cinfo.comp_info[2].v_samp_factor = 1;
      break;

    case JPEG_SUBSAMPLING_2x1_1x1_1x1:
      cinfo.comp_info[0].h_samp_factor = 2;
      cinfo.comp_info[0].v_samp_factor = 1;
      cinfo.comp_info[1].h_samp_factor = 1;
      cinfo.comp_info[1].v_samp_factor = 1;
      cinfo.comp_info[2].h_samp_factor = 1;
      cinfo.comp_info[2].v_samp_factor = 1;
      break;

    case JPEG_SUBSAMPLING_1x1_1x1_1x1:
      cinfo.comp_info[0].h_samp_factor = 1;
      cinfo.comp_info[0].v_samp_factor = 1;
      cinfo.comp_info[1].h_samp_factor = 1;
      cinfo.comp_info[1].v_samp_factor = 1;
      cinfo.comp_info[2].h_samp_factor = 1;
      cinfo.comp_info[2].v_samp_factor = 1;
      break;

    case JPEG_SUBSAMPLING_1x2_1x1_1x1:
      cinfo.comp_info[0].h_samp_factor = 1;
      cinfo.comp_info[0].v_samp_factor = 2;
      cinfo.comp_info[1].h_samp_factor = 1;
      cinfo.comp_info[1].v_samp_factor = 1;
      cinfo.comp_info[2].h_samp_factor = 1;
      cinfo.comp_info[2].v_samp_factor = 1;
      break;
    }

  cinfo.restart_interval = 0;
  cinfo.restart_in_rows = jsvals.restart;

  switch (jsvals.dct)
    {
    case 0:
    default:
      cinfo.dct_method = JDCT_ISLOW;
      break;

    case 1:
      cinfo.dct_method = JDCT_IFAST;
      break;

    case 2:
      cinfo.dct_method = JDCT_FLOAT;
      break;
    }

  {
    gdouble xresolution;
    gdouble yresolution;

    gimp_image_get_resolution (orig_image_ID, &xresolution, &yresolution);

    if (xresolution > 1e-5 && yresolution > 1e-5)
      {
        gdouble factor;

        factor = gimp_unit_get_factor (gimp_image_get_unit (orig_image_ID));

        if (factor == 2.54 /* cm */ ||
            factor == 25.4 /* mm */)
          {
            cinfo.density_unit = 2;  /* dots per cm */

            xresolution /= 2.54;
            yresolution /= 2.54;
          }
        else
          {
            cinfo.density_unit = 1;  /* dots per inch */
          }

        cinfo.X_density = xresolution;
        cinfo.Y_density = yresolution;
      }
  }

  /* Step 4: Start compressor */

  /* TRUE ensures that we will write a complete interchange-JPEG file.
   * Pass TRUE unless you are very sure of what you're doing.
   */
  jpeg_start_compress (&cinfo, TRUE);

  /* Step 4.1: Write the comment out - pw */
  if (image_comment && *image_comment)
    {
#ifdef GIMP_UNSTABLE
      g_print ("jpeg-save: saving image comment (%d bytes)\n",
               (int) strlen (image_comment));
#endif
      jpeg_write_marker (&cinfo, JPEG_COM,
                         (guchar *) image_comment, strlen (image_comment));
    }

  /* Step 4.2: store the color profile if there is one */
  parasite = gimp_image_get_parasite (orig_image_ID, "icc-profile");
  if (parasite)
    {
      jpeg_icc_write_profile (&cinfo,
                              gimp_parasite_data (parasite),
                              gimp_parasite_data_size (parasite));
      gimp_parasite_free (parasite);
    }

  /* Step 5: while (scan lines remain to be written) */
  /*           jpeg_write_scanlines(...); */

  /* Here we use the library's state variable cinfo.next_scanline as the
   * loop counter, so that we don't have to keep track ourselves.
   * To keep things simple, we pass one scanline per call; you can pass
   * more if you wish, though.
   */
  /* JSAMPLEs per row in image_buffer */
  rowstride = cinfo.input_components * cinfo.image_width;
  data = g_new (guchar, rowstride * gimp_tile_height ());

  /* fault if cinfo.next_scanline isn't initially a multiple of
   * gimp_tile_height */
  src = NULL;

  /*
   * sg - if we preview, we want this to happen in the background -- do
   * not duplicate code in the future; for now, it's OK
   */

  if (preview)
    {
      PreviewPersistent *pp = g_new (PreviewPersistent, 1);

      /* pass all the information we need */
      pp->cinfo       = cinfo;
      pp->tile_height = gimp_tile_height();
      pp->data        = data;
      pp->outfile     = outfile;
      pp->has_alpha   = has_alpha;
      pp->rowstride   = rowstride;
      pp->data        = data;
      pp->buffer      = buffer;
      pp->format      = format;
      pp->src         = NULL;
      pp->file_name   = filename;
      pp->abort_me    = FALSE;

      g_warn_if_fail (prev_p == NULL);
      prev_p = pp;

      pp->cinfo.err = jpeg_std_error(&(pp->jerr));
      pp->jerr.error_exit = background_error_exit;

      gtk_label_set_text (GTK_LABEL (preview_size),
                          _("Calculating file size..."));

      pp->source_id = g_idle_add ((GSourceFunc) background_jpeg_save, pp);

      /* background_jpeg_save() will cleanup as needed */
      return TRUE;
    }

  while (cinfo.next_scanline < cinfo.image_height)
    {
      if ((cinfo.next_scanline % gimp_tile_height ()) == 0)
        {
          yend = cinfo.next_scanline + gimp_tile_height ();
          yend = MIN (yend, cinfo.image_height);
          gegl_buffer_get (buffer,
                           GEGL_RECTANGLE (0, cinfo.next_scanline,
                                           cinfo.image_width,
                                           (yend - cinfo.next_scanline)),
                           1.0,
                           format,
                           data,
                           GEGL_AUTO_ROWSTRIDE,
                           GEGL_ABYSS_NONE);
          src = data;
        }

      jpeg_write_scanlines (&cinfo, (JSAMPARRAY) &src, 1);
      src += rowstride;

      if ((cinfo.next_scanline % 32) == 0)
        gimp_progress_update ((gdouble) cinfo.next_scanline /
                              (gdouble) cinfo.image_height);
    }

  /* Step 6: Finish compression */
  jpeg_finish_compress (&cinfo);
  /* After finish_compress, we can close the output file. */
  fclose (outfile);

  /* Step 7: release JPEG compression object */

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

  /* free the temporary buffer */
  g_free (data);

  /* And we're done! */
  gimp_progress_update (1.0);

  g_object_unref (buffer);

  return TRUE;
}
Ejemplo n.º 17
0
static gboolean
save_image (const gchar  *filename,
            GeglBuffer   *buffer,
            GError      **error)
{
  const Babl *format = babl_format ("R'G'B'A u8");
  gint        row, col, cols, rows, x, y;
  gint        colcount, colspan, rowspan;
  gint       *palloc;
  guchar     *buf, *buf2;
  gchar      *width, *height;
  FILE       *fp;

  cols = gegl_buffer_get_width  (buffer);
  rows = gegl_buffer_get_height (buffer);

  fp = g_fopen (filename, "w");

  if (! fp)
    {
      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
                   _("Could not open '%s' for writing: %s"),
                   gimp_filename_to_utf8 (filename), g_strerror (errno));
      return FALSE;
    }

  palloc = g_new (int, rows * cols);

  if (gtmvals.fulldoc)
    {
      fprintf (fp, "<HTML>\n<HEAD><TITLE>%s</TITLE></HEAD>\n<BODY>\n",
               filename);
      fprintf (fp, "<H1>%s</H1>\n",
               filename);
    }

  fprintf (fp, "<TABLE BORDER=%d CELLPADDING=%d CELLSPACING=%d>\n",
           gtmvals.border, gtmvals.cellpadding, gtmvals.cellspacing);

  if (gtmvals.caption)
    fprintf (fp, "<CAPTION>%s</CAPTION>\n",
             gtmvals.captiontxt);

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

  buf  = g_new (guchar, babl_format_get_bytes_per_pixel (format));
  buf2 = g_new (guchar, babl_format_get_bytes_per_pixel (format));

  width = height = NULL;

  if (strcmp (gtmvals.clwidth, "") != 0)
    {
      width = g_strdup_printf (" WIDTH=\"%s\"", gtmvals.clwidth);
    }

  if (strcmp (gtmvals.clheight, "") != 0)
    {
      height = g_strdup_printf (" HEIGHT=\"%s\" ", gtmvals.clheight);
    }

  if (! width)
    width = g_strdup (" ");

  if (! height)
    height = g_strdup (" ");

  /* Initialize array to hold ROWSPAN and COLSPAN cell allocation table */

  for (row = 0; row < rows; row++)
    for (col = 0; col < cols; col++)
      palloc[cols * row + col] = 1;

  colspan = 0;
  rowspan = 0;

  for (y = 0; y < rows; y++)
    {
      fprintf (fp,"   <TR>\n");

      for (x = 0; x < cols; x++)
        {
          gegl_buffer_sample (buffer, x, y, NULL, buf, format,
                              GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);

          /* Determine ROWSPAN and COLSPAN */

          if (gtmvals.spantags)
            {
              col      = x;
              row      = y;
              colcount = 0;
              colspan  = 0;
              rowspan  = 0;

              gegl_buffer_sample (buffer, col, row, NULL, buf2, format,
                                  GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);

              while (color_comp (buf, buf2) &&
                     palloc[cols * row + col] == 1 &&
                     row < rows)
                {
                  while (color_comp (buf, buf2) &&
                         palloc[cols * row + col] == 1 &&
                         col < cols)
                    {
                      colcount++;
                      col++;

                      gegl_buffer_sample (buffer, col, row, NULL, buf2, format,
                                          GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
                    }

                  if (colcount != 0)
                    {
                      row++;
                      rowspan++;
                    }

                  if (colcount < colspan || colspan == 0)
                    colspan = colcount;

                  col = x;
                  colcount = 0;

                  gegl_buffer_sample (buffer, col, row, NULL, buf2, format,
                                      GEGL_SAMPLER_NEAREST, GEGL_ABYSS_NONE);
                }

              if (colspan > 1 || rowspan > 1)
                {
                  for (row = 0; row < rowspan; row++)
                    for (col = 0; col < colspan; col++)
                      palloc[cols * (row + y) + (col + x)] = 0;

                  palloc[cols * y + x] = 2;
                }
            }

          if (palloc[cols * y + x] == 1)
            fprintf (fp, "      <TD%s%sBGCOLOR=#%02x%02x%02x>",
                     width, height, buf[0], buf[1], buf[2]);

          if (palloc[cols * y + x] == 2)
            fprintf (fp,"      <TD ROWSPAN=\"%d\" COLSPAN=\"%d\"%s%sBGCOLOR=#%02x%02x%02x>",
                     rowspan, colspan, width, height,
                     buf[0], buf[1], buf[2]);

          if (palloc[cols * y + x] != 0)
            {
              if (gtmvals.tdcomp)
                fprintf (fp, "%s</TD>\n", gtmvals.cellcontent);
              else
                fprintf (fp, "\n      %s\n      </TD>\n", gtmvals.cellcontent);
            }
        }

      fprintf (fp,"   </TR>\n");

      gimp_progress_update ((double) y / (double) rows);
    }

  gimp_progress_update (1.0);

  if (gtmvals.fulldoc)
    fprintf (fp, "</TABLE></BODY></HTML>\n");
  else
    fprintf (fp, "</TABLE>\n");

  fclose (fp);
  g_free (width);
  g_free (height);
  g_free (palloc);

  return TRUE;
}
Ejemplo n.º 18
0
/* 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;
}
Ejemplo n.º 19
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;
}
Ejemplo n.º 20
0
GimpPDBStatusType
ico_save_image (const gchar  *filename,
                gint32        image,
                gint32        run_mode,
                GError      **error)
{
  FILE *fp;

  gint i;
  gint width, height;
  IcoSaveInfo      info;
  IcoFileHeader    header;
  IcoFileEntry    *entries;
  gboolean          saved;

  D(("*** Saving Microsoft icon file %s\n", filename));

  ico_save_init (image, &info);

  if (run_mode == GIMP_RUN_INTERACTIVE)
    {
      /* Allow user to override default values */
      if ( !ico_save_dialog (image, &info))
        return GIMP_PDB_CANCEL;
    }

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

  if (! (fp = g_fopen (filename, "wb")))
    {
      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
                   _("Could not open '%s' for writing: %s"),
                   gimp_filename_to_utf8 (filename), g_strerror (errno));
      return GIMP_PDB_EXECUTION_ERROR;
    }

  header.reserved = 0;
  header.resource_type = 1;
  header.icon_count = info.num_icons;
  if ( !ico_write_int16 (fp, &header.reserved, 1)
       || !ico_write_int16 (fp, &header.resource_type, 1)
       || !ico_write_int16 (fp, &header.icon_count, 1) )
    {
      ico_save_info_free (&info);
      fclose (fp);
      return GIMP_PDB_EXECUTION_ERROR;
    }

  entries = g_new0 (IcoFileEntry, info.num_icons);
  if (fwrite (entries, sizeof (IcoFileEntry), info.num_icons, fp) <= 0)
    {
      ico_save_info_free (&info);
      g_free (entries);
      fclose (fp);
      return GIMP_PDB_EXECUTION_ERROR;
    }

  for (i = 0; i < info.num_icons; i++)
    {
      gimp_progress_update ((gdouble)i / (gdouble)info.num_icons);

      width = gimp_drawable_width (info.layers[i]);
      height = gimp_drawable_height (info.layers[i]);
      if (width <= 255 && height <= 255)
        {
          entries[i].width = width;
          entries[i].height = height;
        }
      else
        {
          entries[i].width = 0;
          entries[i].height = 0;
        }
      if ( info.depths[i] <= 8 )
        entries[i].num_colors = 1 << info.depths[i];
      else
        entries[i].num_colors = 0;
      entries[i].reserved = 0;
      entries[i].planes = 1;
      entries[i].bpp = info.depths[i];
      entries[i].offset = ftell (fp);

      if (info.compress[i])
        saved = ico_write_png (fp, info.layers[i], info.depths[i]);
      else
        saved = ico_write_icon (fp, info.layers[i], info.depths[i]);

      if (!saved)
        {
          ico_save_info_free (&info);
          fclose (fp);
          return GIMP_PDB_EXECUTION_ERROR;
        }

      entries[i].size = ftell (fp) - entries[i].offset;
    }

  for (i = 0; i < info.num_icons; i++)
    {
      entries[i].planes = GUINT16_TO_LE (entries[i].planes);
      entries[i].bpp    = GUINT16_TO_LE (entries[i].bpp);
      entries[i].size   = GUINT32_TO_LE (entries[i].size);
      entries[i].offset = GUINT32_TO_LE (entries[i].offset);
    }

  if (fseek (fp, sizeof(IcoFileHeader), SEEK_SET) < 0
      || fwrite (entries, sizeof (IcoFileEntry), info.num_icons, fp) <= 0)
    {
      ico_save_info_free (&info);
      fclose (fp);
      return GIMP_PDB_EXECUTION_ERROR;
    }

  gimp_progress_update (1.0);

  ico_save_info_free (&info);
  fclose (fp);
  g_free (entries);

  return GIMP_PDB_SUCCESS;
}
Ejemplo n.º 21
0
static gboolean
lcms_image_apply_profile (gint32                    image,
                          cmsHPROFILE               src_profile,
                          cmsHPROFILE               dest_profile,
                          const gchar              *filename,
                          GimpColorRenderingIntent  intent,
                          gboolean                  bpc)
{
  gint32 saved_selection = -1;

  gimp_image_undo_group_start (image);

  if (! lcms_image_set_profile (image, dest_profile, filename, FALSE))
    {
      gimp_image_undo_group_end (image);

      return FALSE;
    }

  {
    gchar  *src  = lcms_icc_profile_get_desc (src_profile);
    gchar  *dest = lcms_icc_profile_get_desc (dest_profile);

      /* ICC color profile conversion */
      gimp_progress_init_printf (_("Converting from '%s' to '%s'"), src, dest);

      g_printerr ("lcms: converting from '%s' to '%s'\n", src, dest);

      g_free (dest);
      g_free (src);
  }

  if (! gimp_selection_is_empty (image))
    {
      saved_selection = gimp_selection_save (image);
      gimp_selection_none (image);
    }

  switch (gimp_image_base_type (image))
    {
    case GIMP_RGB:
      lcms_image_transform_rgb (image,
                                src_profile, dest_profile, intent, bpc);
      break;

    case GIMP_GRAY:
      g_warning ("colorspace conversion not implemented for "
                 "grayscale images");
      break;

    case GIMP_INDEXED:
      lcms_image_transform_indexed (image,
                                    src_profile, dest_profile, intent, bpc);
      break;
    }

  if (saved_selection != -1)
    {
      gimp_image_select_item (image, GIMP_CHANNEL_OP_REPLACE, saved_selection);
      gimp_image_remove_channel (image, saved_selection);
    }

  gimp_progress_update (1.0);

  gimp_image_undo_group_end (image);

  return TRUE;
}
Ejemplo n.º 22
0
static gint32
webpage_capture (void)
{
  gchar *scheme;
  GtkWidget *window;
  GtkWidget *view;
  WebKitSettings *settings;
  char *ua;

  if ((!webpagevals.url) ||
      (strlen (webpagevals.url) == 0))
    {
      g_set_error (&webpagevals.error, 0, 0, _("No URL was specified"));
      return -1;
    }

  scheme = g_uri_parse_scheme (webpagevals.url);
  if (!scheme)
    {
      char *url;

      /* If we were not given a well-formed URL, make one. */

      url = g_strconcat ("http://", webpagevals.url, NULL);
      g_free (webpagevals.url);
      webpagevals.url = url;

      g_free (scheme);
    }

  if (webpagevals.width < 32)
    {
      g_warning ("Width '%d' is too small. Clamped to 32.",
                 webpagevals.width);
      webpagevals.width = 32;
    }
  else if (webpagevals.width > 8192)
    {
      g_warning ("Width '%d' is too large. Clamped to 8192.",
                 webpagevals.width);
      webpagevals.width = 8192;
    }

  window = gtk_offscreen_window_new ();
  gtk_widget_show (window);

  view = webkit_web_view_new ();
  gtk_widget_show (view);

  gtk_widget_set_vexpand (view, TRUE);
  gtk_widget_set_size_request (view, webpagevals.width, -1);
  gtk_container_add (GTK_CONTAINER (window), view);

  /* Append "GIMP/<GIMP_VERSION>" to the user agent string */
  settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (view));
  ua = g_strdup_printf ("%s GIMP/%s",
                        webkit_settings_get_user_agent (settings),
                        GIMP_VERSION);
  webkit_settings_set_user_agent (settings, ua);
  g_free (ua);

  /* Set font size */
  webkit_settings_set_default_font_size (settings, webpagevals.font_size);

  g_signal_connect (view, "notify::estimated-load-progress",
                    G_CALLBACK (notify_progress_cb),
                    window);
  g_signal_connect (view, "load-failed",
                    G_CALLBACK (load_failed_cb),
                    window);
  g_signal_connect (view, "load-changed",
                    G_CALLBACK (load_changed_cb),
                    window);

  gimp_progress_init_printf (_("Downloading webpage '%s'"), webpagevals.url);

  webkit_web_view_load_uri (WEBKIT_WEB_VIEW (view),
                            webpagevals.url);

  gtk_main ();

  gtk_widget_destroy (window);

  gimp_progress_update (1.0);

  return webpagevals.image;
}
Ejemplo n.º 23
0
/*
 * 'load_image()' - Load a WMF image into a new image window.
 */
static gint32
load_image (const gchar  *filename,
            GError      **error)
{
  gint32        image;
  gint32        layer;
  GimpDrawable *drawable;
  guchar       *pixels;
  GimpPixelRgn  pixel_rgn;
  guint         width, height;
  guint         rowstride;
  guint         count = 0;
  guint         done  = 0;
  gpointer      pr;

  pixels = wmf_load_file (filename, &width, &height, error);

  if (! pixels)
    return -1;

  rowstride = width * 4;

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

  image = gimp_image_new (width, height, GIMP_RGB);
  gimp_image_set_filename (image, filename);
  gimp_image_set_resolution (image,
                             load_vals.resolution, load_vals.resolution);

  layer = gimp_layer_new (image,
                          _("Rendered WMF"),
                          width, height,
                          GIMP_RGBA_IMAGE, 100, GIMP_NORMAL_MODE);

  drawable = gimp_drawable_get (layer);

  gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, width, height, TRUE, FALSE);

  for (pr = gimp_pixel_rgns_register (1, &pixel_rgn);
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr))
    {
      const guchar *src  = pixels + pixel_rgn.y * rowstride + pixel_rgn.x * 4;
      guchar       *dest = pixel_rgn.data;
      gint          y;

      for (y = 0; y < pixel_rgn.h; y++)
        {
          memcpy (dest, src, pixel_rgn.w * pixel_rgn.bpp);

          src  += rowstride;
          dest += pixel_rgn.rowstride;
        }

      done += pixel_rgn.h * pixel_rgn.w;

      if (count++ % 16 == 0)
        gimp_progress_update ((gdouble) done / (width * height));
    }

  g_free (pixels);

  gimp_drawable_detach (drawable);

  gimp_progress_update (1.0);

  /* Tell GIMP to display the image.
   */
  gimp_image_insert_layer (image, layer, -1, 0);
  gimp_drawable_flush (drawable);

  return image;
}
Ejemplo n.º 24
0
/* Save a WebP image to disk */
gboolean save_image(const gchar    *filename,
#ifdef WEBP_0_5
                    gint32          nLayers,
                    gint32         *allLayers,
#endif
                    gint32          drawable_ID,
                    WebPSaveParams *params,
                    GError        **error)
{
    gboolean status  = FALSE;
    FILE    *outfile = NULL;

#ifdef GIMP_2_9
    /* Initialize GEGL */
    gegl_init(NULL, NULL);
#endif

    /* Begin displaying export progress */
    gimp_progress_init_printf("Saving '%s'",
                              gimp_filename_to_utf8(filename));

    /* Attempt to open the output file */
    if((outfile = g_fopen(filename, "wb+")) == NULL) {
        g_set_error(error,
                    G_FILE_ERROR,
                    g_file_error_from_errno(errno),
                    "Unable to open '%s' for writing",
                    gimp_filename_to_utf8(filename));
        return FALSE;
    }

#ifdef WEBP_0_5
    if (params->animation == TRUE) {
        status = save_animation(nLayers,
                                allLayers,
                                outfile,
                                params,
                                error);
    } else {
#endif
        status = save_layer(drawable_ID,
                            webp_file_writer,
                            outfile,
#ifdef WEBP_0_5
                            FALSE,
                            NULL,
                            0,
#endif
                            params,
                            error);
#ifdef WEBP_0_5
    }
#endif

    /* Close the file */
    if(outfile) {
        fclose(outfile);
    }

    return status;
}