Skip to content

Commit 2c1cc22

Browse files
committed
PngSequenceToAvi project
1 parent 0af78c3 commit 2c1cc22

11 files changed

+545
-26
lines changed

Common/MLAVICommon.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,26 @@ enum MLAviImageFormat {
1111
MLIF_Unknown = -1,
1212
MLIF_YUV422_UYVY,
1313
MLIF_YUV422_v210,
14+
MLIF_B8G8R8,
1415
MLIF_RGB10bit_r210,
1516
MLIF_RGB12bit_R12B,
1617
};
1718

1819
uint32_t
1920
MLAviImageFormatToFourcc(MLAviImageFormat t);
2021

22+
/// <summary>
23+
/// 注意!この値はAVIのBitmapInfoHeaderのbiBitCountに書き込む値。
24+
/// ファイルの上で1ピクセルが占めるビット数はMLAviImageFormatToBitsPerPixel2()で取得して下さい。
25+
/// </summary>
2126
int
22-
MLAviImageFormatToBitsPerPixel(MLAviImageFormat t);
27+
MLAviImageFormatToBiBitCount(MLAviImageFormat t);
2328

29+
/// <summary>
30+
/// ファイル上で1ピクセルが占めるビット数。
31+
/// </summary>
32+
int
33+
MLAviImageFormatToBitsPerPixel2(MLAviImageFormat t);
2434

2535
enum MLFOURCC {
2636
MLFOURCC_RIFF = 0x46464952,

Common/MLAviWriter.cpp

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ MLAviWriter::Start(std::wstring path, int width, int height, double fps, MLAviIm
5151
mAudio = bAudio;
5252

5353
switch (mInputImgFmt) {
54+
case MLIF_B8G8R8:
5455
case MLIF_YUV422_v210:
5556
case MLIF_RGB10bit_r210:
5657
// そのままAVIファイルに保存する。
@@ -150,10 +151,11 @@ MLAviWriter::Start(std::wstring path, int width, int height, double fps, MLAviIm
150151
}
151152

152153
uint8_t*
153-
MLAviWriter::ConvCapturedImg(const uint8_t* imgFrom, int fromBytes, int * toBytes_return)
154+
MLAviWriter::ConvImg(const uint8_t* imgFrom, int fromBytes, int * toBytes_return)
154155
{
155156
uint8_t* imgTo = nullptr;
156157
switch (mInputImgFmt) {
158+
case MLIF_B8G8R8:
157159
case MLIF_YUV422_v210:
158160
case MLIF_RGB10bit_r210:
159161
{
@@ -193,7 +195,7 @@ MLAviWriter::AddImage(const uint8_t * img, int bytes)
193195
IncomingItem ii;
194196

195197
int writeBytes;
196-
ii.buf = ConvCapturedImg(img, bytes, &writeBytes);
198+
ii.buf = ConvImg(img, bytes, &writeBytes);
197199

198200
ii.bytes = writeBytes;
199201
ii.bAudio = false;
@@ -348,6 +350,8 @@ uint32_t
348350
MLAviWriter::ImageBytes(void) const
349351
{
350352
switch (mWriteImgFmt) {
353+
case MLIF_B8G8R8:
354+
return mWidth * mHeight * 3;
351355
case MLIF_YUV422_v210:
352356
return mWidth * mHeight * 8 / 3;
353357
case MLIF_RGB10bit_r210:
@@ -390,6 +394,8 @@ uint32_t
390394
MLAviImageFormatToFourcc(MLAviImageFormat t)
391395
{
392396
switch (t) {
397+
case MLIF_B8G8R8:
398+
return 0;
393399
case MLIF_YUV422_UYVY:
394400
return MLStringToFourCC("UYVY");
395401
case MLIF_YUV422_v210:
@@ -405,15 +411,38 @@ MLAviImageFormatToFourcc(MLAviImageFormat t)
405411
}
406412

407413
int
408-
MLAviImageFormatToBitsPerPixel(MLAviImageFormat t)
414+
MLAviImageFormatToBiBitCount(MLAviImageFormat t)
415+
{
416+
// BitmapInfoHeaderのbiBitCountに書き込む値。
417+
// ファイル上で1ピクセルが占めるサイズは以下の値よりも大きい場合がある!
418+
switch (t) {
419+
case MLIF_B8G8R8:
420+
return 24;
421+
case MLIF_YUV422_UYVY:
422+
return 16;
423+
case MLIF_YUV422_v210:
424+
return 20;
425+
case MLIF_RGB10bit_r210:
426+
return 30; //< これが異なる。各ピクセルに要素xが2ビットを占める。
427+
case MLIF_RGB12bit_R12B:
428+
return 36;
429+
default:
430+
assert(0);
431+
return 0;
432+
}
433+
}
434+
int
435+
MLAviImageFormatToBitsPerPixel2(MLAviImageFormat t)
409436
{
410437
switch (t) {
438+
case MLIF_B8G8R8:
439+
return 24;
411440
case MLIF_YUV422_UYVY:
412441
return 16;
413442
case MLIF_YUV422_v210:
414443
return 20;
415444
case MLIF_RGB10bit_r210:
416-
return 30;
445+
return 32;
417446
case MLIF_RGB12bit_R12B:
418447
return 36;
419448
default:
@@ -487,7 +516,7 @@ MLAviWriter::WriteBitmapInfoHeader(void)
487516
ih.biWidth = mWidth;
488517
ih.biHeight = mHeight;
489518
ih.biPlanes = 1;
490-
ih.biBitCount = MLAviImageFormatToBitsPerPixel(mWriteImgFmt);
519+
ih.biBitCount = MLAviImageFormatToBiBitCount(mWriteImgFmt);
491520
ih.biCompression = MLAviImageFormatToFourcc(mWriteImgFmt);
492521
ih.biSizeImage = ImageBytes();
493522
ih.biXPelsPerMeter = 0;

Common/MLAviWriter.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,19 @@ class MLAviWriter {
1515
MLAviWriter(void);
1616
~MLAviWriter(void);
1717

18+
/*
19+
使用方法
20+
Start()
21+
AddImage()
22+
StopBlocking()
23+
24+
または
25+
Start()
26+
AddImage()
27+
StopAsync()
28+
while (!PollThreadEnd()) { }
29+
*/
30+
1831
bool Start(std::wstring path, int width, int height, double fps, MLAviImageFormat imgFmt,
1932
bool bAudio);
2033

@@ -23,7 +36,7 @@ class MLAviWriter {
2336
void AddAudio(const uint8_t * buff, int frames);
2437

2538
// send thread to flush remaining data and end.
26-
// StopAsync() then call PallThreadEnd() every frame until PollThreadEnd() returns true
39+
// StopAsync() then call PollThreadEnd() every frame until PollThreadEnd() returns true
2740
void StopAsync(void);
2841

2942
// returns true when writing thread ends
@@ -131,8 +144,8 @@ class MLAviWriter {
131144
void StopThreadAsync(void);
132145

133146
/// <summary>
134-
/// new[] で確保し、キャプチャー画像を変換またはコピーします
147+
/// toBytes_returnをnew[]で確保、そこに画像をコピーまたはAVIで保存できる形式に変換書き込みします
135148
/// </summary>
136-
uint8_t* ConvCapturedImg(const uint8_t* imgFrom, int fromBytes, int * toBytes_return);
149+
uint8_t* ConvImg(const uint8_t* imgFrom, int fromBytes, int * toBytes_return);
137150
};
138151

Common/MLConverter.cpp

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,101 @@ MLConverter::MLConverter(void)
236236
}
237237
}
238238

239+
240+
void
241+
MLConverter::R8G8B8A8ToB8G8R8_DIB(const uint32_t* pFrom, uint8_t* pTo, const int width, const int height)
242+
{
243+
#pragma omp parallel for
244+
for (int y = 0; y < height; ++y) {
245+
for (int x = 0; x < width; ++x) {
246+
const int posR = x + y * width;
247+
248+
// BMPは上下反転する。
249+
const int posW = 3 * (x + (height - y - 1) * width);
250+
251+
const uint32_t w = pFrom[posR];
252+
253+
const uint8_t r = (w >> 0) & 0xff;
254+
const uint8_t g = (w >> 8) & 0xff;
255+
const uint8_t b = (w >> 16) & 0xff;
256+
pTo[posW + 0] = b;
257+
pTo[posW + 1] = g;
258+
pTo[posW + 2] = r;
259+
}
260+
}
261+
}
262+
263+
264+
void
265+
MLConverter::R8G8B8A8ToB8G8R8A8_DIB(const uint32_t* pFrom, uint8_t* pTo, const int width, const int height)
266+
{
267+
#pragma omp parallel for
268+
for (int y = 0; y < height; ++y) {
269+
for (int x = 0; x < width; ++x) {
270+
const int posR = x + y * width;
271+
// BMPは上下反転する。
272+
const int posW = 4 * (x + (height - y - 1) * width);
273+
274+
const uint32_t w = pFrom[posR];
275+
276+
const uint8_t r = (w >> 0) & 0xff;
277+
const uint8_t g = (w >> 8) & 0xff;
278+
const uint8_t b = (w >> 16) & 0xff;
279+
const uint8_t a = (w >> 24) & 0xff;
280+
281+
pTo[posW + 0] = b;
282+
pTo[posW + 1] = g;
283+
pTo[posW + 2] = r;
284+
pTo[posW + 3] = a;
285+
}
286+
}
287+
}
288+
289+
290+
void
291+
MLConverter::R8G8B8ToB8G8R8_DIB(const uint8_t* pFrom, uint8_t* pTo, const int width, const int height)
292+
{
293+
#pragma omp parallel for
294+
for (int y = 0; y < height; ++y) {
295+
for (int x = 0; x < width; ++x) {
296+
const int posR = 3 * (x + y * width);
297+
// BMPは上下反転する。
298+
const int posW = 3 * (x + (height-y-1) * width);
299+
300+
const uint8_t r = pFrom[posR + 0];
301+
const uint8_t g = pFrom[posR + 1];
302+
const uint8_t b = pFrom[posR + 2];
303+
pTo[posW + 0] = b;
304+
pTo[posW + 1] = g;
305+
pTo[posW + 2] = r;
306+
}
307+
}
308+
}
309+
310+
311+
void
312+
MLConverter::R8G8B8ToB8G8R8A8_DIB(const uint8_t* pFrom, uint8_t* pTo, const int width, const int height, const uint8_t alpha)
313+
{
314+
#pragma omp parallel for
315+
for (int y = 0; y < height; ++y) {
316+
for (int x = 0; x < width; ++x) {
317+
const int posR = 3 * (x + y * width);
318+
// BMPは上下反転する。
319+
const int posW = 4 * (x + (height - y - 1) * width);
320+
321+
const uint8_t r = pFrom[posR + 0];
322+
const uint8_t g = pFrom[posR + 1];
323+
const uint8_t b = pFrom[posR + 2];
324+
const uint8_t a = alpha;
325+
pTo[posW + 0] = b;
326+
pTo[posW + 1] = g;
327+
pTo[posW + 2] = r;
328+
pTo[posW + 3] = a;
329+
}
330+
}
331+
}
332+
333+
239334
void
240335
MLConverter::Uyvy8bitToR8G8B8A8(const ColorSpace colorSpace, const uint32_t* pFrom, uint32_t* pTo, const int width, const int height)
241336
{
@@ -534,6 +629,35 @@ MLConverter::R10G10B10A2ToR210(const uint32_t* pFrom, uint32_t* pTo, const int w
534629
}
535630
}
536631

632+
/// <summary>
633+
/// 16bit RGBA to R210
634+
/// </summary>
635+
void
636+
MLConverter::R16G16B16A16ToR210(const uint16_t* pFrom, uint32_t* pTo, const int width, const int height)
637+
{
638+
#pragma omp parallel for
639+
for (int y = 0; y < height; ++y) {
640+
for (int x = 0; x < width; ++x) {
641+
const int posR = 4 * x + y * width;
642+
const int posW = x + y * width;
643+
644+
// quantize to 10bit
645+
const uint32_t r = (pFrom[posR + 0] >> 6) & 0x3ff;
646+
const uint32_t g = (pFrom[posR + 1] >> 6) & 0x3ff;
647+
const uint32_t b = (pFrom[posR + 2] >> 6) & 0x3ff;
648+
649+
// alpha: quantize to 2bit
650+
const uint32_t a = (pFrom[posR + 3] >> 14) & 0x3;
651+
652+
// bmdFormat10BitRGB
653+
// ビッグエンディアンのX2R10G10B10
654+
655+
const uint32_t r210 = (a << 30) + (r << 20) + (g << 10) + b;
656+
pTo[posW] = HtoNL(r210);
657+
}
658+
}
659+
}
660+
537661
/// <summary>
538662
/// bmdFormat12BitRGB → DXGI_FORMAT_R8G8B8A8_UNORM
539663
/// </summary>

Common/MLConverter.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,18 @@ class MLConverter {
1414
CS_Rec2020,
1515
};
1616

17+
/// <summary>
18+
/// R8G8B8A8 to B8G8R8 for BMP save
19+
/// </summary>
20+
static void R8G8B8A8ToB8G8R8_DIB(const uint32_t* pFrom, uint8_t* pTo, const int width, const int height);
21+
static void R8G8B8A8ToB8G8R8A8_DIB(const uint32_t* pFrom, uint8_t* pTo, const int width, const int height);
22+
23+
/// <summary>
24+
/// R8G8B8 to B8G8R8 for BMP save
25+
/// </summary>
26+
static void R8G8B8ToB8G8R8_DIB(const uint8_t* pFrom, uint8_t* pTo, const int width, const int height);
27+
static void R8G8B8ToB8G8R8A8_DIB(const uint8_t* pFrom, uint8_t* pTo, const int width, const int height, const uint8_t alpha);
28+
1729
/// <summary>
1830
/// bmdFormat8BitYUV UYVY ¨ DXGI_FORMAT_R8G8B8A8_UNORM
1931
/// </summary>
@@ -75,6 +87,11 @@ class MLConverter {
7587
/// </summary>
7688
static void R10G10B10A2ToR210(const uint32_t* pFrom, uint32_t* pTo, const int width, const int height, const uint8_t alpha);
7789

90+
/// <summary>
91+
/// 16bit RGBA to R210
92+
/// </summary>
93+
static void R16G16B16A16ToR210(const uint16_t* pFrom, uint32_t* pTo, const int width, const int height);
94+
7895
private:
7996
half mGammaInv22_10bit[1024];
8097
half mGammaInvST2084_10bit[1024];

0 commit comments

Comments
 (0)