@@ -377,77 +377,92 @@ private ValueGetter<VBuffer<TValue>> GetGetterCore<TValue>(DataViewRow input, in
377377
378378 ImagePixelExtractingEstimator . GetOrder ( ex . OrderOfExtraction , ex . ColorsToExtract , out int a , out int r , out int b , out int g ) ;
379379
380- int h = height ;
381- int w = width ;
382-
383- if ( ex . InterleavePixelColors )
380+ BitmapData bmpData = null ;
381+ try
384382 {
385- int idst = 0 ;
386- for ( int y = 0 ; y < h ; ++ y )
387- for ( int x = 0 ; x < w ; x ++ )
383+ bmpData = src . LockBits ( new Rectangle ( 0 , 0 , src . Width , src . Height ) , ImageLockMode . ReadOnly , src . PixelFormat ) ;
384+ int h = height ;
385+ int w = width ;
386+ byte [ ] row = new byte [ bmpData . Stride ] ;
387+ int pixelSize = System . Drawing . Image . GetPixelFormatSize ( src . PixelFormat ) / 8 ;
388+ Func < int , byte > alpha = pixelSize > 3 ? new Func < int , byte > ( ix => row [ ix + 3 ] ) : new Func < int , byte > ( ix => 255 ) ;
389+
390+ if ( ex . InterleavePixelColors )
391+ {
392+ int idst = 0 ;
393+ for ( int y = 0 ; y < h ; ++ y )
388394 {
389- var pb = src . GetPixel ( x , y ) ;
390- if ( ! vb . IsEmpty )
391- {
392- if ( a != - 1 ) { vb [ idst + a ] = pb . A ; }
393- if ( r != - 1 ) { vb [ idst + r ] = pb . R ; }
394- if ( g != - 1 ) { vb [ idst + g ] = pb . G ; }
395- if ( b != - 1 ) { vb [ idst + b ] = pb . B ; }
396- }
397- else if ( ! needScale )
395+ Marshal . Copy ( bmpData . Scan0 + bmpData . Stride * y , row , 0 , bmpData . Stride ) ;
396+ for ( int x = 0 ; x < w ; x ++ )
398397 {
399- if ( a != - 1 ) { vf [ idst + a ] = pb . A ; }
400- if ( r != - 1 ) { vf [ idst + r ] = pb . R ; }
401- if ( g != - 1 ) { vf [ idst + g ] = pb . G ; }
402- if ( b != - 1 ) { vf [ idst + b ] = pb . B ; }
398+ var ix = x * pixelSize ;
399+ if ( ! vb . IsEmpty )
400+ {
401+ if ( a != - 1 ) { vb [ idst + a ] = alpha ( ix ) ; }
402+ if ( r != - 1 ) { vb [ idst + r ] = row [ ix + 2 ] ; }
403+ if ( g != - 1 ) { vb [ idst + g ] = row [ ix + 1 ] ; }
404+ if ( b != - 1 ) { vb [ idst + b ] = row [ ix + 0 ] ; }
405+ }
406+ else if ( ! needScale )
407+ {
408+ if ( a != - 1 ) { vf [ idst + a ] = alpha ( ix ) ; }
409+ if ( r != - 1 ) { vf [ idst + r ] = row [ ix + 2 ] ; }
410+ if ( g != - 1 ) { vf [ idst + g ] = row [ ix + 1 ] ; }
411+ if ( b != - 1 ) { vf [ idst + b ] = row [ ix + 0 ] ; }
412+ }
413+ else
414+ {
415+
416+ if ( a != - 1 ) { vf [ idst + a ] = ( alpha ( ix ) - offset ) * scale ; }
417+ if ( r != - 1 ) { vf [ idst + r ] = ( row [ ix + 2 ] - offset ) * scale ; }
418+ if ( g != - 1 ) { vf [ idst + g ] = ( row [ ix + 1 ] - offset ) * scale ; }
419+ if ( b != - 1 ) { vf [ idst + b ] = ( row [ ix + 0 ] - offset ) * scale ; }
420+ }
421+ idst += ex . Planes ;
403422 }
404- else
405- {
406-
407- if ( a != - 1 ) { vf [ idst + a ] = ( pb . A - offset ) * scale ; }
408- if ( r != - 1 ) { vf [ idst + r ] = ( pb . R - offset ) * scale ; }
409- if ( g != - 1 ) { vf [ idst + g ] = ( pb . G - offset ) * scale ; }
410- if ( b != - 1 ) { vf [ idst + b ] = ( pb . B - offset ) * scale ; }
411- }
412- idst += ex . Planes ;
413423 }
414- Contracts . Assert ( idst == size ) ;
415- }
416- else
417- {
418- int idstMin = 0 ;
419- for ( int y = 0 ; y < h ; ++ y )
424+ Contracts . Assert ( idst == size ) ;
425+ }
426+ else
420427 {
421- int idst = idstMin + y * w ;
422- for ( int x = 0 ; x < w ; x ++ , idst ++ )
428+ int idstMin = 0 ;
429+ for ( int y = 0 ; y < h ; ++ y )
423430 {
424- if ( ! vb . IsEmpty )
425- {
426- var pb = src . GetPixel ( x , y ) ;
427- if ( a != - 1 ) vb [ idst + cpix * a ] = pb . A ;
428- if ( r != - 1 ) vb [ idst + cpix * r ] = pb . R ;
429- if ( g != - 1 ) vb [ idst + cpix * g ] = pb . G ;
430- if ( b != - 1 ) vb [ idst + cpix * b ] = pb . B ;
431- }
432- else if ( ! needScale )
431+ Marshal . Copy ( bmpData . Scan0 + bmpData . Stride * y , row , 0 , bmpData . Stride ) ;
432+ int idst = idstMin + y * w ;
433+ for ( int x = 0 ; x < w ; x ++ , idst ++ )
433434 {
434- var pb = src . GetPixel ( x , y ) ;
435- if ( a != - 1 ) vf [ idst + cpix * a ] = pb . A ;
436- if ( r != - 1 ) vf [ idst + cpix * r ] = pb . R ;
437- if ( g != - 1 ) vf [ idst + cpix * g ] = pb . G ;
438- if ( b != - 1 ) vf [ idst + cpix * b ] = pb . B ;
439- }
440- else
441- {
442- var pb = src . GetPixel ( x , y ) ;
443- if ( a != - 1 ) vf [ idst + cpix * a ] = ( pb . A - offset ) * scale ;
444- if ( r != - 1 ) vf [ idst + cpix * r ] = ( pb . R - offset ) * scale ;
445- if ( g != - 1 ) vf [ idst + cpix * g ] = ( pb . G - offset ) * scale ;
446- if ( b != - 1 ) vf [ idst + cpix * b ] = ( pb . B - offset ) * scale ;
435+ var ix = x * pixelSize ;
436+ if ( ! vb . IsEmpty )
437+ {
438+ if ( a != - 1 ) vb [ idst + cpix * a ] = alpha ( ix ) ;
439+ if ( r != - 1 ) vb [ idst + cpix * r ] = row [ ix + 2 ] ;
440+ if ( g != - 1 ) vb [ idst + cpix * g ] = row [ ix + 1 ] ;
441+ if ( b != - 1 ) vb [ idst + cpix * b ] = row [ ix + 0 ] ;
442+ }
443+ else if ( ! needScale )
444+ {
445+ if ( a != - 1 ) vf [ idst + cpix * a ] = alpha ( ix ) ;
446+ if ( r != - 1 ) vf [ idst + cpix * r ] = row [ ix + 2 ] ;
447+ if ( g != - 1 ) vf [ idst + cpix * g ] = row [ ix + 1 ] ;
448+ if ( b != - 1 ) vf [ idst + cpix * b ] = row [ ix + 0 ] ;
449+ }
450+ else
451+ {
452+ if ( a != - 1 ) vf [ idst + cpix * a ] = ( alpha ( ix ) - offset ) * scale ;
453+ if ( r != - 1 ) vf [ idst + cpix * r ] = ( row [ ix + 2 ] - offset ) * scale ;
454+ if ( g != - 1 ) vf [ idst + cpix * g ] = ( row [ ix + 1 ] - offset ) * scale ;
455+ if ( b != - 1 ) vf [ idst + cpix * b ] = ( row [ ix + 0 ] - offset ) * scale ;
456+ }
447457 }
448458 }
449459 }
450460 }
461+ finally
462+ {
463+ if ( bmpData != null )
464+ src . UnlockBits ( bmpData ) ;
465+ }
451466
452467 dst = editor . Commit ( ) ;
453468 } ;
0 commit comments