OWLNext    7.0
Borland's Object Windows Library for the modern age
Loading...
Searching...
No Matches
palette.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 TPalette, an encapsulation of the GDI Palette object
7//----------------------------------------------------------------------------
8#include <owl/pch.h>
9#include <owl/defs.h>
10#include <owl/gdiobjec.h>
11#include <owl/clipboar.h>
12#include <owl/file.h>
13#include <owl/filename.h>
14#include <memory.h>
15
16
17#if defined(__BORLANDC__)
18# pragma option -w-ccc // Disable "Condition is always true/false"
19#endif
20
21using namespace std;
22
23namespace owl {
24
26DIAG_DECLARE_GROUP(OwlGDI); // General GDI diagnostic group
27DIAG_DECLARE_GROUP(OwlGDIOrphan); // Orphan control tracing group
28
29//
30// Constructors
31//
32
33//
34/// Alias an existing palette handle. Assume ownership if autoDelete says so
35//
36/// Creates a TPalette object and sets the Handle data member to the given borrowed
37/// handle. The ShouldDelete data member defaults to false, ensuring that the
38/// borrowed handle will not be deleted when the C++ object is destroyed.
39//
47
48//
49/// Creates a TPalette object with values taken from the given clipboard.
50//
52:
53 TGdiObject(clipboard.GetClipboardData(CF_PALETTE))
54{
55 WARNX(OwlGDI, !Handle, 0, "Cannot create TPalette from the clipboard");
56 CheckValid();
59}
60
61//
62/// This public copy constructor creates a complete copy of the given palette object
63/// as in TPalette myPalette = yourPalette;
64//
65/// Always performs full, deep object copy
66//
68{
70 src.GetObject(nColors);
71 if (nColors) {
72 LOGPALETTE* logPal = reinterpret_cast<LOGPALETTE*>( new
73 uint8[sizeof(LOGPALETTE)+(nColors-1)*sizeof(PALETTEENTRY)]);
74
75 logPal->palVersion = 0x300; // !CQ check to see if we should use 0x400
76 logPal->palNumEntries = nColors;
77 src.GetPaletteEntries(0, nColors, logPal->palPalEntry);
79 delete[] logPal;
80 }
81 else
82 Handle = nullptr; // Force a failure
83
84 WARNX(OwlGDI, !Handle, 0, "Cannot create palette from palette " << static_cast<void*>(src.GetHandle()));
85 CheckValid();
87}
88
89//
90/// Creates a TPalette object from the given LOGPALETTE.
91//
93{
95 WARNX(OwlGDI, !Handle, 0, "Cannot create palette from LOGPALETTE @" << static_cast<const void*>(&logPalette));
96 CheckValid();
98}
99
100#if defined(OWL5_COMPAT)
101
102//
103/// Creates a TPalette object from the given LOGPALETTE.
104/// This overload is deprecated. Use the overload that takes a reference instead.
105//
107{
110 WARNX(OwlGDI, !Handle, 0, "Cannot create palette from LOGPALETTE @" << static_cast<const void*>(logPalette));
111 CheckValid();
113}
114
115#endif
116
117//
118/// Creates a TPalette object with count entries from the given entries array.
119//
121{
122 Init(entries, count);
123}
124
125//
126// Initializes a TPalette object with count entries from the given entries array.
127//
128void TPalette::Init(const PALETTEENTRY* entries, int count)
129{
130 LOGPALETTE* logPal = reinterpret_cast<LOGPALETTE*>(new uint8[
131 sizeof(LOGPALETTE)+(count-1)*sizeof(PALETTEENTRY) ]);
132
133 logPal->palVersion = 0x300;
134 logPal->palNumEntries = static_cast<uint16>(count);
135 memcpy(logPal->palPalEntry, entries, count*sizeof(PALETTEENTRY));
137 delete[] logPal;
138
139 WARNX(OwlGDI, !Handle, 0, "Cannot create palette from " << count <<
140 "palette entries @" << static_cast<const void*>(entries));
141 CheckValid();
143}
144
145//
146/// Creates a TPalette object from the color table following the given BITMAPINFO
147/// structure. This constructor works only for 2-color, 16-color, and 256-color
148/// bitmaps. A handle with value 0 (zero) is returned for other bitmaps, including
149/// 24-bit DIBs.
150//
152{
153 Create(&info, flags);
154}
155
156#if defined(OWL5_COMPAT)
157
158//
159/// Creates a TPalette object from the color table following the given BITMAPINFO
160/// structure. This constructor works only for 2-color, 16-color, and 256-color
161/// bitmaps. A handle with value 0 (zero) is returned for other bitmaps, including
162/// 24-bit DIBs.
163/// This overload is deprecated. Use the overload that takes a reference instead.
164//
166{
167 Create(info, flags);
168}
169
170#endif
171
172//
173/// Creates a TPalette object from the given DIB object. The flags argument
174/// represents the values of the LOGPALETTE data structure used to create the
175/// palette.
176//
178{
179 Create(dib.GetInfo(), flags);
180}
181
182//
183/// Read from file: *.dib,*.bmp,*.pal,*.aco,*.act
184//
186{
188 Handle = nullptr;
189
190 Read(fileName);
191
192 WARNX(OwlGDI, !Handle, 0, "Cannot create palette from file: " << fileName);
193
195 ShouldDelete = true;
197}
198
199//
200/// Accept a pointer to a BITMAPINFO structure and create a GDI logical
201/// palette from the color table which follows it, for 2, 16 and 256 color
202/// bitmaps. Fail for all others, including 24-bit DIB's
203///
204/// !CQ Don't fail for other formats!?
205//
206void
208{
210 const RGBQUAD * rgb = info->bmiColors;
211
212 // if the ClrUsed field of the header is non-zero,
213 // it means that we could have have a short color table.
214 //
215 uint16 nColors = uint16(info->bmiHeader.biClrUsed ?
216 info->bmiHeader.biClrUsed :
217 NColors(info->bmiHeader.biBitCount));
218
219 if (nColors) {
220 LOGPALETTE* logPal = reinterpret_cast<LOGPALETTE*>(
221 new uint8[sizeof(LOGPALETTE) + (nColors-1)*sizeof(PALETTEENTRY)]);
222
223 logPal->palVersion = 0x300; // Windows 3.0 version
224 logPal->palNumEntries = nColors;
225 for (uint16 n = 0; n < nColors; n++) {
226 logPal->palPalEntry[n].peRed = rgb[n].rgbRed;
227 logPal->palPalEntry[n].peGreen = rgb[n].rgbGreen;
228 logPal->palPalEntry[n].peBlue = rgb[n].rgbBlue;
229 logPal->palPalEntry[n].peFlags = static_cast<uint8>(flags);
230 }
232 delete[] logPal;
233 }
234 else
235 Handle = nullptr;
236
237 WARNX(OwlGDI, !Handle, 0, "Cannot create palette from bitmapinfo @" << static_cast<const void*>(info));
238 CheckValid();
240}
241
242//
243/// Moves this palette to the target Clipboard argument. If a copy is to be put on
244/// the Clipboard, use TPalette(myPalette).ToClipboard; to make a copy first. The
245/// handle in the temporary copy of the object is moved to the clipboard.
246/// ToClipboard sets ShouldDelete to false so that the object on the clipboard is
247/// not deleted. The handle will still be available for examination.
248//
249void
251{
252 if (Handle) {
254 ShouldDelete = false; // GDI object now owned by Clipboard
256 }
257}
258
259//
260/// Read palette from file
261//
262bool
264{
266 if (!file.IsOpen())
267 return false;
268
269 const tchar* lp = _tcsrchr(filename, _T('.'));
270 if(lp){
271 if(_tcsicmp(lp, _T(".pal"))==0) // check extension
272 return Read_PAL(file);
273 else if(_tcsicmp(lp,_T(".aco"))==0)
274 return Read_ACO(file);
275 else if(_tcsicmp(lp,_T(".act"))==0)
276 return Read_ACT(file);
277 else if(_tcsicmp(lp,_T(".bmp"))==0)
278 return Read_BMP(file);
279 else if(_tcsicmp(lp,_T(".dib"))==0)
280 return Read_BMP(file);
281 }
282 return false;
283}
284
285//
286/// Write this palette into file: *.dib,*.bmp,*.pal,*.aco,*.act
287//
288bool
290{
292 if (!file.IsOpen())
293 return false;
294
295 bool bOk = false;
296 const tchar* lp = _tcsrchr(filename, _T('.'));
297 if(lp){
298 if(_tcsicmp(lp, _T(".pal"))==0) // check extension
299 bOk = Write_PAL(file);
300 else if(_tcsicmp(lp, _T(".aco"))==0)
301 bOk = Write_ACO(file);
302 else if(_tcsicmp(lp, _T(".act"))==0)
303 bOk = Write_ACT(file);
304 else if(_tcsicmp(lp, _T(".bmp"))==0)
305 bOk = Write_BMP(file);
306 else if(_tcsicmp(lp, _T(".dib"))==0)
307 bOk = Write_BMP(file);
308 }
309 if(!bOk)
311
312 return bOk;
313}
314//------------------------------------------------------------------------------
315static TBinField PALHDR_Fields[] = {
316 {varSHORT,2, 1}, /* uint16 Version; */
317 {varSHORT,2, 1}, /* uint16 Count; */
318 {varEnd, 0, 0},
319};
320
321//
322/// read Microsoft *.pal format, return true if success
323//
324bool
326{
327 // Check whether it's a RIFF PAL file.
329 ckFile.Type = owlFCC('P','A','L',' ');
330 if(!file.Descent(ckFile, nullptr, TRiffFile::ffFindRiff)) {
331 WARNX(OwlGDI, 1, 0, "TPalette::Read_PAL() Not a RIFF or PAL file");
333 return false;
334 }
335 // Find the 'data' chunk.
337 ckChunk.CkId = owlFCC('d','a','t','a');
338 if (!file.Descent(ckChunk, &ckFile, TRiffFile::ffFindChunk)) {
339 WARNX(OwlGDI, 1, 0, "TPalette::Read_PAL() No data chunk in file");
341 return false;
342 }
343 // Allocate some memory for the data chunk.
344 int iSize = static_cast<int>(ckChunk.Size);
345 TAPointer<char> pdata(new char[iSize]);
347 // Read the data chunk.
348 if(!file.ReadStruct((char*)pLogPal, PALHDR_Fields, boLittle_Endian)){
349 WARNX(OwlGDI, 1, 0, "TPalette::Read_PAL() Failed to PAL Colors, line" << __LINE__);
350 return false;
351 }
352 uint count = (iSize - sizeof(uint16)*2);
353 if (file.Read(pLogPal->palPalEntry, count) == TFILE_ERROR) {
354 WARNX(OwlGDI, 1, 0, "TPalette::Read_PAL() Failed to PAL Colors, line" << __LINE__);
355 return false;
356 }
357 // The data chunk should be a LOGPALETTE structure
358 // that we can create a palette from.
359 if (pLogPal->palVersion != 0x300) {
360 WARNX(OwlGDI, 1, 0, "TPalette::Read_PAL(): Invalid version number");
362 return false;
363 }
364 // Get the number of entries.
365 if (pLogPal->palNumEntries <= 0){
366 WARNX(OwlGDI, 1, 0, "TPalette::Read_PAL(): No colors in palette");
368 return false;
369 }
371 return true;
372}
373
374/// write Microsoft *.pal format
375///
376/// return true if success
377bool
379{
380 // Create a RIFF chunk for a PAL file.
382 ckFile.Size = 0; // Corrected later
383 ckFile.Type = owlFCC('P','A','L',' ');
384 if (!file.CreateChunk(ckFile, TRiffFile::cfCreateRiff)) {
385 WARNX(OwlGDI, 1, 0, "TPalette::Write_PAL() Failed to create RIFF-PAL chunk");
386 return false;
387 }
388 // Create the LOGPALETTE data which will become
389 // the data chunk.
392 if (!nColors){
393 WARNX(OwlGDI, 1, 0, "TPalette::Write_PAL() no colors in palette");
394 return false;
395 }
396 int iSize = sizeof(LOGPALETTE)+(nColors-1)*sizeof(PALETTEENTRY);
397 TAPointer<char> pdata(new char[iSize]);
398 LOGPALETTE* logPal = reinterpret_cast<LOGPALETTE*>((char*)pdata);
399 logPal->palVersion = 0x300;
400 logPal->palNumEntries = nColors;
401 GetPaletteEntries(0, nColors, logPal->palPalEntry);
402
403 // create the data chunk.
405 ckData.Size = iSize;
406 ckData.CkId = owlFCC('d','a','t','a');
407 if (!file.CreateChunk(ckData)) {
408 WARNX(OwlGDI, 1, 0, "TPalette::Write_PAL() Failed to create data chunk");
409 return false;
410 }
411 // Write the data chunk.
412 if(!file.Write((char*)pdata, iSize)) {
413 WARNX(OwlGDI, 1, 0, "TPalette::Write_PAL() Failed to write data chunk");
414 return false;
415 }
416 // Ascend from the data chunk which will correct the length.
417 file.Ascent(ckData);
418 // Ascend from the RIFF-PAL chunk.
419 file.Ascent(ckFile);
420
421 return true;
422}
423/* -------------------------------------------------------------------------- */
424/// convert HSL to RGB
425///
426/// given h,s,l on [0..1],return r,g,b on [0..1]
427void HSL_to_RGB(double& h, double& sl, double& l, double* r, double* g, double* b)
428{
429 double v;
430 v = (l <= 0.5) ? (l * (1.0 + sl)) : (l + sl - l * sl);
431 if (v <= 0)
432 *r = *g = *b = 0.0;
433 else {
434 double m;
435 double sv;
436 int sextant;
437 double fract, vsf, mid1, mid2;
438
439 m = l + l - v;
440 sv = (v - m ) / v;
441 h *= 6.0;
442 sextant = static_cast<int>(h); //JJH added static cast
443 fract = h - sextant;
444 vsf = v * sv * fract;
445 mid1 = m + vsf;
446 mid2 = v - vsf;
447 switch (sextant) {
448 case 0: *r = v; *g = mid1; *b = m; break;
449 case 1: *r = mid2; *g = v; *b = m; break;
450 case 2: *r = m; *g = v; *b = mid1; break;
451 case 3: *r = m; *g = mid2; *b = v; break;
452 case 4: *r = mid1; *g = m; *b = v; break;
453 case 5: *r = v; *g = m; *b = mid2; break;
454 }
455 }
456}
457#include <pshpack1.h>
458/// ACO header
459struct ACO_Hdr{
460 uint16 Version; ///< Version== 1
461 uint16 Count; ///< number of color
462};
463static TBinField ACO_HdrFields[] = {
464 {varSHORT,2, 1}, /* uint16 Version; */
465 {varSHORT,2, 1}, /* uint16 Count; */
466 {varEnd, 0, 0},
467};
468/// ACO color structure
469struct ACO_Color{
470 uint16 clrSpace; ///< color space
471 uint16 Color1; ///< color value1
472 uint16 Color2; ///< color value2
473 uint16 Color3; ///< color value3
474 uint16 Color4; ///< color value4
475};
476static TBinField ACO_ColorFields[] = {
477 {varSHORT,2, 1}, /* uint16 clrSpace; */
478 {varSHORT,2, 1}, /* uint16 Color1; */
479 {varSHORT,2, 1}, /* uint16 Color2; */
480 {varSHORT,2, 1}, /* uint16 Color3; */
481 {varSHORT,2, 1}, /* uint16 Color4; */
482 {varEnd, 0, 0},
483};
484struct MLOGPALETTE { // lgpl
485 WORD palVersion;
486 WORD palNumEntries;
487 PALETTEENTRY palPalEntry[256];
488};
489#include <poppack.h>
490
491#if !defined(CMYK)
492#define CMYK(c,m,y,k) (static_cast<COLORREF>((((BYTE)(c)|((WORD)((BYTE)(m))<<8))|(((DWORD)(BYTE)(y))<<16))|(((DWORD)(BYTE)(k))<<24)))
493/* Macros to retrieve CMYK values from a COLORREF */
494#define GetCValue(cmyk) ((BYTE)(cmyk))
495#define GetMValue(cmyk) ((BYTE)((cmyk)>> 8))
496#define GetYValue(cmyk) ((BYTE)((cmyk)>>16))
497#define GetKValue(cmyk) ((BYTE)((cmyk)>>24))
498#endif
499
500/* -------------------------------------------------------------------------- */
501/// Read Adobe Photoshop *.ACO color table
502///
503/// return true if success
504//
506{
507 ACO_Hdr hdr;
508 // Read the Header.
509 if(!file.ReadStruct(&hdr, ACO_HdrFields, boBig_Endian)){
510 WARNX(OwlGDI, 1, 0, "TPalette::Read_ACO() Failed to read ACO header");
511 return false;
512 }
513 TRACEX(OwlGDI, 1, "TPalette::Read_ACO() Data for header: hdr.Version = " << dec << hdr.Version <<", hdr.Count = " << hdr.Count);
514 if(hdr.Version != 1){ // equial to 1 ///////////////////////////////
515 WARNX(OwlGDI, 1, 0, "TPalette::Read_ACO() Invalid version number");
517 return false;
518 }
519
520 TAPointer<ACO_Color> clr(new ACO_Color[hdr.Count]);
521
522 // Read the Colors.
523 for(int i = 0; i < hdr.Count; i++){
524 if(!file.ReadStruct((char*)&clr[i], ACO_ColorFields, boBig_Endian)){
525 WARNX(OwlGDI, 1, 0, "TPalette::Read_ACO() Failed to ACO Colors, line" << __LINE__);
526 return false;
527 }
528 }
529#if defined(__TRACE)
530 TRACEX(OwlGDI, 1, "TPalette::Read_ACO() Data for Colors:");
531 for (int j= 0; j < hdr.Count; j++){
532 TRACEX(OwlGDI, 1, "TPalette::Read_ACO() index("<< dec << j << "), clrSpace("
533 << clr[j].clrSpace << "), Color1("<< clr[j].Color1<< "), Color2(" <<
534 clr[j].Color2<< "), Color3("<< clr[j].Color3<<"), Color4("<<
535 clr[j].Color4<< ")");
536 }
537#endif
538 MLOGPALETTE LogPal;
539 LogPal.palVersion = 0x300;
540 LogPal.palNumEntries = 256;
541 memset(&LogPal.palPalEntry, 0, sizeof(LogPal.palPalEntry));
542
543 //////////////////////////////////////////////////////////////////////////////
544 // copy color values from ACO_Clr to logical palette
545 uint colors = 0;
546
547 // only 256 colors use !!!!!!!!!!!!!!!!!!
548 if(hdr.Count > 256)
549 hdr.Count = 256;
550
551 for (int k= 0; k < hdr.Count; k++){
552 switch(clr[k].clrSpace){
553 default:
554 break;
555
556 case 0: // RGB
557 LogPal.palPalEntry[k].peRed = uint8(clr[k].Color1*255ul/65535u);
558 LogPal.palPalEntry[k].peGreen = uint8(clr[k].Color2*255ul/65535u);
559 LogPal.palPalEntry[k].peBlue = uint8(clr[k].Color3*255ul/65535u);
560 LogPal.palPalEntry[k].peFlags = 0;
561 break;
562
563 // not checked
564 case 1: { // HSB (HSL) ?????????????????????????????????????
565 double h,s,l,r,g,b;
566 h = clr[k].Color1/65535.0;
567 s = clr[k].Color2/65535.0;
568 l = clr[k].Color3/65535.0;
569 HSL_to_RGB(h, s, l, &r, &g, &b);
570
571 LogPal.palPalEntry[k].peRed = uint8(r*255u);
572 LogPal.palPalEntry[k].peGreen = uint8(g*255u);
573 LogPal.palPalEntry[k].peBlue = uint8(b*255u);
574 LogPal.palPalEntry[k].peFlags = 0;
575 }
576 break;
577
578 // not checked
579 case 2: { // CMYK
580 COLORREF clrRef = CMYK( uint8(clr[k].Color1*255ul/65535u),
581 uint8(clr[k].Color2*255ul/65535u),
582 uint8(clr[k].Color3*255ul/65535u),
583 uint8(clr[k].Color4*255ul/65535u)
584 );
585 LogPal.palPalEntry[k].peRed = GetRValue(clrRef);
586 LogPal.palPalEntry[k].peGreen = GetGValue(clrRef);
587 LogPal.palPalEntry[k].peBlue = GetBValue(clrRef);
588 LogPal.palPalEntry[k].peFlags = 0;
589 break;
590 }
591
592 // if I must do it also ??????????????????
593 //case 7: // LAB
594 // LogPal.palPalEntry[k].peRed = uint8(clr[k].Color1*255ul/65535u);
595 // LogPal.palPalEntry[k].peGreen = uint8(clr[k].Color2*255ul/65535u);
596 // LogPal.palPalEntry[k].peBlue = uint8(clr[k].Color3*255ul/65535u);
597 // LogPal.palPalEntry[k].peFlags = 0;
598 // break;
599
600 // not checked
601 case 8: // GrayScale
602 LogPal.palPalEntry[k].peRed = uint8(clr[k].Color1*255ul/10000u);
603 LogPal.palPalEntry[k].peGreen = uint8(clr[k].Color1*255ul/10000u);
604 LogPal.palPalEntry[k].peBlue = uint8(clr[k].Color1*255ul/10000u);
605 LogPal.palPalEntry[k].peFlags = 0;
606 break;
607 }
608 colors++;
609 }
610 if(!colors){
611 WARNX(OwlGDI, 1, 0, "TPalette::Read_ACO() Error no colors found.");
612 //TXGdi::Raise(IDS_BADFORMAT);
613 return false;
614 }
616 return true;
617}
618/* -------------------------------------------------------------------------- */
619/// Write Adobe Photoshop *.ACO color table
620///
621/// return true if success
623{
624 // Create the LOGPALETTE data which will become
625 // the data chunk.
628 if (!nColors){
629 WARNX(OwlGDI, 1, 0, "TPalette::Write_ACO() Error no colors in palette");
631 return false;
632 }
635
636 ACO_Hdr hdr;
637 hdr.Version = 0x1;
638 hdr.Count = nColors;
639
640 // Write the Header.
641 if(!file.WriteStruct(&hdr, ACO_HdrFields, boBig_Endian)){
642 WARNX(OwlGDI, 1, 0, "TPalette::Write_ACO() Failed to write ACO header");
643 return false;
644 }
645
646 ACO_Color clr[256];
647 for (int i= 0; i < nColors; i++){
648 clr[i].clrSpace = 0; // RGB
649 clr[i].Color1 = uint16(pColors[i].peRed*65535ul/255);
650 clr[i].Color2 = uint16(pColors[i].peGreen * 65535ul/255);
651 clr[i].Color3 = uint16(pColors[i].peBlue * 65535ul/255);
652 clr[i].Color4 = 0;
653 }
654 // Read the Colors.
655 for(int j = 0; j < nColors; j++){
656 if(!file.WriteStruct(reinterpret_cast<char*>(&clr[j]), ACO_ColorFields, boBig_Endian)){
657 WARNX(OwlGDI, 1, 0, "TPalette::Write_ACO() Failed to write ACO Colors, line" << __LINE__);
658 return false;
659 }
660 }
661 return true;
662}
663// -----------------------------------------------------------------------------
664/// ACT color structure
665struct ACT_Color{
666 uint8 Red; ///< Red compponent
667 uint8 Green; ///< Green compponent
668 uint8 Blue; ///< Blue compponent
669};
670// -----------------------------------------------------------------------------
671/// Read Adobe Photoshop *.ACT color table
672///
673/// return true if success
675{
676 MLOGPALETTE LogPal;
677 LogPal.palVersion = 0x300;
678 LogPal.palNumEntries = 256;
679 memset(&LogPal.palPalEntry, 0, sizeof(LogPal.palPalEntry));
680
681 ACT_Color clr[256];
682
683 // Read the Color table.
684 if(file.Read((char*)&clr, sizeof(clr)) == TFILE_ERROR){
685 WARNX(OwlGDI, 1, 0, "TPalette::Read_ACT() Failed to read ACT colors");
686 return false;
687 }
688 for (int i= 0; i < 256; i++){
689 LogPal.palPalEntry[i].peRed = clr[i].Red;
690 LogPal.palPalEntry[i].peGreen = clr[i].Green;
691 LogPal.palPalEntry[i].peBlue = clr[i].Blue;
692 LogPal.palPalEntry[i].peFlags = 0;
693 }
695 return true;
696}
697/* -------------------------------------------------------------------------- */
698/// Read Adobe Photoshop *.ACT color table
699///
700/// return true if success
702{
703 // Create the LOGPALETTE data which will become
706 if (!nColors){
707 WARNX(OwlGDI, 1, 0, "TPalette::Write_ACT() Error no colors in palette");
708 return false;
709 }
712
713 ACT_Color clr[256];
714 int i = 0;
715 for (; i < nColors; i++){
716 clr[i].Red = pColors[i].peRed;
717 clr[i].Green = pColors[i].peGreen;
718 clr[i].Blue = pColors[i].peBlue;
719 }
720 for (; i < 256; i++){
721 clr[i].Red = 0;
722 clr[i].Green = 0;
723 clr[i].Blue = 0;
724 }
725
726 // Write the data
727 if(!file.Write(reinterpret_cast<char*>(&clr), sizeof(clr))) {
728 WARNX(OwlGDI, 1, 0, "TPalette::Write_ACT() Failed to write ACT data");
729 return false;
730 }
731 return true;
732}
733/* -------------------------------------------------------------------------- */
734/// Read color table from *.DIB
735///
736/// return true if success
738{
739 // Read the Header.
741 // Read the Header.
742 if(file.Read(&bmf, sizeof bmf) == TFILE_ERROR){
743 WARNX(OwlGDI, 1, 0, "TPalette::Read_BMP() Failed to read BMP header");
744 return false;
745 }
746 uint16 bmp_id = 0x4D42; // 'BM'
747 if(bmf.bfType != bmp_id) {
748 WARNX(OwlGDI, 1, 0, "TPalette::Read_BMP() Not a Windows 3.x or PM 1.x bitmap file");
750 return false;
751 }
752 // Read bitmap header size & check it. It must be one of the two known header
753 // sizes.
754 // Will add BITMAPV4HEADER support when available
756 if (file.Read(reinterpret_cast<char*>(&headerSize), sizeof headerSize) == TFILE_ERROR ||
757 (headerSize != sizeof(BITMAPCOREHEADER) && headerSize != sizeof(BITMAPINFOHEADER)))
758 {
759 WARNX(OwlGDI, 1, 0, "TPalette::Read_BMP() Not a Windows 3.x or PM 1.x bitmap file");
761 return false;
762 }
764 int ClrUsed;
765
766 // If this is a PM 1.x DIB, read the core header & copy over to the Info header
767 bool isCore = headerSize == sizeof(BITMAPCOREHEADER);
768 if (isCore) {
769 // Read in the rest of the core header, aborting if it is truncated
771 if (file.Read(reinterpret_cast<char*>(&coreHeader.bcWidth),
772 static_cast<int>(headerSize)-sizeof(uint32))==TFILE_ERROR) {
773 WARNX(OwlGDI, 1, 0, "TPalette::Read_BMP() Invalid PM 1.x DIB Header");
775 return false;
776 }
777 BitCount = coreHeader.bcBitCount;
778 biPlanes = coreHeader.bcPlanes;
779 ClrUsed = 0;
780 }
781 else {
783 infoHeader.biSize = sizeof(BITMAPINFOHEADER);
784 // Read in the rest of the info header, aborting if it is truncated
785 if (file.Read((char*)&infoHeader.biWidth,
786 static_cast<int>(headerSize)-sizeof(uint32))==TFILE_ERROR){
787 WARNX(OwlGDI, 1, 0, "TPalette::Read_BMP() Invalid Win 3.x DIB Header");
789 return false;
790 }
791 BitCount = infoHeader.biBitCount;
792 biPlanes = infoHeader.biPlanes;
793 ClrUsed = infoHeader.biClrUsed;
794 }
795 // Check number of planes. Windows supports only 1 plane DIBs
796 if (biPlanes != 1) {
797 WARNX(OwlGDI, 1, 0, "TPalette::Read_BMP() Invalid number of planes in DIB");
799 return false;
800 }
801
802 // Fill in the default value for biClrsUsed, if not supplied, using the
803 // bit count. Will remain 0 for 16bpp or greater.
804 if (!ClrUsed)
806
807 // Read color table directly into allocated memory
808 // Walk backwards & expand to RGBQUADs if it is a PM Core DIB
809 int colorRead = isCore ? // Color table size on disk
810 static_cast<int>(ClrUsed) * sizeof(RGBTRIPLE) :
811 static_cast<int>(ClrUsed) * sizeof(RGBQUAD);
812
813 RGBQUAD Colors[256];
814 if(ClrUsed){
815 if (file.Read((char*)&Colors, colorRead)==TFILE_ERROR) {
816 WARNX(OwlGDI, 1, 0, "TPalette::Read_BMP() Could not read DIB color table");
817 return false;
818 }
819 if(isCore) {
820 for (int i = int(ClrUsed-1); i >= 0; i--) {
821 Colors[i].rgbRed = ((RGBTRIPLE*)Colors)[i].rgbtRed;
822 Colors[i].rgbGreen = ((RGBTRIPLE*)Colors)[i].rgbtGreen;
823 Colors[i].rgbBlue = ((RGBTRIPLE*)Colors)[i].rgbtBlue;
824 }
825 }
826 }
827 MLOGPALETTE LogPal;
828 LogPal.palVersion = 0x300;
829 LogPal.palNumEntries = 256;
830 memset(&LogPal.palPalEntry, 0, sizeof(LogPal.palPalEntry));
831 int i = 0;
832 for(; i < ClrUsed; i++){
833 LogPal.palPalEntry[i].peRed = Colors[i].rgbRed;
834 LogPal.palPalEntry[i].peGreen = Colors[i].rgbGreen;
835 LogPal.palPalEntry[i].peBlue = Colors[i].rgbBlue;
836 LogPal.palPalEntry[i].peFlags = 0;
837 }
838 for(; i < 256; i++){
839 LogPal.palPalEntry[i].peRed = 0;
840 LogPal.palPalEntry[i].peGreen = 0;
841 LogPal.palPalEntry[i].peBlue = 0;
842 LogPal.palPalEntry[i].peFlags = 0;
843 }
845 return true;
846}
847/* -------------------------------------------------------------------------- */
848/// Write Color table to *.DIB with dimensions 1x1 pixel
849///
850/// return true if success
852{
854 bmf.bfType = 0x4D42; // 'BM'
855 bmf.bfSize = sizeof(bmf) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256 + sizeof(uint8);
856 bmf.bfReserved1 = 0;
857 bmf.bfReserved2 = 0;
858 bmf.bfOffBits = sizeof bmf + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256;
859 if(!file.Write((char*)&bmf, sizeof bmf)){
860 WARNX(OwlGDI, 1, 0, "TPalette::Write_BMP() Error write header");
861 return false;
862 }
863
865 infoHeader.biSize = sizeof(BITMAPINFOHEADER);
866 infoHeader.biWidth = 1;
867 infoHeader.biHeight = 1;
868 infoHeader.biPlanes = 1;
869 infoHeader.biBitCount = 8;
870 infoHeader.biCompression = BI_RGB; // No compression
871 infoHeader.biSizeImage = 1; // Calculate this below
872 infoHeader.biXPelsPerMeter = 0; // Zero is OK
873 infoHeader.biYPelsPerMeter = 0; // Zero is OK
874 infoHeader.biClrUsed = 256; // Calculate this below
875 infoHeader.biClrImportant = 256; // Zero is OK
876
877 // Write the data
878 if(!file.Write((char*)&infoHeader, sizeof(infoHeader))){
879 WARNX(OwlGDI, 1, 0, "TPalette::Write_BMP() Failed to write BMP Info header");
880 return false;
881 }
882
885 if (!nColors){
886 WARNX(OwlGDI, 1, 0, "TPalette::Write_BMP() no colors in palette");
887 return false;
888 }
891
892 RGBQUAD clr[256];
893 int i = 0;
894 for (; i < nColors; i++){
895 clr[i].rgbRed = pColors[i].peRed;
896 clr[i].rgbGreen = pColors[i].peGreen;
897 clr[i].rgbBlue = pColors[i].peBlue;
898 clr[i].rgbReserved = 0;
899 }
900 for (; i < 256; i++){
901 clr[i].rgbRed = 0;
902 clr[i].rgbGreen = 0;
903 clr[i].rgbBlue = 0;
904 clr[i].rgbReserved = 0;
905 }
906
907 // Write the Colors
908 if(!file.Write((char*)&clr, sizeof(clr))) {
909 WARNX(OwlGDI, 1, 0, "TPalette::Write_BMP() Failed to write BMP Colors");
910 return false;
911 }
912 // Write the 1x1 bitmap
913 uint32 pixel = 0;
914 if(!file.Write((char*)&pixel, sizeof(pixel))) {
915 WARNX(OwlGDI, 1, 0, "TPalette::Write_BMP() Failed to write BMP 1x1 bitmap");
916 return false;
917 }
918 return true;
919}
920
921} // OWL namespace
#define WARNX(group, condition, level, message)
Definition checks.h:277
#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
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
Pseudo-GDI object Device Independent Bitmap (DIB) class.
Definition gdiobjec.h:795
@ WriteOnly
Definition file.h:131
@ PermExclusive
Definition file.h:141
@ CreateAlways
Creates a new file. The function overwrites the file if it exists.
Definition file.h:148
The TFileName class constructs filenames.
Definition filename.h:37
bool Remove() const
Deletes this file associated with this name if possible; otherwise attempts to delete the directory a...
Definition filename.cpp:899
GdiObject is the root, pseudo-abstract base class for ObjectWindows' GDI (Graphics Device Interface) ...
Definition gdiobjec.h:68
static void RefInc(HANDLE handle)
Increments by 1 the reference count of the object associated with the given handle.
Definition gdiobjec.cpp:178
void CheckValid(uint resId=IDS_GDIFAILURE)
Definition gdibase.cpp:49
static void RefRemove(HANDLE handle)
Removes the reference entry to the object with the given handle.
Definition gdiobjec.cpp:163
bool ShouldDelete
Should object delete GDI handle in dtor?
Definition gdibase.h:82
static void RefAdd(HANDLE handle, TType type)
RefAdd adds a reference entry for the object with the given handle and type.
Definition gdiobjec.cpp:137
HANDLE Handle
GDI handle of this object.
Definition gdibase.h:81
TPalette is the GDI Palette class derived from TGdiObject.
Definition gdiobjec.h:413
TPalette(HPALETTE handle, TAutoDelete autoDelete=NoAutoDelete)
Alias an existing palette handle. Assume ownership if autoDelete says so.
Definition palette.cpp:40
bool Write_BMP(TRiffFile &file)
Write palette to BMP 1x1 file.
Definition palette.cpp:851
bool Read_BMP(TRiffFile &file)
Read palette from BMP file.
Definition palette.cpp:737
uint GetPaletteEntries(uint16 start, uint16 count, PALETTEENTRY *entries) const
Retrieves a range of entries in this logical palette and places them in the entries array.
Definition gdiobjec.h:1306
bool Write_PAL(TRiffFile &file)
Write Microsoft palette to file.
Definition palette.cpp:378
bool GetObject(uint16 &numEntries) const
Finds the number of entries in this logical palette and sets the value in the numEntries argument.
Definition gdiobjec.h:1336
bool Write(const tchar *fileName)
Write this palette into file: *.dib,*.bmp,*.pal,*.aco,*.act.
Definition palette.cpp:289
bool Read_ACO(TRiffFile &file)
Read Adobe palette from file.
Definition palette.cpp:505
void Create(const BITMAPINFO *info, uint flags)
Accept a pointer to a BITMAPINFO structure and create a GDI logical palette from the color table whic...
Definition palette.cpp:207
bool Read_PAL(TRiffFile &file)
Read Microsoft palette from file.
Definition palette.cpp:325
void ToClipboard(TClipboard &Clipboard)
Moves this palette to the target Clipboard argument.
Definition palette.cpp:250
bool Write_ACT(TRiffFile &file)
Write Adobe palette to file.
Definition palette.cpp:701
bool Read(const tchar *fileName)
Read palette from file.
Definition palette.cpp:263
bool Write_ACO(TRiffFile &file)
Write Adobe palette to file.
Definition palette.cpp:622
bool Read_ACT(TRiffFile &file)
Read Adobe palette from file.
Definition palette.cpp:674
The TRiffFile class is used for reading and writing RIFF files.
Definition file.h:563
static void Raise()
Construct a TXBadFormat exception from scratch, and throws it.
Definition file.cpp:62
Definition of classes for clipboard Encapsulation.
#define _tcsicmp
Definition cygwin.h:76
#define _T(x)
Definition cygwin.h:51
#define _tcsrchr
Definition cygwin.h:86
Definition of abstract GDI object class and derived classes.
TAutoDelete
Flag for Handle ctors to control Handle deletion in dtor.
Definition gdibase.h:70
#define owlFCC(ch0, ch1, ch2, ch3)
Definition file.h:531
#define TFILE_ERROR
Definition file.h:105
@ boLittle_Endian
LSB at lowest address: Intel //.
Definition file.h:49
@ boBig_Endian
MSB at lowest address: Motorola //.
Definition file.h:50
@ varEnd
Definition file.h:69
@ varSHORT
Definition file.h:73
Reliable platform independent header for common memory and string functions.
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 char uint8
Definition number.h:32
void HSL_to_RGB(double &h, double &sl, double &l, double *r, double *g, double *b)
convert HSL to RGB
Definition palette.cpp:427
char tchar
Definition defs.h:77
OWL_DIAGINFO
Definition animctrl.cpp:14
unsigned short uint16
Definition number.h:33
unsigned int uint
Definition number.h:25
General definitions used by all ObjectWindows programs.
#define CMYK(c, m, y, k)
Definition palette.cpp:492
The TBinField struct describes a group of like-typed fields in a structure to be read or written usin...
Definition file.h:98
RIFF chunk information data structure.
Definition file.h:541