summaryrefslogtreecommitdiff
path: root/src/libnsgif.c
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2017-01-27 15:10:47 +0000
committerVincent Sanders <vince@kyllikki.org>2017-01-27 15:10:47 +0000
commit5c5ae3e63a28b5222874017f7ec12d62403063bb (patch)
tree8cc7d9f8b0c716a6babb70f0c1b75cfcc0a2f5c6 /src/libnsgif.c
parentf4ccd56c717d4ee3f2f2a0791b5f8134d8a1645e (diff)
downloadlibnsgif-5c5ae3e63a28b5222874017f7ec12d62403063bb.tar.gz
libnsgif-5c5ae3e63a28b5222874017f7ec12d62403063bb.tar.bz2
remove forward declarations
Diffstat (limited to 'src/libnsgif.c')
-rw-r--r--src/libnsgif.c262
1 files changed, 129 insertions, 133 deletions
diff --git a/src/libnsgif.c b/src/libnsgif.c
index 9f9bd8d..dc2aabb 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -62,16 +62,10 @@
#define GIF_BLOCK_TERMINATOR 0x00
#define GIF_TRAILER 0x3b
+/** standard GIF header size */
#define GIF_STANDARD_HEADER_SIZE 13
-/* Internal GIF routines */
-static gif_result gif_initialise_sprite(gif_animation *gif, unsigned int width, unsigned int height);
-static gif_result gif_initialise_frame(gif_animation *gif);
-static gif_result gif_initialise_frame_extensions(gif_animation *gif, const int frame);
-static gif_result gif_skip_frame_extensions(gif_animation *gif);
-static unsigned int gif_interlaced_line(int height, int y);
-
-
+/** LZW parameters */
struct lzw_s {
unsigned char buf[4];
unsigned char *direct;
@@ -358,6 +352,131 @@ gif_initialise_sprite(gif_animation *gif,
/**
+ * Attempts to initialise the frame's extensions
+ *
+ * \param gif The animation context
+ * \param frame The frame number
+ * @return GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the
+ * frame GIF_OK for successful initialisation.
+ */
+static gif_result
+gif_initialise_frame_extensions(gif_animation *gif, const int frame)
+{
+ unsigned char *gif_data, *gif_end;
+ int gif_bytes;
+ unsigned int block_size;
+
+ /* Get our buffer position etc. */
+ gif_data = (unsigned char *)(gif->gif_data + gif->buffer_position);
+ gif_end = (unsigned char *)(gif->gif_data + gif->buffer_size);
+
+ /* Initialise the extensions */
+ while (gif_data < gif_end && gif_data[0] == GIF_EXTENSION_INTRODUCER) {
+ ++gif_data;
+ if ((gif_bytes = (gif_end - gif_data)) < 1) {
+ return GIF_INSUFFICIENT_FRAME_DATA;
+ }
+
+ /* Switch on extension label */
+ switch (gif_data[0]) {
+ case GIF_EXTENSION_GRAPHIC_CONTROL:
+ /* 6-byte Graphic Control Extension is:
+ *
+ * +0 CHAR Graphic Control Label
+ * +1 CHAR Block Size
+ * +2 CHAR __Packed Fields__
+ * 3BITS Reserved
+ * 3BITS Disposal Method
+ * 1BIT User Input Flag
+ * 1BIT Transparent Color Flag
+ * +3 SHORT Delay Time
+ * +5 CHAR Transparent Color Index
+ */
+ if (gif_bytes < 6) {
+ return GIF_INSUFFICIENT_FRAME_DATA;
+ }
+
+ gif->frames[frame].frame_delay = gif_data[3] | (gif_data[4] << 8);
+ if (gif_data[2] & GIF_TRANSPARENCY_MASK) {
+ gif->frames[frame].transparency = true;
+ gif->frames[frame].transparency_index = gif_data[5];
+ }
+ gif->frames[frame].disposal_method = ((gif_data[2] & GIF_DISPOSAL_MASK) >> 2);
+ /* I have encountered documentation and GIFs in the
+ * wild that use 0x04 to restore the previous frame,
+ * rather than the officially documented 0x03. I
+ * believe some (older?) software may even actually
+ * export this way. We handle this as a type of
+ * "quirks" mode.
+ */
+ if (gif->frames[frame].disposal_method == GIF_FRAME_QUIRKS_RESTORE) {
+ gif->frames[frame].disposal_method = GIF_FRAME_RESTORE;
+ }
+ gif_data += (2 + gif_data[1]);
+ break;
+
+ case GIF_EXTENSION_APPLICATION:
+ /* 14-byte+ Application Extension is:
+ *
+ * +0 CHAR Application Extension Label
+ * +1 CHAR Block Size
+ * +2 8CHARS Application Identifier
+ * +10 3CHARS Appl. Authentication Code
+ * +13 1-256 Application Data (Data sub-blocks)
+ */
+ if (gif_bytes < 17) {
+ return GIF_INSUFFICIENT_FRAME_DATA;
+ }
+ if ((gif_data[1] == 0x0b) &&
+ (strncmp((const char *) gif_data + 2,
+ "NETSCAPE2.0", 11) == 0) &&
+ (gif_data[13] == 0x03) &&
+ (gif_data[14] == 0x01)) {
+ gif->loop_count = gif_data[15] | (gif_data[16] << 8);
+ }
+ gif_data += (2 + gif_data[1]);
+ break;
+
+ case GIF_EXTENSION_COMMENT:
+ /* Move the pointer to the first data sub-block Skip 1
+ * byte for the extension label
+ */
+ ++gif_data;
+ break;
+
+ default:
+ /* Move the pointer to the first data sub-block Skip 2
+ * bytes for the extension label and size fields Skip
+ * the extension size itself
+ */
+ if (gif_bytes < 2) {
+ return GIF_INSUFFICIENT_FRAME_DATA;
+ }
+ gif_data += (2 + gif_data[1]);
+ }
+
+ /* Repeatedly skip blocks until we get a zero block or run out
+ * of data This data is ignored by this gif decoder
+ */
+ gif_bytes = (gif_end - gif_data);
+ block_size = 0;
+ while (gif_data < gif_end && gif_data[0] != GIF_BLOCK_TERMINATOR) {
+ block_size = gif_data[0] + 1;
+ if ((gif_bytes -= block_size) < 0) {
+ return GIF_INSUFFICIENT_FRAME_DATA;
+ }
+ gif_data += block_size;
+ }
+ ++gif_data;
+ }
+
+ /* Set buffer position and return */
+ gif->buffer_position = (gif_data - gif->gif_data);
+ return GIF_OK;
+}
+
+
+/**
* Attempts to initialise the next frame
*
* \param gif The animation context
@@ -593,129 +712,6 @@ static gif_result gif_initialise_frame(gif_animation *gif)
}
-/**
- * Attempts to initialise the frame's extensions
- *
- * \param gif The animation context
- * \param frame The frame number
- * @return GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the
- * frame GIF_OK for successful initialisation.
- */
-static gif_result
-gif_initialise_frame_extensions(gif_animation *gif, const int frame)
-{
- unsigned char *gif_data, *gif_end;
- int gif_bytes;
- unsigned int block_size;
-
- /* Get our buffer position etc. */
- gif_data = (unsigned char *)(gif->gif_data + gif->buffer_position);
- gif_end = (unsigned char *)(gif->gif_data + gif->buffer_size);
-
- /* Initialise the extensions */
- while (gif_data < gif_end && gif_data[0] == GIF_EXTENSION_INTRODUCER) {
- ++gif_data;
- if ((gif_bytes = (gif_end - gif_data)) < 1) {
- return GIF_INSUFFICIENT_FRAME_DATA;
- }
-
- /* Switch on extension label */
- switch (gif_data[0]) {
- case GIF_EXTENSION_GRAPHIC_CONTROL:
- /* 6-byte Graphic Control Extension is:
- *
- * +0 CHAR Graphic Control Label
- * +1 CHAR Block Size
- * +2 CHAR __Packed Fields__
- * 3BITS Reserved
- * 3BITS Disposal Method
- * 1BIT User Input Flag
- * 1BIT Transparent Color Flag
- * +3 SHORT Delay Time
- * +5 CHAR Transparent Color Index
- */
- if (gif_bytes < 6) {
- return GIF_INSUFFICIENT_FRAME_DATA;
- }
-
- gif->frames[frame].frame_delay = gif_data[3] | (gif_data[4] << 8);
- if (gif_data[2] & GIF_TRANSPARENCY_MASK) {
- gif->frames[frame].transparency = true;
- gif->frames[frame].transparency_index = gif_data[5];
- }
- gif->frames[frame].disposal_method = ((gif_data[2] & GIF_DISPOSAL_MASK) >> 2);
- /* I have encountered documentation and GIFs in the
- * wild that use 0x04 to restore the previous frame,
- * rather than the officially documented 0x03. I
- * believe some (older?) software may even actually
- * export this way. We handle this as a type of
- * "quirks" mode.
- */
- if (gif->frames[frame].disposal_method == GIF_FRAME_QUIRKS_RESTORE) {
- gif->frames[frame].disposal_method = GIF_FRAME_RESTORE;
- }
- gif_data += (2 + gif_data[1]);
- break;
-
- case GIF_EXTENSION_APPLICATION:
- /* 14-byte+ Application Extension is:
- *
- * +0 CHAR Application Extension Label
- * +1 CHAR Block Size
- * +2 8CHARS Application Identifier
- * +10 3CHARS Appl. Authentication Code
- * +13 1-256 Application Data (Data sub-blocks)
- */
- if (gif_bytes < 17) {
- return GIF_INSUFFICIENT_FRAME_DATA;
- }
- if ((gif_data[1] == 0x0b) &&
- (strncmp((const char *) gif_data + 2,
- "NETSCAPE2.0", 11) == 0) &&
- (gif_data[13] == 0x03) &&
- (gif_data[14] == 0x01)) {
- gif->loop_count = gif_data[15] | (gif_data[16] << 8);
- }
- gif_data += (2 + gif_data[1]);
- break;
-
- case GIF_EXTENSION_COMMENT:
- /* Move the pointer to the first data sub-block Skip 1
- * byte for the extension label
- */
- ++gif_data;
- break;
-
- default:
- /* Move the pointer to the first data sub-block Skip 2
- * bytes for the extension label and size fields Skip
- * the extension size itself
- */
- if (gif_bytes < 2) {
- return GIF_INSUFFICIENT_FRAME_DATA;
- }
- gif_data += (2 + gif_data[1]);
- }
-
- /* Repeatedly skip blocks until we get a zero block or run out
- * of data This data is ignored by this gif decoder
- */
- gif_bytes = (gif_end - gif_data);
- block_size = 0;
- while (gif_data < gif_end && gif_data[0] != GIF_BLOCK_TERMINATOR) {
- block_size = gif_data[0] + 1;
- if ((gif_bytes -= block_size) < 0) {
- return GIF_INSUFFICIENT_FRAME_DATA;
- }
- gif_data += block_size;
- }
- ++gif_data;
- }
-
- /* Set buffer position and return */
- gif->buffer_position = (gif_data - gif->gif_data);
- return GIF_OK;
-}
/**
@@ -1278,7 +1274,7 @@ gif_result gif_initialise(gif_animation *gif, size_t size, unsigned char *data)
* termination block) Although generally useless, the GIF
* specification does not expressly prohibit this
*/
- if (gif->buffer_size == 14) {
+ if (gif->buffer_size == (GIF_STANDARD_HEADER_SIZE + 1)) {
if (gif_data[0] == GIF_TRAILER) {
return GIF_OK;
} else {
@@ -1286,7 +1282,7 @@ gif_result gif_initialise(gif_animation *gif, size_t size, unsigned char *data)
}
}
- /* Initialise enough workspace for 4 frames initially */
+ /* Initialise enough workspace for a frame */
if ((gif->frames = (gif_frame *)malloc(sizeof(gif_frame))) == NULL) {
gif_finalise(gif);
return GIF_INSUFFICIENT_MEMORY;