"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/fileformat/pfsinyuv.cpp" between
pfstools-2.1.0.tgz and pfstools-2.2.0.tgz

About: pfstools are a set of command line programs (and one GUI program) for reading, writing, manipulating, and viewing high-dynamic range (HDR) images and video frames (similar as the netpbm package does for low-dynamic range images).

pfsinyuv.cpp  (pfstools-2.1.0.tgz):pfsinyuv.cpp  (pfstools-2.2.0.tgz)
/** /**
az @brief Read RAW Yuv files, commonly used for video compression * @brief Read RAW Yuv files, commonly used for video compression
* *
* This file is a part of PFSTOOLS package. * This file is a part of PFSTOOLS package.
* ---------------------------------------------------------------------- * ----------------------------------------------------------------------
* Copyright (C) 2017 Rafal Mantiuk * Copyright (C) 2017 Rafal Mantiuk
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* ---------------------------------------------------------------------- * ----------------------------------------------------------------------
* *
* @author Rafal Mantiuk, <mantiuk@mpi-sb.mpg.de> * @author George Ash
* *
* $Id: pfsinrgbe.cpp,v 1.5 2014/06/17 21:57:08 rafm Exp $
*/ */
#include <config.h> #include <config.h>
#include <string.h> #include <string.h>
#include <cstdlib> #include <cstdlib>
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
#include <vector> #include <vector>
//#include <arpa/inet.h>
#include <cmath>
#include <getopt.h> #include <getopt.h>
#include <pfs.h> #include <pfs.h>
#include <pfsutils.cpp> #include <pfsutils.cpp>
#include <climits> #include <climits>
#define PROG_NAME "pfsinyuv" #define PROG_NAME "pfsinyuv"
char charsToRemove[7] = {'b', 'i', 't', 's', 'f', 'p', 's'}; char charsToRemove[7] = {'b', 'i', 't', 's', 'f', 'p', 's'};
//PL means a planar format per frame.
enum ChromaFormat {PL420, PL444, V210};
template<typename T> template<typename T>
inline T clamp( T val, T min, T max ) inline T clamp( T val, T min, T max )
{ {
if( val < min ) if( val < min )
return min; return min;
if( val > max ) if( val > max )
return max; return max;
return val; return val;
} }
skipping to change at line 81 skipping to change at line 85
for( int x = 0; x < width; x++ ) { for( int x = 0; x < width; x++ ) {
float v_float = (float)line_buf[x]*gain - offset; float v_float = (float)line_buf[x]*gain - offset;
(*dest)(x<<stride, y<<stride) = clamp( v_float, min, max ); (*dest)(x<<stride, y<<stride) = clamp( v_float, min, max );
} }
} }
delete [] line_buf; delete [] line_buf;
return true; return true;
} }
void upscale_420to444( pfs::Array2D *ch )
{
const int height = ch->getRows();
const int width = ch->getCols();
// For even rows
for( int y = 0; y < height; y += 2 ) {
float v_l = (*ch)(0,y);
float v_r;
int x;
for( x = 1; x < (width-1); x += 2 ) {
v_r = (*ch)(x+1,y);
// Interpolate between pixels on the left and right
(*ch)(x,y) = (v_l + v_r)/2.f;
v_l = v_r;
}
if( x < width )
(*ch)(x,y) = v_r;
}
// For odd rows
int y;
for( y = 1; y < (height-1); y += 2 ) {
for( int x = 0; x < width; x++ ) {
(*ch)(x,y) = ((*ch)(x,y-1) + (*ch)(x,y+1))/2.f;
}
}
// Last row
if( y < height ) {
for( int x = 0; x < width; x++ ) {
(*ch)(x,y) = (*ch)(x,y-1);
}
}
}
void upscale_422to444( pfs::Array2D *ch )
{
const int height = ch->getRows();
const int width = ch->getCols();
// For odd columns
for (int y = 0; y < height; y++){
for( int x = 1; x < width-1; x+=2 ) {
(*ch)(x,y) = ((*ch)(x-1,y) + (*ch)(x+1,y))/2.f;
}
}
}
void parse210Block(unsigned int word, pfs::Array2D *thirdPart, pfs::Array2D *sec
ondPart, pfs::Array2D *firstPart, unsigned int thirdPartX, unsigned int secondPa
rtx, unsigned int firstPartX, unsigned int y, bool ycy){ //last bool denotes the
ordering of luma and chroma within a word. not ycy -? cyc
const unsigned int bitmask = 0x03FF;
const float luma_offset = 16.f/219.f;
const float luma_gain = 1.f/( (float)(1<<(2))*219.f);
const float chroma_offset = 128.f/224.f;
const float chroma_gain = 1.f/( (float)(1<<(2))*224.f);
//now because of the somewhat arbitrary ordering, we don't know beforehand wha
t offset and gain to apply. I'm just trying to make this less messy, but there's
definitely a better way. TODO this.
float first_last_gain = ycy ? luma_gain : chroma_gain;
float first_last_offset = ycy ? luma_offset : chroma_offset;
float second_gain = ycy ? chroma_gain : luma_gain;
float second_offset = ycy ? chroma_offset : luma_offset;
(*thirdPart)(thirdPartX,y) = (float)((word&(bitmask<<20))>>20)*first_last_gain
- first_last_offset;
(*secondPart)(secondPartx,y) = (float)((word&(bitmask<<10))>>10)*second_gain -
second_offset;
(*firstPart)(firstPartX,y) = (float)(word&(bitmask))*first_last_gain - first_l
ast_offset;
}
bool read_v210_yuv( FILE *fh, int width, int height, pfs::Array2D *Ydest,pfs::Ar
ray2D *Cbdest, pfs::Array2D *Crdest){
assert(sizeof(unsigned int) == 4);
//2*width needed because width is needed to store luma, and width is also need
ed to store both chroma
unsigned int paddedLineWidth = (unsigned int) ceil(((float)width)/6.)*4; //in
32 bit words
unsigned int * line_buf = new unsigned int[paddedLineWidth];
for( int y = 0; y<height; y++){
size_t read = fread( line_buf, sizeof( unsigned int ), paddedLineWidth, fh )
;
if( y == 0 && read == 0 ) { // End of file reached
delete [] line_buf;
return false;
}
else if (read != paddedLineWidth){
delete [] line_buf;
throw pfs::Exception("Error when reading YUV file");
}
else{
//who came up with this insane format
//we read 4 words at a time :'(
//loop over image pixels, therefore actual data lies in 2* our iteration v
ariable
//+= 6 because we write to 6 pixels below
unsigned int bufIndex;
for (int x = 0; x<width; x+=6){
unsigned int word;
bufIndex = (x/6)*4;
//we store chroma in even cells, will interpolate later
//first block
word = line_buf[bufIndex];
parse210Block(word, Crdest, Ydest, Cbdest, x, x, x, y, false);
//second block
word = line_buf[bufIndex + 1];
parse210Block(word, Ydest, Cbdest, Ydest, x+2, x+2, x+1, y, true);
//third block
word = line_buf[bufIndex + 2];
parse210Block(word, Cbdest, Ydest, Crdest, x+4, x+3, x+2, y, false);
//forth block
word = line_buf[bufIndex + 3];
parse210Block(word, Ydest, Crdest, Ydest, x+5, x+4, x+4, y, true);
}
}
}
delete[] line_buf;
upscale_422to444(Cbdest);
upscale_422to444(Crdest);
return true;
}
void removeCharsFromString(std::string &str, char* charsToRemove ) { void removeCharsFromString(std::string &str, char* charsToRemove ) {
for ( unsigned int i = 0; i < strlen(charsToRemove); ++i ) { for ( unsigned int i = 0; i < strlen(charsToRemove); ++i ) {
str.erase( remove(str.begin(), str.end(), charsToRemove[i]), str.end() ) ; str.erase( remove(str.begin(), str.end(), charsToRemove[i]), str.end() ) ;
} }
} }
int parseIntField(std::string i){ int parseIntField(std::string i){
//parses an integer field. Removes pesky characters like the b in 10b or the p in 1080p //parses an integer field. Removes pesky characters like the b in 10b or the p in 1080p
removeCharsFromString(i, charsToRemove); removeCharsFromString(i, charsToRemove);
return std::atoi(i.data()); return std::atoi(i.data());
skipping to change at line 107 skipping to change at line 240
std::transform(s2.begin(), s2.end(), s2.begin(), ::tolower); std::transform(s2.begin(), s2.end(), s2.begin(), ::tolower);
return s1.find(s2) != std::string::npos || s1 == s2; return s1.find(s2) != std::string::npos || s1 == s2;
} }
//returns a vector of strings tokenized //returns a vector of strings tokenized
std::vector<std::string> split(std::string s, std::string delim){ std::vector<std::string> split(std::string s, std::string delim){
return std::vector<std::string>(); return std::vector<std::string>();
} }
bool parseFileName(const char * fileNameIn, int * width, int * height, int * bi tdepth, pfs::ColorSpace * colorspace, bool * upscale_420, int * fps){ bool parseFileName(const char * fileNameIn, int * width, int * height, int * bi tdepth, pfs::ColorSpace * colorspace, ChromaFormat * chromaFormat, int * fps){
try{ try{
/* Parses the filename, puts the result into fields pointed to by the argume nts /* Parses the filename, puts the result into fields pointed to by the argume nts
returns true if all went well, false if there's a malformed filename returns true if all went well, false if there's a malformed filename
string should be <prefix>_<width>x<height(p)>_<fps>_<bitdepth(b)>_<colorspa ce>_<chroma_format> string should be <prefix>_<width>x<height(p)>_<fps>_<bitdepth(b)>_<colorspa ce>_<chroma_format>
Regex would be nice*/ Regex would be nice*/
std::string fileName(fileNameIn); std::string fileName(fileNameIn);
const std::string delimiter = "_"; const std::string delimiter = "_";
size_t pos = 0; size_t pos = 0;
std::string token; std::string token;
std::vector<std::string> tokens; std::vector<std::string> tokens;
while ((pos = fileName.find(delimiter)) != std::string::npos) { while ((pos = fileName.find(delimiter)) != std::string::npos) {
token = fileName.substr(0, pos); token = fileName.substr(0, pos);
tokens.push_back(token); tokens.push_back(token);
fileName.erase(0, pos + delimiter.length()); fileName.erase(0, pos + delimiter.length());
} }
tokens.push_back(fileName); tokens.push_back(fileName);
for (std::vector<string>::iterator tok = tokens.begin() + 1; tok != tokens.e nd(); ++tok) { for (std::vector<std::string>::iterator tok = tokens.begin() + 1; tok != tok ens.end(); ++tok) {
if (contains(*tok, "x")){ if (contains(*tok, "x")){
sscanf(tok->c_str(), "%dx%d", width, height); sscanf(tok->c_str(), "%dx%d", width, height);
} }
else if(*tok == "10" || *tok == "8" || *tok == "12" || tok->at(tok->length () - 1) == 'b' || contains(*tok, "bit")){ //last character is a b else if(*tok == "10" || *tok == "8" || *tok == "12" || tok->at(tok->length () - 1) == 'b' || contains(*tok, "bit")){ //last character is a b
*bitdepth = parseIntField(*tok); *bitdepth = parseIntField(*tok);
} }
else if(*tok == "24" || *tok == "25" || *tok == "50" || *tok == "60" || co ntains(*tok, "fps")){ else if(*tok == "24" || *tok == "25" || *tok == "50" || *tok == "60" || co ntains(*tok, "fps")){
*fps = parseIntField(*tok); *fps = parseIntField(*tok);
} }
else if (contains(*tok, "pq") || (contains(*tok, "2020") && !contains(*tok , "hlg"))){ else if (contains(*tok, "pq") || (contains(*tok, "2020") && !contains(*tok , "hlg"))){
*colorspace = pfs::CS_PQYCbCr2020; *colorspace = pfs::CS_PQYCbCr2020;
} }
else if (contains(*tok, "bt") || contains(*tok, "709")){ else if (contains(*tok, "bt") || contains(*tok, "709")){
*colorspace = pfs::CS_YCbCr709; *colorspace = pfs::CS_YCbCr709;
} }
else if (contains(*tok, "hlg")){ else if (contains(*tok, "hlg")){
*colorspace = pfs::CS_HLGYCbCr2020; *colorspace = pfs::CS_HLGYCbCr2020;
} }
else if(contains(*tok, "444") || contains(*tok, "420")){ else if(contains(*tok, "444")) *chromaFormat = PL444;
*upscale_420 = contains(*tok, "420"); else if(contains(*tok, "420")) *chromaFormat = PL420;
} else if(contains(*tok, "V210")) *chromaFormat = V210;
} }
return true; return true;
} }
catch(...){ catch(...){
return false; return false;
} }
} }
void upscale_420to444( pfs::Array2D *ch )
{
const int height = ch->getRows();
const int width = ch->getCols();
// For even rows
for( int y = 0; y < height; y += 2 ) {
float v_l = (*ch)(0,y);
float v_r;
int x;
for( x = 1; x < (width-1); x += 2 ) {
v_r = (*ch)(x+1,y);
// Interpolate between pixels on the left and right
(*ch)(x,y) = (v_l + v_r)/2.f;
v_l = v_r;
}
if( x < width )
(*ch)(x,y) = v_r;
}
// For odd rows
int y;
for( y = 1; y < (height-1); y += 2 ) {
for( int x = 0; x < width; x++ ) {
(*ch)(x,y) = ((*ch)(x,y-1) + (*ch)(x,y+1))/2.f;
}
}
// Last row
if( y < height ) {
for( int x = 0; x < width; x++ ) {
(*ch)(x,y) = (*ch)(x,y-1);
}
}
}
class YUVReader class YUVReader
{ {
FILE *fh; FILE *fh;
int width, height; int width, height;
int bit_depth; int bit_depth;
bool subsampling_420; ChromaFormat chromaFormat;
unsigned long int fileSize; unsigned long int fileSize;
enum ColorSpace { REC709, REC2020 }; enum ColorSpace { REC709, REC2020 };
ColorSpace color_space; ColorSpace color_space;
public: public:
YUVReader( FILE *fh, int width, int height, int bit_depth, bool subsampling_42 0 ) : fh(fh), width( width ), height( height ), bit_depth( bit_depth ), subsampl ing_420( subsampling_420 ) YUVReader( FILE *fh, int width, int height, int bit_depth, ChromaFormat chroma Format) : fh(fh), width( width ), height( height ), bit_depth( bit_depth ), chro maFormat( chromaFormat )
{ {
//initialize filesize //initialize filesize
fseek(fh, 0L, SEEK_END); fseek(fh, 0L, SEEK_END);
fileSize = ftell(fh); fileSize = ftell(fh);
//go back from where we came //go back from where we came
fseek(fh, 0L, SEEK_SET); fseek(fh, 0L, SEEK_SET);
} }
int getWidth() const int getWidth() const
{ {
skipping to change at line 236 skipping to change at line 334
} }
/* /*
Advances a number of frames through the file without reading them */ Advances a number of frames through the file without reading them */
// bool advanceFrames(int frameNo){ // bool advanceFrames(int frameNo){
// int divisor = subsampling_420 ? 4 : 1; //this is the integer divisor of th e green and blue channels (they are 4 times smaller if 4:2:0 subsampling is enab led) // int divisor = subsampling_420 ? 4 : 1; //this is the integer divisor of th e green and blue channels (they are 4 times smaller if 4:2:0 subsampling is enab led)
// long int offset = frameNo * (/*Red:*/ width * height * sizeof(STORE_FORMAT ) + /*Green, Blue:*/ 2*width*height*sizeof(STORE_FORMAT)/divisor); // long int offset = frameNo * (/*Red:*/ width * height * sizeof(STORE_FORMAT ) + /*Green, Blue:*/ 2*width*height*sizeof(STORE_FORMAT)/divisor);
// return fseek(fh, offset, SEEK_CUR); // return fseek(fh, offset, SEEK_CUR);
// } // }
/* See to a given frame */ /* Seek to a given frame */
bool seekToFrame(int frameNo){ bool seekToFrame(int frameNo){
unsigned long int offset = getFileOffsetFromFrame(frameNo); unsigned long int offset = getFileOffsetFromFrame(frameNo);
if(offset > fileSize){ if(offset > fileSize){
throw pfs::Exception("Seeking past EOF, is your given frame range within t he range of the input?"); throw pfs::Exception("Seeking past EOF, is your given frame range within t he range of the input?");
} }
else{ else{
return fseek(fh, offset, SEEK_SET); return fseek(fh, offset, SEEK_SET);
} }
} }
//gets the position in the file of the specified frame
unsigned long int getFileOffsetFromFrame(int frameNo){ unsigned long int getFileOffsetFromFrame(int frameNo){
unsigned long int divisor = subsampling_420 ? 4 : 1; //this is the integer d if(chromaFormat == V210){
ivisor of the green and blue channels (they are 4 times smaller if 4:2:0 subsamp /*TODO This*/
ling is enabled) return (unsigned long int) ceil(((float) width)/6)*16*height*frameNo;
}
else{
unsigned long int divisor = chromaFormat == PL420 ? 4 : 1; //this is the i
nteger divisor of the green and blue channels (they are 4 times smaller if 4:2:0
subsampling is enabled)
if( frameNo <= 0 ) if( frameNo <= 0 )
throw pfs::Exception( "Invalid frame index. Frame are indexed from 1" ); throw pfs::Exception( "Invalid frame index. Frame are indexed from 1" );
unsigned long int storeFormatSize = bit_depth <= 8 ? sizeof(unsigned char) : unsigned long int storeFormatSize = bit_depth <= 8 ? sizeof(unsigned char)
sizeof(unsigned short); : sizeof(unsigned short);
unsigned long int offset = (frameNo-1) * (/*Luma:*/ width * height * storeFo unsigned long int offset = (frameNo-1) * (/*Luma:*/ width * height * store
rmatSize + /*CrCb:*/ 2*width*height*storeFormatSize/divisor); FormatSize + /*CrCb:*/ 2*width*height*storeFormatSize/divisor);
return offset; return offset;
}
} }
/** /**
* Read a single frame from Yuv video file and store in 3 RGB channels of type pfs::Array. * Read a single frame from Yuv video file and store in 3 RGB channels of type pfs::Array.
* Integer values are converted into floating point values. * Integer values are converted into floating point values.
* *
* @return TRUE if the frame has been loaded successfully, FALSE if end-of-fil e. * @return TRUE if the frame has been loaded successfully, FALSE if end-of-fil e.
* Exception is thrown if there is an issue reading a full frame. * Exception is thrown if there is an issue reading a full frame.
*/ */
bool readImage( pfs::Array2D *R, pfs::Array2D *G, pfs::Array2D *B ){ bool readImage( pfs::Array2D *R, pfs::Array2D *G, pfs::Array2D *B ){
if(bit_depth <= 8){ if(chromaFormat == V210){
return readImageTyped<unsigned char>(R, G, B); return read_v210_yuv(fh, width, height, R, G, B);
} }
else{ else{
return readImageTyped<unsigned short>(R, G, B); if(bit_depth <= 8){
return readImageTyped<unsigned char>(R, G, B);
}
else{
return readImageTyped<unsigned short>(R, G, B);
}
} }
} }
private: private:
template<typename T> template<typename T>
bool readImageTyped( pfs::Array2D *R, pfs::Array2D *G, pfs::Array2D *B) bool readImageTyped( pfs::Array2D *R, pfs::Array2D *G, pfs::Array2D *B)
{ {
{ // Read Y { // Read Y
const float offset = 16.f/219.f; const float offset = 16.f/219.f;
skipping to change at line 294 skipping to change at line 404
return false; return false;
} }
} }
{ // Read Cb, Cr { // Read Cb, Cr
const float offset = 128.f/224.f; const float offset = 128.f/224.f;
const float gain = 1.f/( (float)(1<<(bit_depth-8))*224.f); const float gain = 1.f/( (float)(1<<(bit_depth-8))*224.f);
unsigned int chroma_width = width; unsigned int chroma_width = width;
unsigned int chroma_height = height; unsigned int chroma_height = height;
unsigned int chroma_stride = 0; unsigned int chroma_stride = 0;
if (subsampling_420){ if (chromaFormat == PL420){
chroma_width = width/2; chroma_width = width/2;
chroma_height = height/2; chroma_height = height/2;
chroma_stride = 1; chroma_stride = 1;
} }
if( !read_yuv_channel<T>( fh, chroma_width, chroma_height, chroma_stride , G, gain, offset, -0.5f, 0.5f ) ) if( !read_yuv_channel<T>( fh, chroma_width, chroma_height, chroma_stride , G, gain, offset, -0.5f, 0.5f ) )
throw pfs::Exception( "EOF reached when reading the Cb portion of a fram e" ); throw pfs::Exception( "EOF reached when reading the Cb portion of a fram e" );
if( !read_yuv_channel<T>( fh, chroma_width, chroma_height, chroma_stride , B, gain, offset, -0.5f, 0.5f ) ) if( !read_yuv_channel<T>( fh, chroma_width, chroma_height, chroma_stride , B, gain, offset, -0.5f, 0.5f ) )
throw pfs::Exception( "EOF reached when reading the Cr portion of a fram e" ); throw pfs::Exception( "EOF reached when reading the Cr portion of a fram e" );
if(subsampling_420){ if(chromaFormat == PL420){
upscale_420to444( B ); upscale_420to444( B );
upscale_420to444( G ); upscale_420to444( G );
} }
} }
return true; return true;
} }
}; };
class QuietException class QuietException
{ {
skipping to change at line 432 skipping to change at line 542
FILE * fh; FILE * fh;
if(filename != NULL){ if(filename != NULL){
fh = fopen (filename, "rb"); fh = fopen (filename, "rb");
} }
if( fh == NULL ) { if( fh == NULL ) {
throw pfs::Exception("Couldn't find a filename to open, did you provide one" ); throw pfs::Exception("Couldn't find a filename to open, did you provide one" );
}; // No more frames }; // No more frames
int width = -1, height = -1, bitdepth = -1, frame_min = 1, frame_max = INT_MAX , frame_stride = 1, fps = -1; int width = -1, height = -1, bitdepth = -1, frame_min = 1, frame_max = INT_MAX , frame_stride = 1, fps = -1;
bool upscale_420 = true; ChromaFormat chromaFormat = PL444;
pfs::ColorSpace colorspace = pfs::CS_INVALID; pfs::ColorSpace colorspace = pfs::CS_INVALID;
VERBOSE_STR << "reading file '" << filename << "'" << std::endl; VERBOSE_STR << "reading file '" << filename << "'" << std::endl;
//we infer the metadata from the filename unless noguess is specified //we infer the metadata from the filename unless noguess is specified
if(!opt_noguess){ if(!opt_noguess){
std::string rawName(filename); //these three lines extract the filename prop er, without the containing directory prefix std::string rawName(filename); //these three lines extract the filename prop er, without the containing directory prefix
long unsigned int substring = rawName.find_last_of("\\/"); long unsigned int substring = rawName.find_last_of("\\/");
rawName = rawName.substr(substring == std::string::npos ? 0 : substring); rawName = rawName.substr(substring == std::string::npos ? 0 : substring);
bool goodFileName = parseFileName(rawName.c_str(), &width, &height, &bitdept h, &colorspace, &upscale_420, &fps); bool goodFileName = parseFileName(rawName.c_str(), &width, &height, &bitdept h, &colorspace, &chromaFormat, &fps);
if(!goodFileName){ if(!goodFileName){
VERBOSE_STR << "Unable to parse filename: " << filename << "\n"; VERBOSE_STR << "Unable to parse filename: " << filename << "\n";
} }
} }
// Over-ride the auto-recognized params with the ones specified as arguments // Over-ride the auto-recognized params with the ones specified as arguments
if( opt_width > -1 ) if( opt_width > -1 )
width = opt_width; width = opt_width;
if( opt_height > -1 ) if( opt_height > -1 )
height = opt_height; height = opt_height;
if( opt_bitdepth > -1 ) if( opt_bitdepth > -1 )
bitdepth = opt_bitdepth; bitdepth = opt_bitdepth;
if( opt_frame_min > -1 ) if( opt_frame_min > -1 )
frame_min = opt_frame_min; frame_min = opt_frame_min;
if( opt_frame_max > -1 ) if( opt_frame_max > -1 )
frame_max = opt_frame_max; frame_max = opt_frame_max;
if( opt_frame_stride != 0) if( opt_frame_stride != 0)
frame_stride = opt_frame_stride; frame_stride = opt_frame_stride;
if( opt_colorspace != pfs::CS_INVALID ) if( opt_colorspace != pfs::CS_INVALID )
colorspace = opt_colorspace; colorspace = opt_colorspace;
if( opt_chroma_subsampling != NULL ){ if( opt_chroma_subsampling != NULL ){
// bad reading, essentially just force upscaling if they input the subsampli //set up our chromat supsampling, defaults to planar 444
ng as 420 chromaFormat =
upscale_420 = strcmp(opt_chroma_subsampling, "420") == 0; strcmp(opt_chroma_subsampling, "420") == 0 ? PL420 :
strcmp(opt_chroma_subsampling, "V210") == 0 ? V210 :
PL444;
} }
if( opt_fps > 0 ){ if( opt_fps > 0 ){
fps = opt_fps; fps = opt_fps;
} }
VERBOSE_STR << "Yuv file " << width << "x" << height << " " << bitdepth << "bi ts" << std::endl; VERBOSE_STR << "Yuv file " << width << "x" << height << " " << bitdepth << "bi ts" << std::endl;
switch( colorspace ) { switch( colorspace ) {
case pfs::CS_PQYCbCr2020: case pfs::CS_PQYCbCr2020:
VERBOSE_STR << "colorspace: HDR PQ BT2020" << std::endl; VERBOSE_STR << "colorspace: HDR PQ BT2020" << std::endl;
break; break;
skipping to change at line 498 skipping to change at line 612
if( frame_min < 0 || frame_max < 0){ if( frame_min < 0 || frame_max < 0){
throw pfs::Exception( "Frame range is invalid "); throw pfs::Exception( "Frame range is invalid ");
} }
if( colorspace == pfs::CS_INVALID ){ if( colorspace == pfs::CS_INVALID ){
throw pfs::Exception( "Unspecified colorspace of the Yuv file" ); throw pfs::Exception( "Unspecified colorspace of the Yuv file" );
} }
if( fps > 0 ){ if( fps > 0 ){
VERBOSE_STR << "FPS: " << fps << std::endl; VERBOSE_STR << "FPS: " << fps << std::endl;
} }
YUVReader reader( fh, width, height, bitdepth, upscale_420); YUVReader reader( fh, width, height, bitdepth, chromaFormat);
int currentFrame = frame_min; int currentFrame = frame_min;
while( (currentFrame <= frame_max && frame_stride > 0) while( (currentFrame <= frame_max && frame_stride > 0)
|| (currentFrame >= frame_max && frame_stride < 0) ) { //inclusive || (currentFrame >= frame_max && frame_stride < 0) ) { //inclusive
pfs::Frame *frame = pfsio.createFrame( reader.getWidth(), pfs::Frame *frame = pfsio.createFrame( reader.getWidth(),
reader.getHeight() ); reader.getHeight() );
pfs::Channel *X, *Y, *Z; pfs::Channel *X, *Y, *Z;
frame->createXYZChannels( X, Y, Z ); frame->createXYZChannels( X, Y, Z );
 End of changes. 26 change blocks. 
67 lines changed or deleted 193 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)