Changeset 1200 in 3DVCSoftware for branches/HTM-14.1-update-dev0/source/Lib/TLibVideoIO
- Timestamp:
- 4 May 2015, 18:38:08 (10 years ago)
- Location:
- branches/HTM-14.1-update-dev0/source/Lib/TLibVideoIO
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HTM-14.1-update-dev0/source/Lib/TLibVideoIO/TVideoIOYuv.cpp
r1179 r1200 2 2 * License, included below. This software may be subject to other third party 3 3 * and contributor rights, including patent rights, and no such rights are 4 * granted under this license. 5 * 6 * Copyright (c) 2010-2015, ITU/ISO/IEC4 * granted under this license. 5 * 6 * Copyright (c) 2010-2015, ITU/ISO/IEC 7 7 * All rights reserved. 8 8 * … … 42 42 #include <fstream> 43 43 #include <iostream> 44 #include <memory.h> 44 45 45 46 #include "TLibCommon/TComRom.h" … … 48 49 using namespace std; 49 50 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 // ==================================================================================================================== 98 54 99 55 /** … … 112 68 * @param maxval maximum clipping value when dividing. 113 69 */ 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 70 static Void scalePlane(Pel* img, const UInt stride, const UInt width, const UInt height, Int shiftbits, Pel minval, Pel maxval) 71 { 122 72 if (shiftbits > 0) 123 73 { 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 { 76 for (UInt x = 0; x < width; x++) 77 { 78 img[x] <<= shiftbits; 79 } 80 } 81 } 82 else if (shiftbits < 0) 83 { 84 shiftbits=-shiftbits; 85 86 Pel rounding = 1 << (shiftbits-1); 87 for (UInt y = 0; y < height; y++, img+=stride) 88 { 89 for (UInt x = 0; x < width; x++) 90 { 91 img[x] = Clip3(minval, maxval, Pel((img[x] + rounding) >> shiftbits)); 92 } 93 } 129 94 } 130 95 } … … 146 111 * 147 112 * \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). 113 * \param bWriteMode file open mode: true=write, false=read 114 * \param fileBitDepth bit-depth array of input/output file data. 115 * \param MSBExtendedBitDepth 116 * \param internalBitDepth bit-depth array to scale image data to/from when reading/writing. 153 117 */ 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; 118 Void 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] ) 119 { 120 //NOTE: files cannot have bit depth greater than 16 121 for(UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++) 122 { 123 m_fileBitdepth [ch] = std::min<UInt>(fileBitDepth[ch], 16); 124 m_MSBExtendedBitDepth[ch] = MSBExtendedBitDepth[ch]; 125 m_bitdepthShift [ch] = internalBitDepth[ch] - m_MSBExtendedBitDepth[ch]; 126 127 if (m_fileBitdepth[ch] > 16) 128 { 129 if (bWriteMode) 130 { 131 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; 132 } 133 else 134 { 135 std::cerr << "\nERROR: Cannot read a yuv file of bit depth greater than 16\n" << std::endl; 136 exit(0); 137 } 138 } 139 } 160 140 161 141 if ( bWriteMode ) 162 142 { 163 143 m_cHandle.open( pchFile, ios::binary | ios::out ); 164 144 165 145 if( m_cHandle.fail() ) 166 146 { … … 172 152 { 173 153 m_cHandle.open( pchFile, ios::binary | ios::in ); 174 154 175 155 if( m_cHandle.fail() ) 176 156 { … … 179 159 } 180 160 } 181 161 182 162 return; 183 163 } … … 204 184 * seekable, by consuming bytes. 205 185 */ 206 void TVideoIOYuv::skipFrames(UInt numFrames, UInt width, UInt height)186 Void TVideoIOYuv::skipFrames(UInt numFrames, UInt width, UInt height, ChromaFormat format) 207 187 { 208 188 if (!numFrames) 189 { 209 190 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; 191 } 192 193 //------------------ 194 //set the frame size according to the chroma format 195 streamoff frameSize = 0; 196 UInt wordsize=1; // default to 8-bit, unless a channel with more than 8-bits is detected. 197 for (UInt component = 0; component < getNumberValidComponents(format); component++) 198 { 199 ComponentID compID=ComponentID(component); 200 frameSize += (width >> getComponentScaleX(compID, format)) * (height >> getComponentScaleY(compID, format)); 201 if (m_fileBitdepth[toChannelType(compID)] > 8) 202 { 203 wordsize=2; 204 } 205 } 206 frameSize *= wordsize; 207 //------------------ 208 209 const streamoff offset = frameSize * numFrames; 214 210 215 211 /* attempt to seek */ 216 212 if (!!m_cHandle.seekg(offset, ios::cur)) 213 { 217 214 return; /* success */ 215 } 218 216 m_cHandle.clear(); 219 217 220 218 /* fall back to consuming the input */ 221 219 Char buf[512]; 222 const UIntoffset_mod_bufsize = offset % sizeof(buf);220 const streamoff offset_mod_bufsize = offset % sizeof(buf); 223 221 for (streamoff i = 0; i < offset - offset_mod_bufsize; i += sizeof(buf)) 224 222 { … … 233 231 * either 8bit or 16bit little-endian lsb-aligned words. 234 232 * 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. 233 * @param dst destination image plane 234 * @param fd input file stream 235 * @param is16bit true if input file carries > 8bit data, false otherwise. 236 * @param stride444 distance between vertically adjacent pixels of dst. 237 * @param width444 width of active area in dst. 238 * @param height444 height of active area in dst. 239 * @param pad_x444 length of horizontal padding. 240 * @param pad_y444 length of vertical padding. 241 * @param compID chroma component 242 * @param destFormat chroma format of image 243 * @param fileFormat chroma format of file 244 * @param fileBitDepth component bit depth in file 243 245 * @return true for success, false in case of error 244 246 */ 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; 247 static Bool readPlane(Pel* dst, 248 istream& fd, 249 Bool is16bit, 250 UInt stride444, 251 UInt width444, 252 UInt height444, 253 UInt pad_x444, 254 UInt pad_y444, 255 const ComponentID compID, 256 const ChromaFormat destFormat, 257 const ChromaFormat fileFormat, 258 const UInt fileBitDepth) 259 { 260 const UInt csx_file =getComponentScaleX(compID, fileFormat); 261 const UInt csy_file =getComponentScaleY(compID, fileFormat); 262 const UInt csx_dest =getComponentScaleX(compID, destFormat); 263 const UInt csy_dest =getComponentScaleY(compID, destFormat); 264 265 const UInt width_dest = width444 >>csx_dest; 266 const UInt height_dest = height444>>csy_dest; 267 const UInt pad_x_dest = pad_x444>>csx_dest; 268 const UInt pad_y_dest = pad_y444>>csy_dest; 269 const UInt stride_dest = stride444>>csx_dest; 270 271 const UInt full_width_dest = width_dest+pad_x_dest; 272 const UInt full_height_dest = height_dest+pad_y_dest; 273 274 const UInt stride_file = (width444 * (is16bit ? 2 : 1)) >> csx_file; 275 276 UChar *buf = new UChar[stride_file]; 277 278 if (compID!=COMPONENT_Y && (fileFormat==CHROMA_400 || destFormat==CHROMA_400)) 279 { 280 if (destFormat!=CHROMA_400) 281 { 282 // set chrominance data to mid-range: (1<<(fileBitDepth-1)) 283 const Pel value=Pel(1<<(fileBitDepth-1)); 284 for (UInt y = 0; y < full_height_dest; y++, dst+=stride_dest) 285 { 286 for (UInt x = 0; x < full_width_dest; x++) 287 { 288 dst[x] = value; 289 } 290 } 291 } 292 293 if (fileFormat!=CHROMA_400) 294 { 295 const UInt height_file = height444>>csy_file; 296 fd.seekg(height_file*stride_file, ios::cur); 297 if (fd.eof() || fd.fail() ) 298 { 299 delete[] buf; 300 return false; 301 } 302 } 303 } 304 else 305 { 306 const UInt mask_y_file=(1<<csy_file)-1; 307 const UInt mask_y_dest=(1<<csy_dest)-1; 308 for(UInt y444=0; y444<height444; y444++) 309 { 310 if ((y444&mask_y_file)==0) 311 { 312 // read a new line 313 fd.read(reinterpret_cast<Char*>(buf), stride_file); 314 if (fd.eof() || fd.fail() ) 315 { 316 delete[] buf; 317 return false; 318 } 319 } 320 321 if ((y444&mask_y_dest)==0) 322 { 323 // process current destination line 324 if (csx_file < csx_dest) 325 { 326 // eg file is 444, dest is 422. 327 const UInt sx=csx_dest-csx_file; 328 if (!is16bit) 329 { 330 for (UInt x = 0; x < width_dest; x++) 331 { 332 dst[x] = buf[x<<sx]; 333 } 334 } 335 else 336 { 337 for (UInt x = 0; x < width_dest; x++) 338 { 339 dst[x] = Pel(buf[(x<<sx)*2+0]) | (Pel(buf[(x<<sx)*2+1])<<8); 340 } 341 } 342 } 343 else 344 { 345 // eg file is 422, dest is 444. 346 const UInt sx=csx_file-csx_dest; 347 if (!is16bit) 348 { 349 for (UInt x = 0; x < width_dest; x++) 350 { 351 dst[x] = buf[x>>sx]; 352 } 353 } 354 else 355 { 356 for (UInt x = 0; x < width_dest; x++) 357 { 358 dst[x] = Pel(buf[(x>>sx)*2+0]) | (Pel(buf[(x>>sx)*2+1])<<8); 359 } 360 } 361 } 362 363 // process right hand side padding 364 const Pel val=dst[width_dest-1]; 365 for (UInt x = width_dest; x < full_width_dest; x++) 366 { 367 dst[x] = val; 368 } 369 370 dst += stride_dest; 371 } 372 } 373 374 // process lower padding 375 for (UInt y = height_dest; y < full_height_dest; y++, dst+=stride_dest) 376 { 377 for (UInt x = 0; x < full_width_dest; x++) 378 { 379 dst[x] = (dst - stride_dest)[x]; 380 } 381 } 289 382 } 290 383 delete[] buf; … … 293 386 294 387 /** 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. 388 * Write an image plane (width444*height444 pixels) from src into output stream fd. 389 * 390 * @param fd output file stream 391 * @param src source image 392 * @param is16bit true if input file carries > 8bit data, false otherwise. 393 * @param stride444 distance between vertically adjacent pixels of src. 394 * @param width444 width of active area in src. 395 * @param height444 height of active area in src. 396 * @param compID chroma component 397 * @param srcFormat chroma format of image 398 * @param fileFormat chroma format of file 399 * @param fileBitDepth component bit depth in file 303 400 * @return true for success, false in case of error 304 401 */ 305 402 static 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; 403 UInt stride444, 404 UInt width444, UInt height444, 405 const ComponentID compID, 406 const ChromaFormat srcFormat, 407 const ChromaFormat fileFormat, 408 const UInt fileBitDepth) 409 { 410 const UInt csx_file =getComponentScaleX(compID, fileFormat); 411 const UInt csy_file =getComponentScaleY(compID, fileFormat); 412 const UInt csx_src =getComponentScaleX(compID, srcFormat); 413 const UInt csy_src =getComponentScaleY(compID, srcFormat); 414 415 const UInt stride_src = stride444>>csx_src; 416 417 const UInt stride_file = (width444 * (is16bit ? 2 : 1)) >> csx_file; 418 const UInt width_file = width444 >>csx_file; 419 const UInt height_file = height444>>csy_file; 420 421 UChar *buf = new UChar[stride_file]; 422 423 if (compID!=COMPONENT_Y && (fileFormat==CHROMA_400 || srcFormat==CHROMA_400)) 424 { 425 if (fileFormat!=CHROMA_400) 426 { 427 const UInt value=1<<(fileBitDepth-1); 428 429 for(UInt y=0; y< height_file; y++) 430 { 431 if (!is16bit) 432 { 433 UChar val(value); 434 for (UInt x = 0; x < width_file; x++) 435 { 436 buf[x]=val; 437 } 438 } 439 else 440 { 441 UShort val(value); 442 for (UInt x = 0; x < width_file; x++) 443 { 444 buf[2*x+0]= (val>>0) & 0xff; 445 buf[2*x+1]= (val>>8) & 0xff; 446 } 447 } 448 449 fd.write(reinterpret_cast<Char*>(buf), stride_file); 450 if (fd.eof() || fd.fail() ) 451 { 452 delete[] buf; 453 return false; 454 } 455 } 456 } 457 } 458 else 459 { 460 const UInt mask_y_file=(1<<csy_file)-1; 461 const UInt mask_y_src =(1<<csy_src )-1; 462 for(UInt y444=0; y444<height444; y444++) 463 { 464 if ((y444&mask_y_file)==0) 465 { 466 // write a new line 467 if (csx_file < csx_src) 468 { 469 // eg file is 444, source is 422. 470 const UInt sx=csx_src-csx_file; 471 if (!is16bit) 472 { 473 for (UInt x = 0; x < width_file; x++) 474 { 475 buf[x] = (UChar)(src[x>>sx]); 476 } 477 } 478 else 479 { 480 for (UInt x = 0; x < width_file; x++) 481 { 482 buf[2*x ] = (src[x>>sx]>>0) & 0xff; 483 buf[2*x+1] = (src[x>>sx]>>8) & 0xff; 484 } 485 } 486 } 487 else 488 { 489 // eg file is 422, src is 444. 490 const UInt sx=csx_file-csx_src; 491 if (!is16bit) 492 { 493 for (UInt x = 0; x < width_file; x++) 494 { 495 buf[x] = (UChar)(src[x<<sx]); 496 } 497 } 498 else 499 { 500 for (UInt x = 0; x < width_file; x++) 501 { 502 buf[2*x ] = (src[x<<sx]>>0) & 0xff; 503 buf[2*x+1] = (src[x<<sx]>>8) & 0xff; 504 } 505 } 506 } 507 508 fd.write(reinterpret_cast<Char*>(buf), stride_file); 509 if (fd.eof() || fd.fail() ) 510 { 511 delete[] buf; 512 return false; 513 } 514 } 515 516 if ((y444&mask_y_src)==0) 517 { 518 src += stride_src; 519 } 520 521 } 336 522 } 337 523 delete[] buf; … … 340 526 341 527 static 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; 528 UInt stride444, 529 UInt width444, UInt height444, 530 const ComponentID compID, 531 const ChromaFormat srcFormat, 532 const ChromaFormat fileFormat, 533 const UInt fileBitDepth, const Bool isTff) 534 { 535 const UInt csx_file =getComponentScaleX(compID, fileFormat); 536 const UInt csy_file =getComponentScaleY(compID, fileFormat); 537 const UInt csx_src =getComponentScaleX(compID, srcFormat); 538 const UInt csy_src =getComponentScaleY(compID, srcFormat); 539 540 const UInt stride_src = stride444>>csx_src; 541 542 const UInt stride_file = (width444 * (is16bit ? 2 : 1)) >> csx_file; 543 const UInt width_file = width444 >>csx_file; 544 const UInt height_file = height444>>csy_file; 545 546 UChar *buf = new UChar[stride_file * 2]; 547 548 if (compID!=COMPONENT_Y && (fileFormat==CHROMA_400 || srcFormat==CHROMA_400)) 549 { 550 if (fileFormat!=CHROMA_400) 551 { 552 const UInt value=1<<(fileBitDepth-1); 553 554 for(UInt y=0; y< height_file; y++) 555 { 556 for (UInt field = 0; field < 2; field++) 557 { 558 UChar *fieldBuffer = buf + (field * stride_file); 559 560 if (!is16bit) 561 { 562 UChar val(value); 563 for (UInt x = 0; x < width_file; x++) 564 { 565 fieldBuffer[x]=val; 566 } 567 } 568 else 569 { 570 UShort val(value); 571 for (UInt x = 0; x < width_file; x++) 572 { 573 fieldBuffer[2*x+0]= (val>>0) & 0xff; 574 fieldBuffer[2*x+1]= (val>>8) & 0xff; 575 } 576 } 577 } 578 579 fd.write(reinterpret_cast<Char*>(buf), (stride_file * 2)); 580 if (fd.eof() || fd.fail() ) 581 { 582 delete[] buf; 583 return false; 584 } 585 } 586 } 587 } 588 else 589 { 590 const UInt mask_y_file=(1<<csy_file)-1; 591 const UInt mask_y_src =(1<<csy_src )-1; 592 for(UInt y444=0; y444<height444; y444++) 593 { 594 if ((y444&mask_y_file)==0) 595 { 596 for (UInt field = 0; field < 2; field++) 597 { 598 UChar *fieldBuffer = buf + (field * stride_file); 599 Pel *src = (((field == 0) && isTff) || ((field == 1) && (!isTff))) ? top : bottom; 600 601 // write a new line 602 if (csx_file < csx_src) 603 { 604 // eg file is 444, source is 422. 605 const UInt sx=csx_src-csx_file; 606 if (!is16bit) 607 { 608 for (UInt x = 0; x < width_file; x++) 609 { 610 fieldBuffer[x] = (UChar)(src[x>>sx]); 611 } 612 } 613 else 614 { 615 for (UInt x = 0; x < width_file; x++) 616 { 617 fieldBuffer[2*x ] = (src[x>>sx]>>0) & 0xff; 618 fieldBuffer[2*x+1] = (src[x>>sx]>>8) & 0xff; 619 } 620 } 621 } 622 else 623 { 624 // eg file is 422, src is 444. 625 const UInt sx=csx_file-csx_src; 626 if (!is16bit) 627 { 628 for (UInt x = 0; x < width_file; x++) 629 { 630 fieldBuffer[x] = (UChar)(src[x<<sx]); 631 } 632 } 633 else 634 { 635 for (UInt x = 0; x < width_file; x++) 636 { 637 fieldBuffer[2*x ] = (src[x<<sx]>>0) & 0xff; 638 fieldBuffer[2*x+1] = (src[x<<sx]>>8) & 0xff; 639 } 640 } 641 } 642 } 643 644 fd.write(reinterpret_cast<Char*>(buf), (stride_file * 2)); 645 if (fd.eof() || fd.fail() ) 646 { 647 delete[] buf; 648 return false; 649 } 650 } 651 652 if ((y444&mask_y_src)==0) 653 { 654 top += stride_src; 655 bottom += stride_src; 656 } 657 658 } 377 659 } 378 660 delete[] buf; 379 661 return true; 380 662 } 663 381 664 /** 382 665 * Read one Y'CbCr frame, performing any required input scaling to change … … 388 671 * file had been provided at the lower-bitdepth compliant to Rec601/709. 389 672 * 390 * @param pPicYuv input picture YUV buffer class pointer 391 * @param aiPad source padding size, aiPad[0] = horizontal, aiPad[1] = vertical 673 * @param pPicYuvUser input picture YUV buffer class pointer 674 * @param pPicYuvTrueOrg 675 * @param ipcsc 676 * @param aiPad source padding size, aiPad[0] = horizontal, aiPad[1] = vertical 677 * @param format chroma format 392 678 * @return true for success, false in case of error 393 679 */ 394 Bool TVideoIOYuv::read ( TComPicYuv* pPicYuv , Int aiPad[2])680 Bool TVideoIOYuv::read ( TComPicYuv* pPicYuvUser, TComPicYuv* pPicYuvTrueOrg, const InputColourSpaceConversion ipcsc, Int aiPad[2], ChromaFormat format, const Bool bClipToRec709 ) 395 681 { 396 682 // check end-of-file 397 if ( isEof() ) return false; 398 399 Int iStride = pPicYuv->getStride(); 400 683 if ( isEof() ) 684 { 685 return false; 686 } 687 TComPicYuv *pPicYuv=pPicYuvTrueOrg; 688 if (format>=NUM_CHROMA_FORMAT) 689 { 690 format=pPicYuv->getChromaFormat(); 691 } 692 693 Bool is16bit = false; 694 695 for(UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++) 696 { 697 if (m_fileBitdepth[ch] > 8) 698 { 699 is16bit=true; 700 } 701 } 702 703 const UInt stride444 = pPicYuv->getStride(COMPONENT_Y); 704 401 705 // 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); 706 const UInt pad_h444 = aiPad[0]; 707 const UInt pad_v444 = aiPad[1]; 708 709 const UInt width_full444 = pPicYuv->getWidth(COMPONENT_Y); 710 const UInt height_full444 = pPicYuv->getHeight(COMPONENT_Y); 711 712 const UInt width444 = width_full444 - pad_h444; 713 const UInt height444 = height_full444 - pad_v444; 714 715 for(UInt comp=0; comp<MAX_NUM_COMPONENT; comp++) 716 { 717 const ComponentID compID = ComponentID(comp); 718 const ChannelType chType=toChannelType(compID); 719 720 const Int desired_bitdepth = m_MSBExtendedBitDepth[chType] + m_bitdepthShift[chType]; 721 722 const Bool b709Compliance=(bClipToRec709) && (m_bitdepthShift[chType] < 0 && desired_bitdepth >= 8); /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */ 723 const Pel minval = b709Compliance? (( 1 << (desired_bitdepth - 8)) ) : 0; 724 const Pel maxval = b709Compliance? ((0xff << (desired_bitdepth - 8)) -1) : (1 << desired_bitdepth) - 1; 725 726 if (! readPlane(pPicYuv->getAddr(compID), m_cHandle, is16bit, stride444, width444, height444, pad_h444, pad_v444, compID, pPicYuv->getChromaFormat(), format, m_fileBitdepth[chType])) 727 { 728 return false; 729 } 730 731 if (compID < pPicYuv->getNumberValidComponents() ) 732 { 733 const UInt csx=getComponentScaleX(compID, pPicYuv->getChromaFormat()); 734 const UInt csy=getComponentScaleY(compID, pPicYuv->getChromaFormat()); 735 scalePlane(pPicYuv->getAddr(compID), stride444>>csx, width_full444>>csx, height_full444>>csy, m_bitdepthShift[chType], minval, maxval); 736 } 737 } 738 739 ColourSpaceConvert(*pPicYuvTrueOrg, *pPicYuvUser, ipcsc, true); 450 740 451 741 return true; … … 456 746 * assumed to be at TVideoIO::m_fileBitdepth depth. 457 747 * 458 * @param pPicYuv input picture YUV buffer class pointer 459 * @param aiPad source padding size, aiPad[0] = horizontal, aiPad[1] = vertical 748 * @param pPicYuvUser input picture YUV buffer class pointer 749 * @param ipCSC 750 * @param confLeft conformance window left border 751 * @param confRight conformance window right border 752 * @param confTop conformance window top border 753 * @param confBottom conformance window bottom border 754 * @param format chroma format 460 755 * @return true for success, false in case of error 461 756 */ 462 Bool TVideoIOYuv::write( TComPicYuv* pPicYuv, Int confLeft, Int confRight, Int confTop, Int confBottom ) 463 { 757 Bool TVideoIOYuv::write( TComPicYuv* pPicYuvUser, const InputColourSpaceConversion ipCSC, Int confLeft, Int confRight, Int confTop, Int confBottom, ChromaFormat format, const Bool bClipToRec709 ) 758 { 759 TComPicYuv cPicYuvCSCd; 760 if (ipCSC!=IPCOLOURSPACE_UNCHANGED) 761 { 762 cPicYuvCSCd.create(pPicYuvUser->getWidth(COMPONENT_Y), pPicYuvUser->getHeight(COMPONENT_Y), pPicYuvUser->getChromaFormat(), pPicYuvUser->getWidth(COMPONENT_Y), pPicYuvUser->getHeight(COMPONENT_Y), 0, false); 763 ColourSpaceConvert(*pPicYuvUser, cPicYuvCSCd, ipCSC, false); 764 } 765 TComPicYuv *pPicYuv=(ipCSC==IPCOLOURSPACE_UNCHANGED) ? pPicYuvUser : &cPicYuvCSCd; 766 464 767 // 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; 768 const Int iStride444 = pPicYuv->getStride(COMPONENT_Y); 769 const UInt width444 = pPicYuv->getWidth(COMPONENT_Y) - confLeft - confRight; 770 const UInt height444 = pPicYuv->getHeight(COMPONENT_Y) - confTop - confBottom; 771 Bool is16bit = false; 772 Bool nonZeroBitDepthShift=false; 773 774 if ((width444 == 0) || (height444 == 0)) 775 { 776 printf ("\nWarning: writing %d x %d luma sample output picture!", width444, height444); 777 } 778 779 for(UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++) 780 { 781 if (m_fileBitdepth[ch] > 8) 782 { 783 is16bit=true; 784 } 785 if (m_bitdepthShift[ch] != 0) 786 { 787 nonZeroBitDepthShift=true; 788 } 789 } 790 469 791 TComPicYuv *dstPicYuv = NULL; 470 792 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) 793 if (format>=NUM_CHROMA_FORMAT) 794 { 795 format=pPicYuv->getChromaFormat(); 796 } 797 798 if (nonZeroBitDepthShift) 478 799 { 479 800 dstPicYuv = new TComPicYuv; 480 dstPicYuv->create( pPicYuv->getWidth( ), pPicYuv->getHeight(), 1, 1, 0);801 dstPicYuv->create( pPicYuv->getWidth(COMPONENT_Y), pPicYuv->getHeight(COMPONENT_Y), pPicYuv->getChromaFormat(), pPicYuv->getWidth(COMPONENT_Y), pPicYuv->getHeight(COMPONENT_Y), 0, false ); 481 802 pPicYuv->copyToPic(dstPicYuv); 482 803 483 Pel minvalY = 0; 484 Pel minvalC = 0; 485 Pel maxvalY = (1 << m_fileBitDepthY) - 1; 486 Pel maxvalC = (1 << m_fileBitDepthC) - 1; 487 #if CLIP_TO_709_RANGE 488 if (-m_bitDepthShiftY < 0 && m_fileBitDepthY >= 8) 489 { 490 /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */ 491 minvalY = 1 << (m_fileBitDepthY - 8); 492 maxvalY = (0xff << (m_fileBitDepthY - 8)) -1; 493 } 494 if (-m_bitDepthShiftC < 0 && m_fileBitDepthC >= 8) 495 { 496 /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */ 497 minvalC = 1 << (m_fileBitDepthC - 8); 498 maxvalC = (0xff << (m_fileBitDepthC - 8)) -1; 499 } 804 for(UInt comp=0; comp<dstPicYuv->getNumberValidComponents(); comp++) 805 { 806 const ComponentID compID=ComponentID(comp); 807 const ChannelType ch=toChannelType(compID); 808 const Bool b709Compliance = bClipToRec709 && (-m_bitdepthShift[ch] < 0 && m_MSBExtendedBitDepth[ch] >= 8); /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */ 809 const Pel minval = b709Compliance? (( 1 << (m_MSBExtendedBitDepth[ch] - 8)) ) : 0; 810 const Pel maxval = b709Compliance? ((0xff << (m_MSBExtendedBitDepth[ch] - 8)) -1) : (1 << m_MSBExtendedBitDepth[ch]) - 1; 811 812 scalePlane(dstPicYuv->getAddr(compID), dstPicYuv->getStride(compID), dstPicYuv->getWidth(compID), dstPicYuv->getHeight(compID), -m_bitdepthShift[ch], minval, maxval); 813 } 814 } 815 else 816 { 817 dstPicYuv = pPicYuv; 818 } 819 #if NH_3D 820 for(UInt comp=0; retval && comp< ::getNumberValidComponents(format); comp++) 821 #else 822 for(UInt comp=0; retval && comp<dstPicYuv->getNumberValidComponents(); comp++) 500 823 #endif 501 scalePlane(dstPicYuv->getLumaAddr(), dstPicYuv->getStride(), dstPicYuv->getWidth(), dstPicYuv->getHeight(), -m_bitDepthShiftY, minvalY, maxvalY); 502 scalePlane(dstPicYuv->getCbAddr(), dstPicYuv->getCStride(), dstPicYuv->getWidth()>>1, dstPicYuv->getHeight()>>1, -m_bitDepthShiftC, minvalC, maxvalC); 503 scalePlane(dstPicYuv->getCrAddr(), dstPicYuv->getCStride(), dstPicYuv->getWidth()>>1, dstPicYuv->getHeight()>>1, -m_bitDepthShiftC, minvalC, maxvalC); 504 } 505 else 506 { 507 dstPicYuv = pPicYuv; 508 } 509 // location of upper left pel in a plane 510 Int planeOffset = confLeft + confTop * iStride; 511 512 if (! writePlane(m_cHandle, dstPicYuv->getLumaAddr() + planeOffset, is16bit, iStride, width, height)) 513 { 514 retval=false; 515 goto exit; 516 } 517 518 width >>= 1; 519 height >>= 1; 520 iStride >>= 1; 521 confLeft >>= 1; 522 confRight >>= 1; 523 confTop >>= 1; 524 confBottom >>= 1; 525 526 planeOffset = confLeft + confTop * iStride; 527 528 if (! writePlane(m_cHandle, dstPicYuv->getCbAddr() + planeOffset, is16bit, iStride, width, height)) 529 { 530 retval=false; 531 goto exit; 532 } 533 if (! writePlane(m_cHandle, dstPicYuv->getCrAddr() + planeOffset, is16bit, iStride, width, height)) 534 { 535 retval=false; 536 goto exit; 537 } 538 539 exit: 540 if (m_bitDepthShiftY != 0 || m_bitDepthShiftC != 0) 824 { 825 const ComponentID compID = ComponentID(comp); 826 const ChannelType ch=toChannelType(compID); 827 const UInt csx = pPicYuv->getComponentScaleX(compID); 828 const UInt csy = pPicYuv->getComponentScaleY(compID); 829 const Int planeOffset = (confLeft>>csx) + (confTop>>csy) * pPicYuv->getStride(compID); 830 if (! writePlane(m_cHandle, dstPicYuv->getAddr(compID) + planeOffset, is16bit, iStride444, width444, height444, compID, dstPicYuv->getChromaFormat(), format, m_fileBitdepth[ch])) 831 { 832 retval=false; 833 } 834 } 835 836 if (nonZeroBitDepthShift) 541 837 { 542 838 dstPicYuv->destroy(); 543 839 delete dstPicYuv; 544 } 840 } 841 842 cPicYuvCSCd.destroy(); 843 545 844 return retval; 546 845 } 547 846 548 549 /** 550 * Write one Y'CbCr frame. No bit-depth conversion is performed, pcPicYuv is 551 * assumed to be at TVideoIO::m_fileBitdepth depth. 552 * 553 * @param pPicTop input top field YUV buffer class pointer 554 * @param pPicBottom input bottom field YUV buffer class pointer 555 * @param aiPad source padding size, aiPad[0] = horizontal, aiPad[1] = vertical 556 * @return true for success, false in case of error 557 */ 558 Bool TVideoIOYuv::write( TComPicYuv* pPicTop, TComPicYuv* pPicBottom, Int cropLeft, Int cropRight, Int cropTop, Int cropBottom , bool isTff) 559 { 560 // compute actual YUV frame size excluding padding size 561 Int iStride = pPicTop->getStride(); 562 UInt width = pPicTop->getWidth() - cropLeft - cropRight; 563 UInt height = pPicTop->getHeight() - cropTop - cropBottom; 564 Bool is16bit = m_fileBitDepthY > 8 || m_fileBitDepthC > 8; 565 566 TComPicYuv *dstPicTop = NULL; 567 TComPicYuv *dstPicBottom = NULL; 568 847 Bool TVideoIOYuv::write( TComPicYuv* pPicYuvUserTop, TComPicYuv* pPicYuvUserBottom, const InputColourSpaceConversion ipCSC, Int confLeft, Int confRight, Int confTop, Int confBottom, ChromaFormat format, const Bool isTff, const Bool bClipToRec709 ) 848 { 849 850 TComPicYuv cPicYuvTopCSCd; 851 TComPicYuv cPicYuvBottomCSCd; 852 if (ipCSC!=IPCOLOURSPACE_UNCHANGED) 853 { 854 cPicYuvTopCSCd .create(pPicYuvUserTop ->getWidth(COMPONENT_Y), pPicYuvUserTop ->getHeight(COMPONENT_Y), pPicYuvUserTop ->getChromaFormat(), pPicYuvUserTop ->getWidth(COMPONENT_Y), pPicYuvUserTop ->getHeight(COMPONENT_Y), 0, false); 855 cPicYuvBottomCSCd.create(pPicYuvUserBottom->getWidth(COMPONENT_Y), pPicYuvUserBottom->getHeight(COMPONENT_Y), pPicYuvUserBottom->getChromaFormat(), pPicYuvUserBottom->getWidth(COMPONENT_Y), pPicYuvUserBottom->getHeight(COMPONENT_Y), 0, false); 856 ColourSpaceConvert(*pPicYuvUserTop, cPicYuvTopCSCd, ipCSC, false); 857 ColourSpaceConvert(*pPicYuvUserBottom, cPicYuvBottomCSCd, ipCSC, false); 858 } 859 TComPicYuv *pPicYuvTop = (ipCSC==IPCOLOURSPACE_UNCHANGED) ? pPicYuvUserTop : &cPicYuvTopCSCd; 860 TComPicYuv *pPicYuvBottom = (ipCSC==IPCOLOURSPACE_UNCHANGED) ? pPicYuvUserBottom : &cPicYuvBottomCSCd; 861 862 Bool is16bit = false; 863 Bool nonZeroBitDepthShift=false; 864 865 for(UInt ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++) 866 { 867 if (m_fileBitdepth[ch] > 8) 868 { 869 is16bit=true; 870 } 871 if (m_bitdepthShift[ch] != 0) 872 { 873 nonZeroBitDepthShift=true; 874 } 875 } 876 877 TComPicYuv *dstPicYuvTop = NULL; 878 TComPicYuv *dstPicYuvBottom = NULL; 879 880 for (UInt field = 0; field < 2; field++) 881 { 882 TComPicYuv *pPicYuv = (field == 0) ? pPicYuvTop : pPicYuvBottom; 883 884 if (format>=NUM_CHROMA_FORMAT) 885 { 886 format=pPicYuv->getChromaFormat(); 887 } 888 889 TComPicYuv* &dstPicYuv = (field == 0) ? dstPicYuvTop : dstPicYuvBottom; 890 891 if (nonZeroBitDepthShift) 892 { 893 dstPicYuv = new TComPicYuv; 894 dstPicYuv->create( pPicYuv->getWidth(COMPONENT_Y), pPicYuv->getHeight(COMPONENT_Y), pPicYuv->getChromaFormat(), pPicYuv->getWidth(COMPONENT_Y), pPicYuv->getHeight(COMPONENT_Y), 0, false ); 895 pPicYuv->copyToPic(dstPicYuv); 896 897 for(UInt comp=0; comp<dstPicYuv->getNumberValidComponents(); comp++) 898 { 899 const ComponentID compID=ComponentID(comp); 900 const ChannelType ch=toChannelType(compID); 901 const Bool b709Compliance=bClipToRec709 && (-m_bitdepthShift[ch] < 0 && m_MSBExtendedBitDepth[ch] >= 8); /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */ 902 const Pel minval = b709Compliance? (( 1 << (m_MSBExtendedBitDepth[ch] - 8)) ) : 0; 903 const Pel maxval = b709Compliance? ((0xff << (m_MSBExtendedBitDepth[ch] - 8)) -1) : (1 << m_MSBExtendedBitDepth[ch]) - 1; 904 905 scalePlane(dstPicYuv->getAddr(compID), dstPicYuv->getStride(compID), dstPicYuv->getWidth(compID), dstPicYuv->getHeight(compID), -m_bitdepthShift[ch], minval, maxval); 906 } 907 } 908 else 909 { 910 dstPicYuv = pPicYuv; 911 } 912 } 913 569 914 Bool retval = true; 570 571 if ((width==0)||(height==0)) 572 { 573 printf ("\nWarning: writing %d x %d luma sample output picture!", width, height); 574 } 575 576 if (m_bitDepthShiftY != 0 || m_bitDepthShiftC != 0) 577 { 578 dstPicTop = new TComPicYuv; 579 dstPicTop->create( pPicTop->getWidth(), pPicTop->getHeight(), 1, 1, 0 ); 580 pPicTop->copyToPic(dstPicTop); 581 582 dstPicBottom = new TComPicYuv; 583 dstPicBottom->create( pPicBottom->getWidth(), pPicBottom->getHeight(), 1, 1, 0 ); 584 pPicBottom->copyToPic(dstPicBottom); 585 586 Pel minvalY = 0; 587 Pel minvalC = 0; 588 Pel maxvalY = (1 << m_fileBitDepthY) - 1; 589 Pel maxvalC = (1 << m_fileBitDepthC) - 1; 590 #if CLIP_TO_709_RANGE 591 if (-m_bitDepthShiftY < 0 && m_fileBitDepthY >= 8) 592 { 593 /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */ 594 minvalY = 1 << (m_fileBitDepthY - 8); 595 maxvalY = (0xff << (m_fileBitDepthY - 8)) -1; 596 } 597 if (-m_bitDepthShiftC < 0 && m_fileBitDepthC >= 8) 598 { 599 /* ITU-R BT.709 compliant clipping for converting say 10b to 8b */ 600 minvalC = 1 << (m_fileBitDepthC - 8); 601 maxvalC = (0xff << (m_fileBitDepthC - 8)) -1; 602 } 603 #endif 604 scalePlane(dstPicTop->getLumaAddr(), dstPicTop->getStride(), dstPicTop->getWidth(), dstPicTop->getHeight(), -m_bitDepthShiftY, minvalY, maxvalY); 605 scalePlane(dstPicTop->getCbAddr(), dstPicTop->getCStride(), dstPicTop->getWidth()>>1, dstPicTop->getHeight()>>1, -m_bitDepthShiftC, minvalC, maxvalC); 606 scalePlane(dstPicTop->getCrAddr(), dstPicTop->getCStride(), dstPicTop->getWidth()>>1, dstPicTop->getHeight()>>1, -m_bitDepthShiftC, minvalC, maxvalC); 607 608 scalePlane(dstPicBottom->getLumaAddr(), dstPicBottom->getStride(), dstPicBottom->getWidth(), dstPicBottom->getHeight(), -m_bitDepthShiftY, minvalY, maxvalY); 609 scalePlane(dstPicBottom->getCbAddr(), dstPicBottom->getCStride(), dstPicBottom->getWidth()>>1, dstPicBottom->getHeight()>>1, -m_bitDepthShiftC, minvalC, maxvalC); 610 scalePlane(dstPicBottom->getCrAddr(), dstPicBottom->getCStride(), dstPicBottom->getWidth()>>1, dstPicBottom->getHeight()>>1, -m_bitDepthShiftC, minvalC, maxvalC); 611 } 612 else 613 { 614 dstPicTop = pPicTop; 615 dstPicBottom = pPicBottom; 616 } 617 // location of upper left pel in a plane 618 Int planeOffset = 0; //cropLeft + cropTop * iStride; 619 //Write luma 620 if (! writeField(m_cHandle, dstPicTop->getLumaAddr() + planeOffset, dstPicBottom->getLumaAddr() + planeOffset, is16bit, iStride, width, height, isTff)) 621 { 622 retval=false; 623 goto exit; 624 } 625 626 width >>= 1; 627 height >>= 1; 628 iStride >>= 1; 629 cropLeft >>= 1; 630 cropRight >>= 1; 631 632 planeOffset = 0; // cropLeft + cropTop * iStride; 633 634 //Write chroma U 635 if (! writeField(m_cHandle, dstPicTop->getCbAddr() + planeOffset, dstPicBottom->getCbAddr() + planeOffset, is16bit, iStride, width, height, isTff)) 636 { 637 retval=false; 638 goto exit; 639 } 640 641 //Write chroma V 642 if (! writeField(m_cHandle, dstPicTop->getCrAddr() + planeOffset, dstPicBottom->getCrAddr() + planeOffset, is16bit, iStride, width, height, isTff)) 643 644 { 645 retval=false; 646 goto exit; 647 } 648 649 exit: 650 if (m_bitDepthShiftY != 0 || m_bitDepthShiftC != 0) 651 { 652 dstPicTop->destroy(); 653 delete dstPicTop; 654 dstPicBottom->destroy(); 655 delete dstPicBottom; 656 } 915 916 assert(dstPicYuvTop->getNumberValidComponents() == dstPicYuvBottom->getNumberValidComponents()); 917 assert(dstPicYuvTop->getChromaFormat() == dstPicYuvBottom->getChromaFormat() ); 918 assert(dstPicYuvTop->getWidth(COMPONENT_Y) == dstPicYuvBottom->getWidth(COMPONENT_Y) ); 919 assert(dstPicYuvTop->getHeight(COMPONENT_Y) == dstPicYuvBottom->getHeight(COMPONENT_Y) ); 920 assert(dstPicYuvTop->getStride(COMPONENT_Y) == dstPicYuvBottom->getStride(COMPONENT_Y) ); 921 922 for(UInt comp=0; retval && comp<dstPicYuvTop->getNumberValidComponents(); comp++) 923 { 924 const ComponentID compID = ComponentID(comp); 925 const ChannelType ch=toChannelType(compID); 926 927 assert(dstPicYuvTop->getComponentScaleX(compID) == dstPicYuvBottom->getComponentScaleX(compID)); 928 assert(dstPicYuvTop->getComponentScaleY(compID) == dstPicYuvBottom->getComponentScaleY(compID)); 929 assert(dstPicYuvTop->getStride (compID) == dstPicYuvBottom->getStride (compID)); 930 931 const UInt width444 = dstPicYuvTop->getWidth(COMPONENT_Y) - (confLeft + confRight); 932 const UInt height444 = dstPicYuvTop->getHeight(COMPONENT_Y) - (confTop + confBottom); 933 934 if ((width444 == 0) || (height444 == 0)) 935 { 936 printf ("\nWarning: writing %d x %d luma sample output picture!", width444, height444); 937 } 938 939 const UInt csx = dstPicYuvTop->getComponentScaleX(compID); 940 const UInt csy = dstPicYuvTop->getComponentScaleY(compID); 941 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 942 943 if (! writeField(m_cHandle, 944 (dstPicYuvTop ->getAddr(compID) + planeOffset), 945 (dstPicYuvBottom->getAddr(compID) + planeOffset), 946 is16bit, 947 dstPicYuvTop->getStride(COMPONENT_Y), 948 width444, height444, compID, dstPicYuvTop->getChromaFormat(), format, m_fileBitdepth[ch], isTff)) 949 { 950 retval=false; 951 } 952 } 953 954 if (nonZeroBitDepthShift) 955 { 956 dstPicYuvTop->destroy(); 957 dstPicYuvBottom->destroy(); 958 delete dstPicYuvTop; 959 delete dstPicYuvBottom; 960 } 961 962 cPicYuvTopCSCd.destroy(); 963 cPicYuvBottomCSCd.destroy(); 964 657 965 return retval; 658 966 } 967 968 static Void 969 copyPlane(const TComPicYuv &src, const ComponentID srcPlane, TComPicYuv &dest, const ComponentID destPlane) 970 { 971 const UInt width=src.getWidth(srcPlane); 972 const UInt height=src.getHeight(srcPlane); 973 assert(dest.getWidth(destPlane) == width); 974 assert(dest.getHeight(destPlane) == height); 975 const Pel *pSrc=src.getAddr(srcPlane); 976 Pel *pDest=dest.getAddr(destPlane); 977 const UInt strideSrc=src.getStride(srcPlane); 978 const UInt strideDest=dest.getStride(destPlane); 979 for(UInt y=0; y<height; y++, pSrc+=strideSrc, pDest+=strideDest) 980 { 981 memcpy(pDest, pSrc, width*sizeof(Pel)); 982 } 983 } 984 985 // static member 986 Void TVideoIOYuv::ColourSpaceConvert(const TComPicYuv &src, TComPicYuv &dest, const InputColourSpaceConversion conversion, Bool bIsForwards) 987 { 988 const ChromaFormat format=src.getChromaFormat(); 989 const UInt numValidComp=src.getNumberValidComponents(); 990 991 switch (conversion) 992 { 993 case IPCOLOURSPACE_YCbCrtoYYY: 994 if (format!=CHROMA_444) 995 { 996 // only 444 is handled. 997 assert(format==CHROMA_444); 998 exit(1); 999 } 1000 1001 { 1002 for(UInt comp=0; comp<numValidComp; comp++) 1003 { 1004 copyPlane(src, ComponentID(bIsForwards?0:comp), dest, ComponentID(comp)); 1005 } 1006 } 1007 break; 1008 case IPCOLOURSPACE_YCbCrtoYCrCb: 1009 { 1010 for(UInt comp=0; comp<numValidComp; comp++) 1011 { 1012 copyPlane(src, ComponentID(comp), dest, ComponentID((numValidComp-comp)%numValidComp)); 1013 } 1014 } 1015 break; 1016 1017 case IPCOLOURSPACE_RGBtoGBR: 1018 { 1019 if (format!=CHROMA_444) 1020 { 1021 // only 444 is handled. 1022 assert(format==CHROMA_444); 1023 exit(1); 1024 } 1025 1026 // channel re-mapping 1027 for(UInt comp=0; comp<numValidComp; comp++) 1028 { 1029 const ComponentID compIDsrc=ComponentID((comp+1)%numValidComp); 1030 const ComponentID compIDdst=ComponentID(comp); 1031 copyPlane(src, bIsForwards?compIDsrc:compIDdst, dest, bIsForwards?compIDdst:compIDsrc); 1032 } 1033 } 1034 break; 1035 1036 case IPCOLOURSPACE_UNCHANGED: 1037 default: 1038 { 1039 for(UInt comp=0; comp<numValidComp; comp++) 1040 { 1041 copyPlane(src, ComponentID(comp), dest, ComponentID(comp)); 1042 } 1043 } 1044 break; 1045 } 1046 } -
branches/HTM-14.1-update-dev0/source/Lib/TLibVideoIO/TVideoIOYuv.h
r1179 r1200 2 2 * License, included below. This software may be subject to other third party 3 3 * and contributor rights, including patent rights, and no such rights are 4 * granted under this license. 4 * granted under this license. 5 5 * 6 * Copyright (c) 2010-2015, ITU/ISO/IEC6 * Copyright (c) 2010-2015, ITU/ISO/IEC 7 7 * All rights reserved. 8 8 * … … 56 56 private: 57 57 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 63 62 public: 64 63 TVideoIOYuv() {} 65 64 virtual ~TVideoIOYuv() {} 66 67 Void open ( Char* pchFile, Bool bWriteMode, Int fileBitDepthY, Int fileBitDepthC, Int internalBitDepthY, Int internalBitDepthC); ///< open or create file65 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 68 67 Void close (); ///< close file 69 68 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 // If fileFormat=NUM_CHROMA_FORMAT, use the format defined by pPicYuvTrueOrg 75 Bool read ( TComPicYuv* pPicYuv, TComPicYuv* pPicYuvTrueOrg, const InputColourSpaceConversion ipcsc, Int aiPad[2], ChromaFormat fileFormat=NUM_CHROMA_FORMAT, const Bool bClipToRec709=false ); ///< read one frame with padding parameter 76 77 // If fileFormat=NUM_CHROMA_FORMAT, use the format defined by pPicYuv 78 Bool write ( TComPicYuv* pPicYuv, const InputColourSpaceConversion ipCSC, Int confLeft=0, Int confRight=0, Int confTop=0, Int confBottom=0, ChromaFormat fileFormat=NUM_CHROMA_FORMAT, const Bool bClipToRec709=false ); ///< write one YUV frame with padding parameter 79 80 // If fileFormat=NUM_CHROMA_FORMAT, use the format defined by pPicYuvTop and pPicYuvBottom 81 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, const Bool isTff=false, const Bool bClipToRec709=false); 82 static Void ColourSpaceConvert(const TComPicYuv &src, TComPicYuv &dest, const InputColourSpaceConversion conversion, Bool bIsForwards); 83 76 84 Bool isEof (); ///< check for end-of-file 77 85 Bool isFail(); ///< check for failure 78 86 87 79 88 }; 80 89
Note: See TracChangeset for help on using the changeset viewer.