summaryrefslogtreecommitdiff
path: root/riscos/gifread.c
diff options
context:
space:
mode:
Diffstat (limited to 'riscos/gifread.c')
-rw-r--r--riscos/gifread.c126
1 files changed, 63 insertions, 63 deletions
diff --git a/riscos/gifread.c b/riscos/gifread.c
index 99b203eec..b0ab90d6d 100644
--- a/riscos/gifread.c
+++ b/riscos/gifread.c
@@ -17,21 +17,21 @@
/* READING GIF FILES
=================
-
+
The functions provided by this file allow for efficient progressive GIF
decoding. Whilst the initialisation does not ensure that there is
sufficient image data to complete the entire frame, it does ensure that
the information provided is valid. Any subsequent attempts to decode an
initialised GIF are guaranteed to succeed, and any bytes of the image
not present are assumed to be totally transparent.
-
+
To begin decoding a GIF, the 'gif' structure must be initialised with
the 'gif_data' and 'buffer_size' set to their initial values. The
'buffer_position' should initially be 0, and will be internally updated
as the decoding commences. The caller should then repeatedly call
gif_initialise() with the structure until the function returns 1, or
no more data is avaliable.
-
+
Once the initialisation has begun, the decoder completes the variables
'frame_count' and 'frame_count_partial'. The former being the total
number of frames that have been successfully initialised, and the
@@ -95,7 +95,7 @@ static int clear_image = FALSE;
/* Initialises any workspace held by the animation and attempts to decode
any information that hasn't already been decoded.
If an error occurs, all previously decoded frames are retained.
-
+
@return -5 for GIF frame data error
-4 for insufficient data to process any more frames
-3 for memory error
@@ -128,13 +128,13 @@ int gif_initialise(struct gif_animation *gif) {
gif->frames = NULL;
gif->local_colour_table = NULL;
gif->global_colour_table = NULL;
-
+
/* The caller may have been lazy and not reset any values
*/
gif->frame_count = 0;
gif->frame_count_partial = 0;
gif->decoded_frame = 0xffffffff;
-
+
/* Check we are a GIF
*/
if (strncmp(gif_data, "GIF", 3) != 0) {
@@ -142,7 +142,7 @@ int gif_initialise(struct gif_animation *gif) {
return GIF_DATA_ERROR;
}
gif_data += 3;
-
+
/* Check we are a GIF type 87a or 89a
*/
if ((strncmp(gif_data, "87a", 3) != 0) &&
@@ -160,9 +160,9 @@ int gif_initialise(struct gif_animation *gif) {
gif->background_colour = gif_data[5];
gif->aspect_ratio = gif_data[6];
gif->dirty_frame = -1;
- gif->loop_count = 0;
+ gif->loop_count = 1;
gif_data += 7;
-
+
/* Allocate some data irrespective of whether we've got any colour tables. We
always get the maximum size in case a GIF is lying to us. It's far better
to give the wrong colours than to trample over some memory somewhere.
@@ -173,7 +173,7 @@ int gif_initialise(struct gif_animation *gif) {
gif_finalise(gif);
return GIF_INSUFFICIENT_MEMORY;
}
-
+
/* Set the first colour to a value that will never occur in reality so we
know if we've processed it
*/
@@ -233,25 +233,25 @@ int gif_initialise(struct gif_animation *gif) {
gif->global_colour_table[1] = 0xffffffff;
}
}
-
+
/* Repeatedly try to decode frames
*/
while ((return_value = gif_initialise_frame(gif)) == 0);
-
+
/* If there was a memory error tell the caller
*/
- if ((return_value == GIF_INSUFFICIENT_MEMORY) ||
+ if ((return_value == GIF_INSUFFICIENT_MEMORY) ||
(return_value == GIF_DATA_ERROR)) {
return return_value;
}
-
+
/* If we didn't have some frames then a GIF_INSUFFICIENT_DATA becomes a
GIF_INSUFFICIENT_FRAME_DATA
*/
if ((return_value == GIF_INSUFFICIENT_DATA) && (gif->frame_count_partial > 0)) {
return_value = GIF_INSUFFICIENT_FRAME_DATA;
}
-
+
/* Return how many we got
*/
return return_value;
@@ -260,7 +260,7 @@ int gif_initialise(struct gif_animation *gif) {
/** Updates the sprite memory size
-
+
@return -3 for a memory error
0 for success
*/
@@ -275,11 +275,11 @@ static int gif_initialise_sprite(struct gif_animation *gif, unsigned int width,
if ((width <= gif->width) && (height <= gif->height)) return 0;
/* Get our maximum values
- */
+ */
max_width = (width > gif->width) ? width : gif->width;
max_height = (height > gif->height) ? height : gif->height;
frame_bytes = max_width * max_height * 4 + sizeof(osspriteop_header);
-
+
/* Allocate some more memory
*/
if ((buffer = (osspriteop_header *)realloc(gif->frame_image, frame_bytes)) == NULL) {
@@ -291,7 +291,7 @@ static int gif_initialise_sprite(struct gif_animation *gif, unsigned int width,
*/
gif->width = max_width;
gif->height = max_height;
-
+
/* Update our sprite image
*/
buffer->size = frame_bytes;
@@ -306,7 +306,7 @@ static int gif_initialise_sprite(struct gif_animation *gif, unsigned int width,
/* Attempts to initialise the next frame
-
+
@return -4 for insufficient data to process the entire frame
-3 for a memory error
-2 for a data error
@@ -363,18 +363,18 @@ int gif_initialise_frame(struct gif_animation *gif) {
*/
gif->frame_holders = frame + 1;
}
-
+
/* Store our frame pointer. We would do it when allocating except we
start off with one frame allocated so we can always use realloc.
*/
gif->frames[frame].frame_pointer = gif->buffer_position;
gif->frames[frame].frame_delay = 100; // Paranoia
gif->frames[frame].redraw_required = 0; // Paranoia
-
+
/* Invalidate any previous decoding we have of this frame
*/
if (gif->decoded_frame == frame) gif->decoded_frame = 0xffffffff;
-
+
/* We pretend to initialise the frames, but really we just skip over all
the data contained within. This is all basically a cut down version of
gif_decode_frame that doesn't have any of the LZW bits in it.
@@ -382,11 +382,11 @@ int gif_initialise_frame(struct gif_animation *gif) {
more_images = 1;
first_image = 1;
while (more_images != 0) {
-
+
/* Ensure we have some data
*/
if ((gif_end - gif_data) < 10) return GIF_INSUFFICIENT_FRAME_DATA;
-
+
/* Decode the extensions
*/
background_action = 0;
@@ -394,7 +394,7 @@ int gif_initialise_frame(struct gif_animation *gif) {
/* Get the extension size
*/
extension_size = gif_data[2];
-
+
/* Check we've enough data for the extension then header
*/
if ((gif_end - gif_data) < (int)(extension_size + 13)) return GIF_INSUFFICIENT_FRAME_DATA;
@@ -405,7 +405,7 @@ int gif_initialise_frame(struct gif_animation *gif) {
gif->frames[frame].frame_delay = gif_data[4] | (gif_data[5] << 8);
background_action = ((gif_data[3] & 0x1c) >> 2);
more_images = ((gif->frames[frame].frame_delay) == 0);
-
+
/* Application extension - handle NETSCAPE2.0 looping
*/
} else if ((gif_data[1] == 0xff) &&
@@ -415,31 +415,31 @@ int gif_initialise_frame(struct gif_animation *gif) {
(gif_data[15] == 0x01)) {
gif->loop_count = gif_data[16] | (gif_data[17] << 8);
}
-
+
/* Move to the first sub-block
*/
gif_data += 2;
-
+
/* Skip all the sub-blocks
*/
while (gif_data[0] != 0x00) {
gif_data += gif_data[0] + 1;
- if ((gif_end - gif_data) < 10) return GIF_INSUFFICIENT_FRAME_DATA;
+ if ((gif_end - gif_data) < 10) return GIF_INSUFFICIENT_FRAME_DATA;
}
gif_data++;
}
-
+
/* We must have at least one image descriptor
*/
if (gif_data[0] != 0x2c) return GIF_FRAME_DATA_ERROR;
-
+
/* Do some simple boundary checking
*/
offset_x = gif_data[1] | (gif_data[2] << 8);
offset_y = gif_data[3] | (gif_data[4] << 8);
width = gif_data[5] | (gif_data[6] << 8);
height = gif_data[7] | (gif_data[8] << 8);
-
+
/* Set up the redraw characteristics. We have to check for extending the area
due to multi-image frames.
*/
@@ -472,34 +472,34 @@ int gif_initialise_frame(struct gif_animation *gif) {
if (gif_initialise_sprite(gif, (offset_x + width), (offset_y + height))) {
return GIF_INSUFFICIENT_MEMORY;
}
-
+
/* Decode the flags
*/
flags = gif_data[9];
colour_table_size = 2 << (flags & 0x07);
-
+
/* Move our data onwards and remember we've got a bit of this frame
*/
gif_data += 10;
gif_bytes = (gif_end - gif_data);
gif->frame_count_partial = frame + 1;
-
+
/* Skip the local colour table
*/
if (flags & 0x80) {
gif_data += 3 * colour_table_size;
if ((gif_bytes = (gif_end - gif_data)) < 0) return GIF_INSUFFICIENT_FRAME_DATA;
}
-
+
/* Ensure we have a correct code size
*/
if (gif_data[0] > GIF_MAX_LZW) return GIF_DATA_ERROR;
-
+
/* Move our data onwards
*/
gif_data++;
if (--gif_bytes < 0) return GIF_INSUFFICIENT_FRAME_DATA;
-
+
/* Repeatedly skip blocks until we get a zero block or run out of data
*/
block_size = 0;
@@ -522,7 +522,7 @@ int gif_initialise_frame(struct gif_animation *gif) {
return GIF_INSUFFICIENT_FRAME_DATA;
} else {
gif->buffer_position = gif_data - gif->gif_data;
- gif->frame_count = frame + 1;
+ gif->frame_count = frame + 1;
if (gif_data[0] == 0x3b) return 1;
}
return 0;
@@ -561,7 +561,7 @@ int gif_decode_frame(struct gif_animation *gif, unsigned int frame) {
*/
if (frame > gif->frame_count_partial) return GIF_INSUFFICIENT_DATA;
if ((!clear_image) && (frame == gif->decoded_frame)) return 0;
-
+
/* If the previous frame was dirty, remove it
*/
if (!clear_image) {
@@ -572,7 +572,7 @@ int gif_decode_frame(struct gif_animation *gif, unsigned int frame) {
}
gif->dirty_frame = -1;
}
-
+
/* Get the start of our frame data and the end of the GIF data
*/
gif_data = gif->gif_data + gif->frames[frame].frame_pointer;
@@ -599,18 +599,18 @@ int gif_decode_frame(struct gif_animation *gif, unsigned int frame) {
*/
save_buffer_position = gif->buffer_position;
gif->buffer_position = gif_data - gif->gif_data;
-
+
/* We've got to do this more than one time if we've got multiple images
*/
more_images = 1;
while (more_images != 0) {
background_action = 0;
-
+
/* Ensure we have some data
*/
gif_data = gif->gif_data + gif->buffer_position;
if ((gif_end - gif_data) < 10) return GIF_INSUFFICIENT_FRAME_DATA;
-
+
/* Decode the extensions
*/
while (gif_data[0] == 0x21) {
@@ -618,7 +618,7 @@ int gif_decode_frame(struct gif_animation *gif, unsigned int frame) {
/* Get the extension size
*/
extension_size = gif_data[2];
-
+
/* Check we've enough data for the extension then header
*/
if ((gif_end - gif_data) < (int)(extension_size + 13)) return GIF_INSUFFICIENT_FRAME_DATA;
@@ -634,12 +634,12 @@ int gif_decode_frame(struct gif_animation *gif, unsigned int frame) {
/* Move to the first sub-block
*/
gif_data += 2;
-
+
/* Skip all the sub-blocks
*/
while (gif_data[0] != 0x00) {
gif_data += gif_data[0] + 1;
- if ((gif_end - gif_data) < 10) return GIF_INSUFFICIENT_FRAME_DATA;
+ if ((gif_end - gif_data) < 10) return GIF_INSUFFICIENT_FRAME_DATA;
}
gif_data++;
}
@@ -658,7 +658,7 @@ int gif_decode_frame(struct gif_animation *gif, unsigned int frame) {
if ((offset_x + width > gif->width) || (offset_y + height > gif->height)) {
return GIF_DATA_ERROR;
}
-
+
/* Decode the flags
*/
flags = gif_data[9];
@@ -669,7 +669,7 @@ int gif_decode_frame(struct gif_animation *gif, unsigned int frame) {
*/
gif_data += 10;
gif_bytes = (int)(gif_end - gif_data);
-
+
/* Set up the colour table
*/
if (flags & 0x80) {
@@ -697,7 +697,7 @@ int gif_decode_frame(struct gif_animation *gif, unsigned int frame) {
if ((background_action == 2) || (background_action == 3)) {
gif->dirty_frame = frame;
}
-
+
/* Initialise the LZW decoding
*/
set_code_size = gif_data[0];
@@ -725,7 +725,7 @@ int gif_decode_frame(struct gif_animation *gif, unsigned int frame) {
decode_y = y + offset_y;
}
frame_scanline = frame_data + offset_x + (decode_y * gif->width);
-
+
/* Rather than decoding pixel by pixel, we try to burst out streams
of data to remove the need for end-of data checks every pixel.
*/
@@ -741,7 +741,7 @@ int gif_decode_frame(struct gif_animation *gif, unsigned int frame) {
} else {
return_value = GIF_INSUFFICIENT_FRAME_DATA;
goto gif_decode_frame_exit;
- }
+ }
/* Try to burst some bytes out
*/
@@ -765,7 +765,7 @@ int gif_decode_frame(struct gif_animation *gif, unsigned int frame) {
memset(frame_scanline, 0x00, width * 4);
}
}
-
+
/* Repeatedly skip blocks until we get a zero block or run out of data
*/
gif_bytes = gif->buffer_size - gif->buffer_position;
@@ -820,7 +820,7 @@ void gif_finalise(struct gif_animation *gif) {
gif->frame_image = NULL;
free(gif->frames);
gif->frames = NULL;
- free(gif->local_colour_table);
+ free(gif->local_colour_table);
gif->local_colour_table = NULL;
free(gif->global_colour_table);
gif->global_colour_table = NULL;
@@ -837,14 +837,14 @@ static int gif_next_LZW(struct gif_animation *gif) {
/* Check we have a valid clear code
*/
if (clear_code >= (1 << GIF_MAX_LZW)) return -2;
-
+
/* Initialise our table
*/
memset(table, 0x00, (1 << GIF_MAX_LZW) * 8);
for (i = 0; i < (unsigned int)clear_code; ++i) {
table[1][i] = i;
}
-
+
/* Update our LZW parameters
*/
code_size = set_code_size + 1;
@@ -883,7 +883,7 @@ static int gif_next_LZW(struct gif_animation *gif) {
if (code == table[0][code]) return(code);
if (((char *)stack_pointer - (char *)stack) >= (int)sizeof(stack)) return(code);
code = table[0][code];
- }
+ }
*stack_pointer++ = firstcode = table[1][code];
@@ -895,7 +895,7 @@ static int gif_next_LZW(struct gif_animation *gif) {
max_code_size = max_code_size << 1;
++code_size;
}
- }
+ }
oldcode = incode;
@@ -920,7 +920,7 @@ static int gif_next_code(struct gif_animation *gif, int code_size) {
if (get_done) return -1;
buf[0] = buf[last_byte - 2];
buf[1] = buf[last_byte - 1];
-
+
/* Get the next block
*/
gif_data = gif->gif_data + gif->buffer_position;
@@ -932,7 +932,7 @@ static int gif_next_code(struct gif_animation *gif, int code_size) {
memcpy(&buf[2], gif_data + 1, count);
}
gif->buffer_position += count + 1;
-
+
/* Update our variables
*/
last_byte = 2 + count;
@@ -940,7 +940,7 @@ static int gif_next_code(struct gif_animation *gif, int code_size) {
lastbit = (2 + count) << 3;
end = curbit + code_size;
}
-
+
j = end >> 3;
i = curbit >> 3;
if (i == j) {
@@ -950,7 +950,7 @@ static int gif_next_code(struct gif_animation *gif, int code_size) {
} else {
ret = (long)buf[i] | ((long)buf[i+1] << 8) | ((long)buf[i+2] << 16);
}
-
+
ret = (ret >> (curbit % 8)) & maskTbl[code_size];
curbit += code_size;
return (int)ret;