void SaveJPG(char *filename, int quality, int image_width, int image_height, byte * image_buffer) { byte *out; size_t bufSize; bufSize = image_width * image_height * 3; out = ri.Malloc(bufSize); bufSize = SaveJPGToBuffer(out, bufSize, quality, image_width, image_height, image_buffer); ri.FS_WriteFile(filename, out, bufSize); ri.Free(out); }
void SaveJPG( char *filename, int quality, int image_width, int image_height, byte *image_buffer ) { byte *out; size_t bufSize; bufSize = image_width * image_height * 3; out = (byte*) ri.Hunk_AllocateTempMemory( bufSize ); bufSize = SaveJPGToBuffer( out, bufSize, quality, image_width, image_height, image_buffer ); ri.FS_WriteFile( filename, out, bufSize ); ri.Hunk_FreeTempMemory( out ); }
/* ================== RB_TakeVideoFrameCmd ================== */ const void *RB_TakeVideoFrameCmd( const void *data ) { const videoFrameCommand_t *cmd; int frameSize; int i; cmd = (const videoFrameCommand_t *)data; qglReadPixels( 0, 0, cmd->width, cmd->height, GL_RGBA, GL_UNSIGNED_BYTE, cmd->captureBuffer ); // gamma correct if( ( tr.overbrightBits > 0 ) && glConfig.deviceSupportsGamma ) R_GammaCorrect( cmd->captureBuffer, cmd->width * cmd->height * 4 ); if( cmd->motionJpeg ) { frameSize = SaveJPGToBuffer( cmd->encodeBuffer, 95, cmd->width, cmd->height, cmd->captureBuffer ); } else { frameSize = cmd->width * cmd->height * 4; // Vertically flip the image for( i = 0; i < cmd->height; i++ ) { Com_Memcpy( &cmd->encodeBuffer[ i * ( cmd->width * 4 ) ], &cmd->captureBuffer[ ( cmd->height - i - 1 ) * ( cmd->width * 4 ) ], cmd->width * 4 ); } } ri.CL_WriteAVIVideoFrame( cmd->encodeBuffer, frameSize ); return (const void *)(cmd + 1); }
/* ================== RB_TakeVideoFrameCmd ================== */ const void *RB_TakeVideoFrameCmd( const void *data ) { const videoFrameCommand_t *cmd; int frameSize; int i; cmd = (const videoFrameCommand_t *)data; qglReadPixels( 0, 0, cmd->width, cmd->height, GL_RGBA, GL_UNSIGNED_BYTE, cmd->captureBuffer ); // gamma correct if( glConfig.deviceSupportsGamma ) R_GammaCorrect( cmd->captureBuffer, cmd->width * cmd->height * 4 ); if( cmd->motionJpeg ) { frameSize = SaveJPGToBuffer( cmd->encodeBuffer, 90, cmd->width, cmd->height, cmd->captureBuffer ); ri.CL_WriteAVIVideoFrame( cmd->encodeBuffer, frameSize ); } else { frameSize = cmd->width * cmd->height; for( i = 0; i < frameSize; i++) // Pack to 24bpp and swap R and B { cmd->encodeBuffer[ i*3 ] = cmd->captureBuffer[ i*4 + 2 ]; cmd->encodeBuffer[ i*3 + 1 ] = cmd->captureBuffer[ i*4 + 1 ]; cmd->encodeBuffer[ i*3 + 2 ] = cmd->captureBuffer[ i*4 ]; } ri.CL_WriteAVIVideoFrame( cmd->encodeBuffer, frameSize * 3 ); } return (const void *)(cmd + 1); }
/* ================== RB_TakeVideoFrameCmd ================== */ const void *RB_TakeVideoFrameCmd( const void *data ) { const videoFrameCommand_t *cmd; GLint packAlign; int lineLen, captureLineLen; byte *pixels; int i; int outputSize; int j; int aviLineLen; cmd = ( const videoFrameCommand_t * ) data; // RB: it is possible to we still have a videoFrameCommand_t but we already stopped // video recording if ( ri.CL_VideoRecording() ) { // take care of alignment issues for reading RGB images.. glGetIntegerv( GL_PACK_ALIGNMENT, &packAlign ); lineLen = cmd->width * 3; captureLineLen = PAD( lineLen, packAlign ); pixels = ( byte * ) PADP( cmd->captureBuffer, packAlign ); glReadPixels( 0, 0, cmd->width, cmd->height, GL_RGB, GL_UNSIGNED_BYTE, pixels ); if ( tr.overbrightBits > 0 && glConfig.deviceSupportsGamma ) { // this also runs over the padding... R_GammaCorrect( pixels, captureLineLen * cmd->height ); } if ( cmd->motionJpeg ) { // Drop alignment and line padding bytes for ( i = 0; i < cmd->height; ++i ) { memmove( cmd->captureBuffer + i * lineLen, pixels + i * captureLineLen, lineLen ); } outputSize = SaveJPGToBuffer( cmd->encodeBuffer, 3 * cmd->width * cmd->height, 90, cmd->width, cmd->height, cmd->captureBuffer ); ri.CL_WriteAVIVideoFrame( cmd->encodeBuffer, outputSize ); } else { aviLineLen = PAD( lineLen, AVI_LINE_PADDING ); for ( i = 0; i < cmd->height; ++i ) { for ( j = 0; j < lineLen; j += 3 ) { cmd->encodeBuffer[ i * aviLineLen + j + 0 ] = pixels[ i * captureLineLen + j + 2 ]; cmd->encodeBuffer[ i * aviLineLen + j + 1 ] = pixels[ i * captureLineLen + j + 1 ]; cmd->encodeBuffer[ i * aviLineLen + j + 2 ] = pixels[ i * captureLineLen + j + 0 ]; } while ( j < aviLineLen ) { cmd->encodeBuffer[ i * aviLineLen + j++ ] = 0; } } ri.CL_WriteAVIVideoFrame( cmd->encodeBuffer, aviLineLen * cmd->height ); } } return ( const void * )( cmd + 1 ); }