winamp/Src/h264dec/lcommon/src/img_io.c
2024-09-24 14:54:57 +02:00

328 lines
8.1 KiB
C

/*!
*************************************************************************************
* \file img_io.c
*
* \brief
* image I/O related functions
*
* \author
* Main contributors (see contributors.h for copyright, address and affiliation details)
* - Alexis Michael Tourapis <alexismt@ieee.org>
*************************************************************************************
*/
#include "contributors.h"
#include "global.h"
#include "img_io.h"
#include "report.h"
static const VIDEO_SIZE VideoRes[] = {
{ "qcif" , 176, 144},
{ "qqvga" , 160, 128},
{ "qvga" , 320, 240},
{ "sif" , 352, 240},
{ "cif" , 352, 288},
{ "vga" , 640, 480},
{ "sd1" , 720, 480},
{ "sd2" , 704, 576},
{ "sd3" , 720, 576},
{ "720p" , 1280, 720},
{ "1080p" , 1920, 1080},
{ NULL, 0, 0}
};
/*!
************************************************************************
* \brief
* Parse Size from from file name
*
************************************************************************
*/
int ParseSizeFromString (VideoDataFile *input_file, int *x_size, int *y_size, double *fps)
{
char *p1, *p2, *tail;
char *fn = input_file->fname;
char c;
int i = 0;
*x_size = *y_size = -1;
p1 = p2 = fn;
while (p1 != NULL && p2 != NULL)
{
// Search for first '_'
p1 = strstr( p1, "_");
if (p1 == NULL)
break;
// Search for end character of x_size (first 'x' after last '_')
p2 = strstr( p1, "x");
// If no 'x' is found, exit
if (p2 == NULL)
break;
// Try conversion of number
*p2 = 0;
*x_size = strtol( p1 + 1, &tail, 10);
// If there are characters left in the string, or the string is null, discard conversion
if (*tail != '\0' || *(p1 + 1) == '\0')
{
*p2 = 'x';
p1 = tail;
continue;
}
// Conversion was correct. Restore string
*p2 = 'x';
// Search for end character of y_size (first '_' or '.' after last 'x')
p1 = strpbrk( p2 + 1, "_.");
// If no '_' or '.' is found, try again from current position
if (p1 == NULL)
{
p1 = p2 + 1;
continue;
}
// Try conversion of number
c = *p1;
*p1 = 0;
*y_size = strtol( p2 + 1, &tail, 10);
// If there are characters left in the string, or the string is null, discard conversion
if (*tail != '\0' || *(p2 + 1) == '\0')
{
*p1 = c;
p1 = tail;
continue;
}
// Conversion was correct. Restore string
*p1 = c;
// Search for end character of y_size (first 'i' or 'p' after last '_')
p2 = strstr( p1 + 1, "ip");
// If no 'i' or 'p' is found, exit
if (p2 == NULL)
break;
// Try conversion of number
c = *p2;
*p2 = 0;
*fps = strtod( p1 + 1, &tail);
// If there are characters left in the string, or the string is null, discard conversion
if (*tail != '\0' || *(p1 + 1) == '\0')
{
*p2 = c;
p1 = tail;
continue;
}
// Conversion was correct. Restore string
*p2 = c;
break;
}
// Now lets test some common video file formats
if (p1 == NULL || p2 == NULL)
{
for (i = 0; VideoRes[i].name != NULL; i++)
{
if (strcasecmp (fn, VideoRes[i].name))
{
*x_size = VideoRes[i].x_size;
*y_size = VideoRes[i].y_size;
// Should add frame rate support as well
break;
}
}
}
return (*x_size == -1 || *y_size == -1) ? 0 : 1;
}
/*!
************************************************************************
* \brief
* Parse Size from from file name
*
************************************************************************
*/
void ParseFrameNoFormatFromString (VideoDataFile *input_file)
{
char *p1, *p2, *tail;
char *fn = input_file->fname;
char *fhead = input_file->fhead;
char *ftail = input_file->ftail;
int *zero_pad = &input_file->zero_pad;
int *num_digits = &input_file->num_digits;
*zero_pad = 0;
*num_digits = -1;
p1 = p2 = fn;
while (p1 != NULL && p2 != NULL)
{
// Search for first '_'
p1 = strstr( p1, "%");
if (p1 == NULL)
break;
strncpy(fhead, fn, p1 - fn);
// Search for end character of x_size (first 'x' after last '_')
p2 = strstr( p1, "d");
// If no 'x' is found, exit
if (p2 == NULL)
break;
// Try conversion of number
*p2 = 0;
if (*(p1 + 1) == '0')
*zero_pad = 1;
*num_digits = strtol( p1 + 1, &tail, 10);
// If there are characters left in the string, or the string is null, discard conversion
if (*tail != '\0' || *(p1 + 1) == '\0')
{
*p2 = 'd';
p1 = tail;
continue;
}
// Conversion was correct. Restore string
*p2 = 'd';
tail++;
strncpy(ftail, tail, strlen(tail));
break;
}
if (input_file->vdtype == VIDEO_TIFF)
{
input_file->is_concatenated = 0;
}
else
input_file->is_concatenated = (*num_digits == -1) ? 1 : 0;
}
/*!
************************************************************************
* \brief
* Open file containing a single frame
************************************************************************
*/
void OpenFrameFile( VideoDataFile *input_file, int FrameNumberInFile)
{
char infile [FILE_NAME_SIZE], in_number[16];
int length = 0;
in_number[length]='\0';
length = strlen(input_file->fhead);
strncpy(infile, input_file->fhead, length);
infile[length]='\0';
if (input_file->zero_pad)
snprintf(in_number, 16, "%0*d", input_file->num_digits, FrameNumberInFile);
else
snprintf(in_number, 16, "%*d", input_file->num_digits, FrameNumberInFile);
strncat(infile, in_number, sizeof(in_number));
length += sizeof(in_number);
infile[length]='\0';
strncat(infile, input_file->ftail, strlen(input_file->ftail));
length += strlen(input_file->ftail);
infile[length]='\0';
if ((input_file->f_num = open(infile, OPENFLAGS_READ)) == -1)
{
printf ("OpenFrameFile: cannot open file %s\n", infile);
report_stats_on_error();
}
}
/*!
************************************************************************
* \brief
* Open file(s) containing the entire frame sequence
************************************************************************
*/
void OpenFiles( VideoDataFile *input_file)
{
if (input_file->is_concatenated == 1)
{
if (strlen(input_file->fname) == 0)
{
snprintf(errortext, ET_SIZE, "No input sequence name was provided. Please check settings.");
error (errortext, 500);
}
if ((input_file->f_num = open(input_file->fname, OPENFLAGS_READ)) == -1)
{
snprintf(errortext, ET_SIZE, "Input file %s does not exist",input_file->fname);
error (errortext, 500);
}
}
}
/*!
************************************************************************
* \brief
* Close input file
************************************************************************
*/
void CloseFiles(VideoDataFile *input_file)
{
if (input_file->f_num != -1)
close(input_file->f_num);
input_file->f_num = -1;
}
/* ==========================================================================
*
* ParseVideoType
*
* ==========================================================================
*/
VideoFileType ParseVideoType (VideoDataFile *input_file)
{
char *format;
format = input_file->fname + strlen(input_file->fname) - 3;
if (strcasecmp (format, "yuv") == 0)
{
input_file->vdtype = VIDEO_YUV;
input_file->format.yuv_format = YUV420;
input_file->avi = NULL;
}
else if (strcasecmp (format, "rgb") == 0)
{
input_file->vdtype = VIDEO_RGB;
input_file->format.yuv_format = YUV444;
input_file->avi = NULL;
}
else if (strcasecmp (format, "tif") == 0)
{
input_file->vdtype = VIDEO_TIFF;
input_file->avi = NULL;
}
else if (strcasecmp (format, "avi") == 0)
{
input_file->vdtype = VIDEO_AVI;
}
else
{
//snprintf(errortext, ET_SIZE, "ERROR: video file format not supported");
//error (errortext, 500);
input_file->vdtype = VIDEO_YUV;
input_file->format.yuv_format = YUV420;
input_file->avi = NULL;
}
return input_file->vdtype;
}