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