Changeset 916 in SHVCSoftware for branches/SHM-upgrade/source/Lib/TLibVideoIO


Ignore:
Timestamp:
12 Nov 2014, 08:09:17 (10 years ago)
Author:
seregin
Message:

initial porting

Location:
branches/SHM-upgrade/source/Lib/TLibVideoIO
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/SHM-upgrade/source/Lib/TLibVideoIO/TVideoIOYuv.cpp

    r823 r916  
    22 * License, included below. This software may be subject to other third party
    33 * and contributor rights, including patent rights, and no such rights are
    4  * granted under this license. 
     4 * granted under this license.
    55 *
    66 * Copyright (c) 2010-2014, ITU/ISO/IEC
     
    4242#include <fstream>
    4343#include <iostream>
     44#include <memory.h>
    4445
    4546#include "TLibCommon/TComRom.h"
     
    4849using namespace std;
    4950
    50 /**
    51  * Perform division with rounding of all pixels in img by
    52  * 2<sup>shiftbits</sup>. All pixels are clipped to [minval, maxval]
    53  *
    54  * @param img        pointer to image to be transformed
    55  * @param stride     distance between vertically adjacent pixels of img.
    56  * @param width      width of active area in img.
    57  * @param height     height of active area in img.
    58  * @param shiftbits  number of rounding bits
    59  * @param minval     minimum clipping value
    60  * @param maxval     maximum clipping value
    61  */
    62 static void invScalePlane(Pel* img, UInt stride, UInt width, UInt height,
    63                        UInt shiftbits, Pel minval, Pel maxval)
    64 {
    65   Pel offset = 1 << (shiftbits-1);
    66   for (UInt y = 0; y < height; y++)
    67   {
    68     for (UInt x = 0; x < width; x++)
    69     {
    70       Pel val = (img[x] + offset) >> shiftbits;
    71       img[x] = Clip3(minval, maxval, val);
    72     }
    73     img += stride;
    74   }
    75 }
    76 
    77 /**
    78  * Multiply all pixels in img by 2<sup>shiftbits</sup>.
    79  *
    80  * @param img        pointer to image to be transformed
    81  * @param stride     distance between vertically adjacent pixels of img.
    82  * @param width      width of active area in img.
    83  * @param height     height of active area in img.
    84  * @param shiftbits  number of bits to shift
    85  */
    86 static void scalePlane(Pel* img, UInt stride, UInt width, UInt height,
    87                        UInt shiftbits)
    88 {
    89   for (UInt y = 0; y < height; y++)
    90   {
    91     for (UInt x = 0; x < width; x++)
    92     {
    93       img[x] <<= shiftbits;
    94     }
    95     img += stride;
    96   }
    97 }
     51// ====================================================================================================================
     52// Local Functions
     53// ====================================================================================================================
    9854
    9955/**
     
    11268 * @param maxval  maximum clipping value when dividing.
    11369 */
    114 static void scalePlane(Pel* img, UInt stride, UInt width, UInt height,
    115                        Int shiftbits, Pel minval, Pel maxval)
    116 {
    117   if (shiftbits == 0)
    118   {
    119     return;
    120   }
    121 
     70static Void scalePlane(Pel* img, const UInt stride, const UInt width, const UInt height, Int shiftbits, Pel minval, Pel maxval)
     71{
    12272  if (shiftbits > 0)
    12373  {
    124     scalePlane(img, stride, width, height, shiftbits);
    125   }
    126   else
    127   {
    128     invScalePlane(img, stride, width, height, -shiftbits, minval, maxval);
     74    for (UInt y = 0; y < height; y++, img+=stride)
     75      for (UInt x = 0; x < width; x++)
     76        img[x] <<= shiftbits;
     77  }
     78  else if (shiftbits < 0)
     79  {
     80    shiftbits=-shiftbits;
     81
     82    Pel rounding = 1 << (shiftbits-1);
     83    for (UInt y = 0; y < height; y++, img+=stride)
     84      for (UInt x = 0; x < width; x++)
     85        img[x] = Clip3(minval, maxval, Pel((img[x] + rounding) >> shiftbits));
    12986  }
    13087}
     
    147104 * \param pchFile          file name string
    148105 * \param bWriteMode       file open mode: true=read, false=write
    149  * \param fileBitDepthY     bit-depth of input/output file data (luma component).
    150  * \param fileBitDepthC     bit-depth of input/output file data (chroma components).
    151  * \param internalBitDepthY bit-depth to scale image data to/from when reading/writing (luma component).
    152  * \param internalBitDepthC bit-depth to scale image data to/from when reading/writing (chroma components).
     106 * \param fileBitDepth     bit-depth array of input/output file data.
     107 * \param internalBitDepth bit-depth array to scale image data to/from when reading/writing.
    153108 */
    154 Void TVideoIOYuv::open( Char* pchFile, Bool bWriteMode, Int fileBitDepthY, Int fileBitDepthC, Int internalBitDepthY, Int internalBitDepthC)
    155 {
    156   m_bitDepthShiftY = internalBitDepthY - fileBitDepthY;
    157   m_bitDepthShiftC = internalBitDepthC - fileBitDepthC;
    158   m_fileBitDepthY = fileBitDepthY;
    159   m_fileBitDepthC = fileBitDepthC;
     109Void TVideoIOYuv::open( Char* pchFile, Bool bWriteMode, const Int fileBitDepth[MAX_NUM_CHANNEL_TYPE], const Int MSBExtendedBitDepth[MAX_NUM_CHANNEL_TYPE], const Int internalBitDepth[MAX_NUM_CHANNEL_TYPE] )
     110{
     111  //NOTE: files cannot have bit depth greater than 16
     112  for(UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++)
     113  {
     114    m_fileBitdepth       [ch] = std::min<UInt>(fileBitDepth[ch], 16);
     115    m_MSBExtendedBitDepth[ch] = MSBExtendedBitDepth[ch];
     116    m_bitdepthShift      [ch] = internalBitDepth[ch] - m_MSBExtendedBitDepth[ch];
     117
     118    if (m_fileBitdepth[ch] > 16)
     119    {
     120      if (bWriteMode)
     121      {
     122        std::cerr << "\nWARNING: Cannot write a yuv file of bit depth greater than 16 - output will be right-shifted down to 16-bit precision\n" << std::endl;
     123      }
     124      else
     125      {
     126        std::cerr << "\nERROR: Cannot read a yuv file of bit depth greater than 16\n" << std::endl;
     127        exit(0);
     128      }
     129    }
     130  }
    160131
    161132  if ( bWriteMode )
    162133  {
    163134    m_cHandle.open( pchFile, ios::binary | ios::out );
    164    
     135
    165136    if( m_cHandle.fail() )
    166137    {
     
    172143  {
    173144    m_cHandle.open( pchFile, ios::binary | ios::in );
    174    
     145
    175146    if( m_cHandle.fail() )
    176147    {
     
    179150    }
    180151  }
    181  
     152
    182153  return;
    183154}
     
    204175 * seekable, by consuming bytes.
    205176 */
    206 void TVideoIOYuv::skipFrames(UInt numFrames, UInt width, UInt height)
     177Void TVideoIOYuv::skipFrames(UInt numFrames, UInt width, UInt height, ChromaFormat format)
    207178{
    208179  if (!numFrames)
    209180    return;
    210181
    211   const UInt wordsize = (m_fileBitDepthY > 8 || m_fileBitDepthC > 8) ? 2 : 1;
    212   const streamoff framesize = wordsize * width * height * 3 / 2;
    213   const streamoff offset = framesize * numFrames;
     182  //------------------
     183  //set the frame size according to the chroma format
     184  streamoff frameSize = 0;
     185  UInt wordsize=1; // default to 8-bit, unless a channel with more than 8-bits is detected.
     186  for (UInt component = 0; component < getNumberValidComponents(format); component++)
     187  {
     188    ComponentID compID=ComponentID(component);
     189    frameSize += (width >> getComponentScaleX(compID, format)) * (height >> getComponentScaleY(compID, format));
     190    if (m_fileBitdepth[toChannelType(compID)] > 8) wordsize=2;
     191  }
     192  frameSize *= wordsize;
     193  //------------------
     194
     195  const streamoff offset = frameSize * numFrames;
    214196
    215197  /* attempt to seek */
     
    243225 * @return true for success, false in case of error
    244226 */
    245 static Bool readPlane(Pel* dst, istream& fd, Bool is16bit,
    246                       UInt stride,
    247                       UInt width, UInt height,
    248                       UInt pad_x, UInt pad_y)
    249 {
    250   Int read_len = width * (is16bit ? 2 : 1);
    251   UChar *buf = new UChar[read_len];
    252   for (Int y = 0; y < height; y++)
    253   {
    254     fd.read(reinterpret_cast<Char*>(buf), read_len);
    255     if (fd.eof() || fd.fail() )
    256     {
    257       delete[] buf;
    258       return false;
    259     }
    260 
    261     if (!is16bit)
    262     {
    263       for (Int x = 0; x < width; x++)
    264       {
    265         dst[x] = buf[x];
    266       }
    267     }
    268     else
    269     {
    270       for (Int x = 0; x < width; x++)
    271       {
    272         dst[x] = (buf[2*x+1] << 8) | buf[2*x];
    273       }
    274     }
    275 
    276     for (Int x = width; x < width + pad_x; x++)
    277     {
    278       dst[x] = dst[width - 1];
    279     }
    280     dst += stride;
    281   }
    282   for (Int y = height; y < height + pad_y; y++)
    283   {
    284     for (Int x = 0; x < width + pad_x; x++)
    285     {
    286       dst[x] = (dst - stride)[x];
    287     }
    288     dst += stride;
     227static Bool readPlane(Pel* dst,
     228                      istream& fd,
     229                      Bool is16bit,
     230                      UInt stride444,
     231                      UInt width444,
     232                      UInt height444,
     233                      UInt pad_x444,
     234                      UInt pad_y444,
     235                      const ComponentID compID,
     236                      const ChromaFormat destFormat,
     237                      const ChromaFormat fileFormat,
     238                      const UInt fileBitDepth)
     239{
     240  const UInt csx_file =getComponentScaleX(compID, fileFormat);
     241  const UInt csy_file =getComponentScaleY(compID, fileFormat);
     242  const UInt csx_dest =getComponentScaleX(compID, destFormat);
     243  const UInt csy_dest =getComponentScaleY(compID, destFormat);
     244
     245  const UInt width_dest       = width444 >>csx_dest;
     246  const UInt height_dest      = height444>>csy_dest;
     247  const UInt pad_x_dest       = pad_x444>>csx_dest;
     248  const UInt pad_y_dest       = pad_y444>>csy_dest;
     249  const UInt stride_dest      = stride444>>csx_dest;
     250
     251  const UInt full_width_dest  = width_dest+pad_x_dest;
     252  const UInt full_height_dest = height_dest+pad_y_dest;
     253
     254  const UInt stride_file      = (width444 * (is16bit ? 2 : 1)) >> csx_file;
     255
     256  UChar  *buf   = new UChar[stride_file];
     257
     258  if (compID!=COMPONENT_Y && (fileFormat==CHROMA_400 || destFormat==CHROMA_400))
     259  {
     260    if (destFormat!=CHROMA_400)
     261    {
     262      // set chrominance data to mid-range: (1<<(fileBitDepth-1))
     263      const Pel value=Pel(1<<(fileBitDepth-1));
     264      for (UInt y = 0; y < full_height_dest; y++, dst+=stride_dest)
     265        for (UInt x = 0; x < full_width_dest; x++)
     266          dst[x] = value;
     267    }
     268
     269    if (fileFormat!=CHROMA_400)
     270    {
     271      const UInt height_file      = height444>>csy_file;
     272      fd.seekg(height_file*stride_file, ios::cur);
     273      if (fd.eof() || fd.fail() )
     274      {
     275        delete[] buf;
     276        return false;
     277      }
     278    }
     279  }
     280  else
     281  {
     282    const UInt mask_y_file=(1<<csy_file)-1;
     283    const UInt mask_y_dest=(1<<csy_dest)-1;
     284    for(UInt y444=0; y444<height444; y444++)
     285    {
     286      if ((y444&mask_y_file)==0)
     287      {
     288        // read a new line
     289        fd.read(reinterpret_cast<Char*>(buf), stride_file);
     290        if (fd.eof() || fd.fail() )
     291        {
     292          delete[] buf;
     293          return false;
     294        }
     295      }
     296
     297      if ((y444&mask_y_dest)==0)
     298      {
     299        // process current destination line
     300        if (csx_file < csx_dest)
     301        {
     302          // eg file is 444, dest is 422.
     303          const UInt sx=csx_dest-csx_file;
     304          if (!is16bit)
     305          {
     306            for (UInt x = 0; x < width_dest; x++)
     307              dst[x] = buf[x<<sx];
     308          }
     309          else
     310          {
     311            for (UInt x = 0; x < width_dest; x++)
     312            {
     313              dst[x] = Pel(buf[(x<<sx)*2+0]) | (Pel(buf[(x<<sx)*2+1])<<8);
     314            }
     315          }
     316        }
     317        else
     318        {
     319          // eg file is 422, dest is 444.
     320          const UInt sx=csx_file-csx_dest;
     321          if (!is16bit)
     322          {
     323            for (UInt x = 0; x < width_dest; x++)
     324              dst[x] = buf[x>>sx];
     325          }
     326          else
     327          {
     328            for (UInt x = 0; x < width_dest; x++)
     329              dst[x] = Pel(buf[(x>>sx)*2+0]) | (Pel(buf[(x>>sx)*2+1])<<8);
     330          }
     331        }
     332
     333        // process right hand side padding
     334        const Pel val=dst[width_dest-1];
     335        for (UInt x = width_dest; x < full_width_dest; x++)
     336          dst[x] = val;
     337
     338        dst += stride_dest;
     339      }
     340    }
     341
     342    // process lower padding
     343    for (UInt y = height_dest; y < full_height_dest; y++, dst+=stride_dest)
     344      for (UInt x = 0; x < full_width_dest; x++)
     345        dst[x] = (dst - stride_dest)[x];
    289346  }
    290347  delete[] buf;
     
    304361 */
    305362static Bool writePlane(ostream& fd, Pel* src, Bool is16bit,
    306                        UInt stride,
    307                        UInt width, UInt height)
    308 {
    309   Int write_len = width * (is16bit ? 2 : 1);
    310   UChar *buf = new UChar[write_len];
    311   for (Int y = 0; y < height; y++)
    312   {
    313     if (!is16bit)
    314     {
    315       for (Int x = 0; x < width; x++)
    316       {
    317         buf[x] = (UChar) src[x];
    318       }
    319     }
    320     else
    321     {
    322       for (Int x = 0; x < width; x++)
    323       {
    324         buf[2*x] = src[x] & 0xff;
    325         buf[2*x+1] = (src[x] >> 8) & 0xff;
    326       }
    327     }
    328 
    329     fd.write(reinterpret_cast<Char*>(buf), write_len);
    330     if (fd.eof() || fd.fail() )
    331     {
    332       delete[] buf;
    333       return false;
    334     }
    335     src += stride;
     363                       UInt stride444,
     364                       UInt width444, UInt height444,
     365                       const ComponentID compID,
     366                       const ChromaFormat srcFormat,
     367                       const ChromaFormat fileFormat,
     368                       const UInt fileBitDepth)
     369{
     370  const UInt csx_file =getComponentScaleX(compID, fileFormat);
     371  const UInt csy_file =getComponentScaleY(compID, fileFormat);
     372  const UInt csx_src  =getComponentScaleX(compID, srcFormat);
     373  const UInt csy_src  =getComponentScaleY(compID, srcFormat);
     374
     375  const UInt stride_src      = stride444>>csx_src;
     376
     377  const UInt stride_file      = (width444 * (is16bit ? 2 : 1)) >> csx_file;
     378  const UInt width_file       = width444 >>csx_file;
     379  const UInt height_file      = height444>>csy_file;
     380
     381  UChar  *buf   = new UChar[stride_file];
     382
     383  if (compID!=COMPONENT_Y && (fileFormat==CHROMA_400 || srcFormat==CHROMA_400))
     384  {
     385    if (fileFormat!=CHROMA_400)
     386    {
     387      const UInt value=1<<(fileBitDepth-1);
     388
     389      for(UInt y=0; y< height_file; y++)
     390      {
     391        if (!is16bit)
     392        {
     393          UChar val(value);
     394          for (UInt x = 0; x < width_file; x++)
     395            buf[x]=val;
     396        }
     397        else
     398        {
     399          UShort val(value);
     400          for (UInt x = 0; x < width_file; x++)
     401          {
     402            buf[2*x+0]= (val>>0) & 0xff;
     403            buf[2*x+1]= (val>>8) & 0xff;
     404          }
     405        }
     406
     407        fd.write(reinterpret_cast<Char*>(buf), stride_file);
     408        if (fd.eof() || fd.fail() )
     409        {
     410          delete[] buf;
     411          return false;
     412        }
     413      }
     414    }
     415  }
     416  else
     417  {
     418    const UInt mask_y_file=(1<<csy_file)-1;
     419    const UInt mask_y_src =(1<<csy_src )-1;
     420    for(UInt y444=0; y444<height444; y444++)
     421    {
     422      if ((y444&mask_y_file)==0)
     423      {
     424        // write a new line
     425        if (csx_file < csx_src)
     426        {
     427          // eg file is 444, source is 422.
     428          const UInt sx=csx_src-csx_file;
     429          if (!is16bit)
     430          {
     431            for (UInt x = 0; x < width_file; x++)
     432            {
     433              buf[x] = (UChar)(src[x>>sx]);
     434            }
     435          }
     436          else
     437          {
     438            for (UInt x = 0; x < width_file; x++)
     439            {
     440              buf[2*x  ] = (src[x>>sx]>>0) & 0xff;
     441              buf[2*x+1] = (src[x>>sx]>>8) & 0xff;
     442            }
     443          }
     444        }
     445        else
     446        {
     447          // eg file is 422, src is 444.
     448          const UInt sx=csx_file-csx_src;
     449          if (!is16bit)
     450          {
     451            for (UInt x = 0; x < width_file; x++)
     452            {
     453              buf[x] = (UChar)(src[x<<sx]);
     454            }
     455          }
     456          else
     457          {
     458            for (UInt x = 0; x < width_file; x++)
     459            {
     460              buf[2*x  ] = (src[x<<sx]>>0) & 0xff;
     461              buf[2*x+1] = (src[x<<sx]>>8) & 0xff;
     462            }
     463          }
     464        }
     465
     466        fd.write(reinterpret_cast<Char*>(buf), stride_file);
     467        if (fd.eof() || fd.fail() )
     468        {
     469          delete[] buf;
     470          return false;
     471        }
     472      }
     473
     474      if ((y444&mask_y_src)==0)
     475      {
     476        src += stride_src;
     477      }
     478
     479    }
    336480  }
    337481  delete[] buf;
     
    340484
    341485static Bool writeField(ostream& fd, Pel* top, Pel* bottom, Bool is16bit,
    342                        UInt stride,
    343                        UInt width, UInt height, bool isTff)
    344 {
    345   Int write_len = width * (is16bit ? 2 : 1)*2;
    346   UChar *buf = new UChar[write_len];
    347   for (Int y = 0; y < height; y++)
    348   {
    349     if (!is16bit)
    350     {
    351       for (Int x = 0; x < width; x++)
    352       {
    353         buf[x] = isTff ? (UChar) top[x] : (UChar) bottom[x];
    354         buf[width+x] = isTff ? (UChar) bottom[x] : (UChar) top[x];
    355       }
    356     }
    357     else
    358     {
    359       for (Int x = 0; x < width; x++)
    360       {
    361         buf[2*x] = isTff ? top[x] & 0xff : bottom[x] & 0xff;
    362         buf[2*x+1] = isTff ? (top[x] >> 8) & 0xff : (bottom[x] >> 8) & 0xff;
    363        
    364         buf[width+2*x] = isTff ? bottom[x] & 0xff : top[x] & 0xff;
    365         buf[width+2*x+1] = isTff ? (bottom[x] >> 8) & 0xff : (top[x] >> 8) & 0xff;
    366       }
    367     }
    368    
    369     fd.write(reinterpret_cast<Char*>(buf), write_len);
    370     if (fd.eof() || fd.fail() )
    371     {
    372       delete[] buf;
    373       return false;
    374     }
    375     top += stride;
    376     bottom += stride;
     486                       UInt stride444,
     487                       UInt width444, UInt height444,
     488                       const ComponentID compID,
     489                       const ChromaFormat srcFormat,
     490                       const ChromaFormat fileFormat,
     491                       const UInt fileBitDepth, const Bool isTff)
     492{
     493  const UInt csx_file =getComponentScaleX(compID, fileFormat);
     494  const UInt csy_file =getComponentScaleY(compID, fileFormat);
     495  const UInt csx_src  =getComponentScaleX(compID, srcFormat);
     496  const UInt csy_src  =getComponentScaleY(compID, srcFormat);
     497
     498  const UInt stride_src      = stride444>>csx_src;
     499
     500  const UInt stride_file      = (width444 * (is16bit ? 2 : 1)) >> csx_file;
     501  const UInt width_file       = width444 >>csx_file;
     502  const UInt height_file      = height444>>csy_file;
     503
     504  UChar  *buf   = new UChar[stride_file * 2];
     505
     506  if (compID!=COMPONENT_Y && (fileFormat==CHROMA_400 || srcFormat==CHROMA_400))
     507  {
     508    if (fileFormat!=CHROMA_400)
     509    {
     510      const UInt value=1<<(fileBitDepth-1);
     511
     512      for(UInt y=0; y< height_file; y++)
     513      {
     514        for (UInt field = 0; field < 2; field++)
     515        {
     516          UChar *fieldBuffer = buf + (field * stride_file);
     517
     518          if (!is16bit)
     519          {
     520            UChar val(value);
     521            for (UInt x = 0; x < width_file; x++)
     522              fieldBuffer[x]=val;
     523          }
     524          else
     525          {
     526            UShort val(value);
     527            for (UInt x = 0; x < width_file; x++)
     528            {
     529              fieldBuffer[2*x+0]= (val>>0) & 0xff;
     530              fieldBuffer[2*x+1]= (val>>8) & 0xff;
     531            }
     532          }
     533        }
     534
     535        fd.write(reinterpret_cast<Char*>(buf), (stride_file * 2));
     536        if (fd.eof() || fd.fail() )
     537        {
     538          delete[] buf;
     539          return false;
     540        }
     541      }
     542    }
     543  }
     544  else
     545  {
     546    const UInt mask_y_file=(1<<csy_file)-1;
     547    const UInt mask_y_src =(1<<csy_src )-1;
     548    for(UInt y444=0; y444<height444; y444++)
     549    {
     550      if ((y444&mask_y_file)==0)
     551      {
     552        for (UInt field = 0; field < 2; field++)
     553        {
     554          UChar *fieldBuffer = buf + (field * stride_file);
     555          Pel   *src         = (((field == 0) && isTff) || ((field == 1) && (!isTff))) ? top : bottom;
     556
     557          // write a new line
     558          if (csx_file < csx_src)
     559          {
     560            // eg file is 444, source is 422.
     561            const UInt sx=csx_src-csx_file;
     562            if (!is16bit)
     563            {
     564              for (UInt x = 0; x < width_file; x++)
     565              {
     566                fieldBuffer[x] = (UChar)(src[x>>sx]);
     567              }
     568            }
     569            else
     570            {
     571              for (UInt x = 0; x < width_file; x++)
     572              {
     573                fieldBuffer[2*x  ] = (src[x>>sx]>>0) & 0xff;
     574                fieldBuffer[2*x+1] = (src[x>>sx]>>8) & 0xff;
     575              }
     576            }
     577          }
     578          else
     579          {
     580            // eg file is 422, src is 444.
     581            const UInt sx=csx_file-csx_src;
     582            if (!is16bit)
     583            {
     584              for (UInt x = 0; x < width_file; x++)
     585              {
     586                fieldBuffer[x] = (UChar)(src[x<<sx]);
     587              }
     588            }
     589            else
     590            {
     591              for (UInt x = 0; x < width_file; x++)
     592              {
     593                fieldBuffer[2*x  ] = (src[x<<sx]>>0) & 0xff;
     594                fieldBuffer[2*x+1] = (src[x<<sx]>>8) & 0xff;
     595              }
     596            }
     597          }
     598        }
     599
     600        fd.write(reinterpret_cast<Char*>(buf), (stride_file * 2));
     601        if (fd.eof() || fd.fail() )
     602        {
     603          delete[] buf;
     604          return false;
     605        }
     606      }
     607
     608      if ((y444&mask_y_src)==0)
     609      {
     610        top    += stride_src;
     611        bottom += stride_src;
     612      }
     613
     614    }
    377615  }
    378616  delete[] buf;
    379617  return true;
    380618}
     619
    381620/**
    382621 * Read one Y'CbCr frame, performing any required input scaling to change
     
    392631 * @return true for success, false in case of error
    393632 */
    394 Bool TVideoIOYuv::read ( TComPicYuv*  pPicYuv, Int aiPad[2] )
     633Bool TVideoIOYuv::read ( TComPicYuv*  pPicYuvUser, TComPicYuv* pPicYuvTrueOrg, const InputColourSpaceConversion ipcsc, Int aiPad[2], ChromaFormat format )
    395634{
    396635  // check end-of-file
    397636  if ( isEof() ) return false;
    398  
    399   Int   iStride = pPicYuv->getStride();
    400  
     637  TComPicYuv *pPicYuv=pPicYuvTrueOrg;
     638  if (format>=NUM_CHROMA_FORMAT) format=pPicYuv->getChromaFormat();
     639
     640  Bool is16bit = false;
     641
     642  for(UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++)
     643  {
     644    if (m_fileBitdepth[ch] > 8) is16bit=true;
     645  }
     646
     647  const UInt stride444      = pPicYuv->getStride(COMPONENT_Y);
     648
    401649  // compute actual YUV width & height excluding padding size
    402   UInt pad_h = aiPad[0];
    403   UInt pad_v = aiPad[1];
    404   UInt width_full = pPicYuv->getWidth();
    405   UInt height_full = pPicYuv->getHeight();
    406   UInt width  = width_full - pad_h;
    407   UInt height = height_full - pad_v;
    408   Bool is16bit = m_fileBitDepthY > 8 || m_fileBitDepthC > 8;
    409 
    410   Int desired_bitdepthY = m_fileBitDepthY + m_bitDepthShiftY;
    411   Int desired_bitdepthC = m_fileBitDepthC + m_bitDepthShiftC;
    412   Pel minvalY = 0;
    413   Pel minvalC = 0;
    414   Pel maxvalY = (1 << desired_bitdepthY) - 1;
    415   Pel maxvalC = (1 << desired_bitdepthC) - 1;
    416 #if CLIP_TO_709_RANGE
    417   if (m_bitdepthShiftY < 0 && desired_bitdepthY >= 8)
    418   {
    419     /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */
    420     minvalY = 1 << (desired_bitdepthY - 8);
    421     maxvalY = (0xff << (desired_bitdepthY - 8)) -1;
    422   }
    423   if (m_bitdepthShiftC < 0 && desired_bitdepthC >= 8)
    424   {
    425     /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */
    426     minvalC = 1 << (desired_bitdepthC - 8);
    427     maxvalC = (0xff << (desired_bitdepthC - 8)) -1;
    428   }
     650  const UInt pad_h444       = aiPad[0];
     651  const UInt pad_v444       = aiPad[1];
     652
     653  const UInt width_full444  = pPicYuv->getWidth(COMPONENT_Y);
     654  const UInt height_full444 = pPicYuv->getHeight(COMPONENT_Y);
     655
     656  const UInt width444       = width_full444 - pad_h444;
     657  const UInt height444      = height_full444 - pad_v444;
     658
     659  for(UInt comp=0; comp<MAX_NUM_COMPONENT; comp++)
     660  {
     661    const ComponentID compID = ComponentID(comp);
     662    const ChannelType chType=toChannelType(compID);
     663
     664    const Int desired_bitdepth = m_MSBExtendedBitDepth[chType] + m_bitdepthShift[chType];
     665
     666#if !CLIP_TO_709_RANGE
     667    const Pel minval = 0;
     668    const Pel maxval = (1 << desired_bitdepth) - 1;
     669#else
     670    const Bool b709Compliance=(m_bitdepthShift[chType] < 0 && desired_bitdepth >= 8);     /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */
     671    const Pel minval = b709Compliance? ((   1 << (desired_bitdepth - 8))   ) : 0;
     672    const Pel maxval = b709Compliance? ((0xff << (desired_bitdepth - 8)) -1) : (1 << desired_bitdepth) - 1;
    429673#endif
    430  
    431   if (! readPlane(pPicYuv->getLumaAddr(), m_cHandle, is16bit, iStride, width, height, pad_h, pad_v))
    432     return false;
    433   scalePlane(pPicYuv->getLumaAddr(), iStride, width_full, height_full, m_bitDepthShiftY, minvalY, maxvalY);
    434 
    435   iStride >>= 1;
    436   width_full >>= 1;
    437   height_full >>= 1;
    438   width >>= 1;
    439   height >>= 1;
    440   pad_h >>= 1;
    441   pad_v >>= 1;
    442 
    443   if (! readPlane(pPicYuv->getCbAddr(), m_cHandle, is16bit, iStride, width, height, pad_h, pad_v))
    444     return false;
    445   scalePlane(pPicYuv->getCbAddr(), iStride, width_full, height_full, m_bitDepthShiftC, minvalC, maxvalC);
    446 
    447   if (! readPlane(pPicYuv->getCrAddr(), m_cHandle, is16bit, iStride, width, height, pad_h, pad_v))
    448     return false;
    449   scalePlane(pPicYuv->getCrAddr(), iStride, width_full, height_full, m_bitDepthShiftC, minvalC, maxvalC);
     674
     675    if (! readPlane(pPicYuv->getAddr(compID), m_cHandle, is16bit, stride444, width444, height444, pad_h444, pad_v444, compID, pPicYuv->getChromaFormat(), format, m_fileBitdepth[chType]))
     676    {
     677      return false;
     678    }
     679
     680    if (compID < pPicYuv->getNumberValidComponents() )
     681    {
     682      const UInt csx=getComponentScaleX(compID, pPicYuv->getChromaFormat());
     683      const UInt csy=getComponentScaleY(compID, pPicYuv->getChromaFormat());
     684      scalePlane(pPicYuv->getAddr(compID), stride444>>csx, width_full444>>csx, height_full444>>csy, m_bitdepthShift[chType], minval, maxval);
     685    }
     686  }
     687
     688  Int internalBitDepth[MAX_NUM_CHANNEL_TYPE];
     689  for(UInt chType=0; chType<MAX_NUM_CHANNEL_TYPE; chType++)
     690  {
     691    internalBitDepth[chType] = m_bitdepthShift[chType] + m_MSBExtendedBitDepth[chType];
     692  }
     693  ColourSpaceConvert(*pPicYuvTrueOrg, *pPicYuvUser, ipcsc, internalBitDepth, true);
    450694
    451695  return true;
     
    460704 * @return true for success, false in case of error
    461705 */
    462 Bool TVideoIOYuv::write( TComPicYuv* pPicYuv, Int confLeft, Int confRight, Int confTop, Int confBottom )
    463 {
     706Bool TVideoIOYuv::write( TComPicYuv* pPicYuvUser, const InputColourSpaceConversion ipCSC, Int confLeft, Int confRight, Int confTop, Int confBottom, ChromaFormat format )
     707{
     708  TComPicYuv cPicYuvCSCd;
     709  if (ipCSC!=IPCOLOURSPACE_UNCHANGED)
     710  {
     711    cPicYuvCSCd.create(pPicYuvUser->getWidth(COMPONENT_Y), pPicYuvUser->getHeight(COMPONENT_Y), pPicYuvUser->getChromaFormat(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth);
     712    Int internalBitDepth[MAX_NUM_CHANNEL_TYPE];
     713    for(UInt chType=0; chType<MAX_NUM_CHANNEL_TYPE; chType++)
     714    {
     715      internalBitDepth[chType] = m_bitdepthShift[chType] + m_MSBExtendedBitDepth[chType];
     716    }
     717    ColourSpaceConvert(*pPicYuvUser, cPicYuvCSCd, ipCSC, internalBitDepth, false);
     718  }
     719  TComPicYuv *pPicYuv=(ipCSC==IPCOLOURSPACE_UNCHANGED) ? pPicYuvUser : &cPicYuvCSCd;
     720
    464721  // compute actual YUV frame size excluding padding size
    465   Int   iStride = pPicYuv->getStride();
    466   UInt  width  = pPicYuv->getWidth()  - confLeft - confRight;
    467   UInt  height = pPicYuv->getHeight() - confTop  - confBottom;
    468   Bool is16bit = m_fileBitDepthY > 8 || m_fileBitDepthC > 8;
     722  const Int   iStride444 = pPicYuv->getStride(COMPONENT_Y);
     723  const UInt width444  = pPicYuv->getWidth(COMPONENT_Y) - confLeft - confRight;
     724  const UInt height444 = pPicYuv->getHeight(COMPONENT_Y) -  confTop  - confBottom;
     725  Bool is16bit = false;
     726  Bool nonZeroBitDepthShift=false;
     727
     728  if ((width444 == 0) || (height444 == 0))
     729  {
     730    printf ("\nWarning: writing %d x %d luma sample output picture!", width444, height444);
     731  }
     732
     733  for(UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++)
     734  {
     735    if (m_fileBitdepth[ch] > 8) is16bit=true;
     736    if (m_bitdepthShift[ch] != 0) nonZeroBitDepthShift=true;
     737  }
     738
    469739  TComPicYuv *dstPicYuv = NULL;
    470740  Bool retval = true;
    471 
    472   if ((width==0)||(height==0))
    473   {
    474     printf ("\nWarning: writing %d x %d luma sample output picture!", width, height);
    475   }
    476 
    477   if (m_bitDepthShiftY != 0 || m_bitDepthShiftC != 0)
     741  if (format>=NUM_CHROMA_FORMAT) format=pPicYuv->getChromaFormat();
     742
     743  if (nonZeroBitDepthShift)
    478744  {
    479745    dstPicYuv = new TComPicYuv;
    480 #if AUXILIARY_PICTURES
    481     dstPicYuv->create( pPicYuv->getWidth(), pPicYuv->getHeight(), pPicYuv->getChromaFormat(), 1, 1, 0 );
     746    dstPicYuv->create( pPicYuv->getWidth(COMPONENT_Y), pPicYuv->getHeight(COMPONENT_Y), pPicYuv->getChromaFormat(), 1, 1, 0 );
     747    pPicYuv->copyToPic(dstPicYuv);
     748
     749    for(UInt comp=0; comp<dstPicYuv->getNumberValidComponents(); comp++)
     750    {
     751      const ComponentID compID=ComponentID(comp);
     752      const ChannelType ch=toChannelType(compID);
     753#if !CLIP_TO_709_RANGE
     754      const Pel minval = 0;
     755      const Pel maxval = (1 << m_MSBExtendedBitDepth[ch]) - 1;
    482756#else
    483     dstPicYuv->create( pPicYuv->getWidth(), pPicYuv->getHeight(), 1, 1, 0 );
     757      const Bool b709Compliance=(-m_bitdepthShift[ch] < 0 && m_MSBExtendedBitDepth[ch] >= 8);     /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */
     758      const Pel minval = b709Compliance? ((   1 << (m_MSBExtendedBitDepth[ch] - 8))   ) : 0;
     759      const Pel maxval = b709Compliance? ((0xff << (m_MSBExtendedBitDepth[ch] - 8)) -1) : (1 << m_MSBExtendedBitDepth[ch]) - 1;
    484760#endif
    485     pPicYuv->copyToPic(dstPicYuv);
    486 
    487     Pel minvalY = 0;
    488     Pel minvalC = 0;
    489     Pel maxvalY = (1 << m_fileBitDepthY) - 1;
    490     Pel maxvalC = (1 << m_fileBitDepthC) - 1;
    491 #if CLIP_TO_709_RANGE
    492     if (-m_bitDepthShiftY < 0 && m_fileBitDepthY >= 8)
    493     {
    494       /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */
    495       minvalY = 1 << (m_fileBitDepthY - 8);
    496       maxvalY = (0xff << (m_fileBitDepthY - 8)) -1;
    497     }
    498     if (-m_bitDepthShiftC < 0 && m_fileBitDepthC >= 8)
    499     {
    500       /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */
    501       minvalC = 1 << (m_fileBitDepthC - 8);
    502       maxvalC = (0xff << (m_fileBitDepthC - 8)) -1;
    503     }
    504 #endif
    505     scalePlane(dstPicYuv->getLumaAddr(), dstPicYuv->getStride(), dstPicYuv->getWidth(), dstPicYuv->getHeight(), -m_bitDepthShiftY, minvalY, maxvalY);
    506     scalePlane(dstPicYuv->getCbAddr(), dstPicYuv->getCStride(), dstPicYuv->getWidth()>>1, dstPicYuv->getHeight()>>1, -m_bitDepthShiftC, minvalC, maxvalC);
    507     scalePlane(dstPicYuv->getCrAddr(), dstPicYuv->getCStride(), dstPicYuv->getWidth()>>1, dstPicYuv->getHeight()>>1, -m_bitDepthShiftC, minvalC, maxvalC);
     761
     762      scalePlane(dstPicYuv->getAddr(compID), dstPicYuv->getStride(compID), dstPicYuv->getWidth(compID), dstPicYuv->getHeight(compID), -m_bitdepthShift[ch], minval, maxval);
     763    }
    508764  }
    509765  else
     
    511767    dstPicYuv = pPicYuv;
    512768  }
    513   // location of upper left pel in a plane
    514   Int planeOffset = confLeft + confTop * iStride;
    515  
    516   if (! writePlane(m_cHandle, dstPicYuv->getLumaAddr() + planeOffset, is16bit, iStride, width, height))
    517   {
    518     retval=false;
    519     goto exit;
    520   }
    521 
    522   width >>= 1;
    523   height >>= 1;
    524   iStride >>= 1;
    525   confLeft >>= 1;
    526   confRight >>= 1;
    527   confTop >>= 1;
    528   confBottom >>= 1;
    529 
    530   planeOffset = confLeft + confTop * iStride;
    531 
    532   if (! writePlane(m_cHandle, dstPicYuv->getCbAddr() + planeOffset, is16bit, iStride, width, height))
    533   {
    534     retval=false;
    535     goto exit;
    536   }
    537   if (! writePlane(m_cHandle, dstPicYuv->getCrAddr() + planeOffset, is16bit, iStride, width, height))
    538   {
    539     retval=false;
    540     goto exit;
    541   }
    542  
    543 exit:
    544   if (m_bitDepthShiftY != 0 || m_bitDepthShiftC != 0)
     769
     770  for(UInt comp=0; retval && comp<dstPicYuv->getNumberValidComponents(); comp++)
     771  {
     772    const ComponentID compID = ComponentID(comp);
     773    const ChannelType ch=toChannelType(compID);
     774    const UInt csx = pPicYuv->getComponentScaleX(compID);
     775    const UInt csy = pPicYuv->getComponentScaleY(compID);
     776    const Int planeOffset =  (confLeft>>csx) + (confTop>>csy) * pPicYuv->getStride(compID);
     777    if (! writePlane(m_cHandle, dstPicYuv->getAddr(compID) + planeOffset, is16bit, iStride444, width444, height444, compID, dstPicYuv->getChromaFormat(), format, m_fileBitdepth[ch]))
     778    {
     779      retval=false;
     780    }
     781  }
     782
     783  if (nonZeroBitDepthShift)
    545784  {
    546785    dstPicYuv->destroy();
    547786    delete dstPicYuv;
    548   } 
     787  }
     788
     789  cPicYuvCSCd.destroy();
     790
    549791  return retval;
    550792}
    551793
    552 
    553 /**
    554  * Write one Y'CbCr frame. No bit-depth conversion is performed, pcPicYuv is
    555  * assumed to be at TVideoIO::m_fileBitdepth depth.
    556  *
    557  * @param pPicTop     input top field YUV buffer class pointer
    558  * @param pPicBottom  input bottom field YUV buffer class pointer
    559  * @param aiPad       source padding size, aiPad[0] = horizontal, aiPad[1] = vertical
    560  * @return true for success, false in case of error
    561  */
    562 Bool TVideoIOYuv::write( TComPicYuv* pPicTop, TComPicYuv* pPicBottom, Int cropLeft, Int cropRight, Int cropTop, Int cropBottom , bool isTff)
    563 {
    564   // compute actual YUV frame size excluding padding size
    565   Int   iStride = pPicTop->getStride();
    566   UInt  width  = pPicTop->getWidth()  - cropLeft - cropRight;
    567   UInt  height = pPicTop->getHeight() - cropTop  - cropBottom;
    568   Bool is16bit = m_fileBitDepthY > 8 || m_fileBitDepthC > 8;
    569  
    570   TComPicYuv *dstPicTop = NULL;
    571   TComPicYuv *dstPicBottom = NULL;
    572  
     794Bool TVideoIOYuv::write( TComPicYuv* pPicYuvUserTop, TComPicYuv* pPicYuvUserBottom, const InputColourSpaceConversion ipCSC, Int confLeft, Int confRight, Int confTop, Int confBottom, ChromaFormat format, const Bool isTff )
     795{
     796
     797  TComPicYuv cPicYuvTopCSCd;
     798  TComPicYuv cPicYuvBottomCSCd;
     799  if (ipCSC!=IPCOLOURSPACE_UNCHANGED)
     800  {
     801    cPicYuvTopCSCd   .create(pPicYuvUserTop   ->getWidth(COMPONENT_Y), pPicYuvUserTop   ->getHeight(COMPONENT_Y), pPicYuvUserTop   ->getChromaFormat(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth);
     802    cPicYuvBottomCSCd.create(pPicYuvUserBottom->getWidth(COMPONENT_Y), pPicYuvUserBottom->getHeight(COMPONENT_Y), pPicYuvUserBottom->getChromaFormat(), g_uiMaxCUWidth, g_uiMaxCUHeight, g_uiMaxCUDepth);
     803    Int internalBitDepth[MAX_NUM_CHANNEL_TYPE];
     804    for(UInt chType=0; chType<MAX_NUM_CHANNEL_TYPE; chType++)
     805    {
     806      internalBitDepth[chType] = m_bitdepthShift[chType] + m_MSBExtendedBitDepth[chType];
     807    }
     808    ColourSpaceConvert(*pPicYuvUserTop,    cPicYuvTopCSCd,    ipCSC, internalBitDepth, false);
     809    ColourSpaceConvert(*pPicYuvUserBottom, cPicYuvBottomCSCd, ipCSC, internalBitDepth, false);
     810  }
     811  TComPicYuv *pPicYuvTop    = (ipCSC==IPCOLOURSPACE_UNCHANGED) ? pPicYuvUserTop    : &cPicYuvTopCSCd;
     812  TComPicYuv *pPicYuvBottom = (ipCSC==IPCOLOURSPACE_UNCHANGED) ? pPicYuvUserBottom : &cPicYuvBottomCSCd;
     813
     814  Bool is16bit = false;
     815  Bool nonZeroBitDepthShift=false;
     816
     817  for(UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++)
     818  {
     819    if (m_fileBitdepth[ch] > 8) is16bit=true;
     820    if (m_bitdepthShift[ch] != 0) nonZeroBitDepthShift=true;
     821  }
     822
     823  TComPicYuv *dstPicYuvTop    = NULL;
     824  TComPicYuv *dstPicYuvBottom = NULL;
     825
     826  for (UInt field = 0; field < 2; field++)
     827  {
     828    TComPicYuv *pPicYuv = (field == 0) ? pPicYuvTop : pPicYuvBottom;
     829
     830    if (format>=NUM_CHROMA_FORMAT) format=pPicYuv->getChromaFormat();
     831
     832    TComPicYuv* &dstPicYuv = (field == 0) ? dstPicYuvTop : dstPicYuvBottom;
     833
     834    if (nonZeroBitDepthShift)
     835    {
     836      dstPicYuv = new TComPicYuv;
     837      dstPicYuv->create( pPicYuv->getWidth(COMPONENT_Y), pPicYuv->getHeight(COMPONENT_Y), pPicYuv->getChromaFormat(), 1, 1, 0 );
     838      pPicYuv->copyToPic(dstPicYuv);
     839
     840      for(UInt comp=0; comp<dstPicYuv->getNumberValidComponents(); comp++)
     841      {
     842        const ComponentID compID=ComponentID(comp);
     843        const ChannelType ch=toChannelType(compID);
     844#if !CLIP_TO_709_RANGE
     845        const Pel minval = 0;
     846        const Pel maxval = (1 << m_MSBExtendedBitDepth[ch]) - 1;
     847#else
     848        const Bool b709Compliance=(-m_bitdepthShift[ch] < 0 && m_MSBExtendedBitDepth[ch] >= 8);     /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */
     849        const Pel minval = b709Compliance? ((   1 << (m_MSBExtendedBitDepth[ch] - 8))   ) : 0;
     850        const Pel maxval = b709Compliance? ((0xff << (m_MSBExtendedBitDepth[ch] - 8)) -1) : (1 << m_MSBExtendedBitDepth[ch]) - 1;
     851#endif
     852
     853        scalePlane(dstPicYuv->getAddr(compID), dstPicYuv->getStride(compID), dstPicYuv->getWidth(compID), dstPicYuv->getHeight(compID), -m_bitdepthShift[ch], minval, maxval);
     854      }
     855    }
     856    else
     857    {
     858      dstPicYuv = pPicYuv;
     859    }
     860  }
     861
    573862  Bool retval = true;
    574  
    575   if ((width==0)||(height==0))
    576   {
    577     printf ("\nWarning: writing %d x %d luma sample output picture!", width, height);
    578   }
    579  
    580   if (m_bitDepthShiftY != 0 || m_bitDepthShiftC != 0)
    581   {
    582     dstPicTop = new TComPicYuv;
    583 #if AUXILIARY_PICTURES
    584     dstPicTop->create( pPicTop->getWidth(), pPicTop->getHeight(), pPicTop->getChromaFormat(), 1, 1, 0 );
    585 #else
    586     dstPicTop->create( pPicTop->getWidth(), pPicTop->getHeight(), 1, 1, 0 );
    587 #endif
    588     pPicTop->copyToPic(dstPicTop);
    589    
    590     dstPicBottom = new TComPicYuv;
    591 #if AUXILIARY_PICTURES
    592     dstPicBottom->create( pPicBottom->getWidth(), pPicBottom->getHeight(), pPicBottom->getChromaFormat(), 1, 1, 0 );
    593 #else
    594     dstPicBottom->create( pPicBottom->getWidth(), pPicBottom->getHeight(), 1, 1, 0 );
    595 #endif
    596     pPicBottom->copyToPic(dstPicBottom);
    597    
    598     Pel minvalY = 0;
    599     Pel minvalC = 0;
    600     Pel maxvalY = (1 << m_fileBitDepthY) - 1;
    601     Pel maxvalC = (1 << m_fileBitDepthC) - 1;
    602 #if CLIP_TO_709_RANGE
    603     if (-m_bitDepthShiftY < 0 && m_fileBitDepthY >= 8)
    604     {
    605       /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */
    606       minvalY = 1 << (m_fileBitDepthY - 8);
    607       maxvalY = (0xff << (m_fileBitDepthY - 8)) -1;
    608     }
    609     if (-m_bitDepthShiftC < 0 && m_fileBitDepthC >= 8)
    610     {
    611       /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */
    612       minvalC = 1 << (m_fileBitDepthC - 8);
    613       maxvalC = (0xff << (m_fileBitDepthC - 8)) -1;
    614     }
    615 #endif
    616     scalePlane(dstPicTop->getLumaAddr(), dstPicTop->getStride(), dstPicTop->getWidth(), dstPicTop->getHeight(), -m_bitDepthShiftY, minvalY, maxvalY);
    617     scalePlane(dstPicTop->getCbAddr(), dstPicTop->getCStride(), dstPicTop->getWidth()>>1, dstPicTop->getHeight()>>1, -m_bitDepthShiftC, minvalC, maxvalC);
    618     scalePlane(dstPicTop->getCrAddr(), dstPicTop->getCStride(), dstPicTop->getWidth()>>1, dstPicTop->getHeight()>>1, -m_bitDepthShiftC, minvalC, maxvalC);
    619    
    620     scalePlane(dstPicBottom->getLumaAddr(), dstPicBottom->getStride(), dstPicBottom->getWidth(), dstPicBottom->getHeight(), -m_bitDepthShiftY, minvalY, maxvalY);
    621     scalePlane(dstPicBottom->getCbAddr(), dstPicBottom->getCStride(), dstPicBottom->getWidth()>>1, dstPicBottom->getHeight()>>1, -m_bitDepthShiftC, minvalC, maxvalC);
    622     scalePlane(dstPicBottom->getCrAddr(), dstPicBottom->getCStride(), dstPicBottom->getWidth()>>1, dstPicBottom->getHeight()>>1, -m_bitDepthShiftC, minvalC, maxvalC);
    623   }
    624   else
    625   {
    626     dstPicTop = pPicTop;
    627     dstPicBottom = pPicBottom;
    628   }
    629   // location of upper left pel in a plane
    630   Int planeOffset = 0; //cropLeft + cropTop * iStride;
    631   //Write luma
    632   if (! writeField(m_cHandle, dstPicTop->getLumaAddr() + planeOffset,  dstPicBottom->getLumaAddr() + planeOffset, is16bit, iStride, width, height, isTff))
    633   {
    634     retval=false;
    635     goto exit;
    636   }
    637  
    638   width >>= 1;
    639   height >>= 1;
    640   iStride >>= 1;
    641   cropLeft >>= 1;
    642   cropRight >>= 1;
    643  
    644   planeOffset = 0; // cropLeft + cropTop * iStride;
    645  
    646   //Write chroma U
    647   if (! writeField(m_cHandle, dstPicTop->getCbAddr() + planeOffset, dstPicBottom->getCbAddr() + planeOffset, is16bit, iStride, width, height, isTff))
    648   {
    649     retval=false;
    650     goto exit;
    651   }
    652  
    653   //Write chroma V
    654   if (! writeField(m_cHandle, dstPicTop->getCrAddr() + planeOffset, dstPicBottom->getCrAddr() + planeOffset, is16bit, iStride, width, height, isTff))
    655    
    656   {
    657     retval=false;
    658     goto exit;
    659   }
    660  
    661 exit:
    662   if (m_bitDepthShiftY != 0 || m_bitDepthShiftC != 0)
    663   {
    664     dstPicTop->destroy();
    665     delete dstPicTop;
    666     dstPicBottom->destroy();
    667     delete dstPicBottom;
    668   } 
     863
     864  assert(dstPicYuvTop->getNumberValidComponents() == dstPicYuvBottom->getNumberValidComponents());
     865  assert(dstPicYuvTop->getChromaFormat()          == dstPicYuvBottom->getChromaFormat()         );
     866  assert(dstPicYuvTop->getWidth(COMPONENT_Y)      == dstPicYuvBottom->getWidth(COMPONENT_Y)    );
     867  assert(dstPicYuvTop->getHeight(COMPONENT_Y)     == dstPicYuvBottom->getHeight(COMPONENT_Y)    );
     868  assert(dstPicYuvTop->getStride(COMPONENT_Y)     == dstPicYuvBottom->getStride(COMPONENT_Y)    );
     869
     870  for(UInt comp=0; retval && comp<dstPicYuvTop->getNumberValidComponents(); comp++)
     871  {
     872    const ComponentID compID = ComponentID(comp);
     873    const ChannelType ch=toChannelType(compID);
     874
     875    assert(dstPicYuvTop->getComponentScaleX(compID) == dstPicYuvBottom->getComponentScaleX(compID));
     876    assert(dstPicYuvTop->getComponentScaleY(compID) == dstPicYuvBottom->getComponentScaleY(compID));
     877    assert(dstPicYuvTop->getStride         (compID) == dstPicYuvBottom->getStride         (compID));
     878
     879    const UInt width444   = dstPicYuvTop->getWidth(COMPONENT_Y)  - (confLeft + confRight);
     880    const UInt height444  = dstPicYuvTop->getHeight(COMPONENT_Y) - (confTop + confBottom);
     881
     882    if ((width444 == 0) || (height444 == 0))
     883    {
     884      printf ("\nWarning: writing %d x %d luma sample output picture!", width444, height444);
     885    }
     886
     887    const UInt csx = dstPicYuvTop->getComponentScaleX(compID);
     888    const UInt csy = dstPicYuvTop->getComponentScaleY(compID);
     889    const Int planeOffset  = (confLeft>>csx) + ( confTop>>csy) * dstPicYuvTop->getStride(compID); //offset is for entire frame - round up for top field and down for bottom field
     890
     891    if (! writeField(m_cHandle,
     892                     (dstPicYuvTop   ->getAddr(compID) + planeOffset),
     893                     (dstPicYuvBottom->getAddr(compID) + planeOffset),
     894                     is16bit,
     895                     dstPicYuvTop->getStride(COMPONENT_Y),
     896                     width444, height444, compID, dstPicYuvTop->getChromaFormat(), format, m_fileBitdepth[ch], isTff))
     897    {
     898      retval=false;
     899    }
     900  }
     901
     902  if (nonZeroBitDepthShift)
     903  {
     904    dstPicYuvTop->destroy();
     905    dstPicYuvBottom->destroy();
     906    delete dstPicYuvTop;
     907    delete dstPicYuvBottom;
     908  }
     909
     910  cPicYuvTopCSCd.destroy();
     911  cPicYuvBottomCSCd.destroy();
     912
    669913  return retval;
    670914}
     915
     916static Void
     917copyPlane(const TComPicYuv &src, const ComponentID srcPlane, TComPicYuv &dest, const ComponentID destPlane)
     918{
     919  const UInt width=src.getWidth(srcPlane);
     920  const UInt height=src.getHeight(srcPlane);
     921  assert(dest.getWidth(destPlane) == width);
     922  assert(dest.getHeight(destPlane) == height);
     923  const Pel *pSrc=src.getAddr(srcPlane);
     924  Pel *pDest=dest.getAddr(destPlane);
     925  const UInt strideSrc=src.getStride(srcPlane);
     926  const UInt strideDest=dest.getStride(destPlane);
     927  for(UInt y=0; y<height; y++, pSrc+=strideSrc, pDest+=strideDest)
     928  {
     929    memcpy(pDest, pSrc, width*sizeof(Pel));
     930  }
     931}
     932
     933// static member
     934Void TVideoIOYuv::ColourSpaceConvert(const TComPicYuv &src, TComPicYuv &dest, const InputColourSpaceConversion conversion, const Int bitDepths[MAX_NUM_CHANNEL_TYPE], Bool bIsForwards)
     935{
     936  const ChromaFormat  format=src.getChromaFormat();
     937  const UInt          numValidComp=src.getNumberValidComponents();
     938
     939  switch (conversion)
     940  {
     941    case IPCOLOURSPACE_YCbCrtoYYY:
     942      if (format!=CHROMA_444)
     943      {
     944        // only 444 is handled.
     945        assert(format==CHROMA_444);
     946        exit(1);
     947      }
     948
     949      {
     950        for(UInt comp=0; comp<numValidComp; comp++)
     951          copyPlane(src, ComponentID(bIsForwards?0:comp), dest, ComponentID(comp));
     952      }
     953      break;
     954    case IPCOLOURSPACE_YCbCrtoYCrCb:
     955      {
     956        for(UInt comp=0; comp<numValidComp; comp++)
     957          copyPlane(src, ComponentID(comp), dest, ComponentID((numValidComp-comp)%numValidComp));
     958      }
     959      break;
     960
     961    case IPCOLOURSPACE_RGBtoGBR:
     962      {
     963        if (format!=CHROMA_444)
     964        {
     965          // only 444 is handled.
     966          assert(format==CHROMA_444);
     967          exit(1);
     968        }
     969
     970        // channel re-mapping
     971        for(UInt comp=0; comp<numValidComp; comp++)
     972        {
     973          const ComponentID compIDsrc=ComponentID((comp+1)%numValidComp);
     974          const ComponentID compIDdst=ComponentID(comp);
     975          copyPlane(src, bIsForwards?compIDsrc:compIDdst, dest, bIsForwards?compIDdst:compIDsrc);
     976        }
     977      }
     978      break;
     979
     980    case IPCOLOURSPACE_UNCHANGED:
     981    default:
     982      {
     983        for(UInt comp=0; comp<numValidComp; comp++)
     984          copyPlane(src, ComponentID(comp), dest, ComponentID(comp));
     985      }
     986      break;
     987  }
     988}
  • branches/SHM-upgrade/source/Lib/TLibVideoIO/TVideoIOYuv.h

    r595 r916  
    22 * License, included below. This software may be subject to other third party
    33 * and contributor rights, including patent rights, and no such rights are
    4  * granted under this license. 
     4 * granted under this license.
    55 *
    66 * Copyright (c) 2010-2014, ITU/ISO/IEC
     
    5656private:
    5757  fstream   m_cHandle;                                      ///< file handle
    58   Int m_fileBitDepthY; ///< bitdepth of input/output video file luma component
    59   Int m_fileBitDepthC; ///< bitdepth of input/output video file chroma component
    60   Int m_bitDepthShiftY;  ///< number of bits to increase or decrease luma by before/after write/read
    61   Int m_bitDepthShiftC;  ///< number of bits to increase or decrease chroma by before/after write/read
    62  
     58  Int       m_fileBitdepth[MAX_NUM_CHANNEL_TYPE]; ///< bitdepth of input/output video file
     59  Int       m_MSBExtendedBitDepth[MAX_NUM_CHANNEL_TYPE];  ///< bitdepth after addition of MSBs (with value 0)
     60  Int       m_bitdepthShift[MAX_NUM_CHANNEL_TYPE];  ///< number of bits to increase or decrease image by before/after write/read
     61
    6362public:
    6463  TVideoIOYuv()           {}
    6564  virtual ~TVideoIOYuv()  {}
    66  
    67   Void  open  ( Char* pchFile, Bool bWriteMode, Int fileBitDepthY, Int fileBitDepthC, Int internalBitDepthY, Int internalBitDepthC ); ///< open or create file
     65
     66  Void  open  ( Char* pchFile, Bool bWriteMode, const Int fileBitDepth[MAX_NUM_CHANNEL_TYPE], const Int MSBExtendedBitDepth[MAX_NUM_CHANNEL_TYPE], const Int internalBitDepth[MAX_NUM_CHANNEL_TYPE] ); ///< open or create file
    6867  Void  close ();                                           ///< close file
    6968
    70   void skipFrames(UInt numFrames, UInt width, UInt height);
    71  
    72   Bool  read  ( TComPicYuv*   pPicYuv, Int aiPad[2] );     ///< read  one YUV frame with padding parameter
    73   Bool  write( TComPicYuv*    pPicYuv, Int confLeft=0, Int confRight=0, Int confTop=0, Int confBottom=0 );
    74   Bool  write( TComPicYuv*    pPicYuv, TComPicYuv*    pPicYuv2, Int confLeft=0, Int confRight=0, Int confTop=0, Int confBottom=0, Bool isTff = false );
    75  
     69  Void skipFrames(UInt numFrames, UInt width, UInt height, ChromaFormat format);
     70
     71  // if fileFormat<NUM_CHROMA_FORMAT, the format of the file is that format specified, else it is the format of the TComPicYuv.
     72
     73
     74  Bool  read  ( TComPicYuv* pPicYuv, TComPicYuv* pPicYuvTrueOrg, const InputColourSpaceConversion ipcsc, Int aiPad[2], ChromaFormat fileFormat=NUM_CHROMA_FORMAT );     ///< read one frame with padding parameter
     75  Bool  write ( TComPicYuv* pPicYuv, const InputColourSpaceConversion ipCSC, Int confLeft=0, Int confRight=0, Int confTop=0, Int confBottom=0, ChromaFormat fileFormat=NUM_CHROMA_FORMAT );     ///< write one YUV frame with padding parameter
     76  Bool  write ( TComPicYuv* pPicYuvTop, TComPicYuv* pPicYuvBottom, const InputColourSpaceConversion ipCSC, Int confLeft=0, Int confRight=0, Int confTop=0, Int confBottom=0, ChromaFormat fileFormat=NUM_CHROMA_FORMAT, Bool isTff=false);
     77  static Void ColourSpaceConvert(const TComPicYuv &src, TComPicYuv &dest, const InputColourSpaceConversion conversion, const Int bitDepths[MAX_NUM_CHANNEL_TYPE], Bool bIsForwards);
     78
    7679  Bool  isEof ();                                           ///< check for end-of-file
    7780  Bool  isFail();                                           ///< check for failure
    78  
     81
     82
    7983};
    8084
Note: See TracChangeset for help on using the changeset viewer.