2007-03-27 17:47:10 +00:00
|
|
|
/*
|
|
|
|
* CiderPress
|
|
|
|
* Copyright (C) 2007 by faddenSoft, LLC. All Rights Reserved.
|
|
|
|
* See the file LICENSE for distribution terms.
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
* [Ported back from libfadden]
|
|
|
|
*
|
|
|
|
* Implementation of DIBitmap class. This began life as a simple DIBSection
|
|
|
|
* wrapper, and has gradually evolved into a bitmap class that creates
|
|
|
|
* DIBSections and DDBs when necessary.
|
|
|
|
*
|
|
|
|
* BMP file format is:
|
2014-11-04 00:26:53 +00:00
|
|
|
* file header (BITMAPFILEHEADER)
|
|
|
|
* information header (BITMAPINFO; size determined by header.vfOffBits)
|
|
|
|
* information (BITMAPINFOHEADER)
|
|
|
|
* color table (RGBQUAD[])
|
|
|
|
* pixel bits
|
2007-03-27 17:47:10 +00:00
|
|
|
*
|
|
|
|
* The DIBSECTION struct includes BITMAP and BITMAPINFOHEADER.
|
|
|
|
*
|
|
|
|
* The DIB we create doesn't really have a color table. The color table is
|
|
|
|
* set when we convert to a DDB or write the bitmap to a file.
|
|
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "MyDIBitmap.h"
|
|
|
|
#include "Util.h"
|
|
|
|
|
|
|
|
//#include "libfadden.h"
|
|
|
|
//using namespace libfadden;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Destroy allocated memory and delete the DIB object.
|
|
|
|
*/
|
|
|
|
MyDIBitmap::~MyDIBitmap(void)
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
if (mhBitmap != nil)
|
|
|
|
::DeleteObject(mhBitmap);
|
|
|
|
delete[] mpFileBuffer;
|
|
|
|
delete[] mpColorTable;
|
2007-03-27 17:47:10 +00:00
|
|
|
|
2014-11-04 00:26:53 +00:00
|
|
|
/* fpPixels point to system-allocated memory inside fhBitmap */
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create a blank DIB with the requested dimensions.
|
|
|
|
*
|
|
|
|
* We probably don't need to allocate DIB storage here. We can do most
|
|
|
|
* operations ourselves, in local memory, and only convert when needed.
|
|
|
|
*
|
|
|
|
* Returns a pointer to the pixel storage on success, or nil on failure.
|
|
|
|
*/
|
|
|
|
void*
|
|
|
|
MyDIBitmap::Create(int width, int height, int bitsPerPixel, int colorsUsed,
|
2014-11-04 00:26:53 +00:00
|
|
|
bool dibSection /*=false*/)
|
2007-03-27 17:47:10 +00:00
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
if (mhBitmap != nil || mpPixels != nil || mpFileBuffer != nil) {
|
|
|
|
WMSG0(" DIB GLITCH: already created\n");
|
|
|
|
assert(false);
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(width > 0 && height > 0);
|
|
|
|
assert(bitsPerPixel == 1 ||
|
|
|
|
bitsPerPixel == 4 ||
|
|
|
|
bitsPerPixel == 8 ||
|
|
|
|
bitsPerPixel == 16 ||
|
|
|
|
bitsPerPixel == 24 ||
|
|
|
|
bitsPerPixel == 32);
|
|
|
|
assert(bitsPerPixel == 24 || bitsPerPixel == 32 || colorsUsed > 0);
|
|
|
|
|
|
|
|
// should include a warning if line stride is not a multiple of 4 bytes
|
|
|
|
|
|
|
|
mBitmapInfoHdr.biSize = sizeof(mBitmapInfoHdr); // BITMAPINFOHEADER
|
|
|
|
mBitmapInfoHdr.biWidth = width;
|
|
|
|
mBitmapInfoHdr.biHeight = height;
|
|
|
|
mBitmapInfoHdr.biPlanes = 1;
|
|
|
|
mBitmapInfoHdr.biBitCount = bitsPerPixel;
|
|
|
|
mBitmapInfoHdr.biCompression = BI_RGB; // has implications for 16-bit
|
|
|
|
mBitmapInfoHdr.biSizeImage = 0;
|
|
|
|
mBitmapInfoHdr.biXPelsPerMeter = 0;
|
|
|
|
mBitmapInfoHdr.biYPelsPerMeter = 0;
|
|
|
|
mBitmapInfoHdr.biClrUsed = colorsUsed;
|
|
|
|
mBitmapInfoHdr.biClrImportant = 0;
|
|
|
|
|
|
|
|
mNumColorsUsed = colorsUsed;
|
|
|
|
if (colorsUsed) {
|
|
|
|
mpColorTable = new RGBQUAD[colorsUsed];
|
|
|
|
if (mpColorTable == nil)
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dibSection) {
|
|
|
|
/*
|
|
|
|
* Create an actual blank DIB section.
|
|
|
|
*/
|
|
|
|
mhBitmap = ::CreateDIBSection(nil, (BITMAPINFO*) &mBitmapInfoHdr,
|
|
|
|
DIB_RGB_COLORS, &mpPixels, nil, 0);
|
|
|
|
if (mhBitmap == nil) {
|
|
|
|
DWORD err = ::GetLastError();
|
|
|
|
//CString msg;
|
|
|
|
//GetWin32ErrorString(err, &msg);
|
Large set of changes to restore CiderPress build.
CiderPress and MDC now compile, and execute far enough to open
their respective "about" boxes, but I doubt they'll do much
more than that.
* Switch from MBCS to UNICODE APIs
Microsoft switched to UTF-16 (by way of UCS-2) a long time ago,
and the support for MBCS seems to be getting phased out. So it's
time to switch to wide strings.
This is a bit awkward for CiderPress because it works with disk
and file archives with 8-bit filenames, and I want NufxLib and
DiskImgLib to continue to work on Linux (which has largely taken
the UTF-8 approach to Unicode). The libraries will continue to
work with 8-bit filenames, with CiderPress/MDC doing the
conversion at the appropriate point.
There were a couple of places where strings from a structure
handed back by one of the libraries were used directly in the UI,
or vice-versa, which is a problem because we have nowhere to
store the result of the conversion. These currently have fixed
place-holder "xyzzy" strings.
All UI strings are now wide.
Various format strings now use "%ls" and "%hs" to explicitly
specify wide and narrow. This doesn't play well with gcc, so
only the Windows-specific parts use those.
* Various updates to vcxproj files
The project-file conversion had some cruft that is now largely
gone. The build now has a common output directory for the EXEs
and libraries, avoiding the old post-build copy steps.
* Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots
The old "prebuilts" directory is now gone. The libraries are now
built as part of building the apps.
I added a minimal set of files for zlib, and a full set for nufxlib.
The Linux-specific nufxlib goodies are included for the benefit of
the Linux utilities, which are currently broken (don't build).
* Replace symbols used for include guards
Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
|
|
|
//WMSG2(" DIB CreateDIBSection failed (err=%d msg='%ls')\n",
|
|
|
|
// err, (LPCWSTR) msg);
|
2014-11-04 00:26:53 +00:00
|
|
|
WMSG1(" DIB CreateDIBSection failed (err=%d)\n", err);
|
|
|
|
LogHexDump(&mBitmapInfoHdr, sizeof(BITMAPINFO));
|
|
|
|
WMSG1("&mpPixels = 0x%08lx\n", &mpPixels);
|
|
|
|
DebugBreak();
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Save some bitmap statistics.
|
|
|
|
*/
|
|
|
|
BITMAP info;
|
|
|
|
int gotten;
|
|
|
|
/* or GetObject(hBitmap, sizeof(DIBSECTION), &dibsection) */
|
|
|
|
gotten = ::GetObject(mhBitmap, sizeof(info), &info);
|
|
|
|
if (gotten != sizeof(info))
|
|
|
|
return nil;
|
|
|
|
mPitchBytes = info.bmWidthBytes;
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Create a buffer in memory.
|
|
|
|
*/
|
|
|
|
mPitchBytes = ((width * mBitmapInfoHdr.biBitCount) +7) / 8;
|
|
|
|
mPitchBytes = (mPitchBytes + 3) & ~(0x03); // 32-bit bounds
|
|
|
|
|
|
|
|
/* we're not allocating full file buffer; should be okay */
|
|
|
|
mpFileBuffer = new char[mPitchBytes * mBitmapInfoHdr.biHeight];
|
|
|
|
mpPixels = mpFileBuffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
mWidth = width;
|
|
|
|
mHeight = height;
|
|
|
|
mBpp = bitsPerPixel;
|
|
|
|
|
|
|
|
/* clear the bitmap, possibly not needed for DIB section */
|
|
|
|
assert(mpPixels != nil);
|
|
|
|
memset(mpPixels, 0, mPitchBytes * mBitmapInfoHdr.biHeight);
|
|
|
|
|
|
|
|
//WMSG2("+++ allocated %d bytes for bitmap pixels (mPitchBytes=%d)\n",
|
|
|
|
// mPitchBytes * mBitmapInfoHdr.biHeight, mPitchBytes);
|
|
|
|
|
|
|
|
return mpPixels;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Open the file and call the FILE* version.
|
|
|
|
*/
|
|
|
|
int
|
Large set of changes to restore CiderPress build.
CiderPress and MDC now compile, and execute far enough to open
their respective "about" boxes, but I doubt they'll do much
more than that.
* Switch from MBCS to UNICODE APIs
Microsoft switched to UTF-16 (by way of UCS-2) a long time ago,
and the support for MBCS seems to be getting phased out. So it's
time to switch to wide strings.
This is a bit awkward for CiderPress because it works with disk
and file archives with 8-bit filenames, and I want NufxLib and
DiskImgLib to continue to work on Linux (which has largely taken
the UTF-8 approach to Unicode). The libraries will continue to
work with 8-bit filenames, with CiderPress/MDC doing the
conversion at the appropriate point.
There were a couple of places where strings from a structure
handed back by one of the libraries were used directly in the UI,
or vice-versa, which is a problem because we have nowhere to
store the result of the conversion. These currently have fixed
place-holder "xyzzy" strings.
All UI strings are now wide.
Various format strings now use "%ls" and "%hs" to explicitly
specify wide and narrow. This doesn't play well with gcc, so
only the Windows-specific parts use those.
* Various updates to vcxproj files
The project-file conversion had some cruft that is now largely
gone. The build now has a common output directory for the EXEs
and libraries, avoiding the old post-build copy steps.
* Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots
The old "prebuilts" directory is now gone. The libraries are now
built as part of building the apps.
I added a minimal set of files for zlib, and a full set for nufxlib.
The Linux-specific nufxlib goodies are included for the benefit of
the Linux utilities, which are currently broken (don't build).
* Replace symbols used for include guards
Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
|
|
|
MyDIBitmap::CreateFromFile(const WCHAR* fileName)
|
2007-03-27 17:47:10 +00:00
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
FILE* fp = nil;
|
|
|
|
int err;
|
|
|
|
|
Large set of changes to restore CiderPress build.
CiderPress and MDC now compile, and execute far enough to open
their respective "about" boxes, but I doubt they'll do much
more than that.
* Switch from MBCS to UNICODE APIs
Microsoft switched to UTF-16 (by way of UCS-2) a long time ago,
and the support for MBCS seems to be getting phased out. So it's
time to switch to wide strings.
This is a bit awkward for CiderPress because it works with disk
and file archives with 8-bit filenames, and I want NufxLib and
DiskImgLib to continue to work on Linux (which has largely taken
the UTF-8 approach to Unicode). The libraries will continue to
work with 8-bit filenames, with CiderPress/MDC doing the
conversion at the appropriate point.
There were a couple of places where strings from a structure
handed back by one of the libraries were used directly in the UI,
or vice-versa, which is a problem because we have nowhere to
store the result of the conversion. These currently have fixed
place-holder "xyzzy" strings.
All UI strings are now wide.
Various format strings now use "%ls" and "%hs" to explicitly
specify wide and narrow. This doesn't play well with gcc, so
only the Windows-specific parts use those.
* Various updates to vcxproj files
The project-file conversion had some cruft that is now largely
gone. The build now has a common output directory for the EXEs
and libraries, avoiding the old post-build copy steps.
* Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots
The old "prebuilts" directory is now gone. The libraries are now
built as part of building the apps.
I added a minimal set of files for zlib, and a full set for nufxlib.
The Linux-specific nufxlib goodies are included for the benefit of
the Linux utilities, which are currently broken (don't build).
* Replace symbols used for include guards
Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
|
|
|
fp = _wfopen(fileName, L"rb");
|
2014-11-04 00:26:53 +00:00
|
|
|
if (fp == nil) {
|
|
|
|
err = errno ? errno : -1;
|
Large set of changes to restore CiderPress build.
CiderPress and MDC now compile, and execute far enough to open
their respective "about" boxes, but I doubt they'll do much
more than that.
* Switch from MBCS to UNICODE APIs
Microsoft switched to UTF-16 (by way of UCS-2) a long time ago,
and the support for MBCS seems to be getting phased out. So it's
time to switch to wide strings.
This is a bit awkward for CiderPress because it works with disk
and file archives with 8-bit filenames, and I want NufxLib and
DiskImgLib to continue to work on Linux (which has largely taken
the UTF-8 approach to Unicode). The libraries will continue to
work with 8-bit filenames, with CiderPress/MDC doing the
conversion at the appropriate point.
There were a couple of places where strings from a structure
handed back by one of the libraries were used directly in the UI,
or vice-versa, which is a problem because we have nowhere to
store the result of the conversion. These currently have fixed
place-holder "xyzzy" strings.
All UI strings are now wide.
Various format strings now use "%ls" and "%hs" to explicitly
specify wide and narrow. This doesn't play well with gcc, so
only the Windows-specific parts use those.
* Various updates to vcxproj files
The project-file conversion had some cruft that is now largely
gone. The build now has a common output directory for the EXEs
and libraries, avoiding the old post-build copy steps.
* Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots
The old "prebuilts" directory is now gone. The libraries are now
built as part of building the apps.
I added a minimal set of files for zlib, and a full set for nufxlib.
The Linux-specific nufxlib goodies are included for the benefit of
the Linux utilities, which are currently broken (don't build).
* Replace symbols used for include guards
Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
|
|
|
WMSG2("Unable to read bitmap from file '%ls' (err=%d)\n",
|
|
|
|
fileName, err);
|
2014-11-04 00:26:53 +00:00
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
long fileLen;
|
|
|
|
fseek(fp, 0, SEEK_END);
|
|
|
|
fileLen = ftell(fp);
|
|
|
|
rewind(fp);
|
|
|
|
|
|
|
|
err = CreateFromFile(fp, fileLen);
|
|
|
|
fclose(fp);
|
|
|
|
return err;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create a DIB by reading a BMP or TGA file into memory.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
MyDIBitmap::CreateFromFile(FILE* fp, long len)
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
void* buf = nil;
|
|
|
|
int err = -1;
|
2007-03-27 17:47:10 +00:00
|
|
|
|
2014-11-04 00:26:53 +00:00
|
|
|
buf = new unsigned char[len];
|
|
|
|
if (buf == nil)
|
|
|
|
return err;
|
2007-03-27 17:47:10 +00:00
|
|
|
|
2014-11-04 00:26:53 +00:00
|
|
|
if (fread(buf, len, 1, fp) != 1) {
|
|
|
|
err = errno ? errno : -1;
|
|
|
|
WMSG2(" DIB failed reading %ld bytes (err=%d)\n", len, err);
|
|
|
|
goto bail;
|
|
|
|
}
|
2007-03-27 17:47:10 +00:00
|
|
|
|
2014-11-04 00:26:53 +00:00
|
|
|
err = CreateFromNewBuffer(buf, len);
|
2007-03-27 17:47:10 +00:00
|
|
|
|
|
|
|
bail:
|
2014-11-04 00:26:53 +00:00
|
|
|
return err;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create object from a copy of the file in memory.
|
|
|
|
*
|
|
|
|
* We want to hang on to the data buffer, but if we don't own it then we
|
|
|
|
* have to make a copy.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
MyDIBitmap::CreateFromBuffer(void* buf, long len, bool doDelete)
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
assert(len > 0);
|
|
|
|
|
|
|
|
if (doDelete) {
|
|
|
|
return CreateFromNewBuffer(buf, len);
|
|
|
|
} else {
|
|
|
|
void* newBuf = new unsigned char[len];
|
|
|
|
if (newBuf == nil)
|
|
|
|
return -1;
|
|
|
|
memcpy(newBuf, buf, len);
|
|
|
|
|
|
|
|
return CreateFromNewBuffer(newBuf, len);
|
|
|
|
}
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create object from a buffer of new[]-created memory that we own.
|
|
|
|
*
|
|
|
|
* The memory will be discarded if this function fails.
|
|
|
|
*
|
|
|
|
* We don't want to create a DIB section if the eventual user of this data
|
|
|
|
* doesn't need it (e.g. it's just getting converted into a 3D texture
|
|
|
|
* without using any GDI calls), so we just leave the pixels in the file
|
|
|
|
* buffer for now.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
MyDIBitmap::CreateFromNewBuffer(void* vbuf, long len)
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
BITMAPFILEHEADER* pHeader = (BITMAPFILEHEADER*) vbuf;
|
|
|
|
unsigned char* buf = (unsigned char*) vbuf;
|
|
|
|
|
|
|
|
assert(pHeader != nil);
|
|
|
|
assert(len > 0);
|
|
|
|
|
|
|
|
if (len > 16 && pHeader->bfType == kBMPMagic && (long) pHeader->bfSize == len)
|
|
|
|
{
|
|
|
|
return ImportBMP(vbuf, len);
|
|
|
|
} else if (len > 16 && buf[0x01] == 0 &&
|
|
|
|
buf[0x02] == 2 && buf[0x05] == 0 && buf[0x06] == 0 &&
|
|
|
|
(buf[0x10] == 16 || buf[0x10] == 24 || buf[0x10] == 32))
|
|
|
|
{
|
|
|
|
return ImportTGA(vbuf, len);
|
|
|
|
} else {
|
|
|
|
WMSG2(" DIB invalid bitmap file (type=0x%04x size=%ld)\n",
|
|
|
|
pHeader->bfType, pHeader->bfSize);
|
|
|
|
delete[] vbuf;
|
|
|
|
return -1;
|
|
|
|
}
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set up internal structures for the BMP file.
|
|
|
|
*
|
|
|
|
* On error, "vbuf" is discarded.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
MyDIBitmap::ImportBMP(void* vbuf, long len)
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
BITMAPFILEHEADER* pHeader = (BITMAPFILEHEADER*) vbuf;
|
|
|
|
BITMAPINFO* pInfo;
|
|
|
|
unsigned char* pBits;
|
|
|
|
int err = -1;
|
|
|
|
|
|
|
|
pInfo = (BITMAPINFO*) (pHeader+1);
|
|
|
|
pBits = (unsigned char*) pHeader + pHeader->bfOffBits;
|
|
|
|
|
|
|
|
// no need to memset mBitmapInfoHdr; that's done during object construction
|
|
|
|
|
|
|
|
if (pInfo->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) {
|
|
|
|
/* deal with older bitmaps */
|
|
|
|
BITMAPCOREHEADER* pCore = (BITMAPCOREHEADER*) pInfo;
|
|
|
|
assert(mBitmapInfoHdr.biSize == 0); // we memset in constructor
|
|
|
|
mBitmapInfoHdr.biSize = sizeof(mBitmapInfoHdr); // BITMAPINFOHEADER
|
|
|
|
mBitmapInfoHdr.biWidth = pCore->bcWidth;
|
|
|
|
mBitmapInfoHdr.biHeight = pCore->bcSize;
|
|
|
|
mBitmapInfoHdr.biPlanes = pCore->bcPlanes;
|
|
|
|
mBitmapInfoHdr.biBitCount = pCore->bcBitCount;
|
|
|
|
mBitmapInfoHdr.biCompression = BI_RGB;
|
|
|
|
} else {
|
|
|
|
/* has at least a BITMAPINFOHEADER in it, use existing fields */
|
|
|
|
assert(mBitmapInfoHdr.biSize == 0); // we memset in constructor
|
|
|
|
assert(pInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER));
|
|
|
|
mBitmapInfoHdr.biSize = sizeof(mBitmapInfoHdr); // BITMAPINFOHEADER
|
|
|
|
mBitmapInfoHdr.biWidth = pInfo->bmiHeader.biWidth;
|
|
|
|
mBitmapInfoHdr.biHeight = pInfo->bmiHeader.biHeight;
|
|
|
|
mBitmapInfoHdr.biPlanes = pInfo->bmiHeader.biPlanes;
|
|
|
|
mBitmapInfoHdr.biBitCount = pInfo->bmiHeader.biBitCount;
|
|
|
|
mBitmapInfoHdr.biCompression = pInfo->bmiHeader.biCompression;
|
|
|
|
}
|
|
|
|
|
|
|
|
mWidth = mBitmapInfoHdr.biWidth;
|
|
|
|
mHeight = mBitmapInfoHdr.biHeight;
|
|
|
|
mBpp = mBitmapInfoHdr.biBitCount;
|
|
|
|
mNumColorsUsed = mBitmapInfoHdr.biClrUsed;
|
|
|
|
mPitchBytes = ((mWidth * mBitmapInfoHdr.biBitCount) +7) / 8;
|
|
|
|
mPitchBytes = (mPitchBytes + 3) & ~(0x03); // round up to mult of 4
|
|
|
|
//WMSG3(" DIB +++ width=%d bits=%d pitch=%d\n", mWidth,
|
|
|
|
// mBitmapInfoHdr.biBitCount, mPitchBytes);
|
|
|
|
|
|
|
|
/* prepare the color table, if any */
|
|
|
|
if (mBpp <= 8) {
|
|
|
|
if (mNumColorsUsed == 0) {
|
|
|
|
mNumColorsUsed = 1 << mBpp;
|
|
|
|
mBitmapInfoHdr.biClrUsed = mNumColorsUsed;
|
|
|
|
}
|
|
|
|
mpColorTable = new RGBQUAD[mNumColorsUsed];
|
|
|
|
if (mpColorTable == nil)
|
|
|
|
goto bail;
|
|
|
|
SetColorTable(pInfo->bmiColors);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* use the buffered bits */
|
|
|
|
mpPixels = pBits;
|
|
|
|
mpFileBuffer = vbuf;
|
|
|
|
err = 0;
|
2007-03-27 17:47:10 +00:00
|
|
|
|
|
|
|
bail:
|
2014-11-04 00:26:53 +00:00
|
|
|
if (err != 0)
|
|
|
|
delete[] vbuf;
|
|
|
|
return err;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set up internal structures for the TGA file.
|
|
|
|
*
|
|
|
|
* We handle 16-, 24-, and 32-bit .TGA files only. They happen to use the
|
|
|
|
* same byte layout as BMP files, so we do very little work here. If we
|
|
|
|
* tried to write the raw data to a BMP file we could end up in trouble,
|
|
|
|
* because we don't force the "pitch must be multiple of 4 bytes" rule.
|
|
|
|
*
|
|
|
|
* On error, "vbuf" is discarded.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
MyDIBitmap::ImportTGA(void* vbuf, long len)
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
TargaHeader targaHdr;
|
|
|
|
unsigned char* hdr = (unsigned char*) vbuf;
|
|
|
|
unsigned char* pBits;
|
|
|
|
int err = -1;
|
|
|
|
|
|
|
|
/* pull the header out of the file */
|
|
|
|
targaHdr.idLength = hdr[0x00];
|
|
|
|
targaHdr.colorMapType = hdr[0x01];
|
|
|
|
targaHdr.imageType = hdr[0x02];
|
|
|
|
targaHdr.colorMapOrigin = hdr[0x03] | hdr[0x04] << 8;
|
|
|
|
targaHdr.colorMapLen = hdr[0x05] | hdr[0x06] << 8;
|
|
|
|
targaHdr.colorMapEntryLen = hdr[0x07];
|
|
|
|
targaHdr.xOffset = hdr[0x08] | hdr[0x09] << 8;
|
|
|
|
targaHdr.yOffset = hdr[0x0a] | hdr[0x0b] << 8;
|
|
|
|
targaHdr.width = hdr[0x0c] | hdr[0x0d] << 8;
|
|
|
|
targaHdr.height = hdr[0x0e] | hdr[0x0f] << 8;
|
|
|
|
targaHdr.bitsPerPixel = hdr[0x10];
|
|
|
|
targaHdr.imageDescriptor = hdr[0x11];
|
|
|
|
|
|
|
|
pBits = hdr + kTargaHeaderLen + targaHdr.idLength;
|
|
|
|
|
|
|
|
// no need to memset mBitmapInfoHdr; that's done during object construction
|
|
|
|
|
|
|
|
assert(mBitmapInfoHdr.biSize == 0); // we memset in constructor
|
|
|
|
mBitmapInfoHdr.biSize = sizeof(mBitmapInfoHdr); // BITMAPINFOHEADER
|
|
|
|
mBitmapInfoHdr.biWidth = targaHdr.width;
|
|
|
|
mBitmapInfoHdr.biHeight = targaHdr.height;
|
|
|
|
mBitmapInfoHdr.biPlanes = 1;
|
|
|
|
mBitmapInfoHdr.biBitCount = targaHdr.bitsPerPixel;
|
|
|
|
mBitmapInfoHdr.biCompression = BI_RGB;
|
|
|
|
|
|
|
|
mWidth = mBitmapInfoHdr.biWidth;
|
|
|
|
mHeight = mBitmapInfoHdr.biHeight;
|
|
|
|
mBpp = mBitmapInfoHdr.biBitCount;
|
|
|
|
mNumColorsUsed = mBitmapInfoHdr.biClrUsed;
|
|
|
|
mPitchBytes = ((mWidth * mBitmapInfoHdr.biBitCount) +7) / 8;
|
|
|
|
if ((mPitchBytes & 0x03) != 0) {
|
|
|
|
/* should only be a problem if we try to save to BMP or conv to DIB */
|
|
|
|
WMSG1(" DIB WARNING: pitchBytes=%d in TGA may not work\n",
|
|
|
|
mPitchBytes);
|
|
|
|
}
|
|
|
|
// mPitchBytes = (mPitchBytes + 3) & ~(0x03); // round up to power of 2
|
2007-03-27 17:47:10 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
| | | This field specifies (width) x (height) pixels. Each |
|
|
|
|
| | | pixel specifies an RGB color value, which is stored as |
|
|
|
|
| | | an integral number of bytes. |
|
|
|
|
| | | |
|
|
|
|
| | | The 2 byte entry is broken down as follows: |
|
|
|
|
| | | ARRRRRGG GGGBBBBB, where each letter represents a bit. |
|
|
|
|
| | | But, because of the lo-hi storage order, the first byte |
|
|
|
|
| | | coming from the file will actually be GGGBBBBB, and the |
|
|
|
|
| | | second will be ARRRRRGG. "A" represents an attribute bit. |
|
|
|
|
| | | |
|
|
|
|
| | | The 3 byte entry contains 1 byte each of blue, green, |
|
|
|
|
| | | and red. |
|
|
|
|
| | | |
|
|
|
|
| | | The 4 byte entry contains 1 byte each of blue, green, |
|
|
|
|
| | | red, and attribute. For faster speed (because of the |
|
|
|
|
| | | hardware of the Targa board itself), Targa 24 images are |
|
|
|
|
| | | sometimes stored as Targa 32 images. |
|
|
|
|
| | | |
|
|
|
|
*/
|
|
|
|
|
2014-11-04 00:26:53 +00:00
|
|
|
/* use the buffered bits */
|
|
|
|
mpPixels = pBits;
|
|
|
|
mpFileBuffer = vbuf;
|
|
|
|
err = 0;
|
|
|
|
//WMSG1("+++ successfully imported %d-bit TGA\n", mBpp);
|
2007-03-27 17:47:10 +00:00
|
|
|
|
2014-11-04 00:26:53 +00:00
|
|
|
if (mBpp == 32) {
|
|
|
|
/* 32-bit TGA is a full-alpha format */
|
|
|
|
mAlphaType = kAlphaFull;
|
|
|
|
}
|
2007-03-27 17:47:10 +00:00
|
|
|
|
|
|
|
//bail:
|
2014-11-04 00:26:53 +00:00
|
|
|
if (err != 0)
|
|
|
|
delete[] vbuf;
|
|
|
|
return err;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the bitmap wasn't initially created as a DIB section, transform it now
|
|
|
|
* so the application can use it in GDI calls.
|
|
|
|
*
|
|
|
|
* Returns 0 on success, -1 on error.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
MyDIBitmap::ConvertBufToDIBSection(void)
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
void* oldPixels = mpPixels;
|
|
|
|
|
|
|
|
assert(mhBitmap == nil);
|
|
|
|
assert(mpFileBuffer != nil);
|
|
|
|
|
|
|
|
WMSG0(" DIB converting buf to DIB Section\n");
|
|
|
|
|
|
|
|
/* alloc storage */
|
|
|
|
mpPixels = nil;
|
|
|
|
mhBitmap = ::CreateDIBSection(nil, (BITMAPINFO*) &mBitmapInfoHdr,
|
|
|
|
DIB_RGB_COLORS, &mpPixels, nil, 0);
|
|
|
|
if (mhBitmap == nil) {
|
|
|
|
DWORD err = ::GetLastError();
|
|
|
|
WMSG1(" DIB CreateDIBSection failed (err=%d)\n", err);
|
|
|
|
LogHexDump(&mBitmapInfoHdr, sizeof(BITMAPINFO));
|
|
|
|
WMSG1("&mpPixels = 0x%08lx\n", &mpPixels);
|
|
|
|
DebugBreak();
|
|
|
|
mpPixels = oldPixels;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
assert(mpPixels != nil);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This shouldn't be necessary; I don't think a DIB section uses a
|
|
|
|
* different bmWidthBytes than a file on disk. If it does, we'll have
|
|
|
|
* to scan-convert it.
|
|
|
|
*/
|
|
|
|
BITMAP info;
|
|
|
|
int gotten;
|
|
|
|
// or GetObject(hBitmap, sizeof(DIBSECTION), &dibsection)
|
|
|
|
gotten = ::GetObject(mhBitmap, sizeof(info), &info);
|
|
|
|
if (gotten != sizeof(info))
|
|
|
|
return nil;
|
|
|
|
assert(mPitchBytes == info.bmWidthBytes);
|
|
|
|
//mPitchBytes = info.bmWidthBytes;
|
|
|
|
|
|
|
|
/* copy the bits in */
|
|
|
|
memcpy(mpPixels, oldPixels, mPitchBytes * mHeight);
|
|
|
|
|
|
|
|
/* throw out the old storage */
|
|
|
|
delete[] mpFileBuffer;
|
|
|
|
mpFileBuffer = nil;
|
|
|
|
|
|
|
|
return 0;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create the object from a resource embedded in the application.
|
|
|
|
*
|
|
|
|
* Use MAKEINTRESOURCE to load a resource by ordinal.
|
|
|
|
*/
|
|
|
|
void*
|
Large set of changes to restore CiderPress build.
CiderPress and MDC now compile, and execute far enough to open
their respective "about" boxes, but I doubt they'll do much
more than that.
* Switch from MBCS to UNICODE APIs
Microsoft switched to UTF-16 (by way of UCS-2) a long time ago,
and the support for MBCS seems to be getting phased out. So it's
time to switch to wide strings.
This is a bit awkward for CiderPress because it works with disk
and file archives with 8-bit filenames, and I want NufxLib and
DiskImgLib to continue to work on Linux (which has largely taken
the UTF-8 approach to Unicode). The libraries will continue to
work with 8-bit filenames, with CiderPress/MDC doing the
conversion at the appropriate point.
There were a couple of places where strings from a structure
handed back by one of the libraries were used directly in the UI,
or vice-versa, which is a problem because we have nowhere to
store the result of the conversion. These currently have fixed
place-holder "xyzzy" strings.
All UI strings are now wide.
Various format strings now use "%ls" and "%hs" to explicitly
specify wide and narrow. This doesn't play well with gcc, so
only the Windows-specific parts use those.
* Various updates to vcxproj files
The project-file conversion had some cruft that is now largely
gone. The build now has a common output directory for the EXEs
and libraries, avoiding the old post-build copy steps.
* Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots
The old "prebuilts" directory is now gone. The libraries are now
built as part of building the apps.
I added a minimal set of files for zlib, and a full set for nufxlib.
The Linux-specific nufxlib goodies are included for the benefit of
the Linux utilities, which are currently broken (don't build).
* Replace symbols used for include guards
Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
|
|
|
MyDIBitmap::CreateFromResource(HINSTANCE hInstance, const WCHAR* rsrc)
|
2007-03-27 17:47:10 +00:00
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
mhBitmap = (HBITMAP) ::LoadImage(hInstance, rsrc, IMAGE_BITMAP, 0, 0,
|
|
|
|
LR_DEFAULTCOLOR | LR_CREATEDIBSECTION);
|
|
|
|
if (mhBitmap == nil) {
|
|
|
|
DWORD err = ::GetLastError();
|
|
|
|
//CString msg;
|
|
|
|
//GetWin32ErrorString(err, &msg);
|
Large set of changes to restore CiderPress build.
CiderPress and MDC now compile, and execute far enough to open
their respective "about" boxes, but I doubt they'll do much
more than that.
* Switch from MBCS to UNICODE APIs
Microsoft switched to UTF-16 (by way of UCS-2) a long time ago,
and the support for MBCS seems to be getting phased out. So it's
time to switch to wide strings.
This is a bit awkward for CiderPress because it works with disk
and file archives with 8-bit filenames, and I want NufxLib and
DiskImgLib to continue to work on Linux (which has largely taken
the UTF-8 approach to Unicode). The libraries will continue to
work with 8-bit filenames, with CiderPress/MDC doing the
conversion at the appropriate point.
There were a couple of places where strings from a structure
handed back by one of the libraries were used directly in the UI,
or vice-versa, which is a problem because we have nowhere to
store the result of the conversion. These currently have fixed
place-holder "xyzzy" strings.
All UI strings are now wide.
Various format strings now use "%ls" and "%hs" to explicitly
specify wide and narrow. This doesn't play well with gcc, so
only the Windows-specific parts use those.
* Various updates to vcxproj files
The project-file conversion had some cruft that is now largely
gone. The build now has a common output directory for the EXEs
and libraries, avoiding the old post-build copy steps.
* Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots
The old "prebuilts" directory is now gone. The libraries are now
built as part of building the apps.
I added a minimal set of files for zlib, and a full set for nufxlib.
The Linux-specific nufxlib goodies are included for the benefit of
the Linux utilities, which are currently broken (don't build).
* Replace symbols used for include guards
Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
|
|
|
//WMSG2(" DIB CreateDIBSection failed (err=%d msg='%ls')\n",
|
|
|
|
// err, (LPCWSTR) msg);
|
2014-11-04 00:26:53 +00:00
|
|
|
WMSG1(" DIB LoadImage failed (err=%d)\n", err);
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Pull out bitmap details.
|
|
|
|
*/
|
|
|
|
DIBSECTION info;
|
|
|
|
int gotten;
|
|
|
|
gotten = ::GetObject(mhBitmap, sizeof(info), &info);
|
|
|
|
if (gotten != sizeof(info))
|
|
|
|
return nil;
|
|
|
|
mPitchBytes = info.dsBm.bmWidthBytes;
|
|
|
|
mWidth = info.dsBm.bmWidth;
|
|
|
|
mHeight = info.dsBm.bmHeight;
|
|
|
|
mBpp = info.dsBm.bmBitsPixel;
|
|
|
|
mpPixels = info.dsBm.bmBits;
|
|
|
|
mNumColorsUsed = info.dsBmih.biClrUsed;
|
|
|
|
|
|
|
|
if (mBpp <= 8) {
|
|
|
|
if (mNumColorsUsed == 0)
|
|
|
|
mNumColorsUsed = 1 << mBpp;
|
|
|
|
mpColorTable = new RGBQUAD[mNumColorsUsed];
|
|
|
|
if (mpColorTable == nil)
|
|
|
|
goto bail; // should reset mpPixels?
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Extracting the color table from a DIB is annoying. I don't
|
|
|
|
* entirely understand the need for all these HDC gymnastics, but
|
|
|
|
* it doesn't work without both handles.
|
|
|
|
*/
|
|
|
|
HDC tmpDC;
|
|
|
|
HDC memDC;
|
|
|
|
HGDIOBJ oldBits;
|
|
|
|
int count;
|
|
|
|
|
|
|
|
tmpDC = GetDC(nil);
|
|
|
|
assert(tmpDC != nil);
|
|
|
|
memDC = CreateCompatibleDC(tmpDC);
|
|
|
|
oldBits = SelectObject(memDC, mhBitmap);
|
|
|
|
count = GetDIBColorTable(memDC, 0, mNumColorsUsed, mpColorTable);
|
|
|
|
if (count == 0) {
|
|
|
|
DWORD err = ::GetLastError();
|
|
|
|
CString buf;
|
|
|
|
GetWin32ErrorString(err, &buf);
|
Large set of changes to restore CiderPress build.
CiderPress and MDC now compile, and execute far enough to open
their respective "about" boxes, but I doubt they'll do much
more than that.
* Switch from MBCS to UNICODE APIs
Microsoft switched to UTF-16 (by way of UCS-2) a long time ago,
and the support for MBCS seems to be getting phased out. So it's
time to switch to wide strings.
This is a bit awkward for CiderPress because it works with disk
and file archives with 8-bit filenames, and I want NufxLib and
DiskImgLib to continue to work on Linux (which has largely taken
the UTF-8 approach to Unicode). The libraries will continue to
work with 8-bit filenames, with CiderPress/MDC doing the
conversion at the appropriate point.
There were a couple of places where strings from a structure
handed back by one of the libraries were used directly in the UI,
or vice-versa, which is a problem because we have nowhere to
store the result of the conversion. These currently have fixed
place-holder "xyzzy" strings.
All UI strings are now wide.
Various format strings now use "%ls" and "%hs" to explicitly
specify wide and narrow. This doesn't play well with gcc, so
only the Windows-specific parts use those.
* Various updates to vcxproj files
The project-file conversion had some cruft that is now largely
gone. The build now has a common output directory for the EXEs
and libraries, avoiding the old post-build copy steps.
* Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots
The old "prebuilts" directory is now gone. The libraries are now
built as part of building the apps.
I added a minimal set of files for zlib, and a full set for nufxlib.
The Linux-specific nufxlib goodies are included for the benefit of
the Linux utilities, which are currently broken (don't build).
* Replace symbols used for include guards
Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
|
|
|
WMSG2(" DIB GetDIBColorTable failed (err=0x%x '%ls')\n",
|
|
|
|
err, (LPCWSTR) buf);
|
2014-11-04 00:26:53 +00:00
|
|
|
}
|
|
|
|
SelectObject(memDC, oldBits);
|
|
|
|
DeleteDC(memDC);
|
|
|
|
ReleaseDC(nil, tmpDC);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Unfortunately it appears that LoadImage sets up the mPitchBytes
|
|
|
|
* improperly for a DIB. I believe DIBs need 4-byte-aligned widths
|
|
|
|
* while compatible bitmaps only need 2-byte-aligned. We need to
|
|
|
|
* tweak mPitchBytes or we'll get garbage.
|
|
|
|
*/
|
|
|
|
if (mPitchBytes & 0x03) {
|
|
|
|
WMSG1(" DIB altering LoadImage pitchBytes (currently %d)\n", mPitchBytes);
|
|
|
|
mPitchBytes = (mPitchBytes + 3) & ~(0x03);
|
|
|
|
}
|
2007-03-27 17:47:10 +00:00
|
|
|
|
|
|
|
bail:
|
2014-11-04 00:26:53 +00:00
|
|
|
assert(mpPixels != nil);
|
|
|
|
return mpPixels;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
2014-11-04 00:26:53 +00:00
|
|
|
#if 0 // this might be a better way??
|
2007-03-27 17:47:10 +00:00
|
|
|
HRSRC hResInfo;
|
|
|
|
HGLOBAL hResData;
|
|
|
|
DWORD dwSize;
|
|
|
|
VOID* pvRes;
|
|
|
|
// Loading it as a file failed, so try it as a resource
|
|
|
|
if( NULL == ( hResInfo = FindResource( NULL, strFileName, TEXT("WAVE") ) ) )
|
|
|
|
{
|
|
|
|
if( NULL == ( hResInfo = FindResource( NULL, strFileName, TEXT("WAV") ) ) )
|
|
|
|
return DXTRACE_ERR( TEXT("FindResource"), E_FAIL );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( NULL == ( hResData = LoadResource( NULL, hResInfo ) ) )
|
|
|
|
return DXTRACE_ERR( TEXT("LoadResource"), E_FAIL );
|
|
|
|
|
|
|
|
if( 0 == ( dwSize = SizeofResource( NULL, hResInfo ) ) )
|
|
|
|
return DXTRACE_ERR( TEXT("SizeofResource"), E_FAIL );
|
|
|
|
|
|
|
|
if( NULL == ( pvRes = LockResource( hResData ) ) )
|
|
|
|
return DXTRACE_ERR( TEXT("LockResource"), E_FAIL );
|
|
|
|
|
|
|
|
m_pResourceBuffer = new CHAR[ dwSize ];
|
|
|
|
memcpy( m_pResourceBuffer, pvRes, dwSize );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Zero out a bitmap's pixels. Does not touch the color table.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
MyDIBitmap::ClearPixels(void)
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
assert(mpPixels != nil);
|
2007-03-27 17:47:10 +00:00
|
|
|
|
2014-11-04 00:26:53 +00:00
|
|
|
//WMSG1(" DIB clearing entire bitmap (%d bytes)\n", mPitchBytes * mHeight);
|
|
|
|
memset(mpPixels, 0, mPitchBytes * mHeight);
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set the values in the color table.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
MyDIBitmap::SetColorTable(const RGBQUAD* pColorTable)
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
assert(pColorTable != nil);
|
|
|
|
|
|
|
|
/* scan for junk */
|
|
|
|
for (int i = 0; i < mNumColorsUsed; i++) {
|
|
|
|
if (pColorTable[i].rgbReserved != 0) {
|
|
|
|
/*
|
|
|
|
* PhotoShop v5.x sets rgbReserved to 1 on every 8th color table
|
|
|
|
* entry on 8-bit images. No idea why.
|
|
|
|
*/
|
|
|
|
//WMSG2(" DIB warning: bogus color entry %d (res=%d)\n", i,
|
|
|
|
// pColorTable[i].rgbReserved);
|
|
|
|
//DebugBreak();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* structs are the same, so just copy it over */
|
|
|
|
memcpy(mpColorTable, pColorTable, mNumColorsUsed * sizeof(RGBQUAD));
|
|
|
|
mColorTableInitialized = true;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Retrieve the transparency color key, if any.
|
|
|
|
*
|
|
|
|
* Returns "false" if no color key has been set.
|
|
|
|
*/
|
|
|
|
bool
|
|
|
|
MyDIBitmap::GetTransparentColor(RGBQUAD* pColor) const
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
if (mAlphaType != kAlphaTransparency)
|
|
|
|
return false;
|
|
|
|
*(DWORD*)pColor = mTransparentColor;
|
|
|
|
return true;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set the transparent color. Changes the alpha mode to kAlphaTransparency.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
MyDIBitmap::SetTransparentColor(const RGBQUAD* pColor)
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
if (mAlphaType == kAlphaFull) {
|
|
|
|
WMSG0(" NOTE: switching from full alpha to transparent-color alpha\n");
|
|
|
|
}
|
|
|
|
mTransparentColor = *(const DWORD*)pColor;
|
|
|
|
mTransparentColor &= ~kAlphaMask; // strip alpha off, want color only
|
|
|
|
mAlphaType = kAlphaTransparency;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Look up an RGB color in an indexed color table.
|
|
|
|
*
|
|
|
|
* Returns the index of the color, or -1 if not found (-2 on error, e.g. this
|
|
|
|
* isn't an indexed-color bitmap or the color table hasn't been created).
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
MyDIBitmap::LookupColor(const RGBQUAD* pRgbQuad)
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
if (mBpp > 8) {
|
|
|
|
WMSG1(" DIB LookupColor on %d-bit image\n", mBpp);
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
if (!mColorTableInitialized) {
|
|
|
|
WMSG0(" DIB can't LookupColor, color table not initialized\n");
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set the rgbReserved field to zero */
|
|
|
|
unsigned long color = *(unsigned long*) pRgbQuad;
|
|
|
|
color &= ~(kAlphaMask);
|
|
|
|
|
|
|
|
int idx;
|
|
|
|
for (idx = 0; idx < mNumColorsUsed; idx++) {
|
|
|
|
if (color == *(unsigned long*)&mpColorTable[idx])
|
|
|
|
return idx;
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Return the RGB value of a single pixel in a bitmap.
|
|
|
|
*
|
|
|
|
* "rgbReserved" is always set to zero.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
MyDIBitmap::GetPixelRGB(int x, int y, RGBQUAD* pRgbQuad) const
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
GetPixelRGBA(x, y, pRgbQuad);
|
|
|
|
pRgbQuad->rgbReserved = 0;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Return the RGBA value of a single pixel in a bitmap.
|
|
|
|
*
|
|
|
|
* This sets rgbReserved appropriately for the current alpha mode.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
MyDIBitmap::GetPixelRGBA(int x, int y, RGBQUAD* pRgbQuad) const
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
assert(x >= 0 && x < mWidth && y >= 0 && y < mHeight);
|
|
|
|
y = mHeight - y -1; // upside-down
|
|
|
|
|
|
|
|
if (mBpp == 32) {
|
|
|
|
assert((mPitchBytes % 4) == 0);
|
|
|
|
assert(sizeof(RGBQUAD) == 4);
|
|
|
|
|
|
|
|
RGBQUAD* lptr = (RGBQUAD*) mpPixels;
|
|
|
|
lptr += y * (mPitchBytes >> 2) + x;
|
|
|
|
*pRgbQuad = *lptr;
|
|
|
|
} else if (mBpp == 24) {
|
|
|
|
unsigned char* ptr = (unsigned char*) mpPixels;
|
|
|
|
|
|
|
|
ptr += y * mPitchBytes + (x << 1) + x;
|
|
|
|
pRgbQuad->rgbBlue = *ptr++;
|
|
|
|
pRgbQuad->rgbGreen = *ptr++;
|
|
|
|
pRgbQuad->rgbRed = *ptr++;
|
|
|
|
//pRgbQuad->rgbReserved = 0;
|
|
|
|
} else if (mBpp == 16) {
|
|
|
|
/* format is XRRRRRGGGGGBBBBB; must convert 0-31 to 0-255 */
|
|
|
|
static const unsigned int conv[32] = {
|
|
|
|
0, 8, 16, 25, 33, 41, 49, 58,
|
|
|
|
66, 74, 82, 90, 99, 107, 115, 123,
|
|
|
|
132, 140, 148, 156, 165, 173, 181, 189,
|
|
|
|
197, 206, 214, 222, 230, 239, 247, 255
|
|
|
|
};
|
|
|
|
unsigned short* ptr = (unsigned short*) mpPixels;
|
|
|
|
unsigned short val;
|
|
|
|
|
|
|
|
ptr += y * (mPitchBytes >> 1) + x;
|
|
|
|
val = *ptr;
|
|
|
|
pRgbQuad->rgbBlue = conv[val & 0x1f];
|
|
|
|
pRgbQuad->rgbGreen = conv[(val >> 5) & 0x1f];
|
|
|
|
pRgbQuad->rgbRed = conv[(val >> 10) & 0x1f];
|
|
|
|
//pRgbQuad->rgbReserved = 0;
|
|
|
|
} else if (mBpp == 8) {
|
|
|
|
unsigned char* ptr = (unsigned char*) mpPixels;
|
|
|
|
int idx;
|
|
|
|
|
|
|
|
ptr += y * mPitchBytes + x;
|
|
|
|
idx = *ptr;
|
|
|
|
*pRgbQuad = mpColorTable[idx];
|
|
|
|
} else if (mBpp == 4) {
|
|
|
|
assert(mpColorTable != nil);
|
|
|
|
unsigned char* ptr = (unsigned char*) mpPixels;
|
|
|
|
int idx;
|
|
|
|
|
|
|
|
ptr += y * mPitchBytes + (x >> 1);
|
|
|
|
if (x & 0x01)
|
|
|
|
idx = (*ptr & 0x0f);
|
|
|
|
else
|
|
|
|
idx = (*ptr & 0xf0) >> 4;
|
|
|
|
*pRgbQuad = mpColorTable[idx];
|
|
|
|
} else if (mBpp == 1) {
|
|
|
|
assert(sizeof(RGBQUAD) == sizeof(DWORD));
|
|
|
|
|
|
|
|
unsigned char* ptr = (unsigned char*) mpPixels;
|
|
|
|
ptr += y * mPitchBytes + (x >> 3);
|
|
|
|
if (*ptr & (0x80 >> (x & 0x07)))
|
|
|
|
*(DWORD*)pRgbQuad = 0xffffff00;
|
|
|
|
else
|
|
|
|
*(DWORD*)pRgbQuad = 0x00000000;
|
|
|
|
} else {
|
|
|
|
assert(false); // bit depth not implemented
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Fix up the "rgbReserved" field. Windows says it must always be zero,
|
|
|
|
* so unless the application changes the alpha type, we leave it that way.
|
|
|
|
*/
|
|
|
|
if (mAlphaType == kAlphaOpaque) {
|
|
|
|
pRgbQuad->rgbReserved = 255; // always force to 255, even on 32bpp
|
|
|
|
} else if (mAlphaType == kAlphaTransparency) {
|
|
|
|
/* test for the transparent color, ignoring alpha */
|
|
|
|
if (((*(DWORD*)pRgbQuad) & ~kAlphaMask) == mTransparentColor)
|
|
|
|
pRgbQuad->rgbReserved = 0; // fully transparent
|
|
|
|
else
|
|
|
|
pRgbQuad->rgbReserved = 255; // fully opaque
|
|
|
|
} else {
|
|
|
|
assert(mAlphaType == kAlphaFull);
|
|
|
|
assert(mBpp == 32);
|
|
|
|
/* full alpha in 32-bit data, leave it be */
|
|
|
|
}
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set the RGB value of a single pixel in a bitmap.
|
|
|
|
*
|
|
|
|
* The "rgbReserved" channel is forced to zero.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
MyDIBitmap::SetPixelRGB(int x, int y, const RGBQUAD* pRgbQuad)
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
if (pRgbQuad->rgbReserved == 0) {
|
|
|
|
SetPixelRGBA(x, y, pRgbQuad);
|
|
|
|
} else {
|
|
|
|
RGBQUAD tmp = *pRgbQuad;
|
|
|
|
tmp.rgbReserved = 0;
|
|
|
|
SetPixelRGBA(x, y, &tmp);
|
|
|
|
}
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set the RGBA value of a single pixel in a bitmap.
|
|
|
|
*
|
|
|
|
* For index-color bitmaps, this requires a (slow) table lookup.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
MyDIBitmap::SetPixelRGBA(int x, int y, const RGBQUAD* pRgbQuad)
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
assert(x >= 0 && x < mWidth && y >= 0 && y < mHeight);
|
|
|
|
y = mHeight - y -1; // upside-down
|
|
|
|
|
|
|
|
if (mBpp == 32) {
|
|
|
|
assert((mPitchBytes % 4) == 0);
|
|
|
|
assert(sizeof(RGBQUAD) == 4);
|
|
|
|
|
|
|
|
RGBQUAD* lptr = (RGBQUAD*) mpPixels;
|
|
|
|
lptr += y * (mPitchBytes >> 2) + x;
|
|
|
|
*lptr = *pRgbQuad;
|
|
|
|
} else if (mBpp == 24) {
|
|
|
|
unsigned char* ptr = (unsigned char*) mpPixels;
|
|
|
|
|
|
|
|
ptr += y * mPitchBytes + (x << 1) + x;
|
|
|
|
*ptr++ = pRgbQuad->rgbBlue;
|
|
|
|
*ptr++ = pRgbQuad->rgbGreen;
|
|
|
|
*ptr++ = pRgbQuad->rgbRed;
|
|
|
|
} else if (mBpp == 8 || mBpp == 4) {
|
|
|
|
int idx = LookupColor(pRgbQuad);
|
|
|
|
if (idx < 0) {
|
|
|
|
WMSG3(" DIB WARNING: unable to set pixel to (%d,%d,%d)\n",
|
|
|
|
pRgbQuad->rgbRed, pRgbQuad->rgbGreen, pRgbQuad->rgbBlue);
|
|
|
|
} else {
|
|
|
|
SetPixelIndex(x, (mHeight - y -1), idx);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
assert(false); // not implemented
|
|
|
|
}
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Get the color table index of the specified pixel.
|
|
|
|
*
|
|
|
|
* Only works on indexed-color formats (8bpp or less).
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
MyDIBitmap::GetPixelIndex(int x, int y, int* pIdx) const
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
assert(x >= 0 && x < mWidth && y >= 0 && y < mHeight);
|
|
|
|
y = mHeight - y -1; // upside-down
|
|
|
|
|
|
|
|
if (mBpp == 8) {
|
|
|
|
unsigned char* ptr = (unsigned char*) mpPixels;
|
|
|
|
|
|
|
|
ptr += y * mPitchBytes + x;
|
|
|
|
*pIdx = *ptr;
|
|
|
|
} else if (mBpp == 4) {
|
|
|
|
unsigned char* ptr = (unsigned char*) mpPixels;
|
|
|
|
|
|
|
|
ptr += y * mPitchBytes + (x >> 1);
|
|
|
|
if (x & 0x01)
|
|
|
|
*pIdx = (*ptr & 0x0f);
|
|
|
|
else
|
|
|
|
*pIdx = (*ptr & 0xf0) >> 4;
|
|
|
|
} else {
|
|
|
|
assert(false); // not implemented
|
|
|
|
}
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Set the index value of a pixel in an indexed-color bitmap (8bpp or less).
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
MyDIBitmap::SetPixelIndex(int x, int y, int idx)
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
if (x < 0 || x >= mWidth || y < 0 || y >= mHeight) {
|
|
|
|
WMSG3("BAD x=%d y=%d idx=%d\n", x, y, idx);
|
|
|
|
WMSG2(" width=%d height=%d\n", mWidth, mHeight);
|
|
|
|
}
|
|
|
|
assert(x >= 0 && x < mWidth && y >= 0 && y < mHeight);
|
|
|
|
y = mHeight - y -1; // upside-down
|
|
|
|
|
|
|
|
if (mBpp == 8) {
|
|
|
|
assert(idx >= 0 && idx < 256);
|
|
|
|
unsigned char* ptr = (unsigned char*) mpPixels;
|
|
|
|
|
|
|
|
ptr += y * mPitchBytes + x;
|
|
|
|
*ptr = idx;
|
|
|
|
} else if (mBpp == 4) {
|
|
|
|
assert(idx >= 0 && idx < 16);
|
|
|
|
unsigned char* ptr = (unsigned char*) mpPixels;
|
|
|
|
|
|
|
|
ptr += y * mPitchBytes + (x >> 1);
|
|
|
|
if (x & 0x01)
|
|
|
|
*ptr = (*ptr & 0xf0) | idx;
|
|
|
|
else
|
|
|
|
*ptr = (*ptr & 0x0f) | idx << 4;
|
|
|
|
} else {
|
|
|
|
assert(false); // not implemented
|
|
|
|
}
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Blit a block of pixels from one bitmap to another.
|
|
|
|
*
|
|
|
|
* The bitmaps must share a common format, and the rectangles must be the
|
|
|
|
* same size. We could implement color conversion and resizing here, but
|
|
|
|
* for now let's not.
|
|
|
|
*/
|
|
|
|
/*static*/ bool
|
|
|
|
MyDIBitmap::Blit(MyDIBitmap* pDstBits, const RECT* pDstRect,
|
2014-11-04 00:26:53 +00:00
|
|
|
const MyDIBitmap* pSrcBits, const RECT* pSrcRect)
|
2007-03-27 17:47:10 +00:00
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
if (pDstRect->right - pDstRect->left !=
|
|
|
|
pSrcRect->right - pSrcRect->left)
|
|
|
|
{
|
|
|
|
WMSG0("DIB blit: widths differ\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (pDstRect->bottom - pDstRect->top !=
|
|
|
|
pSrcRect->bottom - pSrcRect->top)
|
|
|
|
{
|
|
|
|
WMSG0("DIB blit: heights differ\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (pSrcBits->mBpp != pDstBits->mBpp) {
|
|
|
|
WMSG0("DIB blit: different formats\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (pDstRect->right <= pDstRect->left ||
|
|
|
|
pDstRect->bottom <= pDstRect->top)
|
|
|
|
{
|
|
|
|
WMSG0("DIB blit: poorly formed rect\n");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int srcX, srcY, dstX, dstY;
|
|
|
|
srcY = pSrcRect->top;
|
|
|
|
dstY = pDstRect->top;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* A decidedly non-optimized blit function.
|
|
|
|
*
|
|
|
|
* Copy by index when appropriate.
|
|
|
|
*/
|
|
|
|
if (pDstBits->mBpp <= 8) {
|
|
|
|
int idx;
|
|
|
|
while (srcY < pSrcRect->bottom) {
|
|
|
|
srcX = pSrcRect->left;
|
|
|
|
dstX = pDstRect->left;
|
|
|
|
while (srcX < pSrcRect->right) {
|
|
|
|
pSrcBits->GetPixelIndex(srcX, srcY, &idx);
|
|
|
|
pDstBits->SetPixelIndex(dstX, dstY, idx);
|
|
|
|
srcX++;
|
|
|
|
dstX++;
|
|
|
|
}
|
|
|
|
srcY++;
|
|
|
|
dstY++;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
RGBQUAD color;
|
|
|
|
while (srcY < pSrcRect->bottom) {
|
|
|
|
srcX = pSrcRect->left;
|
|
|
|
dstX = pDstRect->left;
|
|
|
|
while (srcX < pSrcRect->right) {
|
|
|
|
pSrcBits->GetPixelRGBA(srcX, srcY, &color);
|
|
|
|
pDstBits->SetPixelRGBA(dstX, dstY, &color);
|
|
|
|
srcX++;
|
|
|
|
dstX++;
|
|
|
|
}
|
|
|
|
srcY++;
|
|
|
|
dstY++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create a DDB from the current bitmap in the specified DC, and return its
|
|
|
|
* handle. The returned handle must eventually be disposed with DeleteObject.
|
|
|
|
*
|
|
|
|
* Since we're just supplying pointers to various pieces of data, there's no
|
|
|
|
* need for us to have a DIB section.
|
|
|
|
*
|
|
|
|
* Returns nil on failure.
|
|
|
|
*/
|
|
|
|
HBITMAP
|
|
|
|
MyDIBitmap::ConvertToDDB(HDC dc) const
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
HBITMAP hBitmap = nil;
|
|
|
|
|
|
|
|
if (mNumColorsUsed != 0 && !mColorTableInitialized) {
|
|
|
|
WMSG0(" DIB color table not initialized!\n");
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Create a BITMAPINFO structure with the BITMAPINFOHEADER from the
|
|
|
|
* DIB and a copy of the color table (if any).
|
|
|
|
*
|
|
|
|
* (We slightly over-allocate here, because the size of the BITMAPINFO
|
|
|
|
* struct actually includes the first color entry.)
|
|
|
|
*/
|
|
|
|
BITMAPINFO* pNewInfo = nil;
|
|
|
|
int colorTableSize = sizeof(RGBQUAD) * mNumColorsUsed;
|
|
|
|
pNewInfo = (BITMAPINFO*)
|
|
|
|
new unsigned char[sizeof(BITMAPINFO) + colorTableSize];
|
|
|
|
if (pNewInfo == nil)
|
|
|
|
return nil;
|
|
|
|
|
|
|
|
pNewInfo->bmiHeader = mBitmapInfoHdr;
|
|
|
|
if (colorTableSize != 0)
|
|
|
|
memcpy(&pNewInfo->bmiColors, mpColorTable, colorTableSize);
|
|
|
|
|
|
|
|
#if 0 // this fails under Win98SE, works under Win2K
|
|
|
|
/*
|
|
|
|
* Create storage.
|
|
|
|
*/
|
|
|
|
hBitmap = ::CreateDIBitmap(dc, &mBitmapInfoHdr, 0, nil, nil, 0);
|
|
|
|
if (hBitmap == nil) {
|
|
|
|
WMSG0(" DIB CreateDIBBitmap failed!\n");
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
WMSG4(" PARM hbit=0x%08lx hgt=%d fpPixels=0x%08lx pNewInfo=0x%08lx\n",
|
|
|
|
hBitmap, mBitmapInfoHdr.biHeight, fpPixels, pNewInfo);
|
|
|
|
LogHexDump(&mBitmapInfoHdr, sizeof(mBitmapInfoHdr));
|
|
|
|
WMSG(" pNewInfo (sz=%d colorTableSize=%d):\n", sizeof(BITMAPINFO),
|
|
|
|
colorTableSize);
|
|
|
|
LogHexDump(pNewInfo, sizeof(BITMAPINFO) + colorTableSize);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Transfer the bits.
|
|
|
|
*/
|
|
|
|
int count = ::SetDIBits(nil, hBitmap, 0, mBitmapInfoHdr.biHeight,
|
|
|
|
mpPixels, pNewInfo, DIB_RGB_COLORS);
|
|
|
|
|
|
|
|
if (count != mBitmapInfoHdr.biHeight) {
|
|
|
|
DWORD err = ::GetLastError();
|
|
|
|
|
|
|
|
WMSG1(" DIB SetDIBits failed, count was %d\n", count);
|
|
|
|
::DeleteObject(hBitmap);
|
|
|
|
hBitmap = nil;
|
|
|
|
|
|
|
|
CString msg;
|
|
|
|
GetWin32ErrorString(err, &msg);
|
Large set of changes to restore CiderPress build.
CiderPress and MDC now compile, and execute far enough to open
their respective "about" boxes, but I doubt they'll do much
more than that.
* Switch from MBCS to UNICODE APIs
Microsoft switched to UTF-16 (by way of UCS-2) a long time ago,
and the support for MBCS seems to be getting phased out. So it's
time to switch to wide strings.
This is a bit awkward for CiderPress because it works with disk
and file archives with 8-bit filenames, and I want NufxLib and
DiskImgLib to continue to work on Linux (which has largely taken
the UTF-8 approach to Unicode). The libraries will continue to
work with 8-bit filenames, with CiderPress/MDC doing the
conversion at the appropriate point.
There were a couple of places where strings from a structure
handed back by one of the libraries were used directly in the UI,
or vice-versa, which is a problem because we have nowhere to
store the result of the conversion. These currently have fixed
place-holder "xyzzy" strings.
All UI strings are now wide.
Various format strings now use "%ls" and "%hs" to explicitly
specify wide and narrow. This doesn't play well with gcc, so
only the Windows-specific parts use those.
* Various updates to vcxproj files
The project-file conversion had some cruft that is now largely
gone. The build now has a common output directory for the EXEs
and libraries, avoiding the old post-build copy steps.
* Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots
The old "prebuilts" directory is now gone. The libraries are now
built as part of building the apps.
I added a minimal set of files for zlib, and a full set for nufxlib.
The Linux-specific nufxlib goodies are included for the benefit of
the Linux utilities, which are currently broken (don't build).
* Replace symbols used for include guards
Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
|
|
|
WMSG2(" DIB CreateDIBSection failed (err=%d msg='%ls')\n",
|
|
|
|
err, (LPCWSTR) msg);
|
2014-11-04 00:26:53 +00:00
|
|
|
//ASSERT(false); // stop & examine this
|
|
|
|
return nil;
|
|
|
|
}
|
2007-03-27 17:47:10 +00:00
|
|
|
#else
|
2014-11-04 00:26:53 +00:00
|
|
|
/*
|
|
|
|
* Create storage.
|
|
|
|
*/
|
|
|
|
hBitmap = ::CreateDIBitmap(dc, &mBitmapInfoHdr, CBM_INIT, mpPixels,
|
|
|
|
pNewInfo, DIB_RGB_COLORS);
|
|
|
|
if (hBitmap == nil) {
|
|
|
|
WMSG0(" DIB CreateDIBBitmap failed!\n");
|
|
|
|
return nil;
|
|
|
|
}
|
2007-03-27 17:47:10 +00:00
|
|
|
#endif
|
|
|
|
|
2014-11-04 00:26:53 +00:00
|
|
|
delete[] pNewInfo;
|
|
|
|
return hBitmap;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Write the bitmap to the named file. Opens the file and calls the FILE*
|
|
|
|
* function.
|
|
|
|
*/
|
|
|
|
int
|
Large set of changes to restore CiderPress build.
CiderPress and MDC now compile, and execute far enough to open
their respective "about" boxes, but I doubt they'll do much
more than that.
* Switch from MBCS to UNICODE APIs
Microsoft switched to UTF-16 (by way of UCS-2) a long time ago,
and the support for MBCS seems to be getting phased out. So it's
time to switch to wide strings.
This is a bit awkward for CiderPress because it works with disk
and file archives with 8-bit filenames, and I want NufxLib and
DiskImgLib to continue to work on Linux (which has largely taken
the UTF-8 approach to Unicode). The libraries will continue to
work with 8-bit filenames, with CiderPress/MDC doing the
conversion at the appropriate point.
There were a couple of places where strings from a structure
handed back by one of the libraries were used directly in the UI,
or vice-versa, which is a problem because we have nowhere to
store the result of the conversion. These currently have fixed
place-holder "xyzzy" strings.
All UI strings are now wide.
Various format strings now use "%ls" and "%hs" to explicitly
specify wide and narrow. This doesn't play well with gcc, so
only the Windows-specific parts use those.
* Various updates to vcxproj files
The project-file conversion had some cruft that is now largely
gone. The build now has a common output directory for the EXEs
and libraries, avoiding the old post-build copy steps.
* Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots
The old "prebuilts" directory is now gone. The libraries are now
built as part of building the apps.
I added a minimal set of files for zlib, and a full set for nufxlib.
The Linux-specific nufxlib goodies are included for the benefit of
the Linux utilities, which are currently broken (don't build).
* Replace symbols used for include guards
Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
|
|
|
MyDIBitmap::WriteToFile(const WCHAR* fileName) const
|
2007-03-27 17:47:10 +00:00
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
FILE* fp = nil;
|
|
|
|
int err;
|
2007-03-27 17:47:10 +00:00
|
|
|
|
2014-11-04 00:26:53 +00:00
|
|
|
assert(fileName != nil);
|
2007-03-27 17:47:10 +00:00
|
|
|
|
Large set of changes to restore CiderPress build.
CiderPress and MDC now compile, and execute far enough to open
their respective "about" boxes, but I doubt they'll do much
more than that.
* Switch from MBCS to UNICODE APIs
Microsoft switched to UTF-16 (by way of UCS-2) a long time ago,
and the support for MBCS seems to be getting phased out. So it's
time to switch to wide strings.
This is a bit awkward for CiderPress because it works with disk
and file archives with 8-bit filenames, and I want NufxLib and
DiskImgLib to continue to work on Linux (which has largely taken
the UTF-8 approach to Unicode). The libraries will continue to
work with 8-bit filenames, with CiderPress/MDC doing the
conversion at the appropriate point.
There were a couple of places where strings from a structure
handed back by one of the libraries were used directly in the UI,
or vice-versa, which is a problem because we have nowhere to
store the result of the conversion. These currently have fixed
place-holder "xyzzy" strings.
All UI strings are now wide.
Various format strings now use "%ls" and "%hs" to explicitly
specify wide and narrow. This doesn't play well with gcc, so
only the Windows-specific parts use those.
* Various updates to vcxproj files
The project-file conversion had some cruft that is now largely
gone. The build now has a common output directory for the EXEs
and libraries, avoiding the old post-build copy steps.
* Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots
The old "prebuilts" directory is now gone. The libraries are now
built as part of building the apps.
I added a minimal set of files for zlib, and a full set for nufxlib.
The Linux-specific nufxlib goodies are included for the benefit of
the Linux utilities, which are currently broken (don't build).
* Replace symbols used for include guards
Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
|
|
|
fp = _wfopen(fileName, L"wb");
|
2014-11-04 00:26:53 +00:00
|
|
|
if (fp == nil) {
|
|
|
|
err = errno ? errno : -1;
|
Large set of changes to restore CiderPress build.
CiderPress and MDC now compile, and execute far enough to open
their respective "about" boxes, but I doubt they'll do much
more than that.
* Switch from MBCS to UNICODE APIs
Microsoft switched to UTF-16 (by way of UCS-2) a long time ago,
and the support for MBCS seems to be getting phased out. So it's
time to switch to wide strings.
This is a bit awkward for CiderPress because it works with disk
and file archives with 8-bit filenames, and I want NufxLib and
DiskImgLib to continue to work on Linux (which has largely taken
the UTF-8 approach to Unicode). The libraries will continue to
work with 8-bit filenames, with CiderPress/MDC doing the
conversion at the appropriate point.
There were a couple of places where strings from a structure
handed back by one of the libraries were used directly in the UI,
or vice-versa, which is a problem because we have nowhere to
store the result of the conversion. These currently have fixed
place-holder "xyzzy" strings.
All UI strings are now wide.
Various format strings now use "%ls" and "%hs" to explicitly
specify wide and narrow. This doesn't play well with gcc, so
only the Windows-specific parts use those.
* Various updates to vcxproj files
The project-file conversion had some cruft that is now largely
gone. The build now has a common output directory for the EXEs
and libraries, avoiding the old post-build copy steps.
* Added zlib 1.2.8 and nufxlib 2.2.2 source snapshots
The old "prebuilts" directory is now gone. The libraries are now
built as part of building the apps.
I added a minimal set of files for zlib, and a full set for nufxlib.
The Linux-specific nufxlib goodies are included for the benefit of
the Linux utilities, which are currently broken (don't build).
* Replace symbols used for include guards
Symbols with a leading "__" are reserved.
2014-11-10 23:32:55 +00:00
|
|
|
WMSG2("Unable to open bitmap file '%ls' (err=%d)\n", fileName, err);
|
2014-11-04 00:26:53 +00:00
|
|
|
return err;
|
|
|
|
}
|
2007-03-27 17:47:10 +00:00
|
|
|
|
2014-11-04 00:26:53 +00:00
|
|
|
err = WriteToFile(fp);
|
|
|
|
fclose(fp);
|
|
|
|
return err;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Write the bitmap to a file.
|
|
|
|
*
|
|
|
|
* Pass in an open, seeked file pointer (make sure to use "wb" mode).
|
|
|
|
*
|
|
|
|
* Returns 0 on success, or nonzero (errno) on failure.
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
MyDIBitmap::WriteToFile(FILE* fp) const
|
|
|
|
{
|
2014-11-04 00:26:53 +00:00
|
|
|
BITMAPFILEHEADER fileHeader;
|
|
|
|
long pixelBufSize;
|
|
|
|
long startOffset;
|
|
|
|
int result = -1;
|
|
|
|
|
|
|
|
assert(fp != nil);
|
|
|
|
|
|
|
|
startOffset = ftell(fp);
|
|
|
|
|
|
|
|
/* make sure all GDI operations on this bitmap have completed */
|
|
|
|
GdiFlush();
|
|
|
|
|
|
|
|
pixelBufSize = mPitchBytes * mBitmapInfoHdr.biHeight;
|
|
|
|
|
|
|
|
fileHeader.bfType = kBMPMagic;
|
|
|
|
fileHeader.bfReserved1 = 0;
|
|
|
|
fileHeader.bfReserved2 = 0;
|
|
|
|
fileHeader.bfOffBits = sizeof(fileHeader) + sizeof(mBitmapInfoHdr) +
|
|
|
|
sizeof(RGBQUAD) * mNumColorsUsed;
|
|
|
|
fileHeader.bfSize = fileHeader.bfOffBits + pixelBufSize;
|
|
|
|
|
|
|
|
WMSG3(" DIB writing bfOffBits=%d, bfSize=%d, pixelBufSize=%d\n",
|
|
|
|
fileHeader.bfOffBits, fileHeader.bfSize, pixelBufSize);
|
|
|
|
|
|
|
|
if (fwrite(&fileHeader, sizeof(fileHeader), 1, fp) != 1) {
|
|
|
|
result = errno ? errno : -1;
|
|
|
|
goto bail;
|
|
|
|
}
|
|
|
|
if (fwrite(&mBitmapInfoHdr, sizeof(mBitmapInfoHdr), 1, fp) != 1) {
|
|
|
|
result = errno ? errno : -1;
|
|
|
|
goto bail;
|
|
|
|
}
|
|
|
|
if (mNumColorsUsed != 0) {
|
|
|
|
assert(mpColorTable != nil);
|
|
|
|
if (fwrite(mpColorTable, sizeof(RGBQUAD) * mNumColorsUsed, 1, fp) != 1)
|
|
|
|
{
|
|
|
|
result = errno ? errno : -1;
|
|
|
|
goto bail;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (fwrite(mpPixels, pixelBufSize, 1, fp) != 1) {
|
|
|
|
result = errno ? errno : -1;
|
|
|
|
goto bail;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* push it out to disk */
|
|
|
|
fflush(fp);
|
|
|
|
|
|
|
|
/* verify the length; useful for detecting "w" vs "wb" */
|
|
|
|
if (ftell(fp) - startOffset != (long) fileHeader.bfSize) {
|
|
|
|
WMSG2("DIB tried to write %ld, wrote %ld (check for \"wb\")\n",
|
|
|
|
fileHeader.bfSize, ftell(fp) - startOffset);
|
|
|
|
assert(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
result = 0;
|
2007-03-27 17:47:10 +00:00
|
|
|
|
|
|
|
bail:
|
2014-11-04 00:26:53 +00:00
|
|
|
return result;
|
2007-03-27 17:47:10 +00:00
|
|
|
}
|