pngfiltr.cpp

Go to the documentation of this file.
00001 // $Id: pngfiltr.cpp 1558 2006-07-26 15:51:53Z 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 
00103 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00104 #include "progress.h"
00105 //#include "docview.h"  // DocView - in camtypes.h [AUTOMATICALLY REMOVED]
00106 #include "pngfiltr.h"
00107 #include "pngutil.h"    // PNG utility class
00108 //#include "oilfltrs.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00109 #include "oilbitmap.h"
00110 //#include "bmpfiltr.h"
00111 //#include "dibutil.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00112 #include "grndbmp.h"
00113 #include "nodebmp.h"
00114 //#include "wbitmap.h"  // Windows specific bitmap information   
00115 //#include "andy.h"
00116 //#include "resource.h" // Inform Warning _R(IDS_OK)
00117 //#include "filtrres.h" // Filter ids
00118 //#include "will3.h"        // for _R(IDS_GENOPTPALMSGID)
00119 #include "outptpng.h"   // PNG filter type, includes imglib.h 
00120 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00121 #include "maskfilt.h"   // MaskedFilter class
00122 #include "bmapprev.h"   // tab preview dialog
00123 #include "palman.h"     // PaletteManager::FindFirstDontUseColourInPalette
00124 //#include "mrhbits.h"  //  For CBMPBits::RenderSelectionToBMP
00125 #include "bitfilt.h"
00126 #include "selall.h"     //  For OPTOKEN_EDITSELECTALL
00127 
00128 CC_IMPLEMENT_DYNAMIC(PNGFilter, MaskedFilter)
00129 CC_IMPLEMENT_DYNCREATE(PNGExportOptions, MaskedFilterExportOptions)
00130 
00131 #define new CAM_DEBUG_NEW
00132 
00133 OutputPNG   PNGFilter::DestPNG;
00134 FilterType  PNGFilter::s_FilterType = PNG;  // Type of filter in use (PNG .. PNG_TRANSINTER)
00135 
00136 #if 1
00137 
00138 UINT32 PNGExportOptions::g_CompactedFlagsForDefaults = 0;
00139 
00140 /********************************************************************************************
00141 
00142 >   static BOOL PNGExportOptions::Declare()
00143 
00144     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> (from Neville)
00145     Created:    29/10/96
00146     Returns:    TRUE if successfully declared preferences
00147                 FALSE otherwise
00148     Purpose:    To declare preferences associated with these export options
00149 
00150 ********************************************************************************************/
00151 BOOL PNGExportOptions::Declare()
00152 {
00153     if (Camelot.DeclareSection(_T("Filters"), 10))
00154         Camelot.DeclarePref( NULL, _T("ExportPNGtype"), &g_CompactedFlagsForDefaults, 0, 3 );
00155 
00156     // All ok
00157     return TRUE;
00158 }
00159 
00160 /********************************************************************************************
00161 
00162 >   PNGExportOptions::PNGExportOptions(const FilterType FilterID, const StringBase* pFilterName)
00163 
00164     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00165     Created:    29/10/96
00166     Purpose:    Default constructor for a PNGExportOptions object to provide PNG export
00167                 options
00168 
00169 ********************************************************************************************/
00170 PNGExportOptions::PNGExportOptions(const FilterType FilterID, const StringBase* pFilterName) :
00171                         MaskedFilterExportOptions(_R(IDD_EXPORTBMPOPTS), FilterID, pFilterName)
00172 {
00173     // just us rats in here
00174 }
00175 
00176 /********************************************************************************************
00177 
00178 >   virtual BOOL PNGExportOptions::RetrieveDefaults()
00179 
00180     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00181     Created:    29/10/96
00182     Purpose:    See BitmapExportOptions for interface details
00183     Notes:      Gets GIF specific preferences
00184 
00185 ********************************************************************************************/
00186 BOOL PNGExportOptions::RetrieveDefaults()
00187 {
00188     if (!MaskedFilterExportOptions::RetrieveDefaults())
00189         return FALSE;
00190 
00191     SetMakeInterlaced(g_CompactedFlagsForDefaults & 1);
00192     return TRUE;
00193 }
00194 
00195 /********************************************************************************************
00196 
00197 >   virtual BOOL PNGExportOptions::SetAsDefaults() const
00198 
00199     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00200     Created:    29/10/96
00201     Purpose:    Provides additional implementation to set PNG specific options as defaults
00202     See Also:   BitmapExportOptions::SetAsDefaults()
00203 
00204 ********************************************************************************************/
00205 BOOL PNGExportOptions::SetAsDefaults() const
00206 {
00207     if (!MaskedFilterExportOptions::SetAsDefaults())
00208         return FALSE;
00209 
00210     g_CompactedFlagsForDefaults = WantTransparent() ? 2 : 0;
00211     g_CompactedFlagsForDefaults |= WantInterlaced() ? 1 : 0;
00212 
00213     return TRUE;
00214 }
00215 
00216 #endif
00217 
00218 /********************************************************************************************
00219 
00220 >   PNGFilter::PNGFilter()
00221 
00222     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00223     Created:    26/4/96
00224     Purpose:    Constructor for an PNGFilter object.  The object should be initialised
00225                 before use.
00226     SeeAlso:    PNGFilter::Init
00227 
00228 ********************************************************************************************/
00229 PNGFilter::PNGFilter() : MaskedFilter()
00230 {
00231     ImportMsgID = _R(IDS_IMPORTMSG_PNG);
00232     Flags.CanImport = TRUE;
00233     Flags.CanExport = TRUE;
00234 
00235     FilterID = PNG;
00236     ExportMsgID = _R(IDS_EXPORTMSG_PNG);            // "Preparing PNG file..."
00237     ExportingMsgID = _R(IDS_EXPORTINGMSG_PNG);      // "Exporting PNG file..."
00238 
00239     // Special Mask prepartion stage ID
00240     Export2ndStageMsgID = _R(IDN_MASKINGMSG_PNG);   // "Preparing mask for PNG file..."
00241     ExportRegion = NULL;
00242 }
00243 
00244 /********************************************************************************************
00245 
00246 >   BOOL PNGFilter::Init()
00247 
00248     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00249     Created:    26/4/96
00250     Returns:    TRUE if the filter was initialised ok, FALSE otherwise.
00251     Purpose:    Initialise an PNGFilter object.
00252     Errors:     Will fail if not enough memory to initialise.
00253     SeeAlso:    EPSStack
00254 
00255 ********************************************************************************************/
00256 BOOL PNGFilter::Init()
00257 {
00258     // Get the OILFilter object
00259     pOILFilter = new PNGOILFilter(this);
00260     if (pOILFilter==NULL)
00261         return FALSE;
00262 
00263     // Load the description strings
00264     FilterName.Load(_R(IDS_PNG_FILTERNAME));
00265     FilterInfo.Load(_R(IDS_PNG_FILTERINFO));
00266 
00267     if (!PNGExportOptions::Declare())
00268         return FALSE;
00269 
00270     // All ok
00271     return TRUE;
00272 }
00273 
00274 /********************************************************************************************
00275 
00276 >   INT32 PNGFilter::HowCompatible(PathName& Filename, ADDR HeaderStart, UINT32 HeaderSize, 
00277                                  UINT32 FileSize)
00278 
00279     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00280     Created:    26/4/96
00281     Inputs:     Filename - name of the file.
00282                 HeaderStart - Address of the first few bytes of the file.
00283                 HeaderSize - the number of bytes in the header pointed to by FileStart.
00284                 FileSize - the size of the whole file, in bytes.
00285     Returns:    0 => Not a PNG file.
00286                 10 => It is a PNG file.
00287     Purpose:    Determine if this filter can load the specified file.
00288 
00289 ********************************************************************************************/
00290 INT32 PNGFilter::HowCompatible(PathName& Filename, ADDR HeaderStart, UINT32 HeaderSize, 
00291                              UINT32 FileSize)
00292 {
00293 PORTNOTE("byteorder", "TODO: Check byte ordering")
00294     // We need to remember what we thought of this file in our class variable.
00295     // So, set it to a nice default value at the start.
00296     PNGHowCompatible = 0;
00297 
00298     // Check that we've got enough data to do our check
00299     if (HeaderSize < 8)
00300         return 0; // Not enough data - ignore this file.
00301 
00302     // Check the header for the "PNG" signature.
00303     // The first eight bytes of a PNG file always contain the following (decimal) values: 
00304     // 137 80 78 71 13 10 26 10 
00305     if (
00306         (HeaderStart[0] == 137) && // 0x89
00307         (HeaderStart[1] == 80) && //  0x50
00308         (HeaderStart[2] == 78) && //  0x4E
00309         (HeaderStart[3] == 71) && //  0x47
00310         (HeaderStart[4] == 13) && // Carriage return
00311         (HeaderStart[5] == 10) && // Line feed
00312         (HeaderStart[6] == 26) && // end of file (0x1a)
00313         (HeaderStart[7] == 10)    // Line feed
00314        )
00315     {
00316         // This should be a good enough check that this is a PNG file
00317         // Hence, we like this file
00318         PNGHowCompatible = 10;
00319     }
00320                 
00321     // Return the found value to the caller.
00322     return PNGHowCompatible;
00323 }
00324 
00325 /********************************************************************************************
00326 
00327 >   virtual BOOL PNGFilter::IsThisBppOk(UINT32 Bpp)
00328 
00329     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00330     Created:    26/4/96
00331     Inputs:     Bpp or Colour depth.
00332     Returns:    TRUE if this filter can cope with this colour depth, FALSE otherwise.
00333     Purpose:    Check if this Bitmap filter can cope with saving at this Bpp/Colour depth.
00334     SeeAlso:    OpMenuExport::DoWithParam;
00335 
00336 ********************************************************************************************/
00337 BOOL PNGFilter::IsThisBppOk(UINT32 Bpp)
00338 {
00339     return (Bpp == 1 || Bpp == 4 || Bpp == 8 || Bpp == 24 || Bpp == 32);
00340 }
00341 
00342 /********************************************************************************************
00343 
00344 >   BOOL PNGFilter::ReadFromFile( OILBitmap* pOilBitmap, BaseCamelotFilter* pFilter,
00345                                   CCLexFile* pFile, BOOL IsCompressed)
00346 
00347     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00348     Created:    20/7/96
00349     Inputs:     pOilBitmap  pointer to the oil bitmap data to be filled in
00350                 pFilter         - the BaseCamelotFilter which provides functions like progress update
00351                 pFile           - the CCFile class to use to read the data from
00352                 IsCompressed    - Flag to say the bitmap is compressed or not.  
00353     Outputs:    Will have filled in BMInfo  pointer to the bitmap header to fill in
00354                                     BMBytes pointer to the bitmap data to fill in
00355     Purpose:    Actually does the process of reading a bitmap from a file.
00356                 Inherited classes override this to read in different file formats.
00357                 It is used by the web/native filters to pull out a bitmap definition from
00358                 inside a bitmap definition record.
00359                 IsCompressed is only used for BMP/BMPZIP type bitmaps at present.
00360                 Assumes:
00361                     pFile has already been opened up for reading
00362                     pFilter has been set up for reading the data e.g. progress bar 
00363     Returns:    TRUE if worked, FALSE if failed.
00364 
00365 ********************************************************************************************/
00366 BOOL PNGFilter::ReadFromFile( OILBitmap* pOilBitmap, BaseCamelotFilter* pFilter,
00367                               CCLexFile* pFile, BOOL IsCompressed)
00368 {
00369     ERROR2IF(pOilBitmap == NULL,FALSE,"BMPFilter::ReadFromFile null OilBitmap pointer");
00370     ERROR2IF(pFilter == NULL,FALSE,"BMPFilter::ReadFromFile null pFilter pointer");
00371     ERROR2IF(pFile == NULL,FALSE,"BMPFilter::ReadFromFile null pFile pointer");
00372 
00373     // Try to import bitmap as usual binary BMP file.
00374     CWxBitmap* pWBitmap = (CWxBitmap*)pOilBitmap;
00375     
00376     LPBITMAPINFO *pInfo = &(pWBitmap->BMInfo);
00377     LPBYTE *pBytes = &(pWBitmap->BMBytes);
00378 
00379     INT32 TransColour = -1;
00380 
00381     // Read from file,using pFilter for progress bar updates
00382     if (!PNGUtil::ReadFromFile(pFile, pInfo, pBytes, &TransColour, NULL, pFilter))
00383         return FALSE;
00384 
00385     if(pWBitmap->BMInfo->bmiHeader.biBitCount == 32)
00386     {
00387         // If we`re exporting a 32Bit BMP then we need to make sure that we convert the
00388         // Alpha channel to Transparency! i.e. invert it!
00389         UINT32 BmpSize = pWBitmap->BMInfo->bmiHeader.biSizeImage;
00390         BYTE* Bits = pWBitmap->BMBytes;
00391 
00392         for(UINT32 i = 0; i < BmpSize; i+=4)
00393             Bits[i+3] = ~Bits[i+3];
00394     }
00395 
00396     // Everything went ok and we imported the bitmap ok
00397     SetTransColour(TransColour);
00398     UINT32 Bpp = pWBitmap->GetBPP();
00399     if (TransColour != -1 && Bpp <= 8)
00400         pOilBitmap->SetTransparencyIndex(TransColour);
00401 
00402     SetLastBitmap();        // can only import one bitmap at the moment
00403     return TRUE;
00404 }
00405 
00406 /********************************************************************************************
00407 
00408 >   BOOL PNGFilter::ReadFromFile(OILBitmap* pOilBitmap)
00409 
00410     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00411     Created:    26/4/96
00412     Inputs:     pOilBitmap  pointer to the oil bitmap data to be filled in
00413     Outputs:    Will have filled in BMInfo  pointer to the bitmap header to fill in
00414                                     BMBytes pointer to the bitmap data to fill in
00415     Purpose:    Actually does the process of reading a bitmap from a file.
00416                 Inherited classes override this to read in different file formats.
00417                 
00418     Returns:    TRUE if worked, FALSE if failed.
00419 
00420 ********************************************************************************************/
00421 BOOL PNGFilter::ReadFromFile(OILBitmap* pOilBitmap)
00422 {
00423     ERROR2IF(pOilBitmap == NULL,FALSE,"PNGFilter::ReadFromFile null OilBitmap pointer");
00424     
00425     // Try to import the bitmap as a PNG file.      
00426     CCLexFile *pImportFile = GetImportFile();
00427     ERROR2IF(pImportFile==NULL,FALSE,"PNGFilter::ReadFromFile - No import file");
00428 
00429     UINT32 ImportMsgId = GetImportMsgID();      
00430     String_64 ProgressString(ImportMsgId);
00431     ProgressString = GetImportProgressString(pImportFile, ImportMsgId);
00432 
00433     CWxBitmap* pWBitmap = (CWxBitmap*)pOilBitmap;
00434     
00435     LPBITMAPINFO *pInfo = &(pWBitmap->BMInfo);
00436     LPBYTE *pBytes = &(pWBitmap->BMBytes);
00437     
00438     INT32 TransColour = -1;
00439 
00440     // The PNG filter liked it very much and so use it, showing progress bar
00441     if (!PNGUtil::ReadFromFile(pImportFile, pInfo, pBytes, &TransColour, &ProgressString))
00442         return FALSE;
00443 
00444     SetTransColour(TransColour);
00445     UINT32 Bpp = pWBitmap->GetBPP();
00446     if (TransColour != -1 && Bpp <= 8)
00447         pOilBitmap->SetTransparencyIndex(TransColour);
00448 
00449     SetLastBitmap();        // can only import one bitmap at the moment
00450     
00451     return TRUE;
00452 }
00453 
00454 /********************************************************************************************
00455 
00456 >   virtual BOOL PNGFilter::GetExportOptions(BitmapExportOptions* pOptions)
00457 
00458     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00459     Created:    12/11/96
00460     Purpose:    See BaseBitmapFilter for interface details
00461 
00462 ********************************************************************************************/
00463 BOOL PNGFilter::GetExportOptions(BitmapExportOptions* pOptions)
00464 {
00465     ERROR2IF(pOptions == NULL, FALSE, "NULL Args");
00466 
00467     PNGExportOptions* pPNGOptions = (PNGExportOptions*)pOptions;
00468     ERROR3IF(!pPNGOptions->IS_KIND_OF(PNGExportOptions), "pPNGOptions isn't");
00469 
00470     // the depth we ask GDraw to render is always 32-bit, so we can get transparency
00471     // we have to convert for other formats when writing the actual bytes to the file
00472     SetDepthToRender(32);
00473 
00474     // We haven't written the header yet
00475     WrittenHeader = FALSE;
00476 
00477     // We are a first pass render and not doing the mask, by default
00478     SecondPass = FALSE;
00479     DoingMask = FALSE;
00480 
00481     // Determine the filter type currently in use in Accusoft format
00482     s_FilterType = PNG;
00483     pPNGOptions->SetFilterType(PNG);
00484 
00485     BOOL Ok = FALSE;
00486 
00487     OpDescriptor* pOpDes = OpDescriptor::FindOpDescriptor(OPTOKEN_GIFTABDLG);
00488     if (pOpDes != NULL)
00489     {
00490         // set up the data for the export options dialog
00491         OpParam Param((void *)pOptions, (void *)this);
00492 
00493         // invoke the dialog
00494         pOpDes->Invoke(&Param);
00495 
00496         // SMFIX
00497         // we have brought the dlg up so get the options from the dlg as the graphic type may have changed
00498         pOptions = BmapPrevDlg::m_pExportOptions;
00499 
00500         // check for valid options
00501         //  This may get messed up, so have to use the second line below.
00502         Ok = BmapPrevDlg::m_bClickedOnExport;
00503     }
00504     else
00505     {   
00506         ERROR3("Unable to find OPTOKEN_BMAPPREVDLG");
00507     } 
00508 
00509     // Return with the ok/cancel state used on the dialog box
00510     return Ok;
00511 }
00512 
00513 // SMFIX sjk 5/12/00 there used to be some junk in the call to GetExportOptions that assumed the
00514 // filter type being used which could be changed by the GetExportOptions call itself
00515 // therefore all this sort of stuff should be called on the correct known filter using this
00516 // call afterwards
00517 void PNGFilter::PostGetExportOptions(BitmapExportOptions* pOptions)
00518 {
00519     // should be of this type
00520     PNGExportOptions* pPNGOptions = (PNGExportOptions*)pOptions;
00521     ERROR3IF(!pPNGOptions->IS_KIND_OF(PNGExportOptions), "pPNGOptions isn't");
00522 
00523     // do the baseclass options
00524     MaskedFilter::PostGetExportOptions(pOptions);
00525 
00526     // do the specific to this class options
00527     // Filter type can be changed by the export options dialog box from say 
00528     // PNG to PNG_INTERLACED
00529     UINT32 Silliness = pPNGOptions->WantTransparent() ? 2 : 0;
00530     Silliness |= pPNGOptions->WantInterlaced() ? 1 : 0;
00531     if (Silliness >= 0 && Silliness <= 4)
00532     {
00533         Compression = Silliness;
00534         // Compression ranges from 0 .. 4 so map this onto our filter types
00535 //      s_FilterType = PNG + Silliness;
00536         switch (Silliness)
00537         {
00538         case 0: s_FilterType = PNG; break;
00539         case 1: s_FilterType = PNG_INTERLACED; break;
00540         case 2: s_FilterType = PNG_TRANSPARENT; break;
00541         case 3: s_FilterType = PNG_TRANSINTER; break;
00542         }
00543 
00544         if (pPNGOptions->WantTransparent() && pPNGOptions->GetSelectionType() == SELECTION)
00545             DoingMask = TRUE;
00546     }
00547 }
00548 
00549 /********************************************************************************************
00550 
00551 >   virtual void PNGFilter::CleanUpAfterExport()
00552 
00553     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00554     Created:    14/5/96
00555     Purpose:    Cleans up the memory allocated at the end of Exporting or when exporting has
00556                 been aborted for some reason. Does its cleaning up and then calls the
00557                 baseclass version to do its stuff,  - used
00558                 when the import process ends, either normally or abnormally. Override if
00559                 extra things are required.
00560     SeeAlso:    BaseBitmapFilter::PrepareToExport(); BaseBitmapFilter::CleanUpAfterExport();
00561     Scope:      Protected
00562 
00563 ********************************************************************************************/
00564 void PNGFilter::CleanUpAfterExport()
00565 {
00566     // Called right at the end of the export process or when the epxort has been aborted
00567     // Clean up any objects unique to this class.
00568     // Free up any DIBs that we might have left lying around on the export
00569     if (pDestBMInfo && pDestBMBytes)
00570     {
00571         FreeDIB( pDestBMInfo, pDestBMBytes );
00572         pDestBMInfo = NULL;
00573         pDestBMBytes = NULL;    
00574     }
00575 
00576     // the depth we ask GDraw to render is always 32-bit, so we can get transparency
00577     // we have to convert for other formats when writing the actual bytes to the file
00578     SetDepthToRender(32);
00579 
00580     // We haven't written the header yet
00581     WrittenHeader = FALSE;
00582 
00583     // We are a first pass render and not doing the mask, by default
00584     SecondPass = FALSE;
00585     DoingMask = FALSE;
00586 
00587     // Now call the baseclass version to do its stuff
00588     BaseBitmapFilter::CleanUpAfterExport();
00589 }
00590 
00591 /********************************************************************************************
00592 
00593 >   virtual UINT32 PNGFilter::GetExportMsgID()
00594 
00595     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00596     Created:    10/07/96
00597     Returns:    The id of the message to put on the progress display whilst exporting.
00598     Purpose:    Used to get the message id to be used during export.
00599                 Overides the baseclass form of the function so that during the two stage
00600                 export process it can change the message.
00601     SeeAlso:    DoExport; TI_GIFFilter::GetExportMsgID;
00602 
00603 ********************************************************************************************/
00604 UINT32 PNGFilter::GetExportMsgID()
00605 {
00606     if (GeneratingOptimisedPalette())
00607         return _R(IDS_GENOPTPALMSGID);              // "Generating optimised palette..."
00608 
00609     PNGExportOptions* pPNGOptions = (PNGExportOptions*)GetBitmapExportOptions();
00610     ERROR2IF(pPNGOptions == NULL, FALSE, "NULL Args");
00611     ERROR3IF(!pPNGOptions->IS_KIND_OF(PNGExportOptions), "pPNGOptions isn't");
00612 
00613     // If we are exporting with transparency on and on first pass use the masking message
00614     // otherwise use the exporting message.
00615     if (pPNGOptions->GetSelectionType() == SELECTION && pPNGOptions->WantTransparent())
00616     {
00617         // Special 4 stage rendering operation
00618         // - Render selected objects to white background
00619         // - Render mask 1bpp
00620         // - Render all objects
00621         // - Save data out to disk
00622         if (!SecondPass)
00623             return Export2ndStageMsgID;         // "Preparing mask for PNG file..."
00624         else
00625             return Filter::GetExportMsgID();    // "Preparing PNG file..."
00626     }
00627     else
00628     {
00629         // Special 3 stage rendering operation
00630         // - Render objects to white background
00631         // - Render mask 1bpp
00632         // - Save data out to disk
00633         if (DoingMask)
00634             return Export2ndStageMsgID;         // "Preparing mask for PNG file..."
00635         else
00636             return Filter::GetExportMsgID();    // "Preparing PNG file..."
00637     }
00638 
00639     return ExportingMsgID;
00640 }
00641 
00642 /********************************************************************************************
00643 
00644 >   BOOL PNGFilter::EndWriteToFile( )
00645 
00646     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00647     Created:    14/5/96
00648     Inputs:     -
00649     Purpose:    Cleans up after writing the bitmap data out to a file. Inherited classes
00650                 override this to write in different file formats.
00651                 This is slightly different to most other bitmap filters in that it is here
00652                 that the data actually gets written out to file, after doing the transparency
00653                 translation, if required.
00654     Returns:    TRUE if worked, FALSE if failed.
00655 
00656 ********************************************************************************************/
00657 BOOL PNGFilter::EndWriteToFile()
00658 {
00659     if (GeneratingOptimisedPalette())
00660         return TRUE;        // No need to output anything
00661 
00662     //  Can reset the band number now.
00663     m_BandNumber = 0;
00664 
00665     PNGExportOptions* pPNGOptions = (PNGExportOptions*)GetBitmapExportOptions();
00666     ERROR2IF(pPNGOptions == NULL, FALSE, "NULL Args");
00667     ERROR3IF(!pPNGOptions->IS_KIND_OF(PNGExportOptions), "pPNGOptions isn't");
00668 
00669     // Do the transparency translation just before we write out the data as a PNG.
00670     // This involves doing a 1 bpp export of the same area and using this to work
00671     // out which areas are transparent or not.
00672     // Only do this if the user has requested transparency and we outputting at 8bpp
00673     BOOL ok = TRUE;
00674     BOOL SaveDataOut = TRUE;
00675 
00676     if (BadExportRender)
00677     {
00678         // Delete our whitearea bitmap
00679         if (pTempBitmapMask != NULL)
00680             CCFree(pTempBitmapMask);
00681 
00682         pTempBitmapMask = NULL;
00683     }
00684 
00685     // Save the data out if required. Only if we exported ok.
00686     if (SaveDataOut && !BadExportRender)
00687     {
00688         if (ok)
00689         {
00690             // Now that we know the transparent index we can output the PNG header
00691             ok = DestPNG.OutputPNGHeader(OutputFile, NULL, pPNGOptions->WantInterlaced(),
00692                                         pPNGOptions->GetTransparencyIndex(),
00693                                         pPNGOptions->GetDepth() <= 8 ? pPNGOptions->GetLogicalPalette() : NULL);
00694         }
00695 
00696         // Actually write the destination bitmap out to the file showing an hourglass
00697         // and/or progress bar as we go. Always show the Exporting message.
00698         // Need to do in one go due to interlacing
00699         if (ok)
00700         {
00701             String_64 ProgressString(ExportingMsgID);
00702             ProgressString = GetExportProgressString(OutputFile, ExportingMsgID);
00703             BeginSlowJob(100, FALSE, &ProgressString);
00704             
00705             DestPNG.OutputPNGBits(OutputFile, DestPNG.GetDestBitmapBits());
00706             
00707             EndSlowJob();
00708         }
00709     }
00710 
00711     ASSERT(ok);
00712     
00713     return DestPNG.TidyUp();
00714 }
00715 
00716 /********************************************************************************************
00717 
00718 >   static BOOL PNGFilter::WriteDataToFile( BOOL End, UINT32 Bpp, UINT32 Compression)
00719 
00720     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00721     Created:    14/5/96
00722     Inputs:     End - TRUE if this is the last block of the file.
00723                 Bpp - output depth in terms of bits per pixel
00724                 Compression - usually True if compression required, False otherwise
00725                               In the PNG case this is used to pass in the transparency and
00726                               interlace state.
00727     Returns:    TRUE if worked, FALSE if errored.
00728     Purpose:    Physically put the bitmap into the disk.
00729                 NOTE - ONLY COPES WITH End=TRUE currently
00730                 AtEnd is ignored now and should always be set to TRUE.
00731                 Unused at present due to static problems when cretaing the 1bpp bitmap. 
00732     SeeAlso:    WriteToFile(); AccusoftFilters::WriteToFile; AccusoftFilters::WriteDataToFile;
00733 
00734 ********************************************************************************************/
00735 BOOL PNGFilter::WriteDataToFile( BOOL End, UINT32 Bpp, UINT32 Compression)
00736 {
00737     ERROR2(FALSE,"PNGFilter::WriteDataToFile called when not implemented");
00738 }
00739 
00740 /********************************************************************************************
00741 
00742 >   virtual BOOL PNGFilter::WriteBitmapToFile(KernelBitmap* pKernelBitmap, double Dpi)
00743 
00744     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00745     Created:    26/4/96
00746     Inputs:     Pointer to the bitmap to save.
00747                 Dpi of the bitmap to be saved
00748     Returns:    TRUE if worked, FALSE if errored.
00749     Purpose:    Physically put the bitmap into the disk.  Inherited classes override this to write
00750                 in different file formats.
00751     SeeAlso:    WriteDataToFile(); AccusoftFilters::WriteToFile; AccusoftFilters::WriteDataToFile;
00752 
00753 ********************************************************************************************/
00754 BOOL PNGFilter::WriteBitmapToFile(KernelBitmap* pKernelBitmap, double Dpi)
00755 {
00756     ERROR2IF(pKernelBitmap == NULL,FALSE,"PNGFilter::WriteBitmapToFile null bitmap pointer specified");
00757 
00758     // Get a pointer to the actual bitmap so that we can get some details from it.
00759     OILBitmap *pOilBitmap = pKernelBitmap->ActualBitmap;
00760     ERROR2IF(pOilBitmap == NULL,FALSE,"PNGFilter::WriteBitmapToFile null oil bitmap pointer");
00761 
00762     // Now get the pointer to the info header and actual bits data.
00763     // Need to use the actual bitmap pointer
00764     CWxBitmap* pWBitmap = (CWxBitmap*)pOilBitmap;
00765     LPBITMAPINFO pInfo = pWBitmap->BMInfo;
00766     LPBYTE pBytes = pWBitmap->BMBytes;
00767 //  UINT32 Bpp = pWBitmap->GetBPP();
00768 
00769     // Now, save the data out showing the correct progress string
00770     String_64 ProgressString(ExportingMsgID);
00771     BOOL ok = FALSE;
00772 //  BOOL Interlace = TRUE;  // Use interlace or not
00773 //  BOOL Transparency = FALSE;  // Use transparency or not
00774 
00775     if(pInfo->bmiHeader.biBitCount == 32)
00776     {
00777         // If we`re exporting a 32Bit BMP then we need to make sure that we convert the
00778         // Alpha channel to Transparency! i.e. invert it!
00779         UINT32 BmpSize = pInfo->bmiHeader.biSizeImage;
00780 
00781         for(UINT32 i = 0; i < BmpSize; i+=4)
00782             pBytes[i+3] = ~pBytes[i+3];
00783     }
00784 
00785     ok = WriteToFile(OutputFile, pInfo, pBytes, &ProgressString);
00786 
00787     //  This function is used when saving from the bitmap gallery. If we save a 32-bit bitmap as
00788     //  a PNG, then we have to undo the alpha channel reversing that we did above.
00789     //  Failure to do this will change the bitmap displayed in the bitmap gallery.
00790     if(pInfo->bmiHeader.biBitCount == 32)
00791     {
00792         UINT32 BmpSize = pInfo->bmiHeader.biSizeImage;
00793 
00794         for(UINT32 i = 0; i < BmpSize; i+=4)
00795             pBytes[i+3] = ~pBytes[i+3];
00796     }
00797     
00798     return ok;
00799 }
00800 
00801 /********************************************************************************************
00802 
00803 >   virtual BOOL PNGFilter::WriteBitmapToFile(KernelBitmap* pKernelBitmap,
00804                                               BaseCamelotFilter*pFilter,
00805                                               CCLexFile* pFile, INT32 Compression);
00806     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00807     Created:    21/6/96
00808     Inputs:     pKernelBitmap   - Pointer to the bitmap to be exported.
00809                 pFilter         - Pointer to the BaseCamelot filter which provides progress functions
00810                 pFile           - Pointer to the CCFile class to use for export
00811                 Compression     - used to flag how much compression of the data is required.
00812     Returns:    TRUE if worked, FALSE if errored.
00813     Purpose:    Physically put the bitmap into the disk.  Inherited classes override this to write
00814                 in different file formats.
00815                 This is used by the native/web format to output the actual bitmap data content
00816                 of a bitmap definition record. The function can assume that the CCFile is open
00817                 and ready for writing and must use the functions provided by pFilter to update
00818                 the progress system.
00819     SeeAlso:    BitmapListComponent::SaveBitmapDefinition;
00820 
00821 ********************************************************************************************/
00822 BOOL PNGFilter::WriteBitmapToFile(KernelBitmap* pKernelBitmap, BaseCamelotFilter* pFilter,
00823                                          CCLexFile* pFile, INT32 Compression)
00824 {
00825     ERROR2IF(pKernelBitmap == NULL,FALSE, "PNGFilter::WriteBitmapToFile null pKernelBitmap");
00826     ERROR2IF(pFilter == NULL,FALSE, "PNGFilter::WriteBitmapToFile null pFilter");
00827     ERROR2IF(pFile == NULL,FALSE, "PNGFilter::WriteBitmapToFile null pFile");
00828 
00829     // Get a pointer to the actual bitmap so that we can get some details from it.
00830     OILBitmap *pOilBitmap = pKernelBitmap->ActualBitmap;
00831     ERROR2IF(pOilBitmap == NULL,FALSE,"PNGFilter::WriteBitmapToFile null oil bitmap pointer");
00832 
00833     // Now get the pointer to the info header and actual bits data.
00834     // Need to use the actual bitmap pointer
00835     CWxBitmap* pWBitmap = (CWxBitmap*)pOilBitmap;
00836     LPBITMAPINFO Info = pWBitmap->BMInfo;
00837     LPBYTE Bytes = pWBitmap->BMBytes;
00838     UINT32 Bpp = pWBitmap->GetBPP();
00839 
00840     // Now, save the data out showing the correct progress string
00841     BOOL ok = FALSE;
00842     BOOL Interlace = FALSE;     // Must not use interlacing as it will screw the progress bar updates
00843 //  BOOL Transparency = FALSE;  // Use transparency or not
00844     INT32 Transparent = -1; // colour or -1 = no transparency
00845     if (Bpp <= 8)
00846         pOilBitmap->GetTransparencyIndex(&Transparent);
00847     
00848     if(Info->bmiHeader.biBitCount == 32)
00849     {
00850         // If we`re exporting a 32Bit BMP then we need to make sure that we convert the
00851         // Alpha channel to Transparency! i.e. invert it!
00852         UINT32 BmpSize = Info->bmiHeader.biSizeImage;
00853 
00854         for(UINT32 i = 0; i < BmpSize; i+=4)
00855             Bytes[i+3] = ~Bytes[i+3];
00856     }
00857     
00858     // Write to file, no header and using pFilter for progress bar updates
00859     ok = WriteToFile(pFile, Info, Bytes, Interlace, Transparent, pFilter);
00860     
00861     return ok;
00862 }
00863 
00864 /********************************************************************************************
00865 
00866 >   static BOOL PNGFilter::WriteToFile ( CCLexFile* File, LPBITMAPINFO Info, LPBYTE Bits,
00867                                          BOOL Interlace, INT32 Transparent,
00868                                          BaseCamelotFilter* pFilter = NULL )
00869 
00870     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00871     Created:    10/7/96
00872     Inputs:     File        An opened CCFile that can be written to. It should be positioned at the
00873                             start. Caller is responsible for closing it. The file needs to be in
00874                             Binary mode.
00875                 Info        BITMAPINFO structure for the dib.
00876                 Bits        The bitmap data itself
00877                 Interlace   allows interlacing to be turned off or on
00878                 Transparent if -1 then no transpparent colour, if not -1 then specifies the index
00879                             number of the transparent colour in the palette
00880                 pFilter     is an alternative way of handling the progress bar, assume the
00881                             progress bar has been start and just call the IncProgressBarCount in BaseCamelotFilter
00882                             to do the progress bar update. Defaults to NULL i.e. no progress bar.
00883     Outputs:    -
00884     Returns:    TRUE if worked, FALSE if failed (error will be set accordingly but not reported)
00885     Purpose:    Write a bitmap in memory straight out as a PNG to file with no rendering or
00886                 conversion between different colour depths (apart from 32 to 24) or resolution.
00887                 ***Errors on 16-bit builds***
00888                 A progress hourglass can be shown if required using the BaseCamelotFilter as
00889                 the controlling influence.
00890                 
00891                 This function is used by the new native/web  file format to do a straight save of 
00892                 the data into the file.
00893 
00894                 (caller should close file)
00895     Errors:     Calls SetError on FALSE returns.
00896     Scope:      Static
00897     SeeAlso:    AccusoftFilters::WriteToFile; DIBUtil::WriteToFile;
00898 
00899 ********************************************************************************************/
00900 BOOL PNGFilter::WriteToFile( CCLexFile* File, LPBITMAPINFO Info, LPBYTE Bits,
00901                              BOOL Interlace, INT32 TransparentColour,
00902                              BaseCamelotFilter* pFilter )
00903 {
00904 #ifdef DO_EXPORT
00905     ERROR2IF(File==NULL,FALSE,"PNGFilter::WriteToFile File pointer is null");
00906     ERROR2IF(Info==NULL,FALSE,"PNGFilter::WriteToFile BitmapInfo pointer is null");
00907     ERROR2IF(Bits==NULL,FALSE,"PNGFilter::WriteToFile Bits pointer is null");
00908 
00909     // BITMAPINFO  consists of:-
00910     //      BITMAPINFOHEADER    bmiHeader;
00911     //      RGBQUAD             bmiColors[1];
00912     LPBITMAPINFOHEADER pInfoHeader = &Info->bmiHeader;
00913     ERROR2IF(pInfoHeader==NULL,FALSE,"PNGFilter::WriteToFile BitmapInfoHeader pointer is null");
00914         
00915     LPRGBQUAD pPalette = &(Info->bmiColors[0]);
00916     ERROR2IF(pPalette==NULL,FALSE,"PNGFilter::WriteToFile palette pointer is null");
00917 
00918     // Set up our format type flags.
00919     if(Info->bmiHeader.biBitCount == 32)
00920     {
00921         // If we`re exporting a 32Bit BMP then we need to make sure that we convert the
00922         // Alpha channel to Transparency! i.e. invert it!
00923         UINT32 BmpSize = Info->bmiHeader.biSizeImage;
00924 
00925         for(UINT32 i = 0; i < BmpSize; i+=4)
00926             Bits[i+3] = ~Bits[i+3];
00927     }
00928 
00929     // Output a PNG header for this file, using the RGBQUAD palette rather than a LOGPALETTE
00930     DestPNG.OutputPNGHeader(File, pInfoHeader, Interlace, TransparentColour, NULL, pPalette);
00931 
00932     // Now write out the bitmap data itself.
00933     DestPNG.OutputPNGBits(File, Bits, TRUE, pFilter);
00934 
00935     // The above has set the OutputFile member variable of DestPNG. We desperately need to
00936     // reset this as otherwise the next bitmap export may go wrong as it calls the tidy up
00937     // and so will refer to the deleted CCFile. Oh Er!
00938     DestPNG.TidyUp();
00939 
00940     // er, we seem to have finished OK so say so
00941     return TRUE;
00942 #else
00943     return FALSE;
00944 #endif
00945 }
00946 
00947 /********************************************************************************************
00948 
00949 >   static BOOL PNGFilter::WriteToFile ( CCLexFile* File, LPBITMAPINFO Info, LPBYTE Bits,
00950                                          String_64* ProgressString = NULL )
00951 
00952     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
00953     Created:    26/4/96
00954     Inputs:     File    An opened CCFile that can be written to. It should be positioned at the
00955                         start. Caller is responsible for closing it. The file needs to be in
00956                         Binary mode.
00957                 Info    BITMAPINFO structure for the dib.
00958                 Bits    The bitmap data itself
00959                 ProgressString allows the user to specify whether they require a progress
00960                         hourglass or not. If NULL then none is shown, otherwise an progress bar 
00961                         is shown using the text supplied. Defaults to NULL i.e. no progress bar.
00962     Outputs:    -
00963     Returns:    TRUE if worked, FALSE if failed (error will be set accordingly but not reported)
00964     Purpose:    Write a bitmap in memory straight out as a PNG to file with no rendering or
00965                 conversion between different colour depths (apart from 32 to 24) or resolution.
00966                 ***Errors on 16-bit builds***
00967                 A progress hourglass can be shown if required.
00968                 This function is used by the save bitmap button on the bitmap gallery. All
00969                 other bitmap export uses the OutputDIB class instead as this copes with using
00970                 a render region and converting from 32 to the destination format.
00971                 (caller should close file)
00972     Errors:     Calls SetError on FALSE returns.
00973     Scope:      Static
00974     SeeAlso:    AccusoftFilters::WriteToFile; DIBUtil::WriteToFile;
00975 
00976 ********************************************************************************************/
00977 BOOL PNGFilter::WriteToFile( CCLexFile* File, LPBITMAPINFO Info, LPBYTE Bits,
00978                              String_64* ProgressString )
00979 {
00980 #ifdef DO_EXPORT
00981     ERROR2IF(File==NULL,FALSE,"PNGFilter::WriteToFile File pointer is null");
00982     ERROR2IF(Info==NULL,FALSE,"PNGFilter::WriteToFile BitmapInfo pointer is null");
00983     ERROR2IF(Bits==NULL,FALSE,"PNGFilter::WriteToFile Bits pointer is null");
00984 
00985     // If the caller has specified a string then assume they require a progress bar
00986     // Start it up.
00987     if (ProgressString != NULL)
00988         BeginSlowJob(100, FALSE, ProgressString);
00989 
00990     // BITMAPINFO  consists of:-
00991     //      BITMAPINFOHEADER    bmiHeader;
00992     //      RGBQUAD             bmiColors[1];
00993     LPBITMAPINFOHEADER pInfoHeader = &Info->bmiHeader;
00994     ERROR2IF(pInfoHeader==NULL,FALSE,"PNGFilter::WriteToFile BitmapInfoHeader pointer is null");
00995         
00996     LPRGBQUAD pPalette = &(Info->bmiColors[0]);
00997     ERROR2IF(pPalette==NULL,FALSE,"PNGFilter::WriteToFile palette pointer is null");
00998 
00999     // Set up our format type flags.
01000     BOOL Interlace = TRUE;  // Use interlace or not
01001     INT32 Transparent = -1; // colour or -1 = no transparency
01002     BOOL WantTransparent = FALSE;
01003 
01004     switch (s_FilterType)
01005     {
01006         default:
01007         case PNG:
01008             Interlace       = FALSE;
01009             WantTransparent = FALSE;
01010             break;
01011         case PNG_INTERLACED:
01012             Interlace       = TRUE;
01013             WantTransparent = FALSE;
01014             break;
01015         case PNG_TRANSPARENT:
01016             Interlace       = FALSE;
01017             WantTransparent = TRUE;
01018             break;
01019         case PNG_TRANSINTER:
01020             Interlace       = TRUE;
01021             WantTransparent = TRUE;
01022             break;
01023     }
01024 
01025     if (WantTransparent)
01026     {
01027         // We want to try and output the transparency if possible ...
01028 
01029         // Scan through the palette, and try and find an index with
01030         // the transparency flag set
01031 
01032         INT32 cols = Info->bmiHeader.biClrUsed;
01033         // If we have zero colours on a bitmap which is 8bpp or less then this is bad.
01034         // This should be translated as the maximum number of colours allowed
01035         if (Info->bmiHeader.biBitCount <= 8 && cols == 0)
01036             cols = 1 << Info->bmiHeader.biBitCount;
01037 
01038         for (INT32 i = 0; i < cols; i++)
01039         {
01040             if (Info->bmiColors[i].rgbReserved == 0xFF)
01041             {
01042                 Transparent = i;
01043                 TRACEUSER( "Neville", _T("PNG output with transp index of %d\n"),Transparent);
01044                 break;
01045             }       
01046         }   
01047     }
01048 
01049     // Output the PNG data
01050     BOOL ok = TRUE;
01051     // Output a PNG header for this file, using the RGBQUAD palette rather than a LOGPALETTE
01052     if (Transparent == -1)
01053         ok = DestPNG.OutputPNGHeader(File, pInfoHeader, Interlace, -1, NULL, pPalette);
01054     else
01055         ok = DestPNG.OutputPNGHeader(File, pInfoHeader, Interlace, Transparent, NULL, pPalette);
01056 
01057     // Now write out the bitmap data itself.
01058     if (ok)
01059         ok = DestPNG.OutputPNGBits(File, Bits, TRUE);
01060     
01061     // If started, then stop then progress bar
01062     if (ProgressString != NULL)
01063         EndSlowJob();
01064 
01065     // er, we seem to have finished OK so say so
01066     return TRUE;
01067 #else
01068     return FALSE;
01069 #endif
01070 }
01071 
01072 /********************************************************************************************
01073 
01074 >   virtual BOOL PNGFilter::WritePreFrame(void)
01075 
01076     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01077     Created:    11/7/96
01078     Inputs:     -
01079     Returns:    FALSE if failed else TRUE
01080     Purpose:    To write out any frame specific info before the image
01081     SeeAlso:    GIFFilter::WritePreFrame(void)
01082 
01083 ********************************************************************************************/
01084 BOOL PNGFilter::WritePreFrame(void)
01085 {
01086     return DestPNG.ReStartFile(NULL);
01087 }
01088 
01089 /********************************************************************************************
01090 
01091 >   virtual BOOL PNGFilter::WriteFrame(void)
01092 
01093     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01094     Created:    11/7/96
01095     Inputs:     -
01096     Returns:    FALSE if failed else TRUE
01097     Purpose:    To write out the image itself
01098                 This base class version actually calls the WriteToFile() function so that
01099                 derived classes do not have to implement any of the multi-image stuff
01100     SeeAlso:    GIFFilter::WriteFrame(void)
01101 
01102 ********************************************************************************************/
01103 BOOL PNGFilter::WriteFrame(void)
01104 {
01105     return MaskedFilter::WriteToFile(TRUE);
01106 }
01107 
01108 
01109 /********************************************************************************************
01110 
01111 >   virtual BOOL PNGFilter::WritePostFrame(void)
01112 
01113     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01114     Created:    11/7/96
01115     Inputs:     -
01116     Returns:    FALSE if failed else TRUE
01117     Purpose:    To write out any frame specific info after the image
01118     SeeAlso:    GIFFilter::WritePostFrame(void)
01119 
01120 ********************************************************************************************/
01121 BOOL PNGFilter::WritePostFrame(void)
01122 {
01123     return EndWriteToFile();
01124 }
01125 
01126 /********************************************************************************************
01127 
01128 >   virtual BOOL PNGFilter::WriteFileEnd(void)
01129 
01130     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01131     Created:    11/7/96
01132     Inputs:     -
01133     Returns:    FALSE if failed else TRUE
01134     Purpose:    To write out the file specific data at the end of the file
01135                 This base class version calls EndWriteToFile() so that derived classes
01136                 do not have to implement the multi-image stuff
01137     SeeAlso:    GIFFilter::WriteFileEnd(void)
01138 
01139 ********************************************************************************************/
01140 BOOL PNGFilter::WriteFileEnd(void)
01141 {
01142     return DestPNG.TidyUp();
01143 }
01144 
01145 /********************************************************************************************
01146 
01147 >   virtual BOOL PNGFilter::WritePreSecondPass(void)
01148 
01149     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01150     Created:    11/7/96
01151     Inputs:     -
01152     Returns:    FALSE if failed else TRUE
01153     Purpose:    Called to do any processing required after the first and before the second
01154                 pass of a two pass export
01155     SeeAlso:    GIFFilter::WritePreSecondPass(void)
01156 
01157 ********************************************************************************************/
01158 BOOL PNGFilter::WritePreSecondPass(void)
01159 {
01160     return EndWriteToFile();
01161 }
01162 
01163 /********************************************************************************************
01164 
01165 >   virtual void PNGFilter::InvertAlpha ( LPBITMAPINFO  lpBitmapInfo,
01166                                           LPBYTE        lpBits )
01167 
01168     Author:     Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
01169     Created:    27/6/00
01170     Purpose:    Camelot uses a different transparency scheme to the rest of the world, in
01171                 that 255 is clear, and 0 is opaque. Until the rest of the world catches up,
01172                 it's necessary to invert the alpha channel to make exported files compatible
01173                 with other programs.
01174 
01175 ********************************************************************************************/
01176 void PNGFilter::InvertAlpha ( LPBITMAPINFO  lpBitmapInfo,
01177                               LPBYTE        lpBits )
01178 {
01179     DIBUtil::InvertAlpha(lpBitmapInfo, lpBits);
01180 }
01181 
01182 /********************************************************************************************
01183 
01184 >   virtual OutputDIB* PNGFilter::GetOutputDIB ( void )
01185 
01186     Author:     Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
01187     Created:    27/6/00
01188     Returns     OutputDIB* - A pointer to DestPNG.
01189     Purpose:    Casts the current output DIB to be a generic OutputDIB class. This allows the
01190                 same code to be re-used in the base class.
01191 
01192 ********************************************************************************************/
01193 OutputDIB* PNGFilter::GetOutputDIB ( void )
01194 {
01195     // Perform an upcast to allow the pointer to be used in a generic manner.
01196     return static_cast<OutputDIB*> ( &DestPNG );
01197 }
01198 
01199 /********************************************************************************************
01200 
01201 >   virtual BitmapExportOptions* PNGFilter::CreateExportOptions() const
01202 
01203     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
01204     Created:    29/10/96
01205     Purpose:    See BaseBitmapFilter for interface details
01206     Notes:      Provides a new PNGExportOptions instance
01207 
01208 ********************************************************************************************/
01209 BitmapExportOptions* PNGFilter::CreateExportOptions() const
01210 {
01211     PNGExportOptions* pPNGOptions = new PNGExportOptions(PNG, &FilterName);
01212     return (BitmapExportOptions*)pPNGOptions;
01213 }
01214 
01215 void PNGFilter::AlterPaletteContents( LPLOGPALETTE pPalette )
01216 {
01217     DestPNG.AlterExportPalette( pPalette );
01218 }

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