OLD | NEW |
1 | 1 |
2 /* pngmem.c - stub functions for memory allocation | 2 /* pngmem.c - stub functions for memory allocation |
3 * | 3 * |
4 * Last changed in libpng 1.6.0 [February 14, 2013] | 4 * Last changed in libpng 1.2.41 [February 25, 2010] |
5 * Copyright (c) 1998-2013 Glenn Randers-Pehrson | 5 * Copyright (c) 1998-2010 Glenn Randers-Pehrson |
6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) | 6 * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) |
7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) | 7 * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) |
8 * | 8 * |
9 * This code is released under the libpng license. | 9 * This code is released under the libpng license. |
10 * For conditions of distribution and use, see the disclaimer | 10 * For conditions of distribution and use, see the disclaimer |
11 * and license in png.h | 11 * and license in png.h |
12 * | 12 * |
13 * This file provides a location for all memory allocation. Users who | 13 * This file provides a location for all memory allocation. Users who |
14 * need special memory handling are expected to supply replacement | 14 * need special memory handling are expected to supply replacement |
15 * functions for png_malloc() and png_free(), and to use | 15 * functions for png_malloc() and png_free(), and to use |
16 * png_create_read_struct_2() and png_create_write_struct_2() to | 16 * png_create_read_struct_2() and png_create_write_struct_2() to |
17 * identify the replacement functions. | 17 * identify the replacement functions. |
18 */ | 18 */ |
19 | 19 |
20 #include "pngpriv.h" | 20 #define PNG_INTERNAL |
21 | 21 #define PNG_NO_PEDANTIC_WARNINGS |
| 22 #include "png.h" |
22 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) | 23 #if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED) |
23 /* Free a png_struct */ | 24 |
| 25 /* Borland DOS special memory handler */ |
| 26 #if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__) |
| 27 /* If you change this, be sure to change the one in png.h also */ |
| 28 |
| 29 /* Allocate memory for a png_struct. The malloc and memset can be replaced |
| 30 by a single call to calloc() if this is thought to improve performance. */ |
| 31 png_voidp /* PRIVATE */ |
| 32 png_create_struct(int type) |
| 33 { |
| 34 #ifdef PNG_USER_MEM_SUPPORTED |
| 35 return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL)); |
| 36 } |
| 37 |
| 38 /* Alternate version of png_create_struct, for use with user-defined malloc. */ |
| 39 png_voidp /* PRIVATE */ |
| 40 png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) |
| 41 { |
| 42 #endif /* PNG_USER_MEM_SUPPORTED */ |
| 43 png_size_t size; |
| 44 png_voidp struct_ptr; |
| 45 |
| 46 if (type == PNG_STRUCT_INFO) |
| 47 size = png_sizeof(png_info); |
| 48 else if (type == PNG_STRUCT_PNG) |
| 49 size = png_sizeof(png_struct); |
| 50 else |
| 51 return (png_get_copyright(NULL)); |
| 52 |
| 53 #ifdef PNG_USER_MEM_SUPPORTED |
| 54 if (malloc_fn != NULL) |
| 55 { |
| 56 png_struct dummy_struct; |
| 57 png_structp png_ptr = &dummy_struct; |
| 58 png_ptr->mem_ptr=mem_ptr; |
| 59 struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size); |
| 60 } |
| 61 else |
| 62 #endif /* PNG_USER_MEM_SUPPORTED */ |
| 63 struct_ptr = (png_voidp)farmalloc(size); |
| 64 if (struct_ptr != NULL) |
| 65 png_memset(struct_ptr, 0, size); |
| 66 return (struct_ptr); |
| 67 } |
| 68 |
| 69 /* Free memory allocated by a png_create_struct() call */ |
24 void /* PRIVATE */ | 70 void /* PRIVATE */ |
25 png_destroy_png_struct(png_structrp png_ptr) | 71 png_destroy_struct(png_voidp struct_ptr) |
26 { | 72 { |
27 if (png_ptr != NULL) | 73 #ifdef PNG_USER_MEM_SUPPORTED |
28 { | 74 png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL); |
29 /* png_free might call png_error and may certainly call | 75 } |
30 * png_get_mem_ptr, so fake a temporary png_struct to support this. | 76 |
31 */ | 77 /* Free memory allocated by a png_create_struct() call */ |
32 png_struct dummy_struct = *png_ptr; | 78 void /* PRIVATE */ |
33 memset(png_ptr, 0, (sizeof *png_ptr)); | 79 png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, |
34 png_free(&dummy_struct, png_ptr); | 80 png_voidp mem_ptr) |
35 | 81 { |
36 # ifdef PNG_SETJMP_SUPPORTED | 82 #endif |
37 /* We may have a jmp_buf left to deallocate. */ | 83 if (struct_ptr != NULL) |
38 png_free_jmpbuf(&dummy_struct); | 84 { |
39 # endif | 85 #ifdef PNG_USER_MEM_SUPPORTED |
| 86 if (free_fn != NULL) |
| 87 { |
| 88 png_struct dummy_struct; |
| 89 png_structp png_ptr = &dummy_struct; |
| 90 png_ptr->mem_ptr=mem_ptr; |
| 91 (*(free_fn))(png_ptr, struct_ptr); |
| 92 return; |
| 93 } |
| 94 #endif /* PNG_USER_MEM_SUPPORTED */ |
| 95 farfree (struct_ptr); |
| 96 } |
| 97 } |
| 98 |
| 99 /* Allocate memory. For reasonable files, size should never exceed |
| 100 * 64K. However, zlib may allocate more then 64K if you don't tell |
| 101 * it not to. See zconf.h and png.h for more information. zlib does |
| 102 * need to allocate exactly 64K, so whatever you call here must |
| 103 * have the ability to do that. |
| 104 * |
| 105 * Borland seems to have a problem in DOS mode for exactly 64K. |
| 106 * It gives you a segment with an offset of 8 (perhaps to store its |
| 107 * memory stuff). zlib doesn't like this at all, so we have to |
| 108 * detect and deal with it. This code should not be needed in |
| 109 * Windows or OS/2 modes, and only in 16 bit mode. This code has |
| 110 * been updated by Alexander Lehmann for version 0.89 to waste less |
| 111 * memory. |
| 112 * |
| 113 * Note that we can't use png_size_t for the "size" declaration, |
| 114 * since on some systems a png_size_t is a 16-bit quantity, and as a |
| 115 * result, we would be truncating potentially larger memory requests |
| 116 * (which should cause a fatal error) and introducing major problems. |
| 117 */ |
| 118 png_voidp /* PRIVATE */ |
| 119 png_calloc(png_structp png_ptr, png_uint_32 size) |
| 120 { |
| 121 png_voidp ret; |
| 122 |
| 123 ret = (png_malloc(png_ptr, size)); |
| 124 if (ret != NULL) |
| 125 png_memset(ret,0,(png_size_t)size); |
| 126 return (ret); |
| 127 } |
| 128 |
| 129 png_voidp PNGAPI |
| 130 png_malloc(png_structp png_ptr, png_uint_32 size) |
| 131 { |
| 132 png_voidp ret; |
| 133 |
| 134 if (png_ptr == NULL || size == 0) |
| 135 return (NULL); |
| 136 |
| 137 #ifdef PNG_USER_MEM_SUPPORTED |
| 138 if (png_ptr->malloc_fn != NULL) |
| 139 ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); |
| 140 else |
| 141 ret = (png_malloc_default(png_ptr, size)); |
| 142 if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) |
| 143 png_error(png_ptr, "Out of memory!"); |
| 144 return (ret); |
| 145 } |
| 146 |
| 147 png_voidp PNGAPI |
| 148 png_malloc_default(png_structp png_ptr, png_uint_32 size) |
| 149 { |
| 150 png_voidp ret; |
| 151 #endif /* PNG_USER_MEM_SUPPORTED */ |
| 152 |
| 153 if (png_ptr == NULL || size == 0) |
| 154 return (NULL); |
| 155 |
| 156 #ifdef PNG_MAX_MALLOC_64K |
| 157 if (size > (png_uint_32)65536L) |
| 158 { |
| 159 png_warning(png_ptr, "Cannot Allocate > 64K"); |
| 160 ret = NULL; |
| 161 } |
| 162 else |
| 163 #endif |
| 164 |
| 165 if (size != (size_t)size) |
| 166 ret = NULL; |
| 167 else if (size == (png_uint_32)65536L) |
| 168 { |
| 169 if (png_ptr->offset_table == NULL) |
| 170 { |
| 171 /* Try to see if we need to do any of this fancy stuff */ |
| 172 ret = farmalloc(size); |
| 173 if (ret == NULL || ((png_size_t)ret & 0xffff)) |
| 174 { |
| 175 int num_blocks; |
| 176 png_uint_32 total_size; |
| 177 png_bytep table; |
| 178 int i; |
| 179 png_byte huge * hptr; |
| 180 |
| 181 if (ret != NULL) |
| 182 { |
| 183 farfree(ret); |
| 184 ret = NULL; |
| 185 } |
| 186 |
| 187 if (png_ptr->zlib_window_bits > 14) |
| 188 num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14)); |
| 189 else |
| 190 num_blocks = 1; |
| 191 if (png_ptr->zlib_mem_level >= 7) |
| 192 num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7)); |
| 193 else |
| 194 num_blocks++; |
| 195 |
| 196 total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16; |
| 197 |
| 198 table = farmalloc(total_size); |
| 199 |
| 200 if (table == NULL) |
| 201 { |
| 202 #ifndef PNG_USER_MEM_SUPPORTED |
| 203 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) |
| 204 png_error(png_ptr, "Out Of Memory."); /* Note "O", "M" */ |
| 205 else |
| 206 png_warning(png_ptr, "Out Of Memory."); |
| 207 #endif |
| 208 return (NULL); |
| 209 } |
| 210 |
| 211 if ((png_size_t)table & 0xfff0) |
| 212 { |
| 213 #ifndef PNG_USER_MEM_SUPPORTED |
| 214 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) |
| 215 png_error(png_ptr, |
| 216 "Farmalloc didn't return normalized pointer"); |
| 217 else |
| 218 png_warning(png_ptr, |
| 219 "Farmalloc didn't return normalized pointer"); |
| 220 #endif |
| 221 return (NULL); |
| 222 } |
| 223 |
| 224 png_ptr->offset_table = table; |
| 225 png_ptr->offset_table_ptr = farmalloc(num_blocks * |
| 226 png_sizeof(png_bytep)); |
| 227 |
| 228 if (png_ptr->offset_table_ptr == NULL) |
| 229 { |
| 230 #ifndef PNG_USER_MEM_SUPPORTED |
| 231 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) |
| 232 png_error(png_ptr, "Out Of memory."); /* Note "O", "m" */ |
| 233 else |
| 234 png_warning(png_ptr, "Out Of memory."); |
| 235 #endif |
| 236 return (NULL); |
| 237 } |
| 238 |
| 239 hptr = (png_byte huge *)table; |
| 240 if ((png_size_t)hptr & 0xf) |
| 241 { |
| 242 hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L); |
| 243 hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */ |
| 244 } |
| 245 for (i = 0; i < num_blocks; i++) |
| 246 { |
| 247 png_ptr->offset_table_ptr[i] = (png_bytep)hptr; |
| 248 hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */ |
| 249 } |
| 250 |
| 251 png_ptr->offset_table_number = num_blocks; |
| 252 png_ptr->offset_table_count = 0; |
| 253 png_ptr->offset_table_count_free = 0; |
| 254 } |
| 255 } |
| 256 |
| 257 if (png_ptr->offset_table_count >= png_ptr->offset_table_number) |
| 258 { |
| 259 #ifndef PNG_USER_MEM_SUPPORTED |
| 260 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) |
| 261 png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */ |
| 262 else |
| 263 png_warning(png_ptr, "Out of Memory."); |
| 264 #endif |
| 265 return (NULL); |
| 266 } |
| 267 |
| 268 ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++]; |
| 269 } |
| 270 else |
| 271 ret = farmalloc(size); |
| 272 |
| 273 #ifndef PNG_USER_MEM_SUPPORTED |
| 274 if (ret == NULL) |
| 275 { |
| 276 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) |
| 277 png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */ |
| 278 else |
| 279 png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */ |
| 280 } |
| 281 #endif |
| 282 |
| 283 return (ret); |
| 284 } |
| 285 |
| 286 /* Free a pointer allocated by png_malloc(). In the default |
| 287 * configuration, png_ptr is not used, but is passed in case it |
| 288 * is needed. If ptr is NULL, return without taking any action. |
| 289 */ |
| 290 void PNGAPI |
| 291 png_free(png_structp png_ptr, png_voidp ptr) |
| 292 { |
| 293 if (png_ptr == NULL || ptr == NULL) |
| 294 return; |
| 295 |
| 296 #ifdef PNG_USER_MEM_SUPPORTED |
| 297 if (png_ptr->free_fn != NULL) |
| 298 { |
| 299 (*(png_ptr->free_fn))(png_ptr, ptr); |
| 300 return; |
| 301 } |
| 302 else |
| 303 png_free_default(png_ptr, ptr); |
| 304 } |
| 305 |
| 306 void PNGAPI |
| 307 png_free_default(png_structp png_ptr, png_voidp ptr) |
| 308 { |
| 309 #endif /* PNG_USER_MEM_SUPPORTED */ |
| 310 |
| 311 if (png_ptr == NULL || ptr == NULL) |
| 312 return; |
| 313 |
| 314 if (png_ptr->offset_table != NULL) |
| 315 { |
| 316 int i; |
| 317 |
| 318 for (i = 0; i < png_ptr->offset_table_count; i++) |
| 319 { |
| 320 if (ptr == png_ptr->offset_table_ptr[i]) |
| 321 { |
| 322 ptr = NULL; |
| 323 png_ptr->offset_table_count_free++; |
| 324 break; |
| 325 } |
| 326 } |
| 327 if (png_ptr->offset_table_count_free == png_ptr->offset_table_count) |
| 328 { |
| 329 farfree(png_ptr->offset_table); |
| 330 farfree(png_ptr->offset_table_ptr); |
| 331 png_ptr->offset_table = NULL; |
| 332 png_ptr->offset_table_ptr = NULL; |
| 333 } |
| 334 } |
| 335 |
| 336 if (ptr != NULL) |
| 337 { |
| 338 farfree(ptr); |
| 339 } |
| 340 } |
| 341 |
| 342 #else /* Not the Borland DOS special memory handler */ |
| 343 |
| 344 /* Allocate memory for a png_struct or a png_info. The malloc and |
| 345 memset can be replaced by a single call to calloc() if this is thought |
| 346 to improve performance noticably. */ |
| 347 png_voidp /* PRIVATE */ |
| 348 png_create_struct(int type) |
| 349 { |
| 350 #ifdef PNG_USER_MEM_SUPPORTED |
| 351 return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL)); |
| 352 } |
| 353 |
| 354 /* Allocate memory for a png_struct or a png_info. The malloc and |
| 355 memset can be replaced by a single call to calloc() if this is thought |
| 356 to improve performance noticably. */ |
| 357 png_voidp /* PRIVATE */ |
| 358 png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr) |
| 359 { |
| 360 #endif /* PNG_USER_MEM_SUPPORTED */ |
| 361 png_size_t size; |
| 362 png_voidp struct_ptr; |
| 363 |
| 364 if (type == PNG_STRUCT_INFO) |
| 365 size = png_sizeof(png_info); |
| 366 else if (type == PNG_STRUCT_PNG) |
| 367 size = png_sizeof(png_struct); |
| 368 else |
| 369 return (NULL); |
| 370 |
| 371 #ifdef PNG_USER_MEM_SUPPORTED |
| 372 if (malloc_fn != NULL) |
| 373 { |
| 374 png_struct dummy_struct; |
| 375 png_structp png_ptr = &dummy_struct; |
| 376 png_ptr->mem_ptr=mem_ptr; |
| 377 struct_ptr = (*(malloc_fn))(png_ptr, size); |
| 378 if (struct_ptr != NULL) |
| 379 png_memset(struct_ptr, 0, size); |
| 380 return (struct_ptr); |
| 381 } |
| 382 #endif /* PNG_USER_MEM_SUPPORTED */ |
| 383 |
| 384 #if defined(__TURBOC__) && !defined(__FLAT__) |
| 385 struct_ptr = (png_voidp)farmalloc(size); |
| 386 #else |
| 387 # if defined(_MSC_VER) && defined(MAXSEG_64K) |
| 388 struct_ptr = (png_voidp)halloc(size, 1); |
| 389 # else |
| 390 struct_ptr = (png_voidp)malloc(size); |
| 391 # endif |
| 392 #endif |
| 393 if (struct_ptr != NULL) |
| 394 png_memset(struct_ptr, 0, size); |
| 395 |
| 396 return (struct_ptr); |
| 397 } |
| 398 |
| 399 |
| 400 /* Free memory allocated by a png_create_struct() call */ |
| 401 void /* PRIVATE */ |
| 402 png_destroy_struct(png_voidp struct_ptr) |
| 403 { |
| 404 #ifdef PNG_USER_MEM_SUPPORTED |
| 405 png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL); |
| 406 } |
| 407 |
| 408 /* Free memory allocated by a png_create_struct() call */ |
| 409 void /* PRIVATE */ |
| 410 png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn, |
| 411 png_voidp mem_ptr) |
| 412 { |
| 413 #endif /* PNG_USER_MEM_SUPPORTED */ |
| 414 if (struct_ptr != NULL) |
| 415 { |
| 416 #ifdef PNG_USER_MEM_SUPPORTED |
| 417 if (free_fn != NULL) |
| 418 { |
| 419 png_struct dummy_struct; |
| 420 png_structp png_ptr = &dummy_struct; |
| 421 png_ptr->mem_ptr=mem_ptr; |
| 422 (*(free_fn))(png_ptr, struct_ptr); |
| 423 return; |
| 424 } |
| 425 #endif /* PNG_USER_MEM_SUPPORTED */ |
| 426 #if defined(__TURBOC__) && !defined(__FLAT__) |
| 427 farfree(struct_ptr); |
| 428 #else |
| 429 # if defined(_MSC_VER) && defined(MAXSEG_64K) |
| 430 hfree(struct_ptr); |
| 431 # else |
| 432 free(struct_ptr); |
| 433 # endif |
| 434 #endif |
40 } | 435 } |
41 } | 436 } |
42 | 437 |
43 /* Allocate memory. For reasonable files, size should never exceed | 438 /* Allocate memory. For reasonable files, size should never exceed |
44 * 64K. However, zlib may allocate more then 64K if you don't tell | 439 * 64K. However, zlib may allocate more then 64K if you don't tell |
45 * it not to. See zconf.h and png.h for more information. zlib does | 440 * it not to. See zconf.h and png.h for more information. zlib does |
46 * need to allocate exactly 64K, so whatever you call here must | 441 * need to allocate exactly 64K, so whatever you call here must |
47 * have the ability to do that. | 442 * have the ability to do that. |
48 */ | 443 */ |
49 PNG_FUNCTION(png_voidp,PNGAPI | 444 |
50 png_calloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) | 445 png_voidp /* PRIVATE */ |
| 446 png_calloc(png_structp png_ptr, png_uint_32 size) |
51 { | 447 { |
52 png_voidp ret; | 448 png_voidp ret; |
53 | 449 |
54 ret = png_malloc(png_ptr, size); | 450 ret = (png_malloc(png_ptr, size)); |
55 | |
56 if (ret != NULL) | 451 if (ret != NULL) |
57 memset(ret, 0, size); | 452 png_memset(ret,0,(png_size_t)size); |
58 | 453 return (ret); |
59 return ret; | 454 } |
60 } | 455 |
61 | 456 png_voidp PNGAPI |
62 /* png_malloc_base, an internal function added at libpng 1.6.0, does the work of | 457 png_malloc(png_structp png_ptr, png_uint_32 size) |
63 * allocating memory, taking into account limits and PNG_USER_MEM_SUPPORTED. | 458 { |
64 * Checking and error handling must happen outside this routine; it returns NULL | 459 png_voidp ret; |
65 * if the allocation cannot be done (for any reason.) | 460 |
66 */ | 461 #ifdef PNG_USER_MEM_SUPPORTED |
67 PNG_FUNCTION(png_voidp /* PRIVATE */, | 462 if (png_ptr == NULL || size == 0) |
68 png_malloc_base,(png_const_structrp png_ptr, png_alloc_size_t size), | 463 return (NULL); |
69 PNG_ALLOCATED) | 464 |
70 { | 465 if (png_ptr->malloc_fn != NULL) |
71 /* Moved to png_malloc_base from png_malloc_default in 1.6.0; the DOS | 466 ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size)); |
72 * allocators have also been removed in 1.6.0, so any 16-bit system now has | 467 else |
73 * to implement a user memory handler. This checks to be sure it isn't | 468 ret = (png_malloc_default(png_ptr, size)); |
74 * called with big numbers. | 469 if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) |
75 */ | 470 png_error(png_ptr, "Out of Memory!"); |
76 #ifdef PNG_USER_MEM_SUPPORTED | 471 return (ret); |
77 PNG_UNUSED(png_ptr) | 472 } |
78 #endif | 473 |
79 if (size > 0 && size <= PNG_SIZE_MAX | 474 png_voidp PNGAPI |
80 # ifdef PNG_MAX_MALLOC_64K | 475 png_malloc_default(png_structp png_ptr, png_uint_32 size) |
81 && size <= 65536U | 476 { |
82 # endif | 477 png_voidp ret; |
83 ) | 478 #endif /* PNG_USER_MEM_SUPPORTED */ |
84 { | 479 |
85 #ifdef PNG_USER_MEM_SUPPORTED | 480 if (png_ptr == NULL || size == 0) |
86 if (png_ptr != NULL && png_ptr->malloc_fn != NULL) | 481 return (NULL); |
87 return png_ptr->malloc_fn(png_constcast(png_structrp,png_ptr), size); | 482 |
88 | 483 #ifdef PNG_MAX_MALLOC_64K |
| 484 if (size > (png_uint_32)65536L) |
| 485 { |
| 486 #ifndef PNG_USER_MEM_SUPPORTED |
| 487 if ((png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) |
| 488 png_error(png_ptr, "Cannot Allocate > 64K"); |
89 else | 489 else |
90 #endif | 490 #endif |
91 return malloc((size_t)size); /* checked for truncation above */ | 491 return NULL; |
92 } | 492 } |
93 | 493 #endif |
94 else | 494 |
95 return NULL; | 495 /* Check for overflow */ |
96 } | 496 #if defined(__TURBOC__) && !defined(__FLAT__) |
97 | 497 if (size != (unsigned long)size) |
98 /* This is really here only to work round a spurious warning in GCC 4.6 and 4.7 | 498 ret = NULL; |
99 * that arises because of the checks in png_realloc_array that are repeated in | 499 else |
100 * png_malloc_array. | 500 ret = farmalloc(size); |
101 */ | 501 #else |
102 static png_voidp | 502 # if defined(_MSC_VER) && defined(MAXSEG_64K) |
103 png_malloc_array_checked(png_const_structrp png_ptr, int nelements, | 503 if (size != (unsigned long)size) |
104 size_t element_size) | 504 ret = NULL; |
105 { | 505 else |
106 png_alloc_size_t req = nelements; /* known to be > 0 */ | 506 ret = halloc(size, 1); |
107 | 507 # else |
108 if (req <= PNG_SIZE_MAX/element_size) | 508 if (size != (size_t)size) |
109 return png_malloc_base(png_ptr, req * element_size); | 509 ret = NULL; |
110 | 510 else |
111 /* The failure case when the request is too large */ | 511 ret = malloc((size_t)size); |
112 return NULL; | 512 # endif |
113 } | 513 #endif |
114 | 514 |
115 PNG_FUNCTION(png_voidp /* PRIVATE */, | 515 #ifndef PNG_USER_MEM_SUPPORTED |
116 png_malloc_array,(png_const_structrp png_ptr, int nelements, | 516 if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0) |
117 size_t element_size),PNG_ALLOCATED) | 517 png_error(png_ptr, "Out of Memory"); |
118 { | 518 #endif |
119 if (nelements <= 0 || element_size == 0) | 519 |
120 png_error(png_ptr, "internal error: array alloc"); | 520 return (ret); |
121 | |
122 return png_malloc_array_checked(png_ptr, nelements, element_size); | |
123 } | |
124 | |
125 PNG_FUNCTION(png_voidp /* PRIVATE */, | |
126 png_realloc_array,(png_const_structrp png_ptr, png_const_voidp old_array, | |
127 int old_elements, int add_elements, size_t element_size),PNG_ALLOCATED) | |
128 { | |
129 /* These are internal errors: */ | |
130 if (add_elements <= 0 || element_size == 0 || old_elements < 0 || | |
131 (old_array == NULL && old_elements > 0)) | |
132 png_error(png_ptr, "internal error: array realloc"); | |
133 | |
134 /* Check for overflow on the elements count (so the caller does not have to | |
135 * check.) | |
136 */ | |
137 if (add_elements <= INT_MAX - old_elements) | |
138 { | |
139 png_voidp new_array = png_malloc_array_checked(png_ptr, | |
140 old_elements+add_elements, element_size); | |
141 | |
142 if (new_array != NULL) | |
143 { | |
144 /* Because png_malloc_array worked the size calculations below cannot | |
145 * overflow. | |
146 */ | |
147 if (old_elements > 0) | |
148 memcpy(new_array, old_array, element_size*(unsigned)old_elements); | |
149 | |
150 memset((char*)new_array + element_size*(unsigned)old_elements, 0, | |
151 element_size*(unsigned)add_elements); | |
152 | |
153 return new_array; | |
154 } | |
155 } | |
156 | |
157 return NULL; /* error */ | |
158 } | |
159 | |
160 /* Various functions that have different error handling are derived from this. | |
161 * png_malloc always exists, but if PNG_USER_MEM_SUPPORTED is defined a separate | |
162 * function png_malloc_default is also provided. | |
163 */ | |
164 PNG_FUNCTION(png_voidp,PNGAPI | |
165 png_malloc,(png_const_structrp png_ptr, png_alloc_size_t size),PNG_ALLOCATED) | |
166 { | |
167 png_voidp ret; | |
168 | |
169 if (png_ptr == NULL) | |
170 return NULL; | |
171 | |
172 ret = png_malloc_base(png_ptr, size); | |
173 | |
174 if (ret == NULL) | |
175 png_error(png_ptr, "Out of memory"); /* 'm' means png_malloc */ | |
176 | |
177 return ret; | |
178 } | |
179 | |
180 #ifdef PNG_USER_MEM_SUPPORTED | |
181 PNG_FUNCTION(png_voidp,PNGAPI | |
182 png_malloc_default,(png_const_structrp png_ptr, png_alloc_size_t size), | |
183 PNG_ALLOCATED PNG_DEPRECATED) | |
184 { | |
185 png_voidp ret; | |
186 | |
187 if (png_ptr == NULL) | |
188 return NULL; | |
189 | |
190 /* Passing 'NULL' here bypasses the application provided memory handler. */ | |
191 ret = png_malloc_base(NULL/*use malloc*/, size); | |
192 | |
193 if (ret == NULL) | |
194 png_error(png_ptr, "Out of Memory"); /* 'M' means png_malloc_default */ | |
195 | |
196 return ret; | |
197 } | |
198 #endif /* PNG_USER_MEM_SUPPORTED */ | |
199 | |
200 /* This function was added at libpng version 1.2.3. The png_malloc_warn() | |
201 * function will issue a png_warning and return NULL instead of issuing a | |
202 * png_error, if it fails to allocate the requested memory. | |
203 */ | |
204 PNG_FUNCTION(png_voidp,PNGAPI | |
205 png_malloc_warn,(png_const_structrp png_ptr, png_alloc_size_t size), | |
206 PNG_ALLOCATED) | |
207 { | |
208 if (png_ptr != NULL) | |
209 { | |
210 png_voidp ret = png_malloc_base(png_ptr, size); | |
211 | |
212 if (ret != NULL) | |
213 return ret; | |
214 | |
215 png_warning(png_ptr, "Out of memory"); | |
216 } | |
217 | |
218 return NULL; | |
219 } | 521 } |
220 | 522 |
221 /* Free a pointer allocated by png_malloc(). If ptr is NULL, return | 523 /* Free a pointer allocated by png_malloc(). If ptr is NULL, return |
222 * without taking any action. | 524 * without taking any action. |
223 */ | 525 */ |
224 void PNGAPI | 526 void PNGAPI |
225 png_free(png_const_structrp png_ptr, png_voidp ptr) | 527 png_free(png_structp png_ptr, png_voidp ptr) |
226 { | 528 { |
227 if (png_ptr == NULL || ptr == NULL) | 529 if (png_ptr == NULL || ptr == NULL) |
228 return; | 530 return; |
229 | 531 |
230 #ifdef PNG_USER_MEM_SUPPORTED | 532 #ifdef PNG_USER_MEM_SUPPORTED |
231 if (png_ptr->free_fn != NULL) | 533 if (png_ptr->free_fn != NULL) |
232 png_ptr->free_fn(png_constcast(png_structrp,png_ptr), ptr); | 534 { |
233 | 535 (*(png_ptr->free_fn))(png_ptr, ptr); |
| 536 return; |
| 537 } |
234 else | 538 else |
235 png_free_default(png_ptr, ptr); | 539 png_free_default(png_ptr, ptr); |
236 } | 540 } |
237 | 541 void PNGAPI |
238 PNG_FUNCTION(void,PNGAPI | 542 png_free_default(png_structp png_ptr, png_voidp ptr) |
239 png_free_default,(png_const_structrp png_ptr, png_voidp ptr),PNG_DEPRECATED) | |
240 { | 543 { |
241 if (png_ptr == NULL || ptr == NULL) | 544 if (png_ptr == NULL || ptr == NULL) |
242 return; | 545 return; |
243 #endif /* PNG_USER_MEM_SUPPORTED */ | 546 |
244 | 547 #endif /* PNG_USER_MEM_SUPPORTED */ |
| 548 |
| 549 #if defined(__TURBOC__) && !defined(__FLAT__) |
| 550 farfree(ptr); |
| 551 #else |
| 552 # if defined(_MSC_VER) && defined(MAXSEG_64K) |
| 553 hfree(ptr); |
| 554 # else |
245 free(ptr); | 555 free(ptr); |
246 } | 556 # endif |
247 | 557 #endif |
248 #ifdef PNG_USER_MEM_SUPPORTED | 558 } |
| 559 |
| 560 #endif /* Not Borland DOS special memory handler */ |
| 561 |
| 562 #ifdef PNG_1_0_X |
| 563 # define png_malloc_warn png_malloc |
| 564 #else |
| 565 /* This function was added at libpng version 1.2.3. The png_malloc_warn() |
| 566 * function will set up png_malloc() to issue a png_warning and return NULL |
| 567 * instead of issuing a png_error, if it fails to allocate the requested |
| 568 * memory. |
| 569 */ |
| 570 png_voidp PNGAPI |
| 571 png_malloc_warn(png_structp png_ptr, png_uint_32 size) |
| 572 { |
| 573 png_voidp ptr; |
| 574 png_uint_32 save_flags; |
| 575 if (png_ptr == NULL) |
| 576 return (NULL); |
| 577 |
| 578 save_flags = png_ptr->flags; |
| 579 png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK; |
| 580 ptr = (png_voidp)png_malloc((png_structp)png_ptr, size); |
| 581 png_ptr->flags=save_flags; |
| 582 return(ptr); |
| 583 } |
| 584 #endif |
| 585 |
| 586 png_voidp PNGAPI |
| 587 png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2, |
| 588 png_uint_32 length) |
| 589 { |
| 590 png_size_t size; |
| 591 |
| 592 size = (png_size_t)length; |
| 593 if ((png_uint_32)size != length) |
| 594 png_error(png_ptr, "Overflow in png_memcpy_check."); |
| 595 |
| 596 return(png_memcpy (s1, s2, size)); |
| 597 } |
| 598 |
| 599 png_voidp PNGAPI |
| 600 png_memset_check (png_structp png_ptr, png_voidp s1, int value, |
| 601 png_uint_32 length) |
| 602 { |
| 603 png_size_t size; |
| 604 |
| 605 size = (png_size_t)length; |
| 606 if ((png_uint_32)size != length) |
| 607 png_error(png_ptr, "Overflow in png_memset_check."); |
| 608 |
| 609 return (png_memset (s1, value, size)); |
| 610 |
| 611 } |
| 612 |
| 613 #ifdef PNG_USER_MEM_SUPPORTED |
249 /* This function is called when the application wants to use another method | 614 /* This function is called when the application wants to use another method |
250 * of allocating and freeing memory. | 615 * of allocating and freeing memory. |
251 */ | 616 */ |
252 void PNGAPI | 617 void PNGAPI |
253 png_set_mem_fn(png_structrp png_ptr, png_voidp mem_ptr, png_malloc_ptr | 618 png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr |
254 malloc_fn, png_free_ptr free_fn) | 619 malloc_fn, png_free_ptr free_fn) |
255 { | 620 { |
256 if (png_ptr != NULL) | 621 if (png_ptr != NULL) |
257 { | 622 { |
258 png_ptr->mem_ptr = mem_ptr; | 623 png_ptr->mem_ptr = mem_ptr; |
259 png_ptr->malloc_fn = malloc_fn; | 624 png_ptr->malloc_fn = malloc_fn; |
260 png_ptr->free_fn = free_fn; | 625 png_ptr->free_fn = free_fn; |
261 } | 626 } |
262 } | 627 } |
263 | 628 |
264 /* This function returns a pointer to the mem_ptr associated with the user | 629 /* This function returns a pointer to the mem_ptr associated with the user |
265 * functions. The application should free any memory associated with this | 630 * functions. The application should free any memory associated with this |
266 * pointer before png_write_destroy and png_read_destroy are called. | 631 * pointer before png_write_destroy and png_read_destroy are called. |
267 */ | 632 */ |
268 png_voidp PNGAPI | 633 png_voidp PNGAPI |
269 png_get_mem_ptr(png_const_structrp png_ptr) | 634 png_get_mem_ptr(png_structp png_ptr) |
270 { | 635 { |
271 if (png_ptr == NULL) | 636 if (png_ptr == NULL) |
272 return NULL; | 637 return (NULL); |
273 | 638 return ((png_voidp)png_ptr->mem_ptr); |
274 return png_ptr->mem_ptr; | |
275 } | 639 } |
276 #endif /* PNG_USER_MEM_SUPPORTED */ | 640 #endif /* PNG_USER_MEM_SUPPORTED */ |
277 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ | 641 #endif /* PNG_READ_SUPPORTED || PNG_WRITE_SUPPORTED */ |
OLD | NEW |