unsigned char * TurboJpegLoadFromFile( const char * filename, int * width, int * height ) { const int fd = open( filename, O_RDONLY ); if ( fd <= 0 ) { return NULL; } struct stat st = {}; if ( fstat( fd, &st ) == -1 ) { LOG( "fstat failed on %s", filename ); close( fd ); return NULL; } const unsigned char * jpg = ( unsigned char * )mmap( NULL, ( size_t )st.st_size, PROT_READ, MAP_SHARED, fd, 0 ); if ( jpg == MAP_FAILED ) { LOG( "Failed to mmap %s, len %i: %s", filename, ( int )st.st_size, strerror( errno ) ); close( fd ); return NULL; } LOG( "mmap %s, %i bytes at %p", filename, ( int )st.st_size, jpg ); unsigned char * ret = TurboJpegLoadFromMemory( jpg, ( int )st.st_size, width, height ); close( fd ); munmap( ( void * )jpg, ( size_t )st.st_size ); return ret; }
unsigned char * VideoBrowser::LoadThumbnail( const char * filename, int & width, int & height ) { LOG( "VideoBrowser::LoadThumbnail loading on %s", filename ); unsigned char * orig = NULL; if ( strstr( filename, "assets/" ) ) { void * buffer = NULL; int length = 0; ovr_ReadFileFromApplicationPackage( filename, length, buffer ); if ( buffer ) { orig = TurboJpegLoadFromMemory( reinterpret_cast< const unsigned char * >( buffer ), length, &width, &height ); free( buffer ); } } else if ( strstr( filename, ".pvr" ) ) { orig = LoadPVRBuffer( filename, width, height ); } else { orig = TurboJpegLoadFromFile( filename, &width, &height ); } if ( orig ) { const int ThumbWidth = GetThumbWidth(); const int ThumbHeight = GetThumbHeight(); if ( ThumbWidth == width && ThumbHeight == height ) { LOG( "VideoBrowser::LoadThumbnail skip resize on %s", filename ); return orig; } LOG( "VideoBrowser::LoadThumbnail resizing %s to %ix%i", filename, ThumbWidth, ThumbHeight ); unsigned char * outBuffer = ScaleImageRGBA( ( const unsigned char * )orig, width, height, ThumbWidth, ThumbHeight, IMAGE_FILTER_CUBIC ); free( orig ); if ( outBuffer ) { width = ThumbWidth; height = ThumbHeight; return outBuffer; } } else { LOG( "Error: VideoBrowser::LoadThumbnail failed to load %s", filename ); } return NULL; }
void * Queue3Thread( void * v ) { int result = pthread_setname_np( pthread_self(), "FileQueue3" ); if ( result != 0 ) { LOG( "InitFileQueue: pthread_setname_np failed %s", strerror( result ) ); } // Process incoming messages until queue is empty for ( ; ; ) { Queue3.SleepUntilMessage(); const char * msg = Queue3.GetNextMessage(); LOG( "Queue3 msg = '%s'", msg ); // Note that Queue3 has cleared the message pthread_mutex_lock( &QueueMutex ); QueueHasCleared = true; pthread_cond_signal( &QueueWake ); pthread_mutex_unlock( &QueueMutex ); char commandName[1024] = {}; sscanf( msg, "%s", commandName ); int numBuffers = strcmp( commandName, "cube" ) == 0 ? 6 : 1; unsigned * b[6] = {}; int blen[6]; if ( numBuffers == 1 ) { sscanf( msg, "%s %p %i", commandName, &b[0], &blen[0] ); } else { OVR_ASSERT( numBuffers == 6 ); sscanf( msg, "%s %p %i %p %i %p %i %p %i %p %i %p %i ", commandName, &b[0], &blen[0], &b[1], &blen[1], &b[2], &blen[2], &b[3], &blen[3], &b[4], &blen[4], &b[5], &blen[5] ); } #define USE_TURBO_JPEG #if !defined( USE_TURBO_JPEG ) stbi_uc * data[6]; #else unsigned char * data[6]; #endif int resolutionX = 0; int resolutionY = 0; int buffCount = 0; for ( ; buffCount < numBuffers; buffCount++ ) { int x, y; unsigned * b1 = b[buffCount]; int b1len = blen[buffCount]; #if !defined( USE_TURBO_JPEG ) int comp; data[buffCount] = stbi_load_from_memory( (const stbi_uc*)b1, b1len, &x, &y, &comp, 4 ); #else data[buffCount] = TurboJpegLoadFromMemory( (unsigned char*)b1, b1len, &x, &y ); #endif if ( buffCount == 0 ) { resolutionX = x; resolutionY = y; } // done with the loading buffer now free( b1 ); if ( data[buffCount] == NULL ) { LOG( "LoadingThread: failed to load from buffer" ); break; } } if ( buffCount != numBuffers ) // an image load failed, free everything and abort this load { for ( int i = 0; i < numBuffers; ++i ) { free( data[i] ); data[i] = NULL; } } else { if ( numBuffers == 1 ) { OVR_ASSERT( data[0] != NULL ); LOG( "Queue3.PostPrintf( \"%s %p %i %i\" )", commandName, data[0], resolutionX, resolutionY ); ( ( Oculus360Photos * )v )->GetBGMessageQueue( ).PostPrintf( "%s %p %i %i", commandName, data[ 0 ], resolutionX, resolutionY ); } else { OVR_ASSERT( numBuffers == 6 ); LOG( "Queue3.PostPrintf( \"%s %i %p %p %p %p %p %p\" )", commandName, resolutionX, data[0], data[1], data[2], data[3], data[4], data[5] ); ( ( Oculus360Photos * )v )->GetBGMessageQueue( ).PostPrintf( "%s %i %p %p %p %p %p %p", commandName, resolutionX, data[0], data[1], data[2], data[3], data[4], data[5] ); } } free( (void *)msg ); } return NULL; }