JPEGImportFilter Class Reference

Provides a JPEG import filter using the IJG JPEG LIBRARY. More...

#include <imjpeg.h>

Inheritance diagram for JPEGImportFilter:

BaseBitmapFilter BitmapFilter Filter ListItem CCObject SimpleCCObject List of all members.

Public Member Functions

 JPEGImportFilter ()
 Default constructor for a JPEGFilter object.
 ~JPEGImportFilter ()
 Default constructor for a JPEGFilter object.
virtual BOOL Init ()
 Initializes the JPEGImportFilter class.
virtual INT32 HowCompatible (PathName &Filename, ADDR HeaderStart, UINT32 HeaderSize, UINT32 FileSize)
 Overrides the Filter class member to determine if the given file is reckoned to be a JPEG.
virtual BOOL ReadFromFile (OILBitmap *pOilBitmap, BaseCamelotFilter *pFilter, CCLexFile *pFile, BOOL IsCompressed)
 Entry point for Native File Format stuff Actually does the process of reading a bitmap from a file. Inherited classes override this to read in different file formats. It is used by the web/native filters to pull out a bitmap definition from inside a bitmap definition record.
virtual BOOL ReadFromFile (OILBitmap *pOilBitmap)
 Actually does the process of reading a bitmap from a file. Inherited classes override this to read in different file formats. JPEG reads a JPEG file.

Static Public Member Functions

static BOOL GetImportAt96dpi ()
static void SetImportAt96dpi (BOOL fImportAt96)

Protected Member Functions

BOOL DoFilter (CCFile *pInputFile, OILBitmap *pOilBitmap)
 Provides the main processing point for the JPEG import. Called by the external interface.
virtual BOOL PrepareFilterForOperation ()
 Default constructor for a JPEGFilter object.
virtual BitmapImportOptionsGetImportOptions ()
 Overrides the BaseBitmapFilter::GetImportOptions to This will read the source datastream header markers, up to the beginning.
virtual BOOL IsFormatLossy () const
 The JPEGImportFilter imports a lossy format & therefore always returns TRUE See Also: BaseBitmapFilter::IsFormatLossy().
virtual OFFSET GetDataStartOffset () const
 Provides information to the BaseBitmapFilter, so that it knows where to start any required BitmapSource. It will only be useful to derived classes that deal with a lossy file format.
virtual BitmapSourceCreateBitmapSource (OFFSET Size) const
 Provides a BitmapSource for lossy file formats. The JPEGImportFilter returns a JPEGBitmapSource.
virtual void PrepareForImage (BitmapImportOptions *pOptions)
 Prepares a place for the actual scanlines using the given options.
virtual void ReadImage ()
 Reads the actual scanlines of the image into this's DIB data members.
virtual void OnImageCompletion ()
 Once an image has been read, this member should be called to complete any processing associated with that image.
virtual BOOL OnFilterCompletion ()
 Default constructor for a JPEGFilter object.
void ReadHeader ()
 This will read the source datastream header markers, up to the beginning of the compressed data proper. On return, the image dimensions and other info have been stored in the JPEG object. The application may wish to consult this information before selecting decompression parameters.
BOOL SetBitmapResolution ()
 Support function that sets the X & Y pixel densities for the bitmap imported from the JPEG file.
BOOL ReadPalette ()
 Reads a palette for the image In this case it just generates a greyscale palette for JCS_GRAYSCALE JPEGs. All other colour models are 24-bit.
BOOL InitErrorHandler ()
 Creates & initializes an error handler for this filter.
BOOL InitFileHandler ()
 Creates & initializes a source data provider for this filter.
BOOL InitProgressMonitor ()
 Creates & initializes the Progress bar for the filtering operation.

Protected Attributes

CCFilem_pFile
BOOL m_bOldReportErrors
BOOL m_bOldThrowExceptions
UINT32 m_uStartOffset
libJPEG::jpeg_decompress_struct m_cinfo
JPEGErrorManagerm_pErrorHandler
JPEGDataSourcem_pSourceHandler
JPEGProgressMonitorm_pProgressMonitor
CCLexFilem_pFileForProgress
Filterm_pFilterForProgress
UINT32 m_uImportSize
LPBITMAPINFOm_ppInfo
LPBYTEm_ppBytes
UINT32 m_uWidth
UINT32 m_uHeight
UINT32 m_uBitsPerPixel

Static Protected Attributes

static BOOL m_fImportAt96dpi = m_fImportAt96dpi

Private Member Functions

 CC_DECLARE_MEMDUMP (JPEGImportFilter)

Detailed Description

Provides a JPEG import filter using the IJG JPEG LIBRARY.

Author:
Date:

Definition at line 123 of file imjpeg.h.


Constructor & Destructor Documentation

JPEGImportFilter::JPEGImportFilter  ) 
 

Default constructor for a JPEGFilter object.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/08/96

Definition at line 173 of file imjpeg.cpp.

00173                                    : 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 }

JPEGImportFilter::~JPEGImportFilter  ) 
 

Default constructor for a JPEGFilter object.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/08/96

Definition at line 216 of file imjpeg.cpp.

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 }


Member Function Documentation

JPEGImportFilter::CC_DECLARE_MEMDUMP JPEGImportFilter   )  [private]
 

BitmapSource * JPEGImportFilter::CreateBitmapSource OFFSET  Size  )  const [protected, virtual]
 

Provides a BitmapSource for lossy file formats. The JPEGImportFilter returns a JPEGBitmapSource.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
21/08/96
Returns:
A pointer to a new BitmapSource
See also:
BaseBitmapFIlter::CreateBitmapSource Scope: protected

Reimplemented from BaseBitmapFilter.

Definition at line 476 of file imjpeg.cpp.

00477 {
00478     BitmapSource* pSource = new JPEGBitmapSource(Size);
00479     return pSource;
00480 }

BOOL JPEGImportFilter::DoFilter CCFile pInputFile,
OILBitmap pOilBitmap
[protected]
 

Provides the main processing point for the JPEG import. Called by the external interface.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
09/08/96
Parameters:
pInputFile : a pointer to an open CCFile containing the JPEG data to be [INPUTS] imported pOilBitmap : pointer to the OILBitmap to be filled in
pOilBitmap : If successful will contain the bitmap data from reading the [OUTPUTS] JPEG file (GetImportFile()).
Returns:
TRUE if successful FALSE if not
Notes: Here's how the IJG docs say we do it: 1) Allocate and initialize a JPEG decompression object 2) Specify the source of the compressed data (eg, a file) 3) Call jpeg_read_header() to obtain image info 4) Set parameters for decompression 5) jpeg_start_decompress(...); 6) while (scan lines remain to be read) jpeg_read_scanlines(...); 7) jpeg_finish_decompress(...); 8) Release the JPEG decompression object

See Also: ReadFromFile(...)

Definition at line 613 of file imjpeg.cpp.

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 }

OFFSET JPEGImportFilter::GetDataStartOffset  )  const [protected, virtual]
 

Provides information to the BaseBitmapFilter, so that it knows where to start any required BitmapSource. It will only be useful to derived classes that deal with a lossy file format.

> virtual OFFSET BaseBitmapFilter::GetDataStartOffset() const

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/08/96
Returns:
The offset from the HeaderStart parameter given in HowCompatible(), from which data essential to the correct functionality of this filter starts.
See Also: BaseBitmapFilter::GetDataStartOffset()

Reimplemented from BaseBitmapFilter.

Definition at line 457 of file imjpeg.cpp.

00458 {
00459     return m_uStartOffset;
00460 }

static BOOL JPEGImportFilter::GetImportAt96dpi  )  [inline, static]
 

Definition at line 146 of file imjpeg.h.

00146 { return m_fImportAt96dpi; }

BitmapImportOptions * JPEGImportFilter::GetImportOptions  )  [protected, virtual]
 

Overrides the BaseBitmapFilter::GetImportOptions to This will read the source datastream header markers, up to the beginning.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/08/96
Returns:
A pointer to some new JPEGImportOptions if successful NULL otherwise
Notes: From the IJG docs:

jpeg_read_header() sets appropriate default decompression parameters based on the properties of the image (in particular, its colorspace). However, you may well want to alter these defaults before beginning the decompression. For example, the default is to produce full color output from a color file. If you want colormapped output you must ask for it. Other options allow the returned image to be scaled and allow various speed/quality tradeoffs to be selected. "Decompression parameter selection", below, gives details.

If the defaults are appropriate, nothing need be done at this step.

Note that all default values are set by each call to jpeg_read_header(). If you reuse a decompression object, you cannot expect your parameter settings to be preserved across cycles, as you can for compression. You must set desired parameter values each time.

See Also: BaseBitmapFilter::GetImportOptions()

Reimplemented from BaseBitmapFilter.

Definition at line 870 of file imjpeg.cpp.

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 }

INT32 JPEGImportFilter::HowCompatible PathName Filename,
ADDR  pHeaderStart,
UINT32  HeaderSize,
UINT32  FileSize
[virtual]
 

Overrides the Filter class member to determine if the given file is reckoned to be a JPEG.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/08/96
Parameters:
Filename - name of the file. [INPUTS] HeaderStart - Address of the first few bytes of the file. HeaderSize - the number of bytes in the header pointed to by FileStart. FileSize - the size of the whole file, in bytes.
Returns:
0 => Not a JPEG file. 10 => Bound to be a JPEG file. 1 - 9 => Might be

Reimplemented from Filter.

Definition at line 320 of file imjpeg.cpp.

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 }

BOOL JPEGImportFilter::Init void   )  [virtual]
 

Initializes the JPEGImportFilter class.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/08/96
Returns:
TRUE if the filter was initialized ok FALSE otherwise

Reimplemented from BaseBitmapFilter.

Definition at line 239 of file imjpeg.cpp.

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 }

BOOL JPEGImportFilter::InitErrorHandler  )  [protected]
 

Creates & initializes an error handler for this filter.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/08/96

Definition at line 1275 of file imjpeg.cpp.

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 }

BOOL JPEGImportFilter::InitFileHandler  )  [protected]
 

Creates & initializes a source data provider for this filter.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/08/96

Definition at line 1299 of file imjpeg.cpp.

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 }

BOOL JPEGImportFilter::InitProgressMonitor  )  [protected]
 

Creates & initializes the Progress bar for the filtering operation.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
08/08/96

Definition at line 1328 of file imjpeg.cpp.

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 }

BOOL JPEGImportFilter::IsFormatLossy  )  const [protected, virtual]
 

The JPEGImportFilter imports a lossy format & therefore always returns TRUE See Also: BaseBitmapFilter::IsFormatLossy().

> virtual BOOL JPEGImportFilter::IsFormatLossy() const

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
20/08/96
Returns:
TRUE

Reimplemented from BaseBitmapFilter.

Definition at line 433 of file imjpeg.cpp.

00434 {
00435     return TRUE;
00436 }

BOOL JPEGImportFilter::OnFilterCompletion  )  [protected, virtual]
 

Default constructor for a JPEGFilter object.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/08/96
Notes: Taken from IJG docs:

When you are done with a JPEG decompression object, destroy it by calling jpeg_destroy_decompress() or jpeg_destroy().

Definition at line 1230 of file imjpeg.cpp.

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 }

void JPEGImportFilter::OnImageCompletion  )  [protected, virtual]
 

Once an image has been read, this member should be called to complete any processing associated with that image.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/08/96
Returns:
Errors: Throws exceptions
Notes: Taken from IJG docs:

After all the image data has been read, call jpeg_finish_decompress() to complete the decompression cycle. This causes working memory associated with the JPEG object to be released.

It is an error to call jpeg_finish_decompress() before reading the correct total number of scanlines. If you wish to abort compression, call jpeg_abort() as discussed below.

After completing a decompression cycle, you may dispose of the JPEG object as discussed next, or you may use it to decompress another image. In that case return to step 2 or 3 as appropriate. If you do not change the source manager, the next image will be read from the same source.

Definition at line 1194 of file imjpeg.cpp.

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 }

BOOL JPEGImportFilter::PrepareFilterForOperation  )  [protected, virtual]
 

Default constructor for a JPEGFilter object.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/08/96
1. Allocate and initialize a JPEG decompression object.

This is just like initialization for compression, as discussed above, except that the object is a "struct jpeg_decompress_struct" and you call jpeg_create_decompress(). Error handling is exactly the same.

A JPEG compression object is a "struct jpeg_compress_struct". (It also has a bunch of subsidiary structures which are allocated via malloc(), but the application doesn't control those directly.) This struct can be just a local variable in the calling routine, if a single routine is going to execute the whole JPEG compression sequence. Otherwise it can be static or allocated from malloc().

You will also need a structure representing a JPEG error handler. The part of this that the library cares about is a "struct jpeg_error_mgr". If you are providing your own error handler, you'll typically want to embed the jpeg_error_mgr struct in a larger structure; this is discussed later under "Error handling". For now we'll assume you are just using the default error handler. The default error handler will print JPEG error/warning messages on stderr, and it will call exit() if a fatal error occurs.

You must initialize the error handler structure, store a pointer to it into the JPEG object's "err" field, and then call jpeg_create_compress() to initialize the rest of the JPEG object.

Typical code:

struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; ... cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo);

jpeg_create_compress allocates a small amount of memory, so it could fail if you are out of memory. In that case it will exit via the error handler; that's why the error handler must be initialized first.

(Both here and in the IJG code, we usually use variable name "cinfo" for both compression and decompression objects.)

2. Specify the source of the compressed data (eg, a file).

As previously mentioned, the JPEG library reads compressed data from a "data source" module. The library includes one data source module which knows how to read from a stdio stream. You can use your own source module if you want to do something else, as discussed later.

If you use the standard source module, you must open the source stdio stream beforehand. Typical code for this step looks like:

FILE * infile; ... if ((infile = fopen(filename, "rb")) == NULL) { fprintf(stderr, "can't open %s\n", filename); exit(1); } jpeg_stdio_src(&cinfo, infile);

where the last line invokes the standard source module.

WARNING: it is critical that the binary compressed data be read unchanged. On non-Unix systems the stdio library may perform newline translation or otherwise corrupt binary data. To suppress this behavior, you may need to use a "b" option to fopen (as shown above), or use setmode() or another routine to put the stdio stream in binary mode. See cjpeg.c and djpeg.c for code that has been found to work on many systems.

You may not change the data source between calling jpeg_read_header() and jpeg_finish_decompress(). If you wish to read a series of JPEG images from a single source file, you should repeat the jpeg_read_header() to jpeg_finish_decompress() sequence without reinitializing either the JPEG object or the data source module; this prevents buffered input data from being discarded.

Definition at line 758 of file imjpeg.cpp.

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 }

void JPEGImportFilter::PrepareForImage BitmapImportOptions pOptions  )  [protected, virtual]
 

Prepares a place for the actual scanlines using the given options.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/08/96
Parameters:
pOptions : a pointer to some JPEGImportOptions (currently NULL) [INPUTS]
Notes: From the IJG docs:

Once the parameter values are satisfactory, call jpeg_start_decompress() to begin decompression. This will initialize internal state, allocate working memory, and prepare for returning data. If you have requested a multi-pass operating mode, such as 2-pass color quantization, jpeg_start_decompress() will do everything needed before data output can begin. In this case jpeg_start_decompress() may take quite a while to complete. With a single-scan (non progressive) JPEG file and default decompression parameters, this will not happen; jpeg_start_decompress() will return quickly.

After this call, the final output image dimensions, including any requested scaling, are available in the JPEG object; so is the selected colormap, if colormapped output has been requested. Useful fields include

output_width image width and height, as scaled output_height out_color_components # of color components in out_color_space output_components # of color components returned per pixel colormap the selected colormap, if any actual_number_of_colors number of entries in colormap

output_components is 1 (a colormap index) when quantizing colors; otherwise it equals out_color_components. It is the number of JSAMPLE values that will be emitted per pixel in the output arrays.

Typically you will need to allocate data buffers to hold the incoming image. You will need output_width * output_components JSAMPLEs per scanline in your output buffer, and a total of output_height scanlines will be returned.

Definition at line 952 of file imjpeg.cpp.

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 }

BOOL JPEGImportFilter::ReadFromFile OILBitmap pOilBitmap  )  [virtual]
 

Actually does the process of reading a bitmap from a file. Inherited classes override this to read in different file formats. JPEG reads a JPEG file.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
09/08/96
Parameters:
pOilBitmap : pointer to the OILBitmap to be filled in [INPUTS]
pOilBitmap : If successful will contain the bitmap data from reading the [OUTPUTS] JPEG file (GetImportFile()).
Returns:
TRUE if successful FALSE if not

Errors: ERROR2s for invalid parameters

Notes: m_uStartOffset must have been set prior to calling this (use HowCompatible() or set it zero).

Reimplemented from BaseBitmapFilter.

Definition at line 568 of file imjpeg.cpp.

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 }

BOOL JPEGImportFilter::ReadFromFile OILBitmap pOilBitmap,
BaseCamelotFilter pFilter,
CCLexFile pFile,
BOOL  IsCompressed
[virtual]
 

Entry point for Native File Format stuff Actually does the process of reading a bitmap from a file. Inherited classes override this to read in different file formats. It is used by the web/native filters to pull out a bitmap definition from inside a bitmap definition record.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com> (from Neville Humphrys in PNGFilter)
Date:
14/08/96
Parameters:
pFilter,: the BaseCamelotFilter which provides functions like [INPUTS] progress update pFile the CCFile class to use to read the data from IsCompressed :Flag to say the bitmap is compressed or not.
pOilBitmap,: Will have filled in BMInfo pointer to the bitmap header to fill [OUTPUTS] in. BMBytes pointer to the bitmap data to fill in
Returns:
TRUE if worked, FALSE if failed.
Notes: m_uStartOffset, the offset in the stream at which the JPEG header starts, is set to zero through this entry point. This assumes, therefore, that the JPEG contains no Adobe style garbage in front of it. Also assumes: pFile has already been opened up for reading pFilter has been set up for reading the data e.g. progress bar

Reimplemented from BaseBitmapFilter.

Definition at line 512 of file imjpeg.cpp.

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 }

void JPEGImportFilter::ReadHeader  )  [protected]
 

This will read the source datastream header markers, up to the beginning of the compressed data proper. On return, the image dimensions and other info have been stored in the JPEG object. The application may wish to consult this information before selecting decompression parameters.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/08/96
Returns:
TRUE if header was correctly read & the data set FALSE otherwise

Errors: Throws exceptions Notes: PrepareFilterForOperation must have been called prior to this call.

From the IJG docs:

More complex code is necessary if A suspending data source is used --- in that case jpeg_read_header() may return before it has read all the header data. Abbreviated JPEG files are to be processed --- see the section on abbreviated datastreams. Standard applications that deal only in interchange JPEG files need not be concerned with this case either.

It is permissible to stop at this point if you just wanted to find out the image dimensions and other header info for a JPEG file. In that case, call jpeg_destroy() when you are done with the JPEG object, or call jpeg_abort() to return it to an idle state before selecting a new data source and reading another header.

Definition at line 833 of file imjpeg.cpp.

00834 {
00835     jpeg_read_header(&m_cinfo, TRUE);
00836 }

void JPEGImportFilter::ReadImage  )  [protected, virtual]
 

Reads the actual scanlines of the image into this's DIB data members.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/08/96
Returns:
Errors: Throws exceptions
Notes: Once PrepareForImage() has been called this function can read in the data

Definition at line 1107 of file imjpeg.cpp.

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 }

BOOL JPEGImportFilter::ReadPalette  )  [protected]
 

Reads a palette for the image In this case it just generates a greyscale palette for JCS_GRAYSCALE JPEGs. All other colour models are 24-bit.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/08/96
Returns:
TRUE if a palette was read correctly & the data set FALSE otherwise

Definition at line 1075 of file imjpeg.cpp.

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 }

BOOL JPEGImportFilter::SetBitmapResolution  )  [protected]
 

Support function that sets the X & Y pixel densities for the bitmap imported from the JPEG file.

Author:
Colin_Barfoot (Xara Group Ltd) <camelotdev@xara.com>
Date:
02/08/96
Returns:
TRUE if resolution set OK FALSE otherwise

Definition at line 1029 of file imjpeg.cpp.

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 }

static void JPEGImportFilter::SetImportAt96dpi BOOL  fImportAt96  )  [inline, static]
 

Definition at line 147 of file imjpeg.h.

00147 { m_fImportAt96dpi = fImportAt96; }


Member Data Documentation

BOOL JPEGImportFilter::m_bOldReportErrors [protected]
 

Definition at line 180 of file imjpeg.h.

BOOL JPEGImportFilter::m_bOldThrowExceptions [protected]
 

Definition at line 181 of file imjpeg.h.

struct libJPEG::jpeg_decompress_struct JPEGImportFilter::m_cinfo [protected]
 

Definition at line 186 of file imjpeg.h.

BOOL JPEGImportFilter::m_fImportAt96dpi = m_fImportAt96dpi [static, protected]
 

Definition at line 183 of file imjpeg.h.

JPEGErrorManager* JPEGImportFilter::m_pErrorHandler [protected]
 

Definition at line 188 of file imjpeg.h.

CCFile* JPEGImportFilter::m_pFile [protected]
 

Definition at line 179 of file imjpeg.h.

CCLexFile* JPEGImportFilter::m_pFileForProgress [protected]
 

Definition at line 193 of file imjpeg.h.

Filter* JPEGImportFilter::m_pFilterForProgress [protected]
 

Definition at line 194 of file imjpeg.h.

LPBYTE* JPEGImportFilter::m_ppBytes [protected]
 

Definition at line 199 of file imjpeg.h.

LPBITMAPINFO* JPEGImportFilter::m_ppInfo [protected]
 

Definition at line 198 of file imjpeg.h.

JPEGProgressMonitor* JPEGImportFilter::m_pProgressMonitor [protected]
 

Definition at line 190 of file imjpeg.h.

JPEGDataSource* JPEGImportFilter::m_pSourceHandler [protected]
 

Definition at line 189 of file imjpeg.h.

UINT32 JPEGImportFilter::m_uBitsPerPixel [protected]
 

Definition at line 203 of file imjpeg.h.

UINT32 JPEGImportFilter::m_uHeight [protected]
 

Definition at line 202 of file imjpeg.h.

UINT32 JPEGImportFilter::m_uImportSize [protected]
 

Definition at line 195 of file imjpeg.h.

UINT32 JPEGImportFilter::m_uStartOffset [protected]
 

Definition at line 182 of file imjpeg.h.

UINT32 JPEGImportFilter::m_uWidth [protected]
 

Definition at line 201 of file imjpeg.h.


The documentation for this class was generated from the following files:
Generated on Sat Nov 10 03:55:37 2007 for Camelot by  doxygen 1.4.4