<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE TIP SYSTEM "http://www.tcl.tk/cgi-bin/tct/tip/tipxml.dtd">
<!-- Converted at Tue Jun 18 22:04:54 GMT 2013 -->
<!-- TIP AutoGenerator - written by Donal K. Fellows -->

<TIP number='116'>
<header><title>More Safety for Large Images</title><author address="mailto:donal.k.fellows@man.ac.uk">Donal K. Fellows</author><status type='project' state='final' tclversion="8.5" vote='after'>$Revision: 1.6 $</status><history></history><created day='28' month='oct' year='2002' /></header>
<abstract>This TIP alters the C API for Tk&apos;s images so that failures to allocate sufficient memory for a large image can be handled more gracefully than a straight <emph style="italic">panic()</emph>.</abstract>
<body><section title="Rationale">
<para>Tk&apos;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&apos;t mean that the best course of action is a <emph style="italic">panic()</emph>-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.</para>
<para>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.</para>
</section>
<section title="Proposed Changes">
<para>I propose making the following functions that currently return <emph style="italic">void</emph> return <emph style="italic">int</emph> instead and that they should additionally take a standard <emph style="italic">Tcl_Interp *interp</emph> 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 <emph style="italic">interp</emph> argument to be <emph style="italic">NULL</emph>, though it will be up to the caller to guess why the failure happened.</para>
<itemize><item.i><para><emph style="italic">Tk_PhotoExpand</emph> will become:</para><verbatim><vline encoding='base64'>aW50</vline><vline encoding='base64'>VGtfUGhvdG9FeHBhbmQoVGNsX0ludGVycCAqaW50ZXJwLCBUa19QaG90b0hhbmRsZSBoYW5kbGUs</vline><vline encoding='base64'>ICAgICAgICAgICAgICAgaW50IHdpZHRoLCBpbnQgaGVpZ2h0KQ==</vline></verbatim></item.i><item.i><para><emph style="italic">Tk_PhotoPutBlock</emph> will become:</para><verbatim><vline encoding='base64'>aW50</vline><vline encoding='base64'>VGtfUGhvdG9QdXRCbG9jayhUY2xfSW50ZXJwICppbnRlcnAsIFRrX1Bob3RvSGFuZGxlIGhhbmRsZSw=</vline><vline encoding='base64'>ICAgICAgICAgICAgICAgICBUa19QaG90b0ltYWdlQmxvY2sgKmJsb2NrUHRyLA==</vline><vline encoding='base64'>ICAgICAgICAgICAgICAgICBpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCwgaW50IGNvbXBSdWxlKQ==</vline></verbatim></item.i><item.i><para><emph style="italic">Tk_PhotoPutZoomedBlock</emph> will become:</para><verbatim><vline encoding='base64'>aW50</vline><vline encoding='base64'>VGtfUGhvdG9QdXRab29tZWRCbG9jayhUY2xfSW50ZXJwICppbnRlcnAsIFRrX1Bob3RvSGFuZGxlIGhhbmRsZSw=</vline><vline encoding='base64'>ICAgICAgICAgICAgICAgICAgICAgICBUa19QaG90b0ltYWdlQmxvY2sgKmJsb2NrUHRyLA==</vline><vline encoding='base64'>ICAgICAgICAgICAgICAgICAgICAgICBpbnQgeCwgaW50IHksIGludCB3aWR0aCwgaW50IGhlaWdodCw=</vline><vline encoding='base64'>ICAgICAgICAgICAgICAgICAgICAgICBpbnQgem9vbVgsIGludCB6b29tWSwgaW50IHN1YnNhbXBsZVgsIGludCBzdWJzYW1wbGVZLA==</vline><vline encoding='base64'>ICAgICAgICAgICAgICAgICAgICAgICBpbnQgY29tcFJ1bGUp</vline></verbatim></item.i><item.i><para><emph style="italic">Tk_PhotoSetSize</emph> will become:</para><verbatim><vline encoding='base64'>aW50</vline><vline encoding='base64'>VGtfUGhvdG9TZXRTaXplKFRjbF9JbnRlcnAgKmludGVycCwgVGtfUGhvdG9IYW5kbGUgaGFuZGxlLA==</vline><vline encoding='base64'>ICAgICAgICAgICAgICAgIGludCB3aWR0aCwgaW50IGhlaWdodCk=</vline></verbatim></item.i></itemize>
<para>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.</para>
</section>
<section title="Backward Compatibility">
<para>This TIP also proposes a backward compatibility interface, so that extensions need not be heavily modified to work with new versions of Tk. This is done by leaving backwardly-compatible functions in the old locations in Tk&apos;s stub table and adding a <emph style="italic">#define</emph> to allow selection of the old API with the standard names. I propose doing this when the symbol <emph style="italic">USE_PANIC_ON_PHOTO_ALLOC_FAILURE</emph> is defined; like this, extension authors can switch from compiling with Tk 8.4 to using later versions by adding just one flag to their makefile (or other build script/environment.)</para>
<para>Note that this interacts with the backward-compatability interface defined in <tipref type="text" tip="98"/>; if that is enabled, the back-compat interface defined here is enabled as well.</para>
</section>
<section title="Sample Implementation">
<para><url ref="http://sf.net/tracker/?func=detail&amp;aid=646382&amp;group_id=12997&amp;atid=312997"/></para>
</section>
<section title="Copyright">
<para>This document has been placed in the public domain.</para>
</section>
</body></TIP>
