windows-nt/Source/XPSP1/NT/multimedia/dshow/mfvideo/mswebdvd/savebmp.cpp
2020-09-26 16:20:57 +08:00

109 lines
2.9 KiB
C++

/*************************************************************************/
/* Copyright (C) 2000 Microsoft Corporation */
/* File: savebmp.cpp */
/* Description: Save a CaptureBitmapData to BMP file format. */
/* Note: This is not a general BMP encode function. */
/* Special assumptions made about bitmap format: */
/* RGB (3 bytes per pixel without colormap) */
/* */
/* Author: Phillip Lu */
/*************************************************************************/
#include "stdafx.h"
#include <stdio.h>
#include "capture.h"
HRESULT WriteBitmapDataToBMPFile(char *filename, CaptureBitmapData *bmpdata)
{
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bmih;
UINT numColors = 0; // Number of colors in bmiColors
FILE *outfile = NULL;
HRESULT hr = S_OK;
BYTE *bufline = NULL;
int bitmapStride;
int nBytesWritten;
// Setup BITMAPINFOHEADER
ZeroMemory(&bmih, sizeof(bmih));
bmih.biSize = sizeof(bmih);
bmih.biWidth = bmpdata->Width;
bmih.biHeight = bmpdata->Height;
bmih.biPlanes = 1;
bmih.biCompression = BI_RGB;
bmih.biBitCount = 24;
// Compute the bitmap stride
bitmapStride = (bmpdata->Width * bmih.biBitCount + 7) / 8;
bitmapStride = (bitmapStride + 3) & (~3);
// Now fill in the BITMAPFILEHEADER
bfh.bfType = 0x4d42;
bfh.bfReserved1 = 0;
bfh.bfReserved2 = 0;
bfh.bfOffBits = sizeof(bfh) + sizeof(bmih) + numColors * sizeof(RGBQUAD);
bfh.bfSize = bfh.bfOffBits + bitmapStride * bmpdata->Height;
// allocate a buffer to hold one line of bitmap data
bufline = new BYTE[bitmapStride];
if (NULL == bufline)
{
hr = E_OUTOFMEMORY;
return hr;
}
ZeroMemory(bufline, bitmapStride);
if ((outfile = fopen(filename, "wb")) == NULL)
{
delete[] bufline;
hr = E_FAIL;
return hr;
}
// Write the BITMAPFILEHEADER
fwrite((void *)&bfh, sizeof(bfh), 1, outfile);
// Write the BITMAPINFOHEADER
fwrite((void *)&bmih, sizeof(bmih), 1, outfile);
// Write bitmap data
for (int iLine = bmpdata->Height-1; iLine >= 0; iLine--)
{
BYTE *bmpSrc = bmpdata->Scan0 + iLine*bmpdata->Stride;
BYTE *bmpDst = bufline;
for (int iPixel=0; iPixel<bmpdata->Width; iPixel++)
{
// in BMP file a pixel is in BGR order, so we have reverse it
bmpDst[2] = *bmpSrc++;
bmpDst[1] = *bmpSrc++;
bmpDst[0] = *bmpSrc++;
bmpDst += 3;
}
fwrite(bufline, bitmapStride, 1, outfile);
}
if (bufline != NULL)
{
delete[] bufline;
}
if (outfile != NULL)
{
fclose(outfile);
}
return hr;
}