00001 // $Id: coplfilr.cpp 1282 2006-06-09 09:46:49Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 00099 /* 00100 */ 00101 00102 #include "camtypes.h" 00103 #include "coplfilr.h" 00104 00105 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00106 //#include "ccfile.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00107 #include "cdrcol.h" 00108 //#include "oilfltrs.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00109 #include "optsunit.h" 00110 #include "progress.h" 00111 #include "scunit.h" 00112 #include "sgcolour.h" 00113 //#include "isetres.h" 00114 00115 //#include "ben.h" 00116 //#include "filtrres.h" 00117 //#include "peter.h" 00118 //#include "will2.h" 00119 00120 DECLARE_SOURCE("$Revision: 1282 $"); 00121 00122 CC_IMPLEMENT_DYNAMIC(PaletteFilter, Filter) 00123 CC_IMPLEMENT_DYNAMIC(CorelPaletteFilter, PaletteFilter) 00124 CC_IMPLEMENT_DYNAMIC(MSPaletteFilter, PaletteFilter) 00125 CC_IMPLEMENT_DYNAMIC(AdobeColourTableFilter, PaletteFilter) 00126 CC_IMPLEMENT_DYNAMIC(AdobeColourSwatchFilter, PaletteFilter) 00127 CC_IMPLEMENT_DYNAMIC(JCWColourFilter, PaletteFilter) 00128 CC_IMPLEMENT_DYNAMIC(PaintShopProPaletteFilter, PaletteFilter) 00129 00130 #define new CAM_DEBUG_NEW 00131 00132 typedef struct { 00133 WORD Unknown; 00134 BYTE Entries[2]; 00135 } cpl_header; 00136 00137 #define CPL_MIN_ENTRY_SIZE 14 // minimum size of an entry in a cpl file 00138 #define CPL_MAX_ENTRY_SIZE (13+32) // max size 00139 #define CPL_CHECK_TEXT_START 16 // place to start checking the text 00140 #define CPF_MAX_COLNAME_SIZE 32 00141 00142 #define CPL_FVU -1 // version unknown 00143 #define CPL_FV4 4 // version 4 00144 #define CPL_FV5 5 // version 5 00145 00146 00147 00148 /******************************************************************************************** 00149 > PaletteFilter::PaletteFilter() 00150 00151 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00152 Created: 30/4/96 00153 Inputs: - 00154 Returns: - 00155 Purpose: Constructor for a base palette filter 00156 SeeAlso: Filter 00157 ********************************************************************************************/ 00158 PaletteFilter::PaletteFilter() 00159 { 00160 m_pNewColours = NULL; 00161 00162 ImportIntoGallery = TRUE; 00163 CurrentGalleryGroup = NULL; 00164 } 00165 00166 00167 /******************************************************************************************** 00168 > PaletteFilter::~PaletteFilter() 00169 00170 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00171 Created: 30/4/96 00172 Inputs: - 00173 Returns: - 00174 Purpose: Destructor for a base palette filter 00175 SeeAlso: Filter 00176 ********************************************************************************************/ 00177 PaletteFilter::~PaletteFilter() 00178 { 00179 if (m_pNewColours != NULL) 00180 { 00181 m_pNewColours->DestroyColours(); 00182 delete m_pNewColours; 00183 m_pNewColours = NULL; 00184 } 00185 } 00186 00187 00188 /******************************************************************************************** 00189 > virtual BOOL PaletteFilter::IsDefaultDocRequired(const TCHAR* pcszPathName) 00190 00191 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00192 Created: 30/4/96 00193 Inputs: pcszPathName - pointer to the name of the file that is about to be imported 00194 Returns: TRUE if a document is required to import this file into, 00195 FALSE if file supplies the document 00196 Purpose: For determining wether this filter needs a document to be created to import 00197 into. 00198 ********************************************************************************************/ 00199 BOOL PaletteFilter::IsDefaultDocRequired(const TCHAR* pcszPathName) 00200 { 00201 // Since palette files are unlikely to supply a document we will return TRUE. 00202 // Derived classes can still virtually override this function and return FALSE if required. 00203 00204 return TRUE; 00205 } 00206 00207 00208 /******************************************************************************************** 00209 > virtual BOOL PaletteFilter::DoImport(SelOperation* pOp, CCLexFile* pFile, Document* pDoc, BOOL AutoChosen, ImportPosition *Pos, 00210 KernelBitmap** ppImportedBitmap, DocCoord* pPosTranslate, String_256* URL) 00211 00212 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00213 Created: 30/4/96 00214 Inputs: pOp - The operation this import is running under 00215 pFile - The file to import from 00216 pDoc - The document to import into 00217 AutoChosen - TRUE if this filter was chosen by the system, FALSE if chosen by the user 00218 ImportPos - The position to import the file data at 00219 Pos - 00220 ppImportedBitmap - this is used mainly in the bitfltr.cpp for the HTML 00221 import filter. HTMLFilter::DoImport() needs a pointer to a kernel bitmap 00222 to set the background bitmap up into Camelot. 00223 pPosTranslate - This is used too by the HTMLFilter in order to do a formatting. 00224 URL - original URL of the imported file 00225 Returns: TRUE for successful import, FALSE if an error occured. 00226 Purpose: Base class for handling palette import 00227 00228 Notes: **** IMPORTANT ************************************************************** 00229 Palette filters can be called directly from the colour gallery (sgcolour.cpp) 00230 library groups to import palette files directly into the gallery. 00231 In this case, pOp and pDoc are NULL, and the member vars CurrentGalleryGroup 00232 and ImportIntoGallery are set up suitably. It is this important that these 00233 filters continue to be happy about not importing into a document! 00234 ***************************************************************************** 00235 00236 SeeAlso: Filter::DoImport 00237 ********************************************************************************************/ 00238 BOOL PaletteFilter::DoImport(SelOperation* pOp, CCLexFile* pFile, Document* pDoc, BOOL AutoChosen, ImportPosition *Pos, 00239 KernelBitmap** ppImportedBitmap, DocCoord* pPosTranslate, String_256* URL) 00240 { 00241 BOOL ok = TRUE; 00242 00243 // Copy parameters into member vars. 00244 // NOTE that we allow pOp and pDoc to be NULL, when we are importing into a gallery! 00245 ERROR2IF(pFile==NULL, FALSE, "NULL parameter passed"); 00246 m_pImportOp = pOp; 00247 m_pImportFile = pFile; 00248 m_pImportDoc = pDoc; 00249 00250 // Determine if this is really a huge bodge and we're importing directly into the colour gallery 00251 #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX) 00252 //ColourSGallery *ParentGal = (ColourSGallery *) OpDisplayColourGallery::FindGallery(); 00253 ColourSGallery *ParentGal = ColourSGallery::GetInstance(); 00254 if (ParentGal != NULL) 00255 CurrentGalleryGroup = ParentGal->GetCurrentImportGroup(); 00256 else 00257 #endif 00258 CurrentGalleryGroup = NULL; 00259 00260 ImportIntoGallery = (CurrentGalleryGroup != NULL); 00261 ERROR2IF(!ImportIntoGallery && (pDoc == NULL || pOp == NULL), FALSE, "NULL doc/op when not importing into gallery"); 00262 00263 // Initialise base class services 00264 if (ok) 00265 ok = PrepareForImport(); 00266 00267 // Call derived loading functions 00268 if (ok) 00269 ok = PreImport(); 00270 if (ok) 00271 ok = ImportPalette(); 00272 if (ok) 00273 ok = PostImport(); 00274 00275 // Finialise base class importation 00276 if (ok) 00277 ok = FinishImport(TRUE); 00278 else 00279 FinishImport(FALSE); 00280 00281 CurrentGalleryGroup = NULL; 00282 ImportIntoGallery = FALSE; 00283 00284 return ok; 00285 } 00286 00287 00288 /******************************************************************************************** 00289 > virtual BOOL PaletteFilter::DoExport(Operation* pOp, CCLexFile* pFile, 00290 PathName* pPath, Document* pDoc, 00291 BOOL ShowOptions) 00292 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00293 Created: 30/4/96 00294 Inputs: pOp - The operation this import is running under 00295 pFile - The file to import from 00296 pPath - Importing path 00297 pDoc - The document to import into 00298 ShowOptions - Show the export options dialogue. 00299 Outputs: - 00300 Returns: TRUE for successful export, FALSE if an error occured. 00301 Purpose: Base class for handling palette export 00302 SeeAlso: Filter::DoImport 00303 ********************************************************************************************/ 00304 BOOL PaletteFilter::DoExport(Operation* pOp, CCLexFile* pFile, 00305 PathName* pPath, Document* pDoc, 00306 BOOL ShowOptions) 00307 { 00308 // For the moment palettes are not exported. 00309 return FALSE; 00310 } 00311 00312 00313 /******************************************************************************************** 00314 > BOOL PaletteFilter::PrepareForImport() 00315 00316 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00317 Created: 1/5/96 00318 Inputs: - 00319 Outputs: - 00320 Returns: TRUE for success, FALSE if an error occured. 00321 Purpose: Initialises the base class before import 00322 ********************************************************************************************/ 00323 BOOL PaletteFilter::PrepareForImport() 00324 { 00325 if (!ImportIntoGallery) 00326 { 00327 ERROR2IF(m_pImportDoc==NULL, FALSE, "NULL pointer"); 00328 00329 // Find the colour list document component 00330 ColourListComponent* pColours = NULL; 00331 DocComponent *pComponent = m_pImportDoc->EnumerateDocComponents(NULL); 00332 while (pComponent != NULL) 00333 { 00334 // If this is the colour component, remember it 00335 if (IS_A(pComponent, ColourListComponent)) 00336 pColours = (ColourListComponent*) pComponent; 00337 00338 // Look for next doc component 00339 pComponent = m_pImportDoc->EnumerateDocComponents(pComponent); 00340 } 00341 ERROR2IF(pColours==NULL, FALSE, "Import document had no colour list"); 00342 00343 // Create a new imported colours manager 00344 ERROR3IF(m_pNewColours != NULL, "ColourImport manager already present\n"); 00345 if (m_pNewColours != NULL) 00346 { 00347 m_pNewColours->DestroyColours(); 00348 delete m_pNewColours; 00349 } 00350 00351 m_pNewColours = new ImportedColours(pColours, FALSE); 00352 if ((m_pNewColours == NULL) || !m_pNewColours->Init()) 00353 return FALSE; 00354 } 00355 00356 return TRUE; 00357 } 00358 00359 00360 /******************************************************************************************** 00361 > BOOL PaletteFilter::FinishImport(BOOL Success) 00362 00363 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00364 Created: 1/5/96 00365 Inputs: Success - TRUE if import has been successful 00366 Outputs: - 00367 Returns: TRUE for success, FALSE if an error occured. 00368 Purpose: Finialises colour import 00369 ********************************************************************************************/ 00370 BOOL PaletteFilter::FinishImport(BOOL Success) 00371 { 00372 BOOL ok = TRUE; 00373 00374 if (!ImportIntoGallery) 00375 { 00376 // If we didn't even get to initialise, then return quietly. 00377 if (m_pNewColours == NULL) 00378 return FALSE; 00379 00380 EndSlowJob(); 00381 BeginSlowJob(-1, FALSE); 00382 00383 // Import is finished, so add any outstanding colours to the document (if the 00384 // import was successful), and delete the colour table 00385 if (Success) 00386 ok = m_pNewColours->AddColoursToDocument(); 00387 else 00388 m_pNewColours->DestroyColours(); 00389 00390 // Clean up claimed memory 00391 delete m_pNewColours; 00392 m_pNewColours = NULL; 00393 } 00394 00395 return ok; 00396 } 00397 00398 00399 /******************************************************************************************** 00400 > BOOL PaletteFilter::ProcessRGBColour(double Red, double Green, double Blue, const StringBase* pColName = NULL) 00401 00402 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00403 Created: 1/5/96 00404 Inputs: Red - red value 0..1 00405 Green - green value 0..1 00406 Blue - blue value 0..1 00407 pColName - name to give the colour (NULL if no name) 00408 Outputs: - 00409 Returns: TRUE for success, FALSE if an error occured. 00410 Purpose: Generates a Camelot RGB colour and adds it to the imported colours list 00411 ********************************************************************************************/ 00412 BOOL PaletteFilter::ProcessRGBColour(double Red, double Green, double Blue, const StringBase* pColName) 00413 { 00414 // Ensure colour components are in range 00415 ERROR3IF(Red<0, "Red component less than 0"); 00416 ERROR3IF(Red>1, "Red component greater than 1"); 00417 ERROR3IF(Green<0, "Green component less than 0"); 00418 ERROR3IF(Green>1, "Green component greater than 1"); 00419 ERROR3IF(Blue<0, "Blue component less than 0"); 00420 ERROR3IF(Blue>1, "Blue component greater than 1"); 00421 Red = ClampZeroToOne(Red); 00422 Green = ClampZeroToOne(Green); 00423 Blue = ClampZeroToOne(Blue); 00424 00425 // Make a Camelot RGB colour 00426 ColourRGBT NewColour; 00427 NewColour.Red = Red; 00428 NewColour.Green = Green; 00429 NewColour.Blue = Blue; 00430 NewColour.Transparent = 0; 00431 00432 // Name the colour 00433 String_64 NewColourName; 00434 BOOL ok = TRUE; 00435 if (pColName==NULL || pColName->IsEmpty()) 00436 ok = NameRGBColour(&NewColour, &NewColourName); 00437 else 00438 NewColourName = *pColName; 00439 00440 if (ok) 00441 { 00442 if (ImportIntoGallery) 00443 ok = AddColourToGallery(PalettePrefix_None, &NewColourName, (ColourGeneric *)&NewColour, COLOURMODEL_RGBT); 00444 else 00445 ok = m_pNewColours->AddColour(&NewColourName, &NewColour); 00446 } 00447 00448 return ok; 00449 } 00450 00451 00452 /******************************************************************************************** 00453 > BOOL PaletteFilter::ProcessCMYKColour(double Cyan, double Magenta, double Yellow, double Key, const StringBase* pColName = NULL) 00454 00455 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00456 Created: 2/5/96 00457 Inputs: Cyan - cyan value 0..1 00458 Magenta - green value 0..1 00459 Yellow - blue value 0..1 00460 Key - black value 0..1 00461 pColName - name to give the colour (NULL if no name) 00462 Outputs: - 00463 Returns: TRUE for success, FALSE if an error occured. 00464 Purpose: Generates a Camelot CMYK colour and adds it to the imported colours list 00465 ********************************************************************************************/ 00466 BOOL PaletteFilter::ProcessCMYKColour(double Cyan, double Magenta, double Yellow, double Key, const StringBase* pColName) 00467 { 00468 // Ensure colour components are in range 00469 ERROR3IF(Cyan<0, "Cyan component less than 0"); 00470 ERROR3IF(Cyan>1, "Cyan component greater than 1"); 00471 ERROR3IF(Magenta<0, "Magenta component less than 0"); 00472 ERROR3IF(Magenta>1, "Magenta component greater than 1"); 00473 ERROR3IF(Yellow<0, "Yellow component less than 0"); 00474 ERROR3IF(Yellow>1, "Yellow component greater than 1"); 00475 ERROR3IF(Key<0, "Key component less than 0"); 00476 ERROR3IF(Key>1, "Key component greater than 1"); 00477 Cyan = ClampZeroToOne(Cyan); 00478 Magenta = ClampZeroToOne(Magenta); 00479 Yellow = ClampZeroToOne(Yellow); 00480 Key = ClampZeroToOne(Key); 00481 00482 // Make a Camelot CMYK colour 00483 ColourCMYK NewColour; 00484 NewColour.Cyan = Cyan; 00485 NewColour.Magenta = Magenta; 00486 NewColour.Yellow = Yellow; 00487 NewColour.Key = Key; 00488 00489 // Name the colour 00490 String_64 NewColourName; 00491 BOOL ok = TRUE; 00492 if (pColName==NULL || pColName->IsEmpty()) 00493 ok = NameCMYKColour(&NewColour, &NewColourName); 00494 else 00495 NewColourName = *pColName; 00496 00497 if (ok) 00498 { 00499 if (ImportIntoGallery) 00500 ok = AddColourToGallery(PalettePrefix_None, &NewColourName, (ColourGeneric *)&NewColour, COLOURMODEL_CMYK); 00501 else 00502 ok = m_pNewColours->AddColour(&NewColourName, &NewColour); 00503 } 00504 00505 return ok; 00506 } 00507 00508 00509 /******************************************************************************************** 00510 > BOOL PaletteFilter::ProcessHSVColour(double Hue, double Sat, double Value, const StringBase* pColName = NULL) 00511 00512 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00513 Created: 2/5/96 00514 Inputs: Hue - Hue value 0..1 00515 Sat - Saturation value 0..1 00516 Value - Brightness value 0..1 00517 pColName - name to give the colour (NULL if no name) 00518 Outputs: - 00519 Returns: TRUE for success, FALSE if an error occured. 00520 Purpose: Generates a Camelot HSV colour and adds it to the imported colours list 00521 ********************************************************************************************/ 00522 BOOL PaletteFilter::ProcessHSVColour(double Hue, double Sat, double Value, const StringBase* pColName) 00523 { 00524 // Ensure colour components are in range 00525 ERROR3IF(Hue<0, "Hue component less than 0"); 00526 ERROR3IF(Hue>1, "Hue component greater than 1"); 00527 ERROR3IF(Sat<0, "Saturation component less than 0"); 00528 ERROR3IF(Sat>1, "Saturation component greater than 1"); 00529 ERROR3IF(Value<0, "Value component less than 0"); 00530 ERROR3IF(Value>1, "Value component greater than 1"); 00531 Hue = ClampZeroToOne(Hue); 00532 Sat = ClampZeroToOne(Sat); 00533 Value = ClampZeroToOne(Value); 00534 00535 // Make a Camelot HSV colour 00536 ColourHSVT NewColour; 00537 NewColour.Hue = Hue; 00538 NewColour.Saturation = Sat; 00539 NewColour.Value = Value; 00540 NewColour.Transparent = 0; 00541 00542 // Name the colour 00543 String_64 NewColourName; 00544 BOOL ok = TRUE; 00545 if (pColName==NULL || pColName->IsEmpty()) 00546 ok = NameHSVColour(&NewColour, &NewColourName); 00547 else 00548 NewColourName = *pColName; 00549 00550 if (ok) 00551 { 00552 if (ImportIntoGallery) 00553 ok = AddColourToGallery(PalettePrefix_None, &NewColourName, (ColourGeneric *)&NewColour, COLOURMODEL_HSVT); 00554 else 00555 ok = m_pNewColours->AddColour(&NewColourName, &NewColour); 00556 } 00557 00558 return ok; 00559 } 00560 00561 00562 /******************************************************************************************** 00563 > BOOL PaletteFilter::ProcessLabColour(double Luminance, double A, double B, const StringBase* pColName = NULL) 00564 00565 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00566 Created: 7/5/96 00567 Inputs: Luminance - Luminance value 0..100 (black to white) 00568 A - a value +127..-128 (green to red) 00569 B - b value +127..-128 (blue to yellow) 00570 pColName - name to give the colour (NULL if no name) 00571 Outputs: - 00572 Returns: TRUE for success, FALSE if an error occured. 00573 Purpose: Generates a name for this colour and adds it to the imported colours list 00574 N.B. Camelot does not support Lab colours so the colour is converted to 00575 RGB or greyscale. 00576 ********************************************************************************************/ 00577 BOOL PaletteFilter::ProcessLabColour(double Luminance, double A, double B, const StringBase* pColName) 00578 { 00579 // Ensure colour components are in range 00580 ERROR3IF(Luminance<0, "Luminance component less than 0"); 00581 ERROR3IF(Luminance>100, "Luminance component greater than 100"); 00582 ERROR3IF(A<-128, "A component less than -128"); 00583 ERROR3IF(A> 127, "A component greater than 127"); 00584 ERROR3IF(B<-128, "B component less than -128"); 00585 ERROR3IF(B> 127, "B component greater than 127"); 00586 Luminance = __min(100, __max(0, Luminance)); 00587 A = __min(127, __max(-128, A)); 00588 B = __min(127, __max(-128, B)); 00589 00590 // Convert to RGB values 00591 Vector3D Lab(Luminance, A, B); 00592 Vector3D RGBResult; 00593 PaletteFilter::ConvertLABToRGB(Lab, &RGBResult); 00594 00595 return ProcessRGBColour(RGBResult.x, RGBResult.y, RGBResult.z, pColName ); 00596 } 00597 00598 00599 /******************************************************************************************** 00600 > BOOL PaletteFilter::ProcessGreyColour(double Intensity, const StringBase* pColName = NULL) 00601 00602 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00603 Created: 7/5/96 00604 Inputs: Intensity - 0..1 (black to white) 00605 pColName - name to give the colour (NULL if no name) 00606 Outputs: - 00607 Returns: TRUE for success, FALSE if an error occured. 00608 Purpose: Generates a Camelot greyscale colour and adds it to the imported colours list 00609 ********************************************************************************************/ 00610 BOOL PaletteFilter::ProcessGreyColour(double Intensity, const StringBase* pColName) 00611 { 00612 // Ensure colour components are in range 00613 ERROR3IF(Intensity<0, "Intensity component less than 0"); 00614 ERROR3IF(Intensity>1, "Intensity component greater than 1"); 00615 Intensity = ClampZeroToOne(Intensity); 00616 00617 // Make a Camelot greyscale colour 00618 ColourGreyT NewColour; 00619 NewColour.Intensity = Intensity; 00620 NewColour.Reserved1 = 0; 00621 NewColour.Reserved2 = 0; 00622 NewColour.Transparent = 0; 00623 00624 // Name the colour 00625 String_64 NewColourName; 00626 BOOL ok = TRUE; 00627 if (pColName==NULL || pColName->IsEmpty()) 00628 ok = NameGreyColour(&NewColour, &NewColourName); 00629 else 00630 NewColourName = *pColName; 00631 00632 if (ok) 00633 { 00634 if (ImportIntoGallery) 00635 ok = AddColourToGallery(PalettePrefix_None, &NewColourName, (ColourGeneric *)&NewColour, COLOURMODEL_GREYT); 00636 else 00637 ok = m_pNewColours->AddColour(&NewColourName, &NewColour); 00638 } 00639 00640 return ok; 00641 } 00642 00643 00644 /******************************************************************************************** 00645 > BOOL PaletteFilter::NameRGBColour(ColourRGBT* pColour, StringBase* pName) 00646 00647 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00648 Created: 3/5/96 00649 Inputs: pColour - the Camelot colour to name 00650 Outputs: pName holds the generated name 00651 Returns: TRUE for success, FALSE if an error occured. 00652 Purpose: Generates a name for this RGB colour 00653 ********************************************************************************************/ 00654 BOOL PaletteFilter::NameRGBColour(ColourRGBT* pColour, StringBase* pName) 00655 { 00656 ERROR2IF(pColour==NULL || pName==NULL, FALSE, "NULL Pointer"); 00657 00658 if (UsePercentageColour()) 00659 { 00660 pName->MakeMsg(_R(IDS_PALETTEIMPORT_RGBPERCENT), 00661 (INT32)(pColour->Red.MakeDouble()*100+0.4999), 00662 (INT32)(pColour->Green.MakeDouble()*100+0.4999), 00663 (INT32)(pColour->Blue.MakeDouble()*100+0.4999) ); 00664 } 00665 else 00666 { 00667 pName->MakeMsg(_R(IDS_PALETTEIMPORT_RGBVALUE), 00668 (INT32)(pColour->Red.MakeDouble()*255+0.4999), 00669 (INT32)(pColour->Green.MakeDouble()*255+0.4999), 00670 (INT32)(pColour->Blue.MakeDouble()*255+0.4999) ); 00671 } 00672 00673 return TRUE; 00674 } 00675 00676 00677 /******************************************************************************************** 00678 > BOOL PaletteFilter::NameCMYKColour(ColourCMYK* pColour, StringBase* pName) 00679 00680 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00681 Created: 3/5/96 00682 Inputs: pColour - the Camelot colour to name 00683 Outputs: pName holds the generated name 00684 Returns: TRUE for success, FALSE if an error occured. 00685 Purpose: Generates a name for this CMYK colour 00686 ********************************************************************************************/ 00687 BOOL PaletteFilter::NameCMYKColour(ColourCMYK* pColour, StringBase* pName) 00688 { 00689 ERROR2IF(pColour==NULL || pName==NULL, FALSE, "NULL Pointer"); 00690 00691 if (UsePercentageColour()) 00692 { 00693 pName->MakeMsg(_R(IDS_PALETTEIMPORT_CMYKPERCENT), 00694 (INT32)(pColour->Cyan.MakeDouble()*100+0.4999), 00695 (INT32)(pColour->Magenta.MakeDouble()*100+0.4999), 00696 (INT32)(pColour->Yellow.MakeDouble()*100+0.4999), 00697 (INT32)(pColour->Key.MakeDouble()*100+0.4999) ); 00698 } 00699 else 00700 { 00701 pName->MakeMsg(_R(IDS_PALETTEIMPORT_CMYKVALUE), 00702 (INT32)(pColour->Cyan.MakeDouble()*255+0.4999), 00703 (INT32)(pColour->Magenta.MakeDouble()*255+0.4999), 00704 (INT32)(pColour->Yellow.MakeDouble()*255+0.4999), 00705 (INT32)(pColour->Key.MakeDouble()*255+0.4999) ); 00706 } 00707 00708 return TRUE; 00709 } 00710 00711 00712 /******************************************************************************************** 00713 > BOOL PaletteFilter::NameHSVColour(ColourHSVT* pColour, StringBase* pName) 00714 00715 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00716 Created: 3/5/96 00717 Inputs: pColour - the Camelot colour to name 00718 Outputs: pName holds the generated name 00719 Returns: TRUE for success, FALSE if an error occured. 00720 Purpose: Generates a name for this CMYK colour 00721 ********************************************************************************************/ 00722 BOOL PaletteFilter::NameHSVColour(ColourHSVT* pColour, StringBase* pName) 00723 { 00724 ERROR2IF(pColour==NULL || pName==NULL, FALSE, "NULL Pointer"); 00725 00726 if (UsePercentageColour()) 00727 { 00728 pName->MakeMsg(_R(IDS_PALETTEIMPORT_HSVPERCENT), 00729 (INT32)(pColour->Hue.MakeDouble()*360+0.4999), 00730 (INT32)(pColour->Saturation.MakeDouble()*100+0.4999), 00731 (INT32)(pColour->Value.MakeDouble()*100+0.4999) ); 00732 } 00733 else 00734 { 00735 pName->MakeMsg(_R(IDS_PALETTEIMPORT_HSVVALUE), 00736 (INT32)(pColour->Hue.MakeDouble()*360+0.4999), 00737 (INT32)(pColour->Saturation.MakeDouble()*255+0.4999), 00738 (INT32)(pColour->Value.MakeDouble()*255+0.4999) ); 00739 } 00740 00741 return TRUE; 00742 } 00743 00744 00745 /******************************************************************************************** 00746 > BOOL PaletteFilter::NameGreyColour(ColourGreyT* pColour, StringBase* pName) 00747 00748 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00749 Created: 7/5/96 00750 Inputs: pColour - the Camelot colour to name 00751 Outputs: pName holds the generated name 00752 Returns: TRUE for success, FALSE if an error occured. 00753 Purpose: Generates a name for this greyscale colour 00754 ********************************************************************************************/ 00755 BOOL PaletteFilter::NameGreyColour(ColourGreyT* pColour, StringBase* pName) 00756 { 00757 ERROR2IF(pColour==NULL || pName==NULL, FALSE, "NULL Pointer"); 00758 00759 if (pColour->Intensity.MakeDouble() <= 0.0) 00760 *pName = String_32(_R(IDS_PALETTEIMPORT_GREYBLACK)); 00761 else if (pColour->Intensity.MakeDouble() >= 1.0) 00762 *pName = String_32(_R(IDS_PALETTEIMPORT_GREYWHITE)); 00763 else 00764 pName->MakeMsg(_R(IDS_PALETTEIMPORT_GREYPERCENT), (INT32)(pColour->Intensity.MakeDouble()*100+0.4999)); 00765 00766 return TRUE; 00767 } 00768 00769 00770 /******************************************************************************************** 00771 > BOOL PaletteFilter::UsePercentageColour() 00772 00773 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00774 Created: 29/5/96 00775 Inputs: - 00776 Outputs: - 00777 Returns: TRUE if the colour editor preference is for percentages, FALSE if not 00778 Purpose: To see wether or not to use the precentage colour naming scheme 00779 ********************************************************************************************/ 00780 BOOL PaletteFilter::UsePercentageColour() 00781 { 00782 // WEBSTER - markn 24/4/97 00783 #ifdef WEBSTER 00784 // Always use percentages for colour units in Webster 00785 return TRUE; 00786 #else 00787 #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX) 00788 // Read what the colour editors preference is 00789 ScaleUnit* pUnit = UnitsTab::GetColourUnitPreference(); 00790 00791 return (pUnit == &StandardUnit::UnitPercent); 00792 #else 00793 return FALSE; 00794 #endif 00795 #endif // WEBSTER 00796 } 00797 00798 00799 /******************************************************************************************** 00800 > BOOL PaletteFilter::StartPercentage(INT32 UpTo = -1) 00801 00802 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00803 Created: 1/5/96 00804 Inputs: UpTo - the 100% value 00805 Outputs: - 00806 Returns: TRUE for success, FALSE if an error occured. 00807 Purpose: Starts a percentage delay indicator that runs from 0 to 100. If you don't 00808 know how many colours you are importing pass -1 and the length of the file 00809 is used 00810 ********************************************************************************************/ 00811 BOOL PaletteFilter::StartPercentage(INT32 UpTo) 00812 { 00813 #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX) 00814 if (UpTo == -1) 00815 { 00816 if (m_pImportFile != NULL) 00817 BeginSlowJob(m_pImportFile->Size()); 00818 else 00819 BeginSlowJob(); 00820 } 00821 else 00822 BeginSlowJob(UpTo); 00823 #endif 00824 return TRUE; 00825 } 00826 00827 00828 /******************************************************************************************** 00829 > BOOL PaletteFilter::SetPercentage(INT32 GotTo) 00830 00831 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00832 Created: 1/5/96 00833 Inputs: GotTo - the current position 00834 Outputs: - 00835 Returns: TRUE for success, FALSE if an error occured. 00836 Purpose: Continues a percentage delay indicator. Pass -1 to use the current import 00837 file position as a progress indicator. 00838 ********************************************************************************************/ 00839 BOOL PaletteFilter::SetPercentage(INT32 GotTo) 00840 { 00841 #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX) 00842 if (GotTo == -1) 00843 { 00844 if (m_pImportFile != NULL) 00845 ContinueSlowJob(m_pImportFile->tell()); 00846 else 00847 ContinueSlowJob(); 00848 } 00849 else 00850 ContinueSlowJob(GotTo); 00851 #endif 00852 return TRUE; 00853 } 00854 00855 00856 00857 /******************************************************************************************** 00858 > void PaletteFilter::ConvertXYZToRGB(const Vector3D& icol, Vector3D& ocol) 00859 00860 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00861 Created: 13/04/96 00862 Inputs: icon = The (Xn, Yn, Zn) coordinates of the white colour in CIE XYZ space. 00863 Outputs: ocol = RGB colour (0..1) 00864 Returns: - 00865 Purpose: To convert colours from CIE XYZ to RGB 00866 ********************************************************************************************/ 00867 void PaletteFilter::ConvertXYZToRGB(const Vector3D& icol, Vector3D& ocol) 00868 { 00869 // Convert from HDTV Rec709 to RGB 00870 ocol.x = ( 3.240479*icol.x) + (-1.537150*icol.y) + (-0.498535*icol.z); 00871 ocol.y = (-0.969256*icol.x) + ( 1.875992*icol.y) + ( 0.041556*icol.z); 00872 ocol.z = ( 0.055648*icol.x) + (-0.204043*icol.y) + ( 1.057311*icol.z); 00873 00874 ClampZeroToOne(ocol.x); 00875 ClampZeroToOne(ocol.y); 00876 ClampZeroToOne(ocol.z); 00877 } 00878 00879 00880 00881 /******************************************************************************************** 00882 > void PaletteFilter::ConvertLABtoXYZ(const Vector3D& white, const Vector3D& icol, Vector3D& ocol) 00883 00884 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00885 Created: 13/04/96 00886 Inputs: white = The (Xn, Yn, Zn) coordinates of the white colour in CIE XYZ space. 00887 icol = CIE LAB colour 00888 Outputs: ocol = CIE XYZ colour 00889 Returns: - 00890 Purpose: To convert colours from CIE LUV to CIE XYZ 00891 ********************************************************************************************/ 00892 void PaletteFilter::ConvertLABtoXYZ(const Vector3D& white, const Vector3D& icol, Vector3D& ocol) 00893 { 00894 double d,e; 00895 static double third = 1.0/3.0; 00896 00897 if (icol.x < 7.9996248) 00898 ocol.y = icol.x * white.y / 903.3; 00899 else 00900 ocol.y = pow((double)((icol.x + 16.0) / 116.0), (double)3.0) * white.y; 00901 00902 e = pow((double)(ocol.y / white.y), third); 00903 d = e + (double)(icol.y / 500); 00904 00905 ocol.x = pow(d, (double)3.0) * white.x; 00906 00907 d = e - (double)(icol.z / 200); 00908 00909 ocol.z = pow(d, (double)3.0) * white.z; 00910 } 00911 00912 00913 /******************************************************************************************** 00914 > void PaletteFilter::ConvertCIEtoXYZ(const Vector3D icol, Vector3D& ocol) 00915 00916 Author: Mike_Kenny (Xara Group Ltd) <camelotdev@xara.com> 00917 Created: 13/04/96 00918 Inputs: icol = (x,y) is the chromaticity value 00919 YY is the corresponding luminance value 00920 Outputs: ocol = (X,Y,Z) coordinates in the CIE XYZ space 00921 00922 Returns: - 00923 Purpose: To convert the given x, y and Y to X, Y and Z in CIE XYZ space 00924 ********************************************************************************************/ 00925 void PaletteFilter::ConvertCIEtoXYZ(const Vector3D& icol, Vector3D& ocol) 00926 { 00927 double d = icol.z / icol.y; 00928 00929 ocol.x = icol.x * d; 00930 ocol.y = icol.z; 00931 ocol.z = (1.0 - icol.x - icol.y) * d; 00932 } 00933 00934 00935 /******************************************************************************************** 00936 > void PaletteFilter::ConvertLABToRGB(const Vector3D& icol, Vector3D* ocol) 00937 00938 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 00939 Created: 10/5/96 00940 Inputs: icol = (x, y, z) - Lab colour (0..100, -128..127, -128..127) 00941 Outputs: ocol = (x, y, z) - RGB colour (0..1, 0..1, 0..1) 00942 Returns: - 00943 Purpose: To convert the given Lab colour to a (near) equivelent RGB colour 00944 This uses the above conversion functions from Mike. They are *not* accurate 00945 but do give a reasonable approximation of the colour. 00946 ********************************************************************************************/ 00947 void PaletteFilter::ConvertLABToRGB(const Vector3D& icol, Vector3D* ocol) 00948 { 00949 // First calculate a XYZ white point 00950 Vector3D CIEWhite = Vector3D(0.3127, 0.3290, 1.0 ); 00951 Vector3D XYZWhite; 00952 PaletteFilter::ConvertCIEtoXYZ(CIEWhite, XYZWhite); 00953 00954 Vector3D LabAsXYZ; 00955 PaletteFilter::ConvertLABtoXYZ(XYZWhite, icol, LabAsXYZ); 00956 00957 // Finally convert XYZ to RGB 00958 Vector3D RGB; 00959 PaletteFilter::ConvertXYZToRGB(LabAsXYZ, RGB); 00960 00961 ocol->x = ClampZeroToOne( pow(RGB.x, 1.0/2.5) ); 00962 ocol->y = ClampZeroToOne( pow(RGB.y, 1.0/2.5) ); 00963 ocol->z = ClampZeroToOne( pow(RGB.z, 1.0/2.5) ); 00964 } 00965 00966 00967 00968 /******************************************************************************************** 00969 00970 > BOOL PaletteFilter::AddColourToGallery(PalettePrefix Prefix, String_64 *Name, 00971 ColourGeneric *Definition, ColourModel Model, 00972 BOOL NewlineAfter = FALSE, IsSpotColour = FALSE) 00973 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00974 Created: 8/8/96 00975 Inputs: Prefix - Indicates a standard library prefix which should be prepended 00976 to the name (remembering the prefix ID is much better than 00977 storing a great long string in every colour) 00978 Name - the name 00979 Definition - the colour definition 00980 Model - The colour model that Definition is given in 00981 NewlineAfter - TRUE to hint to the colour gallery that it should divide 00982 the colour items (by starting a new line in the display) in order to 00983 display them more usefully. 00984 00985 Returns: TRUE if it succeeeds 00986 00987 Purpose: Sticks the given colour into the colour gallery 00988 00989 ********************************************************************************************/ 00990 00991 BOOL PaletteFilter::AddColourToGallery(PalettePrefix Prefix, String_64 *Name, 00992 ColourGeneric *Definition, ColourModel Model, 00993 BOOL NewlineAfter, BOOL IsSpotColour) 00994 { 00995 #if !defined(EXCLUDE_FROM_RALPH) && !defined(EXCLUDE_FROM_XARALX) 00996 if (CurrentGalleryGroup == NULL) 00997 return(FALSE); 00998 00999 // Create a new DocColour for this colour 01000 DocColour NewCol(Model, Definition); 01001 01002 if (Prefix == PalettePrefix_Pantone || Prefix == PalettePrefix_PantoneSpot) 01003 { 01004 // Set the "PANTONE bodge" flag which rounds the colour components to the nearest half percent. 01005 // This gets around errors introduced by storing the 200 possible half-percent values in a 0-255 BYTE 01006 NewCol.ForceRounding(TRUE); 01007 } 01008 01009 SGDisplayLibColour *NewItem = new SGDisplayLibColour(&NewCol, Name, Prefix, NewlineAfter, IsSpotColour); 01010 if (NewItem == NULL) 01011 return(FALSE); 01012 01013 CurrentGalleryGroup->AddItem(NewItem); 01014 #endif 01015 return(TRUE); 01016 } 01017 01018 01019 01020 01021 01022 01023 /******************************************************************************************** 01024 > CorelPaletteFilter::CorelPaletteFilter() 01025 01026 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 01027 Created: 15 03 95 01028 Inputs: As for the Filter class 01029 Returns: As for the Filter class 01030 Purpose: Constructor 01031 SeeAlso: Filter 01032 ********************************************************************************************/ 01033 CorelPaletteFilter::CorelPaletteFilter() 01034 { 01035 // Set up filter descriptions. 01036 FilterName.Load(_R(IDT_CORELPALETTEFILTER_FILTERNAME)); 01037 FilterInfo.Load(_R(IDT_CORELPALETTEFILTER_FILTERINFO)); 01038 FilterID = FILTERID_CORELPALETTEFILE; 01039 01040 #ifndef STANDALONE 01041 Flags.CanImport = TRUE; 01042 Flags.CanExport = FALSE; 01043 #else 01044 Flags.CanImport = FALSE; 01045 Flags.CanExport = FALSE; 01046 #endif 01047 01048 #ifndef DO_EXPORT 01049 Flags.CanExport = FALSE; 01050 #endif 01051 01052 m_FileVersion = CPL_FVU; 01053 } 01054 01055 01056 /******************************************************************************************** 01057 > BOOL CorelPaletteFilter::Init(void) 01058 01059 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 01060 Created: 15 03 95 01061 Inputs: As for the Filter class 01062 Returns: As for the Filter class 01063 Purpose: Initialisation 01064 SeeAlso: Filter 01065 ********************************************************************************************/ 01066 BOOL CorelPaletteFilter::Init(void) 01067 { 01068 // Get the OILFilter object 01069 pOILFilter = new CorelPaletteFileOILFilter(this); 01070 if (pOILFilter == NULL) 01071 return FALSE; 01072 01073 // All ok 01074 return TRUE; 01075 } 01076 01077 01078 /******************************************************************************************** 01079 > INT32 CorelPaletteFilter::HowCompatible(PathName& Filename, ADDR HeaderStart, 01080 UINT32 HeaderSize, UINT32 FileSize) 01081 01082 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 01083 Created: 15 03 95 01084 Inputs: As for the Filter class 01085 Returns: As for the Filter class 01086 Purpose: Examines a file to see how compatable it is with this filter. 01087 SeeAlso: Filter 01088 ********************************************************************************************/ 01089 INT32 CorelPaletteFilter::HowCompatible(PathName& Filename, ADDR HeaderStart, UINT32 HeaderSize, UINT32 FileSize) 01090 { 01091 PORTNOTE("byteorder", "TODO: Check byte ordering") 01092 // Check the filetype matches 01093 if (!pOILFilter->DoesExtensionOfPathNameMatch(&Filename)) 01094 return 0; 01095 01096 m_FileVersion = CPL_FVU; 01097 01098 // is it a .pal file (textualally based)? 01099 INT32 result = 0; 01100 if ((result = HowCompatible4(Filename, HeaderStart, HeaderSize, FileSize)) != 0) 01101 return result; 01102 01103 // is it a .cpl file (binary)? 01104 if ((result = HowCompatible5(Filename, HeaderStart, HeaderSize, FileSize)) != 0) 01105 return result; 01106 01107 // it's not a palette file. 01108 return 0; 01109 } 01110 01111 01112 /******************************************************************************************** 01113 > INT32 CorelPaletteFilter::HowCompatible4(PathName& Filename, ADDR HeaderStart, 01114 UINT32 HeaderSize, UINT32 FileSize) 01115 01116 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 01117 Created: 17 03 95 01118 Inputs: As for the Filter class 01119 Returns: As for the Filter class 01120 Purpose: Examines a file to see how compatable it is with this filter - checks for 01121 version 3 and 4 .pal files (textual CMYK only) 01122 SeeAlso: Filter 01123 ***************