Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / core / src / fxcodec / fx_lpng / lpng_v163 / fx_pngmem.c
1 #if (!defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_) || defined(_PNG_DECODER_)) && !defined(_USE_ADDIN_) && !defined(_FX_EMB_NOUSE_DECODER_)\r
2 /* pngmem.c - stub functions for memory allocation\r
3  *\r
4  * Last changed in libpng 1.6.0 [February 14, 2013]\r
5  * Copyright (c) 1998-2013 Glenn Randers-Pehrson\r
6  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)\r
7  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)\r
8  *\r
9  * This code is released under the libpng license.\r
10  * For conditions of distribution and use, see the disclaimer\r
11  * and license in png.h\r
12  *\r
13  * This file provides a location for all memory allocation.  Users who\r
14  * need special memory handling are expected to supply replacement\r
15  * functions for png_malloc() and png_free(), and to use\r
16  * png_create_read_struct_2() and png_create_write_struct_2() to\r
17  * identify the replacement functions.\r
18  */\r
19 \r
20 #include "pngpriv.h"\r
21 \r
22 #if defined(_FX_MANAGED_CODE_) && defined(__cplusplus)\r
23 extern "C" {\r
24 #endif\r
25 \r
26 void*   FXMEM_DefaultAlloc(int byte_size, int);\r
27 void    FXMEM_DefaultFree(void* pointer, int);\r
28 \r
29 #if defined(_FX_MANAGED_CODE_) && defined(__cplusplus)\r
30 }\r
31 #endif\r
32 \r
33 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)\r
34 /* Free a png_struct */\r
35 void /* PRIVATE */\r
36 png_destroy_png_struct(png_structrp png_ptr)\r
37 {\r
38    if (png_ptr != NULL)\r
39    {\r
40       /* png_free might call png_error and may certainly call\r
41        * png_get_mem_ptr, so fake a temporary png_struct to support this.\r
42        */\r
43       png_struct dummy_struct = *png_ptr;\r
44       memset(png_ptr, 0, (sizeof *png_ptr));\r
45       png_free(&dummy_struct, png_ptr);\r
46 \r
47 #     ifdef PNG_SETJMP_SUPPORTED\r
48          /* We may have a jmp_buf left to deallocate. */\r
49          png_free_jmpbuf(&dummy_struct);\r
50 #     endif\r
51    }\r
52 }\r
53 \r
54 /* Allocate memory.  For reasonable files, size should never exceed\r
55  * 64K.  However, zlib may allocate more then 64K if you don't tell\r
56  * it not to.  See zconf.h and png.h for more information.  zlib does\r
57  * need to allocate exactly 64K, so whatever you call here must\r
58  * have the ability to do that.\r
59  */\r
60 PNG_FUNCTION(png_voidp,PNGAPI\r
61 png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)\r
62 {\r
63    png_voidp ret;\r
64 \r
65    ret = png_malloc(png_ptr, size);\r
66 \r
67    if (ret != NULL)\r
68       memset(ret, 0, size);\r
69 \r
70    return ret;\r
71 }\r
72 \r
73 /* png_malloc_base, an internal function added at libpng 1.6.0, does the work of\r
74  * allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED.\r
75  * Checking and error handling must happen outside this routine; it returns NULL\r
76  * if the allocation cannot be done (for any reason.)\r
77  */\r
78 PNG_FUNCTION(png_voidp /* PRIVATE */,\r
79 png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size),\r
80    PNG_ALLOCATED)\r
81 {\r
82    /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS\r
83     * allocators have also been removed in 1.6.0, so any 16-bit system now has\r
84     * to implement a user memory handler.  This checks to be sure it isn't\r
85     * called with big numbers.\r
86     */\r
87 #ifdef PNG_USER_MEM_SUPPORTED\r
88    PNG_UNUSED(png_ptr)\r
89 #endif\r
90    if (size > 0 && size <= PNG_SIZE_MAX\r
91 #     ifdef PNG_MAX_MALLOC_64K\r
92          && size <= 65536U\r
93 #     endif\r
94       )\r
95    {\r
96 #ifdef PNG_USER_MEM_SUPPORTED\r
97       if (png_ptr != NULL && png_ptr->malloc_fn != NULL)\r
98          return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size);\r
99 \r
100       else\r
101 #endif\r
102          return FXMEM_DefaultAlloc((int)size, 0);\r
103          //return malloc((size_t)size); /* checked for truncation above */\r
104    }\r
105 \r
106    else\r
107       return NULL;\r
108 }\r
109 \r
110 /* This is really here only to work round a spurious warning in GCC 4.6 and 4.7\r
111  * that arises because of the checks in png_realloc_array that are repeated in\r
112  * png_malloc_array.\r
113  */\r
114 static png_voidp\r
115 png_malloc_array_checked(png_const_structrp png_ptr, int nelements,\r
116    size_t element_size)\r
117 {\r
118    png_alloc_size_t req = nelements; /* known to be > 0 */\r
119 \r
120    if (req <= PNG_SIZE_MAX/element_size)\r
121       return png_malloc_base(png_ptr, req * element_size);\r
122 \r
123    /* The failure case when the request is too large */\r
124    return NULL;\r
125 }\r
126 \r
127 PNG_FUNCTION(png_voidp /* PRIVATE */,\r
128 png_malloc_array,(png_const_structrp png_ptr, int nelements,\r
129    size_t element_size),PNG_ALLOCATED)\r
130 {\r
131    if (nelements <= 0 || element_size == 0)\r
132       png_error(png_ptr, "internal error: array alloc");\r
133 \r
134    return png_malloc_array_checked(png_ptr, nelements, element_size);\r
135 }\r
136 \r
137 PNG_FUNCTION(png_voidp /* PRIVATE */,\r
138 png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array,\r
139    int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED)\r
140 {\r
141    /* These are internal errors: */\r
142    if (add_elements <= 0 || element_size == 0 || old_elements < 0 ||\r
143       (old_array == NULL && old_elements > 0))\r
144       png_error(png_ptr, "internal error: array realloc");\r
145 \r
146    /* Check for overflow on the elements count (so the caller does not have to\r
147     * check.)\r
148     */\r
149    if (add_elements <= INT_MAX - old_elements)\r
150    {\r
151       png_voidp new_array = png_malloc_array_checked(png_ptr,\r
152          old_elements+add_elements, element_size);\r
153 \r
154       if (new_array != NULL)\r
155       {\r
156          /* Because png_malloc_array worked the size calculations below cannot\r
157           * overflow.\r
158           */\r
159          if (old_elements > 0)\r
160             memcpy(new_array, old_array, element_size*(unsigned)old_elements);\r
161 \r
162          memset((char*)new_array + element_size*(unsigned)old_elements, 0,\r
163             element_size*(unsigned)add_elements);\r
164 \r
165          return new_array;\r
166       }\r
167    }\r
168 \r
169    return NULL; /* error */\r
170 }\r
171 \r
172 /* Various functions that have different error handling are derived from this.\r
173  * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate\r
174  * function png_malloc_default is also provided.\r
175  */\r
176 PNG_FUNCTION(png_voidp,PNGAPI\r
177 png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED)\r
178 {\r
179    png_voidp ret;\r
180 \r
181    if (png_ptr == NULL)\r
182       return NULL;\r
183 \r
184    ret = png_malloc_base(png_ptr, size);\r
185 \r
186    if (ret == NULL)\r
187        png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */\r
188 \r
189    return ret;\r
190 }\r
191 \r
192 #ifdef PNG_USER_MEM_SUPPORTED\r
193 PNG_FUNCTION(png_voidp,PNGAPI\r
194 png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size),\r
195    PNG_ALLOCATED PNG_DEPRECATED)\r
196 {\r
197    png_voidp ret;\r
198 \r
199    if (png_ptr == NULL)\r
200       return NULL;\r
201 \r
202    /* Passing 'NULL' here bypasses the application provided memory handler. */\r
203    ret = png_malloc_base(NULL/*use malloc*/, size);\r
204 \r
205    if (ret == NULL)\r
206       png_error(png_ptr, "Out of Memory"); /* 'M' means png_malloc_default */\r
207 \r
208    return ret;\r
209 }\r
210 #endif /* PNG_USER_MEM_SUPPORTED */\r
211 \r
212 /* This function was added at libpng version 1.2.3.  The png_malloc_warn()\r
213  * function will issue a png_warning and return NULL instead of issuing a\r
214  * png_error, if it fails to allocate the requested memory.\r
215  */\r
216 PNG_FUNCTION(png_voidp,PNGAPI\r
217 png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size),\r
218    PNG_ALLOCATED)\r
219 {\r
220    if (png_ptr != NULL)\r
221    {\r
222       png_voidp ret = png_malloc_base(png_ptr, size);\r
223 \r
224       if (ret != NULL)\r
225          return ret;\r
226 \r
227       png_warning(png_ptr, "Out of memory");\r
228    }\r
229 \r
230    return NULL;\r
231 }\r
232 \r
233 /* Free a pointer allocated by png_malloc().  If ptr is NULL, return\r
234  * without taking any action.\r
235  */\r
236 void PNGAPI\r
237 png_free(png_const_structrp png_ptr, png_voidp ptr)\r
238 {\r
239    if (png_ptr == NULL || ptr == NULL)\r
240       return;\r
241 \r
242 #ifdef PNG_USER_MEM_SUPPORTED\r
243    if (png_ptr->free_fn != NULL)\r
244       png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr);\r
245 \r
246    else\r
247       png_free_default(png_ptr, ptr);\r
248 }\r
249 \r
250 PNG_FUNCTION(void,PNGAPI\r
251 png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED)\r
252 {\r
253    if (png_ptr == NULL || ptr == NULL)\r
254       return;\r
255 #endif /* PNG_USER_MEM_SUPPORTED */\r
256 \r
257    FXMEM_DefaultFree(ptr, 0);\r
258    //free(ptr);\r
259 }\r
260 \r
261 #ifdef PNG_USER_MEM_SUPPORTED\r
262 /* This function is called when the application wants to use another method\r
263  * of allocating and freeing memory.\r
264  */\r
265 void PNGAPI\r
266 png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr\r
267   malloc_fn, png_free_ptr free_fn)\r
268 {\r
269    if (png_ptr != NULL)\r
270    {\r
271       png_ptr->mem_ptr = mem_ptr;\r
272       png_ptr->malloc_fn = malloc_fn;\r
273       png_ptr->free_fn = free_fn;\r
274    }\r
275 }\r
276 \r
277 /* This function returns a pointer to the mem_ptr associated with the user\r
278  * functions.  The application should free any memory associated with this\r
279  * pointer before png_write_destroy and png_read_destroy are called.\r
280  */\r
281 png_voidp PNGAPI\r
282 png_get_mem_ptr(png_const_structrp png_ptr)\r
283 {\r
284    if (png_ptr == NULL)\r
285       return NULL;\r
286 \r
287    return png_ptr->mem_ptr;\r
288 }\r
289 #endif /* PNG_USER_MEM_SUPPORTED */\r
290 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */\r
291 #endif\r