1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 /**
20 * @file
21 * misc image utilities
22 */
23
33
36 {
37 int i;
38 memset(max_pixsteps, 0, 4*sizeof(max_pixsteps[0]));
39 if (max_pixstep_comps)
40 memset(max_pixstep_comps, 0, 4*sizeof(max_pixstep_comps[0]));
41
42 for (i = 0; i < 4; i++) {
46 if (max_pixstep_comps)
47 max_pixstep_comps[comp->
plane] = i;
48 }
49 }
50 }
51
52 static inline
54 int max_step, int max_step_comp,
56 {
57 int s, shifted_w, linesize;
58
59 if (!desc)
61
62 if (width < 0)
64 s = (max_step_comp == 1 || max_step_comp == 2) ? desc->
log2_chroma_w : 0;
65 shifted_w = ((width + (1 << s) - 1)) >> s;
66 if (shifted_w && max_step > INT_MAX / shifted_w)
68 linesize = max_step * shifted_w;
69
71 linesize = (linesize + 7) >> 3;
72 return linesize;
73 }
74
76 {
78 int max_step [4]; /* max pixel step for each plane */
79 int max_step_comp[4]; /* the component for each plane which has the max pixel step */
80
83
86 }
87
89 {
92 int max_step [4]; /* max pixel step for each plane */
93 int max_step_comp[4]; /* the component for each plane which has the max pixel step */
94
95 memset(linesizes, 0, 4*sizeof(linesizes[0]));
96
99
101 for (i = 0; i < 4; i++) {
105 }
106
107 return 0;
108 }
109
111 uint8_t *ptr,
const int linesizes[4])
112 {
113 int i, total_size,
size[4] = { 0 }, has_plane[4] = { 0 };
114
116 memset(data , 0, sizeof(data[0])*4);
117
120
121 data[0] = ptr;
122 if (linesizes[0] > (INT_MAX - 1024) / height)
124 size[0] = linesizes[0] *
height;
125
128 size[0] = (size[0] + 3) & ~3;
129 data[1] = ptr + size[0]; /* palette is stored here as 256 32 bits words */
130 return size[0] + 256 * 4;
131 }
132
133 for (i = 0; i < 4; i++)
135
136 total_size = size[0];
137 for (i = 1; i < 4 && has_plane[i]; i++) {
139 data[i] = data[i-1] + size[i-1];
140 h = (height + (1 << s) - 1) >> s;
141 if (linesizes[i] > INT_MAX / h)
143 size[i] = h * linesizes[i];
144 if (total_size > INT_MAX - size[i])
146 total_size += size[i];
147 }
148
149 return total_size;
150 }
151
153 {
154 int i;
155
156 for (i = 0; i < 256; i++) {
158
159 switch (pix_fmt) {
161 r = (i>>5 )*36;
162 g = ((i>>2)&7)*36;
163 b = (i&3 )*85;
164 break;
166 b = (i>>6 )*85;
167 g = ((i>>3)&7)*36;
168 r = (i&7 )*36;
169 break;
171 r = (i>>3 )*255;
172 g = ((i>>1)&3)*85;
173 b = (i&1 )*255;
174 break;
176 b = (i>>3 )*255;
177 g = ((i>>1)&3)*85;
178 r = (i&1 )*255;
179 break;
181 r = b = g = i;
182 break;
183 default:
185 }
186 pal[i] = b + (g << 8) + (r << 16) + (0xFF
U << 24);
187 }
188
189 return 0;
190 }
191
194 {
198
199 if (!desc)
201
206
207 for (i = 0; i < 4; i++)
208 linesizes[i] =
FFALIGN(linesizes[i], align);
209
213 if (!buf)
218 }
221
223 }
224
230
232
234 {
236
237 if ((int)w>0 && (int)h>0 && (w+128)*(uint64_t)(h+128) < INT_MAX/8)
238 return 0;
239
242 }
243
245 {
246 int64_t scaled_dim;
247
248 if (sar.
den <= 0 || sar.
num < 0)
250
252 return 0;
253
256 else
258
259 if (scaled_dim > 0)
260 return 0;
261
263 }
264
267 int bytewidth,
int height)
268 {
269 if (!dst || !src)
270 return;
273 for (;height > 0; height--) {
274 memcpy(dst, src, bytewidth);
275 dst += dst_linesize;
276 src += src_linesize;
277 }
278 }
279
281 const uint8_t *src_data[4],
const int src_linesizes[4],
283 {
285
287 return;
288
292 src_data[0], src_linesizes[0],
293 width, height);
294 /* copy the palette */
295 memcpy(dst_data[1], src_data[1], 4*256);
296 } else {
297 int i, planes_nb = 0;
298
301
302 for (i = 0; i < planes_nb; i++) {
305 if (bwidth < 0) {
307 return;
308 }
309 if (i == 1 || i == 2) {
311 }
313 src_data[i], src_linesizes[i],
314 bwidth, h);
315 }
316 }
317 }
318
322 {
324
326 if (ret < 0)
328
330 if (ret < 0)
332
333 for (i = 0; i < 4; i++)
334 dst_linesize[i] =
FFALIGN(dst_linesize[i], align);
335
337 }
338
341 {
343 int linesize[4];
346 if (!desc)
348
350 if (ret < 0)
352
353 // do not include palette for these pseudo-paletted formats
356
358 width, height, align);
359 }
360
362 const uint8_t *
const src_data[4],
363 const int src_linesize[4],
366 {
367 int i, j, nb_planes = 0, linesize[4];
370
371 if (size > dst_size || size < 0 || !desc)
373
376
377 nb_planes++;
378
380 for (i = 0; i < nb_planes; i++) {
383 h = (height + (1 << shift) - 1) >> shift;
384
385 for (j = 0; j < h; j++) {
386 memcpy(dst,
src, linesize[i]);
387 dst +=
FFALIGN(linesize[i], align);
388 src += src_linesize[i];
389 }
390 }
391
393 uint32_t *
d32 = (uint32_t *)(((
size_t)dst + 3) & ~3);
394 for (i = 0; i<256; i++)
396 }
397
399 }