OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
dib.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectWindows
3// Copyright (c) 1992, 1996 by Borland International, All Rights Reserved
4//
5/// \file
6/// Implementation of TDib class, an encapsulation of Device Independent Bitmaps
7/// on disk and in memory.
8//----------------------------------------------------------------------------
9#include <owl/pch.h>
10
11#include <owl/gdiobjec.h>
12#include <owl/metafile.h>
13#include <owl/clipboar.h>
14#include <owl/except.h>
15#include <owl/file.h>
16#include <owl/wsyscls.h>
17
18#if defined(__BORLANDC__)
19# pragma option -w-ccc // Disable "Condition is always true/false"
20#endif
21
22#define BFT_BITMAP 0x4d42 /* 'BM' */
23
24using namespace std;
25
26namespace owl {
27
29DIAG_DECLARE_GROUP(OwlGDI); // General GDI diagnostic group
30
31//
32// Internal DIB file Read/Write functions talk to this IO implementation
33//
34class TFileIO : public TDib::IFileIn, public TDib::IFileOut {
35 public:
36 TFileIO(TFile& file) : File(file) {}
37
38 virtual long Read(void * buffer, long size)
39 {
40 return File.Read(buffer, size);
41 }
42 virtual void Skip(long size)
43 {
44 File.Seek(size, TFile::cur);
45 }
46 virtual bool Write(void * buffer, long size)
47 {
48 return File.Write(buffer, size);
49 }
50
51 private:
52 TFile& File;
53};
54
55
56//
57/// Given a BITMAPINFOHEADER, allocate a global buffer for Handle & init Info
58//
59void
61{
62 // Allocate & lock down the actual single memory block used by this DIB
63 //
64 int maskAlloc = infoHeader.biCompression==BI_BITFIELDS ? 3*sizeof(uint32) : 0;
65 int colorAlloc = int(infoHeader.biClrUsed * sizeof(RGBQUAD)); // Color table size in mem
66 IsResHandle = false;
67 uint32 size = sizeof(BITMAPINFOHEADER) + maskAlloc + colorAlloc + infoHeader.biSizeImage;
69 if (!Handle)
71
72 // Setup Info ptr & copy over working infoHeader. Finish by using
73 // InfoFromHandle to update all members from Info.
74 //
75 Info = reinterpret_cast<LPBITMAPINFO>(::GlobalLock(Handle));
76 Info->bmiHeader = infoHeader;
77
79}
80
81//
82/// Locks the global/res handle if needed and extracts the pointers and cached info
83/// maintained as member variables from Info.
84///
85/// Needs only Info setup, or if Info is 0 then Handle & IsResHandle setup
86//
87void
89{
90 // Get the BITMAPINFO Info from the handle if needed
91 //
92 if (!Info) {
93 if (IsResHandle)
94 Info = reinterpret_cast<LPBITMAPINFO>(::LockResource(Handle));
95 else
96 Info = reinterpret_cast<LPBITMAPINFO>(::GlobalLock(Handle));
97 if (!Info)
99 }
100
101 // Fail if the header does not look OK
102 //
103 if (Info->bmiHeader.biSize != sizeof(BITMAPINFOHEADER)) {
104 if (!IsResHandle)
107 }
108
109 // Determine if there is a bit mask (used by 16 & 32 bpp bmps) and where
110 // the color table starts
111 //
112 if (Info->bmiHeader.biCompression == BI_BITFIELDS) {
113 Mask = reinterpret_cast<uint32 *>(Info->bmiColors);
114 Colors = reinterpret_cast<TRgbQuad *>(reinterpret_cast<char *>(Info->bmiColors) + 3 * sizeof(uint32));
115 }
116 else {
117 Mask = nullptr;
118 Colors = static_cast<TRgbQuad *>(Info->bmiColors);
119 }
120
121 // Figure out the number of colors in the color table using biClrsUsed &
122 // biBitCount.
123 //
124 NumClrs = Info->bmiHeader.biClrUsed
125 ? Info->bmiHeader.biClrUsed
126 : NColors(Info->bmiHeader.biBitCount);
127
128 Bits = reinterpret_cast<char *>(Colors) + static_cast<int>(NumClrs) * sizeof(RGBQUAD);
129
130 // Zero out Colors if there is no color table.
131 //
132 if (!NumClrs)
133 Colors = nullptr;
134
135 Mode = DIB_RGB_COLORS;
136}
137
138//
139/// Under Win32, resources are read-only. So, to allow for modification of the
140/// Dib, a copy must be made.
141//
142void
144{
145 const char* begin = reinterpret_cast<const char*>(Info);
146 const char* end = static_cast<const char*>(Bits) + Info->bmiHeader.biSizeImage;
147 size_t size = end - begin;
149 if (!tempHandle)
151
153 memcpy(tempInfo, Info, size);
154
155 // Handle will now be a memory handle, & no longer a res handle
156 // Update Bits pointer & other members that may have moved.
157 //
159 Info = reinterpret_cast<LPBITMAPINFO>(tempInfo);
160 IsResHandle = false;
162}
163
164
165//
166/// Creates a TDib object and sets the Handle data member to the given borrowed
167/// handle. The ShouldDelete data member defaults to false, ensuring that the
168/// borrowed handle will not be deleted when the C++ object is destroyed.
169//
171:
173 Info(nullptr), IsResHandle(false)
174{
176}
177
178
179//
180/// Constructs a TDib object with a handle borrowed from the given Clipboard.
181//
182TDib::TDib(const TClipboard& clipboard)
183:
184 TGdiBase(clipboard.GetClipboardData(CF_DIB)),
185 Info(nullptr), IsResHandle(false)
186{
188}
189
190
191//
192/// This public copy constructor creates a complete copy of the given src object as
193/// in:
194/// \code
195/// TDib mySrc = yourSrc;
196/// \endcode
197//
199:
200 IsResHandle(false)
201{
202 PRECONDITION(src.Info != 0);
203
204// long size = ::GlobalSize(src.Handle); // !CQ assumes src has a mem handle
205 uint32 size = src.SizeDib();
207 if (!Handle)
209
210 Info = reinterpret_cast<LPBITMAPINFO>(::GlobalLock(Handle));
211 memcpy(Info, src.Info, size);
212
213 Mask = reinterpret_cast<uint32 *>(src.Mask ?
214 reinterpret_cast<char *>(Info) + (reinterpret_cast<char *>(src.Mask) - reinterpret_cast<char *>(src.Info)) : nullptr);
215 Bits = reinterpret_cast<char *>(Info) + (reinterpret_cast<char *>(src.Bits) - reinterpret_cast<char *>(src.Info));
216
217 NumClrs = src.NumClrs;
218
219 // Zero out Colors if there is no color table.
220 //
221 if (!NumClrs)
222 Colors = nullptr;
223 else
224 Colors = reinterpret_cast<TRgbQuad *>(reinterpret_cast<char *>(Info) + (reinterpret_cast<char *>(src.Colors) - reinterpret_cast<char *>(src.Info)));
225
226 Mode = src.Mode;
227}
228
229
230//
231/// Destruct a TDib by unlocking & freeing its global memory handle as required
232//
234{
235 if (!Handle || IsResHandle) return;
237 if (ShouldDelete)
239}
240
241
242//
243/// Converts the existing color table in place to use palette relative values. The
244/// palette that is passed is used as a reference. Returns true if the call is
245/// successful; otherwise returns false.
246///
247/// Makes sure that color table is RGB
248//
249bool
251{
252 if (Mode != DIB_RGB_COLORS)
253 return false;
254
255 uint16 nEntries = pal.GetNumEntries();
256
257 for (int c = 0; c < NumClrs; c++) {
258 uint16 index = uint16(c);
259 for (uint16 i = 0; i < nEntries; i++) {
260 PALETTEENTRY pe; //getting all entries one time up front would be faster
261 pal.GetPaletteEntry(i, pe);
262 if (pe.peRed == Colors[c].rgbRed &&
263 pe.peGreen == Colors[c].rgbGreen &&
264 pe.peBlue == Colors[c].rgbBlue) {
265 index = i;
266 break;
267 }
268 }
269 (reinterpret_cast<uint16*>(Colors))[c] = index;
270 }
271 Mode = DIB_PAL_COLORS;
272 return true;
273}
274
275
276//
277/// Converts the existing color table in place to use absolute RGB values. The
278/// palette that is passed is used as a reference. Returns true if the call is
279/// successful; otherwise returns false.
280///
281/// Makes sure that color table is pal relative & that there is enough space
282//
283bool
285{
286 if (Mode != DIB_PAL_COLORS ||
287 static_cast<uint>(reinterpret_cast<char*>(Bits) - reinterpret_cast<char*>(Info)) < NumClrs*sizeof(RGBQUAD))
288 return false;
289
290 uint16 nEntries = pal.GetNumEntries();
291
292 for (int c = static_cast<int>(NumClrs)-1; c >= 0; c--) {
293 uint16 i = (reinterpret_cast<uint16*>(Colors))[c];
294 if (i >= nEntries)
295 i = 0;
297 pal.GetPaletteEntry(i, pe);
298 Colors[c].rgbRed = pe.peRed;
299 Colors[c].rgbGreen = pe.peGreen;
300 Colors[c].rgbBlue = pe.peBlue;
301 }
302 Mode = DIB_RGB_COLORS;
303 return true;
304}
305
306
307//
308// Get, set, find and map the color table entries as colors (RGBQUADs)
309
310//
311/// Returns the color for the given palette entry.
312//
313TColor
315{
316 if (entry >= 0 && entry < NumClrs)
317 if (Mode == DIB_RGB_COLORS)
318 return GetColors()[entry];
319
320 return TColor();
321}
322
323
324//
325/// Sets the given color for the given palette entry.
326//
327void
329{
330 if (entry >= 0 && entry < NumClrs)
331 if (Mode == DIB_RGB_COLORS)
332 GetColors()[entry] = color;
333}
334
335
336//
337/// Returns the palette entry for the given color.
338//
339int
341{
342 for (int entry = 0; entry < NumClrs; entry++)
343 if (color == GetColors()[entry]) // Small data model requires this order
344 return entry;
345 return -1;
346}
347
348
349//
350/// Maps the first or all occurances of fromColor to the toColor in the current palette of this DIB.
351/// Returns the palette entry for the given color. Returns the palette entry for the
352/// toColor argument.
353//
354int
356{
357 int count = 0;
358 for (int entry = 0; entry < NumClrs; entry++)
359 if (fromColor == GetColors()[entry]) { // Small data model requires this order
361 count++;
362 if (!mapAll)
363 break;
364 }
365 return count;
366}
367
368
369//
370// Get, set, find and map the color table entries as palette indices
371//
372uint16
374{
375 if (entry >= 0 && entry < NumClrs)
376 if (Mode == DIB_PAL_COLORS)
377 return (reinterpret_cast<const uint16*>(GetColors()))[entry];
378
379 return 0;
380}
381
382
383//
384/// Sets the given index for the given entry.
385//
386void
388{
389 if (entry >= 0 && entry < NumClrs)
390 if (Mode == DIB_PAL_COLORS)
391 (reinterpret_cast<uint16*>(GetColors()))[entry] = index;
392}
393
394
395//
396/// Returns the palette entry corresponding to the given index.
397//
398int
400{
401 for (int entry = 0; entry < NumClrs; entry++)
402 if (GetIndices()[entry] == index)
403 return entry;
404 return -1;
405}
406
407
408//
409/// Maps the fromIndex to the toIndex in the current palette of this DIB.
410/// Returns the palette entry for the toIndex argument.
411//
412int
414{
415 int count = 0;
416 for (int entry = 0; entry < NumClrs; entry++)
417 if (GetIndices()[entry] == fromIndex) {
419 count++;
420 if (!doAll)
421 break;
422 }
423 return count;
424}
425
426
427//
428/// Maps the UI colors to the value specified in the parameter, mapColors, which is
429/// one of the values of the Map enum. Use this function to get the colors for the
430/// face shading on push buttons, the highlighting for a selected control button,
431/// the text on push buttons, the shade of the window frame and the background
432/// color.
433//
434/// Use MapColor to map selected standard UI colors in this DIB to their
435/// current system values. Also can map a background color. Used to update a
436/// UI DIB to current colors before rendering.
437///
438/// - \c \b LtGray -> 3d Face
439/// - \c \b Black -> Button Text
440/// - \c \b Gray -> 3d Shadow
441/// - \c \b White -> 3d Hilight
442/// - \c \b Magenta -> Window Frame
443/// - \c \b LtYellow -> bkColor
444//
445void
467
468
469//
470/// Moves this dib to the clipboard. Ownership of the DIB handle is passed to the
471/// clipboard.
472//
473void
475{
476 if (Handle) {
477 if (IsResHandle) {
478 }
479 else {
481 }
482 clipboard.SetClipboardData(CF_DIB, Handle);
483 ShouldDelete = false;
484 Info = nullptr;
485 Bits = nullptr;
486 Handle = nullptr;
487 }
488}
489
490
491//
492/// Creates a DIB object from the given resource file (.bmp).
493//
499
500//
501/// String-aware overload
502//
508
509
510//
511/// Creates a DIB from the file.
512//
518
519//
520/// Creates a DIB from the file stream.
521//
527
528
529//
530/// Constructs an empty DIB for use by derived classes.
531//
533:
534 Info(nullptr), Mask(nullptr), Colors(nullptr), Bits(nullptr),
535 NumClrs(0),
536 IsResHandle(false)
537{
538 // Handle must be set by derived class
539 // InfoFromHandle() or equivalent must then be called
540}
541
542
543//
544/// Tests if the passed file is a Windows 3.x (or PM 1.x) DIB and if so read it.
545///
546/// Returns true if Dib was read OK.
547//
548bool
550{
552 if (!file.IsOpen()) {
553 TRACEX(OwlGDI, 0, "Cannot open bitmap file '" << name << "' to read");
554 return false;
555 }
556
557 // Read the bitmap in, file header & all
558 //
559 bool ok = Read(file, true);
560
561 file.Close();
562 return ok;
563}
564
565
566//
567/// Read a Windows 3.x or PM 1.x device independent bitmap from a TFile
568/// Return true iff Dib was read OK
569//
570bool
572{
573 TFileIO in(file);
574 return Read(in, readFileHeader);
575}
576
577//
578// The ios version of the DIB read requires large data model since the buffers
579// are quite large.
580//
581
582//
583//
584//
585class TStreamIn : public TDib::IFileIn {
586 public:
587 TStreamIn(istream& is) : Is(is) {}
588
589 virtual long Read(void* buffer, long size)
590 {
591 PRECONDITION(size >= 0);
592 streamsize n = Is.read(static_cast<char*>(buffer), size).gcount();
593
594 // Note: 'n' cannot be larger than 'size'; hence we can cast unchecked.
595 // TODO: Widen the return type to avoid the narrowing cast.
596
597 return static_cast<long>(n);
598 }
599
600 virtual void Skip(long size)
601 {
602 Is.seekg(size, ios::cur);
603 }
604
605 private:
606 istream& Is;
607};
608
609//
610//
611/// Read a Windows 3.0 or PM 1.X device independent bitmap from an istream
612///
613/// Checks header, read Info, palette and bitmap. PM DIBs can be converted to
614/// Win 3.x DIBs on the fly.
615///
616/// Returns true iff DIB was read OK
617//
618bool
620{
621 TStreamIn in(is);
622 return Read(in, readFileHeader);
623}
624
625
626//
627/// Reads a Windows 3.0 or PM 1.X device independent bitmap. (.BMP) from an
628/// implementor of TDib's IFileIn interface
629///
630/// Checks header, read Info, palette and bitmap. PM Dibs are converted to
631/// Windows 3.x Dibs on the fly.
632///
633/// Returns true iff Dib was read OK
634//
635bool
637{
638 long offBits = 0;
639
640 // Read file header and verify the signature. Grab bfOffBits if it is != 0
641 // We ignore all other information in the file header since some applications
642 // do not put correct information in the fields...
643 //
644 if (readFileHeader) {
646 if (static_cast<size_t>(in.Read(&bmf, sizeof(bmf))) != sizeof(bmf) || bmf.bfType != BFT_BITMAP) {
647 TRACEX(OwlGDI, 0, "Not a Windows 3.x or PM 1.x bitmap file");
649 return false;
650 }
651 if (bmf.bfOffBits)
652 offBits = bmf.bfOffBits - sizeof(BITMAPFILEHEADER);
653 }
654
655 // Read bitmap header size & check it. It must be one of the two known header
656 // sizes.
657 // Will add BITMAPV4HEADER support when available
658 //
660 size_t n = static_cast<size_t>(in.Read(&headerSize, sizeof(headerSize)));
661 if (n != sizeof(headerSize) ||
662 (headerSize != sizeof(BITMAPCOREHEADER) && headerSize != sizeof(BITMAPINFOHEADER)))
663 {
664 TRACEX(OwlGDI, 0, "Not a Windows 3.x or PM 1.x bitmap file");
666 return false;
667 }
668
669 // Prepare to build or read a header that is an Info (Windows) type
670 //
672 infoHeader.biSize = sizeof(BITMAPINFOHEADER);
673
674 // If this is a PM 1.x DIB, read the core header & copy over to the Info header
675 //
676 bool isCore = headerSize == sizeof(BITMAPCOREHEADER);
677 if (isCore) {
678 // Read in the rest of the core header, aborting if it is truncated
679 //
681 int size = static_cast<int>(headerSize)-sizeof(uint32);
682 if (in.Read(&coreHeader.bcWidth, size) != size) {
683 TRACEX(OwlGDI, 0, "Invalid PM 1.x DIB Header");
685 return false;
686 }
687
688 // Copy core fields over to info fields, filling in the missing pieces
689 //
690 infoHeader.biWidth = coreHeader.bcWidth;
691 infoHeader.biHeight = coreHeader.bcHeight;
692 infoHeader.biPlanes = coreHeader.bcPlanes;
693 infoHeader.biBitCount = coreHeader.bcBitCount;
694 infoHeader.biCompression = BI_RGB; // No compression
695 infoHeader.biSizeImage = 0; // Calculate this below
696 infoHeader.biXPelsPerMeter = 0; // Zero is OK
697 infoHeader.biYPelsPerMeter = 0; // Zero is OK
698 infoHeader.biClrUsed = 0; // Calculate this below
699 infoHeader.biClrImportant = 0; // Zero is OK
700 }
701 // This is a Win 3.x DIB, read the info header
702 //
703 else {
704 // Read in the rest of the info header, aborting if it is truncated
705 //
706 int size = static_cast<int>(headerSize)-sizeof(uint32);
707 if (in.Read(&infoHeader.biWidth, size) != size) {
708 TRACEX(OwlGDI, 0, "Invalid Win 3.x DIB Header");
710 return false;
711 }
712 }
713
714 // Check number of planes. Windows supports only 1 plane DIBs
715 //
716 if (infoHeader.biPlanes != 1) {
717 TRACEX(OwlGDI, 0, "Invalid number of planes in DIB");
719 return false;
720 }
721
722 // Fill in the default value for biClrsUsed, if not supplied, using the
723 // bit count. Will remain 0 for 16bpp or greater.
724 //
725 if (!infoHeader.biClrUsed)
726 infoHeader.biClrUsed = NColors(infoHeader.biBitCount);
727
728 // Some applications do not fill in the biSizeImage field in the header.
729 // (Actually the truth is more likely that some drivers do not fill the
730 // field in and the apps do not compensate for these buggy drivers.)
731 //
732 // Therefore, if compression was not used, we (re)compute the size,
733 // but if compression is used, we have no choice but to trust the size.
734 //
735 if (infoHeader.biCompression == BI_RGB ||
736 infoHeader.biCompression == BI_BITFIELDS)
737 infoHeader.biSizeImage =
738 ScanBytes(infoHeader.biWidth,
739 infoHeader.biBitCount) * infoHeader.biHeight;
740
741 // Setup all members based on InfoHeader
742 //
744
745 // Read color mask directly into allocated memory
746 //
747 if (Mask) {
748 int size = 3*sizeof(uint32);
749 if (in.Read(reinterpret_cast<char *>(Mask), size) != size) {
750 TRACEX(OwlGDI, 0, "Could not read DIB color mask");
752 return false;
753 }
754 }
755
756 // Read color table directly into allocated memory
757 // Walk backwards & expand to RGBQUADs if it is a PM Core DIB
758 //
759 int colorRead = isCore ? // Color table size on disk
760 static_cast<int>(NumClrs) * sizeof(RGBTRIPLE) :
761 static_cast<int>(NumClrs) * sizeof(RGBQUAD);
762 if (Colors) {
763 if (in.Read(reinterpret_cast<char *>(Colors), colorRead) != colorRead) {
764 TRACEX(OwlGDI, 0, "Could not read DIB color table");
766 return false;
767 }
768 if (isCore) {
769 for (int i = int(NumClrs-1); i >= 0; i--) {
770 Colors[i].rgbRed = (reinterpret_cast<RGBTRIPLE*>(Colors))[i].rgbtRed;
771 Colors[i].rgbGreen = (reinterpret_cast<RGBTRIPLE*>(Colors))[i].rgbtGreen;
772 Colors[i].rgbBlue = (reinterpret_cast<RGBTRIPLE*>(Colors))[i].rgbtBlue;
773 Colors[i].rgbReserved = 0;
774 }
775 }
776 }
777
778 // Locate & Read Bits, skipping Pad if any.
779 // Ignore offBits if it is zero, or if less than the current position--it's
780 // probably bad
781 //
782 if (offBits && offBits - static_cast<long>(headerSize+colorRead) > 0)
783 in.Skip(offBits - (headerSize+colorRead));
784 if (!in.Read(Bits, infoHeader.biSizeImage)) {
785 TRACEX(OwlGDI, 0, "Could not read DIB bits");
786 return false;
787 }
788
789 return true;
790}
791
792
793//
794/// Creates a TDib given a module instance and a resource name or int Id
795//
797:
798 Info(nullptr), Mask(nullptr), Colors(nullptr), Bits(nullptr),
799 NumClrs(0),
800 IsResHandle(false)
801{
804}
805
806
807//
808/// Loads this DIB from the given resource and returns true if successful.
809//
810bool
812{
814
815 // First, load the resource into a global memory block.
816 //
817 HRSRC resHandle = ::FindResource(instance, resId, RT_BITMAP);
819 if (!Handle) {
820 TRACEX(OwlGDI, 0, "Cannot access bitmap resource");
821 return false;
822 }
823 IsResHandle = true;
824
825 // Then update our pointers & other info.
826 //
828
829 // Under Win32, resources are read-only. So, to allow for later modification
830 // of the Dib, a copy must be made.
831 //
832 // Could postpone this until dib needed to be written on...
833 //
835
836 return true;
837}
838
839
840//
841/// Writes the DIB into an external file.
842///
843/// Returns true if the call is successful; otherwise returns false.
844//
845bool
847{
849
850 if (!file.IsOpen()) {
851 TRACEX(OwlGDI, 0, "Cannot open bitmap file '" << name << "' to write");
852 return false;
853 }
854
855 bool ok = Write(file, true);
856
857 file.Close();
858 if (!ok) {
859 TRACEX(OwlGDI, 0, "Disk error writing file '" << name << "'");
860 return false;
861 }
862 return true;
863}
864
865
866//
867/// Write this DIB to a file object.
868//
869bool
871{
872 TFileIO out(file);
873 return Write(out, writeFileHeader);
874}
875
876//
877// The ios version of the DIB read requires large data model since the buffers
878// are quite large.
879//
880
881
882//
883//
884//
885class TStreamOut : public TDib::IFileOut {
886 public:
887 TStreamOut( ostream& os) : Os(os) {}
888
889 virtual bool Write(void * buffer, long size)
890 {
891 return Os.write(reinterpret_cast<char*>(buffer), size).good();
892 }
893 private:
894 ostream& Os;
895};
896
897//
898/// Writes this DIB to an ostream.
899//
900bool
902{
903 TStreamOut out(os);
904 return Write(out, writeFileHeader);
905}
906
907
908//
909/// Writes the DIB into a file stream.
910//
911bool
913{
914 size_t size = ::GlobalSize(Handle);
915
916 // Write file header.
917 //
918 if (writeFileHeader)
919 {
920 size_t bfSize = size + sizeof(BITMAPFILEHEADER);
922 return false;
923
924 const char* begin = reinterpret_cast<const char*>(Info);
925 const char* end = static_cast<const char*>(Bits) + sizeof(BITMAPFILEHEADER);
926 size_t bfOffBits = end - begin;
928 return false;
929
931 bmf.bfType = BFT_BITMAP;//'BM';
932 bmf.bfSize = static_cast<DWORD>(bfSize);
933 bmf.bfReserved1 = 0;
934 bmf.bfReserved2 = 0;
935 bmf.bfOffBits = static_cast<DWORD>(bfOffBits);
936 if (!out.Write(&bmf, sizeof(bmf)))
937 return false;
938 }
939
940 // Write rest of dib, including dib header, color table & bits.
941 //
942 if (!IsRepresentable<long>(size))
943 return false;
944 if (!out.Write(Info, static_cast<long>(size))) // TODO: Widen parameter type to avoid this narrowing cast.
945 return false;
946
947 return true;
948}
949
950
951//
952/// Creates a DIB object with the given width, height, number of colors, mode
953/// values.
954//
955TDib::TDib(int width, int height, uint32 nColors, uint16 mode)
956{
957 PRECONDITION(width && height && nColors);
958
960 infoHeader.biSize = sizeof(BITMAPINFOHEADER);
961 infoHeader.biWidth = width;
962 infoHeader.biHeight = height;
963 infoHeader.biPlanes = 1;
964 infoHeader.biBitCount = NBits(nColors);
965 infoHeader.biCompression = BI_RGB;
966 uint32 bytes = ScanBytes(width, infoHeader.biBitCount);
967 infoHeader.biSizeImage = bytes * height;
968 infoHeader.biXPelsPerMeter = 0;
969 infoHeader.biYPelsPerMeter = 0;
970 infoHeader.biClrUsed = infoHeader.biBitCount > 8 ? 0 : nColors;
971 infoHeader.biClrImportant = 0;
972
973 // Setup all members based on infoHeader
974 //
976
977 // Initialize the color table--either Palette or RGB
978 //
979 Mode = mode;
980 if (Mode == DIB_PAL_COLORS) {
981 // Generate a 1:1 palette relative color table- it can later be translated
982 // to RGB given a palette.
983 //
984 for (uint i = 0; i < nColors; i++)
985 (reinterpret_cast<uint16*>(Colors))[i] = static_cast<uint16>(i);
986 }
987 else if(nColors){
988 // Get the system palette and convert to RGB quad format if exist support.
989 //
990 TScreenDC dc;
992 uint clrCnt = ::GetSystemPaletteEntries(dc, 0, nColors, reinterpret_cast<LPPALETTEENTRY>(Colors));
993 for (uint32 i = 0; i < clrCnt; i++) {
994 Swap(Colors[i].rgbRed, Colors[i].rgbBlue);
995 Colors[i].rgbReserved = 0;
996 }
997 }
998 }
999}
1000
1001
1002//
1003/// Creates a DIB object from the given resource bitmap and palette. If pal is 0
1004/// (the default), the default palette is used.
1005//
1007{
1008 BITMAP bm;
1009 bitmap.GetObject(bm);
1010
1012 infoHeader.biSize = sizeof(BITMAPINFOHEADER);
1013 infoHeader.biWidth = bm.bmWidth;
1014 infoHeader.biHeight = bm.bmHeight;
1015 infoHeader.biPlanes = 1;
1017 if (palette) {
1018 palette->GetObject(nColors);
1019 infoHeader.biBitCount = NBits(nColors);
1020 }
1021 else {
1022 infoHeader.biBitCount = uint16(bm.bmBitsPixel*bm.bmPlanes);
1023 nColors = static_cast<uint16>(NColors(infoHeader.biBitCount));
1024 }
1025 infoHeader.biCompression = BI_RGB;
1026 infoHeader.biSizeImage = ScanBytes(infoHeader.biWidth,
1027 infoHeader.biBitCount) * infoHeader.biHeight;
1028 infoHeader.biXPelsPerMeter = 0;
1029 infoHeader.biYPelsPerMeter = 0;
1030 infoHeader.biClrUsed = nColors;
1031 infoHeader.biClrImportant = 0;
1032
1033 // Setup all members based on infoHeader
1034 //
1036
1037 // Copy pixels from given bitmap into our new empty DIB, selecting palette
1038 // if provided
1039 //
1040 TScreenDC dc;
1041 if (palette)
1042 dc.SelectObject(*palette, false);
1043 dc.GetDIBits(bitmap, StartScan(), NumScans(), Bits, *Info, Usage());
1044}
1045
1046
1047//
1048/// Modifies this DIB so that the pixels and color table coincide with a given
1049/// palette.
1050/// !CQ 8bpp only!
1051//
1052void
1054{
1055 // Create a mapping from our current color table to the target palette
1056 //
1057 uint8 map[256];
1058 for (int i = 0; i < 256; i++)
1059 map[i] = static_cast<uint8>(pal.GetNearestPaletteIndex(GetColor(i)));
1060
1061 // Use the map to translate all of the pixels into indexes in the target
1062 // palette
1063 //
1064 uint8 * bits = reinterpret_cast<uint8 *>(GetBits());
1065 long size = Pitch() * Height();
1066 while (size--) {
1067 *bits = map[*bits];
1068 bits++;
1069 }
1070
1071 // Now copy the target palette into our color table
1072 //
1073 PALETTEENTRY pe[256];
1074 pal.GetPaletteEntries(0, 256, pe);
1076 for (int j = 0; j < 256; j++) {
1077 colorTab->rgbRed = pe[j].peRed;
1078 colorTab->rgbGreen = pe[j].peGreen;
1079 colorTab->rgbBlue = pe[j].peBlue;
1080 colorTab++;
1081 }
1082}
1083
1084
1085} // OWL namespace
1086
#define PRECONDITION(condition)
Definition checks.h:227
#define DIAG_DECLARE_GROUP(group)
Definition checks.h:404
#define TRACEX(group, level, message)
Definition checks.h:263
TBitmap is the GDI bitmap class derived from TGdiObject.
Definition gdiobjec.h:510
The clipboard class encapsulates the methods for the clipboard object of Windows.
Definition clipboar.h:32
HANDLE SetClipboardData(uint format, HANDLE handle)
Copy the data onto the clipboard in the format.
Definition clipboar.h:282
Class wrapper for management of color values.
Definition color.h:245
static const TColor LtMagenta
Static TColor object with fixed Value set by RGB(255, 0, 255).
Definition color.h:312
static const TColor SysBtnText
The symbolic system color value for the text on buttons.
Definition color.h:342
static const TColor Sys3dHilight
The symbolic system color value for highlighted 3-dimensional display elements (for edges facing the ...
Definition color.h:344
static const TColor SysWindowFrame
The symbolic system color value for the frame around each window.
Definition color.h:330
static const TColor LtYellow
Static TColor object with fixed Value set by RGB(255, 255, 0).
Definition color.h:310
static const TColor LtGray
Static TColor object with fixed Value set by RGB(192, 192, 192).
Definition color.h:306
static const TColor Sys3dShadow
The symbolic system color value for the shadow regions of 3-dimensional display elements (for edges f...
Definition color.h:340
static const TColor Sys3dFace
The symbolic system color value for the face color of 3-dimensional display elements.
Definition color.h:339
static const TColor Gray
Static TColor object with fixed Value set by RGB(128, 128, 128).
Definition color.h:307
static const TColor White
Static TColor object with fixed Value set by RGB(255, 255, 255).
Definition color.h:314
static const TColor SysWindow
The symbolic system color value for the background of each window.
Definition color.h:329
static const TColor Black
Static TColor object with fixed Value set by RGB(0, 0, 0).
Definition color.h:305
virtual int GetDeviceCaps(int index) const
Used under WIN3.1 or later, GetDeviceCaps returns capability information about this DC.
Definition dc.cpp:373
void SelectObject(const TBrush &brush)
Selects the given GDI brush object into this DC.
Definition dc.cpp:113
int GetDIBits(const TBitmap &bitmap, uint startScan, uint numScans, void *bits, const BITMAPINFO &info, uint16 usage)
The first version retrieves some or all of the bits from the given bitmap on this DC and copies them ...
Definition dc.h:2668
Internal DIB file Reda/Write functions talk to these interfaces.
Definition gdiobjec.h:923
Pseudo-GDI object Device Independent Bitmap (DIB) class.
Definition gdiobjec.h:795
uint NumScans() const
Returns the number of scans in this DIB.
Definition gdiobjec.h:1926
TColor GetColor(int entry) const
Returns the color for the given palette entry.
Definition dib.cpp:314
uint16 Usage() const
Returns the Mode for this DIB.
Definition gdiobjec.h:1954
const uint16 * GetIndices() const
Returns the bmiColors indexes of this DIB.
Definition gdiobjec.h:1711
uint16 GetIndex(int entry) const
Definition dib.cpp:373
int FindIndex(uint16 index)
Returns the palette entry corresponding to the given index.
Definition dib.cpp:399
@ MapHighlight
Definition gdiobjec.h:913
bool Write(TFile &file, bool writeFileHeader=false)
Write this DIB to a file object.
Definition dib.cpp:870
void MapUIColors(uint mapColors, const TColor *bkColor=nullptr)
Maps the UI colors to the value specified in the parameter, mapColors, which is one of the values of ...
Definition dib.cpp:446
bool Read(TFile &file, bool readFileHeader=false)
Read a Windows 3.x or PM 1.x device independent bitmap from a TFile Return true iff Dib was read OK.
Definition dib.cpp:571
void ResToMemHandle()
Under Win32, resources are read-only.
Definition dib.cpp:143
int FindColor(const TColor &color)
Returns the palette entry for the given color.
Definition dib.cpp:340
bool WriteFile(const tstring &filename)
Writes the DIB into an external file.
Definition dib.cpp:846
void SetColor(int entry, const TColor &color)
Sets the given color for the given palette entry.
Definition dib.cpp:328
bool LoadResource(HINSTANCE, TResId)
Loads this DIB from the given resource and returns true if successful.
Definition dib.cpp:811
int MapColor(const TColor &fromColor, const TColor &toColor, bool doAll=false)
Maps the first or all occurances of fromColor to the toColor in the current palette of this DIB.
Definition dib.cpp:355
int MapIndex(uint16 fromIndex, uint16 toIndex, bool doAll=false)
Maps the fromIndex to the toIndex in the current palette of this DIB.
Definition dib.cpp:413
bool ReadFile(const tstring &name)
Tests if the passed file is a Windows 3.x (or PM 1.x) DIB and if so read it.
Definition dib.cpp:549
int Pitch() const
Size of scan in bytes = Pixel Width * bits per pixel rounded up to a uint32 boundary.
Definition gdiobjec.h:1882
TDib()
Protected ctor- derived classes need to fill in handle & get info.
Definition dib.cpp:532
void MapToPalette(const TPalette &pal)
Modifies this DIB so that the pixels and color table coincide with a given palette.
Definition dib.cpp:1053
void ToClipboard(TClipboard &clipboard)
Moves this dib to the clipboard.
Definition dib.cpp:474
static int ScanBytes(long w, int bpp)
Width+bpp to dword aligned bytes.
Definition gdiobjec.h:1865
bool ChangeModeToRGB(const TPalette &pal)
Converts the existing color table in place to use absolute RGB values.
Definition dib.cpp:284
int Height() const
Returns the height of the DIB.
Definition gdiobjec.h:1840
void InfoFromHeader(const BITMAPINFOHEADER &infoHeader)
Given a BITMAPINFOHEADER, allocate a global buffer for Handle & init Info.
Definition dib.cpp:60
void SetIndex(int entry, uint16 index)
Sets the given index for the given entry.
Definition dib.cpp:387
bool ShouldDelete
Should object delete GDI handle in dtor?
Definition gdibase.h:82
virtual ~TDib()
Destruct a TDib by unlocking & freeing its global memory handle as required.
Definition dib.cpp:233
uint StartScan() const
Returns the starting scan line.
Definition gdiobjec.h:1916
HANDLE Handle
GDI handle of this object.
Definition gdibase.h:81
void InfoFromHandle()
Locks the global/res handle if needed and extracts the pointers and cached info maintained as member ...
Definition dib.cpp:88
bool ChangeModeToPal(const TPalette &pal)
Converts the existing color table in place to use palette relative values.
Definition dib.cpp:250
const void * GetBits() const
Returns the Bits data member for this DIB.
Definition gdiobjec.h:1727
const TRgbQuad * GetColors() const
Returns the bmiColors value of this DIB.
Definition gdiobjec.h:1695
The TFile class encapsulates standard file characteristics and operations.
Definition file.h:120
virtual uint64 Seek(int64 offset, TSeekDir origin=beg)
Repositions the file pointer to offset bytes from the specified origin.
Definition file.h:875
@ ReadOnly
Definition file.h:130
@ WriteOnly
Definition file.h:131
@ OpenExisting
Opens the file. The function fails if the file does not exist.
Definition file.h:151
@ PermExclusive
Definition file.h:141
@ CreateAlways
Creates a new file. The function overwrites the file if it exists.
Definition file.h:148
virtual uint32 Read(void *buffer, uint32 numBytes)
Reads numBytes from the file into buffer. The number of bytes read is returned.
Definition file.h:805
virtual bool Write(const void *buffer, uint32 numBytes)
Writes numbytes of buffer to the file.
Definition file.h:813
@ cur
Seek from the current position in the file.
Definition file.h:124
Root and abstract class for Windows object wrappers.
Definition gdibase.h:79
TPalette is the GDI Palette class derived from TGdiObject.
Definition gdiobjec.h:413
Wrapper for Windows' RBGQUAD type.
Definition color.h:433
Derived from TWindowDC, TScreenDC is a DC class that provides direct access to the screen bitmap.
Definition dc.h:610
static void Raise()
Construct a TXBadFormat exception from scratch, and throws it.
Definition file.cpp:62
static void Raise(uint resId=IDS_GDIFAILURE, HANDLE handle=0)
Throws the exception.
Definition gdibase.cpp:112
Definition of classes for clipboard Encapsulation.
#define BFT_BITMAP
Definition dib.cpp:22
Definition of abstract GDI object class and derived classes.
TAutoDelete
Flag for Handle ctors to control Handle deletion in dtor.
Definition gdibase.h:70
static void Raise()
Construct a TXOutOfMemory exception from scratch, and throw it.
Definition except.cpp:301
Definition of TMetafilePict, a MetaFile wrapper class.
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
long NColors(uint16 bitCount)
Functions to convert number of bits to number of palette colors and back, and build an RGB COLORREF.
Definition color.cpp:188
unsigned long uint32
Definition number.h:34
uint16 NBits(long colors)
Return the number of bits required to represent a given number of colors.
Definition color.cpp:201
OWL_DIAGINFO
Definition animctrl.cpp:14
unsigned short uint16
Definition number.h:33
std::string tstring
Definition defs.h:79
unsigned int uint
Definition number.h:25
ObjectWindows exception class & function definitions.
void Swap(T &a, T &b)
Definition defs.h:365
Classes for window system structure and type encapsulation.