GimpImage * gimp_create_image (Gimp *gimp, gint width, gint height, GimpImageBaseType type, GimpPrecision precision, gboolean attach_comment) { GimpImage *image; g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); image = gimp_image_new (gimp, width, height, type, precision); if (attach_comment) { const gchar *comment; comment = gimp_template_get_comment (gimp->config->default_image); if (comment) { GimpParasite *parasite = gimp_parasite_new ("gimp-comment", GIMP_PARASITE_PERSISTENT, strlen (comment) + 1, comment); gimp_image_parasite_attach (image, parasite); gimp_parasite_free (parasite); } } return image; }
gboolean gimp_image_set_icc_profile (GimpImage *image, const guint8 *data, gsize length, GError **error) { GimpParasite *parasite = NULL; g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE); g_return_val_if_fail (data == NULL || length != 0, FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); if (data) { parasite = gimp_parasite_new (GIMP_ICC_PROFILE_PARASITE_NAME, GIMP_PARASITE_PERSISTENT | GIMP_PARASITE_UNDOABLE, length, data); if (! gimp_image_validate_icc_parasite (image, parasite, error)) { gimp_parasite_free (parasite); return FALSE; } } gimp_image_set_icc_parasite (image, parasite); if (parasite) gimp_parasite_free (parasite); return TRUE; }
static void save_defaults (void) { GimpParasite *parasite; gchar *def_str; def_str = g_strdup_printf ("%lf %lf %d %d %d %d %d %d %d %d %d %d %d %d %d", jsvals.quality, jsvals.smoothing, jsvals.optimize, jsvals.progressive, (gint) jsvals.subsmp, jsvals.baseline, jsvals.restart, jsvals.dct, jsvals.preview, jsvals.save_exif, jsvals.save_thumbnail, jsvals.save_xmp, jsvals.use_orig_quality, jsvals.save_iptc, jsvals.arithmetic_coding); parasite = gimp_parasite_new (JPEG_DEFAULTS_PARASITE, GIMP_PARASITE_PERSISTENT, strlen (def_str), def_str); gimp_attach_parasite (parasite); gimp_parasite_free (parasite); g_free (def_str); }
static gint32 create_image (GdkPixbuf *pixbuf, GdkRegion *shape, const gchar *name) { gint32 image; gint32 layer; gdouble xres, yres; gchar *comment; gint width, height; gboolean status; status = gimp_progress_init (_("Importing screenshot")); width = gdk_pixbuf_get_width (pixbuf); height = gdk_pixbuf_get_height (pixbuf); image = gimp_image_new (width, height, GIMP_RGB); gimp_image_undo_disable (image); gimp_get_monitor_resolution (&xres, &yres); gimp_image_set_resolution (image, xres, yres); comment = gimp_get_default_comment (); if (comment) { GimpParasite *parasite; parasite = gimp_parasite_new ("gimp-comment", GIMP_PARASITE_PERSISTENT, strlen (comment) + 1, comment); gimp_image_parasite_attach (image, parasite); gimp_parasite_free (parasite); g_free (comment); } layer = gimp_layer_new_from_pixbuf (image, name ? name : _("Screenshot"), pixbuf, 100, GIMP_NORMAL_MODE, 0.0, 1.0); gimp_image_add_layer (image, layer, 0); if (shape && ! gdk_region_empty (shape)) { image_select_shape (image, shape); if (! gimp_selection_is_empty (image)) { gimp_layer_add_alpha (layer); gimp_edit_clear (layer); gimp_selection_none (image); } } gimp_image_undo_enable (image); return image; }
/* -------------------------------------- * gap_dvref_assign_videoref_parasites * -------------------------------------- * if gpp->drawable_vref contains vaild video reference * then * assign video reference parasites to the specified drawable_id (typically this is a layer.) * (one parasite contains only the videfilename and has variable length, * the other contains framenumber and other information that was used to fetch * the frame from the videofile). * * the video reference is typically set on successful fetch * from a video file. (and reset on all other types of frame fetches) * + TODO: query gimprc parameter that can configures using persitent drawable_videoref_parasites. * (default shall be temporary parasites) */ void gap_dvref_assign_videoref_parasites(GapDrawableVideoRef *dvref, gint32 drawable_id) { GimpParasite *l_parasite; if(gap_debug) { printf("gap_assign_drawable_videoref_parasite: START\n"); gap_dvref_debug_print_GapDrawableVideoRef(dvref); } if(dvref->videofile == NULL) { /* no viedo reference available for the current frame */ return; } l_parasite = gimp_parasite_new(GAP_DRAWABLE_VIDEOFILE_PARASITE_NAME ,0 /* GIMP_PARASITE_PERSISTENT 0 for non persistent */ ,1 + strlen(dvref->videofile) ,dvref->videofile /* parasite data */ ); if(l_parasite) { gimp_drawable_parasite_attach(drawable_id, l_parasite); gimp_parasite_free(l_parasite); } l_parasite = gimp_parasite_new(GAP_DRAWABLE_VIDEOPARAMS_PARASITE_NAME ,0 /* GIMP_PARASITE_PERSISTENT */ ,sizeof(GapDrawableVideoParasite) ,&dvref->para /* parasite data */ ); if(l_parasite) { gimp_drawable_parasite_attach(drawable_id, l_parasite); gimp_parasite_free(l_parasite); } } /* end gap_dvref_assign_videoref_parasites */
/** * gimp_drawable_attach_new_parasite: * @drawable_ID: the ID of the #GimpDrawable to attach the #GimpParasite to. * @name: the name of the #GimpParasite to create and attach. * @flags: the flags set on the #GimpParasite. * @size: the size of the parasite data in bytes. * @data: a pointer to the data attached with the #GimpParasite. * * Convenience function that creates a parasite and attaches it * to GIMP. * * Deprecated: use gimp_image_parasite_attach() instead. * * Return value: TRUE on successful creation and attachment of * the new parasite. * * See Also: gimp_drawable_parasite_attach() */ gboolean gimp_drawable_attach_new_parasite (gint32 drawable_ID, const gchar *name, gint flags, gint size, gconstpointer data) { GimpParasite *parasite = gimp_parasite_new (name, flags, size, data); gboolean success; success = gimp_item_attach_parasite (drawable_ID, parasite); gimp_parasite_free (parasite); return success; }
/* ----------------------------------------- * p_add_image_to_list_of_duplicated_images * ----------------------------------------- * add specified image to the list of duplicated images. * this list contains temporary images of both fetched video frames * and merged duplicates of the cached original images. */ static void p_add_image_to_list_of_duplicated_images(gint32 image_id, gint32 ffetch_user_id) { GimpParasite *l_parasite; /* attach a parasite to mark the image as part of the gap image duplicates cache */ l_parasite = gimp_parasite_new(GAP_IMAGE_DUP_CACHE_PARASITE ,0 /* GIMP_PARASITE_PERSISTENT 0 for non persistent */ , sizeof(gint32) /* size of parasite data */ ,&ffetch_user_id /* parasite data */ ); if(l_parasite) { gimp_image_parasite_attach(image_id, l_parasite); gimp_parasite_free(l_parasite); } } /* end p_add_image_to_list_of_duplicated_images */
GimpParasite * gimp_grid_to_parasite (const GimpGrid *grid) { GimpParasite *parasite; gchar *str; g_return_val_if_fail (GIMP_IS_GRID (grid), NULL); str = gimp_config_serialize_to_string (GIMP_CONFIG (grid), NULL); g_return_val_if_fail (str != NULL, NULL); parasite = gimp_parasite_new (gimp_grid_parasite_name (), GIMP_PARASITE_PERSISTENT, strlen (str) + 1, str); g_free (str); return parasite; }
GimpParasite * gimp_symmetry_to_parasite (const GimpSymmetry *sym) { GimpParasite *parasite; gchar *parasite_name; gchar *str; g_return_val_if_fail (GIMP_IS_SYMMETRY (sym), NULL); str = gimp_config_serialize_to_string (GIMP_CONFIG (sym), NULL); g_return_val_if_fail (str != NULL, NULL); parasite_name = gimp_symmetry_parasite_name (G_TYPE_FROM_INSTANCE (sym)); parasite = gimp_parasite_new (parasite_name, GIMP_PARASITE_PERSISTENT, strlen (str) + 1, str); g_free (parasite_name); g_free (str); return parasite; }
/* ---------------------------------------------------- * p_load_cache_image * ---------------------------------------------------- * load an image from cache or from file (in case image is not already cached) * in case the flag addToCache is TRUE the image will be automatically added * to the cache after read from file operation. */ static gint32 p_load_cache_image(const char* filename, gint32 ffetch_user_id, gboolean addToCache) { gint32 l_image_id; char *l_filename; gint32 *images; gint nimages; gint l_idi; gint l_number_of_cached_images; gint32 l_first_cached_image_id; GimpParasite *l_parasite; if(filename == NULL) { printf("p_load_cache_image: ** ERROR cant load filename == NULL! pid:%d\n", (int)gap_base_getpid()); return -1; } l_image_id = -1; l_first_cached_image_id = -1; l_number_of_cached_images = 0; images = gimp_image_list(&nimages); for(l_idi=0; l_idi < nimages; l_idi++) { l_parasite = gimp_image_parasite_find(images[l_idi], GAP_IMAGE_CACHE_PARASITE); if(l_parasite) { gint32 *mtime_ptr; gint32 *ffetch_id_ptr; gchar *filename_ptr; mtime_ptr = (gint32 *) l_parasite->data; ffetch_id_ptr = (gint32 *)&l_parasite->data[sizeof(gint32)]; filename_ptr = (gchar *)&l_parasite->data[sizeof(gint32) + sizeof(gint32)]; l_number_of_cached_images++; if (l_first_cached_image_id < 0) { l_first_cached_image_id = images[l_idi]; } if(strcmp(filename, filename_ptr) == 0) { gint32 mtimefile; mtimefile = gap_file_get_mtime(filename); if(mtimefile == *mtime_ptr) { /* image found in cache */ l_image_id = images[l_idi]; } else { /* image found in cache, but has changed modification timestamp * (delete from cache and reload) */ if(gap_debug) { printf("FrameFetcher: DELETE because mtime changed : (image_id:%d) ffetchId:%d name:%s mtimefile:%d mtimecache:%d pid:%d\n" , (int)images[l_idi] , (int)*ffetch_id_ptr , gimp_image_get_filename(images[l_idi]) , (int)mtimefile , (int)*mtime_ptr , (int)gap_base_getpid() ); } gap_image_delete_immediate(images[l_idi]); } l_idi = nimages -1; /* force break at next loop iteration */ } gimp_parasite_free(l_parasite); } } if(images) { g_free(images); } if (l_image_id >= 0) { if(gap_debug) { printf("FrameFetcher: p_load_cache_image CACHE-HIT :%s (image_id:%d) pid:%d\n" , filename, (int)l_image_id, (int)gap_base_getpid()); } return(l_image_id); } l_filename = g_strdup(filename); l_image_id = gap_lib_load_image(l_filename); if(gap_debug) { printf("FrameFetcher: loaded image from disk:%s (image_id:%d) pid:%d\n" , l_filename, (int)l_image_id, (int)gap_base_getpid()); } if((l_image_id >= 0) && (addToCache == TRUE)) { guchar *parasite_data; gint32 parasite_size; gint32 *parasite_mtime_ptr; gint32 *parasite_ffetch_id_ptr; gchar *parasite_filename_ptr; gint32 len_filename0; /* filename length including the terminating 0 */ if (l_number_of_cached_images > p_get_ffetch_max_img_cache_elements()) { /* the image cache already has more elements than desired, * drop the 1st cached image */ if(gap_debug) { printf("FrameFetcher: DELETE because cache is full: (image_id:%d) name:%s number_of_cached_images:%d pid:%d\n" , (int)l_first_cached_image_id , gimp_image_get_filename(l_first_cached_image_id) , (int)l_number_of_cached_images , (int)gap_base_getpid() ); } gap_image_delete_immediate(l_first_cached_image_id); } /* build parasite data including mtime and full filename with terminating 0 byte */ len_filename0 = strlen(filename) + 1; parasite_size = sizeof(gint32) + sizeof(gint32) + len_filename0; parasite_data = g_malloc0(parasite_size); parasite_mtime_ptr = (gint32 *)parasite_data; parasite_ffetch_id_ptr = (gint32 *)¶site_data[sizeof(gint32)]; parasite_filename_ptr = (gchar *)¶site_data[sizeof(gint32) + sizeof(gint32)]; *parasite_mtime_ptr = gap_file_get_mtime(filename); *parasite_ffetch_id_ptr = ffetch_user_id; memcpy(parasite_filename_ptr, filename, len_filename0); /* attach a parasite to mark the image as part of the gap image cache */ l_parasite = gimp_parasite_new(GAP_IMAGE_CACHE_PARASITE ,0 /* GIMP_PARASITE_PERSISTENT 0 for non persistent */ ,parasite_size ,parasite_data ); if(l_parasite) { gimp_image_parasite_attach(l_image_id, l_parasite); gimp_parasite_free(l_parasite); } g_free(parasite_data); } g_free(l_filename); return(l_image_id); } /* end p_load_cache_image */
/** * jpeg_detect_original_settings: * @cinfo: a pointer to a JPEG decompressor info. * @image_ID: the image to which the parasite should be attached. * * Analyze the image being decompressed (@cinfo) and extract the * sampling factors, quantization tables and overall image quality. * Store this information in a parasite and attach it to @image_ID. * * This function must be called after jpeg_read_header() so that * @cinfo contains the quantization tables and the sampling factors * for each component. * * Return Value: TRUE if a parasite has been attached to @image_ID. */ gboolean jpeg_detect_original_settings (struct jpeg_decompress_struct *cinfo, gint32 image_ID) { guint parasite_size; guchar *parasite_data; GimpParasite *parasite; guchar *dest; gint quality; gint num_quant_tables = 0; gint t; gint i; g_return_val_if_fail (cinfo != NULL, FALSE); if (cinfo->jpeg_color_space == JCS_UNKNOWN || cinfo->out_color_space == JCS_UNKNOWN) return FALSE; quality = jpeg_detect_quality (cinfo); /* no need to attach quantization tables if they are the ones from IJG */ if (quality <= 0) { for (t = 0; t < 4; t++) if (cinfo->quant_tbl_ptrs[t]) num_quant_tables++; } parasite_size = 4 + cinfo->num_components * 2 + num_quant_tables * 128; parasite_data = g_new (guchar, parasite_size); dest = parasite_data; *dest++ = CLAMP0255 (cinfo->jpeg_color_space); *dest++ = ABS (quality); *dest++ = CLAMP0255 (cinfo->num_components); *dest++ = num_quant_tables; for (i = 0; i < cinfo->num_components; i++) { *dest++ = CLAMP0255 (cinfo->comp_info[i].h_samp_factor); *dest++ = CLAMP0255 (cinfo->comp_info[i].v_samp_factor); } if (quality <= 0) { for (t = 0; t < 4; t++) if (cinfo->quant_tbl_ptrs[t]) for (i = 0; i < DCTSIZE2; i++) { guint16 c = cinfo->quant_tbl_ptrs[t]->quantval[i]; *dest++ = c / 256; *dest++ = c & 255; } } parasite = gimp_parasite_new ("jpeg-settings", GIMP_PARASITE_PERSISTENT, parasite_size, parasite_data); g_free (parasite_data); gimp_image_parasite_attach (image_ID, parasite); gimp_parasite_free (parasite); return TRUE; }
void ptRun(const gchar* Name, gint NrParameters, const GimpParam* Parameter, gint *nreturn_vals, GimpParam **return_vals) { printf("(%s,%d) '%s'\n",__FILE__,__LINE__,__PRETTY_FUNCTION__); printf("Name : '%s'\n",Name); printf("NrParameters : %d\n",NrParameters); if (!strcmp(Name,"photivoSendToGimp")) { printf("RunMode : %d\n",Parameter[0].data.d_int32); printf("FileName1 : '%s'\n",Parameter[1].data.d_string); printf("FileName2 : '%s'\n",Parameter[2].data.d_string); QFile GimpFile(Parameter[1].data.d_string); bool result = GimpFile.open(QIODevice::ReadOnly | QIODevice::Text); assert(result); QTextStream In(&GimpFile); QString ImageFileName = In.readLine(); QString ExifFileName = In.readLine(); QString ICCFileName = In.readLine(); // Read image FILE *InputFile = fopen(ImageFileName.toLocal8Bit().data(),"rb"); if (!InputFile) { ptLogError(1,ImageFileName.toLocal8Bit().data()); return; // ptError_FileOpen; } short Colors; unsigned short Width; unsigned short Height; unsigned short BitsPerColor; char Buffer[128]; // Extremely naive. Probably just enough for testcases. char *s = fgets(Buffer,127,InputFile); assert ( s ); int n = sscanf(Buffer,"P%hd",&Colors); assert ( 1 == n ); assert(Colors == 6 ); do { s = fgets(Buffer,127,InputFile); assert ( s ); } while (Buffer[0] == '#'); sscanf(Buffer,"%hd %hd",&Width,&Height); s = fgets(Buffer,127,InputFile); assert ( s ); sscanf(Buffer,"%hd",&BitsPerColor); assert(BitsPerColor == 0xffff); Colors = 3; unsigned short (* ImageForGimp)[3] = (unsigned short (*)[3]) CALLOC2(Width*Height,sizeof(*ImageForGimp)); ptMemoryError(ImageForGimp,__FILE__,__LINE__); unsigned short* PpmRow = (unsigned short *) CALLOC2(Width*Height,sizeof(*PpmRow)); ptMemoryError(PpmRow,__FILE__,__LINE__); for (unsigned short Row=0; Row<Height; Row++) { size_t RV = fread(PpmRow,Colors*2,Width,InputFile); if (RV != (size_t) Width) { printf("ReadPpm error. Expected %d bytes. Got %d\n",Width,(int)RV); exit(EXIT_FAILURE); } if (htons(0x55aa) != 0x55aa) { swab((char *)PpmRow,(char *)PpmRow,Width*Colors*2); } for (unsigned short Col=0; Col<Width; Col++) { for (short c=0;c<3;c++) { ImageForGimp[Row*Width+Col][c] = PpmRow[Col*Colors+c]; } } } FREE2(PpmRow); FCLOSE(InputFile); QFile ExifFile(ExifFileName); result = ExifFile.open(QIODevice::ReadOnly); assert(result); qint64 FileSize = ExifFile.size(); QDataStream ExifIn(&ExifFile); char* ExifBuffer = (char *) MALLOC2(FileSize); ptMemoryError(ExifBuffer,__FILE__,__LINE__); unsigned ExifBufferLength = ExifIn.readRawData(ExifBuffer,FileSize); ExifFile.close(); QFile ICCFile(ICCFileName); result = ICCFile.open(QIODevice::ReadOnly); assert(result); qint64 FileSize2 = ICCFile.size(); QDataStream ICCIn(&ICCFile); char* ICCBuffer = (char *) MALLOC2(FileSize2); ptMemoryError(ICCBuffer,__FILE__,__LINE__); unsigned ICCBufferLength = ICCIn.readRawData(ICCBuffer,FileSize2); ICCFile.close(); // And now copy to gimp. gint32 GimpImage = gimp_image_new(Width, Height, GIMP_RGB); assert (GimpImage != -1); gint32 GimpLayer = gimp_layer_new(GimpImage, "BG", Width, Height, GIMP_RGB_IMAGE, 100.0, GIMP_NORMAL_MODE); #if GIMP_MINOR_VERSION<=6 gimp_image_add_layer(GimpImage,GimpLayer,0); #else gimp_image_insert_layer(GimpImage,GimpLayer,0,0); #endif GimpDrawable* Drawable = gimp_drawable_get(GimpLayer); GimpPixelRgn PixelRegion; gimp_pixel_rgn_init(&PixelRegion, Drawable, 0, 0, Drawable->width, Drawable->height, true, false); unsigned short TileHeight = gimp_tile_height(); for (unsigned short Row=0; Row<Height; Row+=TileHeight) { unsigned short NrRows = MIN(Height-Row, (int)TileHeight); guint8* Buffer = g_new(guint8,TileHeight*Width*3); for (unsigned short i=0; i<NrRows; i++) { for (unsigned short j=0; j<Width; j++) { for (short c=0;c<3;c++) { Buffer[3*(i*Width+j)+c] = ImageForGimp[(Row+i)*Width+j][c]>>8; } } } gimp_pixel_rgn_set_rect(&PixelRegion, Buffer, 0, Row, Width, NrRows); g_free(Buffer); } gimp_drawable_flush(Drawable); gimp_drawable_detach(Drawable); FREE2(ImageForGimp); GimpParasite* GimpExifData = gimp_parasite_new("exif-data", GIMP_PARASITE_PERSISTENT, ExifBufferLength, ExifBuffer); gimp_image_parasite_attach(GimpImage,GimpExifData); gimp_parasite_free(GimpExifData); FREE2(ExifBuffer); GimpParasite* GimpICCData = gimp_parasite_new("icc-profile", GIMP_PARASITE_PERSISTENT, ICCBufferLength, ICCBuffer); gimp_image_parasite_attach(GimpImage,GimpICCData); gimp_parasite_free(GimpICCData); FREE2(ICCBuffer); static GimpParam Values[2]; *nreturn_vals = 2; *return_vals = Values; Values[0].type = GIMP_PDB_STATUS; Values[0].data.d_status = GIMP_PDB_SUCCESS; Values[1].type = GIMP_PDB_IMAGE; Values[1].data.d_image = GimpImage; QFile::remove(ImageFileName); QFile::remove(ExifFileName); QFile::remove(ICCFileName); QFile::remove(Parameter[1].data.d_string); }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[4]; gint32 image_ID; XMPModel *xmp_model; GimpPDBStatusType status = GIMP_PDB_SUCCESS; GimpParasite *parasite = NULL; *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR; INIT_I18N(); if (! strcmp (name, EDITOR_PROC)) image_ID = param[1].data.d_image; else image_ID = param[0].data.d_image; xmp_model = xmp_model_new (); /* if there is already a metadata parasite, load it */ parasite = gimp_image_get_parasite (image_ID, METADATA_PARASITE); if (parasite) { GError *error = NULL; if (!! strncmp (gimp_parasite_data (parasite), METADATA_MARKER, METADATA_MARKER_LEN) || ! xmp_model_parse_buffer (xmp_model, (const gchar *) gimp_parasite_data (parasite) + METADATA_MARKER_LEN, gimp_parasite_data_size (parasite) - METADATA_MARKER_LEN, TRUE, &error)) { g_printerr ("\nMetadata parasite seems to be corrupt\n"); /* continue anyway, we will attach a clean parasite later */ } gimp_parasite_free (parasite); } /* If we have no metadata yet, try to find an XMP packet in the file * (but ignore errors if nothing is found). * * FIXME: This is a workaround until all file plug-ins do the right * thing when loading their files. */ if (xmp_model_is_empty (xmp_model) && !! strcmp (name, DECODE_XMP_PROC)) { const gchar *filename; GError *error = NULL; filename = gimp_image_get_filename (image_ID); if (filename != NULL) if (xmp_model_parse_file (xmp_model, filename, &error)) /* g_message ("XMP loaded from file '%s'\n", filename) */; } /* Now check what we are supposed to do */ if (! strcmp (name, DECODE_XMP_PROC)) { const gchar *buffer; GError *error = NULL; buffer = param[1].data.d_string; if (! xmp_model_parse_buffer (xmp_model, buffer, strlen (buffer), FALSE, &error)) status = GIMP_PDB_EXECUTION_ERROR; } else if (! strcmp (name, ENCODE_XMP_PROC)) { /* done below together with the parasite */ } else if (! strcmp (name, DECODE_EXIF_PROC)) { GError *error = NULL; if (! xmp_merge_from_exifbuffer (xmp_model, image_ID, &error)) { status = GIMP_PDB_EXECUTION_ERROR; g_printerr ("\nExif to XMP merge failed.\n"); } } else if (! strcmp (name, GET_PROC)) { g_printerr ("Not implemented yet (GET_PROC)\n"); /* FIXME */ status = GIMP_PDB_EXECUTION_ERROR; } else if (! strcmp (name, SET_PROC)) { g_printerr ("Not implemented yet (SET_PROC)\n"); /* FIXME */ status = GIMP_PDB_EXECUTION_ERROR; } else if (! strcmp (name, GET_SIMPLE_PROC)) { const gchar *schema_name; const gchar *property_name; const gchar *value; schema_name = param[1].data.d_string; property_name = param[2].data.d_string; value = xmp_model_get_scalar_property (xmp_model, schema_name, property_name); if (value) { *nreturn_vals = 2; values[1].type = GIMP_PDB_STRING; values[1].data.d_string = g_strdup (value); } else status = GIMP_PDB_EXECUTION_ERROR; } else if (! strcmp (name, SET_SIMPLE_PROC)) { const gchar *schema_name; const gchar *property_name; const gchar *property_value; schema_name = param[1].data.d_string; property_name = param[2].data.d_string; property_value = param[3].data.d_string; if (! xmp_model_set_scalar_property (xmp_model, schema_name, property_name, property_value)) status = GIMP_PDB_EXECUTION_ERROR; } else if (! strcmp (name, IMPORT_PROC)) { const gchar *filename; gchar *buffer; gsize buffer_length; GError *error = NULL; filename = param[1].data.d_string; if (! g_file_get_contents (filename, &buffer, &buffer_length, &error)) { g_error_free (error); status = GIMP_PDB_EXECUTION_ERROR; } else if (! xmp_model_parse_buffer (xmp_model, buffer, buffer_length, TRUE, &error)) { g_error_free (error); status = GIMP_PDB_EXECUTION_ERROR; } g_free (buffer); } else if (! strcmp (name, EXPORT_PROC)) { /* FIXME: this is easy to implement, but the first thing to do is */ /* to improve the code of export_dialog_response() in interface.c */ g_printerr ("Not implemented yet (EXPORT_PROC)\n"); status = GIMP_PDB_EXECUTION_ERROR; } else if (! strcmp (name, EDITOR_PROC)) { GimpRunMode run_mode; run_mode = param[0].data.d_int32; if (run_mode == GIMP_RUN_INTERACTIVE) { if (! metadata_dialog (image_ID, xmp_model)) status = GIMP_PDB_CANCEL; } g_printerr ("Not implemented yet (EDITOR_PROC)\n"); status = GIMP_PDB_EXECUTION_ERROR; } else { status = GIMP_PDB_CALLING_ERROR; } if (status == GIMP_PDB_SUCCESS) { GString *buffer; /* Generate the updated parasite and attach it to the image */ buffer = g_string_new (METADATA_MARKER); xmp_generate_packet (xmp_model, buffer); parasite = gimp_parasite_new (METADATA_PARASITE, GIMP_PARASITE_PERSISTENT, buffer->len, (gpointer) buffer->str); gimp_image_attach_parasite (image_ID, parasite); if (! strcmp (name, ENCODE_XMP_PROC)) { *nreturn_vals = 2; values[1].type = GIMP_PDB_STRING; values[1].data.d_string = g_strdup (buffer->str + METADATA_MARKER_LEN); } g_string_free (buffer, TRUE); } g_object_unref (xmp_model); values[0].data.d_status = status; }
static gboolean lcms_image_set_profile (gint32 image, cmsHPROFILE profile, const gchar *filename, gboolean undo_group) { g_return_val_if_fail (image != -1, FALSE); if (filename) { GimpParasite *parasite; GMappedFile *file; GError *error = NULL; file = g_mapped_file_new (filename, FALSE, &error); if (! file) { g_message ("%s", error->message); g_error_free (error); return FALSE; } /* check that this file is actually an ICC profile */ if (! profile) { profile = cmsOpenProfileFromMem (g_mapped_file_get_contents (file), g_mapped_file_get_length (file)); if (profile) { cmsCloseProfile (profile); } else { g_message (_("'%s' does not appear to be an ICC color profile"), gimp_filename_to_utf8 (filename)); return FALSE; } } if (undo_group) gimp_image_undo_group_start (image); parasite = gimp_parasite_new ("icc-profile", GIMP_PARASITE_PERSISTENT | GIMP_PARASITE_UNDOABLE, g_mapped_file_get_length (file), g_mapped_file_get_contents (file)); g_mapped_file_unref (file); gimp_image_attach_parasite (image, parasite); gimp_parasite_free (parasite); } else { if (undo_group) gimp_image_undo_group_start (image); gimp_image_detach_parasite (image, "icc-profile"); } gimp_image_detach_parasite (image, "icc-profile-name"); if (undo_group) gimp_image_undo_group_end (image); return TRUE; }
static gboolean jpeg_exif_rotate_query_dialog (gint32 image_ID) { GtkWidget *dialog; GtkWidget *hbox; GtkWidget *vbox; GtkWidget *label; GtkWidget *toggle; GdkPixbuf *pixbuf; gint response; dialog = gimp_dialog_new (_("Rotate Image?"), PLUG_IN_BINARY, NULL, 0, NULL, NULL, _("_Keep Orientation"), GTK_RESPONSE_CANCEL, GIMP_STOCK_TOOL_ROTATE, GTK_RESPONSE_OK, NULL); gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); gimp_window_set_transient (GTK_WINDOW (dialog)); hbox = gtk_hbox_new (FALSE, 12); gtk_container_set_border_width (GTK_CONTAINER (hbox), 12); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, FALSE, FALSE, 0); gtk_widget_show (hbox); vbox = gtk_vbox_new (FALSE, 6); gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); gtk_widget_show (vbox); pixbuf = gimp_image_get_thumbnail (image_ID, THUMBNAIL_SIZE, THUMBNAIL_SIZE, GIMP_PIXBUF_SMALL_CHECKS); if (pixbuf) { GtkWidget *image; gchar *name; image = gtk_image_new_from_pixbuf (pixbuf); g_object_unref (pixbuf); gtk_box_pack_start (GTK_BOX (vbox), image, FALSE, FALSE, 0); gtk_widget_show (image); name = gimp_image_get_name (image_ID); label = gtk_label_new (name); gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE); gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_STYLE, PANGO_STYLE_ITALIC, -1); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); gtk_widget_show (label); g_free (name); } vbox = gtk_vbox_new (FALSE, 12); gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); gtk_widget_show (vbox); label = g_object_new (GTK_TYPE_LABEL, "label", _("According to the EXIF data, " "this image is rotated."), "wrap", TRUE, "justify", GTK_JUSTIFY_LEFT, "xalign", 0.0, "yalign", 0.5, NULL); gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_LARGE, PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD, -1); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); gtk_widget_show (label); label = g_object_new (GTK_TYPE_LABEL, "label", _("Would you like GIMP to rotate it " "into the standard orientation?"), "wrap", TRUE, "justify", GTK_JUSTIFY_LEFT, "xalign", 0.0, "yalign", 0.5, NULL); gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); gtk_widget_show (label); toggle = gtk_check_button_new_with_mnemonic (_("_Don't ask me again")); gtk_box_pack_end (GTK_BOX (vbox), toggle, FALSE, FALSE, 0); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (toggle), FALSE); gtk_widget_show (toggle); response = gimp_dialog_run (GIMP_DIALOG (dialog)); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle))) { GimpParasite *parasite; const gchar *str = (response == GTK_RESPONSE_OK) ? "yes" : "no"; parasite = gimp_parasite_new (JPEG_EXIF_ROTATE_PARASITE, GIMP_PARASITE_PERSISTENT, strlen (str), str); gimp_parasite_attach (parasite); gimp_parasite_free (parasite); } gtk_widget_destroy (dialog); return (response == GTK_RESPONSE_OK); }
static gboolean lcms_image_set_profile (gint32 image, cmsHPROFILE profile, GFile *file) { g_return_val_if_fail (image != -1, FALSE); if (file) { cmsHPROFILE file_profile; GimpParasite *parasite; guint8 *profile_data; gsize profile_length; GError *error = NULL; /* check that this file is actually an ICC profile */ file_profile = gimp_lcms_profile_open_from_file (file, &error); if (! file_profile) { g_message ("%s", error->message); g_clear_error (&error); return FALSE; } profile_data = gimp_lcms_profile_save_to_data (file_profile, &profile_length, &error); cmsCloseProfile (file_profile); if (! profile_data) { g_message ("%s", error->message); g_clear_error (&error); return FALSE; } gimp_image_undo_group_start (image); parasite = gimp_parasite_new ("icc-profile", GIMP_PARASITE_PERSISTENT | GIMP_PARASITE_UNDOABLE, profile_length, profile_data); g_free (profile_data); gimp_image_attach_parasite (image, parasite); gimp_parasite_free (parasite); } else { gimp_image_undo_group_start (image); gimp_image_detach_parasite (image, "icc-profile"); } gimp_image_detach_parasite (image, "icc-profile-name"); gimp_image_undo_group_end (image); return TRUE; }
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; }
static void run ( const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[3]; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; SeparateContext mysc; //enum separate_function func = SEP_NONE; run_mode = param[0].data.d_int32; /* setup for localization */ INIT_I18N (); cmsErrorAction( LCMS_ERROR_IGNORE ); mysc.filename = NULL; if( nparams != ( run_mode == GIMP_RUN_NONINTERACTIVE ? 2 : 1 ) ) status = GIMP_PDB_CALLING_ERROR; else if( run_mode == GIMP_RUN_NONINTERACTIVE ) { if( param[1].type != GIMP_PDB_STRING || strlen( param[1].data.d_string ) == 0 ) status = GIMP_PDB_CALLING_ERROR; else mysc.filename = g_strdup( param[1].data.d_string ); } else { gint size = gimp_get_data_size( "plug-in-separate-import/lastpath" ); if( size ) { mysc.filename = g_malloc( size ); gimp_get_data( "plug-in-separate-import/lastpath", mysc.filename ); } } if( status == GIMP_PDB_SUCCESS && ( run_mode == GIMP_RUN_NONINTERACTIVE || separate_import_dialog( &mysc ) ) ) { gint i, j, x, y; TIFF *in; guint32 width, height, stripSize, stripCount, stripHeight; gint16 bps, spp, step, planerConfig, photometric, inkset, resolutionUnit; float xres, yres; const gchar *layerNames[] = { "C", "M", "Y", "K" }; guchar *buf, *maskbuf[4], *srcbuf, *destbuf[4], *iccProfile; gint32 layers[5], masks[4]; GimpDrawable *drw[4]; GimpPixelRgn rgn[4]; GimpRGB primaries[4] = { { .180, .541, .870, 1.0 }, { .925, .149, .388, 1.0 }, { .929, .862, .129, 1.0 }, { 0, 0, 0, 1.0 } }; gchar *str = NULL; gchar *baseName = g_path_get_basename( gimp_filename_to_utf8( mysc.filename ) ); #ifdef G_OS_WIN32 { gchar *_filename = NULL; // win32 filename encoding(not UTF-8) _filename = g_win32_locale_filename_from_utf8( mysc.filename ); in = TIFFOpen( _filename ? _filename : mysc.filename, "r" ); g_free( _filename ); } #else in = TIFFOpen( mysc.filename, "r" ); #endif if( !in ) { str = g_strdup_printf( _( "Cannot open : \"%s\"" ), baseName ); gimp_message( str ); g_free( str ); status = GIMP_PDB_EXECUTION_ERROR; } else { if( ( TIFFGetField( in, TIFFTAG_BITSPERSAMPLE, &bps ) == FALSE || ( bps != 8 && bps != 16 ) ) || ( TIFFGetField( in, TIFFTAG_SAMPLESPERPIXEL, &spp ) == FALSE || spp != 4 ) || ( TIFFGetField( in, TIFFTAG_PHOTOMETRIC, &photometric ) == FALSE || photometric != PHOTOMETRIC_SEPARATED ) || ( TIFFGetField( in, TIFFTAG_PLANARCONFIG, &planerConfig ) == FALSE || planerConfig != PLANARCONFIG_CONTIG ) || ( TIFFGetField( in, TIFFTAG_INKSET, &inkset ) == TRUE && inkset != INKSET_CMYK ) ) { str = g_strdup_printf( _( "\"%s\" is unsupported." ), baseName ); gimp_message( str ); g_free( str ); status = GIMP_PDB_EXECUTION_ERROR; } else { stripCount = TIFFNumberOfStrips( in ); stripSize = TIFFStripSize( in ); TIFFGetField( in, TIFFTAG_IMAGEWIDTH, &width ); TIFFGetField( in, TIFFTAG_IMAGELENGTH, &height ); TIFFGetField( in, TIFFTAG_ROWSPERSTRIP, &stripHeight ); TIFFGetField( in, TIFFTAG_RESOLUTIONUNIT, &resolutionUnit ); TIFFGetField( in, TIFFTAG_XRESOLUTION, &xres ); TIFFGetField( in, TIFFTAG_YRESOLUTION, &yres ); #if 0 str = g_strdup_printf( "Photometric : %d BPS : %d SPP : %d\nInkset : %d StripCount : %d", photometric, bps, spp, inkset, stripCount ); gimp_message( str ); g_free( str ); #endif step = ( bps == 16 ) ? 2 : 1; buf = g_malloc( stripSize ); values[1].data.d_image = gimp_image_new( width, height, GIMP_RGB ); gimp_image_set_resolution( values[1].data.d_image, xres, yres ); gimp_context_push(); for( i = 0; i < 4; i++ ) { layers[i] = gimp_layer_new( values[1].data.d_image, layerNames[i], width, height, GIMP_RGBA_IMAGE, 100.0, GIMP_DARKEN_ONLY_MODE ); gimp_context_set_foreground( &primaries[i] ); gimp_drawable_fill( layers[i], GIMP_FOREGROUND_FILL ); gimp_image_add_layer( values[1].data.d_image, layers[i], i ); masks[i] = gimp_layer_create_mask( layers[i], GIMP_ADD_BLACK_MASK ); gimp_layer_add_mask( layers[i], masks[i] ); drw[i] = gimp_drawable_get( masks[i] ); maskbuf[i] = g_malloc( width * stripHeight ); } gimp_context_pop(); layers[4] = gimp_layer_new( values[1].data.d_image, _( "Background" ), width, height, GIMP_RGB_IMAGE, 100.0, GIMP_NORMAL_MODE ); gimp_drawable_fill( layers[4], GIMP_WHITE_FILL ); gimp_image_add_layer( values[1].data.d_image, layers[4], 4 ); str = g_strdup_printf( _( "Reading \"%s\"..." ), baseName ); gimp_progress_init( str ); g_free( str ); for( i = 0; i < stripCount; i++ ) { guint32 size = TIFFReadEncodedStrip( in, i, buf, stripSize ); guint32 rowCount = ( size < stripSize ? height % stripHeight : stripHeight ); srcbuf = buf; if( bps == 16 ) srcbuf++; for( j = 0; j < 4; j++ ) { gimp_pixel_rgn_init( &( rgn[j] ), drw[j], 0, stripHeight * i, width, rowCount, FALSE, FALSE ); destbuf[j] = maskbuf[j]; } for( y = 0; y < rowCount; y++ ) { for( x = 0; x < width; x++ ) { *destbuf[0]++ = *srcbuf; srcbuf += step; *destbuf[1]++ = *srcbuf; srcbuf += step; *destbuf[2]++ = *srcbuf; srcbuf += step; *destbuf[3]++ = *srcbuf; srcbuf += step; //srcbuf += spp > 4 ? spp - 4 : 0; } } gimp_pixel_rgn_set_rect( &( rgn[0] ), maskbuf[0], 0, stripHeight * i, width, rowCount ); gimp_pixel_rgn_set_rect( &( rgn[1] ), maskbuf[1], 0, stripHeight * i, width, rowCount ); gimp_pixel_rgn_set_rect( &( rgn[2] ), maskbuf[2], 0, stripHeight * i, width, rowCount ); gimp_pixel_rgn_set_rect( &( rgn[3] ), maskbuf[3], 0, stripHeight * i, width, rowCount ); gimp_progress_update( (gdouble)i / stripCount ); } g_free( buf ); for( i = 0; i < 4; i++ ) { g_free( maskbuf[i] ); gimp_drawable_detach( drw[i] ); } #ifdef ENABLE_COLOR_MANAGEMENT if ( TIFFGetField( in, TIFFTAG_ICCPROFILE, &width, &iccProfile ) ) { GimpParasite *parasite; parasite = gimp_parasite_new( CMYKPROFILE, 0, width, iccProfile ); gimp_image_parasite_attach( values[1].data.d_image, parasite ); gimp_parasite_free( parasite ); //g_free( iccProfile ); // This causes clash on TIFFClose( in ). } #endif } TIFFClose( in ); } g_free( baseName ); } else status = GIMP_PDB_CANCEL; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; if( status == GIMP_PDB_SUCCESS ) { *nreturn_vals = 2; values[1].type = GIMP_PDB_IMAGE; if( run_mode != GIMP_RUN_NONINTERACTIVE ) { gimp_image_undo_enable( values[1].data.d_image ); gimp_display_new( values[1].data.d_image ); gimp_displays_flush(); } gimp_set_data( "plug-in-separate-import/lastpath", mysc.filename, strlen( mysc.filename ) + 1 ); } else *nreturn_vals = 1; g_free( mysc.filename ); }
static gint DoExtension (FILE *fd, gint label) { static guchar buf[256]; gchar *str; switch (label) { case 0x01: /* Plain Text Extension */ str = "Plain Text Extension"; #ifdef notdef if (GetDataBlock (fd, (guchar *) buf) == 0) ; lpos = LM_to_uint (buf[0], buf[1]); tpos = LM_to_uint (buf[2], buf[3]); width = LM_to_uint (buf[4], buf[5]); height = LM_to_uint (buf[6], buf[7]); cellw = buf[8]; cellh = buf[9]; foreground = buf[10]; background = buf[11]; while (GetDataBlock (fd, (guchar *) buf) > 0) { PPM_ASSIGN (image[ypos][xpos], cmap[CM_RED][v], cmap[CM_GREEN][v], cmap[CM_BLUE][v]); ++index; } return FALSE; #else break; #endif case 0xff: /* Application Extension */ str = "Application Extension"; break; case 0xfe: /* Comment Extension */ str = "Comment Extension"; while (GetDataBlock (fd, (guchar *) buf) > 0) { gchar *comment = (gchar *) buf; if (! g_utf8_validate (comment, -1, NULL)) continue; if (comment_parasite) gimp_parasite_free (comment_parasite); comment_parasite = gimp_parasite_new ("gimp-comment", GIMP_PARASITE_PERSISTENT, strlen (comment) + 1, comment); } return TRUE; break; case 0xf9: /* Graphic Control Extension */ str = "Graphic Control Extension"; (void) GetDataBlock (fd, (guchar *) buf); Gif89.disposal = (buf[0] >> 2) & 0x7; Gif89.inputFlag = (buf[0] >> 1) & 0x1; Gif89.delayTime = LM_to_uint (buf[1], buf[2]); if ((buf[0] & 0x1) != 0) Gif89.transparent = buf[3]; else Gif89.transparent = -1; while (GetDataBlock (fd, (guchar *) buf) > 0); return FALSE; break; default: str = (gchar *)buf; sprintf ((gchar *)buf, "UNKNOWN (0x%02x)", label); break; } #ifdef GIFDEBUG g_print ("GIF: got a '%s'\n", str); #endif while (GetDataBlock (fd, (guchar *) buf) > 0); return FALSE; }
static gboolean gimp_parasite_list_deserialize (GimpConfig *list, GScanner *scanner, gint nest_level, gpointer data) { GTokenType token; g_scanner_scope_add_symbol (scanner, 0, parasite_symbol, (gpointer) parasite_symbol); token = G_TOKEN_LEFT_PAREN; while (g_scanner_peek_next_token (scanner) == token) { token = g_scanner_get_next_token (scanner); switch (token) { case G_TOKEN_LEFT_PAREN: token = G_TOKEN_SYMBOL; break; case G_TOKEN_SYMBOL: if (scanner->value.v_symbol == parasite_symbol) { gchar *parasite_name = NULL; gint parasite_flags = 0; guint8 *parasite_data = NULL; gint parasite_data_size = 0; GimpParasite *parasite; token = G_TOKEN_STRING; if (g_scanner_peek_next_token (scanner) != token) break; if (! gimp_scanner_parse_string (scanner, ¶site_name)) break; token = G_TOKEN_INT; if (g_scanner_peek_next_token (scanner) != token) goto cleanup; if (! gimp_scanner_parse_int (scanner, ¶site_flags)) goto cleanup; token = G_TOKEN_INT; if (g_scanner_peek_next_token (scanner) != token) { /* old format -- plain string */ gchar *str; if (g_scanner_peek_next_token (scanner) != G_TOKEN_STRING) goto cleanup; if (! gimp_scanner_parse_string (scanner, &str)) goto cleanup; parasite_data_size = strlen (str); parasite_data = (guint8 *) str; } else { /* new format -- properly encoded binary data */ if (! gimp_scanner_parse_int (scanner, ¶site_data_size)) goto cleanup; token = G_TOKEN_STRING; if (g_scanner_peek_next_token (scanner) != token) goto cleanup; if (! gimp_scanner_parse_data (scanner, parasite_data_size, ¶site_data)) goto cleanup; } parasite = gimp_parasite_new (parasite_name, parasite_flags, parasite_data_size, parasite_data); gimp_parasite_list_add (GIMP_PARASITE_LIST (list), parasite); /* adds a copy */ gimp_parasite_free (parasite); token = G_TOKEN_RIGHT_PAREN; g_free (parasite_data); cleanup: g_free (parasite_name); } break; case G_TOKEN_RIGHT_PAREN: token = G_TOKEN_LEFT_PAREN; break; default: /* do nothing */ break; } } return gimp_config_deserialize_return (scanner, token, nest_level); }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[MAX_EXTRACT_IMAGES + 1]; GimpPDBStatusType status = GIMP_PDB_SUCCESS; gint32 num_images; gint32 image_ID_extract[MAX_EXTRACT_IMAGES]; gint32 layer_ID_extract[MAX_EXTRACT_IMAGES]; gint j; gint32 layer; gint32 num_layers; gint32 image_ID; INIT_I18N (); gegl_init (NULL, NULL); run_mode = param[0].data.d_int32; image_ID = param[1].data.d_image; layer = param[2].data.d_drawable; *nreturn_vals = MAX_EXTRACT_IMAGES + 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; for (j = 0; j < MAX_EXTRACT_IMAGES; j++) { values[j+1].type = GIMP_PDB_IMAGE; values[j+1].data.d_int32 = -1; } switch (run_mode) { case GIMP_RUN_INTERACTIVE: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &decovals); /* First acquire information with a dialog */ if (! decompose_dialog ()) return; break; case GIMP_RUN_NONINTERACTIVE: /* Make sure all the arguments are there! */ if (nparams != 4 && nparams != 5 && nparams != 6) { status = GIMP_PDB_CALLING_ERROR; } else { strncpy (decovals.extract_type, param[3].data.d_string, sizeof (decovals.extract_type)); decovals.extract_type[sizeof (decovals.extract_type) - 1] = '\0'; decovals.as_layers = nparams > 4 ? param[4].data.d_int32 : FALSE; decovals.use_registration = (strcmp (name, PLUG_IN_PROC_REG) == 0); } break; case GIMP_RUN_WITH_LAST_VALS: /* Possibly retrieve data */ gimp_get_data (PLUG_IN_PROC, &decovals); break; default: break; } if (status == GIMP_PDB_SUCCESS) { gimp_progress_init (_("Decomposing")); num_images = decompose (image_ID, layer, decovals.extract_type, image_ID_extract, &num_layers, layer_ID_extract); if (num_images <= 0) { status = GIMP_PDB_EXECUTION_ERROR; } else { /* create decompose-data parasite */ GString *data = g_string_new (""); g_string_printf (data, "source=%d type=%s ", layer, decovals.extract_type); for (j = 0; j < num_layers; j++) g_string_append_printf (data, "%d ", layer_ID_extract[j]); for (j = 0; j < num_images; j++) { GimpParasite *parasite; values[j+1].data.d_int32 = image_ID_extract[j]; gimp_image_undo_enable (image_ID_extract[j]); gimp_image_clean_all (image_ID_extract[j]); parasite = gimp_parasite_new ("decompose-data", 0, data->len + 1, data->str); gimp_image_attach_parasite (image_ID_extract[j], parasite); gimp_parasite_free (parasite); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_display_new (image_ID_extract[j]); } /* Store data */ if (run_mode == GIMP_RUN_INTERACTIVE) gimp_set_data (PLUG_IN_PROC, &decovals, sizeof (DecoVals)); } gimp_progress_end (); } values[0].data.d_status = status; }