328 lines
8.1 KiB
C
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;
|
|
}
|