eliminate some unused code
[imager.git] / limits.c
CommitLineData
77157728
TC
1/*
2=head1 NAME
3
4limits.c - manages data/functions for limiting the sizes of images read from files.
5
6=head1 SYNOPSIS
7
8 // user code
9 if (!i_set_image_file_limits(max_width, max_height, max_bytes)) {
10 // error
11 }
12 i_get_image_file_limits(&max_width, &max_height, &max_bytes);
13
14 // file reader implementations
15 if (!i_int_check_image_file_limits(width, height, channels, sizeof(i_sample_t))) {
16 // error handling
17 }
18
19=head1 DESCRIPTION
20
21Manage limits for image files read by Imager.
22
23Setting a value of zero means that limit will be ignored.
24
25 */
26
d896d49c 27#define IMAGER_NO_CONTEXT
92bda632 28#include "imageri.h"
77157728 29
87deb14c 30/*
d03fd5a4
TC
31=item i_set_image_file_limits(width, height, bytes)
32
87deb14c
TC
33=category Files
34=synopsis i_set_image_file_limits(500, 500, 1000000);
35
36Set limits on the sizes of images read by Imager.
37
38Setting a limit to 0 means that limit is ignored.
39
40Negative limits result in failure.
41
8d14daab
TC
42Parameters:
43
44=over
45
46=item *
47
48i_img_dim width, height - maximum width and height.
49
50=item *
51
85cae6e7
TC
52size_t bytes - maximum size in memory in bytes. A value of zero sets
53this limit to one gigabyte.
8d14daab
TC
54
55=back
56
87deb14c
TC
57Returns non-zero on success.
58
59=cut
60*/
61
77157728 62int
d896d49c 63im_set_image_file_limits(pIMCTX, i_img_dim width, i_img_dim height, size_t bytes) {
77157728
TC
64 i_clear_error();
65
66 if (width < 0) {
67 i_push_error(0, "width must be non-negative");
68 return 0;
69 }
70 if (height < 0) {
71 i_push_error(0, "height must be non-negative");
72 return 0;
73 }
74 if (bytes < 0) {
75 i_push_error(0, "bytes must be non-negative");
76 return 0;
77 }
78
d896d49c
TC
79 aIMCTX->max_width = width;
80 aIMCTX->max_height = height;
81 aIMCTX->max_bytes = bytes ? bytes : DEF_BYTES_LIMIT;
77157728
TC
82
83 return 1;
84}
85
87deb14c 86/*
d03fd5a4
TC
87=item i_get_image_file_limits(&width, &height, &bytes)
88
87deb14c
TC
89=category Files
90=synopsis i_get_image_file_limits(&width, &height, &bytes)
91
92Retrieves the file limits set by i_set_image_file_limits().
93
8d14daab
TC
94=over
95
96=item *
97
98i_img_dim *width, *height - the maximum width and height of the image.
99
100=item *
101
102size_t *bytes - size in memory of the image in bytes.
103
104=back
105
87deb14c
TC
106=cut
107*/
108
77157728 109int
d896d49c
TC
110im_get_image_file_limits(pIMCTX, i_img_dim *width, i_img_dim *height, size_t *bytes) {
111 im_clear_error(aIMCTX);
77157728 112
d896d49c
TC
113 *width = aIMCTX->max_width;
114 *height = aIMCTX->max_height;
115 *bytes = aIMCTX->max_bytes;
77157728
TC
116
117 return 1;
118}
119
87deb14c 120/*
d03fd5a4
TC
121=item i_int_check_image_file_limits(width, height, channels, sample_size)
122
87deb14c 123=category Files
d03fd5a4 124=synopsis i_i_int_check_image_file_limits(width, height, channels, sizeof(i_sample_t))
87deb14c
TC
125
126Checks the size of a file in memory against the configured image file
127limits.
128
129This also range checks the values to those permitted by Imager and
130checks for overflows in calculating the size.
131
132Returns non-zero if the file is within limits.
133
134This function is intended to be called by image file read functions.
135
136=cut
137*/
138
77157728 139int
d896d49c 140im_int_check_image_file_limits(pIMCTX, i_img_dim width, i_img_dim height, int channels, size_t sample_size) {
8d14daab 141 size_t bytes;
d896d49c 142 im_clear_error(aIMCTX);
77157728
TC
143
144 if (width <= 0) {
d896d49c 145 im_push_errorf(aIMCTX, 0, "file size limit - image width of %" i_DF " is not positive",
8d14daab 146 i_DFc(width));
77157728
TC
147 return 0;
148 }
d896d49c
TC
149 if (aIMCTX->max_width && width > aIMCTX->max_width) {
150 im_push_errorf(aIMCTX, 0, "file size limit - image width of %" i_DF " exceeds limit of %" i_DF,
151 i_DFc(width), i_DFc(aIMCTX->max_width));
77157728
TC
152 return 0;
153 }
154
155 if (height <= 0) {
d896d49c 156 im_push_errorf(aIMCTX, 0, "file size limit - image height of %" i_DF " is not positive",
8d14daab 157 i_DFc(height));
77157728
TC
158 return 0;
159 }
160
d896d49c
TC
161 if (aIMCTX->max_height && height > aIMCTX->max_height) {
162 im_push_errorf(aIMCTX, 0, "file size limit - image height of %" i_DF
163 " exceeds limit of %" i_DF, i_DFc(height), i_DFc(aIMCTX->max_height));
77157728
TC
164 return 0;
165 }
166
167 if (channels < 1 || channels > MAXCHANNELS) {
d896d49c 168 im_push_errorf(aIMCTX, 0, "file size limit - channels %d out of range",
77157728
TC
169 channels);
170 return 0;
171 }
172
173 if (sample_size < 1 || sample_size > sizeof(long double)) {
d896d49c 174 im_push_errorf(aIMCTX, 0, "file size limit - sample_size %ld out of range",
8d14daab 175 (long)sample_size);
77157728
TC
176 return 0;
177 }
178
179 /* This overflow check is a bit more paranoid than usual.
180 We don't protect it under max_bytes since we always want to check
181 for overflow.
182 */
5caa40a6 183 bytes = width * height * channels * sample_size;
77157728
TC
184 if (bytes / width != height * channels * sample_size
185 || bytes / height != width * channels * sample_size) {
d896d49c 186 im_push_error(aIMCTX, 0, "file size limit - integer overflow calculating storage");
77157728
TC
187 return 0;
188 }
d896d49c
TC
189 if (aIMCTX->max_bytes) {
190 if (bytes > aIMCTX->max_bytes) {
191 im_push_errorf(aIMCTX, 0, "file size limit - storage size of %lu "
8d14daab 192 "exceeds limit of %lu", (unsigned long)bytes,
d896d49c 193 (unsigned long)aIMCTX->max_bytes);
77157728
TC
194 return 0;
195 }
196 }
197
198 return 1;
199}