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