| OLD | NEW |
| 1 /* | 1 /* |
| 2 * This file is part of FFmpeg. | 2 * This file is part of FFmpeg. |
| 3 * | 3 * |
| 4 * FFmpeg is free software; you can redistribute it and/or | 4 * FFmpeg is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU Lesser General Public | 5 * modify it under the terms of the GNU Lesser General Public |
| 6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
| 7 * version 2.1 of the License, or (at your option) any later version. | 7 * version 2.1 of the License, or (at your option) any later version. |
| 8 * | 8 * |
| 9 * FFmpeg is distributed in the hope that it will be useful, | 9 * FFmpeg is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 12 * Lesser General Public License for more details. | 12 * Lesser General Public License for more details. |
| 13 * | 13 * |
| 14 * You should have received a copy of the GNU Lesser General Public | 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 | 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 | 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 17 */ | 17 */ |
| 18 | 18 |
| 19 /** | 19 /** |
| 20 * @file | 20 * @file |
| 21 * misc image utilities | 21 * misc image utilities |
| 22 */ | 22 */ |
| 23 | 23 |
| 24 #include "imgutils.h" | 24 #include "imgutils.h" |
| 25 #include "libavutil/pixdesc.h" | 25 #include "libavutil/pixdesc.h" |
| 26 | 26 |
| 27 int av_fill_image_linesizes(int linesizes[4], enum PixelFormat pix_fmt, int widt
h) | 27 void av_image_fill_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4], |
| 28 const AVPixFmtDescriptor *pixdesc) |
| 29 { |
| 30 int i; |
| 31 memset(max_pixsteps, 0, 4*sizeof(max_pixsteps[0])); |
| 32 if (max_pixstep_comps) |
| 33 memset(max_pixstep_comps, 0, 4*sizeof(max_pixstep_comps[0])); |
| 34 |
| 35 for (i = 0; i < 4; i++) { |
| 36 const AVComponentDescriptor *comp = &(pixdesc->comp[i]); |
| 37 if ((comp->step_minus1+1) > max_pixsteps[comp->plane]) { |
| 38 max_pixsteps[comp->plane] = comp->step_minus1+1; |
| 39 if (max_pixstep_comps) |
| 40 max_pixstep_comps[comp->plane] = i; |
| 41 } |
| 42 } |
| 43 } |
| 44 |
| 45 int av_image_get_linesize(enum PixelFormat pix_fmt, int width, int plane) |
| 46 { |
| 47 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; |
| 48 int max_step [4]; /* max pixel step for each plane */ |
| 49 int max_step_comp[4]; /* the component for each plane which has the ma
x pixel step */ |
| 50 int s; |
| 51 |
| 52 if (desc->flags & PIX_FMT_BITSTREAM) |
| 53 return (width * (desc->comp[0].step_minus1+1) + 7) >> 3; |
| 54 |
| 55 av_image_fill_max_pixsteps(max_step, max_step_comp, desc); |
| 56 s = (max_step_comp[plane] == 1 || max_step_comp[plane] == 2) ? desc->log2_ch
roma_w : 0; |
| 57 return max_step[plane] * (((width + (1 << s) - 1)) >> s); |
| 58 } |
| 59 |
| 60 int av_image_fill_linesizes(int linesizes[4], enum PixelFormat pix_fmt, int widt
h) |
| 28 { | 61 { |
| 29 int i; | 62 int i; |
| 30 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; | 63 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; |
| 31 int max_step [4]; /* max pixel step for each plane */ | 64 int max_step [4]; /* max pixel step for each plane */ |
| 32 int max_step_comp[4]; /* the component for each plane which has the ma
x pixel step */ | 65 int max_step_comp[4]; /* the component for each plane which has the ma
x pixel step */ |
| 33 | 66 |
| 34 memset(linesizes, 0, 4*sizeof(linesizes[0])); | 67 memset(linesizes, 0, 4*sizeof(linesizes[0])); |
| 35 | 68 |
| 36 if (desc->flags & PIX_FMT_HWACCEL) | 69 if ((unsigned)pix_fmt >= PIX_FMT_NB || desc->flags & PIX_FMT_HWACCEL) |
| 37 return AVERROR(EINVAL); | 70 return AVERROR(EINVAL); |
| 38 | 71 |
| 39 if (desc->flags & PIX_FMT_BITSTREAM) { | 72 if (desc->flags & PIX_FMT_BITSTREAM) { |
| 40 linesizes[0] = (width * (desc->comp[0].step_minus1+1) + 7) >> 3; | 73 linesizes[0] = (width * (desc->comp[0].step_minus1+1) + 7) >> 3; |
| 41 return 0; | 74 return 0; |
| 42 } | 75 } |
| 43 | 76 |
| 44 memset(max_step , 0, sizeof(max_step )); | 77 av_image_fill_max_pixsteps(max_step, max_step_comp, desc); |
| 45 memset(max_step_comp, 0, sizeof(max_step_comp)); | |
| 46 for (i = 0; i < 4; i++) { | |
| 47 const AVComponentDescriptor *comp = &(desc->comp[i]); | |
| 48 if ((comp->step_minus1+1) > max_step[comp->plane]) { | |
| 49 max_step [comp->plane] = comp->step_minus1+1; | |
| 50 max_step_comp[comp->plane] = i; | |
| 51 } | |
| 52 } | |
| 53 | |
| 54 for (i = 0; i < 4; i++) { | 78 for (i = 0; i < 4; i++) { |
| 55 int s = (max_step_comp[i] == 1 || max_step_comp[i] == 2) ? desc->log2_ch
roma_w : 0; | 79 int s = (max_step_comp[i] == 1 || max_step_comp[i] == 2) ? desc->log2_ch
roma_w : 0; |
| 56 linesizes[i] = max_step[i] * (((width + (1 << s) - 1)) >> s); | 80 linesizes[i] = max_step[i] * (((width + (1 << s) - 1)) >> s); |
| 57 } | 81 } |
| 58 | 82 |
| 59 return 0; | 83 return 0; |
| 60 } | 84 } |
| 61 | 85 |
| 62 int av_fill_image_pointers(uint8_t *data[4], enum PixelFormat pix_fmt, int heigh
t, | 86 int av_image_fill_pointers(uint8_t *data[4], enum PixelFormat pix_fmt, int heigh
t, |
| 63 uint8_t *ptr, const int linesizes[4]) | 87 uint8_t *ptr, const int linesizes[4]) |
| 64 { | 88 { |
| 65 int i, total_size, size[4], has_plane[4]; | 89 int i, total_size, size[4], has_plane[4]; |
| 66 | 90 |
| 67 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; | 91 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; |
| 68 memset(data , 0, sizeof(data[0])*4); | 92 memset(data , 0, sizeof(data[0])*4); |
| 69 memset(size , 0, sizeof(size)); | 93 memset(size , 0, sizeof(size)); |
| 70 memset(has_plane, 0, sizeof(has_plane)); | 94 memset(has_plane, 0, sizeof(has_plane)); |
| 71 | 95 |
| 72 if (desc->flags & PIX_FMT_HWACCEL) | 96 if ((unsigned)pix_fmt >= PIX_FMT_NB || desc->flags & PIX_FMT_HWACCEL) |
| 73 return AVERROR(EINVAL); | 97 return AVERROR(EINVAL); |
| 74 | 98 |
| 75 data[0] = ptr; | 99 data[0] = ptr; |
| 76 size[0] = linesizes[0] * height; | 100 size[0] = linesizes[0] * height; |
| 77 | 101 |
| 78 if (desc->flags & PIX_FMT_PAL) { | 102 if (desc->flags & PIX_FMT_PAL) { |
| 79 size[0] = (size[0] + 3) & ~3; | 103 size[0] = (size[0] + 3) & ~3; |
| 80 data[1] = ptr + size[0]; /* palette is stored here as 256 32 bits words
*/ | 104 data[1] = ptr + size[0]; /* palette is stored here as 256 32 bits words
*/ |
| 81 return size[0] + 256 * 4; | 105 return size[0] + 256 * 4; |
| 82 } | 106 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 97 } | 121 } |
| 98 | 122 |
| 99 typedef struct ImgUtils { | 123 typedef struct ImgUtils { |
| 100 const AVClass *class; | 124 const AVClass *class; |
| 101 int log_offset; | 125 int log_offset; |
| 102 void *log_ctx; | 126 void *log_ctx; |
| 103 } ImgUtils; | 127 } ImgUtils; |
| 104 | 128 |
| 105 static const AVClass imgutils_class = { "IMGUTILS", av_default_item_name, NULL,
LIBAVUTIL_VERSION_INT, offsetof(ImgUtils, log_offset), offsetof(ImgUtils, log_ct
x) }; | 129 static const AVClass imgutils_class = { "IMGUTILS", av_default_item_name, NULL,
LIBAVUTIL_VERSION_INT, offsetof(ImgUtils, log_offset), offsetof(ImgUtils, log_ct
x) }; |
| 106 | 130 |
| 107 int av_check_image_size(unsigned int w, unsigned int h, int log_offset, void *lo
g_ctx) | 131 int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *lo
g_ctx) |
| 108 { | 132 { |
| 109 ImgUtils imgutils = { &imgutils_class, log_offset, log_ctx }; | 133 ImgUtils imgutils = { &imgutils_class, log_offset, log_ctx }; |
| 110 | 134 |
| 111 if((int)w>0 && (int)h>0 && (w+128)*(uint64_t)(h+128) < INT_MAX/8) | 135 if ((int)w>0 && (int)h>0 && (w+128)*(uint64_t)(h+128) < INT_MAX/8) |
| 112 return 0; | 136 return 0; |
| 113 | 137 |
| 114 av_log(&imgutils, AV_LOG_ERROR, "Picture size %ux%u is invalid\n", w, h); | 138 av_log(&imgutils, AV_LOG_ERROR, "Picture size %ux%u is invalid\n", w, h); |
| 115 return AVERROR(EINVAL); | 139 return AVERROR(EINVAL); |
| 116 } | 140 } |
| 141 |
| 142 void av_image_copy_plane(uint8_t *dst, int dst_linesize, |
| 143 const uint8_t *src, int src_linesize, |
| 144 int bytewidth, int height) |
| 145 { |
| 146 if (!dst || !src) |
| 147 return; |
| 148 for (;height > 0; height--) { |
| 149 memcpy(dst, src, bytewidth); |
| 150 dst += dst_linesize; |
| 151 src += src_linesize; |
| 152 } |
| 153 } |
| 154 |
| 155 void av_image_copy(uint8_t *dst_data[4], int dst_linesizes[4], |
| 156 const uint8_t *src_data[4], const int src_linesizes[4], |
| 157 enum PixelFormat pix_fmt, int width, int height) |
| 158 { |
| 159 const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; |
| 160 |
| 161 if (desc->flags & PIX_FMT_HWACCEL) |
| 162 return; |
| 163 |
| 164 if (desc->flags & PIX_FMT_PAL) { |
| 165 av_image_copy_plane(dst_data[0], dst_linesizes[0], |
| 166 src_data[0], src_linesizes[0], |
| 167 width, height); |
| 168 /* copy the palette */ |
| 169 memcpy(dst_data[1], src_data[1], 4*256); |
| 170 } else { |
| 171 int i, planes_nb = 0; |
| 172 |
| 173 for (i = 0; i < desc->nb_components; i++) |
| 174 planes_nb = FFMAX(planes_nb, desc->comp[i].plane + 1); |
| 175 |
| 176 for (i = 0; i < planes_nb; i++) { |
| 177 int h = height; |
| 178 int bwidth = av_image_get_linesize(pix_fmt, width, i); |
| 179 if (i == 1 || i == 2) { |
| 180 h= -((-height)>>desc->log2_chroma_h); |
| 181 } |
| 182 av_image_copy_plane(dst_data[i], dst_linesizes[i], |
| 183 src_data[i], src_linesizes[i], |
| 184 bwidth, h); |
| 185 } |
| 186 } |
| 187 } |
| 188 |
| 189 #if FF_API_OLD_IMAGE_NAMES |
| 190 void av_fill_image_max_pixsteps(int max_pixsteps[4], int max_pixstep_comps[4], |
| 191 const AVPixFmtDescriptor *pixdesc) |
| 192 { |
| 193 av_image_fill_max_pixsteps(max_pixsteps, max_pixstep_comps, pixdesc); |
| 194 } |
| 195 |
| 196 int av_get_image_linesize(enum PixelFormat pix_fmt, int width, int plane) |
| 197 { |
| 198 return av_image_get_linesize(pix_fmt, width, plane); |
| 199 } |
| 200 |
| 201 int av_fill_image_linesizes(int linesizes[4], enum PixelFormat pix_fmt, int widt
h) |
| 202 { |
| 203 return av_image_fill_linesizes(linesizes, pix_fmt, width); |
| 204 } |
| 205 |
| 206 int av_fill_image_pointers(uint8_t *data[4], enum PixelFormat pix_fmt, int heigh
t, |
| 207 uint8_t *ptr, const int linesizes[4]) |
| 208 { |
| 209 return av_image_fill_pointers(data, pix_fmt, height, ptr, linesizes); |
| 210 } |
| 211 |
| 212 int av_check_image_size(unsigned int w, unsigned int h, int log_offset, void *lo
g_ctx) |
| 213 { |
| 214 return av_image_check_size(w, h, log_offset, log_ctx); |
| 215 } |
| 216 #endif |
| OLD | NEW |