opennurbs_bitmap.h
1 /* $NoKeywords: $ */
2 /*
3 //
4 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
5 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
6 // McNeel & Associates.
7 //
8 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
9 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
10 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
11 //
12 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
13 //
14 ////////////////////////////////////////////////////////////////
15 */
16 
17 ////////////////////////////////////////////////////////////////
18 //
19 // Defines ON_WindowsBITMAPINFO class that is used to provide OS independent
20 // serialization of Windows device independent bitmaps (BITMAPINFO) used
21 // to store preview images.
22 //
23 ////////////////////////////////////////////////////////////////
24 
25 #if !defined(OPENNURBS_BITMAP_INC_)
26 #define OPENNURBS_BITMAP_INC_
27 
28 class ON_CLASS ON_Bitmap : public ON_ModelComponent
29 {
30  ON_OBJECT_DECLARE(ON_Bitmap);
31 
32 public:
33  ON_Bitmap() ON_NOEXCEPT;
34  ~ON_Bitmap() = default;
35  ON_Bitmap(const ON_Bitmap&);
36  ON_Bitmap& operator=(const ON_Bitmap&) = default;
37 
38  static const ON_Bitmap Unset;
39 
40  /*
41  Parameters:
42  model_component_reference - [in]
43  none_return_value - [in]
44  value to return if ON_Layer::Cast(model_component_ref.ModelComponent())
45  is nullptr
46  Returns:
47  If ON_Layer::Cast(model_component_ref.ModelComponent()) is not nullptr,
48  that pointer is returned. Otherwise, none_return_value is returned.
49  */
50  static const ON_Bitmap* FromModelComponentRef(
51  const class ON_ModelComponentReference& model_component_reference,
52  const ON_Bitmap* none_return_value
53  );
54 
55  void Dump(
56  ON_TextLog&
57  ) const override;
58 
59  bool Write( class ON_BinaryArchive& ) const override;
60  bool Read( class ON_BinaryArchive& ) override;
61 
62  unsigned int SizeOf() const override;
63 
64  virtual
65  int Width() const;
66 
67  virtual
68  int Height() const; // >0 means it's a bottom-up bitmap with origin at lower right
69  // <0 means it's a top-down bitmap with origin at upper left
70  virtual
71  int BitsPerPixel() const; // bits per pixel
72 
73  virtual
74  size_t SizeofScan() const; // number of bytes per scan line
75 
76  virtual
77  size_t SizeofImage() const; // size of current map in bytes
78 
79  virtual
80  unsigned char* Bits(
81  int scan_line_index
82  );
83 
84  virtual
85  const unsigned char* Bits(
86  int scan_line_index
87  ) const;
88 
89  const ON_FileReference& FileReference() const;
90  void SetFileReference(
91  const ON_FileReference& file_reference
92  );
93  void SetFileFullPath(
94  const wchar_t* file_full_path,
95  bool bSetContentHash
96  );
97 
98 private:
99  ON_FileReference m_file_reference;
100 };
101 
102 #if defined(ON_DLL_TEMPLATE)
103 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_Bitmap*>;
104 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<const ON_Bitmap*>;
105 #endif
106 
107 #if !defined(ON_OS_WINDOWS_GDI)
108 
109 // These are the values of the Windows defines mentioned
110 // in the comment below. If you're running on Windows,
111 // they get defined by Windows system header files.
112 // If you aren't running on Windows, then you don't
113 // need them.
114 //#define BI_RGB 0L
115 //#define BI_RLE8 1L
116 //#define BI_RLE4 2L
117 //#define BI_BITFIELDS 3L
119 // Windows sizeof(ON_WindowsRGBQUAD) = 4.
120 struct ON_WindowsRGBQUAD {
121  // Mimics Windows RGBQUAD structure.
122  // For details searh for "RGBQUAD" at http://msdn.microsoft.com/default.asp
123  unsigned char rgbBlue; // BYTE
124  unsigned char rgbGreen; // BYTE
125  unsigned char rgbRed; // BYTE
126  unsigned char rgbReserved; // BYTE
127 };
128 
129 // Windows packs BITMAPFILEHEADER
130 #pragma pack(push,2)
132  unsigned short bfType; // WORD = file type, must be BM
133  unsigned int bfSize; // DWORD = size, in bytes, of the bitmap file
134  unsigned short bfReserved1; // WORD Reserved; must be zero
135  unsigned short bfReserved2; // WORD Reserved; must be zero
136  unsigned int bfOffBits; // DWORD = offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits
137 };
138 #pragma pack(pop)
139 
140 // Mimics Windows BITMAPINFOHEADER structure.
141 // For details searh for "BITMAPINFOHEADER" at http://msdn.microsoft.com/default.asp
142 // Windows sizeof(BITMAPINFOHEADER) = 80.
144 {
145  unsigned int biSize; // DWORD = sizeof(BITMAPINFOHEADER)
146  int biWidth; // LONG = width (in pixels) of (decompressed) bitmap
147  int biHeight; // LONG = height (in pixels) of (decompressed) bitmap
148  // >0 means it's a bottom-up bitmap with origin
149  // in the lower left corner.
150  // <0 means it's a top-down bitmap with origin
151  // in the upper left corner.
152  unsigned short biPlanes; // WORD = number of planes
153  // (always 1 in current Windows versions)
154  unsigned short biBitCount; // WORD = bits per pixel (0,1,4,8,16,24,32 are valid)
155  // 1 See http://msdn.microsoft.com/default.asp
156  // 4 See http://msdn.microsoft.com/default.asp
157  // 8 The bitmap has a maximum of 256 colors,
158  // and the bmiColors member contains up
159  // to 256 entries. In this case, each byte
160  // in the array represents a single pixel.
161  // 16 See http://msdn.microsoft.com/default.asp
162  // 24 If biClrUsed=0 and biCompression=BI_RGB(0),
163  // then each 3-byte triplet in the bitmap
164  // array represents the relative intensities
165  // of blue, green, and red, respectively, for
166  // a pixel. For other possibilities, see
167  // http://msdn.microsoft.com/default.asp
168  // 32 If biClrUsed=0 and biCompression=BI_RGB(0),
169  // then each 4-byte DWORD in the bitmap
170  // array represents the relative intensities
171  // of blue, green, and red, respectively, for
172  // a pixel. The high byte in each DWORD is not
173  // used.
174  // If biClrUsed=3, biCompression=BITFIELDS(3),
175  // biColors[0] = red mask (0x00FF0000),
176  // biColors[1] = green mask (0x0000FF00), and
177  // biColors[2] = blue mask (0x000000FF),
178  // then tese masks are used with each 4-byte
179  // DWORD in the bitmap array to determine
180  // the pixel's relative intensities. //
181  // For other possibilities, see
182  // http://msdn.microsoft.com/default.asp
183  unsigned int biCompression; // DWORD Currently, Windows defines the following
184  // types of compression.
185  // =0 BI_RGB (no compression)
186  // =1 BI_RLE8 (run length encoded used for 8 bpp)
187  // =2 BI_RLE4 (run length encoded used for 4 bpp)
188  // =3 BI_BITFIELDS Specifies that the bitmap is
189  // not compressed and that the color table
190  // consists of three DWORD color masks that
191  // specify the red, green, and blue components,
192  // respectively, of each pixel. This is valid
193  // when used with 16- and 32-bit-per-pixel
194  // bitmaps.
195  // =4 BI_JPEG (not supported in Win 95/NT4)
196  //
197  unsigned int biSizeImage; // DWORD = bytes in image
198  int biXPelsPerMeter; // LONG
199  int biYPelsPerMeter; // LONG
200  unsigned int biClrUsed; // DWORD = 0 or true length of bmiColors[] array. If 0,
201  // then the value of biBitCount determines the
202  // length of the bmiColors[] array.
203  unsigned int biClrImportant; // DWORD
204 };
205 
207 {
208  // Mimics Windows BITMAPINFO structure.
209  // For details searh for "BITMAPINFO" at http://msdn.microsoft.com/default.asp
210  ON_WindowsBITMAPINFOHEADER bmiHeader;
211  ON_WindowsRGBQUAD bmiColors[1]; // The "[1]" is for the compiler. In
212  // practice this array commonly has
213  // length 0, 3, or 256 and a BITMAPINFO*
214  // points to a contiguous piece of memory
215  // that contains
216  //
217  // BITMAPINFOHEADER
218  // RGBQUAD[length determined by flags]
219  // unsigned char[biSizeImage]
220  //
221  // See the ON_WindowsBITMAPINFOHEADER comments
222  // and http://msdn.microsoft.com/default.asp
223  // for more details.
224 };
225 
226 #endif
227 
228 class ON_CLASS ON_WindowsBitmap : public ON_Bitmap
229 {
230  ON_OBJECT_DECLARE(ON_WindowsBitmap);
231  // Uncompressed 8 bpp, 24 bpp, or 32 bpp Windows device
232  // independent bitmaps (DIB)
233 public:
234  ON_WindowsBitmap() = default;
235  ~ON_WindowsBitmap();
238 
239  static const ON_WindowsBitmap Unset;
240 
241  /*
242  Parameters:
243  width - [in]
244  height - [in]
245  bits_per_pixel - [in]
246  1, 2, 4, 8, 16, 24, or 32
247  */
248  bool Create(
249  int width,
250  int height,
251  int bits_per_pixel
252  );
253 
254  bool IsValid( class ON_TextLog* text_log = nullptr ) const override;
255 
256  bool IsEmpty() const;
257 
258  bool Write( ON_BinaryArchive& ) const override; // writes compressed image
259  bool Read( ON_BinaryArchive& ) override; // reads compressed image
260  unsigned int SizeOf() const override;
261 
262 public:
263  bool WriteCompressed( ON_BinaryArchive& ) const;
264  bool ReadCompressed( ON_BinaryArchive& );
265  bool WriteUncompressed( ON_BinaryArchive& ) const;
266  bool ReadUncompressed( ON_BinaryArchive& );
267 
268 public:
269  int Width() const override;
270  int Height() const override; // >0 means it's a bottom-up bitmap with origin at lower right
271  // <0 means it's a top-down bitmap with origin at upper left
272 
273  int PaletteColorCount() const; // number of colors in palette
274  int SizeofPalette() const; // number of bytes in palette
275 
276  int BitsPerPixel() const override;
277  size_t SizeofScan() const override; // number of bytes per scan line
278  size_t SizeofImage() const override; // number of bytes in image
279 
280  unsigned char* Bits(
281  int // index of scan line
282  ) override;
283  const unsigned char* Bits(
284  int // index of scan line
285  ) const override;
286 
287  //int PaletteIndex( ON_Color ) const; // for 8bpp bitmaps
288 
289  ON_Color Pixel(
290  int, // 0 <= i < width
291  int // 0 <= j < height
292  ) const;
293  ON_Color Pixel(
294  int, // 0 <= i < width
295  const unsigned char* // value of Bits( j )
296  ) const;
297 
298  //bool SetColor( // sets entire map to specified color
299  // ON_Color
300  // );
301 
302 #if defined(ON_OS_WINDOWS_GDI)
303 
304  /*
305  Description:
306  Create an ON_WindowsBitmap from a contiguous bitmap.
307  Copies src.
308  Parameters:
309  src - [in] contiguous Windows device independent bitmap.
310  Remarks:
311  If the current Windows BITMAPINFO is identical to ON_WindowsBITMAPINFO,
312  then the result of this call is identical to
313 
314  int color_count = number of colors in bitmap's palette;
315  ON_WindowsBitmap::Create( &src, &src.bmiColors[color_count], true ).
316 
317  See Also:
318  ON_WindowsBitmap::Create
319  */
320  ON_WindowsBitmap( const BITMAPINFO& src );
321 
322  /*
323  Description:
324  Create an ON_WindowsBitmap from a contiguous bitmap.
325  Shares bitmap memory with src.
326  Parameters:
327  src - [in] contiguous Windows device independent bitmap.
328  See Also:
329  ON_WindowsBitmap::Create
330  Remarks:
331  ~ON_WindowsBitmap will not delete src.
332  */
333  ON_WindowsBitmap( const BITMAPINFO* src );
334 
335  /*
336  Description:
337  Create an ON_WindowsBitmap from a contiguous bitmap.
338  Copies src.
339  Parameters:
340  src - [in] contiguous Windows device independent bitmap.
341  See Also:
342  ON_WindowsBitmap::Create
343  */
344  ON_WindowsBitmap& operator=( const BITMAPINFO& src );
345 
346  /*
347  Description:
348  Create and ON_WindowsBitmap from a Windows BITMAPINFO pointer
349  and a pointer to the bits.
350 
351  This is intended to make it easy to write compressed bimaps.
352  For ON_WindowsBitmap classes created with ON_WindowsBitmap::Share,
353  ON_WindowsBitmap::Destroy and ~ON_WindowsBitmap will
354  not free the bmi and bits memory.
355 
356  Parameters:
357  bmi - [in] valid BITMAPINFO
358  bits - [in] bits for BITMAPINFO
359  bCopy - [in] If true, the bmi and bits are copied into a contiguous
360  bitmap that will be deleted by ~ON_WindowsBitmap.
361  If false, the m_bmi and m_bits pointers on this class
362  are simply set to bmi and bits. In this case,
363  ~ON_WindowsBitmap will not free the bmi or bits
364  memory.
365 
366  Example:
367 
368  ON_BinaryArchive archive = ...;
369  BITMAPINFO* bmi = 0;
370  unsigned char* bits = 0;
371  int color_count = ...; // number of colors in palette
372 
373  int sizeof_palette = sizeof(bmi->bmiColors[0]) * color_count;
374 
375  BITMAPINFO* bmi = (LPBITMAPINFO)calloc( 1, sizeof(*bmi) + sizeof_palette );
376 
377  bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
378  bmi->bmiHeader.biWidth = width;
379  bmi->bmiHeader.biHeight = height;
380  bmi->bmiHeader.biPlanes = 1;
381  bmi->bmiHeader.biBitCount = (USHORT)color_depth;
382  bmi->bmiHeader.biCompression = BI_RGB;
383  bmi->bmiHeader.biXPelsPerMeter = 0;
384  bmi->bmiHeader.biYPelsPerMeter = 0;
385  bmi->bmiHeader.biClrUsed = 0;
386  bmi->bmiHeader.biClrImportant = 0;
387  bmi->bmiHeader.biSizeImage = GetStorageSize();
388 
389  // initialize palette
390  ...
391 
392  HBITMAP hbm = ::CreateDIBSection( nullptr, bmi, ..., (LPVOID*)&bits, nullptr, 0);
393 
394  {
395  // Use ON_WindowsBitmap to write a compressed bitmap to
396  // archive. Does not modify bmi or bits.
397  ON_WindowsBitmap onbm;
398  onbm.Create(bmi,bit,false);
399  onbm.Write( arcive );
400  }
401 
402  */
403  bool Create(
404  const BITMAPINFO* bmi,
405  const unsigned char* bits,
406  bool bCopy
407  );
408 
409 #endif
411  /*
412  Returns:
413  True if m_bmi and m_bits are in a single contiguous
414  block of memory.
415  False if m_bmi and m_bits are in two blocks of memory.
416  */
417  bool IsContiguous() const;
418 
419 #if defined(ON_OS_WINDOWS_GDI)
420  BITMAPINFO* m_bmi = nullptr;
421 #else
422  struct ON_WindowsBITMAPINFO* m_bmi = nullptr;
423 
424  /*
425 Description:
426  Create an ON_WindowsBitmap from a contiguous bitmap ON_WindowsBITMAPINFO.
427  Parameters:
428  src - [in]
429  A contiguous Windows device independent bitmap. This means that the
430  "bits" in the bitmap begin at the memory location &m_bits->bmiColors[0].
431  See Also:
432  Remarks:
433  ~ON_WindowsBitmap will not delete src.
434  */
435  bool Create (
436  const struct ON_WindowsBITMAPINFO* src
437  );
438 #endif
439 
440  unsigned char* m_bits = nullptr;
441 
442 private:
443  int m_bFreeBMI = 0; // 0 m_bmi and m_bits are not freed by ON_WindowsBitmap::Destroy
444  // 1 m_bmi memory is freed by ON_WindowsBitmap::Destroy
445  // 2 m_bits memory is freed by ON_WindowsBitmap::Destroy
446  // 3 m_bmi and m_bits memory is freed by ON_WindowsBitmap::Destroy
447 
448 private:
449  bool Internal_WriteV5( ON_BinaryArchive& ) const;
450  bool Internal_ReadV5( ON_BinaryArchive& );
451 
452 protected:
453  void Internal_Destroy();
454  void Internal_Copy(
455  const ON_WindowsBitmap& src
456  );
457 };
459 /*
460 Description:
461  ON_WindowsBitmapEx is identical to ON_WindowsBitmap except that
462  it's Read/Write functions save bitmap names.
463 */
464 class ON_CLASS ON_WindowsBitmapEx : public ON_WindowsBitmap
465 {
466  ON_OBJECT_DECLARE(ON_WindowsBitmapEx);
467 public:
468  ON_WindowsBitmapEx() = default;
469  ~ON_WindowsBitmapEx() = default;
470  ON_WindowsBitmapEx(const ON_WindowsBitmapEx&) = default;
472 
473  static const ON_WindowsBitmapEx Unset;
474 
475  bool Write( ON_BinaryArchive& ) const override; // writes compressed image
476  bool Read( ON_BinaryArchive& ) override; // reads compressed image
478 private:
479  bool Internal_WriteV5( ON_BinaryArchive& ) const; // writes compressed image
480  bool Internal_ReadV5( ON_BinaryArchive& ); // reads compressed image
481 };
482 
483 class ON_CLASS ON_EmbeddedBitmap : public ON_Bitmap
484 {
485  ON_OBJECT_DECLARE(ON_EmbeddedBitmap);
486 public:
487  ON_EmbeddedBitmap() = default;
491 
492  static const ON_EmbeddedBitmap Unset;
494  void Create(
495  size_t sizeof_buffer
496  );
497 
498  bool IsValid( class ON_TextLog* text_log = nullptr ) const override;
499 
500  bool Write( ON_BinaryArchive& ) const override;
501  bool Read( ON_BinaryArchive& ) override;
502  unsigned int SizeOf() const override;
503 
504  size_t SizeofImage() const override;
505  unsigned char* Bits(int) override;
506  const unsigned char* Bits(int) const override;
507 
508  const void* m_buffer = nullptr;
509  size_t m_sizeof_buffer = 0;
510  bool m_managed_buffer = false; // true means the ON_EmbeddedBitmap class manages m_buffer memory.
511  ON__UINT32 m_buffer_crc32 = 0; // 32 bit crc from ON_CRC32
512 
513 private:
514  bool Internal_WriteV5( ON_BinaryArchive& ) const;
515  bool Internal_ReadV5( ON_BinaryArchive& );
516 
517 private:
518  void Internal_Destroy();
519  void Internal_Copy(
520  const ON_EmbeddedBitmap& src
521  );
522 };
523 
524 #endif
Definition: opennurbs_bitmap.h:468
The ON_ModelComponent class is a base class for all components in a model and manages the index...
Definition: opennurbs_model_component.h:24
unsigned int SizeOf() const override
void Dump(ON_TextLog &) const override
Creates a text dump of the object.
Definition: opennurbs_array.h:36
bool IsValid(class ON_TextLog *text_log=nullptr) const override
Tests an object to see if its data members are correctly initialized.
Definition: opennurbs_color.h:24
static const ON_Bitmap Unset
Definition: opennurbs_bitmap.h:38
Windows sizeof(ON_WindowsRGBQUAD) = 4.
Definition: opennurbs_bitmap.h:118
Definition: opennurbs_bitmap.h:28
Windows packs BITMAPFILEHEADER.
Definition: opennurbs_bitmap.h:129
static const ON_ModelComponent Unset
Definition: opennurbs_model_component.h:222
Definition: opennurbs_bitmap.h:204
ON_WindowsBitmapEx is identical to ON_WindowsBitmap except that it&#39;s Read/Write functions save bitmap...
Definition: opennurbs_bitmap.h:449
Definition: opennurbs_textlog.h:20
Definition: opennurbs_archive.h:1783
ON_ModelComponent & operator=(const ON_ModelComponent &source)
virtual bool Read(ON_BinaryArchive &binary_archive)
Low level archive writing tool used by ON_BinaryArchive::ReadObject().
Definition: opennurbs_model_component.h:1622
Definition: opennurbs_bitmap.h:226
virtual bool Write(ON_BinaryArchive &binary_archive) const
Low level archive writing tool used by ON_BinaryArchive::WriteObject().
Definition: opennurbs_bitmap.h:141
Definition: opennurbs_file_utilities.h:1125