📄 decodeiff.c
字号:
/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2001, International Telecommunications Union, Geneva
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the user without any
* license fee or royalty on an "as is" basis. The ITU disclaims
* any and all warranties, whether express, implied, or
* statutory, including any implied warranties of merchantability
* or of fitness for a particular purpose. In no event shall the
* contributor or the ITU be liable for any incidental, punitive, or
* consequential damages of any kind whatsoever arising from the
* use of these programs.
*
* This disclaimer of warranty extends to the user of these programs
* and user's customers, employees, agents, transferees, successors,
* and assigns.
*
* The ITU does not represent or warrant that the programs furnished
* hereunder are free of infringement of any third-party patents.
* Commercial implementations of ITU-T Recommendations, including
* shareware, may be subject to royalty fees to patent holders.
* Information regarding the ITU-T patent policy is available from
* the ITU Web site at http://www.itu.int.
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE ITU-T PATENT POLICY.
************************************************************************
*/
/*!
************************************************************************
* \file
* decodeiff.c
* \brief
* Impelentation of the interim file format
* as defined in Appendix III of WD-1 (JVT-A003).
*
* Instructions for a new release of the Joint Model:
* 1. Remember to update WORKING_DRAFT_MAJOR_NO and WORKING_DRAFT_MINOR_NO
* in defines.h appropriately
* 2. Remember to modify the encoder as well
*
* Instructions for modifications to the interim file format:
* 1. Update INTERIM_FILE_MAJOR_NO and INTERIM_FILE_MINOR_NO
* in defines.h appropriately. It is up to the implementor
* to decide, which modification deserves an update in the major
* version number.
*
* The box header only permits compact size (32 bits mode)
* data partition is not supported.
* The source code supports multiple segments per file, but
* the feature has not been tested.
*
* \author
* - Dong Tian <tian@cs.tut.fi>
* - Miska M. Hannuksela <miska.hannuksela@nokia.com>
************************************************************************
*/
/*!
************************************************************************
* \flowchart
* main()
* {
* init
* IFFSequenceHeader(); // Read the first Boxes, and set the initial parameter set
* // according to the input file
* if ( inp->of_mode == PAR_OF_IFF )
* while ( parse_one_box() != -1 );
* else
* while (decode_one_frame() != EOS);
* }
*
* parse_one_box()
* {
* call different funcitons according to the box type
* switch( box type )
* {
* ......
* case segment:
* parse_one_segment
* {
* while ( decode_one_frame() );
* }
* break;
* ......
* }
* }
************************************************************************
*/
#include <stdio.h>
#include <assert.h>
#include <memory.h>
#include <malloc.h>
#include "global.h"
#include "decodeiff.h"
FileTypeBox box_ft;
FileHeaderBox box_fh;
ContentInfoBox box_ci;
AlternateTrackInfoBox box_ati;
ParameterSetBox box_ps;
SegmentBox box_s;
AlternateTrackHeaderBox box_ath;
PayloadInfo currPayloadInfo;
PictureInfo currPictureInfo;
AlternateTrackMediaBox box_atm;
SwitchPictureBox box_sp;
extern int CurrentParameterSet=-1; // Tian Dong: must not be set to 0 here.
static int BeginOfPictureOrSlice; // SOP or SOS
int IFFEndOfFile = FALSE;
int ThisAlternateTrack = 0; // indicate which track in the file will be decoded.
/*!
************************************************************************
* \brief
* Test the file if it is in Interim File Format by reading FileTypeBox
* \return
* 0, if it is in Interim File Format
* -1, otherwise
* \param fp
* input file pointer
************************************************************************
*/
int testFileTypeBox(FILE* fp)
{
int left;
int size, x;
assert( fp != NULL );
box_ft.compatibleBrands = NULL;
x = readfile( &box_ft.type.size, 4, 1, fp );
if ( -1 == x ) return -1;
x = readfile( &box_ft.type.type, 4, 1, fp );
if ( -1 == x ) return -1;
size = box_ft.type.size;
if ( box_ft.type.type != BOX_FTYP ) return -1;
if ( box_ft.type.size > 0 )
{
x = readfile( box_ft.majorBrand, 4, 1, fp );
if ( -1 == x ) return -1;
x = readfile( &box_ft.jmMajorVersion, 2, 1, fp );
if ( -1 == x ) return -1;
x = readfile( &box_ft.jmMinorVersion, 2, 1, fp );
if ( -1 == x ) return -1;
if ( box_ft.jmMajorVersion != WORKING_DRAFT_MAJOR_NO ||
box_ft.jmMinorVersion != WORKING_DRAFT_MINOR_NO)
{
printf( "Error: The working draft version is not supported.\n" );
return -1;
}
left = (int)size - SIZEOF_BOXTYPE - 8;
box_ft.compatibleBrands = calloc( 1, left );
box_ft.numCompatibleBrands = left / 4;
x = fread( box_ft.compatibleBrands, 1, left, fp );
if ( left != x ) return -1;
}
return 0;
}
/*!
************************************************************************
* \brief
* Free the memory allocated for File Type Box
* \return
* None
************************************************************************
*/
void freeFileTypeBox()
{
if ( box_ft.compatibleBrands != NULL )
free( box_ft.compatibleBrands );
}
/*!
************************************************************************
* \brief
* Read the File Header Box
* \return
* 0, if success
* -1, otherwise
* \param fp
* input file pointer
* \param size
* size of the box
************************************************************************
*/
int rdFileHeaderBox( FILE* fp, size_t size )
{
byte cd;
int x;
assert( fp != NULL );
x = readfile(&box_fh.majorVersion, 1, 1, fp);
if ( -1 == x ) return -1;
x = readfile(&box_fh.minorVersion, 1, 1, fp);
if ( -1 == x ) return -1;
if (
box_fh.majorVersion != INTERIM_FILE_MAJOR_NO ||
box_fh.minorVersion != INTERIM_FILE_MINOR_NO )
{
printf( "Error: The interim file format version is not supported.\n" );
return -1;
}
x = readfile(&box_fh.timescale, 4, 1, fp);
if ( -1 == x ) return -1;
x = readfile(&box_fh.numUnitsInTick, 4, 1, fp);
if ( -1 == x ) return -1;
x = readfile(&box_fh.duration, 8, 1, fp);
if ( -1 == x ) return -1;
x = readfile(&box_fh.pixAspectRatioX, 2, 1, fp);
if ( -1 == x ) return -1;
x = readfile(&box_fh.pixAspectRatioY, 2, 1, fp);
if ( -1 == x ) return -1;
x = readfile(&box_fh.maxPicId, 2, 1, fp);
if ( -1 == x ) return -1;
x = readfile(&box_fh.numAlternateTracks, 1, 1, fp);
if ( -1 == x ) return -1;
x = readfile(&cd, 1, 1, fp);
if ( -1 == x ) return -1;
box_fh.numBytesInPayloadCountMinusOne = (cd >> 6);
box_fh.numBytesInPictureOffsetMinusTwo = ((cd & 0x3F) >> 4);
box_fh.numBytesInPictureDisplayTimeMinusOne = ((cd & 0x0f) >> 2);
box_fh.numBytesInPictureCountMinusOne = (cd & 0x03);
x = readfile(&cd, 1, 1, fp);
if ( -1 == x ) return -1;
box_fh.numBytesInPayloadSizeMinusOne = (cd >> 6);
return 0;
}
/*!
************************************************************************
* \brief
* Free the memory allocated for File Header Box
* Do nothing
* \return
* None
************************************************************************
*/
void freeFileHeaderBox()
{
}
/*!
************************************************************************
* \brief
* Tian Dong, Feb 10, 2002:
* Just move the file pointer forward to skip the content info box
* \return
* 0, if success
* -1, otherwise
* \param fp
* input file pointer
* \param size
* size of the box
************************************************************************
*/
int rdContentInfoBox( FILE* fp, size_t size )
{
// do nothing
if ( 0 != fseek( fp, size - SIZEOF_BOXTYPE, SEEK_CUR ) ) return -1;
return 0;
}
/*!
************************************************************************
* \brief
* Free the memory allocated for Content Info Box
* Do nothing
* \return
* None
************************************************************************
*/
void freeContentInfoBox()
{
}
/*!
************************************************************************
* \brief
* Read the Alterate Track Info Box
* Tian Dong, Feb 10, 2002:
* Only one track in the input file
* \return
* 0, if success
* -1, otherwise
* \param fp
* input file pointer
* \param size
* size of the box
************************************************************************
*/
int rdAlternateTrackInfoBox( FILE* fp, unsigned long size )
{
assert( fp != NULL );
assert( box_fh.numAlternateTracks == 1 );
box_ati.info = NULL;
box_ati.info = calloc( box_fh.numAlternateTracks, sizeof(AlternateTrackInfo) );
if ( box_ati.info == NULL ) return -1;
if ( -1 == readfile( &box_ati.info[0].displayWindowWidth, 2, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ati.info[0].displayWindowHeight, 2, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ati.info[0].maxSDUSize, 2, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ati.info[0].avgSDUSize, 2, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ati.info[0].avgBitRate, 4, 1, fp ) ) return -1;
return 0;
}
/*!
************************************************************************
* \brief
* Free the memory allocated for Alternate Track Info Box
* \return
* None
************************************************************************
*/
void freeAlternateTrackInfoBox()
{
if ( box_ati.info != NULL )
free(box_ati.info);
}
/*!
************************************************************************
* \brief
* Read the ParameterSet Box
* Tian Dong, Feb 10, 2002:
* Only one Parameter Set Box in the input file
* \return
* 0, if success
* -1, otherwise
* \param fp
* input file pointer
* \param size
* size of the box
************************************************************************
*/
int rdParameterSetBox( FILE* fp, unsigned long size )
{
assert( fp );
if ( -1 == readfile( &box_ps.parameterSetID, 2, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ps.profile, 1, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ps.level, 1, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ps.version, 1, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ps.pictureWidthInMBs, 2, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ps.pictureHeightInMBs, 2, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ps.displayRectangleOffsetTop, 2, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ps.displayRectangleOffsetLeft, 2, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ps.displayRectangleOffsetBottom, 2, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ps.displayRectangleOffsetRight, 2, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ps.displayMode, 1, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ps.displayRectangleOffsetFromWindowTop, 2, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ps.displayRectangleOffsetFromWindowLeftBorder, 2, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ps.entropyCoding, 1, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ps.motionResolution, 1, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ps.partitioningType, 1, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ps.intraPredictionType, 1, 1, fp ) ) return -1;
if ( -1 == readfile( &box_ps.bufCycle, 1, 1, fp ) ) return -1;
return 0;
}
/*!
************************************************************************
* \brief
* From the current position, find the parameter set which id is given.
* The file pointer must point to the beginning of a box.
* \return
* 0, if success
* -1, otherwise
* \param fp
* input file pointer
* \param pos
* used to store the parameter set box's position
* \param pid
* give the id of the wanted parameter set
************************************************************************
*/
int findParameterSetBox( FILE* fp, long *pos, int pid )
{
int id, size, type;
assert( fp );
while( !feof( fp ) )
{
if ( readfile( &size, 4, 1, fp ) == -1 ) return -1;
if ( readfile( &type, 4, 1, fp ) == -1 ) return -1;
if ( type == BOX_PRMS )
{
if ( readfile( &id, 4, 1, fp ) == -1 ) return -1;
if ( id == pid )
{
*pos = ftell( fp ) - 4;
return 0; // succeed
}
if ( 0 != fseek( fp, size-12, SEEK_CUR ) ) return -1;
}
else
{
if ( 0 != fseek( fp, size-8, SEEK_CUR ) ) return -1;
}
}
return -1;
}
/*!
************************************************************************
* \brief
* Do nothing
* \return
* None
************************************************************************
*/
void freeParameterSetBox()
{
}
/*!
************************************************************************
* \brief
* parse one segment
* Tian Dong, Feb 10, 2002:
* Only one Parameter Set Box in the input file
* \return
* 0, if success
* -1, otherwise
* \param img
* image pointer
* \param inp
* input parameter pointer
* \param snr
* snr pointer
* \param fp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -