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 }