Skip to content

Commit 292ee9a

Browse files
authored
libnsgif: Update to latest upstream. (#2712)
1 parent 2fdab9b commit 292ee9a

File tree

4 files changed

+57
-10
lines changed

4 files changed

+57
-10
lines changed

libvips/foreign/libnsgif/README-ns.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,15 @@ Now you can load the GIF source data into the nsgif object with
4949

5050
This scans the source data and decodes information about each frame, however
5151
it doesn't decode any of the bitmap data for the frames. The client may call
52-
`nsgif_data_scan()` multiple times as source data is fetched. Once the
53-
function has returned `NSGIF_OK` it has enough data to display at least one
54-
frame. The early frames can be decoded before the later frames are scanned.
55-
Frames have to be scanned before they can be decoded.
52+
`nsgif_data_scan()` multiple times as source data is fetched. The early frames
53+
can be decoded before the later frames are scanned. Frames have to be scanned
54+
before they can be decoded.
55+
56+
This function will sometimes return an error. That is OK, and even expected.
57+
It is fine to proceed to decoding any frames that are available after a scan.
58+
Some errors indicate that there is a flaw in the source GIF data (not at all
59+
uncommon, GIF is an ancient format that has had many broken encoders), or that
60+
it has reached the end of the source data.
5661

5762
> **Note**: The client must not free the data until after calling
5863
> `nsgif_destroy()`. You can move the data, e.g. if you realloc to a bigger

libvips/foreign/libnsgif/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ but within the libvips build system.
88
Run `./update.sh` to update this copy of libnsgif from the upstream repo. It
99
will also patch libnsgif.c to prevent it modifying the input.
1010

11-
Last updated 3 Mar 2022.
11+
Last updated 8 Mar 2022.
1212

1313
# To do
1414

libvips/foreign/libnsgif/gif.c

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,34 @@ static nsgif_error nsgif__parse_extension_graphic_control(
770770
return NSGIF_OK;
771771
}
772772

773+
/**
774+
* Check an app ext identifier and authentication code for loop count extension.
775+
*
776+
* \param[in] data The data to decode.
777+
* \param[in] len Byte length of data.
778+
* \return true if extension is a loop count extension.
779+
*/
780+
static bool nsgif__app_ext_is_loop_count(
781+
const uint8_t *data,
782+
size_t len)
783+
{
784+
enum {
785+
EXT_LOOP_COUNT_BLOCK_SIZE = 0x0b,
786+
};
787+
788+
assert(len > 13);
789+
(void)(len);
790+
791+
if (data[1] == EXT_LOOP_COUNT_BLOCK_SIZE) {
792+
if (strncmp((const char *)data + 2, "NETSCAPE2.0", 11) == 0 ||
793+
strncmp((const char *)data + 2, "ANIMEXTS1.0", 11) == 0) {
794+
return true;
795+
}
796+
}
797+
798+
return false;
799+
}
800+
773801
/**
774802
* Parse the application extension
775803
*
@@ -796,10 +824,24 @@ static nsgif_error nsgif__parse_extension_application(
796824
return NSGIF_ERR_END_OF_DATA;
797825
}
798826

799-
if ((data[1] == 0x0b) &&
800-
(strncmp((const char *)data + 2, "NETSCAPE2.0", 11) == 0) &&
801-
(data[13] == 0x03) && (data[14] == 0x01)) {
802-
gif->info.loop_max = data[15] | (data[16] << 8);
827+
if (nsgif__app_ext_is_loop_count(data, len)) {
828+
enum {
829+
EXT_LOOP_COUNT_SUB_BLOCK_SIZE = 0x03,
830+
EXT_LOOP_COUNT_SUB_BLOCK_ID = 0x01,
831+
};
832+
if ((data[13] == EXT_LOOP_COUNT_SUB_BLOCK_SIZE) &&
833+
(data[14] == EXT_LOOP_COUNT_SUB_BLOCK_ID)) {
834+
gif->info.loop_max = data[15] | (data[16] << 8);
835+
836+
/* The value in the source data means repeat N times
837+
* after the first implied play. A value of zero has
838+
* the special meaning of loop forever. (The only way
839+
* to play the animation once is not to have this
840+
* extension at all. */
841+
if (gif->info.loop_max > 0) {
842+
gif->info.loop_max++;
843+
}
844+
}
803845
}
804846

805847
return NSGIF_OK;

libvips/foreign/libnsgif/nsgif.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ typedef struct nsgif_info {
284284
uint32_t height;
285285
/** number of frames decoded */
286286
uint32_t frame_count;
287-
/** number of times to loop animation */
287+
/** number of times to play animation (zero means loop forever) */
288288
int loop_max;
289289
/** number of animation loops so far */
290290
int loop_count;

0 commit comments

Comments
 (0)