00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015
00016
00017 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00018
00019 ON_VIRTUAL_OBJECT_IMPLEMENT( ON_Bitmap, ON_Object, "390465E9-3721-11d4-800B-0010830122F0")
00020 ;
00021
00022 ON_OBJECT_IMPLEMENT( ON_WindowsBitmap, ON_Bitmap, "390465EB-3721-11d4-800B-0010830122F0")
00023 ;
00024
00025 ON_OBJECT_IMPLEMENT( ON_EmbeddedBitmap, ON_Bitmap, "772E6FC1-B17B-4fc4-8F54-5FDA511D76D2")
00026 ;
00027
00028 ON_OBJECT_IMPLEMENT( ON_WindowsBitmapEx, ON_WindowsBitmap, "203AFC17-BCC9-44fb-A07B-7F5C31BD5ED9")
00029 ;
00030
00031 void
00032 ON_Bitmap::EmergencyDestroy ()
00033 {
00034 memset (&m_bitmap_id, 0, sizeof(m_bitmap_id));
00035 m_bitmap_index = -1;
00036 m_bitmap_name.EmergencyDestroy ();
00037 m_bitmap_filename.EmergencyDestroy ();
00038 }
00039
00040 void
00041 ON_Bitmap::Destroy ()
00042 {
00043 m_bitmap_name.Destroy ();
00044 m_bitmap_filename.Destroy ();
00045 ON_Bitmap::EmergencyDestroy ();
00046 }
00047
00048 void
00049 ON_Bitmap::Defaults ()
00050 {
00051 memset (&m_bitmap_id, 0, sizeof(m_bitmap_id));
00052 m_bitmap_index = -1;
00053 m_bitmap_name.Destroy ();
00054 m_bitmap_filename.Destroy ();
00055 }
00056
00057 ON_Bitmap::ON_Bitmap ()
00058 {
00059 memset (&m_bitmap_id, 0, sizeof(m_bitmap_id));
00060 m_bitmap_index = -1;
00061 }
00062
00063 ON_Bitmap::~ON_Bitmap ()
00064 {
00065 }
00066
00067 void
00068 ON_Bitmap::Dump (ON_TextLog& dump) const
00069 {
00070 dump.Print ("width = %d pixels\n", Width ());
00071 dump.Print ("height = %d pixels\n", Height ());
00072 dump.Print ("bits per pixel = %d\n", BitsPerPixel ());
00073 dump.Print ("size of image = %d bytes\n", SizeofImage ());
00074 }
00075
00076 static
00077 int
00078 ON_WindowsBitmapHelper_PaletteColorCount (int bmiHeader_biClrUsed, int bmiHeader_biBitCount)
00079 {
00080 int color_count = 0;
00081
00082 if (bmiHeader_biClrUsed)
00083 {
00084 color_count = bmiHeader_biClrUsed;
00085 }
00086 else
00087 {
00088 switch (bmiHeader_biBitCount)
00089 {
00090 case 1:
00091 color_count = 2;
00092 break;
00093 case 4:
00094 color_count = 16;
00095 break;
00096 case 8:
00097 color_count = 256;
00098 break;
00099 default:
00100 color_count = 0;
00101 break;
00102 }
00103 }
00104 return color_count;
00105 }
00106
00107 static size_t
00108 ON_WindowsBitmapHelper_SizeofPalette (int bmiHeader_biClrUsed, int bmiHeader_biBitCount)
00109 {
00110 #if defined(ON_OS_WINDOWS_GDI)
00111 return ( ON_WindowsBitmapHelper_PaletteColorCount(bmiHeader_biClrUsed,bmiHeader_biBitCount) * sizeof(RGBQUAD) );
00112 #else
00113 return (ON_WindowsBitmapHelper_PaletteColorCount (bmiHeader_biClrUsed, bmiHeader_biBitCount)
00114 * sizeof(ON_WindowsRGBQUAD));
00115 #endif
00116 }
00117
00118 ON_WindowsBitmap::ON_WindowsBitmap () :
00119 m_bmi (0), m_bits (0), m_bFreeBMI (0)
00120 {
00121 }
00122
00123 ON_WindowsBitmap::ON_WindowsBitmap (const ON_WindowsBitmap& src) :
00124 m_bmi (0), m_bits (0), m_bFreeBMI (0)
00125 {
00126 *this = src;
00127 }
00128
00129 void
00130 ON_WindowsBitmap::EmergencyDestroy ()
00131 {
00132 m_bmi = 0;
00133 m_bits = 0;
00134 m_bFreeBMI = 0;
00135 ON_Bitmap::EmergencyDestroy ();
00136 }
00137
00138 void
00139 ON_WindowsBitmap::Destroy ()
00140 {
00141 if (m_bmi)
00142 {
00143 if (1 == m_bFreeBMI || 3 == m_bFreeBMI)
00144 onfree (m_bmi);
00145 m_bmi = 0;
00146 }
00147 if (m_bits)
00148 {
00149 if (2 == m_bFreeBMI || 3 == m_bFreeBMI)
00150 onfree (m_bits);
00151 m_bits = 0;
00152 }
00153 m_bFreeBMI = 0;
00154 ON_Bitmap::Destroy ();
00155 }
00156
00157 ON_BOOL32
00158 ON_WindowsBitmap::IsValid (ON_TextLog* text_log) const
00159 {
00160 bool rc = (m_bmi != NULL && m_bits != NULL && Width () > 0 && Height () > 0) ? true : false;
00161
00162 if (!rc && 0 != text_log)
00163 {
00164
00165 text_log->Print ("ON_WindowsBitmap is not valid\n");
00166 }
00167 return rc;
00168 }
00169
00170 #if defined(ON_OS_WINDOWS_GDI)
00171
00172 static BITMAPINFO*
00173 ON_WindowsBitmapHelper_AllocBMI(size_t sizeof_palette, size_t sizeof_image)
00174 {
00175
00176
00177
00178
00179 size_t sz = sizeof(BITMAPINFO) + sizeof_palette + sizeof_image;
00180 BITMAPINFO* bmi = (BITMAPINFO*)onmalloc(sz);
00181 if ( bmi )
00182 {
00183 memset(bmi,0,sizeof(*bmi));
00184 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
00185 }
00186 return bmi;
00187 }
00188
00189 #else
00190
00191 static ON_WindowsBITMAPINFO*
00192 ON_WindowsBitmapHelper_AllocBMI (size_t sizeof_palette, size_t sizeof_image)
00193 {
00194 size_t sz = sizeof(ON_WindowsBITMAPINFO) + sizeof_palette + sizeof_image;
00195 ON_WindowsBITMAPINFO* bmi = (ON_WindowsBITMAPINFO*)onmalloc (sz);
00196 if (bmi)
00197 {
00198 memset (bmi, 0, sizeof(*bmi));
00199 bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
00200 }
00201 return bmi;
00202 }
00203
00204 #endif
00205
00206 bool
00207 ON_WindowsBitmap::Create (int width, int height, int bits_per_pixel
00208 )
00209 {
00210 Destroy ();
00211
00212 if (width < 1 || height < 1)
00213 {
00214 return false;
00215 }
00216 if (bits_per_pixel != 1 && bits_per_pixel != 2 && bits_per_pixel != 4 && bits_per_pixel != 8 && bits_per_pixel != 16
00217 && bits_per_pixel != 24 && bits_per_pixel != 32)
00218 {
00219 return false;
00220 }
00221
00222 #if defined(ON_OS_WINDOWS_GDI)
00223 BITMAPINFOHEADER bh;
00224 const DWORD sizeof_RGBQUAD = sizeof(RGBQUAD);
00225 #else
00226 ON_WindowsBITMAPINFOHEADER bh;
00227 const unsigned int sizeof_RGBQUAD = sizeof(ON_WindowsRGBQUAD);
00228 #endif
00229 memset (&bh, 0, sizeof(bh));
00230 bh.biSize = sizeof(bh);
00231 bh.biWidth = width;
00232 bh.biHeight = height;
00233 bh.biPlanes = 1;
00234 bh.biBitCount = (unsigned short)bits_per_pixel;
00235 bh.biCompression = 0;
00236 const int sizeof_scan = (((bits_per_pixel * width) + 31) / 32) * 4;
00237 bh.biSizeImage = height * sizeof_scan;
00238 bh.biXPelsPerMeter = 0;
00239 bh.biYPelsPerMeter = 0;
00240 bh.biClrUsed = 0;
00241 bh.biClrImportant = 0;
00242
00243 int palette_color_count = 0;
00244 switch (bits_per_pixel)
00245 {
00246 case 1:
00247 palette_color_count = 2;
00248 break;
00249 case 4:
00250 palette_color_count = 16;
00251 break;
00252 case 8:
00253 palette_color_count = 256;
00254 break;
00255 }
00256 const int sizeof_palette = palette_color_count * sizeof_RGBQUAD;
00257
00258 m_bmi = ON_WindowsBitmapHelper_AllocBMI (sizeof_palette, bh.biSizeImage);
00259
00260 bool rc = false;
00261
00262 if (m_bmi )
00263 {
00264 m_bmi->bmiHeader = bh;
00265 m_bits = (unsigned char*)&m_bmi->bmiColors[palette_color_count];
00266
00267
00268 if (palette_color_count > 0)
00269 {
00270 const int rgb_delta = 256 / palette_color_count;
00271 int i, rgb;
00272 for (i = 0, rgb = 0; i < palette_color_count; i++, rgb += rgb_delta)
00273 {
00274 if (rgb >= 256)
00275 rgb = 255;
00276 m_bmi->bmiColors[i].rgbBlue = (unsigned char)rgb;
00277 m_bmi->bmiColors[i].rgbGreen = (unsigned char)rgb;
00278 m_bmi->bmiColors[i].rgbRed = (unsigned char)rgb;
00279 m_bmi->bmiColors[i].rgbReserved = 0;
00280 }
00281 }
00282 rc = true;
00283 }
00284
00285 return rc;
00286 }
00287
00288 ON_WindowsBitmap::~ON_WindowsBitmap ()
00289 {
00290 Destroy ();
00291 }
00292
00293 ON_WindowsBitmap&
00294 ON_WindowsBitmap::operator= (const ON_WindowsBitmap& src)
00295 {
00296 if (this != &src)
00297 {
00298 Destroy ();
00299 ON_Bitmap::operator= (src);
00300 if (src.m_bmi)
00301 {
00302 const int sizeof_palette = src.SizeofPalette ();
00303 const int sizeof_image = src.SizeofImage ();
00304 m_bmi = ON_WindowsBitmapHelper_AllocBMI (sizeof_palette, sizeof_image);
00305 if (m_bmi)
00306 {
00307 m_bFreeBMI = 1;
00308 m_bmi->bmiHeader = src.m_bmi->bmiHeader;
00309 if (sizeof_palette > 0)
00310 {
00311 memcpy (&m_bmi->bmiColors[0], &src.m_bmi->bmiColors[0], sizeof_palette);
00312 }
00313 if (sizeof_image > 0)
00314 {
00315 m_bits = (unsigned char*)&m_bmi->bmiColors[PaletteColorCount ()];
00316 if (src.m_bits)
00317 memcpy (m_bits, src.m_bits, sizeof_image);
00318 else
00319 memset (m_bits, 0, sizeof_image);
00320 }
00321 else
00322 m_bits = 0;
00323 }
00324 }
00325 }
00326 return *this;
00327 }
00328
00329 int
00330 ON_WindowsBitmap::Width () const
00331 {
00332 return (m_bmi) ? m_bmi->bmiHeader.biWidth : 0;
00333 }
00334
00335 int
00336 ON_WindowsBitmap::Height () const
00337 {
00338 return (m_bmi) ? m_bmi->bmiHeader.biHeight : 0;
00339 }
00340
00341 int
00342 ON_WindowsBitmap::PaletteColorCount () const
00343 {
00344 return m_bmi ? ON_WindowsBitmapHelper_PaletteColorCount (m_bmi->bmiHeader.biClrUsed, m_bmi->bmiHeader.biBitCount) : 0;
00345 }
00346
00347 int
00348 ON_WindowsBitmap::SizeofPalette () const
00349 {
00350 return m_bmi ? ((int)ON_WindowsBitmapHelper_SizeofPalette (m_bmi->bmiHeader.biClrUsed, m_bmi->bmiHeader.biBitCount))
00351 : 0;
00352 }
00353
00354 int
00355 ON_WindowsBitmap::SizeofScan () const
00356 {
00357 int scan_width = 0;
00358 if (m_bmi)
00359 {
00360 int bitcount = m_bmi->bmiHeader.biBitCount;
00361 int width = Width ();
00362 scan_width = (((bitcount * width) + 31) / 32) * 4;
00363 }
00364 return scan_width;
00365 }
00366
00367 int
00368 ON_WindowsBitmap::BitsPerPixel () const
00369 {
00370 return m_bmi ? m_bmi->bmiHeader.biBitCount : 0;
00371 }
00372
00373 int
00374 ON_WindowsBitmap::SizeofImage () const
00375 {
00376 return m_bmi ? m_bmi->bmiHeader.biSizeImage : 0;
00377 }
00378
00379 unsigned char*
00380 ON_WindowsBitmap::Bits (int scan_index)
00381 {
00382 const int sizeof_scan = SizeofScan ();
00383 unsigned char* bits = m_bmi ? (unsigned char*)&m_bmi->bmiColors[PaletteColorCount ()] : 0;
00384 if (bits && sizeof_scan && scan_index >= 0 && scan_index < Height ())
00385 {
00386 bits += (sizeof_scan * scan_index);
00387 }
00388 else
00389 {
00390 bits = 0;
00391 }
00392 return bits;
00393 }
00394
00395 const unsigned char*
00396 ON_WindowsBitmap::Bits (int scan_index) const
00397 {
00398 const int sizeof_scan = SizeofScan ();
00399 const unsigned char* bits = m_bmi ? (const unsigned char*)&m_bmi->bmiColors[PaletteColorCount ()] : 0;
00400 if (bits && sizeof_scan && scan_index >= 0 && scan_index < Height ())
00401 {
00402 bits += (sizeof_scan * scan_index);
00403 }
00404 else
00405 {
00406 bits = 0;
00407 }
00408 return bits;
00409 }
00410
00411 ON_Color
00412 ON_WindowsBitmap::Pixel (int column_index, int row_index) const
00413 {
00414 return Pixel (column_index, Bits (row_index));
00415 }
00416
00417 ON_Color
00418 ON_WindowsBitmap::Pixel (int column_index, const unsigned char* scanbits) const
00419 {
00420 int r = 0, g = 0, b = 0, a = 0;
00421
00422 unsigned int palindex;
00423
00424 if (m_bmi && column_index >= 0 && column_index <= Width () && scanbits && !m_bmi->bmiHeader.biCompression)
00425 {
00426 switch (m_bmi->bmiHeader.biBitCount)
00427 {
00428 case 32:
00429 scanbits += (column_index * 4);
00430 b = *scanbits++;
00431 g = *scanbits++;
00432 r = *scanbits++;
00433 a = *scanbits;
00434 break;
00435
00436 case 24:
00437 scanbits += (column_index * 3);
00438 b = *scanbits++;
00439 g = *scanbits++;
00440 r = *scanbits;
00441 break;
00442
00443 case 8:
00444
00445 palindex = scanbits[column_index];
00446 b = m_bmi->bmiColors[palindex].rgbBlue;
00447 g = m_bmi->bmiColors[palindex].rgbGreen;
00448 r = m_bmi->bmiColors[palindex].rgbRed;
00449 a = m_bmi->bmiColors[palindex].rgbReserved;
00450 break;
00451
00452 case 4:
00453 {
00454
00455 palindex = scanbits[column_index / 2];
00456 if (!(column_index % 2))
00457 palindex >>= 4;
00458 palindex &= 0x0F;
00459 b = m_bmi->bmiColors[palindex].rgbBlue;
00460 g = m_bmi->bmiColors[palindex].rgbGreen;
00461 r = m_bmi->bmiColors[palindex].rgbRed;
00462 a = m_bmi->bmiColors[palindex].rgbReserved;
00463 }
00464 break;
00465
00466 case 1:
00467
00468 palindex = (scanbits[column_index / 8] >> (7 - (column_index % 8))) & 0x01;
00469 b = m_bmi->bmiColors[palindex].rgbBlue;
00470 g = m_bmi->bmiColors[palindex].rgbGreen;
00471 r = m_bmi->bmiColors[palindex].rgbRed;
00472 a = m_bmi->bmiColors[palindex].rgbReserved;
00473 break;
00474 }
00475 }
00476
00477 return ON_Color (r, g, b, a);
00478 }
00479
00480 bool
00481 ON_WindowsBitmap::WriteUncompressed (ON_BinaryArchive& file) const
00482 {
00483 #if defined(ON_OS_WINDOWS_GDI)
00484 BITMAPINFOHEADER bmiHeader;
00485 #else
00486 ON_WindowsBITMAPINFOHEADER bmiHeader;
00487 #endif
00488
00489 if (m_bmi)
00490 {
00491 bmiHeader = m_bmi->bmiHeader;
00492 bmiHeader.biSize = sizeof(bmiHeader);
00493 }
00494 else
00495 {
00496 memset (&bmiHeader, 0, sizeof(bmiHeader));
00497 }
00498 int i;
00499 short s;
00500 i = bmiHeader.biSize;
00501 bool rc = file.WriteInt (i);
00502 i = bmiHeader.biWidth;
00503 if (rc)
00504 rc = file.WriteInt (i);
00505 i = bmiHeader.biHeight;
00506 if (rc)
00507 rc = file.WriteInt (i);
00508 s = bmiHeader.biPlanes;
00509 if (rc)
00510 rc = file.WriteShort (s);
00511 s = bmiHeader.biBitCount;
00512 if (rc)
00513 rc = file.WriteShort (s);
00514 i = bmiHeader.biCompression;
00515 if (rc)
00516 rc = file.WriteInt (i);
00517 i = bmiHeader.biSizeImage;
00518 if (rc)
00519 rc = file.WriteInt (i);
00520 i = bmiHeader.biXPelsPerMeter;
00521 if (rc)
00522 rc = file.WriteInt (i);
00523 i = bmiHeader.biYPelsPerMeter;
00524 if (rc)
00525 rc = file.WriteInt (i);
00526 i = bmiHeader.biClrUsed;
00527 if (rc)
00528 rc = file.WriteInt (i);
00529 i = bmiHeader.biClrImportant;
00530 if (rc)
00531 rc = file.WriteInt (i);
00532
00533 if (rc)
00534 {
00535 const int color_count = PaletteColorCount ();
00536 for (i = 0; i < color_count && rc; i++)
00537 {
00538 if (rc)
00539 rc = file.WriteChar (m_bmi->bmiColors[i].rgbBlue);
00540 if (rc)
00541 rc = file.WriteChar (m_bmi->bmiColors[i].rgbGreen);
00542 if (rc)
00543 rc = file.WriteChar (m_bmi->bmiColors[i].rgbRed);
00544 if (rc)
00545 rc = file.WriteChar (m_bmi->bmiColors[i].rgbReserved);
00546 }
00547 const int sizeof_image = SizeofImage ();
00548 if (sizeof_image > 0 && rc)
00549 {
00550 if (rc)
00551 rc = file.WriteByte (sizeof_image, &m_bmi->bmiColors[color_count]);
00552 }
00553 }
00554
00555 return rc;
00556 }
00557
00558 bool
00559 ON_WindowsBitmap::ReadUncompressed (ON_BinaryArchive& file)
00560 {
00561 #if defined(ON_OS_WINDOWS_GDI)
00562 BITMAPINFOHEADER bmiHeader;
00563 #else
00564 ON_WindowsBITMAPINFOHEADER bmiHeader;
00565 #endif
00566 memset (&bmiHeader, 0, sizeof(bmiHeader));
00567
00568 Destroy ();
00569
00570 int i;
00571 short s;
00572 bool rc;
00573
00574 for (;;)
00575 {
00576 i = 0;
00577 s = 0;
00578 rc = file.ReadInt (&i);
00579 if (!rc)
00580 break;
00581 bmiHeader.biSize = i;
00582 rc = file.ReadInt (&i);
00583 if (!rc)
00584 break;
00585 bmiHeader.biWidth = i;
00586 rc = file.ReadInt (&i);
00587 if (!rc)
00588 break;
00589 bmiHeader.biHeight = i;
00590 rc = file.ReadShort (&s);
00591 if (!rc)
00592 break;
00593 bmiHeader.biPlanes = s;
00594 rc = file.ReadShort (&s);
00595 if (!rc)
00596 break;
00597 bmiHeader.biBitCount = s;
00598 rc = file.ReadInt (&i);
00599 if (!rc)
00600 break;
00601 bmiHeader.biCompression = i;
00602 rc = file.ReadInt (&i);
00603 if (!rc)
00604 break;
00605 bmiHeader.biSizeImage = i;
00606 rc = file.ReadInt (&i);
00607 if (!rc)
00608 break;
00609 bmiHeader.biXPelsPerMeter = i;
00610 rc = file.ReadInt (&i);
00611 if (!rc)
00612 break;
00613 bmiHeader.biYPelsPerMeter = i;
00614 rc = file.ReadInt (&i);
00615 if (!rc)
00616 break;
00617 bmiHeader.biClrUsed = i;
00618 rc = file.ReadInt (&i);
00619 if (!rc)
00620 break;
00621 bmiHeader.biClrImportant = i;
00622 break;
00623 }
00624
00625 if (rc)
00626 {
00627 bmiHeader.biSize = sizeof(bmiHeader);
00628 const size_t sizeof_palette = ON_WindowsBitmapHelper_SizeofPalette (bmiHeader.biClrUsed, bmiHeader.biBitCount);
00629 const size_t sizeof_image = bmiHeader.biSizeImage;
00630
00631 m_bmi = ON_WindowsBitmapHelper_AllocBMI (sizeof_palette, sizeof_image);
00632
00633 if (!m_bmi)
00634 {
00635 rc = false;
00636 }
00637 else
00638 {
00639 m_bFreeBMI = 1;
00640 m_bmi->bmiHeader = bmiHeader;
00641 const int color_count = ON_WindowsBitmapHelper_PaletteColorCount (bmiHeader.biClrUsed, bmiHeader.biBitCount);
00642 int i;
00643 for (i = 0; i < color_count && rc; i++)
00644 {
00645 if (rc)
00646 rc = file.ReadChar (&m_bmi->bmiColors[i].rgbBlue);
00647 if (rc)
00648 rc = file.ReadChar (&m_bmi->bmiColors[i].rgbGreen);
00649 if (rc)
00650 rc = file.ReadChar (&m_bmi->bmiColors[i].rgbRed);
00651 if (rc)
00652 rc = file.ReadChar (&m_bmi->bmiColors[i].rgbReserved);
00653 }
00654 if (sizeof_image > 0 && rc)
00655 {
00656 m_bits = (unsigned char*)&m_bmi->bmiColors[color_count];
00657 if (rc)
00658 rc = file.ReadByte (sizeof_image, m_bits);
00659 }
00660 }
00661 }
00662 return rc;
00663 }
00664
00665 ON_BOOL32
00666 ON_WindowsBitmap::Write (ON_BinaryArchive& file) const
00667 {
00668 return WriteCompressed (file);
00669 }
00670
00671 ON_BOOL32
00672 ON_WindowsBitmap::Read (ON_BinaryArchive& file)
00673 {
00674 bool rc = false;
00675 if (file.Archive3dmVersion () == 1)
00676 rc = ReadUncompressed (file);
00677 else
00678 rc = ReadCompressed (file);
00679 return rc;
00680 }
00681
00682 ON_WindowsBitmapEx::ON_WindowsBitmapEx ()
00683 {
00684 }
00685
00686 ON_WindowsBitmapEx::~ON_WindowsBitmapEx ()
00687 {
00688 }
00689
00690 ON_BOOL32
00691 ON_WindowsBitmapEx::Write (ON_BinaryArchive& file) const
00692 {
00693 ON_BOOL32 rc = file.Write3dmChunkVersion (1, 0);
00694 if (rc)
00695 rc = file.WriteString (m_bitmap_filename);
00696 if (rc)
00697 rc = ON_WindowsBitmap::WriteCompressed (file);
00698 return rc;
00699 }
00700
00701 ON_BOOL32
00702 ON_WindowsBitmapEx::Read (ON_BinaryArchive& file)
00703 {
00704 int major_version = 0;
00705 int minor_version = 0;
00706 ON_BOOL32 rc = file.Read3dmChunkVersion (&major_version, &minor_version);
00707 if (rc && 1 == major_version)
00708 {
00709
00710
00711
00712
00713 ON_wString bitmap_filename;
00714 if (rc)
00715 rc = file.ReadString (bitmap_filename);
00716 if (!rc)
00717 bitmap_filename.Destroy ();
00718
00719 if (rc)
00720 rc = ON_WindowsBitmap::ReadCompressed (file);
00721
00722 m_bitmap_filename = bitmap_filename;
00723 }
00724 else
00725 rc = false;
00726 return rc;
00727 }
00728
00729 bool
00730 ON_WindowsBitmap::WriteCompressed (ON_BinaryArchive& file) const
00731 {
00732 int color_count = 0;
00733 int sizeof_palette = 0;
00734 int sizeof_image = 0;
00735 bool bContiguousBitmap = IsContiguous ();
00736 #if defined(ON_OS_WINDOWS_GDI)
00737 BITMAPINFOHEADER bmiHeader;
00738 #else
00739 ON_WindowsBITMAPINFOHEADER bmiHeader;
00740 #endif
00741 if (m_bmi)
00742 {
00743 bmiHeader = m_bmi->bmiHeader;
00744 color_count = PaletteColorCount ();
00745 sizeof_palette = color_count * sizeof(*m_bmi->bmiColors);
00746 sizeof_image = SizeofImage ();
00747 if (0 == sizeof_image)
00748 bContiguousBitmap = true;
00749 }
00750 else
00751 {
00752 bContiguousBitmap = true;
00753 color_count = 0;
00754 sizeof_palette = 0;
00755 sizeof_image = 0;
00756 memset (&bmiHeader, 0, sizeof(bmiHeader));
00757 }
00758 int i;
00759 short s;
00760 i = bmiHeader.biSize;
00761 bool rc = file.WriteInt (i);
00762 i = bmiHeader.biWidth;
00763 if (rc)
00764 rc = file.WriteInt (i);
00765 i = bmiHeader.biHeight;
00766 if (rc)
00767 rc = file.WriteInt (i);
00768 s = bmiHeader.biPlanes;
00769 if (rc)
00770 rc = file.WriteShort (s);
00771 s = bmiHeader.biBitCount;
00772 if (rc)
00773 rc = file.WriteShort (s);
00774 i = bmiHeader.biCompression;
00775 if (rc)
00776 rc = file.WriteInt (i);
00777 i = bmiHeader.biSizeImage;
00778 if (rc)
00779 rc = file.WriteInt (i);
00780 i = bmiHeader.biXPelsPerMeter;
00781 if (rc)
00782 rc = file.WriteInt (i);
00783 i = bmiHeader.biYPelsPerMeter;
00784 if (rc)
00785 rc = file.WriteInt (i);
00786 i = bmiHeader.biClrUsed;
00787 if (rc)
00788 rc = file.WriteInt (i);
00789 i = bmiHeader.biClrImportant;
00790 if (rc)
00791 rc = file.WriteInt (i);
00792
00793 if (rc)
00794 {
00795 if (bContiguousBitmap)
00796 {
00797 const int sizeof_buffer = sizeof_palette + sizeof_image;
00798
00799 rc = file.WriteCompressedBuffer (sizeof_buffer, (0 != m_bmi) ? m_bmi->bmiColors : 0);
00800 }
00801 else
00802 {
00803
00804
00805
00806 rc = file.WriteCompressedBuffer (sizeof_palette, m_bmi->bmiColors);
00807 if (rc)
00808 {
00809
00810 rc = file.WriteCompressedBuffer (sizeof_image, m_bits);
00811 }
00812 }
00813 }
00814
00815 return rc;
00816 }
00817
00818 bool
00819 ON_WindowsBitmap::ReadCompressed (ON_BinaryArchive& file)
00820 {
00821 ON_BOOL32 bFailedCRC = false;
00822 Destroy ();
00823 #if defined(ON_OS_WINDOWS_GDI)
00824 BITMAPINFOHEADER bmiHeader;
00825 #else
00826 ON_WindowsBITMAPINFOHEADER bmiHeader;
00827 #endif
00828 memset (&bmiHeader, 0, sizeof(bmiHeader));
00829 int i;
00830 short s;
00831 bool rc;
00832
00833 for (;;)
00834 {
00835 i = 0;
00836 s = 0;
00837 rc = file.ReadInt (&i);
00838 if (!rc)
00839 break;
00840 bmiHeader.biSize = i;
00841 rc = file.ReadInt (&i);
00842 if (!rc)
00843 break;
00844 bmiHeader.biWidth = i;
00845 rc = file.ReadInt (&i);
00846 if (!rc)
00847 break;
00848 bmiHeader.biHeight = i;
00849 rc = file.ReadShort (&s);
00850 if (!rc)
00851 break;
00852 bmiHeader.biPlanes = s;
00853 rc = file.ReadShort (&s);
00854 if (!rc)
00855 break;
00856 bmiHeader.biBitCount = s;
00857 rc = file.ReadInt (&i);
00858 if (!rc)
00859 break;
00860 bmiHeader.biCompression = i;
00861 rc = file.ReadInt (&i);
00862 if (!rc)
00863 break;
00864 bmiHeader.biSizeImage = i;
00865 rc = file.ReadInt (&i);
00866 if (!rc)
00867 break;
00868 bmiHeader.biXPelsPerMeter = i;
00869 rc = file.ReadInt (&i);
00870 if (!rc)
00871 break;
00872 bmiHeader.biYPelsPerMeter = i;
00873 rc = file.ReadInt (&i);
00874 if (!rc)
00875 break;
00876 bmiHeader.biClrUsed = i;
00877 rc = file.ReadInt (&i);
00878 if (!rc)
00879 break;
00880 bmiHeader.biClrImportant = i;
00881 break;
00882 }
00883
00884 if (rc)
00885 {
00886 bmiHeader.biSize = sizeof(bmiHeader);
00887 const size_t sizeof_palette = ON_WindowsBitmapHelper_SizeofPalette (bmiHeader.biClrUsed, bmiHeader.biBitCount);
00888 const size_t sizeof_image = bmiHeader.biSizeImage;
00889 m_bmi = ON_WindowsBitmapHelper_AllocBMI (sizeof_palette, sizeof_image);
00890 if (!m_bmi)
00891 {
00892 rc = false;
00893 }
00894 else
00895 {
00896 m_bFreeBMI = 1;
00897 m_bmi->bmiHeader = bmiHeader;
00898 m_bmi->bmiHeader.biSize = sizeof(m_bmi->bmiHeader);
00899 const int color_count = ON_WindowsBitmapHelper_PaletteColorCount (bmiHeader.biClrUsed, bmiHeader.biBitCount);
00900 if (sizeof_image > 0)
00901 m_bits = (unsigned char*)&m_bmi->bmiColors[color_count];
00902 size_t sizeof_buffer = 0;
00903 rc = file.ReadCompressedBufferSize (&sizeof_buffer);
00904 if (rc)
00905 {
00906 const size_t sizeof_colors = color_count * sizeof(*m_bmi->bmiColors);
00907 if (sizeof_buffer == sizeof_colors || sizeof_buffer == sizeof_colors + sizeof_image)
00908 {
00909
00910 rc = file.ReadCompressedBuffer (sizeof_buffer, m_bmi->bmiColors, &bFailedCRC);
00911 if (rc && sizeof_image > 0 && sizeof_buffer == sizeof_colors)
00912 {
00913
00914
00915 sizeof_buffer = 0;
00916 rc = file.ReadCompressedBufferSize (&sizeof_buffer);
00917 if (rc)
00918 {
00919 if (sizeof_buffer == sizeof_image)
00920 {
00921
00922 rc = file.ReadCompressedBuffer (sizeof_buffer, &m_bmi->bmiColors[color_count], &bFailedCRC);
00923 }
00924 else
00925 {
00926 ON_ERROR("ON_WindowsBitmap::ReadCompressed() image bits buffer size mismatch\n");
00927 rc = false;
00928 }
00929 }
00930 }
00931 }
00932 else
00933 {
00934 ON_ERROR("ON_WindowsBitmap::ReadCompressed() buffer size mismatch\n");
00935 rc = false;
00936 }
00937 }
00938 }
00939 }
00940 return rc;
00941 }
00942
00943 bool
00944 ON_WindowsBitmap::IsContiguous () const
00945 {
00946 bool rc = false;
00947 if (0 != m_bmi && 0 != m_bits && m_bmi->bmiHeader.biSizeImage > 0)
00948 {
00949
00950 unsigned char* p1 = (unsigned char*)&m_bmi->bmiColors[PaletteColorCount ()];
00951 rc = (m_bits == p1);
00952 }
00953 return rc;
00954 }
00955
00956 #if defined(ON_OS_WINDOWS_GDI)
00957
00958 #pragma message( " --- OpenNURBS including Windows BITMAPINFO support in ON_WindowsBitmap" )
00959
00960 ON_WindowsBitmap::ON_WindowsBitmap( const BITMAPINFO& src )
00961 : m_bmi(0), m_bits(0), m_bFreeBMI(0)
00962 {
00963 *this = src;
00964 }
00965
00966 ON_WindowsBitmap& ON_WindowsBitmap::operator=( const BITMAPINFO& src )
00967 {
00968 Destroy();
00969 int color_count = ON_WindowsBitmapHelper_PaletteColorCount(src.bmiHeader.biClrUsed, src.bmiHeader.biBitCount );
00970 Create(&src,(const unsigned char*)(&src.bmiColors[color_count]),true);
00971 return *this;
00972 }
00973
00974 bool ON_WindowsBitmap::Create( const BITMAPINFO* bmi, const unsigned char* bits, bool bCopy )
00975 {
00976 bool rc = false;
00977 Destroy();
00978 m_bFreeBMI = 0;
00979 m_bmi = 0;
00980 m_bits = 0;
00981
00982 if ( 0 != bmi )
00983 {
00984 if ( bCopy )
00985 {
00986
00987 const size_t sizeof_palette = ON_WindowsBitmapHelper_SizeofPalette(bmi->bmiHeader.biClrUsed, bmi->bmiHeader.biBitCount );
00988 const int sizeof_image = bmi->bmiHeader.biSizeImage;
00989 m_bmi = ON_WindowsBitmapHelper_AllocBMI( sizeof_palette, (bCopy?sizeof_image:0) );
00990 if ( 0 != m_bmi )
00991 {
00992 rc = true;
00993 m_bFreeBMI = 1;
00994 m_bmi->bmiHeader = bmi->bmiHeader;
00995 m_bmi->bmiHeader.biSize = sizeof(m_bmi->bmiHeader);
00996 int color_count = ON_WindowsBitmapHelper_PaletteColorCount(bmi->bmiHeader.biClrUsed, bmi->bmiHeader.biBitCount );
00997 if ( color_count > 0 )
00998 {
00999 memcpy( &m_bmi->bmiColors[0], &bmi->bmiColors[0], color_count*sizeof(m_bmi->bmiColors[0]) );
01000 }
01001 if ( bCopy && sizeof_image > 0 )
01002 {
01003 m_bits = (unsigned char*)(&m_bmi->bmiColors[color_count]);
01004 if ( 0 != bits )
01005 memcpy( m_bits, bits, sizeof_image );
01006 else
01007 memset( m_bits, 0, sizeof_image );
01008 }
01009 }
01010 }
01011 else
01012 {
01013
01014 rc = true;
01015 m_bmi = const_cast<BITMAPINFO*>(bmi);
01016 m_bits = const_cast<unsigned char*>(bits);
01017 }
01018 }
01019
01020 return rc;
01021 }
01022
01023 ON_WindowsBitmap::ON_WindowsBitmap( const BITMAPINFO* src )
01024 : m_bmi(0), m_bits(0), m_bFreeBMI(0)
01025 {
01026 if ( 0 != src )
01027 {
01028 int color_count = ON_WindowsBitmapHelper_PaletteColorCount(src->bmiHeader.biClrUsed, src->bmiHeader.biBitCount );
01029 Create(src,(const unsigned char*)(&src->bmiColors[color_count]),false);
01030 }
01031 }
01032
01033
01034
01035
01036
01037
01038 #endif
01039
01041
01042
01043
01044
01045 ON_EmbeddedBitmap::ON_EmbeddedBitmap ()
01046 {
01047 m_buffer = 0;
01048 m_sizeof_buffer = 0;
01049 m_free_buffer = 0;
01050 m_biffer_crc32 = 0;
01051 }
01052
01053 ON_EmbeddedBitmap::~ON_EmbeddedBitmap ()
01054 {
01055 Destroy ();
01056 }
01057
01058 void
01059 ON_EmbeddedBitmap::EmergencyDestroy ()
01060 {
01061 m_buffer = 0;
01062 m_sizeof_buffer = 0;
01063 m_free_buffer = 0;
01064 m_biffer_crc32 = 0;
01065 ON_Bitmap::EmergencyDestroy ();
01066 }
01067
01068 void
01069 ON_EmbeddedBitmap::Destroy ()
01070 {
01071 if (0 != m_buffer && 1 == m_free_buffer)
01072 {
01073 onfree (m_buffer);
01074 m_buffer = 0;
01075 }
01076 m_sizeof_buffer = 0;
01077 m_free_buffer = 0;
01078 m_biffer_crc32 = 0;
01079 ON_Bitmap::Destroy ();
01080 }
01081
01082 void
01083 ON_EmbeddedBitmap::Create (int sizeof_buffer)
01084 {
01085 Destroy ();
01086 if (sizeof_buffer > 0)
01087 {
01088 m_buffer = onmalloc (sizeof_buffer);
01089 if (0 != m_buffer)
01090 {
01091 m_sizeof_buffer = sizeof_buffer;
01092 m_free_buffer = 1;
01093 }
01094 }
01095 }
01096
01097 ON_BOOL32
01098 ON_EmbeddedBitmap::IsValid (ON_TextLog* text_log) const
01099 {
01100 if (0 == m_buffer)
01101 {
01102 if (0 != text_log)
01103 text_log->Print ("ON_EmbeddedBitmap m_buffer = 0\n");
01104 return false;
01105 }
01106 return true;
01107 }
01108
01109 ON_BOOL32
01110 ON_EmbeddedBitmap::Write (ON_BinaryArchive& file) const
01111 {
01112 ON_BOOL32 rc = file.Write3dmChunkVersion (1, 0);
01113 if (rc)
01114 rc = file.WriteString (m_bitmap_filename);
01115 if (rc)
01116 rc = file.WriteInt (m_biffer_crc32);
01117 int i = 1;
01118 if (rc)
01119 rc = file.WriteInt (i);
01120 switch (i)
01121 {
01122 case 0:
01123 if (rc)
01124 rc = file.WriteSize (m_sizeof_buffer);
01125 if (rc)
01126 rc = file.WriteByte (m_sizeof_buffer, m_buffer);
01127 break;
01128 case 1:
01129 if (rc)
01130 rc = file.WriteCompressedBuffer (m_sizeof_buffer, m_buffer);
01131 break;
01132 }
01133 return rc;
01134 }
01135
01136 ON_BOOL32
01137 ON_EmbeddedBitmap::Read (ON_BinaryArchive& file)
01138 {
01139 ON_BOOL32 bFailedCRC = false;
01140 Destroy ();
01141
01142 int major_version = 0;
01143 int minor_version = 0;
01144 ON_BOOL32 rc = file.Read3dmChunkVersion (&major_version, &minor_version);
01145 if (rc && 1 == major_version)
01146 {
01147 int i = -1;
01148 if (rc)
01149 rc = file.ReadString (m_bitmap_filename);
01150 if (rc)
01151 rc = file.ReadInt (&m_biffer_crc32);
01152 rc = file.ReadInt (&i);
01153 if (rc)
01154 {
01155 switch (i)
01156 {
01157 case 0:
01158 if (rc)
01159 {
01160 if (rc)
01161 rc = file.ReadSize (&m_sizeof_buffer);
01162 if (rc && m_sizeof_buffer > 0)
01163 {
01164 m_buffer = onmalloc (m_sizeof_buffer);
01165 m_free_buffer = 1;
01166 }
01167 if (rc)
01168 rc = file.ReadByte (m_sizeof_buffer, m_buffer);
01169 }
01170 break;
01171 case 1:
01172 if (rc)
01173 {
01174 if (rc)
01175 rc = file.ReadCompressedBufferSize (&m_sizeof_buffer);
01176 if (rc && m_sizeof_buffer > 0)
01177 {
01178 m_buffer = onmalloc (m_sizeof_buffer);
01179 m_free_buffer = 1;
01180 }
01181 if (rc)
01182 rc = file.ReadCompressedBuffer (m_sizeof_buffer, m_buffer, &bFailedCRC);
01183 }
01184 break;
01185 }
01186 }
01187 }
01188 else
01189 rc = false;
01190
01191 return rc;
01192 }
01193
01194 int
01195 ON_EmbeddedBitmap::Width () const
01196 {
01197 return 0;
01198 }
01199 int
01200 ON_EmbeddedBitmap::Height () const
01201 {
01202 return 0;
01203 }
01204 int
01205 ON_EmbeddedBitmap::BitsPerPixel () const
01206 {
01207 return 0;
01208 }
01209 int
01210 ON_EmbeddedBitmap::SizeofScan () const
01211 {
01212 return 0;
01213 }
01214 int
01215 ON_EmbeddedBitmap::SizeofImage () const
01216 {
01217 return 0;
01218 }
01219 unsigned char*
01220 ON_EmbeddedBitmap::Bits (int)
01221 {
01222 return 0;
01223 }
01224 const unsigned char*
01225 ON_EmbeddedBitmap::Bits (int) const
01226 {
01227 return 0;
01228 }
01229