00001 //--------------------------------------------------------------------- 00002 // CascadeJpegFile.h 00003 // 00004 // The CascadeJpegFile class represents a single JPEG file. It is able 00005 // to parse the EXIF header when present to extract the thumbnail 00006 // and image information. It also uses jpeglib to decode the 00007 // image and return an uncompressed pixmap. 00008 // 00009 // If a maximum size is specified during decompression, an 00010 // appropriate scale factor will be given to jpeglib to limit 00011 // the maximum size of the returned pixmap. Pass zero in this 00012 // argument for no limit to the output buffer size. 00013 // 00014 // Author: Mike Kobb (mjkobb) 00015 // 00016 // Includes some adaptation of a work in the public domain, from the 00017 // book "Graphics Gems III", article "General Filtered Image Rescaling" 00018 // by Dale Schumacher. 00019 // 00020 // (c) 2002-2003 Roku, LLC 00021 //--------------------------------------------------------------------- 00022 00023 #ifndef CASCADEJPEGFILE_H 00024 #define CASCADEJPEGFILE_H 00025 00026 #include <cascade/CascadeTypedefs.h> 00027 00043 class CascadeJpegFile 00044 { 00045 public: 00046 typedef enum 00047 { 00048 eRGB, 00049 eYUV, 00050 eYUYV 00051 } ColorSpace; 00052 00053 public: 00054 CascadeJpegFile(); 00059 00060 virtual ~CascadeJpegFile(); 00062 00063 #if 0 00064 static bool Validate( const char *inFilename ); 00072 #endif 00073 00074 bool Init( CascadeStream *inStream, 00075 const CascadeString &inName, 00076 ColorSpace inColorSpace = eRGB, 00077 bool inDeleteStream = false ); 00096 00097 bool Init( const char *inFilename, ColorSpace inColorSpace=eRGB ); 00108 00109 u32 GetBitmapDataSize( u32 inScaledWidth = 0, u32 inScaledHeight = 0 ); 00120 00121 bool GetBitmapData( u8 *outBitmapData, 00122 u32 inBitmapDataSize, 00123 CascadeRect &inClipRect, 00124 u32 inScaledWidth = 0, 00125 u32 inScaledHeight = 0, 00126 u32 inRotationDegrees = 0 ); 00179 00180 void AbortDecode( void ); 00185 00186 bool GetThumbnailData( u8 *outThumbnailData, 00187 u32 inThumbnailDataSize, 00188 u32 inWidth, 00189 u32 inHeight, 00190 u32 inRotationDegrees = 0 ); 00212 00213 void GetImageInfo( u32 &outWidth, u32 &outHeight, u32 &outBPP ) const; 00222 00223 // NOTE: These three functions return the same data returned in the 00224 // function above, but may be more convenient when passing the data 00225 // as arguments to another function. 00226 00227 u32 GetImageWidth( void ) const; 00231 00232 u32 GetImageHeight( void ) const; 00236 00237 u32 GetImageBPP( void ) const; 00241 00242 u32 GetImageRotation( void ) const; 00253 00254 static bool GetScaledImageDims( u32 inDivisor, 00255 u32 inWidth, 00256 u32 inHeight, 00257 u32 &outWidth, 00258 u32 &outHeight ); 00272 00273 const CascadeString & GetName( void ) const; 00282 00283 const CascadeString & GetImageDate( void ) const; 00294 00295 const CascadeString & GetImageMake( void ) const; 00308 00309 const CascadeString & GetImageModel( void ) const; 00322 00323 const CascadeString & GetImageTitle( void ) const; 00336 00337 const CascadeString & GetImageArtist( void ) const; 00350 00351 const CascadeString & GetImageCopyright( void ) const; 00364 00365 u32 GetImageExposureNumerator( void ) const; 00384 00385 u32 GetImageExposureDenominator( void ) const; 00404 float GetImageFStop( void ) const; 00420 00421 bool GetImageFlashState( bool &outFlashState ) const; 00435 00436 bool HasThumbnail( void ); 00441 00442 #if 0 00443 // Return the width, height and pixel depth of the thumbnail image. 00444 // You should clal hasThumbnail first. Will return all zeroes if no 00445 // thumbnail is present. 00446 // THIS FUNCTION DOES NOT WORK -- IT ALWAYS RETURNS ZEROS 00447 void GetThumbnailInfo( u32 &outWidth, u32 &outHeight, u32 &outBPP ) 00448 { 00449 outWidth = mThumbnailWidth; 00450 outHeight = mThumbnailHeight; 00451 outBPP = mThumbnailBPP; 00452 }; 00453 00454 // Accessors. Same data returned as above, but maybe more convenient 00455 // to pass to other functions. 00456 // You should clal hasThumbnail first. Will return all zeroes if no 00457 // thumbnail is present. 00458 // THESE FUNCTIONS DO NOT WORK -- THEY ALWAYS RETURNS ZEROS 00459 u32 GetThumbnailWidth( void ) { return mThumbnailWidth; }; 00460 u32 GetThumbnailHeight( void ) { return mThumbnailHeight; }; 00461 u32 GetThumbnailBPP( void ) { return mThumbnailBPP; }; 00462 #endif 00463 00464 private: 00465 class PrivateMembers; 00466 PrivateMembers *m_private; 00467 }; 00468 00469 // --------------------------------------------------------------------------- 00470 // Class PixelWriter 00471 // 00472 // Object to handle writing image data into a destination buffer, taking 00473 // rotation into account. Performs one more conditional operation (a test of 00474 // mCurRasterIndex against mRasterWidth) and one more addition (increment 00475 // mCurRasterIndex) per pixel than a straight copy to an upright buffer. 00476 // 00477 // Note the absence of any indexes in the writing function. The assumption 00478 // here is that the object is constructed, and then the pixels are written 00479 // sequentially from the top-left of the source image to the bottom right, 00480 // proceeding horizontally across each row and then on to the next row. 00481 // 00482 // We do support writing more than one pixel per call, for cases where we 00483 // have a buffer of data to write. 00484 // --------------------------------------------------------------------------- 00485 class PixelWriter 00486 { 00487 public: 00488 PixelWriter( u8 *inBuffer, u32 inWidth, u32 inHeight, 00489 u32 inRotationDegees, u32 inColorComponents ); 00490 virtual ~PixelWriter(); 00491 00492 // Copy mColorComponents 8-bit pixel components from this pointer to 00493 // the destination. 00494 void WritePixels( u8* inPixelData, u32 inNumPixels ); 00495 00496 // Reset the internal state so we start writing from the 00497 // beginning of the destination buffer again. 00498 void Reset( void ); 00499 00500 private: 00501 // First pixel (corresponds to top-left pixel in non-rotated image) 00502 u8* mRasterStart; 00503 00504 // Last pixel in the array 00505 u8* mRasterEnd; 00506 00507 // First pixel of current scan line (keeping in mind that we scan 00508 // pixels into the image in source order, so a line may be a column, etc) 00509 u8* mCurRowStart; 00510 00511 // Next pixel to write 00512 u8* mCurPixel; 00513 00514 // Width of one *source* image scan line, in pixels 00515 u32 mRasterWidth; 00516 00517 // Current index into the current scan line 00518 u32 mCurRasterIndex; 00519 00520 // Number of bytes to increment for next pixel. 00521 // 1 pixel for upright 00522 // -1 pixel for 180 00523 // mRasterWidth pixels for 90 degree rotation 00524 // -mRasterWidth pixels for 270 degree rotation 00525 s32 mPixelByteOffset; 00526 00527 // Number of bytes to add to mCurRowStart when mCurRasterIndex == 00528 // mRasterWidth (i.e. we've written mRasterWidth pixels to this row) 00529 // in order to get the next row 00530 // mRasterWidth pixels for upright 00531 // -mRasterWidth pixels for 180 00532 // -1 pixel for 90 00533 // 1 pixel for 270 00534 s32 mRasterOffset; 00535 00536 // FIXME: Could have source and destination components, and use this 00537 // function to pad out alpha as well. 00538 // Number of 8-bit components that make up a pixel 00539 u32 mColorComponents; 00540 }; 00541 00542 00543 #endif //CASCADEJPEGFILE_H 00544 00545 // CHANGE HISTORY 00546 // ============== 00547 // 01/28/2003 mjkobb Post-CES cleanup, rename CascadeJpegFile, convert 00548 // to Cascade typedefs 00549 // 02/21/2003 mjkobb Oops, havent' updated these comments in awhile. This 00550 // checkin includes a reasonably-stable image scaling 00551 // enhancement to GetBitmapData. Scales X and Y axes 00552 // independently and rotates during the decoding process 00553 // to minimize memory required. Uses a "Mitchell" filter 00554 // (a cubic function). 00555 // 03/17/2003 mjkobb Added rudimentary support for aborting a decode 00556 // operation. Strictly speaking, this should have 00557 // some nice thread-safety associated, but right now 00558 // the simple-minded approach works. 00559 // 05/23/2003 mjkobb Major re-structuring. Moved the threaded slideshow 00560 // functionality into CImageWindow, so that 00561 // it and CThumbnailWindow could have independent 00562 // key and command processing. 00563 // 06/05/2003 mjkobb Add setjmp/longjmp-based error recovery to the 00564 // class so that clients don't suddenly exit 00565 // when a problem is encountered. 00566 // 07/02/2003 mjkobb Added support for RGB or YUV color space selection 00567 // 07/24/2003 mjkobb Added accessors for EXIF data and modified return 00568 // types of EXIF Rational functions 00569 // 07/28/2003 mjkobb Make CascadeJpegFile a derivative of CascadeFile for 00570 // easier access to the file name 00571 // 12/09/2003 mjkobb Add YUYV support 00572 // 05/16/2005 mjkobb Cleaned up API to make a proper Cascade class. No 00573 // longer derives from CascadeFile. Accepts a 00574 // CascadeStream in its initialization (with a backward- 00575 // compatible path initializer). 00576 00577