maskfilt.cpp

Go to the documentation of this file.
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 }

Generated on Sat Nov 10 03:48:38 2007 for Camelot by  doxygen 1.4.4