yuv420sp2rgb.tar.gz

  • seanew
    了解作者
  • C/C++
    开发工具
  • 5KB
    文件大小
  • gz
    文件格式
  • 0
    收藏次数
  • 1 积分
    下载积分
  • 53
    下载次数
  • 2014-07-15 04:41
    上传日期
一个YUV420SP格式转为RGB数据的算法,可以用在很多平台.
yuv420sp2rgb.tar.gz
  • yuv420sp2rgb
  • Android.mk
    286B
  • yuv420sp2rgb.c
    9.1KB
  • debug.c
    1005B
  • cmdline.c
    4.4KB
  • cmdline.h
    405B
  • debug.h
    2.6KB
内容介绍
#include <stdio.h> #include <debug.h> #include <cmdline.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> #include <fcntl.h> #include <string.h> #include <errno.h> #include <unistd.h> #ifndef max #define max(a,b) ({typeof(a) _a = (a); typeof(b) _b = (b); _a > _b ? _a : _b; }) #define min(a,b) ({typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? _a : _b; }) #endif #define CONVERT_TYPE_PPM 0 #define CONVERT_TYPE_RGB 1 #define CONVERT_TYPE_ARGB 2 /* YUV 4:2:0 image with a plane of 8 bit Y samples followed by an interleaved U/V plane containing 8 bit 2x2 subsampled chroma samples. except the interleave order of U and V is reversed. H V Y Sample Period 1 1 U (Cb) Sample Period 2 2 V (Cr) Sample Period 2 2 */ typedef struct rgb_context { unsigned char *buffer; int width; int height; int rotate; int i; int j; int size; /* for debugging */ } rgb_context; typedef void (*rgb_cb)( unsigned char r, unsigned char g, unsigned char b, rgb_context *ctx); const int bytes_per_pixel = 2; static void color_convert_common( unsigned char *pY, unsigned char *pUV, int width, int height, unsigned char *buffer, int size, /* buffer size in bytes */ int gray, int rotate, rgb_cb cb) { int i, j; int nR, nG, nB; int nY, nU, nV; rgb_context ctx; ctx.buffer = buffer; ctx.size = size; /* debug */ ctx.width = width; ctx.height = height; ctx.rotate = rotate; if (gray) { for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { nB = *(pY + i * width + j); ctx.i = i; ctx.j = j; cb(nB, nB, nB, &ctx); } } } else { // YUV 4:2:0 for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { nY = *(pY + i * width + j); nV = *(pUV + (i/2) * width + bytes_per_pixel * (j/2)); nU = *(pUV + (i/2) * width + bytes_per_pixel * (j/2) + 1); // Yuv Convert nY -= 16; nU -= 128; nV -= 128; if (nY < 0) nY = 0; // nR = (int)(1.164 * nY + 2.018 * nU); // nG = (int)(1.164 * nY - 0.813 * nV - 0.391 * nU); // nB = (int)(1.164 * nY + 1.596 * nV); nB = (int)(1192 * nY + 2066 * nU); nG = (int)(1192 * nY - 833 * nV - 400 * nU); nR = (int)(1192 * nY + 1634 * nV); nR = min(262143, max(0, nR)); nG = min(262143, max(0, nG)); nB = min(262143, max(0, nB)); nR >>= 10; nR &= 0xff; nG >>= 10; nG &= 0xff; nB >>= 10; nB &= 0xff; ctx.i = i; ctx.j = j; cb(nR, nG, nB, &ctx); } } } } static void rgb16_cb( unsigned char r, unsigned char g, unsigned char b, rgb_context *ctx) { unsigned short *rgb16 = (unsigned short *)ctx->buffer; *(rgb16 + ctx->i * ctx->width + ctx->j) = b | (g << 5) | (r << 11); } static void common_rgb_cb( unsigned char r, unsigned char g, unsigned char b, rgb_context *ctx, int alpha) { unsigned char *out = ctx->buffer; int offset = 0; int bpp; int i = 0; switch(ctx->rotate) { case 0: /* no rotation */ offset = ctx->i * ctx->width + ctx->j; break; case 1: /* 90 degrees */ offset = ctx->height * (ctx->j + 1) - ctx->i; break; case 2: /* 180 degrees */ offset = (ctx->height - 1 - ctx->i) * ctx->width + ctx->j; break; case 3: /* 270 degrees */ offset = (ctx->width - 1 - ctx->j) * ctx->height + ctx->i; break; default: FAILIF(1, "Unexpected roation value %d!\n", ctx->rotate); } bpp = 3 + !!alpha; offset *= bpp; FAILIF(offset < 0, "point (%d, %d) generates a negative offset.\n", ctx->i, ctx->j); FAILIF(offset + bpp > ctx->size, "point (%d, %d) at offset %d exceeds the size %d of the buffer.\n", ctx->i, ctx->j, offset, ctx->size); out += offset; if (alpha) out[i++] = 0xff; out[i++] = r; out[i++] = g; out[i] = b; } static void rgb24_cb( unsigned char r, unsigned char g, unsigned char b, rgb_context *ctx) { return common_rgb_cb(r,g,b,ctx,0); } static void argb_cb( unsigned char r, unsigned char g, unsigned char b, rgb_context *ctx) { return common_rgb_cb(r,g,b,ctx,1); } static void convert(const char *infile, const char *outfile, int height, int width, int gray, int type, int rotate) { void *in, *out; int ifd, ofd, rc; int psz = getpagesize(); static char header[1024]; int header_size; size_t outsize; int bpp = 3; switch (type) { case CONVERT_TYPE_PPM: PRINT("encoding PPM\n"); if (rotate & 1) header_size = snprintf(header, sizeof(header), "P6\n%d %d\n255\n", height, width); else header_size = snprintf(header, sizeof(header), "P6\n%d %d\n255\n", width, height); break; case CONVERT_TYPE_RGB: PRINT("encoding raw RGB24\n"); header_size = 0; break; case CONVERT_TYPE_ARGB: PRINT("encoding raw ARGB\n"); header_size = 0; bpp = 4; break; } outsize = header_size + width * height * bpp; outsize = (outsize + psz - 1) & ~(psz - 1); INFO("Opening input file %s\n", infile); ifd = open(infile, O_RDONLY); FAILIF(ifd < 0, "open(%s) failed: %s (%d)\n", infile, strerror(errno), errno); INFO("Opening output file %s\n", outfile); ofd = open(outfile, O_RDWR | O_CREAT, 0664); FAILIF(ofd < 0, "open(%s) failed: %s (%d)\n", outfile, strerror(errno), errno); INFO("Memory-mapping input file %s\n", infile); in = mmap(0, width * height * 3 / 2, PROT_READ, MAP_PRIVATE, ifd, 0); FAILIF(in == MAP_FAILED, "could not mmap input file: %s (%d)\n", strerror(errno), errno); INFO("Truncating output file %s to %d bytes\n", outfile, outsize); FAILIF(ftruncate(ofd, outsize) < 0, "Could not truncate output file to required size: %s (%d)\n", strerror(errno), errno); INFO("Memory mapping output file %s\n", outfile); out = mmap(0, outsize, PROT_WRITE, MAP_SHARED, ofd, 0); FAILIF(out == MAP_FAILED, "could not mmap output file: %s (%d)\n", strerror(errno), errno); INFO("PPM header (%d) bytes:\n%s\n", header_size, header); FAILIF(write(ofd, header, header_size) != header_size, "Error wrinting PPM header: %s (%d)\n", strerror(errno), errno); INFO("Converting %dx%d YUV 4:2:0 to RGB24...\n", width, height); color_convert_common(in, in + width * height, width, height, out + header_size, outsize - header_size, gray, rotate, type == CONVERT_TYPE_ARGB ? argb_cb : rgb24_cb); } int verbose_flag; int quiet_flag; int main(int argc, char **argv) { char *infile, *outfile, *type; int height, width, gray, rotate; int cmdline_error = 0; /* Parse command-line arguments. */ int first = get_options(argc, argv, &outfile, &height, &width, &gray, &type, &rotate, &verbose_flag); if (first == argc) { ERROR("You must specify an input file!\n
评论
    相关推荐
    • convert_yuv240p_to_yuv422sp.zip
      yuv格式转换,从yuv420转换为yuv422sp格式,c语言编写,效率较高 需要指定转换的yuv420文件路径,输出yuv422sp文件
    • sp2518_yuv.rar
      基于anroid4.4 MTK平台sp2518摄像头驱动
    • yuv420toyuv422convert.rar
      该程序用来实现yuv420yuv422格式的转换,C语言编写。参数可以从程序中设定!
    • YUV420SP_to_YUV420P.rar
      linux YUV420SP_to_YUV420P转换工具
    • YUVPlayer-master.zip
      将rgb格式转化为yuv格式,也包含可以播放yuv格式视频的播放器
    • YUV420.zip
      YUV420格式的详细数据结构和特点,适合编程准备知识,很有帮助
    • android yuv420sp叠加osd
      将摄像机回调出来的yuv420sp数据叠加osd
    • android 显示yuv图片
      android 显示yuv图片
    • YUVPlayer-master.zip
      yuv player - to play a yuv file
    • codesforimageprocessing.rar
      实现简单图像处理,包括256色转灰度图、Hough变换、Walsh变换、中值滤波、二值化变换、亮度增减、傅立叶变换、反色、取对数、取指数、图像平移、图像旋转、图像细化、图像缩放、图像镜像、均值滤波、对比度拉伸、拉普拉斯锐化(边缘检测)、方块编码、梯度锐化、灰度均衡、直方图均衡、离散余弦变换、维纳滤波处理、逆滤波处理、阈值变换、高斯平滑。