Microsoft-3D-Movie-Maker/kauai/TOOLS/MKMBMP.CPP
2022-05-03 16:31:19 -07:00

311 lines
6.5 KiB
C++

/* Copyright (c) Microsoft Corporation.
Licensed under the MIT License. */
/***************************************************************************
Author: ShonK
Project: Kauai
Copyright (c) Microsoft Corporation
Command line tool to make an mbmp from a bitmap file and optionally
compress it.
***************************************************************************/
#include <stdio.h>
#include "frame.h"
ASSERTNAME
bool _FGetLwFromSzs(PSZS pszs, long *plw);
/***************************************************************************
Main routine. Returns non-zero iff there's an error.
***************************************************************************/
int __cdecl main(int cpszs, char *prgpszs[])
{
FNI fniSrc, fniDst;
STN stn;
char chs;
FLO flo;
long lwSig;
PMBMP pmbmp = pvNil;
long cfni = 0;
long xp = 0;
long yp = 0;
long lwTrans = 0;
long cfmt = cfmtNil;
#ifdef UNICODE
fprintf(stderr, "\nMicrosoft (R) Make Mbmp Utility (Unicode; "
Debug("Debug; ") __DATE__ "; " __TIME__ ")\n");
#else //!UNICODE
fprintf(stderr, "\nMicrosoft (R) Make Mbmp Utility (Ansi; "
Debug("Debug; ") __DATE__ "; " __TIME__ ")\n");
#endif //!UNICODE
fprintf(stderr,
"Copyright (C) Microsoft Corp 1995. All rights reserved.\n\n");
flo.pfil = pvNil;
for (prgpszs++; --cpszs > 0; prgpszs++)
{
chs = (*prgpszs)[0];
if (chs == '/' || chs == '-')
{
switch ((*prgpszs)[1])
{
case 'c':
case 'C':
switch ((*prgpszs)[2])
{
case '\0':
cfmt = vpcodmUtil->CfmtDefault();
break;
case '0':
cfmt = cfmtNil;
break;
case '1':
cfmt = kcfmtKauai;
break;
case '2':
cfmt = kcfmtKauai2;
break;
default:
fprintf(stderr, "Bad compression format\n\n");
goto LUsage;
}
break;
case 'p':
case 'P':
if (cpszs <= 0 || !_FGetLwFromSzs(prgpszs[1], &cfmt))
{
fprintf(stderr, "Bad compression format\n\n");
goto LUsage;
}
cpszs--;
prgpszs++;
break;
case 'o':
case 'O':
// get the coordinates of the reference point
if (cpszs < 2)
goto LUsage;
cpszs -= 2;
stn.SetSzs(prgpszs[1]);
if (!stn.FGetLw(&xp))
goto LUsage;
stn.SetSzs(prgpszs[2]);
if (!stn.FGetLw(&yp))
goto LUsage;
prgpszs += 2;
break;
case 't':
case 'T':
// get the transparent pixel value
if (cpszs < 1)
goto LUsage;
cpszs--;
stn.SetSzs(prgpszs[1]);
if (!stn.FGetLw(&lwTrans))
goto LUsage;
prgpszs++;
break;
default:
goto LUsage;
}
}
else if (cfni >= 2)
{
fprintf(stderr, "Too many file names\n\n");
goto LUsage;
}
else
{
stn.SetSzs(prgpszs[0]);
if (!fniDst.FBuildFromPath(&stn))
{
fprintf(stderr, "Bad file name\n\n");
goto LUsage;
}
if (cfni == 0)
fniSrc = fniDst;
cfni++;
}
}
if (cfni != 2)
{
fprintf(stderr, "Wrong number of file names\n\n");
goto LUsage;
}
if (cfmtNil != cfmt && !vpcodmUtil->FCanDo(cfmt, fTrue))
{
fprintf(stderr, "Bad compression type\n\n");
goto LUsage;
}
pmbmp = MBMP::PmbmpReadNative(&fniSrc, B0Lw(lwTrans), xp, yp);
if (pvNil == pmbmp)
{
fprintf(stderr, "reading bitmap failed\n\n");
goto LFail;
}
if (pvNil == (flo.pfil = FIL::PfilCreate(&fniDst)))
{
fprintf(stderr, "Couldn't create destination file\n\n");
goto LFail;
}
flo.fp = size(long);
flo.cb = pmbmp->CbOnFile();
if (cfmtNil != cfmt)
{
BLCK blck;
if (!blck.FSetTemp(flo.cb) || !pmbmp->FWrite(&blck))
{
fprintf(stderr, "allocation failure\n\n");
goto LFail;
}
ReleasePpo(&pmbmp);
if (!blck.FPackData(cfmt))
lwSig = klwSigUnpackedFile;
else
{
lwSig = klwSigPackedFile;
flo.cb = blck.Cb(fTrue);
}
if (!flo.pfil->FWriteRgb(&lwSig, size(long), 0) ||
!blck.FWriteToFlo(&flo, fTrue))
{
fprintf(stderr, "writing to destination file failed\n\n");
goto LFail;
}
}
else
{
lwSig = klwSigUnpackedFile;
if (!flo.pfil->FWriteRgb(&lwSig, size(long), 0) ||
!pmbmp->FWriteFlo(&flo))
{
fprintf(stderr, "writing to destination file failed\n\n");
goto LFail;
}
ReleasePpo(&pmbmp);
}
ReleasePpo(&flo.pfil);
FIL::ShutDown();
return 0;
LUsage:
//print usage
fprintf(stderr, "%s",
"Usage: mkmbmp [-c[0|1|2]] [-p <format>] [-o <x> <y>] [-t <b>] <srcBitmapFile> <dstMbmpFile>\n\n");
LFail:
ReleasePpo(&pmbmp);
if (pvNil != flo.pfil)
flo.pfil->SetTemp();
ReleasePpo(&flo.pfil);
FIL::ShutDown();
return 1;
}
/***************************************************************************
Get a long value from a string. If the string isn't a number and the
length is <= 4, assumes the characters are to be packed into a long
(ala CTGs and FTGs).
***************************************************************************/
bool _FGetLwFromSzs(PSZS pszs, long *plw)
{
STN stn;
long ich;
stn.SetSzs(pszs);
if (stn.FGetLw(plw))
return fTrue;
if (stn.Cch() > 4)
return fFalse;
*plw = 0;
for (ich = 0; ich < stn.Cch(); ich++)
*plw = (*plw << 8) + (byte)stn.Prgch()[ich];
return fTrue;
}
#ifdef DEBUG
bool _fEnableWarnings = fTrue;
/***************************************************************************
Warning proc called by Warn() macro
***************************************************************************/
void WarnProc(PSZS pszsFile, long lwLine, PSZS pszsMessage)
{
if (_fEnableWarnings)
{
fprintf(stderr, "%s(%ld) : warning", pszsFile, lwLine);
if (pszsMessage != pvNil)
{
fprintf(stderr, ": %s", pszsMessage);
}
fprintf(stderr, "\n");
}
}
/***************************************************************************
Returning true breaks into the debugger.
***************************************************************************/
bool FAssertProc(PSZS pszsFile, long lwLine, PSZS pszsMessage,
void *pv, long cb)
{
fprintf(stderr, "An assert occurred: \n");
if (pszsMessage != pvNil)
fprintf(stderr, " Message: %s\n", pszsMessage);
if (pv != pvNil)
{
fprintf(stderr, " Address %x\n", pv);
if (cb != 0)
{
fprintf(stderr, " Value: ");
switch (cb)
{
default:
{
byte *pb;
byte *pbLim;
for (pb = (byte *)pv, pbLim = pb + cb; pb < pbLim; pb++)
fprintf(stderr, "%02x", (int)*pb);
}
break;
case 2:
fprintf(stderr, "%04x", (int)*(short *)pv);
break;
case 4:
fprintf(stderr, "%08lx", *(long *)pv);
break;
}
printf("\n");
}
}
fprintf(stderr, " File: %s\n", pszsFile);
fprintf(stderr, " Line: %ld\n", lwLine);
return fFalse;
}
#endif //DEBUG