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; }
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; }
void gimp_item_parasite_attach (GimpItem *item, const GimpParasite *parasite) { GimpParasite copy; g_return_if_fail (GIMP_IS_ITEM (item)); g_return_if_fail (parasite != NULL); /* make a temporary copy of the GimpParasite struct because * gimp_parasite_shift_parent() changes it */ copy = *parasite; if (gimp_item_is_attached (item)) { /* only set the dirty bit manually if we can be saved and the new * parasite differs from the current one and we aren't undoable */ if (gimp_parasite_is_undoable (©)) { /* do a group in case we have attach_parent set */ gimp_image_undo_group_start (item->image, GIMP_UNDO_GROUP_PARASITE_ATTACH, _("Attach Parasite")); gimp_image_undo_push_item_parasite (item->image, NULL, item, ©); } else if (gimp_parasite_is_persistent (©) && ! gimp_parasite_compare (©, gimp_item_parasite_find (item, gimp_parasite_name (©)))) { gimp_image_undo_push_cantundo (item->image, _("Attach Parasite to Item")); } } gimp_parasite_list_add (item->parasites, ©); if (gimp_parasite_has_flag (©, GIMP_PARASITE_ATTACH_PARENT)) { gimp_parasite_shift_parent (©); gimp_image_parasite_attach (item->image, ©); } else if (gimp_parasite_has_flag (©, GIMP_PARASITE_ATTACH_GRANDPARENT)) { gimp_parasite_shift_parent (©); gimp_parasite_shift_parent (©); gimp_parasite_attach (item->image->gimp, ©); } if (gimp_item_is_attached (item) && gimp_parasite_is_undoable (©)) { gimp_image_undo_group_end (item->image); } }
/** * gimp_image_attach_new_parasite: * @image_ID: the ID of the image 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_image_parasite_attach() */ gboolean gimp_image_attach_new_parasite (gint32 image_ID, const gchar *name, gint flags, gint size, gconstpointer data) { GimpParasite *parasite = gimp_parasite_new (name, flags, size, data); gboolean success; success = gimp_image_parasite_attach (image_ID, parasite); gimp_parasite_free (parasite); return success; }
void gimp_image_set_icc_parasite (GimpImage *image, const GimpParasite *icc_parasite) { g_return_if_fail (GIMP_IS_IMAGE (image)); if (icc_parasite) { g_return_if_fail (gimp_image_validate_icc_parasite (image, icc_parasite, NULL, NULL) == TRUE); gimp_image_parasite_attach (image, icc_parasite); } else { gimp_image_parasite_detach (image, GIMP_ICC_PROFILE_PARASITE_NAME); } }
/* ----------------------------------------- * 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 */
static GValueArray * image_parasite_attach_invoker (GimpProcedure *procedure, Gimp *gimp, GimpContext *context, GimpProgress *progress, const GValueArray *args, GError **error) { gboolean success = TRUE; GimpImage *image; const GimpParasite *parasite; image = gimp_value_get_image (&args->values[0], gimp); parasite = g_value_get_boxed (&args->values[1]); if (success) { gimp_image_parasite_attach (image, parasite); } return gimp_procedure_get_return_values (procedure, success, error ? *error : NULL); }
/** * 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[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 ); }
/* ---------------------------------------------------- * 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 */