This is not necessarily the current version of this TIP.
| TIP: | 116 |
| Title: | More Safety for Large Images |
| Version: | $Revision: 1.2 $ |
| Author: | Donal K. Fellows <donal dot fellows at man dot ac dot uk> |
| State: | Draft |
| Type: | Project |
| Tcl-Version: | 8.5 |
| Vote: | Pending |
| Created: | Monday, 28 October 2002 |
This TIP alters the C API for Tk's images so that failures to allocate sufficient memory for a large image can be handled more gracefully than a straight panic().
Tk's image mechanism is nice and flexible, but it can run into problems with a large image. If we consider a square image that is 2000 pixels on each side (such sizes of images are becoming more common with the increasing popularity and sophistication of digital photography), we find it requires about 16MB of memory to load (4 million pixels, four bytes per pixel) but obviously just because an application fails to load that image (or something even larger), it doesn't mean that the best course of action is a panic()-induced crash. Instead, a graceful failure back to the Tcl interpreter would allow for scripts to find a way to report this low-memory situation in a way that users can understand.
The problem with this is that for many of the routes through the Tk image API, there is no way to report a memory allocation failure; currently, the only failure mode is total. This TIP changes this.
I propose making the following functions that currently return void return int instead and that they should additionally take a standard Tcl_Interp *interp argument to allow an error message describing the failure (currently only due to insufficient memory) to be added to the current interpreter. It will not be an error for the interp argument to be NULL, though it will be up to the caller to guess why the failure happened.
Tk_PhotoExpand will become:
int
Tk_PhotoExpand(Tcl_Interp *interp, Tk_PhotoHandle handle,
int width, int height)
Tk_PhotoPutBlock will become:
int
Tk_PhotoPutBlock(Tcl_Interp *interp, Tk_PhotoHandle handle,
Tk_PhotoImageBlock *blockPtr,
int x, int y, int width, int height, int compRule)
Tk_PhotoPutZoomedBlock will become:
int
Tk_PhotoPutZoomedBlock(Tcl_Interp *interp, Tk_PhotoHandle handle,
Tk_PhotoImageBlock *blockPtr,
int x, int y, int width, int height,
int zoomX, int zoomY, int subsampleX, int subsampleY,
int compRule)
Tk_PhotoSetSize will become:
int
Tk_PhotoSetSize(Tcl_Interp *interp, Tk_PhotoHandle handle,
int width, int height)
A backward-compatibility interface will be provided so that with a suitable #define (name to be decided) the old interface can be used. This will make it easier for existing code to work with the new interface where the alternative (dealing with potential error results) is more awkward.
Also note that as a consequence of this, some image-related Tk commands will also gain additional error return situations. Since these all trigger abnormal process termination (and potentially a core-dump too) at the moment, this change in behaviour is believed to be wholly beneficial.
This document has been placed in the public domain.
This is not necessarily the current version of this TIP.