imjpeg.cpp

Go to the documentation of this file.
00001 // $Id: imjpeg.cpp 1758 2006-09-20 11:25:11Z luke $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 
00099 // A JPEG import filter 
00100 
00101 #include "camtypes.h"
00102 //#include "filters.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00103 //#include "progress.h"
00104 //#include "oilfltrs.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00105 #include "oilbitmap.h"
00106 //#include "dibutil.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00107 //#include "filtrres.h"
00108 //#include "andy.h"         // for _R(IDE_FORMATNOTSUPPORTED)
00109 //#include "resource.h"     // for _R(IDS_OUT_OF_MEMORY)
00110 //#include "accures.h"      // for _R(IDW_CANCELLEDBMPIMPORT)
00111 #include "bmpsrc.h"         // for (JPEG)BitmapSource
00112 //#include "camfiltr.h"     // for GetCurrentRecordSize() - in camtypes.h [AUTOMATICALLY REMOVED]
00113 
00114 #include "imjpeg.h"
00115 #include "jpgsrc.h"
00116 #include "jpgprgrs.h"
00117 #include "jpgermgr.h"
00118 
00119 /********************************************************************************************
00120 
00121 >   class JPEGImportOptions : public BitmapImportOptions
00122 
00123     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00124     Created:    25/06/96
00125     Purpose:    Import options for the JPEG import filter. Allows a clean method of passing
00126                 assorted parameters for the JPEG import filter. Specifically, that the
00127                 calling class should give us a progress bar.
00128     Scope:      public
00129     See Also:   BitmapImportOptions
00130 
00131 ********************************************************************************************/
00132 class JPEGImportOptions : public BitmapImportOptions
00133 {
00134     // Declare the class for memory tracking
00135     CC_DECLARE_MEMDUMP(JPEGImportOptions);
00136 public:
00137     JPEGImportOptions() : BitmapImportOptions() {m_bProvideProgress = TRUE;}
00138 
00139     BOOL m_bProvideProgress;
00140     
00141 };
00142 /*
00143 class JPEGImportResults
00144 {
00145 public:
00146     LPBITMAPINFO    *m_ppInfo;
00147     LPBYTE          *m_ppBytes;
00148 };
00149 */
00150 
00151 // Place any IMPLEMENT type statements here
00152 CC_IMPLEMENT_MEMDUMP(JPEGImportFilter, BaseBitmapFilter)
00153 CC_IMPLEMENT_MEMDUMP(JPEGImportOptions,  BitmapImportOptions)
00154 
00155 BOOL                    JPEGImportFilter::m_fImportAt96dpi = m_fImportAt96dpi;
00156 
00157 // We want better memory tracking
00158 #define new CAM_DEBUG_NEW
00159 
00160 // Functions follow
00161 
00162 
00163 
00164 /********************************************************************************************
00165 
00166 >   JPEGImportFilter::JPEGImportFilter()
00167 
00168     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00169     Created:    02/08/96
00170     Purpose:    Default constructor for a JPEGFilter object.
00171 
00172 ********************************************************************************************/
00173 JPEGImportFilter::JPEGImportFilter() : BaseBitmapFilter()
00174 {
00175     // Initialize members for class Filter
00176     ImportMsgID = _R(IDS_IMPORTMSG_JPEG);
00177 
00178     Flags.CanImport                 = TRUE;
00179     Flags.CanExport                 = FALSE;
00180     Flags.CanExportMultipleImages   = FALSE;
00181     Flags.ShowFilter                = TRUE;
00182 
00183     FilterID = FILTERID_IMPORT_JPEG;
00184 
00185     // Initialize our class members
00186     m_pFile                 = NULL;
00187     m_bOldReportErrors      = FALSE;
00188     m_bOldThrowExceptions   = FALSE;
00189     m_uStartOffset          = 0;        // Offset from start at which header appears, maybe...
00190 
00191     m_pErrorHandler         = NULL;
00192     m_pSourceHandler        = NULL;
00193     m_pProgressMonitor      = NULL;
00194 
00195     m_pFilterForProgress    = NULL;
00196     m_pFileForProgress      = NULL;
00197     m_uImportSize           = 0;
00198 
00199     m_ppInfo                = NULL;
00200     m_ppBytes               = NULL;
00201     m_uWidth                = 0;
00202     m_uHeight               = 0;
00203     m_uBitsPerPixel         = 0;
00204 }
00205 
00206 
00207 /********************************************************************************************
00208 
00209 >   JPEGImportFilter::~JPEGImportFilter()
00210 
00211     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00212     Created:    02/08/96
00213     Purpose:    Default constructor for a JPEGFilter object.
00214 
00215 ********************************************************************************************/
00216 JPEGImportFilter::~JPEGImportFilter()
00217 {
00218     if (m_pErrorHandler != NULL)
00219         delete m_pErrorHandler;
00220 
00221     if (m_pSourceHandler != NULL)
00222         delete m_pSourceHandler;
00223 
00224     if (m_pProgressMonitor != NULL)
00225         delete m_pProgressMonitor;
00226 }
00227 
00228 /********************************************************************************************
00229 
00230 >   BOOL JPEGImportFilter::Init()
00231 
00232     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00233     Created:    02/08/96
00234     Returns:    TRUE if the filter was initialized ok
00235                 FALSE otherwise
00236     Purpose:    Initializes the JPEGImportFilter class.
00237 
00238 ********************************************************************************************/
00239 BOOL JPEGImportFilter::Init()
00240 {
00241     // Get the OILFilter object
00242     pOILFilter = new JPEGImportOILFilter(this);
00243     if (pOILFilter==NULL)
00244         return FALSE;
00245 
00246     // Load the description strings
00247     FilterName.Load(_R(IDS_JPG_IMP_FILTERNAME));
00248     FilterInfo.Load(_R(IDS_JPG_IMP_FILTERINFO));
00249 
00250     if( 9999 == m_fImportAt96dpi &&
00251         Camelot.DeclareSection( _T("Filters"), 10 ) )
00252     {
00253         Camelot.DeclarePref( NULL, _T("ImportJPEGAt96dpi"), &m_fImportAt96dpi, FALSE, TRUE );
00254     }
00255 
00256     // All ok
00257     return TRUE;
00258 }
00259 
00260 
00261 /********************************************************************************************
00262 
00263 >   ADDR FindBytes(ADDR pStart, UINT32 BufferSize, ADDR pBytes, UINT32 BytesSize)
00264 
00265     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00266     Created:    02/08/96
00267     Inputs:     pStart - The address of the first byte in memory from which to start
00268                 BufferSize - The size of the block starting at pStart
00269                 pBytes : the start address of the block of bytes to search for
00270                 BytesSize : The number of bytes in the block pointed to by pBytes
00271     Returns:    The address of the first matching block of memory
00272     Purpose:    Finds BytesSize bytes starting at pBytes in pStart, which is BufferSize long
00273                 Searches for a string of bytes
00274     Scope:      static
00275     Notes:      This should be put somewhere useful really. (Templates!!)
00276                 It could also be more efficient if necessary
00277 
00278 ********************************************************************************************/
00279 ADDR FindBytes(ADDR pStart, UINT32 BufferSize, ADDR pBytes, UINT32 BytesSize)
00280 {
00281     UINT32 BytesRemaining = BufferSize;
00282 
00283     ADDR pCurrentStart = pStart;
00284     while (BytesRemaining - BytesSize > 0)
00285     {
00286         ADDR pFirstFound = (ADDR)memchr(pCurrentStart, pBytes[0], BytesRemaining - BytesSize + 1);
00287         if (pFirstFound == NULL)
00288         {   
00289             return NULL;
00290         }
00291         if (memcmp(pFirstFound + 1, pBytes + 1, BytesSize - 1) == 0)
00292         {
00293             return pFirstFound;
00294         }
00295         pCurrentStart = pFirstFound + 1;
00296         BytesRemaining = BufferSize - (pCurrentStart - pStart);
00297     }
00298     return NULL;
00299 }
00300 
00301 
00302 /********************************************************************************************
00303 
00304 >   virtual INT32 JPEGImportFilter::HowCompatible(PathName& Filename, ADDR HeaderStart, 
00305                                         UINT32 HeaderSize, UINT32 FileSize)
00306 
00307     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00308     Created:    02/08/96
00309     Inputs:     Filename - name of the file.
00310                 HeaderStart - Address of the first few bytes of the file.
00311                 HeaderSize - the number of bytes in the header pointed to by FileStart.
00312                 FileSize - the size of the whole file, in bytes.
00313     Returns:    0 => Not a JPEG file.
00314                 10 => Bound to be a JPEG file.
00315                 1 - 9 => Might be
00316     Purpose:    Overrides the Filter class member to determine if the given file is reckoned
00317                 to be a JPEG.
00318 
00319 ********************************************************************************************/
00320 INT32 JPEGImportFilter::HowCompatible(PathName& Filename, ADDR pHeaderStart, UINT32 HeaderSize, 
00321                              UINT32 FileSize)
00322 {
00323 PORTNOTE("byteorder", "TODO: Check byte ordering")
00324     static BYTE     JPEGSignature[] = {0xFF,0xD8};
00325     static BYTE     APP0Signature[] = {0xFF,0xE0};
00326     static BYTE     APP1Signature[] = {0xFF,0xE1};
00327     static BYTE     JFIFSignature[] = "JFIF";
00328     static BYTE     EXIFSignature[] = "Exif";
00329     // If we're forced to import the file when we don't think there's the remotest
00330     // chance of a match, start at the beginning of the file in ReadFromFile
00331     m_uStartOffset = 0; 
00332 
00333     // Check that we've got enough data to do our check
00334     if (HeaderSize < 2)
00335     {
00336         // Not enough data - ignore this file.
00337         return 0;
00338     }
00339 
00340     INT32 Compatability = 0;
00341     BOOL bFoundSOI  = FALSE;
00342     BOOL bFoundJFIF = FALSE;
00343     BOOL bFoundEXIF = FALSE;
00344 
00345     // Check the header for the JPEG SOI signature, 0xFFD8 (unless it's 0xD8FF).
00346     ADDR pJPEGHeader = FindBytes(pHeaderStart, HeaderSize, JPEGSignature, 2);
00347     if (pJPEGHeader != NULL)
00348     {
00349         // Add in a value of 0 to 5 depending on the distance from the
00350         // start of the header
00351         m_uStartOffset = pJPEGHeader - pHeaderStart;
00352         bFoundSOI = TRUE;
00353     }
00354 
00355     if (bFoundSOI)
00356     {
00357         OFFSET HeaderBytesRemaining = HeaderSize - (pJPEGHeader - pHeaderStart);
00358 
00359         // Look for an APP0 containing JFIF
00360         char* pAPP0Start = (char*)FindBytes(pJPEGHeader + 2, HeaderBytesRemaining - 2, APP0Signature, 2);
00361         if (pAPP0Start)
00362         {
00363             if (strncmp(pAPP0Start + 4, (char *)JFIFSignature, sizeof(JFIFSignature) / sizeof(TCHAR)) == 0)
00364             {
00365                 bFoundJFIF = TRUE;
00366             }
00367         }
00368         
00369         // Look for an APP1 containing Exif
00370         char* pAPP1Start = (char*)FindBytes(pJPEGHeader + 2, HeaderBytesRemaining - 2, APP1Signature, 2);
00371         if (pAPP1Start)
00372         {
00373             if (strncmp(pAPP1Start + 4, (char *)EXIFSignature, sizeof(EXIFSignature) / sizeof(TCHAR)) == 0)
00374             {
00375                 bFoundEXIF = TRUE;
00376             }
00377         }
00378 
00379         // Andy Hills, 02-11-00
00380         // Previously, non-JPEG files were scoring as highly as 9, on the
00381         // basis that they had JPEG headers ... only, not at the start of the
00382         // file, but several hundred bytes in!!!
00383         // Now, we will give a score of 10 to a legit JPEG, or a score of 2-5
00384         // depending upon the nearness of the JPEG header to the start of
00385         // the file. This means that files with JPEG previews will score a few
00386         // points, e.g. PSD & PSP files.
00387 
00388         switch (m_uStartOffset)
00389         {
00390         case 0:
00391             // the header was at the very start of the file -->
00392             // it really is a JPEG!!!
00393             // we will give it a score of up to 10
00394             Compatability = 6;
00395             break;
00396 
00397         default:
00398             // the header was some way into the file -->
00399             // it probably isn't a JPEG, but has a JPEG preview
00400             // we will give it a max score of 5
00401             
00402             // Nearness evaluates to between 0 and 3
00403             INT32 Nearness = (((HeaderSize - m_uStartOffset) * 4) / HeaderSize);
00404             // Compatibility evaluates to between -2 and 1
00405             Compatability = Nearness - 2;
00406             break;
00407         }
00408     }
00409 
00410     if (bFoundJFIF || bFoundEXIF)
00411     {
00412         // Closer still
00413         Compatability += 4;
00414     }
00415 
00416     // Return the found value to the caller.
00417     return max(Compatability,0);
00418 }
00419 
00420 
00421 /********************************************************************************************
00422 
00423  >  virtual BOOL JPEGImportFilter::IsFormatLossy() const
00424 
00425     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00426     Created:    20/08/96
00427 
00428     Returns:    TRUE
00429     Purpose:    The JPEGImportFilter imports a lossy format & therefore always returns TRUE
00430     See Also:   BaseBitmapFilter::IsFormatLossy()
00431 
00432 ********************************************************************************************/
00433 BOOL JPEGImportFilter::IsFormatLossy() const
00434 {
00435     return TRUE;
00436 }
00437 
00438 
00439 /********************************************************************************************
00440 
00441  >  virtual OFFSET BaseBitmapFilter::GetDataStartOffset() const
00442 
00443     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00444     Created:    20/08/96
00445 
00446     Returns:    The offset from the HeaderStart parameter given in HowCompatible(), 
00447                 from which data essential to the correct functionality of this filter 
00448                 starts.
00449 
00450     Purpose:    Provides information to the BaseBitmapFilter, so that it knows where
00451                 to start any required BitmapSource. It will only be useful to derived 
00452                 classes that deal with a lossy file format.
00453 
00454     See Also:   BaseBitmapFilter::GetDataStartOffset()
00455 
00456 ********************************************************************************************/
00457 OFFSET JPEGImportFilter::GetDataStartOffset() const
00458 {
00459     return m_uStartOffset;
00460 }
00461 
00462 
00463 /********************************************************************************************
00464 
00465 >   virtual BitmapSource* BaseBitmapFilter::CreateBitmapSource() const
00466 
00467     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00468     Created:    21/08/96
00469     Returns:    A pointer to a new BitmapSource
00470     Purpose:    Provides a BitmapSource for lossy file formats.
00471                 The JPEGImportFilter returns a JPEGBitmapSource
00472     SeeAlso:    BaseBitmapFIlter::CreateBitmapSource
00473     Scope:      protected
00474 
00475 ********************************************************************************************/
00476 BitmapSource* JPEGImportFilter::CreateBitmapSource(OFFSET Size) const
00477 {
00478     BitmapSource* pSource = new JPEGBitmapSource(Size);
00479     return pSource;
00480 }
00481 
00482 
00483 /********************************************************************************************
00484 
00485 >   BOOL JPEGImportFilter::ReadFromFile(OILBitmap* pOilBitmap, BaseCamelotFilter* pFilter,
00486                                         CCLexFile* pFile, BOOL IsCompressed)
00487 
00488     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> (from Neville Humphrys in PNGFilter)
00489     Created:    14/08/96
00490     Inputs:     pFilter:    the BaseCamelotFilter which provides functions like
00491                             progress update
00492                 pFile       the CCFile class to use to read the data from
00493                 IsCompressed :Flag to say the bitmap is compressed or not.  
00494     Outputs:    pOilBitmap: Will have filled in BMInfo  pointer to the bitmap header to fill
00495                             in. BMBytes pointer to the bitmap data to fill in
00496     Purpose:    Entry point for Native File Format stuff
00497                 Actually does the process of reading a bitmap from a file.
00498                 Inherited classes override this to read in different file formats.
00499                 It is used by the web/native filters to pull out a bitmap definition from
00500                 inside a bitmap definition record.
00501     Returns:    TRUE if worked, FALSE if failed.
00502 
00503     Notes:      m_uStartOffset, the offset in the stream at which the JPEG header starts,
00504                 is set to zero through this entry point. This assumes, therefore, that the
00505                 JPEG contains no Adobe style garbage in front of it.
00506                 Also assumes:
00507                 * pFile has already been opened up for reading
00508                 * pFilter has been set up for reading the data e.g. progress bar 
00509 
00510 ********************************************************************************************/
00511 
00512 BOOL JPEGImportFilter::ReadFromFile(OILBitmap* pOilBitmap, BaseCamelotFilter* pFilter,
00513                                     CCLexFile* pFile, BOOL IsCompressed)
00514 {
00515     ERROR2IF(pOilBitmap == NULL,FALSE,"pOilBitmap NULL");
00516     ERROR2IF(pFilter == NULL,FALSE,"pFilter NULL");
00517     ERROR2IF(pFile == NULL,FALSE,"pFile NULL");
00518 
00519 //  CCFile* pFile   = (CCFile*)pFile->GetIOFile();
00520     
00521     m_pFilterForProgress    = (Filter*)pFilter;
00522     m_pFileForProgress      = NULL;
00523     m_uImportSize           = pFilter->GetCurrentRecordSize();
00524 
00525     // The encapsulated JPEG should always have its header starting at offset
00526     // zero inside its .xar Record
00527     m_uStartOffset = 0;
00528 
00529     // Try to import bitmap from JPEG file
00530     if (!DoFilter(pFile, pOilBitmap))
00531     {
00532         return FALSE;
00533     }
00534 
00535     // Make sure this bitmap is treated as lossy
00536     pOilBitmap->SetAsLossy();
00537 
00538     // Clear any eof signal as CCFile considers this an error
00539     if (m_pFile->eof())
00540     {
00541         m_pFile->SetGoodState();
00542     }
00543     return TRUE;
00544 }
00545 
00546 
00547 /********************************************************************************************
00548 
00549 >   BOOL JPEGImportFilter::ReadFromFile(OILBitmap* pOilBitmap)
00550 
00551     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00552     Created:    09/08/96
00553     Inputs:     pOilBitmap : pointer to the OILBitmap to be filled in
00554     Outputs:    pOilBitmap : If successful will contain the bitmap data from reading the
00555                 JPEG file (GetImportFile()).
00556     Returns:    TRUE if successful
00557                 FALSE if not
00558     Purpose:    Actually does the process of reading a bitmap from a file.
00559                 Inherited classes override this to read in different file formats.
00560                 JPEG reads a JPEG file.
00561     Errors:     ERROR2s for invalid parameters
00562 
00563     Notes:      m_uStartOffset must have been set prior to calling this (use HowCompatible()
00564                 or set it zero).
00565                 
00566 
00567 ********************************************************************************************/
00568 BOOL JPEGImportFilter::ReadFromFile(OILBitmap* pOilBitmap)
00569 {
00570     ERROR2IF(pOilBitmap == NULL, FALSE, "pOilBitmap is NULL");
00571 
00572     m_pFileForProgress      = GetImportFile();      // get BaseBitmapFilter member
00573     m_pFilterForProgress    = NULL;
00574 
00575     CCFile* pFile = GetImportFile();
00576 
00577     return DoFilter(pFile, pOilBitmap);
00578 }
00579 
00580 
00581 
00582 /********************************************************************************************
00583 
00584 >   BOOL JPEGImportFilter::DoFilter(CCFile* pInputFile, OILBitmap* pOilBitmap)
00585 
00586     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00587     Created:    09/08/96
00588     Inputs:     pInputFile : a pointer to an open CCFile containing the JPEG data to be
00589                 imported
00590                 pOilBitmap : pointer to the OILBitmap to be filled in
00591     Outputs:    pOilBitmap : If successful will contain the bitmap data from reading the
00592                 JPEG file (GetImportFile()).
00593     Returns:    TRUE if successful
00594                 FALSE if not
00595     Purpose:    Provides the main processing point for the JPEG import.
00596                 Called by the external interface
00597 
00598     Notes:      Here's how the IJG docs say we do it:
00599                 1) Allocate and initialize a JPEG decompression object
00600                 2) Specify the source of the compressed data (eg, a file)
00601                 3) Call jpeg_read_header() to obtain image info
00602                 4) Set parameters for decompression
00603                 5) jpeg_start_decompress(...);
00604                 6) while (scan lines remain to be read)
00605                     jpeg_read_scanlines(...);
00606                 7) jpeg_finish_decompress(...);
00607                 8) Release the JPEG decompression object
00608 
00609     See Also:   ReadFromFile(...)
00610                 
00611 
00612 ********************************************************************************************/
00613 BOOL JPEGImportFilter::DoFilter(CCFile* pInputFile, OILBitmap* pOilBitmap)
00614 {
00615     ERROR2IF(pOilBitmap == NULL || pInputFile == NULL, FALSE, "NULL Args");
00616     ERROR3IF(!pInputFile->IS_KIND_OF(CCFile), "pInputFile isn't");
00617 
00618     m_pFile = pInputFile;
00619 
00620     CWxBitmap* pWBitmap = (CWxBitmap*)pOilBitmap;
00621     ERROR2IF(!pWBitmap->IS_KIND_OF(CWxBitmap), FALSE, "Only CWxBitmap supported");
00622 
00623     m_ppInfo    = &(pWBitmap->BMInfo);
00624     m_ppBytes   = &(pWBitmap->BMBytes);
00625     
00626     // Try to import the bitmap from a JPEG file.
00627     if (!PrepareFilterForOperation())
00628         return FALSE;
00629 
00630     try
00631     {
00632         ReadHeader();
00633 
00634         PrepareForImage(m_pImportOptions);
00635 
00636         ReadImage();
00637 
00638         OnImageCompletion();
00639     }
00640     catch(...)
00641     {
00642         // catch our form of a file exception
00643         // Tidy up
00644         StringID errorString = m_pErrorHandler->GetStringIDForError();
00645         
00646         Error::SetError(errorString);
00647 
00648         if (*m_ppInfo != NULL && *m_ppBytes != NULL)
00649         {
00650             FreeDIB( *m_ppInfo, *m_ppBytes );                           // free any alloced memory
00651         }
00652         *m_ppInfo = NULL;                                       // and NULL the pointers
00653         *m_ppBytes = NULL;
00654 
00655         /*
00656         The IJG library says:
00657 
00658         You can abort a decompression cycle by calling jpeg_destroy_decompress() or
00659         jpeg_destroy() if you don't need the JPEG object any more, or
00660         jpeg_abort_decompress() or jpeg_abort() if you want to reuse the object.
00661         */
00662 
00663         OnFilterCompletion();       
00664 
00665         return FALSE;
00666     }
00667 
00668     OnFilterCompletion();
00669 
00670     return TRUE;
00671 }
00672 
00673 
00674 
00675 /********************************************************************************************
00676 
00677 >   virtual BOOL JPEGFilter()::PrepareFilterForOperation();
00678 
00679     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00680     Created:    02/08/96
00681     Purpose:    Default constructor for a JPEGFilter object.
00682 
00683 1. Allocate and initialize a JPEG decompression object.
00684 
00685 This is just like initialization for compression, as discussed above,
00686 except that the object is a "struct jpeg_decompress_struct" and you
00687 call jpeg_create_decompress().  Error handling is exactly the same.
00688 
00689 A JPEG compression object is a "struct jpeg_compress_struct".  (It also has
00690 a bunch of subsidiary structures which are allocated via malloc(), but the
00691 application doesn't control those directly.)  This struct can be just a local
00692 variable in the calling routine, if a single routine is going to execute the
00693 whole JPEG compression sequence.  Otherwise it can be static or allocated
00694 from malloc().
00695 
00696 You will also need a structure representing a JPEG error handler.  The part
00697 of this that the library cares about is a "struct jpeg_error_mgr".  If you
00698 are providing your own error handler, you'll typically want to embed the
00699 jpeg_error_mgr struct in a larger structure; this is discussed later under
00700 "Error handling".  For now we'll assume you are just using the default error
00701 handler.  The default error handler will print JPEG error/warning messages
00702 on stderr, and it will call exit() if a fatal error occurs.
00703 
00704 You must initialize the error handler structure, store a pointer to it into
00705 the JPEG object's "err" field, and then call jpeg_create_compress() to
00706 initialize the rest of the JPEG object.
00707 
00708 Typical code:
00709 
00710     struct jpeg_decompress_struct cinfo;
00711     struct jpeg_error_mgr jerr;
00712     ...
00713     cinfo.err = jpeg_std_error(&jerr);
00714     jpeg_create_decompress(&cinfo);
00715 
00716 jpeg_create_compress allocates a small amount of memory, so it could fail
00717 if you are out of memory.  In that case it will exit via the error handler;
00718 that's why the error handler must be initialized first.
00719 
00720 (Both here and in the IJG code, we usually use variable name "cinfo" for
00721 both compression and decompression objects.)
00722 
00723 2. Specify the source of the compressed data (eg, a file).
00724 
00725 As previously mentioned, the JPEG library reads compressed data from a "data
00726 source" module.  The library includes one data source module which knows how
00727 to read from a stdio stream.  You can use your own source module if you want
00728 to do something else, as discussed later.
00729 
00730 If you use the standard source module, you must open the source stdio stream
00731 beforehand.  Typical code for this step looks like:
00732 
00733     FILE * infile;
00734     ...
00735     if ((infile = fopen(filename, "rb")) == NULL) {
00736         fprintf(stderr, "can't open %s\n", filename);
00737         exit(1);
00738     }
00739     jpeg_stdio_src(&cinfo, infile);
00740 
00741 where the last line invokes the standard source module.
00742 
00743 WARNING: it is critical that the binary compressed data be read unchanged.
00744 On non-Unix systems the stdio library may perform newline translation or
00745 otherwise corrupt binary data.  To suppress this behavior, you may need to use
00746 a "b" option to fopen (as shown above), or use setmode() or another routine to
00747 put the stdio stream in binary mode.  See cjpeg.c and djpeg.c for code that
00748 has been found to work on many systems.
00749 
00750 You may not change the data source between calling jpeg_read_header() and
00751 jpeg_finish_decompress().  If you wish to read a series of JPEG images from
00752 a single source file, you should repeat the jpeg_read_header() to
00753 jpeg_finish_decompress() sequence without reinitializing either the JPEG
00754 object or the data source module; this prevents buffered input data from
00755 being discarded.
00756 
00757 ********************************************************************************************/
00758 BOOL JPEGImportFilter::PrepareFilterForOperation()
00759 {
00760     // The error handling in the following should probably be replaced by exceptions at
00761     // some time, when somebody can decide on a standard.
00762 
00763     // Set up a JPEGErrorManager
00764     if (!InitErrorHandler())
00765     {
00766         return FALSE;
00767     }
00768     
00769     // Initialize the main JPG library structure
00770     try
00771     {
00772         using namespace libJPEG;
00773         jpeg_create_decompress( &m_cinfo );
00774     }
00775     catch(...)
00776     {
00777         return FALSE;
00778     }
00779 
00780     // Setup a JPEGDataSource
00781     if (!InitFileHandler())
00782     {
00783         return FALSE;
00784     }
00785 
00786     // Set up a progress bar
00787     if (!InitProgressMonitor())
00788     {
00789         return FALSE;
00790     }
00791 
00792     // Don't let the CCFile report errors or throw exceptions
00793     m_bOldThrowExceptions   = m_pFile->SetThrowExceptions(FALSE);
00794     m_bOldReportErrors      = m_pFile->SetReportErrors(FALSE);
00795 
00796     return TRUE;
00797 }
00798 
00799 
00800 
00801 
00802 /********************************************************************************************
00803 
00804 >   void JPEGImportFilter::ReadHeader()
00805 
00806     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00807     Created:    02/08/96
00808     Returns:    TRUE if header was correctly read & the data set
00809                 FALSE otherwise
00810     Purpose:    This will read the source datastream header markers, up to the beginning
00811                 of the compressed data proper.  On return, the image dimensions and other
00812                 info have been stored in the JPEG object.  The application may wish to
00813                 consult this information before selecting decompression parameters.
00814     Errors:     Throws exceptions
00815     Notes:      PrepareFilterForOperation must have been called prior to this call.
00816                 
00817                 From the IJG docs:
00818 
00819                 More complex code is necessary if
00820                   * A suspending data source is used --- in that case jpeg_read_header()
00821                     may return before it has read all the header data.
00822                   * Abbreviated JPEG files are to be processed --- see the section on
00823                     abbreviated datastreams.  Standard applications that deal only in
00824                     interchange JPEG files need not be concerned with this case either.
00825 
00826                 It is permissible to stop at this point if you just wanted to find out the
00827                 image dimensions and other header info for a JPEG file.  In that case,
00828                 call jpeg_destroy() when you are done with the JPEG object, or call
00829                 jpeg_abort() to return it to an idle state before selecting a new data
00830                 source and reading another header.
00831 
00832 ********************************************************************************************/
00833 void JPEGImportFilter::ReadHeader()
00834 {
00835     jpeg_read_header(&m_cinfo, TRUE);
00836 }
00837 
00838 
00839 /********************************************************************************************
00840 
00841 >   virtual BitmapImportOptions* JPEGImportFilter::GetImportOptions()
00842 
00843     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00844     Created:    02/08/96
00845     Returns:    A pointer to some new JPEGImportOptions if successful
00846                 NULL otherwise
00847     Purpose:    Overrides the BaseBitmapFilter::GetImportOptions to This will read the source datastream header markers, up to the beginning
00848 
00849     Notes:      From the IJG docs:
00850 
00851 
00852 jpeg_read_header() sets appropriate default decompression parameters based on
00853 the properties of the image (in particular, its colorspace).  However, you
00854 may well want to alter these defaults before beginning the decompression.
00855 For example, the default is to produce full color output from a color file.
00856 If you want colormapped output you must ask for it.  Other options allow the
00857 returned image to be scaled and allow various speed/quality tradeoffs to be
00858 selected.  "Decompression parameter selection", below, gives details.
00859 
00860 If the defaults are appropriate, nothing need be done at this step.
00861 
00862 Note that all default values are set by each call to jpeg_read_header().
00863 If you reuse a decompression object, you cannot expect your parameter
00864 settings to be preserved across cycles, as you can for compression.
00865 You must set desired parameter values each time.
00866 
00867     See Also:   BaseBitmapFilter::GetImportOptions()
00868 
00869 ********************************************************************************************/
00870 BitmapImportOptions* JPEGImportFilter::GetImportOptions()
00871 {
00872     JPEGImportOptions* pOptions = NULL;
00873 
00874     // Should ReadHeader here...
00875 
00876     pOptions = new JPEGImportOptions;
00877 
00878 /*
00879     Might want to set one or two of these at some point
00880 
00881     J_COLOR_SPACE out_color_space; // colorspace for output
00882 
00883     UINT32 scale_num, scale_denom; // fraction by which to scale image
00884 
00885     double output_gamma;        // image gamma wanted in output
00886 
00887     boolean buffered_image; // TRUE=multiple output passes
00888     boolean raw_data_out;       // TRUE=downsampled data wanted
00889 
00890     J_DCT_METHOD dct_method;    // IDCT algorithm selector
00891     boolean do_fancy_upsampling;    // TRUE=apply fancy upsampling
00892     boolean do_block_smoothing; // TRUE=apply interblock smoothing
00893 
00894     boolean quantize_colors;    // TRUE=colormapped output wanted
00895 
00896     // the following are ignored if not quantize_colors:
00897     J_DITHER_MODE dither_mode;  //type of color dithering to use
00898     boolean two_pass_quantize;  // TRUE=use two-pass color quantization
00899     INT32 desired_number_of_colors; // max # colors to use in created colormap
00900     
00901     // these are significant only in buffered-image mode:
00902     boolean enable_1pass_quant; // enable future use of 1-pass quantizer
00903     boolean enable_external_quant;// enable future use of external colormap
00904     boolean enable_2pass_quant;  enable future use of 2-pass quantizer
00905 */
00906 
00907     return (BitmapImportOptions*)pOptions;
00908 }
00909 
00910 
00911 /********************************************************************************************
00912 
00913 >   virtual void JPEGImportFilter::PrepareForImage(BitmapImportOptions* pOptions)
00914 
00915     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
00916     Created:    02/08/96
00917     Inputs:     pOptions : a pointer to some JPEGImportOptions (currently NULL)
00918     Purpose:    Prepares a place for the actual scanlines using the given options
00919 
00920     Notes:      From the IJG docs:
00921 
00922                 Once the parameter values are satisfactory, call jpeg_start_decompress() to
00923                 begin decompression.  This will initialize internal state, allocate working
00924                 memory, and prepare for returning data.
00925                 If you have requested a multi-pass operating mode, such as 2-pass color
00926                 quantization, jpeg_start_decompress() will do everything needed before data
00927                 output can begin.  In this case jpeg_start_decompress() may take quite a while
00928                 to complete.  With a single-scan (non progressive) JPEG file and default
00929                 decompression parameters, this will not happen; jpeg_start_decompress() will
00930                 return quickly.
00931 
00932                 After this call, the final output image dimensions, including any requested
00933                 scaling, are available in the JPEG object; so is the selected colormap, if
00934                 colormapped output has been requested.  Useful fields include
00935 
00936                     output_width        image width and height, as scaled
00937                     output_height
00938                     out_color_components    # of color components in out_color_space
00939                     output_components   # of color components returned per pixel
00940                     colormap        the selected colormap, if any
00941                     actual_number_of_colors     number of entries in colormap
00942                 
00943                 output_components is 1 (a colormap index) when quantizing colors; otherwise it
00944                 equals out_color_components.  It is the number of JSAMPLE values that will be
00945                 emitted per pixel in the output arrays.
00946     
00947                 Typically you will need to allocate data buffers to hold the incoming image.
00948                 You will need output_width * output_components JSAMPLEs per scanline in your
00949                 output buffer, and a total of output_height scanlines will be returned.
00950 
00951 ********************************************************************************************/
00952 void JPEGImportFilter::PrepareForImage(BitmapImportOptions* pOptions)
00953 {
00954     //ERROR2IF(pOptions == NULL, FALSE, "pOptions is NULL");
00955 
00956     // Set up conversion parameters (should be in GetImportOptions really)
00957  
00958     //  "The return value need be inspected only if a suspending data source is used"
00959 
00960     /*
00961         One day...
00962     if (m_cinfo.jpeg_color_space == JCS_YCCK)
00963     {
00964         // Convert YCCK to RGB
00965         m_cinfo.out_color_space = JCS_RGB;
00966     }
00967     */
00968     (void)jpeg_start_decompress(&m_cinfo);  
00969 
00970     // Store the image width & height
00971     m_uWidth = m_cinfo.output_width;
00972     m_uHeight = m_cinfo.output_height;
00973 
00974     // Compute colormap size and total file size
00975     switch (m_cinfo.out_color_space)
00976     {
00977         case libJPEG::JCS_RGB:
00978         {
00979             // Unquantized, full color RGB
00980             m_uBitsPerPixel = 24;
00981             break;
00982         }
00983 
00984         case libJPEG::JCS_GRAYSCALE:
00985         {
00986             // Grayscale output
00987             m_uBitsPerPixel = 8;
00988             break;
00989         }
00990 
00991         default:
00992         {
00993             m_pErrorHandler->ThrowError(_R(IDS_JPEG_ERROR_UNSUPPORTED));
00994         }
00995     }
00996 
00997     // So we know
00998     *m_ppInfo = NULL;
00999     *m_ppBytes = NULL;
01000 
01001     // we know what sort of bitmap we are - let's allocate a new LPBITMAPINFO and some bytes
01002     *m_ppInfo = AllocDIB( m_uWidth, m_uHeight, m_uBitsPerPixel, m_ppBytes, NULL );
01003     if (*m_ppInfo == NULL || *m_ppBytes == NULL)
01004     {
01005         m_pErrorHandler->ThrowError( _R(IDS_OUT_OF_MEMORY) );
01006     }
01007 
01008     if (!ReadPalette())
01009     {
01010         m_pErrorHandler->ThrowError( _R(IDS_PNG_ERR_READ_PALETTE) ); // Should be bad palette error
01011     }
01012 
01013 }
01014 
01015 
01016 
01017 /********************************************************************************************
01018 
01019 >   BOOL JPEGImportFilter::SetBitmapResolution()
01020 
01021     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
01022     Created:    02/08/96
01023     Returns:    TRUE if resolution set OK
01024                 FALSE otherwise
01025     Purpose:    Support function that sets the X & Y pixel densities for the bitmap imported
01026                 from the JPEG file.
01027 
01028 ********************************************************************************************/
01029 BOOL JPEGImportFilter::SetBitmapResolution()
01030 {
01031     // Set the horizontal & vertical pixel densities
01032     LPBITMAPINFOHEADER pHeader = &(*m_ppInfo)->bmiHeader;
01033 
01034     // Conviently the import code defaults to 96dpi, so
01035     // we just leave it alone if we're importing at 96dpi
01036     if( !m_fImportAt96dpi )
01037     {
01038         switch (m_cinfo.density_unit)
01039         {
01040         case 1:     // dots/inch
01041             pHeader->biXPelsPerMeter = (INT32)(m_cinfo.X_density * (100 / 2.54));
01042             pHeader->biYPelsPerMeter = (INT32)(m_cinfo.Y_density * (100 / 2.54));
01043             break;
01044 
01045         case 2:     // dots/cm
01046             pHeader->biXPelsPerMeter = m_cinfo.X_density * 100;
01047             pHeader->biYPelsPerMeter = m_cinfo.Y_density * 100;
01048             break;
01049 
01050         default:    // unknown
01051             // Note that the pixel aspect ratio is defined by X_density/Y_density 
01052             // even when density_unit=0.
01053             // So leave it as is: 96dpi
01054             break;
01055         }
01056     }
01057 
01058     return TRUE;
01059 }
01060 
01061 
01062 /********************************************************************************************
01063 
01064 >   BOOL JPEGImportFilter::ReadPalette()
01065 
01066     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
01067     Created:    02/08/96
01068     Returns:    TRUE if a palette was read correctly & the data set
01069                 FALSE otherwise
01070     Purpose:    Reads a palette for the image
01071                 In this case it just generates a greyscale palette for JCS_GRAYSCALE JPEGs.
01072                 All other colour models are 24-bit
01073 
01074 ********************************************************************************************/
01075 BOOL JPEGImportFilter::ReadPalette()
01076 {
01077     if (m_cinfo.out_color_space == libJPEG::JCS_GRAYSCALE)
01078     {
01079         // We'll have to generate a palette for it
01080         LPRGBQUAD pPalette = (*m_ppInfo)->bmiColors;
01081         if (pPalette == NULL)
01082         {
01083             return FALSE;
01084         }
01085 
01086         if (!DIBUtil::GenGreyscalePalette(pPalette, 256))
01087         {
01088             return FALSE;
01089         }
01090     }
01091     return TRUE;
01092 }
01093 
01094 
01095 /********************************************************************************************
01096 
01097 >   virtual void JPEGImportFilter::ReadImage()
01098 
01099     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
01100     Created:    02/08/96
01101     Purpose:    Reads the actual scanlines of the image into this's DIB data members
01102     Errors:     Throws exceptions
01103 
01104     Notes:      Once PrepareForImage() has been called this function can read in the data
01105 
01106 ********************************************************************************************/
01107 void JPEGImportFilter::ReadImage()
01108 {
01109 //#ifndef WIN32
01110 //  Error::SetError( _R(IDE_BADFORMAT) );
01111 //  return FALSE;
01112 //#else
01113 
01114     // Sanity checks on the file that we have been asked to load.
01115     if ((m_uBitsPerPixel != 24 && m_uBitsPerPixel != 8)
01116         || (m_uWidth == 0 || m_uHeight == 0)
01117         || m_cinfo.output_components > 3)
01118     {
01119         m_pErrorHandler->ThrowError( _R(IDE_FORMATNOTSUPPORTED) );
01120     }
01121 
01122     // Work out the word/byte rounded line width rather than the pixel width
01123     INT32 WidthOfLine = DIBUtil::ScanlineSize( m_uWidth, m_uBitsPerPixel );
01124 
01125     // Of course being DIBs we need to read the data in upside down! i.e. bottom to top
01126     // So start from the bottom
01127     LPBYTE pCurrentScanLine = *m_ppBytes + 
01128                                 ((m_uHeight - 1 - m_cinfo.output_scanline)  * WidthOfLine);
01129 
01130     while (m_cinfo.output_scanline < m_cinfo.output_height)
01131     {
01132         // jpeg_read_scanlines expects an array of pointers to scanlines.
01133         // Here the array is only one element long, but you could ask for
01134         // more than one scanline at a time if that's more convenient.
01135     
01136         // Read in from bottom upwards
01137         (void) jpeg_read_scanlines(&m_cinfo, &pCurrentScanLine, 1);
01138         //
01139         // Swap red and blue channels.
01140         //
01141 #if !defined(__WXMSW__) && defined(BIG_ENDIAN)
01142         if ( m_uBitsPerPixel==24 )
01143         {
01144             BYTE* pLine = pCurrentScanLine;
01145             for ( UINT32 i=0 ; i<m_uWidth ; i++ )
01146             {
01147                 BYTE t   = pLine[0];
01148                 pLine[0] = pLine[2];
01149                 pLine[2] = t;
01150                 pLine += 3;
01151             }
01152         }
01153 #endif
01154 
01155         // If JobState is False then the user has probably pressed escape and we should
01156         // immediately stop what we are doing. 
01157         if (m_pProgressMonitor && m_pProgressMonitor->UserAborted())
01158         {
01159             m_pErrorHandler->ThrowError(_R(IDW_CANCELLEDBMPIMPORT));    // Expects error set on cancel
01160         }
01161         // Work backwards through the DIB
01162         pCurrentScanLine -= WidthOfLine;
01163     }
01164 //#endif
01165 }
01166 
01167 
01168 /********************************************************************************************
01169 
01170 >   void JPEGImportFilter::OnImageCompletion()
01171 
01172     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
01173     Created:    02/08/96
01174     Purpose:    Once an image has been read, this member should be called to complete
01175                 any processing associated with that image.
01176     Errors:     Throws exceptions
01177 
01178     Notes:      Taken from IJG docs:
01179 
01180                 After all the image data has been read, call jpeg_finish_decompress() to
01181                 complete the decompression cycle.  This causes working memory associated
01182                 with the JPEG object to be released.
01183 
01184                 It is an error to call jpeg_finish_decompress() before reading the correct
01185                 total number of scanlines.  If you wish to abort compression, call
01186                 jpeg_abort() as discussed below.
01187 
01188                 After completing a decompression cycle, you may dispose of the JPEG object
01189                 as discussed next, or you may use it to decompress another image.  In that
01190                 case return to step 2 or 3 as appropriate.  If you do not change the source
01191                 manager, the next image will be read from the same source.
01192 
01193 ********************************************************************************************/
01194 void JPEGImportFilter::OnImageCompletion()
01195 {
01196     jpeg_finish_decompress(&m_cinfo);
01197 
01198 /*
01199     Might be able to do this on GreyScale
01200 
01201     UINT32 Bpp = pWBitmap->GetBPP();
01202     if (TransColour != -1 && Bpp <= 8)
01203         pOilBitmap->SetTransparencyIndex(TransColour);
01204 */
01205 
01206     if (!SetBitmapResolution())
01207     {
01208         m_pErrorHandler->ThrowError( _R(IDS_JPEG_ERROR_UNSUPPORTED) );
01209     }
01210 
01211     SetLastBitmap();        // can only import one bitmap at the moment
01212 }
01213 
01214 
01215 
01216 /********************************************************************************************
01217 
01218 >   virtual BOOL JPEGImportFilter::OnFilterCompletion()
01219 
01220     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
01221     Created:    02/08/96
01222     Purpose:    Default constructor for a JPEGFilter object.
01223 
01224     Notes:      Taken from IJG docs:
01225 
01226                 When you are done with a JPEG decompression object, destroy it by calling
01227                 jpeg_destroy_decompress() or jpeg_destroy().  
01228 
01229 ********************************************************************************************/
01230 BOOL JPEGImportFilter::OnFilterCompletion()
01231 {
01232     if (m_pErrorHandler != NULL)
01233     {
01234         delete m_pErrorHandler;
01235         m_pErrorHandler = NULL;
01236         m_cinfo.err = NULL;
01237     }
01238 
01239     if (m_pSourceHandler != NULL)
01240     {
01241         delete m_pSourceHandler;
01242         m_pSourceHandler = NULL;
01243         m_cinfo.src = NULL;
01244     }
01245 
01246     if (m_pProgressMonitor != NULL)
01247     {
01248         delete m_pProgressMonitor;
01249         m_pProgressMonitor = NULL;
01250         m_cinfo.progress = NULL;
01251     }
01252 
01253     jpeg_destroy_decompress(&m_cinfo);
01254 
01255     m_pFile->SetThrowExceptions(m_bOldThrowExceptions);
01256     m_pFile->SetReportErrors(m_bOldReportErrors);
01257 
01258     // Start at the beginning of the file next time
01259     m_uStartOffset = 0;
01260 
01261     return TRUE;
01262 }
01263 
01264 
01265 
01266 /********************************************************************************************
01267 
01268 >   BOOL JPEGImportFilter::InitErrorHandler()
01269 
01270     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
01271     Created:    02/08/96
01272     Purpose:    Creates & initializes an error handler for this filter
01273 
01274 ********************************************************************************************/
01275 BOOL JPEGImportFilter::InitErrorHandler()
01276 {
01277     m_pErrorHandler = new JPEGErrorManager;
01278     if (m_pErrorHandler == NULL)
01279     {
01280         return FALSE;
01281     }
01282 
01283     m_cinfo.err = m_pErrorHandler->GetErrorMgrStruct();
01284 
01285     return TRUE;
01286 }
01287 
01288 
01289 
01290 /********************************************************************************************
01291 
01292 >   BOOL JPEGImportFilter::InitFileHandler()
01293 
01294     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
01295     Created:    02/08/96
01296     Purpose:    Creates & initializes a source data provider for this filter.
01297 
01298 ********************************************************************************************/
01299 BOOL JPEGImportFilter::InitFileHandler()
01300 {
01301 
01302     if (m_cinfo.src == NULL)
01303     {
01304         if (m_pSourceHandler == NULL)
01305         {
01306             m_pSourceHandler = new JPEGDataSource(m_pFile);
01307             if (m_pSourceHandler == NULL)
01308                 return FALSE;
01309         }
01310         m_cinfo.src = m_pSourceHandler;
01311         if (!m_pSourceHandler->InitBuffer(&m_cinfo))
01312             return FALSE;
01313     }
01314     return TRUE;
01315 }
01316         
01317 
01318 
01319 /********************************************************************************************
01320 
01321 >   BOOL JPEGImportFilter::InitProgressMonitor()
01322 
01323     Author:     Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
01324     Created:    08/08/96
01325     Purpose:    Creates & initializes the Progress bar for the filtering operation
01326 
01327 ********************************************************************************************/
01328 BOOL JPEGImportFilter::InitProgressMonitor()
01329 {
01330     PORTNOTETRACE("filters","JPEGImportFilter::InitProgressMonitor - do nothing");
01331 #ifndef EXCLUDE_FROM_XARALX
01332     if (m_pFileForProgress == NULL)
01333     {
01334         m_pProgressMonitor = new JPEGProgressByFilter(&m_cinfo, m_pFilterForProgress, 
01335                                                         m_uImportSize);
01336     }
01337     else
01338     {
01339         // We have to provide the progress bar
01340         String_64 string = GetImportProgressString(m_pFileForProgress, GetImportMsgID());
01341         m_pProgressMonitor = new JPEGProgressBySelf(&m_cinfo, string);
01342     }
01343 
01344     // Couldn't create one!!!
01345     if (m_pProgressMonitor == NULL)
01346     {
01347         return FALSE;
01348     }
01349 
01350     // Provide this ProgressMonitor to the IJG library
01351     m_cinfo.progress = m_pProgressMonitor;
01352 #endif
01353     return TRUE;
01354 }
01355 
01356 

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