*/
/**
+ * Read data attached to decoding callback
+ */
+typedef struct {
+ unsigned long long size;
+ void *mem;
+} read_data;
+
+/**
+ * Write data attached to encoding callback
+ */
+typedef struct {
+ unsigned long long size;
+ void **mem;
+} write_data;
+
+/**
* format for gif
*/
typedef enum
typedef struct {
unsigned long long delay_time; /**< pre-display delay in 0.01sec units */
- void *data; /**< data */
unsigned long width; /**< width */
unsigned long height; /**< height */
+ void *data; /**< data */
} mm_util_gif_frame_data;
typedef struct {
- mm_util_gif_frame_data **frames; /**< Frames*/
unsigned long width; /**< width */
unsigned long height; /**< height */
unsigned long long size; /**< size */
unsigned int image_count; /**< ImageCount */
+ bool screen_desc_updated; /**< Check if screen description is updated */
+ unsigned int current_count; /**< ImageCount */
+ write_data write_data_ptr; /**< Encoded output data attached to callback */
+ GifFileType *GifFile; /**< GifFile opened*/
+ mm_util_gif_frame_data **frames; /**< Frames*/
} mm_util_gif_data;
/**
#endif
/**
- * This function encodes raw data to gif file
+ * This function creates gif file for output file
*
* @param encoded [in ] pointer of mm_util_gif_data.
- * After using it, please free the allocated memory.
* @param filename [out] output file name on to which the encoded stream will be written.
* @return This function returns zero on success, or negative value with error code.
* @remark image_count should be set to a valid value depending on number of images
* @see mm_util_gif_data
* @since R1, 1.0
*/
-int mm_util_encode_gif_to_file(mm_util_gif_data * encoded, const char *filename);
+int mm_util_encode_open_gif_file(mm_util_gif_data *encoded, const char *filename);
/**
- * This function encodes raw data to gif memory
+ * This function creates gif file for output memory
*
* @param encoded [in ] pointer of mm_util_gif_data.
- * After using it, please free the allocated memory.
* @param filename [out] output file memory on to which the encoded stream will be written.
* @return This function returns zero on success, or negative value with error code.
* @remark image_count should be set to a valid value depending on number of images
* @see mm_util_gif_data
* @since R1, 1.0
*/
-int mm_util_encode_gif_to_memory(mm_util_gif_data * encoded, void **memory);
+int mm_util_encode_open_gif_memory(mm_util_gif_data *encoded, void **data);
+
+/**
+ * This function encodes raw data to gif file/memory
+ *
+ * @param encoded [in ] pointer of mm_util_gif_data.
+ * @param filename [out] output file name on to which the encoded stream will be written.
+ * @return This function returns zero on success, or negative value with error code.
+ * @remark image_count should be set to a valid value depending on number of images
+ * to be encoded in the gif file.
+ * @see mm_util_gif_data
+ * @since R1, 1.0
+ */
+int mm_util_encode_gif(mm_util_gif_data *encoded);
+
+/**
+ * This function closes and deallocates all the memory allocated with giffile.
+ *
+ * @param encoded [in ] pointer of mm_util_gif_data.
+ * @return This function returns zero on success, or negative value with error code.
+ * @remark image_count should be set to a valid value depending on number of images
+ * to be encoded in the gif file.
+ * @see mm_util_gif_data
+ * @since R1, 1.0
+ */
+int mm_util_encode_close_gif(mm_util_gif_data *encoded);
/**
* This function sets width of the encoded image.
#include "mm_util_gif.h"
#include "mm_util_debug.h"
-typedef struct {
- void *mem;
- unsigned long long size;
-} read_data;
-typedef struct {
- void **mem;
- unsigned long long size;
-} write_data;
-
static int __convert_gif_to_rgba(mm_util_gif_data *decoded, ColorMapObject *color_map, GifRowType *screen_buffer, unsigned long width, unsigned long height)
{
unsigned long i, j;
return MM_UTIL_ERROR_NONE;
}
-static void __outputbuffer_free(GifByteType **OutputBuffer, unsigned int image_count)
-{
- unsigned int j;
-
- for (j = 0; j < image_count; j++) {
- if (OutputBuffer[j] != NULL)
- free((char *)OutputBuffer[j]);
- else
- break;
- }
- free(OutputBuffer);
-}
-
static int __write_function(GifFileType *gft, const GifByteType *data, int size)
{
write_data *write_data_ptr = (write_data *) gft->UserData;
return size;
}
-#define ABS(x) ((x) > 0 ? (x) : (-(x)))
-
-static int __write_gif(mm_util_gif_data *encoded, const char *filename, void **data)
+int mm_util_encode_open_gif_file(mm_util_gif_data *encoded, const char *filename)
{
- int ColorMapSize;
- unsigned int i = 0;
- GifByteType *red = NULL, *green = NULL, *blue = NULL, **OutputBuffer = NULL;
- ColorMapObject *OutputColorMap = NULL;
- GifFileType *GifFile;
- write_data write_data_ptr;
- unsigned char background_color;
- int z;
- int minIndex = 0, minDist = 0;
- GifColorType *color;
-
+ mm_util_debug("mm_util_encode_open_gif_file");
if (filename) {
- if ((GifFile = EGifOpenFileName(filename, 0, NULL)) == NULL) {
+ if ((encoded->GifFile = EGifOpenFileName(filename, 0, NULL)) == NULL) {
mm_util_error("could not open file");
- __outputbuffer_free(OutputBuffer, encoded->image_count);
return MM_UTIL_ERROR_INVALID_OPERATION;
}
- } else {
- write_data_ptr.mem = data;
- write_data_ptr.size = 0;
+ } else
+ return MM_UTIL_ERROR_INVALID_PARAMETER;
+
+ return MM_UTIL_ERROR_NONE;
+}
+
+int mm_util_encode_open_gif_memory(mm_util_gif_data *encoded, void **data)
+{
+ mm_util_debug("mm_util_encode_open_gif_memory");
+ if (data) {
+ encoded->write_data_ptr.mem = data;
+ encoded->write_data_ptr.size = 0;
- if ((GifFile = EGifOpen(&write_data_ptr, __write_function, NULL)) == NULL) {
+ if ((encoded->GifFile = EGifOpen(&(encoded->write_data_ptr), __write_function, NULL)) == NULL) {
mm_util_error("could not open File");
- __outputbuffer_free(OutputBuffer, encoded->image_count);
return MM_UTIL_ERROR_INVALID_OPERATION;
}
- }
+ } else
+ return MM_UTIL_ERROR_INVALID_PARAMETER;
- if (EGifPutScreenDesc(GifFile, encoded->frames[0]->width, encoded->frames[0]->height, 8, 0, NULL) == GIF_ERROR) {
- mm_util_error("could not put screen description");
- if (GifFile != NULL)
- EGifCloseFile(GifFile, NULL);
- __outputbuffer_free(OutputBuffer, encoded->image_count);
+ return MM_UTIL_ERROR_NONE;
+}
+
+int mm_util_encode_close_gif(mm_util_gif_data *encoded)
+{
+ mm_util_debug("mm_util_encode_close_gif");
+ if (EGifCloseFile(encoded->GifFile, NULL) == GIF_ERROR) {
+ mm_util_error("could not close file");
return MM_UTIL_ERROR_INVALID_OPERATION;
}
- for (i = 0; i < encoded->image_count; i++) {
- OutputBuffer = (GifByteType **) realloc(OutputBuffer, (i + 1) * sizeof(GifByteType *));
- if ((OutputBuffer[i] = (GifByteType *) malloc(encoded->frames[i]->width * encoded->frames[i]->height * sizeof(GifByteType))) == NULL) {
+ return MM_UTIL_ERROR_NONE;
+}
+
+#define ABS(x) ((x) > 0 ? (x) : (-(x)))
+static int __write_gif(mm_util_gif_data *encoded)
+{
+ int ColorMapSize;
+ unsigned int i = encoded->current_count;
+ GifByteType *red = NULL, *green = NULL, *blue = NULL, *OutputBuffer = NULL;
+ ColorMapObject *OutputColorMap = NULL;
+ unsigned char background_color;
+ int z;
+ int minIndex = 0, minDist = 0;
+ GifColorType *color;
+
+ if (!encoded->screen_desc_updated) {
+ if (EGifPutScreenDesc(encoded->GifFile, encoded->frames[0]->width, encoded->frames[0]->height, 8, 0, NULL) == GIF_ERROR) {
+ mm_util_error("could not put screen description");
+ if (encoded->GifFile != NULL)
+ EGifCloseFile(encoded->GifFile, NULL);
+ return MM_UTIL_ERROR_INVALID_OPERATION;
+ }
+ encoded->screen_desc_updated = true;
+ }
+
+ for (i = encoded->current_count; i < encoded->image_count; i++) {
+ if ((OutputBuffer = (GifByteType *) malloc(encoded->frames[i]->width * encoded->frames[i]->height * sizeof(GifByteType))) == NULL) {
mm_util_error("Failed to allocate memory required, aborted.");
- __outputbuffer_free(OutputBuffer, encoded->image_count);
return MM_UTIL_ERROR_INVALID_OPERATION;
}
if ((OutputColorMap = GifMakeMapObject(ColorMapSize, NULL)) == NULL) {
mm_util_error("could not map object");
- __outputbuffer_free(OutputBuffer, encoded->image_count);
free((char *)red);
free((char *)green);
free((char *)blue);
+ free(OutputBuffer);
return MM_UTIL_ERROR_INVALID_OPERATION;
}
- if (GifQuantizeBuffer(encoded->frames[i]->width, encoded->frames[i]->height, &ColorMapSize, red, green, blue, OutputBuffer[i], OutputColorMap->Colors) == GIF_ERROR) {
+ if (GifQuantizeBuffer(encoded->frames[i]->width, encoded->frames[i]->height, &ColorMapSize, red, green, blue, OutputBuffer, OutputColorMap->Colors) == GIF_ERROR) {
mm_util_error("could not quantize buffer");
- __outputbuffer_free(OutputBuffer, encoded->image_count);
free((char *)red);
free((char *)green);
free((char *)blue);
+ free(OutputBuffer);
return MM_UTIL_ERROR_INVALID_OPERATION;
}
free((char *)red);
}
background_color = minIndex;
- if (__save_buffer_to_gif(GifFile, OutputBuffer[i], encoded->frames[0]->width, encoded->frames[0]->height, encoded->frames[i]->width, encoded->frames[i]->height, encoded->frames[i]->delay_time, OutputColorMap, background_color) != MM_UTIL_ERROR_NONE) {
- __outputbuffer_free(OutputBuffer, encoded->image_count);
+ if (__save_buffer_to_gif(encoded->GifFile, OutputBuffer, encoded->frames[0]->width, encoded->frames[0]->height, encoded->frames[i]->width, encoded->frames[i]->height, encoded->frames[i]->delay_time, OutputColorMap, background_color) != MM_UTIL_ERROR_NONE)
return MM_UTIL_ERROR_INVALID_OPERATION;
- }
- }
- if (EGifCloseFile(GifFile, NULL) == GIF_ERROR) {
- mm_util_error("could not close file");
- __outputbuffer_free(OutputBuffer, encoded->image_count);
- return MM_UTIL_ERROR_INVALID_OPERATION;
+ free(OutputBuffer);
+ encoded->current_count++;
}
-
- encoded->size = write_data_ptr.size;
- __outputbuffer_free(OutputBuffer, encoded->image_count);
+ encoded->size = encoded->write_data_ptr.size;
return MM_UTIL_ERROR_NONE;
}
-int mm_util_encode_gif_to_file(mm_util_gif_data *encoded, const char *fpath)
-{
- int ret;
-
- mm_util_debug("mm_util_encode_to_gif");
-
- ret = __write_gif(encoded, fpath, NULL);
-
- return ret;
-}
-
-int mm_util_encode_gif_to_memory(mm_util_gif_data *encoded, void **data)
+int mm_util_encode_gif(mm_util_gif_data *encoded)
{
int ret;
- mm_util_debug("mm_util_encode_to_memory");
- ret = __write_gif(encoded, NULL, data);
+ mm_util_debug("mm_util_encode_gif");
+ ret = __write_gif(encoded);
return ret;
}