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