00001 // $Id: maskfilt.cpp 1634 2006-08-01 13:09:37Z luke $ 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 // A PNG import/export filter 00100 00101 #include "camtypes.h" 00102 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00103 //#include "docview.h" // DocView - in camtypes.h [AUTOMATICALLY REMOVED] 00104 #include "maskfilt.h" 00105 //#include "dibutil.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00106 //#include "wbitmap.h" // Windows specific bitmap information 00107 #include "grndbmp.h" 00108 #include "maskedrr.h" // MaskedRenderRegion derived off GRenderBitmap 00109 #include "bmpcomp.h" // BitmapListComponent 00110 //#include "richard2.h" // resource strings _R(IDS_GIFFILTR_FAILED_MASK) 00111 //#include "resource.h" // Inform Warning _R(IDS_OK) 00112 //#include "will3.h" // for _R(IDS_GENOPTPALMSGID) 00113 //#include "bmpres.h" // general bitmap filter based resources (_R(IDE_TIGIFFILTER_MASKFAILED)/MASK) 00114 //#include "bmpfiltr.h" // for GetDefaultDither() 00115 //#include "outptdib.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00116 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00117 #include "bmapprev.h" // To get the current transparent colour 00118 #include "exjpeg.h" 00119 //#include "cxfrec.h" // for CXaraFileRecord - in camtypes.h [AUTOMATICALLY REMOVED] 00120 //#include "mrhbits.h" // For CBMPBits. 00121 #include "selall.h" // For OPTOKEN_EDITSELECTALL. 00122 #include "palman.h" // For PaletteManager. 00123 //#include "ink.h" // For DeselectAll. - in camtypes.h [AUTOMATICALLY REMOVED] 00124 #include "layer.h" 00125 //#include "spread.h" // For the spread interface. - in camtypes.h [AUTOMATICALLY REMOVED] 00126 #include "page.h" // For the page interface. 00127 00128 CC_IMPLEMENT_DYNAMIC(MaskedFilter, BaseBitmapFilter) 00129 00130 #define new CAM_DEBUG_NEW 00131 00132 CC_IMPLEMENT_DYNAMIC(MaskedFilterExportOptions, BitmapExportOptions) 00133 00134 PALETTE MaskedFilterExportOptions::g_Palette = PAL_OPTIMISED; 00135 DITHER MaskedFilterExportOptions::g_Dither = XARADITHER_NONE; // Webster <RanbiR> Intialise the 00136 // global dither type to No Dither. 00137 BOOL MaskedFilterExportOptions::g_bTransparent; 00138 BOOL MaskedFilterExportOptions::g_bInterlaced; 00139 // WEBSTER - markn 17/1/97 00140 UINT32 BitmapExportOptions::g_NumColsInPalette = 256; 00141 BOOL BitmapExportOptions::g_UseSystemColours = FALSE; 00142 00143 /******************************************************************************************** 00144 00145 > static BOOL MaskedFilterExportOptions::Declare() 00146 00147 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> (from Peter) 00148 Created: 29/10/96 00149 Returns: TRUE if successfully declared preferences 00150 FALSE otherwise 00151 Purpose: To declare preferences associated with these export options 00152 00153 ********************************************************************************************/ 00154 BOOL MaskedFilterExportOptions::Declare() 00155 { 00156 if (Camelot.DeclareSection(_T("Filters"), 10)) 00157 { 00158 Camelot.DeclarePref( NULL, _T("Palette"), (INT32*)&g_Palette, 0, 1 ); 00159 Camelot.DeclarePref( NULL, _T("NumColsInPalette"), (INT32*)&g_NumColsInPalette, 0, 256 ); 00160 Camelot.DeclarePref( NULL, _T("UseSystemColours"), (INT32*)&g_UseSystemColours, 0, 1 ); 00161 } 00162 00163 // All ok 00164 return TRUE; 00165 } 00166 00167 /******************************************************************************************** 00168 > MaskedFilterExportOptions::MaskedFilterExportOptions() 00169 00170 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00171 Created: 29/10/96 00172 Inputs: Dialog : 00173 pFilterName : the name of the filter 00174 Purpose: Default constructor 00175 Notes: This is a base class for GIF, PNG, etc.. Since MakedFilter doesn't provide a 00176 CreateExportOptions() member subclasses should either derive a new class from 00177 this one or provide objects of this class in their CreateExportOptions() 00178 ********************************************************************************************/ 00179 MaskedFilterExportOptions::MaskedFilterExportOptions() 00180 : m_Dither(XARADITHER_NONE), // Dither type 00181 m_bInterlaced(FALSE) 00182 { 00183 m_NumColsInPalette = g_NumColsInPalette; // override base class 00184 m_UseSystemColours = g_UseSystemColours; 00185 } 00186 00187 /******************************************************************************************** 00188 > MaskedFilterExportOptions::MaskedFilterExportOptions(const CDlgResID& Dialog, 00189 const FilterType FilterID, const StringBase* pFilterName) 00190 00191 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00192 Created: 29/10/96 00193 Inputs: Dialog : 00194 pFilterName : the name of the filter 00195 Purpose: Constructor 00196 Notes: This is a base class for GIF, PNG, etc.. Since MakedFilter doesn't provide a 00197 CreateExportOptions() member subclasses should either derive a new class from 00198 this one or provide objects of this class in their CreateExportOptions() 00199 ********************************************************************************************/ 00200 MaskedFilterExportOptions::MaskedFilterExportOptions(const CDlgResID& Dialog, 00201 const FilterType FilterID, const StringBase* pFilterName) 00202 : BitmapExportOptions(Dialog, FilterID, pFilterName), 00203 m_Dither(XARADITHER_NONE), // Dither type 00204 m_bInterlaced(FALSE) 00205 { 00206 m_NumColsInPalette = g_NumColsInPalette; // override base class 00207 m_UseSystemColours = g_UseSystemColours; 00208 } 00209 00210 /******************************************************************************************** 00211 00212 > virtual BOOL MaskedFilterExportOptions::CopyFrom(BitmapExportOptions *pSource) 00213 00214 Author: Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> 00215 Created: 19/05/97 00216 Inputs: pSource - the other BitmapExportOptions object to copy the data from 00217 Purpose: Sets the contents of this object from the passed object 00218 See Also: BitmapExportOptions::MakeCopy() 00219 00220 ********************************************************************************************/ 00221 BOOL MaskedFilterExportOptions::CopyFrom(BitmapExportOptions *pSource) 00222 { 00223 // copy the base class first 00224 if (!BitmapExportOptions::CopyFrom(pSource)) 00225 return FALSE; 00226 00227 // must be the same class, otherwise the base class function above returns FALSE 00228 MaskedFilterExportOptions *pOther = (MaskedFilterExportOptions *)pSource; 00229 00230 m_Dither = pOther->m_Dither; 00231 m_bInterlaced = pOther->m_bInterlaced; 00232 00233 return TRUE; 00234 } 00235 00236 /****************************************************************************************** 00237 00238 > BOOL MaskedFilterExportOptions::FileTypeChangeCopyFrom(BitmapExportOptions *pOther) 00239 00240 Author: Alex_Price (Xara Group Ltd) <camelotdev@xara.com> 00241 Created: 15/10/99 00242 Inputs: pOther - A BitmapExportOptions object we want to make a copy of. 00243 Returns: - 00244 Purpose: Copies the information from the BitmapExportOptions object 00245 passed in as the argument to the variables in this class 00246 00247 ******************************************************************************************/ 00248 BOOL MaskedFilterExportOptions::FileTypeChangeCopyFrom(BitmapExportOptions *pOther) 00249 { 00250 // Do the base class piece first 00251 if ( !BitmapExportOptions::FileTypeChangeCopyFrom( pOther ) ) 00252 return FALSE; 00253 00254 MaskedFilterExportOptions* pOther2 = ( MaskedFilterExportOptions* )pOther; 00255 00256 PORTNOTE("BMPFilter", "Removed use of BmpExportOptions") 00257 #ifndef EXCLUDE_FROM_XARALX 00258 if ( pOther->IS_KIND_OF(BMPExportOptions) ) 00259 { 00260 m_Dither = pOther2->m_Dither; 00261 // The following 2 don't exist in the bmp options. 00262 m_bInterlaced = 0; 00263 } 00264 else 00265 #endif 00266 if ( pOther->IS_KIND_OF(JPEGExportOptions) ) 00267 { 00268 // None of these exist in the jpeg options. 00269 // So, give them default values. 00270 m_Dither = g_Dither; 00271 m_bInterlaced = 0; 00272 } 00273 else 00274 { 00275 // Just copy them over 00276 m_Dither = pOther2->m_Dither; 00277 m_bInterlaced = pOther2->m_bInterlaced; 00278 } 00279 00280 return TRUE; 00281 } 00282 00283 /******************************************************************************************** 00284 00285 > virtual BOOL MaskedFilterExportOptions::Equal(BitmapExportOptions *pSource) 00286 00287 Author: Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> 00288 Created: 19/05/97 00289 Inputs: pSource - the other BitmapExportOptions object to copy the data from 00290 Purpose: Compares the contents of this and pOther objects 00291 Returns: TRUE, if objects are equal, FALSE otherwise 00292 See Also: BitmapExportOptions::MakeCopy() 00293 00294 ********************************************************************************************/ 00295 /* 00296 BOOL MaskedFilterExportOptions::Equal(BitmapExportOptions *pSource) 00297 { 00298 BOOL ok = TRUE; 00299 00300 // compare the base classes first 00301 ok = BitmapExportOptions::Equal(pSource); 00302 00303 // must be the same class, otherwise the base class function above returns FALSE 00304 MaskedFilterExportOptions *pOther = (MaskedFilterExportOptions *)pSource; 00305 00306 if (ok) ok = (m_Dither == pOther->m_Dither); 00307 if (ok) ok = (m_bInterlaced == pOther->m_bInterlaced); 00308 return ok; 00309 } 00310 */ 00311 00312 /******************************************************************************************** 00313 00314 > BOOL MaskedFilterExportOptions::CopyFromMasked(MaskedFilterExportOptions *pOther) 00315 00316 Author: Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> 00317 Created: 15/07/97 00318 Inputs: pOther - the other MaskedFilterExportOptions object to copy the data from 00319 Purpose: Sets the contents of this object from the passed object. This differs form the 00320 more general function in that it doesn't require the two objects to be of the 00321 same class. Used to convert from/to PNG options and MakeBitmapExportOptions. 00322 See Also: BitmapExportOptions::MakeCopy() 00323 00324 ********************************************************************************************/ 00325 BOOL MaskedFilterExportOptions::CopyFromMasked(MaskedFilterExportOptions *pOther) 00326 { 00327 if (pOther == NULL) 00328 return FALSE; 00329 00330 //BitmapExportOptions members 00331 m_SelectionType = pOther->m_SelectionType; 00332 m_OutputSize = pOther->m_OutputSize; 00333 m_PixelOutputSize = pOther->m_PixelOutputSize; 00334 m_pBmpDlgParam = pOther->m_pBmpDlgParam; 00335 m_NumColsInPalette = pOther->m_NumColsInPalette; 00336 m_UseSystemColours = pOther->m_UseSystemColours; 00337 m_bSeparateLayerFiles = pOther->m_bSeparateLayerFiles; 00338 m_bTempFileFlag = pOther->m_bTempFileFlag; 00339 00340 SetDPI(pOther->GetDPI()); 00341 SetDepth(pOther->GetDepth()); 00342 SetTransparencyIndex(pOther->GetTransparencyIndex()); 00343 if (pOther->IsValid()) 00344 MarkValid(); 00345 else 00346 MarkInvalid(); 00347 00348 //MaskedFilterExportOptions 00349 m_Dither = pOther->m_Dither; 00350 m_bInterlaced = pOther->m_bInterlaced; 00351 00352 return TRUE; 00353 } 00354 00355 /******************************************************************************************** 00356 00357 > virtual BOOL MaskedFilterExportOptions::RetrieveDefaults() 00358 00359 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00360 Created: 29/10/96 00361 Purpose: See BitmapExportOptions for interface details 00362 Notes: Gets MaskedFilter specific preferences (compression mainly) 00363 00364 ********************************************************************************************/ 00365 BOOL MaskedFilterExportOptions::RetrieveDefaults() 00366 { 00367 if (!BitmapExportOptions::RetrieveDefaults()) 00368 return FALSE; 00369 00370 PORTNOTE("BMPFilter", "Remove use of GetDefaultExportDither") 00371 #ifndef EXCLUDE_FROM_XARALX 00372 UINT32 Dither = BMPFilter::GetDefaultExportDither(); 00373 ERROR2IF(Dither > 4, FALSE, "Dither Invalid"); 00374 #else 00375 UINT32 Dither = 0; 00376 #endif 00377 SetDither((DITHER)Dither); 00378 00379 m_Dither = g_Dither; 00380 m_NumColsInPalette = g_NumColsInPalette; 00381 m_UseSystemColours = g_UseSystemColours; 00382 00383 return TRUE; 00384 } 00385 00386 /******************************************************************************************** 00387 00388 > virtual BOOL MaskedFilterExportOptions::SetAsDefaults() const 00389 00390 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00391 Created: 29/10/96 00392 Purpose: See BitmapExportOptions for interface details 00393 Notes: Sets MaskedFilter specific preferences 00394 00395 ********************************************************************************************/ 00396 BOOL MaskedFilterExportOptions::SetAsDefaults() const 00397 { 00398 PORTNOTE("BMPFilter", "Removed use of BmpExportOptions") 00399 #ifndef EXCLUDE_FROM_XARALX 00400 if (!BitmapExportOptions::SetAsDefaults()) 00401 return FALSE; 00402 00403 BMPFilter::SetDefaultExportDither(GetDither()); 00404 #endif 00405 00406 // Derived classes can do their own thing with these... 00407 // m_bInterlaced; 00408 g_Dither = m_Dither; 00409 g_NumColsInPalette = m_NumColsInPalette; 00410 g_UseSystemColours = m_UseSystemColours; 00411 00412 return TRUE; 00413 } 00414 00415 /******************************************************************************************** 00416 > virtual BOOL MaskedFilterExportOptions::Write(CXaraFileRecord* pRec) 00417 00418 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00419 Created: 21/2/00 00420 Inputs: pRec --- record to write 00421 Returns: TRUE if successful. 00422 Purpose: Writes this object to the given record. 00423 SeeAlso: MaskedFilterExportOptions::Read 00424 ********************************************************************************************/ 00425 BOOL MaskedFilterExportOptions::Write(CXaraFileRecord* pRec) 00426 { 00427 return BitmapExportOptions::Write(pRec) && 00428 pRec->WriteINT16((INT16) m_Dither) && 00429 pRec->WriteINT16((INT16) 0 /*m_Palette*/) && 00430 pRec->WriteBYTE((BYTE) TRUE) && 00431 pRec->WriteBYTE((BYTE) !!m_bInterlaced); 00432 } 00433 00434 /******************************************************************************************** 00435 > virtual BOOL MaskedFilterExportOptions::Read(CXaraFileRecord* pRec) 00436 00437 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00438 Created: 21/2/00 00439 Inputs: pRec --- record to read 00440 Returns: TRUE if successful. 00441 Purpose: Reads this object from the given record. 00442 SeeAlso: MaskedFilterExportOptions::Write 00443 ********************************************************************************************/ 00444 BOOL MaskedFilterExportOptions::Read(CXaraFileRecord* pRec) 00445 { 00446 BYTE Unused; 00447 INT16 AlsoUnused; 00448 m_bInterlaced = FALSE; 00449 return BitmapExportOptions::Read(pRec) && 00450 pRec->ReadINT16((INT16*) &m_Dither) && 00451 pRec->ReadINT16((INT16*) &AlsoUnused /*m_Palette*/) && 00452 pRec->ReadBYTE(&Unused) && 00453 pRec->ReadBYTEtoBOOL(&m_bInterlaced); 00454 } 00455 00456 /******************************************************************************************** 00457 00458 > BOOL MaskedFilterExportOptions::UseSpecificNumColsInPalette() 00459 00460 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00461 Created: 21/1/97 00462 Returns: TRUE if the options define a specific number of colours in the palette 00463 Purpose: Masked filters have the ability to specify the exact number of colours in the 00464 generated optimised palette. 00465 00466 This only returns TRUE if we are generating a bitmap from objects in the document. 00467 It is not available when exporting a bitmap directly, as it will already have a palette 00468 00469 Introduced for WEBSTER 00470 00471 ********************************************************************************************/ 00472 BOOL MaskedFilterExportOptions::UseSpecificNumColsInPalette() 00473 { 00474 // Don't use specific num colours when exporting bitmaps 00475 return (GetSelectionType() != ABITMAP && GetSelectionType() != SOMEBITMAPS); 00476 } 00477 00478 /******************************************************************************************** 00479 00480 > BOOL MaskedFilterExportOptions::SetDither(const DITHER& Dither) 00481 00482 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00483 Created: 29/10/96 00484 Inputs: Dither : The desired dither to be applied to the bitmap before being exported 00485 Returns: TRUE if set successfully 00486 FALSE otherwise 00487 Purpose: Support function to set up information for the ensuing export 00488 See Also: GetDither() 00489 00490 ********************************************************************************************/ 00491 BOOL MaskedFilterExportOptions::SetDither(const DITHER& Dither) 00492 { 00493 if (m_Dither != Dither) 00494 SetTempFileMatchesExportOptions(FALSE); 00495 m_Dither = Dither; 00496 return TRUE; 00497 } 00498 00499 /******************************************************************************************** 00500 00501 > BOOL MaskedFilterExportOptions::WantTransparent() const 00502 00503 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00504 Created: 29/10/96 00505 Returns: TRUE if the bitmap should be exported interlaced, FALSE not 00506 Purpose: Support function to obtain export options 00507 See Also: SetMakeTransparent() 00508 00509 ********************************************************************************************/ 00510 BOOL MaskedFilterExportOptions::WantTransparent() const 00511 { 00512 // smfix - only go on the transp index 00513 return GetTransparencyIndex() != -1; 00514 } 00515 00516 /******************************************************************************************** 00517 00518 > BOOL MaskedFilterExportOptions::SetMakeInterlaced(BOOL bInterlaced) 00519 00520 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00521 Created: 29/10/96 00522 Inputs: bInterlaced : TRUE to indicate the exported bitmap should be interlaced 00523 ...somehow; FALSE for normal non-interlaced mode 00524 Returns: TRUE if set successfully 00525 FALSE otherwise 00526 Purpose: Support function to set up information for the ensuing export 00527 See Also: WantInterlaced() 00528 00529 ********************************************************************************************/ 00530 BOOL MaskedFilterExportOptions::SetMakeInterlaced(BOOL bInterlaced) 00531 { 00532 if (m_bInterlaced != bInterlaced) 00533 SetTempFileMatchesExportOptions(FALSE); 00534 m_bInterlaced = bInterlaced; 00535 return TRUE; 00536 } 00537 00538 00539 /******************************************************************************************** 00540 00541 > MaskedFilter::MaskedFilter() 00542 00543 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00544 Created: 10/7/96 00545 Purpose: Constructor for an MaskedFilter object. The object should be initialised 00546 before use. 00547 SeeAlso: MaskedFilter::Init 00548 00549 ********************************************************************************************/ 00550 00551 MaskedFilter::MaskedFilter() 00552 { 00553 // Used for storing the 8bpp mask until after the second pass is completed 00554 pDestBMInfo = NULL; 00555 pDestBMBytes = NULL; 00556 pTempBitmapMask = NULL; 00557 00558 // Initalise flags 00559 SecondPass = FALSE; 00560 DoingMask = FALSE; 00561 TransColour = -1; // -1 == none, or the transparent colour. 00562 CurrentScanline = 0; 00563 00564 // We don't have any bands to work with yet. 00565 m_BandNumber = 0; 00566 m_bSelection = TRUE; 00567 } 00568 00569 /******************************************************************************************** 00570 00571 > BOOL MaskedFilter::Init() 00572 00573 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 00574 Created: 10/7/96 00575 Returns: TRUE if the filter was initialised ok, FALSE otherwise. 00576 Purpose: Initialise a MaskedFilter object. 00577 00578 ********************************************************************************************/ 00579 BOOL MaskedFilter::Init() 00580 { 00581 return MaskedFilterExportOptions::Declare(); 00582 } 00583 00584 /******************************************************************************************** 00585 00586 > BOOL MaskedFilter::ApplyTransparentColoursToBitmap(KernelBitmap* pExportBitmap, 00587 BitmapExportOptions* pExportOptions) 00588 00589 Author: Mark_Howitt (Xara Group Ltd) <camelotdev@xara.com> 00590 Created: 10/11/00 00591 Inputs: pExportBitmap - the Bitmap to do the work on. 00592 pExportOptions - A pointer to the options to be applied. 00593 Returns: TRUE if everything went ok! 00594 Purpose: Same as the other flavour of this function. 00595 00596 ********************************************************************************************/ 00597 BOOL MaskedFilter::ApplyTransparentColoursToBitmap(KernelBitmap* pExportBitmap, BitmapExportOptions* pExportOptions) 00598 { 00599 // Check the passed in Variables 00600 if(!pExportBitmap || !pExportOptions) 00601 { 00602 ERROR3("Failed to get valid pointers!"); 00603 return FALSE; 00604 } 00605 00606 // Now get the info and data from the passed in Bitmap 00607 BITMAPINFOHEADER* pInfoHeader = pExportBitmap->GetBitmapInfoHeader(); 00608 BYTE* pBMPBits = pExportBitmap->GetBitmapBits(); 00609 00610 // Call the second version of this function 00611 return ApplyTransparentColoursToBitmap(pInfoHeader,pBMPBits,pExportOptions); 00612 } 00613 00614 /******************************************************************************************** 00615 00616 > BOOL MaskedFilter::ApplyTransparentColoursToBitmap(BITMAPINFOHEADER* pInfoHeader, 00617 BYTE* pBMPBits, 00618 BitmapExportOptions* pExportOptions, 00619 UINT32 YOffset, UINT32 StripHeight) 00620 00621 Author: Mark_Howitt (Xara Group Ltd) <camelotdev@xara.com> 00622 Created: 10/11/00 00623 Inputs: pInfoHeader - the header to the Bitmap to do the work on. 00624 pBMPBits - the bits to the Bitmap to do the work on. 00625 pExportOptions - A pointer to the options to be applied. 00626 YOffset - The number of lines into the bitmap to start from. 00627 StripHeight - The height of the current clip. 00628 Returns: TRUE if everything went ok! 00629 Purpose: Sets the relavent bits of the bitmap to transparent depending 00630 on the given options. 00631 00632 ********************************************************************************************/ 00633 BOOL MaskedFilter::ApplyTransparentColoursToBitmap(BITMAPINFOHEADER* pInfoHeader, BYTE* pBMPBits, 00634 BitmapExportOptions* pExportOptions, UINT32 YOffset, UINT32 StripHeight) 00635 { 00636 // Check the passed in pointers! 00637 if(!pInfoHeader || !pBMPBits || !pExportOptions) 00638 { 00639 ERROR3("Failed to get valid pointers!"); 00640 return FALSE; 00641 } 00642 00643 // Get the current Export palette and find out how many colours we`re using. 00644 ExtendedPalette* pPal = pExportOptions->GetPalette(); 00645 ERROR3IF(!pPal,"Failed to get a valid palette pointer!"); 00646 00647 INT32 NumOfTranspColours = 0; 00648 INT32 TransColour[256]; 00649 00650 // First get the Transparency index and the check the background status; 00651 INT32 TranspIndex = pExportOptions->GetTransparencyIndex(); 00652 BOOL TransparentBackground = pExportOptions->IsBackgroundTransparent(); 00653 INT32 flag = 0; 00654 00655 if(pPal) 00656 { 00657 // Loop through the colours getting all the one that are marked transparent! 00658 for(INT32 i = 0; i < pPal->NumberOfColours; i++) 00659 { 00660 flag = pPal->Data[i].Flags; 00661 00662 // If we have the backgroung as transparent then we need to make sure we don`t 00663 // include it in the locked colour checking! 00664 if((flag & TRANSPARENT_COLOUR) && !(TransparentBackground && i == TranspIndex)) 00665 TransColour[NumOfTranspColours++] = i; 00666 } 00667 } 00668 00669 // Make sure we`re not doing something stupid! 00670 if(NumOfTranspColours == 0 && !TransparentBackground) 00671 { 00672 ERROR3("What are we tring to do? Durrrr!"); 00673 return FALSE; 00674 } 00675 00676 GRenderBitmap* pMaskedRegion = NULL; 00677 BITMAPINFO* pAlphaInfo = NULL; 00678 BYTE* pAlphaBits = NULL; 00679 00680 // If we want a transparent background then we need to get a 32Bit Alpha BMP! 00681 if(TransparentBackground) 00682 { 00683 // Create a new 32bpp export region with alpha channel info! 00684 // Don't use rendering matrix when exporting BMPs as it uses coordinates as is 00685 Matrix Identity; 00686 FIXED16 Scale(1); 00687 pMaskedRegion = new GRenderBitmap(ClipRect, Identity, Scale, 32, pExportOptions->GetDPI(),FALSE,0,NULL,TRUE); 00688 00689 // If the render region was not created, drop out of this function. 00690 if ( pMaskedRegion == NULL ) 00691 return FALSE; 00692 00693 pMaskedRegion->SetFilter(this); 00694 00695 // Now make sure we set the compression flag to enable transpareny info! 00696 pMaskedRegion->m_DoCompression = TRUE; 00697 pMaskedRegion->SetRenderComplexShapes(TRUE); 00698 RRCaps NewCaps; 00699 NewCaps.CanDoNothing(); 00700 00701 DocView *View = DocView::GetCurrent(); 00702 00703 if (View) 00704 { 00705 // Must force background rendering off as otherwise we might get a partly 00706 // rendered drawing or object if it is complex. 00707 // We have already remembered the entry state so just force it. 00708 ForceBackgroundRedrawOff(View); 00709 00710 // ERROR3IF ( GetBitmapExportOptions()->GetDepth() == -1, 00711 // "Illegal Output Depth in MaskedFilter::RenderTransparencyMask" ); 00712 00713 if (GetBitmapExportOptions()->GetDepth() == 1) 00714 { 00715 // If we are outputting at 1bpp, then we'll force antialiasing off, 00716 // so that Gavin's palette optimisation can detect objects which 00717 // are 'one solid colour' 00718 ForceAntialiasingOff(View); 00719 } 00720 00721 // Attach to the right device. (note no DC) 00722 pMaskedRegion->AttachDevice(View, NULL, pSpread); 00723 } 00724 else 00725 ERROR2(FALSE,"MaskedFilter::RenderTransparencyMask no current view"); 00726 00727 // Export the data from the view into the 1bpp region we have, ensuring rendering 00728 // in strips is off 00729 RenderInStrips = FALSE; 00730 00731 // Now render everything into the new 32Bit Alpha channel region! 00732 if (!ExportRender(pMaskedRegion, TRUE)) 00733 { 00734 // If we have created the export region then delete it so that we free up 00735 // its huge wadges of memory (as its 32bpp deep!). 00736 delete pMaskedRegion; 00737 pMaskedRegion = NULL; 00738 00739 return FALSE; 00740 } 00741 00742 // Now get the info from the 32bit render region 00743 if(!pMaskedRegion->GetBitmapData(&pAlphaInfo,&pAlphaBits)) 00744 { 00745 delete pMaskedRegion; 00746 pMaskedRegion = NULL; 00747 return FALSE; 00748 } 00749 00750 // Check to see if we`ve got Identically dimensioned Bitmaps! 00751 if(pInfoHeader->biWidth != pAlphaInfo->bmiHeader.biWidth || 00752 (YOffset + StripHeight) > (UINT32)pAlphaInfo->bmiHeader.biHeight) 00753 { 00754 delete pMaskedRegion; 00755 pMaskedRegion = NULL; 00756 return FALSE; 00757 } 00758 } 00759 00760 // make a DWORD Pointer to the Alpha Channel bits 00761 DWORD* pAlpha = (DWORD*)pAlphaBits; 00762 00763 // Now get the scanline width for the current bitmap. This will be in multiples of BYTEs 00764 INT32 ScanLineWidth = DIBUtil::ScanlineSize(pInfoHeader->biWidth,pExportOptions->GetDepth()); 00765 INT32 Depth = pExportOptions->GetDepth(); 00766 INT32 PixelsPerByte = 8 / Depth; 00767 00768 // Get the width in pixels for the 32 bit bitmap 00769 INT32 Width32 = pInfoHeader->biWidth / PixelsPerByte; 00770 INT32 SubWidth32 = pInfoHeader->biWidth % PixelsPerByte; 00771 INT32 Scanline = 0; 00772 INT32 StartingPos = 0; 00773 INT32 PixelPos = 0; 00774 INT32 SubPixPos = 0; 00775 INT32 NumOfSubPixels = 0; 00776 INT32 PixelsPerLine = 0; 00777 INT32 i = 0; 00778 INT32 j = 0; 00779 DWORD ByteData = 0x0; 00780 BOOL Padding = FALSE; 00781 UINT32 StripOffset = 0; 00782 UINT32 NoOfLines = StripHeight; 00783 00784 // As 8Bit, 4Bit and 1Bit BMPs are DWORD Alligned, we need to be a little clever in making sure we don`t 00785 // Over run the 32Bit Scanlines! What we need to do is workout exactly how many bytes/bits we really have 00786 // as bitmap! 00787 // As 8Bit BMPs are BYTE Alligned, we don`t need to anything special and just use the bitmap width as is! 00788 // 4Bit is a little more probmatic in that it uses Half Bytes and even worse is 1Bit BMPs! 00789 00790 if(NoOfLines == 0) 00791 NoOfLines = pInfoHeader->biHeight; 00792 00793 if(YOffset > 0) 00794 { 00795 i = ((Width32 * PixelsPerByte) + SubWidth32) * YOffset; 00796 StripOffset = YOffset; 00797 } 00798 00799 // Loop through line by line setting up the transparency information 00800 for (Scanline = StripOffset; (UINT32)Scanline < NoOfLines + StripOffset; Scanline++) 00801 { 00802 StartingPos = Scanline * ScanLineWidth; 00803 PixelsPerLine = StartingPos + Width32; 00804 00805 if(SubWidth32 > 0) 00806 { 00807 PixelsPerLine++; 00808 } 00809 00810 for(PixelPos = StartingPos; PixelPos < PixelsPerLine; PixelPos++) 00811 { 00812 // Get the current Byte of BMP Data at the current Position 00813 // ByteData = _rotr(pBMPBits[PixelPos],8); 00814 ByteData = pBMPBits[PixelPos]>>8 | pBMPBits[PixelPos]<<24; 00815 00816 NumOfSubPixels = PixelsPerByte; 00817 00818 if(PixelPos == StartingPos + Width32) 00819 NumOfSubPixels = SubWidth32; 00820 00821 // Now loop through all the Sub Byte Pixels setting their appropriate values 00822 for(SubPixPos = 0; SubPixPos < PixelsPerByte; SubPixPos++) 00823 { 00824 // ByteData = _rotl(ByteData,Depth); 00825 ByteData = ByteData<<8 | ByteData>>24; 00826 Padding = (SubPixPos >= NumOfSubPixels); 00827 00828 // First check to see if the alpha channel is fully transparent 00829 if((pAlpha && ((pAlpha[i++] & 0xFF000000) >> 24) == 0xFF) || Padding) 00830 { 00831 if(Padding) 00832 i--; 00833 00834 if(Depth == 8) 00835 { 00836 ByteData = TranspIndex; 00837 } 00838 else if(Depth == 4) 00839 { 00840 ByteData &= 0xFFFFFFF0; // Clear the bits we`re going to replace! 00841 ByteData |= (0xF & TranspIndex); // Now AND it with the TranspIndex 00842 } 00843 else if(Depth == 1) 00844 { 00845 ByteData &= 0xFFFFFFFE; // Clear the bits we`re going to replace! 00846 ByteData |= (0x1 & TranspIndex); // Now AND it with the TranspIndex 00847 } 00848 } 00849 else // If it`s not transparent then check the users transparent colours! 00850 { 00851 for(j = 0; j < NumOfTranspColours; j++) 00852 { 00853 if(Depth == 8 && ByteData == (BYTE)TransColour[j]) 00854 { 00855 ByteData = TranspIndex; 00856 break; 00857 } 00858 else if(Depth == 4 && (0xF & ByteData) == (BYTE)TransColour[j]) 00859 { 00860 ByteData &= 0xFFFFFFF0; // Clear the bits we`re going to replace! 00861 ByteData |= (0xF & TranspIndex); // Now AND it with the TranspIndex 00862 break; 00863 } 00864 else if(Depth == 1 && (0x1 & ByteData) == (BYTE)TransColour[j]) 00865 { 00866 ByteData &= 0xFFFFFFFE; // Clear the bits we`re going to replace! 00867 ByteData |= (0x1 & TranspIndex); // Now AND it with the TranspIndex 00868 break; 00869 } 00870 } 00871 } 00872 } 00873 00874 // Replace the current data with the processed version! 00875 pBMPBits[PixelPos] = (BYTE)ByteData; 00876 } 00877 } 00878 00879 // Now delete the masked region if we created one! 00880 if(pMaskedRegion) 00881 { 00882 delete pMaskedRegion; 00883 pMaskedRegion = NULL; 00884 } 00885 return TRUE; 00886 } 00887 00888 /******************************************************************************************** 00889 00890 > BOOL MaskedFilter::WriteToFile ( void ) 00891 00892 Author: Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com> (From Neville's code.) 00893 Created: 27/6/00 (Originally 24/4/95.) 00894 Returns: TRUE - The export was successful. 00895 FALSE - An error occured. 00896 Purpose: Physically put the bitmap into the disk. 00897 00898 Most of the work now is down by WriteDataToFile as this is a static form 00899 and there is a similar version in the Accusoft DLL. This can therefore be 00900 used to pass work onto the Accusoft DLL, for the cases we don't cope with. 00901 00902 This function was originally duplicated in the TI_GIFFilter, and PNG_Filter, 00903 but have now been rolled into a single function. This makes maintenance 00904 easier, and should reduce code size. 00905 00906 ********************************************************************************************/ 00907 BOOL MaskedFilter::WriteToFile ( BOOL End ) 00908 { 00909 #ifdef DO_EXPORT 00910 00911 if(GeneratingOptimisedPalette()) 00912 return TRUE; // No need to output anything. 00913 00914 BitmapExportOptions* pBMPOptions = GetBitmapExportOptions(); 00915 OutputDIB* pDestDIB = GetOutputDIB(); 00916 00917 LPBITMAPINFO lpBitmapInfo = NULL; 00918 LPBYTE lpBitmapBits = NULL; 00919 LPLOGPALETTE lpPalette = NULL; 00920 00921 // Make sure that valid values have been set. 00922 ERROR2IF ( pBMPOptions == NULL, FALSE, "NULL Args" ); 00923 ERROR2IF ( pDestDIB == NULL, FALSE, "No DIB available for export" ); 00924 00925 // Check that the class variable for the spread to use has been set up in. 00926 ERROR2IF(pSpread==NULL,FALSE,"PNGFilter::WriteToFile spread pointer is null"); 00927 00928 // Increment the band number. 00929 m_BandNumber++; 00930 00931 // Get the bitmap data from the Render Region 00932 ExportRegion->GetBitmapData(&lpBitmapInfo, &lpBitmapBits); 00933 00934 ERROR3IF(lpBitmapBits == NULL, "Bitmap has no data in BMPFilter::WriteDataToFile"); 00935 00936 if (lpBitmapInfo == NULL || lpBitmapBits == NULL) 00937 return FALSE; 00938 00939 // Now call InvertAlpha() - This is for the PNG Derived filter 00940 InvertAlpha(lpBitmapInfo,lpBitmapBits); 00941 00942 // Lets write out a suitable header. 00943 // As we write it in one big chunk (currently), its easy 00944 if (!WrittenHeader) 00945 { 00946 WrittenHeader = TRUE; 00947 00948 LPBITMAPINFO lpInfo = lpBitmapInfo; 00949 ERROR2IF(lpInfo==NULL,FALSE,"PNGFilter::WriteToFile null export region bitmap"); 00950 if (pTempBitmapMask != NULL) 00951 { 00952 TRACEUSER( "SimonK", _T("pTempBitmapMask was not deleted when it should have been")); 00953 CCFree(pTempBitmapMask); 00954 pTempBitmapMask = NULL; 00955 } 00956 00957 // ERROR3IF ( pBMPOptions->GetDepth() == -1, "Illegal OutputDepth in PNGFilter::WriteToFile" ); 00958 00959 // First, get the size of the bitmap we are going to export not just the simple 00960 // lpInfo->bmiHeader.biHeight as this might just be the height of the first 00961 // strip to be exported. With the width we can use the old method. 00962 // const UINT32 OutputWidth = lpInfo->bmiHeader.biWidth; 00963 const UINT32 OutputHeight = (INT32)ExportRegion->GetFullRegionHeight(); 00964 00965 if ( pBMPOptions->GetDepth () == 8 || 00966 pBMPOptions->GetDepth () == 4 || 00967 pBMPOptions->GetDepth () == 1 ) 00968 { 00969 // SMFIX 00970 // get the logical palette from the options 00971 lpPalette = pBMPOptions->GetLogicalPalette(); 00972 } 00973 00974 // Start up the export process and prepare all the bitmaps and files ready for 00975 // the actual bitmap data 00976 // For transparent export we will do this twice so flag which pass we are on. 00977 if ( !pDestDIB->StartFile ( &lpInfo->bmiHeader, 00978 lpPalette, 00979 pBMPOptions->GetDepth(), // actual file depth 00980 Compression, // interlace/transparency 00981 OutputHeight, // all of it 00982 SizeOfExport, // progress bar size 00983 pBMPOptions->GetDither() ) ) // dithering to use 00984 { 00985 return FALSE; 00986 } 00987 } 00988 00989 // Now lets write out our block. This actually just copies the data into our 00990 // destination bitmap. Need to do this so cope with interlacing and transparency 00991 const UINT32 StripHeight = lpBitmapInfo->bmiHeader.biHeight; 00992 00993 // SMFIX - Mark Howitt 00994 // New code to make sure we export with transparency correctly! 00995 INT32 InputBPP = 32; 00996 BYTE* pActualBits = lpBitmapBits; 00997 if ( !pDestDIB->WriteBlock ( 0, // Ypos 00998 StripHeight, // height of this strip 00999 pActualBits, // pointer to actual bitmap data 01000 InputBPP, // input bpp 01001 ProgressOffset ) ) // value to add to progress update 01002 { 01003 return FALSE; 01004 } 01005 01006 // if we have a transparency and we are 8 bit or less 01007 if (pBMPOptions->GetTransparencyIndex() > -1 && pBMPOptions->GetDepth() <= 8) 01008 { 01009 // Now send the intermediate bitmap to the ApplyTransparentColoursToBitmap function 01010 if(!ApplyTransparentColoursToBitmap(&pDestDIB->GetDestBitmapInfo()->bmiHeader,pDestDIB->GetDestBitmapBits(),pBMPOptions,m__StripStart,StripHeight)) 01011 { 01012 ERROR2(FALSE,"Failed to create an intermediate bitmap pointer!"); 01013 } 01014 } 01015 01016 // Add in the height of the strip that we have just exported to the progress offset value 01017 ProgressOffset += StripHeight; 01018 m__StripStart += StripHeight; 01019 #endif 01020 return TRUE; 01021 } 01022 01023 /******************************************************************************************** 01024 01025 > INT32 MaskedFilter::SetTransColour(INT32 NewColour) 01026 01027 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01028 Created: 29/6/95 01029 Inputs: NewColour colour to set as the new transparent colour, -1 if none 01030 Returns: The old transparent colour. 01031 Purpose: To set a new transparent colour. This has most likely been read in from a 01032 GIF file and so needs applying to the bitmap that has just been loaded. 01033 01034 Moved from TI_GIFFilter to MaskedFilter 10/7/96 01035 01036 SeeAlso: TI_GIFFilter::GetTransColour(); 01037 01038 ********************************************************************************************/ 01039 INT32 MaskedFilter::SetTransColour(INT32 NewColour) 01040 { 01041 INT32 OldTransColour = TransColour; 01042 TransColour = NewColour; 01043 01044 return OldTransColour; 01045 } 01046 01047 /******************************************************************************************** 01048 01049 > virtual BOOL MaskedFilter::ExportSelectionOnly() 01050 01051 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01052 Created: 18/09/95 01053 Inputs: - 01054 Outputs: - 01055 Returns: True if this filter wants check if an object is selected or not and so export 01056 only the selected items Or False if want to export everything. 01057 Purpose: Determines if the filter wants to export only selected items. 01058 In the base filters class version the default action will be to 01059 export all objects by default 01060 01061 Moved from TI_GIFFilter to MaskedFilter 10/7/96 01062 01063 SeeAlso: Filter::ExportRender; 01064 01065 ********************************************************************************************/ 01066 BOOL MaskedFilter::ExportSelectionOnly(BOOL MaskedRender) 01067 { 01068 // we dont do any of this secondpass / GeneratingOptimisedPalette bussiness anymore 01069 // that is all done in a nice tight loop. So we would never want to just render the selection 01070 // otherwise the background sometimes disappears which would be odd. sjk 3/1/01 01071 MaskedFilterExportOptions* pMaskedOptions = (MaskedFilterExportOptions*)GetBitmapExportOptions(); 01072 ERROR2IF(pMaskedOptions == NULL, FALSE, "NULL Args"); 01073 ERROR3IF(!pMaskedOptions->IS_KIND_OF(MaskedFilterExportOptions), "pMaskedOptions isn't"); 01074 return (pMaskedOptions->GetSelectionType() == SELECTION && 01075 ((pMaskedOptions->IsBackgroundTransparent() && MaskedRender) 01076 || pMaskedOptions->GetDepth() == 32)); 01077 } 01078 01079 /******************************************************************************************** 01080 01081 > virtual BOOL MaskedFilter::CheckSingleBitmapsOnSpread ( Spread *pSpread, 01082 BOOL *pSamePalettes, 01083 BOOL *pOurBrowserPalette, 01084 BOOL *pAllHaveBitmaps, 01085 BOOL *pAllWithinCount, 01086 UINT32 *pPaletteEntries ) 01087 01088 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01089 Created: 9/7/97 01090 Inputs: pSpread the spread that the bitmaps have been put on 01091 pPaletteEntries Set to the currently requested number of palette entries 01092 Outputs: pSamePalettes Set if the bitmaps have all the same palette 01093 pOurBrowserPalette Set if all bitmaps have our browser palette 01094 pAllHaveBitmaps Set if all the relevant layers have bitmaps on them 01095 pAllWithinCount Set if all the palettes have less entries than required. 01096 pPaletteEntries Set to the max colours in palette found. or number of 01097 palette entries if SamePalettes is true. 01098 Returns: TRUE if was ok, FALSE otherwise. 01099 Purpose: This goes through all bitmaps that are on the layers and sees whether they 01100 have the same palette and whether the palette is the same as our browser 01101 Assumes that each bitmap has been added to a separate layer and that the 01102 referenced bitmap in the layer is set to this loaded bitmap. 01103 SamePalettes and OurBrowserPalettes are just set for the bitmaps found. 01104 01105 ********************************************************************************************/ 01106 BOOL MaskedFilter::CheckSingleBitmapsOnSpread ( Spread *pSpread, 01107 BOOL *pSamePalettes, 01108 BOOL *pOurBrowserPalette, 01109 BOOL *pAllHaveBitmaps, 01110 BOOL *pAllWithinCount, 01111 UINT32 *pPaletteEntries ) 01112 { 01113 ERROR2IF ( pSpread == NULL,FALSE,"CheckSingleBitmapsOnSpread pSpread = NULL" ); 01114 ERROR2IF ( pSamePalettes == NULL || 01115 pOurBrowserPalette == NULL || 01116 pAllHaveBitmaps == NULL, 01117 FALSE, "CheckSingleBitmapsOnSpread bad params!" ); 01118 01119 // Walk through the layers looking at the referenced bitmaps, which are the newly added 01120 // bitmaps. 01121 BOOL SamePalettes = TRUE; 01122 BOOL OurBrowserPalette = TRUE; 01123 BOOL AllHaveBitmaps = TRUE; 01124 BOOL BitmapFound = FALSE; 01125 BOOL AllWithinCount = TRUE; 01126 UINT32 Bpp = 0; 01127 01128 KernelBitmap * pBitmap = NULL; 01129 LPLOGPALETTE pBrowserPalette = NULL; 01130 LPRGBQUAD pPreviousPalette = NULL; 01131 UINT32 PreviousPalEntries = 0; 01132 UINT32 ReqNumberOfPalEntries = 0; 01133 UINT32 MaxPaletteEntries = 0; 01134 if (pPaletteEntries != NULL) 01135 ReqNumberOfPalEntries = *pPaletteEntries; 01136 01137 Layer * pLayer = pSpread->FindFirstLayer(); 01138 while (pLayer != NULL) 01139 { 01140 // Only check pseudo frame layers as these are what the grab frame ops use 01141 if (!pLayer->IsBackground() && !pLayer->IsGuide() && 01142 !pLayer->IsPageBackground()) 01143 { 01144 pBitmap = pLayer->GetReferencedBitmap(); 01145 if (pBitmap) 01146 { 01147 BitmapFound = TRUE; 01148 01149 Bpp = pBitmap->GetBPP(); 01150 if (Bpp <= 8) 01151 { 01152 UINT32 PalEntries = pBitmap->GetNumPaletteEntries(); 01153 // Note this as a possible new maximum number of entries 01154 if (PalEntries > MaxPaletteEntries) 01155 MaxPaletteEntries = PalEntries; 01156 LPRGBQUAD pPalette = pBitmap->GetPaletteForBitmap(); 01157 if (PalEntries > ReqNumberOfPalEntries) 01158 AllWithinCount = FALSE; 01159 01160 // Obviously, browser palettes can only happen on 8bpp bitmaps 01161 if (Bpp == 8 && OurBrowserPalette) 01162 { 01163 // If we haven't done so already, allocate ourselves a browser 01164 // palette. 01165 // This MUST be the same one that we will use on saving 01166 if (pBrowserPalette == NULL) 01167 { 01168 UINT32 PaletteSize = UINT32( pow( 2.0, double(Bpp) ) ); 01169 pBrowserPalette = DIBUtil::AllocateLogPalette(PaletteSize); 01170 if (pBrowserPalette != NULL) 01171 { 01172 // Now force it into a browser compatible state 01173 BOOL AvoidSystemColours = TRUE; 01174 PaletteManager::MakePaletteBrowserCompatible 01175 ( pBrowserPalette, AvoidSystemColours ); 01176 } 01177 } 01178 01179 INT32 TransColour = -1; 01180 pBitmap->GetTransparencyIndex(&TransColour); 01181 01182 if (pBrowserPalette != NULL && OurBrowserPalette) 01183 OurBrowserPalette = pBitmap->ArePalettesTheSame(pBrowserPalette,TransColour); 01184 else 01185 OurBrowserPalette = FALSE; 01186 } 01187 else if (SamePalettes) 01188 { 01189 OurBrowserPalette = FALSE; 01190 01191 // If we have two palettes to compare then do so, 01192 // Otherwise wait for a second palette 01193 if (pPalette && pPreviousPalette) 01194 { 01195 if (PalEntries == PreviousPalEntries) 01196 { 01197 for (UINT32 i = 0; (i < PalEntries) && SamePalettes; i++) 01198 { 01199 if ( pPalette[i].rgbRed != pPreviousPalette[i].rgbRed && 01200 pPalette[i].rgbGreen != pPreviousPalette[i].rgbGreen && 01201 pPalette[i].rgbBlue != pPreviousPalette[i].rgbBlue 01202 ) 01203 SamePalettes = FALSE; 01204 } 01205 } 01206 else 01207 SamePalettes = FALSE; 01208 } 01209 } 01210 else 01211 OurBrowserPalette = FALSE; 01212 } 01213 else 01214 { 01215 OurBrowserPalette = FALSE; 01216 SamePalettes = FALSE; 01217 } 01218 01219 // Note this bitmap as the previous one 01220 PreviousPalEntries = pBitmap->GetNumPaletteEntries(); 01221 pPreviousPalette = pBitmap->GetPaletteForBitmap(); 01222 } 01223 else 01224 AllHaveBitmaps = FALSE; 01225 } 01226 01227 pLayer = pLayer->FindNextLayer(); 01228 } 01229 01230 // If no bitmaps have been found then we must reset the palette flags as otherwise 01231 // they will be showing the wrong value. 01232 if (!BitmapFound) 01233 { 01234 SamePalettes = FALSE; 01235 OurBrowserPalette = FALSE; 01236 AllWithinCount = FALSE; 01237 } 01238 01239 // return the results in the variables supplied 01240 if (pSamePalettes) 01241 *pSamePalettes = SamePalettes; 01242 if (pOurBrowserPalette) 01243 *pOurBrowserPalette = OurBrowserPalette; 01244 if (pAllHaveBitmaps) 01245 *pAllHaveBitmaps = AllHaveBitmaps; 01246 if (pAllWithinCount) 01247 *pAllWithinCount = AllWithinCount; 01248 01249 if (pPaletteEntries) 01250 { 01251 // If we have the same palette on all bitmaps then set the number of palette 01252 // entries to be correct, otherwise set to the maximum found. 01253 if (SamePalettes) 01254 *pPaletteEntries = PreviousPalEntries; 01255 else 01256 *pPaletteEntries = MaxPaletteEntries; 01257 } 01258 01259 // Free up our allocated browser palette 01260 if (pBrowserPalette != NULL) 01261 CCFree(pBrowserPalette); 01262 01263 return TRUE; 01264 } 01265 01266 /******************************************************************************************** 01267 > UINT32 MaskedFilter::GetNumReservedColours() 01268 01269 Author: Peter_Arnold (Xara Group Ltd) <camelotdev@xara.com> 01270 Created: 31/5/96 01271 Inputs: - 01272 Returns: The numbers of colours the filter would like to reserve. 01273 Purpose: If exporting a transparent GIF then reserve 1 palette index for the 01274 transpacency mask index. 01275 01276 Moved from TI_GIFFilter to MaskedFilter 10/7/96 01277 SeeAlso: - 01278 ********************************************************************************************/ 01279 UINT32 MaskedFilter::GetNumReservedColours() 01280 { 01281 MaskedFilterExportOptions* pMaskedOptions = (MaskedFilterExportOptions*)GetBitmapExportOptions(); 01282 ERROR2IF(pMaskedOptions == NULL, FALSE, "NULL Member"); 01283 ERROR3IF(!pMaskedOptions->IS_KIND_OF(MaskedFilterExportOptions), "pMaskedOptions isn't"); 01284 01285 if (pMaskedOptions->WantTransparent()) 01286 return 1; 01287 else 01288 return 0; 01289 } 01290 01291 /******************************************************************************************** 01292 01293 > INT32 MaskedFilter::FindUnusedColour(LPBITMAPINFO pBMInfo, LPBYTE pBMBits) 01294 01295 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 01296 Created: 16/6/96 01297 Inputs: - 01298 Returns: TRUE/FALSE for success/failure 01299 Purpose: Selects an index to use as the transparent colour from the bitmap data in the 01300 output DIB. If an index is unused then this index is used. 01301 If there is not an unused index then it is a bit more tricky - the least used 01302 colour is made transparent except for 1bpp in which case white becomes 01303 transparent. 01304 01305 Moved from TI_GIFFilter to MaskedFilter 10/7/96 01306 01307 ********************************************************************************************/ 01308 INT32 MaskedFilter::FindUnusedColour(LPBITMAPINFO pBMInfo, LPBYTE pBMBits) 01309 { 01310 ERROR2IF(pBMBits==NULL || pBMInfo==NULL, -1, "NULL bitmap pointer"); 01311 01312 // Count the colours used in the bitmap 01313 UINT32* pResults = NULL; 01314 BOOL ok = DIBUtil::CountColoursUsed(pBMInfo, pBMBits, &pResults); 01315 ERROR2IF(pResults == NULL, -1, "NULL results array"); 01316 01317 INT32 TransIndex = -1; 01318 if (ok) 01319 TransIndex = DIBUtil::FindLeastUsedColour(pBMInfo, pResults); 01320 01321 CCFree(pResults); 01322 pResults = NULL; 01323 01324 return TransIndex; 01325 } 01326 01327 01328 /******************************************************************************************** 01329 01330 > virtual BOOL MaskedFilter::SetExportHint(Document* pDoc) 01331 01332 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 01333 Created: 27/07/97 01334 Purpose: Overrides base class to set correct hint 01335 See Also: BaseBitmapFilter::SetExportHint() 01336 01337 ********************************************************************************************/ 01338 BOOL MaskedFilter::SetExportHint(Document* pDoc) 01339 { 01340 if (pDoc != NULL && !IsPreviewBitmap) 01341 { 01342 ExportHint* pHint = pDoc->GetExportHint(); 01343 ERROR3IF(pHint == NULL, "NULL ExportHint"); 01344 01345 BitmapExportOptions* pBaseOptions = GetBitmapExportOptions(); 01346 ERROR3IF(pBaseOptions == NULL, "NULL Options"); 01347 01348 if (pHint != NULL && pBaseOptions != NULL) 01349 { 01350 ERROR3IF(!(pBaseOptions->IsKindOf(CC_RUNTIME_CLASS(MaskedFilterExportOptions))), "Wrong options type"); 01351 MaskedFilterExportOptions* pOptions = (MaskedFilterExportOptions*) pBaseOptions; 01352 01353 // If derived class doesn't wat to hint then exit 01354 if (GetHintType() == HINTTYPE_BAD) 01355 return(TRUE); 01356 01357 pHint->SetType(GetHintType()); 01358 pHint->SetWidth(GetPixelWidth()); 01359 pHint->SetHeight(GetPixelHeight()); 01360 pHint->SetBPP(pOptions->GetDepth()); 01361 01362 String_256 Opts; 01363 Opts._MakeMsg(_T("D#1%ld"), pOptions->GetDither()); 01364 01365 if (pOptions->GetDepth() <= 8) 01366 { 01367 String_256 TempStr; 01368 TempStr._MakeMsg(_T(" P#1%ld N#2%ld"), 01369 pOptions->GetPalette(), 01370 pOptions->GetNumColsInPalette()); 01371 Opts += TempStr; 01372 01373 if (pOptions->GetUseSystemColours()) 01374 Opts += _T(" S"); 01375 } 01376 01377 if (pOptions->WantTransparent()) 01378 Opts += _T(" T"); 01379 if (pOptions->WantInterlaced()) 01380 Opts += _T(" I"); 01381 01382 pHint->SetOptionsString(Opts); 01383 } 01384 } 01385 return(TRUE); 01386 }