/* A function that removes images that are no longer valid from * the image list */ static void validate_image_list (void) { gint32 valid = 0; guint32 i = 0; for (i = 0 ; i < MAX_PAGE_COUNT && i < multi_page.image_count ; i++) { if (gimp_image_is_valid (multi_page.images[i])) { multi_page.images[valid] = multi_page.images[i]; valid++; } } multi_page.image_count = valid; }
/* * save all settings as a resource file "print-settings" * and as an image parasite */ void print_settings_save (PrintData *data) { GKeyFile *key_file = print_settings_key_file_from_settings (data); /* image setup */ if (gimp_image_is_valid (data->image_id)) { g_key_file_set_integer (key_file, "image-setup", "unit", data->unit); g_key_file_set_double (key_file, "image-setup", "x-resolution", data->xres); g_key_file_set_double (key_file, "image-setup", "y-resolution", data->yres); g_key_file_set_double (key_file, "image-setup", "x-offset", data->offset_x); g_key_file_set_double (key_file, "image-setup", "y-offset", data->offset_y); g_key_file_set_integer (key_file, "image-setup", "center-mode", data->center); g_key_file_set_boolean (key_file, "image-setup", "use-full-page", data->use_full_page); g_key_file_set_boolean (key_file, "image-setup", "crop-marks", data->draw_crop_marks); print_utils_key_file_save_as_parasite (key_file, data->image_id, PRINT_SETTINGS_NAME); } /* some settings shouldn't be made persistent on a global level, * so they are only stored in the image, not in the rcfile */ g_key_file_remove_key (key_file, "image-setup", "x-resolution", NULL); g_key_file_remove_key (key_file, "image-setup", "y-resolution", NULL); g_key_file_remove_key (key_file, "image-setup", "x-offset", NULL); g_key_file_remove_key (key_file, "image-setup", "y-offset", NULL); g_key_file_remove_key (key_file, PRINT_SETTINGS_NAME, "n-copies", NULL); print_utils_key_file_save_as_rcfile (key_file, PRINT_SETTINGS_NAME); g_key_file_free (key_file); }
void destroy_preview (void) { if (prev_p && !prev_p->abort_me) { guint id = prev_p->source_id; prev_p->abort_me = TRUE; /* signal the background save to stop */ background_jpeg_save (prev_p); g_source_remove (id); } if (gimp_image_is_valid (preview_image_ID) && gimp_item_is_valid (preview_layer_ID)) { /* assuming that reference counting is working correctly, we do not need to delete the layer, removing it from the image should be sufficient */ gimp_image_remove_layer (preview_image_ID, preview_layer_ID); preview_layer_ID = -1; } }
static void run (const gchar *name, gint nparams, const GimpParam *params, gint *nreturn_vals, GimpParam **return_vals) { // Prepare return values static GimpParam results[1]; results[0].type = GIMP_PDB_STATUS; results[0].data.d_status = GIMP_PDB_SUCCESS; *nreturn_vals = 1; *return_vals = results; // A bit of infrastructure to support debugging #ifdef DEBUG fprintf (stderr, "pid is %d\n", getpid ()); sleep (5); #endif // Get parameters int image = params[1].data.d_image; int drawable = params[2].data.d_drawable; REPORT_INT (image); REPORT_INT (drawable); // Sanity check if (! gimp_image_is_valid (image)) { results[0].data.d_status = GIMP_PDB_CALLING_ERROR; return; } if (! gimp_drawable_is_valid (drawable)) { results[0].data.d_status = GIMP_PDB_CALLING_ERROR; return; } // Set up the tile stream int stream = drawable_new_tile_stream (image, drawable); // Iterate through the region GimpPixelRgn *region; while ((region = tile_stream_get (stream)) != NULL) { guchar *data = region->data; #ifdef DEBUG fprintf (stderr, "Starting tile x=%d, y=%d, w=%d, h=%d\n", region->x, region->y, region->w, region->h); #endif int r; for (r = 0; r < region->h; r++) { guchar *pixel = data; int c; for (c = 0; c < region->w; c++) { // Change the pixel guchar tmp = pixel[0]; pixel[0] = pixel[1]; pixel[1] = pixel[2]; pixel[2] = tmp; // Advance to the next pixel pixel += region->bpp; } // for c data += region->rowstride; } // for each row // Copy the modified data back tile_stream_update (stream, region->data); // Advance to the next tile tile_stream_advance (stream); } // while // Clean up tile_stream_close (stream); } // run
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); }