1 /*
2 * Copyright (c) 2024 The WebM project authors. All Rights Reserved.
3 *
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.
9 */
10
11 #include <climits>
12
13 #include "vpx/vpx_image.h"
14 #include "third_party/googletest/src/include/gtest/gtest.h"
15
TEST(VpxImageTest,VpxImgWrapInvalidAlign)16 TEST(VpxImageTest, VpxImgWrapInvalidAlign) {
17 const int kWidth = 128;
18 const int kHeight = 128;
19 unsigned char buf[kWidth * kHeight * 3];
20
21 vpx_image_t img;
22 // Set img_data and img_data_owner to junk values. vpx_img_wrap() should
23 // not read these values on failure.
24 unsigned char empty[] = "";
25 img.img_data = empty;
26 img.img_data_owner = 1;
27
28 vpx_img_fmt_t format = VPX_IMG_FMT_I444;
29 // 'align' must be a power of 2 but is not. This causes the vpx_img_wrap()
30 // call to fail. The test verifies we do not read the junk values in 'img'.
31 unsigned int align = 31;
32 EXPECT_EQ(vpx_img_wrap(&img, format, kWidth, kHeight, align, buf), nullptr);
33 }
34
TEST(VpxImageTest,VpxImgSetRectOverflow)35 TEST(VpxImageTest, VpxImgSetRectOverflow) {
36 const int kWidth = 128;
37 const int kHeight = 128;
38 unsigned char buf[kWidth * kHeight * 3];
39
40 vpx_image_t img;
41 vpx_img_fmt_t format = VPX_IMG_FMT_I444;
42 unsigned int align = 32;
43 EXPECT_EQ(vpx_img_wrap(&img, format, kWidth, kHeight, align, buf), &img);
44
45 EXPECT_EQ(vpx_img_set_rect(&img, 0, 0, kWidth, kHeight), 0);
46 // This would result in overflow because -1 is cast to UINT_MAX.
47 EXPECT_NE(vpx_img_set_rect(&img, static_cast<unsigned int>(-1),
48 static_cast<unsigned int>(-1), kWidth, kHeight),
49 0);
50 }
51
TEST(VpxImageTest,VpxImgAllocNone)52 TEST(VpxImageTest, VpxImgAllocNone) {
53 const int kWidth = 128;
54 const int kHeight = 128;
55
56 vpx_image_t img;
57 vpx_img_fmt_t format = VPX_IMG_FMT_NONE;
58 unsigned int align = 32;
59 ASSERT_EQ(vpx_img_alloc(&img, format, kWidth, kHeight, align), nullptr);
60 }
61
TEST(VpxImageTest,VpxImgAllocNv12)62 TEST(VpxImageTest, VpxImgAllocNv12) {
63 const int kWidth = 128;
64 const int kHeight = 128;
65
66 vpx_image_t img;
67 vpx_img_fmt_t format = VPX_IMG_FMT_NV12;
68 unsigned int align = 32;
69 EXPECT_EQ(vpx_img_alloc(&img, format, kWidth, kHeight, align), &img);
70 EXPECT_EQ(img.stride[VPX_PLANE_U], img.stride[VPX_PLANE_Y]);
71 EXPECT_EQ(img.stride[VPX_PLANE_V], img.stride[VPX_PLANE_U]);
72 EXPECT_EQ(img.planes[VPX_PLANE_V], img.planes[VPX_PLANE_U] + 1);
73 vpx_img_free(&img);
74 }
75
TEST(VpxImageTest,VpxImgAllocHugeWidth)76 TEST(VpxImageTest, VpxImgAllocHugeWidth) {
77 // The stride (0x80000000 * 2) would overflow unsigned int.
78 vpx_image_t *image =
79 vpx_img_alloc(nullptr, VPX_IMG_FMT_I42016, 0x80000000, 1, 1);
80 ASSERT_EQ(image, nullptr);
81
82 // The stride (0x80000000) would overflow int.
83 image = vpx_img_alloc(nullptr, VPX_IMG_FMT_I420, 0x80000000, 1, 1);
84 ASSERT_EQ(image, nullptr);
85
86 // The aligned width (UINT_MAX + 1) would overflow unsigned int.
87 image = vpx_img_alloc(nullptr, VPX_IMG_FMT_I420, UINT_MAX, 1, 1);
88 ASSERT_EQ(image, nullptr);
89
90 image = vpx_img_alloc(nullptr, VPX_IMG_FMT_I420, 0x7ffffffe, 1, 1);
91 if (image) {
92 vpx_img_free(image);
93 }
94
95 image = vpx_img_alloc(nullptr, VPX_IMG_FMT_I420, 285245883, 64, 1);
96 if (image) {
97 vpx_img_free(image);
98 }
99
100 image = vpx_img_alloc(nullptr, VPX_IMG_FMT_NV12, 285245883, 64, 1);
101 if (image) {
102 vpx_img_free(image);
103 }
104
105 image = vpx_img_alloc(nullptr, VPX_IMG_FMT_YV12, 285245883, 64, 1);
106 if (image) {
107 vpx_img_free(image);
108 }
109
110 image = vpx_img_alloc(nullptr, VPX_IMG_FMT_I42016, 65536, 2, 1);
111 if (image) {
112 uint16_t *y_plane =
113 reinterpret_cast<uint16_t *>(image->planes[VPX_PLANE_Y]);
114 y_plane[0] = 0;
115 y_plane[image->d_w - 1] = 0;
116 vpx_img_free(image);
117 }
118
119 image = vpx_img_alloc(nullptr, VPX_IMG_FMT_I42016, 285245883, 2, 1);
120 if (image) {
121 uint16_t *y_plane =
122 reinterpret_cast<uint16_t *>(image->planes[VPX_PLANE_Y]);
123 y_plane[0] = 0;
124 y_plane[image->d_w - 1] = 0;
125 vpx_img_free(image);
126 }
127 }
128