1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "mozilla/layers/YCbCrImageDataSerializer.h"
8 #define MOZ_ALIGN_WORD(x) (((x) + 3) & ~3)
10 using namespace mozilla::ipc
;
15 // The Data is layed out as follows:
17 // +-----------------+ -++ --+ --+ <-- Beginning of the buffer
18 // | YCbCrBufferInfo | | | |
19 // +-----------------+ --+ | |
20 // | data | | | YCbCrBufferInfo->[mY/mCb/mCr]Offset
21 // +-----------------+ ------+ |
23 // +-----------------+ ----------+
25 // +-----------------+
27 // There can be padding between the blocks above to keep word alignment.
29 // Structure written at the beginning og the data blob containing the image
30 // (as shown in the figure above). It contains the necessary informations to
31 // read the image in the blob.
32 struct YCbCrBufferInfo
43 static YCbCrBufferInfo
* GetYCbCrBufferInfo(uint8_t* aData
)
45 return reinterpret_cast<YCbCrBufferInfo
*>(aData
);
48 bool YCbCrImageDataDeserializerBase::IsValid()
50 if (mData
== nullptr) {
56 uint8_t* YCbCrImageDataDeserializerBase::GetYData()
58 YCbCrBufferInfo
* info
= GetYCbCrBufferInfo(mData
);
59 return reinterpret_cast<uint8_t*>(info
) + info
->mYOffset
;
62 uint8_t* YCbCrImageDataDeserializerBase::GetCbData()
64 YCbCrBufferInfo
* info
= GetYCbCrBufferInfo(mData
);
65 return reinterpret_cast<uint8_t*>(info
) + info
->mCbOffset
;
68 uint8_t* YCbCrImageDataDeserializerBase::GetCrData()
70 YCbCrBufferInfo
* info
= GetYCbCrBufferInfo(mData
);
71 return reinterpret_cast<uint8_t*>(info
) + info
->mCrOffset
;
74 uint8_t* YCbCrImageDataDeserializerBase::GetData()
76 YCbCrBufferInfo
* info
= GetYCbCrBufferInfo(mData
);
77 return (reinterpret_cast<uint8_t*>(info
)) + MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo
));
80 uint32_t YCbCrImageDataDeserializerBase::GetYStride()
82 YCbCrBufferInfo
* info
= GetYCbCrBufferInfo(mData
);
86 uint32_t YCbCrImageDataDeserializerBase::GetCbCrStride()
88 YCbCrBufferInfo
* info
= GetYCbCrBufferInfo(mData
);
89 return info
->mCbCrWidth
;
92 gfxIntSize
YCbCrImageDataDeserializerBase::GetYSize()
94 YCbCrBufferInfo
* info
= GetYCbCrBufferInfo(mData
);
95 return gfxIntSize(info
->mYWidth
, info
->mYHeight
);
98 gfxIntSize
YCbCrImageDataDeserializerBase::GetCbCrSize()
100 YCbCrBufferInfo
* info
= GetYCbCrBufferInfo(mData
);
101 return gfxIntSize(info
->mCbCrWidth
, info
->mCbCrHeight
);
105 static size_t ComputeOffset(uint32_t aHeight
, uint32_t aStride
)
107 return MOZ_ALIGN_WORD(aHeight
* aStride
);
110 // Minimum required shmem size in bytes
112 YCbCrImageDataSerializer::ComputeMinBufferSize(const gfx::IntSize
& aYSize
,
113 const gfx::IntSize
& aCbCrSize
)
115 uint32_t yStride
= aYSize
.width
;
116 uint32_t CbCrStride
= aCbCrSize
.width
;
118 return ComputeOffset(aYSize
.height
, yStride
)
119 + 2 * ComputeOffset(aCbCrSize
.height
, CbCrStride
)
120 + MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo
));
124 YCbCrImageDataSerializer::ComputeMinBufferSize(const gfxIntSize
& aYSize
,
125 const gfxIntSize
& aCbCrSize
)
127 return ComputeMinBufferSize(gfx::IntSize(aYSize
.width
, aYSize
.height
),
128 gfx::IntSize(aCbCrSize
.width
, aCbCrSize
.height
));
131 static size_t ComputeOffset(uint32_t aSize
)
133 return MOZ_ALIGN_WORD(aSize
);
136 // Minimum required shmem size in bytes
138 YCbCrImageDataSerializer::ComputeMinBufferSize(uint32_t aSize
)
140 return ComputeOffset(aSize
) + MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo
));
144 YCbCrImageDataSerializer::InitializeBufferInfo(const gfx::IntSize
& aYSize
,
145 const gfx::IntSize
& aCbCrSize
)
147 YCbCrBufferInfo
* info
= GetYCbCrBufferInfo(mData
);
148 info
->mYOffset
= MOZ_ALIGN_WORD(sizeof(YCbCrBufferInfo
));
149 info
->mCbOffset
= info
->mYOffset
150 + MOZ_ALIGN_WORD(aYSize
.width
* aYSize
.height
);
151 info
->mCrOffset
= info
->mCbOffset
152 + MOZ_ALIGN_WORD(aCbCrSize
.width
* aCbCrSize
.height
);
154 info
->mYWidth
= aYSize
.width
;
155 info
->mYHeight
= aYSize
.height
;
156 info
->mCbCrWidth
= aCbCrSize
.width
;
157 info
->mCbCrHeight
= aCbCrSize
.height
;
161 YCbCrImageDataSerializer::InitializeBufferInfo(const gfxIntSize
& aYSize
,
162 const gfxIntSize
& aCbCrSize
)
164 InitializeBufferInfo(gfx::IntSize(aYSize
.width
, aYSize
.height
),
165 gfx::IntSize(aCbCrSize
.width
, aCbCrSize
.height
));
168 static void CopyLineWithSkip(const uint8_t* src
, uint8_t* dst
, uint32_t len
, uint32_t skip
) {
169 for (uint32_t i
= 0; i
< len
; ++i
) {
177 YCbCrImageDataSerializer::CopyData(const uint8_t* aYData
,
178 const uint8_t* aCbData
, const uint8_t* aCrData
,
179 gfxIntSize aYSize
, uint32_t aYStride
,
180 gfxIntSize aCbCrSize
, uint32_t aCbCrStride
,
181 uint32_t aYSkip
, uint32_t aCbCrSkip
)
183 if (!IsValid() || GetYSize() != aYSize
|| GetCbCrSize() != aCbCrSize
) {
186 for (int i
= 0; i
< aYSize
.height
; ++i
) {
189 memcpy(GetYData() + i
* GetYStride(),
190 aYData
+ i
* aYStride
,
194 CopyLineWithSkip(aYData
+ i
* aYStride
,
195 GetYData() + i
* GetYStride(),
196 aYSize
.width
, aYSkip
);
199 for (int i
= 0; i
< aCbCrSize
.height
; ++i
) {
200 if (aCbCrSkip
== 0) {
202 memcpy(GetCbData() + i
* GetCbCrStride(),
203 aCbData
+ i
* aCbCrStride
,
205 memcpy(GetCrData() + i
* GetCbCrStride(),
206 aCrData
+ i
* aCbCrStride
,
210 CopyLineWithSkip(aCbData
+ i
* aCbCrStride
,
211 GetCbData() + i
* GetCbCrStride(),
212 aCbCrSize
.width
, aCbCrSkip
);
213 CopyLineWithSkip(aCrData
+ i
* aCbCrStride
,
214 GetCrData() + i
* GetCbCrStride(),
215 aCbCrSize
.width
, aCbCrSkip
);