static void gimp_file_dialog_progress_pulse (GimpProgress *progress) { GimpFileDialog *dialog = GIMP_FILE_DIALOG (progress); gimp_progress_pulse (GIMP_PROGRESS (dialog->progress)); }
static void gimp_display_shell_progress_pulse (GimpProgress *progress) { GimpDisplayShell *shell = GIMP_DISPLAY_SHELL (progress); GimpStatusbar *statusbar = gimp_display_shell_get_statusbar (shell); gimp_progress_pulse (GIMP_PROGRESS (statusbar)); }
static void gimp_sub_progress_pulse (GimpProgress *progress) { GimpSubProgress *sub = GIMP_SUB_PROGRESS (progress); if (sub->progress) gimp_progress_pulse (sub->progress); }
static void gimp_display_progress_pulse (GimpProgress *progress) { GimpDisplay *display = GIMP_DISPLAY (progress); if (display->shell) gimp_progress_pulse (GIMP_PROGRESS (display->shell)); }
static void gimp_progress_dialog_progress_pulse (GimpProgress *progress) { GimpProgressDialog *dialog = GIMP_PROGRESS_DIALOG (progress); if (! dialog->box) return; gimp_progress_pulse (GIMP_PROGRESS (dialog->box)); }
void gimp_plug_in_progress_pulse (GimpPlugIn *plug_in) { GimpPlugInProcFrame *proc_frame; g_return_if_fail (GIMP_IS_PLUG_IN (plug_in)); proc_frame = gimp_plug_in_get_proc_frame (plug_in); if (! proc_frame->progress || ! gimp_progress_is_active (proc_frame->progress) || ! proc_frame->progress_cancel_id) { gimp_plug_in_progress_start (plug_in, NULL, NULL); } if (proc_frame->progress && gimp_progress_is_active (proc_frame->progress)) gimp_progress_pulse (proc_frame->progress); }
static void file_remote_progress_callback (goffset current_num_bytes, goffset total_num_bytes, gpointer user_data) { RemoteProgress *progress = user_data; GTimeVal now; /* update the progress only up to 10 times a second */ g_get_current_time (&now); if (progress->last_time.tv_sec && ((now.tv_sec - progress->last_time.tv_sec) * 1000 + (now.tv_usec - progress->last_time.tv_usec) / 1000) < 100) return; progress->last_time = now; if (total_num_bytes > 0) { const gchar *format; gchar *done = g_format_size (current_num_bytes); gchar *total = g_format_size (total_num_bytes); switch (progress->mode) { case DOWNLOAD: format = _("Downloading image (%s of %s)"); break; case UPLOAD: format = _("Uploading image (%s of %s)"); break; default: g_assert_not_reached (); } gimp_progress_set_text (progress->progress, format, done, total); g_free (total); g_free (done); gimp_progress_set_value (progress->progress, (gdouble) current_num_bytes / (gdouble) total_num_bytes); } else { const gchar *format; gchar *done = g_format_size (current_num_bytes); switch (progress->mode) { case DOWNLOAD: format = _("Downloaded %s of image data"); break; case UPLOAD: format = _("Uploaded %s of image data"); break; default: g_assert_not_reached (); } gimp_progress_set_text (progress->progress, format, done); g_free (done); gimp_progress_pulse (progress->progress); } while (! progress->cancel && g_main_context_pending (NULL)) g_main_context_iteration (NULL, FALSE); }
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; }
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; }
static gint32 ReadImage (FILE *fd, const gchar *filename, gint len, gint height, CMap cmap, gint ncols, gint format, gint interlace, gint number, guint leftpos, guint toppos, guint screenwidth, guint screenheight) { static gint32 image_ID = -1; static gint frame_number = 1; gint32 layer_ID; GimpPixelRgn pixel_rgn; GimpDrawable *drawable; guchar *dest, *temp; guchar c; gint xpos = 0, ypos = 0, pass = 0; gint cur_progress, max_progress; gint v; gint i, j; gchar *framename; gchar *framename_ptr; gboolean alpha_frame = FALSE; static gint previous_disposal; /* Guard against bogus frame size */ if (len < 1 || height < 1) { g_message ("Bogus frame dimensions"); return -1; } /* ** Initialize the Compression routines */ if (! ReadOK (fd, &c, 1)) { g_message ("EOF / read error on image data"); return -1; } if (LZWReadByte (fd, TRUE, c) < 0) { g_message ("Error while reading"); return -1; } if (frame_number == 1) { /* Guard against bogus logical screen size values */ if (screenwidth == 0) screenwidth = len; if (screenheight == 0) screenheight = height; image_ID = gimp_image_new (screenwidth, screenheight, GIMP_INDEXED); gimp_image_set_filename (image_ID, filename); for (i = 0, j = 0; i < ncols; i++) { used_cmap[0][i] = gimp_cmap[j++] = cmap[0][i]; used_cmap[1][i] = gimp_cmap[j++] = cmap[1][i]; used_cmap[2][i] = gimp_cmap[j++] = cmap[2][i]; } gimp_image_set_colormap (image_ID, gimp_cmap, ncols); if (Gif89.delayTime < 0) framename = g_strdup (_("Background")); else framename = g_strdup_printf (_("Background (%d%s)"), 10 * Gif89.delayTime, "ms"); previous_disposal = Gif89.disposal; if (Gif89.transparent == -1) { layer_ID = gimp_layer_new (image_ID, framename, len, height, GIMP_INDEXED_IMAGE, 100, GIMP_NORMAL_MODE); } else { layer_ID = gimp_layer_new (image_ID, framename, len, height, GIMP_INDEXEDA_IMAGE, 100, GIMP_NORMAL_MODE); alpha_frame=TRUE; } g_free (framename); } else /* NOT FIRST FRAME */ { gimp_progress_set_text_printf (_("Opening '%s' (frame %d)"), gimp_filename_to_utf8 (filename), frame_number); gimp_progress_pulse (); /* If the colourmap is now different, we have to promote to RGB! */ if (! promote_to_rgb) { for (i = 0; i < ncols; i++) { if ((used_cmap[0][i] != cmap[0][i]) || (used_cmap[1][i] != cmap[1][i]) || (used_cmap[2][i] != cmap[2][i])) { /* Everything is RGB(A) from now on... sigh. */ promote_to_rgb = TRUE; /* Promote everything we have so far into RGB(A) */ #ifdef GIFDEBUG g_print ("GIF: Promoting image to RGB...\n"); #endif gimp_image_convert_rgb (image_ID); break; } } } if (Gif89.delayTime < 0) framename = g_strdup_printf (_("Frame %d"), frame_number); else framename = g_strdup_printf (_("Frame %d (%d%s)"), frame_number, 10 * Gif89.delayTime, "ms"); switch (previous_disposal) { case 0x00: break; /* 'don't care' */ case 0x01: framename_ptr = framename; framename = g_strconcat (framename, " (combine)", NULL); g_free (framename_ptr); break; case 0x02: framename_ptr = framename; framename = g_strconcat (framename, " (replace)", NULL); g_free (framename_ptr); break; case 0x03: /* Rarely-used, and unhandled by many loaders/players (including GIMP: we treat as 'combine' mode). */ framename_ptr = framename; framename = g_strconcat (framename, " (combine) (!)", NULL); g_free (framename_ptr); break; case 0x04: /* I've seen a composite of this type. stvo_online_banner2.gif */ case 0x05: case 0x06: /* I've seen a composite of this type. bn31.Gif */ case 0x07: framename_ptr = framename; framename = g_strconcat (framename, " (unknown disposal)", NULL); g_free (framename_ptr); g_message (_("GIF: Undocumented GIF composite type %d is " "not handled. Animation might not play or " "re-save perfectly."), previous_disposal); break; default: g_message ("Disposal word got corrupted. Bug."); break; } previous_disposal = Gif89.disposal; layer_ID = gimp_layer_new (image_ID, framename, len, height, promote_to_rgb ? GIMP_RGBA_IMAGE : GIMP_INDEXEDA_IMAGE, 100, GIMP_NORMAL_MODE); alpha_frame = TRUE; g_free (framename); } frame_number++; gimp_image_insert_layer (image_ID, layer_ID, -1, 0); gimp_layer_translate (layer_ID, (gint) leftpos, (gint) toppos); drawable = gimp_drawable_get (layer_ID); cur_progress = 0; max_progress = height; if (alpha_frame) dest = (guchar *) g_malloc (len * height * (promote_to_rgb ? 4 : 2)); else dest = (guchar *) g_malloc (len * height); #ifdef GIFDEBUG g_print ("GIF: reading %d by %d%s GIF image, ncols=%d\n", len, height, interlace ? " interlaced" : "", ncols); #endif if (! alpha_frame && promote_to_rgb) { /* I don't see how one would easily construct a GIF in which this could happen, but it's a mad mad world. */ g_message ("Ouch! Can't handle non-alpha RGB frames.\n" "Please file a bug report in GIMP's bugzilla."); gimp_quit (); } while ((v = LZWReadByte (fd, FALSE, c)) >= 0) { if (alpha_frame) { if (((guchar) v > highest_used_index) && !(v == Gif89.transparent)) highest_used_index = (guchar) v; if (promote_to_rgb) { temp = dest + ( (ypos * len) + xpos ) * 4; *(temp ) = (guchar) cmap[0][v]; *(temp+1) = (guchar) cmap[1][v]; *(temp+2) = (guchar) cmap[2][v]; *(temp+3) = (guchar) ((v == Gif89.transparent) ? 0 : 255); } else { temp = dest + ( (ypos * len) + xpos ) * 2; *temp = (guchar) v; *(temp+1) = (guchar) ((v == Gif89.transparent) ? 0 : 255); } } else { if ((guchar) v > highest_used_index) highest_used_index = (guchar) v; temp = dest + (ypos * len) + xpos; *temp = (guchar) v; } xpos++; if (xpos == len) { xpos = 0; if (interlace) { switch (pass) { case 0: case 1: ypos += 8; break; case 2: ypos += 4; break; case 3: ypos += 2; break; } if (ypos >= height) { pass++; switch (pass) { case 1: ypos = 4; break; case 2: ypos = 2; break; case 3: ypos = 1; break; default: goto fini; } } } else { ypos++; } if (frame_number == 1) { cur_progress++; if ((cur_progress % 16) == 0) gimp_progress_update ((gdouble) cur_progress / (gdouble) max_progress); } } if (ypos >= height) break; } fini: if (LZWReadByte (fd, FALSE, c) >= 0) g_print ("GIF: too much input data, ignoring extra...\n"); gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width, drawable->height, TRUE, FALSE); gimp_pixel_rgn_set_rect (&pixel_rgn, dest, 0, 0, drawable->width, drawable->height); g_free (dest); gimp_drawable_flush (drawable); gimp_drawable_detach (drawable); return image_ID; }
static void uri_progress_callback (goffset current_num_bytes, goffset total_num_bytes, gpointer user_data) { UriProgress *progress = user_data; GTimeVal now; /* update the progress only up to 10 times a second */ g_get_current_time (&now); if (progress->last_time.tv_sec && ((now.tv_sec - progress->last_time.tv_sec) * 1000 + (now.tv_usec - progress->last_time.tv_usec) / 1000) < 100) return; progress->last_time = now; if (total_num_bytes > 0) { const gchar *format; gchar *done = g_format_size (current_num_bytes); gchar *total = g_format_size (total_num_bytes); switch (progress->mode) { case DOWNLOAD: format = _("Downloading image (%s of %s)"); break; case UPLOAD: format = _("Uploading image (%s of %s)"); break; default: g_assert_not_reached (); } gimp_progress_set_text_printf (format, done, total); gimp_progress_update ((gdouble) current_num_bytes / (gdouble) total_num_bytes); g_free (total); g_free (done); } else { const gchar *format; gchar *done = g_format_size (current_num_bytes); switch (progress->mode) { case DOWNLOAD: format = _("Downloaded %s of image data"); break; case UPLOAD: format = _("Uploaded %s of image data"); break; default: g_assert_not_reached (); } gimp_progress_set_text_printf (format, done); gimp_progress_pulse (); g_free (done); } }