summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoroehhar <harald.oehlmann@elmicron.de>2020-05-30 21:53:44 (GMT)
committeroehhar <harald.oehlmann@elmicron.de>2020-05-30 21:53:44 (GMT)
commit9da42ea63840166de7979c55a3ba0476cfb245c4 (patch)
treec5c09e3ec1a6bc4f7cb9919b80bbbc26745036d3
parentdd57d00f5c65deebb5bea67608c586856c2c2b7a (diff)
downloadtk-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.decls5
-rw-r--r--generic/tk.h56
-rw-r--r--generic/tkDecls.h8
-rw-r--r--generic/tkImgGIF.c102
-rw-r--r--generic/tkImgPhoto.c312
-rw-r--r--generic/tkInt.h2
-rw-r--r--generic/tkWindow.c2
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);