计算机操作及程序设计
loadbmp.h
#ifndef _LOADBMP_H_
#define _LOADBMP_H_
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef struct {
/* BITMAPFILEHEADER*/
BYTE bfType[2];
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BMPFILEHEAD;
#define FILEHEADSIZE 14
/* windows style*/
typedef struct {
/* BITMAPINFOHEADER*/
DWORD BiSize;
DWORD BiWidth;
DWORD BiHeight;
WORD BiPlanes;
WORD BiBitCount;
DWORD BiCompression;
DWORD BiSizeImage;
DWORD BiXpelsPerMeter;
DWORD BiYpelsPerMeter;
DWORD BiClrUsed;
DWORD BiClrImportant;
} BMPINFOHEAD;
#define INFOHEADSIZE 40
typedef struct _BMP {
BMPINFOHEAD info;
unsigned char *rgba;
unsigned char *yuy2;
unsigned char *yv12;
} BMP, *PBMP;
int LoadBMP(char *name, PBMP pbmp);
int ReleaseBMP(PBMP pbmp);
void rgb_to_yuv(unsigned int r, unsigned int g, unsigned int b,
unsigned int *y, unsigned int *u, unsigned int *v);
#endif/*_LOADBMP_H_*/
loadbmp.c
#include
#include
#include
#include
#include
#include
#include "loadbmp.h"
void rgb_to_yuv(unsigned int r, unsigned int g, unsigned int b,
unsigned int *y, unsigned int *u, unsigned int *v)
{
double dy, du, dv;
dy = (0.257 * (double)r) +
(0.504 * (double)g) + (0.098 * (double)b) + 16.0;
dv= (0.439 * (double)r) - (0.368 * (double)g) - (0.071 * (double)b) +
128.0;
du = -(0.148 * (double)r) - (0.291 * (double)g) +
(0.439 * (double)b) + 128.0;
*y = (unsigned int)dy & 0xff;
*v = (unsigned int)dv & 0xff;
*u = (unsigned int)du & 0xff;
}
static void
convert_to_yv12(PBMP pbmp)
{
int x, y;
unsigned char *in_ptr, *out_ptr_y, *out_ptr_u, *out_ptr_v;
unsigned int Y, U, V;
in_ptr = pbmp->rgba;
out_ptr_y = pbmp->yv12;
out_ptr_u = out_ptr_y + pbmp->info.BiWidth * pbmp->info.BiHeight;
out_ptr_v = out_ptr_u + pbmp->info.BiWidth * pbmp->info.BiHeight / 4;
for (y = 0; y < pbmp->info.BiHeight; y++) {
for (x = 0; x < pbmp->info.BiWidth; x++) {
rgb_to_yuv(in_ptr[0], in_ptr[1], in_ptr[2], &Y, &U, &V);
in_ptr += pbmp->info.BiBitCount / 8;
*out_ptr_y++ = Y;
if (x % 2 == 0 && y % 2 == 0) {
*out_ptr_u++ = V;
*out_ptr_v++ = U;
}
}
}
}
static void
convert_to_yuy2(PBMP pbmp)
{
int x, y;
unsigned char *in, *out;
unsigned int Y, U, V;
in = pbmp->rgba;
out = pbmp->yuy2;
for (y = 0; y < pbmp->info.BiHeight; y++) {
for (x = 0; x < pbmp->info.BiWidth; x++) {
static int cnt = 0;
rgb_to_yuv(in[0], in[1], in[2], &Y, &U, &V);
in += pbmp->info.BiBitCount / 8;
*