import System from './util/System' ; import Exception from './Exception' ; import LuminanceSource from './LuminanceSource' ; import InvertedLuminanceSource from './InvertedLuminanceSource' ; author dswitkin google export default class PlanarYUVLuminanceSource extends LuminanceSource { private static THUMBNAIL_SCALE_FACTOR : number = 2 ; public constructor ( private yuvData , private dataWidth , private dataHeight , private left , private top , width , height , reverseHorizontal ) { super ( width , height ) ; if ( left + width > dataWidth || top + height > dataHeight ) { throw new Exception ( Exception . IllegalArgumentException , "Crop rectangle does not fit within image data." ) ; } if ( reverseHorizontal ) { this . reverseHorizontal ( width , height ) ; } } public getRow ( y , row ? ) { if ( y < 0 || y >= this . getHeight ( ) ) { throw new Exception ( Exception . IllegalArgumentException , "Requested row is outside the image: " + y ) ; } const width = this . getWidth ( ) ; if ( row === null || row === undefined || row . length < width ) { row = new Uint8ClampedArray ( width ) ; } const offset = ( y + this . top ) * this . dataWidth + this . left ; System . arraycopy ( this . yuvData , offset , row , 0 , width ) ; return row ; } public getMatrix ( ) { const width = this . getWidth ( ) ; const height = this . getHeight ( ) ; if ( width == this . dataWidth && height == this . dataHeight ) { return this . yuvData ; } const area = width * height ; const matrix = new Uint8ClampedArray ( area ) ; let inputOffset = this . top * this . dataWidth + this . left ; if ( width === this . dataWidth ) { System . arraycopy ( this . yuvData , inputOffset , matrix , 0 , area ) ; return matrix ; } for ( let y = 0 ; y < height ; y ++ ) { const outputOffset = y * width ; System . arraycopy ( this . yuvData , inputOffset , matrix , outputOffset , width ) ; inputOffset += this . dataWidth ; } return matrix ; } public isCropSupported ( ) { return true ; } public crop ( left , top , width , height ) { return new PlanarYUVLuminanceSource ( this . yuvData , this . dataWidth , this . dataHeight , this . left + left , this . top + top , width , height , false ) ; } public renderThumbnail ( ) { const width = this . getWidth ( ) / PlanarYUVLuminanceSource . THUMBNAIL_SCALE_FACTOR ; const height = this . getHeight ( ) / PlanarYUVLuminanceSource . THUMBNAIL_SCALE_FACTOR ; const pixels = new Int32Array ( width * height ) ; const yuv = this . yuvData ; let inputOffset = this . top * this . dataWidth + this . left ; for ( let y = 0 ; y < height ; y ++ ) { const outputOffset = y * width ; for ( let x = 0 ; x < width ; x ++ ) { const grey = yuv [ inputOffset + x * PlanarYUVLuminanceSource . THUMBNAIL_SCALE_FACTOR ] & 0xff ; pixels [ outputOffset + x ] = 0xFF000000 | ( grey * 0x00010101 ) ; } inputOffset += this . dataWidth * PlanarYUVLuminanceSource . THUMBNAIL_SCALE_FACTOR ; } return pixels ; } return width of image from  {@link #renderThumbnail()} public getThumbnailWidth ( ) { return this . getWidth ( ) / PlanarYUVLuminanceSource . THUMBNAIL_SCALE_FACTOR ; } return height of image from  {@link #renderThumbnail()} public getThumbnailHeight ( ) { return this . getHeight ( ) / PlanarYUVLuminanceSource . THUMBNAIL_SCALE_FACTOR ; } private reverseHorizontal ( width , height ) { const yuvData = this . yuvData ; for ( let y = 0 , rowStart = this . top * this . dataWidth + this . left ; y < height ; y ++ , rowStart += this . dataWidth ) { const middle = rowStart + width / 2 ; for ( let x1 = rowStart , x2 = rowStart + width - 1 ; x1 < middle ; x1 ++ , x2 -- ) { const temp = yuvData [ x1 ] ; yuvData [ x1 ] = yuvData [ x2 ] ; yuvData [ x2 ] = temp ; } } } public invert ( ) { return new InvertedLuminanceSource ( this ) ; } }