/* 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 #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 ] [-o ] [-t ] \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