diff options
author | oehhar <harald.oehlmann@elmicron.de> | 2020-05-30 21:53:44 (GMT) |
---|---|---|
committer | oehhar <harald.oehlmann@elmicron.de> | 2020-05-30 21:53:44 (GMT) |
commit | 9da42ea63840166de7979c55a3ba0476cfb245c4 (patch) | |
tree | c5c09e3ec1a6bc4f7cb9919b80bbbc26745036d3 | |
parent | dd57d00f5c65deebb5bea67608c586856c2c2b7a (diff) | |
download | tk-9da42ea63840166de7979c55a3ba0476cfb245c4.zip tk-9da42ea63840166de7979c55a3ba0476cfb245c4.tar.gz tk-9da42ea63840166de7979c55a3ba0476cfb245c4.tar.bz2 |
TIP529 image metadata: untested sketch to implemet new call interface for Tcl_CreatePhotoImageType with metadata in all functions. Replaces Tk_Get/SetMetadata
-rw-r--r-- | generic/tk.decls | 5 | ||||
-rw-r--r-- | generic/tk.h | 56 | ||||
-rw-r--r-- | generic/tkDecls.h | 8 | ||||
-rw-r--r-- | generic/tkImgGIF.c | 102 | ||||
-rw-r--r-- | generic/tkImgPhoto.c | 312 | ||||
-rw-r--r-- | generic/tkInt.h | 2 | ||||
-rw-r--r-- | generic/tkWindow.c | 2 |
7 files changed, 400 insertions, 87 deletions
diff --git a/generic/tk.decls b/generic/tk.decls index 2952bc3..0cd8fa4 100644 --- a/generic/tk.decls +++ b/generic/tk.decls @@ -1070,10 +1070,7 @@ declare 273 { } # New in Tk8.7 declare 274 { - Tcl_Obj *Tk_PhotoGetMetadata(Tk_PhotoHandle handle); -} -declare 275 { - void Tk_PhotoSetMetadata(Tk_PhotoHandle handle,Tcl_Obj *metadata); + void Tk_CreatePhotoImageFormat87(const Tk_PhotoImageFormat87 *formatPtr) } diff --git a/generic/tk.h b/generic/tk.h index 5efd2cb..5aa8998 100644 --- a/generic/tk.h +++ b/generic/tk.h @@ -1440,6 +1440,30 @@ typedef int (Tk_ImageStringWriteProc) (Tcl_Interp *interp, Tcl_Obj *format, #endif /* USE_OLD_IMAGE */ /* + * The following alternate definitions are used with the Tk8.7 file format + * supporting a metadata dict + */ + +typedef struct Tk_PhotoImageFormat87 Tk_PhotoImageFormat87; +typedef int (Tk_ImageFileMatchProc87) (Tcl_Channel chan, const char *fileName, + Tcl_Obj *format, int *widthPtr, int *heightPtr, Tcl_Interp *interp, + Tcl_Obj **metadataPtr); +typedef int (Tk_ImageStringMatchProc87) (Tcl_Obj *dataObj, Tcl_Obj *format, + int *widthPtr, int *heightPtr, Tcl_Interp *interp, Tcl_Obj **metadataPtr); +typedef int (Tk_ImageFileReadProc87) (Tcl_Interp *interp, Tcl_Channel chan, + const char *fileName, Tcl_Obj *format, Tk_PhotoHandle imageHandle, + int destX, int destY, int width, int height, int srcX, int srcY, + Tcl_Obj **metadataPtr); +typedef int (Tk_ImageStringReadProc87) (Tcl_Interp *interp, Tcl_Obj *dataObj, + Tcl_Obj *format, Tk_PhotoHandle imageHandle, int destX, int destY, + int width, int height, int srcX, int srcY, Tcl_Obj **metadataPtr); +typedef int (Tk_ImageFileWriteProc87) (Tcl_Interp *interp, const char *fileName, + Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr, Tcl_Obj *metadata); +typedef int (Tk_ImageStringWriteProc87) (Tcl_Interp *interp, Tcl_Obj *format, + Tk_PhotoImageBlock *blockPtr, Tcl_Obj *metadata); + + +/* * The following structure represents a particular file format for storing * images (e.g., PPM, GIF, JPEG, etc.). It provides information to allow image * files of that format to be recognized and read into a photo image. @@ -1471,6 +1495,38 @@ struct Tk_PhotoImageFormat { * currently known. Filled in by Tk, not by * image format handler. */ }; + +/* + * The following structure is the same plus added support for the metadata + * structure. + */ + +struct Tk_PhotoImageFormat87 { + const char *name; /* Name of image file format */ + Tk_ImageFileMatchProc87 *fileMatchProc; + /* Procedure to call to determine whether an + * image file matches this format. */ + Tk_ImageStringMatchProc87 *stringMatchProc; + /* Procedure to call to determine whether the + * data in a string matches this format. */ + Tk_ImageFileReadProc87 *fileReadProc; + /* Procedure to call to read data from an + * image file into a photo image. */ + Tk_ImageStringReadProc87 *stringReadProc; + /* Procedure to call to read data from a + * string into a photo image. */ + Tk_ImageFileWriteProc87 *fileWriteProc; + /* Procedure to call to write data from a + * photo image to a file. */ + Tk_ImageStringWriteProc87 *stringWriteProc; + /* Procedure to call to obtain a string + * representation of the data in a photo + * image.*/ + struct Tk_PhotoImageFormat87 *nextPtr; + /* Next in list of all photo image formats + * currently known. Filled in by Tk, not by + * image format handler. */ +}; /* *---------------------------------------------------------------------- diff --git a/generic/tkDecls.h b/generic/tkDecls.h index 094e145..9ba5d88 100644 --- a/generic/tkDecls.h +++ b/generic/tkDecls.h @@ -879,9 +879,8 @@ EXTERN void Tk_CreateOldImageType(const Tk_ImageType *typePtr); EXTERN void Tk_CreateOldPhotoImageFormat( const Tk_PhotoImageFormat *formatPtr); /* 274 */ -EXTERN Tcl_Obj *Tk_PhotoGetMetadata(Tk_PhotoHandle handle); -/* 275 */ -EXTERN void Tk_PhotoSetMetadata(Tk_PhotoHandle handle,Tcl_Obj *metadata); +EXTERN void Tk_CreatePhotoImageFormat87( + const Tk_PhotoImageFormat87 *formatPtr); typedef struct { const struct TkPlatStubs *tkPlatStubs; @@ -1168,8 +1167,7 @@ typedef struct TkStubs { Tcl_Interp * (*tk_Interp) (Tk_Window tkwin); /* 271 */ void (*tk_CreateOldImageType) (const Tk_ImageType *typePtr); /* 272 */ void (*tk_CreateOldPhotoImageFormat) (const Tk_PhotoImageFormat *formatPtr); /* 273 */ - Tcl_Obj *(*tk_PhotoGetMetadata) (Tk_PhotoHandle handle); /* 274 */ - void (*tk_PhotoSetMetadata) (Tk_PhotoHandle handle,Tcl_Obj *metadata); /* 275 */ + void (*tk_CreatePhotoImageFormat87) (const Tk_PhotoImageFormat87 *formatPtr); /* 274 */ } TkStubs; extern const TkStubs *tkStubsPtr; diff --git a/generic/tkImgGIF.c b/generic/tkImgGIF.c index c91a1c0..f3b09e5 100644 --- a/generic/tkImgGIF.c +++ b/generic/tkImgGIF.c @@ -120,26 +120,29 @@ typedef size_t (WriteBytesFunc) (ClientData clientData, const char *bytes, static int FileMatchGIF(Tcl_Channel chan, const char *fileName, Tcl_Obj *format, int *widthPtr, int *heightPtr, - Tcl_Interp *interp); + Tcl_Interp *interp, Tcl_Obj **metadataPtr); static int FileReadGIF(Tcl_Interp *interp, Tcl_Channel chan, const char *fileName, Tcl_Obj *format, Tk_PhotoHandle imageHandle, int destX, int destY, - int width, int height, int srcX, int srcY); + int width, int height, int srcX, int srcY, + Tcl_Obj **metadataPtr); static int StringMatchGIF(Tcl_Obj *dataObj, Tcl_Obj *format, - int *widthPtr, int *heightPtr, Tcl_Interp *interp); + int *widthPtr, int *heightPtr, Tcl_Interp *interp, + Tcl_Obj **metadataPtr); static int StringReadGIF(Tcl_Interp *interp, Tcl_Obj *dataObj, Tcl_Obj *format, Tk_PhotoHandle imageHandle, int destX, int destY, int width, int height, - int srcX, int srcY); + int srcX, int srcY, Tcl_Obj **metadataPtr); static int FileWriteGIF(Tcl_Interp *interp, const char *filename, - Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr); + Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr, + Tcl_Obj *metadata); static int StringWriteGIF(Tcl_Interp *interp, Tcl_Obj *format, - Tk_PhotoImageBlock *blockPtr); + Tk_PhotoImageBlock *blockPtr, Tcl_Obj *metadata); static int CommonWriteGIF(Tcl_Interp *interp, ClientData clientData, WriteBytesFunc *writeProc, Tcl_Obj *format, - Tk_PhotoImageBlock *blockPtr); + Tk_PhotoImageBlock *blockPtr, Tcl_Obj *metadata); -Tk_PhotoImageFormat tkImgFmtGIF = { +Tk_PhotoImageFormat87 tkImgFmtGIF = { "gif", /* name */ FileMatchGIF, /* fileMatchProc */ StringMatchGIF, /* stringMatchProc */ @@ -353,7 +356,8 @@ FileMatchGIF( int *widthPtr, int *heightPtr, /* The dimensions of the image are returned * here if the file is a valid raw GIF file. */ - Tcl_Interp *dummy) /* not used */ + Tcl_Interp *dummy, /* not used */ + Tcl_Obj **metadataPtr) /* metadata to investigate and to return */ { GIFImageConfig gifConf; (void)fileName; @@ -394,8 +398,9 @@ FileReadGIF( * image to be written to. */ int width, int height, /* Dimensions of block of photo image to be * written to. */ - int srcX, int srcY) /* Coordinates of top-left pixel to be used in + int srcX, int srcY, /* Coordinates of top-left pixel to be used in * image being read. */ + Tcl_Obj **metadataPtr) /* metadata to investigate and to return */ { int fileWidth, fileHeight, imageWidth, imageHeight; unsigned int nBytes; @@ -768,10 +773,22 @@ FileReadGIF( result = TCL_OK; /* - * Set the metadata object. - * This increments the ref count + * Return the metadata object + * Increment the refcount again, as it is decremented below + */ + if (*metadataPtr != NULL) { + Tcl_DecrRefCount(*metadataPtr); + } + *metadataPtr = metadata; + + /* + * If a trash buffer has been allocated, free it now. */ - Tk_PhotoSetMetadata(imageHandle, metadata); + + if (trashBuffer != NULL) { + ckfree(trashBuffer); + } + return result; error: /* @@ -854,7 +871,8 @@ StringMatchGIF( Tcl_Obj *format, /* the image format object, or NULL */ int *widthPtr, /* where to put the string width */ int *heightPtr, /* where to put the string height */ - Tcl_Interp *dummy) /* not used */ + Tcl_Interp *dummy, /* not used */ + Tcl_Obj **metadataPtr) /* metadata to investigate and to return */ { unsigned char *data, header[10]; TkSizeT got, length; @@ -925,7 +943,8 @@ StringReadGIF( Tk_PhotoHandle imageHandle, /* the image to write this data into */ int destX, int destY, /* The rectangular region of the */ int width, int height, /* image to copy */ - int srcX, int srcY) + int srcX, int srcY, + Tcl_Obj **metadataPtr) /* metadata to investigate and to return */ { MFile handle, *hdlPtr = &handle; TkSizeT length; @@ -954,7 +973,7 @@ StringReadGIF( */ return FileReadGIF(interp, (Tcl_Channel) hdlPtr, xferFormat, format, - imageHandle, destX, destY, width, height, srcX, srcY); + imageHandle, destX, destY, width, height, srcX, srcY, metadataPtr); } /* @@ -1866,7 +1885,8 @@ FileWriteGIF( Tcl_Interp *interp, /* Interpreter to use for reporting errors. */ const char *filename, Tcl_Obj *format, - Tk_PhotoImageBlock *blockPtr) + Tk_PhotoImageBlock *blockPtr, + Tcl_Obj *metadata) { Tcl_Channel chan = NULL; int result; @@ -1881,7 +1901,7 @@ FileWriteGIF( return TCL_ERROR; } - result = CommonWriteGIF(interp, chan, WriteToChannel, format, blockPtr); + result = CommonWriteGIF(interp, chan, WriteToChannel, format, blockPtr, metadata); if (Tcl_Close(interp, chan) == TCL_ERROR) { return TCL_ERROR; @@ -1889,19 +1909,22 @@ FileWriteGIF( return result; } +/* New parameter "metadata" is appended at the end */ + static int StringWriteGIF( Tcl_Interp *interp, /* Interpreter to use for reporting errors and * returning the GIF data. */ Tcl_Obj *format, - Tk_PhotoImageBlock *blockPtr) + Tk_PhotoImageBlock *blockPtr, + Tcl_Obj *metadata) { int result; Tcl_Obj *objPtr = Tcl_NewObj(); Tcl_IncrRefCount(objPtr); result = CommonWriteGIF(interp, objPtr, WriteToByteArray, format, - blockPtr); + blockPtr, metadata); if (result == TCL_OK) { Tcl_SetObjResult(interp, objPtr); } @@ -1941,7 +1964,8 @@ CommonWriteGIF( ClientData handle, WriteBytesFunc *writeProc, Tcl_Obj *format, - Tk_PhotoImageBlock *blockPtr) + Tk_PhotoImageBlock *blockPtr, + Tcl_Obj *metadata) { GifWriterState state; int resolution; @@ -2071,6 +2095,42 @@ CommonWriteGIF( c = 0; writeProc(handle, (char *) &c, 1); + /* Check for metadata comment block */ + if (NULL != metadata) { + Tcl_Obj *itemData; + if (TCL_ERROR == Tcl_DictObjGet(interp, metadata, + Tcl_NewStringObj("Comment",-1), + &itemData)) { + return TCL_ERROR; + } + /* Check if there is a Comment key */ + if (itemData != NULL) { + int length; + unsigned char *comment; + comment = Tcl_GetByteArrayFromObj(itemData, &length); + if (length > 0) { + /* write comment header */ + writeProc(handle, (char *) "\x21\fe", 2); + /* write comment blocks */ + for (;length > 0;) { + unsigned char blocklength; + if (length > 255) { + length -=255; + blocklength = 255; + } else { + blocklength = (unsigned char)length; + length = 0; + } + writeProc(handle, (char *) blocklength, 1); + writeProc(handle, (char *) comment, blocklength); + comment += blocklength; + } + /* Block terminator */ + c = 0; + writeProc(handle, (char *) &c, 1); + } + } + } c = GIF_TERMINATOR; writeProc(handle, (char *) &c, 1); diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c index a71ad74..b4ad271 100644 --- a/generic/tkImgPhoto.c +++ b/generic/tkImgPhoto.c @@ -142,6 +142,9 @@ typedef struct { Tk_PhotoImageFormat *oldFormatList; /* Pointer to the first in the list of known * photo image formats.*/ + Tk_PhotoImageFormat87 *formatList87; + /* Pointer to the first in the list of known + * photo image formats in 87 format.*/ int initialized; /* Set to 1 if we've initialized the * structure. */ } ThreadSpecificData; @@ -197,11 +200,15 @@ static char * ImgGetPhoto(PhotoMaster *masterPtr, struct SubcommandOptions *optPtr); static int MatchFileFormat(Tcl_Interp *interp, Tcl_Channel chan, const char *fileName, Tcl_Obj *formatString, + Tcl_Obj **metadataObjPtr, Tk_PhotoImageFormat **imageFormatPtr, + Tk_PhotoImageFormat87 **imageFormat87Ptr, int *widthPtr, int *heightPtr, int *oldformat); static int MatchStringFormat(Tcl_Interp *interp, Tcl_Obj *data, Tcl_Obj *formatString, + Tcl_Obj **metadataObjPtr, Tk_PhotoImageFormat **imageFormatPtr, + Tk_PhotoImageFormat87 **imageFormat87Ptr, int *widthPtr, int *heightPtr, int *oldformat); static const char * GetExtension(const char *path); @@ -226,6 +233,7 @@ PhotoFormatThreadExitProc( ClientData dummy) /* not used */ { Tk_PhotoImageFormat *freePtr; + Tk_PhotoImageFormat87 *freePtr87; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); (void)dummy; @@ -241,12 +249,19 @@ PhotoFormatThreadExitProc( ckfree((char *)freePtr->name); ckfree(freePtr); } + while (tsdPtr->formatList87 != NULL) { + freePtr87 = tsdPtr->formatList87; + tsdPtr->formatList87 = tsdPtr->formatList87->nextPtr; + ckfree((char *)freePtr87->name); + ckfree(freePtr87); + } } /* *---------------------------------------------------------------------- * - * Tk_CreateOldPhotoImageFormat, Tk_CreatePhotoImageFormat -- + * Tk_CreateOldPhotoImageFormat, Tk_CreatePhotoImageFormat, + * Tk_CreatePhotoImageFormat87 -- * * This function is invoked by an image file handler to register a new * photo image format and the functions that handle the new format. The @@ -312,6 +327,30 @@ Tk_CreatePhotoImageFormat( tsdPtr->formatList = copyPtr; } } +void +Tk_CreatePhotoImageFormat87( + const Tk_PhotoImageFormat87 *formatPtr) + /* Structure describing the format. All of the + * fields except "nextPtr" must be filled in + * by caller. */ +{ + Tk_PhotoImageFormat87 *copyPtr; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + + if (!tsdPtr->initialized) { + tsdPtr->initialized = 1; + Tcl_CreateThreadExitHandler(PhotoFormatThreadExitProc, NULL); + } + copyPtr = (Tk_PhotoImageFormat87 *)ckalloc(sizeof(Tk_PhotoImageFormat87)); + *copyPtr = *formatPtr; + /* for compatibility with aMSN: make a copy of formatPtr->name */ + char *name = (char *)ckalloc(strlen(formatPtr->name) + 1); + strcpy(name, formatPtr->name); + copyPtr->name = name; + copyPtr->nextPtr = tsdPtr->formatList87; + tsdPtr->formatList87 = copyPtr; +} /* *---------------------------------------------------------------------- @@ -416,6 +455,7 @@ ImgPhotoCmd( unsigned char *pixelPtr; Tk_PhotoImageBlock block; Tk_PhotoImageFormat *imageFormat; + Tk_PhotoImageFormat87 *imageFormat87; TkSizeT length; int imageWidth, imageHeight, matched, oldformat = 0; Tcl_Channel chan; @@ -900,6 +940,7 @@ ImgPhotoCmd( memset(&options, 0, sizeof(options)); options.name = NULL; options.format = NULL; + options.metadata = NULL; if (ParseSubcommandOptions(&options, interp, OPT_TO|OPT_FORMAT|OPT_METADATA, &index, objc, objv) != TCL_OK) { @@ -914,8 +955,10 @@ ImgPhotoCmd( * See if there's a format that can read the data */ - if (MatchStringFormat(interp, objv[2], options.format, &imageFormat, - &imageWidth, &imageHeight, &oldformat) != TCL_OK) { + if (MatchStringFormat(interp, objv[2], options.format, + &(options.metadata), &imageFormat, + &imageFormat87, &imageWidth, &imageHeight, &oldformat) + != TCL_OK) { return TCL_ERROR; } @@ -938,11 +981,21 @@ ImgPhotoCmd( data = (Tcl_Obj *) Tcl_GetString(data); } - if (imageFormat->stringReadProc(interp, data, format, - (Tk_PhotoHandle) masterPtr, options.toX, options.toY, - options.toX2 - options.toX, - options.toY2 - options.toY, 0, 0) != TCL_OK) { - return TCL_ERROR; + if (imageFormat != NULL) { + if (imageFormat->stringReadProc(interp, data, format, + (Tk_PhotoHandle) masterPtr, options.toX, options.toY, + options.toX2 - options.toX, + options.toY2 - options.toY, 0, 0) != TCL_OK) { + return TCL_ERROR; + } + } else { + if (imageFormat87->stringReadProc(interp, data, format, + (Tk_PhotoHandle) masterPtr, options.toX, options.toY, + options.toX2 - options.toX, + options.toY2 - options.toY, 0, 0, + &(options.metadata)) != TCL_OK) { + return TCL_ERROR; + } } /* * SB: is the next line really needed? The stringReadProc @@ -965,6 +1018,7 @@ ImgPhotoCmd( memset(&options, 0, sizeof(options)); options.name = NULL; options.format = NULL; + options.metadata = NULL; if (ParseSubcommandOptions(&options, interp, OPT_FORMAT | OPT_FROM | OPT_TO | OPT_SHRINK | OPT_METADATA, &index, objc, objv) != TCL_OK) { @@ -1007,8 +1061,10 @@ ImgPhotoCmd( } if (MatchFileFormat(interp, chan, - Tcl_GetString(options.name), options.format, &imageFormat, - &imageWidth, &imageHeight, &oldformat) != TCL_OK) { + Tcl_GetString(options.name), options.format, + &(options.metadata), &imageFormat, + &imageFormat87, &imageWidth, &imageHeight, &oldformat) + != TCL_OK) { Tcl_Close(NULL, chan); return TCL_ERROR; } @@ -1059,10 +1115,18 @@ ImgPhotoCmd( if (oldformat && format) { format = (Tcl_Obj *) Tcl_GetString(format); } - result = imageFormat->fileReadProc(interp, chan, - Tcl_GetString(options.name), - format, (Tk_PhotoHandle) masterPtr, options.toX, - options.toY, width, height, options.fromX, options.fromY); + if (imageFormat != NULL) { + result = imageFormat->fileReadProc(interp, chan, + Tcl_GetString(options.name), + format, (Tk_PhotoHandle) masterPtr, options.toX, + options.toY, width, height, options.fromX, options.fromY); + } else { + result = imageFormat87->fileReadProc(interp, chan, + Tcl_GetString(options.name), + format, (Tk_PhotoHandle) masterPtr, options.toX, + options.toY, width, height, options.fromX, options.fromY, + &(options.metadata)); + } if (chan != NULL) { Tcl_Close(NULL, chan); } @@ -1314,6 +1378,7 @@ ImgPhotoCmd( memset(&options, 0, sizeof(options)); options.name = NULL; options.format = NULL; + options.metadata = NULL; if (ParseSubcommandOptions(&options, interp, OPT_FORMAT | OPT_FROM | OPT_GRAYSCALE | OPT_BACKGROUND | OPT_METADATA, @@ -1359,6 +1424,7 @@ ImgPhotoCmd( matched = 0; redoFormatLookup: + imageFormat87 = NULL; for (imageFormat = tsdPtr->formatList; imageFormat != NULL; imageFormat = imageFormat->nextPtr) { if ((fmtString == NULL) @@ -1384,6 +1450,20 @@ ImgPhotoCmd( } } } + if (imageFormat == NULL) { + oldformat = 0; + for (imageFormat87 = tsdPtr->formatList87; imageFormat87 != NULL; + imageFormat87 = imageFormat87->nextPtr) { + if ((fmtString == NULL) + || (strncasecmp(fmtString, imageFormat87->name, + strlen(imageFormat87->name)) == 0)) { + matched = 1; + if (imageFormat87->fileWriteProc != NULL) { + break; + } + } + } + } if (usedExt && !matched) { /* * If we didn't find one and we're using file extensions as the @@ -1395,7 +1475,7 @@ ImgPhotoCmd( fmtString = NULL; goto redoFormatLookup; } - if (imageFormat == NULL) { + if (imageFormat == NULL && imageFormat87 == NULL) { if (fmtString == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "no available image file format has file writing" @@ -1422,8 +1502,14 @@ ImgPhotoCmd( if (oldformat && format) { format = (Tcl_Obj *) Tcl_GetString(options.format); } - result = imageFormat->fileWriteProc(interp, - Tcl_GetString(options.name), format, &block); + if (imageFormat != NULL) { + result = imageFormat->fileWriteProc(interp, + Tcl_GetString(options.name), format, &block); + } else { + result = imageFormat87->fileWriteProc(interp, + Tcl_GetString(options.name), format, &block, + options.metadata); + } if (options.background) { Tk_FreeColor(options.background); } @@ -1808,6 +1894,7 @@ ImgPhotoConfigureMaster( double oldGamma; Tcl_Channel chan; Tk_PhotoImageFormat *imageFormat; + Tk_PhotoImageFormat87 *imageFormat87; const char **args; args = (const char **)ckalloc((objc + 1) * sizeof(char *)); @@ -2004,8 +2091,9 @@ ImgPhotoConfigureMaster( if ((Tcl_SetChannelOption(interp, chan, "-translation", "binary") != TCL_OK) || (MatchFileFormat(interp, chan, masterPtr->fileString, - masterPtr->format, &imageFormat, &imageWidth, - &imageHeight, &oldformat) != TCL_OK)) { + masterPtr->format, &(masterPtr->metadata), + &imageFormat, &imageFormat87, + &imageWidth, &imageHeight, &oldformat) != TCL_OK)) { Tcl_Close(NULL, chan); goto errorExit; } @@ -2021,9 +2109,18 @@ ImgPhotoConfigureMaster( if (oldformat && tempformat) { tempformat = (Tcl_Obj *) Tcl_GetString(tempformat); } - result = imageFormat->fileReadProc(interp, chan, - masterPtr->fileString, tempformat, (Tk_PhotoHandle) masterPtr, - 0, 0, imageWidth, imageHeight, 0, 0); + if (imageFormat != NULL) { + result = imageFormat->fileReadProc(interp, chan, + masterPtr->fileString, tempformat, + (Tk_PhotoHandle) masterPtr, + 0, 0, imageWidth, imageHeight, 0, 0); + } else { + result = imageFormat87->fileReadProc(interp, chan, + masterPtr->fileString, tempformat, + (Tk_PhotoHandle) masterPtr, + 0, 0, imageWidth, imageHeight, 0, 0, + &(masterPtr->metadata)); + } Tcl_Close(NULL, chan); if (result != TCL_OK) { goto errorExit; @@ -2038,7 +2135,8 @@ ImgPhotoConfigureMaster( || (masterPtr->format != oldFormat))) { if (MatchStringFormat(interp, masterPtr->dataString, - masterPtr->format, &imageFormat, &imageWidth, + masterPtr->format, &(masterPtr->metadata), + &imageFormat, &imageFormat87, &imageWidth, &imageHeight, &oldformat) != TCL_OK) { goto errorExit; } @@ -2056,10 +2154,18 @@ ImgPhotoConfigureMaster( } tempdata = (Tcl_Obj *) Tcl_GetString(tempdata); } - if (imageFormat->stringReadProc(interp, tempdata, tempformat, - (Tk_PhotoHandle) masterPtr, 0, 0, imageWidth, imageHeight, - 0, 0) != TCL_OK) { - goto errorExit; + if (imageFormat != NULL) { + if (imageFormat->stringReadProc(interp, tempdata, tempformat, + (Tk_PhotoHandle) masterPtr, 0, 0, imageWidth, imageHeight, + 0, 0) != TCL_OK) { + goto errorExit; + } + } else { + if (imageFormat87->stringReadProc(interp, tempdata, tempformat, + (Tk_PhotoHandle) masterPtr, 0, 0, imageWidth, imageHeight, + 0, 0, &(masterPtr->metadata)) != TCL_OK) { + goto errorExit; + } } Tcl_ResetResult(interp); @@ -2452,9 +2558,9 @@ ImgPhotoSetSize( * * Results: * A standard TCL return value. If the return value is TCL_OK, a pointer - * to the image format record is returned in *imageFormatPtr, and the - * width and height of the image are returned in *widthPtr and - * *heightPtr. + * to the image format record is returned in *imageFormatPtr or + * *imageFormat87Ptr, and the width and height of the image are returned + * in *widthPtr and *heightPtr. * * Side effects: * None. @@ -2468,16 +2574,23 @@ MatchFileFormat( Tcl_Channel chan, /* The image file, open for reading. */ const char *fileName, /* The name of the image file. */ Tcl_Obj *formatObj, /* User-specified format string, or NULL. */ + Tcl_Obj **metadataObjPtr, /* User-specified metadata and return it */ Tk_PhotoImageFormat **imageFormatPtr, /* A pointer to the photo image format record - * is returned here. */ + * is returned here. For format87, this is set + * to NULL*/ + Tk_PhotoImageFormat87 **imageFormat87Ptr, + /* A pointer to the photo image format87 record + * is returned here. For non format87, this is + * set to NULL*/ int *widthPtr, int *heightPtr, /* The dimensions of the image are returned * here. */ int *oldformat) /* Returns 1 if the old image API is used. */ { - int matched = 0, useoldformat = 0; + int matched = 0, useoldformat = 0, use87format = 0; Tk_PhotoImageFormat *formatPtr; + Tk_PhotoImageFormat87 *format87Ptr; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); const char *formatString = NULL; @@ -2558,27 +2671,78 @@ MatchFileFormat( } } - if (formatPtr == NULL) { - if ((formatObj != NULL) && !matched) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "image file format \"%s\" is not supported", - formatString)); - Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT", - formatString, NULL); - } else { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "couldn't recognize data in image file \"%s\"", - fileName)); - Tcl_SetErrorCode(interp, "TK", "PHOTO", "IMAGE", - "UNRECOGNIZED_DATA", NULL); + /* + * For old and not 87 format, exit now with success + */ + + if (formatPtr != NULL) { + *imageFormatPtr = formatPtr; + *imageFormat87Ptr = NULL; + *oldformat = useoldformat; + (void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET); + return TCL_OK; + } + + /* + * Scan through the table of file format 87 handlers to find one which can + * handle the image. + */ + + for (format87Ptr = tsdPtr->formatList87; format87Ptr != NULL; + format87Ptr = format87Ptr->nextPtr) { + if (formatObj != NULL) { + if (strncasecmp(formatString, + format87Ptr->name, strlen(format87Ptr->name)) != 0) { + continue; + } + matched = 1; + if (format87Ptr->fileMatchProc == NULL) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "-file option isn't supported for %s images", + formatString)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "NOT_FILE_FORMAT", NULL); + return TCL_ERROR; + } + } + if (format87Ptr->fileMatchProc != NULL) { + (void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET); + + if (format87Ptr->fileMatchProc(chan, fileName, formatObj, + widthPtr, heightPtr, interp, metadataObjPtr)) { + if (*widthPtr < 1) { + *widthPtr = 1; + } + if (*heightPtr < 1) { + *heightPtr = 1; + } + *imageFormat87Ptr = format87Ptr; + *imageFormatPtr = NULL; + *oldformat = 0; + (void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET); + return TCL_OK; + } } - return TCL_ERROR; } + + /* + * No matching format found + */ - *imageFormatPtr = formatPtr; - *oldformat = useoldformat; - (void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET); - return TCL_OK; + if ((formatObj != NULL) && !matched) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "image file format \"%s\" is not supported", + formatString)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT", + formatString, NULL); + } else { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "couldn't recognize data in image file \"%s\"", + fileName)); + Tcl_SetErrorCode(interp, "TK", "PHOTO", "IMAGE", + "UNRECOGNIZED_DATA", NULL); + } + return TCL_ERROR; } /* @@ -2593,9 +2757,9 @@ MatchFileFormat( * * Results: * A standard TCL return value. If the return value is TCL_OK, a pointer - * to the image format record is returned in *imageFormatPtr, and the - * width and height of the image are returned in *widthPtr and - * *heightPtr. + * to the image format record is returned in *imageFormatPtr or + * *imageFormat87Ptr, and the width and height of the image are returned + * in *widthPtr and *heightPtr. * * Side effects: * None. @@ -2608,16 +2772,23 @@ MatchStringFormat( Tcl_Interp *interp, /* Interpreter to use for reporting errors. */ Tcl_Obj *data, /* Object containing the image data. */ Tcl_Obj *formatObj, /* User-specified format string, or NULL. */ + Tcl_Obj **metadataObjPtr, /* User-specified metadata and return it */ Tk_PhotoImageFormat **imageFormatPtr, /* A pointer to the photo image format record - * is returned here. */ + * is returned here. For format87, this is set + * to NULL*/ + Tk_PhotoImageFormat87 **imageFormat87Ptr, + /* A pointer to the photo image format87 record + * is returned here. For non format87, this is + * set to NULL*/ int *widthPtr, int *heightPtr, /* The dimensions of the image are returned * here. */ int *oldformat) /* Returns 1 if the old image API is used. */ { - int matched = 0, useoldformat = 0; + int matched = 0, useoldformat = 0, use87format = 0; Tk_PhotoImageFormat *formatPtr, *defaultFormatPtr = NULL; + Tk_PhotoImageFormat87 *format87Ptr = NULL; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); const char *formatString = NULL; @@ -2707,6 +2878,36 @@ MatchStringFormat( } if (formatPtr == NULL) { + useoldformat = 0; + for (format87Ptr = tsdPtr->formatList87; format87Ptr != NULL; + format87Ptr = format87Ptr->nextPtr) { + if (formatObj != NULL) { + if (strncasecmp(formatString, + format87Ptr->name, strlen(format87Ptr->name)) != 0) { + continue; + } + matched = 1; + if (format87Ptr->stringMatchProc == NULL) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "-data option isn't supported for %s images", + formatString)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "NOT_DATA_FORMAT", NULL); + return TCL_ERROR; + } + } + if ((format87Ptr->stringMatchProc != NULL) + && (format87Ptr->stringReadProc != NULL) + && format87Ptr->stringMatchProc( + (Tcl_Obj *) Tcl_GetString(data), + (Tcl_Obj *) formatString, + widthPtr, heightPtr, interp, metadataObjPtr)) { + break; + } + } + } + + if (formatPtr == NULL && format87Ptr == 0) { /* * Try the default format as last resort (only if no -format option * was passed). @@ -2747,6 +2948,7 @@ MatchStringFormat( } *imageFormatPtr = formatPtr; + *imageFormat87Ptr = format87Ptr; *oldformat = useoldformat; /* diff --git a/generic/tkInt.h b/generic/tkInt.h index ab06435..ff35195 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -1056,7 +1056,7 @@ MODULE_SCOPE const Tcl_ObjType tkTextIndexType; MODULE_SCOPE const Tk_SmoothMethod tkBezierSmoothMethod; MODULE_SCOPE Tk_ImageType tkBitmapImageType; -MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtGIF; +MODULE_SCOPE Tk_PhotoImageFormat87 tkImgFmtGIF; MODULE_SCOPE void (*tkHandleEventProc) (XEvent* eventPtr); MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtDefault; MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPNG; diff --git a/generic/tkWindow.c b/generic/tkWindow.c index b3527e6..4287b2a 100644 --- a/generic/tkWindow.c +++ b/generic/tkWindow.c @@ -337,7 +337,7 @@ CreateTopLevelWindow( */ Tk_CreatePhotoImageFormat(&tkImgFmtDefault); - Tk_CreatePhotoImageFormat(&tkImgFmtGIF); + Tk_CreatePhotoImageFormat87(&tkImgFmtGIF); Tk_CreatePhotoImageFormat(&tkImgFmtPNG); Tk_CreatePhotoImageFormat(&tkImgFmtPPM); Tk_CreatePhotoImageFormat(&tkImgFmtSVGnano); |