From: <da...@us...> - 2006-10-05 15:32:37
|
Revision: 55 http://svn.sourceforge.net/freepv/?rev=55&view=rev Author: dangelo Date: 2006-10-05 08:32:29 -0700 (Thu, 05 Oct 2006) Log Message: ----------- detect compressed mov files, and print appropriate error message. Modified Paths: -------------- freepv/trunk/src/libfreepv/PanoViewer.cpp freepv/trunk/src/libfreepv/QTVRDecoder.cpp freepv/trunk/src/libfreepv/QTVRDecoder.h Modified: freepv/trunk/src/libfreepv/PanoViewer.cpp =================================================================== --- freepv/trunk/src/libfreepv/PanoViewer.cpp 2006-10-04 21:49:07 UTC (rev 54) +++ freepv/trunk/src/libfreepv/PanoViewer.cpp 2006-10-05 15:32:29 UTC (rev 55) @@ -306,6 +306,7 @@ // do some useful stuff here.. decode image etc. switch (m_state) { case STATE_DOWNLOADING_QTVR: + { // TODO: create panorama object and set to renderer Image *cubeFaces[6]; for (int i=0; i < 6 ; i++) { @@ -317,7 +318,8 @@ m_scene->setStatusText( m_statusMessage ); redraw(); - if (decodeQTVR(filename.c_str(), cubeFaces)) + std::string decoderError; + if (decodeQTVR(filename.c_str(), cubeFaces, decoderError)) { m_statusMessage = "Preparing rendering"; DEBUG_TRACE(m_statusMessage); @@ -334,11 +336,12 @@ m_scene->setStatusText("QTVR successfully loaded"); changeState(STATE_VIEWING); } else { - FPV_S2S(m_statusMessage, "Error during QTVR decoding: " << m_platform->currentDownloadURL() << "."); + FPV_S2S(m_statusMessage, "Error during QTVR decoding: " << decoderError); m_scene->setStatusText( m_statusMessage ); changeState(STATE_ERROR); redraw(); } + } break; default: m_statusMessage = "internal error: invalid state after downloading to file"; Modified: freepv/trunk/src/libfreepv/QTVRDecoder.cpp =================================================================== --- freepv/trunk/src/libfreepv/QTVRDecoder.cpp 2006-10-04 21:49:07 UTC (rev 54) +++ freepv/trunk/src/libfreepv/QTVRDecoder.cpp 2006-10-05 15:32:29 UTC (rev 55) @@ -48,9 +48,13 @@ typedef unsigned int uint32; typedef int int32; + typedef unsigned long u_long; typedef bool Boolean; +typedef int32 DWORD; +typedef short WORD; + #define MAX_TILE_DIMENSIONS 10 // this is the maximum # of tiles x/y that we'll support #define MAX_TILES_PER_FACE (MAX_TILE_DIMENSIONS * MAX_TILE_DIMENSIONS) @@ -94,6 +98,94 @@ PublicHandlerInfo hInfo; }; + +struct QTVRCubicViewAtom{ + float minPan; + float maxPan; + float minTilt; + float maxTilt; + float minFieldOfView; + float maxFieldOfView; + float defaultPan; + float defaultTilt; + float defaultFieldOfView; +}; + +// 'pdat' atom +struct VRPanoSampleAtom{ + WORD majorVersion; + WORD minorVersion; + DWORD imageRefTrackIndex; + DWORD hotSpotRefTrackIndex; + float minPan; + float maxPan; + float minTilt; + float maxTilt; + float minFieldOfView; + float maxFieldOfView; + float defaultPan; + float defaultTilt; + float defaultFieldOfView; + DWORD imageSizeX; + DWORD imageSizeY; + WORD imageNumFramesX; + WORD imageNumFramesY; + DWORD hotSpotSizeX; + DWORD hotSpotSizeY; + WORD hotSpotNumFramesX; + WORD hotSpotNumFramesY; + DWORD flags; + DWORD panoType; + DWORD reserved2; +}; + +// 'cube' +#define kQTVRCube 'cube' +//0x65627563 + +// 'hcyl' +#define kQTVRHorizontalCylinder 'hcyl' +//0x6C796368 + +// 'vcyl' +#define kQTVRVerticalCylinder 'vcyl' +//0x6C796376 + +struct QTVRCubicFaceData{ + float orientation[4]; + float center[2]; + float aspect; + float skew; +}; + +struct VRObjectSampleAtom{ + WORD majorVersion; + WORD minorVersion; + WORD movieType; + WORD viewStateCount; + WORD defaultViewState; + WORD mouseDownViewState; + DWORD viewDuration; + DWORD columns; + DWORD rows; + float mouseMotionScale; + float minPan; + float maxPan; + float defaultPan; + float minTilt; + float maxTilt; + float defaultTilt; + float minFieldOfView; + float fieldOfView; + float defaultFieldOfView; + float defaultViewCenterH; + float defaultViewCenterV; + float viewRate; + float frameRate; + DWORD animationSettings; + DWORD controlSettings; +}; + // dangelo: wrap the parser into a class, this makes the parser // reentrant. Might be important if multiple plugin instances decode a qtvr // at the same time. @@ -115,6 +207,7 @@ void ReadAtom_STCO(long size); void ReadAtom_HDLR(int size); void ReadAtom_STSZ(long size); +void ReadAtom_PDAT(long size); bool SeekAndExtractImages(Image * imgs[6]); bool SeekAndExtractImages_Tiled(Image * imgs[6]); void LoadTilesForFace(int chunkNum); @@ -145,6 +238,11 @@ FILE *gFile; // FILE ref used for fopen(). Not used on Mac since mac uses FSSpec #endif bool m_HostBigEndian; + + DWORD m_imageRefTrackIndex; + DWORD m_panoType; + + std::string m_error; }; /**************** PARSE QUICKTIME MOVIE ***********************/ @@ -152,10 +250,13 @@ // Parses through the QT movie's atoms looking for our 6 cube textures. // -bool decodeQTVR(const char * theDataFilePath, Image * imgs[6]) +bool decodeQTVR(const char * theDataFilePath, Image * imgs[6], std::string & error) { QTVRDecoder decoder; - return decoder.decodeCubic(theDataFilePath, imgs); + bool ok = decoder.decodeCubic(theDataFilePath, imgs); + if (! ok) + error = decoder.m_error; + return ok; } @@ -164,7 +265,8 @@ gCurrentTrackMedia = 0; gAlreadyGotVideoMedia = false; gFoundJPEGs = false; - + m_imageRefTrackIndex = -1; + m_panoType = 0; // determine byteorder int testint = 0x01; unsigned char * testchar = reinterpret_cast< unsigned char * >(&testint); @@ -197,8 +299,10 @@ atomSize = ReadMovieAtom(); }while(atomSize > 0); + if (m_error != "") { + return false; + } - /***************************/ /* SEEK AND EXTRACT IMAGES */ /***************************/ @@ -281,7 +385,7 @@ /* READ THE ATOM SIZE */ - int sz = fread(&atomSize, 1, 4, gFile); + size_t sz = fread(&atomSize, 1, 4, gFile); if (ferror(gFile) || sz != 4) { printf("ReadMovieAtom: fread() failed!\n"); @@ -431,6 +535,12 @@ case 'hdlr': //HandlerAID: //'hdlr' ReadAtom_HDLR(atomSize); break; + case 'pdat': + ReadAtom_PDAT(atomSize); + break; + case 'cmov': + m_error = "Compressed headers not supported."; + break; } @@ -738,9 +848,74 @@ free(atom); } +/********************** READ ATOM: PDAT ****************************/ +void QTVRDecoder::ReadAtom_PDAT(long size) +{ +//int32 count; +VRPanoSampleAtom *atom; +//int32 numEntries, i; + /*****************/ + /* READ THE ATOM */ + /*****************/ + +#ifdef TARGET_OS_MAC + SetFPos(gMovfRefNum, fsFromMark, -8); // back up 8 bytes to the atom's start so we can read it all in +#else + fseek(gFile, -8, SEEK_CUR); +#endif + + /* ALLOC MEMORY FOR IT */ + // + // This is a variable size structure, so we need to allocated based on the size of the atom that's passed in + // + + atom = (VRPanoSampleAtom *) malloc(size); + + + /* READ IT */ + +#ifdef TARGET_OS_MAC + count = size; + if (FSRead(gMovfRefNum, &count, atom) != noErr) + { + printf("ReadAtom_PDAT: FSRead failed!\n"); + return; + } +#else + size_t sz = fread(atom, size, 1, gFile); + if (ferror(gFile) || sz != 1) + { + printf("ReadAtom_PDAT: fread() failed!\n"); + return; + } +#endif + + /* SEE WHAT KIND OF TRACK WE'VE PARSED INTO AND GET CHUNKS BASED ON THAT */ + + // get the track number of the real pano + m_imageRefTrackIndex = atom->imageRefTrackIndex; + Swizzle(&m_imageRefTrackIndex); // convert BigEndian data to LittleEndian (if not Mac) + DEBUG_DEBUG("imageRefTrackIndex " << m_imageRefTrackIndex); + + // check if this is a cubic panorama + m_panoType = atom->panoType; + Swizzle(&m_panoType); // convert BigEndian data to LittleEndian (if not Mac) + char *t = (char*)&m_panoType; + DEBUG_DEBUG("panoType: " << t[0] << t[1] << t[2] << t[3]); + + if (m_panoType != kQTVRCube) { + // abort reading + m_error = "Cylindrical panoramas are not supported yet."; + } + + free(atom); +} + + + /********************* SEEK AND EXTRACT IMAGES ***************************/ // // Finds the 6 cube faces JPEG's in the .mov file and then draws them into texture buffers. Modified: freepv/trunk/src/libfreepv/QTVRDecoder.h =================================================================== --- freepv/trunk/src/libfreepv/QTVRDecoder.h 2006-10-04 21:49:07 UTC (rev 54) +++ freepv/trunk/src/libfreepv/QTVRDecoder.h 2006-10-05 15:32:29 UTC (rev 55) @@ -34,7 +34,7 @@ namespace FPV { -bool decodeQTVR(const char * inputfile, Image *imgs[6]); +bool decodeQTVR(const char * inputfile, Image *imgs[6], std::string & error); } // namespace This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |