00001 // $Id: exjpeg.cpp 1708 2006-08-17 17:13:38Z gerry $ 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 JPEG import filter 00100 00101 #include "camtypes.h" 00102 //#include "filters.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00103 //#include "oilfltrs.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00104 #include "oilbitmap.h" 00105 //#include "dibutil.h" 00106 //#include "filtrres.h" 00107 //#include "resource.h" // for _R(IDS_OUT_OF_MEMORY) 00108 //#include "imglib.h" // for JPEG 00109 #include "grndbmp.h" 00110 //#include "camfiltr.h" // for BaseCamelotFilter progress update - in camtypes.h [AUTOMATICALLY REMOVED] 00111 //#include "app.h" // Camelot!! - in camtypes.h [AUTOMATICALLY REMOVED] 00112 //#include "convert.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00113 00114 #include "exjpeg.h" 00115 #include "jpgdest.h" 00116 #include "jpgermgr.h" 00117 00118 #include "bitmpinf.h" 00119 #include "ccbuffil.h" 00120 00121 #include "progress.h" 00122 #include "bmapprev.h" // tab preview dialog 00123 //#include "cxfrec.h" // for CXaraFileRecord - in camtypes.h [AUTOMATICALLY REMOVED] 00124 00125 #include "exphint.h" 00126 00127 // Place any IMPLEMENT type statements here 00128 CC_IMPLEMENT_DYNAMIC(JPEGExportFilter, BaseBitmapFilter) 00129 CC_IMPLEMENT_DYNCREATE(JPEGExportOptions, BitmapExportOptions) 00130 00131 00132 // We want better memory tracking 00133 #define new CAM_DEBUG_NEW 00134 00135 static TCHAR g_szCompression[] = _T("ExportJPEG\\Compression"); 00136 static TCHAR g_szDCTMethod[] = _T("ExportJPEG\\DCTMethod"); 00137 static TCHAR g_szProgressive[] = _T("ExportJPEG\\DoAsProgressive"); 00138 static TCHAR g_szOptimize[] = _T("ExportJPEG\\Optimize"); 00139 static TCHAR g_szSmoothing[] = _T("ExportJPEG\\Smoothing"); 00140 00141 //RangePreference JPEGExportFilter::Compression(g_szCompression, 0, 100); 00142 //RangePreference DCTMethod(g_szDCTMethod, &GetRefDefaultDCTMethod(), 0, 4); 00143 //BoolPreference Progressive(g_szProgressive, &GetRefDoAsProgressive()); 00144 //RangePreference Xppm(g_szXDpi, 96, MinPelsPerMeter, ); 00145 //RangePreference Yppm(g_szYDpi, 96, MinPelsPerMeter, ); 00146 00147 //JPEG_QUALITY JPEGExportFilter::g_DefaultCompression = 100; 00148 //BOOL JPEGExportFilter::g_bExportProgressive = FALSE; 00149 //J_DCT_METHOD JPEGExportFilter::g_DefaultDCTMethod; 00150 00151 JPEG_QUALITY g_DefaultCompression = 75; 00152 libJPEG::J_DCT_METHOD g_DefaultDCTMethod = libJPEG::JDCT_FLOAT; 00153 BOOL g_bExportProgressive = FALSE; 00154 00155 BOOL g_bOptimizeCoding = FALSE; 00156 JPEG_QUALITY g_Smoothing = 0; 00157 00158 KernelBitmap* JPEGExportOptions::pKernelBitmap = NULL; 00159 BOOL JPEGExportOptions::m_JPEGPresentAndSelected = FALSE; 00160 00161 00162 /******************************************************************************************** 00163 > JPEGExportOptions::JPEGExportOptions() 00164 00165 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00166 Created: 29/10/96 00167 Purpose: Default constructor for a JPEGExportOptions object. 00168 ********************************************************************************************/ 00169 00170 JPEGExportOptions::JPEGExportOptions() 00171 : m_bJPEGPresentAndSelected(0), 00172 m_Quality(100), 00173 m_DoAsProgressive(FALSE), 00174 m_DCTMethod(libJPEG::JDCT_DEFAULT), 00175 m_ColourModel(libJPEG::JCS_UNKNOWN), 00176 m_ColourComponents(0) 00177 { 00178 // Empty. 00179 } 00180 00181 00182 /******************************************************************************************** 00183 > JPEGExportOptions::JPEGExportOptions(const FilterType FilterID, 00184 const StringBase* pFilterName) 00185 00186 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00187 Created: 29/10/96 00188 Purpose: Constructor for a JPEGExportOptions object. 00189 ********************************************************************************************/ 00190 00191 JPEGExportOptions::JPEGExportOptions(const FilterType FilterID, const StringBase* pFilterName) 00192 : BitmapExportOptions(_R(IDD_EXPORTJPEGOPTS), FilterID, pFilterName), 00193 m_bJPEGPresentAndSelected(0), 00194 m_Quality(100), 00195 m_DoAsProgressive(FALSE), 00196 m_DCTMethod(libJPEG::JDCT_DEFAULT), 00197 m_ColourModel(libJPEG::JCS_UNKNOWN), 00198 m_ColourComponents(0) 00199 { 00200 // Empty. 00201 } 00202 00203 00204 /******************************************************************************************** 00205 00206 > virtual BOOL JPEGExportOptions::CopyFrom(BitmapExportOptions *pSource) 00207 00208 Author: Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> 00209 Created: 19/05/97 00210 Inputs: pSource - the other BitmapExportOptions object to copy the data from 00211 Purpose: Sets the contents of this object from the passed object 00212 See Also: BitmapExportOptions::MakeCopy() 00213 00214 ********************************************************************************************/ 00215 BOOL JPEGExportOptions::CopyFrom(BitmapExportOptions *pSource) 00216 { 00217 // copy the base class first 00218 if (!BitmapExportOptions::CopyFrom(pSource)) 00219 return FALSE; 00220 00221 // must be the same class, otherwise the base class function above returns FALSE 00222 JPEGExportOptions *pOther = (JPEGExportOptions *)pSource; 00223 00224 m_Quality = pOther->m_Quality; 00225 m_DoAsProgressive = pOther->m_DoAsProgressive; 00226 m_DCTMethod = pOther->m_DCTMethod; 00227 m_ColourModel = pOther->m_ColourModel; 00228 m_ColourComponents = pOther->m_ColourComponents; 00229 m_bJPEGPresentAndSelected = pOther->m_bJPEGPresentAndSelected; 00230 00231 return TRUE; 00232 }; 00233 00234 00235 BOOL JPEGExportOptions::FileTypeChangeCopyFrom(BitmapExportOptions *pOther) 00236 { 00237 // copy the base class first 00238 if (!BitmapExportOptions::FileTypeChangeCopyFrom(pOther)) 00239 return FALSE; 00240 00241 // No other options types has the JPEG options, so have to use the default values 00242 m_Quality = 75; 00243 m_DoAsProgressive = FALSE; 00244 m_DCTMethod = libJPEG::JDCT_DEFAULT; 00245 m_ColourModel = libJPEG::JCS_UNKNOWN; 00246 m_ColourComponents = 0; 00247 m_bJPEGPresentAndSelected = 0; 00248 00249 // Ensure that the JPEG depth is less than 32 bpp. 00250 if( GetDepth() == 32 ) 00251 { 00252 SetDepth( 24 ); 00253 } 00254 00255 return TRUE; 00256 } 00257 00258 00259 /******************************************************************************************** 00260 00261 > virtual BOOL JPEGExportOptions::Equal(BitmapExportOptions *pSource) 00262 00263 Author: Stefan_Stoykov (Xara Group Ltd) <camelotdev@xara.com> 00264 Created: 19/05/97 00265 Inputs: pSource - the other BitmapExportOptions object to copy the data from 00266 Purpose: Compares the contents of this and pOther objects 00267 Returns: TRUE, if objects are equal, FALSE otherwise 00268 See Also: BitmapExportOptions::MakeCopy() 00269 00270 ********************************************************************************************/ 00271 /* 00272 BOOL JPEGExportOptions::Equal(BitmapExportOptions *pSource) 00273 { 00274 BOOL ok = TRUE; 00275 00276 // compare the base classes first 00277 ok = BitmapExportOptions::Equal(pSource); 00278 00279 // must be the same class, otherwise the base class function above returns FALSE 00280 JPEGExportOptions *pOther = (JPEGExportOptions *)pSource; 00281 00282 if (ok) ok = (m_Quality == pOther->m_Quality); 00283 if (ok) ok = (m_DoAsProgressive == pOther->m_DoAsProgressive); 00284 if (ok) ok = (m_DCTMethod == pOther->m_DCTMethod); 00285 if (ok) ok = (m_ColourModel == pOther->m_ColourModel); 00286 if (ok) ok = (m_ColourComponents == pOther->m_ColourComponents); 00287 if (ok) ok = (m_bJPEGPresentAndSelected == pOther->m_bJPEGPresentAndSelected); 00288 return ok; 00289 }; 00290 */ 00291 00292 /******************************************************************************************** 00293 00294 > virtual BOOL JPEGExportOptions::RetrieveDefaults() 00295 00296 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00297 Created: 29/10/96 00298 Purpose: Provides additional implementation required for retrieving JPEG specific 00299 defaults. 00300 See Also: BitmapExportOptions::RetrieveDefaults() 00301 00302 ********************************************************************************************/ 00303 BOOL JPEGExportOptions::RetrieveDefaults() 00304 { 00305 if (!BitmapExportOptions::RetrieveDefaults()) 00306 { 00307 return FALSE; 00308 } 00309 m_Quality = g_DefaultCompression; 00310 m_DoAsProgressive = g_bExportProgressive; 00311 m_DCTMethod = g_DefaultDCTMethod; 00312 SetDepth(24); // all jpegs are 24 after all -sjk 00313 00314 return TRUE; 00315 } 00316 00317 00318 /******************************************************************************************** 00319 00320 > virtual BOOL JPEGExportOptions::SetAsDefaults() const 00321 00322 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00323 Created: 29/10/96 00324 Purpose: Provides additional implementation to set JPEG specific info as defaults 00325 See Also: BitmapExportOptions::SetAsDefaults() 00326 00327 ********************************************************************************************/ 00328 BOOL JPEGExportOptions::SetAsDefaults() const 00329 { 00330 if (!BitmapExportOptions::SetAsDefaults()) 00331 { 00332 return FALSE; 00333 } 00334 00335 // TODO: Fill in JPEG specific statics need sorting 00336 g_DefaultCompression = m_Quality; 00337 g_bExportProgressive = m_DoAsProgressive; 00338 g_DefaultDCTMethod = m_DCTMethod; 00339 00340 return TRUE; 00341 } 00342 00343 00344 00345 /******************************************************************************************** 00346 > virtual BOOL JPEGExportOptions::Write(CXaraFileRecord* pRec) 00347 00348 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00349 Created: 21/2/00 00350 Inputs: pRec --- record to write 00351 Returns: TRUE if successful. 00352 Purpose: Writes this object to the given record. 00353 SeeAlso: JPEGExportOptions::Read 00354 ********************************************************************************************/ 00355 00356 BOOL JPEGExportOptions::Write(CXaraFileRecord* pRec) 00357 { 00358 return BitmapExportOptions::Write(pRec) && 00359 pRec->WriteUINT32(m_Quality) && 00360 pRec->WriteBYTE((BYTE) !!m_DoAsProgressive) && 00361 pRec->WriteINT16((INT16) m_DCTMethod) && 00362 pRec->WriteINT16((INT16) m_ColourModel) && 00363 pRec->WriteUINT32(m_ColourComponents); 00364 } 00365 00366 00367 00368 /******************************************************************************************** 00369 > virtual BOOL JPEGExportOptions::Read(CXaraFileRecord* pRec) 00370 00371 Author: Justin_Flude (Xara Group Ltd) <camelotdev@xara.com> 00372 Created: 21/2/00 00373 Inputs: pRec --- record to read 00374 Returns: TRUE if successful. 00375 Purpose: Reads this object from the given record. 00376 SeeAlso: JPEGExportOptions::Write 00377 ********************************************************************************************/ 00378 00379 BOOL JPEGExportOptions::Read(CXaraFileRecord* pRec) 00380 { 00381 m_DoAsProgressive = FALSE; 00382 return BitmapExportOptions::Read(pRec) && 00383 pRec->ReadUINT32((UINT32*) &m_Quality) && 00384 pRec->ReadBYTEtoBOOL(&m_DoAsProgressive) && 00385 pRec->ReadINT16((INT16*) &m_DCTMethod) && 00386 pRec->ReadINT16((INT16*) &m_ColourModel) && 00387 pRec->ReadUINT32((UINT32*) &m_ColourComponents); 00388 } 00389 00390 00391 00392 /******************************************************************************************** 00393 00394 > BOOL JPEGExportOptions::DoAsProgressive() const 00395 00396 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00397 Created: 29/10/96 00398 Returns: TRUE if the JPEG should be exported as a progressive file 00399 FALSE otherwise 00400 Purpose: Provides a JPEG specific export parameter 00401 00402 ********************************************************************************************/ 00403 BOOL JPEGExportOptions::DoAsProgressive() const 00404 { 00405 return m_DoAsProgressive; 00406 } 00407 00408 00409 /******************************************************************************************** 00410 00411 > JPEG_QUALITY JPEGExportOptions::GetQuality() const 00412 00413 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00414 Created: 29/10/96 00415 Returns: A JPEG_QUALITY value (0..100) indicating 00416 FALSE otherwise 00417 Purpose: Provides a JPEG specific export parameter 00418 00419 ********************************************************************************************/ 00420 JPEG_QUALITY JPEGExportOptions::GetQuality() const 00421 { 00422 return m_Quality; 00423 } 00424 00425 00426 /******************************************************************************************** 00427 00428 > J_DCT_METHOD JPEGExportOptions::GetDCTMethod() const 00429 00430 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00431 Created: 29/10/96 00432 Returns: TRUE if the JPEG should be exported as a progressive file 00433 FALSE otherwise 00434 Purpose: Provides a JPEG specific export parameter 00435 00436 ********************************************************************************************/ 00437 libJPEG::J_DCT_METHOD JPEGExportOptions::GetDCTMethod() const 00438 { 00439 return m_DCTMethod; 00440 } 00441 00442 00443 /******************************************************************************************** 00444 00445 > BOOL JPEGExportOptions::SetQuality(const JPEG_QUALITY& Quality) 00446 00447 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00448 Created: 29/10/96 00449 Inputs: Quality : 0 - 100 indicating some "quality" 00450 Returns: TRUE if set successfully 00451 FALSE otherwise 00452 Purpose: Sets a JPEG specific export parameter 00453 Errors: ERROR2IF Quality out of range 00454 00455 ********************************************************************************************/ 00456 BOOL JPEGExportOptions::SetQuality(const JPEG_QUALITY& Quality) 00457 { 00458 ERROR2IF(Quality < 0 || Quality > 100, FALSE, "Quality out of range"); 00459 00460 if (m_Quality != Quality) 00461 SetTempFileMatchesExportOptions(FALSE); 00462 m_Quality = Quality; 00463 00464 return TRUE; 00465 } 00466 00467 00468 /******************************************************************************************** 00469 00470 > BOOL JPEGExportOptions::SetMakeProgressive(BOOL bProgressive) 00471 00472 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00473 Created: 29/10/96 00474 Inputs: bProgressive: TRUE if the JPEG should be exported as a progressive, i.e., can 00475 be rendered progressively if you've got the software. FALSE exports normally 00476 Returns: TRUE if set successfully 00477 FALSE otherwise 00478 Purpose: Sets a JPEG specific export parameter 00479 00480 ********************************************************************************************/ 00481 BOOL JPEGExportOptions::SetMakeProgressive(BOOL bProgressive) 00482 { 00483 if (m_DoAsProgressive != bProgressive) 00484 SetTempFileMatchesExportOptions(FALSE); 00485 m_DoAsProgressive = bProgressive; 00486 00487 return TRUE; 00488 } 00489 00490 00491 /******************************************************************************************** 00492 00493 > BOOL JPEGExportOptions::SetDCTMethod(const J_DCT_METHOD& DCTMethod) 00494 00495 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00496 Created: 29/10/96 00497 Inputs: DCTMethod : The DCT method to be used during export (See IJG library for 00498 details) 00499 Returns: TRUE if set successfully 00500 FALSE otherwise 00501 Purpose: Sets an IJG specific parameter 00502 Notes: NOT a user (interface) option 00503 Errors: ERROR2IF DCTMethod not one of: fast,slow or float 00504 00505 ********************************************************************************************/ 00506 BOOL JPEGExportOptions::SetDCTMethod(const libJPEG::J_DCT_METHOD& DCTMethod) 00507 { 00508 ERROR2IF(DCTMethod != libJPEG::JDCT_ISLOW && DCTMethod != libJPEG::JDCT_IFAST && DCTMethod != libJPEG::JDCT_FLOAT, 00509 FALSE, "Invalid DCT method"); 00510 00511 m_DCTMethod = DCTMethod; 00512 00513 return TRUE; 00514 } 00515 00516 00517 /******************************************************************************************** 00518 00519 > BOOL JPEGExportOptions::SetColourModel(const J_COLOR_SPACE& ColourModel) 00520 00521 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00522 Created: 29/10/96 00523 Inputs: ColourModel : The J_COLOR_SPACE that the bitmap is to be exported as 00524 Returns: TRUE if set successfully 00525 FALSE otherwise 00526 Purpose: Sets an IJG specific parameter 00527 Notes: The bitmap is expected to be of the correct format or a converter (DIBConvert) 00528 provided when the bitmap is written. 00529 Errors: ERROR2IF DCTMethod not one of: JCS_RGB or JCS_GRAYSCALE 00530 See Also: JPEGExportFilter::WriteRawBitmap() 00531 00532 ********************************************************************************************/ 00533 BOOL JPEGExportOptions::SetColourModel(const libJPEG::J_COLOR_SPACE& ColourModel) 00534 { 00535 switch (ColourModel) 00536 { 00537 case libJPEG::JCS_RGB: 00538 // This really should be RGB_PIXELSIZE (in jmorecfg.h), but this isn't exported! 00539 m_ColourComponents = 3; 00540 break; 00541 00542 case libJPEG::JCS_GRAYSCALE: 00543 m_ColourComponents = 1; 00544 break; 00545 00546 default: 00547 ERROR2(FALSE, "Invalid Colour Model method"); 00548 00549 } 00550 00551 m_ColourModel = ColourModel; 00552 00553 return TRUE; // success 00554 } 00555 00556 00557 /******************************************************************************************** 00558 00559 > J_COLOR_SPACE JPEGExportOptions::GetColourModel() const 00560 00561 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00562 Created: 29/10/96 00563 Returns: The J_COLOR_SPACE to be used for export 00564 Purpose: Provides a IJG specific export parameter 00565 See Also: GetColourComponentCount() 00566 00567 ********************************************************************************************/ 00568 libJPEG::J_COLOR_SPACE JPEGExportOptions::GetColourModel() const 00569 { 00570 return m_ColourModel; 00571 } 00572 00573 00574 /******************************************************************************************** 00575 00576 > libJPEG::J_COLOR_SPACE JPEGExportOptions::GetColourModel() const 00577 00578 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00579 Created: 29/10/96 00580 Returns: The number of colour components associated with the J_COLOR_SPACE returned by 00581 GetColourModel() 00582 Purpose: Provides an IJG specific export parameter 00583 See Also: GetColourComponentCount() 00584 00585 ********************************************************************************************/ 00586 UINT32 JPEGExportOptions::GetColourComponentCount() const 00587 { 00588 return m_ColourComponents; 00589 } 00590 00591 /******************************************************************************************** 00592 00593 > JPEGExportFilter::JPEGExportFilter() 00594 00595 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00596 Created: 29/10/96 00597 Purpose: Default constructor for a JPEGFilter object. 00598 00599 ********************************************************************************************/ 00600 JPEGExportFilter::JPEGExportFilter() : BaseBitmapFilter() 00601 { 00602 // Initialize members for class Filter 00603 ExportMsgID = _R(IDS_EXPORTMSG_JPG); // "Preparing JPEG file..." 00604 ExportingMsgID = _R(IDS_EXPORTINGMSG_JPG); // "Exporting JPEG file..." 00605 00606 Flags.CanImport = FALSE; 00607 Flags.CanExport = TRUE; 00608 Flags.CanExportMultipleImages = FALSE; 00609 Flags.ShowFilter = TRUE; 00610 00611 FilterID = FILTERID_EXPORT_JPEG; 00612 00613 // Initialize our class members 00614 m_bOldReportErrors = FALSE; 00615 m_bOldThrowExceptions = FALSE; 00616 00617 m_pFilterForUpdate = NULL; 00618 00619 m_pErrorHandler = NULL; 00620 m_pDestinationHandler = NULL; 00621 m_PostOperation = TRUE; 00622 } 00623 00624 00625 /******************************************************************************************** 00626 00627 > JPEGExportFilter::~JPEGExportFilter() 00628 00629 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00630 Created: 29/10/96 00631 Purpose: Default destructor for a JPEGExportFilter object. 00632 00633 ********************************************************************************************/ 00634 JPEGExportFilter::~JPEGExportFilter() 00635 { 00636 if (m_pErrorHandler != NULL) 00637 delete m_pErrorHandler; 00638 00639 if (m_pDestinationHandler != NULL) 00640 delete m_pDestinationHandler; 00641 } 00642 00643 00644 /******************************************************************************************** 00645 00646 > BOOL JPEGExportFilter::Init() 00647 00648 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00649 Created: 29/10/96 00650 Returns: TRUE if the filter was initialized ok 00651 FALSE otherwise 00652 Purpose: Initializes the JPEGExportFilter class. 00653 00654 ********************************************************************************************/ 00655 BOOL JPEGExportFilter::Init() 00656 { 00657 // Get the OILFilter object 00658 pOILFilter = new JPEGExportOILFilter(this); 00659 if (pOILFilter==NULL) 00660 return FALSE; 00661 00662 // Load the description strings 00663 FilterName.Load(_R(IDS_JPG_IMP_FILTERNAME)); 00664 FilterInfo.Load(_R(IDS_JPG_IMP_FILTERINFO)); 00665 00666 if (DeclareFilterPreferenceSection()) 00667 { 00668 Camelot.DeclarePref( NULL, g_szCompression, &g_DefaultCompression, 0, 100 ); 00669 Camelot.DeclarePref( NULL, g_szDCTMethod, (INT32*)&g_DefaultDCTMethod, 0, 2 ); 00670 Camelot.DeclarePref( NULL, g_szProgressive, &g_bExportProgressive, 0, 1 ); 00671 Camelot.DeclarePref( NULL, g_szOptimize, &g_bOptimizeCoding, 0, 1 ); 00672 Camelot.DeclarePref( NULL, g_szSmoothing, &g_Smoothing, 0, 100 ); 00673 00674 // DeclarePreference(Compression); 00675 // DeclarePreference(DCTMethod); 00676 // DeclarePreference(Progressive); 00677 // DeclarePreference(Xppm); 00678 // DeclarePreference(Yppm); 00679 } 00680 // All ok 00681 return TRUE; 00682 } 00683 00684 00685 00686 /******************************************************************************************** 00687 00688 > virtual BOOL JPEGExportFilter::GetRenderBottomToTop() 00689 00690 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00691 Created: 29/10/96 00692 Purpose: See BaseBitmapFilter for details 00693 Notes: From IJG docs: 00694 "Image data should be written in top-to-bottom scanline order. 00695 The JPEG spec contains some weasel wording about how top and bottom are 00696 application-defined terms (a curious interpretation of the English 00697 language...) but if you want your files to be compatible with everyone else's, 00698 you WILL use top-to-bottom order." 00699 00700 ********************************************************************************************/ 00701 BOOL JPEGExportFilter::GetRenderBottomToTop() 00702 { 00703 return FALSE; 00704 } 00705 00706 00707 /******************************************************************************************** 00708 00709 > virtual BOOL JPEGExportFilter::IsThisBppOk(UINT32 Bpp) 00710 00711 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00712 Created: 29/10/96 00713 Inputs: See BaseBitmapFilter for interface details 00714 Purpose: Overriden for JPEG specifics: supports 24 & 8 00715 00716 ********************************************************************************************/ 00717 BOOL JPEGExportFilter::IsThisBppOk(UINT32 Bpp) 00718 { 00719 return (Bpp == 24 || Bpp == 8); 00720 } 00721 00722 00723 /******************************************************************************************** 00724 00725 > virtual BOOL JPEGExportFilter::WriteBitmapToFile(KernelBitmap* pKernelBitmap, double Dpi) 00726 00727 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00728 Created: 29/10/96 00729 Purpose: To duplicate code 00730 SeeAlso: BaseBitmapFilter::WriteBitmapToFile 00731 00732 ********************************************************************************************/ 00733 BOOL JPEGExportFilter::WriteBitmapToFile(KernelBitmap* pKernelBitmap, double Dpi) 00734 { 00735 ERROR2IF(pKernelBitmap == NULL, FALSE, "NULL Args"); 00736 ERROR3IF(!pKernelBitmap->IS_KIND_OF(KernelBitmap), "pKernelBitmap isn't"); 00737 00738 BOOL bSuccess = FALSE; 00739 JPEGExportOptions* pOptions = (JPEGExportOptions*)GetBitmapExportOptions(); 00740 pOptions->RetrieveDefaults(); 00741 pOptions->SetDPI(Dpi); 00742 00743 // export the jpeg just as it is (sjk 21/12/00) 00744 pOptions->m_bJPEGPresentAndSelected = TRUE; 00745 00746 SetFilterForUpdate(NULL); 00747 00748 // Set up the progress bar 00749 ProgressOffset = 0; // reset this Filter member!!! so WriteBitmap() does progress correctly 00750 00751 OILBitmap* pOILBitmap = pKernelBitmap->GetActualBitmap(); 00752 String_64 ProgressString = GetExportProgressString(GetExportFile(), GetExportMsgID()); 00753 BeginSlowJob(pOILBitmap->GetHeight(), FALSE, &ProgressString); 00754 00755 bSuccess = DoFilter(pKernelBitmap, GetExportFile()); 00756 00757 EndSlowJob(); 00758 return bSuccess; 00759 } 00760 00761 /******************************************************************************************** 00762 00763 > virtual BOOL JPEGExportFilter::WriteBitmapToFile( KernelBitmap* pKernelBitmap, 00764 BaseCamelotFilter *pFilter, 00765 CCLexFile *pFile, INT32 Compression) 00766 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00767 Created: 29/10/96 00768 Purpose: To duplicate code 00769 SeeAlso: BaseBitmapFilter::WriteBitmapToFile 00770 00771 ********************************************************************************************/ 00772 BOOL JPEGExportFilter::WriteBitmapToFile( KernelBitmap* pKernelBitmap, 00773 BaseCamelotFilter* pFilter, 00774 CCLexFile* pFile, INT32 Compression) 00775 { 00776 ERROR2IF(pKernelBitmap == NULL || pFilter == NULL || pFile == NULL, FALSE, "NULL Args"); 00777 00778 ERROR3IF(!pKernelBitmap->IS_KIND_OF(KernelBitmap), "pKernelBitmap isn't"); 00779 ERROR3IF(!pFilter->IS_KIND_OF(BaseCamelotFilter), "pFilter isn't"); 00780 ERROR3IF(!pFile->IS_KIND_OF(CCLexFile), "pFile isn't"); 00781 00782 if (!BaseBitmapFilter::WriteBitmapToFile(pKernelBitmap, pFilter, pFile, Compression)) 00783 { 00784 return FALSE; 00785 } 00786 00787 SetFilterForUpdate(pFilter); 00788 00789 JPEGExportOptions* pOptions = (JPEGExportOptions*)GetBitmapExportOptions(); 00790 pOptions->RetrieveDefaults(); 00791 pOptions->SetQuality(Compression); 00792 00793 if (!DoFilter(pKernelBitmap, pFile)) 00794 { 00795 return FALSE; 00796 } 00797 return TRUE; 00798 } 00799 00800 /******************************************************************************************** 00801 00802 > BOOL JPEGExportFilter::WriteBitmapSource(const BitmapSource& Source, UINT32 Height, 00803 BaseCamelotFilter* pThisFilter) 00804 00805 Author: Ranbir_Rana (Xara Group Ltd) <camelotdev@xara.com> (From Colin) 00806 Created: 22/01/97 00807 Inputs: Source : the BitmapSource to write out 00808 Height : the height of the bitmap in this source 00809 pThisFilter : the filter whose IncProgressBarCount we will use for the 00810 progress indicator 00811 Returns: TRUE if written successfully 00812 FALSE otherwise 00813 Purpose: Writes out the given BitmapSource to this file. 00814 00815 Errors: ERROR2's if Height is zero or pThisFilter NULL 00816 See Also: CXaraFile::WriteBitmapSource 00817 00818 ********************************************************************************************/ 00819 00820 BOOL JPEGExportFilter::WriteBitmapSource(BitmapSource *Source, UINT32 Height,BaseCamelotFilter* pThisFilter,CCLexFile* pCCFile) 00821 { 00822 ERROR2IF(pThisFilter == NULL, FALSE, "pThisFilter == NULL"); 00823 ERROR2IF(Height == 0, FALSE, "Height == 0"); 00824 00825 CCBufferFile* pBufferFile = new CCBufferFile(pCCFile); 00826 // Now create a file that can fill it 00827 if (pBufferFile == NULL || !pBufferFile->IsInited()) 00828 { 00829 return FALSE; 00830 } 00831 // Provide the filter with something to work with 00832 Source->AttachToBufferFile(pBufferFile); 00833 00834 // Work out how much to increment the progress bar by on each loop 00835 OFFSET Size = Source->GetSize(); 00836 UINT32 Increment = (Height * CCBufferFile::DEFAULT_BUFSIZ) / Size; 00837 if (Increment > Height) 00838 { 00839 Increment = Height; 00840 } 00841 else if (Increment < 1) 00842 { 00843 Increment = 1; 00844 } 00845 UINT32 UpdateEvery = Size / (Height * CCBufferFile::DEFAULT_BUFSIZ); 00846 00847 // Write out the BitmapSource DEFAULT_BUFSIZ bytes at a time 00848 UINT32 WritesSinceUpdate = 0; 00849 while (!pBufferFile->IsAllWritten()) 00850 { 00851 pBufferFile->write(NULL, CCBufferFile::DEFAULT_BUFSIZ); 00852 if (pBufferFile->bad() || pBufferFile->fail()) 00853 { 00854 delete pBufferFile; 00855 return FALSE; 00856 } 00857 00858 // We've made some progress so provide some user feedback 00859 ++WritesSinceUpdate; 00860 if (WritesSinceUpdate >= UpdateEvery) 00861 { 00862 pThisFilter->IncProgressBarCount(Increment); 00863 WritesSinceUpdate = 0; 00864 } 00865 }; 00866 00867 // Destroy our file handle 00868 delete pBufferFile; 00869 00870 return TRUE; 00871 } 00872 00873 00874 00875 /******************************************************************************************** 00876 00877 > virtual BOOL BOOL JPEGExportFilter::DoFilter( KernelBitmap* pKernelBitmap, 00878 CCLexFile *pFile) 00879 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 00880 Created: 29/10/96 00881 Purpose: Support function to reduce duplicate code 00882 SeeAlso: JPEGExportFilter::WriteBitmapToFile 00883 00884 ********************************************************************************************/ 00885 BOOL JPEGExportFilter::DoFilter(KernelBitmap* pKernelBitmap, CCLexFile *pFile) 00886 { 00887 ERROR2IF(pKernelBitmap == NULL || pFile == NULL, FALSE, "NULL Args"); 00888 ERROR3IF(!pKernelBitmap->IS_KIND_OF(KernelBitmap), "pKernelBitmap isn't"); 00889 ERROR3IF(!pFile->IS_KIND_OF(CCLexFile), "pFile isn't"); 00890 00891 JPEGExportOptions* pOptions = (JPEGExportOptions*)GetBitmapExportOptions(); 00892 00893 if (pOptions == NULL) 00894 return FALSE; 00895 00896 OILBitmap* pOily = pKernelBitmap->GetActualBitmap(); 00897 00898 if (pOptions->GetJPEGPresentAndSelected()) 00899 { 00900 SetPostOperation(FALSE); 00901 00902 // Get the origianl source. 00903 BitmapSource* pSource = NULL; 00904 BaseBitmapFilter* pDummyFilter; 00905 00906 KernelBitmap* pBitmap = pOptions->GetKernelBitmap(); 00907 00908 if (pBitmap == NULL) 00909 return FALSE; 00910 00911 // set our KernelBitmap pointer to NULL. 00912 pOptions->SetKernelBitmap(NULL); 00913 00914 pBitmap->GetOriginalSource(&pSource,&pDummyFilter); 00915 OILBitmap* pOILBitmap = pBitmap->ActualBitmap; 00916 00917 if (pOILBitmap == NULL) 00918 return FALSE; 00919 00920 BitmapInfo Info; 00921 pOILBitmap->GetInfo(&Info); 00922 UINT32 Height = Info.PixelHeight; 00923 00924 // Write out the orginal JPEG image. 00925 if(WriteBitmapSource(pSource, Height, (BaseCamelotFilter*) pDummyFilter, pFile)) 00926 return TRUE; 00927 } 00928 else 00929 { 00930 BOOL bOK = FALSE; 00931 bOK = PrepareForOperation(); 00932 DIBConvert* pConverter = NULL; 00933 00934 switch (pOily->GetBPP()) 00935 { 00936 case 8: 00937 if (pKernelBitmap->IsGreyscale()) 00938 { 00939 pOptions->SetColourModel(libJPEG::JCS_GRAYSCALE); 00940 } 00941 else 00942 { 00943 pOptions->SetColourModel(libJPEG::JCS_RGB); 00944 } 00945 break; 00946 00947 case 24: 00948 case 32: 00949 pOptions->SetColourModel(libJPEG::JCS_RGB); 00950 break; 00951 00952 default: 00953 ERROR3("DoFilter: invalid bpp"); 00954 bOK = FALSE; 00955 break; 00956 } 00957 // Create a converter from bitmap depth to export depth 00958 // pConverter = DIBConvert::Create(((WinBitmap*)pOily)->BMInfo, 00959 // (8 * pOptions->GetColourComponentCount())); 00960 pConverter = DIBConvert::Create(((CWxBitmap*)pOily)->BMInfo, 00961 (8 * pOptions->GetColourComponentCount())); 00962 00963 if (bOK) 00964 { 00965 SetPixelWidth(pOily->GetWidth()); 00966 SetPixelHeight(pOily->GetHeight()); 00967 SetDepthToRender(pOily->GetBPP()); 00968 00969 bOK = InternalPrepareToExport(); 00970 } 00971 00972 if (bOK) 00973 { 00974 bOK = WriteRawBitmap( pKernelBitmap->GetBitmapBits(), 00975 GetPixelWidth(), GetPixelHeight(), pOily->GetBPP(), 00976 pConverter); 00977 } 00978 00979 if (bOK) 00980 { 00981 bOK = WritePostFrame(); 00982 } 00983 00984 00985 if (pConverter != NULL) 00986 { 00987 delete pConverter; 00988 } 00989 CleanUpAfterExport(); 00990 00991 // set our KernelBitmap pointer to NULL. 00992 pOptions->SetKernelBitmap(NULL); 00993 return bOK; 00994 } 00995 // set our KernelBitmap pointer to NULL. 00996 pOptions->SetKernelBitmap(NULL); 00997 return FALSE; 00998 } 00999 01000 01001 /******************************************************************************************** 01002 01003 > virtual BOOL JPEGExportFilter::PrepareForOperation() 01004 01005 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01006 Created: 29/10/96 01007 Purpose: Support function to do something before any actual output 01008 01009 ********************************************************************************************/ 01010 BOOL JPEGExportFilter::PrepareForOperation() 01011 { 01012 // The error handling in the following should probably be replaced by exceptions at 01013 // some time, when somebody can decide on a standard. 01014 01015 // Set up a JPEGErrorManager 01016 if (!InitErrorHandler()) 01017 { 01018 return FALSE; 01019 } 01020 01021 // Initialize the main JPG library structure 01022 try 01023 { 01024 using namespace libJPEG; 01025 jpeg_create_compress(&m_cinfo); 01026 } 01027 catch (...) 01028 { 01029 StringID errorString = m_pErrorHandler->GetStringIDForError(); 01030 Error::SetError(errorString); 01031 return FALSE; 01032 } 01033 01034 // Setup a JPEGDataDestination 01035 if (!InitFileHandler()) 01036 { 01037 return FALSE; 01038 } 01039 01040 // Don't let the CCLexFile report errors or throw exceptions 01041 m_bOldThrowExceptions = GetExportFile()->SetThrowExceptions(FALSE); 01042 m_bOldReportErrors = GetExportFile()->SetReportErrors(FALSE); 01043 01044 // Shouldn't have to do this 01045 PaletteType = PAL_STANDARD; // don't - HATE this 01046 01047 SetDepthToRender(24); // immer but not necessarily what we get 01048 01049 return TRUE; 01050 } 01051 01052 01053 /******************************************************************************************** 01054 01055 > virtual BOOL JPEGExportFilter::GetExportOptions(BitmapExportOptions* pOptions) 01056 01057 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01058 Created: 29/10/96 01059 Purpose: Overridden version provides JPEG export dialog 01060 Scope: Protected 01061 See Also: BaseBitmapFilter::GetBitmapExportOptions() 01062 01063 ********************************************************************************************/ 01064 BOOL JPEGExportFilter::GetExportOptions(BitmapExportOptions* pOptions) 01065 { 01066 #if !defined(EXCLUDE_FROM_RALPH) 01067 ERROR2IF(pOptions == NULL, FALSE, "NULL Args"); 01068 01069 BOOL Ok = TRUE; 01070 01071 // JPEGExportOptions* pJPEGOptions = (JPEGExportOptions*)pOptions; 01072 // ERROR3IF(!pJPEGOptions->IS_KIND_OF(JPEGExportOptions), "pJPEGOptions isn't"); 01073 01074 OpDescriptor* pOpDes = OpDescriptor::FindOpDescriptor(OPTOKEN_GIFTABDLG); 01075 if (pOpDes != NULL) 01076 { 01077 // set up the data for the export options dialog 01078 OpParam Param( pOptions, this ); 01079 01080 // invoke the dialog 01081 pOpDes->Invoke(&Param); 01082 01083 // SMFIX 01084 // we have brought the dlg up so get the options from the dlg as the graphic type may have changed 01085 pOptions = BmapPrevDlg::m_pExportOptions; 01086 01087 // check for valid options 01088 // This may get messed up, so have to use the second line below. 01089 Ok = BmapPrevDlg::m_bClickedOnExport; 01090 01091 } 01092 else 01093 { 01094 ERROR3("Unable to find OPTOKEN_GIFTABDLG"); 01095 } 01096 01097 /* if (Ok) 01098 { 01099 // If Ok used then set the new defaults 01100 pJPEGOptions->SetAsDefaults(); 01101 01102 pJPEGOptions->SetDepth(24); // Always output at 24bpp 01103 01104 SetDepthToRender(24); 01105 } 01106 */ 01107 // Return with the ok/cancel state used on the dialog box 01108 return Ok; 01109 #else 01110 return FALSE; 01111 #endif 01112 } 01113 01114 01115 // SMFIX sjk 5/12/00 there used to be some junk in the call to GetExportOptions that assumed the 01116 // filter type being used which could be changed by the GetExportOptions call itself 01117 // therefore all this sort of stuff should be called on the correct known filter using this 01118 // call afterwards 01119 void JPEGExportFilter::PostGetExportOptions(BitmapExportOptions* pOptions) 01120 { 01121 // should be of this type 01122 01123 // do the baseclass options 01124 BaseBitmapFilter::PostGetExportOptions(pOptions); 01125 01126 // do the specific to this class options 01127 pOptions->SetDepth(24); // Always output at 24bpp 01128 SetDepthToRender(24); 01129 } 01130 01131 /******************************************************************************************** 01132 01133 > BOOL JPEGExportFilter::PrepareToExport(Spread *pSpread, UINT32 Depth, double DPI, 01134 SelectionType Selection, UINT32 Dither) 01135 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01136 Created: 29/10/96 01137 Returns: FALSE if failed else TRUE 01138 Purpose: Provides additional processing to the base class to start the JPEG 01139 compression. 01140 SeeAlso: BaseBitmapFilter::PrepareToExport() 01141 01142 ********************************************************************************************/ 01143 BOOL JPEGExportFilter::PrepareToExport(Spread *pSpread, UINT32 Depth, double DPI, 01144 SelectionType Selection, UINT32 Dither) 01145 { 01146 if (!BaseBitmapFilter::PrepareToExport(pSpread, Depth, DPI, Selection, Dither)) 01147 { 01148 return FALSE; 01149 } 01150 01151 SetFilterForUpdate(NULL); 01152 01153 if (!((JPEGExportOptions*)GetBitmapExportOptions())->SetColourModel(libJPEG::JCS_RGB)) 01154 { 01155 ERROR2(FALSE,"Can't set colour model"); 01156 return FALSE; 01157 } 01158 01159 if (!InternalPrepareToExport()) 01160 { 01161 return FALSE; 01162 } 01163 01164 return TRUE; 01165 } 01166 01167 01168 /******************************************************************************************** 01169 01170 > BOOL JPEGExportFilter::InternalPrepareToExport() 01171 01172 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01173 Created: 29/10/96 01174 Returns: FALSE if failed else TRUE 01175 Purpose: Support function setting up the IJG library options and starting the 01176 compression. 01177 SeeAlso: PrepareToExport(), DoFilter() (callers) 01178 01179 ********************************************************************************************/ 01180 BOOL JPEGExportFilter::InternalPrepareToExport() 01181 { 01182 JPEGExportOptions* pExportInfo = (JPEGExportOptions*)GetBitmapExportOptions(); 01183 ERROR3IF(!pExportInfo->IS_KIND_OF(JPEGExportOptions), "pExportInfo isn't"); 01184 01185 m_cinfo.image_width = GetPixelWidth(); 01186 m_cinfo.image_height = GetPixelHeight(); 01187 01188 m_cinfo.in_color_space = pExportInfo->GetColourModel(); 01189 m_cinfo.input_components = pExportInfo->GetColourComponentCount(); 01190 01191 try 01192 { 01193 libJPEG::jpeg_set_defaults(&m_cinfo); 01194 01195 if (pExportInfo->DoAsProgressive()) 01196 { 01197 libJPEG::jpeg_simple_progression(&m_cinfo); 01198 } 01199 01200 m_cinfo.density_unit = 1; // that's JFIF for DPI 01201 m_cinfo.X_density = UINT16 (pExportInfo->GetDPI()); 01202 m_cinfo.Y_density = UINT16 (pExportInfo->GetDPI()); 01203 01204 libJPEG::jpeg_set_quality (&m_cinfo, pExportInfo->GetQuality(), TRUE); 01205 01206 m_cinfo.optimize_coding = g_bOptimizeCoding; 01207 m_cinfo.smoothing_factor = g_Smoothing; 01208 01209 // DCT algorithm preference 01210 m_cinfo.dct_method = pExportInfo->GetDCTMethod(); 01211 01212 01213 libJPEG::jpeg_start_compress(&m_cinfo, TRUE); // "TRUE" for complete JPEG interchange datastream 01214 } 01215 catch (...) 01216 { 01217 StringID errorString = m_pErrorHandler->GetStringIDForError(); 01218 Error::SetError(errorString); 01219 return FALSE; 01220 } 01221 01222 return TRUE; 01223 } 01224 01225 01226 01227 /******************************************************************************************** 01228 01229 > virtual BOOL JPEGExportFilter::WriteFileHeader(void) 01230 01231 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01232 Created: 29/10/96 01233 Returns: FALSE if failed else TRUE 01234 Purpose: To write out the file specific header data: actually sets up the JPEG filter 01235 SeeAlso: BaseBitmapFilter::WriteFileHeader() 01236 01237 ********************************************************************************************/ 01238 BOOL JPEGExportFilter::WriteFileHeader(void) 01239 { 01240 BOOL ok = FALSE; 01241 01242 ok = PrepareForOperation(); 01243 01244 return ok; 01245 } 01246 01247 01248 /******************************************************************************************** 01249 01250 > virtual BOOL JPEGExportFilter::WriteFrame(void) 01251 01252 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01253 Created: 29/10/96 01254 Returns: FALSE if failed else TRUE 01255 Purpose: Overrides the image itself 01256 This base class version actually calls the WriteToFile() function so that 01257 derived classes do not have to implement any of the multi-image stuff 01258 SeeAlso: BaseBitmapFilter::WriteFrame(void) 01259 01260 8. Aborting. 01261 01262 If you decide to abort a compression cycle before finishing, you can clean up 01263 in either of two ways: 01264 01265 * If you don't need the JPEG object any more, just call 01266 jpeg_destroy_compress() or jpeg_destroy() to release memory. This is 01267 legitimate at any point after calling jpeg_create_compress() --- in fact, 01268 it's safe even if jpeg_create_compress() fails. 01269 01270 * If you want to re-use the JPEG object, call jpeg_abort_compress(), or 01271 jpeg_abort() which works on both compression and decompression objects. 01272 This will return the object to an idle state, releasing any working memory. 01273 jpeg_abort() is allowed at any time after successful object creation. 01274 01275 Note that cleaning up the data destination, if required, is your 01276 responsibility. 01277 01278 ********************************************************************************************/ 01279 BOOL JPEGExportFilter::WriteFrame(void) 01280 { 01281 BOOL Ok; 01282 01283 BMP_SIZE Width, Height; 01284 BMP_DEPTH Depth; 01285 ADDR pBitmapBits; 01286 01287 Ok = GetCurrentStripInfo(&pBitmapBits, &Width, &Height, &Depth); 01288 01289 // Create a converter from bitmap depth to export depth 01290 DIBConvert* pConverter = DIBConvert::Create( Depth, GetRenderDepth(), Width, NULL ); 01291 01292 if (Ok) 01293 { 01294 Ok = WriteRawBitmap( pBitmapBits, Width, Height, Depth, pConverter ); 01295 } 01296 01297 return Ok; 01298 } 01299 01300 01301 01302 /******************************************************************************************** 01303 01304 > virtual BOOL JPEGExportFilter::WriteRawBitmap( const ADDR& pBitmapData, 01305 const BMP_SIZE& Width, const BMP_SIZE& Height, 01306 const BMP_DEPTH& Bpp, 01307 DIBConvert* pConverter) 01308 01309 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01310 Created: 29/10/96 01311 Inputs: pBitmapData : The bits, as in "bitmap" 01312 Width: The bitmap width in pixels 01313 Height: The bitmap height in pixels 01314 Depth: The bitmap depth in bits per pixel 01315 pConverter: A pointer to a DIBConvert to convert the actual bitmap given to 01316 32bpp data 01317 Returns: FALSE if failed else TRUE 01318 Purpose: Support function for writing out the bitmap scanlines 01319 Called by WriteFrame() & WriteBitmap() 01320 01321 ********************************************************************************************/ 01322 BOOL JPEGExportFilter::WriteRawBitmap( const ADDR& pBitmapData, 01323 const BMP_SIZE& Width, const BMP_SIZE& Height, 01324 const BMP_DEPTH& Bpp, 01325 DIBConvert* pConverter) 01326 { 01327 // ERROR2IF(pConverter == NULL && Bpp != (BMP_DEPTH)GetRenderDepth(), FALSE, "Parameters incorrect"); 01328 01329 const UINT32 ScanlineSize = DIBUtil::ScanlineSize( Width, Bpp ); 01330 const UINT32 ExportlineSize = DIBUtil::ScanlineSize( Width, 32 ); 01331 Filter* const pFilterForUpdate = GetFilterForUpdate(); 01332 01333 ADDR pExportBuffer = NULL; 01334 ADDR pBitmapLine = pBitmapData; 01335 ADDR pExportLine = NULL; 01336 01337 01338 if (pConverter != NULL) 01339 { 01340 pExportBuffer = new BYTE[ExportlineSize]; 01341 pExportLine = pExportBuffer; 01342 } 01343 01344 try 01345 { 01346 UINT32 ScanlinesRemaining = Height; 01347 pBitmapLine += (ScanlinesRemaining - 1) * ScanlineSize; 01348 01349 RGBTRIPLE* pTempLine = (RGBTRIPLE*)alloca( ExportlineSize ); 01350 01351 // Do it one line at a time like it or not 01352 while (ScanlinesRemaining > 0) 01353 { 01354 // Convert the bitmap to 32bpp if necessary 01355 if (pConverter == NULL) 01356 { 01357 pExportLine = pBitmapLine; 01358 } 01359 else 01360 { 01361 pConverter->Convert(pBitmapLine, pExportBuffer, 1, FALSE); 01362 } 01363 01364 #if !defined(__WXMSW__) && defined(BIG_ENDIAN) 01365 // Component swapping must be done out-of-line, to stop original 01366 // being blatted 01367 RGBTRIPLE* pExportRGB = (RGBTRIPLE*)pExportLine; 01368 if( pExportLine == pBitmapLine ) 01369 { 01370 pExportRGB = pTempLine; 01371 memcpy( pExportRGB, pExportLine, ExportlineSize ); 01372 pExportLine = PBYTE(pExportRGB); 01373 } 01374 for( unsigned ord = 0; ord < Width; ++ord, ++ pExportRGB ) 01375 std::swap( pExportRGB->rgbtBlue, pExportRGB->rgbtRed ); 01376 #endif 01377 01378 libJPEG::jpeg_write_scanlines(&m_cinfo, &pExportLine, 1); 01379 01380 if (pFilterForUpdate != NULL) 01381 { 01382 // Ask the pFilter to update the progress bar for us 01383 pFilterForUpdate->IncProgressBarCount(1); 01384 } 01385 else 01386 { 01387 ContinueSlowJob(ProgressOffset + (Height - ScanlinesRemaining)); 01388 } 01389 01390 pBitmapLine -= ScanlineSize; 01391 --ScanlinesRemaining; 01392 } 01393 } 01394 catch (...) 01395 { 01396 if (pExportBuffer != NULL) 01397 { 01398 delete pExportBuffer; 01399 } 01400 StringID errorString = m_pErrorHandler->GetStringIDForError(); 01401 Error::SetError(errorString); 01402 01403 return FALSE; 01404 } 01405 01406 if (pExportBuffer != NULL) 01407 { 01408 delete pExportBuffer; 01409 } 01410 01411 if (pFilterForUpdate == NULL) 01412 { 01413 // Add in the height of the strip that we have just exported to the progress offset value 01414 ProgressOffset += Height; 01415 } 01416 01417 return TRUE; 01418 } 01419 01420 01421 /******************************************************************************************** 01422 01423 > virtual BOOL JPEGExportFilter::WritePostFrame(void) 01424 01425 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01426 Created: 29/10/96 01427 Returns: FALSE if failed else TRUE 01428 Purpose: Overrides base class to finish JPEG compression cycle of the current frame 01429 SeeAlso: BaseBitmapFilter 01430 01431 ********************************************************************************************/ 01432 BOOL JPEGExportFilter::WritePostFrame(void) 01433 { 01434 try 01435 { 01436 libJPEG::jpeg_finish_compress(&m_cinfo); 01437 } 01438 catch (...) 01439 { 01440 StringID errorString = m_pErrorHandler->GetStringIDForError(); 01441 Error::SetError(errorString); 01442 01443 return FALSE; 01444 } 01445 01446 return TRUE; 01447 } 01448 01449 01450 01451 /******************************************************************************************** 01452 01453 > virtual BOOL JPEGExportFilter::EndWriteToFile(void) 01454 01455 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01456 Created: 29/10/96 01457 Purpose: Overrides base class: does nothing 01458 See Also: BaseBitmapFilter::EndWriteToFile(void) 01459 01460 ********************************************************************************************/ 01461 BOOL JPEGExportFilter::EndWriteToFile(void) 01462 { 01463 return TRUE; 01464 } 01465 01466 01467 /******************************************************************************************** 01468 01469 > virtual void JPEGExportFilter::CleanUpAfterExport() 01470 01471 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01472 Created: 29/10/96 01473 Purpose: Overridden to clean up JPEG specific mess 01474 SeeAlso: BaseBitmapFilter::CleanUpAfterExport() 01475 01476 ********************************************************************************************/ 01477 void JPEGExportFilter::CleanUpAfterExport() 01478 { 01479 if (GetPostOperation()) 01480 { 01481 libJPEG::jpeg_destroy_compress(&m_cinfo); 01482 } 01483 01484 if (m_pDestinationHandler != NULL) 01485 { 01486 delete m_pDestinationHandler; 01487 m_pDestinationHandler = NULL; 01488 } 01489 01490 if (m_pErrorHandler != NULL) 01491 { 01492 delete m_pErrorHandler; 01493 m_pErrorHandler = NULL; 01494 } 01495 01496 // Now call the baseclass version to do its stuff 01497 BaseBitmapFilter::CleanUpAfterExport(); 01498 } 01499 01500 01501 /******************************************************************************************** 01502 01503 > BOOL JPEGExportFilter::InitErrorHandler() 01504 01505 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01506 Created: 29/10/96 01507 Purpose: Creates & initializes an error handler for this filter 01508 01509 ********************************************************************************************/ 01510 BOOL JPEGExportFilter::InitErrorHandler() 01511 { 01512 if (m_pErrorHandler == NULL) 01513 { 01514 m_pErrorHandler = new JPEGErrorManager; 01515 if (m_pErrorHandler == NULL) 01516 { 01517 Error::SetError(_R(IDS_OUT_OF_MEMORY)); 01518 return FALSE; 01519 } 01520 01521 } 01522 m_cinfo.err = m_pErrorHandler->GetErrorMgrStruct(); 01523 return TRUE; 01524 } 01525 01526 01527 /******************************************************************************************** 01528 01529 > BOOL JPEGExportFilter::InitFileHandler() 01530 01531 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01532 Created: 29/10/96 01533 Purpose: Creates & initializes a source data provider for this filter. 01534 01535 ********************************************************************************************/ 01536 BOOL JPEGExportFilter::InitFileHandler() 01537 { 01538 SetPostOperation(TRUE); 01539 01540 if (m_cinfo.dest == NULL) 01541 { 01542 if (m_pDestinationHandler == NULL) 01543 { 01544 m_pDestinationHandler = new JPEGDataDestination(GetExportFile()); 01545 if (m_pDestinationHandler == NULL) 01546 { 01547 Error::SetError(_R(IDS_OUT_OF_MEMORY)); 01548 return FALSE; 01549 } 01550 } 01551 m_pDestinationHandler->Init(&m_cinfo); 01552 } 01553 return TRUE; 01554 } 01555 01556 01557 /******************************************************************************************** 01558 01559 > virtual BitmapExportOptions* JPEGExportFilter::CreateExportOptions() const 01560 01561 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01562 Created: 29/10/96 01563 Purpose: Overrides base class to provide JPEGExportOptions 01564 See Also: BaseBitmapFilter::CreateExportOptions() 01565 01566 ********************************************************************************************/ 01567 BitmapExportOptions* JPEGExportFilter::CreateExportOptions() const 01568 { 01569 JPEGExportOptions* pExportOptions = new JPEGExportOptions(JPEG, &FilterName); 01570 01571 return (BitmapExportOptions*)pExportOptions; 01572 } 01573 01574 01575 /******************************************************************************************** 01576 01577 > virtual BOOL JPEGExportFilter::SetExportHint(Document* pDoc) 01578 01579 Author: Gerry_Iles (Xara Group Ltd) <camelotdev@xara.com> 01580 Created: 27/07/97 01581 Purpose: Overrides base class to set correct hint 01582 See Also: BaseBitmapFilter::SetExportHint() 01583 01584 ********************************************************************************************/ 01585 01586 BOOL JPEGExportFilter::SetExportHint(Document* pDoc) 01587 { 01588 BOOL Ok = TRUE; 01589 01590 if (pDoc != NULL) 01591 { 01592 ExportHint* pHint = pDoc->GetExportHint(); 01593 ERROR3IF(pHint == NULL, "NULL ExportHint"); 01594 01595 BitmapExportOptions* pBaseOptions = GetBitmapExportOptions(); 01596 ERROR3IF(pBaseOptions == NULL, "NULL Options"); 01597 01598 if (pHint != NULL && pBaseOptions != NULL) 01599 { 01600 ERROR2IF(!(IS_A(pBaseOptions, JPEGExportOptions)), FALSE, "Incorrect type of options"); 01601 JPEGExportOptions* pOptions = (JPEGExportOptions*) pBaseOptions; 01602 01603 pHint->SetType(HINTTYPE_JPEG); 01604 pHint->SetWidth(GetPixelWidth()); 01605 pHint->SetHeight(GetPixelHeight()); 01606 pHint->SetBPP(pOptions->GetDepth()); 01607 01608 String_256 Opts; 01609 01610 Opts._MakeMsg(_T("Q#1%ld"), pOptions->GetQuality()); 01611 01612 String_32 DPIString; 01613 Ok = Convert::DoubleToString( pOptions->GetDPI(), &DPIString, 3); 01614 01615 Opts += _T(" D"); 01616 Opts += DPIString; 01617 01618 if (pOptions->DoAsProgressive()) 01619 { 01620 Opts += _T(" P"); 01621 } 01622 01623 pHint->SetOptionsString(Opts); 01624 } 01625 } 01626 01627 return Ok; 01628 } 01629 01630 01631 /******************************************************************************************** 01632 01633 > Filter* JPEGExportFilter::GetFilterForUpdate() const 01634 01635 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01636 Created: 29/10/96 01637 Returns: A pointer to the filter whose member IncProgressBarCount() is called during 01638 the export for progress update or NULL if no filter is to be used for such 01639 Purpose: Allows feedback to any primary filter 01640 01641 ********************************************************************************************/ 01642 Filter* JPEGExportFilter::GetFilterForUpdate() const 01643 { 01644 return m_pFilterForUpdate; 01645 } 01646 01647 01648 /******************************************************************************************** 01649 01650 > BOOL JPEGExportFilter::SetFilterForUpdate(Filter* const pFilterForUpdate) 01651 01652 Author: Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> 01653 Created: 29/10/96 01654 Returns: TRUE if successfully set, 01655 FALSE otherwise. 01656 Purpose: Sets the filter for any progress update on export 01657 Notes: Should be set to NULL for ordinary import 01658 Errors: ERROR3IF invalid arg type 01659 01660 ********************************************************************************************/ 01661 BOOL JPEGExportFilter::SetFilterForUpdate(Filter* const pFilterForUpdate) 01662 { 01663 ERROR3IF(pFilterForUpdate != NULL && !pFilterForUpdate->IS_KIND_OF(Filter), 01664 "pFilterForUpdate isn't"); 01665 01666 m_pFilterForUpdate = pFilterForUpdate; 01667 01668 return TRUE; 01669 } 01670 01671 01672 01673 01674 /******************************************************************************************** 01675 01676 > BOOL JPEGExportFilter::DoExportBitmapWithOptions(Operation* pOp, CCLexFile* pFile, PathName* pPath, 01677 KernelBitmap* pBitmap, BitmapExportOptions *pOptions) 01678 01679 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01680 Created: 25/4/95 01681 Inputs: 01682 Purpose: Exports the specified bitmap straight out to file with none of the rendering 01683 that DoExport does. Uses the virtual fns of the inherited class. 01684 Do not override unless really necessary. Similar to DoExportBitmap in the base 01685 class, but uses the passed options, rather then invoking a dialog to get ones. 01686 Returns: TRUE if worked, FALSE if failed. 01687 01688 ********************************************************************************************/ 01689 01690 BOOL JPEGExportFilter::DoExportBitmapWithOptions(Operation* pOp, CCLexFile* pFile, PathName* pPath, 01691 KernelBitmap* pBitmap, BitmapExportOptions *pOptions) 01692 { 01693 #ifdef DO_EXPORT 01694 ERROR2IF(pBitmap == NULL,FALSE,"BaseBitmapFilter::DoExportBitmap null bitmap pointer specified"); 01695 01696 if (pOptions == NULL) 01697 { 01698 // Create a record of information about the export 01699 SetUpExportBitmapOptions(&pOptions, pBitmap, TRUE); 01700 } 01701 01702 if (pOptions == NULL) 01703 return FALSE; 01704 01705 // remember the old export options 01706 // BitmapExportOptions *pOldOptions = GetBitmapExportOptions(); 01707 // if (pOldOptions != NULL) 01708 // pOldOptions->RetrieveDefaults(); 01709 01710 // Added by Craig Hamilton 11/9/00. 01711 // Make a copy of the old options since the pointer to the old options gets vaped by 01712 // SetExportOptions. The copy is used to reinitialise pOldOptions later. 01713 // BitmapExportOptions *tempOptions = pOldOptions->MakeCopy(); 01714 // End added. 01715 01716 // set the new ones 01717 SetExportOptions(pOptions); 01718 pOptions->SetAsDefaults(); 01719 01720 // Make a note of the Disk file we are to use 01721 OutputFile = pFile; 01722 01723 // Note this pointer for later use 01724 pExportBitmap = pBitmap; 01725 01726 // Note this ptr for use in JPEG export. 01727 JPEGExportOptions::SetKernelBitmap(pBitmap); 01728 01729 // Get a pointer to the actual bitmap so that we can get some details from it. 01730 OILBitmap *pOilBitmap = pBitmap->ActualBitmap; 01731 ERROR2IF(pOilBitmap == NULL,FALSE,"BaseBitmapFilter::DoExportBitmap null oil bitmap pointer"); 01732 01733 // Get the details from the specified bitmap 01734 BitmapInfo BmInfo; 01735 pOilBitmap->GetInfo(&BmInfo); 01736 GetBitmapExportOptions()->SetDepth(BmInfo.PixelDepth); // get the bitmaps bpp 01737 01738 // Should really save the dpi when we load the file itself rather than doing 01739 // all this conversion with possible rounding errors. 01740 // Use the original size that has been calculated in the info header 01741 UINT32 PixWidth = BmInfo.PixelWidth; 01742 // UINT32 PixHeight = BmInfo.PixelHeight; 01743 MILLIPOINT RecWidth = BmInfo.RecommendedWidth; 01744 // MILLIPOINT RecHeight = BmInfo.RecommendedHeight; 01745 // double DPI = 0.0; 01746 if (PixWidth > 0) 01747 { 01748 //DPI = Mul32Div32( PixWidth, 72000, RecWidth ); 01749 GetBitmapExportOptions()->SetDPI((PixWidth * 72000.0)/(double)RecWidth); 01750 } 01751 01752 BOOL ok = TRUE; 01753 01754 // Used to open the file up before starting DoExport. But this meant a cancel on the export 01755 // options dialog had filled the file, if it was already present. So now up up here if 01756 // not open already. In the PreviewBitmap case the file will already be open. 01757 if (!pFile->isOpen()) 01758 { 01759 if (pFile->IsKindOf(CC_RUNTIME_CLASS(CCDiskFile))) 01760 { 01761 ok = OpenExportFile((CCDiskFile*) pFile, pPath); 01762 if (!ok) return FALSE; 01763 } 01764 else 01765 { 01766 TRACEUSER( "JustinF", _T("Tried to open non-CCDiskFile in BaseBitmapFilter::DoExportBitmap\n")); 01767 return FALSE; 01768 } 01769 } 01770 01771 // Make a note of the Disk file we are to use 01772 OutputFile = pFile; 01773 01774 // We do not use an export region so specify null. 01775 ExportRegion = NULL; 01776 01777 // Actually write to the file, showing progress hourglass as we go 01778 ok = WriteBitmapToFile(pBitmap, GetBitmapExportOptions()->GetDPI()); 01779 01780 if (ok) 01781 WriteFileEnd(); 01782 01783 // All done - deallocate dynamic objects, stop the progress display/hourglass 01784 // and return success. (Also closes file). 01785 CleanUpAfterExport(); 01786 01787 // restore the old export options 01788 // if (pOldOptions != NULL) 01789 // { 01790 // Added by Craig Hamilton 11/9/00. 01791 // With the call to SetExportOptions the memory pointed to by pOldOptions is vaped. 01792 // Use tempOptions to reinitialise or get an access violation. 01793 // pOldOptions = tempOptions->MakeCopy(); 01794 // End added. 01795 01796 // SetExportOptions(pOldOptions); 01797 // pOldOptions->SetAsDefaults(); 01798 // } 01799 01800 // restore the file 01801 OutputFile = pFile; 01802 01803 return ok; 01804 #else 01805 return FALSE; 01806 #endif 01807 } 01808