2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
14 #include "vpx/vpx_image.h"
16 static vpx_image_t
*img_alloc_helper(vpx_image_t
*img
,
20 unsigned int stride_align
,
21 unsigned char *img_data
)
24 unsigned int h
, w
, s
, xcs
, ycs
, bps
;
27 /* Treat align==0 like align==1 */
31 /* Validate alignment (must be power of 2) */
32 if (stride_align
& (stride_align
- 1))
35 /* Get sample size for this format */
38 case VPX_IMG_FMT_RGB32
:
39 case VPX_IMG_FMT_RGB32_LE
:
40 case VPX_IMG_FMT_ARGB
:
41 case VPX_IMG_FMT_ARGB_LE
:
44 case VPX_IMG_FMT_RGB24
:
45 case VPX_IMG_FMT_BGR24
:
48 case VPX_IMG_FMT_RGB565
:
49 case VPX_IMG_FMT_RGB565_LE
:
50 case VPX_IMG_FMT_RGB555
:
51 case VPX_IMG_FMT_RGB555_LE
:
52 case VPX_IMG_FMT_UYVY
:
53 case VPX_IMG_FMT_YUY2
:
54 case VPX_IMG_FMT_YVYU
:
57 case VPX_IMG_FMT_I420
:
58 case VPX_IMG_FMT_YV12
:
59 case VPX_IMG_FMT_VPXI420
:
60 case VPX_IMG_FMT_VPXYV12
:
68 /* Get chroma shift values for this format */
71 case VPX_IMG_FMT_I420
:
72 case VPX_IMG_FMT_YV12
:
73 case VPX_IMG_FMT_VPXI420
:
74 case VPX_IMG_FMT_VPXYV12
:
84 case VPX_IMG_FMT_I420
:
85 case VPX_IMG_FMT_YV12
:
86 case VPX_IMG_FMT_VPXI420
:
87 case VPX_IMG_FMT_VPXYV12
:
95 /* Calculate storage sizes given the chroma subsampling */
96 align
= (1 << xcs
) - 1;
97 w
= (d_w
+ align
) & ~align
;
98 align
= (1 << ycs
) - 1;
99 h
= (d_h
+ align
) & ~align
;
100 s
= (fmt
& VPX_IMG_FMT_PLANAR
) ? w
: bps
* w
/ 8;
101 s
= (s
+ stride_align
- 1) & ~(stride_align
- 1);
103 /* Allocate the new image */
106 img
= (vpx_image_t
*)calloc(1, sizeof(vpx_image_t
));
111 img
->self_allocd
= 1;
115 memset(img
, 0, sizeof(vpx_image_t
));
118 img
->img_data
= img_data
;
122 img
->img_data
= malloc((fmt
& VPX_IMG_FMT_PLANAR
) ? h
* w
* bps
/ 8 : h
* s
);
123 img
->img_data_owner
= 1;
132 img
->x_chroma_shift
= xcs
;
133 img
->y_chroma_shift
= ycs
;
136 /* Calculate strides */
137 img
->stride
[VPX_PLANE_Y
] = img
->stride
[VPX_PLANE_ALPHA
] = s
;
138 img
->stride
[VPX_PLANE_U
] = img
->stride
[VPX_PLANE_V
] = s
>> xcs
;
140 /* Default viewport to entire image */
141 if (!vpx_img_set_rect(img
, 0, 0, d_w
, d_h
))
149 vpx_image_t
*vpx_img_alloc(vpx_image_t
*img
,
153 unsigned int stride_align
)
155 return img_alloc_helper(img
, fmt
, d_w
, d_h
, stride_align
, NULL
);
158 vpx_image_t
*vpx_img_wrap(vpx_image_t
*img
,
162 unsigned int stride_align
,
163 unsigned char *img_data
)
165 return img_alloc_helper(img
, fmt
, d_w
, d_h
, stride_align
, img_data
);
168 int vpx_img_set_rect(vpx_image_t
*img
,
176 if (x
+ w
<= img
->w
&& y
+ h
<= img
->h
)
181 /* Calculate plane pointers */
182 if (!(img
->fmt
& VPX_IMG_FMT_PLANAR
))
184 img
->planes
[VPX_PLANE_PACKED
] =
185 img
->img_data
+ x
* img
->bps
/ 8 + y
* img
->stride
[VPX_PLANE_PACKED
];
189 data
= img
->img_data
;
191 if (img
->fmt
& VPX_IMG_FMT_HAS_ALPHA
)
193 img
->planes
[VPX_PLANE_ALPHA
] =
194 data
+ x
+ y
* img
->stride
[VPX_PLANE_ALPHA
];
195 data
+= img
->h
* img
->stride
[VPX_PLANE_ALPHA
];
198 img
->planes
[VPX_PLANE_Y
] = data
+ x
+ y
* img
->stride
[VPX_PLANE_Y
];
199 data
+= img
->h
* img
->stride
[VPX_PLANE_Y
];
201 if (!(img
->fmt
& VPX_IMG_FMT_UV_FLIP
))
203 img
->planes
[VPX_PLANE_U
] = data
204 + (x
>> img
->x_chroma_shift
)
205 + (y
>> img
->y_chroma_shift
) * img
->stride
[VPX_PLANE_U
];
206 data
+= (img
->h
>> img
->y_chroma_shift
) * img
->stride
[VPX_PLANE_U
];
207 img
->planes
[VPX_PLANE_V
] = data
208 + (x
>> img
->x_chroma_shift
)
209 + (y
>> img
->y_chroma_shift
) * img
->stride
[VPX_PLANE_V
];
213 img
->planes
[VPX_PLANE_V
] = data
214 + (x
>> img
->x_chroma_shift
)
215 + (y
>> img
->y_chroma_shift
) * img
->stride
[VPX_PLANE_V
];
216 data
+= (img
->h
>> img
->y_chroma_shift
) * img
->stride
[VPX_PLANE_V
];
217 img
->planes
[VPX_PLANE_U
] = data
218 + (x
>> img
->x_chroma_shift
)
219 + (y
>> img
->y_chroma_shift
) * img
->stride
[VPX_PLANE_U
];
229 void vpx_img_flip(vpx_image_t
*img
)
231 /* Note: In the calculation pointer adjustment calculation, we want the
232 * rhs to be promoted to a signed type. Section 6.3.1.8 of the ISO C99
233 * standard indicates that if the adjustment parameter is unsigned, the
234 * stride parameter will be promoted to unsigned, causing errors when
235 * the lhs is a larger type than the rhs.
237 img
->planes
[VPX_PLANE_Y
] += (signed)(img
->d_h
- 1) * img
->stride
[VPX_PLANE_Y
];
238 img
->stride
[VPX_PLANE_Y
] = -img
->stride
[VPX_PLANE_Y
];
240 img
->planes
[VPX_PLANE_U
] += (signed)((img
->d_h
>> img
->y_chroma_shift
) - 1)
241 * img
->stride
[VPX_PLANE_U
];
242 img
->stride
[VPX_PLANE_U
] = -img
->stride
[VPX_PLANE_U
];
244 img
->planes
[VPX_PLANE_V
] += (signed)((img
->d_h
>> img
->y_chroma_shift
) - 1)
245 * img
->stride
[VPX_PLANE_V
];
246 img
->stride
[VPX_PLANE_V
] = -img
->stride
[VPX_PLANE_V
];
248 img
->planes
[VPX_PLANE_ALPHA
] += (signed)(img
->d_h
- 1) * img
->stride
[VPX_PLANE_ALPHA
];
249 img
->stride
[VPX_PLANE_ALPHA
] = -img
->stride
[VPX_PLANE_ALPHA
];
252 void vpx_img_free(vpx_image_t
*img
)
256 if (img
->img_data
&& img
->img_data_owner
)
259 if (img
->self_allocd
)