1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/gfx/buffer_format_util.h"
7 #include "base/logging.h"
8 #include "base/numerics/safe_math.h"
12 size_t NumberOfPlanesForBufferFormat(BufferFormat format
) {
14 case BufferFormat::ATC
:
15 case BufferFormat::ATCIA
:
16 case BufferFormat::DXT1
:
17 case BufferFormat::DXT5
:
18 case BufferFormat::ETC1
:
19 case BufferFormat::R_8
:
20 case BufferFormat::RGBA_4444
:
21 case BufferFormat::RGBA_8888
:
22 case BufferFormat::BGRX_8888
:
23 case BufferFormat::BGRA_8888
:
24 case BufferFormat::UYVY_422
:
26 case BufferFormat::YUV_420_BIPLANAR
:
28 case BufferFormat::YUV_420
:
35 size_t SubsamplingFactorForBufferFormat(BufferFormat format
, int plane
) {
37 case BufferFormat::ATC
:
38 case BufferFormat::ATCIA
:
39 case BufferFormat::DXT1
:
40 case BufferFormat::DXT5
:
41 case BufferFormat::ETC1
:
42 case BufferFormat::R_8
:
43 case BufferFormat::RGBA_4444
:
44 case BufferFormat::RGBA_8888
:
45 case BufferFormat::BGRX_8888
:
46 case BufferFormat::BGRA_8888
:
47 case BufferFormat::UYVY_422
:
49 case BufferFormat::YUV_420
: {
50 static size_t factor
[] = {1, 2, 2};
51 DCHECK_LT(static_cast<size_t>(plane
), arraysize(factor
));
54 case gfx::BufferFormat::YUV_420_BIPLANAR
: {
55 static size_t factor
[] = {1, 2};
56 DCHECK_LT(static_cast<size_t>(plane
), arraysize(factor
));
64 size_t RowSizeForBufferFormat(size_t width
, BufferFormat format
, int plane
) {
66 bool valid
= RowSizeForBufferFormatChecked(width
, format
, plane
, &row_size
);
71 bool RowSizeForBufferFormatChecked(
72 size_t width
, BufferFormat format
, int plane
, size_t* size_in_bytes
) {
73 base::CheckedNumeric
<size_t> checked_size
= width
;
75 case BufferFormat::ATCIA
:
76 case BufferFormat::DXT5
:
78 *size_in_bytes
= width
;
80 case BufferFormat::ATC
:
81 case BufferFormat::DXT1
:
82 case BufferFormat::ETC1
:
84 DCHECK_EQ(0u, width
% 2);
85 *size_in_bytes
= width
/ 2;
87 case BufferFormat::R_8
:
89 if (!checked_size
.IsValid())
91 *size_in_bytes
= checked_size
.ValueOrDie() & ~0x3;
93 case BufferFormat::RGBA_4444
:
94 case BufferFormat::UYVY_422
:
96 if (!checked_size
.IsValid())
98 *size_in_bytes
= checked_size
.ValueOrDie();
100 case BufferFormat::BGRX_8888
:
101 case BufferFormat::RGBA_8888
:
102 case BufferFormat::BGRA_8888
:
104 if (!checked_size
.IsValid())
106 *size_in_bytes
= checked_size
.ValueOrDie();
108 case BufferFormat::YUV_420
:
109 DCHECK_EQ(0u, width
% 2);
110 *size_in_bytes
= width
/ SubsamplingFactorForBufferFormat(format
, plane
);
112 case gfx::BufferFormat::YUV_420_BIPLANAR
:
113 DCHECK_EQ(width
% 2, 0u);
114 *size_in_bytes
= width
;
121 size_t BufferSizeForBufferFormat(
122 const Size
& size
, BufferFormat format
) {
123 size_t buffer_size
= 0;
124 bool valid
= BufferSizeForBufferFormatChecked(size
, format
, &buffer_size
);
129 bool BufferSizeForBufferFormatChecked(
130 const Size
& size
, BufferFormat format
, size_t* size_in_bytes
) {
131 base::CheckedNumeric
<size_t> checked_size
= 0;
132 size_t num_planes
= NumberOfPlanesForBufferFormat(format
);
133 for (size_t i
= 0; i
< num_planes
; ++i
) {
135 if (!RowSizeForBufferFormatChecked(size
.width(), format
, i
, &row_size
))
137 base::CheckedNumeric
<size_t> checked_plane_size
= row_size
;
138 checked_plane_size
*= size
.height() /
139 SubsamplingFactorForBufferFormat(format
, i
);
140 if (!checked_plane_size
.IsValid())
142 checked_size
+= checked_plane_size
.ValueOrDie();
143 if (!checked_size
.IsValid())
146 *size_in_bytes
= checked_size
.ValueOrDie();