exjpeg.cpp

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

Generated on Sat Nov 10 03:45:07 2007 for Camelot by  doxygen 1.4.4