Skip to content

Instantly share code, notes, and snippets.

@OliverUv
Created January 30, 2014 10:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OliverUv/8706203 to your computer and use it in GitHub Desktop.
Save OliverUv/8706203 to your computer and use it in GitHub Desktop.
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define rgbtoy(b, g, r, y) \
y=(unsigned char)(((int)(30*r) + (int)(59*g) + (int)(11*b))/100)
#define rgbtoyuv(b, g, r, y, u, v) \
rgbtoy(b, g, r, y); \
u=(unsigned char)(((int)(-17*r) - (int)(33*g) + (int)(50*b)+12800)/100); \
v=(unsigned char)(((int)(50*r) - (int)(42*g) - (int)(8*b)+12800)/100)
inline int RGBToU(unsigned char r, unsigned char g, unsigned char b)
{
return ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128;
}
inline int RGBToV(unsigned char r, unsigned char g, unsigned char b)
{
return ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128;
}
void RGBToUVRow(const unsigned char* src_rgb0, int src_stride_rgb,
unsigned char* dst_u, unsigned char* dst_v, int width)
{
const unsigned char* src_rgb1 = src_rgb0 + src_stride_rgb;
int x = 0;
for (; x < width - 1; x += 2) {
unsigned char ab = (src_rgb0[0] + src_rgb0[3] + src_rgb1[0] + src_rgb1[3]) >> 2;
unsigned char ag = (src_rgb0[1] + src_rgb0[4] + src_rgb1[1] + src_rgb1[4]) >> 2;
unsigned char ar = (src_rgb0[2] + src_rgb0[5] + src_rgb1[2] + src_rgb1[5]) >> 2;
dst_u[0] = RGBToU(ar, ag, ab);
dst_v[0] = RGBToV(ar, ag, ab);
src_rgb0 += 6;
src_rgb1 += 6;
dst_u += 1;
dst_v += 1;
}
}
inline int RGBToY(unsigned char r, unsigned char g, unsigned char b)
{
return (( 66 * r + 129 * g + 25 * b + 128) >> 8) + 16;
}
void RGBToYRow(const unsigned char* src_argb0, unsigned char* dst_y, int width)
{
int x = 0;
for (; x < width; ++x) {
dst_y[0] = RGBToY(src_argb0[2], src_argb0[1], src_argb0[0]);
src_argb0 += 3;
dst_y += 1;
}
}
void RGB24ToI420(const unsigned char* src_rgb, int src_stride_rgb24,
unsigned char* dst_y, int dst_stride_y,
unsigned char* dst_u, int dst_stride_u,
unsigned char* dst_v, int dst_stride_v,
int width, int height)
{
if (height < 0) {
height = -height;
src_rgb = src_rgb + (height - 1) * src_stride_rgb24;
src_stride_rgb24 = -src_stride_rgb24;
}
int y = 0;
for (; y < height - 1; y += 2) {
RGBToUVRow(src_rgb, src_stride_rgb24, dst_u, dst_v, width);
RGBToYRow(src_rgb, dst_y, width);
RGBToYRow(src_rgb + src_stride_rgb24, dst_y + dst_stride_y, width);
src_rgb += src_stride_rgb24 * 2;
dst_y += dst_stride_y * 2;
dst_u += dst_stride_u;
dst_v += dst_stride_v;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment