1 /*
2 * pngxmem.c - libpng extension: memory allocation utilities.
3 *
4 * Copyright (C) 2003-2017 Cosmin Truta.
5 * This software is distributed under the same licensing and warranty terms
6 * as libpng.
7 */
8
9 #include "pngxutil.h"
10 #include <string.h>
11
12
13 #ifdef PNG_INFO_IMAGE_SUPPORTED
14
15
16 png_bytepp PNGAPI
pngx_malloc_rows(png_structp png_ptr,png_infop info_ptr,int filler)17 pngx_malloc_rows(png_structp png_ptr, png_infop info_ptr, int filler)
18 {
19 return pngx_malloc_rows_extended(png_ptr, info_ptr, 0, filler);
20 }
21
22 png_bytepp PNGAPI
pngx_malloc_rows_extended(png_structp png_ptr,png_infop info_ptr,pngx_alloc_size_t min_row_size,int filler)23 pngx_malloc_rows_extended(png_structp png_ptr, png_infop info_ptr,
24 pngx_alloc_size_t min_row_size, int filler)
25 {
26 pngx_alloc_size_t row_size;
27 png_bytep row;
28 png_bytepp rows;
29 png_uint_32 height, i;
30
31 /* Check the image dimensions and calculate the row size. */
32 height = png_get_image_height(png_ptr, info_ptr);
33 if (height == 0)
34 png_error(png_ptr, "Missing IHDR");
35 row_size = png_get_rowbytes(png_ptr, info_ptr);
36 /* libpng sets row_size to 0 when the width is too large to process. */
37 if (row_size == 0 ||
38 (pngx_alloc_size_t)height > (pngx_alloc_size_t)(-1U) / sizeof(png_bytep))
39 png_error(png_ptr, "Can't handle exceedingly large image dimensions");
40 if (row_size < min_row_size)
41 row_size = min_row_size;
42
43 /* Deallocate the currently-existing rows. */
44 png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
45
46 /* Allocate memory for the row index. */
47 rows = (png_bytepp)png_malloc(png_ptr,
48 (pngx_alloc_size_t)(height * sizeof(png_bytep)));
49 if (rows == NULL)
50 return NULL;
51
52 /* Allocate memory for each row. */
53 for (i = 0; i < height; ++i)
54 {
55 row = (png_bytep)png_malloc(png_ptr, row_size);
56 if (row == NULL)
57 {
58 /* Release the memory allocated up to the point of failure. */
59 while (i > 0)
60 png_free(png_ptr, rows[--i]);
61 png_free(png_ptr, rows);
62 return NULL;
63 }
64 if (filler >= 0)
65 memset(row, filler, row_size);
66 rows[i] = row;
67 }
68
69 /* Set the row pointers. */
70 png_set_rows(png_ptr, info_ptr, rows);
71 return rows;
72 }
73
74 #if 0 /* not necessary */
75 void PNGAPI
76 pngx_free_rows(png_structp png_ptr, png_infop info_ptr)
77 {
78 png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
79 }
80 #endif
81
82
83 #endif /* PNG_INFO_IMAGE_SUPPORTED */
84