libcvd-members
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libcvd-members] libcvd/cvd_src/NEON convert_rgb_to_y.cc


From: Gerhard Reitmayr
Subject: [libcvd-members] libcvd/cvd_src/NEON convert_rgb_to_y.cc
Date: Wed, 11 May 2011 15:02:05 +0000

CVSROOT:        /cvsroot/libcvd
Module name:    libcvd
Changes by:     Gerhard Reitmayr <gerhard>      11/05/11 15:02:05

Added files:
        cvd_src/NEON   : convert_rgb_to_y.cc 

Log message:
        added rgb to grey conversion for NEON

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/libcvd/cvd_src/NEON/convert_rgb_to_y.cc?cvsroot=libcvd&rev=1.1

Patches:
Index: convert_rgb_to_y.cc
===================================================================
RCS file: convert_rgb_to_y.cc
diff -N convert_rgb_to_y.cc
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ convert_rgb_to_y.cc 11 May 2011 15:02:05 -0000      1.1
@@ -0,0 +1,53 @@
+#include <cvd/config.h>
+#include <cvd/image_convert.h>
+#include <cvd/utility.h>
+#include <arm_neon.h>
+
+namespace CVD {
+
+       namespace Internal {
+               void convert_rgb_to_grey_NEON(const SubImage<Rgb<byte> >& from, 
SubImage<byte>& to, const unsigned red, const unsigned green, const unsigned 
blue) 
+                       const uint16x8_t red = vdupq_n_u16(red);
+                       const uint16x8_t green = vdupq_n_u16(green);
+                       const uint16x8_t blue = vdupq_n_u16(blue);
+                       
+                       for( int y = 0; y < from.size().y; ++y){
+                               const Rgb<byte> * in = from[y];
+                               byte * out = out[y];
+                               for( int x = 0; x < from.size().x; x+=8, in += 
8, out += 8){
+                                       uint8x8x3_t in_data  = vld3_u8((const 
uint8_t *)in);
+
+                                       uint16x8_t sum = vmulq_u16(in_data[0], 
red);
+                                       sum = vmlaq_u16(sum, in_data[1], green);
+                                       sum = vmlaq_u16(sum, in_data[2], blue);
+
+                                       uint8x8_t final_sum = vshrn_n_u16(sum, 
8); // divide by 256
+                                       vst1_u8(out_data, final_sum);
+                               }
+                       }
+               }
+       }
+
+       void ConvertImage<Rgb<byte>, byte, Pixel::CIE<Rgb<byte>, byte>, 
1>::convert(const SubImage<Rgb<byte> >& from, SubImage<byte>& to) 
+       {
+
+               if((from.size().x % 8) == 0){
+               // red (77) + green (150) + blue (29) = 256
+               Internal::convert_rgb_to_grey_NEON( from, to, 77, 150, 29);
+               } else {
+                       const int multiple_of_8_width = (from.size().x / 8) * 8;
+                       const int remainder = from.size().x - 
multiple_of_8_width;
+                       const ImageRef end_fast(multiple_of_8_width, 
from.size().y);
+
+                       Internal::convert_rgb_to_grey_NEON( 
from.sub_image(ImageRef_zero, end_fast), to.sub_image(ImageRef_zero, end_fast), 
77, 150, 29);
+                       
+                       for(int y = 0; y < from.size().y; ++y){
+                               const Rgb<byte> * in = 
from[y]+multiple_of_8_width;
+                               byte * out = to[y]+multiple_of_8_width;
+                               for(int x = multiple_of_8_width; x < 
from.size().x; ++x, ++in, ++out){
+                                       
Pixel::CIE<Rgb<byte>,byte>::convert(*in, *out);
+                               }
+                       }
+               }
+       }
+}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]