source: SHVCSoftware/branches/SHM-5.1-dev/source/Lib/TLibVideoIO/TVideoIOYuv.cpp @ 1606

Last change on this file since 1606 was 595, checked in by seregin, 11 years ago

merge with SHM-5.0-dev branch

  • Property svn:eol-style set to native
File size: 21.0 KB
Line 
1/* The copyright in this software is being made available under the BSD
2 * License, included below. This software may be subject to other third party
3 * and contributor rights, including patent rights, and no such rights are
4 * granted under this license. 
5 *
6 * Copyright (c) 2010-2014, ITU/ISO/IEC
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 *  * Redistributions of source code must retain the above copyright notice,
13 *    this list of conditions and the following disclaimer.
14 *  * Redistributions in binary form must reproduce the above copyright notice,
15 *    this list of conditions and the following disclaimer in the documentation
16 *    and/or other materials provided with the distribution.
17 *  * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
18 *    be used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/** \file     TVideoIOYuv.cpp
35    \brief    YUV file I/O class
36*/
37
38#include <cstdlib>
39#include <fcntl.h>
40#include <assert.h>
41#include <sys/stat.h>
42#include <fstream>
43#include <iostream>
44
45#include "TLibCommon/TComRom.h"
46#include "TVideoIOYuv.h"
47
48using namespace std;
49
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 */
62static 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 */
86static 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}
98
99/**
100 * Scale all pixels in img depending upon sign of shiftbits by a factor of
101 * 2<sup>shiftbits</sup>.
102 *
103 * @param img        pointer to image to be transformed
104 * @param stride  distance between vertically adjacent pixels of img.
105 * @param width   width of active area in img.
106 * @param height  height of active area in img.
107 * @param shiftbits if zero, no operation performed
108 *                  if > 0, multiply by 2<sup>shiftbits</sup>, see scalePlane()
109 *                  if < 0, divide and round by 2<sup>shiftbits</sup> and clip,
110 *                          see invScalePlane().
111 * @param minval  minimum clipping value when dividing.
112 * @param maxval  maximum clipping value when dividing.
113 */
114static 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
122  if (shiftbits > 0)
123  {
124    scalePlane(img, stride, width, height, shiftbits);
125  }
126  else
127  {
128    invScalePlane(img, stride, width, height, -shiftbits, minval, maxval);
129  }
130}
131
132
133// ====================================================================================================================
134// Public member functions
135// ====================================================================================================================
136
137/**
138 * Open file for reading/writing Y'CbCr frames.
139 *
140 * Frames read/written have bitdepth fileBitDepth, and are automatically
141 * formatted as 8 or 16 bit word values (see TVideoIOYuv::write()).
142 *
143 * Image data read or written is converted to/from internalBitDepth
144 * (See scalePlane(), TVideoIOYuv::read() and TVideoIOYuv::write() for
145 * further details).
146 *
147 * \param pchFile          file name string
148 * \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).
153 */
154Void 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;
160
161  if ( bWriteMode )
162  {
163    m_cHandle.open( pchFile, ios::binary | ios::out );
164   
165    if( m_cHandle.fail() )
166    {
167      printf("\nfailed to write reconstructed YUV file\n");
168      exit(0);
169    }
170  }
171  else
172  {
173    m_cHandle.open( pchFile, ios::binary | ios::in );
174   
175    if( m_cHandle.fail() )
176    {
177      printf("\nfailed to open Input YUV file\n");
178      exit(0);
179    }
180  }
181 
182  return;
183}
184
185Void TVideoIOYuv::close()
186{
187  m_cHandle.close();
188}
189
190Bool TVideoIOYuv::isEof()
191{
192  return m_cHandle.eof();
193}
194
195Bool TVideoIOYuv::isFail()
196{
197  return m_cHandle.fail();
198}
199
200/**
201 * Skip numFrames in input.
202 *
203 * This function correctly handles cases where the input file is not
204 * seekable, by consuming bytes.
205 */
206void TVideoIOYuv::skipFrames(UInt numFrames, UInt width, UInt height)
207{
208  if (!numFrames)
209    return;
210
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;
214
215  /* attempt to seek */
216  if (!!m_cHandle.seekg(offset, ios::cur))
217    return; /* success */
218  m_cHandle.clear();
219
220  /* fall back to consuming the input */
221  Char buf[512];
222  const UInt offset_mod_bufsize = offset % sizeof(buf);
223  for (streamoff i = 0; i < offset - offset_mod_bufsize; i += sizeof(buf))
224  {
225    m_cHandle.read(buf, sizeof(buf));
226  }
227  m_cHandle.read(buf, offset_mod_bufsize);
228}
229
230/**
231 * Read width*height pixels from fd into dst, optionally
232 * padding the left and right edges by edge-extension.  Input may be
233 * either 8bit or 16bit little-endian lsb-aligned words.
234 *
235 * @param dst     destination image
236 * @param fd      input file stream
237 * @param is16bit true if input file carries > 8bit data, false otherwise.
238 * @param stride  distance between vertically adjacent pixels of dst.
239 * @param width   width of active area in dst.
240 * @param height  height of active area in dst.
241 * @param pad_x   length of horizontal padding.
242 * @param pad_y   length of vertical padding.
243 * @return true for success, false in case of error
244 */
245static 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;
289  }
290  delete[] buf;
291  return true;
292}
293
294/**
295 * Write width*height pixels info fd from src.
296 *
297 * @param fd      output file stream
298 * @param src     source image
299 * @param is16bit true if input file carries > 8bit data, false otherwise.
300 * @param stride  distance between vertically adjacent pixels of src.
301 * @param width   width of active area in src.
302 * @param height  height of active area in src.
303 * @return true for success, false in case of error
304 */
305static 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;
336  }
337  delete[] buf;
338  return true;
339}
340
341static 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;
377  }
378  delete[] buf;
379  return true;
380}
381/**
382 * Read one Y'CbCr frame, performing any required input scaling to change
383 * from the bitdepth of the input file to the internal bit-depth.
384 *
385 * If a bit-depth reduction is required, and internalBitdepth >= 8, then
386 * the input file is assumed to be ITU-R BT.601/709 compliant, and the
387 * resulting data is clipped to the appropriate legal range, as if the
388 * file had been provided at the lower-bitdepth compliant to Rec601/709.
389 *
390 * @param pPicYuv      input picture YUV buffer class pointer
391 * @param aiPad        source padding size, aiPad[0] = horizontal, aiPad[1] = vertical
392 * @return true for success, false in case of error
393 */
394Bool TVideoIOYuv::read ( TComPicYuv*  pPicYuv, Int aiPad[2] )
395{
396  // check end-of-file
397  if ( isEof() ) return false;
398 
399  Int   iStride = pPicYuv->getStride();
400 
401  // 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  }
429#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);
450
451  return true;
452}
453
454/**
455 * Write one Y'CbCr frame. No bit-depth conversion is performed, pcPicYuv is
456 * assumed to be at TVideoIO::m_fileBitdepth depth.
457 *
458 * @param pPicYuv     input picture YUV buffer class pointer
459 * @param aiPad       source padding size, aiPad[0] = horizontal, aiPad[1] = vertical
460 * @return true for success, false in case of error
461 */
462Bool TVideoIOYuv::write( TComPicYuv* pPicYuv, Int confLeft, Int confRight, Int confTop, Int confBottom )
463{
464  // 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;
469  TComPicYuv *dstPicYuv = NULL;
470  Bool retval = true;
471
472  if (m_bitDepthShiftY != 0 || m_bitDepthShiftC != 0)
473  {
474    dstPicYuv = new TComPicYuv;
475#if AUXILIARY_PICTURES
476    dstPicYuv->create( pPicYuv->getWidth(), pPicYuv->getHeight(), pPicYuv->getChromaFormat(), 1, 1, 0 );
477#else
478    dstPicYuv->create( pPicYuv->getWidth(), pPicYuv->getHeight(), 1, 1, 0 );
479#endif
480    pPicYuv->copyToPic(dstPicYuv);
481
482    Pel minvalY = 0;
483    Pel minvalC = 0;
484    Pel maxvalY = (1 << m_fileBitDepthY) - 1;
485    Pel maxvalC = (1 << m_fileBitDepthC) - 1;
486#if CLIP_TO_709_RANGE
487    if (-m_bitDepthShiftY < 0 && m_fileBitDepthY >= 8)
488    {
489      /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */
490      minvalY = 1 << (m_fileBitDepthY - 8);
491      maxvalY = (0xff << (m_fileBitDepthY - 8)) -1;
492    }
493    if (-m_bitDepthShiftC < 0 && m_fileBitDepthC >= 8)
494    {
495      /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */
496      minvalC = 1 << (m_fileBitDepthC - 8);
497      maxvalC = (0xff << (m_fileBitDepthC - 8)) -1;
498    }
499#endif
500    scalePlane(dstPicYuv->getLumaAddr(), dstPicYuv->getStride(), dstPicYuv->getWidth(), dstPicYuv->getHeight(), -m_bitDepthShiftY, minvalY, maxvalY);
501    scalePlane(dstPicYuv->getCbAddr(), dstPicYuv->getCStride(), dstPicYuv->getWidth()>>1, dstPicYuv->getHeight()>>1, -m_bitDepthShiftC, minvalC, maxvalC);
502    scalePlane(dstPicYuv->getCrAddr(), dstPicYuv->getCStride(), dstPicYuv->getWidth()>>1, dstPicYuv->getHeight()>>1, -m_bitDepthShiftC, minvalC, maxvalC);
503  }
504  else
505  {
506    dstPicYuv = pPicYuv;
507  }
508  // location of upper left pel in a plane
509  Int planeOffset = confLeft + confTop * iStride;
510 
511  if (! writePlane(m_cHandle, dstPicYuv->getLumaAddr() + planeOffset, is16bit, iStride, width, height))
512  {
513    retval=false; 
514    goto exit;
515  }
516
517  width >>= 1;
518  height >>= 1;
519  iStride >>= 1;
520  confLeft >>= 1;
521  confRight >>= 1;
522  confTop >>= 1;
523  confBottom >>= 1;
524
525  planeOffset = confLeft + confTop * iStride;
526
527  if (! writePlane(m_cHandle, dstPicYuv->getCbAddr() + planeOffset, is16bit, iStride, width, height))
528  {
529    retval=false; 
530    goto exit;
531  }
532  if (! writePlane(m_cHandle, dstPicYuv->getCrAddr() + planeOffset, is16bit, iStride, width, height))
533  {
534    retval=false; 
535    goto exit;
536  }
537 
538exit:
539  if (m_bitDepthShiftY != 0 || m_bitDepthShiftC != 0)
540  {
541    dstPicYuv->destroy();
542    delete dstPicYuv;
543  } 
544  return retval;
545}
546
547
548/**
549 * Write one Y'CbCr frame. No bit-depth conversion is performed, pcPicYuv is
550 * assumed to be at TVideoIO::m_fileBitdepth depth.
551 *
552 * @param pPicTop     input top field YUV buffer class pointer
553 * @param pPicBottom  input bottom field YUV buffer class pointer
554 * @param aiPad       source padding size, aiPad[0] = horizontal, aiPad[1] = vertical
555 * @return true for success, false in case of error
556 */
557Bool TVideoIOYuv::write( TComPicYuv* pPicTop, TComPicYuv* pPicBottom, Int cropLeft, Int cropRight, Int cropTop, Int cropBottom , bool isTff)
558{
559  // compute actual YUV frame size excluding padding size
560  Int   iStride = pPicTop->getStride();
561  UInt  width  = pPicTop->getWidth()  - cropLeft - cropRight;
562  UInt  height = pPicTop->getHeight() - cropTop  - cropBottom;
563  Bool is16bit = m_fileBitDepthY > 8 || m_fileBitDepthC > 8;
564 
565  TComPicYuv *dstPicTop = NULL;
566  TComPicYuv *dstPicBottom = NULL;
567 
568  Bool retval = true;
569 
570  if (m_bitDepthShiftY != 0 || m_bitDepthShiftC != 0)
571  {
572    dstPicTop = new TComPicYuv;
573#if AUXILIARY_PICTURES
574    dstPicTop->create( pPicTop->getWidth(), pPicTop->getHeight(), pPicTop->getChromaFormat(), 1, 1, 0 );
575#else
576    dstPicTop->create( pPicTop->getWidth(), pPicTop->getHeight(), 1, 1, 0 );
577#endif
578    pPicTop->copyToPic(dstPicTop);
579   
580    dstPicBottom = new TComPicYuv;
581#if AUXILIARY_PICTURES
582    dstPicBottom->create( pPicBottom->getWidth(), pPicBottom->getHeight(), pPicBottom->getChromaFormat(), 1, 1, 0 );
583#else
584    dstPicBottom->create( pPicBottom->getWidth(), pPicBottom->getHeight(), 1, 1, 0 );
585#endif
586    pPicBottom->copyToPic(dstPicBottom);
587   
588    Pel minvalY = 0;
589    Pel minvalC = 0;
590    Pel maxvalY = (1 << m_fileBitDepthY) - 1;
591    Pel maxvalC = (1 << m_fileBitDepthC) - 1;
592#if CLIP_TO_709_RANGE
593    if (-m_bitDepthShiftY < 0 && m_fileBitDepthY >= 8)
594    {
595      /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */
596      minvalY = 1 << (m_fileBitDepthY - 8);
597      maxvalY = (0xff << (m_fileBitDepthY - 8)) -1;
598    }
599    if (-m_bitDepthShiftC < 0 && m_fileBitDepthC >= 8)
600    {
601      /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */
602      minvalC = 1 << (m_fileBitDepthC - 8);
603      maxvalC = (0xff << (m_fileBitDepthC - 8)) -1;
604    }
605#endif
606    scalePlane(dstPicTop->getLumaAddr(), dstPicTop->getStride(), dstPicTop->getWidth(), dstPicTop->getHeight(), -m_bitDepthShiftY, minvalY, maxvalY);
607    scalePlane(dstPicTop->getCbAddr(), dstPicTop->getCStride(), dstPicTop->getWidth()>>1, dstPicTop->getHeight()>>1, -m_bitDepthShiftC, minvalC, maxvalC);
608    scalePlane(dstPicTop->getCrAddr(), dstPicTop->getCStride(), dstPicTop->getWidth()>>1, dstPicTop->getHeight()>>1, -m_bitDepthShiftC, minvalC, maxvalC);
609   
610    scalePlane(dstPicBottom->getLumaAddr(), dstPicBottom->getStride(), dstPicBottom->getWidth(), dstPicBottom->getHeight(), -m_bitDepthShiftY, minvalY, maxvalY);
611    scalePlane(dstPicBottom->getCbAddr(), dstPicBottom->getCStride(), dstPicBottom->getWidth()>>1, dstPicBottom->getHeight()>>1, -m_bitDepthShiftC, minvalC, maxvalC);
612    scalePlane(dstPicBottom->getCrAddr(), dstPicBottom->getCStride(), dstPicBottom->getWidth()>>1, dstPicBottom->getHeight()>>1, -m_bitDepthShiftC, minvalC, maxvalC);
613  }
614  else
615  {
616    dstPicTop = pPicTop;
617    dstPicBottom = pPicBottom;
618  }
619  // location of upper left pel in a plane
620  Int planeOffset = 0; //cropLeft + cropTop * iStride;
621  //Write luma
622  if (! writeField(m_cHandle, dstPicTop->getLumaAddr() + planeOffset,  dstPicBottom->getLumaAddr() + planeOffset, is16bit, iStride, width, height, isTff))
623  {
624    retval=false;
625    goto exit;
626  }
627 
628  width >>= 1;
629  height >>= 1;
630  iStride >>= 1;
631  cropLeft >>= 1;
632  cropRight >>= 1;
633 
634  planeOffset = 0; // cropLeft + cropTop * iStride;
635 
636  //Write chroma U
637  if (! writeField(m_cHandle, dstPicTop->getCbAddr() + planeOffset, dstPicBottom->getCbAddr() + planeOffset, is16bit, iStride, width, height, isTff))
638  {
639    retval=false;
640    goto exit;
641  }
642 
643  //Write chroma V
644  if (! writeField(m_cHandle, dstPicTop->getCrAddr() + planeOffset, dstPicBottom->getCrAddr() + planeOffset, is16bit, iStride, width, height, isTff))
645   
646  {
647    retval=false;
648    goto exit;
649  }
650 
651exit:
652  if (m_bitDepthShiftY != 0 || m_bitDepthShiftC != 0)
653  {
654    dstPicTop->destroy();
655    delete dstPicTop;
656    dstPicBottom->destroy();
657    delete dstPicBottom;
658  } 
659  return retval;
660}
Note: See TracBrowser for help on using the repository browser.