<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Mar 9, 2016 at 12:30 AM, Bernhard R. Fischer <span dir="ltr"><<a href="mailto:bf@abenteuerland.at" target="_blank">bf@abenteuerland.at</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On 2016-03-04 19:16, Bryce Harrington wrote:<br>
> On Thu, Mar 03, 2016 at 03:52:12PM +0100, Bernhard R. Fischer wrote:<br>
>> On 2016-03-01 06:58, Bernhard R. Fischer wrote:<br>
>>> The conclusion of this discussion was to slightly adapt the meaning of<br>
>>> the return value of the read_func_t as follows:<br>
>>><br>
>>><br>
>>> The read function shall return the negative number of bytes which have<br>
>>> NOT been read, i.e. - (length - bytes_read).<br>
>>> This is that a full read will return 0 which is CAIRO_STATUS_SUCCESS.<br>
>>> Truncated reads return something between -1 and -length. On error,<br>
>>> CAIRO_STATUS_READ_ERROR is returned (which is a positive value).<br>
>>><br>
>>><br>
>>><br>
>>> If there is the consent of the core devs we should adapt the docs.<br>
>>><br>
>>> I'll have a look at cairo_image_surface_create_from_png_stream() if<br>
>>> there is a change necessary.<br>
>>><br>
>>> Bernhard<br>
>>><br>
>><br>
>><br>
>><br>
>> As promised, I just had a look at implementation of the PNG code of<br>
>> Cairo (cairo-png.c).<br>
>><br>
>> If a read_func() returns a negative value as suggested, the whole<br>
>> program will be aborted because of a call to assert() in<br>
>> _cairo_surface_create_in_error() (cairo-surface.c) which in turn is<br>
>> called by the PNG error handler png_simple_error_callback() in cairo-png.c.<br>
>><br>
>><br>
>> I suggest the following tiny patch (to cairo-1.14.6) to fix this:<br>
>><br>
>><br>
>> *** cairo-png_orig.c    2016-03-03 15:41:35.565400515 +0100<br>
>> --- cairo-png.c 2016-03-03 15:42:05.301547969 +0100<br>
>> ***************<br>
>> *** 525,530 ****<br>
>> --- 525,531 ----<br>
>>       png_closure = png_get_io_ptr (png);<br>
>>       status = png_closure->read_func (png_closure->closure, data, size);<br>
>>       if (unlikely (status)) {<br>
>> +        if ((int) status < 0) status = CAIRO_STATUS_READ_ERROR;<br>
>>         cairo_status_t *error = png_get_error_ptr (png);<br>
>>         if (*error == CAIRO_STATUS_SUCCESS)<br>
>>             *error = status;<br>
><br>
> This would probably need to look more like:<br>
><br>
>     status = png_closure->read_func (png_closure->closure, data, size);<br>
>     if (unlikely (status)) {<br>
>         cairo_status_t *error;<br>
>         if ((int) status < 0)<br>
>             status = CAIRO_STATUS_READ_ERROR;<br>
>         error = png_get_error_ptr (png);<br>
<br>
<br>
</div></div>Why? It makes no difference.<br></blockquote><div><br></div><div>The variables have to be declared first before any statements (required by older C compilers).<br></div><div> </div></div></div></div>