libnsgif: Update to latest upstream. (#2712)
This commit is contained in:
parent
2fdab9ba70
commit
292ee9a47e
@ -49,10 +49,15 @@ Now you can load the GIF source data into the nsgif object with
|
|||||||
|
|
||||||
This scans the source data and decodes information about each frame, however
|
This scans the source data and decodes information about each frame, however
|
||||||
it doesn't decode any of the bitmap data for the frames. The client may call
|
it doesn't decode any of the bitmap data for the frames. The client may call
|
||||||
`nsgif_data_scan()` multiple times as source data is fetched. Once the
|
`nsgif_data_scan()` multiple times as source data is fetched. The early frames
|
||||||
function has returned `NSGIF_OK` it has enough data to display at least one
|
can be decoded before the later frames are scanned. Frames have to be scanned
|
||||||
frame. The early frames can be decoded before the later frames are scanned.
|
before they can be decoded.
|
||||||
Frames have to be scanned before they can be decoded.
|
|
||||||
|
This function will sometimes return an error. That is OK, and even expected.
|
||||||
|
It is fine to proceed to decoding any frames that are available after a scan.
|
||||||
|
Some errors indicate that there is a flaw in the source GIF data (not at all
|
||||||
|
uncommon, GIF is an ancient format that has had many broken encoders), or that
|
||||||
|
it has reached the end of the source data.
|
||||||
|
|
||||||
> **Note**: The client must not free the data until after calling
|
> **Note**: The client must not free the data until after calling
|
||||||
> `nsgif_destroy()`. You can move the data, e.g. if you realloc to a bigger
|
> `nsgif_destroy()`. You can move the data, e.g. if you realloc to a bigger
|
||||||
|
@ -8,7 +8,7 @@ but within the libvips build system.
|
|||||||
Run `./update.sh` to update this copy of libnsgif from the upstream repo. It
|
Run `./update.sh` to update this copy of libnsgif from the upstream repo. It
|
||||||
will also patch libnsgif.c to prevent it modifying the input.
|
will also patch libnsgif.c to prevent it modifying the input.
|
||||||
|
|
||||||
Last updated 3 Mar 2022.
|
Last updated 8 Mar 2022.
|
||||||
|
|
||||||
# To do
|
# To do
|
||||||
|
|
||||||
|
@ -770,6 +770,34 @@ static nsgif_error nsgif__parse_extension_graphic_control(
|
|||||||
return NSGIF_OK;
|
return NSGIF_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check an app ext identifier and authentication code for loop count extension.
|
||||||
|
*
|
||||||
|
* \param[in] data The data to decode.
|
||||||
|
* \param[in] len Byte length of data.
|
||||||
|
* \return true if extension is a loop count extension.
|
||||||
|
*/
|
||||||
|
static bool nsgif__app_ext_is_loop_count(
|
||||||
|
const uint8_t *data,
|
||||||
|
size_t len)
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
EXT_LOOP_COUNT_BLOCK_SIZE = 0x0b,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(len > 13);
|
||||||
|
(void)(len);
|
||||||
|
|
||||||
|
if (data[1] == EXT_LOOP_COUNT_BLOCK_SIZE) {
|
||||||
|
if (strncmp((const char *)data + 2, "NETSCAPE2.0", 11) == 0 ||
|
||||||
|
strncmp((const char *)data + 2, "ANIMEXTS1.0", 11) == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse the application extension
|
* Parse the application extension
|
||||||
*
|
*
|
||||||
@ -796,10 +824,24 @@ static nsgif_error nsgif__parse_extension_application(
|
|||||||
return NSGIF_ERR_END_OF_DATA;
|
return NSGIF_ERR_END_OF_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((data[1] == 0x0b) &&
|
if (nsgif__app_ext_is_loop_count(data, len)) {
|
||||||
(strncmp((const char *)data + 2, "NETSCAPE2.0", 11) == 0) &&
|
enum {
|
||||||
(data[13] == 0x03) && (data[14] == 0x01)) {
|
EXT_LOOP_COUNT_SUB_BLOCK_SIZE = 0x03,
|
||||||
gif->info.loop_max = data[15] | (data[16] << 8);
|
EXT_LOOP_COUNT_SUB_BLOCK_ID = 0x01,
|
||||||
|
};
|
||||||
|
if ((data[13] == EXT_LOOP_COUNT_SUB_BLOCK_SIZE) &&
|
||||||
|
(data[14] == EXT_LOOP_COUNT_SUB_BLOCK_ID)) {
|
||||||
|
gif->info.loop_max = data[15] | (data[16] << 8);
|
||||||
|
|
||||||
|
/* The value in the source data means repeat N times
|
||||||
|
* after the first implied play. A value of zero has
|
||||||
|
* the special meaning of loop forever. (The only way
|
||||||
|
* to play the animation once is not to have this
|
||||||
|
* extension at all. */
|
||||||
|
if (gif->info.loop_max > 0) {
|
||||||
|
gif->info.loop_max++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NSGIF_OK;
|
return NSGIF_OK;
|
||||||
|
@ -284,7 +284,7 @@ typedef struct nsgif_info {
|
|||||||
uint32_t height;
|
uint32_t height;
|
||||||
/** number of frames decoded */
|
/** number of frames decoded */
|
||||||
uint32_t frame_count;
|
uint32_t frame_count;
|
||||||
/** number of times to loop animation */
|
/** number of times to play animation (zero means loop forever) */
|
||||||
int loop_max;
|
int loop_max;
|
||||||
/** number of animation loops so far */
|
/** number of animation loops so far */
|
||||||
int loop_count;
|
int loop_count;
|
||||||
|
Loading…
Reference in New Issue
Block a user