mirror of
				https://github.com/webmproject/libwebp.git
				synced 2025-10-31 18:35:41 +01:00 
			
		
		
		
	Merge "WebPCheckMalloc() and WebPCheckCalloc():" into 0.2.0
This commit is contained in:
		| @@ -47,6 +47,7 @@ LOCAL_SRC_FILES := \ | ||||
|     src/utils/quant_levels.c \ | ||||
|     src/utils/rescaler.c \ | ||||
|     src/utils/thread.c \ | ||||
|     src/utils/utils.c \ | ||||
|  | ||||
| LOCAL_CFLAGS := -Wall -DANDROID -DHAVE_MALLOC_H -DHAVE_PTHREAD \ | ||||
|                 -DNOT_HAVE_LOG2 -DWEBP_USE_THREAD \ | ||||
|   | ||||
| @@ -199,6 +199,7 @@ UTILS_OBJS = \ | ||||
|     $(DIROBJ)\utils\quant_levels.obj \ | ||||
|     $(DIROBJ)\utils\rescaler.obj \ | ||||
|     $(DIROBJ)\utils\thread.obj \ | ||||
|     $(DIROBJ)\utils\utils.obj \ | ||||
|  | ||||
| LIBWEBP_OBJS = $(DEC_OBJS) $(DSP_OBJS) $(ENC_OBJS) $(UTILS_OBJS) $(LIBWEBP_OBJS) | ||||
| LIBWEBPMUX_OBJS = $(MUX_OBJS) $(LIBWEBPMUX_OBJS) | ||||
|   | ||||
| @@ -117,13 +117,12 @@ static int CountOccurrences(const char* arglist[], int list_length, | ||||
| } | ||||
|  | ||||
| static const char* const kErrorMessages[] = { | ||||
|   "WEBP_MUX_ERROR", "WEBP_MUX_NOT_FOUND", "WEBP_MUX_INVALID_ARGUMENT", | ||||
|   "WEBP_MUX_INVALID_PARAMETER", "WEBP_MUX_BAD_DATA", "WEBP_MUX_MEMORY_ERROR", | ||||
|   "WEBP_MUX_NOT_ENOUGH_DATA" | ||||
|   "WEBP_MUX_NOT_FOUND", "WEBP_MUX_INVALID_ARGUMENT", "WEBP_MUX_BAD_DATA", | ||||
|   "WEBP_MUX_MEMORY_ERROR", "WEBP_MUX_NOT_ENOUGH_DATA" | ||||
| }; | ||||
|  | ||||
| static const char* ErrorString(WebPMuxError err) { | ||||
|   assert(err <= WEBP_MUX_ERROR && err >= WEBP_MUX_NOT_ENOUGH_DATA); | ||||
|   assert(err <= WEBP_MUX_NOT_FOUND && err >= WEBP_MUX_NOT_ENOUGH_DATA); | ||||
|   return kErrorMessages[-err]; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -130,6 +130,7 @@ UTILS_OBJS = \ | ||||
|     src/utils/quant_levels.o \ | ||||
|     src/utils/rescaler.o \ | ||||
|     src/utils/thread.o \ | ||||
|     src/utils/utils.o \ | ||||
|  | ||||
| LIBWEBP_OBJS = $(DEC_OBJS) $(DSP_OBJS) $(ENC_OBJS) $(UTILS_OBJS) | ||||
| LIBWEBPMUX_OBJS = $(MUX_OBJS) | ||||
|   | ||||
| @@ -17,15 +17,6 @@ | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| // Object to store metadata about images. | ||||
| typedef struct { | ||||
|   int x_offset_; | ||||
|   int y_offset_; | ||||
|   int duration_; | ||||
|   int width_; | ||||
|   int height_; | ||||
| } WebPImageInfo; | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Life of a mux object. | ||||
|  | ||||
| @@ -111,8 +102,7 @@ static WebPMuxError MuxAddChunk(WebPMux* const mux, uint32_t nth, uint32_t tag, | ||||
|   const WebPData chunk_data = { data, size }; | ||||
|   assert(mux != NULL); | ||||
|   assert(size <= MAX_CHUNK_PAYLOAD); | ||||
|  | ||||
|   if (idx == IDX_NIL) return WEBP_MUX_INVALID_PARAMETER; | ||||
|   assert(idx != IDX_NIL); | ||||
|   return MuxSet(mux, idx, nth, &chunk_data, copy_data); | ||||
| } | ||||
|  | ||||
| @@ -158,7 +148,7 @@ static WebPMuxError CreateFrameTileData(const WebPData* const image, | ||||
| static WebPMuxError GetImageData(const WebPData* const bitstream, | ||||
|                                  WebPData* const image, WebPData* const alpha, | ||||
|                                  int* const is_lossless) { | ||||
|   memset(alpha, 0, sizeof(*alpha));  // Default: no alpha. | ||||
|   WebPDataInit(alpha);  // Default: no alpha. | ||||
|   if (bitstream->size_ < TAG_SIZE || | ||||
|       memcmp(bitstream->bytes_, "RIFF", TAG_SIZE)) { | ||||
|     // It is NOT webp file data. Return input data as is. | ||||
| @@ -360,7 +350,7 @@ static WebPMuxError MuxPushFrameTileInternal( | ||||
|   if (err != WEBP_MUX_OK) return err; | ||||
|   image_tag = is_lossless ? kChunks[IDX_VP8L].tag : kChunks[IDX_VP8].tag; | ||||
|  | ||||
|   memset(&frame_tile, 0, sizeof(frame_tile)); | ||||
|   WebPDataInit(&frame_tile); | ||||
|   ChunkInit(&chunk); | ||||
|   MuxImageInit(&wpi); | ||||
|  | ||||
| @@ -505,30 +495,19 @@ WebPMuxError MuxGetImageWidthHeight(const WebPChunk* const image_chunk, | ||||
| } | ||||
|  | ||||
| static WebPMuxError GetImageInfo(const WebPMuxImage* const wpi, | ||||
|                                  WebPImageInfo* const image_info) { | ||||
|                                  int* const x_offset, int* const y_offset, | ||||
|                                  int* const duration, | ||||
|                                  int* const width, int* const height) { | ||||
|   const WebPChunk* const image_chunk = wpi->img_; | ||||
|   const WebPChunk* const frame_tile_chunk = wpi->header_; | ||||
|   WebPMuxError err; | ||||
|   int x_offset, y_offset, duration; | ||||
|   int width, height; | ||||
|  | ||||
|   memset(image_info, 0, sizeof(*image_info)); | ||||
|  | ||||
|   // Get offsets and duration from FRM/TILE chunk. | ||||
|   err = GetFrameTileInfo(frame_tile_chunk, &x_offset, &y_offset, &duration); | ||||
|   const WebPMuxError err = | ||||
|       GetFrameTileInfo(frame_tile_chunk, x_offset, y_offset, duration); | ||||
|   if (err != WEBP_MUX_OK) return err; | ||||
|  | ||||
|   // Get width and height from VP8/VP8L chunk. | ||||
|   err = MuxGetImageWidthHeight(image_chunk, &width, &height); | ||||
|   if (err != WEBP_MUX_OK) return err; | ||||
|  | ||||
|   // All OK: fill up image_info. | ||||
|   image_info->x_offset_ = x_offset; | ||||
|   image_info->y_offset_ = y_offset; | ||||
|   image_info->duration_ = duration; | ||||
|   image_info->width_    = width; | ||||
|   image_info->height_   = height; | ||||
|   return WEBP_MUX_OK; | ||||
|   return MuxGetImageWidthHeight(image_chunk, width, height); | ||||
| } | ||||
|  | ||||
| static WebPMuxError GetImageCanvasWidthHeight( | ||||
| @@ -536,7 +515,7 @@ static WebPMuxError GetImageCanvasWidthHeight( | ||||
|     int* const width, int* const height) { | ||||
|   WebPMuxImage* wpi = NULL; | ||||
|   assert(mux != NULL); | ||||
|   assert(width && height); | ||||
|   assert(width != NULL && height != NULL); | ||||
|  | ||||
|   wpi = mux->images_; | ||||
|   assert(wpi != NULL); | ||||
| @@ -548,17 +527,18 @@ static WebPMuxError GetImageCanvasWidthHeight( | ||||
|     int64_t image_area = 0; | ||||
|     // Aggregate the bounding box for animation frames & tiled images. | ||||
|     for (; wpi != NULL; wpi = wpi->next_) { | ||||
|       WebPImageInfo image_info; | ||||
|       const WebPMuxError err = GetImageInfo(wpi, &image_info); | ||||
|       const int max_x_pos = image_info.x_offset_ + image_info.width_; | ||||
|       const int max_y_pos = image_info.y_offset_ + image_info.height_; | ||||
|       int x_offset, y_offset, duration, w, h; | ||||
|       const WebPMuxError err = GetImageInfo(wpi, &x_offset, &y_offset, | ||||
|                                             &duration, &w, &h); | ||||
|       const int max_x_pos = x_offset + w; | ||||
|       const int max_y_pos = y_offset + h; | ||||
|       if (err != WEBP_MUX_OK) return err; | ||||
|       assert(image_info.x_offset_ < MAX_POSITION_OFFSET); | ||||
|       assert(image_info.y_offset_ < MAX_POSITION_OFFSET); | ||||
|       assert(x_offset < MAX_POSITION_OFFSET); | ||||
|       assert(y_offset < MAX_POSITION_OFFSET); | ||||
|  | ||||
|       if (max_x_pos > max_x) max_x = max_x_pos; | ||||
|       if (max_y_pos > max_y) max_y = max_y_pos; | ||||
|       image_area += (image_info.width_ * image_info.height_); | ||||
|       image_area += w * h; | ||||
|     } | ||||
|     *width = max_x; | ||||
|     *height = max_y; | ||||
|   | ||||
| @@ -212,17 +212,23 @@ uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst) { | ||||
| //------------------------------------------------------------------------------ | ||||
| // Manipulation of a WebPData object. | ||||
|  | ||||
| void WebPDataInit(WebPData* webp_data) { | ||||
|   if (webp_data != NULL) { | ||||
|     memset(webp_data, 0, sizeof(*webp_data)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void WebPDataClear(WebPData* webp_data) { | ||||
|   if (webp_data != NULL) { | ||||
|     free((void*)webp_data->bytes_); | ||||
|     memset(webp_data, 0, sizeof(*webp_data)); | ||||
|     WebPDataInit(webp_data); | ||||
|   } | ||||
| } | ||||
|  | ||||
| int WebPDataCopy(const WebPData* src, WebPData* dst) { | ||||
|   if (src == NULL || dst == NULL) return 0; | ||||
|  | ||||
|   memset(dst, 0, sizeof(*dst)); | ||||
|   WebPDataInit(dst); | ||||
|   if (src->bytes_ != NULL && src->size_ != 0) { | ||||
|     dst->bytes_ = (uint8_t*)malloc(src->size_); | ||||
|     if (dst->bytes_ == NULL) return 0; | ||||
|   | ||||
| @@ -37,7 +37,7 @@ static WebPMuxError MuxGet(const WebPMux* const mux, CHUNK_INDEX idx, | ||||
|                            uint32_t nth, WebPData* const data) { | ||||
|   assert(mux != NULL); | ||||
|   assert(!IsWPI(kChunks[idx].id)); | ||||
|   memset(data, 0, sizeof(*data)); | ||||
|   WebPDataInit(data); | ||||
|  | ||||
|   SWITCH_ID_LIST(IDX_VP8X, mux->vp8x_); | ||||
|   SWITCH_ID_LIST(IDX_ICCP, mux->iccp_); | ||||
|   | ||||
| @@ -20,6 +20,8 @@ libwebputils_la_SOURCES += rescaler.c | ||||
| libwebputils_la_SOURCES += rescaler.h | ||||
| libwebputils_la_SOURCES += thread.c | ||||
| libwebputils_la_SOURCES += thread.h | ||||
| libwebputils_la_SOURCES += utils.c | ||||
| libwebputils_la_SOURCES += utils.h | ||||
|  | ||||
| libwebputilsinclude_HEADERS = ../webp/types.h | ||||
| libwebputilsincludedir = $(includedir)/webp | ||||
|   | ||||
							
								
								
									
										44
									
								
								src/utils/utils.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/utils/utils.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| // Copyright 2012 Google Inc. All Rights Reserved. | ||||
| // | ||||
| // This code is licensed under the same terms as WebM: | ||||
| //  Software License Agreement:  http://www.webmproject.org/license/software/ | ||||
| //  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/ | ||||
| // ----------------------------------------------------------------------------- | ||||
| // | ||||
| // Misc. common utility functions | ||||
| // | ||||
| // Author: Skal (pascal.massimino@gmail.com) | ||||
|  | ||||
| #include <stdlib.h> | ||||
| #include "./utils.h" | ||||
|  | ||||
| #if defined(__cplusplus) || defined(c_plusplus) | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Checked memory allocation | ||||
|  | ||||
| static int CheckSizeArguments(uint64_t nmemb, size_t size) { | ||||
|   const uint64_t total_size = nmemb * size; | ||||
|   if (nmemb == 0) return 1; | ||||
|   if ((uint64_t)size > WEBP_MAX_ALLOCABLE_MEMORY / nmemb) return 0; | ||||
|   if (total_size != (size_t)total_size) return 0; | ||||
|   return 1; | ||||
| } | ||||
|  | ||||
| void* WebPSafeMalloc(uint64_t nmemb, size_t size) { | ||||
|   if (!CheckSizeArguments(nmemb, size)) return NULL; | ||||
|   return malloc((size_t)(nmemb * size)); | ||||
| } | ||||
|  | ||||
| void* WebPSafeCalloc(uint64_t nmemb, size_t size) { | ||||
|   if (!CheckSizeArguments(nmemb, size)) return NULL; | ||||
|   return calloc((size_t)nmemb, size); | ||||
| } | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| #if defined(__cplusplus) || defined(c_plusplus) | ||||
| }    // extern "C" | ||||
| #endif | ||||
							
								
								
									
										44
									
								
								src/utils/utils.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/utils/utils.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| // Copyright 2012 Google Inc. All Rights Reserved. | ||||
| // | ||||
| // This code is licensed under the same terms as WebM: | ||||
| //  Software License Agreement:  http://www.webmproject.org/license/software/ | ||||
| //  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/ | ||||
| // ----------------------------------------------------------------------------- | ||||
| // | ||||
| // Misc. common utility functions | ||||
| // | ||||
| // Author: Skal (pascal.massimino@gmail.com) | ||||
|  | ||||
| #ifndef WEBP_UTILS_UTILS_H_ | ||||
| #define WEBP_UTILS_UTILS_H_ | ||||
|  | ||||
| #include "../webp/types.h" | ||||
|  | ||||
| #if defined(__cplusplus) || defined(c_plusplus) | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
| // Memory allocation | ||||
|  | ||||
| // This is the maximum memory amount that libwebp will ever try to allocate. | ||||
| #define WEBP_MAX_ALLOCABLE_MEMORY (1ULL << 40) | ||||
|  | ||||
| // size-checking safe malloc/calloc: verify that the requested size is not too | ||||
| // large, or return NULL. You don't need to call these for constructs like | ||||
| // malloc(sizeof(foo)), but only if there's picture-dependent size involved | ||||
| // somewhere (like: malloc(num_pixels * sizeof(*something))). That's why this | ||||
| // safe malloc() borrows the signature from calloc(), pointing at the dangerous | ||||
| // underlying multiply involved. | ||||
| void* WebPSafeMalloc(uint64_t nmemb, size_t size); | ||||
| // Note that WebPSafeCalloc() expects the second argument type to be 'size_t' | ||||
| // in order to favor the "calloc(num_foo, sizeof(foo))" pattern. | ||||
| void* WebPSafeCalloc(uint64_t nmemb, size_t size); | ||||
|  | ||||
| //------------------------------------------------------------------------------ | ||||
|  | ||||
| #if defined(__cplusplus) || defined(c_plusplus) | ||||
| }    // extern "C" | ||||
| #endif | ||||
|  | ||||
| #endif  /* WEBP_UTILS_UTILS_H_ */ | ||||
| @@ -56,13 +56,11 @@ extern "C" { | ||||
| // Error codes | ||||
| typedef enum { | ||||
|   WEBP_MUX_OK                 =  1, | ||||
|   WEBP_MUX_ERROR              =  0, | ||||
|   WEBP_MUX_NOT_FOUND          = -1, | ||||
|   WEBP_MUX_INVALID_ARGUMENT   = -2, | ||||
|   WEBP_MUX_INVALID_PARAMETER  = -3, | ||||
|   WEBP_MUX_BAD_DATA           = -4, | ||||
|   WEBP_MUX_MEMORY_ERROR       = -5, | ||||
|   WEBP_MUX_NOT_ENOUGH_DATA    = -6 | ||||
|   WEBP_MUX_NOT_FOUND          =  0, | ||||
|   WEBP_MUX_INVALID_ARGUMENT   = -1, | ||||
|   WEBP_MUX_BAD_DATA           = -2, | ||||
|   WEBP_MUX_MEMORY_ERROR       = -3, | ||||
|   WEBP_MUX_NOT_ENOUGH_DATA    = -4 | ||||
| } WebPMuxError; | ||||
|  | ||||
| // Flag values for different features used in VP8X chunk. | ||||
| @@ -100,6 +98,9 @@ typedef struct { | ||||
| //------------------------------------------------------------------------------ | ||||
| // Manipulation of a WebPData object. | ||||
|  | ||||
| // Initializes the contents of the 'webp_data' object with default values. | ||||
| WEBP_EXTERN(void) WebPDataInit(WebPData* webp_data); | ||||
|  | ||||
| // Clears the contents of the 'webp_data' object by calling free(). Does not | ||||
| // deallocate the object itself. | ||||
| WEBP_EXTERN(void) WebPDataClear(WebPData* webp_data); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user