Files
opennurbs/opennurbs_bitmap.h
2019-04-09 10:11:17 -07:00

525 lines
19 KiB
C++

/* $NoKeywords: $ */
/*
//
// Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
// OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
// McNeel & Associates.
//
// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
// ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
// MERCHANTABILITY ARE HEREBY DISCLAIMED.
//
// For complete openNURBS copyright information see <http://www.opennurbs.org>.
//
////////////////////////////////////////////////////////////////
*/
////////////////////////////////////////////////////////////////
//
// Defines ON_WindowsBITMAPINFO class that is used to provide OS independent
// serialization of Windows device independent bitmaps (BITMAPINFO) used
// to store preview images.
//
////////////////////////////////////////////////////////////////
#if !defined(OPENNURBS_BITMAP_INC_)
#define OPENNURBS_BITMAP_INC_
class ON_CLASS ON_Bitmap : public ON_ModelComponent
{
ON_OBJECT_DECLARE(ON_Bitmap);
public:
ON_Bitmap() ON_NOEXCEPT;
~ON_Bitmap() = default;
ON_Bitmap(const ON_Bitmap&);
ON_Bitmap& operator=(const ON_Bitmap&) = default;
static const ON_Bitmap Unset;
/*
Parameters:
model_component_reference - [in]
none_return_value - [in]
value to return if ON_Layer::Cast(model_component_ref.ModelComponent())
is nullptr
Returns:
If ON_Layer::Cast(model_component_ref.ModelComponent()) is not nullptr,
that pointer is returned. Otherwise, none_return_value is returned.
*/
static const ON_Bitmap* FromModelComponentRef(
const class ON_ModelComponentReference& model_component_reference,
const ON_Bitmap* none_return_value
);
void Dump(
ON_TextLog&
) const override;
bool Write( class ON_BinaryArchive& ) const override;
bool Read( class ON_BinaryArchive& ) override;
unsigned int SizeOf() const override;
virtual
int Width() const;
virtual
int Height() const; // >0 means it's a bottom-up bitmap with origin at lower right
// <0 means it's a top-down bitmap with origin at upper left
virtual
int BitsPerPixel() const; // bits per pixel
virtual
size_t SizeofScan() const; // number of bytes per scan line
virtual
size_t SizeofImage() const; // size of current map in bytes
virtual
unsigned char* Bits(
int scan_line_index
);
virtual
const unsigned char* Bits(
int scan_line_index
) const;
const ON_FileReference& FileReference() const;
void SetFileReference(
const ON_FileReference& file_reference
);
void SetFileFullPath(
const wchar_t* file_full_path,
bool bSetContentHash
);
private:
ON_FileReference m_file_reference;
};
#if defined(ON_DLL_TEMPLATE)
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_Bitmap*>;
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<const ON_Bitmap*>;
#endif
#if !defined(ON_OS_WINDOWS_GDI)
// These are the values of the Windows defines mentioned
// in the comment below. If you're running on Windows,
// they get defined by Windows system header files.
// If you aren't running on Windows, then you don't
// need them.
//#define BI_RGB 0L
//#define BI_RLE8 1L
//#define BI_RLE4 2L
//#define BI_BITFIELDS 3L
// Windows sizeof(ON_WindowsRGBQUAD) = 4.
struct ON_WindowsRGBQUAD {
// Mimics Windows RGBQUAD structure.
// For details searh for "RGBQUAD" at http://msdn.microsoft.com/default.asp
unsigned char rgbBlue; // BYTE
unsigned char rgbGreen; // BYTE
unsigned char rgbRed; // BYTE
unsigned char rgbReserved; // BYTE
};
// Windows packs BITMAPFILEHEADER
#pragma pack(push,2)
struct ON_WindowsBITMAPFILEHEADER {
unsigned short bfType; // WORD = file type, must be BM
unsigned int bfSize; // DWORD = size, in bytes, of the bitmap file
unsigned short bfReserved1; // WORD Reserved; must be zero
unsigned short bfReserved2; // WORD Reserved; must be zero
unsigned int bfOffBits; // DWORD = offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits
};
#pragma pack(pop)
// Mimics Windows BITMAPINFOHEADER structure.
// For details searh for "BITMAPINFOHEADER" at http://msdn.microsoft.com/default.asp
// Windows sizeof(BITMAPINFOHEADER) = 80.
struct ON_WindowsBITMAPINFOHEADER
{
unsigned int biSize; // DWORD = sizeof(BITMAPINFOHEADER)
int biWidth; // LONG = width (in pixels) of (decompressed) bitmap
int biHeight; // LONG = height (in pixels) of (decompressed) bitmap
// >0 means it's a bottom-up bitmap with origin
// in the lower left corner.
// <0 means it's a top-down bitmap with origin
// in the upper left corner.
unsigned short biPlanes; // WORD = number of planes
// (always 1 in current Windows versions)
unsigned short biBitCount; // WORD = bits per pixel (0,1,4,8,16,24,32 are valid)
// 1 See http://msdn.microsoft.com/default.asp
// 4 See http://msdn.microsoft.com/default.asp
// 8 The bitmap has a maximum of 256 colors,
// and the bmiColors member contains up
// to 256 entries. In this case, each byte
// in the array represents a single pixel.
// 16 See http://msdn.microsoft.com/default.asp
// 24 If biClrUsed=0 and biCompression=BI_RGB(0),
// then each 3-byte triplet in the bitmap
// array represents the relative intensities
// of blue, green, and red, respectively, for
// a pixel. For other possibilities, see
// http://msdn.microsoft.com/default.asp
// 32 If biClrUsed=0 and biCompression=BI_RGB(0),
// then each 4-byte DWORD in the bitmap
// array represents the relative intensities
// of blue, green, and red, respectively, for
// a pixel. The high byte in each DWORD is not
// used.
// If biClrUsed=3, biCompression=BITFIELDS(3),
// biColors[0] = red mask (0x00FF0000),
// biColors[1] = green mask (0x0000FF00), and
// biColors[2] = blue mask (0x000000FF),
// then tese masks are used with each 4-byte
// DWORD in the bitmap array to determine
// the pixel's relative intensities. //
// For other possibilities, see
// http://msdn.microsoft.com/default.asp
unsigned int biCompression; // DWORD Currently, Windows defines the following
// types of compression.
// =0 BI_RGB (no compression)
// =1 BI_RLE8 (run length encoded used for 8 bpp)
// =2 BI_RLE4 (run length encoded used for 4 bpp)
// =3 BI_BITFIELDS Specifies that the bitmap is
// not compressed and that the color table
// consists of three DWORD color masks that
// specify the red, green, and blue components,
// respectively, of each pixel. This is valid
// when used with 16- and 32-bit-per-pixel
// bitmaps.
// =4 BI_JPEG (not supported in Win 95/NT4)
//
unsigned int biSizeImage; // DWORD = bytes in image
int biXPelsPerMeter; // LONG
int biYPelsPerMeter; // LONG
unsigned int biClrUsed; // DWORD = 0 or true length of bmiColors[] array. If 0,
// then the value of biBitCount determines the
// length of the bmiColors[] array.
unsigned int biClrImportant; // DWORD
};
struct ON_WindowsBITMAPINFO
{
// Mimics Windows BITMAPINFO structure.
// For details searh for "BITMAPINFO" at http://msdn.microsoft.com/default.asp
ON_WindowsBITMAPINFOHEADER bmiHeader;
ON_WindowsRGBQUAD bmiColors[1]; // The "[1]" is for the compiler. In
// practice this array commonly has
// length 0, 3, or 256 and a BITMAPINFO*
// points to a contiguous piece of memory
// that contains
//
// BITMAPINFOHEADER
// RGBQUAD[length determined by flags]
// unsigned char[biSizeImage]
//
// See the ON_WindowsBITMAPINFOHEADER comments
// and http://msdn.microsoft.com/default.asp
// for more details.
};
#endif
class ON_CLASS ON_WindowsBitmap : public ON_Bitmap
{
ON_OBJECT_DECLARE(ON_WindowsBitmap);
// Uncompressed 8 bpp, 24 bpp, or 32 bpp Windows device
// independent bitmaps (DIB)
public:
ON_WindowsBitmap() = default;
~ON_WindowsBitmap();
ON_WindowsBitmap(const ON_WindowsBitmap&);
ON_WindowsBitmap& operator=(const ON_WindowsBitmap&);
static const ON_WindowsBitmap Unset;
/*
Parameters:
width - [in]
height - [in]
bits_per_pixel - [in]
1, 2, 4, 8, 16, 24, or 32
*/
bool Create(
int width,
int height,
int bits_per_pixel
);
bool IsValid( class ON_TextLog* text_log = nullptr ) const override;
bool IsEmpty() const;
bool Write( ON_BinaryArchive& ) const override; // writes compressed image
bool Read( ON_BinaryArchive& ) override; // reads compressed image
unsigned int SizeOf() const override;
public:
bool WriteCompressed( ON_BinaryArchive& ) const;
bool ReadCompressed( ON_BinaryArchive& );
bool WriteUncompressed( ON_BinaryArchive& ) const;
bool ReadUncompressed( ON_BinaryArchive& );
public:
int Width() const override;
int Height() const override; // >0 means it's a bottom-up bitmap with origin at lower right
// <0 means it's a top-down bitmap with origin at upper left
int PaletteColorCount() const; // number of colors in palette
int SizeofPalette() const; // number of bytes in palette
int BitsPerPixel() const override;
size_t SizeofScan() const override; // number of bytes per scan line
size_t SizeofImage() const override; // number of bytes in image
unsigned char* Bits(
int // index of scan line
) override;
const unsigned char* Bits(
int // index of scan line
) const override;
//int PaletteIndex( ON_Color ) const; // for 8bpp bitmaps
ON_Color Pixel(
int, // 0 <= i < width
int // 0 <= j < height
) const;
ON_Color Pixel(
int, // 0 <= i < width
const unsigned char* // value of Bits( j )
) const;
//bool SetColor( // sets entire map to specified color
// ON_Color
// );
#if defined(ON_OS_WINDOWS_GDI)
/*
Description:
Create an ON_WindowsBitmap from a contiguous bitmap.
Copies src.
Parameters:
src - [in] contiguous Windows device independent bitmap.
Remarks:
If the current Windows BITMAPINFO is identical to ON_WindowsBITMAPINFO,
then the result of this call is identical to
int color_count = number of colors in bitmap's palette;
ON_WindowsBitmap::Create( &src, &src.bmiColors[color_count], true ).
See Also:
ON_WindowsBitmap::Create
*/
ON_WindowsBitmap( const BITMAPINFO& src );
/*
Description:
Create an ON_WindowsBitmap from a contiguous bitmap.
Shares bitmap memory with src.
Parameters:
src - [in] contiguous Windows device independent bitmap.
See Also:
ON_WindowsBitmap::Create
Remarks:
~ON_WindowsBitmap will not delete src.
*/
ON_WindowsBitmap( const BITMAPINFO* src );
/*
Description:
Create an ON_WindowsBitmap from a contiguous bitmap.
Copies src.
Parameters:
src - [in] contiguous Windows device independent bitmap.
See Also:
ON_WindowsBitmap::Create
*/
ON_WindowsBitmap& operator=( const BITMAPINFO& src );
/*
Description:
Create and ON_WindowsBitmap from a Windows BITMAPINFO pointer
and a pointer to the bits.
This is intended to make it easy to write compressed bimaps.
For ON_WindowsBitmap classes created with ON_WindowsBitmap::Share,
ON_WindowsBitmap::Destroy and ~ON_WindowsBitmap will
not free the bmi and bits memory.
Parameters:
bmi - [in] valid BITMAPINFO
bits - [in] bits for BITMAPINFO
bCopy - [in] If true, the bmi and bits are copied into a contiguous
bitmap that will be deleted by ~ON_WindowsBitmap.
If false, the m_bmi and m_bits pointers on this class
are simply set to bmi and bits. In this case,
~ON_WindowsBitmap will not free the bmi or bits
memory.
Example:
ON_BinaryArchive archive = ...;
BITMAPINFO* bmi = 0;
unsigned char* bits = 0;
int color_count = ...; // number of colors in palette
int sizeof_palette = sizeof(bmi->bmiColors[0]) * color_count;
BITMAPINFO* bmi = (LPBITMAPINFO)calloc( 1, sizeof(*bmi) + sizeof_palette );
bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
bmi->bmiHeader.biWidth = width;
bmi->bmiHeader.biHeight = height;
bmi->bmiHeader.biPlanes = 1;
bmi->bmiHeader.biBitCount = (USHORT)color_depth;
bmi->bmiHeader.biCompression = BI_RGB;
bmi->bmiHeader.biXPelsPerMeter = 0;
bmi->bmiHeader.biYPelsPerMeter = 0;
bmi->bmiHeader.biClrUsed = 0;
bmi->bmiHeader.biClrImportant = 0;
bmi->bmiHeader.biSizeImage = GetStorageSize();
// initialize palette
...
HBITMAP hbm = ::CreateDIBSection( nullptr, bmi, ..., (LPVOID*)&bits, nullptr, 0);
{
// Use ON_WindowsBitmap to write a compressed bitmap to
// archive. Does not modify bmi or bits.
ON_WindowsBitmap onbm;
onbm.Create(bmi,bit,false);
onbm.Write( arcive );
}
*/
bool Create(
const BITMAPINFO* bmi,
const unsigned char* bits,
bool bCopy
);
#endif
/*
Returns:
True if m_bmi and m_bits are in a single contiguous
block of memory.
False if m_bmi and m_bits are in two blocks of memory.
*/
bool IsContiguous() const;
#if defined(ON_OS_WINDOWS_GDI)
BITMAPINFO* m_bmi = nullptr;
#else
struct ON_WindowsBITMAPINFO* m_bmi = nullptr;
/*
Description:
Create an ON_WindowsBitmap from a contiguous bitmap ON_WindowsBITMAPINFO.
Parameters:
src - [in]
A contiguous Windows device independent bitmap. This means that the
"bits" in the bitmap begin at the memory location &m_bits->bmiColors[0].
See Also:
Remarks:
~ON_WindowsBitmap will not delete src.
*/
bool Create (
const struct ON_WindowsBITMAPINFO* src
);
#endif
unsigned char* m_bits = nullptr;
private:
int m_bFreeBMI = 0; // 0 m_bmi and m_bits are not freed by ON_WindowsBitmap::Destroy
// 1 m_bmi memory is freed by ON_WindowsBitmap::Destroy
// 2 m_bits memory is freed by ON_WindowsBitmap::Destroy
// 3 m_bmi and m_bits memory is freed by ON_WindowsBitmap::Destroy
private:
bool Internal_WriteV5( ON_BinaryArchive& ) const;
bool Internal_ReadV5( ON_BinaryArchive& );
protected:
void Internal_Destroy();
void Internal_Copy(
const ON_WindowsBitmap& src
);
};
/*
Description:
ON_WindowsBitmapEx is identical to ON_WindowsBitmap except that
it's Read/Write functions save bitmap names.
*/
class ON_CLASS ON_WindowsBitmapEx : public ON_WindowsBitmap
{
ON_OBJECT_DECLARE(ON_WindowsBitmapEx);
public:
ON_WindowsBitmapEx() = default;
~ON_WindowsBitmapEx() = default;
ON_WindowsBitmapEx(const ON_WindowsBitmapEx&) = default;
ON_WindowsBitmapEx& operator=(const ON_WindowsBitmapEx&) = default;
static const ON_WindowsBitmapEx Unset;
bool Write( ON_BinaryArchive& ) const override; // writes compressed image
bool Read( ON_BinaryArchive& ) override; // reads compressed image
private:
bool Internal_WriteV5( ON_BinaryArchive& ) const; // writes compressed image
bool Internal_ReadV5( ON_BinaryArchive& ); // reads compressed image
};
class ON_CLASS ON_EmbeddedBitmap : public ON_Bitmap
{
ON_OBJECT_DECLARE(ON_EmbeddedBitmap);
public:
ON_EmbeddedBitmap() = default;
~ON_EmbeddedBitmap();
ON_EmbeddedBitmap(const ON_EmbeddedBitmap&);
ON_EmbeddedBitmap& operator=(const ON_EmbeddedBitmap&);
static const ON_EmbeddedBitmap Unset;
void Create(
size_t sizeof_buffer
);
bool IsValid( class ON_TextLog* text_log = nullptr ) const override;
bool Write( ON_BinaryArchive& ) const override;
bool Read( ON_BinaryArchive& ) override;
unsigned int SizeOf() const override;
size_t SizeofImage() const override;
unsigned char* Bits(int) override;
const unsigned char* Bits(int) const override;
const void* m_buffer = nullptr;
size_t m_sizeof_buffer = 0;
bool m_managed_buffer = false; // true means the ON_EmbeddedBitmap class manages m_buffer memory.
ON__UINT32 m_buffer_crc32 = 0; // 32 bit crc from ON_CRC32
private:
bool Internal_WriteV5( ON_BinaryArchive& ) const;
bool Internal_ReadV5( ON_BinaryArchive& );
private:
void Internal_Destroy();
void Internal_Copy(
const ON_EmbeddedBitmap& src
);
};
#endif