1 #define YG 18997 /* round(1.164 * 64 * 256 * 256 / 257) */ 2 #define YGB -1160 /* 1.164 * 64 * -16 + 64 / 2 */ 3 4 #define UB -128 /* max(-128, round(-2.018 * 64)) */ 5 #define UG 25 /* round(0.391 * 64) */ 6 #define VG 52 /* round(0.813 * 64) */ 7 #define VR -102 /* round(-1.596 * 64) */ 8 9 #define BB (UB * 128 + YGB) 10 #define BG (UG * 128 + VG * 128 + YGB) 11 #define BR (VR * 128 + YGB) 12 13 typedef unsigned char sd_uint8; 14 typedef unsigned long sd_uint32; 15 typedef signed long sd_int32; 16 17 sd_int32 clamp0(sd_int32 v) { return ((-(v) >> 31) & (v)); } 18 sd_int32 clamp255(sd_int32 v) { return (((255 - (v)) >> 31) | (v)) & 255; } 19 sd_uint32 Clamp(sd_int32 val) { int v = clamp0(val); return (sd_uint32)(clamp255(v)); } 20 21 void YuvPixel( 22 sd_uint8 y, 23 sd_uint8 u, 24 sd_uint8 v, 25 sd_uint8* b, 26 sd_uint8* g, 27 sd_uint8* r 28 ){ 29 sd_uint32 y1 = (sd_uint32)(y * 0x0101 * YG) >> 16; 30 *r = Clamp((sd_int32)(-(u * UB) + y1 + BB) >> 6); 31 *g = Clamp((sd_int32)(-(v * VG + u * UG) + y1 + BG) >> 6); 32 *b = Clamp((sd_int32)(-(v * VR) + y1 + BR) >> 6); 33 } 34 void NV21ToARGBRow_C( 35 const sd_uint8* src_y, 36 const sd_uint8* src_vu, 37 sd_uint8* rgb_buf, 38 int width 39 ){ 40 int x; 41 for ( x = 0; x < width - 1; x += 2 ) { 42 YuvPixel(src_y[0], src_vu[1], src_vu[0], rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); 43 rgb_buf[3] = 255; 44 YuvPixel(src_y[1], src_vu[1], src_vu[0], rgb_buf + 4, rgb_buf + 5, rgb_buf + 6); 45 rgb_buf[7] = 255; 46 src_y += 2; 47 src_vu += 2; 48 rgb_buf += 8; 49 } 50 if ( width & 1 ) { 51 YuvPixel(src_y[0], src_vu[1], src_vu[0], rgb_buf + 0, rgb_buf + 1, rgb_buf + 2); 52 rgb_buf[3] = 255; 53 } 54 } 55 int NV21ToARGB( 56 const sd_uint8* src_y, 57 int src_stride_y, 58 const sd_uint8* src_uv, 59 int src_stride_uv, 60 sd_uint8* dst_argb, 61 int dst_stride_argb, 62 int width, 63 int height 64 ){ 65 int y; 66 if ( !src_y || !src_uv || !dst_argb || width <= 0 || height == 0 ) { return -1; } 67 for ( y = 0; y < height; ++y ) { 68 NV21ToARGBRow_C(src_y, src_uv, dst_argb, width); 69 dst_argb += dst_stride_argb; 70 src_y += src_stride_y; 71 if ( y & 1 ) { 72 src_uv += src_stride_uv; 73 } 74 } 75 return 0; 76 } 77 int ConvertToARGB( 78 const sd_uint8* sample, // 原图的地址 79 sd_uint8* crop_argb, // RGBA的地址 80 int argb_stride, // should be width * 4 or width must be 1 right 81 int crop_x, // 裁剪的x坐标 82 int crop_y, // 裁剪的y坐标 83 int src_width, // 原图的宽度 84 int src_height, // 原图的高度 85 int crop_width, // 裁剪的宽度 86 int crop_height // 裁剪的高度 87 ){ 88 const sd_uint8* src; 89 const sd_uint8* src_uv; 90 int aligned_src_width = (src_width + 1) & ~1; 91 src = sample + (src_width * crop_y + crop_x); 92 src_uv = sample + aligned_src_width * (src_height + crop_y / 2) + crop_x; 93 // Call NV12 but with u and v parameters swapped. 94 return NV21ToARGB(src, src_width, src_uv, aligned_src_width, crop_argb, argb_stride, crop_width, crop_height); 95 }
时间: 2024-11-08 01:56:15